X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fnetvis.cpp;h=3a0f09219449f46dc9bb5d1be56f116cffc0ad0b;hb=2fe5b8243b3a7e1c6251e83a55d29d175b8905e4;hp=711788b86062c6e2d388cd1025cc1d7c350f343e;hpb=229e1d6ab66a9e987ffe3cd4a8de7c7f874f6de1;p=netvis.git diff --git a/source/netvis.cpp b/source/netvis.cpp index 711788b..3a0f092 100644 --- a/source/netvis.cpp +++ b/source/netvis.cpp @@ -1,9 +1,18 @@ +/* $Id$ + +This file is part of NetVis +Copyright @ 2008 Mikko Rasa, Mikkosoft Productions +Distributed unter the GPL +*/ + #include +#include #include #include #include #include #include +#include #include #include #include @@ -11,16 +20,23 @@ #include #include #include +#include #include #include "host.h" #include "netvis.h" #include "packet.h" +#include "resolver.h" using namespace std; using namespace Msp; -NetVis::NetVis(int /*argc*/, char **argv) +NetVis::NetVis(int argc, char **argv): + draw_labels(true), + blend(true), + frames(0) { + if(argc<2) + throw UsageError("No interface given"); iface=argv[1]; } @@ -34,10 +50,16 @@ int NetVis::main() if(pcap_setnonblock(pcap, true, err)==-1) throw Exception(err); + pcap_lookupnet(iface.c_str(), &localnet, &localnet_mask, err); + localnet=ntohl(localnet); + localnet_mask=ntohl(localnet_mask); + dpy=new Graphics::Display; wnd=new Graphics::Window(*dpy, 1024, 768); glc=new Graphics::GLContext(*wnd); wnd->set_title("NetVis"); + wnd->signal_close.connect(sigc::bind(sigc::mem_fun(this, &NetVis::exit), 0)); + wnd->signal_key_press.connect(sigc::mem_fun(this, &NetVis::key_press)); wnd->show(); GL::enable(GL_BLEND); @@ -49,83 +71,201 @@ int NetVis::main() DataFile::load(*font_tex, "dejavu-10.tex"); font->set_texture(*font_tex); + catch_signal(SIGINT); + + resolver=new Resolver; + + //set_loop_mode(TICK_BUSY); + Application::main(); + delete resolver; + + delete font; + delete font_tex; delete glc; delete wnd; delete dpy; + cout<::iterator i=hosts.begin(); i!=hosts.end(); ++i) + delete i->second; + for(map::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end(); ++i) + delete i->second; + for(list::iterator i=packets.begin(); i!=packets.end(); ++i) + delete *i; + return exit_code; } void NetVis::tick() { Msp::Time::TimeStamp t=Msp::Time::now(); - if(!last_tick) - last_tick=t; - Msp::Time::TimeDelta dt=t-last_tick; - last_tick=t; - - dpy->tick(); + Msp::Time::TimeDelta dt; + if(tick_t) + dt=t-tick_t; + tick_t=t; - pcap_dispatch(pcap, -1, &capture_handler, reinterpret_cast(this)); - - glClear(GL_COLOR_BUFFER_BIT); + if(tick_t>fps_t+Msp::Time::sec) + { + fps=frames/((tick_t-fps_t)/Msp::Time::sec); + fps_t=tick_t; + frames=0; + } - GL::matrix_mode(GL::PROJECTION); - GL::load_identity(); - GL::ortho_centered(1024, 768); - GL::matrix_mode(GL::MODELVIEW); - GL::load_identity(); + dpy->tick(); - for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) { - i->second->tick(dt); - i->second->render(); + Debug::ProfilingScope s(profiler, "capture"); + while(pcap_dispatch(pcap, -1, &capture_handler, reinterpret_cast(this))>0); } - for(list::iterator i=packets.begin(); i!=packets.end();) + { - (*i)->tick(dt); - (*i)->render(); - if((*i)->get_stale()) + Debug::ProfilingScope s(profiler, "tick"); + + resolver->tick(); + + float min_activity=1e7f; + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) + { + i->second->tick(dt); + min_activity=min(min_activity, i->second->get_activity()); + } + for(map::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end(); ++i) + i->second->tick(dt); + + for(map::iterator i=disabled_hosts.begin(); i!=disabled_hosts.end();) + { + if(i->second->get_activity()>min_activity) + { + i->second->set_active(true); + hosts.insert(*i); + disabled_hosts.erase(i++); + } + else + ++i; + } + if(hosts.size()>20) + { + list activity; + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) + activity.push_back(i->second->get_activity()); + activity.sort(); + + list::iterator j=activity.begin(); + advance(j, activity.size()-20); + float limit=*j; + + for(map::iterator i=hosts.begin(); i!=hosts.end();) + { + if(i->second->get_activity()second->set_active(false); + disabled_hosts.insert(*i); + hosts.erase(i++); + } + else + ++i; + } + } + + for(list::iterator i=packets.begin(); i!=packets.end();) { - delete *i; - i=packets.erase(i); + (*i)->tick(dt); + if((*i)->get_stale()) + { + delete *i; + i=packets.erase(i); + } + else + ++i; } - else - ++i; } - GL::translate(-500, 360, 0); - for(map::iterator i=port_colors.begin(); i!=port_colors.end(); ++i) { - GL::Color &color=i->second; + Debug::ProfilingScope s(profiler, "render"); + glClear(GL_COLOR_BUFFER_BIT); - GL::push_matrix(); + GL::matrix_mode(GL::PROJECTION); + GL::load_identity(); + GL::ortho_centered(1024, 768); + GL::matrix_mode(GL::MODELVIEW); + GL::load_identity(); - GL::Immediate imm((GL::COLOR4_UBYTE,GL::VERTEX2)); - imm.begin(GL::QUADS); - imm.color(color.r, color.g, color.b, color.a); - for(float x=0; x<0.5; x+=0.2) + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) + i->second->render(); + if(draw_labels) { - imm.vertex(x+0, 0); - imm.vertex(x+10, 0); - imm.vertex(x+10, 10); - imm.vertex(x+0, 10); + glColor4f(1.0, 1.0, 1.0, 1.0); + for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) + i->second->render_label(); + GL::Texture::unbind(); } + GL::Immediate imm((GL::COLOR4_UBYTE, GL::VERTEX2)); + imm.begin(GL::QUADS); + for(list::iterator i=packets.begin(); i!=packets.end(); ++i) + (*i)->render(imm); imm.end(); - GL::translate(15, 1, 0); + GL::push_matrix(); + GL::translate(-500, 360, 0); + unsigned n=0; + for(map::iterator i=port_colors.begin(); (i!=port_colors.end() && n<20); ++i, ++n) + { + GL::Color &color=i->second; + + imm.begin(GL::QUADS); + imm.color(color.r, color.g, color.b, color.a); + for(unsigned x=0; x<=4; x+=2) + { + imm.vertex(x+0, 0); + imm.vertex(x+10, 0); + imm.vertex(x+10, 10); + imm.vertex(x+0, 10); + } + imm.end(); + + GL::translate(0, -12, 0); + } + GL::pop_matrix(); + + GL::push_matrix(); + if(draw_labels) + { + GL::push_matrix(); + GL::translate(-484, 361, 0); + GL::scale_uniform(10); + glColor4f(1.0, 1.0, 1.0, 1.0); + n=0; + for(map::iterator i=port_colors.begin(); (i!=port_colors.end() && n<20); ++i, ++n) + { + font->draw_string(format("%d", i->first)); + + GL::translate(0, -1.2, 0); + } + GL::pop_matrix(); + GL::Texture::unbind(); + } + GL::pop_matrix(); + + GL::push_matrix(); + GL::translate(-500, -360, 0); GL::scale_uniform(10); - glColor4f(1.0, 1.0, 1.0, 1.0); - font->draw_string(format("%d", i->first)); + font->draw_string(format("%d hosts", hosts.size()+disabled_hosts.size())); + GL::translate(0, -1.2, 0); + font->draw_string(format("%.2f fps", fps)); + GL::pop_matrix(); GL::Texture::unbind(); - GL::pop_matrix(); - GL::translate(0, -12, 0); + glc->swap_buffers(); } - glc->swap_buffers(); + ++frames; } Host &NetVis::get_host(unsigned a) @@ -134,8 +274,15 @@ Host &NetVis::get_host(unsigned a) if(i!=hosts.end()) return *i->second; + i=disabled_hosts.find(a); + if(i!=disabled_hosts.end()) + return *i->second; + Host *host=new Host(*this, a); - host->set_position(Vector2(rand()*30.0/RAND_MAX-15.0, rand()*20.0/RAND_MAX-10.0)); + if((a&localnet_mask)==localnet) + 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)); hosts[a]=host; return *host; } @@ -159,6 +306,17 @@ GL::Color &NetVis::get_port_color(unsigned port) return port_colors[port]=color; } +void NetVis::key_press(unsigned key, unsigned, wchar_t) +{ + if(key==46) + draw_labels=!draw_labels; + else if(key==56) + { + blend=!blend; + GL::set(GL_BLEND, blend); + } +} + void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const unsigned char *data) { NetVis *self=reinterpret_cast(user); @@ -168,8 +326,7 @@ void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const uns { const iphdr *ip=reinterpret_cast(eth+1); - //cout<<"IP packet of "<len<<'/'<tot_len)<<" bytes\n"; - + unsigned size=ntohs(ip->tot_len); unsigned port=0; if(ip->protocol==IPPROTO_TCP) { @@ -185,8 +342,23 @@ void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const uns Host *dhost=0; if((ntohl(ip->daddr)&0xFF)!=0xFF) dhost=&self->get_host(ntohl(ip->daddr)); - self->packets.push_back(new Packet(shost, dhost, self->get_port_color(port), ntohs(ip->tot_len))); + + float throttle=shost.send_packet(); + if(throttle<1) + { + self->packets.push_back(new Packet(shost, dhost, self->get_port_color(port), size)); + self->packets.back()->tick(-throttle*Msp::Time::sec); + } + + shost.add_activity(size); + if(dhost) + dhost->add_activity(size); } } +void NetVis::sighandler(int) +{ + exit(0); +} + Application::RegApp NetVis::reg;