From dab460efb6aaa1a3f4fbc96a497fb666f05d60d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Arreola=20Rodr=C3=ADguez?= Date: Tue, 9 Jan 2024 23:02:39 -0600 Subject: [PATCH] =?UTF-8?q?Reorganizo=20el=20c=C3=B3digo=20para=20separar?= =?UTF-8?q?=20el=20network-inador=20como=20librer=C3=ADa.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 + Makefile.am | 2 +- client-gtk/Makefile.am | 2 +- client-gtk/main.c | 2 +- client-gtk/ni-interface-chooser-dialog.c | 2 +- client-gtk/ni-window-interface.c | 2 +- common/Makefile.am | 12 + src/glist.c => common/flist.c | 694 +++++++++--------- common/flist.h | 150 ++++ common/network-inador-manager.h | 109 +++ {src => common}/resolv_conf_parser.c | 16 +- {src => common}/resolv_conf_parser.h | 10 +- {src => common}/utils.c | 2 +- {src => common}/utils.h | 0 configure.ac | 10 +- lib/Makefile.am | 35 + {src => lib}/bridge.c | 2 +- {src => lib}/bridge.h | 0 {src => lib}/dhcp_client.c | 106 ++- {src => lib}/dhcp_client.h | 5 +- {src => lib}/dhcpc_defs.h | 6 +- lib/handle.c | 314 ++++++++ {src => lib}/interfaces.c | 58 +- {src => lib}/interfaces.h | 63 +- {src => lib}/ip-address.c | 32 +- {src => lib}/ip-address.h | 30 +- lib/launch_process.c | 331 +++++++++ lib/launch_process.h | 29 + lib/netlink-events.c | 91 +++ {src => lib}/netlink-events.h | 12 +- .../network-inador-link-types.h | 0 lib/network-inador-private.h | 75 ++ lib/network-inador.h | 76 ++ lib/network-inador.pc.in | 11 + {src => lib}/resolv_conf_defs.h | 0 {src => lib}/resolv_manager.c | 32 +- {src => lib}/resolv_manager.h | 3 +- {src => lib}/routes.c | 115 +-- {src => lib}/routes.h | 44 +- {src => lib}/struct_addr_union.h | 0 {src => lib}/veth.c | 2 +- {src => lib}/veth.h | 0 {src => lib}/wireless_bss.c | 8 +- {src => lib}/wireless_bss.h | 2 - {src => lib}/wireless_if.c | 14 +- {src => lib}/wireless_if.h | 7 +- lib/wireless_security.c | 24 + lib/wireless_security.h | 27 + lib/wireless_struct.h | 78 ++ src/Makefile.am | 34 +- src/common.h | 261 ------- src/glist.h | 152 ---- src/main.c | 185 +++-- src/manager.c | 2 +- src/netlink-events.c | 160 ---- src/resolv_conf_helper.c | 14 +- 56 files changed, 2263 insertions(+), 1194 deletions(-) create mode 100644 common/Makefile.am rename src/glist.c => common/flist.c (57%) create mode 100644 common/flist.h create mode 100644 common/network-inador-manager.h rename {src => common}/resolv_conf_parser.c (94%) rename {src => common}/resolv_conf_parser.h (84%) rename {src => common}/utils.c (96%) rename {src => common}/utils.h (100%) create mode 100644 lib/Makefile.am rename {src => lib}/bridge.c (99%) rename {src => lib}/bridge.h (100%) rename {src => lib}/dhcp_client.c (83%) rename {src => lib}/dhcp_client.h (94%) rename {src => lib}/dhcpc_defs.h (96%) create mode 100644 lib/handle.c rename {src => lib}/interfaces.c (92%) rename {src => lib}/interfaces.h (57%) rename {src => lib}/ip-address.c (94%) rename {src => lib}/ip-address.h (75%) create mode 100644 lib/launch_process.c create mode 100644 lib/launch_process.h create mode 100644 lib/netlink-events.c rename {src => lib}/netlink-events.h (74%) rename src/link-types.h => lib/network-inador-link-types.h (100%) create mode 100644 lib/network-inador-private.h create mode 100644 lib/network-inador.h create mode 100644 lib/network-inador.pc.in rename {src => lib}/resolv_conf_defs.h (100%) rename {src => lib}/resolv_manager.c (95%) rename {src => lib}/resolv_manager.h (96%) rename {src => lib}/routes.c (88%) rename {src => lib}/routes.h (65%) rename {src => lib}/struct_addr_union.h (100%) rename {src => lib}/veth.c (99%) rename {src => lib}/veth.h (100%) rename {src => lib}/wireless_bss.c (97%) rename {src => lib}/wireless_bss.h (98%) rename {src => lib}/wireless_if.c (98%) rename {src => lib}/wireless_if.h (93%) create mode 100644 lib/wireless_security.c create mode 100644 lib/wireless_security.h create mode 100644 lib/wireless_struct.h delete mode 100644 src/common.h delete mode 100644 src/glist.h delete mode 100644 src/netlink-events.c diff --git a/.gitignore b/.gitignore index 063e57f..0aa34bc 100644 --- a/.gitignore +++ b/.gitignore @@ -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 *~ diff --git a/Makefile.am b/Makefile.am index 9494687..78bd4f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = src client-gtk po +SUBDIRS = common lib src client-gtk po ACLOCAL_AMFLAGS = -I m4 diff --git a/client-gtk/Makefile.am b/client-gtk/Makefile.am index 643e560..9fe88eb 100644 --- a/client-gtk/Makefile.am +++ b/client-gtk/Makefile.am @@ -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) diff --git a/client-gtk/main.c b/client-gtk/main.c index ea58eb5..436b0dd 100644 --- a/client-gtk/main.c +++ b/client-gtk/main.c @@ -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, diff --git a/client-gtk/ni-interface-chooser-dialog.c b/client-gtk/ni-interface-chooser-dialog.c index 3648759..a22385c 100644 --- a/client-gtk/ni-interface-chooser-dialog.c +++ b/client-gtk/ni-interface-chooser-dialog.c @@ -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, diff --git a/client-gtk/ni-window-interface.c b/client-gtk/ni-window-interface.c index 4b55da7..5afb26f 100644 --- a/client-gtk/ni-window-interface.c +++ b/client-gtk/ni-window-interface.c @@ -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" diff --git a/common/Makefile.am b/common/Makefile.am new file mode 100644 index 0000000..76f642b --- /dev/null +++ b/common/Makefile.am @@ -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) diff --git a/src/glist.c b/common/flist.c similarity index 57% rename from src/glist.c rename to common/flist.c index f4d6eea..5bc8a77 100644 --- a/src/glist.c +++ b/common/flist.c @@ -29,14 +29,14 @@ #include #include -#include "glist.h" +#include "flist.h" /** * SECTION:linked_lists_double * @title: Doubly-Linked Lists * @short_description: linked lists that can be iterated over in both directions * - * The #GList structure and its associated functions provide a standard + * The #FList structure and its associated functions provide a standard * doubly-linked list data structure. * * Each element in the list contains a piece of data, together with @@ -58,74 +58,74 @@ * List elements are allocated from the [slice allocator][glib-Memory-Slices], * which is more efficient than allocating elements individually. * - * Note that most of the #GList functions expect to be passed a pointer + * Note that most of the #FList functions expect to be passed a pointer * to the first element in the list. The functions which insert * elements return the new start of the list, which may have changed. * - * There is no function to create a #GList. %NULL is considered to be - * a valid, empty list so you simply set a #GList* to %NULL to initialize + * There is no function to create a #FList. %NULL is considered to be + * a valid, empty list so you simply set a #FList* to %NULL to initialize * it. * - * To add elements, use g_list_append(), g_list_prepend(), - * g_list_insert() and g_list_insert_sorted(). + * To add elements, use f_list_append(), f_list_prepend(), + * f_list_insert() and f_list_insert_sorted(). * * To visit all elements in the list, use a loop over the list: * |[ - * GList *l; + * FList *l; * for (l = list; l != NULL; l = l->next) * { * // do something with l->data * } * ]| * - * To call a function for each element in the list, use g_list_foreach(). + * To call a function for each element in the list, use f_list_foreach(). * * To loop over the list and modify it (e.g. remove a certain element) * a while loop is more appropriate, for example: * |[ - * GList *l = list; + * FList *l = list; * while (l != NULL) * { - * GList *next = l->next; + * FList *next = l->next; * if (should_be_removed (l)) * { * // possibly free l->data - * list = g_list_delete_link (list, l); + * list = f_list_delete_link (list, l); * } * l = next; * } * ]| * - * To remove elements, use g_list_remove(). + * To remove elements, use f_list_remove(). * - * To navigate in a list, use g_list_first(), g_list_last(), - * g_list_next(), g_list_previous(). + * To navigate in a list, use f_list_first(), f_list_last(), + * f_list_next(), f_list_previous(). * - * To find elements in the list use g_list_nth(), g_list_nth_data(), - * g_list_find() and g_list_find_custom(). + * To find elements in the list use f_list_nth(), f_list_nth_data(), + * f_list_find() and f_list_find_custom(). * - * To find the index of an element use g_list_position() and - * g_list_index(). + * To find the index of an element use f_list_position() and + * f_list_index(). * - * To free the entire list, use g_list_free() or g_list_free_full(). + * To free the entire list, use f_list_free() or f_list_free_full(). */ /** - * GList: + * FList: * @data: holds the element's data, which can be a pointer to any kind * of data, or any integer value using the * [Type Conversion Macros][glib-Type-Conversion-Macros] * @next: contains the link to the next element in the list * @prev: contains the link to the previous element in the list * - * The #GList struct is used for each element in a doubly-linked list. + * The #FList struct is used for each element in a doubly-linked list. **/ /** - * g_list_previous: - * @list: an element in a #GList + * f_list_previous: + * @list: an element in a #FList * - * A convenience macro to get the previous element in a #GList. + * A convenience macro to get the previous element in a #FList. * Note that it is considered perfectly acceptable to access * @list->previous directly. * @@ -134,49 +134,49 @@ **/ /** - * g_list_next: - * @list: an element in a #GList + * f_list_next: + * @list: an element in a #FList * - * A convenience macro to get the next element in a #GList. + * A convenience macro to get the next element in a #FList. * Note that it is considered perfectly acceptable to access * @list->next directly. * * Returns: the next element, or %NULL if there are no more elements **/ -#define _g_list_alloc() ((GList *) malloc (sizeof (GList))) -#define _g_list_alloc0() ((GList *) calloc (1, sizeof (GList))) -#define _g_list_free1(list) free (list) +#define _f_list_alloc() ((FList *) malloc (sizeof (FList))) +#define _f_list_alloc0() ((FList *) calloc (1, sizeof (FList))) +#define _f_list_free1(list) free (list) /** - * g_list_alloc: + * f_list_alloc: * - * Allocates space for one #GList element. It is called by - * g_list_append(), g_list_prepend(), g_list_insert() and - * g_list_insert_sorted() and so is rarely used on its own. + * Allocates space for one #FList element. It is called by + * f_list_append(), f_list_prepend(), f_list_insert() and + * f_list_insert_sorted() and so is rarely used on its own. * - * Returns: a pointer to the newly-allocated #GList element + * Returns: a pointer to the newly-allocated #FList element **/ -GList * -g_list_alloc (void) +FList * +f_list_alloc (void) { - return _g_list_alloc0 (); + return _f_list_alloc0 (); } /** - * g_list_free: - * @list: a #GList + * f_list_free: + * @list: a #FList * - * Frees all of the memory used by a #GList. + * Frees all of the memory used by a #FList. * The freed elements are returned to the slice allocator. * * If list elements contain dynamically-allocated memory, you should - * either use g_list_free_full() or free them manually first. + * either use f_list_free_full() or free them manually first. */ void -g_list_free (GList *list) +f_list_free (FList *list) { - GList *n; + FList *n; while (list != NULL) { n = list->next; @@ -187,47 +187,47 @@ g_list_free (GList *list) } /** - * g_list_free_1: - * @list: a #GList element + * f_list_free_1: + * @list: a #FList element * - * Frees one #GList element, but does not update links from the next and + * Frees one #FList element, but does not update links from the next and * previous elements in the list, so you should not call this function on an * element that is currently part of a list. * - * It is usually used after g_list_remove_link(). + * It is usually used after f_list_remove_link(). */ /** - * g_list_free1: + * f_list_free1: * - * Another name for g_list_free_1(). + * Another name for f_list_free_1(). **/ void -g_list_free_1 (GList *list) +f_list_free_1 (FList *list) { - _g_list_free1 (list); + _f_list_free1 (list); } /** - * g_list_free_full: - * @list: a pointer to a #GList + * f_list_free_full: + * @list: a pointer to a #FList * @free_func: the function to be called to free each element's data * - * Convenience method, which frees all the memory used by a #GList, + * Convenience method, which frees all the memory used by a #FList, * and calls @free_func on every element's data. * * Since: 2.28 */ void -g_list_free_full (GList *list, - GDestroyNotify free_func) +f_list_free_full (FList *list, + FDestroyNotify free_func) { - g_list_foreach (list, (GFunc) free_func, NULL); - g_list_free (list); + f_list_foreach (list, (FFunc) free_func, NULL); + f_list_free (list); } /** - * g_list_append: - * @list: a pointer to a #GList + * f_list_append: + * @list: a pointer to a #FList * @data: the data for the new element * * Adds a new element on to the end of the list. @@ -235,40 +235,40 @@ g_list_free_full (GList *list, * Note that the return value is the new start of the list, * if @list was empty; make sure you store the new value. * - * g_list_append() has to traverse the entire list to find the end, + * f_list_append() has to traverse the entire list to find the end, * which is inefficient when adding multiple elements. A common idiom - * to avoid the inefficiency is to use g_list_prepend() and reverse - * the list with g_list_reverse() when all elements have been added. + * to avoid the inefficiency is to use f_list_prepend() and reverse + * the list with f_list_reverse() when all elements have been added. * * |[ * // Notice that these are initialized to the empty list. - * GList *string_list = NULL, *number_list = NULL; + * FList *strinf_list = NULL, *number_list = NULL; * * // This is a list of strings. - * string_list = g_list_append (string_list, "first"); - * string_list = g_list_append (string_list, "second"); + * strinf_list = f_list_append (strinf_list, "first"); + * strinf_list = f_list_append (strinf_list, "second"); * * // This is a list of integers. - * number_list = g_list_append (number_list, int_TO_POINTER (27)); - * number_list = g_list_append (number_list, int_TO_POINTER (14)); + * number_list = f_list_append (number_list, int_TO_POINTER (27)); + * number_list = f_list_append (number_list, int_TO_POINTER (14)); * ]| * - * Returns: either @list or the new start of the #GList if @list was %NULL + * Returns: either @list or the new start of the #FList if @list was %NULL */ -GList * -g_list_append (GList *list, - gpointer data) +FList * +f_list_append (FList *list, + void * data) { - GList *new_list; - GList *last; + FList *new_list; + FList *last; - new_list = _g_list_alloc (); + new_list = _f_list_alloc (); new_list->data = data; new_list->next = NULL; if (list) { - last = g_list_last (list); + last = f_list_last (list); /* g_assert (last != NULL); */ last->next = new_list; new_list->prev = last; @@ -283,8 +283,8 @@ g_list_append (GList *list, } /** - * g_list_prepend: - * @list: a pointer to a #GList, this must point to the top of the list + * f_list_prepend: + * @list: a pointer to a #FList, this must point to the top of the list * @data: the data for the new element * * Prepends a new element on to the start of the list. @@ -294,25 +294,25 @@ g_list_append (GList *list, * * |[ * // Notice that it is initialized to the empty list. - * GList *list = NULL; + * FList *list = NULL; * - * list = g_list_prepend (list, "last"); - * list = g_list_prepend (list, "first"); + * list = f_list_prepend (list, "last"); + * list = f_list_prepend (list, "first"); * ]| * * Do not use this function to prepend a new element to a different - * element than the start of the list. Use g_list_insert_before() instead. + * element than the start of the list. Use f_list_insert_before() instead. * * Returns: a pointer to the newly prepended element, which is the new - * start of the #GList + * start of the #FList */ -GList * -g_list_prepend (GList *list, - gpointer data) +FList * +f_list_prepend (FList *list, + void * data) { - GList *new_list; + FList *new_list; - new_list = _g_list_alloc (); + new_list = _f_list_alloc (); new_list->data = data; new_list->next = list; @@ -330,8 +330,8 @@ g_list_prepend (GList *list, } /** - * g_list_insert: - * @list: a pointer to a #GList, this must point to the top of the list + * f_list_insert: + * @list: a pointer to a #FList, this must point to the top of the list * @data: the data for the new element * @position: the position to insert the element. If this is * negative, or is larger than the number of elements in the @@ -339,26 +339,26 @@ g_list_prepend (GList *list, * * Inserts a new element into the list at the given position. * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ -GList * -g_list_insert (GList *list, - gpointer data, +FList * +f_list_insert (FList *list, + void * data, int position) { - GList *new_list; - GList *tmp_list; + FList *new_list; + FList *tmp_list; if (position < 0) - return g_list_append (list, data); + return f_list_append (list, data); else if (position == 0) - return g_list_prepend (list, data); + return f_list_prepend (list, data); - tmp_list = g_list_nth (list, position); + tmp_list = f_list_nth (list, position); if (!tmp_list) - return g_list_append (list, data); + return f_list_append (list, data); - new_list = _g_list_alloc (); + new_list = _f_list_alloc (); new_list->data = data; new_list->prev = tmp_list->prev; tmp_list->prev->next = new_list; @@ -369,24 +369,24 @@ g_list_insert (GList *list, } /** - * g_list_insert_before: - * @list: a pointer to a #GList, this must point to the top of the list + * f_list_insert_before: + * @list: a pointer to a #FList, this must point to the top of the list * @sibling: the list element before which the new element * is inserted or %NULL to insert at the end of the list * @data: the data for the new element * * Inserts a new element into the list before the given position. * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ -GList * -g_list_insert_before (GList *list, - GList *sibling, - gpointer data) +FList * +f_list_insert_before (FList *list, + FList *sibling, + void * data) { if (!list) { - list = g_list_alloc (); + list = f_list_alloc (); list->data = data; //if (sibling != NULL) return list; //g_return_val_if_fail (sibling == NULL, list); @@ -394,9 +394,9 @@ g_list_insert_before (GList *list, } else if (sibling) { - GList *node; + FList *node; - node = _g_list_alloc (); + node = _f_list_alloc (); node->data = data; node->prev = sibling->prev; node->next = sibling; @@ -414,13 +414,13 @@ g_list_insert_before (GList *list, } else { - GList *last; + FList *last; last = list; while (last->next) last = last->next; - last->next = _g_list_alloc (); + last->next = _f_list_alloc (); last->next->data = data; last->next->prev = last; last->next->next = NULL; @@ -430,33 +430,33 @@ g_list_insert_before (GList *list, } /** - * g_list_concat: - * @list1: a #GList, this must point to the top of the list - * @list2: the #GList to add to the end of the first #GList, + * f_list_concat: + * @list1: a #FList, this must point to the top of the list + * @list2: the #FList to add to the end of the first #FList, * this must point to the top of the list * - * Adds the second #GList onto the end of the first #GList. - * Note that the elements of the second #GList are not copied. + * Adds the second #FList onto the end of the first #FList. + * Note that the elements of the second #FList are not copied. * They are used directly. * * This function is for example used to move an element in the list. * The following example moves an element to the top of the list: * |[ - * list = g_list_remove_link (list, llink); - * list = g_list_concat (llink, list); + * list = f_list_remove_link (list, llink); + * list = f_list_concat (llink, list); * ]| * - * Returns: the start of the new #GList, which equals @list1 if not %NULL + * Returns: the start of the new #FList, which equals @list1 if not %NULL */ -GList * -g_list_concat (GList *list1, - GList *list2) +FList * +f_list_concat (FList *list1, + FList *list2) { - GList *tmp_list; + FList *tmp_list; if (list2) { - tmp_list = g_list_last (list1); + tmp_list = f_list_last (list1); if (tmp_list) tmp_list->next = list2; else @@ -467,9 +467,9 @@ g_list_concat (GList *list1, return list1; } -static inline GList * -_g_list_remove_link (GList *list, - GList *link) +static inline FList * +_f_list_remove_link (FList *list, + FList *link) { if (link == NULL) return list; @@ -478,7 +478,7 @@ _g_list_remove_link (GList *list, { if (link->prev->next == link) link->prev->next = link->next; - else + //else printf ("corrupted double-linked list detected"); } if (link->next) @@ -499,21 +499,21 @@ _g_list_remove_link (GList *list, } /** - * g_list_remove: - * @list: a #GList, this must point to the top of the list + * f_list_remove: + * @list: a #FList, this must point to the top of the list * @data: the data of the element to remove * - * Removes an element from a #GList. + * Removes an element from a #FList. * If two elements contain the same data, only the first is removed. - * If none of the elements contain the data, the #GList is unchanged. + * If none of the elements contain the data, the #FList is unchanged. * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ -GList * -g_list_remove (GList *list, - gconstpointer data) +FList * +f_list_remove (FList *list, + const void * data) { - GList *tmp; + FList *tmp; tmp = list; while (tmp) @@ -522,8 +522,8 @@ g_list_remove (GList *list, tmp = tmp->next; else { - list = _g_list_remove_link (list, tmp); - _g_list_free1 (tmp); + list = _f_list_remove_link (list, tmp); + _f_list_free1 (tmp); break; } @@ -532,22 +532,22 @@ g_list_remove (GList *list, } /** - * g_list_remove_all: - * @list: a #GList, this must point to the top of the list + * f_list_remove_all: + * @list: a #FList, this must point to the top of the list * @data: data to remove * * Removes all list nodes with data equal to @data. * Returns the new head of the list. Contrast with - * g_list_remove() which removes only the first node + * f_list_remove() which removes only the first node * matching the given data. * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ -GList * -g_list_remove_all (GList *list, - gconstpointer data) +FList * +f_list_remove_all (FList *list, + const void * data) { - GList *tmp = list; + FList *tmp = list; while (tmp) { @@ -555,7 +555,7 @@ g_list_remove_all (GList *list, tmp = tmp->next; else { - GList *next = tmp->next; + FList *next = tmp->next; if (tmp->prev) tmp->prev->next = next; @@ -564,7 +564,7 @@ g_list_remove_all (GList *list, if (next) next->prev = tmp->prev; - _g_list_free1 (tmp); + _f_list_free1 (tmp); tmp = next; } } @@ -572,115 +572,115 @@ g_list_remove_all (GList *list, } /** - * g_list_remove_link: - * @list: a #GList, this must point to the top of the list - * @llink: an element in the #GList + * f_list_remove_link: + * @list: a #FList, this must point to the top of the list + * @llink: an element in the #FList * - * Removes an element from a #GList, without freeing the element. + * Removes an element from a #FList, without freeing the element. * The removed element's prev and next links are set to %NULL, so * that it becomes a self-contained list with one element. * * This function is for example used to move an element in the list - * (see the example for g_list_concat()) or to remove an element in + * (see the example for f_list_concat()) or to remove an element in * the list before freeing its data: * |[ - * list = g_list_remove_link (list, llink); + * list = f_list_remove_link (list, llink); * free_some_data_that_may_access_the_list_again (llink->data); - * g_list_free (llink); + * f_list_free (llink); * ]| * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ -GList * -g_list_remove_link (GList *list, - GList *llink) +FList * +f_list_remove_link (FList *list, + FList *llink) { - return _g_list_remove_link (list, llink); + return _f_list_remove_link (list, llink); } /** - * g_list_delete_link: - * @list: a #GList, this must point to the top of the list + * f_list_delete_link: + * @list: a #FList, this must point to the top of the list * @link_: node to delete from @list * * Removes the node link_ from the list and frees it. - * Compare this to g_list_remove_link() which removes the node + * Compare this to f_list_remove_link() which removes the node * without freeing it. * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ -GList * -g_list_delete_link (GList *list, - GList *link_) +FList * +f_list_delete_link (FList *list, + FList *link_) { - list = _g_list_remove_link (list, link_); - _g_list_free1 (link_); + list = _f_list_remove_link (list, link_); + _f_list_free1 (link_); return list; } /** - * g_list_copy: - * @list: a #GList, this must point to the top of the list + * f_list_copy: + * @list: a #FList, this must point to the top of the list * - * Copies a #GList. + * Copies a #FList. * * Note that this is a "shallow" copy. If the list elements * consist of pointers to data, the pointers are copied but - * the actual data is not. See g_list_copy_deep() if you need + * the actual data is not. See f_list_copy_deep() if you need * to copy the data as well. * * Returns: the start of the new list that holds the same data as @list */ -GList * -g_list_copy (GList *list) +FList * +f_list_copy (FList *list) { - return g_list_copy_deep (list, NULL, NULL); + return f_list_copy_deep (list, NULL, NULL); } /** - * g_list_copy_deep: - * @list: a #GList, this must point to the top of the list + * f_list_copy_deep: + * @list: a #FList, this must point to the top of the list * @func: a copy function used to copy every element in the list * @user_data: user data passed to the copy function @func, or %NULL * - * Makes a full (deep) copy of a #GList. + * Makes a full (deep) copy of a #FList. * - * In contrast with g_list_copy(), this function uses @func to make + * In contrast with f_list_copy(), this function uses @func to make * a copy of each list element, in addition to copying the list * container itself. * - * @func, as a #GCopyFunc, takes two arguments, the data to be copied + * @func, as a #FCopyFunc, takes two arguments, the data to be copied * and a @user_data pointer. It's safe to pass %NULL as user_data, * if the copy function takes only one argument. * * For instance, if @list holds a list of GObjects, you can do: * |[ - * another_list = g_list_copy_deep (list, (GCopyFunc) g_object_ref, NULL); + * another_list = f_list_copy_deep (list, (FCopyFunc) g_object_ref, NULL); * ]| * * And, to entirely free the new list, you could do: * |[ - * g_list_free_full (another_list, g_object_unref); + * f_list_free_full (another_list, g_object_unref); * ]| * * Returns: the start of the new list that holds a full copy of @list, - * use g_list_free_full() to free it + * use f_list_free_full() to free it * * Since: 2.34 */ -GList * -g_list_copy_deep (GList *list, - GCopyFunc func, - gpointer user_data) +FList * +f_list_copy_deep (FList *list, + FCopyFunc func, + void * user_data) { - GList *new_list = NULL; + FList *new_list = NULL; if (list) { - GList *last; + FList *last; - new_list = _g_list_alloc (); + new_list = _f_list_alloc (); if (func) new_list->data = func (list->data, user_data); else @@ -690,7 +690,7 @@ g_list_copy_deep (GList *list, list = list->next; while (list) { - last->next = _g_list_alloc (); + last->next = _f_list_alloc (); last->next->prev = last; last = last->next; if (func) @@ -706,18 +706,18 @@ g_list_copy_deep (GList *list, } /** - * g_list_reverse: - * @list: a #GList, this must point to the top of the list + * f_list_reverse: + * @list: a #FList, this must point to the top of the list * - * Reverses a #GList. + * Reverses a #FList. * It simply switches the next and prev pointers of each element. * - * Returns: the start of the reversed #GList + * Returns: the start of the reversed #FList */ -GList * -g_list_reverse (GList *list) +FList * +f_list_reverse (FList *list) { - GList *last; + FList *last; last = NULL; while (list) @@ -732,21 +732,21 @@ g_list_reverse (GList *list) } /** - * g_list_nth: - * @list: a #GList, this must point to the top of the list + * f_list_nth: + * @list: a #FList, this must point to the top of the list * @n: the position of the element, counting from 0 * - * Gets the element at the given position in a #GList. + * Gets the element at the given position in a #FList. * * This iterates over the list until it reaches the @n-th position. If you * intend to iterate over every element, it is better to use a for-loop as - * described in the #GList introduction. + * described in the #FList introduction. * * Returns: the element, or %NULL if the position is off - * the end of the #GList + * the end of the #FList */ -GList * -g_list_nth (GList *list, +FList * +f_list_nth (FList *list, unsigned int n) { while ((n-- > 0) && list) @@ -756,17 +756,17 @@ g_list_nth (GList *list, } /** - * g_list_nth_prev: - * @list: a #GList + * f_list_nth_prev: + * @list: a #FList * @n: the position of the element, counting from 0 * * Gets the element @n places before @list. * * Returns: the element, or %NULL if the position is - * off the end of the #GList + * off the end of the #FList */ -GList * -g_list_nth_prev (GList *list, +FList * +f_list_nth_prev (FList *list, unsigned int n) { while ((n-- > 0) && list) @@ -776,21 +776,21 @@ g_list_nth_prev (GList *list, } /** - * g_list_nth_data: - * @list: a #GList, this must point to the top of the list + * f_list_nth_data: + * @list: a #FList, this must point to the top of the list * @n: the position of the element * * Gets the data of the element at the given position. * * This iterates over the list until it reaches the @n-th position. If you * intend to iterate over every element, it is better to use a for-loop as - * described in the #GList introduction. + * described in the #FList introduction. * * Returns: the element's data, or %NULL if the position - * is off the end of the #GList + * is off the end of the #FList */ -gpointer -g_list_nth_data (GList *list, +void * +f_list_nth_data (FList *list, unsigned int n) { while ((n-- > 0) && list) @@ -800,17 +800,17 @@ g_list_nth_data (GList *list, } /** - * g_list_find: - * @list: a #GList, this must point to the top of the list + * f_list_find: + * @list: a #FList, this must point to the top of the list * @data: the element data to find * - * Finds the element in a #GList which contains the given data. + * Finds the element in a #FList which contains the given data. * - * Returns: the found #GList element, or %NULL if it is not found + * Returns: the found #FList element, or %NULL if it is not found */ -GList * -g_list_find (GList *list, - gconstpointer data) +FList * +f_list_find (FList *list, + const void * data) { while (list) { @@ -823,25 +823,25 @@ g_list_find (GList *list, } /** - * g_list_find_custom: - * @list: a #GList, this must point to the top of the list + * f_list_find_custom: + * @list: a #FList, this must point to the top of the list * @data: user data passed to the function * @func: the function to call for each element. * It should return 0 when the desired element is found * - * Finds an element in a #GList, using a supplied function to + * Finds an element in a #FList, using a supplied function to * find the desired element. It iterates over the list, calling * the given function which should return 0 when the desired - * element is found. The function takes two #gconstpointer arguments, - * the #GList element's data as the first argument and the + * element is found. The function takes two #const void * arguments, + * the #FList element's data as the first argument and the * given user data. * - * Returns: the found #GList element, or %NULL if it is not found + * Returns: the found #FList element, or %NULL if it is not found */ -GList * -g_list_find_custom (GList *list, - gconstpointer data, - GCompareFunc func) +FList * +f_list_find_custom (FList *list, + const void * data, + FCompareFunc func) { if (func == NULL) return list; //g_return_val_if_fail (func != NULL, list); @@ -857,19 +857,19 @@ g_list_find_custom (GList *list, } /** - * g_list_position: - * @list: a #GList, this must point to the top of the list - * @llink: an element in the #GList + * f_list_position: + * @list: a #FList, this must point to the top of the list + * @llink: an element in the #FList * * Gets the position of the given element - * in the #GList (starting from 0). + * in the #FList (starting from 0). * - * Returns: the position of the element in the #GList, + * Returns: the position of the element in the #FList, * or -1 if the element is not found */ int -g_list_position (GList *list, - GList *llink) +f_list_position (FList *list, + FList *llink) { int i; @@ -886,8 +886,8 @@ g_list_position (GList *list, } /** - * g_list_index: - * @list: a #GList, this must point to the top of the list + * f_list_index: + * @list: a #FList, this must point to the top of the list * @data: the data to find * * Gets the position of the element containing @@ -897,8 +897,8 @@ g_list_position (GList *list, * or -1 if the data is not found */ int -g_list_index (GList *list, - gconstpointer data) +f_list_index (FList *list, + const void * data) { int i; @@ -915,16 +915,16 @@ g_list_index (GList *list, } /** - * g_list_last: - * @list: any #GList element + * f_list_last: + * @list: any #FList element * - * Gets the last element in a #GList. + * Gets the last element in a #FList. * - * Returns: the last element in the #GList, - * or %NULL if the #GList has no elements + * Returns: the last element in the #FList, + * or %NULL if the #FList has no elements */ -GList * -g_list_last (GList *list) +FList * +f_list_last (FList *list) { if (list) { @@ -936,16 +936,16 @@ g_list_last (GList *list) } /** - * g_list_first: - * @list: any #GList element + * f_list_first: + * @list: any #FList element * - * Gets the first element in a #GList. + * Gets the first element in a #FList. * - * Returns: the first element in the #GList, - * or %NULL if the #GList has no elements + * Returns: the first element in the #FList, + * or %NULL if the #FList has no elements */ -GList * -g_list_first (GList *list) +FList * +f_list_first (FList *list) { if (list) { @@ -957,20 +957,20 @@ g_list_first (GList *list) } /** - * g_list_length: - * @list: a #GList, this must point to the top of the list + * f_list_length: + * @list: a #FList, this must point to the top of the list * - * Gets the number of elements in a #GList. + * Gets the number of elements in a #FList. * * This function iterates over the whole list to count its elements. - * Use a #GQueue instead of a GList if you regularly need the number + * Use a #GQueue instead of a FList if you regularly need the number * of items. To check whether the list is non-empty, it is faster to check * @list against %NULL. * - * Returns: the number of elements in the #GList + * Returns: the number of elements in the #FList */ unsigned int -g_list_length (GList *list) +f_list_length (FList *list) { unsigned int length; @@ -985,42 +985,42 @@ g_list_length (GList *list) } /** - * g_list_foreach: - * @list: a #GList, this must point to the top of the list + * f_list_foreach: + * @list: a #FList, this must point to the top of the list * @func: the function to call with each element's data * @user_data: user data to pass to the function * - * Calls a function for each element of a #GList. + * Calls a function for each element of a #FList. */ /** - * GFunc: + * FFunc: * @data: the element's data - * @user_data: user data passed to g_list_foreach() or g_slist_foreach() + * @user_data: user data passed to f_list_foreach() or g_slist_foreach() * - * Specifies the type of functions passed to g_list_foreach() and + * Specifies the type of functions passed to f_list_foreach() and * g_slist_foreach(). */ void -g_list_foreach (GList *list, - GFunc func, - gpointer user_data) +f_list_foreach (FList *list, + FFunc func, + void * user_data) { while (list) { - GList *next = list->next; + FList *next = list->next; (*func) (list->data, user_data); list = next; } } -static GList* -g_list_insert_sorted_real (GList *list, - gpointer data, - GFunc func, - gpointer user_data) +static FList* +f_list_insert_sorted_real (FList *list, + void * data, + FFunc func, + void * user_data) { - GList *tmp_list = list; - GList *new_list; + FList *tmp_list = list; + FList *new_list; int cmp; if (func == NULL) return list; @@ -1028,21 +1028,21 @@ g_list_insert_sorted_real (GList *list, if (!list) { - new_list = _g_list_alloc0 (); + new_list = _f_list_alloc0 (); new_list->data = data; return new_list; } - cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); + cmp = ((FCompareDataFunc) func) (data, tmp_list->data, user_data); while ((tmp_list->next) && (cmp > 0)) { tmp_list = tmp_list->next; - cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); + cmp = ((FCompareDataFunc) func) (data, tmp_list->data, user_data); } - new_list = _g_list_alloc0 (); + new_list = _f_list_alloc0 (); new_list->data = data; if ((!tmp_list->next) && (cmp > 0)) @@ -1067,8 +1067,8 @@ g_list_insert_sorted_real (GList *list, } /** - * g_list_insert_sorted: - * @list: a pointer to a #GList, this must point to the top of the + * f_list_insert_sorted: + * @list: a pointer to a #FList, this must point to the top of the * already sorted list * @data: the data for the new element * @func: the function to compare elements in the list. It should @@ -1080,22 +1080,22 @@ g_list_insert_sorted_real (GList *list, * * If you are adding many new elements to a list, and the number of * new elements is much larger than the length of the list, use - * g_list_prepend() to add the new items and sort the list afterwards - * with g_list_sort(). + * f_list_prepend() to add the new items and sort the list afterwards + * with f_list_sort(). * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ -GList * -g_list_insert_sorted (GList *list, - gpointer data, - GCompareFunc func) +FList * +f_list_insert_sorted (FList *list, + void * data, + FCompareFunc func) { - return g_list_insert_sorted_real (list, data, (GFunc) func, NULL); + return f_list_insert_sorted_real (list, data, (FFunc) func, NULL); } /** - * g_list_insert_sorted_with_data: - * @list: a pointer to a #GList, this must point to the top of the + * f_list_insert_sorted_with_data: + * @list: a pointer to a #FList, this must point to the top of the * already sorted list * @data: the data for the new element * @func: the function to compare elements in the list. It should @@ -1108,29 +1108,29 @@ g_list_insert_sorted (GList *list, * * If you are adding many new elements to a list, and the number of * new elements is much larger than the length of the list, use - * g_list_prepend() to add the new items and sort the list afterwards - * with g_list_sort(). + * f_list_prepend() to add the new items and sort the list afterwards + * with f_list_sort(). * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList * * Since: 2.10 */ -GList * -g_list_insert_sorted_with_data (GList *list, - gpointer data, - GCompareDataFunc func, - gpointer user_data) +FList * +f_list_insert_sorted_with_data (FList *list, + void * data, + FCompareDataFunc func, + void * user_data) { - return g_list_insert_sorted_real (list, data, (GFunc) func, user_data); + return f_list_insert_sorted_real (list, data, (FFunc) func, user_data); } -static GList * -g_list_sort_merge (GList *l1, - GList *l2, - GFunc compare_func, - gpointer user_data) +static FList * +f_list_sort_merge (FList *l1, + FList *l2, + FFunc compare_func, + void * user_data) { - GList list, *l, *lprev; + FList list, *l, *lprev; int cmp; l = &list; @@ -1138,7 +1138,7 @@ g_list_sort_merge (GList *l1, while (l1 && l2) { - cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data); + cmp = ((FCompareDataFunc) compare_func) (l1->data, l2->data, user_data); if (cmp <= 0) { @@ -1160,12 +1160,12 @@ g_list_sort_merge (GList *l1, return list.next; } -static GList * -g_list_sort_real (GList *list, - GFunc compare_func, - gpointer user_data) +static FList * +f_list_sort_real (FList *list, + FFunc compare_func, + void * user_data) { - GList *l1, *l2; + FList *l1, *l2; if (!list) return NULL; @@ -1184,28 +1184,28 @@ g_list_sort_real (GList *list, l2 = l1->next; l1->next = NULL; - return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data), - g_list_sort_real (l2, compare_func, user_data), + return f_list_sort_merge (f_list_sort_real (list, compare_func, user_data), + f_list_sort_real (l2, compare_func, user_data), compare_func, user_data); } /** - * g_list_sort: - * @list: a #GList, this must point to the top of the list - * @compare_func: the comparison function used to sort the #GList. - * This function is passed the data from 2 elements of the #GList + * f_list_sort: + * @list: a #FList, this must point to the top of the list + * @compare_func: the comparison function used to sort the #FList. + * This function is passed the data from 2 elements of the #FList * and should return 0 if they are equal, a negative value if the * first element comes before the second, or a positive value if * the first element comes after the second. * - * Sorts a #GList using the given comparison function. The algorithm + * Sorts a #FList using the given comparison function. The algorithm * used is a stable sort. * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ /** - * GCompareFunc: + * FCompareFunc: * @a: a value * @b: a value to compare with * @@ -1217,26 +1217,26 @@ g_list_sort_real (GList *list, * Returns: negative value if @a < @b; zero if @a = @b; positive * value if @a > @b */ -GList * -g_list_sort (GList *list, - GCompareFunc compare_func) +FList * +f_list_sort (FList *list, + FCompareFunc compare_func) { - return g_list_sort_real (list, (GFunc) compare_func, NULL); + return f_list_sort_real (list, (FFunc) compare_func, NULL); } /** - * g_list_sort_with_data: - * @list: a #GList, this must point to the top of the list + * f_list_sort_with_data: + * @list: a #FList, this must point to the top of the list * @compare_func: comparison function * @user_data: user data to pass to comparison function * - * Like g_list_sort(), but the comparison function accepts + * Like f_list_sort(), but the comparison function accepts * a user data argument. * - * Returns: the (possibly changed) start of the #GList + * Returns: the (possibly changed) start of the #FList */ /** - * GCompareDataFunc: + * FCompareDataFunc: * @a: a value * @b: a value to compare with * @user_data: user data @@ -1249,10 +1249,10 @@ g_list_sort (GList *list, * Returns: negative value if @a < @b; zero if @a = @b; positive * value if @a > @b */ -GList * -g_list_sort_with_data (GList *list, - GCompareDataFunc compare_func, - gpointer user_data) +FList * +f_list_sort_with_data (FList *list, + FCompareDataFunc compare_func, + void * user_data) { - return g_list_sort_real (list, (GFunc) compare_func, user_data); + return f_list_sort_real (list, (FFunc) compare_func, user_data); } diff --git a/common/flist.h b/common/flist.h new file mode 100644 index 0000000..5ea783b --- /dev/null +++ b/common/flist.h @@ -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 . + */ + +/* + * 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__ */ diff --git a/common/network-inador-manager.h b/common/network-inador-manager.h new file mode 100644 index 0000000..ffd4cb7 --- /dev/null +++ b/common/network-inador-manager.h @@ -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__ */ + diff --git a/src/resolv_conf_parser.c b/common/resolv_conf_parser.c similarity index 94% rename from src/resolv_conf_parser.c rename to common/resolv_conf_parser.c index 5261e23..f098649 100644 --- a/src/resolv_conf_parser.c +++ b/common/resolv_conf_parser.c @@ -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++; diff --git a/src/resolv_conf_parser.h b/common/resolv_conf_parser.h similarity index 84% rename from src/resolv_conf_parser.h rename to common/resolv_conf_parser.h index fea694f..52f93bd 100644 --- a/src/resolv_conf_parser.h +++ b/common/resolv_conf_parser.h @@ -26,15 +26,11 @@ #include #include -#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__ */ diff --git a/src/utils.c b/common/utils.c similarity index 96% rename from src/utils.c rename to common/utils.c index 7676f22..2e39407 100644 --- a/src/utils.c +++ b/common/utils.c @@ -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); diff --git a/src/utils.h b/common/utils.h similarity index 100% rename from src/utils.h rename to common/utils.h diff --git a/configure.ac b/configure.ac index 6e7edf3..8357dbe 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..040283c --- /dev/null +++ b/lib/Makefile.am @@ -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 diff --git a/src/bridge.c b/lib/bridge.c similarity index 99% rename from src/bridge.c rename to lib/bridge.c index 6c01e5e..bd7288f 100644 --- a/src/bridge.c +++ b/lib/bridge.c @@ -35,7 +35,7 @@ #include #include -#include "common.h" +#include "network-inador-private.h" #include "interfaces.h" int interfaces_bridge_create (NetworkInadorHandle *handle, const char *name) { diff --git a/src/bridge.h b/lib/bridge.h similarity index 100% rename from src/bridge.h rename to lib/bridge.h diff --git a/src/dhcp_client.c b/lib/dhcp_client.c similarity index 83% rename from src/dhcp_client.c rename to lib/dhcp_client.c index 27eed6e..2146975 100644 --- a/src/dhcp_client.c +++ b/lib/dhcp_client.c @@ -34,18 +34,20 @@ #include #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,22 +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, @@ -118,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; } } @@ -155,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); @@ -168,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)); @@ -186,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, @@ -197,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; } @@ -212,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; } @@ -239,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; @@ -253,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; @@ -377,6 +417,6 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand resolv_manager_clear_dhcp_nameservers (handle, iface); } - manager_send_event_dhcp_change (handle, &iface->dhcpc); + //manager_send_event_dhcp_change (handle, &iface->dhcpc); } diff --git a/src/dhcp_client.h b/lib/dhcp_client.h similarity index 94% rename from src/dhcp_client.h rename to lib/dhcp_client.h index cd82aaa..69427cd 100644 --- a/src/dhcp_client.h +++ b/lib/dhcp_client.h @@ -23,7 +23,10 @@ #ifndef __DHCP_CLIENT_H__ #define __DHCP_CLIENT_H__ -#include "common.h" +#include + +#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); diff --git a/src/dhcpc_defs.h b/lib/dhcpc_defs.h similarity index 96% rename from src/dhcpc_defs.h rename to lib/dhcpc_defs.h index d8a5b21..5f8cbbc 100644 --- a/src/dhcpc_defs.h +++ b/lib/dhcpc_defs.h @@ -24,7 +24,7 @@ #define __DHCPC_DEFS_H__ #include -#include +#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; diff --git a/lib/handle.c b/lib/handle.c new file mode 100644 index 0000000..ba104e0 --- /dev/null +++ b/lib/handle.c @@ -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 +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#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); +} + diff --git a/src/interfaces.c b/lib/interfaces.c similarity index 92% rename from src/interfaces.c rename to lib/interfaces.c index b474563..0d5ad2a 100644 --- a/src/interfaces.c +++ b/lib/interfaces.c @@ -27,16 +27,16 @@ #include -#include +#include -#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; @@ -218,6 +218,9 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, iface->vlan_parent = u32data; //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; @@ -233,18 +236,23 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, 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: - memcpy (iface->inet6_data.i6_conf, nla_data (sub_attr), sizeof (iface->inet6_data.i6_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)); @@ -278,18 +286,18 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, iface->link_type = interfaces_check_link_type (iface); - manager_send_event_interface_add (handle, iface); + //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; @@ -302,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; @@ -381,7 +389,7 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) { //printf ("Interface %d se sacó de su bridge\n", iface->index); /* Generar EVENTO AQUI */ - manager_send_event_interface_update (handle, iface); + //manager_send_event_interface_update (handle, iface); return NL_SKIP; } @@ -389,12 +397,12 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) { route_ask_delayed_delroute (handle); //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); } @@ -662,7 +670,8 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n return 0; } -/*int interfaces_set_sysctl_ipv6_params (NetworkInadorHandle *handle, int index, int param, ...) { +#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; @@ -745,7 +754,8 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n } return 0; -}*/ +} +#endif void interfaces_init (NetworkInadorHandle *handle) { /* Si es la primera vez que nos llaman, descargar una primera lista de interfaces */ @@ -776,18 +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; } diff --git a/src/interfaces.h b/lib/interfaces.h similarity index 57% rename from src/interfaces.h rename to lib/interfaces.h index c7839df..79f50c1 100644 --- a/src/interfaces.h +++ b/lib/interfaces.h @@ -25,8 +25,63 @@ #include #include +#include +#include -#include "common.h" +#include +#include + +#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 diff --git a/src/ip-address.c b/lib/ip-address.c similarity index 94% rename from src/ip-address.c rename to lib/ip-address.c index 95aa111..bd8b44a 100644 --- a/src/ip-address.c +++ b/lib/ip-address.c @@ -29,16 +29,14 @@ #include #include -#include - -#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"); diff --git a/src/ip-address.h b/lib/ip-address.h similarity index 75% rename from src/ip-address.h rename to lib/ip-address.h index 931bb2c..df360cb 100644 --- a/src/ip-address.h +++ b/lib/ip-address.h @@ -26,7 +26,35 @@ #include #include -#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); diff --git a/lib/launch_process.c b/lib/launch_process.c new file mode 100644 index 0000000..c5f2c11 --- /dev/null +++ b/lib/launch_process.c @@ -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 +#include +#include + +#include +#include +#include + +#include +#include +#include + +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; +} + diff --git a/lib/launch_process.h b/lib/launch_process.h new file mode 100644 index 0000000..e8472d9 --- /dev/null +++ b/lib/launch_process.h @@ -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__ */ + diff --git a/lib/netlink-events.c b/lib/netlink-events.c new file mode 100644 index 0000000..c334907 --- /dev/null +++ b/lib/netlink-events.c @@ -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 +#include + +#include +#include + +#include + +#include + +#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; + } +} + diff --git a/src/netlink-events.h b/lib/netlink-events.h similarity index 74% rename from src/netlink-events.h rename to lib/netlink-events.h index ad6cd40..ca7b776 100644 --- a/src/netlink-events.h +++ b/lib/netlink-events.h @@ -23,11 +23,13 @@ #ifndef __NETLINK_EVENTS_H__ #define __NETLINK_EVENTS_H__ -#include "common.h" +#include +#include -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 diff --git a/src/link-types.h b/lib/network-inador-link-types.h similarity index 100% rename from src/link-types.h rename to lib/network-inador-link-types.h diff --git a/lib/network-inador-private.h b/lib/network-inador-private.h new file mode 100644 index 0000000..b044033 --- /dev/null +++ b/lib/network-inador-private.h @@ -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 +#include +#include +#include + +#include +#include + +#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__ */ + diff --git a/lib/network-inador.h b/lib/network-inador.h new file mode 100644 index 0000000..e72f3f0 --- /dev/null +++ b/lib/network-inador.h @@ -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 +#include +#include + +#include +#include + +#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__ */ + diff --git a/lib/network-inador.pc.in b/lib/network-inador.pc.in new file mode 100644 index 0000000..25da094 --- /dev/null +++ b/lib/network-inador.pc.in @@ -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 diff --git a/src/resolv_conf_defs.h b/lib/resolv_conf_defs.h similarity index 100% rename from src/resolv_conf_defs.h rename to lib/resolv_conf_defs.h diff --git a/src/resolv_manager.c b/lib/resolv_manager.c similarity index 95% rename from src/resolv_manager.c rename to lib/resolv_manager.c index e4b1c69..a9c1b35 100644 --- a/src/resolv_manager.c +++ b/lib/resolv_manager.c @@ -30,14 +30,14 @@ #include #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; } diff --git a/src/resolv_manager.h b/lib/resolv_manager.h similarity index 96% rename from src/resolv_manager.h rename to lib/resolv_manager.h index 623e1e4..b5b1077 100644 --- a/src/resolv_manager.h +++ b/lib/resolv_manager.h @@ -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); diff --git a/src/routes.c b/lib/routes.c similarity index 88% rename from src/routes.c rename to lib/routes.c index ae5c904..bf3d8a4 100644 --- a/src/routes.c +++ b/lib/routes.c @@ -34,12 +34,13 @@ #include #include -#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 */ } diff --git a/src/routes.h b/lib/routes.h similarity index 65% rename from src/routes.h rename to lib/routes.h index e5263fe..dac075c 100644 --- a/src/routes.h +++ b/lib/routes.h @@ -23,10 +23,52 @@ #ifndef __ROUTES_H__ #define __ROUTES_H__ +#include + #include #include -#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); diff --git a/src/struct_addr_union.h b/lib/struct_addr_union.h similarity index 100% rename from src/struct_addr_union.h rename to lib/struct_addr_union.h diff --git a/src/veth.c b/lib/veth.c similarity index 99% rename from src/veth.c rename to lib/veth.c index ac93fca..13e5c21 100644 --- a/src/veth.c +++ b/lib/veth.c @@ -36,7 +36,7 @@ #include #include -#include "common.h" +#include "network-inador-private.h" #include "interfaces.h" int interfaces_veth_create (NetworkInadorHandle *handle, const char *link_name, const char *peer_name) { diff --git a/src/veth.h b/lib/veth.h similarity index 100% rename from src/veth.h rename to lib/veth.h diff --git a/src/wireless_bss.c b/lib/wireless_bss.c similarity index 97% rename from src/wireless_bss.c rename to lib/wireless_bss.c index d529726..4efc276 100644 --- a/src/wireless_bss.c +++ b/lib/wireless_bss.c @@ -33,7 +33,7 @@ #include -#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) { diff --git a/src/wireless_bss.h b/lib/wireless_bss.h similarity index 98% rename from src/wireless_bss.h rename to lib/wireless_bss.h index 52ffdd5..70ed0bf 100644 --- a/src/wireless_bss.h +++ b/lib/wireless_bss.h @@ -36,8 +36,6 @@ #include -#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); diff --git a/src/wireless_if.c b/lib/wireless_if.c similarity index 98% rename from src/wireless_if.c rename to lib/wireless_if.c index cd7e77b..976ac78 100644 --- a/src/wireless_if.c +++ b/lib/wireless_if.c @@ -33,7 +33,7 @@ #include -#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 } diff --git a/src/wireless_if.h b/lib/wireless_if.h similarity index 93% rename from src/wireless_if.h rename to lib/wireless_if.h index 775ca2b..c716f82 100644 --- a/src/wireless_if.h +++ b/lib/wireless_if.h @@ -23,7 +23,12 @@ #ifndef __WIRELESS_IF_H__ #define __WIRELESS_IF_H__ -#include "common.h" +#include +#include +#include + +#include "network-inador-private.h" +#include "interfaces.h" typedef enum { /*< flags >*/ WIFI_DEVICE_CAP_NONE = 0x00000000, diff --git a/lib/wireless_security.c b/lib/wireless_security.c new file mode 100644 index 0000000..5b8472b --- /dev/null +++ b/lib/wireless_security.c @@ -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" + diff --git a/lib/wireless_security.h b/lib/wireless_security.h new file mode 100644 index 0000000..0e382fc --- /dev/null +++ b/lib/wireless_security.h @@ -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__ */ diff --git a/lib/wireless_struct.h b/lib/wireless_struct.h new file mode 100644 index 0000000..44dd4b6 --- /dev/null +++ b/lib/wireless_struct.h @@ -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 +#include +#include +#include + +#include + +#include +#include + +#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__ */ + diff --git a/src/Makefile.am b/src/Makefile.am index 9a8157c..db38e0a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,31 +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 \ - veth.c veth.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 @@ -35,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 diff --git a/src/common.h b/src/common.h deleted file mode 100644 index f591b81..0000000 --- a/src/common.h +++ /dev/null @@ -1,261 +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 -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#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; - -/* 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; -}; - -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]; - - /* Para los parámetros de IPv4 e IPv6 */ - struct inet6_data inet6_data; - - /* La lista de direcciones IP, ambas */ - 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__ */ - diff --git a/src/glist.h b/src/glist.h deleted file mode 100644 index 7b08976..0000000 --- a/src/glist.h +++ /dev/null @@ -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 . - */ - -/* - * 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__ */ diff --git a/src/main.c b/src/main.c index 8cebd2d..1711536 100644 --- a/src/main.c +++ b/src/main.c @@ -38,29 +38,11 @@ #include -#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 "veth.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) { @@ -115,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; + + if (x->index == 2 && x->address != NULL) { + ip_address_del_ip (&handle, x->index, x->address->data); + } + }*/ - manager_init (&handle); + //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; } diff --git a/src/manager.c b/src/manager.c index cd6910e..9ee2a04 100644 --- a/src/manager.c +++ b/src/manager.c @@ -39,7 +39,7 @@ #include #include -#include "common.h" +#include "network-inador-private.h" #include "interfaces.h" #include "ip-address.h" #include "routes.h" diff --git a/src/netlink-events.c b/src/netlink-events.c deleted file mode 100644 index dcafe9e..0000000 --- a/src/netlink-events.c +++ /dev/null @@ -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 -#include - -#include -#include - -#include - -#include - -#include - -#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); -} - diff --git a/src/resolv_conf_helper.c b/src/resolv_conf_helper.c index 05fe7d5..07a5665 100644 --- a/src/resolv_conf_helper.c +++ b/src/resolv_conf_helper.c @@ -34,7 +34,7 @@ #include #include -#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;