diff --git a/lib/bridge.c b/lib/bridge.c index bd7288f..0de06d0 100644 --- a/lib/bridge.c +++ b/lib/bridge.c @@ -245,55 +245,3 @@ int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int return 0; } -int interfaces_bridge_delete (NetworkInadorHandle *handle, int index) { - struct nl_msg * msg; - struct ifinfomsg iface_hdr; - struct nlattr *info; - int ret, error, len; - Interface *iface; - - iface = _interfaces_locate_by_index (handle->interfaces, index); - - if (iface == NULL) { - printf ("Error, solicitaron operación sobre interfaz que no existe\n"); - - return -1; - } - - memset (&iface_hdr, 0, sizeof (iface_hdr)); - iface_hdr.ifi_family = AF_UNSPEC; - iface_hdr.ifi_index = iface->index; - - msg = nlmsg_alloc_simple (RTM_DELLINK, NLM_F_REQUEST | NLM_F_EXCL); - ret = nlmsg_append (msg, &iface_hdr, sizeof (iface_hdr), NLMSG_ALIGNTO); - - if (ret != 0) { - nlmsg_free (msg); - - return -1; - } - - nl_complete_msg (handle->nl_sock_route, msg); - - ret = nl_send (handle->nl_sock_route, msg); - - nlmsg_free (msg); - if (ret <= 0) { - return -1; - } - - error = 0; - nl_socket_modify_cb (handle->nl_sock_route, NL_CB_VALID, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error); - nl_socket_modify_cb (handle->nl_sock_route, NL_CB_INVALID, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error); - nl_socket_modify_cb (handle->nl_sock_route, NL_CB_ACK, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error); - nl_socket_modify_err_cb (handle->nl_sock_route, NL_CB_CUSTOM, _interfaces_wait_error, &error); - - nl_recvmsgs_default (handle->nl_sock_route); - - if (ret <= 0 || error < 0) { - return -1; - } - - return 0; -} - diff --git a/lib/bridge.h b/lib/bridge.h index a0b2f83..9dc70fa 100644 --- a/lib/bridge.h +++ b/lib/bridge.h @@ -28,7 +28,6 @@ int interfaces_bridge_create (NetworkInadorHandle *handle, const char *name); int interfaces_bridge_set_master_interface (NetworkInadorHandle *handle, int master_index, int index); int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int index); -int interfaces_bridge_delete (NetworkInadorHandle *handle, int index); #endif diff --git a/lib/getters.c b/lib/getters.c index 8125671..d479504 100644 --- a/lib/getters.c +++ b/lib/getters.c @@ -87,10 +87,7 @@ uint8_t network_inador_iface_get_num_ips (Interface *iface) { } 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); + return (IPAddr *) f_list_nth_data (f_list_first (iface->address), index); } Interface *network_inador_ipaddr_get_iface (IPAddr *ip_addr) { diff --git a/lib/interfaces.c b/lib/interfaces.c index 31c77a2..aa4d360 100644 --- a/lib/interfaces.c +++ b/lib/interfaces.c @@ -672,6 +672,58 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n return 0; } +int interfaces_delete (NetworkInadorHandle *handle, int index) { + struct nl_msg * msg; + struct ifinfomsg iface_hdr; + struct nlattr *info; + int ret, error, len; + Interface *iface; + + iface = _interfaces_locate_by_index (handle->interfaces, index); + + if (iface == NULL) { + printf ("Error, solicitaron operación sobre interfaz que no existe\n"); + + return -1; + } + + memset (&iface_hdr, 0, sizeof (iface_hdr)); + iface_hdr.ifi_family = AF_UNSPEC; + iface_hdr.ifi_index = iface->index; + + msg = nlmsg_alloc_simple (RTM_DELLINK, NLM_F_REQUEST | NLM_F_EXCL); + ret = nlmsg_append (msg, &iface_hdr, sizeof (iface_hdr), NLMSG_ALIGNTO); + + if (ret != 0) { + nlmsg_free (msg); + + return -1; + } + + nl_complete_msg (handle->nl_sock_route, msg); + + ret = nl_send (handle->nl_sock_route, msg); + + nlmsg_free (msg); + if (ret <= 0) { + return -1; + } + + error = 0; + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_VALID, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error); + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_INVALID, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error); + nl_socket_modify_cb (handle->nl_sock_route, NL_CB_ACK, NL_CB_CUSTOM, _interfaces_wait_ack_or_error, &error); + nl_socket_modify_err_cb (handle->nl_sock_route, NL_CB_CUSTOM, _interfaces_wait_error, &error); + + nl_recvmsgs_default (handle->nl_sock_route); + + if (ret <= 0 || error < 0) { + return -1; + } + + return 0; +} + #if 0 int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...) { uint32_t new_sysctl[DEVCONF_MAX]; diff --git a/lib/interfaces.h b/lib/interfaces.h index c1b2678..4ef058b 100644 --- a/lib/interfaces.h +++ b/lib/interfaces.h @@ -102,6 +102,8 @@ int interfaces_change_set_up (NetworkInadorHandle *handle, int index); int interfaces_change_set_down (NetworkInadorHandle *handle, int index); int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_name); +int interfaces_delete (NetworkInadorHandle *handle, int index); + //int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...); void interfaces_clean_up (NetworkInadorHandle *handle); diff --git a/lib/network-inador-public.h b/lib/network-inador-public.h index d63c0cd..558b3f6 100644 --- a/lib/network-inador-public.h +++ b/lib/network-inador-public.h @@ -72,10 +72,17 @@ int interfaces_change_set_up (NetworkInadorHandle *handle, int index); int interfaces_change_set_down (NetworkInadorHandle *handle, int index); int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_name); +int interfaces_delete (NetworkInadorHandle *handle, int index); + /* Funciones básicas de IP */ int ip_address_del_ip (NetworkInadorHandle *handle, int index, uint8_t ip_family, uint8_t ip_prefix, uint8_t ip_has_local, void *ip_addr, void *ip_local_addr); int ip_address_add_ip (NetworkInadorHandle *handle, int index, uint8_t ip_family, uint8_t ip_prefix, uint8_t ip_has_local, uint8_t ip_has_brd, uint8_t ip_scope, uint32_t ip_flags, struct ifa_cacheinfo *ip_cacheinfo, void *ip_addr, void *ip_local_addr, void *ip_brd_addr); +/* Funciones de bridge */ +int interfaces_bridge_create (NetworkInadorHandle *handle, const char *name); +int interfaces_bridge_set_master_interface (NetworkInadorHandle *handle, int master_index, int index); +int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int index); + /* Funciones básicas de dhcp */ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags); int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index); diff --git a/src/Makefile.am b/src/Makefile.am index 9b8f726..e2dea4e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,8 @@ 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 + manager-ip.c manager-ip.h \ + manager-bridge.c manager-bridge.h resolvconf_SOURCES = resolv_conf_helper.c \ ../common/flist.c ../common/flist.h \ diff --git a/src/manager-bridge.c b/src/manager-bridge.c new file mode 100644 index 0000000..0a51e28 --- /dev/null +++ b/src/manager-bridge.c @@ -0,0 +1,117 @@ +/* + * manager-bridge.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" + +void _manager_bridge_handle_create (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_bridge_handle_set_or_clear_master (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len, int is_clear) { + Interface *iface, *master; + int ret; + uint32_t u32, master_u32; + + if (is_clear && buffer_len < 6) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CLEAR_MASTER); + return; + } else if (is_clear == FALSE && buffer_len < 10) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_SET_MASTER); + 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_clear ? NET_INADOR_COMMAND_CLEAR_MASTER : NET_INADOR_COMMAND_SET_MASTER)); + return; + } + + if (is_clear == FALSE) { + memcpy (&master_u32, &buffer[6], 4); + master = network_inador_get_iface (manager_client->manager->handle, u32); + + if (master == NULL) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_SET_MASTER); + return; + } + + ret = interfaces_bridge_set_master_interface (manager_client->manager->handle, master_u32, u32); + } else { + ret = interfaces_bridge_remove_master_interface (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_clear ? NET_INADOR_COMMAND_CLEAR_MASTER : NET_INADOR_COMMAND_SET_MASTER)); + } +} + diff --git a/src/manager-bridge.h b/src/manager-bridge.h new file mode 100644 index 0000000..deb40ec --- /dev/null +++ b/src/manager-bridge.h @@ -0,0 +1,38 @@ +/* + * manager-bridge.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_BRIDGE_H__ +#define __MANAGER_BRIDGE_H__ + +#include +#include +#include + +#include "manager-private.h" +#include "network-inador-public.h" +#include "network-inador-manager.h" + +void _manager_bridge_handle_create (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len); +void _manager_bridge_handle_set_or_clear_master (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len, int is_clear); + +#endif /* __MANAGER_BRIDGE_H__ */ + diff --git a/src/manager.c b/src/manager.c index bdcbbf9..92e2ba8 100644 --- a/src/manager.c +++ b/src/manager.c @@ -46,6 +46,7 @@ #include "manager-interfaces.h" #include "manager-ip.h" +#include "manager-bridge.h" #define COMMAND_SOCKET_PATH "/tmp/network-inador.socket" @@ -176,16 +177,16 @@ static gboolean _manager_on_client_data_recv (GIOChannel *source, GIOCondition c case NET_INADOR_COMMAND_SET_EVENT_MASK: _manager_handle_set_event_mask (manager_client, buffer, bytes); break; - /*case NET_INADOR_COMMAND_CREATE_BRIDGE: - _manager_execute_create_bridge (manager_client, buffer, bytes); + case NET_INADOR_COMMAND_CREATE_BRIDGE: + _manager_bridge_handle_create (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_CLEAR_MASTER: - _manager_execute_set_or_clear_master (manager_client, buffer, bytes, TRUE); + _manager_bridge_handle_set_or_clear_master (manager_client, buffer, bytes, TRUE); break; case NET_INADOR_COMMAND_SET_MASTER: - _manager_execute_set_or_clear_master (manager_client, buffer, bytes, FALSE); + _manager_bridge_handle_set_or_clear_master (manager_client, buffer, bytes, FALSE); break; - case NET_INADOR_COMMAND_DHCP_CLIENT_FEED: + /*case NET_INADOR_COMMAND_DHCP_CLIENT_FEED: _manager_execute_dhcp_client_feed (manager_client, buffer, bytes); break; case NET_INADOR_COMMAND_RUN_DHCP: @@ -196,7 +197,7 @@ static gboolean _manager_on_client_data_recv (GIOChannel *source, GIOCondition c break; case NET_INADOR_COMMAND_GET_DHCP_STATUS: _manager_execute_dhcp_get_status (manager_client, buffer, bytes); - break; + break;*/ case NET_INADOR_COMMAND_LIST_ROUTES: _manager_send_list_routes (manager_client, buffer, bytes); break;