Recojo información de IPv6 extra en la interfaz.

master
Félix Arreola Rodríguez 2024-01-08 13:38:06 -06:00
parent a4f9598531
commit 717259e86b
2 changed files with 150 additions and 7 deletions

View File

@ -30,6 +30,8 @@
#include <net/ethernet.h>
#include <linux/if.h>
#include <linux/if_addr.h>
#include <linux/ipv6.h>
#include <linux/if_link.h>
#include <glib.h>
#include <gmodule.h>
@ -118,6 +120,13 @@ typedef struct _WirelessInfo {
GList *aps;
} WirelessInfo;
/* Información extra de IPv6 para la interfaz */
struct inet6_data {
uint32_t i6_flags;
struct ifla_cacheinfo i6_cacheinfo;
uint32_t i6_conf[DEVCONF_MAX];
uint8_t i6_addr_gen_mode;
};
struct _Interface {
NetworkInadorHandle *handle;
@ -145,6 +154,10 @@ struct _Interface {
/* Tipo */
char rtnl_type[IFNAMSIZ];
/* Para los parámetros de IPv4 e IPv6 */
struct inet6_data inet6_data;
/* La lista de direcciones IP, ambas */
GList *address;
InterfaceDHCPClientInfo dhcpc;

View File

@ -216,7 +216,51 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
u32data = nla_get_u32 (attr);
iface->vlan_parent = u32data;
printf ("Interface %d: tiene como padre a %d\n", iface->index, iface->vlan_parent);
//printf ("Interface %d: tiene como padre a %d\n", iface->index, iface->vlan_parent);
break;
case IFLA_AF_SPEC:
{
struct nlattr *sub_family;
int sub_family_len;
sub_family = nla_data (attr);
remaining = nla_len (attr);
while (remaining > sizeof (sub_family)) {
sub_family_len = sub_family->nla_len;
if (sub_family_len > remaining) {
printf ("Los sub atributos se acabaron prematuramente\n");
break;
}
if (sub_family->nla_type == AF_INET6) {
struct nlattr *sub_attr;
int sub_remaining;
nla_for_each_nested(sub_attr, sub_family, sub_remaining) {
switch (nla_type (sub_attr)) {
case IFLA_INET6_FLAGS:
iface->inet6_data.i6_flags = nla_get_u32 (sub_attr);
break;
case IFLA_INET6_CONF:
memcpy (iface->inet6_data.i6_conf, nla_data (sub_attr), sizeof (iface->inet6_data.i6_conf));
break;
case IFLA_INET6_CACHEINFO:
memcpy (&iface->inet6_data.i6_cacheinfo, nla_data (sub_attr), sizeof (iface->inet6_data.i6_cacheinfo));
break;
case IFLA_INET6_ADDR_GEN_MODE:
iface->inet6_data.i6_addr_gen_mode = nla_get_u8 (sub_attr);
break;
}
}
}
/* Avanzar a la siguiente familia presente */
remaining -= RTA_ALIGN (sub_family_len);
sub_family = (struct nlattr *) (((char *) sub_family) + RTA_ALIGN (sub_family_len));
}
}
break;
/*default:
printf ("RTA Attribute \"%hu\" no procesado\n", nla_type (attr));*/
}
@ -229,8 +273,8 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
}
if (was_new) {
printf ("+++++ Interfaz nueva creada: %s\n", iface->name);
wireless_interface_check (handle, iface);
//printf ("+++++ Interfaz nueva creada: %s\n", iface->name);
//wireless_interface_check (handle, iface);
iface->link_type = interfaces_check_link_type (iface);
@ -334,7 +378,7 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) {
}
}
printf ("Interface %d se sacó de su bridge\n", iface->index);
//printf ("Interface %d se sacó de su bridge\n", iface->index);
/* Generar EVENTO AQUI */
manager_send_event_interface_update (handle, iface);
@ -343,7 +387,7 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) {
}
route_ask_delayed_delroute (handle);
printf ("----- Interfaz eliminada: %s\n", iface->name);
//printf ("----- Interfaz eliminada: %s\n", iface->name);
handle->interfaces = g_list_remove (handle->interfaces, iface);
@ -365,7 +409,7 @@ int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
//printf ("Error, solicitaron operación sobre interfaz que no existe\n");
return -1;
}
@ -427,7 +471,7 @@ int interfaces_change_mtu (NetworkInadorHandle *handle, int index, uint32_t new_
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
//printf ("Error, solicitaron operación sobre interfaz que no existe\n");
return -1;
}
@ -618,6 +662,91 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n
return 0;
}
/*int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...) {
uint32_t new_sysctl[DEVCONF_MAX];
Interface *iface;
va_list va_list_params;
uint32_t value;
struct nl_msg * msg, *msg2, *msg3;
struct ifinfomsg iface_hdr;
int ret, error;
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
return -1;
}
/* Copiar los sysctl previos para preservarlos */
memcpy (new_sysctl, iface->inet6_data.i6_conf, sizeof (new_sysctl));
va_start (va_list_params, param);
while (param != -1) {
value = va_arg (va_list_params, uint32_t);
if (param < DEVCONF_MAX) {
new_sysctl[param] = value;
}
param = va_arg (va_list_params, int);
}
va_end (va_list_params);
/* Preparar el mensaje de configurar la interfaz */
memset (&iface_hdr, 0, sizeof (iface_hdr));
#define LINK_ATTR_AF_SPEC (1 << 27)
iface_hdr.ifi_family = AF_UNSPEC;
iface_hdr.ifi_index = iface->index;
iface_hdr.ifi_change = LINK_ATTR_AF_SPEC;
msg = nlmsg_alloc_simple (RTM_SETLINK, NLM_F_REQUEST);
ret = nlmsg_append (msg, &iface_hdr, sizeof (iface_hdr), NLMSG_ALIGNTO);
if (ret != 0) {
nlmsg_free (msg);
return -1;
}
/* FIXME: Aquí el nesting doble o triple */
msg2 = nlmsg_alloc_simple (RTM_NEWLINK, NLM_F_REQUEST);
msg3 = nlmsg_alloc_simple (RTM_NEWLINK, NLM_F_REQUEST);
nla_put (msg3, IFLA_INET6_CONF, sizeof (new_sysctl), new_sysctl);
nla_put_nested (msg2, AF_INET6 | NLA_F_NESTED, msg3);
nla_put_nested (msg, IFLA_AF_SPEC | NLA_F_NESTED, msg2);
nl_complete_msg (handle->nl_sock_route, msg);
ret = nl_send (handle->nl_sock_route, msg);
nlmsg_free (msg);
nlmsg_free (msg2);
nlmsg_free (msg3);
if (ret <= 0) {
return -1;
}
error = 0;
nl_socket_modify_cb (handle->nl_sock_route, NL_CB_VALID, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error);
nl_socket_modify_cb (handle->nl_sock_route, NL_CB_INVALID, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error);
nl_socket_modify_cb (handle->nl_sock_route, NL_CB_ACK, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error);
nl_socket_modify_err_cb (handle->nl_sock_route, NL_CB_CUSTOM, _interfaces_wait_error, &error);
nl_recvmsgs_default (handle->nl_sock_route);
if (ret <= 0 || error < 0) {
return -1;
}
return 0;
}*/
void interfaces_init (NetworkInadorHandle *handle) {
/* Si es la primera vez que nos llaman, descargar una primera lista de interfaces */
struct nl_msg * msg;
@ -661,3 +790,4 @@ void interfaces_clean_up (NetworkInadorHandle *handle) {
g_list_free_full (handle->interfaces, free);
handle->interfaces = NULL;
}