Agrego cliente busybox udhcpc y comandos del manager.
parent
f048dde998
commit
072b89bd62
|
@ -45,6 +45,10 @@
|
|||
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
|
||||
#endif
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
typedef struct _NetworkInadorHandle NetworkInadorHandle;
|
||||
typedef struct _NetworkInadorManager NetworkInadorManager;
|
||||
typedef struct _Interface Interface;
|
||||
|
@ -117,7 +121,8 @@ typedef struct _WirelessInfo {
|
|||
/* Información del proceso de DHCP */
|
||||
enum {
|
||||
IFACE_NO_DHCP = 0,
|
||||
IFACE_ISC_DHCLIENT
|
||||
IFACE_ISC_DHCLIENT,
|
||||
IFACE_BUSYBOX_UDHCPC
|
||||
};
|
||||
|
||||
/* FIXME: Revisar estos estados */
|
||||
|
@ -150,6 +155,7 @@ typedef struct _InterfaceDHCPClientInfo {
|
|||
int prefix;
|
||||
|
||||
struct_addr dhcp_server_ip;
|
||||
uint32_t lease_time;
|
||||
|
||||
/* TODO: Falta almacenar la información de DNS */
|
||||
} InterfaceDHCPClientInfo;
|
||||
|
|
|
@ -41,7 +41,7 @@ void interfaces_dhcp_client_ignore_kill (GPid pid, gint status, gpointer data) {
|
|||
g_spawn_check_exit_status (status, NULL);
|
||||
}
|
||||
|
||||
void interfaces_dhcp_prepare_args_for_dhclient (char **argv, int size, char *iface_name, char *pid_file, size_t pid_file_len) {
|
||||
void interfaces_dhcp_prepare_args_for_isc_dhclient (char **argv, int size, char *iface_name, char *pid_file, size_t pid_file_len) {
|
||||
snprintf (pid_file, pid_file_len, "/run/dhclient-%s.pid", iface_name);
|
||||
|
||||
/* Preparar los argumentos para el proceso */
|
||||
|
@ -56,6 +56,22 @@ void interfaces_dhcp_prepare_args_for_dhclient (char **argv, int size, char *ifa
|
|||
argv[8] = NULL;
|
||||
}
|
||||
|
||||
void interfaces_dhcp_prepare_args_for_busybox_udhcpc (char **argv, int size, char *iface_name, char *pid_file, size_t pid_file_len) {
|
||||
snprintf (pid_file, pid_file_len, "/run/dhclient-%s.pid", iface_name);
|
||||
|
||||
/* Preparar los argumentos para el proceso */
|
||||
argv[0] = "/bin/busybox";
|
||||
argv[1] = "udhcpc";
|
||||
argv[2] = "-i";
|
||||
argv[3] = iface_name;
|
||||
argv[4] = "-p";
|
||||
argv[5] = pid_file;
|
||||
argv[6] = "-s";
|
||||
argv[7] = "/home/gatuno/Proyectos/NetworkInador/src/ni-dhcp-helper";
|
||||
argv[8] = "-f";
|
||||
argv[9] = NULL;
|
||||
}
|
||||
|
||||
void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
|
||||
Interface *iface = (Interface *) data;
|
||||
gboolean ret;
|
||||
|
@ -64,13 +80,17 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
|
|||
gchar pid_file[256];
|
||||
|
||||
/* Preparar los argumentos */
|
||||
interfaces_dhcp_prepare_args_for_dhclient (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT) {
|
||||
interfaces_dhcp_prepare_args_for_isc_dhclient (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||
} else if (iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) {
|
||||
interfaces_dhcp_prepare_args_for_busybox_udhcpc (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||
}
|
||||
|
||||
if (g_spawn_check_exit_status (status, NULL)) {
|
||||
/* Revisar si necesito algo */
|
||||
}
|
||||
|
||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT) {
|
||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT || iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) {
|
||||
if (iface->dhcpc.flags & DHCP_CLIENT_FLAG_AUTO_RESTART) {
|
||||
/* Se cerró o mataron el proceso, reiniciar */
|
||||
ret = g_spawn_async_with_pipes (
|
||||
|
@ -105,6 +125,17 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void interfaces_dhcp_clear_info (InterfaceDHCPClientInfo *dhcpc) {
|
||||
memset (&dhcpc->ip, 0, sizeof (dhcpc->ip));
|
||||
memset (&dhcpc->gateway, 0, sizeof (dhcpc->gateway));
|
||||
memset (&dhcpc->broadcast, 0, sizeof (dhcpc->broadcast));
|
||||
memset (&dhcpc->dhcp_server_ip, 0, sizeof (dhcpc->dhcp_server_ip));
|
||||
dhcpc->lease_time = 0;
|
||||
dhcpc->prefix = 0;
|
||||
|
||||
/* TODO: Borrar la información de DNS */
|
||||
}
|
||||
|
||||
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags) {
|
||||
/* IFNAMSIZ */
|
||||
Interface *iface;
|
||||
|
@ -122,18 +153,23 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
|
|||
}
|
||||
|
||||
/* Preparar los argumentos */
|
||||
interfaces_dhcp_prepare_args_for_dhclient (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||
|
||||
if (type == IFACE_ISC_DHCLIENT) {
|
||||
interfaces_dhcp_prepare_args_for_isc_dhclient (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||
} else if (type == IFACE_BUSYBOX_UDHCPC) {
|
||||
interfaces_dhcp_prepare_args_for_busybox_udhcpc (argv, 20, iface->name, pid_file, sizeof (pid_file));
|
||||
}
|
||||
if (iface->dhcpc.type != IFACE_NO_DHCP) {
|
||||
/* No puedo correr otro tipo de DHCP */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT && iface->dhcpc.dhcp_state != DHCP_CLIENT_KILLED) {
|
||||
if ((iface->dhcpc.type == IFACE_ISC_DHCLIENT || iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) && iface->dhcpc.dhcp_state != DHCP_CLIENT_KILLED) {
|
||||
/* El cliente de dhcp ya está corriendo, no hacer nada */
|
||||
return -1;
|
||||
}
|
||||
|
||||
interfaces_dhcp_clear_info (&iface->dhcpc);
|
||||
|
||||
ret = g_spawn_async_with_pipes (
|
||||
"/",
|
||||
argv,
|
||||
|
@ -157,7 +193,7 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
|
|||
}
|
||||
|
||||
iface->dhcpc.dhcp_state = DHCP_CLIENT_EXTERNAL_RUNNING;
|
||||
iface->dhcpc.type = IFACE_ISC_DHCLIENT;
|
||||
iface->dhcpc.type = type;
|
||||
iface->dhcpc.flags = flags;
|
||||
|
||||
iface->dhcpc.process_watch = g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_killed_cb, iface);
|
||||
|
@ -165,7 +201,7 @@ int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type
|
|||
return 0;
|
||||
}
|
||||
|
||||
void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
||||
int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
||||
Interface *iface;
|
||||
|
||||
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||
|
@ -173,18 +209,18 @@ void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
|||
if (iface == NULL) {
|
||||
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
|
||||
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iface->dhcpc.type == IFACE_NO_DHCP) {
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT) {
|
||||
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return;
|
||||
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.type = IFACE_NO_DHCP;
|
||||
|
||||
iface->dhcpc.flags &= (~DHCP_CLIENT_FLAG_AUTO_RESTART);
|
||||
|
||||
g_source_remove (iface->dhcpc.process_watch);
|
||||
|
@ -192,7 +228,15 @@ void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
|||
g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_ignore_kill, NULL);
|
||||
|
||||
kill (iface->dhcpc.process_pid, SIGTERM);
|
||||
iface->dhcpc.type = IFACE_NO_DHCP;
|
||||
|
||||
/* TODO: Revisar aquí si es pertinente desconfigurar la interfaz y borrar la información obtenida */
|
||||
|
||||
interfaces_dhcp_clear_info (&iface->dhcpc);
|
||||
/* TODO: Enviar actualización de estado aquí */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -211,7 +255,8 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
|
|||
return;
|
||||
}
|
||||
|
||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT) {
|
||||
// TODO: Cuando entre a estado Selecting, previo otro estado diferente, borrar la IP, si es que tenemos
|
||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT || iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) {
|
||||
/* Un proceso muerto no puede informar de cambios de estados */
|
||||
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return;
|
||||
|
||||
|
@ -248,6 +293,7 @@ void interfaces_dhcp_client_internal_feed_from_client (NetworkInadorHandle *hand
|
|||
|
||||
memcpy (&iface->dhcpc.broadcast, broadcast, sizeof (iface->dhcpc.broadcast));
|
||||
memcpy (&iface->dhcpc.dhcp_server_ip, dhcp_server, sizeof (iface->dhcpc.dhcp_server_ip));
|
||||
iface->dhcpc.lease_time = lease_time;
|
||||
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));
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "common.h"
|
||||
|
||||
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags);
|
||||
void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);
|
||||
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 *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__ */
|
||||
|
|
190
src/manager.c
190
src/manager.c
|
@ -46,6 +46,8 @@
|
|||
|
||||
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||
|
||||
void _manager_send_dhcp_status (ManagerClientInfo *manager_client, InterfaceDHCPClientInfo *dhcpc, gboolean is_event);
|
||||
|
||||
static void _manager_send_error (ManagerClientInfo *manager_client, int error, int orig_cmd) {
|
||||
unsigned char buffer[8];
|
||||
|
||||
|
@ -732,7 +734,7 @@ static void _manager_execute_dhcp_client_feed (ManagerClientInfo *manager_client
|
|||
return;
|
||||
}
|
||||
|
||||
if (iface->dhcpc.type != IFACE_ISC_DHCLIENT) {
|
||||
if (iface->dhcpc.type != IFACE_ISC_DHCLIENT && iface->dhcpc.type != IFACE_BUSYBOX_UDHCPC) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||
return;
|
||||
}
|
||||
|
@ -807,6 +809,183 @@ static void _manager_execute_dhcp_client_feed (ManagerClientInfo *manager_client
|
|||
_manager_send_executed (manager_client);
|
||||
}
|
||||
|
||||
static void _manager_execute_dhcp_run (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||
Interface *iface;
|
||||
int ret;
|
||||
int family, tipo;
|
||||
uint32_t flags;
|
||||
|
||||
if (buffer_len < 12) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RUN_DHCP);
|
||||
return;
|
||||
}
|
||||
|
||||
family = buffer[6];
|
||||
|
||||
//if (family != AF_INET && family != AF_INET6) {
|
||||
if (family != AF_INET) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_RUN_DHCP);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_RUN_DHCP);
|
||||
if (iface == NULL) return;
|
||||
|
||||
tipo = buffer[7];
|
||||
if (tipo == 1) {
|
||||
tipo = IFACE_ISC_DHCLIENT;
|
||||
} else if (tipo == 2) {
|
||||
tipo = IFACE_BUSYBOX_UDHCPC;
|
||||
} else {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RUN_DHCP);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Revisar las banderas */
|
||||
memcpy (&flags, &buffer[8], 4);
|
||||
|
||||
ret = interfaces_dhcp_client_run (manager_client->manager->handle, iface->index, tipo, flags);
|
||||
|
||||
if (ret == 0) {
|
||||
/* OK */
|
||||
_manager_send_executed (manager_client);
|
||||
} else {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_RUN_DHCP);
|
||||
}
|
||||
}
|
||||
|
||||
static void _manager_execute_dhcp_stop (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||
Interface *iface;
|
||||
int ret;
|
||||
int family;
|
||||
|
||||
if (buffer_len < 7) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_STOP_DHCP);
|
||||
return;
|
||||
}
|
||||
|
||||
family = buffer[6];
|
||||
|
||||
//if (family != AF_INET && family != AF_INET6) {
|
||||
if (family != AF_INET) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_STOP_DHCP);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_STOP_DHCP);
|
||||
if (iface == NULL) return;
|
||||
|
||||
ret = interfaces_dhcp_client_stop (manager_client->manager->handle, iface->index);
|
||||
|
||||
if (ret == 0) {
|
||||
/* OK */
|
||||
_manager_send_executed (manager_client);
|
||||
} else {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_STOP_DHCP);
|
||||
}
|
||||
}
|
||||
|
||||
static void _manager_execute_dhcp_get_status (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||
Interface *iface;
|
||||
int family;
|
||||
|
||||
if (buffer_len < 7) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_GET_DHCP_STATUS);
|
||||
return;
|
||||
}
|
||||
|
||||
family = buffer[6];
|
||||
|
||||
//if (family != AF_INET && family != AF_INET6) {
|
||||
if (family != AF_INET) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_GET_DHCP_STATUS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_GET_DHCP_STATUS);
|
||||
if (iface == NULL) return;
|
||||
|
||||
_manager_send_dhcp_status (manager_client, &iface->dhcpc, FALSE);
|
||||
}
|
||||
|
||||
void _manager_send_dhcp_status (ManagerClientInfo *manager_client, InterfaceDHCPClientInfo *dhcpc, gboolean is_event) {
|
||||
Interface *iface;
|
||||
unsigned char buffer[80];
|
||||
int family_size = 0;
|
||||
int label_len;
|
||||
int pos;
|
||||
int family = AF_INET;
|
||||
struct in_addr empty;
|
||||
|
||||
memset (&empty, 0, sizeof (empty));
|
||||
|
||||
iface = container_of (dhcpc, Interface, dhcpc);
|
||||
|
||||
if (is_event) {
|
||||
buffer[0] = NET_INADOR_TYPE_EVENT;
|
||||
buffer[1] = NET_INADOR_EVENT_DHCP_STATUS;
|
||||
} else {
|
||||
buffer[0] = NET_INADOR_TYPE_RESPONSE;
|
||||
buffer[1] = NET_INADOR_RESPONSE_DHCP_STATUS;
|
||||
}
|
||||
|
||||
/* Familia */
|
||||
if (family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
}
|
||||
|
||||
memcpy (&buffer[2], &iface->index, 4);
|
||||
buffer[6] = family;
|
||||
buffer[7] = dhcpc->type;
|
||||
buffer[8] = dhcpc->dhcp_state;
|
||||
|
||||
/* Prefijo */
|
||||
buffer[9] = dhcpc->prefix;
|
||||
|
||||
/* Los campos de bits */
|
||||
buffer[10] = 0;
|
||||
if (memcmp (&dhcpc->gateway, &empty, 4) == 0) {
|
||||
buffer[10] |= 0x01;
|
||||
}
|
||||
if (memcmp (&dhcpc->broadcast, &empty, 4) == 0) {
|
||||
buffer[10] |= 0x02;
|
||||
}
|
||||
if (memcmp (&dhcpc->dhcp_server_ip, &empty, 4) == 0) {
|
||||
buffer[10] |= 0x04;
|
||||
}
|
||||
|
||||
/* TODO: Falta enviar la información de cantidad de servidores DNS */
|
||||
buffer[11] = 0;
|
||||
|
||||
memcpy (&buffer[12], &dhcpc->lease_time, 4);
|
||||
|
||||
/* La dirección principal */
|
||||
memcpy (&buffer[16], &dhcpc->ip, family_size);
|
||||
pos = 16 + family_size;
|
||||
if (memcmp (&dhcpc->gateway, &empty, 4) != 0) {
|
||||
memcpy (&buffer[pos], &dhcpc->gateway, family_size);
|
||||
pos += family_size;
|
||||
}
|
||||
|
||||
if (memcmp (&dhcpc->broadcast, &empty, 4) != 0) {
|
||||
memcpy (&buffer[pos], &dhcpc->broadcast, family_size);
|
||||
pos += family_size;
|
||||
}
|
||||
|
||||
if (memcmp (&dhcpc->dhcp_server_ip, &empty, 4) != 0) {
|
||||
memcpy (&buffer[pos], &dhcpc->dhcp_server_ip, family_size);
|
||||
pos += family_size;
|
||||
}
|
||||
|
||||
/* TODO: Falta aquí enviar la lista de servidores DNS y el domain name */
|
||||
|
||||
send (manager_client->fd, buffer, pos, 0);
|
||||
}
|
||||
|
||||
static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition, gpointer data) {
|
||||
ManagerClientInfo *manager_client = (ManagerClientInfo *) data;
|
||||
NetworkInadorManager *manager = manager_client->manager;
|
||||
|
@ -896,6 +1075,15 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition
|
|||
case NET_INADOR_COMMAND_DHCP_CLIENT_FEED:
|
||||
_manager_execute_dhcp_client_feed (manager_client, buffer, bytes);
|
||||
break;
|
||||
case NET_INADOR_COMMAND_RUN_DHCP:
|
||||
_manager_execute_dhcp_run (manager_client, buffer, bytes);
|
||||
break;
|
||||
case NET_INADOR_COMMAND_STOP_DHCP:
|
||||
_manager_execute_dhcp_stop (manager_client, buffer, bytes);
|
||||
break;
|
||||
case NET_INADOR_COMMAND_GET_DHCP_STATUS:
|
||||
_manager_execute_dhcp_get_status (manager_client, buffer, bytes);
|
||||
break;
|
||||
default:
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_WRONG_COMMAND, command);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ enum {
|
|||
/* Lista de eventos */
|
||||
#define NET_INADOR_EVENT_MASK_INTERFACES 0x01
|
||||
#define NET_INADOR_EVENT_MASK_IP 0x02
|
||||
#define NET_INADOR_EVENT_MASK_DHCP_STATUS 0x04
|
||||
|
||||
enum {
|
||||
NET_INADOR_COMMAND_LIST_IFACES = 1,
|
||||
|
@ -34,6 +35,10 @@ enum {
|
|||
NET_INADOR_COMMAND_ADD_IP,
|
||||
NET_INADOR_COMMAND_REMOVE_IP,
|
||||
|
||||
NET_INADOR_COMMAND_RUN_DHCP = 48,
|
||||
NET_INADOR_COMMAND_STOP_DHCP,
|
||||
NET_INADOR_COMMAND_GET_DHCP_STATUS,
|
||||
|
||||
NET_INADOR_COMMAND_SET_EVENT_MASK = 192,
|
||||
|
||||
/* Los siguientes comandos son para uso interno */
|
||||
|
@ -56,7 +61,9 @@ enum {
|
|||
NET_INADOR_EVENT_IFACE_ADDED = 2,
|
||||
NET_INADOR_EVENT_IPADDR_ADDED,
|
||||
NET_INADOR_EVENT_IFACE_REMOVED,
|
||||
NET_INADOR_EVENT_IPADDR_REMOVED
|
||||
NET_INADOR_EVENT_IPADDR_REMOVED,
|
||||
|
||||
NET_INADOR_EVENT_DHCP_STATUS = 6
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -64,6 +71,8 @@ enum {
|
|||
|
||||
NET_INADOR_RESPONSE_IFACE = 2,
|
||||
NET_INADOR_RESPONSE_IPADDR,
|
||||
|
||||
NET_INADOR_RESPONSE_DHCP_STATUS = 6
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
@ -274,17 +274,77 @@ int parse_int (char *var, int *entero) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
IFACE_ISC_DHCLIENT = 1,
|
||||
IFACE_BUSYBOX_UDHCPC
|
||||
};
|
||||
|
||||
const char *isc_dhcp_reasons[] = {
|
||||
"MEDIUM",
|
||||
"PREINIT",
|
||||
"BOUND",
|
||||
"RENEW",
|
||||
"REBIND",
|
||||
"REBOOT",
|
||||
"EXPIRE",
|
||||
"FAIL",
|
||||
"STOP",
|
||||
"RELEASE",
|
||||
"NBI",
|
||||
"TIMEOUT",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *busybox_dhcp_argv[] = {
|
||||
"deconfig",
|
||||
"bound",
|
||||
"renew",
|
||||
"nak"
|
||||
};
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
char *reason, *interface;
|
||||
int s, ret;
|
||||
int s, ret, tipo;
|
||||
struct sockaddr_un path_dest;
|
||||
struct in_addr ip, netmask, gateway, broadcast, dhcp_server;
|
||||
int prefix, lease_time;
|
||||
|
||||
debug (argc, argv);
|
||||
|
||||
tipo = 0;
|
||||
|
||||
/* Tratar de determinar si estamos siendo corridos por un el DHCP del ISC o por el udhcpc busybox */
|
||||
reason = getenv ("reason");
|
||||
|
||||
if (reason != NULL) {
|
||||
s = 0;
|
||||
while (isc_dhcp_reasons[s] != NULL) {
|
||||
if (strcmp (reason, isc_dhcp_reasons[s]) == 0) {
|
||||
/* Es un ISC DHCP Client */
|
||||
tipo = IFACE_ISC_DHCLIENT;
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tipo == 0 && argc > 1) {
|
||||
/* Intentar revisar si es un busybox udhcpc */
|
||||
s = 0;
|
||||
while (busybox_dhcp_argv[s] != NULL) {
|
||||
if (strcmp (argv[1], busybox_dhcp_argv[s]) == 0) {
|
||||
tipo = IFACE_BUSYBOX_UDHCPC;
|
||||
reason = argv[1];
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tipo == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
interface = getenv ("interface");
|
||||
|
||||
if (reason == NULL || interface == NULL) {
|
||||
|
@ -308,12 +368,15 @@ int main (int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp (reason, "PREINIT") == 0) {
|
||||
if (strcmp (reason, "PREINIT") == 0 || // ISC DHCP
|
||||
strcmp (reason, "deconfig") == 0 // Busybox udhcpc
|
||||
) {
|
||||
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
|
||||
strcmp (reason, "RENEW") == 0 || strcmp (reason, "REBIND") == 0 || // 4 de ISC DHCP
|
||||
strcmp (reason, "bound") == 0 || strcmp (reason, "renew") == 0 // 2 de Busybox udhcpc
|
||||
) {
|
||||
/*
|
||||
* Los valores más importantes recibidos:
|
||||
|
@ -328,12 +391,21 @@ int main (int argc, char *argv[]) {
|
|||
*/
|
||||
/* Parsear y revisar las direcciones IP recibidas */
|
||||
char *s_ip, *s_mask, *s_gateway, *s_broadcast, *s_lease_time, *s_dhcp_server;
|
||||
if (tipo == IFACE_ISC_DHCLIENT) {
|
||||
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");
|
||||
} else if (tipo == IFACE_BUSYBOX_UDHCPC) {
|
||||
s_ip = getenv ("ip");
|
||||
s_mask = getenv ("subnet");
|
||||
s_gateway = getenv ("router");
|
||||
s_broadcast = getenv ("broadcast");
|
||||
s_lease_time = getenv ("lease");
|
||||
s_dhcp_server = getenv ("serverid");
|
||||
}
|
||||
/* TODO: Faltan los DNS */
|
||||
|
||||
if (parse_ip (s_ip, &ip) < 0) {
|
||||
|
@ -364,7 +436,9 @@ int main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
int is_bound = 0;
|
||||
if (strcmp (reason, "BOUND") == 0 || strcmp (reason, "REBOOT") == 0) {
|
||||
if (strcmp (reason, "BOUND") == 0 || strcmp (reason, "REBOOT") == 0 || // Del ISC dhcp
|
||||
strcmp (reason, "bound") == 0 // del busybox
|
||||
) {
|
||||
is_bound = 1;
|
||||
}
|
||||
send_bound_renew (s, is_bound, interface, &ip, prefix, &gateway, &broadcast, &dhcp_server, lease_time);
|
||||
|
|
Loading…
Reference in New Issue