Tangle
Check-in [10a6f3b93e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Version 0.2
Timelines: family | ancestors | descendants | both | trunk | 0.2
Files: files | file ages | folders
SHA1:10a6f3b93ed310cd845f1b97b84b1afbbd4fa95d
User & Date: alaric 2012-04-11 13:28:29
Context
2012-04-11
13:28
Version 0.3 check-in: 3a2fdd376f user: alaric tags: trunk, 0.3
13:28
Version 0.2 check-in: 10a6f3b93e user: alaric tags: trunk, 0.2
13:27
Version 0.1 check-in: 7c28e7c533 user: alaric tags: trunk, 0.1
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to README.txt.

5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
..
29
30
31
32
33
34
35

36
37
38
39
40
41
42
...
211
212
213
214
215
216
217
218
219
220
221
222




















It takes a text file that lists:

 * Endpoint devices (eg, servers, workstations)
 * Switches, routers, firewalls
 * Management devices (eg, console/KVM servers, managed PDUs)
 * Network cables
 * Power cables
 * Serial/KVM cables


 * VLANs
 * IPv4 subnets
 * External networks (ISP networks, the phone network, etc)
 * Organisations (that own equipment)

...and how they interconnect.

................................................................................
A simple (all too simple) driver shell script is supplied, called
`document-network.sh`, that runs parts of Tangle to make a veritable
soup of network documentation.

Try it out on the supplied examples. From this directory, run:

    ./document-network.sh examples/home-lan.tangle


...then look at the HTML and PNG files that appear in the examples directory.

# The tangle file format

The network consists of cables, vlans, devices, and ip4 subnets.

................................................................................
* Serial/KVM "splitter" cables
* ...and maybe other uses in future.

We can currently create VLANs on non-Ethernet cables, just it looks
odd; they should be renamed from "VLANs" to "virtual circuits" or some
shorter phrasing.

## More examples

We really need to show off how we do management interfaces in
switches, virtual machines, Cisco router loopback addresses, and other
such more esoteric tricks with virtual cables.



























|
>
>







 







>







 







|

|
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
...
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
It takes a text file that lists:

 * Endpoint devices (eg, servers, workstations)
 * Switches, routers, firewalls
 * Management devices (eg, console/KVM servers, managed PDUs)
 * Network cables
 * Power cables
 * Serial/KVM/USB/parallel cables
 * Telephone cables (for analogue phones that don't go over UTP)
 * Telephones
 * VLANs
 * IPv4 subnets
 * External networks (ISP networks, the phone network, etc)
 * Organisations (that own equipment)

...and how they interconnect.

................................................................................
A simple (all too simple) driver shell script is supplied, called
`document-network.sh`, that runs parts of Tangle to make a veritable
soup of network documentation.

Try it out on the supplied examples. From this directory, run:

    ./document-network.sh examples/home-lan.tangle
    ./document-network.sh examples/office-lan.tangle

...then look at the HTML and PNG files that appear in the examples directory.

# The tangle file format

The network consists of cables, vlans, devices, and ip4 subnets.

................................................................................
* Serial/KVM "splitter" cables
* ...and maybe other uses in future.

We can currently create VLANs on non-Ethernet cables, just it looks
odd; they should be renamed from "VLANs" to "virtual circuits" or some
shorter phrasing.

Suggestion: s/vlan/circuit/ but keep "vlan" as a parser-level synonym.

And add a "type" declaration within a circuit declaration, with values
matching {ethernet|power|other}.


## Generalise device/cable types

The core engine has a fixed list of device and cable types (and vlan
types?), even though it doesn't really care what they are. Front-end
scripts tend to care more, as they often invoke special rendering for
particular types of object.

Adding to this list involves extending the parser regexps, extending
the documentation, and then extending the various rendering scripts.

It might be nice to have a configuration file that lists all the types
of typable things, and then listing key=value properties for them. The
parser can generate its regexps from the lists, and then frontends can
look up keys to find styling information for specific types.

## Minor issues

* Make ip4 reserved ranges appear as a single row in the IP4 displays
  in the HTML.

Changes to document-network.sh.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
mkdir $TMPDIR

echo "Generating HTML..."
python make-network-html.py < $INPUT > $OUTPUT_HTML

echo "Generating diagrams..."
python make-network-vlan-diagram.py < $INPUT > $TMP_VLANS
python make-network-cabling-diagram.py utp fibre virtual < $INPUT > $TMP_NETWORK_CABLES
python make-network-cabling-diagram.py power kvm serial usb telephone parallel other < $INPUT > $TMP_MANAGEMENT_CABLES

echo "Rendering diagrams..."
neato -Tpng -o $OUTPUT_VLANS $TMP_VLANS
neato -Tpng -o $OUTPUT_NETWORK_CABLES $TMP_NETWORK_CABLES
neato -Tpng -o $OUTPUT_MANAGEMENT_CABLES $TMP_MANAGEMENT_CABLES

echo "Tidying up..."
rm -rf $TMPDIR







|
|








18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
mkdir $TMPDIR

echo "Generating HTML..."
python make-network-html.py < $INPUT > $OUTPUT_HTML

echo "Generating diagrams..."
python make-network-vlan-diagram.py < $INPUT > $TMP_VLANS
python make-network-cabling-diagram.py utp fibre telephone virtual < $INPUT > $TMP_NETWORK_CABLES
python make-network-cabling-diagram.py power kvm serial usb parallel other < $INPUT > $TMP_MANAGEMENT_CABLES

echo "Rendering diagrams..."
neato -Tpng -o $OUTPUT_VLANS $TMP_VLANS
neato -Tpng -o $OUTPUT_NETWORK_CABLES $TMP_NETWORK_CABLES
neato -Tpng -o $OUTPUT_MANAGEMENT_CABLES $TMP_MANAGEMENT_CABLES

echo "Tidying up..."
rm -rf $TMPDIR

Added examples/office-lan.tangle.





















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

# VLANs

vlan core.100 {
     title "Border network"

     ip4 subnet 123.123.123.0/29 "Border network" # 123.123.123.0 - 123.123.123.7
}

# Unused:
#     ip4 subnet 123.123.123.8/29 # 123.123.123.8 - 123.123.123.15
# 123.123.123.8 taken as hades' loopback IP

vlan core.210 {
     title "Backbone"
     ip4 subnet 123.123.123.16/28 "Backbone" # 123.123.123.16 - 123.123.123.31
}

vlan core.220 {
     title "Public-facing servers"
     ip4 subnet 123.123.123.32/27 "Public-facing servers" # 123.123.123.32 - 123.123.123.63
}

vlan core.300 {
     title "Workstations"
     ip4 subnet 192.168.1.0/24 "Workstations"
}

vlan core.310 {
     title "Wifi"
     ip4 subnet 192.168.2.0/24 "Wifi"
     ip4 reserved 192.168.2.2-192.168.2.254 "DHCP"
}

vlan core.320 {
     title "Internal servers"
     ip4 subnet 192.168.3.0/24 "Internal servers"
}

vlan core.400 {
     title "Management"
     ip4 subnet 192.168.100.0/24 "Management"
}

# Server Room

## Core Network

device core-switch {
       type switch
       # This IP address is attached to the "management" port
       # of the switch, via a virtual cable (see below)
       ip4 management 192.168.100.10
}

virtual core-switch-mgmt {
	# Here we show how the management interface of a switch
	# works. It's a virtual cable with only one "end",
	# thereby assigning a VLAN to the port "management" on the switch.
	device core-switch/management
	vlan core.400
}

device hades {
       type router
       note "Cisco 2800"
       note "Border router"
       ip4 loopback 123.123.123.8 stub
       ip4 internal core.210 123.123.123.17
       ip4 internal core.220 123.123.123.33
       ip4 external 123.123.123.2
}

virtual hades-loopback {
	device hades/loopback
}

utp 001 {
    device hades/internal
    device core-switch/1
    tagged vlans core.210,core.220
}

serial s1 {
       device hades/console
       device boris/com0
}

device isp {
       type external
       ip4 ntu core.100 123.123.123.1
}

fibre external-fibre {
      device isp/ntu
      device hades/external
      vlan core.100
}

device bovril {
       type firewall
       note "Cisco ASA"
       note "Firewall"
       note "Provides DHCP to 192.168.2.1 on core.310"
       ip4 external 123.123.123.18
       ip4 internal core.300 192.168.1.254
       ip4 internal core.310 192.168.2.1
       ip4 internal core.320 192.168.3.1
       ip4 internal core.400 192.168.100.1
}

serial s2 {
       device bovril/console
       device boris/com1
}

utp 002 {
    device bovril/external
    device core-switch/2
    vlan core.210
}

utp 003 {
    device bovril/internal
    device core-switch/3
    tagged vlans core.300,core.310,core.320,core.400
}

## External Servers

device alice {
       type server
       note "Web/mail server"
       ip4 eth0 123.123.123.34
}

utp 004 {
    device alice/eth0
    device core-switch/4
    vlan  core.220
}

## Internal Servers

device internal-switch {
       type switch
       ip4 management 192.168.100.11
}

virtual internal-switch-mgmt {
	device internal-switch/management
	vlan core.400
}

utp 005 {
    device core-switch/5
    device internal-switch/1
    tagged vlans core.320,core.400,core.310,core.300
}

device boris {
       type server
       note "Workgroup Fileserver"
       ip4 eth0 192.168.3.10
}

utp i002 {
    device internal-switch/2
    device boris/eth0
    vlan core.320
}

device keith {
       type server
       note "VM host"
       ip4 eth0 192.168.3.12
       hosts build-linux
       hosts build-freebsd
}

utp i003 {
    device internal-switch/3
    device keith/eth0
    vlan core.320
}

device build-linux {
       type virtual
       note "Linux build server"
       ip4 eth0 192.168.3.40
}

device build-freebsd {
       type virtual
       note "FreeBSD build server"
       ip4 rtk0 192.168.3.41
}

virtual keith-vswitch {
	device build-linux/eth0
	device build-freebsd/rtk0
	device keith/vif0
	vlan core.320
}

device laserjet {
       type printer
       ip4 ethernet 192.168.3.20
}

utp i004 {
    device internal-switch/4
    device laserjet/ethernet
    vlan core.320
}

## Power management

device pdu1 {
       type manager
       ip4 ethernet 192.168.100.5
}

utp i007 {
    device internal-switch/7
    device pdu1/ethernet
    vlan core.400
}

power P1 {
      device pdu1/1
      device core-switch/ac
}

power P2 {
      device pdu1/2
      device hades/ac
}

power P3 {
      device pdu1/3
      device bovril/ac
}

power P4 {
      device pdu1/4
      device alice/ac
}

power P5 {
      device pdu1/5
      device internal-switch/ac
}

power P6 {
      device pdu1/6
      device boris/ac
}

power P7 {
      device pdu1/7
      device keith/ac
}

power P8 {
      device pdu1/8
      device exchange/ac
}

## Phone system

device exchange {
       type router
       note "Telephone local exchange unit"
       ip4 voip 123.123.123.35
}

utp i008 {
    device internal-switch/8
    device exchange/management
    vlan core.400
}

utp i009 {
    device internal-switch/9
    device exchange/voip
    vlan core.220
}

# Main Office

device office-switch {
       type switch
       ip4 management 192.168.100.12
}

virtual office-switch-mgmt {
	device office-switch/management
	vlan core.400
}

utp i005 {
    device internal-switch/5
    device office-switch/48
    tagged vlans core.400,core.320
}

## Workstations

device pc001 {
       type workstation
       ip4 eth 192.168.1.1
}

utp o001 {
      device pc001/eth
      device office-switch/1
      vlan core.300
}

device pc002 {
       type workstation
       ip4 eth 192.168.1.2
}

utp o002 {
      device pc002/eth
      device office-switch/2
      vlan core.300
}

device pc003 {
       type workstation
       ip4 eth 192.168.1.3
}

utp o003 {
      device pc003/eth
      device office-switch/3
      vlan core.300
}

device pc004 {
       type workstation
       ip4 eth 192.168.1.4
}

utp o004 {
      device pc004/eth
      device office-switch/4
      vlan core.300
}

device pc005 {
       type workstation
       ip4 eth 192.168.1.5
}

utp o005 {
      device pc005/eth
      device office-switch/5
      vlan core.300
}

device pc006 {
       type workstation
       ip4 eth 192.168.1.6
}

utp o006 {
      device pc006/eth
      device office-switch/6
      vlan core.300
}

device pc007 {
       type workstation
       ip4 eth 192.168.1.7
}

utp o007 {
      device pc007/eth
      device office-switch/7
      vlan core.300
}

device pc008 {
       type workstation
       ip4 eth 192.168.1.8
}

utp o008 {
      device pc008/eth
      device office-switch/8
      vlan core.300
}

device pc009 {
       type workstation
       ip4 eth 192.168.1.9
}

utp o009 {
      device pc009/eth
      device office-switch/9
      vlan core.300
}

device pc010 {
       type workstation
       ip4 eth 192.168.1.10
}

utp o010 {
      device pc010/eth
      device office-switch/10
      vlan core.300
}

## Wifi

device wifi-bridge {
       type other
       ip4 ethernet core.400 192.168.100.20
}

virtual wifi {
	device wifi-bridge/wifi
	vlan core.310
}

utp i006 {
    device wifi-bridge/ethernet
    device internal-switch/6
    tagged vlans core.400,core.310
}

## Phones

device phone001 {
       type telephone
}

telephone p001 {
	  device exchange/1
	  device phone001/tel
	  vlan phones
}

device phone002 {
       type telephone
}

telephone p002 {
	  device exchange/2
	  device phone002/tel
	  vlan phones
}

device phone003 {
       type telephone
}

telephone p003 {
	  device exchange/3
	  device phone003/tel
	  vlan phones
}

device phone004 {
       type telephone
}

telephone p004 {
	  device exchange/4
	  device phone004/tel
	  vlan phones
}

device phone005 {
       type telephone
}

telephone p005 {
	  device exchange/5
	  device phone005/tel
	  vlan phones
}

device phone006 {
       type telephone
}

telephone p006 {
	  device exchange/6
	  device phone006/tel
	  vlan phones
}

device phone007 {
       type telephone
}

telephone p007 {
	  device exchange/7
	  device phone007/tel
	  vlan phones
}

device phone008 {
       type telephone
}

telephone p008 {
	  device exchange/8
	  device phone008/tel
	  vlan phones
}

device phone009 {
       type telephone
}

telephone p009 {
	  device exchange/9
	  device phone009/tel
	  vlan phones
}

device phone010 {
       type telephone
}

telephone p010 {
	  device exchange/10
	  device phone010/tel
	  vlan phones
}

Changes to make-network-cabling-diagram.py.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33


34
35
36
37
38
39
40
   print "// Devices"
   print
   
   for deviceName in cabling.devices:
      device = cabling.devices[deviceName]
      deviceType = device.deviceType
      
      if deviceType == "router":
         print "device%s [shape=\"hexagon\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "switch":
         print "device%s [shape=\"trapezium\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "manager" or deviceType == "power":
         print "device%s [shape=\"parallelogram\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "external":
         print "device%s [shape=\"triangle\" label=\"%s\"];" % (makeName(deviceName),deviceName)


      elif deviceType == "virtual":
         print "device%s [shape=\"box\" style=\"dashed\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      else:
         print "device%s [shape=\"box\" label=\"%s\"];" % (makeName(deviceName),deviceName)

   print
   print "// Virtualisation"







|







>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
   print "// Devices"
   print
   
   for deviceName in cabling.devices:
      device = cabling.devices[deviceName]
      deviceType = device.deviceType
      
      if deviceType == "router" or deviceType == "firewall":
         print "device%s [shape=\"hexagon\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "switch":
         print "device%s [shape=\"trapezium\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "manager" or deviceType == "power":
         print "device%s [shape=\"parallelogram\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "external":
         print "device%s [shape=\"triangle\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "telephone":
         print "device%s [shape=\"diamond\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      elif deviceType == "virtual":
         print "device%s [shape=\"box\" style=\"dashed\" label=\"%s\"];" % (makeName(deviceName),deviceName)
      else:
         print "device%s [shape=\"box\" label=\"%s\"];" % (makeName(deviceName),deviceName)

   print
   print "// Virtualisation"

Changes to make-network-vlan-diagram.py.

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
      for link in vlan.ports:
         (deviceName,port,cable) = link
         
         deviceType = cabling.devices[deviceName].deviceType
         cableType = cabling.cables[cable.name].cableType
         
         # Only show switches if this is a virtual cable, eg their admin port
         if deviceType == "switch":
            if cableType == "virtual":
               print "vlan%s -- device%s [headlabel=\"%s\" style=\"dotted\"];" % (makeName(vlanName), makeName(deviceName), port)
            else:

               pass # Ignore
         else:
            print "vlan%s -- device%s [headlabel=\"%s\"];" % (makeName(vlanName), makeName(deviceName), port)
            
         
   print "}"

# 1) Load and process configration

cabling = network.loadCabling (sys.stdin)

# 2) Print it out nicely

printVLANDiagram (cabling)







<
|
|
|
>
|
|
|











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
      for link in vlan.ports:
         (deviceName,port,cable) = link
         
         deviceType = cabling.devices[deviceName].deviceType
         cableType = cabling.cables[cable.name].cableType
         
         # Only show switches if this is a virtual cable, eg their admin port

         if cableType == "virtual":
            print "vlan%s -- device%s [headlabel=\"%s\" style=\"dotted\"];" % (makeName(vlanName), makeName(deviceName), port)
         else:
            if deviceType == "switch":
               pass # ignore non-virtual cables to switches, it just clutters stuff
            else:
               print "vlan%s -- device%s [headlabel=\"%s\"];" % (makeName(vlanName), makeName(deviceName), port)
            
         
   print "}"

# 1) Load and process configration

cabling = network.loadCabling (sys.stdin)

# 2) Print it out nicely

printVLANDiagram (cabling)