From: Mikko Rasa Date: Mon, 16 Jun 2014 17:05:36 +0000 (+0300) Subject: Handle addresses in a more generic way X-Git-Url: http://git.tdb.fi/?p=netvis.git;a=commitdiff_plain;h=c1ea3cf06729622e2287e1604b1847d14fd2089c Handle addresses in a more generic way --- diff --git a/source/address.cpp b/source/address.cpp new file mode 100644 index 0000000..3a49971 --- /dev/null +++ b/source/address.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include "address.h" + +using namespace std; + +Address::Address(): + type(0), + length(0), + mask_bits(0) +{ } + +Address::Address(uint32_t a): + type(ETH_P_IP), + length(4), + mask_bits(32) +{ + for(unsigned i=0; i<4; ++i) + data[i] = a>>(24-i*8); +} + +Address::Address(unsigned short t, const unsigned char *d, unsigned char l): + type(t), + length(l) +{ + copy(d, d+l, data); +} + +void Address::set_mask(const Address &mask) +{ + if(mask.length!=length) + throw invalid_argument("Address::set_mask"); + + mask_bits = 0; + for(unsigned i=0; (i>=1) + --mask_bits; + break; + } + } +} + +string Address::str() const +{ + if(type==ETH_P_IP) + { + char buf[INET_ADDRSTRLEN]; + return inet_ntop(AF_INET, data, buf, INET_ADDRSTRLEN); + } + else + return ""; +} + +unsigned Address::common_prefix_length(const Address &other) const +{ + if(length!=other.length) + return 0; + + unsigned prefix = 0; + for(unsigned i=0; i>=1) + --prefix; + break; + } + } + + return prefix; +} + +bool Address::masked_match(const Address &other) const +{ + unsigned prefix = common_prefix_length(other); + unsigned mask = min(mask_bits, other.mask_bits); + return prefix>=mask; +} + +void Address::to_sockaddr(sockaddr_storage &sa) const +{ + if(type==ETH_P_IP) + { + sockaddr_in &sa_in = reinterpret_cast(sa); + sa_in.sin_family = AF_INET; + sa_in.sin_port = 0; + sa_in.sin_addr.s_addr = *(uint32_t *)data; + } + else + throw runtime_error("Unknown type"); +} + +bool Address::operator<(const Address &other) const +{ + if(length!=other.length) + return length +#include + +struct Address +{ + unsigned short type; + unsigned char length; + unsigned char mask_bits; + unsigned char data[16]; + + Address(); + Address(uint32_t); + Address(unsigned short, const unsigned char *, unsigned char); + + void set_mask(const Address &); + std::string str() const; + unsigned common_prefix_length(const Address &) const; + bool masked_match(const Address &) const; + void to_sockaddr(sockaddr_storage &) const; + + bool operator<(const Address &) const; +}; + +#endif diff --git a/source/host.cpp b/source/host.cpp index afa61b7..93c537e 100644 --- a/source/host.cpp +++ b/source/host.cpp @@ -19,17 +19,15 @@ Distributed unter the GPL using namespace std; using namespace Msp; -Host::Host(NetVis &nv, unsigned a): +Host::Host(NetVis &nv, const Address &a): netvis(nv), addr(a), + name(addr.str()), + short_name(name), local(false), active(true), throttle(0) { - in_addr ina; - ina.s_addr = htonl(addr); - name = inet_ntoa(ina); - short_name = name; } void Host::set_name(const string &n) @@ -99,11 +97,11 @@ void Host::tick(const Msp::Time::TimeDelta &td) if(!active) return; - const map &hosts = netvis.get_hosts(); + const map &hosts = netvis.get_hosts(); float center_force = (local ? 0.5 : 0.1); float fx = -pos.x*center_force; float fy = -pos.y*center_force; - for(map::const_iterator i=hosts.begin(); i!=hosts.end(); ++i) + for(map::const_iterator i=hosts.begin(); i!=hosts.end(); ++i) { if(i->second!=this) { @@ -113,10 +111,7 @@ void Host::tick(const Msp::Time::TimeDelta &td) float d2 = dx*dx+dy*dy; float d = sqrt(d2); - unsigned other_addr = i->second->get_address(); - unsigned matching_bits = 0; - for(unsigned j=32; (j-- && !((addr^other_addr)>>j));) - ++matching_bits; + unsigned matching_bits = addr.common_prefix_length(i->second->get_address()); float optimal_dist = 100+(24-min(matching_bits, 24U))*12; float f = 5000.0*(1.0/optimal_dist-1.0/d); diff --git a/source/host.h b/source/host.h index c41610f..928d7aa 100644 --- a/source/host.h +++ b/source/host.h @@ -12,6 +12,7 @@ Distributed unter the GPL #include #include #include "activity.h" +#include "address.h" #include "vector2.h" class NetVis; @@ -20,7 +21,7 @@ class Host { private: NetVis &netvis; - unsigned addr; + Address addr; std::string name; std::string short_name; bool local; @@ -30,8 +31,9 @@ private: float throttle; public: - Host(NetVis &, unsigned); - unsigned get_address() const { return addr; } + Host(NetVis &, const Address &); + + const Address &get_address() const { return addr; } void set_name(const std::string &); const std::string &get_name() const { return name; } void set_local(bool); diff --git a/source/netvis.cpp b/source/netvis.cpp index 22231b1..a8f6209 100644 --- a/source/netvis.cpp +++ b/source/netvis.cpp @@ -54,9 +54,10 @@ 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); + 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))); resolver = new Resolver; @@ -84,9 +85,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 +119,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 +150,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 +158,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 +245,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,7 +256,7 @@ Host &NetVis::get_host(unsigned a) return *i->second; Host *host = new Host(*this, a); - if((a&localnet_mask)==localnet) + if(localnet.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)); diff --git a/source/netvis.h b/source/netvis.h index 68eed05..a59b650 100644 --- a/source/netvis.h +++ b/source/netvis.h @@ -23,6 +23,7 @@ Distributed unter the GPL #include #include #include +#include "address.h" class History; class Host; @@ -48,16 +49,15 @@ private: std::string iface; pcap_t *pcap; Resolver *resolver; - unsigned localnet; - unsigned localnet_mask; + Address localnet; Msp::Graphics::SimpleGLWindow *wnd; Msp::GL::Font *font; unsigned max_hosts; unsigned max_visible_hosts; - std::map hosts; - std::map disabled_hosts; + std::map hosts; + std::map disabled_hosts; std::list packets; std::map ports; History *history; @@ -72,12 +72,12 @@ public: ~NetVis(); const Msp::GL::Font &get_font() const { return *font; } - const std::map &get_hosts() const { return hosts; } + const std::map &get_hosts() const { return hosts; } const std::map &get_ports() const { return ports; } private: virtual void tick(); void render(); - Host &get_host(unsigned); + Host &get_host(const Address &); Msp::GL::Color generate_color(bool) const; Port &get_port(unsigned); void create_history_texture(); diff --git a/source/resolver.cpp b/source/resolver.cpp index b34fc65..196a8b2 100644 --- a/source/resolver.cpp +++ b/source/resolver.cpp @@ -74,15 +74,14 @@ void Resolver::main() { while(!done) { - sockaddr_in addr; - addr.sin_family = AF_INET; + sockaddr_storage addr; { MutexLock l_(mutex); if(in_queue.empty()) break; current = in_queue.front(); in_queue.erase(in_queue.begin()); - addr.sin_addr.s_addr = htonl(current->get_address()); + current->get_address().to_sockaddr(addr); } char buf[128];