From 38ebabf853454a36d40aacf57c7726a475fe2416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Arreola=20Rodr=C3=ADguez?= Date: Thu, 2 Jan 2025 17:43:10 -0600 Subject: [PATCH] Reconecto el manager, eventos y comandos de interfaces. --- INSTALL | 6 +- client-gtk/ni-client.c | 2 +- client-gtk/ni-interface.c | 2 +- client-gtk/ni-ip.c | 2 +- client-gtk/ni-route.c | 2 +- common/flist.c | 2 +- lib/Makefile.am | 9 +- lib/dhcp_client.c | 12 +- lib/dhcpc_defs.h | 3 +- lib/event_notify.c | 108 + lib/event_notify.h | 38 + lib/getters.c | 200 ++ lib/handle.c | 2 +- lib/interfaces.c | 15 +- lib/interfaces.h | 7 +- lib/ip-address.c | 8 +- lib/ip-address.h | 2 +- lib/network-inador-events.h | 49 + {common => lib}/network-inador-manager.h | 0 lib/network-inador-private.h | 25 +- ...twork-inador.h => network-inador-public.h} | 33 +- src/Makefile.am | 11 +- src/main.c | 8 +- src/manager-interfaces.c | 306 +++ src/manager-interfaces.h | 46 + src/manager-ip.c | 318 +++ src/manager-ip.h | 40 + src/manager-private.h | 55 + src/manager.c | 1735 +---------------- src/manager.h | 44 - src/network-inador-manager.h | 109 -- src/resolv_manager.c | 76 + src/struct_addr_union.h | 32 + 33 files changed, 1424 insertions(+), 1883 deletions(-) create mode 100644 lib/event_notify.c create mode 100644 lib/event_notify.h create mode 100644 lib/getters.c create mode 100644 lib/network-inador-events.h rename {common => lib}/network-inador-manager.h (100%) rename lib/{network-inador.h => network-inador-public.h} (60%) create mode 100644 src/manager-interfaces.c create mode 100644 src/manager-interfaces.h create mode 100644 src/manager-ip.c create mode 100644 src/manager-ip.h create mode 100644 src/manager-private.h delete mode 100644 src/manager.h delete mode 100644 src/network-inador-manager.h create mode 100644 src/resolv_manager.c create mode 100644 src/struct_addr_union.h diff --git a/INSTALL b/INSTALL index 8865734..e82fd21 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* - Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software -Foundation, Inc. + Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free +Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -225,7 +225,7 @@ order to use an ANSI C compiler: and if that doesn't work, install pre-built binaries of GCC for HP-UX. - HP-UX 'make' updates targets which have the same time stamps as their + HP-UX 'make' updates targets which have the same timestamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. diff --git a/client-gtk/ni-client.c b/client-gtk/ni-client.c index a815089..b128186 100644 --- a/client-gtk/ni-client.c +++ b/client-gtk/ni-client.c @@ -36,7 +36,7 @@ #include "ni-marshal.h" #include "ni-route.h" -#include "../src/network-inador-manager.h" +#include "network-inador-manager.h" #define COMMAND_SOCKET_PATH "/tmp/network-inador.socket" diff --git a/client-gtk/ni-interface.c b/client-gtk/ni-interface.c index a365b3f..a410f7e 100644 --- a/client-gtk/ni-interface.c +++ b/client-gtk/ni-interface.c @@ -29,7 +29,7 @@ #include "ni-ip.h" #include "ni-marshal.h" -#include "../src/network-inador-manager.h" +#include "network-inador-manager.h" struct _NIInterfacePrivate { NIClient *ni_client; diff --git a/client-gtk/ni-ip.c b/client-gtk/ni-ip.c index 1b089a4..e27395a 100644 --- a/client-gtk/ni-ip.c +++ b/client-gtk/ni-ip.c @@ -27,7 +27,7 @@ #include "ni-interface.h" #include "ni-ip.h" -#include "../src/network-inador-manager.h" +#include "network-inador-manager.h" struct _NIIPPrivate { NIInterface *ni_interface; diff --git a/client-gtk/ni-route.c b/client-gtk/ni-route.c index fa006ef..8a34a91 100644 --- a/client-gtk/ni-route.c +++ b/client-gtk/ni-route.c @@ -28,7 +28,7 @@ #include "ni-route.h" #include "ni-ip.h" -#include "../src/network-inador-manager.h" +#include "network-inador-manager.h" struct _NIRoutePrivate { NIClient *ni_client; diff --git a/common/flist.c b/common/flist.c index 5bc8a77..90aa025 100644 --- a/common/flist.c +++ b/common/flist.c @@ -478,7 +478,7 @@ _f_list_remove_link (FList *list, { if (link->prev->next == link) link->prev->next = link->next; - //else + else printf ("corrupted double-linked list detected"); } if (link->next) diff --git a/lib/Makefile.am b/lib/Makefile.am index 040283c..b5fe72f 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,8 +1,9 @@ lib_LTLIBRARIES = libnetworkinador.la -libnetworkinador_la_SOURCES = network-inador.h \ - network-inador-private.h \ - network-inador-link-types.h \ +libnetworkinador_la_SOURCES = network-inador-public.h \ + event_notify.c event_notify.h \ + getters.c network-inador-private.h \ + network-inador-link-types.h network-inador-manager.h network-inador-events.h \ struct_addr_union.h wireless_struct.h \ handle.c \ netlink-events.c netlink-events.h \ @@ -29,7 +30,7 @@ libnetworkinador_la_CFLAGS = -I$(top_srcdir)/common $(LIBNL3_CFLAGS) $(LIBNLGEN3 LDADD = $(LIBINTL) libnetworkinadordir = $(includedir)/libnetworkinador -libnetworkinador_HEADERS = network-inador.h network-inador-link-types.h +libnetworkinador_HEADERS = network-inador-public.h network-inador-link-types.h network-inador-manager.h network-inador-events.h pkgconfigdir = $(libdir)/pkgconfig dist_pkgconfig_DATA = network-inador.pc diff --git a/lib/dhcp_client.c b/lib/dhcp_client.c index 2146975..6640c1d 100644 --- a/lib/dhcp_client.c +++ b/lib/dhcp_client.c @@ -35,13 +35,13 @@ #include "interfaces.h" #include "network-inador-private.h" -//#include "manager.h" +#include "network-inador-manager.h" #include "dhcp_client.h" #include "resolv_manager.h" #include "launch_process.h" -#include "network-inador-manager.h" +#include "event_notify.h" static void interfaces_dhcp_clear_info (InterfaceDHCPClientInfo *dhcpc); @@ -111,7 +111,7 @@ void interfaces_dhcp_client_killed_cb (void *data, pid_t pid, int status) { /* Enviar actualización de estado aquí */ iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED; - //manager_send_event_dhcp_change (iface->handle, &iface->dhcpc); + network_manager_trigger_dhcp_event (iface->handle, &iface->dhcpc); if (iface->dhcpc.type == IFACE_ISC_DHCLIENT || iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) { if (iface->dhcpc.flags & DHCP_CLIENT_FLAG_AUTO_RESTART) { @@ -252,7 +252,7 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type iface->dhcpc.process_watch = handle->ops.process_watch (iface->dhcpc.process_pid, interfaces_dhcp_client_killed_cb, iface); } - //manager_send_event_dhcp_change (handle, &iface->dhcpc); + network_manager_trigger_dhcp_event (handle, &iface->dhcpc); return 0; } @@ -293,7 +293,7 @@ int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) { resolv_manager_clear_dhcp_nameservers (handle, iface); /* Enviar actualización de estado aquí */ - //manager_send_event_dhcp_change (handle, &iface->dhcpc); + network_manager_trigger_dhcp_event (handle, &iface->dhcpc); } return 0; @@ -417,6 +417,6 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand resolv_manager_clear_dhcp_nameservers (handle, iface); } - //manager_send_event_dhcp_change (handle, &iface->dhcpc); + network_manager_trigger_dhcp_event (handle, &iface->dhcpc); } diff --git a/lib/dhcpc_defs.h b/lib/dhcpc_defs.h index 5f8cbbc..dde587a 100644 --- a/lib/dhcpc_defs.h +++ b/lib/dhcpc_defs.h @@ -24,7 +24,6 @@ #define __DHCPC_DEFS_H__ #include -#include "flist.h" #include "struct_addr_union.h" @@ -52,7 +51,7 @@ enum { #define DHCP_CLIENT_FLAG_DONT_ADD_ROUTE_INFO 0x0004 #define DHCP_CLIENT_FLAG_DONT_ADD_IP_INFO 0x0008 -typedef struct { +typedef struct _InterfaceDHCPClientInfo { int type; uint32_t flags; diff --git a/lib/event_notify.c b/lib/event_notify.c new file mode 100644 index 0000000..8a0c9d5 --- /dev/null +++ b/lib/event_notify.c @@ -0,0 +1,108 @@ +/* + * event_notify.c + * This file is part of Network-inador + * + * Copyright (C) 2024 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "network-inador-private.h" +#include "network-inador-events.h" +#include "interfaces.h" +#include "ip-address.h" +//#include "dhcp_defs.h" + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* Agregar vigilancias */ +void network_manager_add_watch_dhcp (NetworkInadorHandle *handle, NetworkInadorDHCPEventCB cb, void *data) { + handle->notify_list.dhcp_event_cb = cb; + handle->notify_list.dhcp_event_data = data; +} + +void network_manager_add_watch_interface_added (NetworkInadorHandle *handle, NetworkInadorInterfaceAddEventCB cb, void *data) { + handle->notify_list.interface_add_event_cb = cb; + handle->notify_list.interface_add_event_data = data; +} + +void network_manager_add_watch_interface_updated (NetworkInadorHandle *handle, NetworkInadorInterfaceUpdateEventCB cb, void *data) { + handle->notify_list.interface_update_event_cb = cb; + handle->notify_list.interface_update_event_data = data; +} + +void network_manager_add_watch_interface_deleted (NetworkInadorHandle *handle, NetworkInadorInterfaceDeleteEventCB cb, void *data) { + handle->notify_list.interface_del_event_cb = cb; + handle->notify_list.interface_del_event_data = data; +} + +void network_manager_add_watch_ip_added (NetworkInadorHandle *handle, NetworkInadorIPAddEventCB cb, void *data) { + handle->notify_list.ip_add_event_cb = cb; + handle->notify_list.ip_add_event_data = data; +} + +void network_manager_add_watch_ip_deleted (NetworkInadorHandle *handle, NetworkInadorIPDelEventCB cb, void *data) { + handle->notify_list.ip_del_event_cb = cb; + handle->notify_list.ip_del_event_data = data; +} + +/* Disparar las vigilancias */ +void network_manager_trigger_dhcp_event (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc) { + Interface *iface = container_of (dhcpc, Interface, dhcpc); + + if (handle->notify_list.dhcp_event_cb != NULL) { + handle->notify_list.dhcp_event_cb (handle, iface, dhcpc, handle->notify_list.dhcp_event_data); + } +} + +/* Triggers de interfaces */ +void network_manager_trigger_interface_added_event (NetworkInadorHandle *handle, Interface *iface) { + if (handle->notify_list.interface_add_event_cb != NULL) { + handle->notify_list.interface_add_event_cb (handle, iface, handle->notify_list.interface_add_event_data); + } +} + +void network_manager_trigger_interface_updated_event (NetworkInadorHandle *handle, Interface *iface) { + if (handle->notify_list.interface_update_event_cb != NULL) { + handle->notify_list.interface_update_event_cb (handle, iface, handle->notify_list.interface_update_event_data); + } +} + +void network_manager_trigger_interface_deleted_event (NetworkInadorHandle *handle, uint32_t index) { + if (handle->notify_list.interface_del_event_cb != NULL) { + handle->notify_list.interface_del_event_cb (handle, index, handle->notify_list.interface_del_event_data); + } +} + +/* Triggers de ips */ +void network_manager_trigger_ip_added_event (NetworkInadorHandle *handle, IPAddr *ip_addr) { + if (handle->notify_list.ip_add_event_cb != NULL) { + handle->notify_list.ip_add_event_cb (handle, ip_addr, handle->notify_list.ip_add_event_data); + } +} + +void network_manager_trigger_ip_deleted_event (NetworkInadorHandle *handle, IPAddr *ip_addr) { + if (handle->notify_list.ip_del_event_cb != NULL) { + handle->notify_list.ip_del_event_cb (handle, ip_addr, handle->notify_list.ip_del_event_data); + } +} + diff --git a/lib/event_notify.h b/lib/event_notify.h new file mode 100644 index 0000000..ba5edf3 --- /dev/null +++ b/lib/event_notify.h @@ -0,0 +1,38 @@ +/* + * event_notify.h + * This file is part of Network-inador + * + * Copyright (C) 2024 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __EVENT_NOTIFY_H__ +#define __EVENT_NOTIFY_H__ + +#include + +#include "network-inador-events.h" + +void network_manager_trigger_dhcp_event (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc); +void network_manager_trigger_interface_added_event (NetworkInadorHandle *handle, Interface *iface); +void network_manager_trigger_interface_updated_event (NetworkInadorHandle *handle, Interface *iface); +void network_manager_trigger_interface_deleted_event (NetworkInadorHandle *handle, uint32_t index); +void network_manager_trigger_ip_added_event (NetworkInadorHandle *handle, IPAddr *ip_addr); +void network_manager_trigger_ip_deleted_event (NetworkInadorHandle *handle, IPAddr *ip_addr); + +#endif /* __EVENT_NOTIFY_H__ */ + diff --git a/lib/getters.c b/lib/getters.c new file mode 100644 index 0000000..8125671 --- /dev/null +++ b/lib/getters.c @@ -0,0 +1,200 @@ +/* + * getters.c + * This file is part of Network-inador + * + * Copyright (C) 2025 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "network-inador-private.h" +#include "interfaces.h" +#include "ip-address.h" + +uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle) { + uint32_t *memory; + FList *g; + Interface *iface; + int c; + + memory = (uint32_t *) malloc ((handle->interfaces_counter + 1) * sizeof (uint32_t)); + + if (memory == NULL) return NULL; + + c = 0; + for (g = handle->interfaces; g != NULL; g = g->next) { + iface = (Interface *) g->data; + + memory[c] = iface->index; + c++; + } + memory[c] = 0; + + return memory; +} + +Interface *network_inador_get_iface (NetworkInadorHandle *handle, uint32_t index) { + _interfaces_locate_by_index (handle->interfaces, index); +} + +const unsigned char *network_inador_iface_get_name (Interface *iface) { + return iface->name; +} + +uint32_t network_inador_iface_get_index (Interface *iface) { + return iface->index; +} + +uint32_t network_inador_iface_get_link_type (Interface *iface) { + return iface->link_type; +} + +uint32_t network_inador_iface_get_master_index (Interface *iface) { + return iface->master_index; +} + +uint32_t network_inador_iface_get_mtu (Interface *iface) { + return iface->mtu; +} + +uint16_t network_inador_iface_get_flags (Interface *iface) { + return iface->flags; +} + +uint8_t network_inador_iface_get_is_wireless (Interface *iface) { + return iface->is_wireless; +} + +uint8_t network_inador_iface_get_num_ips (Interface *iface) { + return iface->address_counter; +} + +IPAddr *network_inador_iface_get_ipaddr_by_index (Interface *iface, int index) { + FList *pos; + pos = f_list_nth (f_list_first (iface->address), index); + if (pos == NULL) return NULL; + return (IPAddr *) (pos->data); +} + +Interface *network_inador_ipaddr_get_iface (IPAddr *ip_addr) { + return ip_addr->iface; +} + +uint8_t network_inador_ipaddr_get_family (IPAddr *ip_addr) { + return ip_addr->family; +} + +uint8_t network_inador_ipaddr_get_prefix (IPAddr *ip_addr) { + return ip_addr->prefix; +} + +uint8_t network_inador_ipaddr_has_local (IPAddr *ip_addr) { + return ip_addr->has_local; +} + +uint8_t network_inador_ipaddr_has_brd (IPAddr *ip_addr) { + return ip_addr->has_brd; +} + +uint8_t network_inador_ipaddr_get_scope (IPAddr *ip_addr) { + return ip_addr->scope; +} + +uint32_t network_inador_ipaddr_get_flags (IPAddr *ip_addr) { + return ip_addr->flags; +} + +void network_inador_ipaddr_get_cacheinfo (IPAddr *ip_addr, struct ifa_cacheinfo *cacheinfo) { + memcpy (cacheinfo, &ip_addr->cacheinfo, sizeof (struct ifa_cacheinfo)); +} + +void network_inador_ipaddr_get_addr (IPAddr *ip_addr, void *addr, int *addr_size) { + int family_size = 0; + + if (ip_addr->family == AF_INET) { + family_size = sizeof (struct in_addr); + } else if (ip_addr->family == AF_INET6) { + family_size = sizeof (struct in6_addr); + } + + if (addr_size != NULL) { + /* Verificar que no supere el máximo de la dirección */ + if (*addr_size < family_size) { + family_size = *addr_size; + } + } + + memcpy (addr, &ip_addr->addr, family_size); + + if (addr_size != NULL) { + *addr_size = family_size; + } +} + +void network_inador_ipaddr_get_local_addr (IPAddr *ip_addr, void *addr, int *addr_size) { + int family_size = 0; + + if (ip_addr->family == AF_INET) { + family_size = sizeof (struct in_addr); + } else if (ip_addr->family == AF_INET6) { + family_size = sizeof (struct in6_addr); + } + + if (addr_size != NULL) { + /* Verificar que no supere el máximo de la dirección */ + if (*addr_size < family_size) { + family_size = *addr_size; + } + } + + memcpy (addr, &ip_addr->local_addr, family_size); + + if (addr_size != NULL) { + *addr_size = family_size; + } +} + +void network_inador_ipaddr_get_brd_addr (IPAddr *ip_addr, void *addr, int *addr_size) { + int family_size = 0; + + if (ip_addr->family == AF_INET) { + family_size = sizeof (struct in_addr); + } else if (ip_addr->family == AF_INET6) { + family_size = sizeof (struct in6_addr); + } + + if (addr_size != NULL) { + /* Verificar que no supere el máximo de la dirección */ + if (*addr_size < family_size) { + family_size = *addr_size; + } + } + + memcpy (addr, &ip_addr->brd_addr, family_size); + + if (addr_size != NULL) { + *addr_size = family_size; + } +} + +const unsigned char *network_inador_ipaddr_get_label (IPAddr *ip_addr) { + return ip_addr->label; +} + diff --git a/lib/handle.c b/lib/handle.c index ba104e0..210bf56 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -1,5 +1,5 @@ /* - * main.c + * handle.c * This file is part of Network-inador * * Copyright (C) 2024 - Félix Arreola Rodríguez diff --git a/lib/interfaces.c b/lib/interfaces.c index 0d5ad2a..31c77a2 100644 --- a/lib/interfaces.c +++ b/lib/interfaces.c @@ -34,7 +34,7 @@ #include "routes.h" #include "ip-address.h" #include "wireless_if.h" -//#include "manager.h" +#include "event_notify.h" #include "network-inador-link-types.h" @@ -117,6 +117,7 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, memset (iface, 0, sizeof (Interface)); iface->handle = handle; + handle->interfaces_counter++; handle->interfaces = f_list_append (handle->interfaces, iface); was_new = 1; @@ -137,7 +138,7 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, //printf ("Interface %d agregada a la interfaz %d (bridge)\n", iface->index, iface->master_index); was_update = 1; - //manager_send_event_interface_update (handle, iface); + network_manager_trigger_interface_updated_event (handle, iface); return NL_SKIP; } @@ -286,9 +287,9 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, iface->link_type = interfaces_check_link_type (iface); - //manager_send_event_interface_add (handle, iface); + network_manager_trigger_interface_added_event (handle, iface); } else if (was_update) { - //manager_send_event_interface_update (handle, iface); + network_manager_trigger_interface_updated_event (handle, iface); } return NL_SKIP; @@ -389,7 +390,7 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) { //printf ("Interface %d se sacó de su bridge\n", iface->index); /* Generar EVENTO AQUI */ - //manager_send_event_interface_update (handle, iface); + network_manager_trigger_interface_updated_event (handle, iface); return NL_SKIP; } @@ -398,11 +399,12 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) { //printf ("----- Interfaz eliminada: %s\n", iface->name); handle->interfaces = f_list_remove (handle->interfaces, iface); + handle->interfaces_counter--; /* Antes de eliminar la interfaz, eliminar la lista ligada de todas las direcciones IP */ f_list_free_full (iface->address, free); - //manager_send_event_interface_del (handle, iface->index); + network_manager_trigger_interface_deleted_event (handle, iface->index); free (iface); } @@ -797,6 +799,7 @@ void interfaces_clean_up (NetworkInadorHandle *handle) { iface->address = NULL; } + handle->interfaces_counter = 0; f_list_free_full (handle->interfaces, free); handle->interfaces = NULL; } diff --git a/lib/interfaces.h b/lib/interfaces.h index 79f50c1..c1b2678 100644 --- a/lib/interfaces.h +++ b/lib/interfaces.h @@ -45,7 +45,7 @@ struct inet6_data { uint8_t i6_addr_gen_mode; }; -typedef struct { +typedef struct _Interface { NetworkInadorHandle *handle; uint32_t index; char name[IFNAMSIZ]; @@ -64,7 +64,7 @@ typedef struct { /* Banderas estilo ioctl */ short flags; - int is_wireless; + uint8_t is_wireless; char wireless_protocol[IFNAMSIZ]; @@ -77,6 +77,9 @@ typedef struct { /* La lista de direcciones IP, ambas */ FList *address; + /* Contador auxiliar para la lista de direcciones IP */ + int address_counter; + InterfaceDHCPClientInfo dhcpc; /* Información wireless */ diff --git a/lib/ip-address.c b/lib/ip-address.c index bd8b44a..8371cf0 100644 --- a/lib/ip-address.c +++ b/lib/ip-address.c @@ -32,7 +32,7 @@ #include "network-inador-private.h" #include "ip-address.h" #include "interfaces.h" -//#include "manager.h" +#include "event_notify.h" #include "routes.h" IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, void *addr, uint32_t prefix, void *local_addr) { @@ -162,6 +162,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) { memset (ip_addr, 0, sizeof (*ip_addr)); iface->address = f_list_append (iface->address, ip_addr); + iface->address_counter++; ip_addr->family = addr_msg->ifa_family; memcpy (&ip_addr->addr, &addr, family_size); @@ -203,7 +204,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) { } if (was_new) { - //manager_send_event_ip_add (handle, ip_addr); + network_manager_trigger_ip_added_event (handle, ip_addr); } else { /* En caso contrario, enviar una actualización de IP */ } @@ -286,10 +287,11 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) { printf ("Dirección IP - %s/%d sobre interfaz: %d, scope: %d, flags: %u\n", buffer, ip_addr->prefix, iface->index, (unsigned int) ip_addr->scope, ip_addr->flags); /* Eliminar de la lista ligada */ + iface->address_counter--; iface->address = f_list_remove (iface->address, ip_addr); /* Notificar del evento */ - //manager_send_event_ip_del (handle, ip_addr); + network_manager_trigger_ip_deleted_event (handle, ip_addr); free (ip_addr); diff --git a/lib/ip-address.h b/lib/ip-address.h index df360cb..42f1833 100644 --- a/lib/ip-address.h +++ b/lib/ip-address.h @@ -35,7 +35,7 @@ #define INFINITY_LIFE_TIME 0xFFFFFFFFU #endif -typedef struct { +typedef struct _IPAddr { sa_family_t family; uint8_t prefix; diff --git a/lib/network-inador-events.h b/lib/network-inador-events.h new file mode 100644 index 0000000..94f3264 --- /dev/null +++ b/lib/network-inador-events.h @@ -0,0 +1,49 @@ +/* + * network-inador-events.h + * This file is part of Network-inador + * + * Copyright (C) 2024 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __NETWORK_INADOR_EVENTS_H__ +#define __NETWORK_INADOR_EVENTS_H__ + +#include + +typedef struct _NetworkInadorHandle NetworkInadorHandle; +typedef struct _Interface Interface; +typedef struct _InterfaceDHCPClientInfo InterfaceDHCPClientInfo; +typedef struct _IPAddr IPAddr; + +typedef void (*NetworkInadorDHCPEventCB) (NetworkInadorHandle *handle, Interface *iface, InterfaceDHCPClientInfo *dhcp_info, void *data); +typedef void (*NetworkInadorInterfaceAddEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data); +typedef void (*NetworkInadorInterfaceUpdateEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data); +typedef void (*NetworkInadorInterfaceDeleteEventCB) (NetworkInadorHandle *handle, uint32_t index, void *data); +typedef void (*NetworkInadorIPAddEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data); +typedef void (*NetworkInadorIPDelEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data); + +/* Pendiente notificar rutas */ +void network_manager_add_watch_dhcp (NetworkInadorHandle *handle, NetworkInadorDHCPEventCB cb, void *data); +void network_manager_add_watch_interface_added (NetworkInadorHandle *handle, NetworkInadorInterfaceAddEventCB cb, void *data); +void network_manager_add_watch_interface_updated (NetworkInadorHandle *handle, NetworkInadorInterfaceUpdateEventCB cb, void *data); +void network_manager_add_watch_interface_deleted (NetworkInadorHandle *handle, NetworkInadorInterfaceDeleteEventCB cb, void *data); +void network_manager_add_watch_ip_added (NetworkInadorHandle *handle, NetworkInadorIPAddEventCB cb, void *data); +void network_manager_add_watch_ip_deleted (NetworkInadorHandle *handle, NetworkInadorIPDelEventCB cb, void *data); + +#endif /* __NETWORK_INADOR_EVENTS_H__ */ + diff --git a/common/network-inador-manager.h b/lib/network-inador-manager.h similarity index 100% rename from common/network-inador-manager.h rename to lib/network-inador-manager.h diff --git a/lib/network-inador-private.h b/lib/network-inador-private.h index b044033..4e6d785 100644 --- a/lib/network-inador-private.h +++ b/lib/network-inador-private.h @@ -31,8 +31,9 @@ #include #include -#include "network-inador.h" +#include "network-inador-public.h" #include "flist.h" +#include "network-inador-events.h" /* Para vigilar eventos */ typedef struct { @@ -40,6 +41,23 @@ typedef struct { unsigned int source; } NetlinkEventPair; +typedef struct _NetworkInadorEventList { + NetworkInadorDHCPEventCB dhcp_event_cb; + void *dhcp_event_data; + + NetworkInadorInterfaceAddEventCB interface_add_event_cb; + void *interface_add_event_data; + NetworkInadorInterfaceUpdateEventCB interface_update_event_cb; + void *interface_update_event_data; + NetworkInadorInterfaceDeleteEventCB interface_del_event_cb; + void *interface_del_event_data; + + NetworkInadorIPAddEventCB ip_add_event_cb; + void *ip_add_event_data; + NetworkInadorIPDelEventCB ip_del_event_cb; + void *ip_del_event_data; +} NetworkInadorEventList; + /* La definición principal que engloba todo */ struct _NetworkInadorHandle { struct NetworkInadorOps ops; @@ -50,6 +68,9 @@ struct _NetworkInadorHandle { FList *route_v6_tables; FList *route_tables_names; + /* Auxiliar contador de la lista ligada de interfaces */ + int interfaces_counter; + /* Entradas para el resolv conf */ FList *resolver_entries; int resolver_inotify_fd; @@ -69,6 +90,8 @@ struct _NetworkInadorHandle { /* El pipe de vigilancia especial de las rutas eliminadas */ int pipe_routes[2]; unsigned int source_pipe_routes; + + struct _NetworkInadorEventList notify_list; }; #endif /* __NETWORK_INADOR_PRIVATE_H__ */ diff --git a/lib/network-inador.h b/lib/network-inador-public.h similarity index 60% rename from lib/network-inador.h rename to lib/network-inador-public.h index e72f3f0..47d4bf6 100644 --- a/lib/network-inador.h +++ b/lib/network-inador-public.h @@ -30,6 +30,8 @@ #include #include +#include + #ifndef FALSE #define FALSE 0 #endif @@ -38,8 +40,6 @@ #define TRUE !FALSE #endif -typedef struct _NetworkInadorHandle NetworkInadorHandle; - /* Función que define una lectura desde un FD */ typedef void (*NetworkInadorInputFunc) (void *, int, int); typedef void (*NetworkInadorChildWatchFunc) (void *, pid_t, int); @@ -56,6 +56,10 @@ struct NetworkInadorOps { /* Ver si agregamos timers aquí */ }; +typedef struct _NetworkInadorHandle NetworkInadorHandle; +typedef struct _Interface Interface; +typedef struct _IPAddr IPAddr; + NetworkInadorHandle * network_inador_init_handle (struct NetworkInadorOps *network_inador_ops); void network_inador_destroy_handle (NetworkInadorHandle *handle); @@ -72,5 +76,30 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags); int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index); +/* Lista de getters */ +uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle); +Interface * network_inador_get_iface (NetworkInadorHandle *handle, uint32_t index); +const unsigned char *network_inador_iface_get_name (Interface *iface); +uint32_t network_inador_iface_get_index (Interface *iface); +uint32_t network_inador_iface_get_link_type (Interface *iface); +uint32_t network_inador_iface_get_master_index (Interface *iface); +uint32_t network_inador_iface_get_mtu (Interface *iface); +uint16_t network_inador_iface_get_flags (Interface *iface); +uint8_t network_inador_iface_get_is_wireless (Interface *iface); +uint8_t network_inador_iface_get_num_ips (Interface *iface); +IPAddr *network_inador_iface_get_ipaddr_by_index (Interface *iface, int index); +Interface *network_inador_ipaddr_get_iface (IPAddr *ip_addr); +uint8_t network_inador_ipaddr_get_family (IPAddr *ip_addr); +uint8_t network_inador_ipaddr_get_prefix (IPAddr *ip_addr); +uint8_t network_inador_ipaddr_has_local (IPAddr *ip_addr); +uint8_t network_inador_ipaddr_has_brd (IPAddr *ip_addr); +uint8_t network_inador_ipaddr_get_scope (IPAddr *ip_addr); +uint32_t network_inador_ipaddr_get_flags (IPAddr *ip_addr); +void network_inador_ipaddr_get_cacheinfo (IPAddr *ip_addr, struct ifa_cacheinfo *cacheinfo); +void network_inador_ipaddr_get_addr (IPAddr *ip_addr, void *addr, int *addr_size); +void network_inador_ipaddr_get_local_addr (IPAddr *ip_addr, void *addr, int *addr_size); +void network_inador_ipaddr_get_brd_addr (IPAddr *ip_addr, void *addr, int *addr_size); +const unsigned char *network_inador_ipaddr_get_label (IPAddr *ip_addr); + #endif /* __NETWORK_INADOR_H__ */ diff --git a/src/Makefile.am b/src/Makefile.am index db38e0a..9b8f726 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,10 +1,11 @@ # Automake file for NetworkInador -bin_PROGRAMS = network-inador -network_inador_SOURCES = main.c -# manager.c manager.h +sbin_PROGRAMS = network-inador resolvconf +network_inador_SOURCES = main.c \ + manager.c manager-private.h \ + manager-interfaces.c manager-interfaces.h \ + manager-ip.c manager-ip.h -sbin_PROGRAMS = resolvconf resolvconf_SOURCES = resolv_conf_helper.c \ ../common/flist.c ../common/flist.h \ ../common/resolv_conf_parser.c ../common/resolv_conf_parser.h \ @@ -16,7 +17,7 @@ resolvconf_LDADD = libexec_PROGRAMS = ni-dhcp-helper ni_dhcp_helper_SOURCES = ni-dhcp-iface-helper.c -ni_dhcp_helper_CPPFLAGS = $(AM_CPPFLAGS) +ni_dhcp_helper_CPPFLAGS = -I$(top_srcdir)/lib $(AM_CPPFLAGS) ni_dhcp_helper_CFLAGS = $(AM_CFLAGS) #network_inador_CPPFLAGS = -DGAMEDATA_DIR=\"$(gamedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS) diff --git a/src/main.c b/src/main.c index 1711536..2fa9bf2 100644 --- a/src/main.c +++ b/src/main.c @@ -38,7 +38,8 @@ #include -#include "network-inador.h" +#include "network-inador-public.h" +#include "manager-private.h" /* Usados para salir en caso de una señal */ static int sigterm_pipe_fds[2] = { -1, -1 }; @@ -152,7 +153,8 @@ struct NetworkInadorOps network_ops = { int main (int argc, char *argv[]) { NetworkInadorHandle *handle; GMainLoop *loop = NULL; - + Manager *unix_socket_manager; + #if !defined(GLIB_VERSION_2_36) g_type_init (); #endif @@ -166,6 +168,8 @@ int main (int argc, char *argv[]) { _main_setup_signal (loop); + unix_socket_manager = manager_new (handle, 0); + interfaces_dhcp_client_run (handle, 3, 1, 1); /*IPAddr addr; inet_pton (AF_INET, "192.19.5.6", &addr.sin_addr); diff --git a/src/manager-interfaces.c b/src/manager-interfaces.c new file mode 100644 index 0000000..8aecd4a --- /dev/null +++ b/src/manager-interfaces.c @@ -0,0 +1,306 @@ +/* + * manager-interfaces.c + * This file is part of Network-inador + * + * Copyright (C) 2025 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include + +#include +#include +#include + +#include "manager-private.h" +#include "network-inador-public.h" +#include "network-inador-manager.h" + +/* Empaquetador de datos */ +int _manager_pack_interface_info (unsigned char *buffer, Interface *iface) { + const unsigned char *iface_name; + uint32_t u32; uint16_t u16; uint8_t u8; + int string_len; + + iface_name = network_inador_iface_get_name (iface); + string_len = strlen (iface_name); + + u32 = network_inador_iface_get_index (iface); + memcpy (&buffer[0], &u32, 4); + + u32 = network_inador_iface_get_link_type (iface); + memcpy (&buffer[4], &u32, 4); + + u32 = network_inador_iface_get_master_index (iface); + memcpy (&buffer[8], &u32, 4); + + u32 = network_inador_iface_get_mtu (iface); + memcpy (&buffer[12], &u32, 4); + + u16 = network_inador_iface_get_flags (iface); + memcpy (&buffer[16], &u16, 2); + + buffer[18] = network_inador_iface_get_is_wireless (iface); + buffer[19] = string_len; + memcpy (&buffer[20], iface_name, string_len); + + return 20 + string_len; +} + +/* Los comandos que verdaderamente envian */ +void _manager_send_interface (ManagerClientInfo *manager_client, Interface *iface, uint8_t is_event) { + unsigned char buffer[32 + IFNAMSIZ + IFNAMSIZ]; + int size; + + if (is_event) { + buffer[0] = NET_INADOR_TYPE_EVENT; + buffer[1] = NET_INADOR_EVENT_IFACE_ADDED; + } else { + buffer[0] = NET_INADOR_TYPE_RESPONSE; + buffer[1] = NET_INADOR_RESPONSE_IFACE; + } + + size = 2 + _manager_pack_interface_info (&buffer[2], iface); + + send (manager_client->fd, buffer, size, 0); +} + +void _manager_send_interface_deleted (ManagerClientInfo *manager_client, uint32_t index) { + unsigned char buffer[32]; + + buffer[0] = NET_INADOR_TYPE_EVENT; + buffer[1] = NET_INADOR_EVENT_IFACE_REMOVED; + + memcpy (&buffer[2], &index, 4); + + send (manager_client->fd, buffer, 6, 0); +} + +void _manager_interface_handle_list_interfaces (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { + uint32_t *list_index; + int g; + Interface *iface; + + list_index = network_inador_list_ifaces (manager_client->manager->handle); + + /* TODO Analizar si podemos hacer todo en un solo envio incluyendo el comando de fin de listado */ + if (list_index == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_UNKNOWN, NET_INADOR_COMMAND_LIST_IFACES); + + return; + } + + g = 0; + while (list_index[g] != 0) { + iface = network_inador_get_iface (manager_client->manager->handle, list_index[g]); + if (iface == NULL) continue; + + _manager_send_interface (manager_client, iface, FALSE); + + g++; + } + + _manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_IFACES); + free (list_index); +} + +void _manager_interface_handle_get_interface (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { + Interface *iface; + uint32_t u32; + + if (buffer_len < 6) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_GET_IFACE); + return; + } + + memcpy (&u32, &buffer[2], 4); + iface = network_inador_get_iface (manager_client->manager->handle, u32); + if (iface == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_GET_IFACE); + return; + } + + _manager_send_interface (manager_client, iface, FALSE); +} + +void _manager_interface_handle_up_down_command (ManagerClientInfo *manager_client, uint8_t is_up, unsigned char *buffer, int buffer_len) { + Interface *iface; + uint32_t u32; + int ret; + + if (buffer_len < 6) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, (is_up ? NET_INADOR_COMMAND_IFACE_UP : NET_INADOR_COMMAND_IFACE_DOWN)); + return; + } + + memcpy (&u32, &buffer[2], 4); + iface = network_inador_get_iface (manager_client->manager->handle, u32); + if (iface == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, (is_up ? NET_INADOR_COMMAND_IFACE_UP : NET_INADOR_COMMAND_IFACE_DOWN)); + return; + } + + if (is_up) { + ret = interfaces_change_set_up (manager_client->manager->handle, u32); + } else { + ret = interfaces_change_set_down (manager_client->manager->handle, u32); + } + + if (ret == 0) { + /* OK */ + _manager_send_executed (manager_client); + } else { + _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, (is_up ? NET_INADOR_COMMAND_IFACE_UP : NET_INADOR_COMMAND_IFACE_DOWN)); + } +} + +void _manager_interface_handle_change_name (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { + Interface *iface; + uint32_t u32; + int ret; + int name_len; + unsigned char name[IFNAMSIZ]; + + if (buffer_len < 7) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); + return; + } + + memcpy (&u32, &buffer[2], 4); + iface = network_inador_get_iface (manager_client->manager->handle, u32); + if (iface == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); + return; + } + + name_len = buffer[6]; + if (name_len == 0 || name_len >= IFNAMSIZ) { + _manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); + return; + } + + if (name_len + 7 < buffer_len) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); + return; + } + + memcpy (name, &buffer[7], name_len); + if (name[0] == 0) { + _manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); + return; + } + name[name_len] = 0; + + ret = interfaces_change_name (manager_client->manager->handle, u32, name); + + if (ret == 0) { + /* OK */ + _manager_send_executed (manager_client); + } else { + _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); + } +} + +void _manager_interface_handle_change_mtu (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { + Interface *iface; + uint32_t u32, new_mtu; + int ret; + int name_len; + unsigned char name[IFNAMSIZ]; + + if (buffer_len < 10) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_MTU); + return; + } + + memcpy (&u32, &buffer[2], 4); + iface = network_inador_get_iface (manager_client->manager->handle, u32); + if (iface == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_IFACE_CHANGE_MTU); + return; + } + + memcpy (&new_mtu, &buffer[6], 4); + //new_mtu = ntohl (new_mtu); + + /* TODO: Revisar el máximo de MTU que se puede poner */ + ret = interfaces_change_mtu (manager_client->manager->handle, u32, new_mtu); + + if (ret == 0) { + /* OK */ + _manager_send_executed (manager_client); + } else { + _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_IFACE_CHANGE_MTU); + } +} + +/* Los eventos que vienen desde la librería */ +void _manager_interface_added_event_cb (NetworkInadorHandle *handle, Interface *iface, void *data) { + Manager *manager = (Manager *) data; + GList *g; + ManagerClientInfo *manager_client; + + printf ("___ MANAGER ___ Informando interfaz agregada: %s (%i)\n", network_inador_iface_get_name (iface), network_inador_iface_get_index (iface)); + + for (g = manager->connected_client_list; g != NULL; g = g->next) { + manager_client = (ManagerClientInfo *) g->data; + + if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_INTERFACES) { + printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); + _manager_send_interface (manager_client, iface, TRUE); + } + } +} + +void _manager_interface_updated_event_cb (NetworkInadorHandle *handle, Interface *iface, void *data) { + Manager *manager = (Manager *) data; + GList *g; + ManagerClientInfo *manager_client; + + printf ("___ MANAGER ___ Informando interfaz actualizada: %s (%i)\n", network_inador_iface_get_name (iface), network_inador_iface_get_index (iface)); + + for (g = manager->connected_client_list; g != NULL; g = g->next) { + manager_client = (ManagerClientInfo *) g->data; + + if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_INTERFACES) { + printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); + _manager_send_interface (manager_client, iface, TRUE); + } + } +} + +void _manager_interface_deleted_event_cb (NetworkInadorHandle *handle, uint32_t index, void *data) { + Manager *manager = (Manager *) data; + GList *g; + ManagerClientInfo *manager_client; + + printf ("___ MANAGER ___ Informando interfaz eliminada: %i\n", index); + + for (g = manager->connected_client_list; g != NULL; g = g->next) { + manager_client = (ManagerClientInfo *) g->data; + + if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_INTERFACES) { + printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); + _manager_send_interface_deleted (manager_client, index); + } + } +} + diff --git a/src/manager-interfaces.h b/src/manager-interfaces.h new file mode 100644 index 0000000..7bf13ca --- /dev/null +++ b/src/manager-interfaces.h @@ -0,0 +1,46 @@ +/* + * manager-interfaces.h + * This file is part of Network-inador + * + * Copyright (C) 2025 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __MANAGER_INTERFACES_H__ +#define __MANAGER_INTERFACES_H__ + +#include +#include +#include + +#include "manager-private.h" +#include "network-inador-public.h" +#include "network-inador-manager.h" + +void _manager_interface_handle_list_interfaces (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len); +void _manager_interface_handle_get_interface (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len); +void _manager_interface_handle_up_down_command (ManagerClientInfo *manager_client, uint8_t is_up, unsigned char *buffer, int buffer_len); +void _manager_interface_handle_change_name (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len); +void _manager_interface_handle_change_mtu (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len); + +void _manager_interface_added_event_cb (NetworkInadorHandle *handle, Interface *iface, void *data); +void _manager_interface_updated_event_cb (NetworkInadorHandle *handle, Interface *iface, void *data); +void _manager_interface_deleted_event_cb (NetworkInadorHandle *handle, uint32_t index, void *data); + + +#endif /* __MANAGER_INTERFACES_H__ */ + diff --git a/src/manager-ip.c b/src/manager-ip.c new file mode 100644 index 0000000..4cb3718 --- /dev/null +++ b/src/manager-ip.c @@ -0,0 +1,318 @@ +/* + * manager-ip.c + * This file is part of Network-inador + * + * Copyright (C) 2025 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "manager-private.h" +#include "network-inador-public.h" +#include "network-inador-manager.h" + +int _manager_pack_ip_info (unsigned char *buffer, IPAddr *ip_addr) { + int family_size = 0; + int label_len; + int pos; + int family; + uint32_t index, flags; + Interface *iface; + int has_brd, has_local; + struct ifa_cacheinfo cacheinfo; + const char *label; + + union { + struct in_addr v4; + struct in6_addr v6; + } addr; + + /* Familia y máscara */ + family = network_inador_ipaddr_get_family (ip_addr); + if (family == AF_INET) { + family_size = sizeof (struct in_addr); + } else if (family == AF_INET6) { + family_size = sizeof (struct in6_addr); + } + + iface = network_inador_ipaddr_get_iface (ip_addr); + index = network_inador_iface_get_index (iface); + memcpy (&buffer[0], &index, 4); + buffer[4] = family; + buffer[5] = network_inador_ipaddr_get_prefix (ip_addr); + + has_local = network_inador_ipaddr_has_local (ip_addr); + has_brd = network_inador_ipaddr_has_brd (ip_addr); + + /* Los campos de bits */ + buffer[6] = 0; + if (has_local) { + buffer[6] |= 0x01; + } + if (has_brd) { + buffer[6] |= 0x02; + } + + /* Byte scope y las flags */ + buffer[7] = network_inador_ipaddr_get_scope (ip_addr); + flags = network_inador_ipaddr_get_flags (ip_addr); + memcpy (&buffer[8], &flags, 4); + + network_inador_ipaddr_get_cacheinfo (ip_addr, &cacheinfo); + /* La información de marcas de tiempo de las IPs */ + memcpy (&buffer[12], &cacheinfo, 16); + + /* La dirección principal */ + network_inador_ipaddr_get_addr (ip_addr, &addr, NULL); + memcpy (&buffer[28], &addr, family_size); + pos = 28 + family_size; + if (has_local) { + network_inador_ipaddr_get_local_addr (ip_addr, &addr, NULL); + memcpy (&buffer[pos], &addr, family_size); + pos += family_size; + } + + if (has_brd) { + network_inador_ipaddr_get_brd_addr (ip_addr, &addr, NULL); + memcpy (&buffer[pos], &addr, family_size); + pos += family_size; + } + + label = network_inador_ipaddr_get_label (ip_addr); + if (label[0] != 0) { + label_len = strlen (label); + buffer[pos] = label_len; + pos++; + + memcpy (&buffer[pos], &label, label_len); + pos += label_len; + } else { + buffer[pos] = 0; + pos++; + } + + return pos; +} + +/* Los comandos que verdaderamente envian */ +void _manager_send_ipaddr (ManagerClientInfo *manager_client, IPAddr *ip_addr, uint8_t is_event) { + unsigned char buffer[80]; + int size; + + if (is_event) { + buffer[0] = NET_INADOR_TYPE_EVENT; + buffer[1] = NET_INADOR_EVENT_IPADDR_ADDED; + } else { + buffer[0] = NET_INADOR_TYPE_RESPONSE; + buffer[1] = NET_INADOR_RESPONSE_IPADDR; + } + + size = 2 + _manager_pack_ip_info (&buffer[2], ip_addr); + + send (manager_client->fd, buffer, size, 0); +} + +void _manager_send_ipaddr_deleted (ManagerClientInfo *manager_client, IPAddr *ip_addr) { + unsigned char buffer[80]; + int family_size = 0; + int pos; + int family; + uint32_t index; + Interface *iface; + int has_brd, has_local; + + union { + struct in_addr v4; + struct in6_addr v6; + } addr; + + buffer[0] = NET_INADOR_TYPE_EVENT; + buffer[1] = NET_INADOR_EVENT_IPADDR_REMOVED; + + /* Familia y máscara */ + family = network_inador_ipaddr_get_family (ip_addr); + if (family == AF_INET) { + family_size = sizeof (struct in_addr); + } else if (family == AF_INET6) { + family_size = sizeof (struct in6_addr); + } + iface = network_inador_ipaddr_get_iface (ip_addr); + index = network_inador_iface_get_index (iface); + memcpy (&buffer[2], &index, 4); + buffer[6] = family; + buffer[7] = network_inador_ipaddr_get_prefix (ip_addr); + + has_local = network_inador_ipaddr_has_local (ip_addr); + + buffer[8] = 0; + if (has_local) { + buffer[8] |= 0x01; + } + + buffer[9] = 0; + + network_inador_ipaddr_get_addr (ip_addr, &addr, NULL); + memcpy (&buffer[10], &addr, family_size); + pos = 10 + family_size; + if (has_local) { + network_inador_ipaddr_get_local_addr (ip_addr, &addr, NULL); + memcpy (&buffer[pos], &addr, family_size); + pos += family_size; + } + + send (manager_client->fd, buffer, pos, 0); +} + +void _manager_ip_handle_list_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { + Interface *iface; + int family, ip_family; + uint32_t u32; + int c, total; + IPAddr *ip_addr; + + if (buffer_len < 7) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_LIST_IP); + return; + } + + family = buffer[6]; + + if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_LIST_IP); + + return; + } + + memcpy (&u32, &buffer[2], 4); + iface = network_inador_get_iface (manager_client->manager->handle, u32); + if (iface == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_LIST_IP); + return; + } + + total = network_inador_iface_get_num_ips (iface); + for (c = 0; c < total; c++) { + ip_addr = network_inador_iface_get_ipaddr_by_index (iface, c); + + ip_family = network_inador_ipaddr_get_family (ip_addr); + + if (family != AF_UNSPEC && family != ip_family) continue; + + _manager_send_ipaddr (manager_client, ip_addr, FALSE); + } + + _manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_IP); +} + +void _manager_ip_handle_clear_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { + int family, ip_family; + Interface *iface; + IPAddr *ip_addr; + uint32_t u32; + int ret; + int c, total; + + if (buffer_len < 7) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CLEAR_IP); + return; + } + + family = buffer[6]; + + if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_CLEAR_IP); + + return; + } + + memcpy (&u32, &buffer[2], 4); + iface = network_inador_get_iface (manager_client->manager->handle, u32); + if (iface == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_CLEAR_IP); + return; + } + + ret = 0; + total = network_inador_iface_get_num_ips (iface); + for (c = 0; c < total; c++) { + ip_addr = network_inador_iface_get_ipaddr_by_index (iface, c); + + ip_family = network_inador_ipaddr_get_family (ip_addr); + + if (family != AF_UNSPEC && family != ip_family) continue; + + // AQUÍ GATUNO + //ret |= ip_address_del_ip (manager_client->manager->handle, iface->index, ip_addr); + } + + if (ret == 0) { + /* OK */ + _manager_send_executed (manager_client); + } else { + _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_CLEAR_IP); + } +} + +/* Los eventos que vienen desde la librería */ +void _manager_ip_added_event_cb (NetworkInadorHandle *handle, IPAddr *ip_addr, void *data) { + Manager *manager = (Manager *) data; + GList *g; + ManagerClientInfo *manager_client; + Interface *iface; + + iface = network_inador_ipaddr_get_iface (ip_addr); + printf ("___ MANAGER ___ Informando ip agregada: %s (%i)\n", network_inador_iface_get_name (iface), network_inador_iface_get_index (iface)); + + for (g = manager->connected_client_list; g != NULL; g = g->next) { + manager_client = (ManagerClientInfo *) g->data; + + if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_INTERFACES) { + printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); + _manager_send_ipaddr (manager_client, ip_addr, TRUE); + } + } +} + +void _manager_ip_deleted_event_cb (NetworkInadorHandle *handle, IPAddr *ip_addr, void *data) { + Manager *manager = (Manager *) data; + GList *g; + ManagerClientInfo *manager_client; + Interface *iface; + + iface = network_inador_ipaddr_get_iface (ip_addr); + printf ("___ MANAGER ___ Informando ip eliminada: %s (%i)\n", network_inador_iface_get_name (iface), network_inador_iface_get_index (iface)); + + for (g = manager->connected_client_list; g != NULL; g = g->next) { + manager_client = (ManagerClientInfo *) g->data; + + if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_IP) { + printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); + _manager_send_ipaddr_deleted (manager_client, ip_addr); + } + } +} + diff --git a/src/manager-ip.h b/src/manager-ip.h new file mode 100644 index 0000000..2d35ec4 --- /dev/null +++ b/src/manager-ip.h @@ -0,0 +1,40 @@ +/* + * manager-ip.h + * This file is part of Network-inador + * + * Copyright (C) 2025 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __MANAGER_IP_H__ +#define __MANAGER_IP_H__ + +#include +#include +#include + +#include "manager-private.h" +#include "network-inador-public.h" +#include "network-inador-manager.h" + +void _manager_ip_handle_list_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len); + +void _manager_ip_added_event_cb (NetworkInadorHandle *handle, IPAddr *addr, void *data); +void _manager_ip_deleted_event_cb (NetworkInadorHandle *handle, IPAddr *addr, void *data); + +#endif /* __MANAGER_IP_H__ */ + diff --git a/src/manager-private.h b/src/manager-private.h new file mode 100644 index 0000000..d2b203a --- /dev/null +++ b/src/manager-private.h @@ -0,0 +1,55 @@ +/* + * manager-private.h + * This file is part of Network-inador + * + * Copyright (C) 2024 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __MANAGER_PRIVATE_H__ +#define __MANAGER_PRIVATE_H__ + +#include + +#include "network-inador-public.h" + +/* Para los clientes y sus respectivos eventos */ +typedef struct { + int socket; + + guint source; + GList *connected_client_list; + NetworkInadorHandle *handle; +} Manager; + +typedef struct { + int fd; + + /* Los eventos que quieren ser recibidos en este cliente */ + uint32_t wanted_events; + guint source; + Manager *manager; +} ManagerClientInfo; + +Manager * manager_new (NetworkInadorHandle *handle, int type); + +void _manager_send_error (ManagerClientInfo *manager_client, int error, int orig_cmd); +void _manager_send_executed (ManagerClientInfo *manager_client); +void _manager_send_end_command (ManagerClientInfo *manager_client, int orig_cmd); + +#endif /* __MANAGER_PRIVATE_H__ */ + diff --git a/src/manager.c b/src/manager.c index 9ee2a04..fcf3893 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2,7 +2,7 @@ * manager.c * This file is part of Network-inador * - * Copyright (C) 2011 - Félix Arreola Rodríguez + * Copyright (C) 2024 - Félix Arreola Rodríguez * * Network-inador is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,20 +39,18 @@ #include #include -#include "network-inador-private.h" -#include "interfaces.h" -#include "ip-address.h" -#include "routes.h" -#include "bridge.h" +#include "manager-private.h" +#include "network-inador-public.h" +#include "network-inador-events.h" #include "network-inador-manager.h" -#include "dhcp_client.h" -#include "resolv_manager.h" + +#include "manager-interfaces.h" +#include "manager-ip.h" #define COMMAND_SOCKET_PATH "/tmp/network-inador.socket" -void _manager_send_dhcp_status (ManagerClientInfo *manager_client, InterfaceDHCPClientInfo *dhcpc, gboolean is_event); - -static void _manager_send_error (ManagerClientInfo *manager_client, int error, int orig_cmd) { +/* Funciones comúnes */ +void _manager_send_error (ManagerClientInfo *manager_client, int error, int orig_cmd) { unsigned char buffer[8]; buffer[0] = NET_INADOR_TYPE_RESPONSE_ERROR; @@ -62,7 +60,7 @@ static void _manager_send_error (ManagerClientInfo *manager_client, int error, i send (manager_client->fd, buffer, 3, 0); } -static void _manager_send_executed (ManagerClientInfo *manager_client) { +void _manager_send_executed (ManagerClientInfo *manager_client) { unsigned char buffer[8]; buffer[0] = NET_INADOR_TYPE_RESPONSE; @@ -71,7 +69,7 @@ static void _manager_send_executed (ManagerClientInfo *manager_client) { send (manager_client->fd, buffer, 2, 0); } -static void _manager_send_end_command (ManagerClientInfo *manager_client, int orig_cmd) { +void _manager_send_end_command (ManagerClientInfo *manager_client, int orig_cmd) { unsigned char buffer[8]; buffer[0] = NET_INADOR_TYPE_RESPONSE_LISTING_END; @@ -80,577 +78,6 @@ static void _manager_send_end_command (ManagerClientInfo *manager_client, int or send (manager_client->fd, buffer, 2, 0); } -static Interface * _manager_fetch_interface (ManagerClientInfo *manager_client, unsigned char *buffer, int orig_cmd) { - Interface *iface; - uint32_t index; - - memcpy (&index, buffer, 4); - - /* TODO: Revisar el ntohl */ - iface = _interfaces_locate_by_index (manager_client->manager->handle->interfaces, index); - - if (iface == NULL) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, orig_cmd); - - return NULL; - } - - return iface; -} - -void _manager_send_interface (ManagerClientInfo *manager_client, Interface *iface, gboolean is_event) { - unsigned char buffer[32 + IFNAMSIZ + IFNAMSIZ]; - int name_len = strlen (iface->name); - - if (is_event) { - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_IFACE_ADDED; - } else { - buffer[0] = NET_INADOR_TYPE_RESPONSE; - buffer[1] = NET_INADOR_RESPONSE_IFACE; - } - - memcpy (&buffer[2], &iface->index, 4); - memcpy (&buffer[6], &iface->link_type, 4); - memcpy (&buffer[10], &iface->master_index, 4); - memcpy (&buffer[14], &iface->mtu, 4); - memcpy (&buffer[18], &iface->flags, 2); - buffer[20] = iface->is_wireless; - buffer[21] = name_len; - memcpy (&buffer[22], iface->name, name_len); - - send (manager_client->fd, buffer, 22 + name_len, 0); -} - -void _manager_send_interface_del (ManagerClientInfo *manager_client, uint32_t index) { - unsigned char buffer[8]; - - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_IFACE_REMOVED; - - memcpy (&buffer[2], &index, 4); - - send (manager_client->fd, buffer, 6, 0); -} - -void _manager_send_ip (ManagerClientInfo *manager_client, IPAddr *ip_addr, gboolean is_event) { - unsigned char buffer[80]; - int family_size = 0; - int label_len; - int pos; - - if (is_event) { - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_IPADDR_ADDED; - } else { - buffer[0] = NET_INADOR_TYPE_RESPONSE; - buffer[1] = NET_INADOR_RESPONSE_IPADDR; - } - - /* Familia y máscara */ - if (ip_addr->family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (ip_addr->family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - memcpy (&buffer[2], &ip_addr->iface->index, 4); - buffer[6] = ip_addr->family; - buffer[7] = ip_addr->prefix; - - /* Los campos de bits */ - buffer[8] = 0; - if (ip_addr->has_local) { - buffer[8] |= 0x01; - } - if (ip_addr->has_brd) { - buffer[8] |= 0x02; - } - - /* Byte scope y las flags */ - buffer[9] = ip_addr->scope; - memcpy (&buffer[10], &ip_addr->flags, 4); - - /* La información de marcas de tiempo de las IPs */ - memcpy (&buffer[14], &ip_addr->cacheinfo, 16); - - /* La dirección principal */ - memcpy (&buffer[30], &ip_addr->addr, family_size); - pos = 30 + family_size; - if (ip_addr->has_local) { - memcpy (&buffer[pos], &ip_addr->local_addr, family_size); - pos += family_size; - } - - if (ip_addr->has_brd) { - memcpy (&buffer[pos], &ip_addr->brd_addr, family_size); - pos += family_size; - } - - if (ip_addr->label[0] != 0) { - label_len = strlen (ip_addr->label); - buffer[pos] = label_len; - pos++; - - memcpy (&buffer[pos], &ip_addr->label, label_len); - pos += label_len; - } else { - buffer[pos] = 0; - pos++; - } - send (manager_client->fd, buffer, pos, 0); -} - -void _manager_send_ip_del (ManagerClientInfo *manager_client, IPAddr *ip_addr) { - unsigned char buffer[80]; - int family_size = 0; - int pos; - - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_IPADDR_REMOVED; - - if (ip_addr->family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (ip_addr->family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - memcpy (&buffer[2], &ip_addr->iface->index, 4); - buffer[6] = ip_addr->family; - buffer[7] = ip_addr->prefix; - - buffer[8] = 0; - if (ip_addr->has_local) { - buffer[8] |= 0x01; - } - - buffer[9] = 0; - - memcpy (&buffer[10], &ip_addr->addr, family_size); - pos = 10 + family_size; - if (ip_addr->has_local) { - memcpy (&buffer[pos], &ip_addr->local_addr, family_size); - pos += family_size; - } - - send (manager_client->fd, buffer, pos, 0); -} - -void _manager_send_list_interfaces (ManagerClientInfo *manager_client) { - GList *g; - Interface *iface; - - g = manager_client->manager->handle->interfaces; - while (g != NULL) { - iface = (Interface *) g->data; - - _manager_send_interface (manager_client, iface, FALSE); - g = g->next; - } - - _manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_IFACES); -} - -void _manager_send_iface (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - - if (buffer_len < 6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_GET_IFACE); - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_GET_IFACE); - if (iface == NULL) return; - - _manager_send_interface (manager_client, iface, FALSE); -} - -void _manager_send_list_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - int family; - GList *g; - IPAddr *ip_addr; - Interface *iface; - - if (buffer_len < 7) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_LIST_IP); - return; - } - - family = buffer[6]; - - if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_LIST_IP); - - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_LIST_IP); - if (iface == NULL) return; - - for (g = iface->address; g != NULL; g = g->next) { - ip_addr = (IPAddr *) g->data; - - if (family != AF_UNSPEC && family != ip_addr->family) continue; - - _manager_send_ip (manager_client, ip_addr, FALSE); - } - - _manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_IP); -} - -void _manager_execute_iface_down_up (ManagerClientInfo *manager_client, int is_up, unsigned char *buffer, int buffer_len) { - Interface *iface; - int ret; - - if (buffer_len < 6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, (is_up ? NET_INADOR_COMMAND_IFACE_UP : NET_INADOR_COMMAND_IFACE_DOWN)); - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], (is_up ? NET_INADOR_COMMAND_IFACE_UP : NET_INADOR_COMMAND_IFACE_DOWN)); - if (iface == NULL) return; - - if (is_up) { - ret = interfaces_change_set_up (manager_client->manager->handle, iface->index); - } else { - ret = interfaces_change_set_down (manager_client->manager->handle, iface->index); - } - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, (is_up ? NET_INADOR_COMMAND_IFACE_UP : NET_INADOR_COMMAND_IFACE_DOWN)); - } -} - -void _manager_execute_iface_change_name (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - int ret; - int name_len; - unsigned char name[IFNAMSIZ]; - - if (buffer_len < 7) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_IFACE_CHANGE_NAME); - if (iface == NULL) return; - - name_len = buffer[6]; - if (name_len == 0 || name_len >= IFNAMSIZ) { - _manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); - return; - } - - if (name_len + 7 < buffer_len) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); - return; - } - - memcpy (name, &buffer[7], name_len); - if (name[0] == 0) { - _manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); - return; - } - name[name_len] = 0; - - ret = interfaces_change_name (manager_client->manager->handle, iface->index, name); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_IFACE_CHANGE_NAME); - } -} - -void _manager_execute_iface_change_mtu (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - int ret; - uint32_t new_mtu; - - if (buffer_len < 6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_MTU); - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_IFACE_CHANGE_NAME); - if (iface == NULL) return; - - memcpy (&new_mtu, &buffer[6], 4); - //new_mtu = ntohl (new_mtu); - - /* TODO: Revisar el máximo de MTU que se puede poner */ - ret = interfaces_change_mtu (manager_client->manager->handle, iface->index, new_mtu); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_IFACE_CHANGE_MTU); - } -} - -void _manager_execute_clear_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - int family; - Interface *iface; - IPAddr *ip_addr; - GList *g; - int ret; - - if (buffer_len < 7) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CLEAR_IP); - return; - } - - family = buffer[6]; - - if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_CLEAR_IP); - - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_CLEAR_IP); - if (iface == NULL) return; - - ret = 0; - for (g = iface->address; g != NULL; g = g->next) { - ip_addr = (IPAddr *) g->data; - - if (family != AF_UNSPEC && family != ip_addr->family) continue; - - ret |= ip_address_del_ip (manager_client->manager->handle, iface->index, ip_addr); - } - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_CLEAR_IP); - } -} - -void _manager_execute_add_ip (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - IPAddr ip_addr; - int ret; - int family_size, wanted_size, family; - - if (buffer_len < 14) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_IP); - return; - } - - family = ip_addr.family = buffer[6]; - - if (family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_ADD_IP); - - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_ADD_IP); - if (iface == NULL) return; - - ip_addr.prefix = buffer[7]; - if (ip_addr.family == AF_INET && (ip_addr.prefix > 32 || ip_addr.prefix < 1)) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_ADD_IP); - return; - } else if (ip_addr.family == AF_INET6 && (ip_addr.prefix > 128 || ip_addr.prefix < 1)) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_ADD_IP); - return; - } - - ip_addr.has_local = buffer[8] & 0x01; - ip_addr.has_brd = (buffer[8] & 0x02) >> 1; - - if (ip_addr.family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (ip_addr.family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - /* Ya puedo revisar el resto de la longitud */ - wanted_size = 22 + family_size + (family_size * ip_addr.has_local) + (family_size * ip_addr.has_brd); - if (buffer_len < wanted_size) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_IP); - return; - } - - ip_addr.scope = buffer[9]; - memcpy (&ip_addr.flags, &buffer[10], 4); - - /* Copiar los timestamp de tiempo válido y preferido */ - memset (&ip_addr.cacheinfo, 0, sizeof (ip_addr.cacheinfo)); - memcpy (&ip_addr.cacheinfo, &buffer[14], 8); - - /* Copiar las direcciones */ - memcpy (&ip_addr.addr, &buffer[22], family_size); - wanted_size = 22 + family_size; - - if (ip_addr.has_local) { - memcpy (&ip_addr.local_addr, &buffer[wanted_size], family_size); - wanted_size += family_size; - } else { - memcpy (&ip_addr.local_addr, &ip_addr.addr, family_size); - } - - if (ip_addr.has_brd) { - memcpy (&ip_addr.brd_addr, &buffer[wanted_size], family_size); - wanted_size += family_size; - } else { - memset (&ip_addr.brd_addr, 0, sizeof (ip_addr.brd_addr)); - } - - ret = ip_address_add_ip (manager_client->manager->handle, iface->index, &ip_addr); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_ADD_IP); - } -} - -void _manager_execute_delete_ip (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - IPAddr *ip_addr; - struct_addr addr, local_addr; - int has_local; - int ret; - int family_size, wanted_size, family; - int prefix; - - if (buffer_len < 9) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_REMOVE_IP); - return; - } - - family = buffer[6]; - - if (family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_REMOVE_IP); - - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_REMOVE_IP); - if (iface == NULL) return; - - prefix = buffer[7]; - if (family == AF_INET && (prefix > 32 || prefix < 1)) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_REMOVE_IP); - return; - } else if (family == AF_INET6 && (prefix > 128 || prefix < 1)) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_REMOVE_IP); - return; - } - - has_local = buffer[8] & 0x01; - - if (family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - /* Ya puedo revisar el resto de la longitud */ - wanted_size = 9 + family_size + (family_size * has_local); - if (buffer_len < wanted_size) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_REMOVE_IP); - return; - } - - memcpy (&addr, &buffer[9], family_size); - - if (has_local) { - memcpy (&local_addr, &buffer[9 + family_size], family_size); - } - - ip_addr = _ip_address_search_addr (iface, family, &addr, prefix, (has_local ? &local_addr : NULL)); - - if (ip_addr == NULL) { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_REMOVE_IP); - return; - } - - ret = ip_address_del_ip (manager_client->manager->handle, iface->index, ip_addr); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_REMOVE_IP); - } -} - -void _manager_execute_create_bridge (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - int ret; - int name_len; - unsigned char name[IFNAMSIZ]; - - if (buffer_len < 3) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CREATE_BRIDGE); - return; - } - - name_len = buffer[2]; - if (name_len == 0 || name_len >= IFNAMSIZ) { - _manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_CREATE_BRIDGE); - return; - } - - if (name_len + 3 < buffer_len) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CREATE_BRIDGE); - return; - } - - memcpy (name, &buffer[3], name_len); - if (name[0] == 0) { - _manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_CREATE_BRIDGE); - return; - } - name[name_len] = 0; - - ret = interfaces_bridge_create (manager_client->manager->handle, name); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_CREATE_BRIDGE); - } -} - -void _manager_execute_set_or_clear_master (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len, gboolean is_clear) { - Interface *iface, *master; - int ret; - - if (buffer_len < 6 && is_clear) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CLEAR_MASTER); - return; - } else if (buffer_len < 10 && is_clear == FALSE) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_SET_MASTER); - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], (is_clear ? NET_INADOR_COMMAND_CLEAR_MASTER : NET_INADOR_COMMAND_SET_MASTER)); - - if (is_clear == FALSE) { - master = _manager_fetch_interface (manager_client, &buffer[6], NET_INADOR_COMMAND_SET_MASTER); - - ret = interfaces_bridge_set_master_interface (manager_client->manager->handle, master->index, iface->index); - } else { - ret = interfaces_bridge_remove_master_interface (manager_client->manager->handle, iface->index); - } - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, (is_clear ? NET_INADOR_COMMAND_CLEAR_MASTER : NET_INADOR_COMMAND_SET_MASTER)); - } -} - static void _manager_handle_set_event_mask (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { uint32_t events; @@ -665,909 +92,15 @@ static void _manager_handle_set_event_mask (ManagerClientInfo *manager_client, u manager_client->wanted_events = events; } -#define _MANAGER_CHECK_BYTE_OR_OUT(FAMILY,BUF,POS) \ - if (BUF[POS] != 0) { \ - if (FAMILY == AF_INET && BUF[POS] != 4) { \ - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); \ - return; \ - } \ - } - -static void _manager_execute_dhcp_client_feed (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - int name_len, wanted; - unsigned char name[IFNAMSIZ]; - unsigned char domain_name[256]; - Interface *iface; - int family; - int pos, prefix, g; - uint32_t lease_time; - struct_addr ip, broadcast, dhcp_server; - struct_addr dns[8], gateways[8]; - int gw_c, dns_c; - - if (buffer_len < 16) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - /* Revisar la familia */ - family = buffer[2]; - - if (family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - - return; - } - - /* Revisar el estado */ - if (buffer[3] < DHCP_CLIENT_SELECTING || buffer[3] > DHCP_CLIENT_FAILED) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - /* Revisar la longitud del nombre de la interfaz */ - name_len = buffer[4]; - if (name_len == 0 || name_len >= IFNAMSIZ) { - _manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - _MANAGER_CHECK_BYTE_OR_OUT(family, buffer, 5); // Dirección IP - _MANAGER_CHECK_BYTE_OR_OUT(family, buffer, 8); // Dirección Broadcast - _MANAGER_CHECK_BYTE_OR_OUT(family, buffer, 9); // Dirección del servidor - - /* Revisar la posible ruta de gateways */ - if (family == AF_INET && buffer[7] % 4 != 0) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - /* La lista de servidores DNS */ - if (family == AF_INET && buffer[10] % 4 != 0) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - wanted = 16 + name_len + buffer[5] + buffer[7] + buffer[8] + buffer[9] + buffer[10] + buffer[11]; - if (wanted < buffer_len) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - /* Recuperar el nombre de la interfaz */ - memcpy (name, &buffer[16], name_len); - name[name_len] = 0; - - iface = _interfaces_locate_by_name (manager_client->manager->handle->interfaces, name); - if (iface == NULL) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - if (iface->dhcpc.type != IFACE_ISC_DHCLIENT && iface->dhcpc.type != IFACE_BUSYBOX_UDHCPC) { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - - /* Recuperar el resto de valores, empezando por la IP */ - if (buffer[5] != 0) { - pos = 16 + name_len; - memcpy (&ip, &buffer[pos], buffer[5]); - } else { - memset (&ip, 0, sizeof (ip)); - } - - /* Recuperar la ruta por defecto */ - gw_c = buffer[7] / 4; - pos = 16 + name_len + buffer[5]; - for (g = 0; g < gw_c && g < 8; g++) { - memcpy (&gateways[g].v4, &buffer[pos], 4); - pos += 4; - } - - /* Recuperar el broadcast */ - if (buffer[8] != 0) { - pos = 16 + name_len + buffer[5] + buffer[7]; - memcpy (&broadcast, &buffer[pos], buffer[8]); - } else { - memset (&broadcast, 0, sizeof (broadcast)); - } - - /* Recuperar el servidor DHCP */ - if (buffer[9] != 0) { - pos = 16 + name_len + buffer[5] + buffer[7] + buffer[8]; - memcpy (&dhcp_server, &buffer[pos], buffer[9]); - } else { - memset (&dhcp_server, 0, sizeof (dhcp_server)); - } - - /* Recuperar todos los servidores DNS */ - dns_c = buffer[10] / 4; - pos = 16 + name_len + buffer[5] + buffer[7] + buffer[8] + buffer[9]; - for (g = 0; g < 8 && g < dns_c; g++) { - memcpy (&dns[g].v4, &buffer[pos], 4); - pos += 4; - } - - /* Recuperar el domain name */ - domain_name[0] = 0; - if (buffer[11] != 0) { - pos = 16 + name_len + buffer[5] + buffer[7] + buffer[8] + buffer[9] + buffer[10]; - memcpy (domain_name, &buffer[pos], buffer[11]); - domain_name[buffer[11]] = 0; - } - - /* Copiar el lease_time */ - memcpy (&lease_time, &buffer[12], 4); - - /* TODO: Ejecutar aquí validaciones de estado, revisar que la IP existe, que el prefix sea válido, bla, bla, bla */ - if (family == AF_INET) { - prefix = buffer[6]; - if (prefix > 32) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); - return; - } - } - interfaces_dhcp_client_internal_feed_from_client (manager_client->manager->handle, iface->index, buffer[3], &ip, buffer[6], gateways, gw_c, &broadcast, &dhcp_server, lease_time, dns, dns_c, domain_name); - - /* OK */ - _manager_send_executed (manager_client); +/* Los eventos que vienen desde la librería */ +void _manager_dhcp_event_cb (NetworkInadorHandle *handle, Interface *iface, InterfaceDHCPClientInfo *dhcp_info, void *data) { + Manager *manager = (Manager *) data; } -static void _manager_execute_resolvconf_feed (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - int name_len, wanted; - unsigned char iface_prog[256]; - unsigned char iface_name[256], prog[256]; - char *point; - ResolvConfEntry *resolv_entries; - int entries_count; - - int ns_count; - int search_count; - int g, h, pos, ns_pos; - int family; - int iface_index; - Interface *iface; - - int do_write = 0; - - if (buffer_len < 3) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED); - return; - } - - name_len = buffer[2]; - - if (buffer_len < 3 + name_len || name_len == 0) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED); - return; - } - - memcpy (iface_prog, &buffer[3], name_len); - iface_prog[name_len] = 0; - - if (iface_prog[0] == '.') { - /* No permitimos interfaces vacías */ - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RESOLVCONF_FEED); - - return; - } - - point = strchr (iface_prog, '.'); - if (point == NULL) { - prog[0] = 0; - strncpy (iface_name, iface_prog, sizeof (iface_name)); - } else { - point[0] = 0; - strncpy (iface_name, iface_prog, sizeof (iface_name)); - strncpy (prog, &point[1], sizeof (prog)); - } - - iface = _interfaces_locate_by_name (manager_client->manager->handle->interfaces, iface_name); - if (iface != NULL) { - iface_index = iface->index; - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RESOLVCONF_FEED); - return; - } - - pos = 3 + name_len; - if (buffer_len < pos) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED); - return; - } - - /* Revisar la cantidad de nameservers */ - ns_count = buffer[pos]; - pos++; - - /* TODO: Sumar las otras entradas */ - entries_count = ns_count; - - ns_pos = pos; - /* Los nameserver vienen con un byte de familia y luego los bytes correspondientes a la IP */ - for (g = 0; g < ns_count; g++) { - /* Revisar que en la longitud venga el byte de la familia */ - if (buffer_len < pos + 1) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED); - return; - } - - family = buffer[pos]; - pos++; /* El byte de la familia */ - - if (family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_RESOLVCONF_FEED); - - return; - } - - if (family == AF_INET) { - wanted = 4; - } else if (family == AF_INET6) { - wanted = 16; - } - - if (buffer_len < pos + wanted) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED); - return; - } - pos += wanted; - } - - /* TODO: Validar otro tipo de entradas */ - - /* Notificar al cliente */ - _manager_send_executed (manager_client); - - - /* Re-agrupar los datos para enviarlos al resolv_manager */ - resolv_entries = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry) * entries_count); - h = 0; - - pos = ns_pos; - for (g = 0; g < ns_count; g++) { - family = buffer[pos]; - resolv_entries[h].ns_family = family; - pos++; /* El byte de la familia */ - - wanted = (family == AF_INET) ? 4 : 16; - - /* Tengo un Nameserver completo, buscar y dependiendo del caso, actualizar o crear */ - memcpy (&resolv_entries[h].nameserver, &buffer[pos], wanted); - inet_ntop (family, &resolv_entries[h].nameserver, resolv_entries[h].value, sizeof (resolv_entries[h].value)); - - pos += wanted; - resolv_entries[h].resolv_type = RESOLV_TYPE_NAMESERVER; - resolv_entries[h].origin = RESOLV_ORIGIN_RESOLVCONF; - resolv_entries[h].owner_interface_index = iface_index; - strncpy (resolv_entries[h].owner_prog, prog, sizeof (resolv_entries[h].owner_prog)); - h++; - } - - resolv_manager_process_resolvconf_entries (manager_client->manager->handle, resolv_entries, entries_count); -} -static void _manager_execute_resolvconf_remove (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - int name_len; - unsigned char iface_prog[256]; - unsigned char iface_name[256], prog[256]; - char *point; - Interface *iface; - int iface_index; - - name_len = buffer[2]; - - if (buffer_len < 3 + name_len || name_len == 0) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_REMOVE); - return; - } - - memcpy (iface_prog, &buffer[3], name_len); - iface_prog[name_len] = 0; - - if (iface_prog[0] == '.') { - /* No permitimos interfaces vacías */ - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RESOLVCONF_REMOVE); - - return; - } - - point = strchr (iface_prog, '.'); - if (point == NULL) { - prog[0] = 0; - strncpy (iface_name, iface_prog, sizeof (iface_name)); - } else { - point[0] = 0; - strncpy (iface_name, iface_prog, sizeof (iface_name)); - strncpy (prog, &point[1], sizeof (prog)); - } - - iface = _interfaces_locate_by_name (manager_client->manager->handle->interfaces, iface_name); - if (iface != NULL) { - iface_index = iface->index; - } else { - iface_index = 0; - } - - resolv_manager_clear_entries_by_prog (manager_client->manager->handle, iface_index, prog); - - _manager_send_executed (manager_client); -} - -static void _manager_execute_dhcp_run (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - int ret; - int family, tipo; - uint32_t flags; - - if (buffer_len < 12) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RUN_DHCP); - return; - } - - family = buffer[6]; - - //if (family != AF_INET && family != AF_INET6) { - if (family != AF_INET) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_RUN_DHCP); - - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_RUN_DHCP); - if (iface == NULL) return; - - tipo = buffer[7]; - if (tipo == 1) { - tipo = IFACE_ISC_DHCLIENT; - } else if (tipo == 2) { - tipo = IFACE_BUSYBOX_UDHCPC; - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RUN_DHCP); - - return; - } - - /* TODO: Revisar las banderas */ - memcpy (&flags, &buffer[8], 4); - - ret = interfaces_dhcp_client_run (manager_client->manager->handle, iface->index, tipo, flags); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_RUN_DHCP); - } -} - -static void _manager_execute_dhcp_stop (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - int ret; - int family; - - if (buffer_len < 7) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_STOP_DHCP); - return; - } - - family = buffer[6]; - - //if (family != AF_INET && family != AF_INET6) { - if (family != AF_INET) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_STOP_DHCP); - - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_STOP_DHCP); - if (iface == NULL) return; - - ret = interfaces_dhcp_client_stop (manager_client->manager->handle, iface->index); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_STOP_DHCP); - } -} - -static void _manager_execute_dhcp_get_status (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Interface *iface; - int family; - - if (buffer_len < 7) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_GET_DHCP_STATUS); - return; - } - - family = buffer[6]; - - //if (family != AF_INET && family != AF_INET6) { - if (family != AF_INET) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_GET_DHCP_STATUS); - - return; - } - - iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_GET_DHCP_STATUS); - if (iface == NULL) return; - - _manager_send_dhcp_status (manager_client, &iface->dhcpc, FALSE); -} - -void _manager_send_dhcp_status (ManagerClientInfo *manager_client, InterfaceDHCPClientInfo *dhcpc, gboolean is_event) { - Interface *iface; - unsigned char buffer[80]; - int family_size = 0; - int label_len; - int pos; - int family = AF_INET; - struct in_addr empty; - int g; - - memset (&empty, 0, sizeof (empty)); - - iface = container_of (dhcpc, Interface, dhcpc); - - if (is_event) { - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_DHCP_STATUS; - } else { - buffer[0] = NET_INADOR_TYPE_RESPONSE; - buffer[1] = NET_INADOR_RESPONSE_DHCP_STATUS; - } - - /* Familia */ - if (family == AF_INET) { - family_size = sizeof (struct in_addr); - } - - memcpy (&buffer[2], &iface->index, 4); - buffer[6] = family; - buffer[7] = dhcpc->type; - buffer[8] = dhcpc->dhcp_state; - - /* Prefijo */ - buffer[9] = dhcpc->prefix; - - /* Los campos de bits */ - buffer[10] = 0; - if (memcmp (&dhcpc->broadcast, &empty, 4) != 0) { - buffer[10] |= 0x01; - } - if (memcmp (&dhcpc->dhcp_server_ip, &empty, 4) != 0) { - buffer[10] |= 0x02; - } - - /* Cantidad de GWs */ - g = dhcpc->gw_c & 0x07; - buffer[10] |= (g << 2); - - /* Cantidad de DNS */ - g = dhcpc->dns_c & 0x07; - buffer[10] |= (g << 5); - - buffer[11] = strlen (dhcpc->domain_name); - - memcpy (&buffer[12], &dhcpc->lease_time, 4); - - /* La dirección principal */ - memcpy (&buffer[16], &dhcpc->ip, family_size); - pos = 16 + family_size; - - for (g = 0; g < dhcpc->gw_c; g++) { - memcpy (&buffer[pos], &dhcpc->gateways[g], family_size); - pos += family_size; - } - - if (memcmp (&dhcpc->broadcast, &empty, 4) != 0) { - memcpy (&buffer[pos], &dhcpc->broadcast, family_size); - pos += family_size; - } - - if (memcmp (&dhcpc->dhcp_server_ip, &empty, 4) != 0) { - memcpy (&buffer[pos], &dhcpc->dhcp_server_ip, family_size); - pos += family_size; - } - - for (g = 0; g < dhcpc->dns_c; g++) { - memcpy (&buffer[pos], &dhcpc->dns[g], family_size); - pos += family_size; - } - - memcpy (&buffer[pos], dhcpc->domain_name, buffer[11]); - pos += buffer[11]; - - send (manager_client->fd, buffer, pos, 0); -} - -void _manager_send_route (ManagerClientInfo *manager_client, Route *route, gboolean is_event) { - unsigned char buffer[80]; - int family_size = 0; - int pos, has_gw; - struct_addr empty; - GList *g; - RouteNH *nexthop; - - memset (&empty, 0, sizeof (empty)); - - if (is_event) { - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_ROUTE_ADDED; - } else { - buffer[0] = NET_INADOR_TYPE_RESPONSE; - buffer[1] = NET_INADOR_RESPONSE_ROUTE; - } - - /* Familia y máscara */ - if (route->family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (route->family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - buffer[2] = route->family; - buffer[3] = route->type; - memcpy (&buffer[4], &route->table, 4); - buffer[8] = route->prefix; - buffer[9] = route->protocol; - buffer[10] = route->tos; - buffer[11] = route->scope; - buffer[12] = 0; - if (memcmp (&empty, &route->prefsrc, family_size) != 0) { - /* Tiene pref-src */ - buffer[12] |= 0x01; - } - - buffer[13] = 0; /* Los next-hop se incrementarán conforme los recorra */ - memcpy (&buffer[14], &route->priority, 4); - - /* Copiar la Ruta de destino */ - memcpy (&buffer[18], &route->dest, family_size); - pos = 18 + family_size; - - /* Copiar el pref-src, si lo tiene */ - if (buffer[12] & 0x01) { - memcpy (&buffer[pos], &route->prefsrc, family_size); - pos += family_size; - } - - /* TODO: Recorrer todos los nexthops */ - g = route->nexthops; - while (g != NULL) { - nexthop = (RouteNH *) g->data; - - buffer[pos] = 0; - has_gw = 0; - if (memcmp (&nexthop->gw, &empty, family_size) != 0) { - has_gw = 1; - buffer[pos] |= 0x01; - } - pos++; - buffer[pos++] = nexthop->nh_flags; /* Flags next-hop */ - buffer[pos++] = nexthop->nh_weight; /* Weight next-hop */ - - buffer[pos++] = 0; /* Omitimos un byte faltante */ - - /* La interfaz de salida */ - memcpy (&buffer[pos], &nexthop->out_index, 4); - pos += 4; - - if (has_gw) { - memcpy (&buffer[pos], &nexthop->gw, family_size); - pos += family_size; - } - - /* El contador de next-hops */ - buffer[13]++; - - g = g->next; - } - - send (manager_client->fd, buffer, pos, 0); -} - -void _manager_send_route_del (ManagerClientInfo *manager_client, Route *route) { - unsigned char buffer[80]; - int family_size = 0; - - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_ROUTE_REMOVED; - - /* Familia y máscara */ - if (route->family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (route->family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - buffer[2] = route->family; - buffer[3] = route->tos; - memcpy (&buffer[4], &route->table, 4); - buffer[8] = route->prefix; - memcpy (&buffer[9], &route->priority, 4); - - /* Copiar la Ruta de destino */ - memcpy (&buffer[13], &route->dest, family_size); - - send (manager_client->fd, buffer, 13 + family_size, 0); -} - -void _manager_send_list_routes (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - int family; - GList *g; - Route *route; - uint32_t table; - - if (buffer_len < 7) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_LIST_ROUTES); - return; - } - - family = buffer[6]; - - if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_LIST_ROUTES); - - return; - } - - memcpy (&table, &buffer[2], 4); - - if (family == AF_UNSPEC || family == AF_INET) { - for (g = manager_client->manager->handle->route_v4_tables; g != NULL; g = g->next) { - route = (Route *) g->data; - - if (table != 0 && route->table != table) continue; - - _manager_send_route (manager_client, route, FALSE); - } - } - - if (family == AF_UNSPEC || family == AF_INET6) { - for (g = manager_client->manager->handle->route_v6_tables; g != NULL; g = g->next) { - route = (Route *) g->data; - - if (table != 0 && route->table != table) continue; - - _manager_send_route (manager_client, route, FALSE); - } - } - - _manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_ROUTES); -} - -void _manager_execute_add_route (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Route route; - int ret, has_prefsrc; - int family_size, wanted_size, family, nexthops_needed; - int g, rem, pos; - RouteNH *nh; - - if (buffer_len < 18) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_ROUTE); - return; - } - - family = buffer[2]; - - if (family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_ADD_ROUTE); - - return; - } - - if (family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - - has_prefsrc = 0; - if (buffer[12] & 0x01) { - has_prefsrc = 1; - } - /* Ya puedo revisar el resto de la longitud */ - wanted_size = 18 + family_size + (family_size * has_prefsrc); - if (buffer_len < wanted_size) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_ROUTE); - return; - } - - /* Revisar los next hops */ - g = buffer[13]; - rem = buffer_len - wanted_size; - pos = wanted_size; - while (g > 0) { - if (rem < 8) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_ROUTE); - return; - } - - if (buffer[pos] & 0x01 && rem < 12) { - /* Tiene GW */ - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_ROUTE); - return; - } - - g--; - if (buffer[pos] & 0x01) { - rem -= 12; - pos += 12; - } else { - rem -= 8; - pos += 8; - } - } - - memset (&route, 0, sizeof (route)); - - /* Ejecutar el parsing */ - route.family = family; - route.type = buffer[3]; - memcpy (&route.table, &buffer[4], 4); - route.prefix = buffer[8]; - route.protocol = buffer[9]; - route.tos = buffer[10]; - route.scope = buffer[11]; - memcpy (&route.priority, &buffer[14], 4); - - memcpy (&route.dest, &buffer[18], family_size); - pos = 18 + family_size; - if (has_prefsrc) { - memcpy (&route.prefsrc, &buffer[pos], family_size); - pos += family_size; - } - - /* Recorrer cada next-hop */ - g = buffer[13]; - route.nexthops = NULL; - while (g > 0) { - nh = (RouteNH *) malloc (sizeof (RouteNH)); - - memset (nh, 0, sizeof (RouteNH)); - nh->nh_flags = buffer[pos + 1]; - nh->nh_weight = buffer[pos + 2]; - memcpy (&nh->out_index, &buffer[pos + 4], 4); - - if (buffer[pos] & 0x01) { - /* Tiene GW */ - memcpy (&nh->gw, &buffer[pos + 8], family_size); - pos += (8 + family_size); - } else { - pos += 8; - } - route.nexthops = g_list_append (route.nexthops, nh); - g--; - } - - ret = routes_add (manager_client->manager->handle, &route); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_ADD_ROUTE); - } -} - -void _manager_execute_del_route (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - Route route; - int ret; - int family_size, wanted_size, family; - int g, rem, pos; - - if (buffer_len < 13) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_REMOVE_ROUTE); - return; - } - - family = buffer[2]; - - if (family != AF_INET && family != AF_INET6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_REMOVE_ROUTE); - - return; - } - - if (family == AF_INET) { - family_size = sizeof (struct in_addr); - } else if (family == AF_INET6) { - family_size = sizeof (struct in6_addr); - } - - /* Ya puedo revisar el resto de la longitud */ - wanted_size = 13 + family_size; - if (buffer_len < wanted_size) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_REMOVE_ROUTE); - return; - } - - memset (&route, 0, sizeof (route)); - - /* Ejecutar el parsing */ - route.family = family; - route.tos = buffer[3]; - memcpy (&route.table, &buffer[4], 4); - route.prefix = buffer[8]; - memcpy (&route.priority, &buffer[9], 4); - - memcpy (&route.dest, &buffer[13], family_size); - ret = routes_del (manager_client->manager->handle, &route); - - if (ret == 0) { - /* OK */ - _manager_send_executed (manager_client); - } else { - _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_REMOVE_ROUTE); - } -} - -void _manager_send_route_table (ManagerClientInfo *manager_client, RouteTable *rtable, gboolean is_event) { - unsigned char buffer[80]; - int name_len; - - if (is_event) { - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_ROUTE_TABLE_ADDED; - } else { - buffer[0] = NET_INADOR_TYPE_RESPONSE; - buffer[1] = NET_INADOR_RESPONSE_ROUTE_TABLE; - } - - memcpy (&buffer[2], &rtable->table, 4); - - name_len = strlen (rtable->name); - buffer[6] = name_len; - memcpy (&buffer[7], rtable->name, name_len); - - send (manager_client->fd, buffer, 7 + name_len, 0); -} - -void _manager_send_route_table_del (ManagerClientInfo *manager_client, RouteTable *rtable) { - unsigned char buffer[80]; - int name_len; - - buffer[0] = NET_INADOR_TYPE_EVENT; - buffer[1] = NET_INADOR_EVENT_ROUTE_TABLE_REMOVED; - - memcpy (&buffer[2], &rtable->table, 4); - - send (manager_client->fd, buffer, 6, 0); -} - -void _manager_send_list_route_tables (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { - GList *g; - RouteTable *rtable; - uint32_t table; - - if (buffer_len < 6) { - _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_LIST_ROUTE_TABLES); - return; - } - - memcpy (&table, &buffer[2], 4); - - for (g = manager_client->manager->handle->route_tables_names; g != NULL; g = g->next) { - rtable = (RouteTable *) g->data; - - if (table != 0 && rtable->table != table) continue; - - _manager_send_route_table (manager_client, rtable, FALSE); - } - - _manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_ROUTE_TABLES); -} - -static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition, gpointer data) { +static gboolean _manager_on_client_data_recv (GIOChannel *source, GIOCondition condition, gpointer data) { ManagerClientInfo *manager_client = (ManagerClientInfo *) data; - NetworkInadorManager *manager = manager_client->manager; + Manager *manager = manager_client->manager; int type, command; Interface *iface; int g; @@ -1610,27 +143,28 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition } command = buffer[1]; + switch (command) { case NET_INADOR_COMMAND_LIST_IFACES: - _manager_send_list_interfaces (manager_client); + _manager_interface_handle_list_interfaces (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_GET_IFACE: - _manager_send_iface (manager_client, buffer, bytes); + _manager_interface_handle_get_interface (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_IFACE_UP: case NET_INADOR_COMMAND_IFACE_DOWN: - _manager_execute_iface_down_up (manager_client, (command == NET_INADOR_COMMAND_IFACE_UP), buffer, bytes); + _manager_interface_handle_up_down_command (manager_client, (command == NET_INADOR_COMMAND_IFACE_UP), buffer, bytes); break; case NET_INADOR_COMMAND_IFACE_CHANGE_NAME: - _manager_execute_iface_change_name (manager_client, buffer, bytes); + _manager_interface_handle_change_name (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_IFACE_CHANGE_MTU: - _manager_execute_iface_change_mtu (manager_client, buffer, bytes); + _manager_interface_handle_change_mtu (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_LIST_IP: - _manager_send_list_ips (manager_client, buffer, bytes); + _manager_ip_handle_list_ips (manager_client, buffer, bytes); break; - case NET_INADOR_COMMAND_CLEAR_IP: + /*case NET_INADOR_COMMAND_CLEAR_IP: _manager_execute_clear_ips (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_ADD_IP: @@ -1639,10 +173,11 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition case NET_INADOR_COMMAND_REMOVE_IP: _manager_execute_delete_ip (manager_client, buffer, bytes); break; + */ case NET_INADOR_COMMAND_SET_EVENT_MASK: _manager_handle_set_event_mask (manager_client, buffer, bytes); break; - case NET_INADOR_COMMAND_CREATE_BRIDGE: + /*case NET_INADOR_COMMAND_CREATE_BRIDGE: _manager_execute_create_bridge (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_CLEAR_MASTER: @@ -1680,16 +215,17 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition break; case NET_INADOR_COMMAND_RESOLVCONF_REMOVE: _manager_execute_resolvconf_remove (manager_client, buffer, bytes); - break; + break;*/ default: _manager_send_error (manager_client, NET_INADOR_ERROR_WRONG_COMMAND, command); } + return TRUE; } -static gboolean _manager_client_connect (GIOChannel *source, GIOCondition condition, gpointer data) { - NetworkInadorManager *manager = (NetworkInadorManager *) data; +static gboolean _manager_on_client_connect (GIOChannel *source, GIOCondition condition, gpointer data) { + Manager *manager = (Manager *) data; ManagerClientInfo *manager_client; int fd; GIOChannel *channel; @@ -1712,7 +248,7 @@ static gboolean _manager_client_connect (GIOChannel *source, GIOCondition condit /* Generar el vigilador */ channel = g_io_channel_unix_new (fd); - manager_client->source = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, _manager_client_data, manager_client); + manager_client->source = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, _manager_on_client_data_recv, manager_client); g_io_channel_unref (channel); manager_client->manager = manager; @@ -1721,200 +257,19 @@ static gboolean _manager_client_connect (GIOChannel *source, GIOCondition condit return TRUE; } -void manager_send_event_interface_add (NetworkInadorHandle *handle, Interface *iface) { - printf ("___ MANAGER ___ Informando interfaz agregada: %s (%i)\n", iface->name, iface->index); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_INTERFACES) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_interface (manager_client, iface, TRUE); - } - } -} - -void manager_send_event_interface_del (NetworkInadorHandle *handle, uint32_t index) { - printf ("___ MANAGER ___ Informando interfaz eliminada: %i\n", index); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_INTERFACES) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_interface_del (manager_client, index); - } - } -} - -void manager_send_event_interface_update (NetworkInadorHandle *handle, Interface *iface) { - printf ("___ MANAGER ___ Informando interfaz actualizada: %s (%i)\n", iface->name, iface->index); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_INTERFACES) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_interface (manager_client, iface, TRUE); - } - } -} - -void manager_send_event_ip_add (NetworkInadorHandle *handle, IPAddr *ip_addr) { - printf ("___ MANAGER ___ Informando ip agregada: %s (%i)\n", ip_addr->iface->name, ip_addr->iface->index); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_IP) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_ip (manager_client, ip_addr, TRUE); - } - } -} - -void manager_send_event_ip_del (NetworkInadorHandle *handle, IPAddr *ip_addr) { - printf ("___ MANAGER ___ Informando ip eliminada: %s (%i)\n", ip_addr->iface->name, ip_addr->iface->index); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_IP) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_ip_del (manager_client, ip_addr); - } - } -} - -void manager_send_event_dhcp_change (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc) { - Interface *iface = container_of (dhcpc, Interface, dhcpc); - GList *g; - ManagerClientInfo *manager_client; - - printf ("___ MANAGER ___ Informando cambio DHCP: %s (%i)\n", iface->name, iface->index); - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_DHCP_STATUS) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_dhcp_status (manager_client, dhcpc, TRUE); - } - } -} - -void manager_send_event_route_add (NetworkInadorHandle *handle, Route *route) { - char buffer_ip[1024]; - inet_ntop (route->family, &route->dest, buffer_ip, sizeof (buffer_ip)); - printf ("___ MANAGER ___ Informando ruta agregada: %s/%i [Tabla %i]\n", buffer_ip, route->prefix, route->table); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_ROUTES) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_route (manager_client, route, TRUE); - } - } -} - -void manager_send_event_route_del (NetworkInadorHandle *handle, Route *route) { - char buffer_ip[1024]; - inet_ntop (route->family, &route->dest, buffer_ip, sizeof (buffer_ip)); - printf ("___ MANAGER ___ Informando ruta eliminada: %s/%i [Tabla %i]\n", buffer_ip, route->prefix, route->table); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_ROUTES) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_route_del (manager_client, route); - } - } -} - -void manager_send_event_route_update (NetworkInadorHandle *handle, Route *route) { - manager_send_event_route_add (handle, route); -} - -void manager_send_event_route_table_del (NetworkInadorHandle *handle, RouteTable *rtable) { - char buffer_ip[1024]; - printf ("___ MANAGER ___ Informando tabla de ruteo eliminada: %s %i\n", rtable->name, rtable->table); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_ROUTE_TABLES) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_route_table_del (manager_client, rtable); - } - } -} - -void manager_send_event_route_table_add (NetworkInadorHandle *handle, RouteTable *rtable) { - char buffer_ip[1024]; - printf ("___ MANAGER ___ Informando tabla de ruteo agregada: %s %i\n", rtable->name, rtable->table); - GList *g; - ManagerClientInfo *manager_client; - - if (handle->manager == NULL) return; - - for (g = handle->manager->connected_client_list; g != NULL; g = g->next) { - manager_client = (ManagerClientInfo *) g->data; - - if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_ROUTE_TABLES) { - printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd); - _manager_send_route_table (manager_client, rtable, TRUE); - } - } -} - -int manager_init (NetworkInadorHandle *handle) { - NetworkInadorManager *manager; +Manager * manager_new (NetworkInadorHandle *handle, int type) { + Manager *manager; struct sockaddr_un socket_name; GIOChannel *channel; - manager = malloc (sizeof (NetworkInadorManager)); + manager = malloc (sizeof (Manager)); if (manager == NULL) { - return -1; + return NULL; } memset (manager, 0, sizeof (*manager)); + /* TODO: Aquí revisar el tipo de socket a abrir */ manager->socket = socket (AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0); if (manager->socket < 0) { @@ -1922,7 +277,7 @@ int manager_init (NetworkInadorHandle *handle) { free (manager); - return -1; + return NULL; } fcntl (manager->socket, F_SETFD, 1); @@ -1941,7 +296,7 @@ int manager_init (NetworkInadorHandle *handle) { manager->socket = -1; free (manager); - return -1; + return NULL; } if (listen (manager->socket, 10) < 0) { @@ -1951,7 +306,7 @@ int manager_init (NetworkInadorHandle *handle) { manager->socket = -1; free (manager); - return -1; + return NULL; } /* TODO: Aplicar permisos aquí */ @@ -1959,12 +314,18 @@ int manager_init (NetworkInadorHandle *handle) { channel = g_io_channel_unix_new (manager->socket); - manager->source = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, _manager_client_connect, manager); + manager->source = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, _manager_on_client_connect, manager); g_io_channel_unref (channel); manager->handle = handle; - handle->manager = manager; + /* Agregar vigilancias aquí */ + network_manager_add_watch_dhcp (handle, _manager_dhcp_event_cb, manager); + network_manager_add_watch_interface_added (handle, _manager_interface_added_event_cb, manager); + network_manager_add_watch_interface_updated (handle, _manager_interface_updated_event_cb, manager); + network_manager_add_watch_interface_deleted (handle, _manager_interface_deleted_event_cb, manager); + network_manager_add_watch_ip_added (handle, _manager_ip_added_event_cb, manager); + network_manager_add_watch_ip_deleted (handle, _manager_ip_deleted_event_cb, manager); - return 0; + return manager; } diff --git a/src/manager.h b/src/manager.h deleted file mode 100644 index 291b5e7..0000000 --- a/src/manager.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * manager.h - * This file is part of Network Inador - * - * Copyright (C) 2021 - Gatuno - * - * Network Inador is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Network Inador is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Network Inador; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#ifndef __MANAGER_H__ -#define __MANAGER_H__ - -#include - -#include "common.h" - -int manager_init (NetworkInadorHandle *handle); -void manager_send_event_interface_add (NetworkInadorHandle *handle, Interface *iface); -void manager_send_event_interface_del (NetworkInadorHandle *handle, uint32_t index); -void manager_send_event_interface_update (NetworkInadorHandle *handle, Interface *iface); -void manager_send_event_ip_add (NetworkInadorHandle *handle, IPAddr *ip_addr); -void manager_send_event_ip_del (NetworkInadorHandle *handle, IPAddr *ip_addr); -void manager_send_event_dhcp_change (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc); -void manager_send_event_route_add (NetworkInadorHandle *handle, Route *route); -void manager_send_event_route_del (NetworkInadorHandle *handle, Route *route); -void manager_send_event_route_update (NetworkInadorHandle *handle, Route *route); -void manager_send_event_route_table_del (NetworkInadorHandle *handle, RouteTable *rtable); -void manager_send_event_route_table_add (NetworkInadorHandle *handle, RouteTable *rtable); - -#endif /* __MANAGER_H__ */ - diff --git a/src/network-inador-manager.h b/src/network-inador-manager.h deleted file mode 100644 index ffd4cb7..0000000 --- a/src/network-inador-manager.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef __NETWOR_INADOR_MANAGER_H__ -#define __NETWOR_INADOR_MANAGER_H__ - -enum { - NET_INADOR_TYPE_COMMAND = 1, - NET_INADOR_TYPE_RESPONSE = 2, - NET_INADOR_TYPE_RESPONSE_ERROR = 3, - NET_INADOR_TYPE_RESPONSE_LISTING_END = 4, - NET_INADOR_TYPE_EVENT = 16 -}; - -/* Lista de eventos */ -#define NET_INADOR_EVENT_MASK_INTERFACES 0x01 -#define NET_INADOR_EVENT_MASK_IP 0x02 -#define NET_INADOR_EVENT_MASK_DHCP_STATUS 0x04 -#define NET_INADOR_EVENT_MASK_ROUTES 0x08 -#define NET_INADOR_EVENT_MASK_ROUTE_TABLES 0x10 - -enum { - NET_INADOR_COMMAND_LIST_IFACES = 1, - - NET_INADOR_COMMAND_GET_IFACE, - - NET_INADOR_COMMAND_IFACE_UP, - NET_INADOR_COMMAND_IFACE_DOWN, - - NET_INADOR_COMMAND_IFACE_CHANGE_NAME, - - NET_INADOR_COMMAND_IFACE_CHANGE_MTU, - - NET_INADOR_COMMAND_CREATE_BRIDGE = 16, - NET_INADOR_COMMAND_CLEAR_MASTER, - NET_INADOR_COMMAND_SET_MASTER, - - NET_INADOR_COMMAND_LIST_IP = 32, - NET_INADOR_COMMAND_CLEAR_IP, - NET_INADOR_COMMAND_ADD_IP, - NET_INADOR_COMMAND_REMOVE_IP, - - NET_INADOR_COMMAND_RUN_DHCP = 48, - NET_INADOR_COMMAND_STOP_DHCP, - NET_INADOR_COMMAND_GET_DHCP_STATUS, - - NET_INADOR_COMMAND_LIST_ROUTES = 64, - NET_INADOR_COMMAND_ADD_ROUTE, - NET_INADOR_COMMAND_REMOVE_ROUTE, - - NET_INADOR_COMMAND_LIST_ROUTE_TABLES = 72, - - NET_INADOR_COMMAND_SET_EVENT_MASK = 192, - - /* Los siguientes comandos son para uso interno */ - NET_INADOR_COMMAND_DHCP_CLIENT_FEED = 224, - NET_INADOR_COMMAND_RESOLVCONF_FEED = 225, - NET_INADOR_COMMAND_RESOLVCONF_REMOVE = 226, -}; - -enum { - NET_INADOR_ERROR_UNKNOWN = 0, - - NET_INADOR_ERROR_WRONG_COMMAND, - NET_INADOR_ERROR_INCOMPLETE_REQUEST, - NET_INADOR_ERROR_INVALID_IFACE_INDEX, - NET_INADOR_ERROR_INVALID_FAMILY, - NET_INADOR_ERROR_INVALID_VALUE, - NET_INADOR_ERROR_NOT_EXECUTED, - NET_INADOR_ERROR_BAD_STRING, -}; - -enum { - NET_INADOR_EVENT_IFACE_ADDED = 2, - NET_INADOR_EVENT_IPADDR_ADDED, - NET_INADOR_EVENT_IFACE_REMOVED, - NET_INADOR_EVENT_IPADDR_REMOVED, - - NET_INADOR_EVENT_DHCP_STATUS = 6, - - NET_INADOR_EVENT_ROUTE_ADDED = 10, - NET_INADOR_EVENT_ROUTE_REMOVED, - - NET_INADOR_EVENT_ROUTE_TABLE_ADDED = 14, - NET_INADOR_EVENT_ROUTE_TABLE_REMOVED, -}; - -enum { - NET_INADOR_RESPONSE_EXECUTED = 1, - - NET_INADOR_RESPONSE_IFACE = 2, - NET_INADOR_RESPONSE_IPADDR, - - NET_INADOR_RESPONSE_DHCP_STATUS = 6, - - NET_INADOR_RESPONSE_ROUTE = 10, - - NET_INADOR_RESPONSE_ROUTE_TABLE = 14 -}; - -enum { - NET_INADOR_DHCP_STATUS_SELECTING = 1, - NET_INADOR_DHCP_STATUS_BOUND, - NET_INADOR_DHCP_STATUS_RENEWED, - - NET_INADOR_DHCP_STATUS_EXPIRED, - NET_INADOR_DHCP_STATUS_FAILED, - -}; - -#endif /* __NETWOR_INADOR_MANAGER_H__ */ - diff --git a/src/resolv_manager.c b/src/resolv_manager.c new file mode 100644 index 0000000..4c8eb31 --- /dev/null +++ b/src/resolv_manager.c @@ -0,0 +1,76 @@ +/* + * resolv_manager.c + * This file is part of Network-inador + * + * Copyright (C) 2022 - Félix Arreola Rodríguez + * + * Network-inador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Network-inador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Network-inador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include + +#include "common.h" +#include "utils.h" +#include "resolv_conf_parser.h" + +GList * resolv_manager_clear_entries (GList *entries, char *prog) { + GList *g, *next; + ResolvConfEntry *entry; + + g = entries; + while (g != NULL) { + next = g->next; + + entry = (ResolvConfEntry *) g->data; + + if (strcmp (entry->owner_prog, prog) == 0) { + /* Hay que eliminar esta entrada, coincide por nombre de programa */ + + } + + + g = next; + } + + return entries; +} + +GList *resolv_manager_generate_entries (NetworkInadorHandle *handle) { + +} + +void resolv_manager_init (NetworkInadorHandle *handle) { + FILE *fd; + GList *entries; + + /* Debemos primero instalar el manejador de eventos de escritura sobre el resolv.conf */ + + handle->resolver_entries = NULL; + /* Luego, leer el resolv.conf */ + fd = fopen ("/etc/resolv.conf", "r"); + if (fd != NULL) { + entries = resolv_manager_parse_file (fd, RESOLV_ORIGIN_RESOLVCONF); + + handle->resolver_entries_from_file = entries; + } + + +} + diff --git a/src/struct_addr_union.h b/src/struct_addr_union.h new file mode 100644 index 0000000..de390ed --- /dev/null +++ b/src/struct_addr_union.h @@ -0,0 +1,32 @@ +/* + * struct_addr_union.h + * This file is part of NetworkInador + * + * Copyright (C) 2023 - Félix Arreola Rodríguez + * + * NetworkInador is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * NetworkInador is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NetworkInador; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __STRUCT_ADDR_UNION_H__ +#define __STRUCT_ADDR_UNION_H__ + +typedef union { + struct in_addr v4; + struct in6_addr v6; +} struct_addr; + +#endif /* __STRUCT_ADDR_UNION_H__ */ +