Skip to content

About

A fast, concurrent open-source network scanner with a TUI and plain-text CLI, built in Go. It discovers live hosts on your network, scans their open ports, resolves hostnames, and fingerprints operating systems.

Topics

Resources

Contributing

Stars

32 stars

Watchers

0 watching

Forks

Repository files navigation

✧ SubnetLens ✧

Go Version Bubble Tea Cobra Visitors

CLI Interface License

A fast, concurrent open-source network scanner with a TUI and plain-text CLI, built in Go.

Website: https://ostefani.github.io/subnetlens/ — Core vs Pro comparison.

📌

Not affiliated with subnetlens.com. This project (github.com/ostefani/subnetlens) is an independent open-source tool, first released in March 2026 under the MIT license and developed by Olha Stefanishyna. It has no affiliation with, and is not endorsed by, the website subnetlens.com or any software sold there. The only official source code and releases are in this repository.

Learn more about official SubnetLens Pro at GitHub Pages.

📌

Key Rotation Note: New signature keys effective Oct 8, 2026. Legacy keys are no longer active on this profile. Commits signed before that date may appear Unverified as a result of the rotation.

Supports multiple discovery methods:

  • TCP connect scan (no elevated privileges required)
  • ICMP echo (requires root / administrator)
  • ARP scan (Linux/macOS; Windows requires Npcap)
  • mDNS (passive listener + active discovery trigger)
  • Hostname resolution via mDNS, NBNS, and reverse DNS (PTR)

Features

  • Host discovery (TCP, ICMP, ARP, mDNS)
  • Port scanning (TCP connect)
  • OS & Device Fingerprinting: Heuristically detects operating systems and device types.
  • Vendor & MAC Resolution: Uses OUI databases to identify device vendors and detects randomized MAC addresses.
  • Streaming TUI: A visual interface built with Charm's Bubbletea.
  • Plain Text Mode: Script-friendly output.
  • Single binary

Preview

SubnetLens TUI

OUI database

The file scanner/oui.csv maps MAC address prefixes to device vendors. It is obtained from the IEEE Registration Authority and is included in this repository so that both local builds and the release binary ship with full vendor resolution.

If you need to refresh it, download the latest CSV from the link above and replace scanner/oui.csv.

Quick Start

Clone the repository to build from source, see Install a built binary or use a precompiled binary. Pay attention that bynaries attached to the release are not signed, so MacOS and Windows will complain about it. If you don't want to see the warnings build from source.

Note: On macOS and Linux, run with sudo to enable ARP and ICMP. On Windows, run the terminal as Administrator. TCP scan requires no elevated privileges.

Prerequisites

  • Go 1.25+ (go version)
  • Clone and enter the repo:
git clone https://github.com/ostefani/subnetlens
cd subnetlens
go mod tidy

Run in dev mode (no install)

Use this while developing. It always runs the current source and leaves no binary behind:

go run . scan <target> --plain

Examples:

go run . scan 192.168.1.0/24 --plain
sudo go run . scan 192.168.1.0/24 --plain   # enables ARP + ICMP

Use --plain for script-friendly output while testing; omit it to launch the TUI.

Build a local binary

go build -o subnetlens .
./subnetlens scan <target> --plain

Note the ./ prefix: zsh does not look in the current directory, so bare subnetlens scan ... reports command not found until the binary is installed on your PATH.

Install a built binary

Pick one:

# Option A: install via Go (binary lands in $(go env GOPATH)/bin)
go install .
# then make sure that directory is on your PATH, e.g.:
export PATH="$PATH:$(go env GOPATH)/bin"

# Option B: build, then install your local build system-wide
go build -o subnetlens .
sudo install ./subnetlens /usr/local/bin/subnetlens

Verify:

which subnetlens
subnetlens --help
subnetlens scan 192.168.1.0/24 --plain

Debug mode

# Into console
sudo SLENS_DEBUG=1 ./subnetlens scan <target> --plain
# Into file
sudo SLENS_DEBUG=1 ./subnetlens scan <target> --plain 2>debug.log
# Print from file
cat debug.log

Testing

go test ./...
go test -race ./...

