Mejoras en el cliente dhcp y el cliente gtk.

master
Félix Arreola Rodríguez 2023-07-28 17:01:59 -06:00
parent 009e568920
commit 050fa2893a
11 changed files with 554 additions and 111 deletions

View File

@ -874,10 +874,10 @@ void ni_client_ask_up_down_interface (NIClient *ni_client, NIInterface *ni_inter
send (ni_client->priv->client_socket, buffer, 6, 0);
}
void ni_client_ask_dhcp_run_interface (NIClient *ni_client, NIInterface *ni_interface, int type) {
void ni_client_ask_dhcp_run_interface (NIClient *ni_client, NIInterface *ni_interface, int type, guint flags) {
unsigned char buffer[16];
uint32_t index;
uint32_t flags = 0x1;
uint32_t flags_to_send = flags;
if (ni_client->priv->client_socket < 0) {
return;
@ -895,7 +895,7 @@ void ni_client_ask_dhcp_run_interface (NIClient *ni_client, NIInterface *ni_inte
buffer[6] = AF_INET;
buffer[7] = type;
memcpy (&buffer[8], &flags, 4);
memcpy (&buffer[8], &flags_to_send, 4);
send (ni_client->priv->client_socket, buffer, 12, 0);
}

View File

@ -113,7 +113,7 @@ void ni_client_ask_interface_clear_master (NIClient *ni_client, NIInterface *ni_
void ni_client_ask_interface_set_master (NIClient *ni_client, NIInterface *ni_interface, NIInterface *master);
void ni_client_ask_dhcp_stop_interface (NIClient *ni_client, NIInterface *ni_interface);
void ni_client_ask_dhcp_run_interface (NIClient *ni_client, NIInterface *ni_interface, int type);
void ni_client_ask_dhcp_run_interface (NIClient *ni_client, NIInterface *ni_interface, int type, guint flags);
void ni_client_ask_interface_dhcp_status (NIClient *ni_client, NIInterface *ni_interface);

View File

@ -828,10 +828,10 @@ void ni_interface_set_up (NIInterface *ni_interface) {
ni_client_ask_up_down_interface (ni_interface->priv->ni_client, ni_interface, TRUE);
}
void ni_interface_run_dhcp (NIInterface *ni_interface, int type) {
void ni_interface_run_dhcp (NIInterface *ni_interface, int type, guint flags) {
g_return_if_fail (NI_IS_INTERFACE (ni_interface));
ni_client_ask_dhcp_run_interface (ni_interface->priv->ni_client, ni_interface, type);
ni_client_ask_dhcp_run_interface (ni_interface->priv->ni_client, ni_interface, type, flags);
}
void ni_interface_stop_dhcp (NIInterface *ni_interface) {

View File

@ -79,7 +79,7 @@ const GList *ni_interface_get_ip_list (NIInterface *ni_interface);
guint ni_interface_get_flags (NIInterface *ni_interface);
void ni_interface_set_down (NIInterface *ni_interface);
void ni_interface_set_up (NIInterface *ni_interface);
void ni_interface_run_dhcp (NIInterface *ni_interface, int type);
void ni_interface_run_dhcp (NIInterface *ni_interface, int type, guint flags);
void ni_interface_stop_dhcp (NIInterface *ni_interface);
guint ni_interface_get_dhcp_type (NIInterface *ni_interface);

View File

@ -57,7 +57,12 @@ struct _NIWindowInterfacePrivate {
GtkWidget *tree_ipv4, *tree_ipv6, *tree_bridge_ports;
GtkWidget *button_dhcp_run, *button_dhcp_stop;
GtkWidget *dhcpv4_info;
GtkWidget *vbox_dhcpv4_info;
GtkWidget *check_flag_autorestart, *check_flag_no_dns, *check_flag_no_gws, *check_flag_no_ip;
GtkWidget *dhcpv4_process, *dhcpv4_status;
GtkWidget *dhcpv4_ip_label, *dhcpv4_gateway_label;
GtkWidget *dhcpv4_bcast_label, *dhcpv4_dns_label, *dhcpv4_server_label;
GtkWidget *dhcpv4_time_label, *dhcpv4_domain_label;
GtkWidget *menu_dhcpv4;
int dhcp_type;
};
@ -585,76 +590,110 @@ static void ni_window_interface_update_dhcp_status (NIWindowInterface *window_if
type = ni_interface_get_dhcp_type (ni_interface);
if (type == 0) {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_info), "Información cliente DHCP:\nNo hay proceso corriendo");
gtk_widget_hide (window_iface->priv->vbox_dhcpv4_info);
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_process), "Ninguno");
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "No hay proceso corriendo");
} else {
if (type == 1) {
pos = g_snprintf (buffer, sizeof (buffer), "Información cliente DHCP: Cliente ISC\n");
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_process), "Cliente DHCP ISC");
} else if (type == 2) {
pos = g_snprintf (buffer, sizeof (buffer), "Información cliente DHCP: Cliente Busybox UDHCPC\n");
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_process), "Cliente Busybox UDHCPC");
}
status = ni_interface_get_dhcp_status (ni_interface);
if (status == 5) {
/* El proceso murió */
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Proceso muerto");
gtk_widget_hide (window_iface->priv->vbox_dhcpv4_info);
return;
} else if (status == 0 || status == 4) {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Buscando...");
gtk_widget_hide (window_iface->priv->vbox_dhcpv4_info);
return;
} else if (status == 1 || status == 2) {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Concesión obtenida");
} else if (status == 3) {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Concesión expirada");
}
addr = ni_interface_get_dhcp_addr (ni_interface);
prefix = ni_interface_get_dhcp_prefix (ni_interface);
inet_ntop (AF_INET, addr, buffer_ip, sizeof (buffer_ip));
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "Dirección IP: %s/%i\n", buffer_ip, prefix);
g_snprintf (buffer, sizeof (buffer), "%s/%i", buffer_ip, prefix);
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_ip_label), buffer);
c = ni_interface_get_dhcp_gw_count (ni_interface);
addr = ni_interface_get_dhcp_gw_addr (ni_interface);
if (c > 0) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "Gateway: ");
}
for (g = 0; g < c; g++) {
inet_ntop (AF_INET, &addr[g], buffer_ip, sizeof (buffer_ip));
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "%s,", buffer_ip);
}
if (c > 0) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "\n");
if (c == 0) {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_gateway_label), "");
} else {
pos = 0;
for (g = 0; g < c; g++) {
inet_ntop (AF_INET, &addr[g], buffer_ip, sizeof (buffer_ip));
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "%s", buffer_ip);
if (g != c - 1) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, ", ");
}
}
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_gateway_label), buffer);
}
if (ni_interface_has_dhcp_brd_addr (ni_interface)) {
addr = ni_interface_get_dhcp_brd_addr (ni_interface);
inet_ntop (AF_INET, addr, buffer_ip, sizeof (buffer_ip));
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "Broadcast: %s\n", buffer_ip);
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_bcast_label), buffer_ip);
} else {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_bcast_label), "");
}
c = ni_interface_get_dhcp_dns_count (ni_interface);
addr = ni_interface_get_dhcp_dns_addr (ni_interface);
if (c > 0) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "DNS: ");
}
for (g = 0; g < c; g++) {
inet_ntop (AF_INET, &addr[g], buffer_ip, sizeof (buffer_ip));
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "%s,", buffer_ip);
}
if (c > 0) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "\n");
if (c == 0) {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_dns_label), "");
} else {
pos = 0;
for (g = 0; g < c; g++) {
inet_ntop (AF_INET, &addr[g], buffer_ip, sizeof (buffer_ip));
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "%s", buffer_ip);
if (g != c - 1) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, ", ");
}
}
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_dns_label), buffer);
}
if (ni_interface_has_dhcp_server_addr (ni_interface)) {
addr = ni_interface_get_dhcp_server_addr (ni_interface);
inet_ntop (AF_INET, addr, buffer_ip, sizeof (buffer_ip));
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "DHCP Server: %s\n", buffer_ip);
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_server_label), buffer_ip);
} else {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_server_label), "");
}
lease_time = ni_interface_get_dhcp_lease_time (ni_interface);
if (lease_time != 0) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "Tiempo de concesión: %i seg(s)\n", lease_time);
g_snprintf (buffer, sizeof (buffer), "%i seg(s)", lease_time);
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_time_label), buffer);
} else {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_time_label), "");
}
domain_name = ni_interface_get_dhcp_domain_name (ni_interface);
if (domain_name != NULL) {
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "Nombre de dominio: %s\n", domain_name);
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_domain_label), domain_name);
} else {
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_domain_label), "");
}
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_info), buffer);
gtk_widget_show (window_iface->priv->vbox_dhcpv4_info);
}
}
@ -816,9 +855,27 @@ static void ni_window_interface_aditional_setup_for_bridge (NIWindowInterface *w
/* Eventos de los botones de DHCP */
static void ni_window_interface_dhcp_run_cb (GtkWidget *button, gpointer data) {
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
guint flags;
flags = 0;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_autorestart))) {
flags |= 0x0001;
}
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_no_dns))) {
flags |= 0x0002;
}
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_no_gws))) {
flags |= 0x0004;
}
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_no_ip))) {
flags |= 0x0008;
}
// Ejecutar el DHCP aquí
ni_interface_run_dhcp (window_iface->priv->ni_interface, window_iface->priv->dhcp_type);
ni_interface_run_dhcp (window_iface->priv->ni_interface, window_iface->priv->dhcp_type, flags);
}
static void ni_window_interface_dhcp_stop_cb (GtkWidget *button, gpointer data) {
@ -1196,6 +1253,7 @@ static void prepare_bridge_tab (NIWindowInterface *window_iface) {
static void prepare_dhcpv4_tab (NIWindowInterface *window_iface) {
GtkWidget *vbox, *hbox, *label, *button;
GtkSizeGroup *size_l;
GtkWidget *expander;
GtkWindow *window = GTK_WINDOW (window_iface);
NIWindowInterfacePrivate *priv = window_iface->priv;
GtkWidget *item;
@ -1245,11 +1303,162 @@ static void prepare_dhcpv4_tab (NIWindowInterface *window_iface) {
g_signal_connect (priv->button_dhcp_run, "clicked", G_CALLBACK (ni_window_interface_dhcp_run_cb), window_iface);
gtk_box_pack_end (GTK_BOX (hbox), priv->button_dhcp_run, FALSE, FALSE, 0);
/* Generar un expander para opciones avanzadas */
expander = gtk_expander_new_with_mnemonic ("_Opciones avanzadas");
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), expander, FALSE, FALSE, 0);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
gtk_container_add (GTK_CONTAINER (expander), vbox);
/* Primera opción, autoreiniciar */
priv->check_flag_autorestart = gtk_check_button_new_with_label ("Autoreiniciar proceso");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_autorestart), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_autorestart, FALSE, FALSE, 3);
/* Segunda opción, no instalar información DNS */
priv->check_flag_no_dns = gtk_check_button_new_with_label ("No instalar información DNS");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_no_dns), FALSE);
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_no_dns, FALSE, FALSE, 3);
/* Tercera opción, no instalar información del gateway */
priv->check_flag_no_gws = gtk_check_button_new_with_label ("No instalar rutas por defecto");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_no_gws), FALSE);
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_no_gws, FALSE, FALSE, 3);
/* Cuarta opción, no instalar información de las ips */
priv->check_flag_no_ip = gtk_check_button_new_with_label ("No instalar dirección IP adquirida");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_no_ip), FALSE);
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_no_ip, FALSE, FALSE, 3);
/* Las labels del estado */
priv->dhcpv4_info = gtk_label_new ("Información cliente DHCP: ");
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_info), TRUE);
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_info), 0.0);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), priv->dhcpv4_info, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Tipo de cliente:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_process = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_process), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_process), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_process, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Estado:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_status = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_status), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_status), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_status, FALSE, FALSE, 0);
/* Un super vbox para ocultar toda la información de DHCP */
priv->vbox_dhcpv4_info = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), priv->vbox_dhcpv4_info, FALSE, FALSE, 10);
/* Placeholder para la IP */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Dirección IP:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_ip_label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_ip_label), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_ip_label), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_ip_label, FALSE, FALSE, 0);
/* Placeholder para el gateway */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Gateway:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_gateway_label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_gateway_label), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_gateway_label), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_gateway_label, FALSE, FALSE, 0);
/* Placeholder para el broadcast, si está presente */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Broadcast:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_bcast_label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_bcast_label), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_bcast_label), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_bcast_label, FALSE, FALSE, 0);
/* Placer holder para los DNS */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("DNS:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_dns_label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_dns_label), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_dns_label), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_dns_label, FALSE, FALSE, 0);
/* Placer holder para el nombre del servidor DHCP */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Servidor DHCP:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_server_label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_server_label), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_server_label), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_server_label, FALSE, FALSE, 0);
/* Placeholder para el tiempo de concesión */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Tiempo de concesión:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_time_label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_time_label), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_time_label), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_time_label, FALSE, FALSE, 0);
/* Placeholder para el dominio */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Dominio:");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_size_group_add_widget (size_l, label);
priv->dhcpv4_domain_label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_domain_label), 0.0);
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_domain_label), TRUE);
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_domain_label, FALSE, FALSE, 0);
}
static void ni_window_interface_init (NIWindowInterface *window_iface) {

View File

@ -3,6 +3,7 @@
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 \

View File

@ -36,7 +36,7 @@
#include "struct_addr_union.h"
#include "resolv_conf_defs.h"
#include "dhcpc_defs.h"
#ifndef FALSE
#define FALSE 0
@ -118,47 +118,6 @@ typedef struct _WirelessInfo {
GList *aps;
} WirelessInfo;
/* Información del proceso de DHCP */
enum {
IFACE_NO_DHCP = 0,
IFACE_ISC_DHCLIENT,
IFACE_BUSYBOX_UDHCPC
};
/* FIXME: Revisar estos estados */
enum {
DHCP_CLIENT_SELECTING,
DHCP_CLIENT_BOUND,
DHCP_CLIENT_RENEWED,
DHCP_CLIENT_EXPIRED,
DHCP_CLIENT_FAILED,
DHCP_CLIENT_KILLED,
};
#define DHCP_CLIENT_FLAG_AUTO_RESTART 0x0001
typedef struct _InterfaceDHCPClientInfo {
int type;
uint32_t flags;
int dhcp_state;
/* Para vigilar el proceso */
GPid process_pid;
guint process_watch;
/* La información obtenida desde el cliente */
struct_addr ip, broadcast;
struct_addr gateways[7], dns[7];
char domain_name[256];
int gw_c, dns_c;
int prefix;
struct_addr dhcp_server_ip;
uint32_t lease_time;
} InterfaceDHCPClientInfo;
struct _Interface {
NetworkInadorHandle *handle;

View File

@ -39,6 +39,7 @@
#include "dhcp_client.h"
#include "network-inador-manager.h"
#include "resolv_manager.h"
static void interfaces_dhcp_clear_info (InterfaceDHCPClientInfo *dhcpc);
@ -96,6 +97,8 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
}
interfaces_dhcp_clear_info (&iface->dhcpc);
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);
@ -130,6 +133,7 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
} else {
/* En caso contrario, solo dejar la muerte escrita */
iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED;
g_source_remove (iface->dhcpc.process_watch);
iface->dhcpc.process_watch = 0;
}
}
@ -230,22 +234,23 @@ int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
}
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT || iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) {
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return -1;
/* Proceso, matar y reiniciar estado */
iface->dhcpc.flags &= (~DHCP_CLIENT_FLAG_AUTO_RESTART);
g_source_remove (iface->dhcpc.process_watch);
iface->dhcpc.process_watch = 0;
g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_ignore_kill, NULL);
kill (iface->dhcpc.process_pid, SIGTERM);
if (iface->dhcpc.dhcp_state != DHCP_CLIENT_KILLED) {
/* Proceso, matar y reiniciar estado */
iface->dhcpc.flags &= (~DHCP_CLIENT_FLAG_AUTO_RESTART);
g_source_remove (iface->dhcpc.process_watch);
iface->dhcpc.process_watch = 0;
g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_ignore_kill, NULL);
kill (iface->dhcpc.process_pid, SIGTERM);
iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED;
}
iface->dhcpc.type = IFACE_NO_DHCP;
iface->dhcpc.dhcp_state = DHCP_CLIENT_KILLED;
/* TODO: Revisar aquí si es pertinente desconfigurar la interfaz y borrar la información obtenida */
interfaces_dhcp_clear_info (&iface->dhcpc);
/* TODO: Revisar aquí si es pertinente desconfigurar la interfaz y borrar la información obtenida */
resolv_manager_clear_dhcp_nameservers (handle, iface);
/* Enviar actualización de estado aquí */
manager_send_event_dhcp_change (handle, &iface->dhcpc);
}
@ -255,10 +260,10 @@ int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *handle, int index, int status, struct_addr *ip, int prefix, struct_addr *gateways, int gw_c, struct_addr *broadcast, struct_addr *dhcp_server, uint32_t lease_time, struct_addr *dns_list, int dns_count, char *domain_name) {
Interface *iface;
struct in_addr empty_v4;
int g;
struct_addr old_dns[7];
int old_dns_c;
int dns_changed;
iface = _interfaces_locate_by_index (handle->interfaces, index);
@ -300,6 +305,7 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
printf ("----> DHCP status: %i\n", iface->dhcpc.dhcp_state);
if (status == NET_INADOR_DHCP_STATUS_BOUND || status == NET_INADOR_DHCP_STATUS_RENEWED) {
dns_changed = 0;
/* Copiar la información de DNS para saber si hubo cambios */
old_dns_c = iface->dhcpc.dns_c;
if (old_dns_c != dns_count) {
@ -308,8 +314,6 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
}
/* Copiar las variables de estado */
memset (&empty_v4, 0, sizeof (empty_v4));
memcpy (&iface->dhcpc.ip, ip, sizeof (iface->dhcpc.ip));
iface->dhcpc.prefix = prefix;
@ -327,13 +331,23 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
memcpy (&iface->dhcpc.dns[g], &dns_list[g], 4);
}
if (strcmp (iface->dhcpc.domain_name, domain_name) != 0) {
/* El nombre de dominio cambió */
dns_changed = 1;
}
strncpy (iface->dhcpc.domain_name, domain_name, sizeof (iface->dhcpc.domain_name));
if (iface->dhcpc.dns_c != old_dns_c) {
/* TODO: Tenemos cambio en los DNS, actualizar el resolv.conf */
/* Tenemos cambio en los DNS, actualizar el resolv.conf */
dns_changed = 1;
} 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 */
/* Tenemos cambio en los DNS, actualizar el resolv.conf */
dns_changed = 1;
}
strncpy (iface->dhcpc.domain_name, domain_name, sizeof (iface->dhcpc.domain_name));
if (dns_changed) {
resolv_manager_process_dhcp_nameservers (handle, iface);
}
/* Esto solo es para impresión */
char buf_a[256], buf_b[256], buf_c[256], buf_d[256];
@ -354,6 +368,11 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
}
printf (" y domain name <%s>\n", domain_name);
} else if (status == NET_INADOR_DHCP_STATUS_SELECTING || status == NET_INADOR_DHCP_STATUS_EXPIRED || status == NET_INADOR_DHCP_STATUS_FAILED) {
/* Cuando entramos a SELECTING, debemos limpiar los DNS del resolv.conf */
interfaces_dhcp_clear_info (&iface->dhcpc);
resolv_manager_clear_dhcp_nameservers (handle, iface);
}
manager_send_event_dhcp_change (handle, &iface->dhcpc);

