> ## Content Index
> Fetch the complete content index at: https://www.pinglabz.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Netdisco on Cisco IOS XE: CDP Topology, MAC and ARP Search over SNMPv3
- URL: https://www.pinglabz.com/obs-netdisco-topology/
- Published: 2026-11-03T18:12:18.000Z
- Updated: 2026-11-03T18:31:50.000Z
- Description: Netdisco 2.117001 on IOS XE 17.18 over SNMPv3: one seed router, CDP finds the rest, then MAC and ARP search and the neighbour map. Plus what a small lab can't show.
- Author: Jaime
- Tags: Grafana, Monitoring, SNMP, Cisco IOS XE, Linux, Tools

Netdisco answers the questions you ask during an outage: where is this MAC, which port is this IP on, and what's plugged into what. I installed Netdisco 2.117001 (BSD-3-Clause, released November 2, 2026) in my home lab, pointed it at one router, and let CDP find the rest: two Cisco IOS XE 17.18.2 WAN routers and an IOS XE 17.18.2 access switch, all over SNMPv3.

It's a small lab, so I'll be clear about what it could and couldn't show. The topology and ARP parts work well. The MAC table part mostly had nothing to find.

![Netdisco neighbor map showing wan-rtr1.lab linked to wan-rtr2.lab and acc-sw1.lab](https://storage.ghost.io/c/ff/28/ff28db4a-11e1-4835-b928-158974cf96c1/content/images/2026/11/n-map.png)

The neighbour map Netdisco built from CDP, seeded with one router.

[![Lab diagram: The Netdisco 2.117001 backend (10.66.20.44) polls one seed device, wan-rtr1 (10.66.20.11), over SNMPv3. Its CDP table leads Netdisco to wan-rtr2 (10.66.20.12) and acc-sw1 (10.66.20.21). Discover, macsuck and arpnip jobs run on all three devices and write links, ports and ARP data to PostgreSQL, which feeds the web UI map and MAC/IP search. The CDP links are wan-rtr1 Et0/1 (10.0.12.1) to wan-rtr2 Et0/1 (10.0.12.2), and wan-rtr1 Et0/2 (aa:bb:cc:00:02:20, 10.0.10.1) to acc-sw1 Et0/1 (10.0.10.2, Vlan10). Notes say MAC aa:bb:cc:00:02:20 lands on wan-rtr1 Et0/2, and that there are no access-port hosts, so uplink MACs are not tracked. At idle the stack uses about 1.6 GiB: backend 875 MiB, web 665 MiB, PostgreSQL 94 MiB.](https://storage.ghost.io/c/ff/28/ff28db4a-11e1-4835-b928-158974cf96c1/content/images/2026/11/diagram-topology-44.png)](https://storage.ghost.io/c/ff/28/ff28db4a-11e1-4835-b928-158974cf96c1/content/images/2026/11/diagram-topology-44.png?ref=pinglabz.com)

Netdisco starts from one seed, finds wan-rtr2 and acc-sw1 through CDP, and stores links, ports and ARP for the map and MAC/IP search.

## Setup

I used the official Docker images (backend, web and PostgreSQL), pinned to the 2.117001 tags. The backend runs the SNMP jobs and needs an IP the devices accept SNMP from. My routers and switch only allow a short list of pollers, so I added the backend's address to the switch's SNMP ACL first:

```
acc-sw1(config)# ip access-list standard ZBX-SNMP
acc-sw1(config-std-nacl)# 30 permit 10.66.20.44
```

The routers use SNMPv3 authPriv and the switch uses authNoPriv, so `deployment.yml` gets one credential set for each, matched by IP. `discover_only` keeps Netdisco from wandering off to anything CDP mentions outside the lab:

```
device_auth:
  - tag: v3_routers
    only: [10.66.20.11, 10.66.20.12]
    user: zbxmon
    auth: { pass: <AUTH>, proto: SHA }
    priv: { pass: <PRIV>, proto: AES }
  - tag: v3_switch_authnopriv
    only: [10.66.20.21]
    user: zbxmon
    auth: { pass: <AUTH>, proto: SHA }
discover_only: [10.66.20.0/24]
```

I set `no_auth: true` so the web UI opens without a login. That's fine in a closed lab. Don't do it anywhere else, because the UI can also change port settings if you turn that on.

## Discovery from one seed

```
$ netdisco-do discover -d 10.66.20.11
info App::Netdisco version 2.117001 loaded.
info discover: [10.66.20.11] started at Tue Nov  3 17:31:21 2026
info discover: finished at Tue Nov  3 17:31:24 2026
info discover: status done: Successful discover for existing device 10.66.20.11

real	0m4.130s
```

On the first run, the backend queued wan-rtr2 and acc-sw1 from wan-rtr1's CDP table and discovered both on its own. It then ran `macsuck` (MAC tables) and `arpnip` (ARP tables) against all three. The whole lab was in the database within a minute or so. The links it stored:

```
     ip      |    port     |  remote_ip  | remote_port
-------------+-------------+-------------+-------------
 10.66.20.11 | Ethernet0/0 | 10.66.20.12 | Ethernet0/0
 10.66.20.11 | Ethernet0/1 | 10.0.12.2   | Ethernet0/1
 10.66.20.11 | Ethernet0/2 | 10.0.10.2   | Ethernet0/1
 10.66.20.21 | Ethernet0/1 | 10.0.10.1   | Ethernet0/2
 10.66.20.12 | Ethernet0/1 | 10.0.12.1   | Ethernet0/1
```

CDP gives the neighbour's address on that link (10.0.12.2, 10.0.10.2), not its management IP. Netdisco matches those back to the right devices anyway, which is why the map above has three clean nodes and no duplicates.

## Device and port views

![Netdisco details page for acc-sw1.lab: model C365048TS, IOS-XE 17.18.2, location PingLabz lab rack 2, layers 2 and 3, discover, arpnip and macsuck times](https://storage.ghost.io/c/ff/28/ff28db4a-11e1-4835-b928-158974cf96c1/content/images/2026/11/n-device.png)

acc-sw1 details. Times on this page are UTC.

The ports tab shows each interface with its MAC, state and whatever is connected. The two uplinks on acc-sw1 show wan-rtr1 as the neighbour:

![Netdisco ports tab for acc-sw1.lab listing Ethernet0/0 to Ethernet0/3, Null0 and Vlan10 with port MACs, up/up status and wan-rtr1.lab as the connected device on Ethernet0/0 and Ethernet0/1](https://storage.ghost.io/c/ff/28/ff28db4a-11e1-4835-b928-158974cf96c1/content/images/2026/11/n-ports.png)

acc-sw1 ports with the columns I care about switched on.

## Find a host by MAC or IP

This is the feature people install Netdisco for. I searched for `aa:bb:cc:00:02:20`, a MAC the switch had learned on Et0/1\. Netdisco knew it was wan-rtr1's own Et0/2 interface MAC and jumped straight to that port, with acc-sw1 Et0/1 as the far end:

![Netdisco search for MAC aa:bb:cc:00:02:20 opening wan-rtr1.lab Ethernet0/2, connected to acc-sw1.lab Ethernet0/1](https://storage.ghost.io/c/ff/28/ff28db4a-11e1-4835-b928-158974cf96c1/content/images/2026/11/n-macfind.png)

A MAC search landing on the port that owns it.

Searching by IP uses the ARP data. 10.0.10.1 resolves to that same MAC, seen in acc-sw1's ARP table:

![Netdisco node search for 10.0.10.1 showing MAC aa:bb:cc:00:02:20 seen as IP to MAC via acc-sw1.lab](https://storage.ghost.io/c/ff/28/ff28db4a-11e1-4835-b928-158974cf96c1/content/images/2026/11/n-arp.png)

IP to MAC, and which device reported it.

Across the three devices, arpnip collected 18 active ARP entries.

## What this lab couldn't show

The usual Netdisco story is "this laptop is on switch X, port Y, VLAN Z". That needs end hosts on access ports, and my switch has none. Its MAC table had exactly one entry:

```
acc-sw1# show mac address-table dynamic
Vlan    Mac Address       Type        Ports
----    -----------       --------    -----
  10    aabb.cc00.0220    DYNAMIC     Et0/1
```

That MAC is wan-rtr1, and it's on a port with a CDP neighbour. Netdisco treats ports with a device neighbour as uplinks and doesn't record end-host locations there, so the node table stayed empty. On top of that, macsuck logged `no VLANs found` for this switch over SNMP, so it fell back to reading the bridge table without a VLAN context. On a real Catalyst with access ports and hosts, both of these behave differently. I'd test there before trusting it for host tracking at scale.

## Resource use

Idle, after discovery, from `docker stats`: backend 875 MiB, web 665 MiB and PostgreSQL 94 MiB, so about 1.6 GiB in total. That's more than LibreNMS used for the same three devices in [the previous post](https://www.pinglabz.com/obs-librenms-vs-zabbix/). Most of it is the Perl workers.

## Where it fits

Netdisco doesn't do graphs or alerts. It's a lookup and inventory tool. It sits well beside Zabbix or LibreNMS: they tell you something broke, and Netdisco tells you where a MAC or IP lives and what's cabled to what. The CDP-based map is a quick check against the neighbour map I built with Ansible in [the CDP and LLDP post](https://www.pinglabz.com/ansible-cdp-lldp-neighbor-map-ios/), and the device list is a cross-check for whatever you keep in [NetBox](https://www.pinglabz.com/config-netbox-source-of-truth/).

## Related posts

- Previous: [LibreNMS vs Zabbix on Cisco IOS XE](https://www.pinglabz.com/obs-librenms-vs-zabbix/)
- [Add Cisco IOS XE Routers and Switches to Zabbix over SNMPv3](https://www.pinglabz.com/zabbix-cisco-ios-xe-snmpv3/)
- [Build a CDP and LLDP Neighbor Map with Ansible on Cisco IOS XE](https://www.pinglabz.com/ansible-cdp-lldp-neighbor-map-ios/)

Now live: [Suricata and Zeek on the management network](https://www.pinglabz.com/obs-suricata-zeek-noc/), the last post in this part of the series, watches who talks to these same devices.