Compare commits
4 Commits
38ebabf853
...
0ea2ec7ca3
Author | SHA1 | Date |
---|---|---|
|
0ea2ec7ca3 | |
|
ed22081f6a | |
|
ba639bf3a7 | |
|
b83407a7f3 |
|
@ -318,6 +318,8 @@ gboolean ni_add_ip_dialog_get_address (NIAddIPDialog *dialog, struct_addr *addr,
|
||||||
*prefix = lprefix;
|
*prefix = lprefix;
|
||||||
}
|
}
|
||||||
inet_pton (AF_INET6, ip, addr);
|
inet_pton (AF_INET6, ip, addr);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -800,6 +800,23 @@ void ni_client_ask_ip_delete (NIClient *ni_client, NIInterface *ni_interface, NI
|
||||||
send (ni_client->priv->client_socket, buffer, pos, 0);
|
send (ni_client->priv->client_socket, buffer, pos, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ni_client_ask_ip_clear (NIClient *ni_client, NIInterface *ni_interface, int family) {
|
||||||
|
unsigned char buffer[32];
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
if (ni_client->priv->client_socket < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = ni_interface_get_index (ni_interface);
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_CLEAR_IP;
|
||||||
|
memcpy (&buffer[2], &index, 4);
|
||||||
|
buffer[6] = family;
|
||||||
|
|
||||||
|
send (ni_client->priv->client_socket, buffer, 7, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void ni_client_ask_change_iface_name (NIClient *ni_client, NIInterface *ni_interface, const gchar *new_name) {
|
void ni_client_ask_change_iface_name (NIClient *ni_client, NIInterface *ni_interface, const gchar *new_name) {
|
||||||
unsigned char buffer[128];
|
unsigned char buffer[128];
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
|
|
|
@ -91,6 +91,7 @@ gboolean ni_client_connect (NIClient *ni_client);
|
||||||
void ni_client_ask_ip_interface (NIClient *ni_client, NIInterface *ni_interface, int family);
|
void ni_client_ask_ip_interface (NIClient *ni_client, NIInterface *ni_interface, int family);
|
||||||
void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr, uint32_t *cacheinfo);
|
void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr, uint32_t *cacheinfo);
|
||||||
void ni_client_ask_ip_delete (NIClient *ni_client, NIInterface *ni_interface, NIIP *ni_ip);
|
void ni_client_ask_ip_delete (NIClient *ni_client, NIInterface *ni_interface, NIIP *ni_ip);
|
||||||
|
void ni_client_ask_ip_clear (NIClient *ni_client, NIInterface *ni_interface, int family);
|
||||||
void ni_client_ask_change_iface_name (NIClient *ni_client, NIInterface *ni_interface, const gchar *new_name);
|
void ni_client_ask_change_iface_name (NIClient *ni_client, NIInterface *ni_interface, const gchar *new_name);
|
||||||
void ni_client_ask_change_iface_mtu (NIClient *ni_client, NIInterface *ni_interface, guint new_mtu);
|
void ni_client_ask_change_iface_mtu (NIClient *ni_client, NIInterface *ni_interface, guint new_mtu);
|
||||||
void ni_client_ask_up_down_interface (NIClient *ni_client, NIInterface *ni_interface, gboolean is_up);
|
void ni_client_ask_up_down_interface (NIClient *ni_client, NIInterface *ni_interface, gboolean is_up);
|
||||||
|
|
|
@ -538,10 +538,12 @@ static void ni_interface_process_ip_removed (NIInterface *ni_interface, gpointer
|
||||||
GList *g;
|
GList *g;
|
||||||
NIIP *ni_ip;
|
NIIP *ni_ip;
|
||||||
|
|
||||||
|
memset (&search_ip, 0, sizeof (search_ip));
|
||||||
search_ip.family = buffer[6];
|
search_ip.family = buffer[6];
|
||||||
search_ip.prefix = buffer[7];
|
search_ip.prefix = buffer[7];
|
||||||
bits = buffer[8];
|
bits = buffer[8];
|
||||||
|
|
||||||
|
search_ip.has_local_addr = FALSE;
|
||||||
if (bits & 0x01) search_ip.has_local_addr = TRUE;
|
if (bits & 0x01) search_ip.has_local_addr = TRUE;
|
||||||
|
|
||||||
if (search_ip.family == AF_INET) {
|
if (search_ip.family == AF_INET) {
|
||||||
|
|
|
@ -304,6 +304,20 @@ static void ni_window_interface_addr_v6_button_del_cb (GtkWidget *widget, gpoint
|
||||||
ni_window_interface_addr_button_del_cb (widget, AF_INET6, data);
|
ni_window_interface_addr_button_del_cb (widget, AF_INET6, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_addr_button_clear_cb (GtkWidget *widget, int family, gpointer data) {
|
||||||
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
||||||
|
|
||||||
|
ni_client_ask_ip_clear (ni_interface_get_client (window_iface->priv->ni_interface), window_iface->priv->ni_interface, family);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_addr_v4_button_clear_cb (GtkWidget *widget, gpointer data) {
|
||||||
|
ni_window_interface_addr_button_clear_cb (widget, AF_INET, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_addr_v6_button_clear_cb (GtkWidget *widget, gpointer data) {
|
||||||
|
ni_window_interface_addr_button_clear_cb (widget, AF_INET6, data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Función para renderizar el tiempo de la IP en el arbol */
|
/* Función para renderizar el tiempo de la IP en el arbol */
|
||||||
void ni_window_interface_cell_renderer_timestamp (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) {
|
void ni_window_interface_cell_renderer_timestamp (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) {
|
||||||
NIIP *ni_ip;
|
NIIP *ni_ip;
|
||||||
|
@ -1519,6 +1533,10 @@ static void ni_window_interface_init (NIWindowInterface *window_iface) {
|
||||||
g_signal_connect (priv->del_ipv4_button, "clicked", G_CALLBACK (ni_window_interface_addr_v4_button_del_cb), window_iface);
|
g_signal_connect (priv->del_ipv4_button, "clicked", G_CALLBACK (ni_window_interface_addr_v4_button_del_cb), window_iface);
|
||||||
gtk_widget_set_sensitive (priv->del_ipv4_button, FALSE);
|
gtk_widget_set_sensitive (priv->del_ipv4_button, FALSE);
|
||||||
|
|
||||||
|
button = gtk_button_new_from_icon_name ("edit-clear-all", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (ni_window_interface_addr_v4_button_clear_cb), window_iface);
|
||||||
|
|
||||||
/* Conectar la señal de cambio de selección del tree view */
|
/* Conectar la señal de cambio de selección del tree view */
|
||||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_ipv4));
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_ipv4));
|
||||||
g_signal_connect (selection, "changed", G_CALLBACK (has_ip_selected_v4_cb), window_iface);
|
g_signal_connect (selection, "changed", G_CALLBACK (has_ip_selected_v4_cb), window_iface);
|
||||||
|
@ -1561,6 +1579,10 @@ static void ni_window_interface_init (NIWindowInterface *window_iface) {
|
||||||
g_signal_connect (priv->del_ipv6_button, "clicked", G_CALLBACK (ni_window_interface_addr_v6_button_del_cb), window_iface);
|
g_signal_connect (priv->del_ipv6_button, "clicked", G_CALLBACK (ni_window_interface_addr_v6_button_del_cb), window_iface);
|
||||||
gtk_widget_set_sensitive (priv->del_ipv6_button, FALSE);
|
gtk_widget_set_sensitive (priv->del_ipv6_button, FALSE);
|
||||||
|
|
||||||
|
button = gtk_button_new_from_icon_name ("edit-clear-all", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (ni_window_interface_addr_v6_button_clear_cb), window_iface);
|
||||||
|
|
||||||
/* Conectar la señal de cambio de selección del tree view */
|
/* Conectar la señal de cambio de selección del tree view */
|
||||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_ipv6));
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_ipv6));
|
||||||
g_signal_connect (selection, "changed", G_CALLBACK (has_ip_selected_v6_cb), window_iface);
|
g_signal_connect (selection, "changed", G_CALLBACK (has_ip_selected_v6_cb), window_iface);
|
||||||
|
|
|
@ -40,7 +40,7 @@ void utils_trim (char * s) {
|
||||||
|
|
||||||
void utils_trim_comment (char *s) {
|
void utils_trim_comment (char *s) {
|
||||||
char *p = s;
|
char *p = s;
|
||||||
int l = strlen (p);
|
//int l = strlen (p);
|
||||||
|
|
||||||
while (*p != 0 && *p != '#') {
|
while (*p != 0 && *p != '#') {
|
||||||
++p;
|
++p;
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
lib_LTLIBRARIES = libnetworkinador.la
|
lib_LTLIBRARIES = libnetworkinador.la
|
||||||
libnetworkinador_la_SOURCES = network-inador-public.h \
|
libnetworkinador_la_SOURCES = network-inador-public.h \
|
||||||
event_notify.c event_notify.h \
|
event_notify.c event_notify.h \
|
||||||
getters.c network-inador-private.h \
|
getters.c setters.c network-inador-private.h \
|
||||||
network-inador-link-types.h network-inador-manager.h network-inador-events.h \
|
network-inador-link-types.h network-inador-manager.h network-inador-events.h \
|
||||||
struct_addr_union.h wireless_struct.h \
|
struct_addr_union.h wireless_struct.h \
|
||||||
handle.c \
|
handle.c \
|
||||||
netlink-events.c netlink-events.h \
|
netlink-events.c netlink-events.h \
|
||||||
|
file_watcher.c file_watcher.h \
|
||||||
interfaces.c interfaces.h \
|
interfaces.c interfaces.h \
|
||||||
ip-address.c ip-address.h \
|
ip-address.c ip-address.h \
|
||||||
routes.c routes.h \
|
routes.c routes.h \
|
||||||
|
|
54
lib/bridge.c
54
lib/bridge.c
|
@ -127,7 +127,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_set_master_interface (NetworkInadorHandle *handle, int master_index, int index) {
|
||||||
struct nl_msg * msg;
|
struct nl_msg * msg;
|
||||||
struct ifinfomsg iface_hdr;
|
struct ifinfomsg iface_hdr;
|
||||||
struct nlattr *info;
|
|
||||||
int ret, error;
|
int ret, error;
|
||||||
Interface *master_iface, *iface;
|
Interface *master_iface, *iface;
|
||||||
|
|
||||||
|
@ -188,7 +187,6 @@ int interfaces_bridge_set_master_interface (NetworkInadorHandle *handle, int mas
|
||||||
int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int index) {
|
int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int index) {
|
||||||
struct nl_msg * msg;
|
struct nl_msg * msg;
|
||||||
struct ifinfomsg iface_hdr;
|
struct ifinfomsg iface_hdr;
|
||||||
struct nlattr *info;
|
|
||||||
int ret, error;
|
int ret, error;
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
|
|
||||||
|
@ -245,55 +243,3 @@ int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int
|
||||||
return 0;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
int interfaces_bridge_create (NetworkInadorHandle *handle, const char *name);
|
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_set_master_interface (NetworkInadorHandle *handle, int master_index, int index);
|
||||||
int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int index);
|
int interfaces_bridge_remove_master_interface (NetworkInadorHandle *handle, int index);
|
||||||
int interfaces_bridge_delete (NetworkInadorHandle *handle, int index);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,21 @@ void network_manager_add_watch_ip_deleted (NetworkInadorHandle *handle, NetworkI
|
||||||
handle->notify_list.ip_del_event_data = data;
|
handle->notify_list.ip_del_event_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void network_manager_add_watch_route_added (NetworkInadorHandle *handle, NetworkInadorRouteAddEventCB cb, void *data) {
|
||||||
|
handle->notify_list.route_add_event_cb = cb;
|
||||||
|
handle->notify_list.route_add_event_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_manager_add_watch_route_updated (NetworkInadorHandle *handle, NetworkInadorRouteUpdateEventCB cb, void *data) {
|
||||||
|
handle->notify_list.route_update_event_cb = cb;
|
||||||
|
handle->notify_list.route_update_event_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_manager_add_watch_route_deleted (NetworkInadorHandle *handle, NetworkInadorRouteDelEventCB cb, void *data) {
|
||||||
|
handle->notify_list.route_del_event_cb = cb;
|
||||||
|
handle->notify_list.route_del_event_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
/* Disparar las vigilancias */
|
/* Disparar las vigilancias */
|
||||||
void network_manager_trigger_dhcp_event (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc) {
|
void network_manager_trigger_dhcp_event (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc) {
|
||||||
Interface *iface = container_of (dhcpc, Interface, dhcpc);
|
Interface *iface = container_of (dhcpc, Interface, dhcpc);
|
||||||
|
@ -106,3 +121,22 @@ void network_manager_trigger_ip_deleted_event (NetworkInadorHandle *handle, IPAd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Triggers de rutas */
|
||||||
|
void network_manager_trigger_route_added_event (NetworkInadorHandle *handle, Route *route) {
|
||||||
|
if (handle->notify_list.route_add_event_cb != NULL) {
|
||||||
|
handle->notify_list.route_add_event_cb (handle, route, handle->notify_list.route_add_event_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_manager_trigger_route_updated_event (NetworkInadorHandle *handle, Route *route) {
|
||||||
|
if (handle->notify_list.route_update_event_cb != NULL) {
|
||||||
|
handle->notify_list.route_update_event_cb (handle, route, handle->notify_list.route_update_event_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_manager_trigger_route_deleted_event (NetworkInadorHandle *handle, Route *route) {
|
||||||
|
if (handle->notify_list.route_del_event_cb != NULL) {
|
||||||
|
handle->notify_list.route_del_event_cb (handle, route, handle->notify_list.route_del_event_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ void network_manager_trigger_interface_updated_event (NetworkInadorHandle *handl
|
||||||
void network_manager_trigger_interface_deleted_event (NetworkInadorHandle *handle, uint32_t index);
|
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_added_event (NetworkInadorHandle *handle, IPAddr *ip_addr);
|
||||||
void network_manager_trigger_ip_deleted_event (NetworkInadorHandle *handle, IPAddr *ip_addr);
|
void network_manager_trigger_ip_deleted_event (NetworkInadorHandle *handle, IPAddr *ip_addr);
|
||||||
|
void network_manager_trigger_route_added_event (NetworkInadorHandle *handle, Route *route);
|
||||||
|
void network_manager_trigger_route_updated_event (NetworkInadorHandle *handle, Route *route);
|
||||||
|
void network_manager_trigger_route_deleted_event (NetworkInadorHandle *handle, Route *route);
|
||||||
|
|
||||||
#endif /* __EVENT_NOTIFY_H__ */
|
#endif /* __EVENT_NOTIFY_H__ */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* file_watcher.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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
|
||||||
|
#include "file_watcher.h"
|
||||||
|
#include "network-inador-private.h"
|
||||||
|
|
||||||
|
static void network_inador_file_watcher_deliver_event (NetworkInadorHandle *handle, struct inotify_event *event, INotifyWD *inotwd) {
|
||||||
|
/* Este es el que pidió cierre de escritura */
|
||||||
|
if (event->mask & IN_CLOSE_WRITE) {
|
||||||
|
if (inotwd->close_write_cb != NULL) {
|
||||||
|
inotwd->close_write_cb (handle, NULL, inotwd->close_write_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((event->mask & IN_IGNORED) || (event->mask & IN_DELETE_SELF) || (event->mask & IN_MOVE_SELF)) {
|
||||||
|
/* El evento fué eliminado, quitar de la lista de wds */
|
||||||
|
handle->file_watcher.wds = f_list_remove (handle->file_watcher.wds, inotwd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void network_inador_file_watcher_inotify_read_cb (void *data, int fd, int condition) {
|
||||||
|
NetworkInadorHandle *handle = (NetworkInadorHandle *) data;
|
||||||
|
int res, g, n;
|
||||||
|
struct inotify_event events[20];
|
||||||
|
FList *p, *next;
|
||||||
|
INotifyWD *inotwd;
|
||||||
|
|
||||||
|
inotify_read_again:
|
||||||
|
res = read (handle->file_watcher.inotify_fd, events, sizeof (events));
|
||||||
|
|
||||||
|
/* Nada que leer */
|
||||||
|
if (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) return;
|
||||||
|
|
||||||
|
if (res <= 0) {
|
||||||
|
/* El inotify fué cerrado, cancelar la vigilancia y quitar el source */
|
||||||
|
handle->ops.input_remove (handle->file_watcher.inotify_source);
|
||||||
|
handle->file_watcher.inotify_source = 0;
|
||||||
|
|
||||||
|
f_list_free_full (handle->file_watcher.wds, free);
|
||||||
|
handle->file_watcher.has_inotify = FALSE;
|
||||||
|
|
||||||
|
close (handle->file_watcher.inotify_fd);
|
||||||
|
handle->file_watcher.inotify_fd = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = res / sizeof (events[0]);
|
||||||
|
|
||||||
|
for (g = 0; g < n; g++) {
|
||||||
|
p = handle->file_watcher.wds;
|
||||||
|
while (p != NULL) {
|
||||||
|
next = p->next;
|
||||||
|
inotwd = (INotifyWD *) p->data;
|
||||||
|
|
||||||
|
if (inotwd->inotify_wd == events[g].wd) {
|
||||||
|
network_inador_file_watcher_deliver_event (handle, &events[g], inotwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == sizeof (events)) goto inotify_read_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_file_watcher_init (NetworkInadorHandle *handle) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (handle->ops.input_add != NULL) {
|
||||||
|
/* Como tenemos vigilancia de fds, podemos intentar inicializar el inotify */
|
||||||
|
fd = inotify_init1 (IN_NONBLOCK | IN_CLOEXEC);
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
handle->file_watcher.has_inotify = FALSE;
|
||||||
|
handle->file_watcher.inotify_fd = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->file_watcher.inotify_source = handle->ops.input_add (fd, POLLIN, network_inador_file_watcher_inotify_read_cb, handle);
|
||||||
|
|
||||||
|
handle->file_watcher.has_inotify = TRUE;
|
||||||
|
handle->file_watcher.inotify_fd = fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_file_watcher_add_file (NetworkInadorHandle *handle, const char *path, FileWatcherCloseWriteCB close_write_cb, void *close_write_data) {
|
||||||
|
int res, wd;
|
||||||
|
INotifyWD *inotwd;
|
||||||
|
|
||||||
|
if (handle->file_watcher.has_inotify == FALSE) return;
|
||||||
|
|
||||||
|
wd = inotify_add_watch (handle->file_watcher.inotify_fd, path, IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MOVE_SELF);
|
||||||
|
|
||||||
|
if (wd < 0) return; /* No lo pude agregar */
|
||||||
|
|
||||||
|
inotwd = (INotifyWD *) malloc (sizeof (INotifyWD));
|
||||||
|
if (inotwd == NULL) {
|
||||||
|
inotify_rm_watch (handle->file_watcher.inotify_fd, wd);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (inotwd, 0, sizeof (INotifyWD));
|
||||||
|
inotwd->inotify_wd = wd;
|
||||||
|
inotwd->close_write_cb = close_write_cb;
|
||||||
|
inotwd->close_write_data = close_write_data;
|
||||||
|
|
||||||
|
strncpy (inotwd->path, path, sizeof (inotwd->path));
|
||||||
|
|
||||||
|
handle->file_watcher.wds = f_list_append (handle->file_watcher.wds, inotwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_file_watcher_cleanup (NetworkInadorHandle *handle) {
|
||||||
|
if (handle->file_watcher.has_inotify) {
|
||||||
|
close (handle->file_watcher.inotify_fd);
|
||||||
|
handle->file_watcher.inotify_fd = -1;
|
||||||
|
|
||||||
|
if (handle->file_watcher.inotify_source != 0 && handle->ops.input_remove != NULL) {
|
||||||
|
handle->ops.input_remove (handle->file_watcher.inotify_source);
|
||||||
|
handle->file_watcher.inotify_source = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* file_watcher.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 __FILE_WATCHER_H__
|
||||||
|
#define __FILE_WATCHER_H__
|
||||||
|
|
||||||
|
#include "network-inador-public.h"
|
||||||
|
#include "flist.h"
|
||||||
|
|
||||||
|
typedef void (*FileWatcherCloseWriteCB) (NetworkInadorHandle *handle, const char *path, void *data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int inotify_wd;
|
||||||
|
|
||||||
|
char path[4096];
|
||||||
|
FileWatcherCloseWriteCB close_write_cb;
|
||||||
|
void *close_write_data;
|
||||||
|
} INotifyWD;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int has_inotify;
|
||||||
|
|
||||||
|
int inotify_fd;
|
||||||
|
int inotify_source;
|
||||||
|
|
||||||
|
FList *wds;
|
||||||
|
} NetworkInadorFileWatcher;
|
||||||
|
|
||||||
|
void network_inador_file_watcher_init (NetworkInadorHandle *handle);
|
||||||
|
void network_inador_file_watcher_add_file (NetworkInadorHandle *handle, const char *path, FileWatcherCloseWriteCB close_write_cb, void *close_write_data);
|
||||||
|
|
||||||
|
void network_inador_file_watcher_cleanup (NetworkInadorHandle *handle);
|
||||||
|
|
||||||
|
#endif /* __FILE_WATCHER_H__ */
|
||||||
|
|
163
lib/getters.c
163
lib/getters.c
|
@ -27,6 +27,7 @@
|
||||||
#include "network-inador-private.h"
|
#include "network-inador-private.h"
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
#include "ip-address.h"
|
#include "ip-address.h"
|
||||||
|
#include "routes.h"
|
||||||
|
|
||||||
uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle) {
|
uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle) {
|
||||||
uint32_t *memory;
|
uint32_t *memory;
|
||||||
|
@ -51,7 +52,11 @@ uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Interface *network_inador_get_iface (NetworkInadorHandle *handle, uint32_t index) {
|
Interface *network_inador_get_iface (NetworkInadorHandle *handle, uint32_t index) {
|
||||||
_interfaces_locate_by_index (handle->interfaces, index);
|
return _interfaces_locate_by_index (handle->interfaces, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Interface *network_inador_get_iface_by_name (NetworkInadorHandle *handle, const char *name) {
|
||||||
|
return _interfaces_locate_by_name (handle->interfaces, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char *network_inador_iface_get_name (Interface *iface) {
|
const unsigned char *network_inador_iface_get_name (Interface *iface) {
|
||||||
|
@ -87,10 +92,7 @@ uint8_t network_inador_iface_get_num_ips (Interface *iface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
IPAddr *network_inador_iface_get_ipaddr_by_index (Interface *iface, int index) {
|
IPAddr *network_inador_iface_get_ipaddr_by_index (Interface *iface, int index) {
|
||||||
FList *pos;
|
return (IPAddr *) f_list_nth_data (f_list_first (iface->address), index);
|
||||||
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) {
|
Interface *network_inador_ipaddr_get_iface (IPAddr *ip_addr) {
|
||||||
|
@ -198,3 +200,154 @@ const unsigned char *network_inador_ipaddr_get_label (IPAddr *ip_addr) {
|
||||||
return ip_addr->label;
|
return ip_addr->label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int network_inador_get_routes_count (NetworkInadorHandle *handle, int family) {
|
||||||
|
if (family == AF_UNSPEC) {
|
||||||
|
return handle->route_v4_counter + handle->route_v6_counter;
|
||||||
|
} else if (family == AF_INET) {
|
||||||
|
return handle->route_v4_counter;
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
return handle->route_v6_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Route *network_inador_get_route_by_index (NetworkInadorHandle *handle, int family, int index) {
|
||||||
|
if (family == AF_INET) {
|
||||||
|
return (Route *) f_list_nth_data (f_list_first (handle->route_v4_tables), index);
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
return (Route *) f_list_nth_data (f_list_first (handle->route_v6_tables), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_route_get_family (Route *route) {
|
||||||
|
return route->family;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_route_get_type (Route *route) {
|
||||||
|
return route->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t network_inador_route_get_table (Route *route) {
|
||||||
|
return route->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_route_get_prefix (Route *route) {
|
||||||
|
return route->prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_route_get_protocol (Route *route) {
|
||||||
|
return route->protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_route_get_tos (Route *route) {
|
||||||
|
return route->tos;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_route_get_scope (Route *route) {
|
||||||
|
return route->scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_route_has_prefsrc (Route *route) {
|
||||||
|
return route->has_prefsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t network_inador_route_get_priority (Route *route) {
|
||||||
|
return route->priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_route_get_dest (Route *route, void *dest, int *addr_size) {
|
||||||
|
int family_size = 0;
|
||||||
|
|
||||||
|
if (route->family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (route->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 (dest, &route->dest, family_size);
|
||||||
|
|
||||||
|
if (addr_size != NULL) {
|
||||||
|
*addr_size = family_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_route_get_prefsrc (Route *route, void *prefsrc, int *addr_size) {
|
||||||
|
int family_size = 0;
|
||||||
|
|
||||||
|
if (route->family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (route->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 (prefsrc, &route->prefsrc, family_size);
|
||||||
|
|
||||||
|
if (addr_size != NULL) {
|
||||||
|
*addr_size = family_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int network_inador_route_get_num_nexthops (Route *route) {
|
||||||
|
return f_list_length (route->nexthops);
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteNH *network_inador_route_get_nexthop_by_index (Route *route, int index) {
|
||||||
|
return (RouteNH *) f_list_nth_data (f_list_first (route->nexthops), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_nexthop_has_gw (RouteNH *nexthop) {
|
||||||
|
return nexthop->has_gw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_nexthop_get_gw (RouteNH *nexthop, void *gw, int *addr_size) {
|
||||||
|
int family_size = 0;
|
||||||
|
|
||||||
|
if (nexthop->family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (nexthop->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 (gw, &nexthop->gw, family_size);
|
||||||
|
|
||||||
|
if (addr_size != NULL) {
|
||||||
|
*addr_size = family_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_nexthop_get_flags (RouteNH *nexthop) {
|
||||||
|
return nexthop->nh_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t network_inador_nexthop_get_weight (RouteNH *nexthop) {
|
||||||
|
return nexthop->nh_weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t network_inador_nexthop_get_out_index (RouteNH *nexthop) {
|
||||||
|
return nexthop->out_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
#include "resolv_manager.h"
|
#include "resolv_manager.h"
|
||||||
|
#include "file_watcher.h"
|
||||||
|
|
||||||
struct _NetworkInadorWatchedPID {
|
struct _NetworkInadorWatchedPID {
|
||||||
unsigned int source;
|
unsigned int source;
|
||||||
|
@ -250,6 +251,8 @@ NetworkInadorHandle * network_inador_init_handle (struct NetworkInadorOps *netwo
|
||||||
_network_inador_try_pipe_routes (handle);
|
_network_inador_try_pipe_routes (handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network_inador_file_watcher_init (handle);
|
||||||
|
|
||||||
/* Inicializar las interfaces (y las direcciones IP) */
|
/* Inicializar las interfaces (y las direcciones IP) */
|
||||||
interfaces_init (handle);
|
interfaces_init (handle);
|
||||||
|
|
||||||
|
@ -277,6 +280,8 @@ void network_inador_destroy_handle (NetworkInadorHandle *handle) {
|
||||||
network_inador_pipes_child_notify[1] = -1;
|
network_inador_pipes_child_notify[1] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network_inador_file_watcher_cleanup (handle);
|
||||||
|
|
||||||
if (handle->has_route_events) {
|
if (handle->has_route_events) {
|
||||||
/* Quitar la vigilancia */
|
/* Quitar la vigilancia */
|
||||||
handle->ops.input_remove (handle->route_events.source);
|
handle->ops.input_remove (handle->route_events.source);
|
||||||
|
|
|
@ -672,6 +672,57 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int interfaces_delete (NetworkInadorHandle *handle, int index) {
|
||||||
|
struct nl_msg * msg;
|
||||||
|
struct ifinfomsg iface_hdr;
|
||||||
|
int ret, error;
|
||||||
|
Interface *iface;
|
||||||
|
|
||||||
|
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||||
|
|
||||||
|
if (iface == NULL) {
|
||||||
|
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#if 0
|
||||||
int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...) {
|
int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...) {
|
||||||
uint32_t new_sysctl[DEVCONF_MAX];
|
uint32_t new_sysctl[DEVCONF_MAX];
|
||||||
|
|
|
@ -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_set_down (NetworkInadorHandle *handle, int index);
|
||||||
int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_name);
|
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, ...);
|
//int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...);
|
||||||
|
|
||||||
void interfaces_clean_up (NetworkInadorHandle *handle);
|
void interfaces_clean_up (NetworkInadorHandle *handle);
|
||||||
|
|
|
@ -322,7 +322,7 @@ static int _ip_address_wait_error (struct sockaddr_nl *nla, struct nlmsgerr *l_e
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_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) {
|
||||||
struct nl_msg * msg;
|
struct nl_msg * msg;
|
||||||
struct ifaddrmsg addr_hdr;
|
struct ifaddrmsg addr_hdr;
|
||||||
int ret, error;
|
int ret, error;
|
||||||
|
@ -338,10 +338,10 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_hdr.ifa_family = ip_addr->family;
|
addr_hdr.ifa_family = ip_family;
|
||||||
addr_hdr.ifa_prefixlen = ip_addr->prefix;
|
addr_hdr.ifa_prefixlen = ip_prefix;
|
||||||
addr_hdr.ifa_flags = ip_addr->flags;
|
addr_hdr.ifa_flags = ip_flags;
|
||||||
addr_hdr.ifa_scope = ip_addr->scope;
|
addr_hdr.ifa_scope = ip_scope;
|
||||||
addr_hdr.ifa_index = index;
|
addr_hdr.ifa_index = index;
|
||||||
|
|
||||||
msg = nlmsg_alloc_simple (RTM_NEWADDR, NLM_F_REQUEST);
|
msg = nlmsg_alloc_simple (RTM_NEWADDR, NLM_F_REQUEST);
|
||||||
|
@ -353,28 +353,28 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip_addr->family == AF_INET) {
|
if (ip_family == AF_INET) {
|
||||||
family_size = sizeof (struct in_addr);
|
family_size = sizeof (struct in_addr);
|
||||||
} else if (ip_addr->family == AF_INET6) {
|
} else if (ip_family == AF_INET6) {
|
||||||
family_size = sizeof (struct in6_addr);
|
family_size = sizeof (struct in6_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nla_put (msg, IFA_ADDRESS, family_size, &ip_addr->addr);
|
ret = nla_put (msg, IFA_ADDRESS, family_size, ip_addr);
|
||||||
if (ip_addr->has_local) {
|
if (ip_has_local) {
|
||||||
ret |= nla_put (msg, IFA_LOCAL, family_size, &ip_addr->local_addr);
|
ret |= nla_put (msg, IFA_LOCAL, family_size, ip_local_addr);
|
||||||
} else {
|
} else {
|
||||||
ret |= nla_put (msg, IFA_LOCAL, family_size, &ip_addr->addr);
|
ret |= nla_put (msg, IFA_LOCAL, family_size, ip_addr);
|
||||||
}
|
}
|
||||||
if (ip_addr->has_brd) {
|
if (ip_has_brd) {
|
||||||
ret |= nla_put (msg, IFA_BROADCAST, family_size, &ip_addr->brd_addr);
|
ret |= nla_put (msg, IFA_BROADCAST, family_size, ip_brd_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* El tiempo preferido no puede ser mayor que el tiempo válido */
|
/* El tiempo preferido no puede ser mayor que el tiempo válido */
|
||||||
if (ip_addr->cacheinfo.ifa_prefered > ip_addr->cacheinfo.ifa_valid) {
|
if (ip_cacheinfo->ifa_prefered > ip_cacheinfo->ifa_valid) {
|
||||||
ip_addr->cacheinfo.ifa_prefered = ip_addr->cacheinfo.ifa_valid;
|
ip_cacheinfo->ifa_prefered = ip_cacheinfo->ifa_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret |= nla_put (msg, IFA_CACHEINFO, 16, &ip_addr->cacheinfo);
|
ret |= nla_put (msg, IFA_CACHEINFO, 16, ip_cacheinfo);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
nlmsg_free (msg);
|
nlmsg_free (msg);
|
||||||
|
@ -406,12 +406,11 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr) {
|
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) {
|
||||||
struct nl_msg * msg;
|
struct nl_msg * msg;
|
||||||
struct ifaddrmsg addr_hdr;
|
struct ifaddrmsg addr_hdr;
|
||||||
int ret, error;
|
int ret, error;
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
FList *addr_pos;
|
|
||||||
int family_size = 0;
|
int family_size = 0;
|
||||||
|
|
||||||
/* TODO: Si no tenemos los eventos, podemos ejecutar una lectura de interfaces para refrescar la información */
|
/* TODO: Si no tenemos los eventos, podemos ejecutar una lectura de interfaces para refrescar la información */
|
||||||
|
@ -423,18 +422,9 @@ int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_pos = f_list_find (iface->address, ip_addr);
|
memset (&addr_hdr, 0, sizeof (addr_hdr));
|
||||||
|
addr_hdr.ifa_family = ip_family;
|
||||||
if (addr_pos == NULL) {
|
addr_hdr.ifa_prefixlen = ip_prefix;
|
||||||
printf ("Error, la dirección solicitada no pertenece a la interfaz\n");
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_hdr.ifa_family = ip_addr->family;
|
|
||||||
addr_hdr.ifa_prefixlen = ip_addr->prefix;
|
|
||||||
addr_hdr.ifa_flags = ip_addr->flags;
|
|
||||||
addr_hdr.ifa_scope = ip_addr->scope;
|
|
||||||
addr_hdr.ifa_index = index;
|
addr_hdr.ifa_index = index;
|
||||||
|
|
||||||
msg = nlmsg_alloc_simple (RTM_DELADDR, NLM_F_REQUEST);
|
msg = nlmsg_alloc_simple (RTM_DELADDR, NLM_F_REQUEST);
|
||||||
|
@ -446,18 +436,15 @@ int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip_addr->family == AF_INET) {
|
if (ip_family == AF_INET) {
|
||||||
family_size = sizeof (struct in_addr);
|
family_size = sizeof (struct in_addr);
|
||||||
} else if (ip_addr->family == AF_INET6) {
|
} else if (ip_family == AF_INET6) {
|
||||||
family_size = sizeof (struct in6_addr);
|
family_size = sizeof (struct in6_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nla_put (msg, IFA_ADDRESS, family_size, &ip_addr->addr);
|
ret = nla_put (msg, IFA_ADDRESS, family_size, ip_addr);
|
||||||
if (ip_addr->has_local) {
|
if (ip_has_local) {
|
||||||
ret |= nla_put (msg, IFA_LOCAL, family_size, &ip_addr->local_addr);
|
ret |= nla_put (msg, IFA_LOCAL, family_size, ip_local_addr);
|
||||||
}
|
|
||||||
if (ip_addr->has_brd) {
|
|
||||||
ret |= nla_put (msg, IFA_BROADCAST, family_size, &ip_addr->brd_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
|
|
@ -60,8 +60,8 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg);
|
||||||
int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg);
|
int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg);
|
||||||
void ip_address_init (NetworkInadorHandle *handle);
|
void ip_address_init (NetworkInadorHandle *handle);
|
||||||
|
|
||||||
int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *addr);
|
int ip_address_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);
|
||||||
int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *addr);
|
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);
|
||||||
|
|
||||||
IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, void *addr, uint32_t prefix, void *local_addr);
|
IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, void *addr, uint32_t prefix, void *local_addr);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct _NetworkInadorHandle NetworkInadorHandle;
|
||||||
typedef struct _Interface Interface;
|
typedef struct _Interface Interface;
|
||||||
typedef struct _InterfaceDHCPClientInfo InterfaceDHCPClientInfo;
|
typedef struct _InterfaceDHCPClientInfo InterfaceDHCPClientInfo;
|
||||||
typedef struct _IPAddr IPAddr;
|
typedef struct _IPAddr IPAddr;
|
||||||
|
typedef struct _Route Route;
|
||||||
|
|
||||||
typedef void (*NetworkInadorDHCPEventCB) (NetworkInadorHandle *handle, Interface *iface, InterfaceDHCPClientInfo *dhcp_info, void *data);
|
typedef void (*NetworkInadorDHCPEventCB) (NetworkInadorHandle *handle, Interface *iface, InterfaceDHCPClientInfo *dhcp_info, void *data);
|
||||||
typedef void (*NetworkInadorInterfaceAddEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data);
|
typedef void (*NetworkInadorInterfaceAddEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data);
|
||||||
|
@ -36,6 +37,9 @@ typedef void (*NetworkInadorInterfaceUpdateEventCB) (NetworkInadorHandle *handle
|
||||||
typedef void (*NetworkInadorInterfaceDeleteEventCB) (NetworkInadorHandle *handle, uint32_t index, void *data);
|
typedef void (*NetworkInadorInterfaceDeleteEventCB) (NetworkInadorHandle *handle, uint32_t index, void *data);
|
||||||
typedef void (*NetworkInadorIPAddEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
typedef void (*NetworkInadorIPAddEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
||||||
typedef void (*NetworkInadorIPDelEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
typedef void (*NetworkInadorIPDelEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
||||||
|
typedef void (*NetworkInadorRouteAddEventCB) (NetworkInadorHandle *handle, Route *route, void *data);
|
||||||
|
typedef void (*NetworkInadorRouteUpdateEventCB) (NetworkInadorHandle *handle, Route *route, void *data);
|
||||||
|
typedef void (*NetworkInadorRouteDelEventCB) (NetworkInadorHandle *handle, Route *route, void *data);
|
||||||
|
|
||||||
/* Pendiente notificar rutas */
|
/* Pendiente notificar rutas */
|
||||||
void network_manager_add_watch_dhcp (NetworkInadorHandle *handle, NetworkInadorDHCPEventCB cb, void *data);
|
void network_manager_add_watch_dhcp (NetworkInadorHandle *handle, NetworkInadorDHCPEventCB cb, void *data);
|
||||||
|
@ -45,5 +49,9 @@ void network_manager_add_watch_interface_deleted (NetworkInadorHandle *handle, N
|
||||||
void network_manager_add_watch_ip_added (NetworkInadorHandle *handle, NetworkInadorIPAddEventCB 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);
|
void network_manager_add_watch_ip_deleted (NetworkInadorHandle *handle, NetworkInadorIPDelEventCB cb, void *data);
|
||||||
|
|
||||||
|
void network_manager_add_watch_route_added (NetworkInadorHandle *handle, NetworkInadorRouteAddEventCB cb, void *data);
|
||||||
|
void network_manager_add_watch_route_updated (NetworkInadorHandle *handle, NetworkInadorRouteUpdateEventCB cb, void *data);
|
||||||
|
void network_manager_add_watch_route_deleted (NetworkInadorHandle *handle, NetworkInadorRouteDelEventCB cb, void *data);
|
||||||
|
|
||||||
#endif /* __NETWORK_INADOR_EVENTS_H__ */
|
#endif /* __NETWORK_INADOR_EVENTS_H__ */
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "network-inador-public.h"
|
#include "network-inador-public.h"
|
||||||
#include "flist.h"
|
#include "flist.h"
|
||||||
#include "network-inador-events.h"
|
#include "network-inador-events.h"
|
||||||
|
#include "file_watcher.h"
|
||||||
|
|
||||||
/* Para vigilar eventos */
|
/* Para vigilar eventos */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -56,6 +57,13 @@ typedef struct _NetworkInadorEventList {
|
||||||
void *ip_add_event_data;
|
void *ip_add_event_data;
|
||||||
NetworkInadorIPDelEventCB ip_del_event_cb;
|
NetworkInadorIPDelEventCB ip_del_event_cb;
|
||||||
void *ip_del_event_data;
|
void *ip_del_event_data;
|
||||||
|
|
||||||
|
NetworkInadorRouteAddEventCB route_add_event_cb;
|
||||||
|
void *route_add_event_data;
|
||||||
|
NetworkInadorRouteUpdateEventCB route_update_event_cb;
|
||||||
|
void *route_update_event_data;
|
||||||
|
NetworkInadorRouteDelEventCB route_del_event_cb;
|
||||||
|
void *route_del_event_data;
|
||||||
} NetworkInadorEventList;
|
} NetworkInadorEventList;
|
||||||
|
|
||||||
/* La definición principal que engloba todo */
|
/* La definición principal que engloba todo */
|
||||||
|
@ -70,11 +78,11 @@ struct _NetworkInadorHandle {
|
||||||
|
|
||||||
/* Auxiliar contador de la lista ligada de interfaces */
|
/* Auxiliar contador de la lista ligada de interfaces */
|
||||||
int interfaces_counter;
|
int interfaces_counter;
|
||||||
|
int route_v4_counter;
|
||||||
|
int route_v6_counter;
|
||||||
|
|
||||||
/* Entradas para el resolv conf */
|
/* Entradas para el resolv conf */
|
||||||
FList *resolver_entries;
|
FList *resolver_entries;
|
||||||
int resolver_inotify_fd;
|
|
||||||
int resolver_inotify_watch;
|
|
||||||
|
|
||||||
/* Estos sockets ejecutan comandos */
|
/* Estos sockets ejecutan comandos */
|
||||||
struct nl_sock * nl_sock_route;
|
struct nl_sock * nl_sock_route;
|
||||||
|
@ -91,6 +99,10 @@ struct _NetworkInadorHandle {
|
||||||
int pipe_routes[2];
|
int pipe_routes[2];
|
||||||
unsigned int source_pipe_routes;
|
unsigned int source_pipe_routes;
|
||||||
|
|
||||||
|
/* Para la vigilancia de cambios en los archivos */
|
||||||
|
NetworkInadorFileWatcher file_watcher;
|
||||||
|
|
||||||
|
/* Para notificar los eventos fuera de la librería */
|
||||||
struct _NetworkInadorEventList notify_list;
|
struct _NetworkInadorEventList notify_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@ struct NetworkInadorOps {
|
||||||
typedef struct _NetworkInadorHandle NetworkInadorHandle;
|
typedef struct _NetworkInadorHandle NetworkInadorHandle;
|
||||||
typedef struct _Interface Interface;
|
typedef struct _Interface Interface;
|
||||||
typedef struct _IPAddr IPAddr;
|
typedef struct _IPAddr IPAddr;
|
||||||
|
typedef struct _Route Route;
|
||||||
|
typedef struct _RouteNH RouteNH;
|
||||||
|
|
||||||
NetworkInadorHandle * network_inador_init_handle (struct NetworkInadorOps *network_inador_ops);
|
NetworkInadorHandle * network_inador_init_handle (struct NetworkInadorOps *network_inador_ops);
|
||||||
void network_inador_destroy_handle (NetworkInadorHandle *handle);
|
void network_inador_destroy_handle (NetworkInadorHandle *handle);
|
||||||
|
@ -72,13 +74,32 @@ int interfaces_change_set_up (NetworkInadorHandle *handle, int index);
|
||||||
int interfaces_change_set_down (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_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 */
|
/* Funciones básicas de dhcp */
|
||||||
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags);
|
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags);
|
||||||
int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);
|
int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);
|
||||||
|
|
||||||
|
/* Funciones de Rutas */
|
||||||
|
int routes_add (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint8_t route_protocol, uint8_t route_scope, uint8_t route_type, void *dest, void *prefsrc, uint32_t route_priority, void *route_nexthops);
|
||||||
|
int routes_del (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint32_t route_priority, void *dest);
|
||||||
|
|
||||||
|
/* Funciones de resolvconf */
|
||||||
|
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries);
|
||||||
|
|
||||||
/* Lista de getters */
|
/* Lista de getters */
|
||||||
uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle);
|
uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle);
|
||||||
Interface * network_inador_get_iface (NetworkInadorHandle *handle, uint32_t index);
|
Interface * network_inador_get_iface (NetworkInadorHandle *handle, uint32_t index);
|
||||||
|
Interface *network_inador_get_iface_by_name (NetworkInadorHandle *handle, const char *name);
|
||||||
const unsigned char *network_inador_iface_get_name (Interface *iface);
|
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_index (Interface *iface);
|
||||||
uint32_t network_inador_iface_get_link_type (Interface *iface);
|
uint32_t network_inador_iface_get_link_type (Interface *iface);
|
||||||
|
@ -101,5 +122,33 @@ void network_inador_ipaddr_get_local_addr (IPAddr *ip_addr, void *addr, int *add
|
||||||
void network_inador_ipaddr_get_brd_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);
|
const unsigned char *network_inador_ipaddr_get_label (IPAddr *ip_addr);
|
||||||
|
|
||||||
|
int network_inador_get_routes_count (NetworkInadorHandle *handle, int family);
|
||||||
|
Route *network_inador_get_route_by_index (NetworkInadorHandle *handle, int family, int index);
|
||||||
|
|
||||||
|
uint8_t network_inador_route_get_family (Route *route);
|
||||||
|
uint8_t network_inador_route_get_type (Route *route);
|
||||||
|
uint32_t network_inador_route_get_table (Route *route);
|
||||||
|
uint8_t network_inador_route_get_prefix (Route *route);
|
||||||
|
uint8_t network_inador_route_get_protocol (Route *route);
|
||||||
|
uint8_t network_inador_route_get_tos (Route *route);
|
||||||
|
uint8_t network_inador_route_get_scope (Route *route);
|
||||||
|
uint8_t network_inador_route_has_prefsrc (Route *route);
|
||||||
|
uint32_t network_inador_route_get_priority (Route *route);
|
||||||
|
void network_inador_route_get_dest (Route *route, void *dest, int *addr_size);
|
||||||
|
void network_inador_route_get_prefsrc (Route *route, void *prefsrc, int *addr_size);
|
||||||
|
int network_inador_route_get_num_nexthops (Route *route);
|
||||||
|
RouteNH *network_inador_route_get_nexthop_by_index (Route *route, int index);
|
||||||
|
uint8_t network_inador_nexthop_has_gw (RouteNH *nexthop);
|
||||||
|
void network_inador_nexthop_get_gw (RouteNH *nexthop, void *gw, int *addr_size);
|
||||||
|
uint8_t network_inador_nexthop_get_flags (RouteNH *nexthop);
|
||||||
|
uint8_t network_inador_nexthop_get_weight (RouteNH *nexthop);
|
||||||
|
uint32_t network_inador_nexthop_get_out_index (RouteNH *nexthop);
|
||||||
|
|
||||||
|
void *network_inador_route_append_nexthop (void *list, uint8_t family, void *gw, uint32_t out_iface, uint8_t weight, uint8_t flags);
|
||||||
|
void network_inador_route_free_all_nexthops (void *list);
|
||||||
|
|
||||||
|
void *network_inador_resolvconf_append_ns_entry (void *list, int family, void *addr, int iface_index, const char *owner_prog);
|
||||||
|
void network_inador_resolvconf_free_all_entries (void *list);
|
||||||
|
|
||||||
#endif /* __NETWORK_INADOR_H__ */
|
#endif /* __NETWORK_INADOR_H__ */
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "resolv_conf_parser.h"
|
#include "resolv_conf_parser.h"
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
|
#include "file_watcher.h"
|
||||||
|
|
||||||
void resolv_manager_write (NetworkInadorHandle *handle);
|
void resolv_manager_write (NetworkInadorHandle *handle);
|
||||||
|
|
||||||
|
@ -111,64 +112,70 @@ void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, ResolvConfEntry *entries, int num_entries) {
|
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries) {
|
||||||
int g;
|
ResolvConfEntry *new_entry, *found_entry;
|
||||||
ResolvConfEntry *entry;
|
FList *g, *pos_searched_entry;
|
||||||
FList *pos_entry;
|
|
||||||
int do_write = 0;
|
int do_write = 0;
|
||||||
|
int n;
|
||||||
|
|
||||||
resolv_manager_clear_tag_on_all (handle);
|
resolv_manager_clear_tag_on_all (handle);
|
||||||
|
|
||||||
for (g = 0; g < num_entries; g++) {
|
g = entries;
|
||||||
entry = NULL;
|
n = 0;
|
||||||
while (entry == NULL) {
|
while (g != NULL) {
|
||||||
pos_entry = resolv_parser_search_entry (handle->resolver_entries, entries[g].resolv_type, entries[g].ns_family, &entries[g].nameserver, entries[g].value, 1);
|
new_entry = (ResolvConfEntry *) g->data;
|
||||||
if (pos_entry == NULL) break;
|
|
||||||
|
found_entry = NULL;
|
||||||
|
while (found_entry == NULL) {
|
||||||
|
pos_searched_entry = resolv_parser_search_entry (handle->resolver_entries, new_entry->resolv_type, new_entry->ns_family, &new_entry->nameserver, new_entry->value, 1);
|
||||||
|
if (pos_searched_entry == NULL) break;
|
||||||
|
|
||||||
/* De ser posible, hacer conciliación */
|
/* De ser posible, hacer conciliación */
|
||||||
entry = (ResolvConfEntry *) pos_entry->data;
|
found_entry = (ResolvConfEntry *) pos_searched_entry->data;
|
||||||
|
|
||||||
if (entry->origin == RESOLV_ORIGIN_FILE) {
|
if (found_entry->origin == RESOLV_ORIGIN_FILE) {
|
||||||
/* Hacer esta entrada nuestra */
|
/* Hacer esta entrada nuestra */
|
||||||
entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
found_entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||||
entry->owner_interface_index = entries[g].owner_interface_index;
|
found_entry->owner_interface_index = new_entry->owner_interface_index;
|
||||||
entry->tagged = 1;
|
found_entry->tagged = 1;
|
||||||
strncpy (entry->owner_prog, entries[g].owner_prog, sizeof (entry->owner_prog));
|
strncpy (found_entry->owner_prog, new_entry->owner_prog, sizeof (found_entry->owner_prog));
|
||||||
printf ("/// Asociando una entrada %s existente del archivo al: %s\n", entry->value, entry->owner_prog);
|
printf ("/// Asociando una entrada %s existente del archivo al: %s\n", found_entry->value, found_entry->owner_prog);
|
||||||
#if 0
|
#if 0
|
||||||
} else if (entry->origin == RESOLV_ORIGIN_DHCP) {
|
} else if (found_entry->origin == RESOLV_ORIGIN_DHCP) {
|
||||||
/* Una entrada que coincide con la actual solo se puede re-asociar al resolvconf si pertenece a la misma interfaz */
|
/* Una entrada que coincide con la actual solo se puede re-asociar al resolvconf si pertenece a la misma interfaz */
|
||||||
if (entry->owner_interface_index != entries[g].owner_interface_index) {
|
if (found_entry->owner_interface_index != new_entry->owner_interface_index) {
|
||||||
entry->tagged = 1;
|
found_entry->tagged = 1;
|
||||||
entry = NULL;
|
found_entry = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* Existe la entrada, pero no la podemos tomar como nuestra, crear otra */
|
/* Existe la entrada, pero no la podemos tomar como nuestra, crear otra */
|
||||||
entry->tagged = 1;
|
found_entry->tagged = 1;
|
||||||
entry = NULL;
|
found_entry = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Si no existe, crearla */
|
/* Si no existe, crearla */
|
||||||
if (entry == NULL) {
|
if (found_entry == NULL) {
|
||||||
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
found_entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
||||||
|
|
||||||
memcpy (entry, &entries[g], sizeof (ResolvConfEntry));
|
memcpy (found_entry, new_entry, sizeof (ResolvConfEntry));
|
||||||
entry->file_order = g; /* TODO: Revisar esto del file order */
|
found_entry->file_order = n; /* TODO: Revisar esto del file order */
|
||||||
entry->tagged = 0;
|
found_entry->tagged = 0;
|
||||||
entry->priority = 0;
|
found_entry->priority = 0;
|
||||||
entry->for_purge = 0;
|
found_entry->for_purge = 0;
|
||||||
|
|
||||||
/* Anexar al final de la lista */
|
/* Anexar al final de la lista */
|
||||||
handle->resolver_entries = f_list_append (handle->resolver_entries, entry);
|
handle->resolver_entries = f_list_append (handle->resolver_entries, found_entry);
|
||||||
|
|
||||||
/* TODO: Como creamos una entrada via el resolvconf, regenerar el archivo */
|
/* TODO: Como creamos una entrada via el resolvconf, regenerar el archivo */
|
||||||
printf ("/// Nueva entrada %s via resolvconf, programando regeneración.\n", entry->value);
|
printf ("/// Nueva entrada %s via resolvconf, programando regeneración.\n", found_entry->value);
|
||||||
do_write = 1;
|
do_write = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g = g->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Si hubo actualización cambios, disparar ahora */
|
/* Si hubo actualización cambios, disparar ahora */
|
||||||
|
@ -373,7 +380,7 @@ void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
|
||||||
/* A la salida, borrar las que ya no siguen en el archivo */
|
/* A la salida, borrar las que ya no siguen en el archivo */
|
||||||
pos = handle->resolver_entries;
|
pos = handle->resolver_entries;
|
||||||
while (pos != NULL) {
|
while (pos != NULL) {
|
||||||
//next = pos->next;
|
next = pos->next;
|
||||||
entry = (ResolvConfEntry *) pos->data;
|
entry = (ResolvConfEntry *) pos->data;
|
||||||
|
|
||||||
if (entry->origin == RESOLV_ORIGIN_FILE && entry->tagged == 0) {
|
if (entry->origin == RESOLV_ORIGIN_FILE && entry->tagged == 0) {
|
||||||
|
@ -381,13 +388,13 @@ void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
|
||||||
printf ("/// La entrada %s del resolv.conf fué eliminada del archivo. Purgando nosotros.\n", entry->value);
|
printf ("/// La entrada %s del resolv.conf fué eliminada del archivo. Purgando nosotros.\n", entry->value);
|
||||||
|
|
||||||
entry->for_purge = 1;
|
entry->for_purge = 1;
|
||||||
/*handle->resolver_entries = f_list_delete_link (handle->resolver_entries, pos);
|
handle->resolver_entries = f_list_delete_link (handle->resolver_entries, pos);
|
||||||
free (entry);
|
free (entry);
|
||||||
entry = NULL;*/
|
entry = NULL;
|
||||||
} else {
|
} else {
|
||||||
printf ("/// La entrada %s del resolv.conf sigue en el archivo.\n", entry->value);
|
printf ("/// La entrada %s del resolv.conf sigue en el archivo.\n", entry->value);
|
||||||
}
|
}
|
||||||
pos = pos->next;
|
pos = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reordenar las entradas. TODO: Falta leer los ficheros de configuración del resolv.conf */
|
/* Reordenar las entradas. TODO: Falta leer los ficheros de configuración del resolv.conf */
|
||||||
|
@ -464,20 +471,13 @@ void resolv_manager_write (NetworkInadorHandle *handle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resolv_manager_notify_close_write_cb (NetworkInadorHandle *handle, const char *path, void *data) {
|
||||||
|
/* Cuando se nos notifique acerca de un cambio en el resolv.conf re-leer el archivo */
|
||||||
|
resolv_manager_read_local_etc_resolv (handle);
|
||||||
|
}
|
||||||
|
|
||||||
void resolv_manager_init (NetworkInadorHandle *handle) {
|
void resolv_manager_init (NetworkInadorHandle *handle) {
|
||||||
|
network_inador_file_watcher_add_file (handle, "/etc/resolv.conf", resolv_manager_notify_close_write_cb, NULL);
|
||||||
//handle->resolver_inotify_fd = inotify_init1 (IN_NONBLOCK | IN_CLOEXEC);
|
|
||||||
|
|
||||||
if (handle->resolver_inotify_fd >= 0) {
|
|
||||||
/* Debemos primero instalar el manejador de eventos de escritura sobre el resolv.conf */
|
|
||||||
/*
|
|
||||||
IN_CLOSE_WRITE Releer archivo.
|
|
||||||
IN_DELETE_SELF Dejar de hacer watch
|
|
||||||
IN_MOVE_SELF Dejar de hacer watch
|
|
||||||
*/
|
|
||||||
|
|
||||||
//handle->resolver_inotify_watch = inotify_add_watch (handle->resolver_inotify_fd, "/etc/resolv.conf",
|
|
||||||
}
|
|
||||||
|
|
||||||
handle->resolver_entries = NULL;
|
handle->resolver_entries = NULL;
|
||||||
/* Luego, leer el resolv.conf */
|
/* Luego, leer el resolv.conf */
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
void resolv_manager_init (NetworkInadorHandle *handle);
|
void resolv_manager_init (NetworkInadorHandle *handle);
|
||||||
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog);
|
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog);
|
||||||
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, ResolvConfEntry *entries, int num_entries);
|
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries);
|
||||||
void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);
|
void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);
|
||||||
void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);
|
void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);
|
||||||
//void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle);
|
//void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle);
|
||||||
|
|
111
lib/routes.c
111
lib/routes.c
|
@ -37,7 +37,7 @@
|
||||||
#include "flist.h"
|
#include "flist.h"
|
||||||
#include "network-inador-private.h"
|
#include "network-inador-private.h"
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
//#include "manager.h"
|
#include "event_notify.h"
|
||||||
|
|
||||||
int _route_compare_nexthop_v4 (const void * a, const void * b);
|
int _route_compare_nexthop_v4 (const void * a, const void * b);
|
||||||
int _route_compare_nexthop_v6 (const void * a, const void * b);
|
int _route_compare_nexthop_v6 (const void * a, const void * b);
|
||||||
|
@ -155,22 +155,23 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
||||||
struct nlmsghdr *reply;
|
struct nlmsghdr *reply;
|
||||||
Route *route = NULL;
|
Route *route = NULL;
|
||||||
uint32_t table, prefix;
|
uint32_t table, prefix;
|
||||||
int remaining, remaining2;
|
int remaining;
|
||||||
int family, family_size = 0;
|
int family, family_size = 0;
|
||||||
struct rtmsg *rtm_hdr;
|
struct rtmsg *rtm_hdr;
|
||||||
struct nlattr *attr, *nest_attr_gw;
|
struct nlattr *attr, *nest_attr_gw;
|
||||||
RouteNH *next_hop;
|
RouteNH *next_hop;
|
||||||
struct rtnexthop *nhptr;
|
struct rtnexthop *nhptr;
|
||||||
int rtnhp_len;
|
|
||||||
int multipath_len;
|
int multipath_len;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
uint8_t route_type, tos;
|
uint8_t route_type, tos;
|
||||||
struct_addr dest;
|
struct_addr dest, empty;
|
||||||
uint32_t priority = 0;
|
uint32_t priority = 0;
|
||||||
int was_new = 0, was_update = 0;
|
int was_new = 0, was_update = 0;
|
||||||
FList *route_list = NULL;
|
FList *route_list = NULL;
|
||||||
FList *old_next_hops = NULL;
|
FList *old_next_hops = NULL;
|
||||||
|
|
||||||
|
memset (&empty, 0, sizeof (empty));
|
||||||
|
|
||||||
reply = nlmsg_hdr (msg);
|
reply = nlmsg_hdr (msg);
|
||||||
|
|
||||||
if (reply->nlmsg_type != RTM_NEWROUTE) return NL_SKIP;
|
if (reply->nlmsg_type != RTM_NEWROUTE) return NL_SKIP;
|
||||||
|
@ -244,13 +245,14 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
||||||
|
|
||||||
if (family == AF_INET) {
|
if (family == AF_INET) {
|
||||||
handle->route_v4_tables = f_list_append (handle->route_v4_tables, route);
|
handle->route_v4_tables = f_list_append (handle->route_v4_tables, route);
|
||||||
|
handle->route_v4_counter++;
|
||||||
} else if (family == AF_INET6) {
|
} else if (family == AF_INET6) {
|
||||||
handle->route_v6_tables = f_list_append (handle->route_v6_tables, route);
|
handle->route_v6_tables = f_list_append (handle->route_v6_tables, route);
|
||||||
|
handle->route_v6_counter++;
|
||||||
}
|
}
|
||||||
was_new = 1;
|
was_new = 1;
|
||||||
} else {
|
} else {
|
||||||
/* Liberar los next-hops, puesto que volverán a ser creados */
|
/* Liberar los next-hops, puesto que volverán a ser creados */
|
||||||
//f_list_free_full (route->nexthops, free);
|
|
||||||
old_next_hops = route->nexthops;
|
old_next_hops = route->nexthops;
|
||||||
route->nexthops = NULL;
|
route->nexthops = NULL;
|
||||||
route->for_delete = 0;
|
route->for_delete = 0;
|
||||||
|
@ -270,6 +272,8 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
||||||
next_hop = (RouteNH *) malloc (sizeof (RouteNH));
|
next_hop = (RouteNH *) malloc (sizeof (RouteNH));
|
||||||
memset (next_hop, 0, sizeof (RouteNH));
|
memset (next_hop, 0, sizeof (RouteNH));
|
||||||
|
|
||||||
|
next_hop->family = family;
|
||||||
|
|
||||||
nlmsg_for_each_attr(attr, reply, sizeof (struct rtmsg), remaining) {
|
nlmsg_for_each_attr(attr, reply, sizeof (struct rtmsg), remaining) {
|
||||||
switch (nla_type (attr)) {
|
switch (nla_type (attr)) {
|
||||||
case RTA_PREFSRC:
|
case RTA_PREFSRC:
|
||||||
|
@ -283,6 +287,7 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
memcpy (&next_hop->gw, nla_data (attr), family_size);
|
memcpy (&next_hop->gw, nla_data (attr), family_size);
|
||||||
|
next_hop->has_gw = TRUE;
|
||||||
break;
|
break;
|
||||||
case RTA_OIF:
|
case RTA_OIF:
|
||||||
if (nla_len (attr) != 4) {
|
if (nla_len (attr) != 4) {
|
||||||
|
@ -307,6 +312,12 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
||||||
|
|
||||||
if (nest_attr_gw != NULL && nla_len (nest_attr_gw) == family_size) {
|
if (nest_attr_gw != NULL && nla_len (nest_attr_gw) == family_size) {
|
||||||
memcpy (&next_hop->gw, nla_data (nest_attr_gw), family_size);
|
memcpy (&next_hop->gw, nla_data (nest_attr_gw), family_size);
|
||||||
|
|
||||||
|
if (memcmp (&next_hop->gw, &empty, family_size) == 0) {
|
||||||
|
next_hop->has_gw = FALSE;
|
||||||
|
} else {
|
||||||
|
next_hop->has_gw = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
multipath_len -= nhptr->rtnh_len;
|
multipath_len -= nhptr->rtnh_len;
|
||||||
|
@ -318,12 +329,19 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
||||||
|
|
||||||
next_hop = (RouteNH *) malloc (sizeof (RouteNH));
|
next_hop = (RouteNH *) malloc (sizeof (RouteNH));
|
||||||
memset (next_hop, 0, sizeof (RouteNH));
|
memset (next_hop, 0, sizeof (RouteNH));
|
||||||
|
next_hop->family = family;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (memcmp (&empty, &route->prefsrc, family_size) == 0) {
|
||||||
|
route->has_prefsrc = FALSE;
|
||||||
|
} else {
|
||||||
|
route->has_prefsrc = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
route->nexthops = f_list_append (route->nexthops, next_hop);
|
route->nexthops = f_list_append (route->nexthops, next_hop);
|
||||||
route->nexthops = _route_sort_nexthops (family, route->nexthops);
|
route->nexthops = _route_sort_nexthops (family, route->nexthops);
|
||||||
|
|
||||||
|
@ -337,10 +355,10 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
||||||
|
|
||||||
if (was_new) {
|
if (was_new) {
|
||||||
/* Enviar aquí evento de ruta agregada */
|
/* Enviar aquí evento de ruta agregada */
|
||||||
//manager_send_event_route_add (handle, route);
|
network_manager_trigger_route_added_event (handle, route);
|
||||||
} else if (was_update) {
|
} else if (was_update) {
|
||||||
/* Enviar actualización */
|
/* Enviar actualización */
|
||||||
//manager_send_event_route_update (handle, route);
|
network_manager_trigger_route_updated_event (handle, route);
|
||||||
}
|
}
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
}
|
}
|
||||||
|
@ -419,13 +437,15 @@ int routes_receive_message_delroute (struct nl_msg *msg, void *arg) {
|
||||||
|
|
||||||
if (family == AF_INET) {
|
if (family == AF_INET) {
|
||||||
/* Eliminar de la lista ligada */
|
/* Eliminar de la lista ligada */
|
||||||
|
handle->route_v4_counter--;
|
||||||
handle->route_v4_tables = f_list_remove (handle->route_v4_tables, route);
|
handle->route_v4_tables = f_list_remove (handle->route_v4_tables, route);
|
||||||
} else if (family == AF_INET6) {
|
} else if (family == AF_INET6) {
|
||||||
|
handle->route_v6_counter--;
|
||||||
handle->route_v6_tables = f_list_remove (handle->route_v6_tables, route);
|
handle->route_v6_tables = f_list_remove (handle->route_v6_tables, route);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notificar del evento */
|
/* Notificar del evento */
|
||||||
//manager_send_event_route_del (handle, route);
|
network_manager_trigger_route_deleted_event (handle, route);
|
||||||
|
|
||||||
/* Eliminar todos los next-hops primero */
|
/* Eliminar todos los next-hops primero */
|
||||||
f_list_free_full (route->nexthops, free);
|
f_list_free_full (route->nexthops, free);
|
||||||
|
@ -459,7 +479,7 @@ static int _route_wait_error (struct sockaddr_nl *nla, struct nlmsgerr *l_err, v
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int routes_add (NetworkInadorHandle *handle, Route *route) {
|
int routes_add (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint8_t route_protocol, uint8_t route_scope, uint8_t route_type, void *dest, void *prefsrc, uint32_t route_priority, void *route_nexthops) {
|
||||||
struct nl_msg * msg, *msg_nh;
|
struct nl_msg * msg, *msg_nh;
|
||||||
struct rtmsg route_hdr;
|
struct rtmsg route_hdr;
|
||||||
int ret, error;
|
int ret, error;
|
||||||
|
@ -472,14 +492,16 @@ int routes_add (NetworkInadorHandle *handle, Route *route) {
|
||||||
char buffer_nexthops[8192];
|
char buffer_nexthops[8192];
|
||||||
int size_nexthops;
|
int size_nexthops;
|
||||||
|
|
||||||
route_hdr.rtm_family = route->family;
|
memset (&empty, 0, sizeof (empty));
|
||||||
route_hdr.rtm_dst_len = route->prefix;
|
|
||||||
|
route_hdr.rtm_family = route_family;
|
||||||
|
route_hdr.rtm_dst_len = route_prefix;
|
||||||
route_hdr.rtm_src_len = 0;
|
route_hdr.rtm_src_len = 0;
|
||||||
route_hdr.rtm_tos = route->tos;
|
route_hdr.rtm_tos = route_tos;
|
||||||
route_hdr.rtm_table = route->table;
|
route_hdr.rtm_table = route_table;
|
||||||
route_hdr.rtm_protocol = route->protocol;
|
route_hdr.rtm_protocol = route_protocol;
|
||||||
route_hdr.rtm_scope = route->scope;
|
route_hdr.rtm_scope = route_scope;
|
||||||
route_hdr.rtm_type = route->type;
|
route_hdr.rtm_type = route_type;
|
||||||
route_hdr.rtm_flags = 0;
|
route_hdr.rtm_flags = 0;
|
||||||
|
|
||||||
msg = nlmsg_alloc_simple (RTM_NEWROUTE, NLM_F_REQUEST | NLM_F_CREATE);
|
msg = nlmsg_alloc_simple (RTM_NEWROUTE, NLM_F_REQUEST | NLM_F_CREATE);
|
||||||
|
@ -491,26 +513,27 @@ int routes_add (NetworkInadorHandle *handle, Route *route) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route->family == AF_INET) {
|
if (route_family == AF_INET) {
|
||||||
family_size = sizeof (struct in_addr);
|
family_size = sizeof (struct in_addr);
|
||||||
} else if (route->family == AF_INET6) {
|
} else if (route_family == AF_INET6) {
|
||||||
family_size = sizeof (struct in6_addr);
|
family_size = sizeof (struct in6_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nla_put (msg, RTA_DST, family_size, &route->dest);
|
ret = nla_put (msg, RTA_DST, family_size, dest);
|
||||||
if (route->priority != 0) {
|
if (route_priority != 0) {
|
||||||
ret |= nla_put (msg, RTA_PRIORITY, 4, &route->priority);
|
ret |= nla_put (msg, RTA_PRIORITY, 4, &route_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (&empty, 0, sizeof (empty));
|
if (prefsrc != NULL) {
|
||||||
if (memcmp (&empty, &route->prefsrc, family_size) != 0) {
|
ret |= nla_put (msg, RTA_PREFSRC, family_size, prefsrc);
|
||||||
ret |= nla_put (msg, RTA_PREFSRC, family_size, &route->prefsrc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hop_count = f_list_length (route->nexthops);
|
hop_count = f_list_length ((FList *) route_nexthops);
|
||||||
if (hop_count <= 1) {
|
if (hop_count == 0) {
|
||||||
|
/* Revisar si no hay nexthops */
|
||||||
|
} else if (hop_count == 1) {
|
||||||
/* Agregar por el método 1 */
|
/* Agregar por el método 1 */
|
||||||
nh = (RouteNH *) route->nexthops->data;
|
nh = (RouteNH *) ((FList *) route_nexthops)->data;
|
||||||
|
|
||||||
ret |= nla_put (msg, RTA_OIF, 4, &nh->out_index);
|
ret |= nla_put (msg, RTA_OIF, 4, &nh->out_index);
|
||||||
|
|
||||||
|
@ -522,7 +545,7 @@ int routes_add (NetworkInadorHandle *handle, Route *route) {
|
||||||
//nest = nla_nest_start (msg, RTA_MULTIPATH);
|
//nest = nla_nest_start (msg, RTA_MULTIPATH);
|
||||||
size_nexthops = 0;
|
size_nexthops = 0;
|
||||||
|
|
||||||
g = route->nexthops;
|
g = (FList *) route_nexthops;
|
||||||
while (g != NULL) {
|
while (g != NULL) {
|
||||||
nh = (RouteNH *) g->data;
|
nh = (RouteNH *) g->data;
|
||||||
|
|
||||||
|
@ -585,22 +608,18 @@ int routes_add (NetworkInadorHandle *handle, Route *route) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int routes_del (NetworkInadorHandle *handle, Route *route) {
|
int routes_del (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint32_t route_priority, void *dest) {
|
||||||
struct nl_msg * msg;
|
struct nl_msg * msg;
|
||||||
struct rtmsg route_hdr;
|
struct rtmsg route_hdr;
|
||||||
int ret, error;
|
int ret, error;
|
||||||
int family_size = 0;
|
int family_size = 0;
|
||||||
struct_addr empty;
|
|
||||||
int hop_count;
|
|
||||||
RouteNH *nh;
|
|
||||||
FList *g;
|
|
||||||
|
|
||||||
memset (&route_hdr, 0, sizeof (route_hdr));
|
memset (&route_hdr, 0, sizeof (route_hdr));
|
||||||
|
|
||||||
route_hdr.rtm_family = route->family;
|
route_hdr.rtm_family = route_family;
|
||||||
route_hdr.rtm_dst_len = route->prefix;
|
route_hdr.rtm_dst_len = route_prefix;
|
||||||
route_hdr.rtm_tos = route->tos;
|
route_hdr.rtm_tos = route_tos;
|
||||||
route_hdr.rtm_table = route->table;
|
route_hdr.rtm_table = route_table;
|
||||||
|
|
||||||
msg = nlmsg_alloc_simple (RTM_DELROUTE, NLM_F_REQUEST);
|
msg = nlmsg_alloc_simple (RTM_DELROUTE, NLM_F_REQUEST);
|
||||||
ret = nlmsg_append (msg, &route_hdr, sizeof (route_hdr), NLMSG_ALIGNTO);
|
ret = nlmsg_append (msg, &route_hdr, sizeof (route_hdr), NLMSG_ALIGNTO);
|
||||||
|
@ -611,15 +630,15 @@ int routes_del (NetworkInadorHandle *handle, Route *route) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route->family == AF_INET) {
|
if (route_family == AF_INET) {
|
||||||
family_size = sizeof (struct in_addr);
|
family_size = sizeof (struct in_addr);
|
||||||
} else if (route->family == AF_INET6) {
|
} else if (route_family == AF_INET6) {
|
||||||
family_size = sizeof (struct in6_addr);
|
family_size = sizeof (struct in6_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nla_put (msg, RTA_DST, family_size, &route->dest);
|
ret = nla_put (msg, RTA_DST, family_size, dest);
|
||||||
if (route->priority != 0) {
|
if (route_priority != 0) {
|
||||||
ret |= nla_put (msg, RTA_PRIORITY, 4, &route->priority);
|
ret |= nla_put (msg, RTA_PRIORITY, 4, &route_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
@ -703,10 +722,11 @@ void routes_ask (NetworkInadorHandle *handle) {
|
||||||
r = (Route *) g->data;
|
r = (Route *) g->data;
|
||||||
if (r->for_delete == 0) continue;
|
if (r->for_delete == 0) continue;
|
||||||
|
|
||||||
|
handle->route_v4_counter--;
|
||||||
handle->route_v4_tables = f_list_remove (handle->route_v4_tables, r);
|
handle->route_v4_tables = f_list_remove (handle->route_v4_tables, r);
|
||||||
|
|
||||||
/* Notificar del evento */
|
/* Notificar del evento */
|
||||||
//manager_send_event_route_del (handle, r);
|
network_manager_trigger_route_deleted_event (handle, r);
|
||||||
|
|
||||||
/* Eliminar todos los next-hops primero */
|
/* Eliminar todos los next-hops primero */
|
||||||
f_list_free_full (r->nexthops, free);
|
f_list_free_full (r->nexthops, free);
|
||||||
|
@ -720,10 +740,11 @@ void routes_ask (NetworkInadorHandle *handle) {
|
||||||
r = (Route *) g->data;
|
r = (Route *) g->data;
|
||||||
if (r->for_delete == 0) continue;
|
if (r->for_delete == 0) continue;
|
||||||
|
|
||||||
|
handle->route_v6_counter--;
|
||||||
handle->route_v6_tables = f_list_remove (handle->route_v6_tables, r);
|
handle->route_v6_tables = f_list_remove (handle->route_v6_tables, r);
|
||||||
|
|
||||||
/* Notificar del evento */
|
/* Notificar del evento */
|
||||||
//manager_send_event_route_del (handle, r);
|
network_manager_trigger_route_deleted_event (handle, r);
|
||||||
|
|
||||||
/* Eliminar todos los next-hops primero */
|
/* Eliminar todos los next-hops primero */
|
||||||
f_list_free_full (r->nexthops, free);
|
f_list_free_full (r->nexthops, free);
|
||||||
|
@ -888,6 +909,7 @@ void routes_clean_up (NetworkInadorHandle *handle) {
|
||||||
|
|
||||||
f_list_free_full (handle->route_v4_tables, free);
|
f_list_free_full (handle->route_v4_tables, free);
|
||||||
handle->route_v4_tables = NULL;
|
handle->route_v4_tables = NULL;
|
||||||
|
handle->route_v4_counter = 0;
|
||||||
|
|
||||||
for (g = handle->route_v6_tables; g != NULL; g = g->next) {
|
for (g = handle->route_v6_tables; g != NULL; g = g->next) {
|
||||||
route = (Route *) g->data;
|
route = (Route *) g->data;
|
||||||
|
@ -898,6 +920,7 @@ void routes_clean_up (NetworkInadorHandle *handle) {
|
||||||
|
|
||||||
f_list_free_full (handle->route_v6_tables, free);
|
f_list_free_full (handle->route_v6_tables, free);
|
||||||
handle->route_v6_tables = NULL;
|
handle->route_v6_tables = NULL;
|
||||||
|
handle->route_v6_counter = 0;
|
||||||
|
|
||||||
/* FIXME: Falta liberar el nombre de las tablas */
|
/* FIXME: Falta liberar el nombre de las tablas */
|
||||||
}
|
}
|
||||||
|
|
11
lib/routes.h
11
lib/routes.h
|
@ -33,15 +33,17 @@
|
||||||
#include "flist.h"
|
#include "flist.h"
|
||||||
|
|
||||||
/* Un Next-hop */
|
/* Un Next-hop */
|
||||||
typedef struct {
|
typedef struct _RouteNH {
|
||||||
|
sa_family_t family;
|
||||||
struct_addr gw;
|
struct_addr gw;
|
||||||
|
uint8_t has_gw;
|
||||||
uint32_t out_index;
|
uint32_t out_index;
|
||||||
uint8_t nh_weight;
|
uint8_t nh_weight;
|
||||||
uint8_t nh_flags;
|
uint8_t nh_flags;
|
||||||
} RouteNH;
|
} RouteNH;
|
||||||
|
|
||||||
/* La tabla de ruteo */
|
/* La tabla de ruteo */
|
||||||
typedef struct {
|
typedef struct _Route {
|
||||||
sa_family_t family; /* AF_INET, AF_INET6 */
|
sa_family_t family; /* AF_INET, AF_INET6 */
|
||||||
|
|
||||||
uint8_t type; /* Unicast, local, broadcast, etc... */
|
uint8_t type; /* Unicast, local, broadcast, etc... */
|
||||||
|
@ -53,6 +55,7 @@ typedef struct {
|
||||||
uint8_t protocol;
|
uint8_t protocol;
|
||||||
uint8_t scope;
|
uint8_t scope;
|
||||||
|
|
||||||
|
uint8_t has_prefsrc;
|
||||||
struct_addr prefsrc;
|
struct_addr prefsrc;
|
||||||
uint32_t priority;
|
uint32_t priority;
|
||||||
|
|
||||||
|
@ -74,8 +77,8 @@ void routes_init (NetworkInadorHandle *handle);
|
||||||
void routes_ask (NetworkInadorHandle *handle);
|
void routes_ask (NetworkInadorHandle *handle);
|
||||||
int routes_receive_message_newroute (struct nl_msg *msg, void *arg);
|
int routes_receive_message_newroute (struct nl_msg *msg, void *arg);
|
||||||
int routes_receive_message_delroute (struct nl_msg *msg, void *arg);
|
int routes_receive_message_delroute (struct nl_msg *msg, void *arg);
|
||||||
int routes_add (NetworkInadorHandle *handle, Route *route);
|
int routes_add (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint8_t route_protocol, uint8_t route_scope, uint8_t route_type, void *dest, void *prefsrc, uint32_t route_priority, void *route_nexthops);
|
||||||
int routes_del (NetworkInadorHandle *handle, Route *route);
|
int routes_del (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint32_t route_priority, void *dest);
|
||||||
|
|
||||||
void route_ask_delayed_delroute (NetworkInadorHandle *handle);
|
void route_ask_delayed_delroute (NetworkInadorHandle *handle);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* setters.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 <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "network-inador-private.h"
|
||||||
|
#include "flist.h"
|
||||||
|
#include "routes.h"
|
||||||
|
#include "resolv_conf_defs.h"
|
||||||
|
|
||||||
|
void *network_inador_route_append_nexthop (void *list, uint8_t family, void *gw, uint32_t out_iface, uint8_t weight, uint8_t flags) {
|
||||||
|
RouteNH *nexthop;
|
||||||
|
int family_size;
|
||||||
|
|
||||||
|
nexthop = (RouteNH *) malloc (sizeof (RouteNH));
|
||||||
|
memset (nexthop, 0, sizeof (RouteNH));
|
||||||
|
|
||||||
|
if (family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
family_size = sizeof (struct in6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
nexthop->family = family;
|
||||||
|
if (gw != NULL) {
|
||||||
|
nexthop->has_gw = 1;
|
||||||
|
|
||||||
|
memcpy (&nexthop->gw, gw, family_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (&nexthop->out_index, &out_iface, 4);
|
||||||
|
nexthop->nh_weight = weight;
|
||||||
|
nexthop->nh_flags = flags;
|
||||||
|
|
||||||
|
list = f_list_append (list, nexthop);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_route_free_all_nexthops (void *list) {
|
||||||
|
f_list_free_full ((FList *) list, free);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *network_inador_resolvconf_append_ns_entry (void *list, int family, void *addr, int iface_index, const char *owner_prog) {
|
||||||
|
ResolvConfEntry *entry;
|
||||||
|
int family_size;
|
||||||
|
|
||||||
|
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
||||||
|
memset (entry, 0, sizeof (ResolvConfEntry));
|
||||||
|
|
||||||
|
if (family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
family_size = sizeof (struct in6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->resolv_type = RESOLV_TYPE_NAMESERVER;
|
||||||
|
entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||||
|
entry->ns_family = family;
|
||||||
|
|
||||||
|
memcpy (&entry->nameserver, addr, family_size);
|
||||||
|
inet_ntop (family, addr, entry->value, sizeof (entry->value));
|
||||||
|
|
||||||
|
entry->owner_interface_index = iface_index;
|
||||||
|
strncpy (entry->owner_prog, owner_prog, sizeof (entry->owner_prog));
|
||||||
|
|
||||||
|
list = f_list_append (list, entry);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_inador_resolvconf_free_all_entries (void *list) {
|
||||||
|
f_list_free_full ((FList *) list, free);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ sbin_PROGRAMS = network-inador resolvconf
|
||||||
network_inador_SOURCES = main.c \
|
network_inador_SOURCES = main.c \
|
||||||
manager.c manager-private.h \
|
manager.c manager-private.h \
|
||||||
manager-interfaces.c manager-interfaces.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 \
|
||||||
|
manager-routes.c manager-routes.h \
|
||||||
|
manager-resolvconf.c manager-resolvconf.h
|
||||||
|
|
||||||
resolvconf_SOURCES = resolv_conf_helper.c \
|
resolvconf_SOURCES = resolv_conf_helper.c \
|
||||||
../common/flist.c ../common/flist.h \
|
../common/flist.c ../common/flist.h \
|
||||||
|
|
|
@ -170,7 +170,7 @@ int main (int argc, char *argv[]) {
|
||||||
|
|
||||||
unix_socket_manager = manager_new (handle, 0);
|
unix_socket_manager = manager_new (handle, 0);
|
||||||
|
|
||||||
interfaces_dhcp_client_run (handle, 3, 1, 1);
|
//interfaces_dhcp_client_run (handle, 3, 1, 1);
|
||||||
/*IPAddr addr;
|
/*IPAddr addr;
|
||||||
inet_pton (AF_INET, "192.19.5.6", &addr.sin_addr);
|
inet_pton (AF_INET, "192.19.5.6", &addr.sin_addr);
|
||||||
addr.family = AF_INET;
|
addr.family = AF_INET;
|
||||||
|
|
|
@ -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 <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <linux/if.h>
|
||||||
|
#include <linux/if_addr.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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__ */
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
/* Empaquetador de datos */
|
/* Empaquetador de datos */
|
||||||
int _manager_pack_interface_info (unsigned char *buffer, Interface *iface) {
|
int _manager_pack_interface_info (unsigned char *buffer, Interface *iface) {
|
||||||
const unsigned char *iface_name;
|
const unsigned char *iface_name;
|
||||||
uint32_t u32; uint16_t u16; uint8_t u8;
|
uint32_t u32; uint16_t u16;
|
||||||
int string_len;
|
int string_len;
|
||||||
|
|
||||||
iface_name = network_inador_iface_get_name (iface);
|
iface_name = network_inador_iface_get_name (iface);
|
||||||
|
@ -223,8 +223,6 @@ void _manager_interface_handle_change_mtu (ManagerClientInfo *manager_client, un
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
uint32_t u32, new_mtu;
|
uint32_t u32, new_mtu;
|
||||||
int ret;
|
int ret;
|
||||||
int name_len;
|
|
||||||
unsigned char name[IFNAMSIZ];
|
|
||||||
|
|
||||||
if (buffer_len < 10) {
|
if (buffer_len < 10) {
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_MTU);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_MTU);
|
||||||
|
|
189
src/manager-ip.c
189
src/manager-ip.c
|
@ -143,7 +143,7 @@ void _manager_send_ipaddr_deleted (ManagerClientInfo *manager_client, IPAddr *ip
|
||||||
int family;
|
int family;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
int has_brd, has_local;
|
int has_local;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct in_addr v4;
|
struct in_addr v4;
|
||||||
|
@ -235,6 +235,12 @@ void _manager_ip_handle_clear_ips (ManagerClientInfo *manager_client, unsigned c
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
int ret;
|
int ret;
|
||||||
int c, total;
|
int c, total;
|
||||||
|
uint8_t ip_prefix;
|
||||||
|
uint8_t has_local;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} addr, local_addr;
|
||||||
|
|
||||||
if (buffer_len < 7) {
|
if (buffer_len < 7) {
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CLEAR_IP);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_CLEAR_IP);
|
||||||
|
@ -265,8 +271,19 @@ void _manager_ip_handle_clear_ips (ManagerClientInfo *manager_client, unsigned c
|
||||||
|
|
||||||
if (family != AF_UNSPEC && family != ip_family) continue;
|
if (family != AF_UNSPEC && family != ip_family) continue;
|
||||||
|
|
||||||
|
ip_prefix = network_inador_ipaddr_get_prefix (ip_addr);
|
||||||
|
|
||||||
|
network_inador_ipaddr_get_addr (ip_addr, &addr, NULL);
|
||||||
|
|
||||||
|
has_local = network_inador_ipaddr_has_local (ip_addr);
|
||||||
|
if (has_local) {
|
||||||
|
network_inador_ipaddr_get_local_addr (ip_addr, &local_addr, NULL);
|
||||||
|
} else {
|
||||||
|
memcpy (&local_addr, &addr, sizeof (local_addr));
|
||||||
|
}
|
||||||
|
|
||||||
// AQUÍ GATUNO
|
// AQUÍ GATUNO
|
||||||
//ret |= ip_address_del_ip (manager_client->manager->handle, iface->index, ip_addr);
|
ret |= ip_address_del_ip (manager_client->manager->handle, u32, ip_family, ip_prefix, has_local, &addr, &local_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
@ -277,6 +294,174 @@ void _manager_ip_handle_clear_ips (ManagerClientInfo *manager_client, unsigned c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _manager_ip_handle_add_ip (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
Interface *iface;
|
||||||
|
int ret;
|
||||||
|
int family_size, wanted_size, family;
|
||||||
|
uint32_t u32, ip_flags;
|
||||||
|
uint8_t ip_prefix, ip_scope;
|
||||||
|
uint8_t has_local, has_brd;
|
||||||
|
struct ifa_cacheinfo ip_cacheinfo;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} addr, local_addr, brd_addr;
|
||||||
|
|
||||||
|
if (buffer_len < 14) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_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_ADD_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_ADD_IP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_prefix = buffer[7];
|
||||||
|
if (family == AF_INET && (ip_prefix > 32 || ip_prefix < 1)) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_ADD_IP);
|
||||||
|
return;
|
||||||
|
} else if (family == AF_INET6 && (ip_prefix > 128 || ip_prefix < 1)) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_ADD_IP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
has_local = buffer[8] & 0x01;
|
||||||
|
has_brd = (buffer[8] & 0x02) >> 1;
|
||||||
|
|
||||||
|
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 = 22 + family_size + (family_size * has_local) + (family_size * has_brd);
|
||||||
|
if (buffer_len < wanted_size) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_IP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_scope = buffer[9];
|
||||||
|
memcpy (&ip_flags, &buffer[10], 4);
|
||||||
|
|
||||||
|
/* Copiar los timestamp de tiempo válido y preferido */
|
||||||
|
memset (&ip_cacheinfo, 0, sizeof (ip_cacheinfo));
|
||||||
|
memcpy (&ip_cacheinfo, &buffer[14], 8);
|
||||||
|
|
||||||
|
/* Copiar las direcciones */
|
||||||
|
memcpy (&addr, &buffer[22], family_size);
|
||||||
|
wanted_size = 22 + family_size;
|
||||||
|
|
||||||
|
if (has_local) {
|
||||||
|
memcpy (&local_addr, &buffer[wanted_size], family_size);
|
||||||
|
wanted_size += family_size;
|
||||||
|
} else {
|
||||||
|
memcpy (&local_addr, &addr, family_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_brd) {
|
||||||
|
memcpy (&brd_addr, &buffer[wanted_size], family_size);
|
||||||
|
wanted_size += family_size;
|
||||||
|
} else {
|
||||||
|
memset (&brd_addr, 0, sizeof (brd_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ip_address_add_ip (manager_client->manager->handle, u32, family, ip_prefix, has_local, has_brd, ip_scope, ip_flags, &ip_cacheinfo, &addr, &local_addr, &brd_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_ip_handle_del_ip (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
Interface *iface;
|
||||||
|
int ret;
|
||||||
|
int family_size, wanted_size, family;
|
||||||
|
uint32_t u32;
|
||||||
|
uint8_t ip_prefix;
|
||||||
|
uint8_t has_local;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} addr, local_addr;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_REMOVE_IP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_prefix = buffer[7];
|
||||||
|
if (family == AF_INET && (ip_prefix > 32 || ip_prefix < 1)) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_REMOVE_IP);
|
||||||
|
return;
|
||||||
|
} else if (family == AF_INET6 && (ip_prefix > 128 || ip_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copiar las direcciones */
|
||||||
|
memcpy (&addr, &buffer[9], family_size);
|
||||||
|
wanted_size = 9 + family_size;
|
||||||
|
|
||||||
|
if (has_local) {
|
||||||
|
memcpy (&local_addr, &buffer[wanted_size], family_size);
|
||||||
|
wanted_size += family_size;
|
||||||
|
} else {
|
||||||
|
memcpy (&local_addr, &addr, family_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ip_address_del_ip (manager_client->manager->handle, u32, family, ip_prefix, has_local, &addr, &local_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Los eventos que vienen desde la librería */
|
/* Los eventos que vienen desde la librería */
|
||||||
void _manager_ip_added_event_cb (NetworkInadorHandle *handle, IPAddr *ip_addr, void *data) {
|
void _manager_ip_added_event_cb (NetworkInadorHandle *handle, IPAddr *ip_addr, void *data) {
|
||||||
Manager *manager = (Manager *) data;
|
Manager *manager = (Manager *) data;
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#include "network-inador-manager.h"
|
#include "network-inador-manager.h"
|
||||||
|
|
||||||
void _manager_ip_handle_list_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
void _manager_ip_handle_list_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
void _manager_ip_handle_clear_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
void _manager_ip_handle_add_ip (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
void _manager_ip_handle_del_ip (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
|
||||||
void _manager_ip_added_event_cb (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
void _manager_ip_added_event_cb (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
||||||
void _manager_ip_deleted_event_cb (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
void _manager_ip_deleted_event_cb (NetworkInadorHandle *handle, IPAddr *addr, void *data);
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* manager-resolvconf.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 <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "manager-private.h"
|
||||||
|
#include "network-inador-public.h"
|
||||||
|
#include "network-inador-manager.h"
|
||||||
|
|
||||||
|
void _manager_resolvconf_handle_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;
|
||||||
|
void *resolv_entries;
|
||||||
|
int entries_count;
|
||||||
|
|
||||||
|
int ns_count;
|
||||||
|
int search_count;
|
||||||
|
int g, pos, ns_pos;
|
||||||
|
int family;
|
||||||
|
uint32_t iface_index;
|
||||||
|
Interface *iface;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} addr;
|
||||||
|
|
||||||
|
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 = network_inador_get_iface_by_name (manager_client->manager->handle, iface_name);
|
||||||
|
if (iface == NULL) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
iface_index = network_inador_iface_get_index (iface);
|
||||||
|
|
||||||
|
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 */
|
||||||
|
pos = ns_pos;
|
||||||
|
resolv_entries = NULL;
|
||||||
|
for (g = 0; g < ns_count; g++) {
|
||||||
|
family = buffer[pos];
|
||||||
|
pos++; /* El byte de la familia */
|
||||||
|
|
||||||
|
wanted = (family == AF_INET) ? 4 : 16;
|
||||||
|
memcpy (&addr, &buffer[pos], wanted);
|
||||||
|
pos += wanted;
|
||||||
|
|
||||||
|
resolv_entries = network_inador_resolvconf_append_ns_entry (resolv_entries, family, &addr, iface_index, prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolv_manager_process_resolvconf_entries (manager_client->manager->handle, resolv_entries);
|
||||||
|
network_inador_resolvconf_free_all_entries (resolv_entries);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* manager-resolvconf.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_RESOLVCONF_H__
|
||||||
|
#define __MANAGER_RESOLVCONF_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "manager-private.h"
|
||||||
|
#include "network-inador-public.h"
|
||||||
|
#include "network-inador-manager.h"
|
||||||
|
|
||||||
|
void _manager_resolvconf_handle_feed (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
|
||||||
|
#endif /* __MANAGER_RESOLVCONF_H__ */
|
||||||
|
|
|
@ -0,0 +1,501 @@
|
||||||
|
/*
|
||||||
|
* manager-routes.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 <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <linux/if.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "manager-private.h"
|
||||||
|
#include "network-inador-public.h"
|
||||||
|
#include "network-inador-manager.h"
|
||||||
|
|
||||||
|
/* Empaquetador de datos */
|
||||||
|
int _manager_pack_route_info (unsigned char *buffer, Route *route) {
|
||||||
|
uint8_t route_family, route_type, route_prefix;
|
||||||
|
uint8_t route_protocol, route_tos, route_scope;
|
||||||
|
uint8_t has_prefsrc, has_gw;
|
||||||
|
uint32_t route_table, route_priority, out_index;
|
||||||
|
int family_size = 0;
|
||||||
|
int num_nexthops, g, pos;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} dest, prefsrc, gw;
|
||||||
|
RouteNH *nexthop;
|
||||||
|
|
||||||
|
route_family = network_inador_route_get_family (route);
|
||||||
|
|
||||||
|
if (route_family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (route_family == AF_INET6) {
|
||||||
|
family_size = sizeof (struct in6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
route_type = network_inador_route_get_type (route);
|
||||||
|
route_table = network_inador_route_get_table (route);
|
||||||
|
route_prefix = network_inador_route_get_prefix (route);
|
||||||
|
route_protocol = network_inador_route_get_protocol (route);
|
||||||
|
route_tos = network_inador_route_get_tos (route);
|
||||||
|
route_scope = network_inador_route_get_scope (route);
|
||||||
|
has_prefsrc = network_inador_route_has_prefsrc (route);
|
||||||
|
route_priority = network_inador_route_get_priority (route);
|
||||||
|
|
||||||
|
buffer[0] = route_family;
|
||||||
|
buffer[1] = route_type;
|
||||||
|
memcpy (&buffer[2], &route_table, 4);
|
||||||
|
buffer[6] = route_prefix;
|
||||||
|
buffer[7] = route_protocol;
|
||||||
|
buffer[8] = route_tos;
|
||||||
|
buffer[9] = route_scope;
|
||||||
|
buffer[10] = 0;
|
||||||
|
if (has_prefsrc) {
|
||||||
|
/* Tiene pref-src */
|
||||||
|
buffer[10] |= 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_nexthops = network_inador_route_get_num_nexthops (route);
|
||||||
|
|
||||||
|
buffer[11] = num_nexthops;
|
||||||
|
memcpy (&buffer[12], &route_priority, 4);
|
||||||
|
|
||||||
|
/* Copiar la Ruta de destino */
|
||||||
|
network_inador_route_get_dest (route, &dest, NULL);
|
||||||
|
memcpy (&buffer[16], &dest, family_size);
|
||||||
|
pos = 16 + family_size;
|
||||||
|
|
||||||
|
/* Copiar el pref-src, si lo tiene */
|
||||||
|
if (has_prefsrc) {
|
||||||
|
network_inador_route_get_prefsrc (route, &prefsrc, NULL);
|
||||||
|
memcpy (&buffer[pos], &prefsrc, family_size);
|
||||||
|
pos += family_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Recorrer todos los nexthops */
|
||||||
|
for (g = 0; g < num_nexthops; g++) {
|
||||||
|
nexthop = network_inador_route_get_nexthop_by_index (route, g);
|
||||||
|
|
||||||
|
buffer[pos] = 0;
|
||||||
|
has_gw = network_inador_nexthop_has_gw (nexthop);
|
||||||
|
if (has_gw) {
|
||||||
|
buffer[pos] |= 0x01;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
buffer[pos++] = network_inador_nexthop_get_flags (nexthop); /* Flags next-hop */
|
||||||
|
buffer[pos++] = network_inador_nexthop_get_weight (nexthop); /* Weight next-hop */
|
||||||
|
|
||||||
|
buffer[pos++] = 0; /* Omitimos un byte faltante */
|
||||||
|
|
||||||
|
/* La interfaz de salida */
|
||||||
|
out_index = network_inador_nexthop_get_out_index (nexthop);
|
||||||
|
memcpy (&buffer[pos], &out_index, 4);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
if (has_gw) {
|
||||||
|
network_inador_nexthop_get_gw (nexthop, &gw, NULL);
|
||||||
|
memcpy (&buffer[pos], &gw, family_size);
|
||||||
|
pos += family_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Los comandos que verdaderamente envian */
|
||||||
|
void _manager_send_route (ManagerClientInfo *manager_client, Route *route, uint8_t is_event) {
|
||||||
|
unsigned char buffer[100];
|
||||||
|
int size;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = 2 + _manager_pack_route_info (&buffer[2], route);
|
||||||
|
|
||||||
|
send (manager_client->fd, buffer, size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _manager_send_route_deleted (ManagerClientInfo *manager_client, Route *route) {
|
||||||
|
unsigned char buffer[80];
|
||||||
|
int family_size = 0;
|
||||||
|
uint8_t route_family;
|
||||||
|
uint32_t route_table, route_priority;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} dest;
|
||||||
|
|
||||||
|
buffer[0] = NET_INADOR_TYPE_EVENT;
|
||||||
|
buffer[1] = NET_INADOR_EVENT_ROUTE_REMOVED;
|
||||||
|
|
||||||
|
route_family = network_inador_route_get_family (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);
|
||||||
|
}
|
||||||
|
|
||||||
|
route_table = network_inador_route_get_table (route);
|
||||||
|
route_priority = network_inador_route_get_priority (route);
|
||||||
|
|
||||||
|
buffer[2] = route_family;
|
||||||
|
buffer[3] = network_inador_route_get_tos (route);
|
||||||
|
memcpy (&buffer[4], &route_table, 4);
|
||||||
|
buffer[8] = network_inador_route_get_prefix (route);
|
||||||
|
memcpy (&buffer[9], &route_priority, 4);
|
||||||
|
|
||||||
|
network_inador_route_get_dest (route, &dest, NULL);
|
||||||
|
/* Copiar la Ruta de destino */
|
||||||
|
memcpy (&buffer[13], &dest, family_size);
|
||||||
|
|
||||||
|
send (manager_client->fd, buffer, 13 + family_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _manager_route_handle_list_routes (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
int family;
|
||||||
|
Route *route;
|
||||||
|
uint32_t wanted_table, route_table;
|
||||||
|
int g, route_count;
|
||||||
|
|
||||||
|
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 (&wanted_table, &buffer[2], 4);
|
||||||
|
|
||||||
|
if (family == AF_UNSPEC || family == AF_INET) {
|
||||||
|
route_count = network_inador_get_routes_count (manager_client->manager->handle, AF_INET);
|
||||||
|
for (g = 0; g < route_count; g++) {
|
||||||
|
route = network_inador_get_route_by_index (manager_client->manager->handle, AF_INET, g);
|
||||||
|
|
||||||
|
route_table = network_inador_route_get_table (route);
|
||||||
|
if (wanted_table != 0 && route_table != wanted_table) continue;
|
||||||
|
|
||||||
|
_manager_send_route (manager_client, route, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (family == AF_UNSPEC || family == AF_INET6) {
|
||||||
|
route_count = network_inador_get_routes_count (manager_client->manager->handle, AF_INET6);
|
||||||
|
for (g = 0; g < route_count; g++) {
|
||||||
|
route = network_inador_get_route_by_index (manager_client->manager->handle, AF_INET6, g);
|
||||||
|
|
||||||
|
route_table = network_inador_route_get_table (route);
|
||||||
|
if (wanted_table != 0 && route_table != wanted_table) continue;
|
||||||
|
|
||||||
|
_manager_send_route (manager_client, route, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_ROUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _manager_route_handle_add_route (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
int ret, has_prefsrc, nh_has_gw;
|
||||||
|
uint8_t family, route_type, route_prefix, route_protocol;
|
||||||
|
uint8_t route_tos, route_scope;
|
||||||
|
uint8_t nh_flags, nh_weight;
|
||||||
|
int family_size, wanted_size;
|
||||||
|
uint32_t out_iface;
|
||||||
|
uint32_t route_table, route_priority;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} dest, prefsrc, nh_gw;
|
||||||
|
int g, rem, pos;
|
||||||
|
void *nexthops;
|
||||||
|
|
||||||
|
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 < (8 + family_size)) {
|
||||||
|
/* Tiene GW */
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_ROUTE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g--;
|
||||||
|
if (buffer[pos] & 0x01) {
|
||||||
|
rem -= (8 + family_size);
|
||||||
|
pos += (8 + family_size);
|
||||||
|
} else {
|
||||||
|
rem -= 8;
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ejecutar el parsing */
|
||||||
|
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 (&dest, &buffer[18], family_size);
|
||||||
|
pos = 18 + family_size;
|
||||||
|
if (has_prefsrc) {
|
||||||
|
memcpy (&prefsrc, &buffer[pos], family_size);
|
||||||
|
pos += family_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recorrer cada next-hop */
|
||||||
|
g = buffer[13];
|
||||||
|
nexthops = NULL;
|
||||||
|
while (g > 0) {
|
||||||
|
nh_has_gw = 0;
|
||||||
|
nh_flags = buffer[pos + 1];
|
||||||
|
nh_weight = buffer[pos + 2];
|
||||||
|
memcpy (&out_iface, &buffer[pos + 4], 4);
|
||||||
|
|
||||||
|
if (buffer[pos] & 0x01) {
|
||||||
|
nh_has_gw = 1;
|
||||||
|
/* Tiene GW */
|
||||||
|
memcpy (&nh_gw, &buffer[pos + 8], family_size);
|
||||||
|
pos += (8 + family_size);
|
||||||
|
} else {
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
nexthops = network_inador_route_append_nexthop (nexthops, family, (nh_has_gw == 0 ? NULL : &nh_gw), out_iface, nh_weight, nh_flags);
|
||||||
|
g--;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = routes_add (manager_client->manager->handle, family, route_prefix, route_tos, route_table, route_protocol, route_scope, route_type, &dest, (has_prefsrc == 0 ? NULL : &prefsrc), route_priority, nexthops);
|
||||||
|
|
||||||
|
network_inador_route_free_all_nexthops (nexthops);
|
||||||
|
nexthops = NULL;
|
||||||
|
|
||||||
|
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_route_handle_del_route (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
int ret;
|
||||||
|
uint8_t family, route_prefix;
|
||||||
|
uint8_t route_tos;
|
||||||
|
int family_size, wanted_size;
|
||||||
|
uint32_t route_table, route_priority;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} dest;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ejecutar el parsing */
|
||||||
|
route_tos = buffer[3];
|
||||||
|
memcpy (&route_table, &buffer[4], 4);
|
||||||
|
route_prefix = buffer[8];
|
||||||
|
memcpy (&route_priority, &buffer[9], 4);
|
||||||
|
|
||||||
|
/* Copiar la dirección de destino */
|
||||||
|
memcpy (&dest, &buffer[13], family_size);
|
||||||
|
|
||||||
|
ret = routes_del (manager_client->manager->handle, family, route_prefix, route_tos, route_table, route_priority, &dest);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Los eventos que vienen desde la librería */
|
||||||
|
void _manager_route_added_event_cb (NetworkInadorHandle *handle, Route *route, void *data) {
|
||||||
|
Manager *manager = (Manager *) data;
|
||||||
|
GList *g;
|
||||||
|
ManagerClientInfo *manager_client;
|
||||||
|
uint8_t family, prefix;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} dest;
|
||||||
|
uint32_t table;
|
||||||
|
char buffer_ip[200];
|
||||||
|
|
||||||
|
family = network_inador_route_get_family (route);
|
||||||
|
table = network_inador_route_get_table (route);
|
||||||
|
prefix = network_inador_route_get_prefix (route);
|
||||||
|
network_inador_route_get_dest (route, &dest, NULL);
|
||||||
|
|
||||||
|
inet_ntop (family, &dest, buffer_ip, sizeof (buffer_ip));
|
||||||
|
|
||||||
|
printf ("___ MANAGER ___ Informando ruta agregada: %s/%i [Tabla %i]\n", buffer_ip, prefix, table);
|
||||||
|
|
||||||
|
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_ROUTES) {
|
||||||
|
printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd);
|
||||||
|
_manager_send_route (manager_client, route, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _manager_route_updated_event_cb (NetworkInadorHandle *handle, Route *route, void *data) {
|
||||||
|
Manager *manager = (Manager *) data;
|
||||||
|
GList *g;
|
||||||
|
ManagerClientInfo *manager_client;
|
||||||
|
uint8_t family, prefix;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} dest;
|
||||||
|
uint32_t table;
|
||||||
|
char buffer_ip[200];
|
||||||
|
|
||||||
|
family = network_inador_route_get_family (route);
|
||||||
|
table = network_inador_route_get_table (route);
|
||||||
|
prefix = network_inador_route_get_prefix (route);
|
||||||
|
network_inador_route_get_dest (route, &dest, NULL);
|
||||||
|
|
||||||
|
inet_ntop (family, &dest, buffer_ip, sizeof (buffer_ip));
|
||||||
|
|
||||||
|
printf ("___ MANAGER ___ Informando ruta actualizada: %s/%i [Tabla %i]\n", buffer_ip, prefix, table);
|
||||||
|
|
||||||
|
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_ROUTES) {
|
||||||
|
printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd);
|
||||||
|
_manager_send_route (manager_client, route, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _manager_route_deleted_event_cb (NetworkInadorHandle *handle, Route *route, void *data) {
|
||||||
|
Manager *manager = (Manager *) data;
|
||||||
|
GList *g;
|
||||||
|
ManagerClientInfo *manager_client;
|
||||||
|
uint8_t family, prefix;
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} dest;
|
||||||
|
uint32_t table;
|
||||||
|
char buffer_ip[200];
|
||||||
|
|
||||||
|
family = network_inador_route_get_family (route);
|
||||||
|
table = network_inador_route_get_table (route);
|
||||||
|
prefix = network_inador_route_get_prefix (route);
|
||||||
|
network_inador_route_get_dest (route, &dest, NULL);
|
||||||
|
|
||||||
|
inet_ntop (family, &dest, buffer_ip, sizeof (buffer_ip));
|
||||||
|
|
||||||
|
printf ("___ MANAGER ___ Informando ruta eliminada: %s/%i [Tabla %i]\n", buffer_ip, prefix, table);
|
||||||
|
|
||||||
|
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_ROUTES) {
|
||||||
|
printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd);
|
||||||
|
_manager_send_route_deleted (manager_client, route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* manager-routes.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_ROUTES_H__
|
||||||
|
#define __MANAGER_ROUTES_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "manager-private.h"
|
||||||
|
#include "network-inador-public.h"
|
||||||
|
#include "network-inador-manager.h"
|
||||||
|
|
||||||
|
void _manager_route_handle_list_routes (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
void _manager_route_handle_add_route (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
void _manager_route_handle_del_route (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
|
||||||
|
|
||||||
|
void _manager_route_added_event_cb (NetworkInadorHandle *handle, Route *route, void *data);
|
||||||
|
void _manager_route_updated_event_cb (NetworkInadorHandle *handle, Route *route, void *data);
|
||||||
|
void _manager_route_deleted_event_cb (NetworkInadorHandle *handle, Route *route, void *data);
|
||||||
|
|
||||||
|
#endif /* __MANAGER_ROUTES_H__ */
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
|
|
||||||
#include "manager-interfaces.h"
|
#include "manager-interfaces.h"
|
||||||
#include "manager-ip.h"
|
#include "manager-ip.h"
|
||||||
|
#include "manager-bridge.h"
|
||||||
|
#include "manager-routes.h"
|
||||||
|
#include "manager-resolvconf.h"
|
||||||
|
|
||||||
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||||
|
|
||||||
|
@ -102,7 +105,6 @@ static gboolean _manager_on_client_data_recv (GIOChannel *source, GIOCondition c
|
||||||
ManagerClientInfo *manager_client = (ManagerClientInfo *) data;
|
ManagerClientInfo *manager_client = (ManagerClientInfo *) data;
|
||||||
Manager *manager = manager_client->manager;
|
Manager *manager = manager_client->manager;
|
||||||
int type, command;
|
int type, command;
|
||||||
Interface *iface;
|
|
||||||
int g;
|
int g;
|
||||||
|
|
||||||
unsigned char buffer[8192];
|
unsigned char buffer[8192];
|
||||||
|
@ -164,29 +166,28 @@ static gboolean _manager_on_client_data_recv (GIOChannel *source, GIOCondition c
|
||||||
case NET_INADOR_COMMAND_LIST_IP:
|
case NET_INADOR_COMMAND_LIST_IP:
|
||||||
_manager_ip_handle_list_ips (manager_client, buffer, bytes);
|
_manager_ip_handle_list_ips (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
/*case NET_INADOR_COMMAND_CLEAR_IP:
|
case NET_INADOR_COMMAND_CLEAR_IP:
|
||||||
_manager_execute_clear_ips (manager_client, buffer, bytes);
|
_manager_ip_handle_clear_ips (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_ADD_IP:
|
case NET_INADOR_COMMAND_ADD_IP:
|
||||||
_manager_execute_add_ip (manager_client, buffer, bytes);
|
_manager_ip_handle_add_ip (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_REMOVE_IP:
|
case NET_INADOR_COMMAND_REMOVE_IP:
|
||||||
_manager_execute_delete_ip (manager_client, buffer, bytes);
|
_manager_ip_handle_del_ip (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
case NET_INADOR_COMMAND_SET_EVENT_MASK:
|
case NET_INADOR_COMMAND_SET_EVENT_MASK:
|
||||||
_manager_handle_set_event_mask (manager_client, buffer, bytes);
|
_manager_handle_set_event_mask (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
/*case NET_INADOR_COMMAND_CREATE_BRIDGE:
|
case NET_INADOR_COMMAND_CREATE_BRIDGE:
|
||||||
_manager_execute_create_bridge (manager_client, buffer, bytes);
|
_manager_bridge_handle_create (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_CLEAR_MASTER:
|
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;
|
break;
|
||||||
case NET_INADOR_COMMAND_SET_MASTER:
|
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;
|
break;
|
||||||
case NET_INADOR_COMMAND_DHCP_CLIENT_FEED:
|
/*case NET_INADOR_COMMAND_DHCP_CLIENT_FEED:
|
||||||
_manager_execute_dhcp_client_feed (manager_client, buffer, bytes);
|
_manager_execute_dhcp_client_feed (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_RUN_DHCP:
|
case NET_INADOR_COMMAND_RUN_DHCP:
|
||||||
|
@ -197,23 +198,23 @@ static gboolean _manager_on_client_data_recv (GIOChannel *source, GIOCondition c
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_GET_DHCP_STATUS:
|
case NET_INADOR_COMMAND_GET_DHCP_STATUS:
|
||||||
_manager_execute_dhcp_get_status (manager_client, buffer, bytes);
|
_manager_execute_dhcp_get_status (manager_client, buffer, bytes);
|
||||||
break;
|
break;*/
|
||||||
case NET_INADOR_COMMAND_LIST_ROUTES:
|
case NET_INADOR_COMMAND_LIST_ROUTES:
|
||||||
_manager_send_list_routes (manager_client, buffer, bytes);
|
_manager_route_handle_list_routes (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_ADD_ROUTE:
|
case NET_INADOR_COMMAND_ADD_ROUTE:
|
||||||
_manager_execute_add_route (manager_client, buffer, bytes);
|
_manager_route_handle_add_route (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_REMOVE_ROUTE:
|
case NET_INADOR_COMMAND_REMOVE_ROUTE:
|
||||||
_manager_execute_del_route (manager_client, buffer, bytes);
|
_manager_route_handle_del_route (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_LIST_ROUTE_TABLES:
|
/*case NET_INADOR_COMMAND_LIST_ROUTE_TABLES:
|
||||||
_manager_send_list_route_tables (manager_client, buffer, bytes);
|
_manager_send_list_route_tables (manager_client, buffer, bytes);
|
||||||
break;
|
break;*/
|
||||||
case NET_INADOR_COMMAND_RESOLVCONF_FEED:
|
case NET_INADOR_COMMAND_RESOLVCONF_FEED:
|
||||||
_manager_execute_resolvconf_feed (manager_client, buffer, bytes);
|
_manager_resolvconf_handle_feed (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_RESOLVCONF_REMOVE:
|
/*case NET_INADOR_COMMAND_RESOLVCONF_REMOVE:
|
||||||
_manager_execute_resolvconf_remove (manager_client, buffer, bytes);
|
_manager_execute_resolvconf_remove (manager_client, buffer, bytes);
|
||||||
break;*/
|
break;*/
|
||||||
default:
|
default:
|
||||||
|
@ -320,12 +321,18 @@ Manager * manager_new (NetworkInadorHandle *handle, int type) {
|
||||||
|
|
||||||
/* Agregar vigilancias aquí */
|
/* Agregar vigilancias aquí */
|
||||||
network_manager_add_watch_dhcp (handle, _manager_dhcp_event_cb, manager);
|
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_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_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_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_added (handle, _manager_ip_added_event_cb, manager);
|
||||||
network_manager_add_watch_ip_deleted (handle, _manager_ip_deleted_event_cb, manager);
|
network_manager_add_watch_ip_deleted (handle, _manager_ip_deleted_event_cb, manager);
|
||||||
|
|
||||||
|
network_manager_add_watch_route_added (handle, _manager_route_added_event_cb, manager);
|
||||||
|
network_manager_add_watch_route_updated (handle, _manager_route_updated_event_cb, manager);
|
||||||
|
network_manager_add_watch_route_deleted (handle, _manager_route_deleted_event_cb, manager);
|
||||||
|
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue