Compare commits

..

3 Commits

Author SHA1 Message Date
Félix Arreola Rodríguez dab460efb6 Reorganizo el código para separar el network-inador como librería. 2024-01-09 23:02:39 -06:00
Félix Arreola Rodríguez 717259e86b Recojo información de IPv6 extra en la interfaz. 2024-01-08 13:38:06 -06:00
Félix Arreola Rodríguez a4f9598531 Agrego interfaces veth. 2024-01-07 19:16:40 -06:00
56 changed files with 2594 additions and 1183 deletions

4
.gitignore vendored
View File

@ -19,8 +19,12 @@ config.log
config.status
.deps
src/network-inador
lib/libnetworkinador.la
lib/network-inador.pc
src/dhcpc/nidhcpc
*.o
*.lo
.libs
stamp-h1
*~

View File

@ -1,4 +1,4 @@
SUBDIRS = src client-gtk po
SUBDIRS = common lib src client-gtk po
ACLOCAL_AMFLAGS = -I m4

View File

@ -20,7 +20,7 @@ inador_gtk_client_SOURCES = main.c \
#inador_gtk_client_CPPFLAGS = -DGAMEDATA_DIR=\"$(gamedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
inador_gtk_client_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
inador_gtk_client_CFLAGS = $(GTK_CFLAGS) $(AM_CFLAGS)
inador_gtk_client_CFLAGS = -I$(top_srcdir)/lib $(GTK_CFLAGS) $(AM_CFLAGS)
inador_gtk_client_LDADD = $(GTK_LIBS)
LDADD = $(LIBINTL)

View File

@ -7,7 +7,7 @@
#include "ni-window-interface.h"
#include "ni-window-route.h"
#include "../src/link-types.h"
#include "network-inador-link-types.h"
enum {
COL_IFACE_OBJECT,

View File

@ -33,7 +33,7 @@
#include "ni-interface.h"
#include "ni-interface-filter.h"
#include "../src/link-types.h"
#include "network-inador-link-types.h"
enum {
COL_INTERFACE_CHOOSER_NAME,

View File

@ -38,7 +38,7 @@
#include "ni-interface.h"
#include "ni-ip.h"
#include "ni-add-ip-dialog.h"
#include "../src/link-types.h"
#include "network-inador-link-types.h"
#include "ni-interface-chooser-dialog.h"
#include "ni-interface-filter.h"

12
common/Makefile.am 100644
View File

@ -0,0 +1,12 @@
#noinst_LIBRARIES = libnicommon.a
#libnicommon_a_SOURCES = flist.c flist.h
# resolv_conf_parser.c resolv_conf_parser.h
# utils.c utils.h
EXTRA_DIST = flist.c flist.h \
resolv_conf_parser.c resolv_conf_parser.h \
utils.c utils.h
#libnicommon_a_CPPFLAGS = -DSHAREDATA_DIR=\"$(sharedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
#libnicommon_a_CFLAGS = -I$(top_srcdir)/lib $(AM_CFLAGS)
#LDADD = $(LIBINTL)

File diff suppressed because it is too large Load Diff

150
common/flist.h 100644
View File

@ -0,0 +1,150 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __F_LIST_H__
#define __F_LIST_H__
#define F_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
typedef void (*FDestroyNotify) (void * data);
typedef void (*FFunc) (void * data, void * user_data);
typedef int (*FCompareDataFunc) (const void * a, const void * b, void * user_data);
typedef int (*FCompareFunc) (const void * a, const void * b);
typedef void * (*FCopyFunc) (const void * src, void * data);
typedef struct _FList FList;
struct _FList
{
void * data;
FList *next;
FList *prev;
};
/* Doubly linked lists
*/
FList* f_list_alloc (void) F_GNUC_WARN_UNUSED_RESULT;
void f_list_free (FList *list);
void f_list_free_1 (FList *list);
#define f_list_free1 f_list_free_1
void f_list_free_full (FList *list,
FDestroyNotify free_func);
FList* f_list_append (FList *list,
void * data) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_prepend (FList *list,
void * data) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_insert (FList *list,
void * data,
int position) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_insert_sorted (FList *list,
void * data,
FCompareFunc func) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_insert_sorted_with_data (FList *list,
void * data,
FCompareDataFunc func,
void * user_data) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_insert_before (FList *list,
FList *sibling,
void * data) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_concat (FList *list1,
FList *list2) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_remove (FList *list,
const void * data) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_remove_all (FList *list,
const void * data) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_remove_link (FList *list,
FList *llink) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_delete_link (FList *list,
FList *link_) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_reverse (FList *list) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_copy (FList *list) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_copy_deep (FList *list,
FCopyFunc func,
void * user_data) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_nth (FList *list,
unsigned int n);
FList* f_list_nth_prev (FList *list,
unsigned int n);
FList* f_list_find (FList *list,
const void * data);
FList* f_list_find_custom (FList *list,
const void * data,
FCompareFunc func);
int f_list_position (FList *list,
FList *llink);
int f_list_index (FList *list,
const void * data);
FList* f_list_last (FList *list);
FList* f_list_first (FList *list);
unsigned int f_list_length (FList *list);
void f_list_foreach (FList *list,
FFunc func,
void * user_data);
FList* f_list_sort (FList *list,
FCompareFunc compare_func) F_GNUC_WARN_UNUSED_RESULT;
FList* f_list_sort_with_data (FList *list,
FCompareDataFunc compare_func,
void * user_data) F_GNUC_WARN_UNUSED_RESULT;
void * f_list_nth_data (FList *list,
unsigned int n);
#define f_list_previous(list) ((list) ? (((FList *)(list))->prev) : NULL)
#define f_list_next(list) ((list) ? (((FList *)(list))->next) : NULL)
#endif /* __F_LIST_H__ */

View File

@ -0,0 +1,109 @@
#ifndef __NETWOR_INADOR_MANAGER_H__
#define __NETWOR_INADOR_MANAGER_H__
enum {
NET_INADOR_TYPE_COMMAND = 1,
NET_INADOR_TYPE_RESPONSE = 2,
NET_INADOR_TYPE_RESPONSE_ERROR = 3,
NET_INADOR_TYPE_RESPONSE_LISTING_END = 4,
NET_INADOR_TYPE_EVENT = 16
};
/* Lista de eventos */
#define NET_INADOR_EVENT_MASK_INTERFACES 0x01
#define NET_INADOR_EVENT_MASK_IP 0x02
#define NET_INADOR_EVENT_MASK_DHCP_STATUS 0x04
#define NET_INADOR_EVENT_MASK_ROUTES 0x08
#define NET_INADOR_EVENT_MASK_ROUTE_TABLES 0x10
enum {
NET_INADOR_COMMAND_LIST_IFACES = 1,
NET_INADOR_COMMAND_GET_IFACE,
NET_INADOR_COMMAND_IFACE_UP,
NET_INADOR_COMMAND_IFACE_DOWN,
NET_INADOR_COMMAND_IFACE_CHANGE_NAME,
NET_INADOR_COMMAND_IFACE_CHANGE_MTU,
NET_INADOR_COMMAND_CREATE_BRIDGE = 16,
NET_INADOR_COMMAND_CLEAR_MASTER,
NET_INADOR_COMMAND_SET_MASTER,
NET_INADOR_COMMAND_LIST_IP = 32,
NET_INADOR_COMMAND_CLEAR_IP,
NET_INADOR_COMMAND_ADD_IP,
NET_INADOR_COMMAND_REMOVE_IP,
NET_INADOR_COMMAND_RUN_DHCP = 48,
NET_INADOR_COMMAND_STOP_DHCP,
NET_INADOR_COMMAND_GET_DHCP_STATUS,
NET_INADOR_COMMAND_LIST_ROUTES = 64,
NET_INADOR_COMMAND_ADD_ROUTE,
NET_INADOR_COMMAND_REMOVE_ROUTE,
NET_INADOR_COMMAND_LIST_ROUTE_TABLES = 72,
NET_INADOR_COMMAND_SET_EVENT_MASK = 192,
/* Los siguientes comandos son para uso interno */
NET_INADOR_COMMAND_DHCP_CLIENT_FEED = 224,
NET_INADOR_COMMAND_RESOLVCONF_FEED = 225,
NET_INADOR_COMMAND_RESOLVCONF_REMOVE = 226,
};
enum {
NET_INADOR_ERROR_UNKNOWN = 0,
NET_INADOR_ERROR_WRONG_COMMAND,
NET_INADOR_ERROR_INCOMPLETE_REQUEST,
NET_INADOR_ERROR_INVALID_IFACE_INDEX,
NET_INADOR_ERROR_INVALID_FAMILY,
NET_INADOR_ERROR_INVALID_VALUE,
NET_INADOR_ERROR_NOT_EXECUTED,
NET_INADOR_ERROR_BAD_STRING,
};
enum {
NET_INADOR_EVENT_IFACE_ADDED = 2,
NET_INADOR_EVENT_IPADDR_ADDED,
NET_INADOR_EVENT_IFACE_REMOVED,
NET_INADOR_EVENT_IPADDR_REMOVED,
NET_INADOR_EVENT_DHCP_STATUS = 6,
NET_INADOR_EVENT_ROUTE_ADDED = 10,
NET_INADOR_EVENT_ROUTE_REMOVED,
NET_INADOR_EVENT_ROUTE_TABLE_ADDED = 14,
NET_INADOR_EVENT_ROUTE_TABLE_REMOVED,
};
enum {
NET_INADOR_RESPONSE_EXECUTED = 1,
NET_INADOR_RESPONSE_IFACE = 2,
NET_INADOR_RESPONSE_IPADDR,
NET_INADOR_RESPONSE_DHCP_STATUS = 6,
NET_INADOR_RESPONSE_ROUTE = 10,
NET_INADOR_RESPONSE_ROUTE_TABLE = 14
};
enum {
NET_INADOR_DHCP_STATUS_SELECTING = 1,
NET_INADOR_DHCP_STATUS_BOUND,
NET_INADOR_DHCP_STATUS_RENEWED,
NET_INADOR_DHCP_STATUS_EXPIRED,
NET_INADOR_DHCP_STATUS_FAILED,
};
#endif /* __NETWOR_INADOR_MANAGER_H__ */

View File

@ -28,11 +28,7 @@
#include "resolv_conf_defs.h"
#include "resolv_conf_parser.h"
#include "utils.h"
#ifdef STAND_ALONE_RESOLV_CONF_HELPER_BUILD
#include "glist.h"
#else
#include "common.h"
#endif
#include "flist.h"
static const char *resolv_conf_keywords[NUM_RESOLV_TYPES] = {
"nameserver",
@ -88,8 +84,8 @@ int resolv_conf_parse_line (const char *line, int *ns_family, struct_addr *names
return -1;
}
GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value, int skip_tagged) {
GList *g;
FList * resolv_parser_search_entry (FList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value, int skip_tagged) {
FList *g;
ResolvConfEntry *entry;
g = all_entries;
@ -133,10 +129,10 @@ GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, c
return NULL;
}
GList * resolv_parser_parse_local_file (GList *all_entries, FILE *fd, int origin) {
FList * resolv_parser_parse_local_file (FList *all_entries, FILE *fd, int origin) {
char buffer[8192], value[2048];
ResolvConfEntry *entry = NULL;
GList *pos, *next;
FList *pos, *next;
int g, len;
struct_addr direccion;
int type;
@ -176,7 +172,7 @@ GList * resolv_parser_parse_local_file (GList *all_entries, FILE *fd, int origin
entry->owner_interface_index = 0;
entry->owner_prog[0] = 0;
all_entries = g_list_append (all_entries, entry);
all_entries = f_list_append (all_entries, entry);
}
entry->tagged = 1;
entry->file_order = order++;

View File

@ -26,15 +26,11 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef STAND_ALONE_RESOLV_CONF_HELPER_BUILD
#include "glist.h"
#else
#include "common.h"
#endif
#include "flist.h"
int resolv_conf_parse_line (const char *line, int *ns_family, struct_addr *nameserver, char *value, const size_t value_size);
GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value, int skip_on_file);
GList * resolv_parser_parse_local_file (GList *all_entries, FILE *fd, int origin);
FList * resolv_parser_search_entry (FList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value, int skip_on_file);
FList * resolv_parser_parse_local_file (FList *all_entries, FILE *fd, int origin);
#endif /* __RESOLV_CONF_PARSER_H__ */

View File

@ -32,7 +32,7 @@ void utils_trim (char * s) {
char * p = s;
int l = strlen(p);
while(isspace(p[l - 1])) p[--l] = 0;
while(l > 0 && isspace(p[l - 1])) p[--l] = 0;
while(* p && isspace(* p)) ++p, --l;
memmove(s, p, l + 1);

View File

@ -13,7 +13,7 @@ AC_PREFIX_DEFAULT([/usr])
AC_PROG_CC
# and automake
AM_INIT_AUTOMAKE([-Wall -Werror])
AM_INIT_AUTOMAKE([-Wall -Werror subdir-objects])
# Translate this program
AM_GNU_GETTEXT_VERSION([0.19.8])
@ -22,6 +22,11 @@ AM_GNU_GETTEXT([external])
ALL_LINGUAS=""
AC_SUBST(ALL_LINGUAS)
AM_PROG_AR
# Es una libreria, necesitamos libtool
LT_INIT
AM_PROG_CC_C_O
# Revisar el host
@ -61,6 +66,9 @@ AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
common/Makefile
lib/Makefile
lib/network-inador.pc
src/Makefile
client-gtk/Makefile
po/Makefile.in

35
lib/Makefile.am 100644
View File

@ -0,0 +1,35 @@
lib_LTLIBRARIES = libnetworkinador.la
libnetworkinador_la_SOURCES = network-inador.h \
network-inador-private.h \
network-inador-link-types.h \
struct_addr_union.h wireless_struct.h \
handle.c \
netlink-events.c netlink-events.h \
interfaces.c interfaces.h \
ip-address.c ip-address.h \
routes.c routes.h \
launch_process.c launch_process.h \
dhcp_client.c dhcp_client.h dhcpc_defs.h \
wireless_if.c wireless_if.h \
wireless_bss.c wireless_bss.h \
veth.c veth.h \
resolv_manager.c resolv_manager.h \
resolv_conf_defs.h \
bridge.c bridge.h \
../common/flist.c ../common/flist.h \
../common/resolv_conf_parser.c ../common/resolv_conf_parser.h \
../common/utils.c ../common/utils.h
#wireless-security.c wireless-security.h
libnetworkinador_la_CPPFLAGS = -DSHAREDATA_DIR=\"$(sharedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
libnetworkinador_la_LIBADD = $(LIBNL3_LIBS) $(LIBNLGEN3_LIBS)
#../common/libnicommon.a
libnetworkinador_la_CFLAGS = -I$(top_srcdir)/common $(LIBNL3_CFLAGS) $(LIBNLGEN3_CFLAGS) $(AM_CFLAGS)
LDADD = $(LIBINTL)
libnetworkinadordir = $(includedir)/libnetworkinador
libnetworkinador_HEADERS = network-inador.h network-inador-link-types.h
pkgconfigdir = $(libdir)/pkgconfig
dist_pkgconfig_DATA = network-inador.pc

View File

@ -35,7 +35,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include "common.h"
#include "network-inador-private.h"
#include "interfaces.h"
int interfaces_bridge_create (NetworkInadorHandle *handle, const char *name) {

View File

@ -34,18 +34,20 @@
#include <signal.h>
#include "interfaces.h"
#include "common.h"
#include "manager.h"
#include "network-inador-private.h"
//#include "manager.h"
#include "dhcp_client.h"
#include "network-inador-manager.h"
#include "resolv_manager.h"
#include "launch_process.h"
#include "network-inador-manager.h"
static void interfaces_dhcp_clear_info (InterfaceDHCPClientInfo *dhcpc);
void interfaces_dhcp_client_ignore_kill (GPid pid, gint status, gpointer data) {
/*void interfaces_dhcp_client_ignore_kill (GPid pid, gint status, gpointer data) {
g_spawn_check_exit_status (status, NULL);
}
}*/
void interfaces_dhcp_prepare_args_for_isc_dhclient (char **argv, int size, char *iface_name, char *pid_file, size_t pid_file_len) {
snprintf (pid_file, pid_file_len, "/run/dhclient-%s.pid", iface_name);
@ -78,12 +80,13 @@ void interfaces_dhcp_prepare_args_for_busybox_udhcpc (char **argv, int size, cha
argv[9] = NULL;
}
void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
void interfaces_dhcp_client_killed_cb (void *data, pid_t pid, int status) {
Interface *iface = (Interface *) data;
gboolean ret;
GError *error = NULL;
NetworkInadorHandle *handle = iface->handle;
int ret;
int error = 0;
char *argv[20];
gchar pid_file[256];
char pid_file[256];
/* Preparar los argumentos */
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT) {
@ -92,21 +95,37 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
interfaces_dhcp_prepare_args_for_busybox_udhcpc (argv, 20, iface->name, pid_file, sizeof (pid_file));
}
if (g_spawn_check_exit_status (status, NULL)) {
if (WIFEXITED (status)) {
/* Revisar si necesito algo */
}
/* Por limpieza, quitar la vigilancia del proceso */
if (handle->ops.process_unwatch != NULL) {
handle->ops.process_unwatch (iface->dhcpc.process_watch);
}
iface->dhcpc.process_watch = 0;
interfaces_dhcp_clear_info (&iface->dhcpc);
/* FIXME: ¿Debemos limpiar la información de DNS si no la movimos? */
resolv_manager_clear_dhcp_nameservers (iface->handle, iface);
/* Enviar actualización de estado aquí */
iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED;
manager_send_event_dhcp_change (iface->handle, &iface->dhcpc);
//manager_send_event_dhcp_change (iface->handle, &iface->dhcpc);
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT || iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) {
if (iface->dhcpc.flags & DHCP_CLIENT_FLAG_AUTO_RESTART) {
/* Se cerró o mataron el proceso, reiniciar */
ret = g_spawn_async_with_pipes (
ret = launch_process (
"/",
argv,
NULL,
&iface->dhcpc.process_pid,
NULL,
NULL,
NULL,
&error);
/*ret = g_spawn_async_with_pipes (
"/",
argv,
NULL,
@ -117,23 +136,25 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
NULL,
NULL,
NULL,
&error);
&error);*/
if (ret == FALSE) {
printf ("Error dhcp: %s\n", error->message);
g_error_free (error);
error = NULL;
printf ("Error dhcp: %s\n", strerror (error));
iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED;
iface->dhcpc.process_watch = 0;
} else {
iface->dhcpc.dhcp_state = DHCP_CLIENT_SELECTING;
iface->dhcpc.process_watch = g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_killed_cb, iface);
if (handle->ops.process_watch != NULL) {
iface->dhcpc.process_watch = handle->ops.process_watch (iface->dhcpc.process_pid, interfaces_dhcp_client_killed_cb, iface);
}
}
} else {
/* En caso contrario, solo dejar la muerte escrita */
iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED;
g_source_remove (iface->dhcpc.process_watch);
if (handle->ops.process_unwatch != NULL) {
handle->ops.process_unwatch (iface->dhcpc.process_watch);
}
iface->dhcpc.process_watch = 0;
}
}
@ -154,10 +175,10 @@ static void interfaces_dhcp_clear_info (InterfaceDHCPClientInfo *dhcpc) {
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags) {
/* IFNAMSIZ */
Interface *iface;
gboolean ret;
GError *error = NULL;
int ret;
int error;
char *argv[20];
gchar pid_file[256];
char pid_file[256];
iface = _interfaces_locate_by_index (handle->interfaces, index);
@ -167,6 +188,8 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
return -1;
}
/* Revisar que tenga la función vigiladora de hijos muertos */
/* Preparar los argumentos */
if (type == IFACE_ISC_DHCLIENT) {
interfaces_dhcp_prepare_args_for_isc_dhclient (argv, 20, iface->name, pid_file, sizeof (pid_file));
@ -185,7 +208,16 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
interfaces_dhcp_clear_info (&iface->dhcpc);
ret = g_spawn_async_with_pipes (
ret = launch_process (
"/",
argv,
NULL,
&iface->dhcpc.process_pid,
NULL,
NULL,
NULL,
&error);
/* ret = g_spawn_async_with_pipes (
"/",
argv,
NULL,
@ -196,13 +228,18 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
NULL,
NULL,
NULL,
&error);
&error);*/
/*printf ("Por favor corre el siguiente comando DHCP:\n");
int g = 0;
while (argv[g] != NULL) {
printf ("%s ", argv[g]);
g++;
}
printf ("\n");
ret = TRUE;*/
if (ret == FALSE) {
printf ("Error dhcp: %s\n", error->message);
g_error_free (error);
error = NULL;
printf ("Error dhcp: %s\n", strerror (error));
return -1;
}
@ -211,9 +248,11 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
iface->dhcpc.type = type;
iface->dhcpc.flags = flags;
iface->dhcpc.process_watch = g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_killed_cb, iface);
if (handle->ops.process_watch != NULL) {
iface->dhcpc.process_watch = handle->ops.process_watch (iface->dhcpc.process_pid, interfaces_dhcp_client_killed_cb, iface);
}
manager_send_event_dhcp_change (handle, &iface->dhcpc);
//manager_send_event_dhcp_change (handle, &iface->dhcpc);
return 0;
}
@ -238,9 +277,11 @@ int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
/* Proceso, matar y reiniciar estado */
iface->dhcpc.flags &= (~DHCP_CLIENT_FLAG_AUTO_RESTART);
g_source_remove (iface->dhcpc.process_watch);
if (handle->ops.process_unwatch != NULL) {
handle->ops.process_unwatch (iface->dhcpc.process_watch);
}
iface->dhcpc.process_watch = 0;
g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_ignore_kill, NULL);
// Si el proces muere, realmente no importa
kill (iface->dhcpc.process_pid, SIGTERM);
iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED;
@ -252,7 +293,7 @@ int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
resolv_manager_clear_dhcp_nameservers (handle, iface);
/* Enviar actualización de estado aquí */
manager_send_event_dhcp_change (handle, &iface->dhcpc);
//manager_send_event_dhcp_change (handle, &iface->dhcpc);
}
return 0;
@ -345,7 +386,7 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
dns_changed = 1;
}
if (dns_changed) {
if (dns_changed && (iface->dhcpc.flags & DHCP_CLIENT_FLAG_DONT_ADD_DNS_INFO) == 0) {
resolv_manager_process_dhcp_nameservers (handle, iface);
}
@ -372,9 +413,10 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
/* Cuando entramos a SELECTING, debemos limpiar los DNS del resolv.conf */
interfaces_dhcp_clear_info (&iface->dhcpc);
/* FIXME: ¿Debemos limpiar la información DNS si no la movimos? */
resolv_manager_clear_dhcp_nameservers (handle, iface);
}
manager_send_event_dhcp_change (handle, &iface->dhcpc);
//manager_send_event_dhcp_change (handle, &iface->dhcpc);
}

View File

@ -23,7 +23,10 @@
#ifndef __DHCP_CLIENT_H__
#define __DHCP_CLIENT_H__
#include "common.h"
#include <stdint.h>
#include "struct_addr_union.h"
#include "network-inador-private.h"
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags);
int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);

View File

@ -24,7 +24,7 @@
#define __DHCPC_DEFS_H__
#include <stdint.h>
#include <glib.h>
#include "flist.h"
#include "struct_addr_union.h"
@ -59,8 +59,8 @@ typedef struct {
int dhcp_state;
/* Para vigilar el proceso */
GPid process_pid;
guint process_watch;
pid_t process_pid;
unsigned int process_watch;
/* La información obtenida desde el cliente */
struct_addr ip, broadcast;

314
lib/handle.c 100644
View File

@ -0,0 +1,314 @@
/*
* main.c
* This file is part of Network-inador
*
* Copyright (C) 2024 - Félix Arreola Rodríguez
*
* Network-inador is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Network-inador is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Network-inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include "network-inador-private.h"
#include "netlink-events.h"
#include "interfaces.h"
#include "routes.h"
#include "resolv_manager.h"
struct _NetworkInadorWatchedPID {
unsigned int source;
pid_t child_pid;
NetworkInadorChildWatchFunc func;
void *data;
};
/* Variables si nosotros hacemos vigilancia de procesos */
static FList *network_inador_watched_childs = NULL;
static unsigned int network_inador_watched_child_source_counter = 1;
static int network_inador_pipes_child_notify[2] = {-1, -1};
static int network_inador_child_source_watcher = 0;
static unsigned int network_inador_add_watch_process (pid_t pid, NetworkInadorChildWatchFunc func, void *user_data) {
struct _NetworkInadorWatchedPID *watcher;
watcher = (struct _NetworkInadorWatchedPID *) malloc (sizeof (struct _NetworkInadorWatchedPID));
assert (watcher != NULL);
watcher->source = network_inador_watched_child_source_counter;
network_inador_watched_child_source_counter++;
watcher->child_pid = pid;
watcher->func = func;
watcher->data = user_data;
network_inador_watched_childs = f_list_append (network_inador_watched_childs, watcher);
return watcher->source;
}
static void network_inador_remove_watch_process (unsigned int source) {
/* Recorrer la lista para eliminar el watch, ignorar si no está en la lista */
struct _NetworkInadorWatchedPID *watcher;
FList *g, *next;
g = network_inador_watched_childs;
while (g != NULL) {
next = g->next;
watcher = (struct _NetworkInadorWatchedPID *) g->data;
if (watcher->source == source) {
network_inador_watched_childs = f_list_delete_link (network_inador_watched_childs, g);
free (watcher);
break;
}
g = next;
}
}
static void _network_inador_try_setup_route_events (NetworkInadorHandle *handle) {
struct nl_sock * sock_req;
sock_req = nl_socket_alloc ();
int fd;
if (nl_connect (sock_req, NETLINK_ROUTE) != 0) {
nl_socket_free (sock_req);
return;
}
nl_socket_set_nonblocking (sock_req);
nl_socket_disable_seq_check (sock_req);
fd = nl_socket_get_fd (sock_req);
/* Set close-on-exec */
fcntl (fd, F_SETFD, FD_CLOEXEC);
handle->route_events.nl_sock = sock_req;
handle->has_route_events = 1;
handle->route_events.source = handle->ops.input_add (fd, POLLIN, netlink_events_route_events_handle_read, handle);
nl_socket_add_memberships (sock_req, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, RTNLGRP_IPV6_IFINFO, RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE, 0);
nl_socket_modify_cb (sock_req, NL_CB_VALID, NL_CB_CUSTOM, netlink_events_route_dispatcher, handle);
}
static void _network_inador_try_pipe_routes (NetworkInadorHandle *handle) {
int ret, flags;
int pipe_fds[2];
ret = pipe (pipe_fds);
if (ret < 0) {
return;
}
handle->pipe_routes[0] = pipe_fds[0];
handle->pipe_routes[1] = pipe_fds[1];
flags = fcntl (pipe_fds[0], F_GETFL);
fcntl (pipe_fds[0], F_SETFL, flags | O_NONBLOCK);
handle->source_pipe_routes = handle->ops.input_add (pipe_fds[0], POLLIN, netlink_events_pipe_route_handle_read, handle);
}
static void network_inador_signal_handler_child (int signum) {
//fprintf (stderr, "SIGCHLD session handler\n");
char byte = 1;
/* Avisar que un proceso hijo murió */
if (network_inador_pipes_child_notify[1] >= 0) {
write (network_inador_pipes_child_notify[1], &byte, 1);
}
}
static void network_inador_child_pipe_read (void *data, int fd, int condition) {
pid_t pid;
int status;
FList *g, *next;
char byte;
struct _NetworkInadorWatchedPID *watcher;
int n;
n = read (fd, &byte, 1);
if (n <= 0) return;
while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
g = network_inador_watched_childs;
fprintf (stderr, "El proceso hijo murió: %i\n", pid);
while (g != NULL) {
next = g->next;
watcher = (struct _NetworkInadorWatchedPID *) g->data;
if (watcher->child_pid == pid) {
/* Este es la vigilancia del proceso que buscamos */
watcher->func (watcher->data, pid, status);
/* Como ya murió el proceso, lo eliminamos de la lista de vigilancia */
network_inador_watched_childs = f_list_delete_link (network_inador_watched_childs, g);
free (watcher);
break;
}
g = next;
}
}
}
void network_inador_setup_child_handler (NetworkInadorHandle *handle) {
struct sigaction act;
sigset_t empty_mask;
if (handle->ops.input_add == NULL) {
/* No tenemos vigilancia de entrada, no podemos manejar las señales */
return;
}
if (pipe (network_inador_pipes_child_notify) != 0) {
return;
}
/* Queremos que estos pipes se cierren automáticamente */
fcntl (network_inador_pipes_child_notify[0], F_SETFD, FD_CLOEXEC);
fcntl (network_inador_pipes_child_notify[1], F_SETFD, FD_CLOEXEC);
/* Establecer un manejador de SIGCHLD para los procesos hijos que se generen */
sigemptyset (&empty_mask);
act.sa_mask = empty_mask;
act.sa_flags = 0;
act.sa_handler = &network_inador_signal_handler_child;
if (sigaction (SIGCHLD, &act, NULL) < 0) {
perror ("Failed to register SIGCHLD handler");
close (network_inador_pipes_child_notify[0]);
network_inador_pipes_child_notify[0] = -1;
close (network_inador_pipes_child_notify[1]);
network_inador_pipes_child_notify[1] = -1;
return;
}
network_inador_child_source_watcher = handle->ops.input_add (network_inador_pipes_child_notify[0], POLLIN, network_inador_child_pipe_read, handle);
handle->ops.process_watch = network_inador_add_watch_process;
handle->ops.process_unwatch = network_inador_remove_watch_process;
}
NetworkInadorHandle * network_inador_init_handle (struct NetworkInadorOps *network_inador_ops) {
NetworkInadorHandle *handle;
struct nl_sock * sock_req;
handle = (NetworkInadorHandle *) malloc (sizeof (NetworkInadorHandle));
assert (handle != NULL);
memset (handle, 0, sizeof (NetworkInadorHandle));
handle->pipe_routes[0] = -1;
handle->pipe_routes[1] = -1;
/* Copiar la información de eventos para vigilancia */
handle->ops = *network_inador_ops;
/* Crear el socket de peticiones */
sock_req = nl_socket_alloc ();
if (nl_connect (sock_req, NETLINK_ROUTE) != 0) {
perror ("Falló conectar netlink socket\n");
free (handle);
return NULL;
}
handle->nl_sock_route = sock_req;
/* Si tenemos una ops de configuración de eventos, entonces, configurar el otro socket de eventos async */
if (handle->ops.input_add != NULL) {
_network_inador_try_setup_route_events (handle);
_network_inador_try_pipe_routes (handle);
}
/* Inicializar las interfaces (y las direcciones IP) */
interfaces_init (handle);
/* Inicializar las rutas */
routes_init (handle);
/* Inicializar el resolv.conf */
resolv_manager_init (handle);
return handle;
}
void network_inador_destroy_handle (NetworkInadorHandle *handle) {
if (network_inador_pipes_child_notify[0] >= 0) {
if (handle->ops.input_remove != NULL) {
handle->ops.input_remove (network_inador_child_source_watcher);
network_inador_child_source_watcher = 0;
}
close (network_inador_pipes_child_notify[0]);
network_inador_pipes_child_notify[0] = -1;
}
if (network_inador_pipes_child_notify[1] >= 0) {
close (network_inador_pipes_child_notify[1]);
network_inador_pipes_child_notify[1] = -1;
}
if (handle->has_route_events) {
/* Quitar la vigilancia */
handle->ops.input_remove (handle->route_events.source);
handle->route_events.source = 0;
/* Cerrar el socket de eventos */
nl_socket_free (handle->route_events.nl_sock);
handle->route_events.nl_sock = NULL;
}
if (handle->source_pipe_routes != 0) {
handle->ops.input_remove (handle->source_pipe_routes);
handle->source_pipe_routes = 0;
}
if (handle->pipe_routes[0] >= 0) {
close (handle->pipe_routes[0]);
handle->pipe_routes[0] = -1;
}
if (handle->pipe_routes[1] >= 0) {
close (handle->pipe_routes[1]);
handle->pipe_routes[1] = -1;
}
/* TODO: Liberar las listas ligadas aquí */
routes_clean_up (handle);
interfaces_clean_up (handle);
nl_socket_free (handle->nl_sock_route);
handle->nl_sock_route = NULL;
free (handle);
}

View File

@ -27,16 +27,16 @@
#include <linux/if_arp.h>
#include <gmodule.h>
#include <stdarg.h>
#include "common.h"
#include "network-inador-private.h"
#include "interfaces.h"
#include "routes.h"
#include "ip-address.h"
#include "wireless_if.h"
#include "manager.h"
//#include "manager.h"
#include "link-types.h"
#include "network-inador-link-types.h"
static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, int first_time);
@ -117,7 +117,7 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
memset (iface, 0, sizeof (Interface));
iface->handle = handle;
handle->interfaces = g_list_append (handle->interfaces, iface);
handle->interfaces = f_list_append (handle->interfaces, iface);
was_new = 1;
}
@ -135,9 +135,9 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
}
}
printf ("Interface %d agregada a la interfaz %d (bridge)\n", iface->index, iface->master_index);
//printf ("Interface %d agregada a la interfaz %d (bridge)\n", iface->index, iface->master_index);
was_update = 1;
manager_send_event_interface_update (handle, iface);
//manager_send_event_interface_update (handle, iface);
return NL_SKIP;
}
@ -191,7 +191,7 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
break;
case IFLA_LINKINFO:
{
printf ("La interfaz tiene linkinfo");
printf ("La interfaz tiene linkinfo");
struct nlattr *sub_attr;
int sub_remaining;
@ -216,7 +216,59 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
u32data = nla_get_u32 (attr);
iface->vlan_parent = u32data;
printf ("Interface %d: tiene como padre a %d\n", iface->index, iface->vlan_parent);
//printf ("Interface %d: tiene como padre a %d\n", iface->index, iface->vlan_parent);
break;
case IFLA_PROTINFO:
printf ("OoOoO Interface %i tiene IFLA_PROTINFO oOoOo: %i\n", iface->index, IFLA_PROTINFO);
break;
case IFLA_AF_SPEC:
{
struct nlattr *sub_family;
int sub_family_len;
sub_family = nla_data (attr);
remaining = nla_len (attr);
while (remaining > sizeof (sub_family)) {
sub_family_len = sub_family->nla_len;
if (sub_family_len > remaining) {
printf ("Los sub atributos se acabaron prematuramente\n");
break;
}
printf ("Interface %d, IFLA_AF_SPEC, sub attributo type: %i, tamaño: %i\n", iface->index, sub_family->nla_type, sub_family_len);
if (sub_family->nla_type == AF_INET6) {
struct nlattr *sub_attr;
int sub_remaining;
nla_for_each_nested(sub_attr, sub_family, sub_remaining) {
printf ("\tIFLA_AF_SPEC, family: %i attr: %i, len: %i\n", sub_family->nla_type, nla_type (sub_attr), sub_attr->nla_len);
unsigned char *ttt;
switch (nla_type (sub_attr)) {
case IFLA_INET6_FLAGS:
iface->inet6_data.i6_flags = nla_get_u32 (sub_attr);
break;
case IFLA_INET6_CONF:
ttt = nla_data (sub_attr);
printf ("Size of data: %i, sizeof struct: %i\n", nla_len (sub_attr), sizeof (iface->inet6_data.i6_conf));
memcpy (iface->inet6_data.i6_conf, ttt, sizeof (iface->inet6_data.i6_conf));
break;
case IFLA_INET6_CACHEINFO:
memcpy (&iface->inet6_data.i6_cacheinfo, nla_data (sub_attr), sizeof (iface->inet6_data.i6_cacheinfo));
break;
case IFLA_INET6_ADDR_GEN_MODE:
iface->inet6_data.i6_addr_gen_mode = nla_get_u8 (sub_attr);
break;
}
}
}
/* Avanzar a la siguiente familia presente */
remaining -= RTA_ALIGN (sub_family_len);
sub_family = (struct nlattr *) (((char *) sub_family) + RTA_ALIGN (sub_family_len));
}
}
break;
/*default:
printf ("RTA Attribute \"%hu\" no procesado\n", nla_type (attr));*/
}
@ -229,23 +281,23 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
}
if (was_new) {
printf ("+++++ Interfaz nueva creada: %s\n", iface->name);
wireless_interface_check (handle, iface);
//printf ("+++++ Interfaz nueva creada: %s\n", iface->name);
//wireless_interface_check (handle, iface);
iface->link_type = interfaces_check_link_type (iface);
manager_send_event_interface_add (handle, iface);
//manager_send_event_interface_add (handle, iface);
} else if (was_update) {
manager_send_event_interface_update (handle, iface);
//manager_send_event_interface_update (handle, iface);
}
return NL_SKIP;
}
Interface * _interfaces_locate_by_index (GList *list, int index) {
Interface * _interfaces_locate_by_index (FList *list, int index) {
Interface *iface;
GList *g;
FList *g;
for (g = list; g != NULL; g = g->next) {
iface = (Interface *) g->data;
@ -258,10 +310,10 @@ Interface * _interfaces_locate_by_index (GList *list, int index) {
return NULL;
}
Interface * _interfaces_locate_by_name (GList *list, const char *name) {
Interface * _interfaces_locate_by_name (FList *list, const char *name) {
Interface *iface;
GList *g;
FList *g;
for (g = list; g != NULL; g = g->next) {
iface = (Interface *) g->data;
@ -334,23 +386,23 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) {
}
}
printf ("Interface %d se sacó de su bridge\n", iface->index);
//printf ("Interface %d se sacó de su bridge\n", iface->index);
/* Generar EVENTO AQUI */
manager_send_event_interface_update (handle, iface);
//manager_send_event_interface_update (handle, iface);
return NL_SKIP;
}
route_ask_delayed_delroute (handle);
printf ("----- Interfaz eliminada: %s\n", iface->name);
//printf ("----- Interfaz eliminada: %s\n", iface->name);
handle->interfaces = g_list_remove (handle->interfaces, iface);
handle->interfaces = f_list_remove (handle->interfaces, iface);
/* Antes de eliminar la interfaz, eliminar la lista ligada de todas las direcciones IP */
g_list_free_full (iface->address, free);
f_list_free_full (iface->address, free);
manager_send_event_interface_del (handle, iface->index);
//manager_send_event_interface_del (handle, iface->index);
free (iface);
}
@ -365,7 +417,7 @@ int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
//printf ("Error, solicitaron operación sobre interfaz que no existe\n");
return -1;
}
@ -427,7 +479,7 @@ int interfaces_change_mtu (NetworkInadorHandle *handle, int index, uint32_t new_
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
//printf ("Error, solicitaron operación sobre interfaz que no existe\n");
return -1;
}
@ -618,6 +670,93 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n
return 0;
}
#if 0
int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...) {
uint32_t new_sysctl[DEVCONF_MAX];
Interface *iface;
va_list va_list_params;
uint32_t value;
struct nl_msg * msg, *msg2, *msg3;
struct ifinfomsg iface_hdr;
int ret, error;
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
return -1;
}
/* Copiar los sysctl previos para preservarlos */
memcpy (new_sysctl, iface->inet6_data.i6_conf, sizeof (new_sysctl));
va_start (va_list_params, param);
while (param != -1) {
value = va_arg (va_list_params, uint32_t);
if (param < DEVCONF_MAX) {
new_sysctl[param] = value;
}
param = va_arg (va_list_params, int);
}
va_end (va_list_params);
/* Preparar el mensaje de configurar la interfaz */
memset (&iface_hdr, 0, sizeof (iface_hdr));
#define LINK_ATTR_AF_SPEC (1 << 27)
iface_hdr.ifi_family = AF_UNSPEC;
iface_hdr.ifi_index = iface->index;
iface_hdr.ifi_change = LINK_ATTR_AF_SPEC;
msg = nlmsg_alloc_simple (RTM_SETLINK, NLM_F_REQUEST);
ret = nlmsg_append (msg, &iface_hdr, sizeof (iface_hdr), NLMSG_ALIGNTO);
if (ret != 0) {
nlmsg_free (msg);
return -1;
}
/* FIXME: Aquí el nesting doble o triple */
msg2 = nlmsg_alloc_simple (RTM_NEWLINK, NLM_F_REQUEST);
msg3 = nlmsg_alloc_simple (RTM_NEWLINK, NLM_F_REQUEST);
nla_put (msg3, IFLA_INET6_CONF, sizeof (new_sysctl), new_sysctl);
nla_put_nested (msg2, AF_INET6 | NLA_F_NESTED, msg3);
nla_put_nested (msg, IFLA_AF_SPEC | NLA_F_NESTED, msg2);
nl_complete_msg (handle->nl_sock_route, msg);
ret = nl_send (handle->nl_sock_route, msg);
nlmsg_free (msg);
nlmsg_free (msg2);
nlmsg_free (msg3);
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;
}
#endif
void interfaces_init (NetworkInadorHandle *handle) {
/* Si es la primera vez que nos llaman, descargar una primera lista de interfaces */
struct nl_msg * msg;
@ -647,17 +786,18 @@ void interfaces_init (NetworkInadorHandle *handle) {
}
void interfaces_clean_up (NetworkInadorHandle *handle) {
GList *g;
FList *g;
Interface *iface;
for (g = handle->interfaces; g != NULL; g = g->next) {
iface = (Interface *) g->data;
/* Antes de eliminar la interfaz, eliminar la lista ligada de todas las direcciones IP */
g_list_free_full (iface->address, free);
f_list_free_full (iface->address, free);
iface->address = NULL;
}
g_list_free_full (handle->interfaces, free);
f_list_free_full (handle->interfaces, free);
handle->interfaces = NULL;
}

View File

@ -25,8 +25,63 @@
#include <netlink/socket.h>
#include <netlink/msg.h>
#include <stdarg.h>
#include <stdint.h>
#include "common.h"
#include <linux/ipv6.h>
#include <linux/if_link.h>
#include "flist.h"
#include "network-inador-private.h"
#include "dhcpc_defs.h"
#include "wireless_struct.h"
/* Información extra de IPv6 para la interfaz */
struct inet6_data {
uint32_t i6_flags;
struct ifla_cacheinfo i6_cacheinfo;
uint32_t i6_conf[DEVCONF_MAX];
uint8_t i6_addr_gen_mode;
};
typedef struct {
NetworkInadorHandle *handle;
uint32_t index;
char name[IFNAMSIZ];
uint32_t link_type;
uint16_t arp_type;
unsigned char real_hw[ETHER_ADDR_LEN * 2 + 1];
/* Para las interfaces dentro de un bridge */
uint32_t master_index;
uint32_t mtu;
/* Para las interfaces vlan */
unsigned int vlan_parent;
/* Banderas estilo ioctl */
short flags;
int is_wireless;
char wireless_protocol[IFNAMSIZ];
/* Tipo */
char rtnl_type[IFNAMSIZ];
/* Para los parámetros de IPv4 e IPv6 */
struct inet6_data inet6_data;
/* La lista de direcciones IP, ambas */
FList *address;
InterfaceDHCPClientInfo dhcpc;
/* Información wireless */
WirelessInfo *wireless;
} Interface;
void interfaces_init (NetworkInadorHandle *handle);
int interface_receive_message_newlink (struct nl_msg *msg, void *arg);
@ -35,8 +90,8 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg);
int _interfaces_wait_ack_or_error (struct nl_msg *msg, void *arg);
int _interfaces_wait_error (struct sockaddr_nl *nla, struct nlmsgerr *l_err, void *arg);
Interface * _interfaces_locate_by_index (GList *list, int index);
Interface * _interfaces_locate_by_name (GList *list, const char *name);
Interface * _interfaces_locate_by_index (FList *list, int index);
Interface * _interfaces_locate_by_name (FList *list, const char *name);
int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void *new_mac);
int interfaces_change_mtu (NetworkInadorHandle *handle, int index, uint32_t new_mtu);
@ -44,6 +99,8 @@ int interfaces_change_set_up (NetworkInadorHandle *handle, int index);
int interfaces_change_set_down (NetworkInadorHandle *handle, int index);
int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_name);
//int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...);
void interfaces_clean_up (NetworkInadorHandle *handle);
#endif

