Agrego métodos para agregar y quitar IP's.

master
Félix Arreola Rodríguez 2020-01-02 17:03:01 -06:00
parent d2cea315d1
commit 29ee2fa97c
5 changed files with 183 additions and 13 deletions

View File

@ -280,7 +280,7 @@ int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void
iface = _interfaces_locate_by_index (handle->interfaces, index); iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) { 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; return -1;
} }
@ -325,7 +325,7 @@ int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void
nl_recvmsgs_default (handle->nl_sock_route); nl_recvmsgs_default (handle->nl_sock_route);
if (ret != 0 || error < 0) { if (ret <= 0 || error < 0) {
return -1; 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); iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) { 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; return -1;
} }
@ -387,7 +387,7 @@ int interfaces_change_mtu (NetworkInadorHandle *handle, int index, uint32_t new_
nl_recvmsgs_default (handle->nl_sock_route); nl_recvmsgs_default (handle->nl_sock_route);
if (ret != 0 || error < 0) { if (ret <= 0 || error < 0) {
return -1; return -1;
} }
@ -403,7 +403,7 @@ static int _interfaces_change_admin_up (NetworkInadorHandle *handle, int index,
iface = _interfaces_locate_by_index (handle->interfaces, index); iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) { 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; return -1;
} }
@ -452,7 +452,7 @@ static int _interfaces_change_admin_up (NetworkInadorHandle *handle, int index,
nl_recvmsgs_default (handle->nl_sock_route); nl_recvmsgs_default (handle->nl_sock_route);
if (ret != 0 || error < 0) { if (ret <= 0 || error < 0) {
return -1; 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); iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) { 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; 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); ret = nl_recvmsgs_default (handle->nl_sock_route);
if (ret != 0 || error < 0) { if (ret <= 0 || error < 0) {
return -1; return -1;
} }

View File

@ -180,6 +180,173 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) {
return NL_SKIP; 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) { void ip_address_init (NetworkInadorHandle *handle) {
/* Si es la primera vez que nos llaman, descargar una primera lista de direcciones en todas las interfaces */ /* Si es la primera vez que nos llaman, descargar una primera lista de direcciones en todas las interfaces */
struct nl_msg * msg; struct nl_msg * msg;

View File

@ -31,4 +31,7 @@
int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg); int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg);
void ip_address_init (NetworkInadorHandle *handle); 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 #endif

View File

@ -103,6 +103,10 @@ int main (int argc, char *argv[]) {
GMainLoop *loop = NULL; GMainLoop *loop = NULL;
struct nl_sock * sock_req; struct nl_sock * sock_req;
#if !defined(GLIB_VERSION_2_36)
g_type_init ();
#endif
_init_handle (&handle); _init_handle (&handle);
/* Crear el socket de peticiones */ /* Crear el socket de peticiones */
@ -119,10 +123,6 @@ int main (int argc, char *argv[]) {
/* Crear el socket que escucha eventos */ /* Crear el socket que escucha eventos */
netlink_events_setup (&handle); netlink_events_setup (&handle);
#if !defined(GLIB_VERSION_2_36)
g_type_init ();
#endif
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
_main_setup_signal (loop); _main_setup_signal (loop);

View File

@ -73,7 +73,7 @@ void netlink_events_setup (NetworkInadorHandle *handle) {
} }
nl_socket_set_nonblocking (sock_req); 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_disable_seq_check (sock_req);
nl_socket_modify_cb (sock_req, NL_CB_VALID, NL_CB_CUSTOM, _netlink_events_route_dispatcher, handle); nl_socket_modify_cb (sock_req, NL_CB_VALID, NL_CB_CUSTOM, _netlink_events_route_dispatcher, handle);