X-Git-Url: http://git.tdb.fi/?p=netvis.git;a=blobdiff_plain;f=source%2Fnetvis.cpp;h=0e2378fd689ac6ee9efb96a6d77a0ff9af10efc9;hp=a8f6209142b2e12505e8017613bf5385c2d88d49;hb=e4b57e21ec2bc7f99c182eea23ecec297e111799;hpb=c1ea3cf06729622e2287e1604b1847d14fd2089c diff --git a/source/netvis.cpp b/source/netvis.cpp index a8f6209..0e2378f 100644 --- a/source/netvis.cpp +++ b/source/netvis.cpp @@ -46,7 +46,11 @@ NetVis::NetVis(int argc, char **argv): throw usage_error("No interface given"); iface = argv[1]; - char err[1024]; + char err[PCAP_ERRBUF_SIZE]; + pcap_if_t *devs; + if(pcap_findalldevs(&devs, err)==-1) + throw runtime_error(err); + pcap = pcap_open_live(iface.c_str(), 128, true, 0, err); if(!pcap) throw runtime_error(err); @@ -54,10 +58,29 @@ NetVis::NetVis(int argc, char **argv): if(pcap_setnonblock(pcap, true, err)==-1) throw runtime_error(err); - unsigned local_addr, local_mask; - pcap_lookupnet(iface.c_str(), &local_addr, &local_mask, err); - localnet = Address(ntohl(local_addr)); - localnet.set_mask(Address(ntohl(local_mask))); + for(pcap_if_t *d=devs; d; d=d->next) + if(iface==d->name) + { + for(pcap_addr_t *a=d->addresses; a; a=a->next) + { + if(a->addr->sa_family==AF_INET) + { + Address addr(ntohl(reinterpret_cast(a->addr)->sin_addr.s_addr)); + if(a->netmask) + addr.set_mask(Address(ntohl(reinterpret_cast(a->netmask)->sin_addr.s_addr))); + localnets.push_back(addr); + } + else if(a->addr->sa_family==AF_INET6) + { + Address addr(reinterpret_cast(a->addr)->sin6_addr); + if(a->netmask) + addr.set_mask(Address(reinterpret_cast(a->netmask)->sin6_addr)); + localnets.push_back(addr); + } + } + } + + pcap_freealldevs(devs); resolver = new Resolver; @@ -256,8 +279,9 @@ Host &NetVis::get_host(const Address &a) return *i->second; Host *host = new Host(*this, a); - if(localnet.masked_match(a)) - host->set_local(true); + for(list
::const_iterator j=localnets.begin(); j!=localnets.end(); ++j) + if(j->masked_match(a)) + host->set_local(true); resolver->push(host); host->set_position(Vector2(rand()*400.0/RAND_MAX-200.0, rand()*400.0/RAND_MAX-200.0)); for(unsigned j=0; j<100; ++j) @@ -296,6 +320,11 @@ void NetVis::handle_ethernet(CaptureContext &ctx, const ethhdr *eth, unsigned le const iphdr *ip = reinterpret_cast(eth+1); handle_ipv4(ctx, ip, len-sizeof(ethhdr)); } + else if(proto==ETH_P_IPV6) + { + const ip6_hdr *ip6 = reinterpret_cast(eth+1); + handle_ipv6(ctx, ip6, len-sizeof(ethhdr)); + } else IO::print("Unknown protocol in eth: %d\n", proto); } @@ -320,6 +349,25 @@ void NetVis::handle_ipv4(CaptureContext &ctx, const iphdr *ip, unsigned len) IO::print("Unknown protocol in ip: %d\n", ip->protocol); } +void NetVis::handle_ipv6(CaptureContext &ctx, const ip6_hdr *ip6, unsigned len) +{ + ctx.src_host = &get_host(ip6->ip6_src); + if(!IN6_IS_ADDR_MULTICAST(ip6->ip6_dst.s6_addr)) + ctx.dst_host = &get_host(ip6->ip6_dst); + + if(ip6->ip6_nxt==IPPROTO_TCP) + { + const tcphdr *tcp = reinterpret_cast(ip6+1); + handle_tcp(ctx, tcp, len-sizeof(ip6_hdr)); + } + else if(ip6->ip6_nxt==IPPROTO_UDP) + { + const udphdr *udp = reinterpret_cast(ip6+1); + handle_udp(ctx, udp, len-sizeof(ip6_hdr)); + } + else + IO::print("Unknown next header in ip6: %d\n", ip6->ip6_nxt); +} void NetVis::handle_tcp(CaptureContext &ctx, const tcphdr *tcp, unsigned) {