View File

@ -29,16 +29,14 @@
#include <linux/if_addr.h>
#include <arpa/inet.h>
#include <gmodule.h>
#include "common.h"
#include "network-inador-private.h"
#include "ip-address.h"
#include "interfaces.h"
#include "manager.h"
//#include "manager.h"
#include "routes.h"
IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, void *addr, uint32_t prefix, void *local_addr) {
GList *g;
FList *g;
IPAddr *ip_addr;
int family_size = 0;
@ -105,7 +103,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
return NL_SKIP;
}
printf ("-> New addr\n");
//printf ("-> New addr\n");
new_flags = addr_msg->ifa_flags;
@ -126,7 +124,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
cacheinfo.tstamp = 0;
nlmsg_for_each_attr(attr, reply, sizeof (struct ifaddrmsg), remaining) {
printf ("-> new addr type attr: %i\n", nla_type (attr));
//printf ("-> new addr type attr: %i\n", nla_type (attr));
switch (nla_type (attr)) {
case IFA_FLAGS:
new_flags = nla_get_u32 (attr);
@ -163,7 +161,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
ip_addr = malloc (sizeof (IPAddr));
memset (ip_addr, 0, sizeof (*ip_addr));
iface->address = g_list_append (iface->address, ip_addr);
iface->address = f_list_append (iface->address, ip_addr);
ip_addr->family = addr_msg->ifa_family;
memcpy (&ip_addr->addr, &addr, family_size);
@ -205,7 +203,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
}
if (was_new) {
manager_send_event_ip_add (handle, ip_addr);
//manager_send_event_ip_add (handle, ip_addr);
} else {
/* En caso contrario, enviar una actualización de IP */
}
@ -260,9 +258,9 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) {
family_size = sizeof (struct in6_addr);
}
printf ("DEL MSG\n");
//printf ("DEL MSG\n");
nlmsg_for_each_attr(attr, reply, sizeof (struct ifaddrmsg), remaining) {
printf ("-> del addr type attr: %i\n", nla_type (attr));
//printf ("-> del addr type attr: %i\n", nla_type (attr));
switch (nla_type (attr)) {
case IFA_ADDRESS:
memcpy (&addr, nla_data (attr), nla_len (attr));
@ -279,7 +277,7 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) {
ip_addr = _ip_address_search_addr (iface, family, &addr, addr_msg->ifa_prefixlen, (has_local ? &local_addr : NULL));
if (ip_addr == NULL) {
printf ("IP no encontrada\n");
//printf ("IP no encontrada\n");
return NL_SKIP;
}
@ -288,10 +286,10 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) {
printf ("Dirección IP - %s/%d sobre interfaz: %d, scope: %d, flags: %u\n", buffer, ip_addr->prefix, iface->index, (unsigned int) ip_addr->scope, ip_addr->flags);
/* Eliminar de la lista ligada */
iface->address = g_list_remove (iface->address, ip_addr);
iface->address = f_list_remove (iface->address, ip_addr);
/* Notificar del evento */
manager_send_event_ip_del (handle, ip_addr);
//manager_send_event_ip_del (handle, ip_addr);
free (ip_addr);
@ -329,6 +327,7 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
Interface *iface;
int family_size = 0;
/* TODO: Si no tenemos los route events, podríamos ejecutar una lectura de interfaces para refrescar la lista */
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
@ -410,9 +409,10 @@ int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
struct ifaddrmsg addr_hdr;
int ret, error;
Interface *iface;
GList *addr_pos;
FList *addr_pos;
int family_size = 0;
/* TODO: Si no tenemos los eventos, podemos ejecutar una lectura de interfaces para refrescar la información */
iface = _interfaces_locate_by_index (handle->interfaces, index);
if (iface == NULL) {
@ -421,7 +421,7 @@ int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
return -1;
}
addr_pos = g_list_find (iface->address, ip_addr);
addr_pos = f_list_find (iface->address, ip_addr);
if (addr_pos == NULL) {
printf ("Error, la dirección solicitada no pertenece a la interfaz\n");

View File

@ -26,7 +26,35 @@
#include <netlink/socket.h>
#include <netlink/msg.h>
#include "common.h"
#include "network-inador-private.h"
#include "interfaces.h"
#include "struct_addr_union.h"
#ifndef INFINITY_LIFE_TIME
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
#endif
typedef struct {
sa_family_t family;
uint8_t prefix;
struct_addr local_addr;
struct_addr addr;
struct_addr brd_addr;
char label[256];
struct ifa_cacheinfo cacheinfo;
uint8_t is_p2p;
uint8_t has_brd;
uint8_t has_local;
uint32_t flags;
uint8_t scope;
Interface *iface;
} IPAddr;
int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg);
int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg);

View File

@ -0,0 +1,331 @@
/*
* lauch_process.c
* This file is part of Network-Inador
*
* Copyright (C) 2024 - Félix Arreola Rodríguez
*
* Network-Inador is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Network-Inador is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Network-Inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
static ssize_t write_all (int fd, const void * vbuf, size_t to_write) {
char *buf = (char *) vbuf;
while (to_write > 0) {
ssize_t count = write (fd, buf, to_write);
if (count < 0) {
if (errno != EINTR)
return 0;
} else {
to_write -= count;
buf += count;
}
}
return 1;
}
/* This function is called between fork() and exec() and hence must be
* async-signal-safe (see signal-safety(7)). */
static void write_err_and_exit (int fd, int msg) {
int en = errno;
write_all (fd, &msg, sizeof (msg));
write_all (fd, &en, sizeof (en));
_exit (1);
}
static int safe_close (int fd) {
int ret;
do {
ret = close (fd);
} while (ret < 0 && errno == EINTR);
return ret;
}
static void close_and_invalidate (int *fd) {
if (*fd < 0) {
return;
} else {
safe_close (*fd);
*fd = -1;
}
}
static int safe_dup2 (int fd1, int fd2) {
int ret;
do {
ret = dup2 (fd1, fd2);
} while (ret < 0 && (errno == EINTR || errno == EBUSY));
return ret;
}
static int read_ints (int fd, int *buf, int n_ints_in_buf, int *n_ints_read, int *error) {
size_t bytes = 0;
while (1) {
ssize_t chunk;
if (bytes >= sizeof (int) * 2)
break; /* give up, who knows what happened, should not be possible. */
again:
chunk = read (fd,((char *) buf) + bytes, sizeof (int) * n_ints_in_buf - bytes);
if (chunk < 0 && errno == EINTR)
goto again;
if (chunk < 0) {
if (error != NULL) {
*error = errno;
}
return 0;
} else if (chunk == 0) {
break; /* EOF */
} else {/* chunk > 0 */
bytes += chunk;
}
}
*n_ints_read = (int) (bytes / sizeof (int));
return 1;
}
enum {
CHILD_CHDIR_FAILED,
CHILD_EXEC_FAILED,
CHILD_DUP2_FAILED,
CHILD_FORK_FAILED
};
static void do_exec (int child_err_report_fd, int stdin_fd, int stdout_fd, int stderr_fd, const char *working_directory, char **argv, char **envp) {
if (working_directory && chdir (working_directory) < 0) {
write_err_and_exit (child_err_report_fd, CHILD_CHDIR_FAILED);
}
if (stdin_fd >= 0) {
if (safe_dup2 (stdin_fd, 0) < 0) {
write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED);
}
close (stdin_fd);
} else {
int read_null = open ("/dev/null", O_RDONLY);
if (read_null < 0) {
write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED);
}
safe_dup2 (read_null, 0);
close_and_invalidate (&read_null);
}
if (stdout_fd >= 0) {
if (safe_dup2 (stdout_fd, 1) < 0) {
write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED);
}
close (stdout_fd);
} else {
int read_null = open ("/dev/null", O_WRONLY);
if (read_null < 0) {
write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED);
}
safe_dup2 (read_null, 1);
close_and_invalidate (&read_null);
}
/* Ahora para stderr */
if (stderr_fd >= 0) {
if (safe_dup2 (stderr_fd, 2) < 0) {
write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED);
}
close (stderr_fd);
} else {
int read_null = open ("/dev/null", O_WRONLY);
if (read_null < 0) {
write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED);
}
safe_dup2 (read_null, 2);
close_and_invalidate (&read_null);
}
/* TODO: Si queremos cerrar todos los descriptores, este es el momento */
fcntl (child_err_report_fd, F_SETFD, FD_CLOEXEC);
/* Hacer el exec */
execvpe (argv[0], argv, envp);
write_err_and_exit (child_err_report_fd, CHILD_EXEC_FAILED);
}
static int fork_exec_with_fds (const char *working_directory, char **argv, char **envp, pid_t *child_pid, int *child_close_fds, int stdin_fd, int stdout_fd, int stderr_fd, int *error) {
pid_t pid;
int child_err_report_pipe[2] = { -1, -1 };
if (pipe (child_err_report_pipe) != 0) {
if (error != NULL) *error = errno;
return 0;
}
pid = fork ();
if (pid < 0) {
if (error != NULL) *error = errno;
goto cleanup_and_fail;
} else if (pid == 0) {
/* Proceso intermedio */
/* Reset some signal handlers that we may use */
signal (SIGCHLD, SIG_DFL);
signal (SIGINT, SIG_DFL);
signal (SIGTERM, SIG_DFL);
signal (SIGHUP, SIG_DFL);
/* Be sure we crash if the parent exits
* and we write to the err_report_pipe
*/
signal (SIGPIPE, SIG_DFL);
/* Close the parent's end of the pipes;
* not needed in the close_descriptors case,
* though
*/
close_and_invalidate (&child_err_report_pipe[0]);
if (child_close_fds != NULL) {
int i = -1;
while (child_close_fds[++i] != -1)
close_and_invalidate (&child_close_fds[i]);
}
do_exec (child_err_report_pipe[1], stdin_fd, stdout_fd, stderr_fd, working_directory, argv, envp);
} else {
/* Proceso padre */
int buf[2];
int n_ints = 0;
close_and_invalidate (&child_err_report_pipe[1]);
if (!read_ints (child_err_report_pipe[0], buf, 2, &n_ints, error)) {
goto cleanup_and_fail;
}
if (n_ints >= 2) {
/* El argumento buf[0] tiene el error, el buf[1] tiene el errno del proceso hijo */
if (error != NULL) *error = buf[1];
goto cleanup_and_fail;
}
close_and_invalidate (&child_err_report_pipe[0]);
if (child_pid) {
*child_pid = pid;
}
return 1;
}
cleanup_and_fail:
if (pid > 0) {
wait_failed:
if (waitpid (pid, NULL, 0) < 0) {
if (errno == EINTR)
goto wait_failed;
else if (errno == ECHILD)
; /* do nothing, child already reaped */
/*else
g_warning ("waitpid() should not fail in 'fork_exec_with_pipes'");*/
}
}
close_and_invalidate (&child_err_report_pipe[0]);
close_and_invalidate (&child_err_report_pipe[1]);
return 0;
}
int launch_process (const char *working_directory, char **argv, char **envp, pid_t *child_pid, int *standard_input, int *standard_output, int *standard_error, int *error) {
int stdin_pipe[2] = { -1, -1 };
int stdout_pipe[2] = { -1, -1 };
int stderr_pipe[2] = { -1, -1 };
int child_close_fds[4];
int c;
int ret;
if (standard_input && pipe (stdin_pipe) != 0)
goto failed_launch_cleanup;
if (standard_output && pipe (stdout_pipe) != 0)
goto failed_launch_cleanup;
if (standard_error && pipe (stderr_pipe) != 0)
goto failed_launch_cleanup;
c = 0;
if (stdin_pipe[1] != -1) child_close_fds[c++] = stdin_pipe[1];
if (stdout_pipe[0] != -1) child_close_fds[c++] = stdout_pipe[0];
if (stderr_pipe[0] != -1) child_close_fds[c++] = stderr_pipe[0];
child_close_fds[c++] = -1;
ret = fork_exec_with_fds (working_directory, argv, envp, child_pid, child_close_fds, stdin_pipe[0], stdout_pipe[1], stderr_pipe[1], error);
if (!ret) goto failed_launch_cleanup;
close_and_invalidate (&stdin_pipe[0]);
close_and_invalidate (&stdout_pipe[1]);
close_and_invalidate (&stderr_pipe[1]);
if (standard_input) {
*standard_input = stdin_pipe[1];
}
if (standard_output) {
*standard_output = stdout_pipe[0];
}
if (standard_error) {
*standard_error = stderr_pipe[0];
}
return 1;
failed_launch_cleanup:
close_and_invalidate (&stdin_pipe[0]);
close_and_invalidate (&stdin_pipe[1]);
close_and_invalidate (&stdout_pipe[0]);
close_and_invalidate (&stdout_pipe[1]);
close_and_invalidate (&stderr_pipe[0]);
close_and_invalidate (&stderr_pipe[1]);
return 0;
}

