Agrego marcas de tiempo y etiquetas de las direcciones IP.

master
Félix Arreola Rodríguez 2022-01-01 18:29:39 -06:00
parent 476ab66ca8
commit bf315b5b03
9 changed files with 201 additions and 16 deletions

View File

@ -381,7 +381,7 @@ void ni_client_ask_interfaces (NIClient *ni_client) {
send (ni_client->priv->client_socket, buffer, 2, 0);
}
void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr) {
void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr, uint32_t *cacheinfo) {
unsigned char buffer[80];
uint32_t index;
int family_size;
@ -416,9 +416,12 @@ void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int f
buffer[9] = scope;
memcpy (&buffer[10], &flags, 4);
memcpy (&buffer[14], addr, family_size);
/* Copiar los timestamp solicitados */
memcpy (&buffer[14], cacheinfo, 8);
pos = 14 + family_size;
memcpy (&buffer[22], addr, family_size);
pos = 22 + family_size;
if (has_local) {
memcpy (&buffer[pos], local_addr, family_size);

View File

@ -78,7 +78,7 @@ NIClient *ni_client_new_with_path (const char *path);
gboolean ni_client_connect (NIClient *ni_client);
void ni_client_ask_ip_interface (NIClient *ni_client, NIInterface *ni_interface, int family);
void ni_client_ask_ips (NIClient *ni_client, NIInterface *ni_interface);
void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr);
void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr, uint32_t *cacheinfo);
void ni_client_ask_ip_delete (NIClient *ni_client, NIInterface *ni_interface, NIIP *ni_ip);
void ni_client_ask_change_iface_name (NIClient *ni_client, NIInterface *ni_interface, const gchar *new_name);
void ni_client_ask_change_iface_mtu (NIClient *ni_client, NIInterface *ni_interface, guint new_mtu);

View File

