From fstd.lkml at gmail.com Mon Jul 20 19:29:13 2015 From: fstd.lkml at gmail.com (Timo Buhrmester) Date: Mon, 20 Jul 2015 20:29:13 +0200 Subject: [Iftop-users] (patch) iftop may ignore IPv6 traffic Message-ID: <20150720182913.GA25766@frozen.localdomain> I've been running iftop on my home gateway (NetBSD/i386) for a while, and recently realized that it completely ignores the IPv6 traffic going through. The problem is that `handle_ip_packet` ends up throwing away the IPv6 packets when it can't figure out the direction of a packet. Here's what's going on, we're in `handle_ip_packet` and have an IPv6 packet pointed to by `iptr`: | if(hw_dir == 1) { Nope, hardware doesn't tell the direction | } else if(hw_dir == 0) { Nope, see above. | } else if((IP_V(iptr) == 4) && have_ip_addr && ip_addr_match(iptr->ip_src)) { Nope, this isn't IPv4 | } else if((IP_V(iptr) == 4) && have_ip_addr && ip_addr_match(iptr->ip_dst)) { Nope, see above. | } else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_src)) { Nope, this is IPv6, but `have_ip6_addr` is zero -- we couldn't get an ipv6 interface address because get_addrs_ioctl() is IPv4-specific. getifaddrs() *is* available on NetBSD, so that could be used. But I believe this is unrelated to the problem I am reporting, because on a router, even if we knew our interface address, the traffic going through would usually not carry our interface address. | } else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_dst)) { Nope, see above. | } else if (IP_V(iptr) == 4 && IN_MULTICAST(iptr->ip_dst.s_addr)) { Nope, this isn't IPv4 | } else if (IP_V(iptr) == 6 && IN6_IS_ADDR_MULTICAST(&ip6tr->ip6_dst)) { Nope, this isn't multicast either | } else if (options.promiscuous_but_choosy) { Nope, not set | } else if((IP_V(iptr) == 4) && (iptr->ip_src.s_addr < iptr->ip_dst.s_addr)) { Nope, this isn't IPv4 | } else if(IP_V(iptr) == 4) { Nope, this isn't IPv4 | } else | return; The IPv6 packet is thus discarded here and is never shown or accounted for. Now, all the last `else if` branch in the above list does is: | assign_addr_pair(&ap, iptr, 0); | direction = 0; which on the first glance should work with IPv6 as well. With the below patch, my IPv6 traffic is now showing. Best regards, Timo Buhrmester --- iftop.c.orig 2015-07-20 19:53:07.000000000 +0200 +++ iftop.c 2015-07-20 19:52:35.000000000 +0200 @@ -327,13 +327,10 @@ assign_addr_pair(&ap, iptr, 1); direction = 0; } - else if(IP_V(iptr) == 4) { + else { /* IPv4 or IPv6 */ assign_addr_pair(&ap, iptr, 0); direction = 0; } - /* Drop other uncertain packages. */ - else - return; } if(IP_V(iptr) == 4 && options.netfilter != 0) {