X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fnetvis.cpp;h=0e2378fd689ac6ee9efb96a6d77a0ff9af10efc9;hb=e4b57e21ec2bc7f99c182eea23ecec297e111799;hp=22231b150a4b62356c312d403534fed34ff6f2ff;hpb=597a794cd648dd7b4c9d442fdc39f5961a38aba0;p=netvis.git diff --git a/source/netvis.cpp b/source/netvis.cpp index 22231b1..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,9 +58,29 @@ NetVis::NetVis(int argc, char **argv): if(pcap_setnonblock(pcap, true, err)==-1) throw runtime_error(err); - pcap_lookupnet(iface.c_str(), &localnet, &localnet_mask, err); - localnet = ntohl(localnet); - localnet_mask = ntohl(localnet_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; @@ -84,9 +108,9 @@ NetVis::~NetVis() delete wnd; pcap_close(pcap); - for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) delete i->second; - for(map::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end(); ++i) + for(map::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end(); ++i) delete i->second; for(map::iterator i=ports.begin(); i!=ports.end(); ++i) delete i->second; @@ -118,13 +142,13 @@ void NetVis::tick() float min_activity = numeric_limits::max(); - for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) { i->second->tick(dt); min_activity = min(min_activity, i->second->get_activity()); } float del_limit = pow(10, 6-0.1*static_cast(max_hosts-hosts.size()-disabled_hosts.size())); - for(map::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end();) + for(map::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end();) { i->second->tick(dt); @@ -149,7 +173,7 @@ void NetVis::tick() if(hosts.size()>max_visible_hosts) { list activity; - for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) activity.push_back(i->second->get_activity()); activity.sort(); @@ -157,7 +181,7 @@ void NetVis::tick() advance(j, activity.size()-max_visible_hosts); float limit = *j; - for(map::iterator i=hosts.begin(); i!=hosts.end();) + for(map::iterator i=hosts.begin(); i!=hosts.end();) { if(i->second->get_activity()::iterator i=hosts.begin(); i!=hosts.end(); ++i) + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) i->second->render(); { GL::Immediate imm((GL::COLOR4_UBYTE, GL::VERTEX2)); @@ -244,9 +268,9 @@ void NetVis::render() history->render(); } -Host &NetVis::get_host(unsigned a) +Host &NetVis::get_host(const Address &a) { - map::iterator i = hosts.find(a); + map::iterator i = hosts.find(a); if(i!=hosts.end()) return *i->second; @@ -255,8 +279,9 @@ Host &NetVis::get_host(unsigned a) return *i->second; Host *host = new Host(*this, a); - if((a&localnet_mask)==localnet) - 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) @@ -295,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); } @@ -319,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) {