1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#!/usr/bin/python
# -*- 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]')
print (' overlap=false')
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 +=",group=\""+v['external-ip'].replace(".","")+"\""
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)
|