@ -433,7 +433,10 @@ static void ni_interface_process_ip_added (NIInterface *ni_interface, gpointer d
unsigned char *buffer = (unsigned char *) data;
uint32_t index, flags;
guint family, prefix, bits, scope, pos;
guint32 cacheinfo[4];
char label[256];
gint family_size = 0;
gint label_len;
gboolean has_local_addr = FALSE, has_brd_addr = FALSE;
NIIP *ni_ip;
struct_addr addr, local_addr, brd_addr;
@ -454,9 +457,12 @@ static void ni_interface_process_ip_added (NIInterface *ni_interface, gpointer d
family_size = sizeof (struct in6_addr);
}
memcpy (&addr, &buffer[14], family_size);
/* Copiar los timestamp */
memcpy (cacheinfo, &buffer[14], 16);
pos = 14 + family_size;
memcpy (&addr, &buffer[30], family_size);
pos = 30 + family_size;
if (has_local_addr) {
memcpy (&local_addr, &buffer[pos], family_size);
pos += family_size;
@ -464,9 +470,20 @@ static void ni_interface_process_ip_added (NIInterface *ni_interface, gpointer d
if (has_brd_addr) {
memcpy (&brd_addr, &buffer[pos], family_size);
pos += family_size;
}
ni_ip = ni_ip_new (ni_interface, family, prefix, &addr, flags, scope, has_local_addr, (has_local_addr ? &local_addr : NULL), has_brd_addr, (has_brd_addr ? &brd_addr : NULL));
/* Leer la label, si es que existe */
label[0] = 0;
label_len = buffer[pos];
pos++;
if (label_len > 0) {
memcpy (label, &buffer[pos], label_len);
label[label_len] = 0;
}
ni_ip = ni_ip_new (ni_interface, family, prefix, &addr, flags, scope, has_local_addr, (has_local_addr ? &local_addr : NULL), has_brd_addr, (has_brd_addr ? &brd_addr : NULL), cacheinfo, (label_len != 0) ? label : NULL);
ni_interface->priv->ip_list = g_list_append (ni_interface->priv->ip_list, ni_ip);

View File

@ -40,11 +40,19 @@ struct _NIIPPrivate {
struct_addr addr;
struct_addr brd_addr;
/* Timestamps */
guint32 ifa_prefered;
guint32 ifa_valid;
guint32 cstamp;
guint32 tstamp;
gboolean has_brd;
gboolean has_local;
uint32_t flags;
unsigned char scope;
char label[256];
};
enum {
@ -174,11 +182,35 @@ const struct_addr *ni_ip_get_brd_addr (NIIP *ni_ip) {
return &ni_ip->priv->brd_addr;
}
uint32_t ni_ip_get_ifa_prefered (NIIP *ni_ip) {
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
NIIP *ni_ip_new (NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr) {
return ni_ip->priv->ifa_prefered;
}
uint32_t ni_ip_get_ifa_valid (NIIP *ni_ip) {
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
return ni_ip->priv->ifa_valid;
}
uint32_t ni_ip_get_cstamp (NIIP *ni_ip) {
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
return ni_ip->priv->cstamp;
}
uint32_t ni_ip_get_tstamp (NIIP *ni_ip) {
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
return ni_ip->priv->tstamp;
}
NIIP *ni_ip_new (NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr, guint32 *cacheinfo, char *label) {
NIIP *ni_ip;
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), NULL);
g_return_val_if_fail (cacheinfo != NULL, NULL);
ni_ip = g_object_new (NI_TYPE_IP, "ni-interface", ni_interface, NULL);
@ -190,6 +222,16 @@ NIIP *ni_ip_new (NIInterface *ni_interface, int family, int prefix, struct_addr
ni_ip->priv->flags = flags;
ni_ip->priv->scope = scope;
/* Copiar los valores del arreglo */
ni_ip->priv->ifa_prefered = cacheinfo[0];
ni_ip->priv->ifa_valid = cacheinfo[1];
ni_ip->priv->cstamp = cacheinfo[2];
ni_ip->priv->tstamp = cacheinfo[3];
ni_ip->priv->label[0] = 0;
if (label != NULL && label[0] != 0) {
strncpy (ni_ip->priv->label, label, sizeof (ni_ip->priv->label));
}
if (family == AF_INET) {
ni_ip->priv->family_size = sizeof (struct in_addr);
} else if (family == AF_INET6) {

View File

@ -80,8 +80,12 @@ unsigned char ni_ip_get_scope (NIIP *ni_ip);
const struct_addr *ni_ip_get_addr (NIIP *ni_ip);
const struct_addr *ni_ip_get_local_addr (NIIP *ni_ip);
const struct_addr *ni_ip_get_brd_addr (NIIP *ni_ip);
uint32_t ni_ip_get_ifa_prefered (NIIP *ni_ip);
uint32_t ni_ip_get_ifa_valid (NIIP *ni_ip);
uint32_t ni_ip_get_cstamp (NIIP *ni_ip);
uint32_t ni_ip_get_tstamp (NIIP *ni_ip);
NIIP *ni_ip_new (NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr);
NIIP *ni_ip_new (NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr, guint32 *cacheinfo, char *label);
G_END_DECLS

View File

@ -187,7 +187,11 @@ static void ni_window_interface_addr_button_add_cb (GtkWidget *widget, int famil
}
//void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr) {
ni_client_ask_ip_new (ni_client, window_iface->priv->ni_interface, family, prefix, &addr, flags, 0, has_p2p, (has_p2p ? &p2p_addr : NULL), FALSE, NULL);
/* TODO: Pedir los tiempos de validez de la interfaz */
guint32 cacheinfo[2];
cacheinfo[0] = 0xFFFFFFFFU;
cacheinfo[1] = 0xFFFFFFFFU;
ni_client_ask_ip_new (ni_client, window_iface->priv->ni_interface, family, prefix, &addr, flags, 0, has_p2p, (has_p2p ? &p2p_addr : NULL), FALSE, NULL, cacheinfo);
}
gtk_widget_destroy (dialog);
@ -293,6 +297,45 @@ static void ni_window_interface_addr_v6_button_del_cb (GtkWidget *widget, gpoint
ni_window_interface_addr_button_del_cb (widget, AF_INET6, data);
}
/* Función para renderizar el tiempo de la IP en el arbol */
void ni_window_interface_cell_renderer_timestamp (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) {
NIIP *ni_ip;
char buffer[256];
guint32 valid, prefered;
gint horas, minutos, segundos;
gtk_tree_model_get (tree_model, iter, IP_STORE_COL_OBJECT, &ni_ip, -1);
valid = ni_ip_get_ifa_valid (ni_ip);
prefered = ni_ip_get_ifa_prefered (ni_ip);
if (valid == 0xFFFFFFFFU) {
g_object_set (cell, "text", "Indefinida", NULL);
} else {
horas = valid / 3600;
segundos = valid - (horas * 3600);
minutos = segundos / 60;
segundos = segundos - (minutos * 60);
if (horas > 0) {
if (minutos > 0) {
snprintf (buffer, sizeof (buffer), "%i hora(s), %i minuto(s)", horas, minutos);
} else {
snprintf (buffer, sizeof (buffer), "%i hora(s)", horas);
}
} else if (minutos > 0) {
if (segundos > 0) {
snprintf (buffer, sizeof (buffer), "%i minuto(s), %i segundo(s)", minutos, segundos);
} else {
snprintf (buffer, sizeof (buffer), "%i minuto(s)", minutos);
}
} else {
snprintf (buffer, sizeof (buffer), "%i segundo(s)", segundos);
}
g_object_set (cell, "text", buffer, NULL);
}
}
/* Evento cuando cambian el nombre de la interfaz en el entry */
static void ni_window_interface_name_edit_cb (GtkEditable *editable, gpointer data) {
NIWindowInterface *window_iface = (NIWindowInterface *) data;
@ -795,6 +838,7 @@ GtkWidget *ni_window_interface_create_tree_for_ip (GtkListStore *store, GtkWidge
*tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (*tree), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
h = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (*tree));
v = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (*tree));
@ -803,6 +847,15 @@ GtkWidget *ni_window_interface_create_tree_for_ip (GtkListStore *store, GtkWidge
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Dirección", renderer, "text", IP_STORE_COL_MAIN_IP, NULL);
gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (column), TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW (*tree), column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (column), TRUE);
gtk_tree_view_column_set_title (GTK_TREE_VIEW_COLUMN (column), "Vigencia");
gtk_tree_view_column_pack_start (GTK_TREE_VIEW_COLUMN (column), renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column), renderer, ni_window_interface_cell_renderer_timestamp, NULL, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (*tree), column);
gtk_container_add (GTK_CONTAINER (scrolled), *tree);

View File

@ -41,6 +41,10 @@
#define TRUE !FALSE
#endif
#ifndef INFINITY_LIFE_TIME
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
#endif
typedef struct _NetworkInadorHandle NetworkInadorHandle;
typedef struct _NetworkInadorManager NetworkInadorManager;
typedef struct _Interface Interface;
@ -58,6 +62,9 @@ typedef struct _IPAddr {
struct_addr addr;
struct_addr brd_addr;
char label[256];
struct ifa_cacheinfo cacheinfo;
int is_p2p;
int has_brd;
int has_local;

View File

@ -77,6 +77,8 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
int remaining;
struct nlattr *attr;
struct ifa_cacheinfo cacheinfo;
char label[256];
int label_len;
struct_addr addr;
struct_addr local_addr;
@ -86,7 +88,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
/* TODO: Decidir si guardamos también la IP anycast */
int family;
int has_brd = 0, has_local = 0;
int has_brd = 0, has_local = 0, has_cacheinfo = 0;
int family_size = 0;
int was_new = 0;
@ -114,6 +116,15 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
family_size = sizeof (struct in6_addr);
}
label[0] = 0;
label_len = 0;
/* Prevaciar el cacheinfo */
cacheinfo.ifa_prefered = INFINITY_LIFE_TIME;
cacheinfo.ifa_valid = INFINITY_LIFE_TIME;
cacheinfo.cstamp = 0;
cacheinfo.tstamp = 0;
nlmsg_for_each_attr(attr, reply, sizeof (struct ifaddrmsg), remaining) {
printf ("-> new addr type attr: %i\n", nla_type (attr));
switch (nla_type (attr)) {
@ -134,6 +145,13 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
case IFA_CACHEINFO:
memcpy (&cacheinfo, nla_data (attr), nla_len (attr));
printf ("Cache info timestamp: preferred: %u, valid: %u, created: %u, updated: %u\n", cacheinfo.ifa_prefered, cacheinfo.ifa_valid, cacheinfo.cstamp, cacheinfo.tstamp);
has_cacheinfo = 1;
break;
case IFA_LABEL:
label_len = nla_len (attr);
memcpy (label, nla_data(attr), label_len);
label[label_len] = 0;
printf ("-> La IP tiene label: %s\n", label);
break;
}
}
@ -171,11 +189,21 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
}
}
ip_addr->label[0] = 0;
if (label[0] != 0) {
memcpy (ip_addr->label, label, label_len);
ip_addr->label[label_len] = 0;
}
if (has_brd) {
ip_addr->has_brd = 1;
memcpy (&ip_addr->brd_addr, &brd_addr, family_size);
}
if (has_cacheinfo) {
memcpy (&ip_addr->cacheinfo, &cacheinfo, sizeof (cacheinfo));
}
if (was_new) {
manager_send_event_ip_add (handle, ip_addr);
} else {
@ -338,6 +366,13 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr)
ret |= nla_put (msg, IFA_BROADCAST, family_size, &ip_addr->brd_addr);
}
/* El tiempo preferido no puede ser mayor que el tiempo válido */
if (ip_addr->cacheinfo.ifa_prefered > ip_addr->cacheinfo.ifa_valid) {
ip_addr->cacheinfo.ifa_prefered = ip_addr->cacheinfo.ifa_valid;
}
ret |= nla_put (msg, IFA_CACHEINFO, 16, &ip_addr->cacheinfo);
if (ret != 0) {
nlmsg_free (msg);

View File

@ -130,6 +130,7 @@ void _manager_send_interface_del (ManagerClientInfo *manager_client, uint32_t in
void _manager_send_ip (ManagerClientInfo *manager_client, IPAddr *ip_addr, gboolean is_event) {
unsigned char buffer[80];
int family_size = 0;
int label_len;
int pos;
if (is_event) {
@ -140,6 +141,7 @@ void _manager_send_ip (ManagerClientInfo *manager_client, IPAddr *ip_addr, gbool
buffer[1] = NET_INADOR_RESPONSE_IPADDR;
}
/* Familia y máscara */
if (ip_addr->family == AF_INET) {
family_size = sizeof (struct in_addr);
} else if (ip_addr->family == AF_INET6) {
@ -149,6 +151,7 @@ void _manager_send_ip (ManagerClientInfo *manager_client, IPAddr *ip_addr, gbool
buffer[6] = ip_addr->family;
buffer[7] = ip_addr->prefix;
/* Los campos de bits */
buffer[8] = 0;
if (ip_addr->has_local) {
buffer[8] |= 0x01;
@ -157,11 +160,16 @@ void _manager_send_ip (ManagerClientInfo *manager_client, IPAddr *ip_addr, gbool
buffer[8] |= 0x02;
}
/* Byte scope y las flags */
buffer[9] = ip_addr->scope;
memcpy (&buffer[10], &ip_addr->flags, 4);
memcpy (&buffer[14], &ip_addr->addr, family_size);
pos = 14 + family_size;
/* La información de marcas de tiempo de las IPs */
memcpy (&buffer[14], &ip_addr->cacheinfo, 16);
/* La dirección principal */
memcpy (&buffer[30], &ip_addr->addr, family_size);
pos = 30 + family_size;
if (ip_addr->has_local) {
memcpy (&buffer[pos], &ip_addr->local_addr, family_size);
pos += family_size;
@ -172,6 +180,17 @@ void _manager_send_ip (ManagerClientInfo *manager_client, IPAddr *ip_addr, gbool
pos += family_size;
}
if (ip_addr->label[0] != 0) {
label_len = strlen (ip_addr->label);
buffer[pos] = label_len;
pos++;
memcpy (&buffer[pos], &ip_addr->label, label_len);
pos += label_len;
} else {
buffer[pos] = 0;
pos++;
}
send (manager_client->fd, buffer, pos, 0);
}
@ -446,7 +465,7 @@ void _manager_execute_add_ip (ManagerClientInfo *manager_client, unsigned char *
family_size = sizeof (struct in6_addr);
}
/* Ya puedo revisar el resto de la longitud */
wanted_size = 14 + family_size + (family_size * ip_addr.has_local) + (family_size * ip_addr.has_brd);
wanted_size = 22 + family_size + (family_size * ip_addr.has_local) + (family_size * ip_addr.has_brd);
if (buffer_len < wanted_size) {
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_ADD_IP);
return;
@ -455,8 +474,13 @@ void _manager_execute_add_ip (ManagerClientInfo *manager_client, unsigned char *
ip_addr.scope = buffer[9];
memcpy (&ip_addr.flags, &buffer[10], 4);
memcpy (&ip_addr.addr, &buffer[14], family_size);
wanted_size = 14 + family_size;
/* Copiar los timestamp de tiempo válido y preferido */
memset (&ip_addr.cacheinfo, 0, sizeof (ip_addr.cacheinfo));
memcpy (&ip_addr.cacheinfo, &buffer[14], 8);
/* Copiar las direcciones */
memcpy (&ip_addr.addr, &buffer[22], family_size);
wanted_size = 22 + family_size;
if (ip_addr.has_local) {
memcpy (&ip_addr.local_addr, &buffer[wanted_size], family_size);