Reorganizo las estructuras de direcciones de IPv4 y IPv6.
parent
8a9690c502
commit
89570f4139
32
src/common.h
32
src/common.h
|
@ -41,15 +41,27 @@
|
|||
#define TRUE !FALSE
|
||||
#endif
|
||||
|
||||
typedef struct _NetworkInadorHandle NetworkInadorHandle;
|
||||
typedef struct _NetworkInadorManager NetworkInadorManager;
|
||||
|
||||
typedef union {
|
||||
struct in_addr v4;
|
||||
struct in6_addr v6;
|
||||
} struct_addr;
|
||||
|
||||
typedef struct _IPAddr {
|
||||
sa_family_t family;
|
||||
union {
|
||||
struct in_addr sin_addr;
|
||||
struct in6_addr sin6_addr;
|
||||
};
|
||||
uint32_t prefix;
|
||||
|
||||
unsigned char flags;
|
||||
int prefix;
|
||||
struct_addr local_addr;
|
||||
struct_addr addr;
|
||||
struct_addr brd_addr;
|
||||
|
||||
int is_p2p;
|
||||
int has_brd;
|
||||
int has_local;
|
||||
|
||||
uint32_t flags;
|
||||
unsigned char scope;
|
||||
} IPAddr;
|
||||
|
||||
|
@ -93,15 +105,15 @@ typedef struct _WirelessInfo {
|
|||
} WirelessInfo;
|
||||
|
||||
typedef struct _Interface {
|
||||
uint32_t index;
|
||||
char name[IFNAMSIZ];
|
||||
int ifi_type;
|
||||
uint16_t ifi_type;
|
||||
unsigned char real_hw[ETHER_ADDR_LEN * 2 + 1];
|
||||
unsigned int index;
|
||||
|
||||
/* Para las interfaces dentro de un bridge */
|
||||
unsigned int master_index;
|
||||
uint32_t master_index;
|
||||
|
||||
unsigned int mtu;
|
||||
uint32_t mtu;
|
||||
|
||||
/* Para las interfaces vlan */
|
||||
unsigned int vlan_parent;
|
||||
|
|
259
src/ip-address.c
259
src/ip-address.c
|
@ -34,18 +34,29 @@
|
|||
#include "ip-address.h"
|
||||
#include "interfaces.h"
|
||||
|
||||
static IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, void *addr_data, uint32_t prefix) {
|
||||
static IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, void *addr, uint32_t prefix, void *local_addr) {
|
||||
GList *g;
|
||||
IPAddr *addr;
|
||||
IPAddr *ip_addr;
|
||||
int family_size = 0;
|
||||
|
||||
if (family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
for (g = iface->address; g != NULL; g = g->next) {
|
||||
addr = (IPAddr *) g->data;
|
||||
ip_addr = (IPAddr *) g->data;
|
||||
|
||||
if (addr->family == family) {
|
||||
if (family == AF_INET && memcmp (&addr->sin_addr, addr_data, sizeof (struct in_addr)) == 0 && addr->prefix == prefix) {
|
||||
return addr;
|
||||
} else if (family == AF_INET6 && memcmp (&addr->sin6_addr, addr_data, sizeof (struct in6_addr)) == 0 && addr->prefix == prefix) {
|
||||
return addr;
|
||||
if (ip_addr->family != family) continue;
|
||||
|
||||
if (memcmp (&ip_addr->addr, addr, family_size) == 0 && ip_addr->prefix == prefix) {
|
||||
if (local_addr != NULL) {
|
||||
if (memcmp (&ip_addr->local_addr, local_addr, family_size) == 0) {
|
||||
return ip_addr;
|
||||
}
|
||||
} else {
|
||||
return ip_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,16 +65,24 @@ static IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, vo
|
|||
}
|
||||
|
||||
int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
|
||||
NetworkInadorHandle *handle = (NetworkInadorHandle *) arg;
|
||||
Interface *iface;
|
||||
IPAddr *ip_addr;
|
||||
|
||||
struct nlmsghdr *reply;
|
||||
struct ifaddrmsg *addr_msg;
|
||||
int remaining;
|
||||
struct nlattr *attr;
|
||||
NetworkInadorHandle *handle = (NetworkInadorHandle *) arg;
|
||||
Interface *iface;
|
||||
int has_addr = 0;
|
||||
struct in_addr sin_addr;
|
||||
struct in6_addr sin6_addr;
|
||||
IPAddr *addr;
|
||||
|
||||
struct_addr addr;
|
||||
struct_addr local_addr;
|
||||
struct_addr brd_addr;
|
||||
/* TODO: Decidir si guardamos también la IP anycast */
|
||||
|
||||
uint32_t flags;
|
||||
int family;
|
||||
int has_brd = 0, has_local = 0;
|
||||
int family_size = 0;
|
||||
|
||||
reply = nlmsg_hdr (msg);
|
||||
|
||||
|
@ -78,62 +97,100 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
|
|||
return NL_SKIP;
|
||||
}
|
||||
|
||||
printf ("-> New addr\n");
|
||||
|
||||
flags = addr_msg->ifa_flags;
|
||||
|
||||
family = addr_msg->ifa_family;
|
||||
if (family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
nlmsg_for_each_attr(attr, reply, sizeof (struct ifaddrmsg), remaining) {
|
||||
if (nla_type (attr) != IFA_ADDRESS) continue;
|
||||
|
||||
if (addr_msg->ifa_family == AF_INET && nla_len (attr) == 4) {
|
||||
/* IP de ipv4 */
|
||||
memcpy (&sin_addr, nla_data (attr), nla_len (attr));
|
||||
has_addr = 1;
|
||||
} else if (addr_msg->ifa_family == AF_INET6 && nla_len (attr) == 16) {
|
||||
/* IP de ipv6 */
|
||||
memcpy (&sin6_addr, nla_data (attr), nla_len (attr));
|
||||
has_addr = 1;
|
||||
printf ("-> new addr type attr: %i\n", nla_type (attr));
|
||||
switch (nla_type (attr)) {
|
||||
case IFA_FLAGS:
|
||||
memcpy (&flags, nla_data (attr), nla_len (attr));
|
||||
break;
|
||||
case IFA_ADDRESS:
|
||||
memcpy (&addr, nla_data (attr), nla_len (attr));
|
||||
break;
|
||||
case IFA_LOCAL:
|
||||
memcpy (&local_addr, nla_data (attr), nla_len (attr));
|
||||
has_local = 1;
|
||||
break;
|
||||
case IFA_BROADCAST:
|
||||
memcpy (&brd_addr, nla_data (attr), nla_len (attr));
|
||||
has_brd = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ip_addr = _ip_address_search_addr (iface, family, &addr, addr_msg->ifa_prefixlen, (has_local ? &local_addr : NULL));
|
||||
|
||||
if (addr_msg->ifa_family == AF_INET) {
|
||||
addr = _ip_address_search_addr (iface, AF_INET, &sin_addr, addr_msg->ifa_prefixlen);
|
||||
} else if (addr_msg->ifa_family == AF_INET6) {
|
||||
addr = _ip_address_search_addr (iface, AF_INET6, &sin6_addr, addr_msg->ifa_prefixlen);
|
||||
/* Agregar los datos al objeto */
|
||||
if (ip_addr == NULL) {
|
||||
ip_addr = g_new0 (IPAddr, 1);
|
||||
|
||||
iface->address = g_list_append (iface->address, ip_addr);
|
||||
|
||||
ip_addr->family = addr_msg->ifa_family;
|
||||
memcpy (&ip_addr->addr, &addr, family_size);
|
||||
|
||||
ip_addr->prefix = addr_msg->ifa_prefixlen;
|
||||
}
|
||||
|
||||
if (addr == NULL) {
|
||||
addr = g_new0 (IPAddr, 1);
|
||||
|
||||
iface->address = g_list_append (iface->address, addr);
|
||||
|
||||
addr->family = addr_msg->ifa_family;
|
||||
if (addr->family == AF_INET) {
|
||||
memcpy (&addr->sin_addr, &sin_addr, sizeof (struct in_addr));
|
||||
} else if (addr->family == AF_INET6) {
|
||||
memcpy (&addr->sin6_addr, &sin6_addr, sizeof (struct in6_addr));
|
||||
ip_addr->flags = flags;
|
||||
ip_addr->scope = addr_msg->ifa_scope;
|
||||
|
||||
/* Actualizar la local o la broadcast */
|
||||
ip_addr->is_p2p = 0;
|
||||
|
||||
if (has_local) {
|
||||
ip_addr->has_local = 1;
|
||||
memcpy (&ip_addr->local_addr, &local_addr, family_size);
|
||||
/* Revisar si las direcciones son P2P */
|
||||
if (memcmp (&local_addr, &addr, family_size) != 0) {
|
||||
ip_addr->is_p2p = 1;
|
||||
}
|
||||
|
||||
addr->prefix = addr_msg->ifa_prefixlen;
|
||||
}
|
||||
|
||||
addr->flags = addr_msg->ifa_flags;
|
||||
addr->scope = addr_msg->ifa_scope;
|
||||
if (has_brd) {
|
||||
ip_addr->has_brd = 1;
|
||||
memcpy (&ip_addr->brd_addr, &brd_addr, family_size);
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
inet_ntop (addr->family, &addr->sin_addr, buffer, sizeof (buffer));
|
||||
printf ("Dirección IP + %s/%d sobre interfaz: %d, scope: %d, flags: %d\n", buffer, addr->prefix, iface->index, ((unsigned int) addr->scope), ((unsigned int) addr->flags));
|
||||
char buffer_2[2048];
|
||||
if (ip_addr->is_p2p) {
|
||||
inet_ntop (ip_addr->family, &ip_addr->addr, buffer_2, sizeof (buffer_2));
|
||||
inet_ntop (ip_addr->family, &ip_addr->local_addr, buffer, sizeof (buffer));
|
||||
|
||||
printf ("Dirección IP + %s/%d peer %s sobre interfaz: %d, scope: %d, flags: %u\n", buffer, ip_addr->prefix, buffer_2, iface->index, (unsigned int) ip_addr->scope, ip_addr->flags);
|
||||
} else {
|
||||
inet_ntop (ip_addr->family, &ip_addr->addr, buffer, sizeof (buffer));
|
||||
printf ("Dirección IP + %s/%d sobre interfaz: %d, scope: %d, flags: %u\n", buffer, ip_addr->prefix, iface->index, (unsigned int) ip_addr->scope, ip_addr->flags);
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) {
|
||||
NetworkInadorHandle *handle = (NetworkInadorHandle *) arg;
|
||||
Interface *iface;
|
||||
IPAddr *ip_addr = NULL;
|
||||
|
||||
struct nlmsghdr *reply;
|
||||
struct ifaddrmsg *addr_msg;
|
||||
int remaining;
|
||||
struct nlattr *attr;
|
||||
NetworkInadorHandle *handle = (NetworkInadorHandle *) arg;
|
||||
Interface *iface;
|
||||
struct in_addr sin_addr;
|
||||
struct in6_addr sin6_addr;
|
||||
IPAddr *addr = NULL;
|
||||
|
||||
struct_addr addr;
|
||||
struct_addr local_addr;
|
||||
int family, family_size = 0;
|
||||
int has_local = 0;
|
||||
|
||||
reply = nlmsg_hdr (msg);
|
||||
|
||||
|
@ -148,34 +205,42 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) {
|
|||
return NL_SKIP;
|
||||
}
|
||||
|
||||
family = addr_msg->ifa_family;
|
||||
if (family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
printf ("DEL MSG\n");
|
||||
nlmsg_for_each_attr(attr, reply, sizeof (struct ifaddrmsg), remaining) {
|
||||
if (nla_type (attr) != IFA_ADDRESS) continue;
|
||||
|
||||
if (addr_msg->ifa_family == AF_INET && nla_len (attr) == 4) {
|
||||
/* IP de ipv4 */
|
||||
memcpy (&sin_addr, nla_data (attr), nla_len (attr));
|
||||
} else if (addr_msg->ifa_family == AF_INET6 && nla_len (attr) == 16) {
|
||||
/* IP de ipv6 */
|
||||
memcpy (&sin6_addr, nla_data (attr), nla_len (attr));
|
||||
printf ("-> del addr type attr: %i\n", nla_type (attr));
|
||||
switch (nla_type (attr)) {
|
||||
case IFA_ADDRESS:
|
||||
memcpy (&addr, nla_data (attr), nla_len (attr));
|
||||
break;
|
||||
case IFA_LOCAL:
|
||||
memcpy (&local_addr, nla_data (attr), nla_len (attr));
|
||||
has_local = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ip_addr = _ip_address_search_addr (iface, family, &addr, addr_msg->ifa_prefixlen, (has_local ? &local_addr : NULL));
|
||||
|
||||
if (addr_msg->ifa_family == AF_INET) {
|
||||
addr = _ip_address_search_addr (iface, AF_INET, &sin_addr, addr_msg->ifa_prefixlen);
|
||||
} else if (addr_msg->ifa_family == AF_INET6) {
|
||||
addr = _ip_address_search_addr (iface, AF_INET6, &sin6_addr, addr_msg->ifa_prefixlen);
|
||||
}
|
||||
|
||||
if (addr == NULL) {
|
||||
if (ip_addr == NULL) {
|
||||
printf ("IP no encontrada\n");
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
/* Eliminar de la lista ligada */
|
||||
iface->address = g_list_remove (iface->address, addr);
|
||||
char buffer[2048];
|
||||
inet_ntop (ip_addr->family, &ip_addr->local_addr, buffer, sizeof (buffer));
|
||||
printf ("Dirección IP - %s/%d sobre interfaz: %d, scope: %d, flags: %u\n", buffer, ip_addr->prefix, iface->index, (unsigned int) ip_addr->scope, ip_addr->flags);
|
||||
|
||||
g_free (addr);
|
||||
/* Eliminar de la lista ligada */
|
||||
iface->address = g_list_remove (iface->address, ip_addr);
|
||||
|
||||
g_free (ip_addr);
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
@ -204,11 +269,12 @@ static int _ip_address_wait_error (struct sockaddr_nl *nla, struct nlmsgerr *l_e
|
|||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
||||
int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr) {
|
||||
struct nl_msg * msg;
|
||||
struct ifaddrmsg addr_hdr;
|
||||
int ret, error;
|
||||
Interface *iface;
|
||||
int family_size = 0;
|
||||
|
||||
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||
|
||||
|
@ -218,10 +284,10 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
addr_hdr.ifa_family = addr->family;
|
||||
addr_hdr.ifa_prefixlen = addr->prefix;
|
||||
addr_hdr.ifa_flags = addr->flags;
|
||||
addr_hdr.ifa_scope = addr->scope;
|
||||
addr_hdr.ifa_family = ip_addr->family;
|
||||
addr_hdr.ifa_prefixlen = ip_addr->prefix;
|
||||
addr_hdr.ifa_flags = ip_addr->flags;
|
||||
addr_hdr.ifa_scope = ip_addr->scope;
|
||||
addr_hdr.ifa_index = index;
|
||||
|
||||
msg = nlmsg_alloc_simple (RTM_NEWADDR, NLM_F_REQUEST);
|
||||
|
@ -233,12 +299,18 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (addr->family == AF_INET) {
|
||||
ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin_addr), &addr->sin_addr);
|
||||
ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin_addr), &addr->sin_addr);
|
||||
} else {
|
||||
ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin6_addr), &addr->sin6_addr);
|
||||
ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin6_addr), &addr->sin6_addr);
|
||||
if (ip_addr->family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (ip_addr->family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
ret = nla_put (msg, IFA_ADDRESS, family_size, &ip_addr->addr);
|
||||
if (ip_addr->has_local) {
|
||||
ret |= nla_put (msg, IFA_LOCAL, family_size, &ip_addr->local_addr);
|
||||
}
|
||||
if (ip_addr->has_brd) {
|
||||
ret |= nla_put (msg, IFA_LOCAL, family_size, &ip_addr->brd_addr);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
|
@ -271,12 +343,13 @@ int ip_address_add_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
||||
int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *ip_addr) {
|
||||
struct nl_msg * msg;
|
||||
struct ifaddrmsg addr_hdr;
|
||||
int ret, error;
|
||||
Interface *iface;
|
||||
GList *addr_pos;
|
||||
int family_size = 0;
|
||||
|
||||
iface = _interfaces_locate_by_index (handle->interfaces, index);
|
||||
|
||||
|
@ -286,7 +359,7 @@ int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
addr_pos = g_list_find (iface->address, addr);
|
||||
addr_pos = g_list_find (iface->address, ip_addr);
|
||||
|
||||
if (addr_pos == NULL) {
|
||||
printf ("Error, la dirección solicitada no pertenece a la interfaz\n");
|
||||
|
@ -294,10 +367,10 @@ int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
addr_hdr.ifa_family = addr->family;
|
||||
addr_hdr.ifa_prefixlen = addr->prefix;
|
||||
addr_hdr.ifa_flags = addr->flags;
|
||||
addr_hdr.ifa_scope = addr->scope;
|
||||
addr_hdr.ifa_family = ip_addr->family;
|
||||
addr_hdr.ifa_prefixlen = ip_addr->prefix;
|
||||
addr_hdr.ifa_flags = ip_addr->flags;
|
||||
addr_hdr.ifa_scope = ip_addr->scope;
|
||||
addr_hdr.ifa_index = index;
|
||||
|
||||
msg = nlmsg_alloc_simple (RTM_DELADDR, NLM_F_REQUEST);
|
||||
|
@ -309,12 +382,18 @@ int ip_address_del_ip (NetworkInadorHandle *handle, int index, IPAddr *addr) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (addr->family == AF_INET) {
|
||||
ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin_addr), &addr->sin_addr);
|
||||
ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin_addr), &addr->sin_addr);
|
||||
} else {
|
||||
ret = nla_put (msg, IFA_LOCAL, sizeof (addr->sin6_addr), &addr->sin6_addr);
|
||||
ret = nla_put (msg, IFA_ADDRESS, sizeof (addr->sin6_addr), &addr->sin6_addr);
|
||||
if (ip_addr->family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (ip_addr->family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
ret = nla_put (msg, IFA_ADDRESS, family_size, &ip_addr->addr);
|
||||
if (ip_addr->has_local) {
|
||||
ret |= nla_put (msg, IFA_LOCAL, family_size, &ip_addr->local_addr);
|
||||
}
|
||||
if (ip_addr->has_brd) {
|
||||
ret |= nla_put (msg, IFA_LOCAL, family_size, &ip_addr->brd_addr);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
|
|
Loading…
Reference in New Issue