NetStacksNetStacks

Network Discovery

Enterprise

Discover network neighbors with SNMP LLDP/CDP, SSH show commands, and nmap, plus traceroute hop resolution, to build NetStacks topology automatically.

Overview

Network Discovery in NetStacks finds the Layer 2/3 neighbors of devices you already have, so the topology graph can be drawn automatically instead of by hand. You point discovery at a set of known targets (the devices in a topology group) and NetStacks queries each one for its neighbor tables, returning the device name, platform string, and the list of connected neighbors with local and remote interfaces.

Discovery methods

Each target is tried with an ordered list of methods. The first method that returns neighbors wins; the rest are skipped for that target.

  • snmp — walks the LLDP-MIB first, then falls back to the CDP-MIB, using the SNMP community resolved from the target's credential profile. Also reads sysName and sysDescr.
  • cli — connects over SSH and runs show cdp neighbors detail then show lldp neighbors detail, parsing the output. Used when SNMP is unavailable.
  • nmap — fingerprints a host (open ports, service versions, and OS guess) when neither SNMP nor CLI returns neighbors. Requires the nmap binary on the agent host.

The default method order is ["snmp", "cli"]. Add "nmap" explicitly when you want fingerprinting as a last resort.

Discovery feeds topology

Discovery is launched from the topology view and its results flow straight into the topology graph — there is no separate staging or approval queue. NetStacks correlates the discovered neighbor relationships against the devices in the selected group to draw the links.

How It Works

Per-target method order

Discovery runs per target, not as a recursive seed crawl. For each target the agent attempts the requested methods in order and returns the first non-empty result:

  1. SNMP (LLDP then CDP) — if any SNMP community is resolved for the target, the agent reads sysName/sysDescr, walks the LLDP-MIB, and walks the CDP-MIB if LLDP is empty. The result method is reported as snmp-lldp or snmp-cdp.
  2. CLI — if SSH credentials are resolved, the agent connects and runs the show cdp/lldp neighbors detail commands, parsing platform-specific output.
  3. nmap — if requested, the agent runs an nmap fingerprint of the host. nmap does not return neighbor links, only host/port/OS data.

If no method succeeds, the target's result has discoveryMethod: "none" and an error describing the last failure.

Concurrency

Batch discovery processes targets in parallel with a bounded pool (up to 10 targets at a time). Each target resolves its own SNMP communities and SSH credentials from the profile or session you supply, including jump-host routing when the profile or session has a bastion configured.

What a result contains

  • ip — the target that was queried.
  • sysName / sysDescr — device name and platform string (SNMP only; CLI fills only the name).
  • neighbors[] — each with localInterface, neighborName, neighborIp, neighborInterface, neighborPlatform, and protocol (lldp or cdp).
  • discoveryMethod — which method succeeded.
  • nmap — fingerprint result when the nmap method ran.

Running Discovery

Discovery is driven from the Topology Discovery dialog, which scans the devices already in a topology group.

  1. Make sure each device you want to scan has a credential profile attached that provides an SNMP community (for the SNMP method) and SSH auth (for the CLI fallback). See SNMP Communities and SSH Passwords & Keys.
  2. Open the topology for a device group and start Topology Discovery. The dialog lists the devices that will be scanned and shows whether nmap is available on the agent.
  3. Click Start Discovery. A progress bar and a live log stream show per-device results, for example Found 4 neighbor(s) via snmp-lldp or No neighbors found (method: none).
  4. When it completes, choose View Topology to see the links that were correlated from the discovered neighbors.
SNMP credentials and lockouts

The SNMP method tries each community resolved for a target in order. Make sure firewalls allow SNMP (UDP 161) from the agent to the targets, and that LLDP or CDP is enabled on the devices — some platforms disable both by default. The CLI fallback authenticates over SSH, so repeated wrong credentials can trigger lockouts on hardened devices.

Batch Discovery API Enterprise

The dialog calls a single agent endpoint: POST /api/discovery/batch. It takes a list of targets and an optional ordered list of methods, and returns one result per target. There is no seed/hop-limit crawl — you pass exactly the targets you want scanned.

Request

discovery-batch-request.jsonjson
POST /api/discovery/batch
Content-Type: application/json

{
  "targets": [
    {
      "ip": "10.0.1.10",
      "snmpProfileId": "prof_snmp_core",
      "credentialProfileId": "prof_ssh_core"
    },
    {
      "ip": "10.0.2.10",
      "sessionId": "sess_abc123",
      "cliFlavor": "cisco-ios"
    }
  ],
  "methods": ["snmp", "cli", "nmap"]
}

Each target field is optional except ip (which may be empty if sessionId is given, since the IP is then taken from the session):

  • ip — target IP or hostname.
  • sessionId — reuse an open session's credentials and jump host.
  • snmpProfileId — profile to resolve SNMP communities from.
  • credentialProfileId — profile to resolve SSH auth (and, if no SNMP profile, SNMP communities) from.
  • cliFlavor — optional CLI flavor hint, e.g. cisco-ios, juniper-junos, arista-eos.

methods defaults to ["snmp", "cli"] when omitted. Add "nmap" to enable fingerprinting.

Controller vs. agent credential fields

When running through the Enterprise controller, targets may also carry snmpCredentialId and sshCredentialId (vault UUIDs). The frontend sends both naming schemes; the agent ignores fields it does not use, and the controller accepts the alias form.

Response

The endpoint returns an array of per-target results. Field names are camelCase.

discovery-batch-response.jsonjson
[
  {
    "ip": "10.0.1.10",
    "sysName": "dist-sw-01",
    "sysDescr": "Cisco NX-OS(tm) n9000, Software version 9.3(8)",
    "neighbors": [
      {
        "localInterface": "Ethernet1/1",
        "neighborName": "core-rtr-01",
        "neighborIp": "10.0.0.1",
        "neighborInterface": "GigabitEthernet0/1",
        "neighborPlatform": "Cisco IOS",
        "protocol": "lldp"
      }
    ],
    "discoveryMethod": "snmp-lldp",
    "nmap": null,
    "error": null
  },
  {
    "ip": "10.0.2.10",
    "sysName": "access-sw-01",
    "sysDescr": null,
    "neighbors": [
      {
        "localInterface": "Gi1/0/1",
        "neighborName": "dist-sw-01",
        "neighborIp": null,
        "neighborInterface": "Eth1/2",
        "neighborPlatform": "cisco",
        "protocol": "cdp"
      }
    ],
    "discoveryMethod": "cdp-cli",
    "nmap": null,
    "error": null
  }
]

nmap fingerprint result

When the nmap method runs, the target's nmap object is populated. With passwordless sudo the agent runs a SYN scan with OS detection (nmap -sS -sV -O --top-ports 100 -T4); otherwise it runs a TCP connect scan without OS detection (nmap -sT -sV --top-ports 100 -T4).

discovery-nmap-result.jsonjson
{
  "ip": "10.0.9.5",
  "sysName": "Linux 5.x",
  "sysDescr": null,
  "neighbors": [],
  "discoveryMethod": "nmap",
  "nmap": {
    "host": "10.0.9.5",
    "state": "up",
    "osFamily": "Linux",
    "osMatch": "Linux 5.x",
    "osAccuracy": 96,
    "ports": [
      { "port": 22, "protocol": "tcp", "state": "open", "service": "ssh", "version": "OpenSSH 8.9" },
      { "port": 443, "protocol": "tcp", "state": "open", "service": "https", "version": "nginx 1.24" }
    ],
    "macAddress": "00:1a:2b:3c:4d:5e",
    "vendor": "Cisco Systems",
    "scanTimeMs": 4210,
    "error": null
  },
  "error": null
}

Traceroute Hop Resolution Enterprise

Beyond neighbor discovery, NetStacks can take a list of traceroute hops and resolve each hop IP to the device that owns it, then run neighbor discovery on that device. This is useful for mapping the path between two endpoints onto your real device inventory.

The endpoint is POST /api/discovery/traceroute-resolve. For each hop it:

  1. Queries configured integration sources (NetBox, NetStacks-Crawler, and LibreNMS) to resolve the hop IP to a parent device and management IP.
  2. If resolved, runs SNMP neighbor discovery against the parent device's management IP.
  3. If no integration matches, tries SNMP, then CLI, then nmap directly against the hop IP.
Integrations resolve hops, not enrich discovery

The integration sources are used only to turn an interface IP into its parent device during traceroute resolution. Batch neighbor discovery itself does not call any external inventory API.

Request

traceroute-resolve-request.jsonjson
POST /api/discovery/traceroute-resolve
Content-Type: application/json

{
  "hops": [
    { "hopNumber": 1, "ip": "10.0.0.1" },
    { "hopNumber": 2, "ip": "10.0.10.2" },
    { "hopNumber": 3, "ip": "10.0.20.3" }
  ],
  "snmpProfileIds": ["prof_snmp_core"],
  "credentialProfileIds": ["prof_ssh_core"]
}

