Skip to content

feat(scan): work out the network you are on instead of demanding a CIDR - #7

Merged
gclluch merged 2 commits into
mainfrom
feat/subnet-autodetect
Aug 1, 2026
Merged

feat(scan): work out the network you are on instead of demanding a CIDR#7
gclluch merged 2 commits into
mainfrom
feat/subnet-autodetect

Conversation

@gclluch

@gclluch gclluch commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Two commits, the second found while testing the first.

The subnet is now optional

netdiff scan and netdiff audit work out the network you are on. Walking into somewhere new and running the tool no longer means first going to read your own IP settings.

local_address() gets our own address by connecting a UDP socket to TEST-NET-1. A connected UDP socket sends nothing - the kernel just consults the routing table and binds a source address, which is exactly the question being asked. The destination is reserved and routed nowhere, so that stays true even if it ever did send.

The mask is then read from ip -o -4 addr or ifconfig, in all three shapes those print it: a CIDR suffix, a macOS hex mask, a Linux dotted mask. Same runner= seam as read_arp_table, so the tests cover all three against captured output without touching a socket.

If the mask cannot be read it raises and asks for a subnet rather than assuming /24. Guessing would be right most of the time, which is precisely the kind of nearly-true this tool refuses everywhere else.

resolve_subnet prints the subnet it inferred. That is not decoration - a scan whose target was inferred has to show its target, or the report is about a network the reader never chose.

--no-ports was inventing changes

Found by running the above against a live network:

$ netdiff scan --no-ports
changes since last scan: 2 port-closed
  [port-closed] 192.168.1.1 (80, 443)

Nothing closed. Nothing was looked at. A device with no ports scanned and a device with no ports open are the same empty tuple, so the diff could not tell them apart and the caller has to say - diff(..., compare_ports=False).

Worth fixing properly rather than quietly: a change that did not happen is the one failure mode diff.py exists to avoid, and it is the same class of decision already made for services, which is deliberately never compared because one missed mDNS reply would report a change every other scan.

@gclluch
gclluch merged commit 9cfd756 into main Aug 1, 2026
8 checks passed
@gclluch
gclluch deleted the feat/subnet-autodetect branch August 1, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant