17407056obrien/*-
2e0dc992peter * Copyright (c) 1983, 1988, 1993, 1995
3f9ab90drgrimes *	The Regents of the University of California.  All rights reserved.
4f9ab90drgrimes *
5f9ab90drgrimes * Redistribution and use in source and binary forms, with or without
6f9ab90drgrimes * modification, are permitted provided that the following conditions
7f9ab90drgrimes * are met:
8f9ab90drgrimes * 1. Redistributions of source code must retain the above copyright
9f9ab90drgrimes *    notice, this list of conditions and the following disclaimer.
10f9ab90drgrimes * 2. Redistributions in binary form must reproduce the above copyright
11f9ab90drgrimes *    notice, this list of conditions and the following disclaimer in the
12f9ab90drgrimes *    documentation and/or other materials provided with the distribution.
137e6cabdimp * 3. Neither the name of the University nor the names of its contributors
14f9ab90drgrimes *    may be used to endorse or promote products derived from this software
15f9ab90drgrimes *    without specific prior written permission.
16f9ab90drgrimes *
17f9ab90drgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18f9ab90drgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19f9ab90drgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20f9ab90drgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21f9ab90drgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22f9ab90drgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23f9ab90drgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24f9ab90drgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25f9ab90drgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26f9ab90drgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27f9ab90drgrimes * SUCH DAMAGE.
28f9ab90drgrimes */
29f9ab90drgrimes
30cd48a1dcharnier#if 0
31f9ab90drgrimes#ifndef lint
32e0dc992peterstatic char sccsid[] = "@(#)inet.c	8.5 (Berkeley) 5/24/95";
33f9ab90drgrimes#endif /* not lint */
34cd48a1dcharnier#endif
35cd48a1dcharnier
36cd48a1dcharnier#include <sys/cdefs.h>
37cd48a1dcharnier__FBSDID("$FreeBSD$");
38f9ab90drgrimes
39f9ab90drgrimes#include <sys/param.h>
404239068dg#include <sys/queue.h>
4127187e7jhb#include <sys/domain.h>
42aa17b30emax#include <sys/protosw.h>
43f9ab90drgrimes#include <sys/socket.h>
447168facglebius#define	_WANT_SOCKET
45f9ab90drgrimes#include <sys/socketvar.h>
46fefb319wollman#include <sys/sysctl.h>
47f9ab90drgrimes
48f9ab90drgrimes#include <net/route.h>
4960eb51egnn#include <net/if_arp.h>
50f9ab90drgrimes#include <netinet/in.h>
51f9ab90drgrimes#include <netinet/in_systm.h>
52f9ab90drgrimes#include <netinet/ip.h>
53e1d2263glebius#include <netinet/ip_carp.h>
5470f0bdfshin#ifdef INET6
5570f0bdfshin#include <netinet/ip6.h>
5670f0bdfshin#endif /* INET6 */
57f9ab90drgrimes#include <netinet/in_pcb.h>
58f9ab90drgrimes#include <netinet/ip_icmp.h>
59f9ab90drgrimes#include <netinet/icmp_var.h>
60f9ab90drgrimes#include <netinet/igmp_var.h>
61f9ab90drgrimes#include <netinet/ip_var.h>
622732540hsu#include <netinet/pim_var.h>
63f9ab90drgrimes#include <netinet/tcp.h>
64f9ab90drgrimes#include <netinet/tcpip.h>
65f9ab90drgrimes#include <netinet/tcp_seq.h>
667407056obrien#define	TCPSTATES
67f9ab90drgrimes#include <netinet/tcp_fsm.h>
68f9ab90drgrimes#include <netinet/tcp_timer.h>
69f9ab90drgrimes#include <netinet/tcp_var.h>
70f9ab90drgrimes#include <netinet/udp.h>
71f9ab90drgrimes#include <netinet/udp_var.h>
72f9ab90drgrimes
73f9ab90drgrimes#include <arpa/inet.h>
74e37570dwollman#include <err.h>
75e37570dwollman#include <errno.h>
76dd004dabrian#include <libutil.h>
77f9ab90drgrimes#include <netdb.h>
78e1db503yar#include <stdint.h>
79f9ab90drgrimes#include <stdio.h>
80e37570dwollman#include <stdlib.h>
810ea1b83marcel#include <stdbool.h>
82f9ab90drgrimes#include <string.h>
83f9ab90drgrimes#include <unistd.h>
840ea1b83marcel#include <libxo/xo.h>
85f9ab90drgrimes#include "netstat.h"
86c39b2fdglebius#include "nl_defs.h"
87f9ab90drgrimes
88ba9633bbz#ifdef INET
89ba9633bbzstatic void inetprint(const char *, struct in_addr *, int, const char *, int,
90745eb99ume    const int);
91ba9633bbz#endif
9270f0bdfshin#ifdef INET6
935115240jeffstatic int udp_done, tcp_done, sdp_done;
9470f0bdfshin#endif /* INET6 */
95f9ab90drgrimes
9627187e7jhbstatic int
973a5c9aaglebiuspcblist_sysctl(int proto, const char *name, char **bufp)
9827187e7jhb{
9927187e7jhb	const char *mibvar;
10027187e7jhb	char *buf;
10127187e7jhb	size_t len;
10227187e7jhb
10327187e7jhb	switch (proto) {
10427187e7jhb	case IPPROTO_TCP:
10527187e7jhb		mibvar = "net.inet.tcp.pcblist";
10627187e7jhb		break;
10727187e7jhb	case IPPROTO_UDP:
10827187e7jhb		mibvar = "net.inet.udp.pcblist";
10927187e7jhb		break;
11027187e7jhb	case IPPROTO_DIVERT:
11127187e7jhb		mibvar = "net.inet.divert.pcblist";
11227187e7jhb		break;
11327187e7jhb	default:
11427187e7jhb		mibvar = "net.inet.raw.pcblist";
11527187e7jhb		break;
11627187e7jhb	}
1175115240jeff	if (strncmp(name, "sdp", 3) == 0)
1185115240jeff		mibvar = "net.inet.sdp.pcblist";
11927187e7jhb	len = 0;
12027187e7jhb	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
12127187e7jhb		if (errno != ENOENT)
1220ea1b83marcel			xo_warn("sysctl: %s", mibvar);
12327187e7jhb		return (0);
12427187e7jhb	}
125d2d25bbaraujo	if ((buf = malloc(len)) == NULL) {
1260ea1b83marcel		xo_warnx("malloc %lu bytes", (u_long)len);
12727187e7jhb		return (0);
12827187e7jhb	}
12927187e7jhb	if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
1300ea1b83marcel		xo_warn("sysctl: %s", mibvar);
13127187e7jhb		free(buf);
13227187e7jhb		return (0);
13327187e7jhb	}
13427187e7jhb	*bufp = buf;
13527187e7jhb	return (1);
13627187e7jhb}
13727187e7jhb
13827187e7jhb/*
13927187e7jhb * Copied directly from uipc_socket2.c.  We leave out some fields that are in
14027187e7jhb * nested structures that aren't used to avoid extra work.
14127187e7jhb */
14227187e7jhbstatic void
14327187e7jhbsbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb)
14427187e7jhb{
14525da94eglebius	xsb->sb_cc = sb->sb_ccc;
14627187e7jhb	xsb->sb_hiwat = sb->sb_hiwat;
14727187e7jhb	xsb->sb_mbcnt = sb->sb_mbcnt;
148368bdf0gnn	xsb->sb_mcnt = sb->sb_mcnt;
149368bdf0gnn	xsb->sb_ccnt = sb->sb_ccnt;
15027187e7jhb	xsb->sb_mbmax = sb->sb_mbmax;
15127187e7jhb	xsb->sb_lowat = sb->sb_lowat;
15227187e7jhb	xsb->sb_flags = sb->sb_flags;
15327187e7jhb	xsb->sb_timeo = sb->sb_timeo;
15427187e7jhb}
15527187e7jhb
15627187e7jhbint
15727187e7jhbsotoxsocket(struct socket *so, struct xsocket *xso)
15827187e7jhb{
15927187e7jhb	struct protosw proto;
16027187e7jhb	struct domain domain;
16127187e7jhb
16227187e7jhb	bzero(xso, sizeof *xso);
16327187e7jhb	xso->xso_len = sizeof *xso;
16439f527ebrooks	xso->xso_so = (uintptr_t)so;
16527187e7jhb	xso->so_type = so->so_type;
16627187e7jhb	xso->so_options = so->so_options;
16727187e7jhb	xso->so_linger = so->so_linger;
16827187e7jhb	xso->so_state = so->so_state;
16939f527ebrooks	xso->so_pcb = (uintptr_t)so->so_pcb;
17027187e7jhb	if (kread((uintptr_t)so->so_proto, &proto, sizeof(proto)) != 0)
17127187e7jhb		return (-1);
17227187e7jhb	xso->xso_protocol = proto.pr_protocol;
17327187e7jhb	if (kread((uintptr_t)proto.pr_domain, &domain, sizeof(domain)) != 0)
17427187e7jhb		return (-1);
17527187e7jhb	xso->xso_family = domain.dom_family;
17627187e7jhb	xso->so_timeo = so->so_timeo;
17727187e7jhb	xso->so_error = so->so_error;
1787168facglebius	if ((so->so_options & SO_ACCEPTCONN) != 0) {
179e35d543glebius		xso->so_qlen = so->sol_qlen;
180e35d543glebius		xso->so_incqlen = so->sol_incqlen;
181e35d543glebius		xso->so_qlimit = so->sol_qlimit;
182e35d543glebius	} else {
183e35d543glebius		sbtoxsockbuf(&so->so_snd, &xso->so_snd);
184e35d543glebius		sbtoxsockbuf(&so->so_rcv, &xso->so_rcv);
185e35d543glebius		xso->so_oobmark = so->so_oobmark;
186e35d543glebius	}
18727187e7jhb	return (0);
18827187e7jhb}
18927187e7jhb
190f9ab90drgrimes/*
191f9ab90drgrimes * Print a summary of connections related to an Internet
192f9ab90drgrimes * protocol.  For TCP, also give state of connection.
193f9ab90drgrimes * Listening processes (aflag) are suppressed unless the
194f9ab90drgrimes * -a (all) flag is specified.
195f9ab90drgrimes */
196f9ab90drgrimesvoid
19727187e7jhbprotopr(u_long off, const char *name, int af1, int proto)
198f9ab90drgrimes{
199f9ab90drgrimes	static int first = 1;
2003a5c9aaglebius	int istcp;
201e37570dwollman	char *buf;
20227187e7jhb	const char *vchar;
2033a5c9aaglebius	struct xtcpcb *tp;
2043a5c9aaglebius	struct xinpcb *inp;
205e37570dwollman	struct xinpgen *xig, *oxig;
206e37570dwollman	struct xsocket *so;
207f9ab90drgrimes
208e37570dwollman	istcp = 0;
209e37570dwollman	switch (proto) {
210e37570dwollman	case IPPROTO_TCP:
21170f0bdfshin#ifdef INET6
2125115240jeff		if (strncmp(name, "sdp", 3) != 0) {
2135115240jeff			if (tcp_done != 0)
2145115240jeff				return;
2155115240jeff			else
2165115240jeff				tcp_done = 1;
2175115240jeff		} else {
2185115240jeff			if (sdp_done != 0)
2195115240jeff				return;
2205115240jeff			else
2215115240jeff				sdp_done = 1;
2225115240jeff		}
22370f0bdfshin#endif
224e37570dwollman		istcp = 1;
225e37570dwollman		break;
226e37570dwollman	case IPPROTO_UDP:
22770f0bdfshin#ifdef INET6
22870f0bdfshin		if (udp_done != 0)
22970f0bdfshin			return;
23070f0bdfshin		else
23170f0bdfshin			udp_done = 1;
23270f0bdfshin#endif
233e37570dwollman		break;
234e37570dwollman	}
2353a5c9aaglebius
2363a5c9aaglebius	if (!pcblist_sysctl(proto, name, &buf))
2373a5c9aaglebius		return;
238aef6dbddg
239e37570dwollman	oxig = xig = (struct xinpgen *)buf;
240e37570dwollman	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
2410ea1b83marcel	    xig->xig_len > sizeof(struct xinpgen);
2420ea1b83marcel	    xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
243f9ab90drgrimes		if (istcp) {
2443a5c9aaglebius			tp = (struct xtcpcb *)xig;
2453a5c9aaglebius			inp = &tp->xt_inp;
246e37570dwollman		} else {
2473a5c9aaglebius			inp = (struct xinpcb *)xig;
248f9ab90drgrimes		}
2493a5c9aaglebius		so = &inp->xi_socket;
250e37570dwollman
251e37570dwollman		/* Ignore sockets for protocols other than the desired one. */
25227187e7jhb		if (so->xso_protocol != proto)
253e37570dwollman			continue;
254e37570dwollman
255e37570dwollman		/* Ignore PCBs which were freed during copyout. */
256e37570dwollman		if (inp->inp_gencnt > oxig->xig_gen)
257e37570dwollman			continue;
258e37570dwollman
259cb46049dwmalone		if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
26070f0bdfshin#ifdef INET6
261cb46049dwmalone		    || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
26270f0bdfshin#endif /* INET6 */
263cb46049dwmalone		    || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
26470f0bdfshin#ifdef INET6
26542e1a3cobrien					  && (inp->inp_vflag & INP_IPV6) == 0
26670f0bdfshin#endif /* INET6 */
26770f0bdfshin			))
26870f0bdfshin		    )
26970f0bdfshin			continue;
27070f0bdfshin		if (!aflag &&
27170f0bdfshin		    (
2726f2c3adbms		     (istcp && tp->t_state == TCPS_LISTEN)
2736f2c3adbms		     || (af1 == AF_INET &&
27470f0bdfshin		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
27570f0bdfshin#ifdef INET6
276cb46049dwmalone		     || (af1 == AF_INET6 &&
27770f0bdfshin			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
27870f0bdfshin#endif /* INET6 */
279cb46049dwmalone		     || (af1 == AF_UNSPEC &&
28070f0bdfshin			 (((inp->inp_vflag & INP_IPV4) != 0 &&
28170f0bdfshin			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
28270f0bdfshin#ifdef INET6
28370f0bdfshin			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
28470f0bdfshin			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
28570f0bdfshin#endif
28670f0bdfshin			  ))
28770f0bdfshin		     ))
288e37570dwollman			continue;
289e37570dwollman
290f9ab90drgrimes		if (first) {
29139eef9aguido			if (!Lflag) {
2920ea1b83marcel				xo_emit("Active Internet connections");
29339eef9aguido				if (aflag)
2940ea1b83marcel					xo_emit(" (including servers)");
29539eef9aguido			} else
2960ea1b83marcel				xo_emit(
29739eef9aguido	"Current listen queue sizes (qlen/incqlen/maxqlen)");
2980ea1b83marcel			xo_emit("\n");
299f9ab90drgrimes			if (Aflag)
3000ea1b83marcel				xo_emit("{T:/%-*s} ", 2 * (int)sizeof(void *),
3010ea1b83marcel				    "Tcpcb");
30239eef9aguido			if (Lflag)
3030ea1b83marcel				xo_emit((Aflag && !Wflag) ?
3047df95e0tuexen				    "{T:/%-5.5s} {T:/%-32.32s} {T:/%-18.18s}" :
305745eb99ume				    ((!Wflag || af1 == AF_INET) ?
3067df95e0tuexen				    "{T:/%-5.5s} {T:/%-32.32s} {T:/%-22.22s}" :
3077df95e0tuexen				    "{T:/%-5.5s} {T:/%-32.32s} {T:/%-45.45s}"),
30842e1a3cobrien				    "Proto", "Listen", "Local Address");
309dbaa5c8ru			else if (Tflag)
3100ea1b83marcel				xo_emit((Aflag && !Wflag) ?
3110ea1b83marcel    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%s}" :
312745eb99ume				    ((!Wflag || af1 == AF_INET) ?
313745eb99ume    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%s}" :
314745eb99ume    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%s}"),
31567b3b6bgnn				    "Proto", "Rexmit", "OOORcv", "0-win",
31667b3b6bgnn				    "Local Address", "Foreign Address");
317dbaa5c8ru			else {
3180ea1b83marcel				xo_emit((Aflag && !Wflag) ?
3190ea1b83marcel    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%-18.18s}" :
320745eb99ume				    ((!Wflag || af1 == AF_INET) ?
321745eb99ume    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%-22.22s}" :
322745eb99ume    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%-45.45s}"),
3230ea1b83marcel				    "Proto", "Recv-Q", "Send-Q",
3240ea1b83marcel				    "Local Address", "Foreign Address");
325a2ba9f1adrian				if (!xflag && !Rflag)
326a93bdf6jtl					xo_emit(" {T:/%-11.11s}", "(state)");
327dbaa5c8ru			}
32867b3b6bgnn			if (xflag) {
3290ea1b83marcel				xo_emit(" {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} "
3300ea1b83marcel				    "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} "
3310ea1b83marcel				    "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} "
3320ea1b83marcel				    "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s}",
3330ea1b83marcel				    "R-MBUF", "S-MBUF", "R-CLUS", "S-CLUS",
3340ea1b83marcel				    "R-HIWA", "S-HIWA", "R-LOWA", "S-LOWA",
3350ea1b83marcel				    "R-BCNT", "S-BCNT", "R-BMAX", "S-BMAX");
3360ea1b83marcel				xo_emit(" {T:/%7.7s} {T:/%7.7s} {T:/%7.7s} "
3370ea1b83marcel				    "{T:/%7.7s} {T:/%7.7s} {T:/%7.7s}",
3380ea1b83marcel				    "rexmt", "persist", "keep", "2msl",
3390ea1b83marcel				    "delack", "rcvtime");
340a2ba9f1adrian			} else if (Rflag) {
3410ea1b83marcel				xo_emit("  {T:/%8.8s} {T:/%5.5s}",
342a2ba9f1adrian				    "flowid", "ftype");
3433d2c99agnn			}
344a93bdf6jtl			if (Pflag)
345a93bdf6jtl				xo_emit(" {T:/%s}", "Log ID");
3460ea1b83marcel			xo_emit("\n");
347f9ab90drgrimes			first = 0;
348f9ab90drgrimes		}
349733af41ru		if (Lflag && so->so_qlimit == 0)
350733af41ru			continue;
3510ea1b83marcel		xo_open_instance("socket");
352ebe2a5bdes		if (Aflag) {
353ebe2a5bdes			if (istcp)
3540ea1b83marcel				xo_emit("{q:address/%*lx} ",
3550ea1b83marcel				    2 * (int)sizeof(void *),
3560ea1b83marcel				    (u_long)inp->inp_ppcb);
357ebe2a5bdes			else
35822a79f8glebius				xo_emit("{q:address/%*lx} ",
3590ea1b83marcel				    2 * (int)sizeof(void *),
3600ea1b83marcel				    (u_long)so->so_pcb);
361ebe2a5bdes		}
36270f0bdfshin#ifdef INET6
363733af41ru		if ((inp->inp_vflag & INP_IPV6) != 0)
36442e1a3cobrien			vchar = ((inp->inp_vflag & INP_IPV4) != 0) ?
3650ea1b83marcel			    "46" : "6";
366733af41ru		else
367733af41ru#endif
36842e1a3cobrien		vchar = ((inp->inp_vflag & INP_IPV4) != 0) ?
3690ea1b83marcel		    "4" : "";
37067d5f1anp		if (istcp && (tp->t_flags & TF_TOE) != 0)
3710ea1b83marcel			xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", "toe", vchar);
37267d5f1anp		else
3730ea1b83marcel			xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", name, vchar);
374733af41ru		if (Lflag) {
375b04e8a5alfred			char buf1[33];
376b8e8875shin
377b04e8a5alfred			snprintf(buf1, sizeof buf1, "%u/%u/%u", so->so_qlen,
37842e1a3cobrien			    so->so_incqlen, so->so_qlimit);
379b04e8a5alfred			xo_emit("{:listen-queue-sizes/%-32.32s} ", buf1);
38067b3b6bgnn		} else if (Tflag) {
38167b3b6bgnn			if (istcp)
3820ea1b83marcel				xo_emit("{:sent-retransmit-packets/%6u} "
3830ea1b83marcel				    "{:received-out-of-order-packets/%6u} "
3840ea1b83marcel				    "{:sent-zero-window/%6u} ",
3850ea1b83marcel				    tp->t_sndrexmitpack, tp->t_rcvoopack,
3860ea1b83marcel				    tp->t_sndzerowin);
38797e188cume			else
38897e188cume				xo_emit("{P:/%21s}", "");
389733af41ru		} else {
3900ea1b83marcel			xo_emit("{:receive-bytes-waiting/%6u} "
3910ea1b83marcel			    "{:send-bytes-waiting/%6u} ",
39225da94eglebius			    so->so_rcv.sb_cc, so->so_snd.sb_cc);
393b8e8875shin		}
394ea6e16bassar		if (numeric_port) {
395ba9633bbz#ifdef INET
39670f0bdfshin			if (inp->inp_vflag & INP_IPV4) {
3970ea1b83marcel				inetprint("local", &inp->inp_laddr,
398745eb99ume				    (int)inp->inp_lport, name, 1, af1);
39939eef9aguido				if (!Lflag)
4000ea1b83marcel					inetprint("remote", &inp->inp_faddr,
401745eb99ume					    (int)inp->inp_fport, name, 1, af1);
40270f0bdfshin			}
403ba9633bbz#endif
404ba9633bbz#if defined(INET) && defined(INET6)
405ba9633bbz			else
406ba9633bbz#endif
40770f0bdfshin#ifdef INET6
408ba9633bbz			if (inp->inp_vflag & INP_IPV6) {
4090ea1b83marcel				inet6print("local", &inp->in6p_laddr,
41042e1a3cobrien				    (int)inp->inp_lport, name, 1);
41139eef9aguido				if (!Lflag)
4120ea1b83marcel					inet6print("remote", &inp->in6p_faddr,
41342e1a3cobrien					    (int)inp->inp_fport, name, 1);
41470f0bdfshin			} /* else nothing printed now */
41570f0bdfshin#endif /* INET6 */
416e37570dwollman		} else if (inp->inp_flags & INP_ANONPORT) {
417ba9633bbz#ifdef INET
41870f0bdfshin			if (inp->inp_vflag & INP_IPV4) {
4190ea1b83marcel				inetprint("local", &inp->inp_laddr,
420745eb99ume				    (int)inp->inp_lport, name, 1, af1);
42139eef9aguido				if (!Lflag)
4220ea1b83marcel					inetprint("remote", &inp->inp_faddr,
423745eb99ume					    (int)inp->inp_fport, name, 0, af1);
42470f0bdfshin			}
425ba9633bbz#endif
426ba9633bbz#if defined(INET) && defined(INET6)
427ba9633bbz			else
428ba9633bbz#endif
42970f0bdfshin#ifdef INET6
430ba9633bbz			if (inp->inp_vflag & INP_IPV6) {
4310ea1b83marcel				inet6print("local", &inp->in6p_laddr,
43242e1a3cobrien				    (int)inp->inp_lport, name, 1);
43339eef9aguido				if (!Lflag)
4340ea1b83marcel					inet6print("remote", &inp->in6p_faddr,
43542e1a3cobrien					    (int)inp->inp_fport, name, 0);
43670f0bdfshin			} /* else nothing printed now */
43770f0bdfshin#endif /* INET6 */
438733856fphk		} else {
439ba9633bbz#ifdef INET
44070f0bdfshin			if (inp->inp_vflag & INP_IPV4) {
4410ea1b83marcel				inetprint("local", &inp->inp_laddr,
442745eb99ume				    (int)inp->inp_lport, name, 0, af1);
44339eef9aguido				if (!Lflag)
4440ea1b83marcel					inetprint("remote", &inp->inp_faddr,
44542e1a3cobrien					    (int)inp->inp_fport, name,
446745eb99ume					    inp->inp_lport != inp->inp_fport,
447745eb99ume					    af1);
44870f0bdfshin			}
449ba9633bbz#endif
450ba9633bbz#if defined(INET) && defined(INET6)
451ba9633bbz			else
452ba9633bbz#endif
45370f0bdfshin#ifdef INET6
454ba9633bbz			if (inp->inp_vflag & INP_IPV6) {
4550ea1b83marcel				inet6print("local", &inp->in6p_laddr,
45642e1a3cobrien				    (int)inp->inp_lport, name, 0);
45739eef9aguido				if (!Lflag)
4580ea1b83marcel					inet6print("remote", &inp->in6p_faddr,
45942e1a3cobrien					    (int)inp->inp_fport, name,
46042e1a3cobrien					    inp->inp_lport != inp->inp_fport);
46170f0bdfshin			} /* else nothing printed now */
46270f0bdfshin#endif /* INET6 */
463733856fphk		}
464368bdf0gnn		if (xflag) {
4650ea1b83marcel			xo_emit("{:receive-mbufs/%6u} {:send-mbufs/%6u} "
4660ea1b83marcel			    "{:receive-clusters/%6u} {:send-clusters/%6u} "
4670ea1b83marcel			    "{:receive-high-water/%6u} {:send-high-water/%6u} "
4680ea1b83marcel			    "{:receive-low-water/%6u} {:send-low-water/%6u} "
4690ea1b83marcel			    "{:receive-mbuf-bytes/%6u} {:send-mbuf-bytes/%6u} "
4700ea1b83marcel			    "{:receive-mbuf-bytes-max/%6u} "
4710ea1b83marcel			    "{:send-mbuf-bytes-max/%6u}",
4720ea1b83marcel			    so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt,
4730ea1b83marcel			    so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt,
4740ea1b83marcel			    so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat,
4750ea1b83marcel			    so->so_rcv.sb_lowat, so->so_snd.sb_lowat,
4760ea1b83marcel			    so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt,
4770ea1b83marcel			    so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax);
4783a5c9aaglebius			if (istcp)
4790ea1b83marcel				xo_emit(" {:retransmit-timer/%4d.%02d} "
4800ea1b83marcel				    "{:persist-timer/%4d.%02d} "
4810ea1b83marcel				    "{:keepalive-timer/%4d.%02d} "
4820ea1b83marcel				    "{:msl2-timer/%4d.%02d} "
4830ea1b83marcel				    "{:delay-ack-timer/%4d.%02d} "
4840ea1b83marcel				    "{:inactivity-timer/%4d.%02d}",
4853a5c9aaglebius				    tp->tt_rexmt / 1000,
4863a5c9aaglebius				    (tp->tt_rexmt % 1000) / 10,
4873a5c9aaglebius				    tp->tt_persist / 1000,
4883a5c9aaglebius				    (tp->tt_persist % 1000) / 10,
4893a5c9aaglebius				    tp->tt_keep / 1000,
4903a5c9aaglebius				    (tp->tt_keep % 1000) / 10,
4913a5c9aaglebius				    tp->tt_2msl / 1000,
4923a5c9aaglebius				    (tp->tt_2msl % 1000) / 10,
4933a5c9aaglebius				    tp->tt_delack / 1000,
4943a5c9aaglebius				    (tp->tt_delack % 1000) / 10,
4953a5c9aaglebius				    tp->t_rcvtime / 1000,
4963a5c9aaglebius				    (tp->t_rcvtime % 1000) / 10);
497368bdf0gnn		}
498a2ba9f1adrian		if (istcp && !Lflag && !xflag && !Tflag && !Rflag) {
499e37570dwollman			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
500a93bdf6jtl				xo_emit("{:tcp-state/%-11d}", tp->t_state);
501368bdf0gnn			else {
502a93bdf6jtl				xo_emit("{:tcp-state/%-11s}",
5030ea1b83marcel				    tcpstates[tp->t_state]);
5045bca481adam#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
50542e1a3cobrien				/* Show T/TCP `hidden state' */
50642e1a3cobrien				if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
5070ea1b83marcel					xo_emit("{:need-syn-or-fin/*}");
5085bca481adam#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
50942e1a3cobrien			}
510a2ba9f1adrian		}
511a2ba9f1adrian		if (Rflag) {
5120ea1b83marcel			/* XXX: is this right Alfred */
5130ea1b83marcel			xo_emit(" {:flow-id/%08x} {:flow-type/%5d}",
514a2ba9f1adrian			    inp->inp_flowid,
515a2ba9f1adrian			    inp->inp_flowtype);
516