Skip to main content

Network Topology Scanner

CI

Scans a network range, discovers active hosts, their open ports/services, vendor (via MAC) and device type, and generates an interactive HTML topology graph with icons per category (router, PC, NAS, printer, etc). Flags hosts with sensitive open ports in red (Telnet, SMB, RDP, FTP, VNC), stores every scan in SQLite to diff against the previous one (new/dropped hosts, ports that changed), and can export the inventory to CSV. Optionally queries your routers/switches over SNMP to draw the real topology (which host hangs from which switch port or access point) instead of an approximate star. Available as a CLI or as a local web interface (Streamlit, optional).

Command Center dashboard Inventory and changes

Screenshots use fictional demo data — no real network is exposed here.

Only use this tool on networks you own or have explicit authorization to scan (your homelab, or your workplace's network if you have permission). Scanning networks without consent is illegal in most countries.

Project structure

network-topology-scanner/
├── src/topology_scanner/
│   ├── scanner.py        # nmap scanning (discovery + ports)
│   ├── classifier.py      # Device classification by MAC/vendor
│   ├── graph.py            # Graph construction (networkx)
│   ├── export.py           # HTML export (pyvis), text and CSV
│   ├── history.py          # Scan history in SQLite (diff vs. the previous scan)
│   ├── snmp.py             # Real topology via SNMP (ARP, routes, MAC table, neighbors)
│   ├── cli.py               # Command-line interface
│   └── webapp.py            # Web interface (Streamlit, optional)
├── scripts/demo_arbol.py    # Fictional SNMP tree for the README screenshot
├── tests/                   # pytest, with nmap mocks (no real network needed)
└── pyproject.toml           # single source of dependencies (pip install -e ".[dev,web,snmp]")

Installation

Requires Python 3.10+.

# System dependency
sudo apt install nmap        # Linux
# On Windows: download the installer from nmap.org

# Virtual environment
python3 -m venv venv
source venv/bin/activate      # Linux/Mac
# venv\Scripts\Activate.ps1   # Windows PowerShell

# From PyPI
pip install topology-scanner
pip install "topology-scanner[web,snmp]"   # optional: web interface and real topology via SNMP

For development, from a clone of the repo:

pip install -e ".[dev,web,snmp]"

Usage

sudo topology-scanner 192.168.1.0/24
sudo topology-scanner 192.168.1.0/24 --rapido
sudo topology-scanner 192.168.1.0/24 --con-so --output my_network.html

# Several ranges at once (e.g. your LAN and a homelab subnet behind another router)
sudo topology-scanner 192.168.1.0/24 10.0.10.0/24

# Real topology: query the router(s) over SNMP (see below)
export TOPOLOGY_SNMP_COMMUNITY='your-read-only-community'
sudo -E topology-scanner 192.168.1.0/24 --snmp 192.168.1.1

# Alternative without the installed entry point:
sudo python3 -m topology_scanner 192.168.1.0/24
Flag Description Default
range CIDR range(s) to scan, space-separated; history is kept per range (required)
--ports Ports to scan (nmap format) common ports
--nmap-args Extra arguments passed to nmap -sV -T4
--output Output HTML file name topologia_red.html
--con-so Enables OS detection (-O), the slowest option disabled
--sin-2-fases Disables the preliminary ping scan, scans the full range directly disabled
--rapido Max-speed preset, ports only (incompatible with --con-so/--nmap-args) disabled
--csv Also exports a CSV inventory to the given path disabled
--history-db SQLite file where scan history is stored historial.db
--sin-historial Skips saving the scan to history / diffing against the previous one disabled
--snmp Routers/switches to query over SNMP v2c (comma-separated IPs) disabled (star layout)

Web interface

Requires the [web] extra (see Installation). Form with automatic detection of your local network, real cancellable scanning (kills the actual nmap process, not just the UI), results table, CSV download and the embedded graph. Several ranges can be scanned at once by separating them with spaces in the range field. The "Real topology via SNMP" switch in the sidebar draws the tree described below, over SNMP v2c or v3 (community and keys are password inputs; leave them empty to use the TOPOLOGY_SNMP_* environment variables).

topology-scanner-web
# or, without the installed entry point:
streamlit run src/topology_scanner/webapp.py

Real topology via SNMP

By default the graph is an approximate star: nmap knows which hosts are alive, not how they are connected. With --snmp, the scanner reads a few standard tables from your routers/switches and builds a tree instead:

SNMP table What it tells Used for
Routes (ipCidrRouteTable) "10.0.10.0/24 is behind 192.168.1.44" Upstream gateway, downstream routers and their subnets
Neighbors (MikroTik mtxrNeighborTable, MNDP/LLDP/CDP) "Access point X is on my ether2" Links between network devices
Neighbors (standard LLDP-MIB, any vendor) "Switch Y sees me on its port3" Links, with the port on both ends (ether2 ↔ port3)
MAC table (BRIDGE-MIB) "MAC aa:bb:… is on port wlan1" Which port each host is on
ARP (ipNetToMediaTable) "192.168.1.20 is aa:bb:…" Matching MACs to the IPs nmap found

Hosts seen on a port that leads to another network device hang from that device; hosts that only SNMP sees (not detected by nmap) are shown too — an unknown device on a switch port is exactly what you want to notice. If no device answers, the scan still finishes with the star layout.

Real topology via SNMP

Fictional demo data, generated with python scripts/demo_arbol.py (no scan involved).

Setup (MikroTik RouterOS example — read-only, restricted to the scanning machine):

/snmp community add name=<long-random-string> addresses=<scanner-ip>/32 read-access=yes write-access=no
/snmp community set [find name=public] disabled=yes
/snmp set enabled=yes

The community is read from the TOPOLOGY_SNMP_COMMUNITY environment variable, never from a command-line argument (arguments show up in ps and in your shell history). On Windows PowerShell: $env:TOPOLOGY_SNMP_COMMUNITY = "...".

SNMPv3 (recommended: v2c sends the community in clear text). In RouterOS v6 the community name is the v3 user, and security=private means authentication + encryption:

/snmp community add name=<user> addresses=<scanner-ip>/32 security=private \
    authentication-protocol=SHA1 authentication-password=<8+ chars> \
    encryption-protocol=AES encryption-password=<8+ chars> read-access=yes write-access=no
Variable Meaning Default
TOPOLOGY_SNMP_USER v3 user (if set, v3 is used and the community is ignored) —
TOPOLOGY_SNMP_AUTH_KEY Authentication key (8+ characters) required
TOPOLOGY_SNMP_PRIV_KEY Encryption key (8+ characters); empty = authenticate without encryption —
TOPOLOGY_SNMP_AUTH_PROTO MD5, SHA, SHA224, SHA256, SHA384, SHA512 SHA
TOPOLOGY_SNMP_PRIV_PROTO DES, AES, AES192, AES256 AES

Current limitations: links between network devices come from MikroTik's neighbor table and from the standard LLDP-MIB, so devices that don't run LLDP (or don't expose it over SNMP) are only placed by routes, ARP and the MAC table.

Device classification

Each host's MAC address is used to look up its vendor (via nmap's built-in database), which is then heuristically mapped to a category with its own icon: router, firewall, VM, NAS, printer, camera, IoT, mobile, Apple, PC.

Limitation: MAC resolution only works if the scanning machine is on the same L2 segment as the target host (ARP doesn't cross routers/VLANs). Hosts on other subnets will show up as category "unknown".

Tests

pytest tests/ -v
pytest tests/ --cov=topology_scanner   # with coverage

scanner.py tests use unittest.mock to simulate nmap's responses, so they run without a real network or the nmap binary installed.

Roadmap

  • Visual alerts for sensitive open ports (RDP, Telnet, SMB, FTP, VNC)
  • Scan history in SQLite (new/dropped hosts, ports that change)
  • CSV export for audits/inventory
  • Visual icon/color legend in the HTML
  • Web interface with Streamlit
  • CI: run tests + ruff on every push
  • Real topology via SNMP against routers/switches, CLI (instead of the approximate star layout)
  • SNMP in the web interface
  • Standard LLDP-MIB (links between devices from any vendor, with the port on both ends)
  • SNMPv3 (authentication and encryption)
  • v1.0 on PyPI, published by GitHub Actions from a tag (trusted publishing, no tokens)

See CHANGELOG.md for release notes.

Metadata

Release files for topology-scanner 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for topology-scanner 1.0.0
File Size Uploaded Provenance
topology_scanner-1.0.0.tar.gz 102.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for topology-scanner 1.0.0
File Interpreter ABI Platform
topology_scanner-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 166.8 kB

Release files / topology_scanner-1.0.0.tar.gz

Download URL topology_scanner-1.0.0.tar.gz
Size 102.0 kB
Tags Source
SHA-256 checksum
How to use checksums
cb7a8017342bf042b715f2eb10b52a4fd72f33041ef1fbce8c4640d148458085
BLAKE2b-256 checksum
How to use checksums
ab90d43e34ace6e416bea22222e380a77fb18a671324f73b022fd7f116197c2c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / topology_scanner-1.0.0-py3-none-any.whl

Download URL topology_scanner-1.0.0-py3-none-any.whl
Size 64.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
86e6961fd435ae9ce33885e1a6c5dc7a362716db06767cec6cb9dabe8ba533e7
BLAKE2b-256 checksum
How to use checksums
98a6171587f7f6a36d8fd4895956f4ba32c14f28bab7d0a1494dfb3be4523c39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for topology-scanner 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for topology_scanner-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page