diff options
Diffstat (limited to 'retiolum/scripts/adv_graphgen')
| -rw-r--r-- | retiolum/scripts/adv_graphgen/README | 28 | ||||
| -rwxr-xr-x | retiolum/scripts/adv_graphgen/parse.py | 101 | ||||
| -rwxr-xr-x | retiolum/scripts/adv_graphgen/sanitize.sh | 13 | 
3 files changed, 142 insertions, 0 deletions
| diff --git a/retiolum/scripts/adv_graphgen/README b/retiolum/scripts/adv_graphgen/README new file mode 100644 index 00000000..082e0f2b --- /dev/null +++ b/retiolum/scripts/adv_graphgen/README @@ -0,0 +1,28 @@ +The folder contains a number of scripts which provide a convenient way to +generate advanced graphs from the SIGUSR2 output of tinc. + +it currently contains the following files: + +sanitize.sh: +    wrapper arond parse.py which filters the syslog file for all tinc +    related lines and removes the status informations:  +    this means that +    <code> +    May 19 20:40:44 servarch dnsmasq[5382]: reading /etc/resolv.conf +    May 19 20:41:38 servarch tinc.retiolum[4780]: Error looking up pa-sharepoint.informatik.ba-stuttgart.de port 655: Name or service not known +    </code> +    becomes +    <code> +    Error looking up pa-sharepoint.informatik.ba-stuttgart.de port 655: Name or service not known +    </code> +    and so on. +    It also provides a wrapper around graphviz which automagically +    generates graphs from the produced graph file + +parse.py: +    reads from stdin the sanitized syslog file and prints a valid dot file +    from the given output. +    The parser module may also produce any other output (e.g. for dns +    entries and so on) you will need to actually read and modify the source +    in order to be able to do this. ~May the source be with you~ +     diff --git a/retiolum/scripts/adv_graphgen/parse.py b/retiolum/scripts/adv_graphgen/parse.py new file mode 100755 index 00000000..639c5316 --- /dev/null +++ b/retiolum/scripts/adv_graphgen/parse.py @@ -0,0 +1,101 @@ +#!/usr/bin/python2 +# -*- coding: utf8 -*- + +import sys +""" TODO: Refactoring needed to pull the edges out of the node structures again, +it should be easier to handle both structures""" + +def write_digraph(nodes): +  """ +  writes the complete digraph in dot format +  """ +  print ('digraph retiolum {') +  print ('  node[shape=box,style=filled,fillcolor=grey]') +  generate_stats(nodes) +  nodes = delete_unused_nodes(nodes) +  merge_edges(nodes) +  for k,v in nodes.iteritems(): +    write_node(k,v) +  print ('}') +def generate_stats(nodes): +  """ Generates some statistics of the network and nodes +  """ +  for k,v in nodes.iteritems(): +    v['num_conns'] = len(v.get('to',[])) +def delete_unused_nodes(nodes): +  new_nodes = {} +  for k,v in nodes.iteritems(): +    if v.get('to',[]): +      new_nodes[k] = v +  return new_nodes +def merge_edges(nodes): +  """ merge back and forth edges into one +  DESTRUCTS the current structure by deleting "connections" in the nodes + +  """ +  for k,v in nodes.iteritems(): +    for con in v.get('to',[]): +      for i,secon in enumerate(nodes[con['name']].get('to',[])): +        if k == secon['name']: +          del (nodes[con['name']]['to'][i]) +          con['bidirectional'] = True + + +def write_node(k,v): +  """ writes a single node and its edges  +      edges are weightet with the informations inside the nodes provided by +      tinc +  """ +  node = "  "+k+"[label=\"" +  node += k+"\\l" +  node += "external:"+v['external-ip']+":"+v['external-port']+"\\l" +  if v.has_key('num_conns'): +    node += "Num Connects:"+str(v['num_conns'])+"\\l" +  for addr in v.get('internal-ip',['¯\\\\(°_o)/¯']): +    node += "internal:"+addr+"\\l" +  node +="\"" +  if v['external-ip'] == "MYSELF": +    node += ",fillcolor=steelblue1" +  node += "]" +  print node + +  for con in v.get('to',[]): +    edge = "  "+k+ " -> " +con['name'] + "[weight="+str(float(con['weight'])) +    if con.get('bidirectional',False): +      edge += ",dir=both" +    edge += "]" +    print edge + +def parse_input(): +  nodes={} +  for line in sys.stdin: +    line = line.replace('\n','') +    if line == 'Nodes:': +      nodes={} +      for line in sys.stdin: +        if line == 'End of nodes.\n': +          break +        l = line.replace('\n','').split() #TODO unhack me +        nodes[l[0]]= { 'external-ip': l[2], 'external-port' : l[4] } +    if line == 'Subnet list:': +      for line in sys.stdin: +        if line == 'End of subnet list.\n': +          break +        l = line.replace('\n','').split()  +        if not nodes[l[2]].get('internal-ip',False): +           nodes[l[2]]['internal-ip'] = [] +        nodes[l[2]]['internal-ip'].append(l[0].split('#')[0]) +    if line == 'Edges:': +      edges = {} +      for line in sys.stdin: +        if line == 'End of edges.\n': +          break +        l = line.replace('\n','').split()  + +        if not nodes[l[0]].has_key('to') : +          nodes[l[0]]['to'] = [] +        nodes[l[0]]['to'].append( +            {'name':l[2],'addr':l[4],'port':l[6],'weight' : l[10] }) +  return nodes +nodes = parse_input() +write_digraph(nodes) diff --git a/retiolum/scripts/adv_graphgen/sanitize.sh b/retiolum/scripts/adv_graphgen/sanitize.sh new file mode 100755 index 00000000..0e12d207 --- /dev/null +++ b/retiolum/scripts/adv_graphgen/sanitize.sh @@ -0,0 +1,13 @@ +GRAPH_SETTER1=dot +GRAPH_SETTER2=circo +LOG_FILE=/var/log/everything.log +OPENER=/bin/true + +sudo pkill -USR2 tincd +sudo sed -n '/tinc.retiolum/{s/.*tinc.retiolum\[[0-9]*\]: //gp}' $LOG_FILE |\ +    ./parse.py > retiolum.dot + +$GRAPH_SETTER1 -Tpng -o $1retiolum_1.png retiolum.dot +$GRAPH_SETTER2 -Tpng -o $1retiolum_2.png retiolum.dot +$OPENER retiolum_1.png &>/dev/null  +#rm retiolum.dot | 
