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