View File

@ -0,0 +1,29 @@
/*
* launch_process.h
* This file is part of Network-Inador
*
* Copyright (C) 2024 - Félix Arreola Rodríguez
*
* Network-Inador is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Network-Inador is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Network-Inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __LAUNCH_PROCESS_H__
#define __LAUNCH_PROCESS_H__
int launch_process (const char *working_directory, char **argv, char **envp, pid_t *child_pid, int *standard_input, int *standard_output, int *standard_error, int *error);
#endif /* __LAUNCH_PROCESS_H__ */

View File

@ -0,0 +1,91 @@
/*
* netlink-events.c
* This file is part of Network-inador
*
* Copyright (C) 2019, 2020 - 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 <unistd.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include <linux/nl80211.h>
#include <fcntl.h>
#include "network-inador-private.h"
#include "interfaces.h"
#include "ip-address.h"
#include "routes.h"
int netlink_events_route_dispatcher (struct nl_msg *msg, void *arg) {
struct nlmsghdr *reply;
reply = nlmsg_hdr (msg);
switch (reply->nlmsg_type) {
case RTM_NEWLINK:
return interface_receive_message_newlink (msg, arg);
break;
case RTM_DELLINK:
return interface_receive_message_dellink (msg, arg);
break;
case RTM_NEWADDR:
return ip_address_receive_message_newaddr (msg, arg);
break;
case RTM_DELADDR:
return ip_address_receive_message_deladdr (msg, arg);
break;
case RTM_NEWROUTE:
return routes_receive_message_newroute (msg, arg);
break;
case RTM_DELROUTE:
return routes_receive_message_delroute (msg, arg);
break;
}
return NL_SKIP;
}
void netlink_events_route_events_handle_read (void *data, int fd, int condition) {
NetworkInadorHandle *handle = (NetworkInadorHandle *) data;
nl_recvmsgs_default (handle->route_events.nl_sock);
}
void netlink_events_pipe_route_handle_read (void *data, int fd, int condition) {
NetworkInadorHandle *handle = (NetworkInadorHandle *) data;
char buffer[8192];
int ret;
ret = read (handle->pipe_routes[0], buffer, sizeof (buffer));
if (ret > 0) {
/* Leimos algo en el aviso de re-procesar rutas */
routes_ask (handle);
} else if (ret == 0) {
/* Cerrar el pipe */
close (handle->pipe_routes[0]);
handle->pipe_routes[0] = -1;
handle->ops.input_remove (handle->source_pipe_routes);
handle->source_pipe_routes = 0;
}
}

