From 717259e86be7ff19e2fc03b10de92a9dafc5ec76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Arreola=20Rodr=C3=ADguez?= Date: Mon, 8 Jan 2024 13:38:06 -0600 Subject: [PATCH] =?UTF-8?q?Recojo=20informaci=C3=B3n=20de=20IPv6=20extra?= =?UTF-8?q?=20en=20la=20interfaz.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common.h | 13 +++++ src/interfaces.c | 144 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/src/common.h b/src/common.h index e232462..f591b81 100644 --- a/src/common.h +++ b/src/common.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -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; diff --git a/src/interfaces.c b/src/interfaces.c index ec7472b..b474563 100644 --- a/src/interfaces.c +++ b/src/interfaces.c @@ -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; } +