The current test suite includes regression coverage for:

  • models.Host sanitization, concurrent mutation, snapshot safety, and scan option defaults
  • host registry merge behavior for late ARP updates and duplicate events
  • engine coordination, so pre-ready host updates do not emit premature callbacks, and preheating is skipped when target expansion fails
  • scanner resource planning, resolver socket accounting, and local discovery helpers
  • TUI viewport, batching, cached rendering, and local-machine presentation

Update dependencies

go get -u all

Usage

Scan Your Own Machine

Check interfaces and their assigned IPs. Scan only the subnet that matches your WiFi interface (en0) to stay on your home network.

ip addr                      # Linux
ifconfig  | grep "inet "     # macOS
subnetlens scan [subnet] [flags]

With no target — subnetlens scan or subnetlens scan local — the local subnet is detected automatically from your active network interfaces. Private (home/office) networks win over VPN tunnels, and a detected subnet over 1024 addresses narrows to your /24 unless --allow-large-scan is given.

Flags:

  • -p, --ports string Comma-separated ports to scan (default: common 23 ports)
  • -t, --timeout int Per-connection timeout in ms (default: 500)
  • -c, --concurrency int Max concurrent port scan and banner probes (default: 100)
  • --discovery-concurrency int Max concurrent host discovery probes (0 reuses --concurrency)
  • -b, --banners Grab service banners
  • --plain Plain text output (no TUI)
  • --all-alive Show all discovered hosts, including those that respond with TCP connection errors.
  • --allow-large-scan Confirm scans expanding to more than 1024 addresses (see Large scans)
  • --output string Save the scan report into DIR instead of ~/.subnetlens (the file is named automatically; - prints to stdout)
  • --format string Report format: json or csv (required with --output; without --output, saves to ~/.subnetlens)
  • --sort string Host listing order: discovery, ip, latency, vendor, hostname (default discovery)
  • --filter string Only show hosts matching EXPR, e.g. "port:22,os:linux" (see Sorting and filtering)

Platform Support

Feature Linux macOS Windows
TCP scan ✔ ✔ ✔
ICMP ✔ (root) ✔ (root) ✔ (admin)
ARP ✔ ✔ ✔ (Npcap required)
mDNS ✔ ✔ not tested

Windows prerequisite: Active ARP scanning requires Npcap — a kernel-level packet capture driver. If you have Wireshark installed, Npcap should be already present.

Examples:

  subnetlens scan
  subnetlens scan local
  subnetlens scan <IP>
  subnetlens scan <IP start>-<IP end>
  subnetlens scan <IP> --ports 22,80,443,8080
  subnetlens scan <IP> --plain --banners
  subnetlens scan <IP> --concurrency 100 --discovery-concurrency 400 --timeout 300
  subnetlens scan <IP> --format json
  subnetlens scan <IP> --plain --output ~/Downloads/ --format csv

Scan reports are saved only when you ask for them. --format json (or csv) saves a timestamped report to ~/.subnetlens (for example scan-20260928-093000.json); every run creates a new file, so past reports are kept and can be compared over time. On Windows this folder is %USERPROFILE%\.subnetlens. Pass --output with a folder to save somewhere else instead — the file is still named automatically. --format is required whenever --output is given. JSON is a versioned document (subnet, timestamps, hosts with open ports, issues); CSV is one row per open port with a header. Quitting the TUI before the scan finishes skips the export.

To print to the terminal instead of saving a file, use --output - (stdout, requires --format since there is no extension to infer from):

  subnetlens scan <IP> --plain
  subnetlens scan <IP> --plain --output - --format csv | head
  subnetlens scan <IP> --output - --format csv

Sorting and filtering

--sort orders the host listing: discovery (arrival order, the default), ip (numeric), latency (fastest first, unknown last), vendor, or hostname. In --plain mode, sorted or filtered output prints when the scan completes instead of streaming; exports always carry the full unfiltered result.

--filter narrows the listing to matching hosts. Comma separates AND conditions; repeating a key ORs its values. String values match case-insensitively as substrings; a bare term without a colon searches IP, hostname, MAC, vendor, OS, and device.

