X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fnetvis.cpp;h=771af7f5db93272ee673faffc481810f81ee1164;hb=HEAD;hp=a8f6209142b2e12505e8017613bf5385c2d88d49;hpb=c1ea3cf06729622e2287e1604b1847d14fd2089c;p=netvis.git diff --git a/source/netvis.cpp b/source/netvis.cpp index a8f6209..771af7f 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) @@ -272,6 +296,13 @@ Port &NetVis::get_port(unsigned number) if(i!=ports.end()) return *i->second; Port *port = new Port(*this, number); + if(number>=0x10000) + { + if((number&0xFF)==IPPROTO_ICMP) + port->set_name("icmp"); + else if((number&0xFF)==IPPROTO_ICMPV6) + port->set_name("icmp6"); + } ports[number] = port; return *port; } @@ -296,6 +327,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); } @@ -316,10 +352,39 @@ void NetVis::handle_ipv4(CaptureContext &ctx, const iphdr *ip, unsigned len) const udphdr *udp = reinterpret_cast(ip+1); handle_udp(ctx, udp, len-sizeof(iphdr)); } + else if(ip->protocol==IPPROTO_ICMP) + { + const icmphdr *icmp = reinterpret_cast(ip+1); + handle_icmp(ctx, icmp, len-sizeof(iphdr)); + } else 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 if(ip6->ip6_nxt==IPPROTO_ICMPV6) + { + const icmp6_hdr *icmp6 = reinterpret_cast(ip6+1); + handle_icmp6(ctx, icmp6, 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) { @@ -335,6 +400,20 @@ void NetVis::handle_udp(CaptureContext &ctx, const udphdr *udp, unsigned) handle_packet(ctx); } +void NetVis::handle_icmp(CaptureContext &ctx, const icmphdr *, unsigned) +{ + ctx.src_port = &get_port(0x10000|IPPROTO_ICMP); + ctx.dst_port = ctx.src_port; + handle_packet(ctx); +} + +void NetVis::handle_icmp6(CaptureContext &ctx, const icmp6_hdr *, unsigned) +{ + ctx.src_port = &get_port(0x10000|IPPROTO_ICMPV6); + ctx.dst_port = ctx.src_port; + handle_packet(ctx); +} + void NetVis::handle_packet(CaptureContext &ctx) { Port *port = 0;