A network security monitoring platform that discovers devices on your local network, scans for open ports, fingerprints services, detects network changes over time, scores host risk, generates alerts, and provides a real-time dashboard with live scan progress for security operations.
Host Discovery — ARP scan via scapy + concurrent ICMP ping sweep (merged for best coverage)
Port Scanning — Concurrent TCP connect scanner with 120+ common ports database
Service Fingerprinting — Banner grabbing for SSH, HTTP, FTP, SMTP, MySQL, PostgreSQL, Redis, MongoDB
MAC Vendor Lookup — Resolve MAC addresses to device manufacturers
HTML Report — Static D3.js network topology with dark theme
JSON Export — Machine-readable output for scripting
REST API — 33 endpoints for scans, hosts, alerts, risk scores, schedules, changes, settings, and export
WebSocket — Real-time scan progress streaming at /api/ws/scans/{id}
Scan Persistence — SQLite database stores full scan history with hosts and ports
Background Scans — Trigger scans via API, results stored automatically
Swagger Docs — Auto-generated interactive API documentation at /docs
Network Drift Monitoring — Automatically diffs consecutive scans for the same subnet
Event Types — New host appeared, host disappeared, port opened, port closed
Full Context — Each change event includes MAC, vendor, hostname, service info
Recurring Scans — APScheduler-based scheduler with configurable intervals (1 min to 24 hours)
Auto-Detection — Scheduled scans trigger change detection and alert evaluation automatically
CRUD API — Create, update, enable/disable, and delete schedules
6-Factor Weighted Scoring (0-100 per host):
Risky ports (35%) — FTP, Telnet, RDP, SMB, Redis, MongoDB, etc.
Total open ports (20%) — logarithmic scale
Unknown vendor (15%) — unidentified devices score higher
No hostname (10%) — missing reverse DNS
Banner exposure (10%) — version info leaked in service banners
Vulnerable services (10%) — regex matching against known-bad software versions
20 risky ports defined with threat descriptions
9 vulnerable software patterns (outdated OpenSSH, Apache, IIS, PHP, etc.)
5 Built-in Rules:
new_device (medium) — unknown device appeared on the network
host_disappeared (low) — previously seen device no longer responding
risky_port_opened (high) — commonly targeted port detected
high_risk_host (high) — host risk score exceeds 70
critical_risk_host (critical) — host risk score exceeds 90
Read/Unread Tracking — mark individual or bulk mark-all-read
Severity Filtering — filter alerts by critical, high, medium, low
Dashboard — Stats cards, recent alerts, network changes, top risk hosts, scan history
Network Topology — Interactive D3.js force graph with drag, hover, click-to-navigate
Host Detail — Full device profile with ports table, banners, risk gauge
Scan History — All scans with status, duration, host/port counts
Scan Detail — Per-scan breakdown with detected changes, hosts, and export buttons
Scan Comparison — Side-by-side diff of two scans showing new/lost hosts and ports
Alerts Panel — Severity-filtered alert list with stats and bulk actions
Settings Page — Configure scan defaults (subnet, timeout, workers, fingerprinting)
Live Scan Progress — WebSocket-powered real-time updates during scans
Data Export — Download scan results as JSON or CSV
Dark Theme — GitHub-inspired dark UI design
Python 3.11+
Node.js 18+ (for the dashboard)
Npcap (Windows only — npcap.com , required for scapy ARP scanning)
1. Clone and install the Python backend
git clone https://github.com/yourusername/portmapper.git
cd portmapper
pip install -e .
cd frontend
npm install
cd ..
The API starts at http://localhost:8000. Swagger docs are at http://localhost:8000/docs.
4. Start the dashboard (separate terminal)
The dashboard opens at http://localhost:3000.
Either click "New Scan" in the dashboard (with live progress), or use the CLI:
# CLI scan with terminal output
portmapper scan -f
# Or trigger via API
curl -X POST http://localhost:8000/api/scans \
-H " Content-Type: application/json" \
-d ' {"fingerprint": true}'
portmapper scan — Run a network scan
# Auto-detect subnet, scan top ports
portmapper scan
# Specific subnet with fingerprinting
portmapper scan 192.168.1.0/24 -f
# Custom ports + HTML report
portmapper scan --ports 22,80,443,3389 -f --output report.html
# JSON output for scripting
portmapper scan --format json > results.json
# Ping sweep (no admin privileges needed)
portmapper scan --no-arp
# Fast scan with more threads
portmapper scan --timeout 0.3 --workers 200
Option
Short
Default
Description
SUBNET
auto-detect
Target network in CIDR notation
--ports
-p
top 120+
Ports to scan (e.g., 22,80,443 or 1-1024)
--timeout
-t
0.5
Socket timeout in seconds
--workers
-w
100
Concurrent threads for port scanning
--fingerprint
-f
off
Enable service fingerprinting via banner grabbing
--output
-o
none
Save HTML report to file
--format
table
Output format: table or json
--no-arp
off
Skip ARP scan, use ping sweep only
--discovery-timeout
2.0
Timeout for host discovery phase
portmapper serve — Start the API server
# Default (0.0.0.0:8000)
portmapper serve
# Custom host and port
portmapper serve --host 127.0.0.1 --port 9000
Option
Default
Description
--host
0.0.0.0
Host to bind the server to
--port
8000
Port to bind the server to
--reload
off
Enable auto-reload for development
All endpoints are prefixed with /api. Full interactive docs available at /docs when the server is running.
Method
Endpoint
Description
POST
/api/scans
Trigger a new scan (returns immediately, runs in background)
GET
/api/scans
List all scans with status/pagination filters
GET
/api/scans/{id}
Full scan detail with hosts and ports
GET
/api/scans/{id}/compare/{other_id}
Compare two scans (new/lost hosts, opened/closed ports)
DELETE
/api/scans/{id}
Delete a scan and all results
Endpoint
Description
ws://host:port/api/ws/scans/{id}
Stream live scan progress (phase, host count, port count)
Method
Endpoint
Description
GET
/api/hosts
List hosts (defaults to latest completed scan)
GET
/api/hosts/{id}
Host detail with all open ports
Method
Endpoint
Description
POST
/api/schedules
Create a recurring scan schedule
GET
/api/schedules
List all schedules
GET
/api/schedules/{id}
Schedule detail
PATCH
/api/schedules/{id}
Update interval, enabled status, or options
DELETE
/api/schedules/{id}
Remove schedule
Method
Endpoint
Description
GET
/api/changes
List change events (filter by scan_id, event_type, ip)
GET
/api/changes/{id}
Change event detail
Method
Endpoint
Description
GET
/api/alerts
List alerts (filter by severity, read status, rule name)
GET
/api/alerts/stats
Alert statistics (total, unread, by severity)
GET
/api/alerts/{id}
Alert detail
PATCH
/api/alerts/{id}
Mark alert read/unread
POST
/api/alerts/mark-all-read
Bulk mark all alerts as read
DELETE
/api/alerts/{id}
Delete an alert
Method
Endpoint
Description
GET
/api/risk/latest
Risk scores from latest scan (filter by min_score)
GET
/api/risk/scans/{id}
All risk scores for a specific scan
GET
/api/risk/hosts/{id}
Latest risk score for a specific host
Method
Endpoint
Description
GET
/api/settings
Get current scan configuration
PUT
/api/settings
Update scan configuration
Method
Endpoint
Description
GET
/api/export/scans/{id}/json
Download full scan data as JSON file
GET
/api/export/scans/{id}/csv
Download scan hosts/ports as CSV file
GET
/api/export/report
Download summary report of latest scan
Method
Endpoint
Description
GET
/api/health
Server health check and version
portmapper scan 192.168.1.0/24 -f
┌──────────────────┐
│ 1. Discovery │ ARP broadcast + ICMP ping sweep (merged)
└────────┬─────────┘ 50 concurrent workers for ping
▼
┌──────────────────┐
│ 2. Port Scanning │ ThreadPoolExecutor: 100 threads x 120+ ports
└────────┬─────────┘ socket.connect_ex() → open / closed / filtered
▼
┌──────────────────┐
│ 3. Fingerprint │ Connect to open ports, read banners
└────────┬─────────┘ Parse: SSH version, HTTP server, DB type
▼
┌──────────────────┐
│ 4. Persist │ Write scan, hosts, ports to SQLite
└────────┬─────────┘
▼
┌──────────────────┐
│ 5. Change Detect │ Diff vs previous scan for same subnet
└────────┬─────────┘ → new_host, lost_host, port_opened, port_closed
▼
┌──────────────────┐
│ 6. Risk Scoring │ 6-factor weighted score per host (0-100)
└────────┬─────────┘
▼
┌──────────────────┐
│ 7. Alert Engine │ Evaluate 5 rules against changes + risk
└──────────────────┘ → Generate alerts with severity levels
Factor
Weight
What it measures
Risky ports
35%
FTP(21), Telnet(23), RDP(3389), SMB(445), Redis(6379), MongoDB(27017), etc.
Total open ports
20%
More exposure = higher risk (logarithmic scale)
Unknown vendor
15%
Unidentified devices are suspicious
No hostname
10%
Missing reverse DNS suggests unmanaged device
Banner exposure
10%
Version strings leaked in service banners
Vulnerable services
10%
Outdated OpenSSH, Apache 2.2, IIS 5-7, PHP 5.x, etc.
portmapper/
├── portmapper/ # Python backend
│ ├── __init__.py # Package version (1.0.0)
│ ├── cli.py # Click CLI (scan + serve commands)
│ ├── models.py # Host, Port, PortState dataclasses
│ ├── discovery.py # ARP scan + concurrent ping sweep (merged)
│ ├── scanner.py # Concurrent TCP port scanner
│ ├── fingerprint.py # Banner grabbing + service ID
│ ├── network_utils.py # Subnet detection, MAC lookup, port helpers
│ ├── api/
│ │ ├── app.py # FastAPI app factory + lifespan
│ │ ├── ws.py # WebSocket scan progress endpoint
│ │ └── routers/
│ │ ├── scans.py # Scan CRUD + comparison endpoints
│ │ ├── hosts.py # Host list/detail endpoints
│ │ ├── schedules.py # Schedule CRUD endpoints
│ │ ├── changes.py # Change event endpoints
│ │ ├── alerts.py # Alert endpoints
│ │ ├── risk.py # Risk score endpoints
│ │ ├── settings.py # Settings GET/PUT endpoints
│ │ └── export.py # JSON/CSV export endpoints
│ ├── db/
│ │ ├── engine.py # SQLAlchemy engine + session
│ │ └── models.py # ORM models (8 tables)
│ ├── schemas/ # Pydantic request/response schemas
│ │ ├── scan.py # Scan + ScanComparison schemas
│ │ ├── host.py, port.py # Host and port schemas
│ │ ├── schedule.py # Schedule schemas
│ │ ├── change.py # Change event schemas
│ │ ├── risk.py # Risk score schemas
│ │ ├── alert.py # Alert schemas
│ │ └── settings.py # Settings schemas
│ ├── services/
│ │ ├── scan_service.py # Scan orchestration + progress tracking
│ │ ├── change_detection.py # Network diff engine
│ │ ├── scheduler_service.py # APScheduler management
│ │ ├── risk_engine.py # 6-factor risk scoring
│ │ ├── alert_service.py # Rule-based alert generation
│ │ └── settings_service.py # JSON file settings persistence
│ ├── config/
│ │ ├── risk_rules.py # Risk scoring weights + risky ports
│ │ └── alert_rules.py # Alert rule definitions
│ └── report/
│ ├── console.py # Rich terminal output
│ ├── html.py # Static HTML report generator
│ └── templates/
│ └── report.html # Jinja2 + D3.js template
├── frontend/ # Next.js dashboard
│ ├── src/
│ │ ├── app/
│ │ │ ├── page.tsx # Dashboard overview
│ │ │ ├── topology/ # Network topology graph
│ │ │ ├── hosts/ # Host list + detail
│ │ │ ├── scans/ # Scan history + detail + comparison
│ │ │ ├── alerts/ # Alert management
│ │ │ └── settings/ # Settings configuration page
│ │ ├── components/
│ │ │ ├── Sidebar.tsx # Navigation sidebar
│ │ │ ├── NetworkTopology.tsx # D3.js force graph
│ │ │ ├── StatCard.tsx # Metric display card
│ │ │ ├── PortBadge.tsx # Port/service badge
│ │ │ ├── RiskGauge.tsx # Circular risk indicator
│ │ │ └── ScanButton.tsx # Scan trigger with WebSocket progress
│ │ └── lib/
│ │ ├── api.ts # Typed API client (33 endpoints)
│ │ ├── hooks.ts # useAPI data fetching hook
│ │ └── utils.ts # Helpers (timeAgo, colors, cn)
│ └── package.json
├── data/
│ ├── common_ports.json # 120+ common ports database
│ └── settings.json # Scan configuration (auto-created)
├── pyproject.toml
├── requirements.txt
└── README.md
Version
What was added
v0.1
ARP host discovery with ping sweep fallback
v0.2
TCP port scanner with concurrent execution
v0.3
Service fingerprinting via banner grabbing
v0.4
Interactive HTML report with D3.js topology
v0.5
FastAPI backend + SQLite persistence + REST API
v0.6
Scan scheduler + change detection engine
v0.7
Risk scoring engine + configurable alert system
v0.8
Next.js dashboard with topology, hosts, scans, alerts UI
v0.9
WebSocket live scan progress + scan comparison
v1.0
Settings management + data export (JSON/CSV)
ARP scanning requires admin/root privileges. Run with sudo on Linux/macOS or as Administrator on Windows. Use --no-arp for unprivileged ping sweep.
Windows users need Npcap installed for scapy raw socket support. Download from npcap.com .
Discovery runs both ARP + ping sweep and merges results for maximum coverage. ARP provides MAC/vendor data, ping sweep catches devices that don't respond to ARP.
The SQLite database is stored at data/portmapper.db (auto-created on first portmapper serve). Override with PORTMAPPER_DB_URL environment variable.
Settings are stored in data/settings.json and can be configured via the Settings page or API.
The frontend expects the API at http://localhost:8000. Override with NEXT_PUBLIC_API_URL in frontend/.env.local.
Use --workers to tune scan concurrency. Higher values scan faster but may overwhelm consumer routers.
MIT