Merge pull request #35 from raboof/multiple_addresses

support for multiple IP addresses on one device with getifaddrs
This commit is contained in:
Arnout Engelen
2016-03-01 10:02:40 +01:00
2 changed files with 34 additions and 92 deletions

View File

@@ -90,42 +90,13 @@ public:
inet_ntop (AF_INET, &m_addr, string, 15);
}
/* this constructor takes an char address[33] */
local_addr (char m_address [33], local_addr * m_next = NULL)
local_addr (struct in6_addr *m_addr, local_addr * m_next = NULL)
{
addr6 = *m_addr;
next = m_next;
char address [40];
address[0] = m_address[0]; address[1] = m_address[1];
address[2] = m_address[2]; address[3] = m_address[3];
address[4] = ':';
address[5] = m_address[4]; address[6] = m_address[5];
address[7] = m_address[6]; address[8] = m_address[7];
address[9] = ':';
address[10] = m_address[8]; address[11] = m_address[9];
address[12] = m_address[10]; address[13] = m_address[11];
address[14] = ':';
address[15] = m_address[12]; address[16] = m_address[13];
address[17] = m_address[14]; address[18] = m_address[15];
address[19] = ':';
address[20] = m_address[16]; address[21] = m_address[17];
address[22] = m_address[18]; address[23] = m_address[19];
address[24] = ':';
address[25] = m_address[20]; address[26] = m_address[21];
address[27] = m_address[22]; address[28] = m_address[23];
address[29] = ':';
address[30] = m_address[24]; address[31] = m_address[25];
address[32] = m_address[26]; address[33] = m_address[27];
address[34] = ':';
address[35] = m_address[28]; address[36] = m_address[29];
address[37] = m_address[30]; address[38] = m_address[31];
address[39] = 0;
string = strdup(address);
//if (DEBUG)
// std::cout << "Converting address " << address << std::endl;
int result = inet_pton (AF_INET6, address, &addr6);
assert (result > 0);
sa_family = AF_INET6;
string = (char*) malloc (64);
inet_ntop (AF_INET6, &m_addr, string, 63);
}
bool contains (const in_addr_t & n_addr);

View File

@@ -1,4 +1,4 @@
/*
/*
* packet.cpp
*
* Copyright (c) 2004-2006,2008 Arnout Engelen
@@ -36,79 +36,50 @@
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <sys/ioctl.h>
#include <cstdio>
#include <ifaddrs.h>
// #include "inet6.c"
local_addr * local_addrs = NULL;
/* moves the pointer right until a non-space is seen */
char * stripspaces (char * input)
{
char * retval = input;
while (*retval == ' ')
retval++;
return retval;
}
/*
* getLocal
* device: This should be device explicit (e.g. eth0:1)
*
* uses ioctl to get address of this device, and adds it to the
* uses getifaddrs to get addresses of this device, and adds them to the
* local_addrs-list.
*/
void getLocal (const char *device, bool tracemode)
{
/* get local IPv4 addresses */
int sock;
struct ifreq iFreq;
struct sockaddr_in *saddr;
if((sock=socket(AF_INET, SOCK_DGRAM, 0))<0)
forceExit(false, "creating socket failed while establishing local IP - are you root?");
strcpy(iFreq.ifr_name, device);
if(ioctl(sock, SIOCGIFADDR, &iFreq)<0)
forceExit(false, "ioctl failed while establishing local IP for selected device %s. You may specify the device on the command line.", device);
saddr=(struct sockaddr_in*)&iFreq.ifr_addr;
local_addrs = new local_addr (saddr->sin_addr.s_addr, local_addrs);
if (tracemode || DEBUG) {
printf ("Adding local address: %s\n", inet_ntoa(saddr->sin_addr));
struct ifaddrs *ifaddr, *ifa;
if(getifaddrs(&ifaddr) == -1) {
forceExit(false, "getifaddrs failed while establishing local IP.");
}
/* also get local IPv6 addresses */
FILE * ifinfo = fopen ("/proc/net/if_inet6", "r");
char buffer [500];
if (ifinfo)
{
do
{
if (fgets(buffer, sizeof(buffer), ifinfo))
{
char address [33];
char ifname [9];
int n_results = sscanf (buffer, "%32[0-9a-f] %*d %*d %*d %*d %8[0-9a-zA-Z]", address, ifname);
assert (n_results = 2);
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if(ifa->ifa_addr == NULL)
continue;
if (strcmp (stripspaces(ifname), device) == 0)
{
local_addrs = new local_addr (address, local_addrs);
if (tracemode || DEBUG) {
printf ("Adding local address: %s\n", address);
}
}
#if DEBUG
else
{
std::cerr << "Address skipped for interface " << ifname << std::endl;
}
#endif
if(strcmp(ifa->ifa_name, device) != 0)
continue;
int family = ifa->ifa_addr->sa_family;
if(family == AF_INET){
struct sockaddr_in *addr = (struct sockaddr_in*)ifa->ifa_addr;
local_addrs = new local_addr(addr->sin_addr.s_addr, local_addrs);
if (tracemode || DEBUG) {
printf("Adding local address: %s\n", inet_ntoa(addr->sin_addr));
}
} while (!feof(ifinfo));
fclose(ifinfo);
}else if(family == AF_INET6){
struct sockaddr_in6 *addr = (struct sockaddr_in6*)ifa->ifa_addr;
local_addrs = new local_addr(&addr->sin6_addr, local_addrs);
if (tracemode || DEBUG) {
char host[512];
printf("Adding local address: %s\n",
inet_ntop(AF_INET6, &addr->sin6_addr, host, sizeof(host)));
}
}
}
}
@@ -305,5 +276,5 @@ bool Packet::match (Packet * other)
bool Packet::matchSource (Packet * other)
{
return (sport == other->sport) && (sameinaddr(sip, other->sip));
return (sport == other->sport) && (sameinaddr(sip, other->sip));
}