xref: /freebsd/usr.bin/sockstat/sockstat.c (revision 54521a2ff93ae06c95c31f79f89dc23c9b51c20b)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2002 Dag-Erling 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/param.h>
32 #include <sys/file.h>
33 #include <sys/socket.h>
34 #include <sys/socketvar.h>
35 #include <sys/sysctl.h>
36 #include <sys/jail.h>
37 #include <sys/user.h>
38 #include <sys/queue.h>
39 #include <sys/tree.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 <capsicum_helpers.h>
57 #include <ctype.h>
58 #include <err.h>
59 #include <errno.h>
60 #include <inttypes.h>
61 #include <jail.h>
62 #include <netdb.h>
63 #include <pwd.h>
64 #include <stdarg.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69 
70 #include <libcasper.h>
71 #include <casper/cap_net.h>
72 #include <casper/cap_netdb.h>
73 #include <casper/cap_pwd.h>
74 #include <casper/cap_sysctl.h>
75 
76 #define	sstosin(ss)	((struct sockaddr_in *)(ss))
77 #define	sstosin6(ss)	((struct sockaddr_in6 *)(ss))
78 #define	sstosun(ss)	((struct sockaddr_un *)(ss))
79 #define	sstosa(ss)	((struct sockaddr *)(ss))
80 
81 static int	 opt_4;		/* Show IPv4 sockets */
82 static int	 opt_6;		/* Show IPv6 sockets */
83 static int	 opt_C;		/* Show congestion control */
84 static int	 opt_c;		/* Show connected sockets */
85 static int	 opt_I;		/* Show spliced socket addresses */
86 static int	 opt_i;		/* Show inp_gencnt */
87 static int	 opt_j;		/* Show specified jail */
88 static int	 opt_L;		/* Don't show IPv4 or IPv6 loopback sockets */
89 static int	 opt_l;		/* Show listening sockets */
90 static int	 opt_n;		/* Don't resolve UIDs to user names */
91 static int	 opt_q;		/* Don't show header */
92 static int	 opt_S;		/* Show protocol stack if applicable */
93 static int	 opt_s;		/* Show protocol state if applicable */
94 static int	 opt_U;		/* Show remote UDP encapsulation port number */
95 static int	 opt_u;		/* Show Unix domain sockets */
96 static int	 opt_v;		/* Verbose mode */
97 static int	 opt_w;		/* Wide print area for addresses */
98 
99 /*
100  * Default protocols to use if no -P was defined.
101  */
102 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
103 static size_t	   default_numprotos = nitems(default_protos);
104 
105 static int	*protos;	/* protocols to use */
106 static size_t	 numprotos;	/* allocated size of protos[] */
107 
108 static int	*ports;
109 
110 #define	INT_BIT (sizeof(int)*CHAR_BIT)
111 #define	SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
112 #define	CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
113 
114 struct addr {
115 	union {
116 		struct sockaddr_storage address;
117 		struct {	/* unix(4) faddr */
118 			kvaddr_t conn;
119 			kvaddr_t firstref;
120 			kvaddr_t nextref;
121 		};
122 	};
123 	unsigned int encaps_port;
124 	int state;
125 	struct addr *next;
126 };
127 
128 struct sock {
129 	union {
130 		RB_ENTRY(sock) socket_tree;	/* tree of pcbs with socket */
131 		SLIST_ENTRY(sock) socket_list;	/* list of pcbs w/o socket */
132 	};
133 	RB_ENTRY(sock) pcb_tree;
134 	kvaddr_t socket;
135 	kvaddr_t pcb;
136 	kvaddr_t splice_socket;
137 	uint64_t inp_gencnt;
138 	int shown;
139 	int vflag;
140 	int family;
141 	int proto;
142 	int state;
143 	const char *protoname;
144 	char stack[TCP_FUNCTION_NAME_LEN_MAX];
145 	char cc[TCP_CA_NAME_MAX];
146 	struct addr *laddr;
147 	struct addr *faddr;
148 };
149 
150 static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks);
151 static int64_t
152 socket_compare(const struct sock *a, const struct sock *b)
153 {
154 	return ((int64_t)(a->socket/2 - b->socket/2));
155 }
156 RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare);
157 
158 static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs);
159 static int64_t
160 pcb_compare(const struct sock *a, const struct sock *b)
161 {
162         return ((int64_t)(a->pcb/2 - b->pcb/2));
163 }
164 RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare);
165 
166 static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks);
167 
168 struct file {
169 	RB_ENTRY(file)	file_tree;
170 	kvaddr_t	xf_data;
171 	pid_t	xf_pid;
172 	uid_t	xf_uid;
173 	int	xf_fd;
174 };
175 
176 static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree);
177 static int64_t
178 file_compare(const struct file *a, const struct file *b)
179 {
180 	return ((int64_t)(a->xf_data/2 - b->xf_data/2));
181 }
182 RB_GENERATE_STATIC(files_t, file, file_tree, file_compare);
183 
184 static struct file *files;
185 static int nfiles;
186 
187 static cap_channel_t *capnet;
188 static cap_channel_t *capnetdb;
189 static cap_channel_t *capsysctl;
190 static cap_channel_t *cappwd;
191 
192 static int
193 xprintf(const char *fmt, ...)
194 {
195 	va_list ap;
196 	int len;
197 
198 	va_start(ap, fmt);
199 	len = vprintf(fmt, ap);
200 	va_end(ap);
201 	if (len < 0)
202 		err(1, "printf()");
203 	return (len);
204 }
205 
206 static bool
207 _check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
208 {
209 	if (received_size != expected_size) {
210 		warnx("%s size mismatch: expected %zd, received %zd",
211 		    struct_name, expected_size, received_size);
212 		return false;
213 	}
214 	return true;
215 }
216 #define check_ksize(_sz, _struct)	(_check_ksize(_sz, sizeof(_struct), #_struct))
217 
218 static void
219 _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
220 {
221 	if (received_size != expected_size) {
222 		errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
223 		    struct_name, expected_size, received_size);
224 	}
225 }
226 #define enforce_ksize(_sz, _struct)	(_enforce_ksize(_sz, sizeof(_struct), #_struct))
227 
228 static int
229 get_proto_type(const char *proto)
230 {
231 	struct protoent *pent;
232 
233 	if (strlen(proto) == 0)
234 		return (0);
235 	if (capnetdb != NULL)
236 		pent = cap_getprotobyname(capnetdb, proto);
237 	else
238 		pent = getprotobyname(proto);
239 	if (pent == NULL) {
240 		warn("cap_getprotobyname");
241 		return (-1);
242 	}
243 	return (pent->p_proto);
244 }
245 
246 static void
247 init_protos(int num)
248 {
249 	int proto_count = 0;
250 
251 	if (num > 0) {
252 		proto_count = num;
253 	} else {
254 		/* Find the maximum number of possible protocols. */
255 		while (getprotoent() != NULL)
256 			proto_count++;
257 		endprotoent();
258 	}
259 
260 	if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
261 		err(1, "malloc");
262 	numprotos = proto_count;
263 }
264 
265 static int
266 parse_protos(char *protospec)
267 {
268 	char *prot;
269 	int proto_type, proto_index;
270 
271 	if (protospec == NULL)
272 		return (-1);
273 
274 	init_protos(0);
275 	proto_index = 0;
276 	while ((prot = strsep(&protospec, ",")) != NULL) {
277 		if (strlen(prot) == 0)
278 			continue;
279 		proto_type = get_proto_type(prot);
280 		if (proto_type != -1)
281 			protos[proto_index++] = proto_type;
282 	}
283 	numprotos = proto_index;
284 	return (proto_index);
285 }
286 
287 static void
288 parse_ports(const char *portspec)
289 {
290 	const char *p, *q;
291 	int port, end;
292 
293 	if (ports == NULL)
294 		if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
295 			err(1, "calloc()");
296 	p = portspec;
297 	while (*p != '\0') {
298 		if (!isdigit(*p))
299 			errx(1, "syntax error in port range");
300 		for (q = p; *q != '\0' && isdigit(*q); ++q)
301 			/* nothing */ ;
302 		for (port = 0; p < q; ++p)
303 			port = port * 10 + digittoint(*p);
304 		if (port < 0 || port > 65535)
305 			errx(1, "invalid port number");
306 		SET_PORT(port);
307 		switch (*p) {
308 		case '-':
309 			++p;
310 			break;
311 		case ',':
312 			++p;
313 			/* fall through */
314 		case '\0':
315 		default:
316 			continue;
317 		}
318 		for (q = p; *q != '\0' && isdigit(*q); ++q)
319 			/* nothing */ ;
320 		for (end = 0; p < q; ++p)
321 			end = end * 10 + digittoint(*p);
322 		if (end < port || end > 65535)
323 			errx(1, "invalid port number");
324 		while (port++ < end)
325 			SET_PORT(port);
326 		if (*p == ',')
327 			++p;
328 	}
329 }
330 
331 static void
332 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
333 {
334 	struct sockaddr_in *sin4;
335 	struct sockaddr_in6 *sin6;
336 
337 	bzero(ss, sizeof(*ss));
338 	switch (af) {
339 	case AF_INET:
340 		sin4 = sstosin(ss);
341 		sin4->sin_len = sizeof(*sin4);
342 		sin4->sin_family = af;
343 		sin4->sin_port = port;
344 		sin4->sin_addr = *(struct in_addr *)addr;
345 		break;
346 	case AF_INET6:
347 		sin6 = sstosin6(ss);
348 		sin6->sin6_len = sizeof(*sin6);
349 		sin6->sin6_family = af;
350 		sin6->sin6_port = port;
351 		sin6->sin6_addr = *(struct in6_addr *)addr;
352 #define	s6_addr16	__u6_addr.__u6_addr16
353 		if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
354 			sin6->sin6_scope_id =
355 			    ntohs(sin6->sin6_addr.s6_addr16[1]);
356 			sin6->sin6_addr.s6_addr16[1] = 0;
357 		}
358 		break;
359 	default:
360 		abort();
361 	}
362 }
363 
364 static void
365 free_socket(struct sock *sock)
366 {
367 	struct addr *cur, *next;
368 
369 	cur = sock->laddr;
370 	while (cur != NULL) {
371 		next = cur->next;
372 		free(cur);
373 		cur = next;
374 	}
375 	cur = sock->faddr;
376 	while (cur != NULL) {
377 		next = cur->next;
378 		free(cur);
379 		cur = next;
380 	}
381 	free(sock);
382 }
383 
384 static void
385 gather_sctp(void)
386 {
387 	struct sock *sock;
388 	struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
389 	struct xsctp_inpcb *xinpcb;
390 	struct xsctp_tcb *xstcb;
391 	struct xsctp_raddr *xraddr;
392 	struct xsctp_laddr *xladdr;
393 	const char *varname;
394 	size_t len, offset;
395 	char *buf;
396 	int vflag;
397 	int no_stcb, local_all_loopback, foreign_all_loopback;
398 
399 	vflag = 0;
400 	if (opt_4)
401 		vflag |= INP_IPV4;
402 	if (opt_6)
403 		vflag |= INP_IPV6;
404 
405 	varname = "net.inet.sctp.assoclist";
406 	if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
407 		if (errno != ENOENT)
408 			err(1, "cap_sysctlbyname()");
409 		return;
410 	}
411 	if ((buf = (char *)malloc(len)) == NULL) {
412 		err(1, "malloc()");
413 		return;
414 	}
415 	if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
416 		err(1, "cap_sysctlbyname()");
417 		free(buf);
418 		return;
419 	}
420 	xinpcb = (struct xsctp_inpcb *)(void *)buf;
421 	offset = sizeof(struct xsctp_inpcb);
422 	while ((offset < len) && (xinpcb->last == 0)) {
423 		if ((sock = calloc(1, sizeof *sock)) == NULL)
424 			err(1, "malloc()");
425 		sock->socket = xinpcb->socket;
426 		sock->proto = IPPROTO_SCTP;
427 		sock->protoname = "sctp";
428 		if (xinpcb->maxqlen == 0)
429 			sock->state = SCTP_CLOSED;
430 		else
431 			sock->state = SCTP_LISTEN;
432 		if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
433 			sock->family = AF_INET6;
434 			/*
435 			 * Currently there is no way to distinguish between
436 			 * IPv6 only sockets or dual family sockets.
437 			 * So mark it as dual socket.
438 			 */
439 			sock->vflag = INP_IPV6 | INP_IPV4;
440 		} else {
441 			sock->family = AF_INET;
442 			sock->vflag = INP_IPV4;
443 		}
444 		prev_laddr = NULL;
445 		local_all_loopback = 1;
446 		while (offset < len) {
447 			xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
448 			offset += sizeof(struct xsctp_laddr);
449 			if (xladdr->last == 1)
450 				break;
451 			if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
452 				err(1, "malloc()");
453 			switch (xladdr->address.sa.sa_family) {
454 			case AF_INET:
455 #define	__IN_IS_ADDR_LOOPBACK(pina) \
456 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
457 				if (!__IN_IS_ADDR_LOOPBACK(
458 				    &xladdr->address.sin.sin_addr))
459 					local_all_loopback = 0;
460 #undef	__IN_IS_ADDR_LOOPBACK
461 				sockaddr(&laddr->address, AF_INET,
462 				    &xladdr->address.sin.sin_addr,
463 				    htons(xinpcb->local_port));
464 				break;
465 			case AF_INET6:
466 				if (!IN6_IS_ADDR_LOOPBACK(
467 				    &xladdr->address.sin6.sin6_addr))
468 					local_all_loopback = 0;
469 				sockaddr(&laddr->address, AF_INET6,
470 				    &xladdr->address.sin6.sin6_addr,
471 				    htons(xinpcb->local_port));
472 				break;
473 			default:
474 				errx(1, "address family %d not supported",
475 				    xladdr->address.sa.sa_family);
476 			}
477 			laddr->next = NULL;
478 			if (prev_laddr == NULL)
479 				sock->laddr = laddr;
480 			else
481 				prev_laddr->next = laddr;
482 			prev_laddr = laddr;
483 		}
484 		if (sock->laddr == NULL) {
485 			if ((sock->laddr =
486 			    calloc(1, sizeof(struct addr))) == NULL)
487 				err(1, "malloc()");
488 			sock->laddr->address.ss_family = sock->family;
489 			if (sock->family == AF_INET)
490 				sock->laddr->address.ss_len =
491 				    sizeof(struct sockaddr_in);
492 			else
493 				sock->laddr->address.ss_len =
494 				    sizeof(struct sockaddr_in6);
495 			local_all_loopback = 0;
496 		}
497 		if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
498 			err(1, "malloc()");
499 		sock->faddr->address.ss_family = sock->family;
500 		if (sock->family == AF_INET)
501 			sock->faddr->address.ss_len =
502 			    sizeof(struct sockaddr_in);
503 		else
504 			sock->faddr->address.ss_len =
505 			    sizeof(struct sockaddr_in6);
506 		no_stcb = 1;
507 		while (offset < len) {
508 			xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
509 			offset += sizeof(struct xsctp_tcb);
510 			if (no_stcb) {
511 				if (opt_l && (sock->vflag & vflag) &&
512 				    (!opt_L || !local_all_loopback) &&
513 				    ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
514 				     (xstcb->last == 1))) {
515 					RB_INSERT(socks_t, &socks, sock);
516 				} else {
517 					free_socket(sock);
518 				}
519 			}
520 			if (xstcb->last == 1)
521 				break;
522 			no_stcb = 0;
523 			if (opt_c) {
524 				if ((sock = calloc(1, sizeof *sock)) == NULL)
525 					err(1, "malloc()");
526 				sock->socket = xinpcb->socket;
527 				sock->proto = IPPROTO_SCTP;
528 				sock->protoname = "sctp";
529 				sock->state = (int)xstcb->state;
530 				if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
531 					sock->family = AF_INET6;
532 				/*
533 				 * Currently there is no way to distinguish
534 				 * between IPv6 only sockets or dual family
535 				 *  sockets. So mark it as dual socket.
536 				 */
537 					sock->vflag = INP_IPV6 | INP_IPV4;
538 				} else {
539 					sock->family = AF_INET;
540 					sock->vflag = INP_IPV4;
541 				}
542 			}
543 			prev_laddr = NULL;
544 			local_all_loopback = 1;
545 			while (offset < len) {
546 				xladdr = (struct xsctp_laddr *)(void *)(buf +
547 				    offset);
548 				offset += sizeof(struct xsctp_laddr);
549 				if (xladdr->last == 1)
550 					break;
551 				if (!opt_c)
552 					continue;
553 				laddr = calloc(1, sizeof(struct addr));
554 				if (laddr == NULL)
555 					err(1, "malloc()");
556 				switch (xladdr->address.sa.sa_family) {
557 				case AF_INET:
558 #define	__IN_IS_ADDR_LOOPBACK(pina) \
559 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
560 					if (!__IN_IS_ADDR_LOOPBACK(
561 					    &xladdr->address.sin.sin_addr))
562 						local_all_loopback = 0;
563 #undef	__IN_IS_ADDR_LOOPBACK
564 					sockaddr(&laddr->address, AF_INET,
565 					    &xladdr->address.sin.sin_addr,
566 					    htons(xstcb->local_port));
567 					break;
568 				case AF_INET6:
569 					if (!IN6_IS_ADDR_LOOPBACK(
570 					    &xladdr->address.sin6.sin6_addr))
571 						local_all_loopback = 0;
572 					sockaddr(&laddr->address, AF_INET6,
573 					    &xladdr->address.sin6.sin6_addr,
574 					    htons(xstcb->local_port));
575 					break;
576 				default:
577 					errx(1,
578 					    "address family %d not supported",
579 					    xladdr->address.sa.sa_family);
580 				}
581 				laddr->next = NULL;
582 				if (prev_laddr == NULL)
583 					sock->laddr = laddr;
584 				else
585 					prev_laddr->next = laddr;
586 				prev_laddr = laddr;
587 			}
588 			prev_faddr = NULL;
589 			foreign_all_loopback = 1;
590 			while (offset < len) {
591 				xraddr = (struct xsctp_raddr *)(void *)(buf +
592 				    offset);
593 				offset += sizeof(struct xsctp_raddr);
594 				if (xraddr->last == 1)
595 					break;
596 				if (!opt_c)
597 					continue;
598 				faddr = calloc(1, sizeof(struct addr));
599 				if (faddr == NULL)
600 					err(1, "malloc()");
601 				switch (xraddr->address.sa.sa_family) {
602 				case AF_INET:
603 #define	__IN_IS_ADDR_LOOPBACK(pina) \
604 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
605 					if (!__IN_IS_ADDR_LOOPBACK(
606 					    &xraddr->address.sin.sin_addr))
607 						foreign_all_loopback = 0;
608 #undef	__IN_IS_ADDR_LOOPBACK
609 					sockaddr(&faddr->address, AF_INET,
610 					    &xraddr->address.sin.sin_addr,
611 					    htons(xstcb->remote_port));
612 					break;
613 				case AF_INET6:
614 					if (!IN6_IS_ADDR_LOOPBACK(
615 					    &xraddr->address.sin6.sin6_addr))
616 						foreign_all_loopback = 0;
617 					sockaddr(&faddr->address, AF_INET6,
618 					    &xraddr->address.sin6.sin6_addr,
619 					    htons(xstcb->remote_port));
620 					break;
621 				default:
622 					errx(1,
623 					    "address family %d not supported",
624 					    xraddr->address.sa.sa_family);
625 				}
626 				faddr->encaps_port = xraddr->encaps_port;
627 				faddr->state = xraddr->state;
628 				faddr->next = NULL;
629 				if (prev_faddr == NULL)
630 					sock->faddr = faddr;
631 				else
632 					prev_faddr->next = faddr;
633 				prev_faddr = faddr;
634 			}
635 			if (opt_c) {
636 				if ((sock->vflag & vflag) &&
637 				    (!opt_L ||
638 				     !(local_all_loopback ||
639 				     foreign_all_loopback))) {
640 					RB_INSERT(socks_t, &socks, sock);
641 				} else {
642 					free_socket(sock);
643 				}
644 			}
645 		}
646 		xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
647 		offset += sizeof(struct xsctp_inpcb);
648 	}
649 	free(buf);
650 }
651 
652 static void
653 gather_inet(int proto)
654 {
655 	struct xinpgen *xig, *exig;
656 	struct xinpcb *xip;
657 	struct xtcpcb *xtp = NULL;
658 	struct xsocket *so;
659 	struct sock *sock;
660 	struct addr *laddr, *faddr;
661 	const char *varname, *protoname;
662 	size_t len, bufsize;
663 	void *buf;
664 	int retry, vflag;
665 
666 	vflag = 0;
667 	if (opt_4)
668 		vflag |= INP_IPV4;
669 	if (opt_6)
670 		vflag |= INP_IPV6;
671 
672 	switch (proto) {
673 	case IPPROTO_TCP:
674 		varname = "net.inet.tcp.pcblist";
675 		protoname = "tcp";
676 		break;
677 	case IPPROTO_UDP:
678 		varname = "net.inet.udp.pcblist";
679 		protoname = "udp";
680 		break;
681 	case IPPROTO_DIVERT:
682 		varname = "net.inet.divert.pcblist";
683 		protoname = "div";
684 		break;
685 	default:
686 		errx(1, "protocol %d not supported", proto);
687 	}
688 
689 	buf = NULL;
690 	bufsize = 8192;
691 	retry = 5;
692 	do {
693 		for (;;) {
694 			if ((buf = realloc(buf, bufsize)) == NULL)
695 				err(1, "realloc()");
696 			len = bufsize;
697 			if (cap_sysctlbyname(capsysctl, varname, buf, &len,
698 			    NULL, 0) == 0)
699 				break;
700 			if (errno == ENOENT)
701 				goto out;
702 			if (errno != ENOMEM || len != bufsize)
703 				err(1, "cap_sysctlbyname()");
704 			bufsize *= 2;
705 		}
706 		xig = (struct xinpgen *)buf;
707 		exig = (struct xinpgen *)(void *)
708 		    ((char *)buf + len - sizeof *exig);
709 		enforce_ksize(xig->xig_len, struct xinpgen);
710 		enforce_ksize(exig->xig_len, struct xinpgen);
711 	} while (xig->xig_gen != exig->xig_gen && retry--);
712 
713 	if (xig->xig_gen != exig->xig_gen && opt_v)
714 		warnx("warning: data may be inconsistent");
715 
716 	for (;;) {
717 		xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
718 		if (xig >= exig)
719 			break;
720 		switch (proto) {
721 		case IPPROTO_TCP:
722 			xtp = (struct xtcpcb *)xig;
723 			xip = &xtp->xt_inp;
724 			if (!check_ksize(xtp->xt_len, struct xtcpcb))
725 				goto out;
726 			protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
727 			break;
728 		case IPPROTO_UDP:
729 		case IPPROTO_DIVERT:
730 			xip = (struct xinpcb *)xig;
731 			if (!check_ksize(xip->xi_len, struct xinpcb))
732 				goto out;
733 			break;
734 		default:
735 			errx(1, "protocol %d not supported", proto);
736 		}
737 		so = &xip->xi_socket;
738 		if ((xip->inp_vflag & vflag) == 0)
739 			continue;
740 		if (xip->inp_vflag & INP_IPV4) {
741 			if ((xip->inp_fport == 0 && !opt_l) ||
742 			    (xip->inp_fport != 0 && !opt_c))
743 				continue;
744 #define	__IN_IS_ADDR_LOOPBACK(pina) \
745 	((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
746 			if (opt_L &&
747 			    (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
748 			     __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
749 				continue;
750 #undef	__IN_IS_ADDR_LOOPBACK
751 		} else if (xip->inp_vflag & INP_IPV6) {
752 			if ((xip->inp_fport == 0 && !opt_l) ||
753 			    (xip->inp_fport != 0 && !opt_c))
754 				continue;
755 			if (opt_L &&
756 			    (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
757 			     IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
758 				continue;
759 		} else {
760 			if (opt_v)
761 				warnx("invalid vflag 0x%x", xip->inp_vflag);
762 			continue;
763 		}
764 		if ((sock = calloc(1, sizeof(*sock))) == NULL)
765 			err(1, "malloc()");
766 		if ((laddr = calloc(1, sizeof *laddr)) == NULL)
767 			err(1, "malloc()");
768 		if ((faddr = calloc(1, sizeof *faddr)) == NULL)
769 			err(1, "malloc()");
770 		sock->socket = so->xso_so;
771 		sock->splice_socket = so->so_splice_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 					if (f != NULL) {
1171 						pos += xprintf("[%lu %d]",
1172 						    (u_long)f->xf_pid,
1173 						    f->xf_fd);
1174 					}
1175 				} else
1176 					pos += printaddr(&p->laddr->address);
1177 			}
1178 			/* Remote peer(s) connect(2)ed to us, if any. */
1179 			if (faddr->firstref != 0) {
1180 				struct sock *p;
1181 				struct file *f;
1182 				kvaddr_t ref = faddr->firstref;
1183 				bool fref = true;
1184 
1185 				pos += xprintf(" <- ");
1186 
1187 				while ((p = RB_FIND(pcbs_t, &pcbs,
1188 				    &(struct sock){ .pcb = ref })) != 0) {
1189 					f = RB_FIND(files_t, &ftree,
1190 					    &(struct file){ .xf_data =
1191 					    p->socket });
1192 					if (f != NULL) {
1193 						pos += xprintf("%s[%lu %d]",
1194 						    fref ? "" : ",",
1195 						    (u_long)f->xf_pid,
1196 						    f->xf_fd);
1197 					}
1198 					ref = p->faddr->nextref;
1199 					fref = false;
1200 				}
1201 			}
1202 			offset += opt_w ? 92 : 44;
1203 			break;
1204 		default:
1205 			abort();
1206 		}
1207 		if (opt_I) {
1208 			if (s->splice_socket != 0) {
1209 				struct sock *sp;
1210 
1211 				sp = RB_FIND(socks_t, &socks, &(struct sock)
1212 				    { .socket = s->splice_socket });
1213 				if (sp != NULL) {
1214 					while (pos < offset)
1215 						pos += xprintf(" ");
1216 					pos += printaddr(&sp->laddr->address);
1217 				} else {
1218 					while (pos < offset)
1219 						pos += xprintf(" ");
1220 					pos += xprintf("??");
1221 					offset += opt_w ? 46 : 22;
1222 				}
1223 			}
1224 			offset += opt_w ? 46 : 22;
1225 		}
1226 		if (opt_i) {
1227 			if (s->proto == IPPROTO_TCP ||
1228 			    s->proto == IPPROTO_UDP) {
1229 				while (pos < offset)
1230 					pos += xprintf(" ");
1231 				pos += xprintf("%" PRIu64, s->inp_gencnt);
1232 			}
1233 			offset += 9;
1234 		}
1235 		if (opt_U) {
1236 			if (faddr != NULL &&
1237 			    ((s->proto == IPPROTO_SCTP &&
1238 			      s->state != SCTP_CLOSED &&
1239 			      s->state != SCTP_BOUND &&
1240 			      s->state != SCTP_LISTEN) ||
1241 			     (s->proto == IPPROTO_TCP &&
1242 			      s->state != TCPS_CLOSED &&
1243 			      s->state != TCPS_LISTEN))) {
1244 				while (pos < offset)
1245 					pos += xprintf(" ");
1246 				pos += xprintf("%u",
1247 				    ntohs(faddr->encaps_port));
1248 			}
1249 			offset += 7;
1250 		}
1251 		if (opt_s) {
1252 			if (faddr != NULL &&
1253 			    s->proto == IPPROTO_SCTP &&
1254 			    s->state != SCTP_CLOSED &&
1255 			    s->state != SCTP_BOUND &&
1256 			    s->state != SCTP_LISTEN) {
1257 				while (pos < offset)
1258 					pos += xprintf(" ");
1259 				pos += xprintf("%s",
1260 				    sctp_path_state(faddr->state));
1261 			}
1262 			offset += 13;
1263 		}
1264 		if (first) {
1265 			if (opt_s) {
1266 				if (s->proto == IPPROTO_SCTP ||
1267 				    s->proto == IPPROTO_TCP) {
1268 					while (pos < offset)
1269 						pos += xprintf(" ");
1270 					switch (s->proto) {
1271 					case IPPROTO_SCTP:
1272 						pos += xprintf("%s",
1273 						    sctp_conn_state(s->state));
1274 						break;
1275 					case IPPROTO_TCP:
1276 						if (s->state >= 0 &&
1277 						    s->state < TCP_NSTATES)
1278 							pos += xprintf("%s",
1279 							    tcpstates[s->state]);
1280 						else
1281 							pos += xprintf("?");
1282 						break;
1283 					}
1284 				}
1285 				offset += 13;
1286 			}
1287 			if (opt_S) {
1288 				if (s->proto == IPPROTO_TCP) {
1289 					while (pos < offset)
1290 						pos += xprintf(" ");
1291 					pos += xprintf("%.*s",
1292 					    TCP_FUNCTION_NAME_LEN_MAX,
1293 					    s->stack);
1294 				}
1295 				offset += TCP_FUNCTION_NAME_LEN_MAX + 1;
1296 			}
1297 			if (opt_C) {
1298 				if (s->proto == IPPROTO_TCP) {
1299 					while (pos < offset)
1300 						pos += xprintf(" ");
1301 					xprintf("%.*s", TCP_CA_NAME_MAX, s->cc);
1302 				}
1303 				offset += TCP_CA_NAME_MAX + 1;
1304 			}
1305 		}
1306 		if (laddr != NULL)
1307 			laddr = laddr->next;
1308 		if (faddr != NULL)
1309 			faddr = faddr->next;
1310 		if ((laddr != NULL) || (faddr != NULL)) {
1311 			xprintf("\n");
1312 			pos = 0;
1313 		}
1314 		first = 0;
1315 	}
1316 	xprintf("\n");
1317 }
1318 
1319 static void
1320 display(void)
1321 {
1322 	struct passwd *pwd;
1323 	struct file *xf;
1324 	struct sock *s;
1325 	int n, pos;
1326 
1327 	if (opt_q != 1) {
1328 		printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s",
1329 		    "USER", "COMMAND", "PID", "FD", "PROTO",
1330 		    opt_w ? 45 : 21, "LOCAL ADDRESS",
1331 		    opt_w ? 45 : 21, "FOREIGN ADDRESS");
1332 		if (opt_I)
1333 			printf(" %-*s", opt_w ? 45 : 21, "SPLICE ADDRESS");
1334 		if (opt_i)
1335 			printf(" %-8s", "ID");
1336 		if (opt_U)
1337 			printf(" %-6s", "ENCAPS");
1338 		if (opt_s) {
1339 			printf(" %-12s", "PATH STATE");
1340 			printf(" %-12s", "CONN STATE");
1341 		}
1342 		if (opt_S)
1343 			printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX,
1344 			    TCP_FUNCTION_NAME_LEN_MAX, "STACK");
1345 		if (opt_C)
1346 			printf(" %-.*s", TCP_CA_NAME_MAX, "CC");
1347 		printf("\n");
1348 	}
1349 	cap_setpassent(cappwd, 1);
1350 	for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
1351 		if (xf->xf_data == 0)
1352 			continue;
1353 		if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1354 			continue;
1355 		s = RB_FIND(socks_t, &socks,
1356 		    &(struct sock){ .socket = xf->xf_data});
1357 		if (s != NULL && check_ports(s)) {
1358 			s->shown = 1;
1359 			pos = 0;
1360 			if (opt_n ||
1361 			    (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
1362 				pos += xprintf("%lu ", (u_long)xf->xf_uid);
1363 			else
1364 				pos += xprintf("%s ", pwd->pw_name);
1365 			while (pos < 9)
1366 				pos += xprintf(" ");
1367 			pos += xprintf("%.10s", getprocname(xf->xf_pid));
1368 			while (pos < 20)
1369 				pos += xprintf(" ");
1370 			pos += xprintf("%5lu ", (u_long)xf->xf_pid);
1371 			while (pos < 26)
1372 				pos += xprintf(" ");
1373 			pos += xprintf("%-3d ", xf->xf_fd);
1374 			displaysock(s, pos);
1375 		}
1376 	}
1377 	if (opt_j >= 0)
1378 		return;
1379 	SLIST_FOREACH(s, &nosocks, socket_list) {
1380 		if (!check_ports(s))
1381 			continue;
1382 		pos = xprintf("%-8s %-10s %-5s %-2s ",
1383 		    "?", "?", "?", "?");
1384 		displaysock(s, pos);
1385 	}
1386 	RB_FOREACH(s, socks_t, &socks) {
1387 		if (s->shown)
1388 			continue;
1389 		if (!check_ports(s))
1390 			continue;
1391 		pos = xprintf("%-8s %-10s %-5s %-2s ",
1392 		    "?", "?", "?", "?");
1393 		displaysock(s, pos);
1394 	}
1395 }
1396 
1397 static int
1398 set_default_protos(void)
1399 {
1400 	struct protoent *prot;
1401 	const char *pname;
1402 	size_t pindex;
1403 
1404 	init_protos(default_numprotos);
1405 
1406 	for (pindex = 0; pindex < default_numprotos; pindex++) {
1407 		pname = default_protos[pindex];
1408 		prot = cap_getprotobyname(capnetdb, pname);
1409 		if (prot == NULL)
1410 			err(1, "cap_getprotobyname: %s", pname);
1411 		protos[pindex] = prot->p_proto;
1412 	}
1413 	numprotos = pindex;
1414 	return (pindex);
1415 }
1416 
1417 /*
1418  * Return the vnet property of the jail, or -1 on error.
1419  */
1420 static int
1421 jail_getvnet(int jid)
1422 {
1423 	struct iovec jiov[6];
1424 	int vnet;
1425 	size_t len = sizeof(vnet);
1426 
1427 	if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0)
1428 		return (0);
1429 
1430 	vnet = -1;
1431 	jiov[0].iov_base = __DECONST(char *, "jid");
1432 	jiov[0].iov_len = sizeof("jid");
1433 	jiov[1].iov_base = &jid;
1434 	jiov[1].iov_len = sizeof(jid);
1435 	jiov[2].iov_base = __DECONST(char *, "vnet");
1436 	jiov[2].iov_len = sizeof("vnet");
1437 	jiov[3].iov_base = &vnet;
1438 	jiov[3].iov_len = sizeof(vnet);
1439 	jiov[4].iov_base = __DECONST(char *, "errmsg");
1440 	jiov[4].iov_len = sizeof("errmsg");
1441 	jiov[5].iov_base = jail_errmsg;
1442 	jiov[5].iov_len = JAIL_ERRMSGLEN;
1443 	jail_errmsg[0] = '\0';
1444 	if (jail_get(jiov, nitems(jiov), 0) < 0) {
1445 		if (!jail_errmsg[0])
1446 			snprintf(jail_errmsg, JAIL_ERRMSGLEN,
1447 			    "jail_get: %s", strerror(errno));
1448 		return (-1);
1449 	}
1450 	return (vnet);
1451 }
1452 
1453 static void
1454 usage(void)
1455 {
1456 	fprintf(stderr,
1457     "usage: sockstat [-46CcIiLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]\n");
1458 	exit(1);
1459 }
1460 
1461 int
1462 main(int argc, char *argv[])
1463 {
1464 	cap_channel_t *capcas;
1465 	cap_net_limit_t *limit;
1466 	const char *pwdcmds[] = { "setpassent", "getpwuid" };
1467 	const char *pwdfields[] = { "pw_name" };
1468 	int protos_defined = -1;
1469 	int o, i;
1470 
1471 	opt_j = -1;
1472 	while ((o = getopt(argc, argv, "46CcIij:Llnp:P:qSsUuvw")) != -1)
1473 		switch (o) {
1474 		case '4':
1475 			opt_4 = 1;
1476 			break;
1477 		case '6':
1478 			opt_6 = 1;
1479 			break;
1480 		case 'C':
1481 			opt_C = 1;
1482 			break;
1483 		case 'c':
1484 			opt_c = 1;
1485 			break;
1486 		case 'I':
1487 			opt_I = 1;
1488 			break;
1489 		case 'i':
1490 			opt_i = 1;
1491 			break;
1492 		case 'j':
1493 			opt_j = jail_getid(optarg);
1494 			if (opt_j < 0)
1495 				errx(1, "jail_getid: %s", jail_errmsg);
1496 			break;
1497 		case 'L':
1498 			opt_L = 1;
1499 			break;
1500 		case 'l':
1501 			opt_l = 1;
1502 			break;
1503 		case 'n':
1504 			opt_n = 1;
1505 			break;
1506 		case 'p':
1507 			parse_ports(optarg);
1508 			break;
1509 		case 'P':
1510 			protos_defined = parse_protos(optarg);
1511 			break;
1512 		case 'q':
1513 			opt_q = 1;
1514 			break;
1515 		case 'S':
1516 			opt_S = 1;
1517 			break;
1518 		case 's':
1519 			opt_s = 1;
1520 			break;
1521 		case 'U':
1522 			opt_U = 1;
1523 			break;
1524 		case 'u':
1525 			opt_u = 1;
1526 			break;
1527 		case 'v':
1528 			++opt_v;
1529 			break;
1530 		case 'w':
1531 			opt_w = 1;
1532 			break;
1533 		default:
1534 			usage();
1535 		}
1536 
1537 	argc -= optind;
1538 	argv += optind;
1539 
1540 	if (argc > 0)
1541 		usage();
1542 
1543 	if (opt_j > 0) {
1544 		switch (jail_getvnet(opt_j)) {
1545 		case -1:
1546 			errx(2, "jail_getvnet: %s", jail_errmsg);
1547 		case JAIL_SYS_NEW:
1548 			if (jail_attach(opt_j) < 0)
1549 				err(3, "jail_attach()");
1550 			/* Set back to -1 for normal output in vnet jail. */
1551 			opt_j = -1;
1552 			break;
1553 		default:
1554 			break;
1555 		}
1556 	}
1557 
1558 	capcas = cap_init();
1559 	if (capcas == NULL)
1560 		err(1, "Unable to contact Casper");
1561 	if (caph_enter_casper() < 0)
1562 		err(1, "Unable to enter capability mode");
1563 	capnet = cap_service_open(capcas, "system.net");
1564 	if (capnet == NULL)
1565 		err(1, "Unable to open system.net service");
1566 	capnetdb = cap_service_open(capcas, "system.netdb");
1567 	if (capnetdb == NULL)
1568 		err(1, "Unable to open system.netdb service");
1569 	capsysctl = cap_service_open(capcas, "system.sysctl");
1570 	if (capsysctl == NULL)
1571 		err(1, "Unable to open system.sysctl service");
1572 	cappwd = cap_service_open(capcas, "system.pwd");
1573 	if (cappwd == NULL)
1574 		err(1, "Unable to open system.pwd service");
1575 	cap_close(capcas);
1576 	limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
1577 	if (limit == NULL)
1578 		err(1, "Unable to init cap_net limits");
1579 	if (cap_net_limit(limit) < 0)
1580 		err(1, "Unable to apply limits");
1581 	if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
1582 		err(1, "Unable to apply pwd commands limits");
1583 	if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
1584 		err(1, "Unable to apply pwd commands limits");
1585 
1586 	if ((!opt_4 && !opt_6) && protos_defined != -1)
1587 		opt_4 = opt_6 = 1;
1588 	if (!opt_4 && !opt_6 && !opt_u)
1589 		opt_4 = opt_6 = opt_u = 1;
1590 	if ((opt_4 || opt_6) && protos_defined == -1)
1591 		protos_defined = set_default_protos();
1592 	if (!opt_c && !opt_l)
1593 		opt_c = opt_l = 1;
1594 
1595 	if (opt_4 || opt_6) {
1596 		for (i = 0; i < protos_defined; i++)
1597 			if (protos[i] == IPPROTO_SCTP)
1598 				gather_sctp();
1599 			else
1600 				gather_inet(protos[i]);
1601 	}
1602 
1603 	if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1604 		gather_unix(SOCK_STREAM);
1605 		gather_unix(SOCK_DGRAM);
1606 		gather_unix(SOCK_SEQPACKET);
1607 	}
1608 	getfiles();
1609 	display();
1610 	exit(0);
1611 }
1612