Agrego comandos que alimentan la información del cliente DHCP
parent
bf315b5b03
commit
f048dde998
|
@ -48,4 +48,4 @@ client-gtk/ni-marshal.c
|
||||||
client-gtk/ni-marshal.h
|
client-gtk/ni-marshal.h
|
||||||
client-gtk/core
|
client-gtk/core
|
||||||
|
|
||||||
src/ni-iface-helper
|
src/ni-dhcp-helper
|
||||||
|
|
|
@ -12,11 +12,11 @@ network_inador_SOURCES = main.c \
|
||||||
wireless_if.c wireless_if.h \
|
wireless_if.c wireless_if.h \
|
||||||
wireless_bss.c wireless_bss.h
|
wireless_bss.c wireless_bss.h
|
||||||
|
|
||||||
libexec_PROGRAMS = ni-iface-helper
|
libexec_PROGRAMS = ni-dhcp-helper
|
||||||
|
|
||||||
ni_iface_helper_SOURCES = ni-iface-helper.c
|
ni_dhcp_helper_SOURCES = ni-dhcp-iface-helper.c
|
||||||
ni_iface_helper_CPPFLAGS = $(AM_CPPFLAGS)
|
ni_dhcp_helper_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
ni_iface_helper_CFLAGS = $(AM_CFLAGS)
|
ni_dhcp_helper_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
#network_inador_CPPFLAGS = -DGAMEDATA_DIR=\"$(gamedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
|
#network_inador_CPPFLAGS = -DGAMEDATA_DIR=\"$(gamedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
|
||||||
network_inador_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
|
network_inador_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
|
||||||
|
|
17
src/common.h
17
src/common.h
|
@ -120,13 +120,14 @@ enum {
|
||||||
IFACE_ISC_DHCLIENT
|
IFACE_ISC_DHCLIENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* FIXME: Revisar estos estados */
|
||||||
enum {
|
enum {
|
||||||
DHCP_CLIENT_INITING,
|
|
||||||
|
|
||||||
DHCP_CLIENT_SELECTING,
|
DHCP_CLIENT_SELECTING,
|
||||||
DHCP_CLIENT_REQUESTING,
|
|
||||||
DHCP_CLIENT_BOUND,
|
DHCP_CLIENT_BOUND,
|
||||||
DHCP_CLIENT_RENEWING,
|
DHCP_CLIENT_RENEWED,
|
||||||
|
|
||||||
|
DHCP_CLIENT_EXPIRED,
|
||||||
|
DHCP_CLIENT_FAILED,
|
||||||
|
|
||||||
DHCP_CLIENT_KILLED,
|
DHCP_CLIENT_KILLED,
|
||||||
DHCP_CLIENT_EXTERNAL_RUNNING
|
DHCP_CLIENT_EXTERNAL_RUNNING
|
||||||
|
@ -143,6 +144,14 @@ typedef struct _InterfaceDHCPClientInfo {
|
||||||
/* Para vigilar el proceso */
|
/* Para vigilar el proceso */
|
||||||
GPid process_pid;
|
GPid process_pid;
|
||||||
guint process_watch;
|
guint process_watch;
|
||||||
|
|
||||||
|
/* La información obtenida desde el cliente */
|
||||||
|
struct_addr ip, gateway, broadcast;
|
||||||
|
int prefix;
|
||||||
|
|
||||||
|
struct_addr dhcp_server_ip;
|
||||||
|
|
||||||
|
/* TODO: Falta almacenar la información de DNS */
|
||||||
} InterfaceDHCPClientInfo;
|
} InterfaceDHCPClientInfo;
|
||||||
|
|
||||||
struct _Interface {
|
struct _Interface {
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
|
@ -38,10 +41,9 @@ void interfaces_dhcp_client_ignore_kill (GPid pid, gint status, gpointer data) {
|
||||||
g_spawn_check_exit_status (status, NULL);
|
g_spawn_check_exit_status (status, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void interfaces_dhcp_prepare_args_for_dhclient (char **argv, int size, char *iface_name) {
|
void interfaces_dhcp_prepare_args_for_dhclient (char **argv, int size, char *iface_name, char *pid_file, size_t pid_file_len) {
|
||||||
gchar pid_file[256];
|
snprintf (pid_file, pid_file_len, "/run/dhclient-%s.pid", iface_name);
|
||||||
|
|
||||||
snprintf (pid_file, sizeof (pid_file), "/run/dhclient-%s.pid", iface_name);
|
|
||||||
/* Preparar los argumentos para el proceso */
|
/* Preparar los argumentos para el proceso */
|
||||||
argv[0] = "/sbin/dhclient";
|
argv[0] = "/sbin/dhclient";
|
||||||
argv[1] = "-d";
|
argv[1] = "-d";
|
||||||
|
@ -49,7 +51,7 @@ void interfaces_dhcp_prepare_args_for_dhclient (char **argv, int size, char *ifa
|
||||||
argv[3] = "-pf";
|
argv[3] = "-pf";
|
||||||
argv[4] = pid_file;
|
argv[4] = pid_file;
|
||||||
argv[5] = "-sf";
|
argv[5] = "-sf";
|
||||||
argv[6] = "/home/gatuno/Proyectos/NetworkInador/src/ni-iface-helper";
|
argv[6] = "/home/gatuno/Proyectos/NetworkInador/src/ni-dhcp-helper";
|
||||||
argv[7] = iface_name;
|
argv[7] = iface_name;
|
||||||
argv[8] = NULL;
|
argv[8] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -59,9 +61,10 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *argv[20];
|
char *argv[20];
|
||||||
|
gchar pid_file[256];
|
||||||
|
|
||||||
/* Preparar los argumentos */
|
/* Preparar los argumentos */
|
||||||
interfaces_dhcp_prepare_args_for_dhclient (argv, 20, iface->name);
|
interfaces_dhcp_prepare_args_for_dhclient (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||||
|
|
||||||
if (g_spawn_check_exit_status (status, NULL)) {
|
if (g_spawn_check_exit_status (status, NULL)) {
|
||||||
/* Revisar si necesito algo */
|
/* Revisar si necesito algo */
|
||||||
|
@ -108,6 +111,7 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *argv[20];
|
char *argv[20];
|
||||||
|
gchar pid_file[256];
|
||||||
|
|
||||||
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||||
|
|
||||||
|
@ -118,7 +122,7 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Preparar los argumentos */
|
/* Preparar los argumentos */
|
||||||
interfaces_dhcp_prepare_args_for_dhclient (argv, 20, iface->name);
|
interfaces_dhcp_prepare_args_for_dhclient (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||||
|
|
||||||
if (iface->dhcpc.type != IFACE_NO_DHCP) {
|
if (iface->dhcpc.type != IFACE_NO_DHCP) {
|
||||||
/* No puedo correr otro tipo de DHCP */
|
/* No puedo correr otro tipo de DHCP */
|
||||||
|
@ -191,8 +195,9 @@ void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void interfaces_dhcp_client_internal_set_status (NetworkInadorHandle *handle, int index, int status) {
|
void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *handle, int index, int status, struct_addr *ip, int prefix, struct_addr *gateway, struct_addr *broadcast, struct_addr *dhcp_server, uint32_t lease_time, struct_addr *dns_list, int dns_count, char *domain_name) {
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
|
struct in_addr empty_v4;
|
||||||
|
|
||||||
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||||
|
|
||||||
|
@ -211,10 +216,45 @@ void interfaces_dhcp_client_internal_set_status (NetworkInadorHandle *handle, in
|
||||||
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return;
|
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return;
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case NET_INADOR_DHCP_STATUS_INITING:
|
case NET_INADOR_DHCP_STATUS_SELECTING:
|
||||||
iface->dhcpc.dhcp_state = DHCP_CLIENT_INITING;
|
iface->dhcpc.dhcp_state = DHCP_CLIENT_SELECTING;
|
||||||
|
break;
|
||||||
|
case NET_INADOR_DHCP_STATUS_BOUND:
|
||||||
|
iface->dhcpc.dhcp_state = DHCP_CLIENT_BOUND;
|
||||||
|
break;
|
||||||
|
case NET_INADOR_DHCP_STATUS_RENEWED:
|
||||||
|
iface->dhcpc.dhcp_state = DHCP_CLIENT_RENEWED;
|
||||||
|
break;
|
||||||
|
case NET_INADOR_DHCP_STATUS_EXPIRED:
|
||||||
|
iface->dhcpc.dhcp_state = DHCP_CLIENT_EXPIRED;
|
||||||
|
/* Borrar la IP anterior, si es que está puesta */
|
||||||
|
break;
|
||||||
|
case NET_INADOR_DHCP_STATUS_FAILED:
|
||||||
|
iface->dhcpc.dhcp_state = DHCP_CLIENT_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf ("----> DHCP status: %i\n", iface->dhcpc.dhcp_state);
|
||||||
|
|
||||||
|
if (status == NET_INADOR_DHCP_STATUS_BOUND || status == NET_INADOR_DHCP_STATUS_RENEWED) {
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
memcpy (&iface->dhcpc.gateway, gateway, sizeof (iface->dhcpc.gateway));
|
||||||
|
|
||||||
|
memcpy (&iface->dhcpc.broadcast, broadcast, sizeof (iface->dhcpc.broadcast));
|
||||||
|
memcpy (&iface->dhcpc.dhcp_server_ip, dhcp_server, sizeof (iface->dhcpc.dhcp_server_ip));
|
||||||
|
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.gateway, buf_b, sizeof (buf_b));
|
||||||
|
inet_ntop (AF_INET, &iface->dhcpc.broadcast, buf_c, sizeof (buf_c));
|
||||||
|
inet_ntop (AF_INET, &iface->dhcpc.dhcp_server_ip, buf_d, sizeof (buf_d));
|
||||||
|
printf ("----> DHCP Server (%s), IP obtenida: %s/%i, GW: %s y bcast: %s, lease: %i\n", buf_d, buf_a, prefix, buf_b, buf_c, lease_time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags);
|
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags);
|
||||||
void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);
|
void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);
|
||||||
void interfaces_dhcp_client_internal_set_status (NetworkInadorHandle *handle, int index, int status);
|
void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *handle, int index, int status, struct_addr *ip, int prefix, struct_addr *gateway, struct_addr *broadcast, struct_addr *dhcp_server, uint32_t lease_time, struct_addr *dns_list, int dns_count, char *domain_name);
|
||||||
|
|
||||||
#endif /* __DHCP_CLIENT_H__ */
|
#endif /* __DHCP_CLIENT_H__ */
|
||||||
|
|
||||||
|
|
131
src/manager.c
131
src/manager.c
|
@ -659,52 +659,149 @@ static void _manager_handle_set_event_mask (ManagerClientInfo *manager_client, u
|
||||||
manager_client->wanted_events = events;
|
manager_client->wanted_events = events;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _manager_execute_dhcp_set_status (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
#define _MANAGER_CHECK_BYTE_OR_OUT(FAMILY,BUF,POS) \
|
||||||
int name_len;
|
if (BUF[POS] != 0) { \
|
||||||
|
if (FAMILY == AF_INET && BUF[POS] != 4) { \
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _manager_execute_dhcp_client_feed (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||||
|
int name_len, wanted;
|
||||||
unsigned char name[IFNAMSIZ];
|
unsigned char name[IFNAMSIZ];
|
||||||
|
unsigned char domain_name[256];
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
|
int family;
|
||||||
|
int pos, prefix, g;
|
||||||
|
uint32_t lease_time;
|
||||||
|
struct_addr ip, gateway, broadcast, dhcp_server;
|
||||||
|
struct_addr dns[8];
|
||||||
|
|
||||||
if (buffer_len < 4) {
|
if (buffer_len < 16) {
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_DHCP_SET_STATUS);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
name_len = buffer[3];
|
/* Revisar la familia */
|
||||||
|
family = buffer[2];
|
||||||
|
|
||||||
|
if (family != AF_INET && family != AF_INET6) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Revisar el estado */
|
||||||
|
if (buffer[3] < DHCP_CLIENT_SELECTING || buffer[3] > DHCP_CLIENT_EXPIRED) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Revisar la longitud del nombre de la interfaz */
|
||||||
|
name_len = buffer[4];
|
||||||
if (name_len == 0 || name_len >= IFNAMSIZ) {
|
if (name_len == 0 || name_len >= IFNAMSIZ) {
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_DHCP_SET_STATUS);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_BAD_STRING, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name_len + 4 < buffer_len) {
|
_MANAGER_CHECK_BYTE_OR_OUT(family, buffer, 5); // Dirección IP
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_DHCP_SET_STATUS);
|
_MANAGER_CHECK_BYTE_OR_OUT(family, buffer, 7); // Ruta por defecto
|
||||||
|
_MANAGER_CHECK_BYTE_OR_OUT(family, buffer, 8); // Dirección Broadcast
|
||||||
|
_MANAGER_CHECK_BYTE_OR_OUT(family, buffer, 9); // Dirección del servidor
|
||||||
|
|
||||||
|
/* La lista de servidores DNS */
|
||||||
|
if (family == AF_INET && buffer[10] % 4 != 0) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer[2] < NET_INADOR_DHCP_STATUS_INITING || buffer[2] > NET_INADOR_DHCP_STATUS_RENEWING) {
|
wanted = 16 + name_len + buffer[5] + buffer[7] + buffer[8] + buffer[9] + buffer[10] + buffer[11];
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_SET_STATUS);
|
if (wanted < buffer_len) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (name, &buffer[4], name_len);
|
/* Recuperar el nombre de la interfaz */
|
||||||
|
memcpy (name, &buffer[16], name_len);
|
||||||
name[name_len] = 0;
|
name[name_len] = 0;
|
||||||
|
|
||||||
iface = _interfaces_locate_by_name (manager_client->manager->handle->interfaces, name);
|
iface = _interfaces_locate_by_name (manager_client->manager->handle->interfaces, name);
|
||||||
if (iface == NULL) {
|
if (iface == NULL) {
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_DHCP_SET_STATUS);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_IFACE_INDEX, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iface->dhcpc.type != IFACE_ISC_DHCLIENT) {
|
if (iface->dhcpc.type != IFACE_ISC_DHCLIENT) {
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_SET_STATUS);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) {
|
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) {
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_SET_STATUS);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaces_dhcp_client_internal_set_status (manager_client->manager->handle, iface->index, buffer[2]);
|
/* Recuperar el resto de valores, empezando por la IP */
|
||||||
|
if (buffer[5] != 0) {
|
||||||
|
pos = 16 + name_len;
|
||||||
|
memcpy (&ip, &buffer[pos], buffer[5]);
|
||||||
|
} else {
|
||||||
|
memset (&ip, 0, sizeof (ip));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recuperar la ruta por defecto */
|
||||||
|
if (buffer[7] != 0) {
|
||||||
|
pos = 16 + name_len + buffer[5];
|
||||||
|
memcpy (&gateway, &buffer[pos], buffer[7]);
|
||||||
|
} else {
|
||||||
|
memset (&gateway, 0, sizeof (gateway));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recuperar el broadcast */
|
||||||
|
if (buffer[8] != 0) {
|
||||||
|
pos = 16 + name_len + buffer[5] + buffer[7];
|
||||||
|
memcpy (&broadcast, &buffer[pos], buffer[8]);
|
||||||
|
} else {
|
||||||
|
memset (&broadcast, 0, sizeof (broadcast));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recuperar el servidor DHCP */
|
||||||
|
if (buffer[9] != 0) {
|
||||||
|
pos = 16 + name_len + buffer[5] + buffer[7] + buffer[8];
|
||||||
|
memcpy (&dhcp_server, &buffer[pos], buffer[9]);
|
||||||
|
} else {
|
||||||
|
memset (&dhcp_server, 0, sizeof (dhcp_server));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recuperar todos los servidores DNS */
|
||||||
|
g = 0;
|
||||||
|
while (g < 8 && g < (buffer[10] / 4)) {
|
||||||
|
memcpy (&dns[g].v4, &buffer[pos], 4);
|
||||||
|
pos += 4;
|
||||||
|
g++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recuperar el domain name */
|
||||||
|
domain_name[0] = 0;
|
||||||
|
if (buffer[11] != 0) {
|
||||||
|
pos = 16 + name_len + buffer[5] + buffer[7] + buffer[8] + buffer[9] + buffer[10];
|
||||||
|
memcpy (domain_name, &buffer[pos], buffer[11]);
|
||||||
|
domain_name[buffer[11]] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copiar el lease_time */
|
||||||
|
memcpy (&lease_time, &buffer[12], 4);
|
||||||
|
|
||||||
|
/* TODO: Ejecutar aquí validaciones de estado, revisar que la IP existe, que el prefix sea válido, bla, bla, bla */
|
||||||
|
if (family == AF_INET) {
|
||||||
|
prefix = buffer[6];
|
||||||
|
if (prefix > 32) {
|
||||||
|
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interfaces_dhcp_client_internal_feed_from_client (manager_client->manager->handle, iface->index, buffer[3], &ip, buffer[6], &gateway, &broadcast, &dhcp_server, lease_time, dns, (buffer[10] / 4), domain_name);
|
||||||
|
|
||||||
/* OK */
|
/* OK */
|
||||||
_manager_send_executed (manager_client);
|
_manager_send_executed (manager_client);
|
||||||
|
@ -796,8 +893,8 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition
|
||||||
case NET_INADOR_COMMAND_SET_MASTER:
|
case NET_INADOR_COMMAND_SET_MASTER:
|
||||||
_manager_execute_set_or_clear_master (manager_client, buffer, bytes, FALSE);
|
_manager_execute_set_or_clear_master (manager_client, buffer, bytes, FALSE);
|
||||||
break;
|
break;
|
||||||
case NET_INADOR_COMMAND_DHCP_SET_STATUS:
|
case NET_INADOR_COMMAND_DHCP_CLIENT_FEED:
|
||||||
_manager_execute_dhcp_set_status (manager_client, buffer, bytes);
|
_manager_execute_dhcp_client_feed (manager_client, buffer, bytes);
|
||||||
break;
|
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);
|
||||||
|
|
|
@ -37,7 +37,7 @@ enum {
|
||||||
NET_INADOR_COMMAND_SET_EVENT_MASK = 192,
|
NET_INADOR_COMMAND_SET_EVENT_MASK = 192,
|
||||||
|
|
||||||
/* Los siguientes comandos son para uso interno */
|
/* Los siguientes comandos son para uso interno */
|
||||||
NET_INADOR_COMMAND_DHCP_SET_STATUS = 224,
|
NET_INADOR_COMMAND_DHCP_CLIENT_FEED = 224,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -67,11 +67,13 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NET_INADOR_DHCP_STATUS_INITING = 1,
|
NET_INADOR_DHCP_STATUS_SELECTING = 1,
|
||||||
NET_INADOR_DHCP_STATUS_SELECTING,
|
|
||||||
NET_INADOR_DHCP_STATUS_REQUESTING,
|
|
||||||
NET_INADOR_DHCP_STATUS_BOUND,
|
NET_INADOR_DHCP_STATUS_BOUND,
|
||||||
NET_INADOR_DHCP_STATUS_RENEWING
|
NET_INADOR_DHCP_STATUS_RENEWED,
|
||||||
|
|
||||||
|
NET_INADOR_DHCP_STATUS_EXPIRED,
|
||||||
|
NET_INADOR_DHCP_STATUS_FAILED,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __NETWOR_INADOR_MANAGER_H__ */
|
#endif /* __NETWOR_INADOR_MANAGER_H__ */
|
||||||
|
|
|
@ -0,0 +1,380 @@
|
||||||
|
/*
|
||||||
|
* ni-iface-helper.c
|
||||||
|
* This file is part of Network Inador
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 - 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 <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "network-inador-manager.h"
|
||||||
|
|
||||||
|
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||||
|
|
||||||
|
extern char** environ;
|
||||||
|
|
||||||
|
int debug (int argc, char *argv[]) {
|
||||||
|
char **item;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open ("/tmp/var_dhcp.env", O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item = environ; *item; item++) {
|
||||||
|
char *name, *val, **p;
|
||||||
|
|
||||||
|
/* Split on the = */
|
||||||
|
name = strdup (*item);
|
||||||
|
val = strchr (name, '=');
|
||||||
|
if (!val || val == name) {
|
||||||
|
free (name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*val++ = '\0';
|
||||||
|
|
||||||
|
/* Ignore non-DCHP-related environment variables
|
||||||
|
for (p = (char **) ignore; *p; p++) {
|
||||||
|
if (strncmp (name, *p, strlen (*p)) == 0)
|
||||||
|
goto next;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
write (fd, "Name: <", 7);
|
||||||
|
write (fd, name, strlen (name));
|
||||||
|
write (fd, ">, Value: <", 11);
|
||||||
|
write (fd, val, strlen (val));
|
||||||
|
write (fd, ">\n", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t utils_ip4_netmask_to_prefix (uint32_t netmask) {
|
||||||
|
uint32_t prefix;
|
||||||
|
uint8_t v;
|
||||||
|
const uint8_t *p = (uint8_t *) &netmask;
|
||||||
|
|
||||||
|
if (p[3]) {
|
||||||
|
prefix = 24;
|
||||||
|
v = p[3];
|
||||||
|
} else if (p[2]) {
|
||||||
|
prefix = 16;
|
||||||
|
v = p[2];
|
||||||
|
} else if (p[1]) {
|
||||||
|
prefix = 8;
|
||||||
|
v = p[1];
|
||||||
|
} else {
|
||||||
|
prefix = 0;
|
||||||
|
v = p[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (v) {
|
||||||
|
prefix++;
|
||||||
|
v <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *retrieve_env (const char *name) {
|
||||||
|
char *bus, *dup, *get;
|
||||||
|
|
||||||
|
get = getenv (name);
|
||||||
|
|
||||||
|
if (get == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bus = strchr (get, '=');
|
||||||
|
|
||||||
|
if (!bus || bus == get) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dup = strdup (&get[1]);
|
||||||
|
|
||||||
|
if (dup == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_preinit (int s, char *interface) {
|
||||||
|
unsigned char buffer[128];
|
||||||
|
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_DHCP_CLIENT_FEED;
|
||||||
|
|
||||||
|
buffer[2] = AF_INET;
|
||||||
|
buffer[3] = NET_INADOR_DHCP_STATUS_SELECTING;
|
||||||
|
buffer[4] = strlen (interface);
|
||||||
|
memset (&buffer[5], 0, 11);
|
||||||
|
|
||||||
|
strncpy (&buffer[16], interface, buffer[4]);
|
||||||
|
|
||||||
|
send (s, buffer, 16 + buffer[4], 0);
|
||||||
|
|
||||||
|
if (wait_for_ack_or_error (s) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_bound_renew (int s, int is_bound, char *interface, struct in_addr *ip, int prefix, struct in_addr *gateway, struct in_addr *broadcast, struct in_addr *dhcp_server, uint32_t lease_time) {
|
||||||
|
unsigned char buffer[128];
|
||||||
|
struct in_addr empty;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
memset (&empty, 0, sizeof (empty));
|
||||||
|
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_DHCP_CLIENT_FEED;
|
||||||
|
|
||||||
|
buffer[2] = AF_INET;
|
||||||
|
if (is_bound) {
|
||||||
|
buffer[3] = NET_INADOR_DHCP_STATUS_BOUND;
|
||||||
|
} else {
|
||||||
|
buffer[3] = NET_INADOR_DHCP_STATUS_RENEWED;
|
||||||
|
}
|
||||||
|
buffer[4] = strlen (interface);
|
||||||
|
memset (&buffer[5], 0, 11);
|
||||||
|
|
||||||
|
buffer[6] = prefix;
|
||||||
|
|
||||||
|
pos = 16;
|
||||||
|
|
||||||
|
/* Copiar el nombre de la interfaz */
|
||||||
|
strncpy (&buffer[16], interface, buffer[4]);
|
||||||
|
pos = 16 + buffer[4];
|
||||||
|
|
||||||
|
if (memcmp (&empty, ip, sizeof (empty)) != 0) {
|
||||||
|
/* Tenemos una IP */
|
||||||
|
buffer[5] = 4;
|
||||||
|
memcpy (&buffer[pos], ip, 4);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp (&empty, gateway, sizeof (empty)) != 0) {
|
||||||
|
/* Tenemos una ruta */
|
||||||
|
buffer[7] = 4;
|
||||||
|
memcpy (&buffer[pos], gateway, 4);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp (&empty, broadcast, sizeof (empty)) != 0) {
|
||||||
|
/* Tenemos broadcast */
|
||||||
|
buffer[8] = 4;
|
||||||
|
memcpy (&buffer[pos], broadcast, 4);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp (&empty, dhcp_server, sizeof (empty)) != 0) {
|
||||||
|
/* Tenemos IP del servidor DHCP */
|
||||||
|
buffer[9] = 4;
|
||||||
|
memcpy (&buffer[pos], dhcp_server, 4);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lease_time != 0) {
|
||||||
|
memcpy (&buffer[12], &lease_time, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Faltan los DNS */
|
||||||
|
send (s, buffer, pos, 0);
|
||||||
|
|
||||||
|
if (wait_for_ack_or_error (s) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_ip (char *var, struct in_addr *addr) {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (var == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = inet_pton (AF_INET, var, addr);
|
||||||
|
|
||||||
|
if (res <= 0) {
|
||||||
|
memset (addr, 0, sizeof (*addr));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_int (char *var, int *entero) {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (var == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sscanf (var, "%i", entero);
|
||||||
|
|
||||||
|
if (res <= 0) {
|
||||||
|
*entero = 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]) {
|
||||||
|
char *reason, *interface;
|
||||||
|
int s, ret;
|
||||||
|
struct sockaddr_un path_dest;
|
||||||
|
struct in_addr ip, netmask, gateway, broadcast, dhcp_server;
|
||||||
|
int prefix, lease_time;
|
||||||
|
|
||||||
|
debug (argc, argv);
|
||||||
|
|
||||||
|
reason = getenv ("reason");
|
||||||
|
|
||||||
|
interface = getenv ("interface");
|
||||||
|
|
||||||
|
if (reason == NULL || interface == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Intentar abrir el socket a la escucha */
|
||||||
|
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 (strcmp (reason, "PREINIT") == 0) {
|
||||||
|
send_preinit (s, interface);
|
||||||
|
} if (strcmp (reason, "FAIL") == 0) {
|
||||||
|
|
||||||
|
} else if (strcmp (reason, "BOUND") == 0 || strcmp (reason, "REBOOT") == 0 ||
|
||||||
|
strcmp (reason, "RENEW") == 0 || strcmp (reason, "REBIND") == 0
|
||||||
|
) {
|
||||||
|
/*
|
||||||
|
* Los valores más importantes recibidos:
|
||||||
|
* new_domain_name_servers -> los DNS
|
||||||
|
* new_expiry -> el timestamp de la hora
|
||||||
|
* new_domain_name -> DNS search name
|
||||||
|
* new_routers -> Lista de routers
|
||||||
|
* new_subnet_mask -> Máscara de red en formato largo
|
||||||
|
* new_broadcast_address -> Dirección broadcast
|
||||||
|
* new_ip_address -> Dirección IP
|
||||||
|
* new_dhcp_lease_time -> Tiempo en segundos
|
||||||
|
*/
|
||||||
|
/* Parsear y revisar las direcciones IP recibidas */
|
||||||
|
char *s_ip, *s_mask, *s_gateway, *s_broadcast, *s_lease_time, *s_dhcp_server;
|
||||||
|
s_ip = getenv ("new_ip_address");
|
||||||
|
s_mask = getenv ("new_subnet_mask");
|
||||||
|
s_gateway = getenv ("new_routers");
|
||||||
|
s_broadcast = getenv ("new_broadcast_address");
|
||||||
|
s_lease_time = getenv ("new_dhcp_lease_time");
|
||||||
|
s_dhcp_server = getenv ("new_dhcp_server_identifier");
|
||||||
|
/* TODO: Faltan los DNS */
|
||||||
|
|
||||||
|
if (parse_ip (s_ip, &ip) < 0) {
|
||||||
|
close (s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_ip (s_mask, &netmask) < 0) {
|
||||||
|
close (s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix = utils_ip4_netmask_to_prefix (netmask.s_addr);
|
||||||
|
if (parse_ip (s_gateway, &gateway) < 0) {
|
||||||
|
memset (&gateway, 0, sizeof (gateway));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_ip (s_broadcast, &broadcast) < 0) {
|
||||||
|
memset (&broadcast, 0, sizeof (broadcast));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_ip (s_dhcp_server, &dhcp_server) < 0) {
|
||||||
|
memset (&dhcp_server, 0, sizeof (dhcp_server));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_int (s_lease_time, &lease_time) < 0) {
|
||||||
|
lease_time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_bound = 0;
|
||||||
|
if (strcmp (reason, "BOUND") == 0 || strcmp (reason, "REBOOT") == 0) {
|
||||||
|
is_bound = 1;
|
||||||
|
}
|
||||||
|
send_bound_renew (s, is_bound, interface, &ip, prefix, &gateway, &broadcast, &dhcp_server, lease_time);
|
||||||
|
} else if (strcmp (reason, "EXPIRE") == 0 || strcmp (reason, "STOP") == 0 || strcmp (reason, "RELEASE") == 0) {
|
||||||
|
/* Los mismos valores, pero con old_ */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
close (s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,203 +0,0 @@
|
||||||
/*
|
|
||||||
* ni-iface-helper.c
|
|
||||||
* This file is part of Network Inador
|
|
||||||
*
|
|
||||||
* Copyright (C) 2021 - 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 <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
|
|
||||||
#include "network-inador-manager.h"
|
|
||||||
|
|
||||||
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
|
||||||
|
|
||||||
extern char** environ;
|
|
||||||
|
|
||||||
int debug (int argc, char *argv[]) {
|
|
||||||
char **item;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = open ("/tmp/var_dhcp.env", O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (item = environ; *item; item++) {
|
|
||||||
char *name, *val, **p;
|
|
||||||
|
|
||||||
/* Split on the = */
|
|
||||||
name = strdup (*item);
|
|
||||||
val = strchr (name, '=');
|
|
||||||
if (!val || val == name) {
|
|
||||||
free (name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*val++ = '\0';
|
|
||||||
|
|
||||||
/* Ignore non-DCHP-related environment variables
|
|
||||||
for (p = (char **) ignore; *p; p++) {
|
|
||||||
if (strncmp (name, *p, strlen (*p)) == 0)
|
|
||||||
goto next;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
write (fd, "Name: <", 7);
|
|
||||||
write (fd, name, strlen (name));
|
|
||||||
write (fd, ">, Value: <", 11);
|
|
||||||
write (fd, val, strlen (val));
|
|
||||||
write (fd, ">\n", 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
close (fd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *retrieve_env (const char *name) {
|
|
||||||
char *bus, *dup, *get;
|
|
||||||
|
|
||||||
get = getenv (name);
|
|
||||||
|
|
||||||
if (get == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bus = strchr (get, '=');
|
|
||||||
|
|
||||||
if (!bus || bus == get) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dup = strdup (&get[1]);
|
|
||||||
|
|
||||||
if (dup == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dup;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_preinit (int s, char *interface) {
|
|
||||||
unsigned char buffer[128];
|
|
||||||
|
|
||||||
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
|
||||||
buffer[1] = NET_INADOR_COMMAND_DHCP_SET_STATUS;
|
|
||||||
|
|
||||||
buffer[2] = NET_INADOR_DHCP_STATUS_INITING;
|
|
||||||
buffer[3] = strlen (interface);
|
|
||||||
strncpy (&buffer[4], interface, buffer[3]);
|
|
||||||
|
|
||||||
send (s, buffer, 3 + buffer[3], 0);
|
|
||||||
|
|
||||||
if (wait_for_ack_or_error (s) < 0) {
|
|
||||||
close (s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
close (s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
|
||||||
char *reason, *interface;
|
|
||||||
int s, ret;
|
|
||||||
struct sockaddr_un path_dest;
|
|
||||||
|
|
||||||
debug (argc, argv);
|
|
||||||
|
|
||||||
reason = retrieve_env ("reason");
|
|
||||||
|
|
||||||
interface = retrieve_env ("interface");
|
|
||||||
|
|
||||||
if (reason == NULL || interface == NULL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Intentar abrir el socket a la escucha */
|
|
||||||
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 (strcmp (reason, "PREINIT") == 0 || strcmp (reason, "FAIL") == 0) {
|
|
||||||
send_preinit (s, interface);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else if (strcmp (reason, "REBOOT") == 0 || strcmp (reason, "RENEW") == 0) {
|
|
||||||
/*
|
|
||||||
* Los valores más importantes recibidos:
|
|
||||||
* new_domain_name_servers -> los DNS
|
|
||||||
* new_expiry -> el timestamp de la hora
|
|
||||||
* new_domain_name -> DNS search name
|
|
||||||
* new_routers -> Lista de routers
|
|
||||||
* new_subnet_mask -> Máscara de red en formato largo
|
|
||||||
* new_broadcast_address -> Dirección broadcast
|
|
||||||
* new_ip_address -> Dirección IP
|
|
||||||
* new_dhcp_lease_time -> Tiempo en segundos
|
|
||||||
*/
|
|
||||||
} else if (strcmp (reason, "EXPIRE") == 0) {
|
|
||||||
/* Los mismos valores, pero con old_ */
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
|
||||||
close (s);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue