def graph(self, **kargs): g = [ 'digraph "pipe" {', "\tnode [shape=rectangle];", ] for p in self.active_pipes: g.append('\t"%i" [label="%s"];' % (id(p), p.name)) g.append("") g.append("\tedge [color=blue, arrowhead=vee];") for p in self.active_pipes: for q in p.sinks: g.append('\t"%i" -> "%i";' % (id(p), id(q))) g.append("") g.append("\tedge [color=purple, arrowhead=veevee];") for p in self.active_pipes: for q in p.high_sinks: g.append('\t"%i" -> "%i";' % (id(p), id(q))) g.append("") g.append("\tedge [color=red, arrowhead=diamond];") for p in self.active_pipes: for q in p.trigger_sinks: g.append('\t"%i" -> "%i";' % (id(p), id(q))) g.append('}') graph = "\n".join(g) do_graph(graph, **kargs)
def _make_graph(self, other_keys=[], **kargs): nodes = [(k, self[k]) for k in self.iterkeys()] oids = [self[k] for k in self.iterkeys()] for k in other_keys: if k not in oids: nodes.append(self.oidname(k), k) s = 'digraph "mib" {\n\trankdir=LR;\n\n' for k, o in nodes: s += '\t"%s" [ label="%s" ];\n' % (o, k) s += "\n" for k, o in nodes: parent, remainder = self._findroot(o[:-1]) remainder = remainder[1:] + o[-1] if parent != ".": parent = self[parent] s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o, remainder) s += "}\n" do_graph(s, **kargs)
def _make_graph(self, other_keys=[], **kargs): nodes = [(k,self[k]) for k in self.keys()] oids = [self[k] for k in self.keys()] for k in other_keys: if k not in oids: nodes.append(self.oidname(k),k) s = 'digraph "mib" {\n\trankdir=LR;\n\n' for k,o in nodes: s += '\t"%s" [ label="%s" ];\n' % (o,k) s += "\n" for k,o in nodes: parent,remainder = self._findroot(o[:-1]) remainder = remainder[1:]+o[-1] if parent != ".": parent = self[parent] s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o,remainder) s += "}\n" do_graph(s, **kargs)
def conversations( self, getsrcdst=None, # type: Optional[Callable[[Packet], Tuple[Any, ...]]] # noqa: E501 **kargs # type: Any ): # type: (...) -> Any """Graphes a conversations between sources and destinations and display it (using graphviz and imagemagick) :param 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 :param type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option :param target: filename or redirect. Defaults pipe to Imagemagick's display program :param prog: which graphviz program to use """ if getsrcdst is None: def _getsrcdst(pkt): # type: (Packet) -> Tuple[str, str] """Extract src and dst addresses""" if 'IP' in pkt: return (pkt['IP'].src, pkt['IP'].dst) if 'IPv6' in pkt: return (pkt['IPv6'].src, pkt['IPv6'].dst) if 'ARP' in pkt: return (pkt['ARP'].psrc, pkt['ARP'].pdst) raise TypeError() getsrcdst = _getsrcdst conv = {} # type: Dict[Tuple[Any, ...], Any] for p in self.res: p = self._elt2pkt(p) try: c = getsrcdst(p) except Exception: # 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 six.iteritems(conv): 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 _make_graph(self, other_keys=None, **kargs): if other_keys is None: other_keys = [] nodes = [(self[key], key) for key in self.iterkeys()] oids = set(self.iterkeys()) for k in other_keys: if k not in oids: nodes.append(self.oidname(k), k) s = 'digraph "mib" {\n\trankdir=LR;\n\n' for k, o in nodes: s += '\t"%s" [ label="%s" ];\n' % (o, k) s += "\n" for k, o in nodes: parent, parent_key, remainder = self._findroot(o[:-1]) remainder = remainder[1:] + o[-1] if parent != ".": parent = parent_key s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o, remainder) s += "}\n" do_graph(s, **kargs)
def _make_graph(self, other_keys=None, **kargs): if other_keys is None: other_keys = [] nodes = [(self[k], k) for k in six.iterkeys(self)] oids = self.keys() for k in other_keys: if k not in oids: nodes.append(self.oidname(k), k) s = 'digraph "mib" {\n\trankdir=LR;\n\n' for k, o in nodes: s += '\t"%s" [ label="%s" ];\n' % (o, k) s += "\n" for k, o in nodes: parent, parent_key, remainder = self._findroot(o[:-1]) remainder = remainder[1:] + o[-1] if parent != ".": parent = parent_key s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o, remainder) s += "}\n" do_graph(s, **kargs)
def graph(self, **kargs): g = ['digraph "pipe" {', "\tnode [shape=rectangle];", ] for p in self.active_pipes: g.append('\t"%i" [label="%s"];' % (id(p), p.name)) g.append("") g.append("\tedge [color=blue, arrowhead=vee];") for p in self.active_pipes: for q in p.sinks: g.append('\t"%i" -> "%i";' % (id(p), id(q))) g.append("") g.append("\tedge [color=purple, arrowhead=veevee];") for p in self.active_pipes: for q in p.high_sinks: g.append('\t"%i" -> "%i";' % (id(p), id(q))) g.append("") g.append("\tedge [color=red, arrowhead=diamond];") for p in self.active_pipes: for q in p.trigger_sinks: g.append('\t"%i" -> "%i";' % (id(p), id(q))) g.append('}') graph = "\n".join(g) do_graph(graph, **kargs)
def graph(self, **kargs): s = 'digraph "%s" {\n' % self.__class__.__name__ se = "" # Keep initial nodes at the beginning for better rendering for st in six.itervalues(self.states): if st.atmt_initial: se = ( '\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state) + se # noqa: E501 elif st.atmt_final: se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state # noqa: E501 elif st.atmt_error: se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state # noqa: E501 s += se for st in six.itervalues(self.states): for n in st.atmt_origfunc.__code__.co_names + st.atmt_origfunc.__code__.co_consts: # noqa: E501 if n in self.states: s += '\t"%s" -> "%s" [ color=green ];\n' % ( st.atmt_state, n) # noqa: E501 for c, k, v in ( [("purple", k, v) for k, v in self.conditions.items()] + # noqa: E501 [("red", k, v) for k, v in self.recv_conditions.items()] + # noqa: E501 [("orange", k, v) for k, v in self.ioevents.items()]): for f in v: for n in f.__code__.co_names + f.__code__.co_consts: if n in self.states: line = f.atmt_condname for x in self.actions[f.atmt_condname]: line += "\\l>[%s]" % x.__name__ s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % ( k, n, line, c) # noqa: E501 for k, v in six.iteritems(self.timeout): for t, f in v: if f is None: continue for n in f.__code__.co_names + f.__code__.co_consts: if n in self.states: line = "%s/%.1fs" % (f.atmt_condname, t) for x in self.actions[f.atmt_condname]: line += "\\l>[%s]" % x.__name__ s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % ( k, n, line) # noqa: E501 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 # noqa: E501 target: filename or redirect. Defaults pipe to Imagemagick's display program # noqa: E501 prog: which graphviz program to use""" if getsrcdst is None: def getsrcdst(pkt): """Extract src and dst addresses""" if 'IP' in pkt: return (pkt['IP'].src, pkt['IP'].dst) if 'IPv6' in pkt: return (pkt['IPv6'].src, pkt['IPv6'].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 six.iteritems(conv): 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 graph(self, **kargs): s = 'digraph "%s" {\n' % self.__class__.__name__ se = "" # Keep initial nodes at the begining for better rendering for st in six.itervalues(self.states): 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 six.itervalues(self.states): for n in st.atmt_origfunc.__code__.co_names+st.atmt_origfunc.__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.__code__.co_names+f.__code__.co_consts: if n in self.states: l = f.atmt_condname for x in self.actions[f.atmt_condname]: l += "\\l>[%s]" % x.__name__ s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k,n,l,c) for k,v in six.iteritems(self.timeout): for t,f in v: if f is None: continue for n in f.__code__.co_names+f.__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.__name__ s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k,n,l) s += "}\n" return do_graph(s, **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 = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((a, a) for a in x)) if m == M: m = 0 if M == 0: M = 1 return m, M mins, maxs = minmax(x for x, _ in six.itervalues(sl)) mine, maxe = minmax(x for x, _ in six.itervalues(el)) mind, maxd = minmax(six.itervalues(dl)) 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' % ( repr(s), repr(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' % ( repr(e), repr(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' % ( repr(d), repr(d), n, n) gr += "###\n" for s in sl: n, l = sl[s] for e in l: gr += ' "src.%s" -> "evt.%s";\n' % (repr(s), repr(e)) for e in el: n, l = el[e] for d in l: gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e), repr(d)) gr += "}" return do_graph(gr, **kargs)
def graph(self, **kargs): s = self.build_graph() return do_graph(s, **kargs)
def afterglow( self, src=None, # type: Optional[Callable[[_Inner], Any]] event=None, # type: Optional[Callable[[_Inner], Any]] dst=None, # type: Optional[Callable[[_Inner], Any]] **kargs # type: Any ): # type: (...) -> Any """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[0]['IP'].src if event is None: event = lambda *x: x[0]['IP'].dport if dst is None: dst = lambda *x: x[0]['IP'].dst sl = {} # type: Dict[Any, Tuple[Union[float, int], List[Any]]] el = {} # type: Dict[Any, Tuple[Union[float, int], List[Any]]] dl = {} # type: Dict[Any, int] for i in self.res: try: s, e, d = src(i), event(i), dst(i) if s in sl: n, lst = sl[s] n += 1 if e not in lst: lst.append(e) sl[s] = (n, lst) else: sl[s] = (1, [e]) if e in el: n, lst = el[e] n += 1 if d not in lst: lst.append(d) el[e] = (n, lst) else: el[e] = (1, [d]) dl[d] = dl.get(d, 0) + 1 except Exception: continue def minmax(x): # type: (Any) -> Tuple[int, int] m, M = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((a, a) for a in x)) if m == M: m = 0 if M == 0: M = 1 return m, M mins, maxs = minmax(x for x, _ in six.itervalues(sl)) mine, maxe = minmax(x for x, _ in six.itervalues(el)) mind, maxd = minmax(six.itervalues(dl)) gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' gr += "# src nodes\n" for s in sl: n, _ = 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' % ( repr(s), repr(s), n, n) # noqa: E501 gr += "# event nodes\n" for e in el: n, _ = el[e] 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' % ( repr(e), repr(e), n, n) # noqa: E501 for d in dl: n = dl[d] 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' % ( repr(d), repr(d), n, n) # noqa: E501 gr += "###\n" for s in sl: n, lst1 = sl[s] for e in lst1: gr += ' "src.%s" -> "evt.%s";\n' % (repr(s), repr(e)) for e in el: n, lst2 = el[e] for d in lst2: gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e), repr(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(n)/4.0 def minmax(x): m, M = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((a, a) for a in x)) if m == M: m = 0 if M == 0: M = 1 return m, M mins, maxs = minmax(x for x, _ in sl.itervalues()) mine, maxe = minmax(x for x, _ in el.itervalues()) mind, maxd = minmax(dl.itervalues()) 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' % (repr(s),repr(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' % (repr(e),repr(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' % (repr(d),repr(d),n,n) gr += "###\n" for s in sl: n,l = sl[s] for e in l: gr += ' "src.%s" -> "evt.%s";\n' % (repr(s),repr(e)) for e in el: n,l = el[e] for d in l: gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e),repr(d)) gr += "}" return do_graph(gr, **kargs)
def graph(self, **kargs): # type: (Any) -> Optional[str] s = self.build_graph() return do_graph(s, **kargs)