diff --git a/scapy/layers/dot11.py b/scapy/layers/dot11.py index a6593fec5f43e7546dcb8e75a689e7a1766870fa..0159eac0762b9179c0422307faa516793f268347 100644 --- a/scapy/layers/dot11.py +++ b/scapy/layers/dot11.py @@ -2,6 +2,7 @@ import re,struct from scapy.packet import * from scapy.fields import * +from scapy.plist import PacketList from scapy.layers.l2 import * class PrismHeader(Packet): @@ -468,3 +469,24 @@ iwconfig wlan0 mode managed conf.stats_dot11_protocols += [Dot11WEP, Dot11Beacon, ] + + + + + +class Dot11PacketList(PacketList): + def __init__(self, res=None, name="Dot11List", stats=None): + if stats is None: + stats = conf.stats_dot11_protocols + + PacketList.__init__(self, res, name, stats) + def toEthernet(self): + data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res)) + r2 = [] + for p in data: + q = p.copy() + q.unwep() + r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP + return PacketList(r2,name="Ether from %s"%self.listname) + + diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py index acda9a28f965a89b842c3617b22c09d9aa056804..c1a2e72ceaa4b32a1a9a471841088f44bd883e80 100644 --- a/scapy/layers/inet.py +++ b/scapy/layers/inet.py @@ -7,7 +7,9 @@ from scapy.packet import * from scapy.volatile import * from scapy.config import conf from scapy.sendrecv import sr,sr1 +from scapy.plist import PacketList,SndRcvList +import scapy.as_resolvers #################### @@ -685,6 +687,367 @@ def defragment(plist): + + + +class TracerouteResult(SndRcvList): + def __init__(self, res=None, name="Traceroute", stats=None): + PacketList.__init__(self, res, name, stats) + self.graphdef = None + self.graphASres = 0 + self.padding = 0 + self.hloc = None + self.nloc = None + + def show(self): + return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"), + s.ttl, + r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}"))) + + + def get_trace(self): + trace = {} + for s,r in self.res: + if IP not in s: + continue + d = s[IP].dst + if d not in trace: + trace[d] = {} + trace[d][s[IP].ttl] = r[IP].src, ICMP not in r + for k in trace.values(): + m = filter(lambda x:k[x][1], k.keys()) + if not m: + continue + m = min(m) + for l in k.keys(): + if l > m: + del(k[l]) + return trace + + def trace3D(self): + """Give a 3D representation of the traceroute. + right button: rotate the scene + middle button: zoom + left button: move the scene + left button on a ball: toggle IP displaying + ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result""" + trace = self.get_trace() + import visual + + class IPsphere(visual.sphere): + def __init__(self, ip, **kargs): + visual.sphere.__init__(self, **kargs) + self.ip=ip + self.label=None + self.setlabel(self.ip) + def setlabel(self, txt,visible=None): + if self.label is not None: + if visible is None: + visible = self.label.visible + self.label.visible = 0 + elif visible is None: + visible=0 + self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible) + def action(self): + self.label.visible ^= 1 + + visual.scene = visual.display() + visual.scene.exit_on_close(0) + start = visual.box() + rings={} + tr3d = {} + for i in trace: + tr = trace[i] + tr3d[i] = [] + ttl = tr.keys() + for t in range(1,max(ttl)+1): + if t not in rings: + rings[t] = [] + if t in tr: + if tr[t] not in rings[t]: + rings[t].append(tr[t]) + tr3d[i].append(rings[t].index(tr[t])) + else: + rings[t].append(("unk",-1)) + tr3d[i].append(len(rings[t])-1) + for t in rings: + r = rings[t] + l = len(r) + for i in range(l): + if r[i][1] == -1: + col = (0.75,0.75,0.75) + elif r[i][1]: + col = visual.color.green + else: + col = visual.color.blue + + s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t), + ip = r[i][0], + color = col) + for trlst in tr3d.values(): + if t <= len(trlst): + if trlst[t-1] == i: + trlst[t-1] = s + forecol = colgen(0.625, 0.4375, 0.25, 0.125) + for trlst in tr3d.values(): + col = forecol.next() + start = (0,0,0) + for ip in trlst: + visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2) + start = ip.pos + + movcenter=None + while 1: + if visual.scene.kb.keys: + k = visual.scene.kb.getkey() + if k == "esc": + break + if visual.scene.mouse.events: + ev = visual.scene.mouse.getevent() + if ev.press == "left": + o = ev.pick + if o: + if ev.ctrl: + if o.ip == "unk": + continue + savcolor = o.color + o.color = (1,0,0) + a,b=sendrecv.sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2) + o.color = savcolor + if len(a) == 0: + txt = "%s:\nno results" % o.ip + else: + txt = "%s:\n" % o.ip + for s,r in a: + txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n") + o.setlabel(txt, visible=1) + else: + if hasattr(o, "action"): + o.action() + elif ev.drag == "left": + movcenter = ev.pos + elif ev.drop == "left": + movcenter = None + if movcenter: + visual.scene.center -= visual.scene.mouse.pos-movcenter + movcenter = visual.scene.mouse.pos + + + def world_trace(self): + from modules.geo import locate_ip + ips = {} + rt = {} + ports_done = {} + for s,r in self.res: + ips[r.src] = None + if s.haslayer(TCP) or s.haslayer(UDP): + trace_id = (s.src,s.dst,s.proto,s.dport) + elif s.haslayer(ICMP): + trace_id = (s.src,s.dst,s.proto,s.type) + else: + trace_id = (s.src,s.dst,s.proto,0) + trace = rt.get(trace_id,{}) + if not r.haslayer(ICMP) or r.type != 11: + if ports_done.has_key(trace_id): + continue + ports_done[trace_id] = None + trace[s.ttl] = r.src + rt[trace_id] = trace + + trt = {} + for trace_id in rt: + trace = rt[trace_id] + loctrace = [] + for i in range(max(trace.keys())): + ip = trace.get(i,None) + if ip is None: + continue + loc = locate_ip(ip) + if loc is None: + continue +# loctrace.append((ip,loc)) # no labels yet + loctrace.append(loc) + if loctrace: + trt[trace_id] = loctrace + + tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values()) + g = Gnuplot.Gnuplot() + world = Gnuplot.File(conf.gnuplot_world,with="lines") + g.plot(world,*tr) + return g + + def make_graph(self,ASres=None,padding=0): + if ASres is None: + ASres = conf.AS_resolver + self.graphASres = ASres + self.graphpadding = padding + ips = {} + rt = {} + ports = {} + ports_done = {} + for s,r in self.res: + r = r[IP] or r[IPv6] or r + s = s[IP] or s[IPv6] or s + ips[r.src] = None + if TCP in s: + trace_id = (s.src,s.dst,6,s.dport) + elif UDP in s: + trace_id = (s.src,s.dst,17,s.dport) + elif ICMP in s: + trace_id = (s.src,s.dst,1,s.type) + else: + trace_id = (s.src,s.dst,s.proto,0) + trace = rt.get(trace_id,{}) + ttl = IPv6 in s and s.hlim or s.ttl + if not (ICMP in r and r[ICMP].type == 11) and not (IPv6 in r and ICMPv6TimeExceeded in r): + if trace_id in ports_done: + continue + ports_done[trace_id] = None + p = ports.get(r.src,[]) + if TCP in r: + p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%")) + trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%') + elif UDP in r: + p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%")) + trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%') + elif ICMP in r: + p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%")) + trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%') + else: + p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}")) + trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}') + ports[r.src] = p + else: + trace[ttl] = r.sprintf('"%r,src%"') + rt[trace_id] = trace + + # Fill holes with unk%i nodes + unknown_label = incremental_label("unk%i") + blackholes = [] + bhip = {} + for rtk in rt: + trace = rt[rtk] + k = trace.keys() + for n in range(min(k), max(k)): + if not trace.has_key(n): + trace[n] = unknown_label.next() + if not ports_done.has_key(rtk): + if rtk[2] == 1: #ICMP + bh = "%s %i/icmp" % (rtk[1],rtk[3]) + elif rtk[2] == 6: #TCP + bh = "%s %i/tcp" % (rtk[1],rtk[3]) + elif rtk[2] == 17: #UDP + bh = '%s %i/udp' % (rtk[1],rtk[3]) + else: + bh = '%s %i/proto' % (rtk[1],rtk[2]) + ips[bh] = None + bhip[rtk[1]] = bh + bh = '"%s"' % bh + trace[max(k)+1] = bh + blackholes.append(bh) + + # Find AS numbers + ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys() + if ASres is None: + ASNlist = [] + else: + ASNlist = ASres.resolve(*ASN_query_list) + + ASNs = {} + ASDs = {} + for ip,asn,desc, in ASNlist: + if asn is None: + continue + iplist = ASNs.get(asn,[]) + if ip in bhip: + if ip in ports: + iplist.append(ip) + iplist.append(bhip[ip]) + else: + iplist.append(ip) + ASNs[asn] = iplist + ASDs[asn] = desc + + + backcolorlist=colgen("60","86","ba","ff") + forecolorlist=colgen("a0","70","40","20") + + s = "digraph trace {\n" + + s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n" + + s += "\n#ASN clustering\n" + for asn in ASNs: + s += '\tsubgraph cluster_%s {\n' % asn + col = backcolorlist.next() + s += '\t\tcolor="#%s%s%s";' % col + s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col + s += '\t\tfontsize = 10;' + s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn]) + for ip in ASNs[asn]: + + s += '\t\t"%s";\n'%ip + s += "\t}\n" + + + + + s += "#endpoints\n" + for p in ports: + s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p])) + + s += "\n#Blackholes\n" + for bh in blackholes: + s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh + + if padding: + s += "\n#Padding\n" + pad={} + for snd,rcv in self.res: + if rcv.src not in ports and rcv.haslayer(Padding): + p = rcv.getlayer(Padding).load + if p != "\x00"*len(p): + pad[rcv.src]=None + for rcv in pad: + s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv + + + + s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n" + + + for rtk in rt: + s += "#---[%s\n" % `rtk` + s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next() + trace = rt[rtk] + k = trace.keys() + for n in range(min(k), max(k)): + s += '\t%s ->\n' % trace[n] + s += '\t%s;\n' % trace[max(k)] + + s += "}\n"; + self.graphdef = s + + def graph(self, ASres=None, padding=0, **kargs): + """x.graph(ASres=conf.AS_resolver, other args): + ASres=None : no AS resolver => no clustering + ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net) + ASres=AS_resolver_cymru(): use whois.cymru.com whois database + ASres=AS_resolver(server="whois.ra.net") + type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option + target: filename or redirect. Defaults pipe to Imagemagick's display program + prog: which graphviz program to use""" + if ASres is None: + ASres = conf.AS_resolver + if (self.graphdef is None or + self.graphASres != ASres or + self.graphpadding != padding): + self.make_graph(ASres,padding) + + return do_graph(self.graphdef, **kargs) + + + def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs): """Instant TCP traceroute diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py index 1e4cadf0f3a8321b7d9cbc6d34ad2cfa53b49002..57afe2afe612acccae6daa4b2c68db6df4068607 100644 --- a/scapy/layers/l2.py +++ b/scapy/layers/l2.py @@ -2,6 +2,7 @@ import os,struct,time from scapy.config import conf from scapy.packet import * from scapy.ansmachine import * +from scapy.plist import SndRcvList class Ether_or_Dot3_metaclass(Packet_metaclass): def __call__(self, _pkt=None, *args, **kargs): @@ -284,6 +285,16 @@ arpcachepoison(target, victim, [interval=60]) -> None pass +class ARPingResult(SndRcvList): + def __init__(self, res=None, name="ARPing", stats=None): + PacketList.__init__(self, res, name, stats) + + def show(self): + for s,r in self.res: + print r.sprintf("%Ether.src% %ARP.psrc%") + + + def arping(net, timeout=2, cache=0, verbose=None, **kargs): """Send ARP who-has requests to determine which hosts are up arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None diff --git a/scapy/plist.py b/scapy/plist.py index feda560ceca1615a193b65fe11606ea319e53d24..07657ca385e0d3a1e79c690d8481209b07537e73 100644 --- a/scapy/plist.py +++ b/scapy/plist.py @@ -4,11 +4,6 @@ from error import warning from base_classes import BasePacket,BasePacketList from utils import incremental_label,colgen,do_graph,hexdump,make_table,make_lined_table,make_tex_table -from packet import Padding,Raw -from layers.inet import IP,TCP,UDP,ICMP -from layers.l2 import Ether -from layers.dot11 import Dot11 -from layers.ip6 import IPv6 #,ICMPv6TimeExceeded import arch if arch.GNUPLOT: @@ -431,26 +426,6 @@ lfilter: truth function to apply to each packet to decide whether it will be dis - - - -class Dot11PacketList(PacketList): - def __init__(self, res=None, name="Dot11List", stats=None): - if stats is None: - stats = conf.stats_dot11_protocols - - PacketList.__init__(self, res, name, stats) - def toEthernet(self): - data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res)) - r2 = [] - for p in data: - q = p.copy() - q.unwep() - r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP - return PacketList(r2,name="Ether from %s"%self.listname) - - - class SndRcvList(PacketList): def __init__(self, res=None, name="Results", stats=None): PacketList.__init__(self, res, name, stats) @@ -460,372 +435,11 @@ class SndRcvList(PacketList): return "%s ==> %s" % (elt[0].summary(),elt[1].summary()) -class ARPingResult(SndRcvList): - def __init__(self, res=None, name="ARPing", stats=None): - PacketList.__init__(self, res, name, stats) - - def show(self): - for s,r in self.res: - print r.sprintf("%Ether.src% %ARP.psrc%") - - - - -class TracerouteResult(SndRcvList): - def __init__(self, res=None, name="Traceroute", stats=None): - PacketList.__init__(self, res, name, stats) - self.graphdef = None - self.graphASres = 0 - self.padding = 0 - self.hloc = None - self.nloc = None - - def show(self): - return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"), - s.ttl, - r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}"))) - - - def get_trace(self): - trace = {} - for s,r in self.res: - if IP not in s: - continue - d = s[IP].dst - if d not in trace: - trace[d] = {} - trace[d][s[IP].ttl] = r[IP].src, ICMP not in r - for k in trace.values(): - m = filter(lambda x:k[x][1], k.keys()) - if not m: - continue - m = min(m) - for l in k.keys(): - if l > m: - del(k[l]) - return trace - - def trace3D(self): - """Give a 3D representation of the traceroute. - right button: rotate the scene - middle button: zoom - left button: move the scene - left button on a ball: toggle IP displaying - ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result""" - trace = self.get_trace() - import visual - - class IPsphere(visual.sphere): - def __init__(self, ip, **kargs): - visual.sphere.__init__(self, **kargs) - self.ip=ip - self.label=None - self.setlabel(self.ip) - def setlabel(self, txt,visible=None): - if self.label is not None: - if visible is None: - visible = self.label.visible - self.label.visible = 0 - elif visible is None: - visible=0 - self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible) - def action(self): - self.label.visible ^= 1 - - visual.scene = visual.display() - visual.scene.exit_on_close(0) - start = visual.box() - rings={} - tr3d = {} - for i in trace: - tr = trace[i] - tr3d[i] = [] - ttl = tr.keys() - for t in range(1,max(ttl)+1): - if t not in rings: - rings[t] = [] - if t in tr: - if tr[t] not in rings[t]: - rings[t].append(tr[t]) - tr3d[i].append(rings[t].index(tr[t])) - else: - rings[t].append(("unk",-1)) - tr3d[i].append(len(rings[t])-1) - for t in rings: - r = rings[t] - l = len(r) - for i in range(l): - if r[i][1] == -1: - col = (0.75,0.75,0.75) - elif r[i][1]: - col = visual.color.green - else: - col = visual.color.blue - - s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t), - ip = r[i][0], - color = col) - for trlst in tr3d.values(): - if t <= len(trlst): - if trlst[t-1] == i: - trlst[t-1] = s - forecol = colgen(0.625, 0.4375, 0.25, 0.125) - for trlst in tr3d.values(): - col = forecol.next() - start = (0,0,0) - for ip in trlst: - visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2) - start = ip.pos - - movcenter=None - while 1: - if visual.scene.kb.keys: - k = visual.scene.kb.getkey() - if k == "esc": - break - if visual.scene.mouse.events: - ev = visual.scene.mouse.getevent() - if ev.press == "left": - o = ev.pick - if o: - if ev.ctrl: - if o.ip == "unk": - continue - savcolor = o.color - o.color = (1,0,0) - a,b=sendrecv.sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2) - o.color = savcolor - if len(a) == 0: - txt = "%s:\nno results" % o.ip - else: - txt = "%s:\n" % o.ip - for s,r in a: - txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n") - o.setlabel(txt, visible=1) - else: - if hasattr(o, "action"): - o.action() - elif ev.drag == "left": - movcenter = ev.pos - elif ev.drop == "left": - movcenter = None - if movcenter: - visual.scene.center -= visual.scene.mouse.pos-movcenter - movcenter = visual.scene.mouse.pos - - - def world_trace(self): - from modules.geo import locate_ip - ips = {} - rt = {} - ports_done = {} - for s,r in self.res: - ips[r.src] = None - if s.haslayer(TCP) or s.haslayer(UDP): - trace_id = (s.src,s.dst,s.proto,s.dport) - elif s.haslayer(ICMP): - trace_id = (s.src,s.dst,s.proto,s.type) - else: - trace_id = (s.src,s.dst,s.proto,0) - trace = rt.get(trace_id,{}) - if not r.haslayer(ICMP) or r.type != 11: - if ports_done.has_key(trace_id): - continue - ports_done[trace_id] = None - trace[s.ttl] = r.src - rt[trace_id] = trace - - trt = {} - for trace_id in rt: - trace = rt[trace_id] - loctrace = [] - for i in range(max(trace.keys())): - ip = trace.get(i,None) - if ip is None: - continue - loc = locate_ip(ip) - if loc is None: - continue -# loctrace.append((ip,loc)) # no labels yet - loctrace.append(loc) - if loctrace: - trt[trace_id] = loctrace - - tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values()) - g = Gnuplot.Gnuplot() - world = Gnuplot.File(conf.gnuplot_world,with="lines") - g.plot(world,*tr) - return g - def make_graph(self,ASres=None,padding=0): - if ASres is None: - ASres = conf.AS_resolver - self.graphASres = ASres - self.graphpadding = padding - ips = {} - rt = {} - ports = {} - ports_done = {} - for s,r in self.res: - r = r[IP] or r[IPv6] or r - s = s[IP] or s[IPv6] or s - ips[r.src] = None - if TCP in s: - trace_id = (s.src,s.dst,6,s.dport) - elif UDP in s: - trace_id = (s.src,s.dst,17,s.dport) - elif ICMP in s: - trace_id = (s.src,s.dst,1,s.type) - else: - trace_id = (s.src,s.dst,s.proto,0) - trace = rt.get(trace_id,{}) - ttl = IPv6 in s and s.hlim or s.ttl - if not (ICMP in r and r[ICMP].type == 11) and not (IPv6 in r and ICMPv6TimeExceeded in r): - if trace_id in ports_done: - continue - ports_done[trace_id] = None - p = ports.get(r.src,[]) - if TCP in r: - p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%")) - trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%') - elif UDP in r: - p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%")) - trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%') - elif ICMP in r: - p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%")) - trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%') - else: - p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}")) - trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}') - ports[r.src] = p - else: - trace[ttl] = r.sprintf('"%r,src%"') - rt[trace_id] = trace - - # Fill holes with unk%i nodes - unknown_label = incremental_label("unk%i") - blackholes = [] - bhip = {} - for rtk in rt: - trace = rt[rtk] - k = trace.keys() - for n in range(min(k), max(k)): - if not trace.has_key(n): - trace[n] = unknown_label.next() - if not ports_done.has_key(rtk): - if rtk[2] == 1: #ICMP - bh = "%s %i/icmp" % (rtk[1],rtk[3]) - elif rtk[2] == 6: #TCP - bh = "%s %i/tcp" % (rtk[1],rtk[3]) - elif rtk[2] == 17: #UDP - bh = '%s %i/udp' % (rtk[1],rtk[3]) - else: - bh = '%s %i/proto' % (rtk[1],rtk[2]) - ips[bh] = None - bhip[rtk[1]] = bh - bh = '"%s"' % bh - trace[max(k)+1] = bh - blackholes.append(bh) - - # Find AS numbers - ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys() - if ASres is None: - ASNlist = [] - else: - ASNlist = ASres.resolve(*ASN_query_list) - - ASNs = {} - ASDs = {} - for ip,asn,desc, in ASNlist: - if asn is None: - continue - iplist = ASNs.get(asn,[]) - if ip in bhip: - if ip in ports: - iplist.append(ip) - iplist.append(bhip[ip]) - else: - iplist.append(ip) - ASNs[asn] = iplist - ASDs[asn] = desc - - - backcolorlist=colgen("60","86","ba","ff") - forecolorlist=colgen("a0","70","40","20") - - s = "digraph trace {\n" - - s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n" - - s += "\n#ASN clustering\n" - for asn in ASNs: - s += '\tsubgraph cluster_%s {\n' % asn - col = backcolorlist.next() - s += '\t\tcolor="#%s%s%s";' % col - s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col - s += '\t\tfontsize = 10;' - s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn]) - for ip in ASNs[asn]: - - s += '\t\t"%s";\n'%ip - s += "\t}\n" - - - - s += "#endpoints\n" - for p in ports: - s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p])) - - s += "\n#Blackholes\n" - for bh in blackholes: - s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh - - if padding: - s += "\n#Padding\n" - pad={} - for snd,rcv in self.res: - if rcv.src not in ports and rcv.haslayer(Padding): - p = rcv.getlayer(Padding).load - if p != "\x00"*len(p): - pad[rcv.src]=None - for rcv in pad: - s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv - - - - s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n" - - - for rtk in rt: - s += "#---[%s\n" % `rtk` - s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next() - trace = rt[rtk] - k = trace.keys() - for n in range(min(k), max(k)): - s += '\t%s ->\n' % trace[n] - s += '\t%s;\n' % trace[max(k)] - - s += "}\n"; - self.graphdef = s - - def graph(self, ASres=None, padding=0, **kargs): - """x.graph(ASres=conf.AS_resolver, other args): - ASres=None : no AS resolver => no clustering - ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net) - ASres=AS_resolver_cymru(): use whois.cymru.com whois database - ASres=AS_resolver(server="whois.ra.net") - type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option - target: filename or redirect. Defaults pipe to Imagemagick's display program - prog: which graphviz program to use""" - if ASres is None: - ASres = conf.AS_resolver - if (self.graphdef is None or - self.graphASres != ASres or - self.graphpadding != padding): - self.make_graph(ASres,padding) - - return do_graph(self.graphdef, **kargs) - +# Theses import must come in last to avoid problems with cyclic dependencies +from packet import Padding,Raw +from layers.inet import IP,TCP +