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).

ScannerKeyProtocolPrivileged?What it finds
ARParpARP (L2)Yes (Scapy)MAC addresses, OUI vendor lookup, L2 topology
PingpingICMP via subprocessNoLive hosts without raw sockets
TCP porttcp_portTCP connectNoOpen ports; maps to service type
HTTP servicehttp_serviceHTTP/HTTPSNoWeb interfaces, admin panels, device model headers
Banner grabbannerSSH/TelnetNoDevice OS/version from login banner
SNMPsnmpSNMP v1/v2c UDP 161NosysDescr, sysName, interfaces, OID-based type detection
NetBIOSnetbiosNetBIOS UDP 137NoWindows hostnames, workgroup, domain
mDNSmdnsMulticast UDP 5353NoBonjour services (printers, Apple devices, IoT)
SSDPssdpMulticast UDP 1900NoUPnP devices, smart home, media servers
SIPsipSIP OPTIONS UDP 5060NoVoIP phones, gateways, PBX trunks
DNS reversednsDNSNoHostnames for discovered IPs
RTSPrtspTCP 554NoIP cameras, NVRs, RTSP streams
ONVIF WS-DiscoveryonvifWS-Discovery UDP 3702NoONVIF-capable cameras and NVRs
Hikvision SADPsadpProprietary UDP 37020NoHikvision cameras and NVRs (including unconfigured devices)

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

ProfileKeyScanners activatedTypical use
QuickquickpingFast host enumeration
Cameracameraping, onvif, sadp, rtspFind all cameras and NVRs
VoIPvoipping, sip, mdnsFind phones, gateways, PBX
IoTiotping, mdns, ssdpSmart devices, media servers
Port scanportping, tcp_port, http_service, bannerOpen service enumeration
Windowswindowsping, netbiosWindows hosts and shares
FullfullAll scannersComprehensive, 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
}
}
ListenerKeyWhat it capturesPrivilege requirement
LLDPlldpLayer 2 neighbor information (switch ports, VLANs, capabilities)Raw L2 socket, root
CDPcdpCisco Discovery Protocol framesRaw L2 socket, root
SNMP trapsnmp_trapSNMP trap PDUs from devicesUDP 162, root (privileged port)
SyslogsyslogRFC 3164/5424 syslog messagesUDP 514, root (privileged port)
DHCP watcherdhcpDHCP lease events and ARP table changesPromiscuous 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

FieldRangeExamples
Minute0-590, */15, 0,30
Hour0-232, */4, 8-18
Day of month1-31*, 1, 15
Month1-12*, 6, 1,7
Day of week0-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)
LimitValue
Maximum schedules per agent50
Minimum cron interval5 minutes (expressions firing more than 12×/hour are rejected)
Maximum concurrent scheduled scans4

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