From 398c5e3e6e03080b6b057fd56858ab04694969ed Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 25 Oct 2009 11:55:01 +0000 Subject: [PATCH] Add a traffic history graph Make the resolver thread terminate faster Don't spend too much time generating colors Use netinet/ether.h instead of linux/if_ether.h --- source/history.cpp | 152 ++++++++++++++++++++++++++++++++++++++++++++ source/history.h | 48 ++++++++++++++ source/netvis.cpp | 17 ++++- source/netvis.h | 3 + source/port.cpp | 9 ++- source/resolver.cpp | 4 +- source/ringbuffer.h | 28 ++++++++ 7 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 source/history.cpp create mode 100644 source/history.h create mode 100644 source/ringbuffer.h diff --git a/source/history.cpp b/source/history.cpp new file mode 100644 index 0000000..adcc3ec --- /dev/null +++ b/source/history.cpp @@ -0,0 +1,152 @@ +/* $Id$ + +This file is part of NetVis +Copyright @ 2008 Mikko Rasa, Mikkosoft Productions +Distributed unter the GPL +*/ + +#include +#include +#include +#include +#include +#include +#include "history.h" +#include "netvis.h" + +using namespace std; +using namespace Msp; + +History::History(NetVis &n, unsigned w, unsigned h): + netvis(n), + width(w), + height(h), + buffer(w), + scale(1024), + mesh((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2)) +{ + texture.storage(GL::RGBA, height, width, 0); + texture.set_min_filter(GL::LINEAR); + GL::MeshBuilder bld(mesh); + bld.color(1.0f, 1.0f, 1.0f); + bld.begin(GL::QUADS); + bld.texcoord(0, 1); + bld.vertex(0, 0); + bld.texcoord(0, 0); + bld.vertex(width, 0); + bld.texcoord(1, 0); + bld.vertex(width, height); + bld.texcoord(1, 1); + bld.vertex(0, height); + bld.end(); +} + +void History::activity(unsigned down, unsigned up) +{ + accum.down += down; + accum.up += up; +} + +void History::tick(const Time::TimeStamp &t) +{ + if(t>next_push) + { + buffer.push(accum); + accum = Bandwidth(); + next_push += Time::sec; + if(next_push=scale*1000) + scale *= 1024; + while(m>=scale*5) + scale *= 10; + if(m>scale*2) + scale *= 5; + else if(m>scale) + scale *= 2; + + create_texture(); + } +} + +void History::render() const +{ + texture.bind(); + mesh.draw(); + + char suffix = 'B'; + unsigned value = scale; + if(value>=1024) + { + value /= 1024; + suffix = 'k'; + } + if(value>=1024) + { + value /= 1024; + suffix = 'M'; + } + GL::PushMatrix push_; + GL::translate(width+5, height-10, 0); + GL::scale_uniform(10); + GL::Immediate imm((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2)); + imm.color(1.0f, 1.0f, 1.0f); + netvis.get_font().draw_string(format("%d%c", value, suffix), imm); + GL::translate(0, (height-12)*-0.05, 0); + netvis.get_font().draw_string(format("%g%c", value*0.5, suffix), imm); + GL::translate(0, (height-12)*-0.05, 0); + netvis.get_font().draw_string(format("0%c", suffix), imm); + GL::Texture::unbind(); +} + +void History::create_texture() +{ + vector data(width*height); + for(unsigned y=0; y0) + { + unsigned value = (up+buffer.get(y-1).up*height/scale)/2; + up_min = min(value+1, up_min); + up_max = max(value, up_max); + } + if(y=up_min && x<=up_max) + row[x] = 0xFF8000FF; + else if(x<=down) + row[x] = 0xFF80FF80; + else if(x%25==24 || y%60==0) + row[x] = 0x40FFFFFF; + else + row[x] = 0x00000000; + } + } + texture.image(0, GL::RGBA, GL::UNSIGNED_BYTE, data.data()); +} + + +History::Bandwidth::Bandwidth(): + down(0), + up(0) +{ } diff --git a/source/history.h b/source/history.h new file mode 100644 index 0000000..65deec7 --- /dev/null +++ b/source/history.h @@ -0,0 +1,48 @@ +/* $Id$ + +This file is part of NetVis +Copyright @ 2008 Mikko Rasa, Mikkosoft Productions +Distributed unter the GPL +*/ + +#ifndef HISTORY_H_ +#define HISTORY_H_ + +#include +#include +#include +#include "ringbuffer.h" + +class NetVis; + +class History +{ +private: + struct Bandwidth + { + unsigned down; + unsigned up; + + Bandwidth(); + }; + + NetVis &netvis; + unsigned width; + unsigned height; + Bandwidth accum; + RingBuffer buffer; + Msp::Time::TimeStamp next_push; + unsigned scale; + Msp::GL::Texture2D texture; + Msp::GL::Mesh mesh; + +public: + History(NetVis &, unsigned, unsigned); + void activity(unsigned, unsigned); + void tick(const Msp::Time::TimeStamp &); + void render() const; +private: + void create_texture(); +}; + +#endif diff --git a/source/netvis.cpp b/source/netvis.cpp index fb02c0d..ff05507 100644 --- a/source/netvis.cpp +++ b/source/netvis.cpp @@ -9,10 +9,10 @@ Distributed unter the GPL #include #include #include +#include #include #include #include -#include #include #include #include @@ -26,6 +26,7 @@ Distributed unter the GPL #include #include #include +#include "history.h" #include "host.h" #include "netvis.h" #include "packet.h" @@ -73,6 +74,8 @@ NetVis::NetVis(int argc, char **argv): font = new GL::Font; DataFile::load(*font, "dejavu-10.font"); + history = new History(*this, 301, 100); + catch_signal(SIGINT); } @@ -114,6 +117,8 @@ void NetVis::tick() while(pcap_dispatch(pcap, -1, &capture_handler, reinterpret_cast(this))>0) ; resolver->tick(); + history->tick(tick_t); + float min_activity = numeric_limits::max(); for(map::iterator i=hosts.begin(); i!=hosts.end(); ++i) @@ -221,6 +226,11 @@ void NetVis::render() font->draw_string(format("%.2f fps", fps)); GL::Texture::unbind(); GL::pop_matrix(); + + GL::push_matrix(); + GL::translate(170, -370, 0); + history->render(); + GL::pop_matrix(); } Host &NetVis::get_host(unsigned a) @@ -288,6 +298,11 @@ void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const uns shost.add_activity(size); if(dhost) dhost->add_activity(size); + + if((ntohl(ip->saddr)&self->localnet_mask)==self->localnet) + self->history->activity(0, size); + else if((ntohl(ip->daddr)&self->localnet_mask)==self->localnet) + self->history->activity(size, 0); } } diff --git a/source/netvis.h b/source/netvis.h index eb8c0a8..989e060 100644 --- a/source/netvis.h +++ b/source/netvis.h @@ -20,6 +20,7 @@ Distributed unter the GPL #include #include +class History; class Host; class Packet; class Port; @@ -43,6 +44,7 @@ private: std::map disabled_hosts; std::list packets; std::map ports; + History *history; Msp::Time::TimeStamp tick_t; Msp::Time::TimeStamp fps_t; @@ -62,6 +64,7 @@ private: Host &get_host(unsigned); Msp::GL::Color generate_color(bool) const; const Port &get_port(unsigned); + void create_history_texture(); static void capture_handler(unsigned char *, const pcap_pkthdr *, const unsigned char *); diff --git a/source/port.cpp b/source/port.cpp index d4be82c..1c940af 100644 --- a/source/port.cpp +++ b/source/port.cpp @@ -35,8 +35,12 @@ Port::Port(NetVis &v, unsigned n): else name = Msp::lexical_cast(number); + const map &ports = netvis.get_ports(); + unsigned tries = 100; + if(ports.size()>100 && number>=1024) + tries = 10000/ports.size()+1; float best_score = 0; - for(unsigned i=0; (i<100 && best_score<1); ++i) + for(unsigned i=0; (i &ports = netvis.get_ports(); for(map::const_iterator j=ports.begin(); j!=ports.end(); ++j) { + if(number<1024 && j->first>1024) + break; const GL::Color &other = j->second->get_color(); float dr = c.r-other.r; float dg = c.g-other.g; diff --git a/source/resolver.cpp b/source/resolver.cpp index 1bf6c39..d8dc41d 100644 --- a/source/resolver.cpp +++ b/source/resolver.cpp @@ -47,7 +47,7 @@ void Resolver::main() { while(!done) { - while(1) + while(!done) { Host *host; { @@ -70,6 +70,6 @@ void Resolver::main() } } - Time::sleep(Time::sec); + Time::sleep(100*Time::msec); } } diff --git a/source/ringbuffer.h b/source/ringbuffer.h new file mode 100644 index 0000000..c118019 --- /dev/null +++ b/source/ringbuffer.h @@ -0,0 +1,28 @@ +/* $Id$ + +This file is part of NetVis +Copyright @ 2008 Mikko Rasa, Mikkosoft Productions +Distributed unter the GPL +*/ + +#ifndef RINGBUFFER_H_ +#define RINGBUFFER_H_ + +#include + +template +class RingBuffer +{ +private: + unsigned sz; + std::vector data; + unsigned pos; + +public: + RingBuffer(unsigned s): sz(s), data(sz), pos(0) { } + void push(const T &v) { data[pos=(pos+1)%sz] = v; } + const T &get(unsigned i) const { return data[(pos+sz-i)%sz]; } + unsigned size() const { return sz; } +}; + +#endif -- 2.43.0