77
src/dhcpc_defs.h 100644
View File

@ -0,0 +1,77 @@
/*
* dhcpc_defs.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 __DHCPC_DEFS_H__
#define __DHCPC_DEFS_H__
#include <stdint.h>
#include <glib.h>
#include "struct_addr_union.h"
/* Información del proceso de DHCP */
enum {
IFACE_NO_DHCP = 0,
IFACE_ISC_DHCLIENT,
IFACE_BUSYBOX_UDHCPC
};
/* FIXME: Revisar estos estados */
enum {
DHCP_CLIENT_SELECTING,
DHCP_CLIENT_BOUND,
DHCP_CLIENT_RENEWED,
DHCP_CLIENT_EXPIRED,
DHCP_CLIENT_FAILED,
DHCP_CLIENT_KILLED,
};
#define DHCP_CLIENT_FLAG_AUTO_RESTART 0x0001
#define DHCP_CLIENT_FLAG_DONT_ADD_DNS_INFO 0x0002
#define DHCP_CLIENT_FLAG_DONT_ADD_ROUTE_INFO 0x0004
#define DHCP_CLIENT_FLAG_DONT_ADD_IP_INFO 0x0008
typedef struct {
int type;
uint32_t flags;
int dhcp_state;
/* Para vigilar el proceso */
GPid process_pid;
guint process_watch;
/* La información obtenida desde el cliente */
struct_addr ip, broadcast;
struct_addr gateways[7], dns[7];
char domain_name[256];
int gw_c, dns_c;
int prefix;
struct_addr dhcp_server_ip;
uint32_t lease_time;
} InterfaceDHCPClientInfo;
#endif /* __DHCPC_DEFS_H__ */

