|
| 1 | +# mnet |
| 2 | +mnet Suite - Tools for network professionals. |
| 3 | +Michael Laforest `<mjlaforest` *at* `gmail` *dot* `com>` |
| 4 | + |
| 5 | +Automated discovery and diagram tools using SNMP, CDP, and LLDP. |
| 6 | + |
| 7 | +# Support |
| 8 | + |
| 9 | +If you use any of these tools or find them useful please consider donating. |
| 10 | + |
| 11 | +Donation Method | Address | QR Code |
| 12 | +--- | --- | --- |
| 13 | +Bitcoin (BTC) | 1HY3jPYVfE6YZbuYTYfMpazvSKRXjZDMbS | ") |
| 14 | +Bitcoin Cash (BCH) | 1HSycjR3LAZxuLG34aEBbQdUSayPkh8XsH | ") |
| 15 | + |
| 16 | +# Suite Tools |
| 17 | +| Module | Description | |
| 18 | +| --- | --- | |
| 19 | +| Diagram | Discovers a network and generates a diagram based on CDP and LLDP neighbor information. | |
| 20 | +| TraceMAC | Attempts to locate a specific MAC address by recursively looking it up in switch CAM tables. | |
| 21 | +| GetMACS | Collect a list of all MAC addresses on the discovered network and generate a report. | |
| 22 | + |
| 23 | +# Installing mnet |
| 24 | + |
| 25 | +mnet can be installed through Python's pip. |
| 26 | + |
| 27 | +`# pip install mnet` |
| 28 | + |
| 29 | +# Running mnet |
| 30 | + |
| 31 | +### Network Discovery |
| 32 | + |
| 33 | +A network discovery will be performed For the `diagram` and `getmacs` modules. The discovery process will use SNMP, CDP, and LLDP to discover the network topology and details about each node. |
| 34 | + |
| 35 | +The discovery will begin at the specified root node and perform the following actions: |
| 36 | + |
| 37 | +1. Collect a list of adjacencies through CDP and LLDP. |
| 38 | +2. Evaluate each adjacent node against the `discover` ACL. |
| 39 | +3. If the ACL permits discovery then collect information from that node. |
| 40 | +4. If the current discovered depth is less than the user deviced maximum depth, repeat step 1 with this node. |
| 41 | + |
| 42 | +The `discover` ACL is defined in the configuration file as: |
| 43 | + |
| 44 | +``` |
| 45 | +"discover" : [ |
| 46 | + ACE, |
| 47 | + ACE, |
| 48 | + ACE |
| 49 | +] |
| 50 | +``` |
| 51 | + |
| 52 | +An ACE is defined as: |
| 53 | + |
| 54 | +```<permit|deny|leaf|include|;> < [host REGEX] | [ip CIDR] >``` |
| 55 | + |
| 56 | +| Option | Include Node | Collect Node Information | Allow Discovery of Adjacencies | |
| 57 | +| --- |:---:|:---:|:---:| |
| 58 | +| permit | X | X | X | |
| 59 | +| leaf | X | X | | |
| 60 | +| include | X | | | |
| 61 | +| deny | | | | |
| 62 | + |
| 63 | +| Parameter | Description | Example | |
| 64 | +| --- | --- | --- | |
| 65 | +| host REGEX | The host can be matched against any regular expression string. The host string is what is reported from CDP or LLDP. | `host Router-.*` | |
| 66 | +| ip CIDR | The ip can be matched against and CIDR. | `ip 10.50.31.0/24` | |
| 67 | + |
| 68 | +### Diagram Module |
| 69 | + |
| 70 | +``` |
| 71 | +mnet.py diagram -r <root IP> |
| 72 | + -o <output file> |
| 73 | + [-d <max depth>] |
| 74 | + [-c <config file>] |
| 75 | + [-t <diagram title>] |
| 76 | + [-C <catalog file>] |
| 77 | +``` |
| 78 | +The above command will discover the network and generate a network diagram. |
| 79 | + |
| 80 | +| Option | Description | |
| 81 | +| --- | --- | |
| 82 | +| `-r <root IP>` | IP address of the network node to start on. | |
| 83 | +| `-o <output file>` | The file that the output will be written to.<br />Common file extensions: `.png`, `.pdf`, `.svg` | |
| 84 | +| `-c <config file>` | The JSON configuration file to use. | |
| 85 | +| `-d <max depth>` | The maximum hop depth to discover, starting at the root node specified by `-r` | |
| 86 | +| `-t <diagram title>` | The title to give your generated network diagram. | |
| 87 | +| `-C <catalog file>` | If specified, mnet will generate a comma separated (CSV) catalog file with a list of all devices discovered. | |
| 88 | + |
| 89 | +### TraceMAC Module |
| 90 | + |
| 91 | +``` |
| 92 | +mnet.py tracemac -r <root IP> |
| 93 | + -m <MAC Address> |
| 94 | + [-c <config file>] |
| 95 | +``` |
| 96 | +The above command will run the `TraceMAC` module and trace a MAC address through CAM tables. |
| 97 | + |
| 98 | +| Option | Description | |
| 99 | +| --- | --- | |
| 100 | +| `-r <root IP>` | IP address of the network node to start on. | |
| 101 | +| `-m <MAC Address>` | The MAC address to locate. Can be in any form. Ex: `11:22:33:44:55:66` or `112233445566` or `1122.3344.5566` | |
| 102 | +| `-c <config file>` | The JSON configuration file to use. | |
| 103 | + |
| 104 | +### GetMACS Module |
| 105 | + |
| 106 | +``` |
| 107 | +mnet.py getmacs -r <root IP> |
| 108 | + -o <output CSV file> |
| 109 | + [-d <mac depth>] |
| 110 | + [-c <config file>] |
| 111 | +``` |
| 112 | +Discover the network per the `discover` rules in the configuration file, then generate a CSV output file of all MAC addresses. |
| 113 | + |
| 114 | +| Option | Description | |
| 115 | +| --- | --- | |
| 116 | +| `-r <root IP>` | IP address of the network node to start on. | |
| 117 | +| `-o <output CSV file>` | The comma separated value (.csv) file that the output will be written to. | |
| 118 | +| `-d <max depth>` | The maximum hop depth to discover, starting at the root node specified by `-r` | |
| 119 | +| `-c <config file>` | The JSON configuration file to use. | |
| 120 | + |
| 121 | + |
| 122 | +### Config Module |
| 123 | + |
| 124 | +``` |
| 125 | +mnet.py config |
| 126 | +``` |
| 127 | +The above command will run the `config` module and output a standard config to stdout. |
| 128 | + |
| 129 | +Use this module and redirect stdout to a file in order to create a new blank config file. |
| 130 | +`# mnet.py config > mnet.conf` |
| 131 | + |
| 132 | +# Configuration File |
| 133 | + |
| 134 | +The toolset uses a JSON configuration file for common parameters. |
| 135 | + |
| 136 | +``` |
| 137 | +{ |
| 138 | + "snmp" : [ |
| 139 | + { "community":"private", "ver":2 }, |
| 140 | + { "community":"public", "ver":2 } |
| 141 | + ], |
| 142 | + "domains" : [ |
| 143 | + ".company.net", |
| 144 | + ".company.com" |
| 145 | + ], |
| 146 | + "discover" : [ |
| 147 | + "permit ip 10.0.0.0/8", |
| 148 | + "permit host Router[1,2]", |
| 149 | + "deny ip any", |
| 150 | + ], |
| 151 | + "diagram" : { |
| 152 | + "node_text_size" : 10, |
| 153 | + "link_text_size" : 9, |
| 154 | + "title_text_size" : 15, |
| 155 | + "get_stack_members" : 0, |
| 156 | + "get_vss_members" : 0, |
| 157 | + "expand_stackwise" : 0, |
| 158 | + "expand_vss" : 0, |
| 159 | + "expand_lag" : 1, |
| 160 | + "group_vpc" : 0 |
| 161 | + } |
| 162 | + |
| 163 | +} |
| 164 | +``` |
| 165 | + |
| 166 | +| Block / Variable | Description | |
| 167 | +| --- | --- | |
| 168 | +| `snmp` | Defines a list of SNMP credentials. When connecting to a node, each of these credentials is tried in order until one is successful. This allows crawling a large network with devices that potentially use different SNMP credentials. | |
| 169 | +| `discover` | Defines a Cisco-style ACL. See the `Network Discovery` section. | |
| 170 | +| `diagram` | Defines specific values used to change diagram attributes. Detailed below in the *Diagram block* table. | |
| 171 | + |
| 172 | +**Diagram block** |
| 173 | + |
| 174 | +| Variable | Type | Default Value | Description | |
| 175 | +| --- | --- | --- | --- | |
| 176 | +| `node_text_size` | integer | `10` | Node text size. | |
| 177 | +| `link_text_size` | integer | `9` | Link text size. | |
| 178 | +| `title_text_size` | integer | `15` | Diagram title text size. | |
| 179 | +| `get_stack_members` | bool | `0` | If set to `1`, nodes will include details about stackwise members. | |
| 180 | +| `get_vss_members` | bool | `0` | If set to `1`, nodes will include details about VSS members. | |
| 181 | +| `expand_stackwise` | bool | `0` | If set to `1`, nodes belonging to stackwise groups will be expanded to show each member as a node. | |
| 182 | +| `expand_vss` | bool | `0` | If set to `1`, nodes belonging to VSS groups will be expanded to show each member as a node. | |
| 183 | +| `expand_lag` | bool | `1` | If set to `1`, each link between nodes will be shown. If set to `0`, links of the same logical link channel will be grouped and only the channel link will be shown. | |
| 184 | +| `group_vpc` | bool | `0` | If set to `1`, VPC peers will be grouped together on the diagram, otherwise they will not be clustered. | |
| 185 | + |
| 186 | +# mnet's Diagram Module |
| 187 | + |
| 188 | +### Details |
| 189 | + |
| 190 | +A network discovery will be performed and a network diagram will be generated. |
| 191 | + |
| 192 | +mnet will attempt to collect the following information and include it in the generated diagram: |
| 193 | ++ All devices (via CDP and LLDP) |
| 194 | ++ Interface names |
| 195 | ++ IP addresses |
| 196 | ++ VLAN memberships |
| 197 | ++ Etherchannel memberships (LACP only) |
| 198 | ++ Identify trunk links |
| 199 | ++ Identify switched links |
| 200 | ++ Identify routed links |
| 201 | ++ BGP Local AS |
| 202 | ++ OSPF Router ID |
| 203 | ++ HSRP Virtual IP |
| 204 | ++ HSRP Priority |
| 205 | ++ VSS Domain |
| 206 | ++ Stackwise membership |
| 207 | ++ VPC peerlink information |
| 208 | + |
| 209 | +mnet's Diagram module attempts to include all of the above information in the diagram in an intuitive way. The keep the diagram clean, the following are used: |
| 210 | ++ Nodes |
| 211 | + + Circle nodes represent layer 2 switches. |
| 212 | + + Diamond nodes represent layer 3 switches or routers. |
| 213 | + + If a node has multiple borders then either VSS or StackWise is enabled. |
| 214 | + + VSS - Will always have a double border. |
| 215 | + + StackWise - The number of borders denotes the number of switches in the stack. |
| 216 | + + If the configuration specifies, VSS/VPC/Stackwise nodes will be grouped in larger squares. |
| 217 | ++ Links |
| 218 | + + Links are shown with arrowed lines. The end with no arrow is the *parent* and the end with the arrow is the *child*, such that the arrangement is *parent*->*child*. |
| 219 | + + If a link says *P:gi0/1* , *C:gi1/4* then the parent node's connection is on port gi0/1 and the child node's connection is on port gi1/4. |
| 220 | + + If the link is part of an Etherchannel the etherchannel's interface name will also be shown. Since an etherchannel interface is locally significiant, a *P:* and *C:* will also be shown if available. |
| 221 | + |
| 222 | +### Examples |
| 223 | + |
| 224 | +Example 1 |
| 225 | + |
| 226 | + |
| 227 | +Example 2 |
| 228 | + |
| 229 | + |
| 230 | +Example 3 |
| 231 | + |
| 232 | + |
| 233 | +# mnet's TraceMAC Module |
| 234 | + |
| 235 | +### Examples |
| 236 | + |
| 237 | +The below example shows a trace for MAC address `00:23:68:63:75:70` starting |
| 238 | +at node `10.10.0.3`. The MAC address is found on switch `IDF3_D` on port |
| 239 | +`Gi0/11`. |
| 240 | + |
| 241 | +``` |
| 242 | +# mnet.py tracemac -r 10.10.0.3 -m 0023.6863.7570 |
| 243 | +MNet Suite v0.7 |
| 244 | +Written by Michael Laforest <[email protected]> |
| 245 | +
|
| 246 | + Config file: ./mnet.conf |
| 247 | + Root node: 10.10.0.3 |
| 248 | + MAC address: 0023.6863.7570 |
| 249 | +
|
| 250 | +
|
| 251 | +
|
| 252 | +Start trace. |
| 253 | +------------ |
| 254 | +IDF1_A (10.10.0.3) |
| 255 | + VLAN: 1 |
| 256 | + Port: Gi1/3 |
| 257 | + Next Node: IDF1_B |
| 258 | + Next Node IP: 10.10.0.2 |
| 259 | +------------ |
| 260 | +IDF1_B (10.10.0.2) |
| 261 | + VLAN: 1 |
| 262 | + Port: Gi0/24 |
| 263 | + Next Node: IDF3_D |
| 264 | + Next Node IP: 10.10.0.6 |
| 265 | +------------ |
| 266 | +IDF3_D (10.10.0.6) |
| 267 | + VLAN: 1 |
| 268 | + Port: Gi0/11 |
| 269 | +------------ |
| 270 | +Trace complete. |
| 271 | +``` |
| 272 | + |
| 273 | +# FAQ |
| 274 | + |
| 275 | +**Q.** `My diagram is too large. I only want to diagram part of my network.` |
| 276 | + |
| 277 | +**A.** Try changing the config `discover` ACL to narrow down the scope of your discovery. You can explicitly deny CIDR's or host name regex patterns if you do not want them included in your diagram. |
| 278 | + |
| 279 | +**Q.** `My diagram is still too wide. What can I do?` |
| 280 | + |
| 281 | +**A.** Try to use the Graphviz `unflatted` command line program to reformat the generated dot file. |
| 282 | + |
| 283 | +**Q.** `Where is the config file?` |
| 284 | + |
| 285 | +*A.* If you need a config file you can generate a new one with `# mnet.py config > mnet.conf` . |
| 286 | + |
| 287 | +**Q.** `I need a diagram with less proprietary information. Can I get one without IPs or serial numbers?` |
| 288 | + |
| 289 | +*A.* Yes, you can change the text inside each node by editing the config option `diagram\node_text`. Below is an example that would produce a minimal information diagram: |
| 290 | + |
| 291 | +``` |
| 292 | +"diagram" : { |
| 293 | + node_text = '<font point-size="10"><b>{node.name}</b></font><br />{node.ios}<br />{node.plat}' |
| 294 | +} |
| 295 | +``` |
| 296 | + |
0 commit comments