support for multiple IP addresses on one device with getifaddrs
This commit is contained in:
37
nethogs.h
37
nethogs.h
@@ -90,42 +90,13 @@ public:
|
|||||||
inet_ntop (AF_INET, &m_addr, string, 15);
|
inet_ntop (AF_INET, &m_addr, string, 15);
|
||||||
}
|
}
|
||||||
/* this constructor takes an char address[33] */
|
/* 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;
|
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;
|
sa_family = AF_INET6;
|
||||||
|
string = (char*) malloc (64);
|
||||||
|
inet_ntop (AF_INET6, &m_addr, string, 63);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains (const in_addr_t & n_addr);
|
bool contains (const in_addr_t & n_addr);
|
||||||
|
|||||||
72
packet.cpp
72
packet.cpp
@@ -36,79 +36,51 @@
|
|||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <cstdio>
|
#include <ifaddrs.h>
|
||||||
// #include "inet6.c"
|
// #include "inet6.c"
|
||||||
|
|
||||||
local_addr * local_addrs = NULL;
|
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
|
* getLocal
|
||||||
* device: This should be device explicit (e.g. eth0:1)
|
* 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.
|
* local_addrs-list.
|
||||||
*/
|
*/
|
||||||
void getLocal (const char *device, bool tracemode)
|
void getLocal (const char *device, bool tracemode)
|
||||||
{
|
{
|
||||||
/* get local IPv4 addresses */
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
int sock;
|
if(getifaddrs(&ifaddr) == -1) {
|
||||||
struct ifreq iFreq;
|
forceExit(false, "getifaddrs failed while establishing local IP.");
|
||||||
struct sockaddr_in *saddr;
|
}
|
||||||
|
|
||||||
if((sock=socket(AF_INET, SOCK_DGRAM, 0))<0)
|
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||||
forceExit(false, "creating socket failed while establishing local IP - are you root?");
|
if(ifa->ifa_addr == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
strcpy(iFreq.ifr_name, device);
|
if(strcmp(ifa->ifa_name, device) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(ioctl(sock, SIOCGIFADDR, &iFreq)<0)
|
int family = ifa->ifa_addr->sa_family;
|
||||||
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;
|
if(family == AF_INET){
|
||||||
local_addrs = new local_addr (saddr->sin_addr.s_addr, local_addrs);
|
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) {
|
if (tracemode || DEBUG) {
|
||||||
printf ("Adding local address: %s\n", inet_ntoa(saddr->sin_addr));
|
printf("Adding local address: %s\n", inet_ntoa(addr->sin_addr));
|
||||||
}
|
}
|
||||||
|
}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);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
if (strcmp (stripspaces(ifname), device) == 0)
|
|
||||||
{
|
|
||||||
local_addrs = new local_addr (address, local_addrs);
|
|
||||||
if (tracemode || DEBUG) {
|
if (tracemode || DEBUG) {
|
||||||
printf ("Adding local address: %s\n", address);
|
char host[512];
|
||||||
|
printf("Adding local address: %s\n",
|
||||||
|
inet_ntop(AF_INET6, &addr->sin6_addr, host, sizeof(struct in6_addr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if DEBUG
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Address skipped for interface " << ifname << std::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} while (!feof(ifinfo));
|
|
||||||
fclose(ifinfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user