fixed netlink socket receiver code
implemented interface enumeration code with netlink: no getifaddrs reqired anymore
This commit is contained in:
@@ -435,189 +435,6 @@ status_t sender(private_socket_t *this, packet_t *packet)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements socket_t.is_local_address
|
||||
*/
|
||||
static bool is_local_address(private_socket_t *this, host_t *host, char **dev)
|
||||
{
|
||||
#ifdef HAVE_GETIFADDRS
|
||||
struct ifaddrs *list;
|
||||
struct ifaddrs *cur;
|
||||
bool found = FALSE;
|
||||
|
||||
if (getifaddrs(&list) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (cur = list; cur != NULL; cur = cur->ifa_next)
|
||||
{
|
||||
if (!(cur->ifa_flags & IFF_UP))
|
||||
{
|
||||
/* ignore interface which are down */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cur->ifa_addr == NULL ||
|
||||
cur->ifa_addr->sa_family != host->get_family(host))
|
||||
{
|
||||
/* no match in family */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (cur->ifa_addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *listed, *requested;
|
||||
listed = (struct sockaddr_in*)cur->ifa_addr;
|
||||
requested = (struct sockaddr_in*)host->get_sockaddr(host);
|
||||
if (listed->sin_addr.s_addr == requested->sin_addr.s_addr)
|
||||
{
|
||||
found = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *listed, *requested;
|
||||
listed = (struct sockaddr_in6*)cur->ifa_addr;
|
||||
requested = (struct sockaddr_in6*)host->get_sockaddr(host);
|
||||
if (memcmp(&listed->sin6_addr, &requested->sin6_addr,
|
||||
sizeof(listed->sin6_addr)) == 0)
|
||||
{
|
||||
found = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (dev && cur->ifa_name)
|
||||
{
|
||||
/* return interface name, if requested */
|
||||
*dev = strdup(cur->ifa_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeifaddrs(list);
|
||||
return found;
|
||||
#else /* !HAVE_GETIFADDRS */
|
||||
|
||||
int skt = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
struct ifconf conf;
|
||||
struct ifreq reqs[16];
|
||||
|
||||
conf.ifc_len = sizeof(reqs);
|
||||
conf.ifc_req = reqs;
|
||||
|
||||
if (ioctl(skt, SIOCGIFCONF, &conf) == -1)
|
||||
{
|
||||
DBG1(DBG_NET, "checking address using ioctl() failed: %m");
|
||||
close(skt);
|
||||
return FALSE;
|
||||
}
|
||||
close(skt);
|
||||
|
||||
while (conf.ifc_len >= sizeof(struct ifreq))
|
||||
{
|
||||
/* only IPv4 supported yet */
|
||||
if (conf.ifc_req->ifr_addr.sa_family == AF_INET &&
|
||||
host->get_family(host) == AF_INET)
|
||||
{
|
||||
struct sockaddr_in *listed, *requested;
|
||||
listed = (struct sockaddr_in*)&conf.ifc_req->ifr_addr;
|
||||
requested = (struct sockaddr_in*)host->get_sockaddr(host);
|
||||
if (listed->sin_addr.s_addr == requested->sin_addr.s_addr)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
conf.ifc_len -= sizeof(struct ifreq);
|
||||
conf.ifc_req++;
|
||||
}
|
||||
return FALSE;
|
||||
#endif /* HAVE_GETIFADDRS */
|
||||
}
|
||||
|
||||
/**
|
||||
* implements socket_t.create_local_address_list
|
||||
*/
|
||||
static linked_list_t* create_local_address_list(private_socket_t *this)
|
||||
{
|
||||
#ifdef HAVE_GETIFADDRS
|
||||
struct ifaddrs *list;
|
||||
struct ifaddrs *cur;
|
||||
host_t *host;
|
||||
linked_list_t *result = linked_list_create();
|
||||
|
||||
if (getifaddrs(&list) < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
for (cur = list; cur != NULL; cur = cur->ifa_next)
|
||||
{
|
||||
if (!(cur->ifa_flags & IFF_UP))
|
||||
{
|
||||
/* ignore interface which are down */
|
||||
continue;
|
||||
}
|
||||
|
||||
host = host_create_from_sockaddr(cur->ifa_addr);
|
||||
if (host)
|
||||
{
|
||||
/* we use always the IKEv2 port. This is relevant for
|
||||
* natd payload hashing. */
|
||||
host->set_port(host, this->port);
|
||||
result->insert_last(result, host);
|
||||
}
|
||||
}
|
||||
freeifaddrs(list);
|
||||
return result;
|
||||
#else /* !HAVE_GETIFADDRS */
|
||||
int skt = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
struct ifconf conf;
|
||||
struct ifreq reqs[16];
|
||||
linked_list_t *result = linked_list_create();
|
||||
host_t *host;
|
||||
|
||||
conf.ifc_len = sizeof(reqs);
|
||||
conf.ifc_req = reqs;
|
||||
|
||||
if (ioctl(skt, SIOCGIFCONF, &conf) == -1)
|
||||
{
|
||||
DBG1(DBG_NET, "getting address list using ioctl() failed: %m");
|
||||
close(skt);
|
||||
return FALSE;
|
||||
}
|
||||
close(skt);
|
||||
|
||||
while (conf.ifc_len >= sizeof(struct ifreq))
|
||||
{
|
||||
/* only IPv4 supported yet */
|
||||
if (conf.ifc_req->ifr_addr.sa_family == AF_INET)
|
||||
{
|
||||
host = host_create_from_sockaddr(&conf.ifc_req->ifr_addr);
|
||||
if (host)
|
||||
{
|
||||
/* we use always the IKEv2 port. This is relevant for
|
||||
* natd payload hashing. */
|
||||
host->set_port(host, this->port);
|
||||
result->insert_last(result, host);
|
||||
}
|
||||
}
|
||||
conf.ifc_len -= sizeof(struct ifreq);
|
||||
conf.ifc_req++;
|
||||
}
|
||||
return result;
|
||||
#endif /* HAVE_GETIFADDRS */
|
||||
}
|
||||
|
||||
/**
|
||||
* open a socket to send packets
|
||||
*/
|
||||
@@ -871,8 +688,6 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
|
||||
/* public functions */
|
||||
this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
|
||||
this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
|
||||
this->public.is_local_address = (bool(*)(socket_t*, host_t*,char**))is_local_address;
|
||||
this->public.create_local_address_list = (linked_list_t*(*)(socket_t*))create_local_address_list;
|
||||
this->public.destroy = (void(*)(socket_t*)) destroy;
|
||||
|
||||
this->port = port;
|
||||
|
||||
Reference in New Issue
Block a user