From 29ee2fa97c990c41d6b2419f27cc2ce171bf10a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Arreola=20Rodr=C3=ADguez?= Date: Thu, 2 Jan 2020 17:03:01 -0600 Subject: [PATCH] =?UTF-8?q?Agrego=20m=C3=A9todos=20para=20agregar=20y=20qu?= =?UTF-8?q?itar=20IP's.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interfaces.c | 16 ++--- src/ip-address.c | 167 +++++++++++++++++++++++++++++++++++++++++++ src/ip-address.h | 3 + src/main.c | 8 +-- src/netlink-events.c | 2 +- 5 files changed, 183 insertions(+), 13 deletions(-) diff --git a/src/interfaces.c b/src/interfaces.c index 9632c89..a3cab69 100644 --- a/src/interfaces.c +++ b/src/interfaces.c @@ -280,7 +280,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 eliminar interfaz que ya no existe\n"); + printf ("Error, solicitaron operación sobre interfaz que no existe\n"); return -1; } @@ -325,7 +325,7 @@ int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void nl_recvmsgs_default (handle->nl_sock_route); - if (ret != 0 || error < 0) { + if (ret <= 0 || error < 0) { return -1; } @@ -342,7 +342,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 eliminar interfaz que ya no existe\n"); + printf ("Error, solicitaron operación sobre interfaz que no existe\n"); return -1; } @@ -387,7 +387,7 @@ int interfaces_change_mtu (NetworkInadorHandle *handle, int index, uint32_t new_ nl_recvmsgs_default (handle->nl_sock_route); - if (ret != 0 || error < 0) { + if (ret <= 0 || error < 0) { return -1; } @@ -403,7 +403,7 @@ static int _interfaces_change_admin_up (NetworkInadorHandle *handle, int index, iface = _interfaces_locate_by_index (handle->interfaces, index); if (iface == NULL) { - printf ("Error, solicitaron eliminar interfaz que ya no existe\n"); + printf ("Error, solicitaron operación sobre interfaz que no existe\n"); return -1; } @@ -452,7 +452,7 @@ static int _interfaces_change_admin_up (NetworkInadorHandle *handle, int index, nl_recvmsgs_default (handle->nl_sock_route); - if (ret != 0 || error < 0) { + if (ret <= 0 || error < 0) { return -1; } @@ -477,7 +477,7 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n iface = _interfaces_locate_by_index (handle->interfaces, index); if (iface == NULL) { - printf ("Error, solicitaron eliminar interfaz que ya no existe\n"); + printf ("Error, solicitaron operación sobre interfaz que no existe\n"); return -1; } @@ -526,7 +526,7 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n ret = nl_recvmsgs_default (handle->nl_sock_route); - if (ret != 0 || error < 0) { + if (ret <= 0 || error < 0) { return -1; } diff --git a/src/ip-address.c b/src/ip-address.c index 02babef..39f1e0d 100644 --- a/src/ip-address.c +++ b/src/ip-address.c @@ -180,6 +180,173 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) { return NL_SKIP; } +static int _ip_address_wait_ack_or_error (struct nl_msg *msg, void *arg) { + int *ret = (int *) arg; + struct nlmsgerr *l_err; + struct nlmsghdr *reply; + + reply = nlmsg_hdr (msg); + + if (reply->nlmsg_type == NLMSG_ERROR) { + l_err = nlmsg_data (reply); + + *ret = l_err->error; + } + + return NL_SKIP; +} + +static int _ip_address_wait_error (struct sockaddr_nl *nla, struct nlmsgerr *l_err, void *arg) { + int *ret = (int *) arg; + + *ret = l_err->error; + + return NL_SKIP; +} + +int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) { + struct nl_msg * msg; + struct ifaddrmsg addr_hdr; + int ret, error; + Interface *iface; + + iface = _interfaces_locate_by_index (handle->interfaces, index); + + if (iface == NULL) { + printf ("Error, solicitaron operación sobre interfaz que no existe\n"); + + return -1; + } + + addr_hdr.ifa_family = addr->family; + addr_hdr.ifa_prefixlen = addr->prefix; + addr_hdr.ifa_flags = addr->flags; + addr_hdr.ifa_scope = addr->scope; + addr_hdr.ifa_index = index; + + msg = nlmsg_alloc_simple (RTM_NEWADDR, NLM_F_REQUEST); + ret = nlmsg_append (msg, &addr_hdr, sizeof (addr_hdr), NLMSG_ALIGNTO); + + if (ret != 0) { + nlmsg_free (msg); + + return -1; + } + + if (addr->family == AF_INET) { + ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin_addr), &addr->sin_addr); + ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin_addr), &addr->sin_addr); + } else { + ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin6_addr), &addr->sin6_addr); + ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin6_addr), &addr->sin6_addr); + } + + if (ret != 0) { + nlmsg_free (msg); + + return -1; + } + + nl_complete_msg (handle->nl_sock_route, msg); + + ret = nl_send (handle->nl_sock_route, msg); + + nlmsg_free (msg); + if (ret <= 0) { + return -1; + } + + error = 0; + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_VALID, NL_CB_CUSTOM, _ip_address_wait_ack_or_error, &error); + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_INVALID, NL_CB_CUSTOM, _ip_address_wait_ack_or_error, &error); + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_ACK, NL_CB_CUSTOM, _ip_address_wait_ack_or_error, &error); + nl_socket_modify_err_cb (handle->nl_sock_route, NL_CB_CUSTOM, _ip_address_wait_error, &error); + + nl_recvmsgs_default (handle->nl_sock_route); + + if (ret <= 0 || error < 0) { + return -1; + } + + return 0; +} + +int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) { + struct nl_msg * msg; + struct ifaddrmsg addr_hdr; + int ret, error; + Interface *iface; + GList *addr_pos; + + iface = _interfaces_locate_by_index (handle->interfaces, index); + + if (iface == NULL) { + printf ("Error, solicitaron operación sobre interfaz que no existe\n"); + + return -1; + } + + addr_pos = g_list_find (iface->address, addr); + + if (addr_pos == NULL) { + printf ("Error, la dirección solicitada no pertenece a la interfaz\n"); + + return -1; + } + + addr_hdr.ifa_family = addr->family; + addr_hdr.ifa_prefixlen = addr->prefix; + addr_hdr.ifa_flags = addr->flags; + addr_hdr.ifa_scope = addr->scope; + addr_hdr.ifa_index = index; + + msg = nlmsg_alloc_simple (RTM_DELADDR, NLM_F_REQUEST); + ret = nlmsg_append (msg, &addr_hdr, sizeof (addr_hdr), NLMSG_ALIGNTO); + + if (ret != 0) { + nlmsg_free (msg); + + return -1; + } + + if (addr->family == AF_INET) { + ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin_addr), &addr->sin_addr); + ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin_addr), &addr->sin_addr); + } else { + ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin6_addr), &addr->sin6_addr); + ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin6_addr), &addr->sin6_addr); + } + + if (ret != 0) { + nlmsg_free (msg); + + return -1; + } + + nl_complete_msg (handle->nl_sock_route, msg); + + ret = nl_send (handle->nl_sock_route, msg); + + nlmsg_free (msg); + if (ret <= 0) { + return -1; + } + + error = 0; + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_VALID, NL_CB_CUSTOM, _ip_address_wait_ack_or_error, &error); + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_INVALID, NL_CB_CUSTOM, _ip_address_wait_ack_or_error, &error); + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_ACK, NL_CB_CUSTOM, _ip_address_wait_ack_or_error, &error); + nl_socket_modify_err_cb (handle->nl_sock_route, NL_CB_CUSTOM, _ip_address_wait_error, &error); + + nl_recvmsgs_default (handle->nl_sock_route); + + if (ret <= 0 || error < 0) { + return -1; + } + + return 0; +} + void ip_address_init (NetworkInadorHandle *handle) { /* Si es la primera vez que nos llaman, descargar una primera lista de direcciones en todas las interfaces */ struct nl_msg * msg; diff --git a/src/ip-address.h b/src/ip-address.h index 35ddf4a..cd59df3 100644 --- a/src/ip-address.h +++ b/src/ip-address.h @@ -31,4 +31,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg); void ip_address_init (NetworkInadorHandle *handle); +int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *addr); +int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *addr); + #endif diff --git a/src/main.c b/src/main.c index 05098c6..d220858 100644 --- a/src/main.c +++ b/src/main.c @@ -102,6 +102,10 @@ int main (int argc, char *argv[]) { NetworkInadorHandle handle; GMainLoop *loop = NULL; struct nl_sock * sock_req; + +#if !defined(GLIB_VERSION_2_36) + g_type_init (); +#endif _init_handle (&handle); @@ -119,10 +123,6 @@ int main (int argc, char *argv[]) { /* Crear el socket que escucha eventos */ netlink_events_setup (&handle); -#if !defined(GLIB_VERSION_2_36) - g_type_init (); -#endif - loop = g_main_loop_new (NULL, FALSE); _main_setup_signal (loop); diff --git a/src/netlink-events.c b/src/netlink-events.c index 6a21b56..27f5229 100644 --- a/src/netlink-events.c +++ b/src/netlink-events.c @@ -73,7 +73,7 @@ void netlink_events_setup (NetworkInadorHandle *handle) { } nl_socket_set_nonblocking (sock_req); - nl_socket_add_memberships (sock_req, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, 0); + nl_socket_add_memberships (sock_req, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, RTNLGRP_IPV6_IFINFO, 0); nl_socket_disable_seq_check (sock_req); nl_socket_modify_cb (sock_req, NL_CB_VALID, NL_CB_CUSTOM, _netlink_events_route_dispatcher, handle);