Skip to content

Scanning and Schedules

The agent’s scanner engine is the core of device discovery. This page covers the 14 active scanners, 5 passive listeners, scan profiles, interactive scanning from the control plane, and scheduled scans.

Active scanners probe the network on demand. They run in parallel with a configurable concurrency limit (default 50 concurrent probes per scan).

Scanner Key Protocol Privileged? What it finds
ARP arp ARP (L2) Yes (Scapy) MAC addresses, OUI vendor lookup, L2 topology
Ping ping ICMP via subprocess No Live hosts without raw sockets
TCP port tcp_port TCP connect No Open ports; maps to service type
HTTP service http_service HTTP/HTTPS No Web interfaces, admin panels, device model headers
Banner grab banner SSH/Telnet No Device OS/version from login banner
SNMP snmp SNMP v1/v2c UDP 161 No sysDescr, sysName, interfaces, OID-based type detection
NetBIOS netbios NetBIOS UDP 137 No Windows hostnames, workgroup, domain
mDNS mdns Multicast UDP 5353 No Bonjour services (printers, Apple devices, IoT)
SSDP ssdp Multicast UDP 1900 No UPnP devices, smart home, media servers
SIP sip SIP OPTIONS UDP 5060 No VoIP phones, gateways, PBX trunks
DNS reverse dns DNS No Hostnames for discovered IPs
RTSP rtsp TCP 554 No IP cameras, NVRs, RTSP streams
ONVIF WS-Discovery onvif WS-Discovery UDP 3702 No ONVIF-capable cameras and NVRs
Hikvision SADP sadp Proprietary UDP 37020 No Hikvision cameras and NVRs (including unconfigured devices)

Seven composite profiles ship out of the box. Each activates a subset of the scanners above:

Profile Key Scanners activated Typical use
Quick quick ping Fast host enumeration
Camera camera ping, onvif, sadp, rtsp Find all cameras and NVRs
VoIP voip ping, sip, mdns Find phones, gateways, PBX
IoT iot ping, mdns, ssdp Smart devices, media servers
Port scan port ping, tcp_port, http_service, banner Open service enumeration
Windows windows ping, netbios Windows hosts and shares
Full full All scanners Comprehensive, slower

The agent advertises only the profiles it can fully execute - if Scapy is not installed, camera is excluded from the advertised scan_types. This is a conservative advertisement policy: the onvif and sadp scanners themselves use plain UDP sockets and do not require Scapy at runtime, but the capability module omits them when Scapy is absent to avoid scheduling scans on agents where the full intended stack is not present.

Passive listeners run as long-lived background asyncio tasks. They are disabled by default because they require root/SYSTEM privileges. Enable them in passive section of the agent config:

{
"passive": {
"enable_lldp": true,
"enable_cdp": true,
"enable_snmp_traps": false,
"snmp_trap_port": 162,
"enable_syslog": false,
"syslog_port": 514,
"enable_dhcp_watcher": false
}
}
Listener Key What it captures Privilege requirement
LLDP lldp Layer 2 neighbor information (switch ports, VLANs, capabilities) Raw L2 socket, root
CDP cdp Cisco Discovery Protocol frames Raw L2 socket, root
SNMP trap snmp_trap SNMP trap PDUs from devices UDP 162, root (privileged port)
Syslog syslog RFC 3164/5424 syslog messages UDP 514, root (privileged port)
DHCP watcher dhcp DHCP lease events and ARP table changes Promiscuous mode, root

Events from passive listeners are forwarded to the control plane via WebSocket: LLDP and CDP emit topology_update reports; SNMP traps and DHCP watcher emit device_event reports; syslog emits log reports.

An admin can trigger a scan on any approved, connected agent directly from the FreeSDN UI:

  1. Go to Discovery in the sidebar
  2. Select the Agents tab
  3. Choose a connected agent, enter a CIDR target (e.g. 192.168.1.0/24), select a scan profile
  4. Click Run Scan

