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