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