The control plane sends a scan_network command over the WebSocket:

{
"id": "uuid",
"type": "scan_network",
"payload": {
"targets": ["192.168.1.0/24"],
"scan_type": "quick"
},
"priority": 5,
"timeout_seconds": 300
}

The agent reports progress back in real time (scan_progress messages) and submits results when complete (scan_result). Progress and discovered devices appear live in the UI.

The fingerprint_device command runs all available scanners against a single IP for maximum detail:

{
"type": "fingerprint_device",
"payload": { "ip_address": "192.168.1.150" }
}

The desktop app exposes this as the Fingerprint button in the device detail panel.

Run a scan locally without the control plane:

Terminal window
# Quick scan of the local subnet (auto-detects interfaces)
freesdn-agent scan --type quick
# Camera scan of a specific subnet
freesdn-agent scan --type camera --targets 10.10.20.0/24
# Full scan on a specific interface
freesdn-agent scan --type full --targets 192.168.1.0/24 --interface eth0

Results are printed to stdout. Use this to verify scanners work before deploying the daemon.

The daemon supports cron-scheduled scans that run automatically without operator intervention.

Schedules are created and stored in the FreeSDN control plane (not just in the local config file). When the agent connects, the server pushes the current schedule list via a update_schedule WebSocket command. Changes made in the UI take effect immediately - the server pushes an update_schedule command over the WebSocket connection to any connected agents at the site as soon as a schedule is created, updated, or deleted. No agent restart is required.

Terminal window
# List current schedules at this agent's site
freesdn-agent schedule list
# Add a daily camera scan at 2 AM
freesdn-agent schedule add \
--name "nightly-cameras" \
--cron "0 2 * * *" \
--scan-type camera \
--targets 10.10.20.0/24
# Add a quick scan every 4 hours
freesdn-agent schedule add \
--name "frequent-poll" \
--cron "0 */4 * * *" \
--scan-type quick
# Remove a schedule by UUID
freesdn-agent schedule remove <schedule-uuid>

Standard 5-field cron: minute hour day-of-month month day-of-week

Field Range Examples
Minute 0-59 0, */15, 0,30
Hour 0-23 2, */4, 8-18
Day of month 1-31 *, 1, 15
Month 1-12 *, 6, 1,7
Day of week 0-6 (Sun=0) *, 1-5, 0,6

Examples:

0 6 * * * Daily at 06:00
0 */4 * * * Every 4 hours
0 2 * * 0 Every Sunday at 02:00
*/5 * * * * Every 5 minutes (minimum allowed interval)
Limit Value
Maximum schedules per agent 50
Minimum cron interval 5 minutes (expressions firing more than 12×/hour are rejected)
Maximum concurrent scheduled scans 4

If a scheduled scan is still running when its next cron slot fires, the new trigger is skipped for that slot (no double-run).

Scheduled scan results flow through the same scan_result WebSocket report as interactive scans. The payload includes schedule_name, duration_seconds, device_count, and status. The control plane records these in agent_schedule_runs for history and updates last_fired_at on the schedule record.

Failed runs are also recorded - the report uses status: "failed" with an error field so the history table has a single timeline of all runs.

After a scan, use the Inventory page in FreeSDN to view discovered hosts. Hosts can be adopted individually (click Adopt) or in bulk. The CLI also supports this workflow:

Terminal window
# List unadopted discovered hosts at the agent's site
freesdn-agent list-discovered
# Adopt specific hosts (server auto-matches adapter/driver)
freesdn-agent adopt 192.168.1.150 192.168.1.51
# Adopt all unadopted hosts
freesdn-agent adopt all
# Adopt with an explicit driver override
freesdn-agent adopt 192.168.1.150 --driver mikrotik_routeros
# Dry run - shows payload without submitting
freesdn-agent adopt 192.168.1.150 --dry-run

All product names, logos, and brands are property of their respective owners. FreeSDN is an independent project and is not affiliated with or endorsed by the vendors it integrates with. See Trademarks.