Agrego cliente busybox udhcpc y comandos del manager.
parent
f048dde998
commit
072b89bd62
|
@ -45,6 +45,10 @@
|
||||||
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
|
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
|
||||||
#endif
|
#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 _NetworkInadorHandle NetworkInadorHandle;
|
||||||
typedef struct _NetworkInadorManager NetworkInadorManager;
|
typedef struct _NetworkInadorManager NetworkInadorManager;
|
||||||
typedef struct _Interface Interface;
|
typedef struct _Interface Interface;
|
||||||
|
@ -117,7 +121,8 @@ typedef struct _WirelessInfo {
|
||||||
/* Información del proceso de DHCP */
|
/* Información del proceso de DHCP */
|
||||||
enum {
|
enum {
|
||||||
IFACE_NO_DHCP = 0,
|
IFACE_NO_DHCP = 0,
|
||||||
IFACE_ISC_DHCLIENT
|
IFACE_ISC_DHCLIENT,
|
||||||
|
IFACE_BUSYBOX_UDHCPC
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME: Revisar estos estados */
|
/* FIXME: Revisar estos estados */
|
||||||
|
@ -150,6 +155,7 @@ typedef struct _InterfaceDHCPClientInfo {
|
||||||
int prefix;
|
int prefix;
|
||||||
|
|
||||||
struct_addr dhcp_server_ip;
|
struct_addr dhcp_server_ip;
|
||||||
|
uint32_t lease_time;
|
||||||
|
|
||||||
/* TODO: Falta almacenar la información de DNS */
|
/* TODO: Falta almacenar la información de DNS */
|
||||||
} InterfaceDHCPClientInfo;
|
} InterfaceDHCPClientInfo;
|
||||||
|
|
|
@ -41,7 +41,7 @@ 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, 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);
|
snprintf (pid_file, pid_file_len, "/run/dhclient-%s.pid", iface_name);
|
||||||
|
|
||||||
/* Preparar los argumentos para el proceso */
|
/* 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;
|
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) {
|
void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
|
||||||
Interface *iface = (Interface *) data;
|
Interface *iface = (Interface *) data;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
@ -64,13 +80,17 @@ void interfaces_dhcp_client_killed_cb (GPid pid, gint status, gpointer data) {
|
||||||
gchar pid_file[256];
|
gchar pid_file[256];
|
||||||
|
|
||||||
/* Preparar los argumentos */
|
/* 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)) {
|
if (g_spawn_check_exit_status (status, NULL)) {
|
||||||
/* Revisar si necesito algo */
|
/* 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) {
|
if (iface->dhcpc.flags & DHCP_CLIENT_FLAG_AUTO_RESTART) {
|
||||||
/* Se cerró o mataron el proceso, reiniciar */
|
/* Se cerró o mataron el proceso, reiniciar */
|
||||||
ret = g_spawn_async_with_pipes (
|
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) {
|
int interfaces_dhcp_client_run (NetworkInadorHandle *handle, int index, int type, uint32_t flags) {
|
||||||
/* IFNAMSIZ */
|
/* IFNAMSIZ */
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
|
@ -122,18 +153,23 @@ 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, 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) {
|
if (iface->dhcpc.type != IFACE_NO_DHCP) {
|
||||||
/* No puedo correr otro tipo de DHCP */
|
/* No puedo correr otro tipo de DHCP */
|
||||||
return -1;
|
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 */
|
/* El cliente de dhcp ya está corriendo, no hacer nada */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interfaces_dhcp_clear_info (&iface->dhcpc);
|
||||||
|
|
||||||
ret = g_spawn_async_with_pipes (
|
ret = g_spawn_async_with_pipes (
|
||||||
"/",
|
"/",
|
||||||
argv,
|
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.dhcp_state = DHCP_CLIENT_EXTERNAL_RUNNING;
|
||||||
iface->dhcpc.type = IFACE_ISC_DHCLIENT;
|
iface->dhcpc.type = type;
|
||||||
iface->dhcpc.flags = flags;
|
iface->dhcpc.flags = flags;
|
||||||
|
|
||||||
iface->dhcpc.process_watch = g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_killed_cb, iface);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
||||||
Interface *iface;
|
Interface *iface;
|
||||||
|
|
||||||
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||||
|
@ -173,18 +209,18 @@ void interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index) {
|
||||||
if (iface == NULL) {
|
if (iface == NULL) {
|
||||||
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
|
printf ("Error, solicitaron operación sobre interfaz que no existe\n");
|
||||||
|
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iface->dhcpc.type == IFACE_NO_DHCP) {
|
if (iface->dhcpc.type == IFACE_NO_DHCP) {
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT) {
|
if (iface->dhcpc.type == IFACE_ISC_DHCLIENT || iface->dhcpc.type == IFACE_BUSYBOX_UDHCPC) {
|
||||||
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return;
|
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return -1;
|
||||||
|
|
||||||
/* Proceso, matar y reiniciar estado */
|
/* Proceso, matar y reiniciar estado */
|
||||||
iface->dhcpc.type = IFACE_NO_DHCP;
|
|
||||||
iface->dhcpc.flags &= (~DHCP_CLIENT_FLAG_AUTO_RESTART);
|
iface->dhcpc.flags &= (~DHCP_CLIENT_FLAG_AUTO_RESTART);
|
||||||
|
|
||||||
g_source_remove (iface->dhcpc.process_watch);
|
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);
|
g_child_watch_add (iface->dhcpc.process_pid, interfaces_dhcp_client_ignore_kill, NULL);
|
||||||
|
|
||||||
kill (iface->dhcpc.process_pid, SIGTERM);
|
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) {
|
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;
|
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 */
|
/* Un proceso muerto no puede informar de cambios de estados */
|
||||||
if (iface->dhcpc.dhcp_state == DHCP_CLIENT_KILLED) return;
|
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.broadcast, broadcast, sizeof (iface->dhcpc.broadcast));
|
||||||
memcpy (&iface->dhcpc.dhcp_server_ip, dhcp_server, sizeof (iface->dhcpc.dhcp_server_ip));
|
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];
|
char buf_a[256], buf_b[256], buf_c[256], buf_d[256];
|
||||||
|
|
||||||
inet_ntop (AF_INET, &iface->dhcpc.ip, buf_a, sizeof (buf_a));
|
inet_ntop (AF_INET, &iface->dhcpc.ip, buf_a, sizeof (buf_a));
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
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);
|
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);
|
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__ */
|
||||||
|
|
190
src/manager.c
190
src/manager.c
|
@ -46,6 +46,8 @@
|
||||||
|
|
||||||
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
#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) {
|
static void _manager_send_error (ManagerClientInfo *manager_client, int error, int orig_cmd) {
|
||||||
unsigned char buffer[8];
|
unsigned char buffer[8];
|
||||||
|
|
||||||
|
@ -732,7 +734,7 @@ static void _manager_execute_dhcp_client_feed (ManagerClientInfo *manager_client
|
||||||
return;
|
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);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_DHCP_CLIENT_FEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -807,6 +809,183 @@ static void _manager_execute_dhcp_client_feed (ManagerClientInfo *manager_client
|
||||||
_manager_send_executed (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) {
|
static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition, gpointer data) {
|
||||||
ManagerClientInfo *manager_client = (ManagerClientInfo *) data;
|
ManagerClientInfo *manager_client = (ManagerClientInfo *) data;
|
||||||
NetworkInadorManager *manager = manager_client->manager;
|
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:
|
case NET_INADOR_COMMAND_DHCP_CLIENT_FEED:
|
||||||
_manager_execute_dhcp_client_feed (manager_client, buffer, bytes);
|
_manager_execute_dhcp_client_feed (manager_client, buffer, bytes);
|
||||||
break;
|
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:
|
default:
|
||||||
_manager_send_error (manager_client, NET_INADOR_ERROR_WRONG_COMMAND, command);
|
_manager_send_error (manager_client, NET_INADOR_ERROR_WRONG_COMMAND, command);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ enum {
|
||||||
/* Lista de eventos */
|
/* Lista de eventos */
|
||||||
#define NET_INADOR_EVENT_MASK_INTERFACES 0x01
|
#define NET_INADOR_EVENT_MASK_INTERFACES 0x01
|
||||||
#define NET_INADOR_EVENT_MASK_IP 0x02
|
#define NET_INADOR_EVENT_MASK_IP 0x02
|
||||||
|
#define NET_INADOR_EVENT_MASK_DHCP_STATUS 0x04
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NET_INADOR_COMMAND_LIST_IFACES = 1,
|
NET_INADOR_COMMAND_LIST_IFACES = 1,
|
||||||
|
@ -34,6 +35,10 @@ enum {
|
||||||
NET_INADOR_COMMAND_ADD_IP,
|
NET_INADOR_COMMAND_ADD_IP,
|
||||||
NET_INADOR_COMMAND_REMOVE_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,
|
NET_INADOR_COMMAND_SET_EVENT_MASK = 192,
|
||||||
|
|
||||||
/* Los siguientes comandos son para uso interno */
|
/* Los siguientes comandos son para uso interno */
|
||||||
|
@ -56,7 +61,9 @@ enum {
|
||||||
NET_INADOR_EVENT_IFACE_ADDED = 2,
|
NET_INADOR_EVENT_IFACE_ADDED = 2,
|
||||||
NET_INADOR_EVENT_IPADDR_ADDED,
|
NET_INADOR_EVENT_IPADDR_ADDED,
|
||||||
NET_INADOR_EVENT_IFACE_REMOVED,
|
NET_INADOR_EVENT_IFACE_REMOVED,
|
||||||
NET_INADOR_EVENT_IPADDR_REMOVED
|
NET_INADOR_EVENT_IPADDR_REMOVED,
|
||||||
|
|
||||||
|
NET_INADOR_EVENT_DHCP_STATUS = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -64,6 +71,8 @@ enum {
|
||||||
|
|
||||||
NET_INADOR_RESPONSE_IFACE = 2,
|
NET_INADOR_RESPONSE_IFACE = 2,
|
||||||
NET_INADOR_RESPONSE_IPADDR,
|
NET_INADOR_RESPONSE_IPADDR,
|
||||||
|
|
||||||
|
NET_INADOR_RESPONSE_DHCP_STATUS = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -274,17 +274,77 @@ int parse_int (char *var, int *entero) {
|
||||||
return 0;
|
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[]) {
|
int main (int argc, char *argv[]) {
|
||||||
char *reason, *interface;
|
char *reason, *interface;
|
||||||
int s, ret;
|
int s, ret, tipo;
|
||||||
struct sockaddr_un path_dest;
|
struct sockaddr_un path_dest;
|
||||||
struct in_addr ip, netmask, gateway, broadcast, dhcp_server;
|
struct in_addr ip, netmask, gateway, broadcast, dhcp_server;
|
||||||
int prefix, lease_time;
|
int prefix, lease_time;
|
||||||
|
|
||||||
debug (argc, argv);
|
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");
|
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");
|
interface = getenv ("interface");
|
||||||
|
|
||||||
if (reason == NULL || interface == NULL) {
|
if (reason == NULL || interface == NULL) {
|
||||||
|
@ -308,12 +368,15 @@ int main (int argc, char *argv[]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp (reason, "PREINIT") == 0) {
|
if (strcmp (reason, "PREINIT") == 0 || // ISC DHCP
|
||||||
|
strcmp (reason, "deconfig") == 0 // Busybox udhcpc
|
||||||
|
) {
|
||||||
send_preinit (s, interface);
|
send_preinit (s, interface);
|
||||||
} if (strcmp (reason, "FAIL") == 0) {
|
} if (strcmp (reason, "FAIL") == 0) {
|
||||||
|
|
||||||
} else if (strcmp (reason, "BOUND") == 0 || strcmp (reason, "REBOOT") == 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:
|
* Los valores más importantes recibidos:
|
||||||
|
@ -328,12 +391,21 @@ int main (int argc, char *argv[]) {
|
||||||
*/
|
*/
|
||||||
/* Parsear y revisar las direcciones IP recibidas */
|
/* Parsear y revisar las direcciones IP recibidas */
|
||||||
char *s_ip, *s_mask, *s_gateway, *s_broadcast, *s_lease_time, *s_dhcp_server;
|
char *s_ip, *s_mask, *s_gateway, *s_broadcast, *s_lease_time, *s_dhcp_server;
|
||||||
s_ip = getenv ("new_ip_address");
|
if (tipo == IFACE_ISC_DHCLIENT) {
|
||||||
s_mask = getenv ("new_subnet_mask");
|
s_ip = getenv ("new_ip_address");
|
||||||
s_gateway = getenv ("new_routers");
|
s_mask = getenv ("new_subnet_mask");
|
||||||
s_broadcast = getenv ("new_broadcast_address");
|
s_gateway = getenv ("new_routers");
|
||||||
s_lease_time = getenv ("new_dhcp_lease_time");
|
s_broadcast = getenv ("new_broadcast_address");
|
||||||
s_dhcp_server = getenv ("new_dhcp_server_identifier");
|
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 */
|
/* TODO: Faltan los DNS */
|
||||||
|
|
||||||
if (parse_ip (s_ip, &ip) < 0) {
|
if (parse_ip (s_ip, &ip) < 0) {
|
||||||
|
@ -364,7 +436,9 @@ int main (int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_bound = 0;
|
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;
|
is_bound = 1;
|
||||||
}
|
}
|
||||||
send_bound_renew (s, is_bound, interface, &ip, prefix, &gateway, &broadcast, &dhcp_server, lease_time);
|
send_bound_renew (s, is_bound, interface, &ip, prefix, &gateway, &broadcast, &dhcp_server, lease_time);
|
||||||
|
|
Loading…
Reference in New Issue