fixed netlink socket receiver code

implemented interface enumeration code with netlink: no getifaddrs reqired anymore
This commit is contained in:
Martin Willi
2007-03-03 14:56:24 +00:00
parent 285bbed595
commit 373b8a607f
8 changed files with 190 additions and 289 deletions
-185
View File
@@ -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;