View File

@ -26,6 +26,8 @@
#include <ctype.h>
#include <sys/inotify.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include "resolv_manager.h"
#include "common.h"
@ -70,13 +72,8 @@ void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const in
while (g != NULL) {
entry = (ResolvConfEntry *) g->data;
if (entry->origin != RESOLV_ORIGIN_RESOLVCONF) {
/* Solo borramos las entradas creadas via resolvconf */
g = g->next;
continue;
}
if (entry->owner_interface_index != iface_index) {
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 */
g = g->next;
continue;
}
@ -138,6 +135,7 @@ void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, Res
entry->tagged = 1;
strncpy (entry->owner_prog, entries[g].owner_prog, sizeof (entry->owner_prog));
printf ("/// Asociando una entrada %s existente del archivo al: %s\n", entry->value, entry->owner_prog);
#if 0
} else if (entry->origin == RESOLV_ORIGIN_DHCP) {
/* Una entrada que coincide con la actual solo se puede re-asociar al resolvconf si pertenece a la misma interfaz */
if (entry->owner_interface_index != entries[g].owner_interface_index) {
@ -145,6 +143,7 @@ void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, Res
entry = NULL;
continue;
}
#endif
} else {
/* Existe la entrada, pero no la podemos tomar como nuestra, crear otra */
entry->tagged = 1;
@ -178,6 +177,183 @@ void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, Res
}
}
void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface) {
GList *pos_entry;
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 */
handle->resolver_entries = g_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);
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 */
handle->resolver_entries = g_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);
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) {
GList *pos_entry;
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);
}
}
void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
FILE *fd;
GList *pos, *next;
@ -248,7 +424,7 @@ void resolv_manager_write (NetworkInadorHandle *handle) {
if (entry->origin == RESOLV_ORIGIN_FILE) {
fprintf (fd, "# This entry was previously on file, preserving");
} else if (entry->origin == RESOLV_ORIGIN_DHCP) {
fprintf (fd, "# This entry was added via DHCP (on %s) via NetworkInador", (iface != NULL ? iface->name : "unknown"));
fprintf (fd, "# This entry was added via DHCP (on %s) by NetworkInador", (iface != NULL ? iface->name : "unknown"));
} 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) {

View File

@ -30,6 +30,8 @@
void resolv_manager_init (NetworkInadorHandle *handle);
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog);
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, ResolvConfEntry *entries, int num_entries);
void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);
void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);
//void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle);
//void resolv_manager_write (NetworkInadorHandle *handle);