Skip site navigation (1)Skip section navigation (2)
Date:      4 Apr 2001 21:06:24 -0000
From:      Peter Pentchev <roam@orbitel.bg>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/26359: [PATCH] a minor nit in how netstat detects 'server sockets'
Message-ID:  <20010404210624.7541.qmail@ringworld.nanolink.com>

next in thread | raw e-mail | index | archive | help

>Number:         26359
>Category:       bin
>Synopsis:       [PATCH] a minor nit in how netstat detects 'server sockets'
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 04 14:10:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Peter Pentchev
>Release:        FreeBSD 4.3-RC i386
>Organization:
Orbitel JSCo.
>Environment:
4.3-RC FreeBSD 4.3-RC #43: Wed Apr 4 12:58:23 EEST 2001

>Description:

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

>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]$

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

Index: src/usr.bin/netstat/inet.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/netstat/inet.c,v
retrieving revision 1.41
diff -u -r1.41 inet.c
--- src/usr.bin/netstat/inet.c	2001/03/15 20:46:04	1.41
+++ src/usr.bin/netstat/inet.c	2001/04/04 20:33:51
@@ -189,17 +189,17 @@
 		if (!aflag &&
 		    (
 		     (af == AF_INET &&
-		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
+		      inet_lnaof(inp->inp_faddr) == INADDR_ANY)
 #ifdef INET6
 		     || (af == AF_INET6 &&
-			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
+			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
 #endif /* INET6 */
 		     || (af == AF_UNSPEC &&
 			 (((inp->inp_vflag & INP_IPV4) != 0 &&
-			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
+			   inet_lnaof(inp->inp_faddr) == INADDR_ANY)
 #ifdef INET6
 			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
-			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
+			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
 #endif
 			  ))
 		     ))
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010404210624.7541.qmail>