1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2002 Dag-Erling Co��dan Sm��rgrav
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer
12 *    in this position and unchanged.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/11/usr.bin/sockstat/sockstat.c 336040 2018-07-06 19:10:11Z jamie $");
33
34#include <sys/param.h>
35#include <sys/socket.h>
36#include <sys/socketvar.h>
37#include <sys/sysctl.h>
38#include <sys/file.h>
39#include <sys/user.h>
40
41#include <sys/un.h>
42#include <sys/unpcb.h>
43
44#include <net/route.h>
45
46#include <netinet/in.h>
47#include <netinet/in_pcb.h>
48#include <netinet/sctp.h>
49#include <netinet/tcp.h>
50#define TCPSTATES /* load state names */
51#include <netinet/tcp_fsm.h>
52#include <netinet/tcp_seq.h>
53#include <netinet/tcp_var.h>
54#include <arpa/inet.h>
55
56#include <ctype.h>
57#include <err.h>
58#include <errno.h>
59#include <jail.h>
60#include <netdb.h>
61#include <pwd.h>
62#include <stdarg.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include <unistd.h>
67
68#define	sstosin(ss)	((struct sockaddr_in *)(ss))
69#define	sstosin6(ss)	((struct sockaddr_in6 *)(ss))
70#define	sstosun(ss)	((struct sockaddr_un *)(ss))
71#define	sstosa(ss)	((struct sockaddr *)(ss))
72
73static int	 opt_4;		/* Show IPv4 sockets */
74static int	 opt_6;		/* Show IPv6 sockets */
75static int	 opt_c;		/* Show connected sockets */
76static int	 opt_j;		/* Show specified jail */
77static int	 opt_L;		/* Don't show IPv4 or IPv6 loopback sockets */
78static int	 opt_l;		/* Show listening sockets */
79static int	 opt_s;		/* Show protocol state if applicable */
80static int	 opt_u;		/* Show Unix domain sockets */
81static int	 opt_v;		/* Verbose mode */
82
83/*
84 * Default protocols to use if no -P was defined.
85 */
86static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
87static size_t	   default_numprotos = nitems(default_protos);
88
89static int	*protos;	/* protocols to use */
90static size_t	 numprotos;	/* allocated size of protos[] */
91
92static int	*ports;
93
94#define	INT_BIT (sizeof(int)*CHAR_BIT)
95#define	SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
96#define	CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
97
98struct addr {
99	struct sockaddr_storage address;
100	struct addr *next;
101};
102
103struct sock {
104	void *socket;
105	void *pcb;
106	int shown;
107	int vflag;
108	int family;
109	int proto;
110	int state;
111	const char *protoname;
112	struct addr *laddr;
113	struct addr *faddr;
114	struct sock *next;
115};
116
117#define	HASHSIZE 1009
118static struct sock *sockhash[HASHSIZE];
119
120static struct xfile *xfiles;
121static int nxfiles;
122
123static int
124xprintf(const char *fmt, ...)
125{
126	va_list ap;
127	int len;
128
129	va_start(ap, fmt);
130	len = vprintf(fmt, ap);
131	va_end(ap);
132	if (len < 0)
133		err(1, "printf()");
134	return (len);
135}
136
137static int
138get_proto_type(const char *proto)
139{
140	struct protoent *pent;
141
142	if (strlen(proto) == 0)
143		return (0);
144	pent = getprotobyname(proto);
145	if (pent == NULL) {
146		warn("getprotobyname");
147		return (-1);
148	}
149	return (pent->p_proto);
150}
151
152static void
153init_protos(int num)
154{
155	int proto_count = 0;
156
157	if (num > 0) {
158		proto_count = num;
159	} else {
160		/* Find the maximum number of possible protocols. */
161		while (getprotoent() != NULL)
162			proto_count++;
163		endprotoent();
164	}
165
166	if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
167		err(1, "malloc");
168	numprotos = proto_count;
169}
170
171static int
172parse_protos(char *protospec)
173{
174	char *prot;
175	int proto_type, proto_index;
176
177	if (protospec == NULL)
178		return (-1);
179
180	init_protos(0);
181	proto_index = 0;
182	while ((prot = strsep(&protospec, ",")) != NULL) {
183		if (strlen(prot) == 0)
184			continue;
185		proto_type = get_proto_type(prot);
186		if (proto_type != -1)
187			protos[proto_index++] = proto_type;
188	}
189	numprotos = proto_index;
190	return (proto_index);
191}
192
193static void
194parse_ports(const char *portspec)
195{
196	const char *p, *q;
197	int port, end;
198
199	if (ports == NULL)
200		if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
201			err(1, "calloc()");
202	p = portspec;
203	while (*p != '\0') {
204		if (!isdigit(*p))
205			errx(1, "syntax error in port range");
206		for (q = p; *q != '\0' && isdigit(*q); ++q)
207			/* nothing */ ;
208		for (port = 0; p < q; ++p)
209			port = port * 10 + digittoint(*p);
210		if (port < 0 || port > 65535)
211			errx(1, "invalid port number");
212		SET_PORT(port);
213		switch (*p) {
214		case '-':
215			++p;
216			break;
217		case ',':
218			++p;
219			/* fall through */
220		case '\0':
221		default:
222			continue;
223		}
224		for (q = p; *q != '\0' && isdigit(*q); ++q)
225			/* nothing */ ;
226		for (end = 0; p < q; ++p)
227			end = end * 10 + digittoint(*p);
228		if (end < port || end > 65535)
229			errx(1, "invalid port number");
230		while (port++ < end)
231			SET_PORT(port);
232		if (*p == ',')
233			++p;
234	}
235}
236
237static void
238sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
239{
240	struct sockaddr_in *sin4;
241	struct sockaddr_in6 *sin6;
242
243	bzero(ss, sizeof(*ss));
244	switch (af) {
245	case AF_INET:
246		sin4 = sstosin(ss);
247		sin4->sin_len = sizeof(*sin4);
248		sin4->sin_family = af;
249		sin4->sin_port = port;
250		sin4->sin_addr = *(struct in_addr *)addr;
251		break;
252	case AF_INET6:
253		sin6 = sstosin6(ss);
254		sin6->sin6_len = sizeof(*sin6);
255		sin6->sin6_family = af;
256		sin6->sin6_port = port;
257		sin6->sin6_addr = *(struct in6_addr *)addr;
258#define	s6_addr16	__u6_addr.__u6_addr16
259		if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
260			sin6->sin6_scope_id =
261			    ntohs(sin6->sin6_addr.s6_addr16[1]);
262			sin6->sin6_addr.s6_addr16[1] = 0;
263		}
264		break;
265	default:
266		abort();
267	}
268}
269
270static void
271free_socket(struct sock *sock)
272{
273	struct addr *cur, *next;
274
275	cur = sock->laddr;
276	while (cur != NULL) {
277		next = cur->next;
278		free(cur);
279		cur = next;
280	}
281	cur = sock->faddr;
282	while (cur != NULL) {
283		next = cur->next;
284		free(cur);
285		cur = next;
286	}
287	free(sock);
288}
289
290static void
291gather_sctp(void)
292{
293	struct sock *sock;
294	struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
295	struct xsctp_inpcb *xinpcb;
296	struct xsctp_tcb *xstcb;
297	struct xsctp_raddr *xraddr;
298	struct xsctp_laddr *xladdr;
299	const char *varname;
300	size_t len, offset;
301	char *buf;
302	int hash, vflag;
303	int no_stcb, local_all_loopback, foreign_all_loopback;
304
305	vflag = 0;
306	if (opt_4)
307		vflag |= INP_IPV4;
308	if (opt_6)
309		vflag |= INP_IPV6;
310
311	varname = "net.inet.sctp.assoclist";
312	if (sysctlbyname(varname, 0, &len, 0, 0) < 0) {
313		if (errno != ENOENT)
314			err(1, "sysctlbyname()");
315		return;
316	}
317	if ((buf = (char *)malloc(len)) == NULL) {
318		err(1, "malloc()");
319		return;
320	}
321	if (sysctlbyname(varname, buf, &len, 0, 0) < 0) {
322		err(1, "sysctlbyname()");
323		free(buf);
324		return;
325	}
326	xinpcb = (struct xsctp_inpcb *)(void *)buf;
327	offset = sizeof(struct xsctp_inpcb);
328	while ((offset < len) && (xinpcb->last == 0)) {
329		if ((sock = calloc(1, sizeof *sock)) == NULL)
330			err(1, "malloc()");
331		sock->socket = xinpcb->socket;
332		sock->proto = IPPROTO_SCTP;
333		sock->protoname = "sctp";
334		if (xinpcb->maxqlen == 0)
335			sock->state = SCTP_CLOSED;
336		else
337			sock->state = SCTP_LISTEN;
338		if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
339			sock->family = AF_INET6;
340			/*
341			 * Currently there is no way to distinguish between
342			 * IPv6 only sockets or dual family sockets.
343			 * So mark it as dual socket.
344			 */
345			sock->vflag = INP_IPV6 | INP_IPV4;
346		} else {
347			sock->family = AF_INET;
348			sock->vflag = INP_IPV4;
349		}
350		prev_laddr = NULL;
351		local_all_loopback = 1;
352		while (offset < len) {
353			xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
354			offset += sizeof(struct xsctp_laddr);
355			if (xladdr->last == 1)
356				break;
357			if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
358				err(1, "malloc()");
359			switch (xladdr->address.sa.sa_family) {
360			case AF_INET:
361#define	__IN_IS_ADDR_LOOPBACK(pina) \
362	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
363				if (!__IN_IS_ADDR_LOOPBACK(
364				    &xladdr->address.sin.sin_addr))
365					local_all_loopback = 0;
366#undef	__IN_IS_ADDR_LOOPBACK
367				sockaddr(&laddr->address, AF_INET,
368				    &xladdr->address.sin.sin_addr,
369				    htons(xinpcb->local_port));
370				break;
371			case AF_INET6:
372				if (!IN6_IS_ADDR_LOOPBACK(
373				    &xladdr->address.sin6.sin6_addr))
374					local_all_loopback = 0;
375				sockaddr(&laddr->address, AF_INET6,
376				    &xladdr->address.sin6.sin6_addr,
377				    htons(xinpcb->local_port));
378				break;
379			default:
380				errx(1, "address family %d not supported",
381				    xladdr->address.sa.sa_family);
382			}
383			laddr->next = NULL;
384			if (prev_laddr == NULL)
385				sock->laddr = laddr;
386			else
387				prev_laddr->next = laddr;
388			prev_laddr = laddr;
389		}
390		if (sock->laddr == NULL) {
391			if ((sock->laddr =
392			    calloc(1, sizeof(struct addr))) == NULL)
393				err(1, "malloc()");
394			sock->laddr->address.ss_family = sock->family;
395			if (sock->family == AF_INET)
396				sock->laddr->address.ss_len =
397				    sizeof(struct sockaddr_in);
398			else
399				sock->laddr->address.ss_len =
400				    sizeof(struct sockaddr_in6);
401			local_all_loopback = 0;
402		}
403		if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
404			err(1, "malloc()");
405		sock->faddr->address.ss_family = sock->family;
406		if (sock->family == AF_INET)
407			sock->faddr->address.ss_len =
408			    sizeof(struct sockaddr_in);
409		else
410			sock->faddr->address.ss_len =
411			    sizeof(struct sockaddr_in6);
412		no_stcb = 1;
413		while (offset < len) {
414			xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
415			offset += sizeof(struct xsctp_tcb);
416			if (no_stcb) {
417				if (opt_l && (sock->vflag & vflag) &&
418				    (!opt_L || !local_all_loopback) &&
419				    ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
420				     (xstcb->last == 1))) {
421					hash = (int)((uintptr_t)sock->socket %
422					    HASHSIZE);
423					sock->next = sockhash[hash];
424					sockhash[hash] = sock;
425				} else {
426					free_socket(sock);
427				}
428			}
429			if (xstcb->last == 1)
430				break;
431			no_stcb = 0;
432			if (opt_c) {
433				if ((sock = calloc(1, sizeof *sock)) == NULL)
434					err(1, "malloc()");
435				sock->socket = xinpcb->socket;
436				sock->proto = IPPROTO_SCTP;
437				sock->protoname = "sctp";
438				sock->state = (int)xstcb->state;
439				if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
440					sock->family = AF_INET6;
441				/*
442				 * Currently there is no way to distinguish
443				 * between IPv6 only sockets or dual family
444				 *  sockets. So mark it as dual socket.
445				 */
446					sock->vflag = INP_IPV6 | INP_IPV4;
447				} else {
448					sock->family = AF_INET;
449					sock->vflag = INP_IPV4;
450				}
451			}
452			prev_laddr = NULL;
453			local_all_loopback = 1;
454			while (offset < len) {
455				xladdr = (struct xsctp_laddr *)(void *)(buf +
456				    offset);
457				offset += sizeof(struct xsctp_laddr);
458				if (xladdr->last == 1)
459					break;
460				if (!opt_c)
461					continue;
462				laddr = calloc(1, sizeof(struct addr));
463				if (laddr == NULL)
464					err(1, "malloc()");
465				switch (xladdr->address.sa.sa_family) {
466				case AF_INET:
467#define	__IN_IS_ADDR_LOOPBACK(pina) \
468	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
469					if (!__IN_IS_ADDR_LOOPBACK(
470					    &xladdr->address.sin.sin_addr))
471						local_all_loopback = 0;
472#undef	__IN_IS_ADDR_LOOPBACK
473					sockaddr(&laddr->address, AF_INET,
474					    &xladdr->address.sin.sin_addr,
475					    htons(xstcb->local_port));
476					break;
477				case AF_INET6:
478					if (!IN6_IS_ADDR_LOOPBACK(
479					    &xladdr->address.sin6.sin6_addr))
480						local_all_loopback = 0;
481					sockaddr(&laddr->address, AF_INET6,
482					    &xladdr->address.sin6.sin6_addr,
483					    htons(xstcb->local_port));
484					break;
485				default:
486					errx(1,
487					    "address family %d not supported",
488					    xladdr->address.sa.sa_family);
489				}
490				laddr->next = NULL;
491				if (prev_laddr == NULL)
492					sock->laddr = laddr;
493				else
494					prev_laddr->next = laddr;
495				prev_laddr = laddr;
496			}
497			prev_faddr = NULL;
498			foreign_all_loopback = 1;
499			while (offset < len) {
500				xraddr = (struct xsctp_raddr *)(void *)(buf +
501				    offset);
502				offset += sizeof(struct xsctp_raddr);
503				if (xraddr->last == 1)
504					break;
505				if (!opt_c)
506					continue;
507				faddr = calloc(1, sizeof(struct addr));
508				if (faddr == NULL)
509					err(1, "malloc()");
510				switch (xraddr->address.sa.sa_family) {
511				case AF_INET:
512#define	__IN_IS_ADDR_LOOPBACK(pina) \
513	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
514					if (!__IN_IS_ADDR_LOOPBACK(
515					    &xraddr->address.sin.sin_addr))
516						foreign_all_loopback = 0;
517#undef	__IN_IS_ADDR_LOOPBACK
518					sockaddr(&faddr->address, AF_INET,
519					    &xraddr->address.sin.sin_addr,
520					    htons(xstcb->remote_port));
521					break;
522				case AF_INET6:
523					if (!IN6_IS_ADDR_LOOPBACK(
524					    &xraddr->address.sin6.sin6_addr))
525						foreign_all_loopback = 0;
526					sockaddr(&faddr->address, AF_INET6,
527					    &xraddr->address.sin6.sin6_addr,
528					    htons(xstcb->remote_port));
529					break;
530				default:
531					errx(1,
532					    "address family %d not supported",
533					    xraddr->address.sa.sa_family);
534				}
535				faddr->next = NULL;
536				if (prev_faddr == NULL)
537					sock->faddr = faddr;
538				else
539					prev_faddr->next = faddr;
540				prev_faddr = faddr;
541			}
542			if (opt_c) {
543				if ((sock->vflag & vflag) &&
544				    (!opt_L ||
545				     !(local_all_loopback ||
546				     foreign_all_loopback))) {
547					hash = (int)((uintptr_t)sock->socket %
548					    HASHSIZE);
549					sock->next = sockhash[hash];
550					sockhash[hash] = sock;
551				} else {
552					free_socket(sock);
553				}
554			}
555		}
556		xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
557		offset += sizeof(struct xsctp_inpcb);
558	}
559	free(buf);
560}
561
562static void
563gather_inet(int proto)
564{
565	struct xinpgen *xig, *exig;
566	struct xinpcb *xip;
567	struct xtcpcb *xtp;
568	struct inpcb *inp;
569	struct xsocket *so;
570	struct sock *sock;
571	struct addr *laddr, *faddr;
572	const char *varname, *protoname;
573	size_t len, bufsize;
574	void *buf;
575	int hash, retry, vflag;
576
577	vflag = 0;
578	if (opt_4)
579		vflag |= INP_IPV4;
580	if (opt_6)
581		vflag |= INP_IPV6;
582
583	switch (proto) {
584	case IPPROTO_TCP:
585		varname = "net.inet.tcp.pcblist";
586		protoname = "tcp";
587		break;
588	case IPPROTO_UDP:
589		varname = "net.inet.udp.pcblist";
590		protoname = "udp";
591		break;
592	case IPPROTO_DIVERT:
593		varname = "net.inet.divert.pcblist";
594		protoname = "div";
595		break;
596	default:
597		errx(1, "protocol %d not supported", proto);
598	}
599
600	buf = NULL;
601	bufsize = 8192;
602	retry = 5;
603	do {
604		for (;;) {
605			if ((buf = realloc(buf, bufsize)) == NULL)
606				err(1, "realloc()");
607			len = bufsize;
608			if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
609				break;
610			if (errno == ENOENT)
611				goto out;
612			if (errno != ENOMEM || len != bufsize)
613				err(1, "sysctlbyname()");
614			bufsize *= 2;
615		}
616		xig = (struct xinpgen *)buf;
617		exig = (struct xinpgen *)(void *)
618		    ((char *)buf + len - sizeof *exig);
619		if (xig->xig_len != sizeof *xig ||
620		    exig->xig_len != sizeof *exig)
621			errx(1, "struct xinpgen size mismatch");
622	} while (xig->xig_gen != exig->xig_gen && retry--);
623
624	if (xig->xig_gen != exig->xig_gen && opt_v)
625		warnx("warning: data may be inconsistent");
626
627	for (;;) {
628		xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
629		if (xig >= exig)
630			break;
631		xip = (struct xinpcb *)xig;
632		xtp = (struct xtcpcb *)xig;
633		switch (proto) {
634		case IPPROTO_TCP:
635			if (xtp->xt_len != sizeof(*xtp)) {
636				warnx("struct xtcpcb size mismatch");
637				goto out;
638			}
639			inp = &xtp->xt_inp;
640			so = &xtp->xt_socket;
641			protoname = xtp->xt_tp.t_flags & TF_TOE ? "toe" : "tcp";
642			break;
643		case IPPROTO_UDP:
644		case IPPROTO_DIVERT:
645			if (xip->xi_len != sizeof(*xip)) {
646				warnx("struct xinpcb size mismatch");
647				goto out;
648			}
649			inp = &xip->xi_inp;
650			so = &xip->xi_socket;
651			break;
652		default:
653			errx(1, "protocol %d not supported", proto);
654		}
655		if ((inp->inp_vflag & vflag) == 0)
656			continue;
657		if (inp->inp_vflag & INP_IPV4) {
658			if ((inp->inp_fport == 0 && !opt_l) ||
659			    (inp->inp_fport != 0 && !opt_c))
660				continue;
661#define	__IN_IS_ADDR_LOOPBACK(pina) \
662	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
663			if (opt_L &&
664			    (__IN_IS_ADDR_LOOPBACK(&inp->inp_faddr) ||
665			     __IN_IS_ADDR_LOOPBACK(&inp->inp_laddr)))
666				continue;
667#undef	__IN_IS_ADDR_LOOPBACK
668		} else if (inp->inp_vflag & INP_IPV6) {
669			if ((inp->inp_fport == 0 && !opt_l) ||
670			    (inp->inp_fport != 0 && !opt_c))
671				continue;
672			if (opt_L &&
673			    (IN6_IS_ADDR_LOOPBACK(&inp->in6p_faddr) ||
674			     IN6_IS_ADDR_LOOPBACK(&inp->in6p_laddr)))
675				continue;
676		} else {
677			if (opt_v)
678				warnx("invalid vflag 0x%x", inp->inp_vflag);
679			continue;
680		}
681		if ((sock = calloc(1, sizeof(*sock))) == NULL)
682			err(1, "malloc()");
683		if ((laddr = calloc(1, sizeof *laddr)) == NULL)
684			err(1, "malloc()");
685		if ((faddr = calloc(1, sizeof *faddr)) == NULL)
686			err(1, "malloc()");
687		sock->socket = so->xso_so;
688		sock->proto = proto;
689		if (inp->inp_vflag & INP_IPV4) {
690			sock->family = AF_INET;
691			sockaddr(&laddr->address, sock->family,
692			    &inp->inp_laddr, inp->inp_lport);
693			sockaddr(&faddr->address, sock->family,
694			    &inp->inp_faddr, inp->inp_fport);
695		} else if (inp->inp_vflag & INP_IPV6) {
696			sock->family = AF_INET6;
697			sockaddr(&laddr->address, sock->family,
698			    &inp->in6p_laddr, inp->inp_lport);
699			sockaddr(&faddr->address, sock->family,
700			    &inp->in6p_faddr, inp->inp_fport);
701		}
702		laddr->next = NULL;
703		faddr->next = NULL;
704		sock->laddr = laddr;
705		sock->faddr = faddr;
706		sock->vflag = inp->inp_vflag;
707		if (proto == IPPROTO_TCP)
708			sock->state = xtp->xt_tp.t_state;
709		sock->protoname = protoname;
710		hash = (int)((uintptr_t)sock->socket % HASHSIZE);
711		sock->next = sockhash[hash];
712		sockhash[hash] = sock;
713	}
714out:
715	free(buf);
716}
717
718static void
719gather_unix(int proto)
720{
721	struct xunpgen *xug, *exug;
722	struct xunpcb *xup;
723	struct sock *sock;
724	struct addr *laddr, *faddr;
725	const char *varname, *protoname;
726	size_t len, bufsize;
727	void *buf;
728	int hash, retry;
729
730	switch (proto) {
731	case SOCK_STREAM:
732		varname = "net.local.stream.pcblist";
733		protoname = "stream";
734		break;
735	case SOCK_DGRAM:
736		varname = "net.local.dgram.pcblist";
737		protoname = "dgram";
738		break;
739	case SOCK_SEQPACKET:
740		varname = "net.local.seqpacket.pcblist";
741		protoname = "seqpac";
742		break;
743	default:
744		abort();
745	}
746	buf = NULL;
747	bufsize = 8192;
748	retry = 5;
749	do {
750		for (;;) {
751			if ((buf = realloc(buf, bufsize)) == NULL)
752				err(1, "realloc()");
753			len = bufsize;
754			if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
755				break;
756			if (errno != ENOMEM || len != bufsize)
757				err(1, "sysctlbyname()");
758			bufsize *= 2;
759		}
760		xug = (struct xunpgen *)buf;
761		exug = (struct xunpgen *)(void *)
762		    ((char *)buf + len - sizeof(*exug));
763		if (xug->xug_len != sizeof(*xug) ||
764		    exug->xug_len != sizeof(*exug)) {
765			warnx("struct xinpgen size mismatch");
766			goto out;
767		}
768	} while (xug->xug_gen != exug->xug_gen && retry--);
769
770	if (xug->xug_gen != exug->xug_gen && opt_v)
771		warnx("warning: data may be inconsistent");
772
773	for (;;) {
774		xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
775		if (xug >= exug)
776			break;
777		xup = (struct xunpcb *)xug;
778		if (xup->xu_len != sizeof(*xup)) {
779			warnx("struct xunpcb size mismatch");
780			goto out;
781		}
782		if ((xup->xu_unp.unp_conn == NULL && !opt_l) ||
783		    (xup->xu_unp.unp_conn != NULL && !opt_c))
784			continue;
785		if ((sock = calloc(1, sizeof(*sock))) == NULL)
786			err(1, "malloc()");
787		if ((laddr = calloc(1, sizeof *laddr)) == NULL)
788			err(1, "malloc()");
789		if ((faddr = calloc(1, sizeof *faddr)) == NULL)
790			err(1, "malloc()");
791		sock->socket = xup->xu_socket.xso_so;
792		sock->pcb = xup->xu_unpp;
793		sock->proto = proto;
794		sock->family = AF_UNIX;
795		sock->protoname = protoname;
796		if (xup->xu_unp.unp_addr != NULL)
797			laddr->address =
798			    *(struct sockaddr_storage *)(void *)&xup->xu_addr;
799		else if (xup->xu_unp.unp_conn != NULL)
800			*(void **)&(faddr->address) = xup->xu_unp.unp_conn;
801		laddr->next = NULL;
802		faddr->next = NULL;
803		sock->laddr = laddr;
804		sock->faddr = faddr;
805		hash = (int)((uintptr_t)sock->socket % HASHSIZE);
806		sock->next = sockhash[hash];
807		sockhash[hash] = sock;
808	}
809out:
810	free(buf);
811}
812
813static void
814getfiles(void)
815{
816	size_t len, olen;
817
818	olen = len = sizeof(*xfiles);
819	if ((xfiles = malloc(len)) == NULL)
820		err(1, "malloc()");
821	while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) {
822		if (errno != ENOMEM || len != olen)
823			err(1, "sysctlbyname()");
824		olen = len *= 2;
825		if ((xfiles = realloc(xfiles, len)) == NULL)
826			err(1, "realloc()");
827	}
828	if (len > 0 && xfiles->xf_size != sizeof(*xfiles))
829		errx(1, "struct xfile size mismatch");
830	nxfiles = len / sizeof(*xfiles);
831}
832
833static int
834printaddr(struct sockaddr_storage *ss)
835{
836	struct sockaddr_un *sun;
837	char addrstr[NI_MAXHOST] = { '\0', '\0' };
838	int error, off, port = 0;
839
840	switch (ss->ss_family) {
841	case AF_INET:
842		if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY)
843			addrstr[0] = '*';
844		port = ntohs(sstosin(ss)->sin_port);
845		break;
846	case AF_INET6:
847		if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
848			addrstr[0] = '*';
849		port = ntohs(sstosin6(ss)->sin6_port);
850		break;
851	case AF_UNIX:
852		sun = sstosun(ss);
853		off = (int)((char *)&sun->sun_path - (char *)sun);
854		return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
855	}
856	if (addrstr[0] == '\0') {
857		error = getnameinfo(sstosa(ss), ss->ss_len, addrstr,
858		    sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
859		if (error)
860			errx(1, "getnameinfo()");
861	}
862	if (port == 0)
863		return xprintf("%s:*", addrstr);
864	else
865		return xprintf("%s:%d", addrstr, port);
866}
867
868static const char *
869getprocname(pid_t pid)
870{
871	static struct kinfo_proc proc;
872	size_t len;
873	int mib[4];
874
875	mib[0] = CTL_KERN;
876	mib[1] = KERN_PROC;
877	mib[2] = KERN_PROC_PID;
878	mib[3] = (int)pid;
879	len = sizeof(proc);
880	if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
881		/* Do not warn if the process exits before we get its name. */
882		if (errno != ESRCH)
883			warn("sysctl()");
884		return ("??");
885	}
886	return (proc.ki_comm);
887}
888
889static int
890getprocjid(pid_t pid)
891{
892	static struct kinfo_proc proc;
893	size_t len;
894	int mib[4];
895
896	mib[0] = CTL_KERN;
897	mib[1] = KERN_PROC;
898	mib[2] = KERN_PROC_PID;
899	mib[3] = (int)pid;
900	len = sizeof(proc);
901	if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) {
902		/* Do not warn if the process exits before we get its jid. */
903		if (errno != ESRCH)
904			warn("sysctl()");
905		return (-1);
906	}
907	return (proc.ki_jid);
908}
909
910static int
911check_ports(struct sock *s)
912{
913	int port;
914	struct addr *addr;
915
916	if (ports == NULL)
917		return (1);
918	if ((s->family != AF_INET) && (s->family != AF_INET6))
919		return (1);
920	for (addr = s->laddr; addr != NULL; addr = addr->next) {
921		if (s->family == AF_INET)
922			port = ntohs(sstosin(&addr->address)->sin_port);
923		else
924			port = ntohs(sstosin6(&addr->address)->sin6_port);
925		if (CHK_PORT(port))
926			return (1);
927	}
928	for (addr = s->faddr; addr != NULL; addr = addr->next) {
929		if (s->family == AF_INET)
930			port = ntohs(sstosin(&addr->address)->sin_port);
931		else
932			port = ntohs(sstosin6(&addr->address)->sin6_port);
933		if (CHK_PORT(port))
934			return (1);
935	}
936	return (0);
937}
938
939static const char *
940sctp_state(int state)
941{
942	switch (state) {
943	case SCTP_CLOSED:
944		return "CLOSED";
945		break;
946	case SCTP_BOUND:
947		return "BOUND";
948		break;
949	case SCTP_LISTEN:
950		return "LISTEN";
951		break;
952	case SCTP_COOKIE_WAIT:
953		return "COOKIE_WAIT";
954		break;
955	case SCTP_COOKIE_ECHOED:
956		return "COOKIE_ECHOED";
957		break;
958	case SCTP_ESTABLISHED:
959		return "ESTABLISHED";
960		break;
961	case SCTP_SHUTDOWN_SENT:
962		return "SHUTDOWN_SENT";
963		break;
964	case SCTP_SHUTDOWN_RECEIVED:
965		return "SHUTDOWN_RECEIVED";
966		break;
967	case SCTP_SHUTDOWN_ACK_SENT:
968		return "SHUTDOWN_ACK_SENT";
969		break;
970	case SCTP_SHUTDOWN_PENDING:
971		return "SHUTDOWN_PENDING";
972		break;
973	default:
974		return "UNKNOWN";
975		break;
976	}
977}
978
979static void
980displaysock(struct sock *s, int pos)
981{
982	void *p;
983	int hash, first;
984	struct addr *laddr, *faddr;
985	struct sock *s_tmp;
986
987	while (pos < 29)
988		pos += xprintf(" ");
989	pos += xprintf("%s", s->protoname);
990	if (s->vflag & INP_IPV4)
991		pos += xprintf("4");
992	if (s->vflag & INP_IPV6)
993		pos += xprintf("6");
994	if (s->vflag & (INP_IPV4 | INP_IPV6))
995		pos += xprintf(" ");
996	laddr = s->laddr;
997	faddr = s->faddr;
998	first = 1;
999	while (laddr != NULL || faddr != NULL) {
1000		while (pos < 36)
1001			pos += xprintf(" ");
1002		switch (s->family) {
1003		case AF_INET:
1004		case AF_INET6:
1005			if (laddr != NULL) {
1006				pos += printaddr(&laddr->address);
1007				if (s->family == AF_INET6 && pos >= 58)
1008					pos += xprintf(" ");
1009			}
1010			while (pos < 58)
1011				pos += xprintf(" ");
1012			if (faddr != NULL)
1013				pos += printaddr(&faddr->address);
1014			break;
1015		case AF_UNIX:
1016			if ((laddr == NULL) || (faddr == NULL))
1017				errx(1, "laddr = %p or faddr = %p is NULL",
1018				    (void *)laddr, (void *)faddr);
1019			/* server */
1020			if (laddr->address.ss_len > 0) {
1021				pos += printaddr(&laddr->address);
1022				break;
1023			}
1024			/* client */
1025			p = *(void **)&(faddr->address);
1026			if (p == NULL) {
1027				pos += xprintf("(not connected)");
1028				break;
1029			}
1030			pos += xprintf("-> ");
1031			for (hash = 0; hash < HASHSIZE; ++hash) {
1032				for (s_tmp = sockhash[hash];
1033				    s_tmp != NULL;
1034				    s_tmp = s_tmp->next)
1035					if (s_tmp->pcb == p)
1036						break;
1037				if (s_tmp != NULL)
1038					break;
1039			}
1040			if (s_tmp == NULL || s_tmp->laddr == NULL ||
1041			    s_tmp->laddr->address.ss_len == 0)
1042				pos += xprintf("??");
1043			else
1044				pos += printaddr(&s_tmp->laddr->address);
1045			break;
1046		default:
1047			abort();
1048		}
1049		if (first && opt_s &&
1050		    (s->proto == IPPROTO_SCTP || s->proto == IPPROTO_TCP)) {
1051			while (pos < 80)
1052				pos += xprintf(" ");
1053			switch (s->proto) {
1054			case IPPROTO_SCTP:
1055				pos += xprintf("%s", sctp_state(s->state));
1056				break;
1057			case IPPROTO_TCP:
1058				if (s->state >= 0 && s->state < TCP_NSTATES)
1059					pos +=
1060					    xprintf("%s", tcpstates[s->state]);
1061				else
1062					pos += xprintf("?");
1063				break;
1064			}
1065		}
1066		if (laddr != NULL)
1067			laddr = laddr->next;
1068		if (faddr != NULL)
1069			faddr = faddr->next;
1070		if ((laddr != NULL) || (faddr != NULL)) {
1071			xprintf("\n");
1072			pos = 0;
1073		}
1074		first = 0;
1075	}
1076	xprintf("\n");
1077}
1078
1079static void
1080display(void)
1081{
1082	struct passwd *pwd;
1083	struct xfile *xf;
1084	struct sock *s;
1085	int hash, n, pos;
1086
1087	printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s",
1088	    "USER", "COMMAND", "PID", "FD", "PROTO",
1089	    "LOCAL ADDRESS", "FOREIGN ADDRESS");
1090	if (opt_s)
1091		printf(" %-12s", "STATE");
1092	printf("\n");
1093	setpassent(1);
1094	for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
1095		if (xf->xf_data == NULL)
1096			continue;
1097		if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1098			continue;
1099		hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
1100		for (s = sockhash[hash]; s != NULL; s = s->next) {
1101			if ((void *)s->socket != xf->xf_data)
1102				continue;
1103			if (!check_ports(s))
1104				continue;
1105			s->shown = 1;
1106			pos = 0;
1107			if ((pwd = getpwuid(xf->xf_uid)) == NULL)
1108				pos += xprintf("%lu ", (u_long)xf->xf_uid);
1109			else
1110				pos += xprintf("%s ", pwd->pw_name);
1111			while (pos < 9)
1112				pos += xprintf(" ");
1113			pos += xprintf("%.10s", getprocname(xf->xf_pid));
1114			while (pos < 20)
1115				pos += xprintf(" ");
1116			pos += xprintf("%lu ", (u_long)xf->xf_pid);
1117			while (pos < 26)
1118				pos += xprintf(" ");
1119			pos += xprintf("%d ", xf->xf_fd);
1120			displaysock(s, pos);
1121		}
1122	}
1123	if (opt_j >= 0)
1124		return;
1125	for (hash = 0; hash < HASHSIZE; hash++) {
1126		for (s = sockhash[hash]; s != NULL; s = s->next) {
1127			if (s->shown)
1128				continue;
1129			if (!check_ports(s))
1130				continue;
1131			pos = 0;
1132			pos += xprintf("%-8s %-10s %-5s %-2s ",
1133			    "?", "?", "?", "?");
1134			displaysock(s, pos);
1135		}
1136	}
1137}
1138
1139static int set_default_protos(void)
1140{
1141	struct protoent *prot;
1142	const char *pname;
1143	size_t pindex;
1144
1145	init_protos(default_numprotos);
1146
1147	for (pindex = 0; pindex < default_numprotos; pindex++) {
1148		pname = default_protos[pindex];
1149		prot = getprotobyname(pname);
1150		if (prot == NULL)
1151			err(1, "getprotobyname: %s", pname);
1152		protos[pindex] = prot->p_proto;
1153	}
1154	numprotos = pindex;
1155	return (pindex);
1156}
1157
1158static void
1159usage(void)
1160{
1161	fprintf(stderr,
1162	    "usage: sockstat [-46cLlsu] [-j jid] [-p ports] [-P protocols]\n");
1163	exit(1);
1164}
1165
1166int
1167main(int argc, char *argv[])
1168{
1169	int protos_defined = -1;
1170	int o, i;
1171
1172	opt_j = -1;
1173	while ((o = getopt(argc, argv, "46cj:Llp:P:suv")) != -1)
1174		switch (o) {
1175		case '4':
1176			opt_4 = 1;
1177			break;
1178		case '6':
1179			opt_6 = 1;
1180			break;
1181		case 'c':
1182			opt_c = 1;
1183			break;
1184		case 'j':
1185			opt_j = jail_getid(optarg);
1186			if (opt_j < 0)
1187				errx(1, "%s", jail_errmsg);
1188			break;
1189		case 'L':
1190			opt_L = 1;
1191			break;
1192		case 'l':
1193			opt_l = 1;
1194			break;
1195		case 'p':
1196			parse_ports(optarg);
1197			break;
1198		case 'P':
1199			protos_defined = parse_protos(optarg);
1200			break;
1201		case 's':
1202			opt_s = 1;
1203			break;
1204		case 'u':
1205			opt_u = 1;
1206			break;
1207		case 'v':
1208			++opt_v;
1209			break;
1210		default:
1211			usage();
1212		}
1213
1214	argc -= optind;
1215	argv += optind;
1216
1217	if (argc > 0)
1218		usage();
1219
1220	if ((!opt_4 && !opt_6) && protos_defined != -1)
1221		opt_4 = opt_6 = 1;
1222	if (!opt_4 && !opt_6 && !opt_u)
1223		opt_4 = opt_6 = opt_u = 1;
1224	if ((opt_4 || opt_6) && protos_defined == -1)
1225		protos_defined = set_default_protos();
1226	if (!opt_c && !opt_l)
1227		opt_c = opt_l = 1;
1228
1229	if (opt_4 || opt_6) {
1230		for (i = 0; i < protos_defined; i++)
1231			if (protos[i] == IPPROTO_SCTP)
1232				gather_sctp();
1233			else
1234				gather_inet(protos[i]);
1235	}
1236
1237	if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1238		gather_unix(SOCK_STREAM);
1239		gather_unix(SOCK_DGRAM);
1240		gather_unix(SOCK_SEQPACKET);
1241	}
1242	getfiles();
1243	display();
1244	exit(0);
1245}
1246