2023-07-21 22:58:05 -06:00
|
|
|
/*
|
|
|
|
* 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>
|
2023-07-28 17:01:59 -06:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <arpa/inet.h>
|
2023-07-21 22:58:05 -06:00
|
|
|
|
2023-07-25 18:34:23 -06:00
|
|
|
#include "resolv_manager.h"
|
2024-01-09 23:02:39 -06:00
|
|
|
#include "network-inador-private.h"
|
2023-07-21 22:58:05 -06:00
|
|
|
#include "utils.h"
|
|
|
|
#include "resolv_conf_parser.h"
|
2023-07-25 18:34:23 -06:00
|
|
|
#include "interfaces.h"
|
2025-01-13 17:25:09 -06:00
|
|
|
#include "file_watcher.h"
|
2023-07-25 18:34:23 -06:00
|
|
|
|
|
|
|
void resolv_manager_write (NetworkInadorHandle *handle);
|
|
|
|
|
2024-01-09 23:02:39 -06:00
|
|
|
int resolv_manager_sort_entries (const void *a, const void *b, void * data) {
|
2023-07-25 18:34:23 -06:00
|
|
|
const ResolvConfEntry *aa = (ResolvConfEntry *) a;
|
|
|
|
const ResolvConfEntry *bb = (ResolvConfEntry *) b;
|
|
|
|
|
|
|
|
/* Primero, las purgadas van al final */
|
|
|
|
if (aa->for_purge == 1 && bb->for_purge == 0) {
|
|
|
|
return 1;
|
|
|
|
} else if (aa->for_purge == 0 && bb->for_purge == 1) {
|
|
|
|
return -1;
|
|
|
|
} else if (aa->for_purge == 1) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (aa->tagged == 1 && bb->tagged == 0) {
|
|
|
|
/* TODO: Revisar este orden por prioridades */
|
|
|
|
return -1;
|
|
|
|
} else if (aa->tagged == 0 && bb->tagged == 1) {
|
|
|
|
return 1;
|
|
|
|
} else if (aa->tagged == 1) {
|
|
|
|
/* Como los dos están en el archivo, comparar por el file_order */
|
|
|
|
return (aa->file_order - bb->file_order);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: Estas entradas necesitan resolverse por prioridad de configuración */
|
|
|
|
return 0;
|
|
|
|
}
|
2023-07-21 22:58:05 -06:00
|
|
|
|
|
|
|
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog) {
|
2024-01-09 23:02:39 -06:00
|
|
|
FList *g;
|
2023-07-21 22:58:05 -06:00
|
|
|
ResolvConfEntry *entry;
|
2023-07-25 18:34:23 -06:00
|
|
|
int do_write = 0;
|
2023-07-21 22:58:05 -06:00
|
|
|
|
|
|
|
g = handle->resolver_entries;
|
|
|
|
while (g != NULL) {
|
|
|
|
entry = (ResolvConfEntry *) g->data;
|
|
|
|
|
2023-07-28 17:01:59 -06:00
|
|
|
if (entry->origin != RESOLV_ORIGIN_RESOLVCONF || entry->owner_interface_index != iface_index) {
|
|
|
|
/* Solo borramos las entradas creadas via resolvconf y que pertenezcan a esta interfaz */
|
2023-07-25 18:34:23 -06:00
|
|
|
g = g->next;
|
2023-07-21 22:58:05 -06:00
|
|
|
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);
|
2023-07-25 18:34:23 -06:00
|
|
|
/*free (entry);
|
2023-07-21 22:58:05 -06:00
|
|
|
|
2024-01-09 23:02:39 -06:00
|
|
|
handle->resolver_entries = f_list_delete_link (handle->resolver_entries, g);*/
|
2023-07-25 18:34:23 -06:00
|
|
|
entry->for_purge = 1;
|
|
|
|
do_write = 1;
|
2023-07-21 22:58:05 -06:00
|
|
|
}
|
|
|
|
|
2023-07-25 18:34:23 -06:00
|
|
|
g = g->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Solicitar una escritura del archivo, via el resolvconf fuimos modificados */
|
|
|
|
if (do_write == 1) {
|
|
|
|
resolv_manager_write (handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle) {
|
2024-01-09 23:02:39 -06:00
|
|
|
FList *pos;
|
2023-07-25 18:34:23 -06:00
|
|
|
ResolvConfEntry *entry;
|
|
|
|
|
|
|
|
/* Borrar el atributo "tagged" */
|
|
|
|
pos = handle->resolver_entries;
|
|
|
|
while (pos != NULL) {
|
|
|
|
entry = (ResolvConfEntry *) pos->data;
|
|
|
|
|
|
|
|
entry->tagged = 0;
|
2025-01-13 20:25:22 -06:00
|
|
|
entry->was_new = 0;
|
2023-07-25 18:34:23 -06:00
|
|
|
pos = pos->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-13 17:25:09 -06:00
|
|
|
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries) {
|
|
|
|
ResolvConfEntry *new_entry, *found_entry;
|
|
|
|
FList *g, *pos_searched_entry;
|
2023-07-25 18:34:23 -06:00
|
|
|
int do_write = 0;
|
2025-01-13 17:25:09 -06:00
|
|
|
int n;
|
2023-07-25 18:34:23 -06:00
|
|
|
|
|
|
|
resolv_manager_clear_tag_on_all (handle);
|
|
|
|
|
2025-01-13 17:25:09 -06:00
|
|
|
g = entries;
|
|
|
|
n = 0;
|
|
|
|
while (g != NULL) {
|
|
|
|
new_entry = (ResolvConfEntry *) g->data;
|
|
|
|
|
|
|
|
found_entry = NULL;
|
|
|
|
while (found_entry == NULL) {
|
|
|
|
pos_searched_entry = resolv_parser_search_entry (handle->resolver_entries, new_entry->resolv_type, new_entry->ns_family, &new_entry->nameserver, new_entry->value, 1);
|
|
|
|
if (pos_searched_entry == NULL) break;
|
2023-07-25 18:34:23 -06:00
|
|
|
|
|
|
|
/* De ser posible, hacer conciliación */
|
2025-01-13 17:25:09 -06:00
|
|
|
found_entry = (ResolvConfEntry *) pos_searched_entry->data;
|
2023-07-25 18:34:23 -06:00
|
|
|
|
2025-01-13 17:25:09 -06:00
|
|
|
if (found_entry->origin == RESOLV_ORIGIN_FILE) {
|
2023-07-25 18:34:23 -06:00
|
|
|
/* Hacer esta entrada nuestra */
|
2025-01-13 17:25:09 -06:00
|
|
|
found_entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
|
|
|
found_entry->owner_interface_index = new_entry->owner_interface_index;
|
|
|
|
found_entry->tagged = 1;
|
|
|
|
strncpy (found_entry->owner_prog, new_entry->owner_prog, sizeof (found_entry->owner_prog));
|
|
|
|
printf ("/// Asociando una entrada %s existente del archivo al: %s\n", found_entry->value, found_entry->owner_prog);
|
2023-07-28 17:01:59 -06:00
|
|
|
#if 0
|
2025-01-13 17:25:09 -06:00
|
|
|
} else if (found_entry->origin == RESOLV_ORIGIN_DHCP) {
|
2023-07-25 18:34:23 -06:00
|
|
|
/* Una entrada que coincide con la actual solo se puede re-asociar al resolvconf si pertenece a la misma interfaz */
|
2025-01-13 17:25:09 -06:00
|
|
|
if (found_entry->owner_interface_index != new_entry->owner_interface_index) {
|
|
|
|
found_entry->tagged = 1;
|
|
|
|
found_entry = NULL;
|
2023-07-25 18:34:23 -06:00
|
|
|
continue;
|
|
|
|
}
|
2023-07-28 17:01:59 -06:00
|
|
|
#endif
|
2023-07-25 18:34:23 -06:00
|
|
|
} else {
|
|
|
|
/* Existe la entrada, pero no la podemos tomar como nuestra, crear otra */
|
2025-01-13 17:25:09 -06:00
|
|
|
found_entry->tagged = 1;
|
|
|
|
found_entry = NULL;
|
2023-07-25 18:34:23 -06:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Si no existe, crearla */
|
2025-01-13 17:25:09 -06:00
|
|
|
if (found_entry == NULL) {
|
|
|
|
found_entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
2023-07-25 18:34:23 -06:00
|
|
|
|
2025-01-13 17:25:09 -06:00
|
|
|
memcpy (found_entry, new_entry, sizeof (ResolvConfEntry));
|
|
|
|
found_entry->file_order = n; /* TODO: Revisar esto del file order */
|
|
|
|
found_entry->tagged = 0;
|
|
|
|
found_entry->priority = 0;
|
|
|
|
found_entry->for_purge = 0;
|
2023-07-25 18:34:23 -06:00
|
|
|
|
|
|
|
/* Anexar al final de la lista */
|
2025-01-13 17:25:09 -06:00
|
|
|
handle->resolver_entries = f_list_append (handle->resolver_entries, found_entry);
|
2023-07-25 18:34:23 -06:00
|
|
|
|
|
|
|
/* TODO: Como creamos una entrada via el resolvconf, regenerar el archivo */
|
2025-01-13 17:25:09 -06:00
|
|
|
printf ("/// Nueva entrada %s via resolvconf, programando regeneración.\n", found_entry->value);
|
2023-07-25 18:34:23 -06:00
|
|
|
do_write = 1;
|
|
|
|
}
|
2025-01-13 17:25:09 -06:00
|
|
|
|
|
|
|
g = g->next;
|
2023-07-25 18:34:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Si hubo actualización cambios, disparar ahora */
|
|
|
|
if (do_write == 1) {
|
|
|
|
resolv_manager_write (handle);
|
2023-07-21 22:58:05 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-28 17:01:59 -06:00
|
|
|
void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface) {
|
2024-01-09 23:02:39 -06:00
|
|
|
FList *pos_entry;
|
2023-07-28 17:01:59 -06:00
|
|
|
int h;
|
|
|
|
ResolvConfEntry *entry;
|
|
|
|
int do_write = 0;
|
|
|
|
|
|
|
|
/* Recorrer todas las entradas que sean tipo DHCP y marcar para eliminación */
|
|
|
|
resolv_manager_clear_tag_on_all (handle);
|
|
|
|
|
|
|
|
pos_entry = handle->resolver_entries;
|
|
|
|
while (pos_entry != NULL) {
|
|
|
|
entry = (ResolvConfEntry *) pos_entry->data;
|
|
|
|
|
|
|
|
if (entry->origin == RESOLV_ORIGIN_DHCP && entry->owner_interface_index == iface->index) {
|
|
|
|
/* Nos interesa para eliminación */
|
|
|
|
entry->for_purge = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos_entry = pos_entry->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ahora, procesar la información de DHCP buscando entradas (viejas o de archivo) para reciclar.
|
|
|
|
* Si no, crear */
|
|
|
|
for (h = 0; h < iface->dhcpc.dns_c; h++) {
|
|
|
|
entry = NULL;
|
|
|
|
while (entry == NULL) {
|
|
|
|
pos_entry = resolv_parser_search_entry (handle->resolver_entries, RESOLV_TYPE_NAMESERVER, AF_INET, &iface->dhcpc.dns[h], "", 1);
|
|
|
|
if (pos_entry == NULL) break;
|
|
|
|
|
|
|
|
/* 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_DHCP;
|
|
|
|
entry->owner_interface_index = iface->index;
|
|
|
|
entry->tagged = 1;
|
|
|
|
entry->owner_prog[0] = 0;
|
|
|
|
printf ("/// Asociando una entrada %s existente del archivo al DHCP (%s)\n", entry->value, iface->name);
|
|
|
|
} else if (entry->origin == RESOLV_ORIGIN_DHCP && entry->owner_interface_index == iface->index) {
|
|
|
|
/* Una entrada vieja coincide, reciclar */
|
|
|
|
entry->tagged = 1;
|
|
|
|
entry->for_purge = 0;
|
|
|
|
} else {
|
|
|
|
/* Existe la entrada, pero no la podemos tomar como nuestra, buscar otra */
|
|
|
|
entry->tagged = 1;
|
|
|
|
entry = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Si la entrada no se pudo conciliar, crear una */
|
|
|
|
if (entry == NULL) {
|
|
|
|
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
|
|
|
|
|
|
|
entry->resolv_type = RESOLV_TYPE_NAMESERVER;
|
|
|
|
entry->origin = RESOLV_ORIGIN_DHCP;
|
|
|
|
entry->owner_interface_index = iface->index;
|
|
|
|
entry->owner_prog[0] = 0;
|
|
|
|
entry->file_order = h;
|
|
|
|
entry->tagged = 0;
|
|
|
|
entry->priority = 0;
|
|
|
|
entry->for_purge = 0;
|
|
|
|
entry->ns_family = AF_INET;
|
|
|
|
memcpy (&entry->nameserver, &iface->dhcpc.dns[h], 4);
|
|
|
|
inet_ntop (AF_INET, &entry->nameserver, entry->value, sizeof (entry->value));
|
|
|
|
|
|
|
|
/* Anexar al final de la lista */
|
2024-01-09 23:02:39 -06:00
|
|
|
handle->resolver_entries = f_list_append (handle->resolver_entries, entry);
|
2023-07-28 17:01:59 -06:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
do_write = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Si tiene un nombre de dominio, agregar como entrada tipo search */
|
|
|
|
if (iface->dhcpc.domain_name[0] != 0) {
|
|
|
|
entry = NULL;
|
|
|
|
while (entry == NULL) {
|
|
|
|
pos_entry = resolv_parser_search_entry (handle->resolver_entries, RESOLV_TYPE_SEARCH, AF_INET, NULL, iface->dhcpc.domain_name, 1);
|
|
|
|
if (pos_entry == NULL) break;
|
|
|
|
|
|
|
|
/* 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_DHCP;
|
|
|
|
entry->owner_interface_index = iface->index;
|
|
|
|
entry->tagged = 1;
|
|
|
|
entry->owner_prog[0] = 0;
|
|
|
|
printf ("/// Asociando una entrada search %s existente del archivo al DHCP (%s)\n", entry->value, iface->name);
|
|
|
|
} else if (entry->origin == RESOLV_ORIGIN_DHCP && entry->owner_interface_index == iface->index) {
|
|
|
|
/* Una entrada vieja coincide, reciclar */
|
|
|
|
entry->tagged = 1;
|
|
|
|
entry->for_purge = 0;
|
|
|
|
} else {
|
|
|
|
/* Existe la entrada, pero no la podemos tomar como nuestra, buscar otra */
|
|
|
|
entry->tagged = 1;
|
|
|
|
entry = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Si la entrada no se pudo conciliar, crear una */
|
|
|
|
if (entry == NULL) {
|
|
|
|
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
|
|
|
|
|
|
|
entry->resolv_type = RESOLV_TYPE_SEARCH;
|
|
|
|
entry->origin = RESOLV_ORIGIN_DHCP;
|
|
|
|
entry->owner_interface_index = iface->index;
|
|
|
|
entry->owner_prog[0] = 0;
|
|
|
|
entry->file_order = h;
|
|
|
|
entry->tagged = 0;
|
|
|
|
entry->priority = 0;
|
|
|
|
entry->for_purge = 0;
|
|
|
|
entry->ns_family = AF_INET;
|
|
|
|
memset (&entry->nameserver, 0, sizeof (entry->nameserver));
|
|
|
|
strncpy (entry->value, iface->dhcpc.domain_name, sizeof (entry->value));
|
|
|
|
|
|
|
|
/* Anexar al final de la lista */
|
2024-01-09 23:02:39 -06:00
|
|
|
handle->resolver_entries = f_list_append (handle->resolver_entries, entry);
|
2023-07-28 17:01:59 -06:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
do_write = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Después de recorrer las entradas, revisar si quedaron entradas por purgar.
|
|
|
|
* Si hay entradas por purgar, programar una reescritura de archivo */
|
|
|
|
pos_entry = handle->resolver_entries;
|
|
|
|
while (pos_entry != NULL) {
|
|
|
|
entry = (ResolvConfEntry *) pos_entry->data;
|
|
|
|
|
|
|
|
if (entry->for_purge == 1) {
|
|
|
|
do_write = 1;
|
|
|
|
printf ("/// Entrada %s eliminada via DHCP (%s), programando regeneración.\n", entry->value, iface->name);
|
|
|
|
//break;
|
|
|
|
}
|
|
|
|
pos_entry = pos_entry->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (do_write) {
|
|
|
|
resolv_manager_write (handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface) {
|
2024-01-09 23:02:39 -06:00
|
|
|
FList *pos_entry;
|
2023-07-28 17:01:59 -06:00
|
|
|
int h;
|
|
|
|
ResolvConfEntry *entry;
|
|
|
|
int do_write = 0;
|
|
|
|
|
|
|
|
/* Recorrer todas las entradas que sean tipo DHCP y marcar para eliminación */
|
|
|
|
resolv_manager_clear_tag_on_all (handle);
|
|
|
|
|
|
|
|
pos_entry = handle->resolver_entries;
|
|
|
|
while (pos_entry != NULL) {
|
|
|
|
entry = (ResolvConfEntry *) pos_entry->data;
|
|
|
|
|
|
|
|
if (entry->origin == RESOLV_ORIGIN_DHCP && entry->owner_interface_index == iface->index) {
|
|
|
|
/* Nos interesa para eliminación */
|
|
|
|
printf ("/// Entrada %s eliminada via DHCP (%s), programando regeneración.\n", entry->value, iface->name);
|
|
|
|
entry->for_purge = 1;
|
|
|
|
do_write = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos_entry = pos_entry->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (do_write) {
|
|
|
|
resolv_manager_write (handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-21 22:58:05 -06:00
|
|
|
void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
|
|
|
|
FILE *fd;
|
2024-01-09 23:02:39 -06:00
|
|
|
FList *pos, *next;
|
2023-07-21 22:58:05 -06:00
|
|
|
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 */
|
2023-07-25 18:34:23 -06:00
|
|
|
resolv_manager_clear_tag_on_all (handle);
|
|
|
|
|
|
|
|
handle->resolver_entries = resolv_parser_parse_local_file (handle->resolver_entries, fd, RESOLV_ORIGIN_FILE);
|
|
|
|
|
|
|
|
fclose (fd);
|
|
|
|
|
|
|
|
/* A la salida, borrar las que ya no siguen en el archivo */
|
2023-07-21 22:58:05 -06:00
|
|
|
pos = handle->resolver_entries;
|
|
|
|
while (pos != NULL) {
|
2025-01-13 17:25:09 -06:00
|
|
|
next = pos->next;
|
2023-07-21 22:58:05 -06:00
|
|
|
entry = (ResolvConfEntry *) pos->data;
|
|
|
|
|
2023-07-25 18:34:23 -06:00
|
|
|
if (entry->origin == RESOLV_ORIGIN_FILE && entry->tagged == 0) {
|
|
|
|
/* Esta entrada se va, la eliminaron */
|
|
|
|
printf ("/// La entrada %s del resolv.conf fué eliminada del archivo. Purgando nosotros.\n", entry->value);
|
|
|
|
|
|
|
|
entry->for_purge = 1;
|
2025-01-13 17:25:09 -06:00
|
|
|
handle->resolver_entries = f_list_delete_link (handle->resolver_entries, pos);
|
2023-07-25 18:34:23 -06:00
|
|
|
free (entry);
|
2025-01-13 17:25:09 -06:00
|
|
|
entry = NULL;
|
2023-07-25 18:34:23 -06:00
|
|
|
} else {
|
2025-01-13 20:25:22 -06:00
|
|
|
if (entry->was_new) {
|
|
|
|
printf ("/// La entrada %s es nueva en el resolv.conf\n", entry->value);
|
|
|
|
} else {
|
|
|
|
printf ("/// La entrada %s del resolv.conf sigue en el archivo.\n", entry->value);
|
|
|
|
}
|
2023-07-25 18:34:23 -06:00
|
|
|
}
|
2025-01-13 17:25:09 -06:00
|
|
|
pos = next;
|
2023-07-21 22:58:05 -06:00
|
|
|
}
|
|
|
|
|
2023-07-25 18:34:23 -06:00
|
|
|
/* Reordenar las entradas. TODO: Falta leer los ficheros de configuración del resolv.conf */
|
2024-01-09 23:02:39 -06:00
|
|
|
handle->resolver_entries = f_list_sort_with_data (handle->resolver_entries, resolv_manager_sort_entries, NULL);
|
2023-07-25 18:34:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void resolv_manager_write (NetworkInadorHandle *handle) {
|
|
|
|
FILE *fd;
|
2024-01-09 23:02:39 -06:00
|
|
|
FList *pos, *next;
|
2023-07-25 18:34:23 -06:00
|
|
|
ResolvConfEntry *entry;
|
|
|
|
Interface *iface;
|
2023-07-21 22:58:05 -06:00
|
|
|
|
2023-07-25 18:34:23 -06:00
|
|
|
/* Antes de hacer la escritura, siempre hacemos una lectura */
|
2025-01-13 20:25:22 -06:00
|
|
|
printf ("/// Ejecutando pre-lectura de resolv.conf para poderlo modificar\n");
|
2023-07-25 18:34:23 -06:00
|
|
|
resolv_manager_read_local_etc_resolv (handle);
|
2023-07-21 22:58:05 -06:00
|
|
|
|
2023-07-25 18:34:23 -06:00
|
|
|
/* Intentar la escritura */
|
|
|
|
fd = fopen ("/etc/resolv.conf", "w");
|
|
|
|
if (fd != NULL) {
|
|
|
|
fprintf (fd, "# Autogenered by NetworkInador, you can change this file, changes are preserved");
|
|
|
|
fprintf (fd, "\n\n");
|
|
|
|
|
|
|
|
pos = handle->resolver_entries;
|
|
|
|
while (pos != NULL) {
|
|
|
|
entry = (ResolvConfEntry *) pos->data;
|
|
|
|
|
|
|
|
if (entry->for_purge == 1) {
|
|
|
|
/* Omitir */
|
|
|
|
pos = pos->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
iface = _interfaces_locate_by_index (handle->interfaces, entry->owner_interface_index);
|
|
|
|
/* Escribir esta entrada "buena" al resolv.conf */
|
|
|
|
if (entry->origin == RESOLV_ORIGIN_FILE) {
|
|
|
|
fprintf (fd, "# This entry was previously on file, preserving");
|
|
|
|
} else if (entry->origin == RESOLV_ORIGIN_DHCP) {
|
2023-07-28 17:01:59 -06:00
|
|
|
fprintf (fd, "# This entry was added via DHCP (on %s) by NetworkInador", (iface != NULL ? iface->name : "unknown"));
|
2023-07-25 18:34:23 -06:00
|
|
|
} else if (entry->origin == RESOLV_ORIGIN_RESOLVCONF) {
|
|
|
|
fprintf (fd, "# This entry was added via resolvconf (%s.%s)", (iface != NULL ? iface->name : "unknown"), entry->owner_prog);
|
|
|
|
} else if (entry->origin == RESOLV_ORIGIN_SLAAC_RDNSS) {
|
|
|
|
fprintf (fd, "# This entry was added via RDNSS (IPv6)");
|
|
|
|
}
|
|
|
|
fprintf (fd, "\n");
|
|
|
|
|
|
|
|
if (entry->resolv_type == RESOLV_TYPE_NAMESERVER) {
|
|
|
|
fprintf (fd, "nameserver %s\n", entry->value);
|
|
|
|
} else if (entry->resolv_type == RESOLV_TYPE_DOMAIN) {
|
|
|
|
fprintf (fd, "domain %s\n", entry->value);
|
|
|
|
} else if (entry->resolv_type == RESOLV_TYPE_SEARCH) {
|
|
|
|
fprintf (fd, "search %s\n", entry->value);
|
|
|
|
} else if (entry->resolv_type == RESOLV_TYPE_SORTLIST) {
|
|
|
|
fprintf (fd, "sortlist %s\n", entry->value);
|
|
|
|
} else if (entry->resolv_type == RESOLV_TYPE_OPTIONS) {
|
|
|
|
fprintf (fd, "options %s\n", entry->value);
|
|
|
|
}
|
|
|
|
pos = pos->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose (fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Purgar las entradas marcadas para purge */
|
2023-07-21 22:58:05 -06:00
|
|
|
pos = handle->resolver_entries;
|
|
|
|
while (pos != NULL) {
|
|
|
|
next = pos->next;
|
|
|
|
entry = (ResolvConfEntry *) pos->data;
|
|
|
|
|
2023-07-25 18:34:23 -06:00
|
|
|
if (entry->for_purge == 1) {
|
2024-01-09 23:02:39 -06:00
|
|
|
handle->resolver_entries = f_list_delete_link (handle->resolver_entries, pos);
|
2023-07-21 22:58:05 -06:00
|
|
|
free (entry);
|
|
|
|
entry = NULL;
|
|
|
|
}
|
|
|
|
pos = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-13 17:25:09 -06:00
|
|
|
void resolv_manager_notify_close_write_cb (NetworkInadorHandle *handle, const char *path, void *data) {
|
|
|
|
/* Cuando se nos notifique acerca de un cambio en el resolv.conf re-leer el archivo */
|
|
|
|
resolv_manager_read_local_etc_resolv (handle);
|
|
|
|
}
|
|
|
|
|
2023-07-21 22:58:05 -06:00
|
|
|
void resolv_manager_init (NetworkInadorHandle *handle) {
|
2025-01-13 17:25:09 -06:00
|
|
|
network_inador_file_watcher_add_file (handle, "/etc/resolv.conf", resolv_manager_notify_close_write_cb, NULL);
|
2023-07-21 22:58:05 -06:00
|
|
|
|
|
|
|
handle->resolver_entries = NULL;
|
|
|
|
/* Luego, leer el resolv.conf */
|
|
|
|
resolv_manager_read_local_etc_resolv (handle);
|
|
|
|
}
|
|
|
|
|