Skip to content

fix: handle non-canonical CIDR notation where host bits are set - #899

Merged
bee-san merged 2 commits into
bee-san:masterfrom
Nicceboy:fix-noncanonical-cidr
Oct 1, 2026
Merged

bee-san merged 2 commits into
bee-san:masterfrom
Nicceboy:fix-noncanonical-cidr

Conversation

@Nicceboy

Copy link
Copy Markdown
Contributor

Problem

RustScan fails silently when a CIDR is given where the input IP has host bits set (i.e. the IP is not the network address for that prefix).

rustscan -a 192.168.1.13/29
[!] Host "192.168.1.13/29" could not be resolved.
[!] No IPs could be resolved, aborting scan.

This is valid and common input. Users naturally provide their known host IP with a subnet mask to mean "scan this subnet". Tools like nmap accept it without complaint.

What currently happens:

  1. IpInet::from_str("192.168.1.13/29") rejects it — host bits 101 in .13 are non-zero
  2. Falls through to DNS resolution, which also fails
  3. Address is treated as a file path, which also fails
  4. A misleading "could not be resolved" warning is shown

Fix

Adds a normalize_cidr helper that masks off the host bits to derive the true network address before parsing. 192.168.1.13/29 becomes 192.168.1.8/29 (.13 = 0000 1101 → mask last 3 bits → .8 = 0000 1000), which is then expanded to the expected 8 addresses.

The change is one helper function and one additional else if branch in parse_address.

Nicceboy and others added 2 commits April 27, 2026 22:56
master already accepts CIDRs with host bits set: since 3bdac9c parse_address
uses IpInet::from_str, which keeps the host bits, and then expands
net_addr.network(). normalize_cidr could therefore never be reached, so take
master's parse_address and keep this PR's regression tests. Drop the
DNS-dependent resolver tests, which master removed in bee-san#942.
@bee-san bee-san mentioned this pull request Oct 1, 2026

@bee-san bee-san left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Nicceboy, and thanks for the clear bit-by-bit explanation! While merging master in I found the bug itself was already fixed on master by 3bdac9c. parse_address now uses IpInet::from_str, which accepts host bits, and expands network(), so 192.168.1.13/29 already resolves to .8–.15 and normalize_cidr could never be reached. I dropped the helper and kept your four tests as regression coverage, which is valuable on its own. They pass on all four CI platforms. I'm merging it as a test-only change.

@bee-san
bee-san merged commit c027ebc into bee-san:master Oct 1, 2026
4 checks passed
@Nicceboy

Nicceboy commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for letting me know!

@Nicceboy
Nicceboy deleted the fix-noncanonical-cidr branch October 1, 2026 11:24
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.

2 participants