Agrego primeras pruebas para procesar el resolv.conf
parent
4660add5ad
commit
95d4826615
|
@ -49,3 +49,4 @@ client-gtk/ni-marshal.h
|
||||||
client-gtk/core
|
client-gtk/core
|
||||||
|
|
||||||
src/ni-dhcp-helper
|
src/ni-dhcp-helper
|
||||||
|
src/resolvconf
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
bin_PROGRAMS = network-inador
|
bin_PROGRAMS = network-inador
|
||||||
network_inador_SOURCES = main.c \
|
network_inador_SOURCES = main.c \
|
||||||
common.h link-types.h \
|
common.h link-types.h \
|
||||||
|
struct_addr_union.h resolv_conf_defs.h \
|
||||||
netlink-events.c netlink-events.h \
|
netlink-events.c netlink-events.h \
|
||||||
interfaces.c interfaces.h \
|
interfaces.c interfaces.h \
|
||||||
ip-address.c ip-address.h \
|
ip-address.c ip-address.h \
|
||||||
|
@ -10,8 +11,19 @@ network_inador_SOURCES = main.c \
|
||||||
manager.c manager.h \
|
manager.c manager.h \
|
||||||
dhcp_client.c dhcp_client.h \
|
dhcp_client.c dhcp_client.h \
|
||||||
routes.c routes.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_if.c wireless_if.h \
|
||||||
wireless_bss.c wireless_bss.h
|
wireless_bss.c wireless_bss.h \
|
||||||
|
utils.c utils.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
|
||||||
|
|
||||||
libexec_PROGRAMS = ni-dhcp-helper
|
libexec_PROGRAMS = ni-dhcp-helper
|
||||||
|
|
||||||
|
|
17
src/common.h
17
src/common.h
|
@ -29,10 +29,15 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
|
#include <linux/if_addr.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
|
||||||
|
#include "struct_addr_union.h"
|
||||||
|
#include "resolv_conf_defs.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,11 +58,6 @@ typedef struct _NetworkInadorHandle NetworkInadorHandle;
|
||||||
typedef struct _NetworkInadorManager NetworkInadorManager;
|
typedef struct _NetworkInadorManager NetworkInadorManager;
|
||||||
typedef struct _Interface Interface;
|
typedef struct _Interface Interface;
|
||||||
|
|
||||||
typedef union {
|
|
||||||
struct in_addr v4;
|
|
||||||
struct in6_addr v6;
|
|
||||||
} struct_addr;
|
|
||||||
|
|
||||||
typedef struct _IPAddr {
|
typedef struct _IPAddr {
|
||||||
sa_family_t family;
|
sa_family_t family;
|
||||||
|
|
||||||
|
@ -255,12 +255,19 @@ typedef struct _RouteTable {
|
||||||
int for_delete, was_new;
|
int for_delete, was_new;
|
||||||
} RouteTable;
|
} RouteTable;
|
||||||
|
|
||||||
|
/* La definición principal que engloba todo */
|
||||||
struct _NetworkInadorHandle {
|
struct _NetworkInadorHandle {
|
||||||
GList *interfaces;
|
GList *interfaces;
|
||||||
GList *route_v4_tables;
|
GList *route_v4_tables;
|
||||||
GList *route_v6_tables;
|
GList *route_v6_tables;
|
||||||
GList *route_tables_names;
|
GList *route_tables_names;
|
||||||
|
|
||||||
|
/* Entradas para el resolv conf */
|
||||||
|
GList *resolver_entries;
|
||||||
|
int resolver_inotify_fd;
|
||||||
|
int resolver_inotify_watch;
|
||||||
|
|
||||||
|
/* El manager */
|
||||||
NetworkInadorManager *manager;
|
NetworkInadorManager *manager;
|
||||||
|
|
||||||
/* Estos sockets ejecutan comandos */
|
/* Estos sockets ejecutan comandos */
|
||||||
|
|
|
@ -257,6 +257,8 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
struct in_addr empty_v4;
|
struct in_addr empty_v4;
|
||||||
int g;
|
int g;
|
||||||
|
struct_addr old_dns[7];
|
||||||
|
int old_dns_c;
|
||||||
|
|
||||||
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||||
|
|
||||||
|
@ -298,6 +300,13 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
|
||||||
printf ("----> DHCP status: %i\n", iface->dhcpc.dhcp_state);
|
printf ("----> DHCP status: %i\n", iface->dhcpc.dhcp_state);
|
||||||
|
|
||||||
if (status == NET_INADOR_DHCP_STATUS_BOUND || status == NET_INADOR_DHCP_STATUS_RENEWED) {
|
if (status == NET_INADOR_DHCP_STATUS_BOUND || status == NET_INADOR_DHCP_STATUS_RENEWED) {
|
||||||
|
/* Copiar la información de DNS para saber si hubo cambios */
|
||||||
|
old_dns_c = iface->dhcpc.dns_c;
|
||||||
|
if (old_dns_c != dns_count) {
|
||||||
|
/* Copiamos los dns viejos solo si la cantidad es diferente */
|
||||||
|
memcpy (old_dns, iface->dhcpc.dns, old_dns_c * (sizeof (iface->dhcpc.dns[0])));
|
||||||
|
}
|
||||||
|
|
||||||
/* Copiar las variables de estado */
|
/* Copiar las variables de estado */
|
||||||
memset (&empty_v4, 0, sizeof (empty_v4));
|
memset (&empty_v4, 0, sizeof (empty_v4));
|
||||||
|
|
||||||
|
@ -318,8 +327,15 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
|
||||||
memcpy (&iface->dhcpc.dns[g], &dns_list[g], 4);
|
memcpy (&iface->dhcpc.dns[g], &dns_list[g], 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iface->dhcpc.dns_c != old_dns_c) {
|
||||||
|
/* TODO: Tenemos cambio en los DNS, actualizar el resolv.conf */
|
||||||
|
} else if (memcmp (iface->dhcpc.dns, old_dns, dns_count * (sizeof (iface->dhcpc.dns[0]))) != 0) {
|
||||||
|
/* TODO: Tenemos cambio en los DNS, actualizar el resolv.conf */
|
||||||
|
}
|
||||||
|
|
||||||
strncpy (iface->dhcpc.domain_name, domain_name, sizeof (iface->dhcpc.domain_name));
|
strncpy (iface->dhcpc.domain_name, domain_name, sizeof (iface->dhcpc.domain_name));
|
||||||
|
|
||||||
|
/* Esto solo es para impresión */
|
||||||
char buf_a[256], buf_b[256], buf_c[256], buf_d[256];
|
char buf_a[256], buf_b[256], buf_c[256], buf_d[256];
|
||||||
|
|
||||||
inet_ntop (AF_INET, &iface->dhcpc.ip, buf_a, sizeof (buf_a));
|
inet_ntop (AF_INET, &iface->dhcpc.ip, buf_a, sizeof (buf_a));
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,152 @@
|
||||||
|
/* GLIB - Library of useful routines for C programming
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
||||||
|
* file for a list of people on the GLib Team. See the ChangeLog
|
||||||
|
* files for a list of changes. These files are distributed with
|
||||||
|
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __G_LIST_H__
|
||||||
|
#define __G_LIST_H__
|
||||||
|
|
||||||
|
#define G_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||||
|
|
||||||
|
typedef void * gpointer;
|
||||||
|
typedef const void * gconstpointer;
|
||||||
|
typedef void (*GDestroyNotify) (gpointer data);
|
||||||
|
typedef void (*GFunc) (gpointer data, gpointer user_data);
|
||||||
|
typedef int (*GCompareDataFunc) (gconstpointer a, gconstpointer b, gpointer user_data);
|
||||||
|
typedef int (*GCompareFunc) (gconstpointer a, gconstpointer b);
|
||||||
|
typedef gpointer (*GCopyFunc) (gconstpointer src, gpointer data);
|
||||||
|
|
||||||
|
typedef struct _GList GList;
|
||||||
|
|
||||||
|
struct _GList
|
||||||
|
{
|
||||||
|
gpointer data;
|
||||||
|
GList *next;
|
||||||
|
GList *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Doubly linked lists
|
||||||
|
*/
|
||||||
|
|
||||||
|
GList* g_list_alloc (void) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
void g_list_free (GList *list);
|
||||||
|
|
||||||
|
void g_list_free_1 (GList *list);
|
||||||
|
#define g_list_free1 g_list_free_1
|
||||||
|
|
||||||
|
void g_list_free_full (GList *list,
|
||||||
|
GDestroyNotify free_func);
|
||||||
|
|
||||||
|
GList* g_list_append (GList *list,
|
||||||
|
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_prepend (GList *list,
|
||||||
|
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_insert (GList *list,
|
||||||
|
gpointer data,
|
||||||
|
int position) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_insert_sorted (GList *list,
|
||||||
|
gpointer data,
|
||||||
|
GCompareFunc func) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_insert_sorted_with_data (GList *list,
|
||||||
|
gpointer data,
|
||||||
|
GCompareDataFunc func,
|
||||||
|
gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_insert_before (GList *list,
|
||||||
|
GList *sibling,
|
||||||
|
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_concat (GList *list1,
|
||||||
|
GList *list2) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_remove (GList *list,
|
||||||
|
gconstpointer data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_remove_all (GList *list,
|
||||||
|
gconstpointer data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_remove_link (GList *list,
|
||||||
|
GList *llink) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_delete_link (GList *list,
|
||||||
|
GList *link_) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_reverse (GList *list) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_copy (GList *list) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
|
||||||
|
GList* g_list_copy_deep (GList *list,
|
||||||
|
GCopyFunc func,
|
||||||
|
gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
|
||||||
|
GList* g_list_nth (GList *list,
|
||||||
|
unsigned int n);
|
||||||
|
|
||||||
|
GList* g_list_nth_prev (GList *list,
|
||||||
|
unsigned int n);
|
||||||
|
|
||||||
|
GList* g_list_find (GList *list,
|
||||||
|
gconstpointer data);
|
||||||
|
|
||||||
|
GList* g_list_find_custom (GList *list,
|
||||||
|
gconstpointer data,
|
||||||
|
GCompareFunc func);
|
||||||
|
|
||||||
|
int g_list_position (GList *list,
|
||||||
|
GList *llink);
|
||||||
|
|
||||||
|
int g_list_index (GList *list,
|
||||||
|
gconstpointer data);
|
||||||
|
|
||||||
|
GList* g_list_last (GList *list);
|
||||||
|
|
||||||
|
GList* g_list_first (GList *list);
|
||||||
|
|
||||||
|
unsigned int g_list_length (GList *list);
|
||||||
|
|
||||||
|
void g_list_foreach (GList *list,
|
||||||
|
GFunc func,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GList* g_list_sort (GList *list,
|
||||||
|
GCompareFunc compare_func) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
GList* g_list_sort_with_data (GList *list,
|
||||||
|
GCompareDataFunc compare_func,
|
||||||
|
gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
gpointer g_list_nth_data (GList *list,
|
||||||
|
unsigned int n);
|
||||||
|
|
||||||
|
|
||||||
|
#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL)
|
||||||
|
#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __G_LIST_H__ */
|
|
@ -46,6 +46,7 @@
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
#include "dhcp_client.h"
|
#include "dhcp_client.h"
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
|
#include "resolv_manager.h"
|
||||||
|
|
||||||
/* Usados para salir en caso de una señal */
|
/* Usados para salir en caso de una señal */
|
||||||
static int sigterm_pipe_fds[2] = { -1, -1 };
|
static int sigterm_pipe_fds[2] = { -1, -1 };
|
||||||
|
@ -148,6 +149,9 @@ int main (int argc, char *argv[]) {
|
||||||
/* Inicializar las rutas */
|
/* Inicializar las rutas */
|
||||||
routes_init (&handle);
|
routes_init (&handle);
|
||||||
|
|
||||||
|
/* Inicializar el resolv.conf */
|
||||||
|
resolv_manager_init (&handle);
|
||||||
|
|
||||||
manager_init (&handle);
|
manager_init (&handle);
|
||||||
|
|
||||||
g_main_loop_run (loop);
|
g_main_loop_run (loop);
|
||||||
|
|
203
src/manager.c
203
src/manager.c
|
@ -46,6 +46,8 @@
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
#include "network-inador-manager.h"
|
#include "network-inador-manager.h"
|
||||||
#include "dhcp_client.h"
|
#include "dhcp_client.h"
|
||||||
|
#include "struct_addr_union.h"
|
||||||
|
#include "resolv_manager.h"
|
||||||
|
|
||||||
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||||
|
|
||||||
|
@ -818,6 +820,201 @@ static void _manager_execute_dhcp_client_feed (ManagerClientInfo *manager_client
|
||||||
_manager_send_executed (manager_client);
|
_manager_send_executed (manager_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _manager_execute_resolvconf_feed (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
int name_len, wanted;
|
||||||
|
unsigned char iface_prog[256];
|
||||||
|
unsigned char iface_name[256], prog[256];
|
||||||
|
char value[2048];
|
||||||
|
char *point;
|
||||||
|
ResolvConfEntry *entry;
|
||||||
|
GList *pos_entry;
|
||||||
|
|
||||||
|
int ns_count;
|
||||||
|
int search_count;
|
||||||
|
int g, h, pos;
|
||||||
|
int family;
|
||||||
|
int order = 0;
|
||||||
|
struct_addr direccion;
|
||||||
|
int iface_index;
|
||||||
|
Interface *iface;
|
||||||
|
|
||||||
|
if (buffer_len < 3) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
name_len = buffer[2];
|
||||||
|
|
||||||
|
if (buffer_len < 3 + name_len || name_len == 0) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (iface_prog, &buffer[3], name_len);
|
||||||
|
iface_prog[name_len] = 0;
|
||||||
|
|
||||||
|
if (iface_prog[0] == '.') {
|
||||||
|
/* No permitimos interfaces vacías */
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
point = strchr (iface_prog, '.');
|
||||||
|
if (point == NULL) {
|
||||||
|
prog[0] = 0;
|
||||||
|
strncpy (iface_name, iface_prog, sizeof (iface_name));
|
||||||
|
} else {
|
||||||
|
point[0] = 0;
|
||||||
|
strncpy (iface_name, iface_prog, sizeof (iface_name));
|
||||||
|
strncpy (prog, &point[1], sizeof (prog));
|
||||||
|
}
|
||||||
|
|
||||||
|
iface = _interfaces_locate_by_name (manager_client->manager->handle->interfaces, iface_name);
|
||||||
|
if (iface != NULL) {
|
||||||
|
iface_index = iface->index;
|
||||||
|
} else {
|
||||||
|
iface_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 3 + name_len;
|
||||||
|
if (buffer_len < pos) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Revisar la cantidad de nameservers */
|
||||||
|
ns_count = buffer[pos];
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
/* Los nameserver vienen con un byte de familia y luego los bytes correspondientes a la IP */
|
||||||
|
for (g = 0; g < ns_count; g++) {
|
||||||
|
/* Revisar que en la longitud venga el byte de la familia */
|
||||||
|
if (buffer_len < pos + 1) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
family = buffer[pos];
|
||||||
|
pos++; /* El byte de la familia */
|
||||||
|
|
||||||
|
if (family != AF_INET && family != AF_INET6) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (family == AF_INET) {
|
||||||
|
wanted = 4;
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
wanted = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer_len < pos + wanted) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tengo un Nameserver completo, buscar y dependiendo del caso, actualizar o crear */
|
||||||
|
memcpy (&direccion, &buffer[pos], wanted);
|
||||||
|
inet_ntop (family, &direccion, value, sizeof (value));
|
||||||
|
|
||||||
|
pos_entry = resolv_parser_search_entry (manager_client->manager->handle->resolver_entries, RESOLV_TYPE_NAMESERVER, family, &direccion, value);
|
||||||
|
if (pos_entry != NULL) {
|
||||||
|
/* De ser posible, hacer conciliación */
|
||||||
|
entry = (ResolvConfEntry *) pos_entry->data;
|
||||||
|
|
||||||
|
if (entry->origin == RESOLV_ORIGIN_FILE) {
|
||||||
|
/* Hacer esta entrada nuestra */
|
||||||
|
entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||||
|
entry->owner_interface_index = iface_index;
|
||||||
|
strncpy (entry->owner_prog, prog, sizeof (entry->owner_prog));
|
||||||
|
printf ("/// Asociando una entrada %s existente del archivo al: %s\n", entry->value, entry->owner_prog);
|
||||||
|
} else {
|
||||||
|
/* Existe la entrada, pero no la podemos tomar como nuestra, crear otra */
|
||||||
|
entry = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Si no existe, crearla */
|
||||||
|
if (entry == NULL) {
|
||||||
|
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
||||||
|
|
||||||
|
entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||||
|
entry->resolv_type = RESOLV_TYPE_NAMESERVER;
|
||||||
|
entry->file_order = 0;
|
||||||
|
entry->is_on_file = 0;
|
||||||
|
entry->priority = 0;
|
||||||
|
|
||||||
|
entry->ns_family = family;
|
||||||
|
memcpy (&entry->nameserver, &direccion, wanted);
|
||||||
|
strncpy (entry->value, value, sizeof (entry->value));
|
||||||
|
entry->owner_interface_index = iface_index;
|
||||||
|
strncpy (entry->owner_prog, prog, sizeof (entry->owner_prog));
|
||||||
|
|
||||||
|
/* Anexar al final de la lista */
|
||||||
|
manager_client->manager->handle->resolver_entries = g_list_append (manager_client->manager->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ahora crear y parsear */
|
||||||
|
|
||||||
|
/* OK */
|
||||||
|
_manager_send_executed (manager_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _manager_execute_resolvconf_remove (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
int name_len;
|
||||||
|
unsigned char iface_prog[256];
|
||||||
|
unsigned char iface_name[256], prog[256];
|
||||||
|
char *point;
|
||||||
|
Interface *iface;
|
||||||
|
int iface_index;
|
||||||
|
|
||||||
|
name_len = buffer[2];
|
||||||
|
|
||||||
|
if (buffer_len < 3 + name_len || name_len == 0) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_REMOVE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (iface_prog, &buffer[3], name_len);
|
||||||
|
iface_prog[name_len] = 0;
|
||||||
|
|
||||||
|
if (iface_prog[0] == '.') {
|
||||||
|
/* No permitimos interfaces vacías */
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RESOLVCONF_REMOVE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
point = strchr (iface_prog, '.');
|
||||||
|
if (point == NULL) {
|
||||||
|
prog[0] = 0;
|
||||||
|
strncpy (iface_name, iface_prog, sizeof (iface_name));
|
||||||
|
} else {
|
||||||
|
point[0] = 0;
|
||||||
|
strncpy (iface_name, iface_prog, sizeof (iface_name));
|
||||||
|
strncpy (prog, &point[1], sizeof (prog));
|
||||||
|
}
|
||||||
|
|
||||||
|
iface = _interfaces_locate_by_name (manager_client->manager->handle->interfaces, iface_name);
|
||||||
|
if (iface != NULL) {
|
||||||
|
iface_index = iface->index;
|
||||||
|
} else {
|
||||||
|
iface_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolv_manager_clear_entries_by_prog (manager_client->manager->handle, iface_index, prog);
|
||||||
|
|
||||||
|
_manager_send_executed (manager_client);
|
||||||
|
}
|
||||||
|
|
||||||
static void _manager_execute_dhcp_run (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
static void _manager_execute_dhcp_run (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1493,6 +1690,12 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition
|
||||||
case NET_INADOR_COMMAND_LIST_ROUTE_TABLES:
|
case NET_INADOR_COMMAND_LIST_ROUTE_TABLES:
|
||||||
_manager_send_list_route_tables (manager_client, buffer, bytes);
|
_manager_send_list_route_tables (manager_client, buffer, bytes);
|
||||||
break;
|
break;
|
||||||
|
case NET_INADOR_COMMAND_RESOLVCONF_FEED:
|
||||||
|
_manager_execute_resolvconf_feed (manager_client, buffer, bytes);
|
||||||
|
break;
|
||||||
|
case NET_INADOR_COMMAND_RESOLVCONF_REMOVE:
|
||||||
|
_manager_execute_resolvconf_remove (manager_client, buffer, bytes);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_WRONG_COMMAND, command);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_WRONG_COMMAND, command);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ enum {
|
||||||
|
|
||||||
/* Los siguientes comandos son para uso interno */
|
/* Los siguientes comandos son para uso interno */
|
||||||
NET_INADOR_COMMAND_DHCP_CLIENT_FEED = 224,
|
NET_INADOR_COMMAND_DHCP_CLIENT_FEED = 224,
|
||||||
|
NET_INADOR_COMMAND_RESOLVCONF_FEED = 225,
|
||||||
|
NET_INADOR_COMMAND_RESOLVCONF_REMOVE = 226,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* ni-iface-helper.c
|
* ni-dhcp-iface-helper.c
|
||||||
* This file is part of Network Inador
|
* This file is part of Network Inador
|
||||||
*
|
*
|
||||||
* Copyright (C) 2021 - Félix Arreola Rodríguez
|
* Copyright (C) 2021 - Félix Arreola Rodríguez
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* resolv_conf_defs.h
|
||||||
|
* This file is part of NetworkInador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* NetworkInador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NetworkInador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NetworkInador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RESOLV_CONF_DEFS_H__
|
||||||
|
#define __RESOLV_CONF_DEFS_H__
|
||||||
|
|
||||||
|
#include <linux/if.h>
|
||||||
|
|
||||||
|
#include "struct_addr_union.h"
|
||||||
|
|
||||||
|
/* Cosas del resolv.conf */
|
||||||
|
enum {
|
||||||
|
RESOLV_TYPE_NAMESERVER,
|
||||||
|
RESOLV_TYPE_DOMAIN,
|
||||||
|
RESOLV_TYPE_SEARCH,
|
||||||
|
RESOLV_TYPE_SORTLIST,
|
||||||
|
RESOLV_TYPE_OPTIONS,
|
||||||
|
|
||||||
|
NUM_RESOLV_TYPES
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RESOLV_ORIGIN_FILE,
|
||||||
|
RESOLV_ORIGIN_DHCP,
|
||||||
|
RESOLV_ORIGIN_RESOLVCONF,
|
||||||
|
|
||||||
|
RESOLV_ORIGIN_SLAAC_RDNSS,
|
||||||
|
|
||||||
|
NUM_RESOLV_ORIGINS
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _ResolvConfEntry {
|
||||||
|
int resolv_type;
|
||||||
|
int origin;
|
||||||
|
|
||||||
|
int file_order;
|
||||||
|
int is_on_file;
|
||||||
|
int priority;
|
||||||
|
|
||||||
|
int ns_family;
|
||||||
|
struct_addr nameserver;
|
||||||
|
char value[2048];
|
||||||
|
|
||||||
|
//char owner_interface[IFNAMSIZ];
|
||||||
|
int owner_interface_index;
|
||||||
|
char owner_prog[256];
|
||||||
|
} ResolvConfEntry;
|
||||||
|
|
||||||
|
#endif /* __RESOLV_CONF_DEFS_H__ */
|
||||||
|
|
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* resolv_conf_helper.c
|
||||||
|
* This file is part of NetworkInador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* NetworkInador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NetworkInador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NetworkInador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "glist.h"
|
||||||
|
|
||||||
|
#include "network-inador-manager.h"
|
||||||
|
#include "resolv_conf_defs.h"
|
||||||
|
#include "struct_addr_union.h"
|
||||||
|
#include "resolv_conf_parser.h"
|
||||||
|
|
||||||
|
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||||
|
|
||||||
|
static const struct option long_options[] = {
|
||||||
|
{"enable-updates", 0, NULL, 'z' },
|
||||||
|
{"disable-updates", 0, NULL, 'y' },
|
||||||
|
{"updates-are-enabled", 0, NULL, 'x' },
|
||||||
|
{"create-runtime-directories", 0, NULL, 'w' },
|
||||||
|
{"wipe-runtime-directories", 0, NULL, 'v' },
|
||||||
|
{NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *short_options = "a:d:u";
|
||||||
|
|
||||||
|
int wait_for_ack_or_error (int s) {
|
||||||
|
unsigned char buffer[128];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = recv (s, buffer, sizeof (buffer), 0);
|
||||||
|
|
||||||
|
if (ret < 3) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer[0] == NET_INADOR_TYPE_RESPONSE_ERROR) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer[0] == NET_INADOR_TYPE_RESPONSE && buffer[1] == NET_INADOR_RESPONSE_EXECUTED) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_entries (int s, GList *entries, const char *iface_prog) {
|
||||||
|
char buffer[2048];
|
||||||
|
int pos, len, pos_name_count;
|
||||||
|
GList *g;
|
||||||
|
int n;
|
||||||
|
ResolvConfEntry *entry;
|
||||||
|
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_RESOLVCONF_FEED;
|
||||||
|
|
||||||
|
/* El segundo byte es el nombre seguido del nombre en sí */
|
||||||
|
len = strlen (iface_prog);
|
||||||
|
buffer[2] = len;
|
||||||
|
|
||||||
|
memcpy (&buffer[3], iface_prog, len);
|
||||||
|
|
||||||
|
pos_name_count = 3 + len;
|
||||||
|
|
||||||
|
/* Contar los nameservers que tengo */
|
||||||
|
g = entries;
|
||||||
|
n = 0;
|
||||||
|
pos = pos_name_count + 1;
|
||||||
|
while (g != NULL) {
|
||||||
|
entry = (ResolvConfEntry *) g->data;
|
||||||
|
|
||||||
|
if (entry->resolv_type == RESOLV_TYPE_NAMESERVER) {
|
||||||
|
n++;
|
||||||
|
buffer[pos] = entry->ns_family;
|
||||||
|
pos++;
|
||||||
|
if (entry->ns_family == AF_INET) {
|
||||||
|
memcpy (&buffer[pos], &entry->nameserver, 4);
|
||||||
|
pos += 4;
|
||||||
|
} else if (entry->ns_family == AF_INET6) {
|
||||||
|
memcpy (&buffer[pos], &entry->nameserver, 16);
|
||||||
|
pos += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g = g->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[pos_name_count] = n;
|
||||||
|
|
||||||
|
send (s, buffer, pos, 0);
|
||||||
|
|
||||||
|
if (wait_for_ack_or_error (s) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_remove_entries (int s, const char *iface_prog) {
|
||||||
|
char buffer[2048];
|
||||||
|
int pos, len;
|
||||||
|
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_RESOLVCONF_REMOVE;
|
||||||
|
|
||||||
|
/* El segundo byte es el nombre seguido del nombre en sí */
|
||||||
|
len = strlen (iface_prog);
|
||||||
|
buffer[2] = len;
|
||||||
|
|
||||||
|
memcpy (&buffer[3], iface_prog, len);
|
||||||
|
|
||||||
|
send (s, buffer, 3 + len, 0);
|
||||||
|
|
||||||
|
if (wait_for_ack_or_error (s) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]) {
|
||||||
|
int next_option;
|
||||||
|
const char *iface_prog = NULL;
|
||||||
|
int action = 0;
|
||||||
|
GList *entries;
|
||||||
|
int s, ret;
|
||||||
|
struct sockaddr_un path_dest;
|
||||||
|
|
||||||
|
do {
|
||||||
|
next_option = getopt_long (argc, argv, short_options, long_options, NULL);
|
||||||
|
|
||||||
|
switch (next_option) {
|
||||||
|
case 'z':
|
||||||
|
case 'y':
|
||||||
|
case 'x':
|
||||||
|
case 'w':
|
||||||
|
case 'v':
|
||||||
|
/* Ignorar */
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
action = 'a';
|
||||||
|
iface_prog = optarg;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
action = 'd';
|
||||||
|
iface_prog = optarg;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
/* Opción incorrecta */
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
/* Fin de opciones */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (next_option != -1);
|
||||||
|
|
||||||
|
if (action == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validar el nombre del argumento del -a o del -d */
|
||||||
|
if (iface_prog == NULL || iface_prog[0] == 0) {
|
||||||
|
fprintf (stderr, "interface record name empty\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strchr (iface_prog, '/') != NULL) {
|
||||||
|
/* Diagonal no permitida */
|
||||||
|
fprintf (stderr, "Slash not allowed in interface record name\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strchr (iface_prog, ' ') != NULL) {
|
||||||
|
fprintf (stderr, "Space not allowed in interface record name\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface_prog[0] == '.') {
|
||||||
|
fprintf (stderr, "Space not allowed in interface record name\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface_prog[0] == '-') {
|
||||||
|
fprintf (stderr, "Initial hyphen not allowed in interface record name\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface_prog[0] == '~') {
|
||||||
|
fprintf (stderr, "Initial tilde not allowed in interface record name\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen (iface_prog) > 255) {
|
||||||
|
fprintf (stderr, "Interface too long\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Intentar abrir el socket al network inador */
|
||||||
|
s = socket (AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
|
||||||
|
|
||||||
|
if (s < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
path_dest.sun_family = AF_UNIX;
|
||||||
|
strncpy (path_dest.sun_path, COMMAND_SOCKET_PATH, sizeof (path_dest.sun_path));
|
||||||
|
ret = connect (s, (struct sockaddr *) &path_dest, sizeof (path_dest));
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
perror ("Connect");
|
||||||
|
close (s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == 'a') {
|
||||||
|
/* Parsear el archivo primero */
|
||||||
|
entries = resolv_parser_parse_file (NULL, stdin, RESOLV_ORIGIN_RESOLVCONF);
|
||||||
|
|
||||||
|
/* Preparar un paquete de datos para enviar via el socket */
|
||||||
|
send_entries (s, entries, iface_prog);
|
||||||
|
} else if (action == 'd') {
|
||||||
|
send_remove_entries (s, iface_prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
close (s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* resolv_conf_parser.c
|
||||||
|
* This file is part of NetworkInador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* NetworkInador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NetworkInador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NetworkInador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
static const char *resolv_conf_keywords[NUM_RESOLV_TYPES] = {
|
||||||
|
"nameserver",
|
||||||
|
"domain",
|
||||||
|
"search",
|
||||||
|
"sortlist",
|
||||||
|
"options"
|
||||||
|
};
|
||||||
|
|
||||||
|
int resolv_conf_parse_line (const char *line, int *ns_family, struct_addr *nameserver, char *value, const size_t value_size) {
|
||||||
|
int g, len;
|
||||||
|
int af;
|
||||||
|
struct_addr temp_addr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Recorrer cada palabra clave posible de los resolv.conf */
|
||||||
|
for (g = 0; g < NUM_RESOLV_TYPES; g++) {
|
||||||
|
len = strlen (resolv_conf_keywords[g]);
|
||||||
|
if (strncmp (line, resolv_conf_keywords[g], len) == 0 && line[len] == ' ') {
|
||||||
|
if (g == RESOLV_TYPE_NAMESERVER) {
|
||||||
|
/* Los nameserver solo pueden ser direcciones IP de IPv4 o IPv6 */
|
||||||
|
af = AF_INET;
|
||||||
|
ret = inet_pton (AF_INET, &line[len + 1], &temp_addr);
|
||||||
|
if (ret == 0) {
|
||||||
|
af = AF_INET6;
|
||||||
|
ret = inet_pton (AF_INET6, &line[len + 1], &temp_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
/* No es una dirección IP, ignorar */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Revisar por posibles restricciones en otros tipos */
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy (value, &line[len + 1], value_size);
|
||||||
|
value[value_size - 1] = 0;
|
||||||
|
|
||||||
|
if (g == RESOLV_TYPE_NAMESERVER) {
|
||||||
|
*ns_family = af;
|
||||||
|
memcpy (nameserver, &temp_addr, sizeof (temp_addr));
|
||||||
|
} else {
|
||||||
|
*ns_family = AF_UNSPEC;
|
||||||
|
memset (nameserver, 0, sizeof (temp_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No es alguna linea válida */
|
||||||
|
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) {
|
||||||
|
GList *g;
|
||||||
|
ResolvConfEntry *entry;
|
||||||
|
|
||||||
|
g = all_entries;
|
||||||
|
while (g != NULL) {
|
||||||
|
entry = (ResolvConfEntry *) g->data;
|
||||||
|
|
||||||
|
if (resolv_type != entry->resolv_type) {
|
||||||
|
/* Pasar a la siguiente entrada, no es del mismo tipo */
|
||||||
|
g = g->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comparar dependiendo del tipo */
|
||||||
|
if (resolv_type == RESOLV_TYPE_NAMESERVER) {
|
||||||
|
if (ns_family == AF_INET && entry->ns_family == AF_INET) {
|
||||||
|
if (memcmp (nameserver, &entry->nameserver, sizeof (struct in_addr)) == 0) {
|
||||||
|
/* Es la entrada que andamos buscando */
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
} else if (ns_family == AF_INET6 && entry->ns_family == AF_INET6) {
|
||||||
|
if (memcmp (nameserver, &entry->nameserver, sizeof (struct in6_addr)) == 0) {
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* TODO: Revisar si las otras entradas requieren otro tipo de comparación */
|
||||||
|
if (strcmp (value, entry->value) == 0) {
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g = g->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin) {
|
||||||
|
char buffer[8192], value[2048];
|
||||||
|
ResolvConfEntry *entry = NULL;
|
||||||
|
GList *pos, *next;
|
||||||
|
int g, len;
|
||||||
|
struct_addr direccion;
|
||||||
|
int type;
|
||||||
|
int family;
|
||||||
|
int order;
|
||||||
|
|
||||||
|
order = 0;
|
||||||
|
while (fgets (buffer, sizeof (buffer), fd), feof (fd) == 0) {
|
||||||
|
utils_trim (buffer);
|
||||||
|
utils_trim_comment (buffer);
|
||||||
|
if (buffer[0] == 0) continue;
|
||||||
|
|
||||||
|
type = resolv_conf_parse_line (buffer, &family, &direccion, value, sizeof (value));
|
||||||
|
|
||||||
|
if (type == -1) {
|
||||||
|
/* Linea no válida de acuerdo al parser, ignorar */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Tenemos una linea buena, buscar si esta linea ya existe en nuestra lista de entradas */
|
||||||
|
pos = resolv_parser_search_entry (all_entries, type, family, &direccion, value);
|
||||||
|
|
||||||
|
if (pos != NULL) {
|
||||||
|
/* Ya existe, refrescar que está en el archivo */
|
||||||
|
entry = (ResolvConfEntry *) pos->data;
|
||||||
|
} else {
|
||||||
|
/* Como no existe, crear y anexar al final de la lista */
|
||||||
|
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
||||||
|
|
||||||
|
entry->resolv_type = type;
|
||||||
|
entry->origin = origin;
|
||||||
|
|
||||||
|
entry->ns_family = family;
|
||||||
|
memcpy (&entry->nameserver, &direccion, sizeof (direccion));
|
||||||
|
strncpy (entry->value, value, sizeof (entry->value));
|
||||||
|
|
||||||
|
entry->owner_interface_index = 0;
|
||||||
|
entry->owner_prog[0] = 0;
|
||||||
|
|
||||||
|
all_entries = g_list_append (all_entries, entry);
|
||||||
|
}
|
||||||
|
entry->is_on_file = 1;
|
||||||
|
entry->file_order = order++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* resolv_conf_parser.h
|
||||||
|
* This file is part of NetworkInador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* NetworkInador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NetworkInador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NetworkInador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RESOLV_CONF_PARSER_H__
|
||||||
|
#define __RESOLV_CONF_PARSER_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef STAND_ALONE_RESOLV_CONF_HELPER_BUILD
|
||||||
|
#include "glist.h"
|
||||||
|
#else
|
||||||
|
#include "common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value);
|
||||||
|
GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin);
|
||||||
|
|
||||||
|
#endif /* __RESOLV_CONF_PARSER_H__ */
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* resolv_manager.c
|
||||||
|
* This file is part of Network-inador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* Network-inador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Network-inador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Network-inador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "resolv_conf_parser.h"
|
||||||
|
|
||||||
|
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog) {
|
||||||
|
GList *g, *next;
|
||||||
|
ResolvConfEntry *entry;
|
||||||
|
|
||||||
|
g = handle->resolver_entries;
|
||||||
|
while (g != NULL) {
|
||||||
|
next = g->next;
|
||||||
|
|
||||||
|
entry = (ResolvConfEntry *) g->data;
|
||||||
|
|
||||||
|
if (entry->origin != RESOLV_ORIGIN_RESOLVCONF) {
|
||||||
|
/* Solo borramos las entradas creadas via resolvconf */
|
||||||
|
g = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->owner_interface_index != iface_index) {
|
||||||
|
g = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prog == NULL || strcmp (entry->owner_prog, prog) == 0) {
|
||||||
|
/* Hay que eliminar esta entrada, coincide por la interfaz o nombre de programa */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
g = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
|
||||||
|
FILE *fd;
|
||||||
|
GList *pos, *next;
|
||||||
|
ResolvConfEntry *entry;
|
||||||
|
|
||||||
|
fd = fopen ("/etc/resolv.conf", "r");
|
||||||
|
if (fd == NULL) return;
|
||||||
|
|
||||||
|
printf ("/// Ejecutando lectura de resolv.conf\n");
|
||||||
|
/* Etiquetar las entradas con origen del archivo como "ya no en el archivo", para que cuando se lea el archivo, nos queden las que vamos a eliminar */
|
||||||
|
/* Borrar cuáles están en el archivo */
|
||||||
|
pos = handle->resolver_entries;
|
||||||
|
while (pos != NULL) {
|
||||||
|
entry = (ResolvConfEntry *) pos->data;
|
||||||
|
|
||||||
|
entry->is_on_file = 0;
|
||||||
|
pos = pos->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->resolver_entries = resolv_parser_parse_file (handle->resolver_entries, fd, RESOLV_ORIGIN_FILE);
|
||||||
|
|
||||||
|
fclose (fd);
|
||||||
|
|
||||||
|
/* A la salida, borrar las que ya no siguen en el archivo */
|
||||||
|
pos = handle->resolver_entries;
|
||||||
|
while (pos != NULL) {
|
||||||
|
next = pos->next;
|
||||||
|
entry = (ResolvConfEntry *) pos->data;
|
||||||
|
|
||||||
|
if (entry->origin == RESOLV_ORIGIN_FILE && entry->is_on_file == 0) {
|
||||||
|
/* Esta entrada se va, la eliminaron */
|
||||||
|
printf ("/// La entrada %s del resolv.conf fué eliminada del archivo. Purgando nosotros.\n", entry->value);
|
||||||
|
|
||||||
|
handle->resolver_entries = g_list_delete_link (handle->resolver_entries, pos);
|
||||||
|
free (entry);
|
||||||
|
entry = NULL;
|
||||||
|
} else {
|
||||||
|
printf ("/// La entrada %s del resolv.conf sigue en el archivo.\n", entry->value);
|
||||||
|
}
|
||||||
|
pos = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolv_manager_init (NetworkInadorHandle *handle) {
|
||||||
|
|
||||||
|
//handle->resolver_inotify_fd = inotify_init1 (IN_NONBLOCK | IN_CLOEXEC);
|
||||||
|
|
||||||
|
if (handle->resolver_inotify_fd >= 0) {
|
||||||
|
/* Debemos primero instalar el manejador de eventos de escritura sobre el resolv.conf */
|
||||||
|
/*
|
||||||
|
IN_CLOSE_WRITE Releer archivo.
|
||||||
|
IN_DELETE_SELF Dejar de hacer watch
|
||||||
|
IN_MOVE_SELF Dejar de hacer watch
|
||||||
|
*/
|
||||||
|
|
||||||
|
//handle->resolver_inotify_watch = inotify_add_watch (handle->resolver_inotify_fd, "/etc/resolv.conf",
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->resolver_entries = NULL;
|
||||||
|
/* Luego, leer el resolv.conf */
|
||||||
|
resolv_manager_read_local_etc_resolv (handle);
|
||||||
|
|
||||||
|
resolv_manager_read_local_etc_resolv (handle);
|
||||||
|
|
||||||
|
resolv_manager_read_local_etc_resolv (handle);
|
||||||
|
|
||||||
|
resolv_manager_read_local_etc_resolv (handle);
|
||||||
|
|
||||||
|
resolv_manager_read_local_etc_resolv (handle);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* resolv_manager.h
|
||||||
|
* This file is part of Network-inador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* Network-inador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Network-inador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Network-inador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RESOLV_MANAGER_H__
|
||||||
|
#define __RESOLV_MANAGER_H__
|
||||||
|
|
||||||
|
#include "struct_addr_union.h"
|
||||||
|
#include "resolv_conf_parser.h"
|
||||||
|
|
||||||
|
void resolv_manager_init (NetworkInadorHandle *handle);
|
||||||
|
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog);
|
||||||
|
|
||||||
|
#endif /* __RESOLV_MANAGER_H__ */
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* struct_addr_union.h
|
||||||
|
* This file is part of NetworkInador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* NetworkInador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NetworkInador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NetworkInador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __STRUCT_ADDR_UNION_H__
|
||||||
|
#define __STRUCT_ADDR_UNION_H__
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} struct_addr;
|
||||||
|
|
||||||
|
#endif /* __STRUCT_ADDR_UNION_H__ */
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* utils.c
|
||||||
|
* This file is part of Network-inador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* Network-inador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Network-inador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Network-inador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
void utils_trim (char * s) {
|
||||||
|
char * p = s;
|
||||||
|
int l = strlen(p);
|
||||||
|
|
||||||
|
while(isspace(p[l - 1])) p[--l] = 0;
|
||||||
|
while(* p && isspace(* p)) ++p, --l;
|
||||||
|
|
||||||
|
memmove(s, p, l + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void utils_trim_comment (char *s) {
|
||||||
|
char *p = s;
|
||||||
|
int l = strlen (p);
|
||||||
|
|
||||||
|
while (*p != 0 && *p != '#') {
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '#') {
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* utils.h
|
||||||
|
* This file is part of Network-inador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 - Félix Arreola Rodríguez
|
||||||
|
*
|
||||||
|
* Network-inador is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Network-inador is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Network-inador; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTILS_H__
|
||||||
|
#define __UTILS_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
void utils_trim (char * s);
|
||||||
|
void utils_trim_comment (char *s);
|
||||||
|
|
||||||
|
#endif /* __UTILS_H__ */
|
||||||
|
|
Loading…
Reference in New Issue