xref: /freebsd/usr.bin/sockstat/sockstat.c (revision 38a52bd3b5cac3da6f7f6eef3dd050e6aa08ebb3)
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$");
33 
34 #include <sys/param.h>
35 #include <sys/file.h>
36 #include <sys/socket.h>
37 #include <sys/socketvar.h>
38 #include <sys/sysctl.h>
39 #include <sys/jail.h>
40 #include <sys/user.h>
41 #include <sys/queue.h>
42 #include <sys/tree.h>
43 
44 #include <sys/un.h>
45 #include <sys/unpcb.h>
46 
47 #include <net/route.h>
48 
49 #include <netinet/in.h>
50 #include <netinet/in_pcb.h>
51 #include <netinet/sctp.h>
52 #include <netinet/tcp.h>
53 #define TCPSTATES /* load state names */
54 #include <netinet/tcp_fsm.h>
55 #include <netinet/tcp_seq.h>
56 #include <netinet/tcp_var.h>
57 #include <arpa/inet.h>
58 
59 #include <capsicum_helpers.h>
60 #include <ctype.h>
61 #include <err.h>
62 #include <errno.h>
63 #include <inttypes.h>
64 #include <jail.h>
65 #include <netdb.h>
66 #include <pwd.h>
67 #include <stdarg.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <string.h>
71 #include <unistd.h>
72 
73 #include <libcasper.h>
74 #include <casper/cap_net.h>
75 #include <casper/cap_netdb.h>
76 #include <casper/cap_pwd.h>
77 #include <casper/cap_sysctl.h>
78 
79 #define	sstosin(ss)	((struct sockaddr_in *)(ss))
80 #define	sstosin6(ss)	((struct sockaddr_in6 *)(ss))
81 #define	sstosun(ss)	((struct sockaddr_un *)(ss))
82 #define	sstosa(ss)	((struct sockaddr *)(ss))
83 
84 static int	 opt_4;		/* Show IPv4 sockets */
85 static int	 opt_6;		/* Show IPv6 sockets */
86 static int	 opt_C;		/* Show congestion control */
87 static int	 opt_c;		/* Show connected sockets */
88 static int	 opt_i;		/* Show inp_gencnt */
89 static int	 opt_j;		/* Show specified jail */
90 static int	 opt_L;		/* Don't show IPv4 or IPv6 loopback sockets */
91 static int	 opt_l;		/* Show listening sockets */
92 static int	 opt_n;		/* Don't resolve UIDs to user names */
93 static int	 opt_q;		/* Don't show header */
94 static int	 opt_S;		/* Show protocol stack if applicable */
95 static int	 opt_s;		/* Show protocol state if applicable */
96 static int	 opt_U;		/* Show remote UDP encapsulation port number */
97 static int	 opt_u;		/* Show Unix domain sockets */
98 static int	 opt_v;		/* Verbose mode */
99 static int	 opt_w;		/* Wide print area for addresses */
100 
101 /*
102  * Default protocols to use if no -P was defined.
103  */
104 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
105 static size_t	   default_numprotos = nitems(default_protos);
106 
107 static int	*protos;	/* protocols to use */
108 static size_t	 numprotos;	/* allocated size of protos[] */
109 
110 static int	*ports;
111 
112 #define	INT_BIT (sizeof(int)*CHAR_BIT)
113 #define	SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
114 #define	CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
115 
116 struct addr {
117 	union {
118 		struct sockaddr_storage address;
119 		struct {	/* unix(4) faddr */
120 			kvaddr_t conn;
121 			kvaddr_t firstref;
122 			kvaddr_t nextref;
123 		};
124 	};
125 	unsigned int encaps_port;
126 	int state;
127 	struct addr *next;
128 };
129 
130 struct sock {
131 	union {
132 		RB_ENTRY(sock) socket_tree;	/* tree of pcbs with socket */
133 		SLIST_ENTRY(sock) socket_list;	/* list of pcbs w/o socket */
134 	};
135 	RB_ENTRY(sock) pcb_tree;
136 	kvaddr_t socket;
137 	kvaddr_t pcb;
138 	uint64_t inp_gencnt;
139 	int shown;
140 	int vflag;
141 	int family;
142 	int proto;
143 	int state;
144 	const char *protoname;
145 	char stack[TCP_FUNCTION_NAME_LEN_MAX];
146 	char cc[TCP_CA_NAME_MAX];
147 	struct addr *laddr;
148 	struct addr *faddr;
149 };
150 
151 static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks);
152 static int64_t
153 socket_compare(const struct sock *a, const struct sock *b)
154 {
155 	return ((int64_t)(a->socket/2 - b->socket/2));
156 }
157 RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare);
158 
159 static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs);
160 static int64_t
161 pcb_compare(const struct sock *a, const struct sock *b)
162 {
163         return ((int64_t)(a->pcb/2 - b->pcb/2));
164 }
165 RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare);
166 
167 static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks);
168 
169 struct file {
170 	RB_ENTRY(file)	file_tree;
171 	kvaddr_t	xf_data;
172 	pid_t	xf_pid;
173 	uid_t	xf_uid;
174 	int	xf_fd;
175 };
176 
177 static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree);
178 static int64_t
179 file_compare(const struct file *a, const struct file *b)
180 {
181 	return ((int64_t)(a->xf_data/2 - b->xf_data/2));
182 }
183 RB_GENERATE_STATIC(files_t, file, file_tree, file_compare);
184 
185 static struct file *files;
186 static int nfiles;
187 
188 static cap_channel_t *capnet;
189 static cap_channel_t *capnetdb;
190 static cap_channel_t *capsysctl;
191 static cap_channel_t *cappwd;
192 
193 static int
194 xprintf(const char *fmt, ...)
195 {
196 	va_list ap;
197 	int len;
198 
199 	va_start(ap, fmt);
200 	len = vprintf(fmt, ap);
201 	va_end(ap);
202 	if (len < 0)
203 		err(1, "printf()");
204 	return (len);
205 }
206 
207 static bool
208 _check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
209 {
210 	if (received_size != expected_size) {
211 		warnx("%s size mismatch: expected %zd, received %zd",
212 		    struct_name, expected_size, received_size);
213 		return false;
214 	}
215 	return true;
216 }
217 #define check_ksize(_sz, _struct)	(_check_ksize(_sz, sizeof(_struct), #_struct))
218 
219 static void
220 _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
221 {
222 	if (received_size != expected_size) {
223 		errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
224 		    struct_name, expected_size, received_size);
225 	}
226 }
227 #define enforce_ksize(_sz, _struct)	(_enforce_ksize(_sz, sizeof(_struct), #_struct))
228 
229 static int
230 get_proto_type(const char *proto)
231 {
232 	struct protoent *pent;
233 
234 	if (strlen(proto) == 0)
235 		return (0);
236 	if (capnetdb != NULL)
237 		pent = cap_getprotobyname(capnetdb, proto);
238 	else
239 		pent = getprotobyname(proto);
240 	if (pent == NULL) {
241 		warn("cap_getprotobyname");
242 		return (-1);
243 	}
244 	return (pent->p_proto);
245 }
246 
247 static void
248 init_protos(int num)
249 {
250 	int proto_count = 0;
251 
252 	if (num > 0) {
253 		proto_count = num;
254 	} else {
255 		/* Find the maximum number of possible protocols. */
256 		while (getprotoent() != NULL)
257 			proto_count++;
258 		endprotoent();
259 	}
260 
261 	if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
262 		err(1, "malloc");
263 	numprotos = proto_count;
264 }
265 
266 static int
267 parse_protos(char *protospec)
268 {
269 	char *prot;
270 	int proto_type, proto_index;
271 
272 	if (protospec == NULL)
273 		return (-1);
274 
275 	init_protos(0);
276 	proto_index = 0;
277 	while ((prot = strsep(&protospec, ",")) != NULL) {
278 		if (strlen(prot) == 0)
279 			continue;
280 		proto_type = get_proto_type(prot);
281 		if (proto_type != -1)
282 			protos[proto_index++] = proto_type;
283 	}
284 	numprotos = proto_index;
285 	return (proto_index);
286 }
287 
288 static void
289 parse_ports(const char *portspec)
290 {
291 	const char *p, *q;
292 	int port, end;
293 
294 	if (ports == NULL)
295 		if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
296 			err(1, "calloc()");
297 	p = portspec;
298 	while (*p != '\0') {
299 		if (!isdigit(*p))
300 			errx(1, "syntax error in port range");
301 		for (q = p; *q != '\0' && isdigit(*q); ++q)
302 			/* nothing */ ;
303 		for (port = 0; p < q; ++p)
304 			port = port * 10 + digittoint(*p);
305 		if (port < 0 || port > 65535)
306 			errx(1, "invalid port number");
307 		SET_PORT(port);
308 		switch (*p) {
309 		case '-':
310 			++p;
311 			break;
312 		case ',':
313 			++p;
314 			/* fall through */
315 		case '\0':
316 		default:
317 			continue;
318 		}
319 		for (q = p; *q != '\0' && isdigit(*q); ++q)
320 			/* nothing */ ;
321 		for (end = 0; p < q; ++p)
322 			end = end * 10 + digittoint(*p);
323 		if (end < port || end > 65535)
324 			errx(1, "invalid port number");
325 		while (port++ < end)
326 			SET_PORT(port);
327 		if (*p == ',')
328 			++p;
329 	}
330 }
331 
332 static void
333 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
334 {
335 	struct sockaddr_in *sin4;
336 	struct sockaddr_in6 *sin6;
337 
338 	bzero(ss, sizeof(*ss));
339 	switch (af) {
340 	case AF_INET:
341 		sin4 = sstosin(ss);
342 		sin4->sin_len = sizeof(*sin4);
343 		sin4->sin_family = af;
344 		sin4->sin_port = port;
345 		sin4->sin_addr = *(struct in_addr *)addr;
346 		break;
347 	case AF_INET6:
348 		sin6 = sstosin6(ss);
349 		sin6->sin6_len = sizeof(*sin6);
350 		sin6->sin6_family = af;
351 		sin6->sin6_port = port;
352 		sin6->sin6_addr = *(struct in6_addr *)addr;
353 #define	s6_addr16	__u6_addr.__u6_addr16
354 		if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
355 			sin6->sin6_scope_id =
356 			    ntohs(sin6->sin6_addr.s6_addr16[1]);
357 			sin6->sin6_addr.s6_addr16[1] = 0;
358 		}
359 		break;
360 	default:
361 		abort();
362 	}
363 }
364 
365 static void
366 free_socket(struct sock *sock)
367 {
368 	struct addr *cur, *next;
369 
370 	cur = sock->laddr;
371 	while (cur != NULL) {
372 		next = cur->next;
373 		free(cur);
374 		cur = next;
375 	}
376 	cur = sock->faddr;
377 	while (cur != NULL) {
378 		next = cur->next;
379 		free(cur);
380 		cur = next;
381 	}
382 	free(sock);
383 }
384 
385 static void
386 gather_sctp(void)
387 {
388 	struct sock *sock;
389 	struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
390 	struct xsctp_inpcb *xinpcb;
391 	struct xsctp_tcb *xstcb;
392 	struct xsctp_raddr *xraddr;
393 	struct xsctp_laddr *xladdr;
394 	const char *varname;
395 	size_t len, offset;
396 	char *buf;
397 	int vflag;
398 	int no_stcb, local_all_loopback, foreign_all_loopback;
399 
400 	vflag = 0;
401 	if (opt_4)
402 		vflag |= INP_IPV4;
403 	if (opt_6)
404 		vflag |= INP_IPV6;
405 
406 	varname = "net.inet.sctp.assoclist";
407 	if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
408 		if (errno != ENOENT)
409 			err(1, "cap_sysctlbyname()");
410 		return;
411 	}
412 	if ((buf = (char *)malloc(len)) == NULL) {
413 		err(1, "malloc()");
414 		return;
415 	}
416 	if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
417 		err(1, "cap_sysctlbyname()");
418 		free(buf);
419 		return;
420 	}
421 	xinpcb = (struct xsctp_inpcb *)(void *)buf;
422 	offset = sizeof(struct xsctp_inpcb);
423 	while ((offset < len) && (xinpcb->last == 0)) {
424 		if ((sock = calloc(1, sizeof *sock)) == NULL)
425 			err(1, "malloc()");
426 		sock->socket = xinpcb->socket;
427 		sock->proto = IPPROTO_SCTP;
428 		sock->protoname = "sctp";
429 		if (xinpcb->maxqlen == 0)
430 			sock->state = SCTP_CLOSED;
431 		else
432 			sock->state = SCTP_LISTEN;
433 		if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
434 			sock->family = AF_INET6;
435 			/*
436 			 * Currently there is no way to distinguish between
437 			 * IPv6 only sockets or dual family sockets.
438 			 * So mark it as dual socket.
439 			 */
440 			sock->vflag = INP_IPV6 | INP_IPV4;
441 		} else {
442 			sock->family = AF_INET;
443 			sock->vflag = INP_IPV4;
444 		}
445 		prev_laddr = NULL;
446 		local_all_loopback = 1;
447 		while (offset < len) {
448 			xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
449 			offset += sizeof(struct xsctp_laddr);
450 			if (xladdr->last == 1)
451 				break;
452 			if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
453 				err(1, "malloc()");
454 			switch (xladdr->address.sa.sa_family) {
455 			case AF_INET:
456 #define	__IN_IS_ADDR_LOOPBACK(pina) \
457 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
458 				if (!__IN_IS_ADDR_LOOPBACK(
459 				    &xladdr->address.sin.sin_addr))
460 					local_all_loopback = 0;
461 #undef	__IN_IS_ADDR_LOOPBACK
462 				sockaddr(&laddr->address, AF_INET,
463 				    &xladdr->address.sin.sin_addr,
464 				    htons(xinpcb->local_port));
465 				break;
466 			case AF_INET6:
467 				if (!IN6_IS_ADDR_LOOPBACK(
468 				    &xladdr->address.sin6.sin6_addr))
469 					local_all_loopback = 0;
470 				sockaddr(&laddr->address, AF_INET6,
471 				    &xladdr->address.sin6.sin6_addr,
472 				    htons(xinpcb->local_port));
473 				break;
474 			default:
475 				errx(1, "address family %d not supported",
476 				    xladdr->address.sa.sa_family);
477 			}
478 			laddr->next = NULL;
479 			if (prev_laddr == NULL)
480 				sock->laddr = laddr;
481 			else
482 				prev_laddr->next = laddr;
483 			prev_laddr = laddr;
484 		}
485 		if (sock->laddr == NULL) {
486 			if ((sock->laddr =
487 			    calloc(1, sizeof(struct addr))) == NULL)
488 				err(1, "malloc()");
489 			sock->laddr->address.ss_family = sock->family;
490 			if (sock->family == AF_INET)
491 				sock->laddr->address.ss_len =
492 				    sizeof(struct sockaddr_in);
493 			else
494 				sock->laddr->address.ss_len =
495 				    sizeof(struct sockaddr_in6);
496 			local_all_loopback = 0;
497 		}
498 		if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
499 			err(1, "malloc()");
500 		sock->faddr->address.ss_family = sock->family;
501 		if (sock->family == AF_INET)
502 			sock->faddr->address.ss_len =
503 			    sizeof(struct sockaddr_in);
504 		else
505 			sock->faddr->address.ss_len =
506 			    sizeof(struct sockaddr_in6);
507 		no_stcb = 1;
508 		while (offset < len) {
509 			xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
510 			offset += sizeof(struct xsctp_tcb);
511 			if (no_stcb) {
512 				if (opt_l && (sock->vflag & vflag) &&
513 				    (!opt_L || !local_all_loopback) &&
514 				    ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
515 				     (xstcb->last == 1))) {
516 					RB_INSERT(socks_t, &socks, sock);
517 				} else {
518 					free_socket(sock);
519 				}
520 			}
521 			if (xstcb->last == 1)
522 				break;
523 			no_stcb = 0;
524 			if (opt_c) {
525 				if ((sock = calloc(1, sizeof *sock)) == NULL)
526 					err(1, "malloc()");
527 				sock->socket = xinpcb->socket;
528 				sock->proto = IPPROTO_SCTP;
529 				sock->protoname = "sctp";
530 				sock->state = (int)xstcb->state;
531 				if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
532 					sock->family = AF_INET6;
533 				/*
534 				 * Currently there is no way to distinguish
535 				 * between IPv6 only sockets or dual family
536 				 *  sockets. So mark it as dual socket.
537 				 */
538 					sock->vflag = INP_IPV6 | INP_IPV4;
539 				} else {
540 					sock->family = AF_INET;
541 					sock->vflag = INP_IPV4;
542 				}
543 			}
544 			prev_laddr = NULL;
545 			local_all_loopback = 1;
546 			while (offset < len) {
547 				xladdr = (struct xsctp_laddr *)(void *)(buf +
548 				    offset);
549 				offset += sizeof(struct xsctp_laddr);
550 				if (xladdr->last == 1)
551 					break;
552 				if (!opt_c)
553 					continue;
554 				laddr = calloc(1, sizeof(struct addr));
555 				if (laddr == NULL)
556 					err(1, "malloc()");
557 				switch (xladdr->address.sa.sa_family) {
558 				case AF_INET:
559 #define	__IN_IS_ADDR_LOOPBACK(pina) \
560 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
561 					if (!__IN_IS_ADDR_LOOPBACK(
562 					    &xladdr->address.sin.sin_addr))
563 						local_all_loopback = 0;
564 #undef	__IN_IS_ADDR_LOOPBACK
565 					sockaddr(&laddr->address, AF_INET,
566 					    &xladdr->address.sin.sin_addr,
567 					    htons(xstcb->local_port));
568 					break;
569 				case AF_INET6:
570 					if (!IN6_IS_ADDR_LOOPBACK(
571 					    &xladdr->address.sin6.sin6_addr))
572 						local_all_loopback = 0;
573 					sockaddr(&laddr->address, AF_INET6,
574 					    &xladdr->address.sin6.sin6_addr,
575 					    htons(xstcb->local_port));
576 					break;
577 				default:
578 					errx(1,
579 					    "address family %d not supported",
580 					    xladdr->address.sa.sa_family);
581 				}
582 				laddr->next = NULL;
583 				if (prev_laddr == NULL)
584 					sock->laddr = laddr;
585 				else
586 					prev_laddr->next = laddr;
587 				prev_laddr = laddr;
588 			}
589 			prev_faddr = NULL;
590 			foreign_all_loopback = 1;
591 			while (offset < len) {
592 				xraddr = (struct xsctp_raddr *)(void *)(buf +
593 				    offset);
594 				offset += sizeof(struct xsctp_raddr);
595 				if (xraddr->last == 1)
596 					break;
597 				if (!opt_c)
598 					continue;
599 				faddr = calloc(1, sizeof(struct addr));
600 				if (faddr == NULL)
601 					err(1, "malloc()");
602 				switch (xraddr->address.sa.sa_family) {
603 				case AF_INET:
604 #define	__IN_IS_ADDR_LOOPBACK(pina) \
605 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
606 					if (!__IN_IS_ADDR_LOOPBACK(
607 					    &xraddr->address.sin.sin_addr))
608 						foreign_all_loopback = 0;
609 #undef	__IN_IS_ADDR_LOOPBACK
610 					sockaddr(&faddr->address, AF_INET,
611 					    &xraddr->address.sin.sin_addr,
612 					    htons(xstcb->remote_port));
613 					break;
614 				case AF_INET6:
615 					if (!IN6_IS_ADDR_LOOPBACK(
616 					    &xraddr->address.sin6.sin6_addr))
617 						foreign_all_loopback = 0;
618 					sockaddr(&faddr->address, AF_INET6,
619 					    &xraddr->address.sin6.sin6_addr,
620 					    htons(xstcb->remote_port));
621 					break;
622 				default:
623 					errx(1,
624 					    "address family %d not supported",
625 					    xraddr->address.sa.sa_family);
626 				}
627 				faddr->encaps_port = xraddr->encaps_port;
628 				faddr->state = xraddr->state;
629 				faddr->next = NULL;
630 				if (prev_faddr == NULL)
631 					sock->faddr = faddr;
632 				else
633 					prev_faddr->next = faddr;
634 				prev_faddr = faddr;
635 			}
636 			if (opt_c) {
637 				if ((sock->vflag & vflag) &&
638 				    (!opt_L ||
639 				     !(local_all_loopback ||
640 				     foreign_all_loopback))) {
641 					RB_INSERT(socks_t, &socks, sock);
642 				} else {
643 					free_socket(sock);
644 				}
645 			}
646 		}
647 		xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
648 		offset += sizeof(struct xsctp_inpcb);
649 	}
650 	free(buf);
651 }
652 
653 static void
654 gather_inet(int proto)
655 {
656 	struct xinpgen *xig, *exig;
657 	struct xinpcb *xip;
658 	struct xtcpcb *xtp = NULL;
659 	struct xsocket *so;
660 	struct sock *sock;
661 	struct addr *laddr, *faddr;
662 	const char *varname, *protoname;
663 	size_t len, bufsize;
664 	void *buf;
665 	int retry, vflag;
666 
667 	vflag = 0;
668 	if (opt_4)
669 		vflag |= INP_IPV4;
670 	if (opt_6)
671 		vflag |= INP_IPV6;
672 
673 	switch (proto) {
674 	case IPPROTO_TCP:
675 		varname = "net.inet.tcp.pcblist";
676 		protoname = "tcp";
677 		break;
678 	case IPPROTO_UDP:
679 		varname = "net.inet.udp.pcblist";
680 		protoname = "udp";
681 		break;
682 	case IPPROTO_DIVERT:
683 		varname = "net.inet.divert.pcblist";
684 		protoname = "div";
685 		break;
686 	default:
687 		errx(1, "protocol %d not supported", proto);
688 	}
689 
690 	buf = NULL;
691 	bufsize = 8192;
692 	retry = 5;
693 	do {
694 		for (;;) {
695 			if ((buf = realloc(buf, bufsize)) == NULL)
696 				err(1, "realloc()");
697 			len = bufsize;
698 			if (cap_sysctlbyname(capsysctl, varname, buf, &len,
699 			    NULL, 0) == 0)
700 				break;
701 			if (errno == ENOENT)
702 				goto out;
703 			if (errno != ENOMEM || len != bufsize)
704 				err(1, "cap_sysctlbyname()");
705 			bufsize *= 2;
706 		}
707 		xig = (struct xinpgen *)buf;
708 		exig = (struct xinpgen *)(void *)
709 		    ((char *)buf + len - sizeof *exig);
710 		enforce_ksize(xig->xig_len, struct xinpgen);
711 		enforce_ksize(exig->xig_len, struct xinpgen);
712 	} while (xig->xig_gen != exig->xig_gen && retry--);
713 
714 	if (xig->xig_gen != exig->xig_gen && opt_v)
715 		warnx("warning: data may be inconsistent");
716 
717 	for (;;) {
718 		xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
719 		if (xig >= exig)
720 			break;
721 		switch (proto) {
722 		case IPPROTO_TCP:
723 			xtp = (struct xtcpcb *)xig;
724 			xip = &xtp->xt_inp;
725 			if (!check_ksize(xtp->xt_len, struct xtcpcb))
726 				goto out;
727 			protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
728 			break;
729 		case IPPROTO_UDP:
730 		case IPPROTO_DIVERT:
731 			xip = (struct xinpcb *)xig;
732 			if (!check_ksize(xip->xi_len, struct xinpcb))
733 				goto out;
734 			break;
735 		default:
736 			errx(1, "protocol %d not supported", proto);
737 		}
738 		so = &xip->xi_socket;
739 		if ((xip->inp_vflag & vflag) == 0)
740 			continue;
741 		if (xip->inp_vflag & INP_IPV4) {
742 			if ((xip->inp_fport == 0 && !opt_l) ||
743 			    (xip->inp_fport != 0 && !opt_c))
744 				continue;
745 #define	__IN_IS_ADDR_LOOPBACK(pina) \
746 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
747 			if (opt_L &&
748 			    (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
749 			     __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
750 				continue;
751 #undef	__IN_IS_ADDR_LOOPBACK
752 		} else if (xip->inp_vflag & INP_IPV6) {
753 			if ((xip->inp_fport == 0 && !opt_l) ||
754 			    (xip->inp_fport != 0 && !opt_c))
755 				continue;
756 			if (opt_L &&
757 			    (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
758 			     IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
759 				continue;
760 		} else {
761 			if (opt_v)
762 				warnx("invalid vflag 0x%x", xip->inp_vflag);
763 			continue;
764 		}
765 		if ((sock = calloc(1, sizeof(*sock))) == NULL)
766 			err(1, "malloc()");
767 		if ((laddr = calloc(1, sizeof *laddr)) == NULL)
768 			err(1, "malloc()");
769 		if ((faddr = calloc(1, sizeof *faddr)) == NULL)
770 			err(1, "malloc()");
771 		sock->socket = so->xso_so;
772 		sock->proto = proto;
773 		sock->inp_gencnt = xip->inp_gencnt;
774 		if (xip->inp_vflag & INP_IPV4) {
775 			sock->family = AF_INET;
776 			sockaddr(&laddr->address, sock->family,
777 			    &xip->inp_laddr, xip->inp_lport);
778 			sockaddr(&faddr->address, sock->family,
779 			    &xip->inp_faddr, xip->inp_fport);
780 		} else if (xip->inp_vflag & INP_IPV6) {
781 			sock->family = AF_INET6;
782 			sockaddr(&laddr->address, sock->family,
783 			    &xip->in6p_laddr, xip->inp_lport);
784 			sockaddr(&faddr->address, sock->family,
785 			    &xip->in6p_faddr, xip->inp_fport);
786 		}
787 		if (proto == IPPROTO_TCP)
788 			faddr->encaps_port = xtp->xt_encaps_port;
789 		laddr->next = NULL;
790 		faddr->next = NULL;
791 		sock->laddr = laddr;
792 		sock->faddr = faddr;
793 		sock->vflag = xip->inp_vflag;
794 		if (proto == IPPROTO_TCP) {
795 			sock->state = xtp->t_state;
796 			memcpy(sock->stack, xtp->xt_stack,
797 			    TCP_FUNCTION_NAME_LEN_MAX);
798 			memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX);
799 		}
800 		sock->protoname = protoname;
801 		if (sock->socket != 0)
802 			RB_INSERT(socks_t, &socks, sock);
803 		else
804 			SLIST_INSERT_HEAD(&nosocks, sock, socket_list);
805 	}
806 out:
807 	free(buf);
808 }
809 
810 static void
811 gather_unix(int proto)
812 {
813 	struct xunpgen *xug, *exug;
814 	struct xunpcb *xup;
815 	struct sock *sock;
816 	struct addr *laddr, *faddr;
817 	const char *varname, *protoname;
818 	size_t len, bufsize;
819 	void *buf;
820 	int retry;
821 
822 	switch (proto) {
823 	case SOCK_STREAM:
824 		varname = "net.local.stream.pcblist";
825 		protoname = "stream";
826 		break;
827 	case SOCK_DGRAM:
828 		varname = "net.local.dgram.pcblist";
829 		protoname = "dgram";
830 		break;
831 	case SOCK_SEQPACKET:
832 		varname = "net.local.seqpacket.pcblist";
833 		protoname = "seqpac";
834 		break;
835 	default:
836 		abort();
837 	}
838 	buf = NULL;
839 	bufsize = 8192;
840 	retry = 5;
841 	do {
842 		for (;;) {
843 			if ((buf = realloc(buf, bufsize)) == NULL)
844 				err(1, "realloc()");
845 			len = bufsize;
846 			if (cap_sysctlbyname(capsysctl, varname, buf, &len,
847 			    NULL, 0) == 0)
848 				break;
849 			if (errno != ENOMEM || len != bufsize)
850 				err(1, "cap_sysctlbyname()");
851 			bufsize *= 2;
852 		}
853 		xug = (struct xunpgen *)buf;
854 		exug = (struct xunpgen *)(void *)
855 		    ((char *)buf + len - sizeof(*exug));
856 		if (!check_ksize(xug->xug_len, struct xunpgen) ||
857 		    !check_ksize(exug->xug_len, struct xunpgen))
858 			goto out;
859 	} while (xug->xug_gen != exug->xug_gen && retry--);
860 
861 	if (xug->xug_gen != exug->xug_gen && opt_v)
862 		warnx("warning: data may be inconsistent");
863 
864 	for (;;) {
865 		xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
866 		if (xug >= exug)
867 			break;
868 		xup = (struct xunpcb *)xug;
869 		if (!check_ksize(xup->xu_len, struct xunpcb))
870 			goto out;
871 		if ((xup->unp_conn == 0 && !opt_l) ||
872 		    (xup->unp_conn != 0 && !opt_c))
873 			continue;
874 		if ((sock = calloc(1, sizeof(*sock))) == NULL)
875 			err(1, "malloc()");
876 		if ((laddr = calloc(1, sizeof *laddr)) == NULL)
877 			err(1, "malloc()");
878 		if ((faddr = calloc(1, sizeof *faddr)) == NULL)
879 			err(1, "malloc()");
880 		sock->socket = xup->xu_socket.xso_so;
881 		sock->pcb = xup->xu_unpp;
882 		sock->proto = proto;
883 		sock->family = AF_UNIX;
884 		sock->protoname = protoname;
885 		if (xup->xu_addr.sun_family == AF_UNIX)
886 			laddr->address =
887 			    *(struct sockaddr_storage *)(void *)&xup->xu_addr;
888 		faddr->conn = xup->unp_conn;
889 		faddr->firstref = xup->xu_firstref;
890 		faddr->nextref = xup->xu_nextref;
891 		laddr->next = NULL;
892 		faddr->next = NULL;
893 		sock->laddr = laddr;
894 		sock->faddr = faddr;
895 		RB_INSERT(socks_t, &socks, sock);
896 		RB_INSERT(pcbs_t, &pcbs, sock);
897 	}
898 out:
899 	free(buf);
900 }
901 
902 static void
903 getfiles(void)
904 {
905 	struct xfile *xfiles;
906 	size_t len, olen;
907 
908 	olen = len = sizeof(*xfiles);
909 	if ((xfiles = malloc(len)) == NULL)
910 		err(1, "malloc()");
911 	while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0)
912 	    == -1) {
913 		if (errno != ENOMEM || len != olen)
914 			err(1, "cap_sysctlbyname()");
915 		olen = len *= 2;
916 		if ((xfiles = realloc(xfiles, len)) == NULL)
917 			err(1, "realloc()");
918 	}
919 	if (len > 0)
920 		enforce_ksize(xfiles->xf_size, struct xfile);
921 	nfiles = len / sizeof(*xfiles);
922 
923 	if ((files = malloc(nfiles * sizeof(struct file))) == NULL)
924 		err(1, "malloc()");
925 
926 	for (int i = 0; i < nfiles; i++) {
927 		files[i].xf_data = xfiles[i].xf_data;
928 		files[i].xf_pid = xfiles[i].xf_pid;
929 		files[i].xf_uid = xfiles[i].xf_uid;
930 		files[i].xf_fd = xfiles[i].xf_fd;
931 		RB_INSERT(files_t, &ftree, &files[i]);
932 	}
933 
934 	free(xfiles);
935 }
936 
937 static int
938 printaddr(struct sockaddr_storage *ss)
939 {
940 	struct sockaddr_un *sun;
941 	char addrstr[NI_MAXHOST] = { '\0', '\0' };
942 	int error, off, port = 0;
943 
944 	switch (ss->ss_family) {
945 	case AF_INET:
946 		if (sstosin(ss)->sin_addr.s_addr == INADDR_ANY)
947 			addrstr[0] = '*';
948 		port = ntohs(sstosin(ss)->sin_port);
949 		break;
950 	case AF_INET6:
951 		if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
952 			addrstr[0] = '*';
953 		port = ntohs(sstosin6(ss)->sin6_port);
954 		break;
955 	case AF_UNIX:
956 		sun = sstosun(ss);
957 		off = (int)((char *)&sun->sun_path - (char *)sun);
958 		return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
959 	}
960 	if (addrstr[0] == '\0') {
961 		error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
962 		    addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
963 		if (error)
964 			errx(1, "cap_getnameinfo()");
965 	}
966 	if (port == 0)
967 		return xprintf("%s:*", addrstr);
968 	else
969 		return xprintf("%s:%d", addrstr, port);
970 }
971 
972 static const char *
973 getprocname(pid_t pid)
974 {
975 	static struct kinfo_proc proc;
976 	size_t len;
977 	int mib[4];
978 
979 	mib[0] = CTL_KERN;
980 	mib[1] = KERN_PROC;
981 	mib[2] = KERN_PROC_PID;
982 	mib[3] = (int)pid;
983 	len = sizeof(proc);
984 	if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
985 	    == -1) {
986 		/* Do not warn if the process exits before we get its name. */
987 		if (errno != ESRCH)
988 			warn("cap_sysctl()");
989 		return ("??");
990 	}
991 	return (proc.ki_comm);
992 }
993 
994 static int
995 getprocjid(pid_t pid)
996 {
997 	static struct kinfo_proc proc;
998 	size_t len;
999 	int mib[4];
1000 
1001 	mib[0] = CTL_KERN;
1002 	mib[1] = KERN_PROC;
1003 	mib[2] = KERN_PROC_PID;
1004 	mib[3] = (int)pid;
1005 	len = sizeof(proc);
1006 	if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
1007 	    == -1) {
1008 		/* Do not warn if the process exits before we get its jid. */
1009 		if (errno != ESRCH)
1010 			warn("cap_sysctl()");
1011 		return (-1);
1012 	}
1013 	return (proc.ki_jid);
1014 }
1015 
1016 static int
1017 check_ports(struct sock *s)
1018 {
1019 	int port;
1020 	struct addr *addr;
1021 
1022 	if (ports == NULL)
1023 		return (1);
1024 	if ((s->family != AF_INET) && (s->family != AF_INET6))
1025 		return (1);
1026 	for (addr = s->laddr; addr != NULL; addr = addr->next) {
1027 		if (s->family == AF_INET)
1028 			port = ntohs(sstosin(&addr->address)->sin_port);
1029 		else
1030 			port = ntohs(sstosin6(&addr->address)->sin6_port);
1031 		if (CHK_PORT(port))
1032 			return (1);
1033 	}
1034 	for (addr = s->faddr; addr != NULL; addr = addr->next) {
1035 		if (s->family == AF_INET)
1036 			port = ntohs(sstosin(&addr->address)->sin_port);
1037 		else
1038 			port = ntohs(sstosin6(&addr->address)->sin6_port);
1039 		if (CHK_PORT(port))
1040 			return (1);
1041 	}
1042 	return (0);
1043 }
1044 
1045 static const char *
1046 sctp_conn_state(int state)
1047 {
1048 	switch (state) {
1049 	case SCTP_CLOSED:
1050 		return "CLOSED";
1051 		break;
1052 	case SCTP_BOUND:
1053 		return "BOUND";
1054 		break;
1055 	case SCTP_LISTEN:
1056 		return "LISTEN";
1057 		break;
1058 	case SCTP_COOKIE_WAIT:
1059 		return "COOKIE_WAIT";
1060 		break;
1061 	case SCTP_COOKIE_ECHOED:
1062 		return "COOKIE_ECHOED";
1063 		break;
1064 	case SCTP_ESTABLISHED:
1065 		return "ESTABLISHED";
1066 		break;
1067 	case SCTP_SHUTDOWN_SENT:
1068 		return "SHUTDOWN_SENT";
1069 		break;
1070 	case SCTP_SHUTDOWN_RECEIVED:
1071 		return "SHUTDOWN_RECEIVED";
1072 		break;
1073 	case SCTP_SHUTDOWN_ACK_SENT:
1074 		return "SHUTDOWN_ACK_SENT";
1075 		break;
1076 	case SCTP_SHUTDOWN_PENDING:
1077 		return "SHUTDOWN_PENDING";
1078 		break;
1079 	default:
1080 		return "UNKNOWN";
1081 		break;
1082 	}
1083 }
1084 
1085 static const char *
1086 sctp_path_state(int state)
1087 {
1088 	switch (state) {
1089 	case SCTP_UNCONFIRMED:
1090 		return "UNCONFIRMED";
1091 		break;
1092 	case SCTP_ACTIVE:
1093 		return "ACTIVE";
1094 		break;
1095 	case SCTP_INACTIVE:
1096 		return "INACTIVE";
1097 		break;
1098 	default:
1099 		return "UNKNOWN";
1100 		break;
1101 	}
1102 }
1103 
1104 static void
1105 displaysock(struct sock *s, int pos)
1106 {
1107 	int first, offset;
1108 	struct addr *laddr, *faddr;
1109 
1110 	while (pos < 30)
1111 		pos += xprintf(" ");
1112 	pos += xprintf("%s", s->protoname);
1113 	if (s->vflag & INP_IPV4)
1114 		pos += xprintf("4");
1115 	if (s->vflag & INP_IPV6)
1116 		pos += xprintf("6");
1117 	if (s->vflag & (INP_IPV4 | INP_IPV6))
1118 		pos += xprintf(" ");
1119 	laddr = s->laddr;
1120 	faddr = s->faddr;
1121 	first = 1;
1122 	while (laddr != NULL || faddr != NULL) {
1123 		offset = 37;
1124 		while (pos < offset)
1125 			pos += xprintf(" ");
1126 		switch (s->family) {
1127 		case AF_INET:
1128 		case AF_INET6:
1129 			if (laddr != NULL) {
1130 				pos += printaddr(&laddr->address);
1131 				if (s->family == AF_INET6 && pos >= 58)
1132 					pos += xprintf(" ");
1133 			}
1134 			offset += opt_w ? 46 : 22;
1135 			while (pos < offset)
1136 				pos += xprintf(" ");
1137 			if (faddr != NULL)
1138 				pos += printaddr(&faddr->address);
1139 			offset += opt_w ? 46 : 22;
1140 			break;
1141 		case AF_UNIX:
1142 			if ((laddr == NULL) || (faddr == NULL))
1143 				errx(1, "laddr = %p or faddr = %p is NULL",
1144 				    (void *)laddr, (void *)faddr);
1145 			if (laddr->address.ss_len == 0 && faddr->conn == 0) {
1146 				pos += xprintf("(not connected)");
1147 				offset += opt_w ? 92 : 44;
1148 				break;
1149 			}
1150 			/* Local bind(2) address, if any. */
1151 			if (laddr->address.ss_len > 0)
1152 				pos += printaddr(&laddr->address);
1153 			/* Remote peer we connect(2) to, if any. */
1154 			if (faddr->conn != 0) {
1155 				struct sock *p;
1156 
1157 				pos += xprintf("%s-> ",
1158 				    laddr->address.ss_len > 0 ? " " : "");
1159 				p = RB_FIND(pcbs_t, &pcbs,
1160 				    &(struct sock){ .pcb = faddr->conn });
1161 				if (__predict_false(p == NULL)) {
1162 					/* XXGL: can this happen at all? */
1163 					pos += xprintf("??");
1164 				}  else if (p->laddr->address.ss_len == 0) {
1165 					struct file *f;
1166 
1167 					f = RB_FIND(files_t, &ftree,
1168 					    &(struct file){ .xf_data =
1169 					    p->socket });
1170 					pos += xprintf("[%lu %d]",
1171 					    (u_long)f->xf_pid, f->xf_fd);
1172 				} else
1173 					pos += printaddr(&p->laddr->address);
1174 			}
1175 			/* Remote peer(s) connect(2)ed to us, if any. */
1176 			if (faddr->firstref != 0) {
1177 				struct sock *p;
1178 				struct file *f;
1179 				kvaddr_t ref = faddr->firstref;
1180 				bool fref = true;
1181 
1182 				pos += xprintf(" <- ");
1183 
1184 				while ((p = RB_FIND(pcbs_t, &pcbs,
1185 				    &(struct sock){ .pcb = ref })) != 0) {
1186 					f = RB_FIND(files_t, &ftree,
1187 					    &(struct file){ .xf_data =
1188 					    p->socket });
1189 					pos += xprintf("%s[%lu %d]",
1190 					    fref ? "" : ",",
1191 					    (u_long)f->xf_pid, f->xf_fd);
1192 					ref = p->faddr->nextref;
1193 					fref = false;
1194 				}
1195 			}
1196 			offset += opt_w ? 92 : 44;
1197 			break;
1198 		default:
1199 			abort();
1200 		}
1201 		if (opt_i) {
1202 			if (s->proto == IPPROTO_TCP ||
1203 			    s->proto == IPPROTO_UDP) {
1204 				while (pos < offset)
1205 					pos += xprintf(" ");
1206 				pos += xprintf("%" PRIu64, s->inp_gencnt);
1207 			}
1208 			offset += 9;
1209 		}
1210 		if (opt_U) {
1211 			if (faddr != NULL &&
1212 			    ((s->proto == IPPROTO_SCTP &&
1213 			      s->state != SCTP_CLOSED &&
1214 			      s->state != SCTP_BOUND &&
1215 			      s->state != SCTP_LISTEN) ||
1216 			     (s->proto == IPPROTO_TCP &&
1217 			      s->state != TCPS_CLOSED &&
1218 			      s->state != TCPS_LISTEN))) {
1219 				while (pos < offset)
1220 					pos += xprintf(" ");
1221 				pos += xprintf("%u",
1222 				    ntohs(faddr->encaps_port));
1223 			}
1224 			offset += 7;
1225 		}
1226 		if (opt_s) {
1227 			if (faddr != NULL &&
1228 			    s->proto == IPPROTO_SCTP &&
1229 			    s->state != SCTP_CLOSED &&
1230 			    s->state != SCTP_BOUND &&
1231 			    s->state != SCTP_LISTEN) {
1232 				while (pos < offset)
1233 					pos += xprintf(" ");
1234 				pos += xprintf("%s",
1235 				    sctp_path_state(faddr->state));
1236 			}
1237 			offset += 13;
1238 		}
1239 		if (first) {
1240 			if (opt_s) {
1241 				if (s->proto == IPPROTO_SCTP ||
1242 				    s->proto == IPPROTO_TCP) {
1243 					while (pos < offset)
1244 						pos += xprintf(" ");
1245 					switch (s->proto) {
1246 					case IPPROTO_SCTP:
1247 						pos += xprintf("%s",
1248 						    sctp_conn_state(s->state));
1249 						break;
1250 					case IPPROTO_TCP:
1251 						if (s->state >= 0 &&
1252 						    s->state < TCP_NSTATES)
1253 							pos += xprintf("%s",
1254 							    tcpstates[s->state]);
1255 						else
1256 							pos += xprintf("?");
1257 						break;
1258 					}
1259 				}
1260 				offset += 13;
1261 			}
1262 			if (opt_S) {
1263 				if (s->proto == IPPROTO_TCP) {
1264 					while (pos < offset)
1265 						pos += xprintf(" ");
1266 					pos += xprintf("%.*s",
1267 					    TCP_FUNCTION_NAME_LEN_MAX,
1268 					    s->stack);
1269 				}
1270 				offset += TCP_FUNCTION_NAME_LEN_MAX + 1;
1271 			}
1272 			if (opt_C) {
1273 				if (s->proto == IPPROTO_TCP) {
1274 					while (pos < offset)
1275 						pos += xprintf(" ");
1276 					xprintf("%.*s", TCP_CA_NAME_MAX, s->cc);
1277 				}
1278 				offset += TCP_CA_NAME_MAX + 1;
1279 			}
1280 		}
1281 		if (laddr != NULL)
1282 			laddr = laddr->next;
1283 		if (faddr != NULL)
1284 			faddr = faddr->next;
1285 		if ((laddr != NULL) || (faddr != NULL)) {
1286 			xprintf("\n");
1287 			pos = 0;
1288 		}
1289 		first = 0;
1290 	}
1291 	xprintf("\n");
1292 }
1293 
1294 static void
1295 display(void)
1296 {
1297 	struct passwd *pwd;
1298 	struct file *xf;
1299 	struct sock *s;
1300 	int n, pos;
1301 
1302 	if (opt_q != 1) {
1303 		printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s",
1304 		    "USER", "COMMAND", "PID", "FD", "PROTO",
1305 		    opt_w ? 45 : 21, "LOCAL ADDRESS",
1306 		    opt_w ? 45 : 21, "FOREIGN ADDRESS");
1307 		if (opt_i)
1308 			printf(" %-8s", "ID");
1309 		if (opt_U)
1310 			printf(" %-6s", "ENCAPS");
1311 		if (opt_s) {
1312 			printf(" %-12s", "PATH STATE");
1313 			printf(" %-12s", "CONN STATE");
1314 		}
1315 		if (opt_S)
1316 			printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX,
1317 			    TCP_FUNCTION_NAME_LEN_MAX, "STACK");
1318 		if (opt_C)
1319 			printf(" %-.*s", TCP_CA_NAME_MAX, "CC");
1320 		printf("\n");
1321 	}
1322 	cap_setpassent(cappwd, 1);
1323 	for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
1324 		if (xf->xf_data == 0)
1325 			continue;
1326 		if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1327 			continue;
1328 		s = RB_FIND(socks_t, &socks,
1329 		    &(struct sock){ .socket = xf->xf_data});
1330 		if (s != NULL && check_ports(s)) {
1331 			s->shown = 1;
1332 			pos = 0;
1333 			if (opt_n ||
1334 			    (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
1335 				pos += xprintf("%lu ", (u_long)xf->xf_uid);
1336 			else
1337 				pos += xprintf("%s ", pwd->pw_name);
1338 			while (pos < 9)
1339 				pos += xprintf(" ");
1340 			pos += xprintf("%.10s", getprocname(xf->xf_pid));
1341 			while (pos < 20)
1342 				pos += xprintf(" ");
1343 			pos += xprintf("%5lu ", (u_long)xf->xf_pid);
1344 			while (pos < 26)
1345 				pos += xprintf(" ");
1346 			pos += xprintf("%-3d ", xf->xf_fd);
1347 			displaysock(s, pos);
1348 		}
1349 	}
1350 	if (opt_j >= 0)
1351 		return;
1352 	SLIST_FOREACH(s, &nosocks, socket_list) {
1353 		if (!check_ports(s))
1354 			continue;
1355 		pos = xprintf("%-8s %-10s %-5s %-2s ",
1356 		    "?", "?", "?", "?");
1357 		displaysock(s, pos);
1358 	}
1359 	RB_FOREACH(s, socks_t, &socks) {
1360 		if (s->shown)
1361 			continue;
1362 		if (!check_ports(s))
1363 			continue;
1364 		pos = xprintf("%-8s %-10s %-5s %-2s ",
1365 		    "?", "?", "?", "?");
1366 		displaysock(s, pos);
1367 	}
1368 }
1369 
1370 static int
1371 set_default_protos(void)
1372 {
1373 	struct protoent *prot;
1374 	const char *pname;
1375 	size_t pindex;
1376 
1377 	init_protos(default_numprotos);
1378 
1379 	for (pindex = 0; pindex < default_numprotos; pindex++) {
1380 		pname = default_protos[pindex];
1381 		prot = cap_getprotobyname(capnetdb, pname);
1382 		if (prot == NULL)
1383 			err(1, "cap_getprotobyname: %s", pname);
1384 		protos[pindex] = prot->p_proto;
1385 	}
1386 	numprotos = pindex;
1387 	return (pindex);
1388 }
1389 
1390 /*
1391  * Return the vnet property of the jail, or -1 on error.
1392  */
1393 static int
1394 jail_getvnet(int jid)
1395 {
1396 	struct iovec jiov[6];
1397 	int vnet;
1398 	size_t len = sizeof(vnet);
1399 
1400 	if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0)
1401 		return (0);
1402 
1403 	vnet = -1;
1404 	jiov[0].iov_base = __DECONST(char *, "jid");
1405 	jiov[0].iov_len = sizeof("jid");
1406 	jiov[1].iov_base = &jid;
1407 	jiov[1].iov_len = sizeof(jid);
1408 	jiov[2].iov_base = __DECONST(char *, "vnet");
1409 	jiov[2].iov_len = sizeof("vnet");
1410 	jiov[3].iov_base = &vnet;
1411 	jiov[3].iov_len = sizeof(vnet);
1412 	jiov[4].iov_base = __DECONST(char *, "errmsg");
1413 	jiov[4].iov_len = sizeof("errmsg");
1414 	jiov[5].iov_base = jail_errmsg;
1415 	jiov[5].iov_len = JAIL_ERRMSGLEN;
1416 	jail_errmsg[0] = '\0';
1417 	if (jail_get(jiov, nitems(jiov), 0) < 0) {
1418 		if (!jail_errmsg[0])
1419 			snprintf(jail_errmsg, JAIL_ERRMSGLEN,
1420 			    "jail_get: %s", strerror(errno));
1421 		return (-1);
1422 	}
1423 	return (vnet);
1424 }
1425 
1426 static void
1427 usage(void)
1428 {
1429 	fprintf(stderr,
1430 	    "usage: sockstat [-46CciLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]\n");
1431 	exit(1);
1432 }
1433 
1434 int
1435 main(int argc, char *argv[])
1436 {
1437 	cap_channel_t *capcas;
1438 	cap_net_limit_t *limit;
1439 	const char *pwdcmds[] = { "setpassent", "getpwuid" };
1440 	const char *pwdfields[] = { "pw_name" };
1441 	int protos_defined = -1;
1442 	int o, i;
1443 
1444 	opt_j = -1;
1445 	while ((o = getopt(argc, argv, "46Ccij:Llnp:P:qSsUuvw")) != -1)
1446 		switch (o) {
1447 		case '4':
1448 			opt_4 = 1;
1449 			break;
1450 		case '6':
1451 			opt_6 = 1;
1452 			break;
1453 		case 'C':
1454 			opt_C = 1;
1455 			break;
1456 		case 'c':
1457 			opt_c = 1;
1458 			break;
1459 		case 'i':
1460 			opt_i = 1;
1461 			break;
1462 		case 'j':
1463 			opt_j = jail_getid(optarg);
1464 			if (opt_j < 0)
1465 				errx(1, "jail_getid: %s", jail_errmsg);
1466 			break;
1467 		case 'L':
1468 			opt_L = 1;
1469 			break;
1470 		case 'l':
1471 			opt_l = 1;
1472 			break;
1473 		case 'n':
1474 			opt_n = 1;
1475 			break;
1476 		case 'p':
1477 			parse_ports(optarg);
1478 			break;
1479 		case 'P':
1480 			protos_defined = parse_protos(optarg);
1481 			break;
1482 		case 'q':
1483 			opt_q = 1;
1484 			break;
1485 		case 'S':
1486 			opt_S = 1;
1487 			break;
1488 		case 's':
1489 			opt_s = 1;
1490 			break;
1491 		case 'U':
1492 			opt_U = 1;
1493 			break;
1494 		case 'u':
1495 			opt_u = 1;
1496 			break;
1497 		case 'v':
1498 			++opt_v;
1499 			break;
1500 		case 'w':
1501 			opt_w = 1;
1502 			break;
1503 		default:
1504 			usage();
1505 		}
1506 
1507 	argc -= optind;
1508 	argv += optind;
1509 
1510 	if (argc > 0)
1511 		usage();
1512 
1513 	if (opt_j > 0) {
1514 		switch (jail_getvnet(opt_j)) {
1515 		case -1:
1516 			errx(2, "jail_getvnet: %s", jail_errmsg);
1517 		case JAIL_SYS_NEW:
1518 			if (jail_attach(opt_j) < 0)
1519 				err(3, "jail_attach()");
1520 			/* Set back to -1 for normal output in vnet jail. */
1521 			opt_j = -1;
1522 			break;
1523 		default:
1524 			break;
1525 		}
1526 	}
1527 
1528 	capcas = cap_init();
1529 	if (capcas == NULL)
1530 		err(1, "Unable to contact Casper");
1531 	if (caph_enter_casper() < 0)
1532 		err(1, "Unable to enter capability mode");
1533 	capnet = cap_service_open(capcas, "system.net");
1534 	if (capnet == NULL)
1535 		err(1, "Unable to open system.net service");
1536 	capnetdb = cap_service_open(capcas, "system.netdb");
1537 	if (capnetdb == NULL)
1538 		err(1, "Unable to open system.netdb service");
1539 	capsysctl = cap_service_open(capcas, "system.sysctl");
1540 	if (capsysctl == NULL)
1541 		err(1, "Unable to open system.sysctl service");
1542 	cappwd = cap_service_open(capcas, "system.pwd");
1543 	if (cappwd == NULL)
1544 		err(1, "Unable to open system.pwd service");
1545 	cap_close(capcas);
1546 	limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
1547 	if (limit == NULL)
1548 		err(1, "Unable to init cap_net limits");
1549 	if (cap_net_limit(limit) < 0)
1550 		err(1, "Unable to apply limits");
1551 	if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
1552 		err(1, "Unable to apply pwd commands limits");
1553 	if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
1554 		err(1, "Unable to apply pwd commands limits");
1555 
1556 	if ((!opt_4 && !opt_6) && protos_defined != -1)
1557 		opt_4 = opt_6 = 1;
1558 	if (!opt_4 && !opt_6 && !opt_u)
1559 		opt_4 = opt_6 = opt_u = 1;
1560 	if ((opt_4 || opt_6) && protos_defined == -1)
1561 		protos_defined = set_default_protos();
1562 	if (!opt_c && !opt_l)
1563 		opt_c = opt_l = 1;
1564 
1565 	if (opt_4 || opt_6) {
1566 		for (i = 0; i < protos_defined; i++)
1567 			if (protos[i] == IPPROTO_SCTP)
1568 				gather_sctp();
1569 			else
1570 				gather_inet(protos[i]);
1571 	}
1572 
1573 	if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1574 		gather_unix(SOCK_STREAM);
1575 		gather_unix(SOCK_DGRAM);
1576 		gather_unix(SOCK_SEQPACKET);
1577 	}
1578 	getfiles();
1579 	display();
1580 	exit(0);
1581 }
1582