Bug 26359

Summary: [PATCH] a minor nit in how netstat detects 'server sockets'
Product: Base System Reporter: Peter Pentchev <roam>
Component: binAssignee: Bruce M Simpson <bms>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Peter Pentchev 2001-04-04 22:10:01 UTC
The netstat(1) manpage, as well as common sense, says that netstat, when
invoked without the -a option, should not show 'server sockets'.

What exactly is a server socket?  Is it a listening socket, or merely
a socket bound to INADDR_ANY on the local side?  If the latter, then
allow me to disagree; a server could just as well only listen on a couple
of the available interfaces.  If the former, read on.

The netstat(1) in both -stable and -current (actually ALL versions of
netstat, ever since it was imported) honors the former definition,
as demonstrated by a quick peek around line 190 of src/usr.bin/netstat/inet.c
- there are all kinds of checks there, all checking if the local address
of the socket is bound to INADDR_ANY.  This causes netstat -n to display
some server sockets, too :)

Fix: Here's a kind of a workaround, not a real fix - check the foreign address
of the socket against INADDR_ANY (a bind() usually produces this kind
of socket).  I know that a 'more correct' fix would check the state
itself for TCP sockets, but for UDP sockets IMHO the correct thing would
still be checking the foreign address against INADDR_ANY.
How-To-Repeat: 
Start an inetd listening on port 7200 of a single interface..

[roam@ref5 ~/fbsd/src/usr.bin/netstat]$ inetd -d -a 216.136.204.102 ~/inetd.conf
ADD : fodms proto=tcp accept=1 max=0 user=roam group=(null)class=daemon builtin=0x0 server=/usr/bin/true policy=""
inetd: fodms/tcp: ipsec initialization failed; in entrust
inetd: fodms/tcp: ipsec initialization failed; out entrust
inetd: enabling fodms, fd 4
inetd: registered /usr/bin/true on 4
^Z
[1]+  Stopped                 inetd -d -a 216.136.204.102 ~/inetd.conf

The 'normal' netstat, even without -a, shows the new server socket..

[roam@ref5 ~/fbsd/src/usr.bin/netstat]$ netstat -n | fgrep tcp4
tcp4       0      0  216.136.204.102.7200   *.*                    LISTEN
tcp4       0     20  216.136.204.102.22     216.136.204.21.3319    ESTABLISHED

A recompiled version, checking against the foreign address, only shows
the 'real' client connection (barring non-sgid-kmem kvm errors ;)

[roam@ref5 ~/fbsd/src/usr.bin/netstat]$ ./netstat -n | fgrep tcp4
netstat: kvm not available
netstat: kvm not available
tcp4       0      0  216.136.204.102.22     216.136.204.21.3319    ESTABLISHED

..and just for completeness, here's the inetd.conf used:

[roam@ref5 ~/fbsd/src/usr.bin/netstat]$ cat ~/inetd.conf
fodms stream tcp nowait roam /usr/bin/true true
[roam@ref5 ~/fbsd/src/usr.bin/netstat]$
Comment 1 Bruce M Simpson freebsd_committer freebsd_triage 2004-06-14 16:24:39 UTC
State Changed
From-To: open->analyzed

There's definitely a bug in here somewhere. 

tcpcb->t_state probably needs to be checked for LISTEN; 
for a udp socket, the check probably needs to be for 'unbound 
to a remote address' by looking for INADDR_ANY.
Comment 2 Bruce M Simpson freebsd_committer freebsd_triage 2004-06-14 16:26:58 UTC
Responsible Changed
From-To: freebsd-bugs->bms

I'll take this
Comment 3 Bruce M Simpson freebsd_committer freebsd_triage 2004-06-16 08:00:29 UTC
State Changed
From-To: analyzed->patched

An appropriate fix has been committed to HEAD
Comment 4 Craig Rodrigues freebsd_committer freebsd_triage 2005-09-11 17:35:46 UTC
State Changed
From-To: patched->closed

Fixed in FreeBSD 5.x and higher.