View File

@ -23,11 +23,13 @@
#ifndef __NETLINK_EVENTS_H__
#define __NETLINK_EVENTS_H__
#include "common.h"
#include <netlink/socket.h>
#include <netlink/msg.h>
void netlink_events_create_pair (NetlinkEventPair *pair, int family);
void netlink_events_clear_pair (NetlinkEventPair *pair);
void netlink_events_setup (NetworkInadorHandle *handle);
void netlink_events_clear (NetworkInadorHandle *handle);
#include "network-inador-private.h"
int netlink_events_route_dispatcher (struct nl_msg *msg, void *arg);
void netlink_events_route_events_handle_read (void *data, int fd, int condition);
void netlink_events_pipe_route_handle_read (void *data, int fd, int condition);
#endif

View File

@ -0,0 +1,75 @@
/*
* network-inador-private.h
* This file is part of Network-Inador
*
* Copyright (C) 2024 - Félix Arreola Rodríguez
*
* Network-Inador is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Network-Inador is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Network-Inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __NETWORK_INADOR_PRIVATE_H__
#define __NETWORK_INADOR_PRIVATE_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include "network-inador.h"
#include "flist.h"
/* Para vigilar eventos */
typedef struct {
struct nl_sock * nl_sock;
unsigned int source;
} NetlinkEventPair;
/* La definición principal que engloba todo */
struct _NetworkInadorHandle {
struct NetworkInadorOps ops;
/* La verdadera información */
FList *interfaces;
FList *route_v4_tables;
FList *route_v6_tables;
FList *route_tables_names;
/* Entradas para el resolv conf */
FList *resolver_entries;
int resolver_inotify_fd;
int resolver_inotify_watch;
/* Estos sockets ejecutan comandos */
struct nl_sock * nl_sock_route;
//struct nl_sock * nl_sock_nl80211;
/* Estos sockets son de vigilancia de eventos */
int has_route_events;
NetlinkEventPair route_events;
/*NetlinkEventPair nl80211_scan;
NetlinkEventPair nl80211_scan_results;*/
/* El pipe de vigilancia especial de las rutas eliminadas */
int pipe_routes[2];
unsigned int source_pipe_routes;
};
#endif /* __NETWORK_INADOR_PRIVATE_H__ */

View File

@ -0,0 +1,76 @@
/*
* main.c
* This file is part of Network-inador
*
* Copyright (C) 2024 - Félix Arreola Rodríguez
*
* Network-inador is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Network-inador is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Network-inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __NETWORK_INADOR_H__
#define __NETWORK_INADOR_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE !FALSE
#endif
typedef struct _NetworkInadorHandle NetworkInadorHandle;
/* Función que define una lectura desde un FD */
typedef void (*NetworkInadorInputFunc) (void *, int, int);
typedef void (*NetworkInadorChildWatchFunc) (void *, pid_t, int);
struct NetworkInadorOps {
/* Vigilar FDs */
unsigned int (*input_add) (int fd, int cond, NetworkInadorInputFunc func, void *user_data);
void (*input_remove) (unsigned int);
/* Vigilar procesos */
unsigned int (*process_watch) (pid_t pid, NetworkInadorChildWatchFunc, void *user_data);
void (*process_unwatch) (unsigned int);
/* Ver si agregamos timers aquí */
};
NetworkInadorHandle * network_inador_init_handle (struct NetworkInadorOps *network_inador_ops);
void network_inador_destroy_handle (NetworkInadorHandle *handle);
void network_inador_setup_child_handler (NetworkInadorHandle *handle);
/* Funciones básicas de interfaces */
int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void *new_mac);
int interfaces_change_mtu (NetworkInadorHandle *handle, int index, uint32_t new_mtu);
int interfaces_change_set_up (NetworkInadorHandle *handle, int index);
int interfaces_change_set_down (NetworkInadorHandle *handle, int index);
int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_name);
/* Funciones básicas de dhcp */
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags);
int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);
#endif /* __NETWORK_INADOR_H__ */

View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Network Inador Library
Description: Network Inador Library main functions
Version: @VERSION@
Libs: -L${libdir} -lnetworkinador
Libs.private:
Cflags: -I${includedir}/libnetworkinador

View File

