Skip to content

Nping: pass the correct sockaddr length to nsock_iod_set_localaddr - #3511

Closed
MRX-72 wants to merge 1 commit into
nmap:masterfrom
MRX-72:nping-localaddr-sslen
Closed

MRX-72 wants to merge 1 commit into
nmap:masterfrom
MRX-72:nping-localaddr-sslen

Conversation

@MRX-72

@MRX-72 MRX-72 commented Sep 22, 2026

Copy link
Copy Markdown

Fixes #3510.

Both probe handlers in nping/ProbeMode.cc pass sizeof(sockaddr_storage) (128) as the length of the local address, but the address is only a sockaddr_in or a sockaddr_in6. nsock_iod_set_localaddr() stores that length verbatim in nsi->locallen and mksock_bind_addr() gives it to bind() unchanged. Linux ignores the extra length, the BSDs validate it and fail with EINVAL, so on macOS and the BSDs every probe dies before anything goes out:

$ nping --tcp-connect -p 18080 127.0.0.1 -c 5 --rate 5
libnsock mksock_bind_addr(): Bind to 0.0.0.0:0 failed (IOD #1): Invalid argument (22)
...
TCP connection attempts: 5 | Successful connections: 0 | Failed: 5 (100.00%)

Same for unprivileged nping --udp.

This is the same defect as #3438. 84420aa narrowed the length in NmapOps::setSourceSockAddr(), Target::setSourceSockAddr() and NpingTarget::setSourceSockAddr(), but these two sites hand the length straight to nsock and bypass all three.

Both handlers already compute the right length into sslen a few lines earlier for the destination sockaddr, so this just uses that. EchoClient.cc already passes the correct length, so ProbeMode was the only place affected.

After the change the same command reports 5 of 5 successful connections. I checked that --source-port still binds where asked (listener printing the client source port confirms 44444), and that IPv6 works against an ::1 listener.

The TCP-connect and UDP-unprivileged probe handlers both passed
sizeof(sockaddr_storage) (128) as the length of the local address, even
though the address itself is a sockaddr_in or a sockaddr_in6. Linux
ignores the oversized length, but the BSD socket implementations validate
it, so bind() fails with EINVAL and every probe is aborted before a packet
goes out:

  $ nping --tcp-connect -p 18080 127.0.0.1 -c 5 --rate 5
  libnsock mksock_bind_addr(): Bind to 0.0.0.0:0 failed (IOD nmap#1): Invalid argument (22)
  ...
  TCP connection attempts: 5 | Successful connections: 0 | Failed: 5 (100.00%)

That makes --tcp-connect and unprivileged --udp unusable on macOS and the
BSDs. Use sslen, which both handlers already derive from the address
family a few lines earlier. EchoClient.cc already passes the correct
length, so only ProbeMode was affected.

With this change the same command reports 5 successful connections, IPv6
targets work against an ::1 listener, and --source-port still binds as
requested (confirmed with a listener that prints the client source port).
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.

Nping: wrong sockaddr length passed to nsock_iod_set_localaddr breaks --tcp-connect and unprivileged --udp on macOS/BSD

1 participant