{josuah.net} | {panoramix-labs.fr}
 (DIR)  • {josuah.net}
 (DIR)  • {panoramix-labs.fr}
       
        {git} | {cv} | {links} | {quotes} | {ascii} | {tgtimes} | {gopher} | {mail}
 (DIR)  • {git}
 (BIN)  • {cv}
 (DIR)  • {links}
 (DIR)  • {quotes}
 (DIR)  • {ascii}
 (HTM)  • {tgtimes}
 (DIR)  • {gopher}
       
       ━━━━━━
       netini
       ━━━━━━
 (TXT)  `git://git.josuah.net/netini` - {0.4}
       
 (IMG)  {{network graph generated by netini}}
       
        Network layer topology in red, physical connexions in grey.
       
       What is it for?
       ───────────────
        Plotting networks is extremely useful for understanding how it works and
        troubleshoot problems. Particularly when you do not know the network in
        advance.
       
        In theory, from an access to that place's router and switches, using arp tables
        and mac address tables, you can guess some of the L1/L2/L3 topology.
       
        netini is a toolset doing this: build network graph out of simple declarative
        config files, and generate config files out of raw command output from routers
        and switches.
       
       How to use it?
       ──────────────
 (DIR)  The {netini-dot(1)} tool generating the plots is reading a trivial .ini format
        from all files passed as argument:
       
        Example for a network named `sky`:
       
        ┊ [net]
        ┊ name = skynet-wan-knet
        ┊ ip = 92.118.99.140/30
        ┊ 
        ┊ [net]
        ┊ name = skynet-lan-user
        ┊ ip = 10.191.10.0/23
        ┊ vlan = 10
        ┊ 
        ┊ [net]
        ┊ name = skynet-lan-server
        ┊ ip = 10.191.20.0/24
        ┊ vlan = 20
        ┊ 
        ┊ [net]
        ┊ name = skynet-lan-admin
        ┊ ip = 10.191.30.0/24
        ┊ vlan = 20
        ┊ 
        ┊ [host]
        ┊ name = skynet-modem-knet-1
        ┊ ip = 92.118.99.141
        ┊ 
        ┊ [host]
        ┊ name = skynet-router-1
        ┊ ip = 92.118.99.142
        ┊ ip = 10.191.10.1
        ┊ ip = 10.191.20.1
        ┊ ip = 10.191.30.1
        ┊ 
        ┊ [host]
        ┊ name = skynet-switch-1
        ┊ ip = 10.191.30.2
        ┊ link = skynet-router-1
        ┊ link = 0c:1c:20:69:d8:d8
        ┊ link = 08:4a:cf:e6:d0:08
        ┊ link = e8:5b:5b:b1:5d:db
        ┊ link = 5c:d2:e4:1b:1e:ee
        ┊ 
        ┊ [host]
        ┊ name = skynet-switch-2
        ┊ ip = 10.191.30.2
        ┊ link = skynet-router-1
        ┊ link = 00:c0:a3:91:9d:e2
        ┊ link = 48:9d:24:c9:f8:79
        ┊ link = f4:32:3d:40:c6:18
        ┊ link = 84:18:26:bd:88:2d
        ┊ 
        ┊ [host]
        ┊ name = skynet-workstation-1
        ┊ ip = 10.191.10.1
        ┊ link = 0c:1c:20:69:d8:d8
        ┊ 
        ┊ [host]
        ┊ name = skynet-workstation-2
        ┊ ip = 10.191.10.1
        ┊ link = 08:4a:cf:e6:d0:08
        ┊ ...
       
        All hosts with IPs that fit a network are linked automatically to it on the
        plot.
       
        `link=` variables in hosts permit to build L1 links by using a hostname, a MAC
        address or an IP as value.
       
        Any other detail might be added, and will be shown on the item label.
       
        Other tools are available to generate parts of these configuration files from
        command output coming from local hosts or routers.
       
       How is the matching done?
       ─────────────────────────
        Connecting hosts to networks is done by defining a network with subnet, and
        adding IPs that belong to that network to the hosts. The classic IP matching
        algorythm does the wiring job on its own. This means that autogenerated output
        can
       
        For link-layer, the `link=` entries of hosts bind them to other hosts.
       
       What does it looks like in practice?
       ────────────────────────────────────
        From this from `arp -a` (or `ip neigh show` on Linux, randomly generated
        here):
       
        ┊ 10.191.10.130 dev wlan0 lladdr 0c:1c:20:69:d8:d8 ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.10.65 dev wlan0 lladdr 08:4a:cf:e6:d0:08 ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.10.28 dev wlan0 lladdr e8:5b:5b:b1:5d:db ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.10.85 dev wlan0 lladdr 08:00:33:00:b7:2e ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.11.239 dev wlan0 lladdr 5c:d2:e4:1b:1e:ee ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.11.105 dev wlan0 lladdr 74:6e:e4:71:05:25 ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.20.36 dev wlan0 lladdr 68:d4:82:66:29:7b ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.20.247 dev wlan0 lladdr ac:19:9f:03:6c:f2 ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.20.113 dev wlan0 lladdr 00:c0:a3:91:9d:e2 ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.20.178 dev wlan0 lladdr 48:9d:24:c9:f8:79 ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.20.11 dev wlan0 lladdr f4:32:3d:40:c6:18 ref 1 used 0/0/0 probes 6 REACHABLE
        ┊ 10.191.20.31 dev wlan0 lladdr 84:18:26:bd:88:2d ref 1 used 0/0/0 probes 6 REACHABLE
       
        `netini-arp linux skynet` turns it into this:
       
        ┊ [host]
        ┊ name = skynet-Kakao-1
        ┊ ip = 10.191.10.130
        ┊ mac = 0c:1c:20:69:d8:d8
        ┊ 
        ┊ [host]
        ┊ name = skynet-Kakao-2
        ┊ ip = 10.191.10.65
        ┊ mac = 0c:1c:20:69:d8:d9
        ┊ 
        ┊ [host]
        ┊ name = skynet-LgElectronics-1
        ┊ ip = 10.191.10.28
        ┊ mac = e8:5b:5b:b1:5d:db
        ┊ 
        ┊ [host]
        ┊ name = skynet-BauschAndLomb-1
        ┊ ip = 10.191.10.85
        ┊ mac = 08:00:33:00:b7:2e
        ┊ 
        ┊ [host]
        ┊ name = skynet-IntelOrate-1
        ┊ ip = 10.191.11.239
        ┊ mac = 5c:d2:e4:1b:1e:ee
        ┊ 
        ┊ [host]
        ┊ name = skynet-AsiaVitalMponents-1
        ┊ ip = 10.191.11.105
        ┊ mac = 74:6e:e4:71:05:25
        ┊ 
        ┊ [host]
        ┊ name = skynet-ShenzhenGongjinElectronics-1
        ┊ ip = 10.191.20.36
        ┊ mac = 68:d4:82:66:29:7b
        ┊ 
        ┊ [host]
        ┊ name = skynet-SungrowPowerSupply-1
        ┊ ip = 10.191.20.247
        ┊ mac = ac:19:9f:03:6c:f2
        ┊ 
        ┊ [host]
        ┊ name = skynet-DualEnterprises-1
        ┊ ip = 10.191.20.113
        ┊ mac = 00:c0:a3:91:9d:e2
        ┊ 
        ┊ [host]
        ┊ name = skynet-BlackberryRts-1
        ┊ ip = 10.191.20.178
        ┊ mac = 48:9d:24:c9:f8:79
        ┊ 
        ┊ [host]
        ┊ name = skynet-SichuanTianyiKangheMmunications-1
        ┊ ip = 10.191.20.11
        ┊ mac = f4:32:3d:40:c6:18
        ┊ 
        ┊ [host]
        ┊ name = skynet-Osram-1
        ┊ ip = 10.191.20.31
        ┊ mac = 84:18:26:bd:88:2d
       
        `netini-dot` turns it into this:
       
        ┊ graph G {
        ┊         { "skynet-Kakao-1" [shape=rectangle; label="skynet-Kakao-1\nip 10.191.10.130\nmac 0c:1c:20:69:d8:d8\n"] }
        ┊         { "skynet-GuangdongOppoMobileTelecommunications-1" [shape=rectangle; label="skynet-GuangdongOppoMobileTelecommunications-1\nip 10.191.10.65\nmac 08:4a:cf:e6:d0:08\n"] }
        ┊         { "skynet-LgElectronics-1" [shape=rectangle; label="skynet-LgElectronics-1\nip 10.191.10.28\nmac e8:5b:5b:b1:5d:db\n"] }
        ┊         { "skynet-BauschAndLomb-1" [shape=rectangle; label="skynet-BauschAndLomb-1\nip 10.191.10.85\nmac 08:00:33:00:b7:2e\n"] }
        ┊         { "skynet-IntelOrate-1" [shape=rectangle; label="skynet-IntelOrate-1\nip 10.191.11.239\nmac 5c:d2:e4:1b:1e:ee\n"] }
        ┊         { "skynet-AsiaVitalMponents-1" [shape=rectangle; label="skynet-AsiaVitalMponents-1\nip 10.191.11.105\nmac 74:6e:e4:71:05:25\n"] }
        ┊         { "skynet-ShenzhenGongjinElectronics-1" [shape=rectangle; label="skynet-ShenzhenGongjinElectronics-1\nip 10.191.20.36\nmac 68:d4:82:66:29:7b\n"] }
        ┊         { "skynet-SungrowPowerSupply-1" [shape=rectangle; label="skynet-SungrowPowerSupply-1\nip 10.191.20.247\nmac ac:19:9f:03:6c:f2\n"] }
        ┊         { "skynet-DualEnterprises-1" [shape=rectangle; label="skynet-DualEnterprises-1\nip 10.191.20.113\nmac 00:c0:a3:91:9d:e2\n"] }
        ┊         { "skynet-BlackberryRts-1" [shape=rectangle; label="skynet-BlackberryRts-1\nip 10.191.20.178\nmac 48:9d:24:c9:f8:79\n"] }
        ┊         { "skynet-SichuanTianyiKangheMmunications-1" [shape=rectangle; label="skynet-SichuanTianyiKangheMmunications-1\nip 10.191.20.11\nmac f4:32:3d:40:c6:18\n"] }
        ┊         { "skynet-Osram-1" [shape=rectangle; label="skynet-Osram-1\nip 10.191.20.31\nmac 84:18:26:bd:88:2d\n"] }
        ┊ }
       
 (HTM)  Finally plotted by {graphviz}.
       
        Note that extra data can be added at each step, and `netini-merge` lets one
        have manual entries that override the autogenerated ones.
       
       How did you get these device brand names out of numbers?
       ────────────────────────────────────────────────────────
        Each MAC address has its 6 first bytes ("OUI") associated to a manufacturer, so
        the `netini-oui` tool downloads the definition a
        [`oui.csv`(http://standards-oui.ieee.org/oui/oui.csv) from IANA to resolve the
        OUI identifiers.
       
        The heuristics comes from a WireShark python script.
       
       More features?
       ──────────────
        Mail me your suggestions as a request or as a patch.