From b0033564eb0d50289b9f3248de4795e2dec6682e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E4=BA=91?= Date: Mon, 29 Feb 2016 12:06:48 +0800 Subject: [PATCH 1/2] support for multiple IP addresses on one device with getifaddrs --- nethogs.h | 37 +++-------------------- packet.cpp | 86 ++++++++++++++++++------------------------------------ 2 files changed, 33 insertions(+), 90 deletions(-) diff --git a/nethogs.h b/nethogs.h index 5bbcfec..6de37fe 100644 --- a/nethogs.h +++ b/nethogs.h @@ -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); diff --git a/packet.cpp b/packet.cpp index ab6d894..fee8a7f 100644 --- a/packet.cpp +++ b/packet.cpp @@ -36,79 +36,51 @@ #include #include #include -#include +#include // #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(struct in6_addr))); + } + } } } From 7855236c31b8f6e61bd4e8e527333babe513b5ac Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Mon, 29 Feb 2016 23:49:39 +0100 Subject: [PATCH 2/2] Correctly print ipv6 addresses --- packet.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packet.cpp b/packet.cpp index fee8a7f..fc69a9c 100644 --- a/packet.cpp +++ b/packet.cpp @@ -1,4 +1,4 @@ -/* +/* * packet.cpp * * Copyright (c) 2004-2006,2008 Arnout Engelen @@ -74,11 +74,10 @@ void getLocal (const char *device, bool tracemode) }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(struct in6_addr))); + inet_ntop(AF_INET6, &addr->sin6_addr, host, sizeof(host))); } } } @@ -277,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)); }