def graph(self, **kargs): s = 'digraph "%s" {\n' % self.__class__.__name__ se = "" # Keep initial nodes at the begining for better rendering for st in self.states.itervalues(): if st.atmt_initial: se = ( '\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state) + se elif st.atmt_final: se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state elif st.atmt_error: se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state s += se for st in self.states.values(): for n in st.atmt_origfunc.func_code.co_names + st.atmt_origfunc.func_code.co_consts: if n in self.states: s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state, n) for c, k, v in ([("purple", k, v) for k, v in self.conditions.items()] + [("red", k, v) for k, v in self.recv_conditions.items()] + [("orange", k, v) for k, v in self.ioevents.items()]): for f in v: for n in f.func_code.co_names + f.func_code.co_consts: if n in self.states: l = f.atmt_condname for x in self.actions[f.atmt_condname]: l += "\\l>[%s]" % x.func_name s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % ( k, n, l, c) for k, v in self.timeout.iteritems(): for t, f in v: if f is None: continue for n in f.func_code.co_names + f.func_code.co_consts: if n in self.states: l = "%s/%.1fs" % (f.atmt_condname, t) for x in self.actions[f.atmt_condname]: l += "\\l>[%s]" % x.func_name s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % ( k, n, l) s += "}\n" return do_graph(s, **kargs)
def conversations(self, getsrcdst=None, **kargs): """Graphes a conversations between sources and destinations and display it (using graphviz and imagemagick) getsrcdst: a function that takes an element of the list and returns the source, the destination and optionally a label. By default, returns the IP source and destination from IP and ARP layers 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 getsrcdst is None: def getsrcdst(pkt): if IP in pkt: return (pkt[IP].src, pkt[IP].dst) if ARP in pkt: return (pkt[ARP].psrc, pkt[ARP].pdst) raise TypeError() conv = {} for p in self.res: p = self._elt2pkt(p) try: c = getsrcdst(p) except: # No warning here: it's OK that getsrcdst() raises an # exception, since it might be, for example, a # function that expects a specific layer in each # packet. The try/except approach is faster and # considered more Pythonic than adding tests. continue if len(c) == 3: conv.setdefault(c[:2], set()).add(c[2]) else: conv[c] = conv.get(c, 0) + 1 gr = 'digraph "conv" {\n' for (s, d), l in conv.iteritems(): gr += '\t "%s" -> "%s" [label="%s"]\n' % (s, d, ', '.join( str(x) for x in l) if isinstance(l, set) else l) gr += "}\n" return do_graph(gr, **kargs)
def conversations(self, getsrcdst=None,**kargs): """Graphes a conversations between sources and destinations and display it (using graphviz and imagemagick) getsrcdst: a function that takes an element of the list and returns the source, the destination and optionally a label. By default, returns the IP source and destination from IP and ARP layers 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 getsrcdst is None: def getsrcdst(pkt): if IP in pkt: return (pkt[IP].src, pkt[IP].dst) if ARP in pkt: return (pkt[ARP].psrc, pkt[ARP].pdst) raise TypeError() conv = {} for p in self.res: p = self._elt2pkt(p) try: c = getsrcdst(p) except: # No warning here: it's OK that getsrcdst() raises an # exception, since it might be, for example, a # function that expects a specific layer in each # packet. The try/except approach is faster and # considered more Pythonic than adding tests. continue if len(c) == 3: conv.setdefault(c[:2], set()).add(c[2]) else: conv[c] = conv.get(c, 0) + 1 gr = 'digraph "conv" {\n' for (s, d), l in conv.iteritems(): gr += '\t "%s" -> "%s" [label="%s"]\n' % ( s, d, ', '.join(str(x) for x in l) if isinstance(l, set) else l ) gr += "}\n" return do_graph(gr, **kargs)
def conversations(self, getsrcdst=None,**kargs): """Graphes a conversations between sources and destinations and display it (using graphviz and imagemagick) getsrcdst: a function that takes an element of the list and return the source and dest by defaults, return source and destination IP 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 getsrcdst is None: getsrcdst = lambda x:(x['IP'].src, x['IP'].dst) conv = {} for p in self.res: p = self._elt2pkt(p) try: c = getsrcdst(p) except: #XXX warning() continue conv[c] = conv.get(c,0)+1 gr = 'digraph "conv" {\n' for s,d in conv: gr += '\t "%s" -> "%s"\n' % (s,d) gr += "}\n" return do_graph(gr, **kargs)
def conversations(self, getsrcdst=None, **kargs): """Graphes a conversations between sources and destinations and display it (using graphviz and imagemagick) getsrcdst: a function that takes an element of the list and return the source and dest by defaults, return source and destination IP 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 getsrcdst is None: getsrcdst = lambda x: (x['IP'].src, x['IP'].dst) conv = {} for p in self.res: p = self._elt2pkt(p) try: c = getsrcdst(p) except: #XXX warning() continue conv[c] = conv.get(c, 0) + 1 gr = 'digraph "conv" {\n' for s, d in conv: gr += '\t "%s" -> "%s"\n' % (s, d) gr += "}\n" return do_graph(gr, **kargs)
def afterglow(self, src=None, event=None, dst=None, **kargs): """Experimental clone attempt of http://sourceforge.net/projects/afterglow each datum is reduced as src -> event -> dst and the data are graphed. by default we have IP.src -> IP.dport -> IP.dst""" if src is None: src = lambda x: x['IP'].src if event is None: event = lambda x: x['IP'].dport if dst is None: dst = lambda x: x['IP'].dst sl = {} el = {} dl = {} for i in self.res: try: s,e,d = src(i),event(i),dst(i) if s in sl: n,l = sl[s] n += 1 if e not in l: l.append(e) sl[s] = (n,l) else: sl[s] = (1,[e]) if e in el: n,l = el[e] n+=1 if d not in l: l.append(d) el[e] = (n,l) else: el[e] = (1,[d]) dl[d] = dl.get(d,0)+1 except: continue import math def normalize(n): return 2+math.log(n)/4.0 def minmax(x): m,M = min(x),max(x) if m == M: m = 0 if M == 0: M = 1 return m,M mins,maxs = minmax(map(lambda (x,y): x, sl.values())) mine,maxe = minmax(map(lambda (x,y): x, el.values())) mind,maxd = minmax(dl.values()) gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' gr += "# src nodes\n" for s in sl: n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins) gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (`s`,`s`,n,n) gr += "# event nodes\n" for e in el: n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine) gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`e`,`e`,n,n) for d in dl: n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind) gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`d`,`d`,n,n) gr += "###\n" for s in sl: n,l = sl[s] for e in l: gr += ' "src.%s" -> "evt.%s";\n' % (`s`,`e`) for e in el: n,l = el[e] for d in l: gr += ' "evt.%s" -> "dst.%s";\n' % (`e`,`d`) gr += "}" return do_graph(gr, **kargs)
def afterglow(self, src=None, event=None, dst=None, **kargs): """Experimental clone attempt of http://sourceforge.net/projects/afterglow each datum is reduced as src -> event -> dst and the data are graphed. by default we have IP.src -> IP.dport -> IP.dst""" if src is None: src = lambda x: x['IP'].src if event is None: event = lambda x: x['IP'].dport if dst is None: dst = lambda x: x['IP'].dst sl = {} el = {} dl = {} for i in self.res: try: s, e, d = src(i), event(i), dst(i) if s in sl: n, l = sl[s] n += 1 if e not in l: l.append(e) sl[s] = (n, l) else: sl[s] = (1, [e]) if e in el: n, l = el[e] n += 1 if d not in l: l.append(d) el[e] = (n, l) else: el[e] = (1, [d]) dl[d] = dl.get(d, 0) + 1 except: continue import math def normalize(n): return 2 + math.log_robot_message(n) / 4.0 def minmax(x): m, M = min(x), max(x) if m == M: m = 0 if M == 0: M = 1 return m, M mins, maxs = minmax(map(lambda (x, y): x, sl.values())) mine, maxe = minmax(map(lambda (x, y): x, el.values())) mind, maxd = minmax(dl.values()) gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' gr += "# src nodes\n" for s in sl: n, l = sl[s] n = 1 + float(n - mins) / (maxs - mins) gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % ( ` s `, ` s `, n, n) gr += "# event nodes\n" for e in el: n, l = el[e] n = n = 1 + float(n - mine) / (maxe - mine) gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % ( ` e `, ` e `, n, n) for d in dl: n = dl[d] n = n = 1 + float(n - mind) / (maxd - mind) gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % ( ` d `, ` d `, n, n) gr += "###\n" for s in sl: n, l = sl[s] for e in l: gr += ' "src.%s" -> "evt.%s";\n' % ( ` s `, ` e `) for e in el: n, l = el[e] for d in l: gr += ' "evt.%s" -> "dst.%s";\n' % ( ` e `, ` d `) gr += "}" return do_graph(gr, **kargs)