Response

traceroute-resolve-response.jsonjson
[
  {
    "hopNumber": 2,
    "ip": "10.0.10.2",
    "resolved": true,
    "source": "netbox",
    "parentDevice": {
      "hostname": "core-rtr-02",
      "managementIp": "10.0.0.2",
      "interfaceName": "GigabitEthernet0/1",
      "deviceType": "Router",
      "platform": "Cisco IOS"
    },
    "neighbors": [
      {
        "localInterface": "Gi0/1",
        "neighborName": "dist-sw-01",
        "neighborIp": "10.0.1.10",
        "neighborInterface": "Eth1/1",
        "neighborPlatform": "Cisco NX-OS",
        "protocol": "lldp"
      }
    ],
    "nmap": null,
    "error": null
  }
]

The source field reports which integration resolved the hop (netbox, netstacks-crawler, or librenms). When a hop cannot be resolved by any source, resolved is false and the result reflects whatever direct SNMP/CLI/nmap attempt succeeded.

Checking Capabilities

SNMP is built into the agent and always available. The CLI method depends on SSH credentials, and the nmap method depends on the nmap binary (and passwordless sudo for OS detection). Query GET /api/discovery/capabilities to see what the agent host supports before relying on a method.

discovery-capabilities.jsonjson
GET /api/discovery/capabilities

# Response
{
  "nmapAvailable": true,
  "nmapSudo": false,
  "snmpAvailable": true
}

With nmapSudo: false, nmap runs a TCP connect scan without OS detection. The Topology Discovery dialog surfaces this as nmap: available vs. nmap: available (with OS detection).

Q&A

Q: What protocols does discovery use?
A: SNMP neighbor discovery walks the LLDP-MIB and then the CDP-MIB (reporting snmp-lldp or snmp-cdp). The CLI fallback parses show cdp neighbors detail and show lldp neighbors detail over SSH. nmap fingerprints hosts but does not return neighbor links.
Q: How do I discover a device that does not respond to SNMP?
A: Attach an SSH credential profile so the CLI method can run. If neither SNMP nor CLI works, include "nmap" in the method list to at least fingerprint the host's open ports and OS.
Q: Does discovery crawl outward from a seed device?
A: No. Discovery scans exactly the targets you provide (the devices in a topology group). There is no hop-limit seed crawl. To map a path, use traceroute hop resolution, which resolves each supplied hop IP to its parent device.
Q: Is there an approval queue for discovered devices?
A: No. Discovery does not stage devices for approval. Results are correlated into the topology graph for the group you scanned. Devices are added to inventory through the normal add-device or bulk-import flows.
Q: How are SNMP communities and SSH credentials chosen?
A: Each target resolves credentials from its snmpProfileId and credentialProfileId (or from an open sessionId). The SNMP method tries each resolved community in turn; the CLI method uses the resolved SSH auth. Jump hosts configured on the profile or session are applied automatically.
Q: How many devices run at once?
A: Batch discovery processes up to 10 targets concurrently. Large groups can take several minutes; the dialog shows elapsed time and per-device progress.

Troubleshooting

SNMP returns no neighbors

  • Confirm the community is correct — test with snmpwalk -v2c -c COMMUNITY TARGET_IP 1.0.8802.1.1.2 (LLDP-MIB) or the CDP-MIB.
  • Verify UDP 161 is permitted from the agent to the target.
  • Ensure LLDP or CDP is enabled on the device — if both are off, SNMP returns an empty neighbor table and discovery falls through to CLI.

Method reports "none"

  • No SNMP community was resolved (no profile attached) and no SSH auth was resolved, so both methods were skipped. Attach a credential profile with the needed secrets.
  • The target was unreachable on all attempted methods. Check the error field in the result for the last failure message.

CLI fallback fails

  • Make sure the SSH credential profile has valid auth and that the device supports show cdp neighbors detail or show lldp neighbors detail.
  • Provide a cliFlavor hint for non-Cisco platforms so the parser matches the output format.

nmap not available

  • Install the nmap binary on the agent host. Confirm with GET /api/discovery/capabilities.
  • For OS detection, grant the agent passwordless sudo for nmap; otherwise scans run without the -O flag.

Traceroute hops not resolving

  • Resolution depends on configured NetBox, NetStacks-Crawler, or LibreNMS sources. With none configured, hops fall back to direct SNMP/CLI/nmap against the hop IP.
  • Pass the right snmpProfileIds and credentialProfileIds so the agent can query resolved parent devices.