2 #include <netinet/ip.h>
3 #include <netinet/tcp.h>
4 #include <netinet/udp.h>
5 #include <linux/if_ether.h>
6 #include <msp/core/except.h>
7 #include <msp/gl/immediate.h>
8 #include <msp/gl/matrix.h>
9 #include <msp/gl/misc.h>
10 #include <msp/gl/projection.h>
11 #include <msp/gl/texture2d.h>
12 #include <msp/gl/transform.h>
13 #include <msp/strings/formatter.h>
14 #include <msp/time/utils.h>
22 NetVis::NetVis(int /*argc*/, char **argv)
30 pcap=pcap_open_live(iface.c_str(), 128, true, 0, err);
34 if(pcap_setnonblock(pcap, true, err)==-1)
37 dpy=new Graphics::Display;
38 wnd=new Graphics::Window(*dpy, 1024, 768);
39 glc=new Graphics::GLContext(*wnd);
40 wnd->set_title("NetVis");
44 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
47 DataFile::load(*font, "dejavu-10.font");
48 font_tex=new GL::Texture2D;
49 DataFile::load(*font_tex, "dejavu-10.tex");
50 font->set_texture(*font_tex);
63 Msp::Time::TimeStamp t=Msp::Time::now();
66 Msp::Time::TimeDelta dt=t-last_tick;
71 pcap_dispatch(pcap, -1, &capture_handler, reinterpret_cast<unsigned char *>(this));
73 glClear(GL_COLOR_BUFFER_BIT);
75 GL::matrix_mode(GL::PROJECTION);
77 GL::ortho_centered(1024, 768);
78 GL::matrix_mode(GL::MODELVIEW);
81 for(map<unsigned, Host *>::iterator i=hosts.begin(); i!=hosts.end(); ++i)
86 for(list<Packet *>::iterator i=packets.begin(); i!=packets.end();)
99 GL::translate(-500, 360, 0);
100 for(map<unsigned, GL::Color>::iterator i=port_colors.begin(); i!=port_colors.end(); ++i)
102 GL::Color &color=i->second;
106 GL::Immediate imm((GL::COLOR4_UBYTE,GL::VERTEX2));
107 imm.begin(GL::QUADS);
108 imm.color(color.r, color.g, color.b, color.a);
109 for(float x=0; x<0.5; x+=0.2)
113 imm.vertex(x+10, 10);
118 GL::translate(15, 1, 0);
119 GL::scale_uniform(10);
120 glColor4f(1.0, 1.0, 1.0, 1.0);
121 font->draw_string(format("%d", i->first));
122 GL::Texture::unbind();
125 GL::translate(0, -12, 0);
131 Host &NetVis::get_host(unsigned a)
133 map<unsigned, Host *>::iterator i=hosts.find(a);
137 Host *host=new Host(*this, a);
138 host->set_position(Vector2(rand()*30.0/RAND_MAX-15.0, rand()*20.0/RAND_MAX-10.0));
143 GL::Color &NetVis::get_port_color(unsigned port)
145 map<unsigned, GL::Color>::iterator i=port_colors.find(port);
146 if(i!=port_colors.end())
152 color.r=rand()*1.0/RAND_MAX;
153 color.g=rand()*1.0/RAND_MAX;
154 color.b=rand()*1.0/RAND_MAX;
155 if(color.r>0.5 || color.g>0.5 || color.b>0.7)
159 return port_colors[port]=color;
162 void NetVis::capture_handler(unsigned char *user, const pcap_pkthdr *, const unsigned char *data)
164 NetVis *self=reinterpret_cast<NetVis *>(user);
166 const ethhdr *eth=reinterpret_cast<const ethhdr *>(data);
167 if(ntohs(eth->h_proto)==ETH_P_IP)
169 const iphdr *ip=reinterpret_cast<const iphdr *>(eth+1);
171 //cout<<"IP packet of "<<hdr->len<<'/'<<ntohs(ip->tot_len)<<" bytes\n";
174 if(ip->protocol==IPPROTO_TCP)
176 const tcphdr *tcp=reinterpret_cast<const tcphdr *>(ip+1);
177 port=min(ntohs(tcp->source), ntohs(tcp->dest));
179 else if(ip->protocol==IPPROTO_UDP)
181 const udphdr *udp=reinterpret_cast<const udphdr *>(ip+1);
182 port=min(ntohs(udp->source), ntohs(udp->dest));
184 Host &shost=self->get_host(ntohl(ip->saddr));
186 if((ntohl(ip->daddr)&0xFF)!=0xFF)
187 dhost=&self->get_host(ntohl(ip->daddr));
188 self->packets.push_back(new Packet(shost, dhost, self->get_port_color(port), ntohs(ip->tot_len)));
192 Application::RegApp<NetVis> NetVis::reg;