@ -30,14 +30,14 @@
#include <arpa/inet.h>
#include "resolv_manager.h"
#include "common.h"
#include "network-inador-private.h"
#include "utils.h"
#include "resolv_conf_parser.h"
#include "interfaces.h"
void resolv_manager_write (NetworkInadorHandle *handle);
gint resolv_manager_sort_entries (const void *a, const void *b, gpointer data) {
int resolv_manager_sort_entries (const void *a, const void *b, void * data) {
const ResolvConfEntry *aa = (ResolvConfEntry *) a;
const ResolvConfEntry *bb = (ResolvConfEntry *) b;
@ -64,7 +64,7 @@ gint resolv_manager_sort_entries (const void *a, const void *b, gpointer data) {
}
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog) {
GList *g;
FList *g;
ResolvConfEntry *entry;
int do_write = 0;
@ -83,7 +83,7 @@ void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const in
printf ("/// Eliminando entrada %s por via resolvconf. Prog = «%s»\n", entry->value, prog);
/*free (entry);
handle->resolver_entries = g_list_delete_link (handle->resolver_entries, g);*/
handle->resolver_entries = f_list_delete_link (handle->resolver_entries, g);*/
entry->for_purge = 1;
do_write = 1;
}
@ -98,7 +98,7 @@ void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const in
}
void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle) {
GList *pos;
FList *pos;
ResolvConfEntry *entry;
/* Borrar el atributo "tagged" */
@ -114,7 +114,7 @@ void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle) {
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, ResolvConfEntry *entries, int num_entries) {
int g;
ResolvConfEntry *entry;
GList *pos_entry;
FList *pos_entry;
int do_write = 0;
resolv_manager_clear_tag_on_all (handle);
@ -163,7 +163,7 @@ void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, Res
entry->for_purge = 0;
/* Anexar al final de la lista */
handle->resolver_entries = g_list_append (handle->resolver_entries, entry);
handle->resolver_entries = f_list_append (handle->resolver_entries, entry);
/* TODO: Como creamos una entrada via el resolvconf, regenerar el archivo */
printf ("/// Nueva entrada %s via resolvconf, programando regeneración.\n", entry->value);
@ -178,7 +178,7 @@ void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, Res
}
void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface) {
GList *pos_entry;
FList *pos_entry;
int h;
ResolvConfEntry *entry;
int do_write = 0;
@ -245,7 +245,7 @@ void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Inter
inet_ntop (AF_INET, &entry->nameserver, entry->value, sizeof (entry->value));
/* Anexar al final de la lista */
handle->resolver_entries = g_list_append (handle->resolver_entries, entry);
handle->resolver_entries = f_list_append (handle->resolver_entries, entry);
/* Como creamos una entrada via el dhcp, regenerar el archivo */
printf ("/// Nueva entrada %s via DHCP (%s), programando regeneración.\n", entry->value, iface->name);
@ -299,7 +299,7 @@ void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Inter
strncpy (entry->value, iface->dhcpc.domain_name, sizeof (entry->value));
/* Anexar al final de la lista */
handle->resolver_entries = g_list_append (handle->resolver_entries, entry);
handle->resolver_entries = f_list_append (handle->resolver_entries, entry);
/* Como creamos una entrada via el dhcp, regenerar el archivo */
printf ("/// Nueva entrada search %s via DHCP (%s), programando regeneración.\n", entry->value, iface->name);
@ -327,7 +327,7 @@ void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Inter
}
void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface) {
GList *pos_entry;
FList *pos_entry;
int h;
ResolvConfEntry *entry;
int do_write = 0;
@ -356,7 +356,7 @@ void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interfa
void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
FILE *fd;
GList *pos, *next;
FList *pos, *next;
ResolvConfEntry *entry;
fd = fopen ("/etc/resolv.conf", "r");
@ -381,7 +381,7 @@ 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);
entry->for_purge = 1;
/*handle->resolver_entries = g_list_delete_link (handle->resolver_entries, pos);
/*handle->resolver_entries = f_list_delete_link (handle->resolver_entries, pos);
free (entry);
entry = NULL;*/
} else {
@ -391,12 +391,12 @@ void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
}
/* Reordenar las entradas. TODO: Falta leer los ficheros de configuración del resolv.conf */
handle->resolver_entries = g_list_sort_with_data (handle->resolver_entries, resolv_manager_sort_entries, NULL);
handle->resolver_entries = f_list_sort_with_data (handle->resolver_entries, resolv_manager_sort_entries, NULL);
}
void resolv_manager_write (NetworkInadorHandle *handle) {
FILE *fd;
GList *pos, *next;
FList *pos, *next;
ResolvConfEntry *entry;
Interface *iface;
@ -456,7 +456,7 @@ void resolv_manager_write (NetworkInadorHandle *handle) {
entry = (ResolvConfEntry *) pos->data;
if (entry->for_purge == 1) {
handle->resolver_entries = g_list_delete_link (handle->resolver_entries, pos);
handle->resolver_entries = f_list_delete_link (handle->resolver_entries, pos);
free (entry);
entry = NULL;
}

View File

@ -23,9 +23,10 @@
#ifndef __RESOLV_MANAGER_H__
#define __RESOLV_MANAGER_H__
#include "common.h"
#include "network-inador-private.h"
#include "struct_addr_union.h"
#include "resolv_conf_defs.h"
#include "interfaces.h"
void resolv_manager_init (NetworkInadorHandle *handle);
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog);

View File

@ -34,12 +34,13 @@
#include <netlink/socket.h>
#include <netlink/msg.h>
#include "common.h"
#include "flist.h"
#include "network-inador-private.h"
#include "routes.h"
#include "manager.h"
//#include "manager.h"
gint _route_compare_nexthop_v4 (gconstpointer a, gconstpointer b);
gint _route_compare_nexthop_v6 (gconstpointer a, gconstpointer b);
int _route_compare_nexthop_v4 (const void * a, const void * b);
int _route_compare_nexthop_v6 (const void * a, const void * b);
void route_ask_delayed_delroute (NetworkInadorHandle *handle) {
if (handle->pipe_routes[1] > 0) {
@ -47,14 +48,14 @@ void route_ask_delayed_delroute (NetworkInadorHandle *handle) {
}
}
int _route_same_list_nexthops (int family, GList *nexthops_a, GList *nexthops_b) {
int _route_same_list_nexthops (int family, FList *nexthops_a, FList *nexthops_b) {
int count_a, count_b;
RouteNH *nha, *nhb;
GList *p_a, *p_b;
FList *p_a, *p_b;
count_a = g_list_length (nexthops_a);
count_b = g_list_length (nexthops_b);
count_a = f_list_length (nexthops_a);
count_b = f_list_length (nexthops_b);
if (count_a != count_b) return 1;
@ -77,8 +78,8 @@ int _route_same_list_nexthops (int family, GList *nexthops_a, GList *nexthops_b)
return 0;
}
Route *_route_search_route (GList *list_routes, sa_family_t family, uint8_t tos, uint32_t table, void *dest, uint32_t prefix, uint32_t priority) {
GList *g;
Route *_route_search_route (FList *list_routes, sa_family_t family, uint8_t tos, uint32_t table, void *dest, uint32_t prefix, uint32_t priority) {
FList *g;
Route *route;
int family_size = 0;
@ -107,7 +108,7 @@ Route *_route_search_route (GList *list_routes, sa_family_t family, uint8_t tos,
return NULL;
}
gint _route_compare_nexthop_v4 (gconstpointer a, gconstpointer b) {
int _route_compare_nexthop_v4 (const void * a, const void * b) {
int ret;
RouteNH *nha = (RouteNH *) a, *nhb = (RouteNH *) b;
@ -123,7 +124,7 @@ gint _route_compare_nexthop_v4 (gconstpointer a, gconstpointer b) {
return ret;
}
gint _route_compare_nexthop_v6 (gconstpointer a, gconstpointer b) {
int _route_compare_nexthop_v6 (const void * a, const void * b) {
int ret;
RouteNH *nha = (RouteNH *) a, *nhb = (RouteNH *) b;
@ -139,11 +140,11 @@ gint _route_compare_nexthop_v6 (gconstpointer a, gconstpointer b) {
return ret;
}
GList * _route_sort_nexthops (int family, GList *nexthops) {
FList * _route_sort_nexthops (int family, FList *nexthops) {
if (family == AF_INET) {
return g_list_sort (nexthops, _route_compare_nexthop_v4);
return f_list_sort (nexthops, _route_compare_nexthop_v4);
} else if (family == AF_INET6) {
return g_list_sort (nexthops, _route_compare_nexthop_v6);
return f_list_sort (nexthops, _route_compare_nexthop_v6);
}
return nexthops;
@ -167,8 +168,8 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
struct_addr dest;
uint32_t priority = 0;
int was_new = 0, was_update = 0;
GList *route_list = NULL;
GList *old_next_hops = NULL;
FList *route_list = NULL;
FList *old_next_hops = NULL;
reply = nlmsg_hdr (msg);
@ -242,14 +243,14 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
memcpy (&route->dest, &dest, family_size);
if (family == AF_INET) {
handle->route_v4_tables = g_list_append (handle->route_v4_tables, route);
handle->route_v4_tables = f_list_append (handle->route_v4_tables, route);
} else if (family == AF_INET6) {
handle->route_v6_tables = g_list_append (handle->route_v6_tables, route);
handle->route_v6_tables = f_list_append (handle->route_v6_tables, route);
}
was_new = 1;
} else {
/* Liberar los next-hops, puesto que volverán a ser creados */
//g_list_free_full (route->nexthops, free);
//f_list_free_full (route->nexthops, free);
old_next_hops = route->nexthops;
route->nexthops = NULL;
route->for_delete = 0;
@ -313,7 +314,7 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
/* Reservar el siguiente next-hop */
if (multipath_len > 0) {
route->nexthops = g_list_append (route->nexthops, next_hop);
route->nexthops = f_list_append (route->nexthops, next_hop);
next_hop = (RouteNH *) malloc (sizeof (RouteNH));
memset (next_hop, 0, sizeof (RouteNH));
@ -323,7 +324,7 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
}
}
route->nexthops = g_list_append (route->nexthops, next_hop);
route->nexthops = f_list_append (route->nexthops, next_hop);
route->nexthops = _route_sort_nexthops (family, route->nexthops);
if (_route_same_list_nexthops (family, route->nexthops, old_next_hops) == 1) {
@ -332,14 +333,14 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
}
/* Liberar la lista vieja de next_hops */
g_list_free_full (old_next_hops, free);
f_list_free_full (old_next_hops, free);
if (was_new) {
/* Enviar aquí evento de ruta agregada */
manager_send_event_route_add (handle, route);
//manager_send_event_route_add (handle, route);
} else if (was_update) {
/* Enviar actualización */
manager_send_event_route_update (handle, route);
//manager_send_event_route_update (handle, route);
}
return NL_SKIP;
}
@ -356,7 +357,7 @@ int routes_receive_message_delroute (struct nl_msg *msg, void *arg) {
uint8_t route_tos;
struct_addr dest;
uint32_t priority = 0;
GList *route_list = NULL;
FList *route_list = NULL;
reply = nlmsg_hdr (msg);
if (reply->nlmsg_type != RTM_DELROUTE) return NL_SKIP;
@ -418,16 +419,16 @@ int routes_receive_message_delroute (struct nl_msg *msg, void *arg) {
if (family == AF_INET) {
/* Eliminar de la lista ligada */
handle->route_v4_tables = g_list_remove (handle->route_v4_tables, route);
handle->route_v4_tables = f_list_remove (handle->route_v4_tables, route);
} else if (family == AF_INET6) {
handle->route_v6_tables = g_list_remove (handle->route_v6_tables, route);
handle->route_v6_tables = f_list_remove (handle->route_v6_tables, route);
}
/* Notificar del evento */
manager_send_event_route_del (handle, route);
//manager_send_event_route_del (handle, route);
/* Eliminar todos los next-hops primero */
g_list_free_full (route->nexthops, free);
f_list_free_full (route->nexthops, free);
free (route);
@ -466,7 +467,7 @@ int routes_add (NetworkInadorHandle *handle, Route *route) {
struct_addr empty;
int hop_count;
RouteNH *nh;
GList *g;
FList *g;
struct rtnexthop nexthop_hdr, *nhptr;
char buffer_nexthops[8192];
int size_nexthops;
@ -506,7 +507,7 @@ int routes_add (NetworkInadorHandle *handle, Route *route) {
ret |= nla_put (msg, RTA_PREFSRC, family_size, &route->prefsrc);
}
hop_count = g_list_length (route->nexthops);
hop_count = f_list_length (route->nexthops);
if (hop_count <= 1) {
/* Agregar por el método 1 */
nh = (RouteNH *) route->nexthops->data;
@ -592,7 +593,7 @@ int routes_del (NetworkInadorHandle *handle, Route *route) {
struct_addr empty;
int hop_count;
RouteNH *nh;
GList *g;
FList *g;
memset (&route_hdr, 0, sizeof (route_hdr));
@ -657,7 +658,7 @@ void routes_ask (NetworkInadorHandle *handle) {
.rtm_family = AF_UNSPEC,
};
int ret;
GList *g, *n;
FList *g, *n;
Route *r;
/* Recorrer todas las rutas en la tabla de ruteo y marcarlas para eliminación */
@ -702,13 +703,13 @@ void routes_ask (NetworkInadorHandle *handle) {
r = (Route *) g->data;
if (r->for_delete == 0) continue;
handle->route_v4_tables = g_list_remove (handle->route_v4_tables, r);
handle->route_v4_tables = f_list_remove (handle->route_v4_tables, r);
/* Notificar del evento */
manager_send_event_route_del (handle, r);
//manager_send_event_route_del (handle, r);
/* Eliminar todos los next-hops primero */
g_list_free_full (r->nexthops, free);
f_list_free_full (r->nexthops, free);
free (r);
}
@ -719,19 +720,19 @@ void routes_ask (NetworkInadorHandle *handle) {
r = (Route *) g->data;
if (r->for_delete == 0) continue;
handle->route_v6_tables = g_list_remove (handle->route_v6_tables, r);
handle->route_v6_tables = f_list_remove (handle->route_v6_tables, r);
/* Notificar del evento */
manager_send_event_route_del (handle, r);
//manager_send_event_route_del (handle, r);
/* Eliminar todos los next-hops primero */
g_list_free_full (r->nexthops, free);
f_list_free_full (r->nexthops, free);
free (r);
}
}
gint _routes_table_find_by_number (gconstpointer left, gconstpointer right) {
int _routes_table_find_by_number (const void * left, const void * right) {
RouteTable *a, *b;
a = (RouteTable *) left;
@ -741,7 +742,7 @@ gint _routes_table_find_by_number (gconstpointer left, gconstpointer right) {
}
void _routes_table_parse_file (NetworkInadorHandle *handle, FILE *fd) {
GList *g;
FList *g;
int ret;
RouteTable *rtable, temp_table;
char buffer[2048];
@ -755,7 +756,7 @@ void _routes_table_parse_file (NetworkInadorHandle *handle, FILE *fd) {
continue;
}
g = g_list_find_custom (handle->route_tables_names, &temp_table, _routes_table_find_by_number);
g = f_list_find_custom (handle->route_tables_names, &temp_table, _routes_table_find_by_number);
if (g != NULL) {
/* El número de tabla ya existe, marcar y actualizar el nombre */
@ -765,7 +766,7 @@ void _routes_table_parse_file (NetworkInadorHandle *handle, FILE *fd) {
rtable->was_new = 0;
} else {
/* No existe, crear nueva */
rtable = (RouteTable *) g_malloc (sizeof (RouteTable));
rtable = (RouteTable *) malloc (sizeof (RouteTable));
rtable->table = temp_table.table;
rtable->for_delete = 0;
rtable->was_new = 1;
@ -773,13 +774,13 @@ void _routes_table_parse_file (NetworkInadorHandle *handle, FILE *fd) {
/* En cualquier caso actualizar el nombre */
strncpy (rtable->name, temp_table.name, sizeof (rtable->name));
handle->route_tables_names = g_list_append (handle->route_tables_names, rtable);
handle->route_tables_names = f_list_append (handle->route_tables_names, rtable);
}
}
void routes_tables_read (NetworkInadorHandle *handle, int do_notify) {
FILE *fd;
GList *g, *h;
FList *g, *h;
RouteTable *rtable;
DIR *dir;
struct dirent *direntry;
@ -795,7 +796,7 @@ void routes_tables_read (NetworkInadorHandle *handle, int do_notify) {
g = g->next;
}
//g_list_free_full (handle->route_tables_names, g_free);
//f_list_free_full (handle->route_tables_names, g_free);
//handle->route_tables_names = NULL;
/* Intentar abrir /etc/iproute2/rt_tables */
@ -839,13 +840,13 @@ void routes_tables_read (NetworkInadorHandle *handle, int do_notify) {
rtable = (RouteTable *) g->data;
if (rtable->for_delete) {
handle->route_tables_names = g_list_delete_link (handle->route_tables_names, g);
handle->route_tables_names = f_list_delete_link (handle->route_tables_names, g);
if (do_notify) {
manager_send_event_route_table_del (handle, rtable);
//manager_send_event_route_table_del (handle, rtable);
}
g_free (rtable);
free (rtable);
}
g = h;
@ -857,7 +858,7 @@ void routes_tables_read (NetworkInadorHandle *handle, int do_notify) {
if (rtable->was_new) {
if (do_notify) {
manager_send_event_route_table_add (handle, rtable);
//manager_send_event_route_table_add (handle, rtable);
}
rtable->was_new = 0;
}
@ -875,27 +876,29 @@ void routes_init (NetworkInadorHandle *handle) {
}
void routes_clean_up (NetworkInadorHandle *handle) {
GList *g;
FList *g;
Route *route;
for (g = handle->route_v4_tables; g != NULL; g = g->next) {
route = (Route *) g->data;
g_list_free_full (route->nexthops, free);
f_list_free_full (route->nexthops, free);
route->nexthops = NULL;
}
g_list_free_full (handle->route_v4_tables, free);
f_list_free_full (handle->route_v4_tables, free);
handle->route_v4_tables = NULL;
for (g = handle->route_v6_tables; g != NULL; g = g->next) {
route = (Route *) g->data;
g_list_free_full (route->nexthops, free);
f_list_free_full (route->nexthops, free);
route->nexthops = NULL;
}
g_list_free_full (handle->route_v6_tables, free);
f_list_free_full (handle->route_v6_tables, free);
handle->route_v6_tables = NULL;
/* FIXME: Falta liberar el nombre de las tablas */
}

View File

@ -23,10 +23,52 @@
#ifndef __ROUTES_H__
#define __ROUTES_H__
#include <stdint.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include "common.h"
#include "network-inador-private.h"
#include "struct_addr_union.h"
#include "flist.h"
/* Un Next-hop */
typedef struct {
struct_addr gw;
uint32_t out_index;
uint8_t nh_weight;
uint8_t nh_flags;
} RouteNH;
/* La tabla de ruteo */
typedef struct {
sa_family_t family; /* AF_INET, AF_INET6 */
uint8_t type; /* Unicast, local, broadcast, etc... */
uint32_t table;
struct_addr dest;
uint8_t prefix;
uint8_t tos;
uint8_t protocol;
uint8_t scope;
struct_addr prefsrc;
uint32_t priority;
/* Los brincos */
FList *nexthops;
/* Variable usada para determinar si debemos eliminar la ruta */
int for_delete;
} Route;
typedef struct {
uint32_t table;
char name[256];
int for_delete, was_new;
} RouteTable;
void routes_init (NetworkInadorHandle *handle);
void routes_ask (NetworkInadorHandle *handle);

166
lib/veth.c 100644
View File

@ -0,0 +1,166 @@
/*
* veth.c
* This file is part of Network-inador
*
* Copyright (C) 2023 - 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 <sys/types.h>
#include <sys/socket.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/veth.h>
#include "network-inador-private.h"
#include "interfaces.h"
int interfaces_veth_create (NetworkInadorHandle *handle, const char *link_name, const char *peer_name) {
struct nl_msg * msg;
struct ifinfomsg iface_hdr, peer_hdr;
struct nlattr *info, *data, *peer;
int ret, error, len;
const char *type = "veth";
if (link_name != NULL) {
/* Validar la longitud del nombre, por seguridad */
len = strlen (link_name) + 1;
if (len == 1) {
/* Nombre muy corto */
return -1;
}
if (len > IFNAMSIZ) {
/* Nombre muy largo */
return -1;
}
}
if (peer_name != NULL) {
/* Validar la longitud del nombre, por seguridad */
len = strlen (peer_name) + 1;
if (len == 1) {
/* Nombre muy corto */
return -1;
}
if (len > IFNAMSIZ) {
/* Nombre muy largo */
return -1;
}
}
memset (&iface_hdr, 0, sizeof (iface_hdr));
iface_hdr.ifi_family = AF_UNSPEC;
iface_hdr.ifi_index = 0;
msg = nlmsg_alloc_simple (RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
ret = nlmsg_append (msg, &iface_hdr, sizeof (iface_hdr), NLMSG_ALIGNTO);
if (ret != 0) {
nlmsg_free (msg);
return -1;
}
/* Anexar el nombre, si es que especificaron uno */
if (link_name != NULL) {
ret = nla_put (msg, IFLA_IFNAME, strlen (link_name) + 1, link_name);
if (ret != 0) {
nlmsg_free (msg);
return -1;
}
}
info = nla_nest_start (msg, IFLA_LINKINFO);
if (info == NULL) {
nlmsg_free (msg);
return -1;
}
//ret = nla_put_string (msg, IFLA_INFO_KIND, type);
ret = nla_put (msg, IFLA_INFO_KIND, strlen (type), type);
if (ret != 0) {
nla_nest_end (msg, info);
nlmsg_free (msg);
return -1;
}
/* Ver cómo anexar IFLA_INFO_DATA */
data = nla_nest_start (msg, IFLA_INFO_DATA);
/* Vaciar la estructura del peer */
memset (&peer_hdr, 0, sizeof (peer_hdr));
peer_hdr.ifi_family = AF_UNSPEC;
peer_hdr.ifi_index = 0;
peer = nla_nest_start (msg, VETH_INFO_PEER);
nlmsg_append (msg, &peer_hdr, sizeof (peer_hdr), 0);
if (peer_name != NULL) {
ret = nla_put (msg, IFLA_IFNAME, strlen (peer_name) + 1, peer_name);
if (ret != 0) {
nlmsg_free (msg);
return -1;
}
}
nla_nest_end (msg, peer); /* Cerrar el VETH_INFO_PEER */
nla_nest_end (msg, data); /* Cerrar el IFLA_INFO_DATA */
nla_nest_end (msg, info); /* Cerrar el IFLA_LINKINFO */
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;
}

29
lib/veth.h 100644
View File

@ -0,0 +1,29 @@
/*
* veth.h
* This file is part of Network-inador
*
* Copyright (C) 2023 - 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 __VETH_H__
#define __VETH_H__
int interfaces_veth_create (NetworkInadorHandle *handle, const char *link, const char *peer);
#endif /* __VETH_H__ */

View File

@ -33,7 +33,7 @@
#include <linux/nl80211.h>
#include "common.h"
#include "network-inador-private.h"
#include "interfaces.h"
#include "netlink-events.h"
#include "wireless_if.h"
@ -43,7 +43,7 @@
int wireless_bss_finish_scan (struct nl_msg *msg, void *arg) {
#if 0
GList *g;
FList *g;
WirelessBSS *bss;
printf ("Scan finish handler\n");
@ -71,7 +71,7 @@ static void _wireless_bss_find_ssid (uint8_t *ies, uint32_t ies_len, uint8_t **s
}
static WirelessBSS * _wireless_bss_get (Interface *iface, const uint8_t *bssid, const uint8_t *ssid, int ssid_len) {
GList *g;
FList *g;
WirelessBSS *bss;
if (iface->is_wireless == 0) return NULL;
@ -100,7 +100,7 @@ static WirelessBSS * _wireless_bss_add_bss (Interface *iface, WirelessBSS *bss)
new->last_update_idx = iface->wireless->bss_update_idx;
new->scan_miss_count = 0;
iface->wireless->aps = g_list_append (iface->wireless->aps, new);
iface->wireless->aps = f_list_append (iface->wireless->aps, new);
}
static void _wireless_bss_update_bss (Interface *iface, WirelessBSS *bss, WirelessBSS *updated) {

View File

@ -36,8 +36,6 @@
#include <linux/nl80211.h>
#include "common.h"
int wireless_bss_parse_station_scan (struct nl_msg *msg, void *arg);
int wireless_bss_finish_scan (struct nl_msg *msg, void *arg);

View File

@ -33,7 +33,7 @@
#include <linux/nl80211.h>
#include "common.h"
#include "network-inador-private.h"
#include "interfaces.h"
#include "netlink-events.h"
#include "wireless_if.h"
@ -78,7 +78,7 @@ static void _wireless_if_process_bands (struct nlattr *list_bands, WirelessInfo
}
printf ("La supuesta cantidad de frecuencias es: %i\n", info->num_freqs);
info->freqs = (guint32 *) malloc (sizeof (guint32) * info->num_freqs);
info->freqs = (uint32_t *) malloc (sizeof (uint32_t) * info->num_freqs);
freq_index = 0;
nla_for_each_nested (band, list_bands, remaining) {
@ -243,6 +243,7 @@ gboolean wireless_interface_timer_trigger (gpointer data) {
#endif
static void wireless_interface_init_nl80211 (NetworkInadorHandle *handle) {
#if 0
int family_id;
int mcid;
struct nl_sock * sock_req;
@ -284,9 +285,11 @@ static void wireless_interface_init_nl80211 (NetworkInadorHandle *handle) {
/* Instalar un timer para ejecutar TRIGGER_SCAN cada minuto */
//g_timeout_add_seconds (50, wireless_interface_timer_trigger, handle);
#endif
}
int wireless_events_dispatcher (struct nl_msg *msg, void *arg) {
#if 0
NetworkInadorHandle *handle = (NetworkInadorHandle *) arg;
struct nlmsghdr *reply;
struct genlmsghdr *gnlh;
@ -343,9 +346,11 @@ int wireless_events_dispatcher (struct nl_msg *msg, void *arg) {
}
return NL_SKIP;
#endif
}
void wireless_interface_trigger_scan (NetworkInadorHandle *handle, Interface *iface) {
#if 0
struct nl_msg *msg;
int error, ret;
struct nlattr *ssid;
@ -391,9 +396,11 @@ void wireless_interface_trigger_scan (NetworkInadorHandle *handle, Interface *if
printf ("Error al hacer NL80211_CMD_TRIGGER_SCAN error = %i\n", error);
return;
}
#endif
}
void wireless_interface_get_scan (NetworkInadorHandle *handle, Interface *iface) {
#if 0
struct nl_msg *msg;
int error, ret;
struct genlmsghdr *gnlh;
@ -441,9 +448,11 @@ void wireless_interface_get_scan (NetworkInadorHandle *handle, Interface *iface)
}
//nl_recvmsgs_default (handle->nl_sock_nl80211);
#endif
}
void wireless_interface_check (NetworkInadorHandle *handle, Interface *iface) {
#if 0
struct nl_msg * msg;
int ret;
struct _wireless_iface_is_wifi is_wifi;
@ -503,4 +512,5 @@ void wireless_interface_check (NetworkInadorHandle *handle, Interface *iface) {
} else {
free (info);
}
#endif
}

View File

@ -23,7 +23,12 @@
#ifndef __WIRELESS_IF_H__
#define __WIRELESS_IF_H__
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "network-inador-private.h"
#include "interfaces.h"
typedef enum { /*< flags >*/
WIFI_DEVICE_CAP_NONE = 0x00000000,

View File

@ -0,0 +1,24 @@
/*
* wireless_security.c
* This file is part of Network-inador
*
* Copyright (C) 2020 - 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 "wireless_security.h"

View File

@ -0,0 +1,27 @@
/*
* wireless_security.h
* This file is part of Network-inador
*
* Copyright (C) 2020 - 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 __WIRELESS_SECURITY_H__
#define __WIRELESS_SECURITY_H__
#endif /* __WIRELESS_SECURITY_H__ */

View File

@ -0,0 +1,78 @@
/*
* wireless_struct.h
* This file is part of Network-Inador
*
* Copyright (C) 2024 - Félix Arreola Rodríguez
*
* Network-Inador is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Network-Inador is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Network-Inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __WIRELESS_STRUCT_H__
#define __WIRELESS_STRUCT_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <net/ethernet.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include "flist.h"
#define SSID_MAX_LEN 32
typedef struct _WirelessBSS {
/** Number of counts without seeing this BSS */
unsigned int scan_miss_count;
/** Index of the last scan update */
unsigned int last_update_idx;
/** BSSID */
uint8_t bssid[ETHER_ADDR_LEN * 2 + 1];
/** HESSID */
//u8 hessid[ETHER_ADDR_LEN * 2 + 1];
/** SSID */
uint8_t ssid[SSID_MAX_LEN];
/** Length of SSID */
size_t ssid_len;
/** Frequency of the channel in MHz (e.g., 2412 = channel 1) */
int freq;
/** Capability information field in host byte order */
uint16_t caps;
/** Timestamp of last Beacon/Probe Response frame */
uint64_t tsf;
/** Time of the last update (i.e., Beacon or Probe Response RX) */
struct timespec last_update;
} WirelessBSS;
typedef struct _WirelessInfo {
int phy;
uint32_t *freqs;
int num_freqs;
uint32_t caps;
uint8_t can_scan;
uint8_t can_scan_ssid;
uint8_t supported;
unsigned int bss_update_idx;
FList *aps;
} WirelessInfo;
#endif /* __WIRELESS_STRUCT_H__ */

View File

@ -1,30 +1,17 @@
# Automake file for NetworkInador
bin_PROGRAMS = network-inador
network_inador_SOURCES = main.c \
common.h link-types.h \
dhcpc_defs.h \
struct_addr_union.h resolv_conf_defs.h \
netlink-events.c netlink-events.h \
interfaces.c interfaces.h \
ip-address.c ip-address.h \
bridge.c bridge.h \
manager.c manager.h \
dhcp_client.c dhcp_client.h \
routes.c routes.h \
resolv_manager.c resolv_manager.h \
resolv_conf_parser.c resolv_conf_parser.h \
wireless_if.c wireless_if.h \
wireless_bss.c wireless_bss.h \
utils.c utils.h
network_inador_SOURCES = main.c
# manager.c manager.h
sbin_PROGRAMS = resolvconf
resolvconf_SOURCES = resolv_conf_helper.c \
struct_addr_union.h resolv_conf_defs.h \
resolv_conf_parser.c resolv_conf_parser.h \
utils.c utils.h \
glist.c glist.h
resolvconf_CFLAGS = -DSTAND_ALONE_RESOLV_CONF_HELPER_BUILD
../common/flist.c ../common/flist.h \
../common/resolv_conf_parser.c ../common/resolv_conf_parser.h \
../common/utils.c ../common/utils.h
resolvconf_CFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/lib -DSTAND_ALONE_RESOLV_CONF_HELPER_BUILD
resolvconf_LDADD =
#../common/libnicommon.a
libexec_PROGRAMS = ni-dhcp-helper
@ -34,8 +21,8 @@ ni_dhcp_helper_CFLAGS = $(AM_CFLAGS)
#network_inador_CPPFLAGS = -DGAMEDATA_DIR=\"$(gamedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
network_inador_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
network_inador_CFLAGS = $(GLIB_CFLAGS) $(LIBNL3_CFLAGS) $(LIBNLGEN3_CFLAGS) $(AM_CFLAGS)
network_inador_LDADD = $(GLIB_LIBS) $(LIBNL3_LIBS) $(LIBNLGEN3_LIBS)
network_inador_CFLAGS = -I$(top_srcdir)/lib $(GLIB_CFLAGS) $(LIBNL3_CFLAGS) $(LIBNLGEN3_CFLAGS) $(AM_CFLAGS)
network_inador_LDADD = $(GLIB_LIBS) $(LIBNL3_LIBS) $(LIBNLGEN3_LIBS) ../lib/libnetworkinador.la
LDADD = $(LIBINTL)
#SUBDIRS = client_test dhcpc

View File

@ -1,248 +0,0 @@
/*
* common.h
* This file is part of Network-inador
*
* Copyright (C) 2019, 2020 - 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 __COMMON_H__
#define __COMMON_H__
#include <stdint.h>
#include <time.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <linux/if.h>
#include <linux/if_addr.h>
#include <glib.h>
#include <gmodule.h>
#include "struct_addr_union.h"
#include "resolv_conf_defs.h"
#include "dhcpc_defs.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE !FALSE
#endif
#ifndef INFINITY_LIFE_TIME
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
#endif
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
typedef struct _NetworkInadorHandle NetworkInadorHandle;
typedef struct _NetworkInadorManager NetworkInadorManager;
typedef struct _Interface Interface;
typedef struct _IPAddr {
sa_family_t family;
uint8_t prefix;
struct_addr local_addr;
struct_addr addr;
struct_addr brd_addr;
char label[256];
struct ifa_cacheinfo cacheinfo;
uint8_t is_p2p;
uint8_t has_brd;
uint8_t has_local;
uint32_t flags;
uint8_t scope;
Interface *iface;
} IPAddr;
#define SSID_MAX_LEN 32
typedef struct _WirelessBSS {
/** Number of counts without seeing this BSS */
unsigned int scan_miss_count;
/** Index of the last scan update */
unsigned int last_update_idx;
/** BSSID */
uint8_t bssid[ETHER_ADDR_LEN * 2 + 1];
/** HESSID */
//u8 hessid[ETHER_ADDR_LEN * 2 + 1];
/** SSID */
uint8_t ssid[SSID_MAX_LEN];
/** Length of SSID */
size_t ssid_len;
/** Frequency of the channel in MHz (e.g., 2412 = channel 1) */
int freq;
/** Capability information field in host byte order */
uint16_t caps;
/** Timestamp of last Beacon/Probe Response frame */
uint64_t tsf;
/** Time of the last update (i.e., Beacon or Probe Response RX) */
struct timespec last_update;
} WirelessBSS;
typedef struct _WirelessInfo {
int phy;
uint32_t *freqs;
int num_freqs;
uint32_t caps;
gboolean can_scan;
gboolean can_scan_ssid;
gboolean supported;
unsigned int bss_update_idx;
GList *aps;
} WirelessInfo;
struct _Interface {
NetworkInadorHandle *handle;
uint32_t index;
char name[IFNAMSIZ];
uint32_t link_type;
uint16_t arp_type;
unsigned char real_hw[ETHER_ADDR_LEN * 2 + 1];
/* Para las interfaces dentro de un bridge */
uint32_t master_index;
uint32_t mtu;
/* Para las interfaces vlan */
unsigned int vlan_parent;
/* Banderas estilo ioctl */
short flags;
int is_wireless;
char wireless_protocol[IFNAMSIZ];
/* Tipo */
char rtnl_type[IFNAMSIZ];
GList *address;
InterfaceDHCPClientInfo dhcpc;
/* Información wireless */
WirelessInfo *wireless;
};
/* Para los clientes y sus respectivos eventos */
typedef struct {
int fd;
/* Los eventos que quieren ser recibidos en este cliente */
uint32_t wanted_events;
guint source;
NetworkInadorManager *manager;
} ManagerClientInfo;
struct _NetworkInadorManager {
int socket;
guint source;
GList *connected_client_list;
NetworkInadorHandle *handle;
};
/* Para vigilar eventos */
typedef struct _netlink_event_pair {
struct nl_sock * nl_sock;
guint source;
} NetlinkEventPair;
typedef struct _RouteNH {
struct_addr gw;
uint32_t out_index;
uint8_t nh_weight;
uint8_t nh_flags;
} RouteNH;
/* La tabla de ruteo */
typedef struct _Route {
sa_family_t family; /* AF_INET, AF_INET6 */
uint8_t type; /* Unicast, local, broadcast, etc... */
uint32_t table;
struct_addr dest;
uint8_t prefix;
uint8_t tos;
uint8_t protocol;
uint8_t scope;
struct_addr prefsrc;
uint32_t priority;
/* Los brincos */
GList *nexthops;
/* Variable usada para determinar si debemos eliminar la ruta */
int for_delete;
} Route;
typedef struct _RouteTable {
uint32_t table;
char name[256];
int for_delete, was_new;
} RouteTable;
/* La definición principal que engloba todo */
struct _NetworkInadorHandle {
GList *interfaces;
GList *route_v4_tables;
GList *route_v6_tables;
GList *route_tables_names;
/* Entradas para el resolv conf */
GList *resolver_entries;
int resolver_inotify_fd;
int resolver_inotify_watch;
/* El manager */
NetworkInadorManager *manager;
/* Estos sockets ejecutan comandos */
struct nl_sock * nl_sock_route;
struct nl_sock * nl_sock_nl80211;
/* Estos sockets son de vigilancia de eventos */
NetlinkEventPair route_events;
NetlinkEventPair nl80211_scan;
NetlinkEventPair nl80211_scan_results;
/* El pipe de vigilancia especial de las rutas eliminadas */
int pipe_routes[2];
guint source_pipe_routes;
};
#endif /* __COMMON_H__ */

View File

@ -1,152 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __G_LIST_H__
#define __G_LIST_H__
#define G_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
typedef void * gpointer;
typedef const void * gconstpointer;
typedef void (*GDestroyNotify) (gpointer data);
typedef void (*GFunc) (gpointer data, gpointer user_data);
typedef int (*GCompareDataFunc) (gconstpointer a, gconstpointer b, gpointer user_data);
typedef int (*GCompareFunc) (gconstpointer a, gconstpointer b);
typedef gpointer (*GCopyFunc) (gconstpointer src, gpointer data);
typedef struct _GList GList;
struct _GList
{
gpointer data;
GList *next;
GList *prev;
};
/* Doubly linked lists
*/
GList* g_list_alloc (void) G_GNUC_WARN_UNUSED_RESULT;
void g_list_free (GList *list);
void g_list_free_1 (GList *list);
#define g_list_free1 g_list_free_1
void g_list_free_full (GList *list,
GDestroyNotify free_func);
GList* g_list_append (GList *list,
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_prepend (GList *list,
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_insert (GList *list,
gpointer data,
int position) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_insert_sorted (GList *list,
gpointer data,
GCompareFunc func) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_insert_sorted_with_data (GList *list,
gpointer data,
GCompareDataFunc func,
gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_insert_before (GList *list,
GList *sibling,
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_concat (GList *list1,
GList *list2) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_remove (GList *list,
gconstpointer data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_remove_all (GList *list,
gconstpointer data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_remove_link (GList *list,
GList *llink) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_delete_link (GList *list,
GList *link_) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_reverse (GList *list) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_copy (GList *list) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_copy_deep (GList *list,
GCopyFunc func,
gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_nth (GList *list,
unsigned int n);
GList* g_list_nth_prev (GList *list,
unsigned int n);
GList* g_list_find (GList *list,
gconstpointer data);
GList* g_list_find_custom (GList *list,
gconstpointer data,
GCompareFunc func);
int g_list_position (GList *list,
GList *llink);
int g_list_index (GList *list,
gconstpointer data);
GList* g_list_last (GList *list);
GList* g_list_first (GList *list);
unsigned int g_list_length (GList *list);
void g_list_foreach (GList *list,
GFunc func,
gpointer user_data);
GList* g_list_sort (GList *list,
GCompareFunc compare_func) G_GNUC_WARN_UNUSED_RESULT;
GList* g_list_sort_with_data (GList *list,
GCompareDataFunc compare_func,
gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
gpointer g_list_nth_data (GList *list,
unsigned int n);
#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL)
#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL)
#endif /* __G_LIST_H__ */

View File

@ -38,28 +38,11 @@
#include <fcntl.h>
#include "common.h"
#include "manager.h"
#include "interfaces.h"
#include "netlink-events.h"
#include "ip-address.h"
#include "bridge.h"
#include "dhcp_client.h"
#include "routes.h"
#include "resolv_manager.h"
#include "network-inador.h"
/* Usados para salir en caso de una señal */
static int sigterm_pipe_fds[2] = { -1, -1 };
static void _init_handle (NetworkInadorHandle *handle) {
assert (handle != NULL);
memset (handle, 0, sizeof (NetworkInadorHandle));
handle->interfaces = NULL;
handle->pipe_routes[0] = -1;
handle->pipe_routes[1] = -1;
}
static void _sigterm_handler (int signum) {
//fprintf (stderr, "SIGTERM SIGINT Handler\n");
if (sigterm_pipe_fds[1] >= 0) {
@ -114,54 +97,163 @@ static void _main_setup_signal (void *loop) {
}
}
typedef struct _NetworkInadorGLibIOClosure {
NetworkInadorInputFunc function;
guint result;
gpointer data;
} NetworkInadorGLibIOClosure;
static void glib_io_destroy (gpointer data) {
g_free (data);
}
gboolean glib_io_invoke (GIOChannel *source, GIOCondition condition, gpointer data) {
NetworkInadorGLibIOClosure *closure = data;
int cond = 0;
if (condition & G_IO_IN) {
cond |= POLLIN;
}
if (condition & G_IO_OUT) {
cond |= POLLOUT;
}
closure->function (closure->data, g_io_channel_unix_get_fd (source), cond);
return TRUE;
}
unsigned int glib_input_add (int fd, int cond, NetworkInadorInputFunc func, void *user_data) {
GIOChannel *channel;
NetworkInadorGLibIOClosure *closure = g_new0 (NetworkInadorGLibIOClosure, 1);
GIOCondition gcond = 0;
closure->function = func;
closure->data = user_data;
if (cond == POLLIN) {
gcond = G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_ERR;
} else if (cond == POLLOUT) {
gcond = G_IO_OUT | G_IO_PRI | G_IO_HUP | G_IO_ERR;
}
channel = g_io_channel_unix_new (fd);
closure->result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond, glib_io_invoke, closure, glib_io_destroy);
g_io_channel_unref(channel);
return closure->result;
}
struct NetworkInadorOps network_ops = {
.input_add = glib_input_add,
.input_remove = g_source_remove,
};
int main (int argc, char *argv[]) {
NetworkInadorHandle handle;
NetworkInadorHandle *handle;
GMainLoop *loop = NULL;
struct nl_sock * sock_req;
#if !defined(GLIB_VERSION_2_36)
g_type_init ();
#endif
_init_handle (&handle);
handle = network_inador_init_handle (&network_ops);
/* Crear el socket de peticiones */
sock_req = nl_socket_alloc ();
if (nl_connect (sock_req, NETLINK_ROUTE) != 0) {
perror ("Falló conectar netlink socket\n");
return -1;
}
handle.nl_sock_route = sock_req;
/* Crear el socket que escucha eventos */
netlink_events_setup (&handle);
/* Dejar que la librería maneje los procesos hijos muertos */
network_inador_setup_child_handler (handle);
loop = g_main_loop_new (NULL, FALSE);
_main_setup_signal (loop);
/* Inicializar las interfaces (y las direcciones IP) */
interfaces_init (&handle);
interfaces_dhcp_client_run (handle, 3, 1, 1);
/*IPAddr addr;
inet_pton (AF_INET, "192.19.5.6", &addr.sin_addr);
addr.family = AF_INET;
addr.prefix = 25;
addr.flags = 128;
addr.scope = 0;
/* Inicializar las rutas */
routes_init (&handle);
ip_address_add_ip (&handle, 3, &addr);*/
/* Inicializar el resolv.conf */
resolv_manager_init (&handle);
/*GList *g;
Interface *x;
for (g = handle.interfaces; g != NULL; g = g->next) {
x = (Interface *) g->data;
manager_init (&handle);
if (x->index == 2 && x->address != NULL) {
ip_address_del_ip (&handle, x->index, x->address->data);
}
}*/
//interfaces_bridge_create (&handle, "br0");
//interfaces_bridge_set_master_interface (&handle, 4, 5);
//interfaces_bridge_remove_master_interface (&handle, 5);
//interfaces_bridge_delete (&handle, 4);
//interfaces_dhcp_client_run (&handle, 2, IFACE_BUSYBOX_UDHCPC, DHCP_CLIENT_FLAG_AUTO_RESTART);
#if 0
// Prueba de agregar ruta
Route route;
GList nhl1, nhl2;
RouteNH nh1, nh2;
memset (&route, 0, sizeof (route));
route.family = AF_INET;
route.type = RTN_UNICAST;
route.table = 0;
inet_pton (AF_INET, "10.8.9.0", &route.dest);
route.prefix = 24;
route.protocol = RTPROT_STATIC;
route.tos = 0;
route.priority = 400;
route.nexthops = &nhl1;
memset (&nh1, 0, sizeof (nh1));
memset (&nh2, 0, sizeof (nh2));
nhl1.prev = NULL;
nhl1.next = &nhl2;
nhl2.prev = &nhl1;
nhl2.next = NULL;
nhl1.data = &nh1;
nhl2.data = &nh2;
inet_pton (AF_INET, "172.22.201.1", &nh1.gw);
inet_pton (AF_INET, "172.22.201.2", &nh2.gw);
nh1.out_index = 0;
nh2.out_index = 0;
nh1.nh_weight = 4;
nh2.nh_weight = 9;
routes_add (&handle, &route);
#endif
#if 0
// Prueba de eliminar una ruta
Route route;
memset (&route, 0, sizeof (route));
route.family = AF_INET;
route.table = 0;
inet_pton (AF_INET, "172.18.5.0", &route.dest);
route.prefix = 24;
route.tos = 0x18;
routes_del (&handle, &route);
interfaces_veth_create (&handle, "abc", "def");
#endif
/*interfaces_change_set_down (&handle, 4);
int ret = interfaces_set_sysctl_ipv6_params (&handle, 4, DEVCONF_DISABLE_IPV6, (uint32_t) 1, -1);
printf ("Ret sel sysctl: %i\n", ret);
interfaces_change_set_up (&handle, 4);*/
g_main_loop_run (loop);
/* Detener la llegada de eventos */
netlink_events_clear (&handle);
network_inador_destroy_handle (handle);
routes_clean_up (&handle);
interfaces_clean_up (&handle);
// nl_socket_free???
g_main_loop_unref (loop);
return 0;
}

View File

@ -39,7 +39,7 @@
#include <linux/if_addr.h>
#include <sys/stat.h>
#include "common.h"
#include "network-inador-private.h"
#include "interfaces.h"
#include "ip-address.h"
#include "routes.h"

View File

@ -1,160 +0,0 @@
/*
* netlink-events.c
* This file is part of Network-inador
*
* Copyright (C) 2019, 2020 - 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 <unistd.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include <glib.h>
#include <linux/nl80211.h>
#include <fcntl.h>
#include "common.h"
#include "interfaces.h"
#include "ip-address.h"
#include "routes.h"
static int _netlink_events_route_dispatcher (struct nl_msg *msg, void *arg) {
struct nlmsghdr *reply;
reply = nlmsg_hdr (msg);
switch (reply->nlmsg_type) {
case RTM_NEWLINK:
return interface_receive_message_newlink (msg, arg);
break;
case RTM_DELLINK:
return interface_receive_message_dellink (msg, arg);
break;
case RTM_NEWADDR:
return ip_address_receive_message_newaddr (msg, arg);
break;
case RTM_DELADDR:
return ip_address_receive_message_deladdr (msg, arg);
break;
case RTM_NEWROUTE:
return routes_receive_message_newroute (msg, arg);
break;
case RTM_DELROUTE:
return routes_receive_message_delroute (msg, arg);
break;
}
return NL_SKIP;
}
static gboolean _netlink_events_handle_read (GIOChannel *source, GIOCondition condition, gpointer data) {
struct nl_sock *socket = (struct nl_sock *) data;
nl_recvmsgs_default (socket);
return TRUE;
}
static gboolean _netlink_events_handle_route_ask (GIOChannel *source, GIOCondition condition, gpointer data) {
NetworkInadorHandle *handle = (NetworkInadorHandle *) data;
char buffer[8192];
int ret;
ret = read (handle->pipe_routes[0], buffer, sizeof (buffer));
if (ret > 0) {
/* Leimos algo en el aviso de re-procesar rutas */
routes_ask (handle);
} else if (ret == 0) {
/* Cerrar el pipe */
close (handle->pipe_routes[0]);
handle->pipe_routes[0] = -1;
return FALSE;
}
return TRUE;
}
void netlink_events_create_pair (NetlinkEventPair *pair, int family) {
struct nl_sock * sock_req;
int fd;
GIOChannel *channel;
if (pair == NULL) return;
sock_req = nl_socket_alloc ();
if (nl_connect (sock_req, family) != 0) {
perror ("Falló conectar netlink socket para eventos\n");
return;
}
nl_socket_set_nonblocking (sock_req);
nl_socket_disable_seq_check (sock_req);
fd = nl_socket_get_fd (sock_req);
fcntl (fd, F_SETFD, 1);
channel = g_io_channel_unix_new (fd);
pair->source = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, _netlink_events_handle_read, sock_req);
pair->nl_sock = sock_req;
g_io_channel_unref (channel);
}
void netlink_events_clear_pair (NetlinkEventPair *pair) {
g_source_remove (pair->source);
pair->source = 0;
/* Cerrar el socket */
nl_close (pair->nl_sock);
pair->nl_sock = NULL;
}
void netlink_events_setup (NetworkInadorHandle *handle) {
int ret;
GIOChannel *channel;
netlink_events_create_pair (&handle->route_events, NETLINK_ROUTE);
int flags;
nl_socket_add_memberships (handle->route_events.nl_sock, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, RTNLGRP_IPV6_IFINFO, RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE, 0);
nl_socket_modify_cb (handle->route_events.nl_sock, NL_CB_VALID, NL_CB_CUSTOM, _netlink_events_route_dispatcher, handle);
/* Crear un pipe para vigilar y procesar los cambios de rutas */
ret = pipe (handle->pipe_routes);
if (ret < 0) {
handle->pipe_routes[0] = handle->pipe_routes[1] = -1;
} else {
flags = fcntl (handle->pipe_routes[0], F_GETFL);
fcntl (handle->pipe_routes[0], F_SETFL, flags | O_NONBLOCK);
channel = g_io_channel_unix_new (handle->pipe_routes[0]);
handle->source_pipe_routes = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, _netlink_events_handle_route_ask, handle);
g_io_channel_unref (channel);
}
}
void netlink_events_clear (NetworkInadorHandle *handle) {
/* Primero, detener los eventos del source watch */
netlink_events_clear_pair (&handle->route_events);
}

View File

@ -34,7 +34,7 @@
#include <sys/un.h>
#include <arpa/inet.h>
#include "glist.h"
#include "flist.h"
#include "network-inador-manager.h"
#include "resolv_conf_defs.h"
@ -76,10 +76,10 @@ int wait_for_ack_or_error (int s) {
return -1;
}
GList * helper_parser_parse_input (GList *all_entries, FILE *fd, int origin) {
FList * helper_parser_parse_input (FList *all_entries, FILE *fd, int origin) {
char buffer[8192], value[2048];
ResolvConfEntry *entry = NULL;
GList *pos, *next;
FList *pos, *next;
int g, len;
struct_addr direccion;
int type;
@ -112,7 +112,7 @@ GList * helper_parser_parse_input (GList *all_entries, FILE *fd, int origin) {
entry->owner_interface_index = 0;
entry->owner_prog[0] = 0;
all_entries = g_list_append (all_entries, entry);
all_entries = f_list_append (all_entries, entry);
entry->tagged = 1;
entry->file_order = order++;
}
@ -120,10 +120,10 @@ GList * helper_parser_parse_input (GList *all_entries, FILE *fd, int origin) {
return all_entries;
}
void send_entries (int s, GList *entries, const char *iface_prog) {
void send_entries (int s, FList *entries, const char *iface_prog) {
char buffer[2048];
int pos, len, pos_name_count;
GList *g;
FList *g;
int n;
ResolvConfEntry *entry;
@ -194,7 +194,7 @@ int main (int argc, char *argv[]) {
int next_option;
const char *iface_prog = NULL;
int action = 0;
GList *entries;
FList *entries;
int s, ret;
struct sockaddr_un path_dest;