Keys: ip, host, mac, vendor, os, device, service (open-port service), port (open-port number), weak / alive (true/false), source (discovery source).

  subnetlens scan 192.168.1.0/24 --sort ip --plain
  subnetlens scan 192.168.1.0/24 --filter "port:22,os:linux" --plain
  subnetlens scan 192.168.1.0/24 --filter "port:22,port:80" --plain   # either port open
  subnetlens scan 192.168.1.0/24 --filter "printer,weak:false" --plain

In the TUI, --sort and --filter set the starting state, and keys adjust it live: s cycles the sort order, w hides weak-liveness hosts, o hides hosts with no open ports, c clears all filters. Scrolling: ↑/↓ or j/k, PgUp/PgDn, Home/End; q quits. The status line under the table always shows the active sort, filters, and keys.

Large scans

Targets expanding to more than 1024 addresses require explicit consent. A /24 (254 usable hosts) scans as usual; a /16 (65,534) does not:

  subnetlens scan 10.0.0.0/16
  # Error: target "10.0.0.0/16" expands to 65534 addresses
  # (over the 1024 address confirmation threshold): re-run with --allow-large-scan

  subnetlens scan 10.0.0.0/16 --allow-large-scan
  # Warning: target "10.0.0.0/16" expands to 65534 addresses: ...
  # ...scan proceeds in plain or TUI mode

The threshold is UX safety, not an architectural limit: enumeration streams (memory scales with discovered hosts, not candidate addresses), so cost grows in wall time — roughly one worst-case probe batch per discovery-concurrency window — which is what the flag asks you to accept. There is no hard maximum on 64-bit platforms. Library users set ScanOptions.AllowLargeScan; an invalid target fails fast the same way, before any socket is opened.

Project Structure

subnetlens /
├── main.go               # Entrypoint
├── cmd/
│   └── root.go           # Cobra CLI commands
├── scanner/              # Engine, discovery, enrichment, registry
│   ├── contracts/        # Extension seams (DiscoveryModule, HostScanner, ...)
│   └── oui.csv           # bundled IEEE OUI data used for vendor resolution
├── transports/           # TCP, ARP, ICMP, mDNS, NBNS protocol code
├── fingerprint/          # Rule-based OS/device hints from banners
├── internal/             # Shared net/text helpers
├── models/               # Host, ScanOptions, ScanResult
├── ui/tui/               # Bubble Tea interface
└── docs/                 # Landing page (https://ostefani.github.io/subnetlens/)

Roadmap

  • ARP-based host discovery (requires raw sockets / root)
  • MAC address vendor lookup
  • mDNS listening
  • Add tests
  • Scan profiles: --all-alive
  • JSON / CSV export (--format json)
  • UDP port scanning (Pro — private release)
  • GUI with interactive network node graph (Pro)
  • subnetlens watch — re-scan on interval, alert on changes (Pro — private release)

Contributing

Please see CONTRIBUTING.md for contribution and PR guidelines

License

MIT © 2026 Olha Stefanishyna

Disclaimer: This tool is intended for authorized network testing and diagnostics only. Do not scan networks or systems without explicit permission. Use responsibly.

SubnetLens Pro

A proprietary extension of SubnetLens focused on advanced scanning capabilities. Finished and distributed as a private release — request access via GitHub issues. Designed for users who need deeper visibility, automation, and continuous monitoring.

Available in Pro now

  • UDP discovery (SSDP, mDNS) and protocol-specific host probing (SSDP, mDNS, NBNS, SNMP, DNS, NTP)
  • Evidence-based service fingerprinting and metadata-driven device classification
  • subnetlens watch — continuous scanning with change detection, grace windows, and HMAC-signed webhook alerts

Planned

  • Interactive GUI with network visualization
  • Advanced output formats and reporting (JSON/CSV export)

Note: the Pro binary uses -subnet / -watch flags instead of the Core scan subcommand; details ship with the Pro README on access.

The core project will remain open source and fully usable. Pro features are designed for advanced analysis and extended workflows.

About

A fast, concurrent open-source network scanner with a TUI and plain-text CLI, built in Go. It discovers live hosts on your network, scans their open ports, resolves hostnames, and fingerprints operating systems.

Topics

Resources

Contributing

Stars

32 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages