Skip to content

Commit eb34eb6

Browse files
committed
feat: add scan diffing, OS fingerprinting, watch mode, multi-subnet, and inventory check (v0.3.0)
1 parent 1a0f436 commit eb34eb6

12 files changed

Lines changed: 845 additions & 136 deletions

File tree

README.md

Lines changed: 104 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# whoson
22

3-
A lightweight subnet audit tool. Scan a network, see what's alive, and export a topology image -- all from the terminal.
3+
A lightweight subnet audit tool. Scan a network, see what's alive, diff changes, and export a topology image -- all from the terminal.
44

55
[![PyPI](https://img.shields.io/pypi/v/whoson)](https://pypi.org/project/whoson/)
66
[![CI](https://github.com/daniissac/whoson/actions/workflows/ci.yml/badge.svg)](https://github.com/daniissac/whoson/actions/workflows/ci.yml)
@@ -24,75 +24,146 @@ pip install whoson
2424
# Scan a subnet and print a host table
2525
whoson 192.168.1.0/24
2626

27-
# Save a topology diagram as PNG
28-
whoson 192.168.1.0/24 -i topology.png
27+
# Scan multiple subnets at once
28+
whoson 192.168.1.0/24 10.0.0.0/24
2929

30-
# Or as JPEG or SVG
30+
# Save a topology diagram as PNG, JPEG, or SVG
31+
whoson 192.168.1.0/24 -i topology.png
3132
whoson 192.168.1.0/24 -i topology.jpg
3233
whoson 192.168.1.0/24 -i topology.svg
3334

3435
# Export as JSON or CSV
3536
whoson 192.168.1.0/24 --json results.json
3637
whoson 192.168.1.0/24 --csv hosts.csv
3738

38-
# Use ping-only scan (faster, but no port/MAC info without root)
39+
# Use ping-only scan (faster, but no port info)
3940
whoson 192.168.1.0/24 -t ping
4041

41-
# SYN stealth scan (faster than tcp, requires root)
42+
# SYN stealth scan (requires root)
4243
sudo whoson 10.0.0.0/24 -t syn
4344

4445
# Quiet mode -- only write files, no terminal output
4546
whoson 192.168.1.0/24 -i out.png --json out.json -q
4647

47-
# Combine everything (sudo for MAC/vendor info)
48+
# Combine everything (sudo for MAC/vendor/OS info)
4849
sudo whoson 192.168.1.0/24 -i topology.png --json data.json --csv hosts.csv
4950
```
5051

52+
### Scan Diffing
53+
54+
Save a baseline scan and compare later to spot what changed:
55+
56+
```bash
57+
# Save today's scan
58+
whoson 192.168.1.0/24 --save baseline.json
59+
60+
# Later, compare against the baseline
61+
whoson 192.168.1.0/24 --diff baseline.json
62+
```
63+
64+
Output shows added, removed, and changed hosts:
65+
66+
```
67+
+ 192.168.1.42 new host (workstation)
68+
- 192.168.1.50 gone (was: workstation)
69+
~ 192.168.1.10 port 8080 opened
70+
```
71+
72+
### Watch Mode
73+
74+
Continuously rescan and report changes:
75+
76+
```bash
77+
# Rescan every 60 seconds
78+
whoson 192.168.1.0/24 --watch 60
79+
80+
# Or use minute notation
81+
whoson 192.168.1.0/24 --watch 5m
82+
```
83+
84+
### Known-Host Inventory
85+
86+
Compare scan results against an expected inventory CSV to flag rogue or missing hosts:
87+
88+
```bash
89+
whoson 192.168.1.0/24 --inventory hosts.csv
90+
```
91+
92+
Inventory CSV format:
93+
94+
```csv
95+
IP,Hostname,Type
96+
192.168.1.1,router,gateway
97+
192.168.1.10,web-srv,server
98+
```
99+
100+
Output:
101+
102+
```
103+
ROGUE (1 unknown hosts):
104+
! 192.168.1.42 -
105+
MISSING (1 expected hosts not found):
106+
? 192.168.1.50 db (expected: server)
107+
OK (2 hosts match inventory)
108+
```
109+
51110
### Example output
52111

53112
```
54113
Scanning 192.168.1.0/24 (254 usable addresses, tcp scan)
55114
Found 5 hosts in 4.2s
56115
57-
IP Hostname Type MAC Vendor Ports
58-
--------------------------------------------------------------------------------
59-
192.168.1.1 router.local gateway AA:BB:CC:DD:EE:01 Cisco -
60-
192.168.1.10 web-srv server AA:BB:CC:DD:EE:10 Dell 80,443
61-
192.168.1.15 db-srv server AA:BB:CC:DD:EE:15 Dell 3306
62-
192.168.1.50 - workstation AA:BB:CC:DD:EE:50 Apple -
63-
192.168.1.99 hp-printer printer AA:BB:CC:DD:EE:99 HP 9100
116+
IP Hostname Type OS MAC Vendor Ports
117+
--------------------------------------------------------------------------------------------------
118+
192.168.1.1 router.local gateway Cisco IOS 15.1 AA:BB:CC:DD:EE:01 Cisco -
119+
192.168.1.10 web-srv server Linux 5.4 AA:BB:CC:DD:EE:10 Dell 80,443
120+
192.168.1.15 db-srv server Ubuntu 20.04 AA:BB:CC:DD:EE:15 Dell 3306
121+
192.168.1.50 - workstation - AA:BB:CC:DD:EE:50 Apple -
122+
192.168.1.99 hp-printer printer HP LaserJet AA:BB:CC:DD:EE:99 HP 9100
64123
```
65124

66125
## Scan Types
67126

68-
| Type | Flag | Root | Ports | MAC/Vendor | Speed |
69-
|------|------|------|-------|------------|-------|
70-
| TCP connect (default) | `-t tcp` | No | Yes | With `sudo` | Moderate |
71-
| SYN stealth | `-t syn` | Yes | Yes | Yes | Fast |
72-
| Ping only | `-t ping` | No | No | With `sudo` | Fastest |
127+
| Type | Flag | Root | Ports | MAC/Vendor | OS Detection | Speed |
128+
|------|------|------|-------|------------|--------------|-------|
129+
| TCP connect (default) | `-t tcp` | No | Yes | With `sudo` | With `sudo` | Moderate |
130+
| SYN stealth | `-t syn` | Yes | Yes | Yes | Yes | Fast |
131+
| Ping only | `-t ping` | No | No | With `sudo` | With `sudo` | Fastest |
73132

74-
Use `sudo` for MAC/vendor detection on any scan type. Without root, you still get IP, hostname, and open ports (on tcp/syn scans).
133+
Use `sudo` for MAC/vendor and OS detection on any scan type. OS fingerprinting (`nmap -O`) is enabled automatically when running as root.
75134

76135
## Host Classification
77136

137+
Hosts are classified using OS fingerprint data (when available) and open ports:
138+
78139
| Type | Criteria | Color |
79140
|------|----------|-------|
80-
| Gateway | IP ends in `.1` or `.254` | Red |
81-
| Server | Open ports: 22, 80, 443, 25, 53, etc. | Teal |
82-
| Printer | Open ports: 515, 631, 9100 | Green |
141+
| Gateway | OS contains network keywords (IOS, RouterOS, etc.) or IP ends in `.1`/`.254` | Red |
142+
| Server | OS contains server keywords (Linux, Ubuntu, etc.) or open ports: 22, 80, 443, 25, 53, etc. | Teal |
143+
| Printer | OS contains printer keywords (LaserJet, Ricoh, etc.) or open ports: 515, 631, 9100 | Green |
83144
| Workstation | Default | Blue |
84145

85-
## Export Formats
146+
## CLI Reference
86147

87-
| Format | Flag | Description |
88-
|--------|------|-------------|
89-
| PNG | `-i out.png` | Raster topology image |
90-
| JPEG | `-i out.jpg` | Raster topology image (compressed) |
91-
| SVG | `-i out.svg` | Vector topology image (scalable) |
92-
| JSON | `--json FILE` | Full topology data with metadata |
93-
| CSV | `--csv FILE` | Host list with IP, hostname, type, MAC, vendor, ports |
148+
```
149+
whoson [-h] [-t {ping,tcp,syn}] [-i FILE] [--json FILE] [--csv FILE]
150+
[--save FILE] [--diff FILE] [--watch INTERVAL]
151+
[--inventory FILE] [-q]
152+
SUBNET [SUBNET ...]
153+
```
94154

95-
The `-i` / `--image` flag detects the format from the file extension (`.png`, `.jpg`, `.jpeg`, `.svg`).
155+
| Flag | Description |
156+
|------|-------------|
157+
| `SUBNET` | One or more networks in CIDR notation |
158+
| `-t`, `--type` | Scan type: `ping`, `tcp` (default), `syn` |
159+
| `-i`, `--image FILE` | Save topology image (`.png`, `.jpg`, `.svg`) |
160+
| `--json FILE` | Save topology data as JSON |
161+
| `--csv FILE` | Save host list as CSV |
162+
| `--save FILE` | Save scan result JSON for later diffing |
163+
| `--diff FILE` | Compare current scan against a saved baseline |
164+
| `--watch INTERVAL` | Rescan at interval, show changes (e.g. `60`, `5m`) |
165+
| `--inventory FILE` | Compare scan against known-host inventory CSV |
166+
| `-q`, `--quiet` | Suppress table output (only write files) |
96167

97168
## Scope and Limitations
98169

@@ -102,7 +173,7 @@ For real topology discovery using CDP/LLDP/SNMP, see [LibreNMS](https://www.libr
102173

103174
## Dependencies
104175

105-
**Runtime:** `python-nmap` + `Pillow` (2 packages).
176+
**Runtime:** `python-nmap` + `Pillow` (2 packages). Zero new dependencies for all features.
106177

107178
**System:** `nmap` must be available on `PATH`.
108179

0 commit comments

Comments
 (0)