2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2002 Dag-Erling Coïdan Smørgrav
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
36 #include <sys/socket.h>
37 #include <sys/socketvar.h>
38 #include <sys/sysctl.h>
41 #include <sys/queue.h>
45 #include <sys/unpcb.h>
47 #include <net/route.h>
49 #include <netinet/in.h>
50 #include <netinet/in_pcb.h>
51 #include <netinet/sctp.h>
52 #include <netinet/tcp.h>
53 #define TCPSTATES /* load state names */
54 #include <netinet/tcp_fsm.h>
55 #include <netinet/tcp_seq.h>
56 #include <netinet/tcp_var.h>
57 #include <arpa/inet.h>
59 #include <capsicum_helpers.h>
73 #include <libcasper.h>
74 #include <casper/cap_net.h>
75 #include <casper/cap_netdb.h>
76 #include <casper/cap_pwd.h>
77 #include <casper/cap_sysctl.h>
79 #define sstosin(ss) ((struct sockaddr_in *)(ss))
80 #define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
81 #define sstosun(ss) ((struct sockaddr_un *)(ss))
82 #define sstosa(ss) ((struct sockaddr *)(ss))
84 static int opt_4; /* Show IPv4 sockets */
85 static int opt_6; /* Show IPv6 sockets */
86 static int opt_C; /* Show congestion control */
87 static int opt_c; /* Show connected sockets */
88 static int opt_i; /* Show inp_gencnt */
89 static int opt_j; /* Show specified jail */
90 static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */
91 static int opt_l; /* Show listening sockets */
92 static int opt_n; /* Don't resolve UIDs to user names */
93 static int opt_q; /* Don't show header */
94 static int opt_S; /* Show protocol stack if applicable */
95 static int opt_s; /* Show protocol state if applicable */
96 static int opt_U; /* Show remote UDP encapsulation port number */
97 static int opt_u; /* Show Unix domain sockets */
98 static int opt_v; /* Verbose mode */
99 static int opt_w; /* Wide print area for addresses */
102 * Default protocols to use if no -P was defined.
104 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
105 static size_t default_numprotos = nitems(default_protos);
107 static int *protos; /* protocols to use */
108 static size_t numprotos; /* allocated size of protos[] */
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)))
118 struct sockaddr_storage address;
119 struct { /* unix(4) faddr */
125 unsigned int encaps_port;
132 RB_ENTRY(sock) socket_tree; /* tree of pcbs with socket */
133 SLIST_ENTRY(sock) socket_list; /* list of pcbs w/o socket */
135 RB_ENTRY(sock) pcb_tree;
144 const char *protoname;
145 char stack[TCP_FUNCTION_NAME_LEN_MAX];
146 char cc[TCP_CA_NAME_MAX];
151 static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks);
153 socket_compare(const struct sock *a, const struct sock *b)
155 return ((int64_t)(a->socket/2 - b->socket/2));
157 RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare);
159 static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs);
161 pcb_compare(const struct sock *a, const struct sock *b)
163 return ((int64_t)(a->pcb/2 - b->pcb/2));
165 RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare);
167 static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks);
170 RB_ENTRY(file) file_tree;
177 static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree);
179 file_compare(const struct file *a, const struct file *b)
181 return ((int64_t)(a->xf_data/2 - b->xf_data/2));
183 RB_GENERATE_STATIC(files_t, file, file_tree, file_compare);
185 static struct file *files;
188 static cap_channel_t *capnet;
189 static cap_channel_t *capnetdb;
190 static cap_channel_t *capsysctl;
191 static cap_channel_t *cappwd;
194 xprintf(const char *fmt, ...)
200 len = vprintf(fmt, ap);
208 _check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
210 if (received_size != expected_size) {
211 warnx("%s size mismatch: expected %zd, received %zd",
212 struct_name, expected_size, received_size);
217 #define check_ksize(_sz, _struct) (_check_ksize(_sz, sizeof(_struct), #_struct))
220 _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
222 if (received_size != expected_size) {
223 errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
224 struct_name, expected_size, received_size);
227 #define enforce_ksize(_sz, _struct) (_enforce_ksize(_sz, sizeof(_struct), #_struct))
230 get_proto_type(const char *proto)
232 struct protoent *pent;
234 if (strlen(proto) == 0)
236 if (capnetdb != NULL)
237 pent = cap_getprotobyname(capnetdb, proto);
239 pent = getprotobyname(proto);
241 warn("cap_getprotobyname");
244 return (pent->p_proto);
255 /* Find the maximum number of possible protocols. */
256 while (getprotoent() != NULL)
261 if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
263 numprotos = proto_count;
267 parse_protos(char *protospec)
270 int proto_type, proto_index;
272 if (protospec == NULL)
277 while ((prot = strsep(&protospec, ",")) != NULL) {
278 if (strlen(prot) == 0)
280 proto_type = get_proto_type(prot);
281 if (proto_type != -1)
282 protos[proto_index++] = proto_type;
284 numprotos = proto_index;
285 return (proto_index);
289 parse_ports(const char *portspec)
295 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
300 errx(1, "syntax error in port range");
301 for (q = p; *q != '\0' && isdigit(*q); ++q)
303 for (port = 0; p < q; ++p)
304 port = port * 10 + digittoint(*p);
305 if (port < 0 || port > 65535)
306 errx(1, "invalid port number");
319 for (q = p; *q != '\0' && isdigit(*q); ++q)
321 for (end = 0; p < q; ++p)
322 end = end * 10 + digittoint(*p);
323 if (end < port || end > 65535)
324 errx(1, "invalid port number");
333 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
335 struct sockaddr_in *sin4;
336 struct sockaddr_in6 *sin6;
338 bzero(ss, sizeof(*ss));
342 sin4->sin_len = sizeof(*sin4);
343 sin4->sin_family = af;
344 sin4->sin_port = port;
345 sin4->sin_addr = *(struct in_addr *)addr;
349 sin6->sin6_len = sizeof(*sin6);
350 sin6->sin6_family = af;
351 sin6->sin6_port = port;
352 sin6->sin6_addr = *(struct in6_addr *)addr;
353 #define s6_addr16 __u6_addr.__u6_addr16
354 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
355 sin6->sin6_scope_id =
356 ntohs(sin6->sin6_addr.s6_addr16[1]);
357 sin6->sin6_addr.s6_addr16[1] = 0;
366 free_socket(struct sock *sock)
368 struct addr *cur, *next;
371 while (cur != NULL) {
377 while (cur != NULL) {
389 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
390 struct xsctp_inpcb *xinpcb;
391 struct xsctp_tcb *xstcb;
392 struct xsctp_raddr *xraddr;
393 struct xsctp_laddr *xladdr;
398 int no_stcb, local_all_loopback, foreign_all_loopback;
406 varname = "net.inet.sctp.assoclist";
407 if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
409 err(1, "cap_sysctlbyname()");
412 if ((buf = (char *)malloc(len)) == NULL) {
416 if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
417 err(1, "cap_sysctlbyname()");
421 xinpcb = (struct xsctp_inpcb *)(void *)buf;
422 offset = sizeof(struct xsctp_inpcb);
423 while ((offset < len) && (xinpcb->last == 0)) {
424 if ((sock = calloc(1, sizeof *sock)) == NULL)
426 sock->socket = xinpcb->socket;
427 sock->proto = IPPROTO_SCTP;
428 sock->protoname = "sctp";
429 if (xinpcb->maxqlen == 0)
430 sock->state = SCTP_CLOSED;
432 sock->state = SCTP_LISTEN;
433 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
434 sock->family = AF_INET6;
436 * Currently there is no way to distinguish between
437 * IPv6 only sockets or dual family sockets.
438 * So mark it as dual socket.
440 sock->vflag = INP_IPV6 | INP_IPV4;
442 sock->family = AF_INET;
443 sock->vflag = INP_IPV4;
446 local_all_loopback = 1;
447 while (offset < len) {
448 xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
449 offset += sizeof(struct xsctp_laddr);
450 if (xladdr->last == 1)
452 if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
454 switch (xladdr->address.sa.sa_family) {
456 #define __IN_IS_ADDR_LOOPBACK(pina) \
457 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
458 if (!__IN_IS_ADDR_LOOPBACK(
459 &xladdr->address.sin.sin_addr))
460 local_all_loopback = 0;
461 #undef __IN_IS_ADDR_LOOPBACK
462 sockaddr(&laddr->address, AF_INET,
463 &xladdr->address.sin.sin_addr,
464 htons(xinpcb->local_port));
467 if (!IN6_IS_ADDR_LOOPBACK(
468 &xladdr->address.sin6.sin6_addr))
469 local_all_loopback = 0;
470 sockaddr(&laddr->address, AF_INET6,
471 &xladdr->address.sin6.sin6_addr,
472 htons(xinpcb->local_port));
475 errx(1, "address family %d not supported",
476 xladdr->address.sa.sa_family);
479 if (prev_laddr == NULL)
482 prev_laddr->next = laddr;
485 if (sock->laddr == NULL) {
487 calloc(1, sizeof(struct addr))) == NULL)
489 sock->laddr->address.ss_family = sock->family;
490 if (sock->family == AF_INET)
491 sock->laddr->address.ss_len =
492 sizeof(struct sockaddr_in);
494 sock->laddr->address.ss_len =
495 sizeof(struct sockaddr_in6);
496 local_all_loopback = 0;
498 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
500 sock->faddr->address.ss_family = sock->family;
501 if (sock->family == AF_INET)
502 sock->faddr->address.ss_len =
503 sizeof(struct sockaddr_in);
505 sock->faddr->address.ss_len =
506 sizeof(struct sockaddr_in6);
508 while (offset < len) {
509 xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
510 offset += sizeof(struct xsctp_tcb);
512 if (opt_l && (sock->vflag & vflag) &&
513 (!opt_L || !local_all_loopback) &&
514 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
515 (xstcb->last == 1))) {
516 RB_INSERT(socks_t, &socks, sock);
521 if (xstcb->last == 1)
525 if ((sock = calloc(1, sizeof *sock)) == NULL)
527 sock->socket = xinpcb->socket;
528 sock->proto = IPPROTO_SCTP;
529 sock->protoname = "sctp";
530 sock->state = (int)xstcb->state;
531 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
532 sock->family = AF_INET6;
534 * Currently there is no way to distinguish
535 * between IPv6 only sockets or dual family
536 * sockets. So mark it as dual socket.
538 sock->vflag = INP_IPV6 | INP_IPV4;
540 sock->family = AF_INET;
541 sock->vflag = INP_IPV4;
545 local_all_loopback = 1;
546 while (offset < len) {
547 xladdr = (struct xsctp_laddr *)(void *)(buf +
549 offset += sizeof(struct xsctp_laddr);
550 if (xladdr->last == 1)
554 laddr = calloc(1, sizeof(struct addr));
557 switch (xladdr->address.sa.sa_family) {
559 #define __IN_IS_ADDR_LOOPBACK(pina) \
560 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
561 if (!__IN_IS_ADDR_LOOPBACK(
562 &xladdr->address.sin.sin_addr))
563 local_all_loopback = 0;
564 #undef __IN_IS_ADDR_LOOPBACK
565 sockaddr(&laddr->address, AF_INET,
566 &xladdr->address.sin.sin_addr,
567 htons(xstcb->local_port));
570 if (!IN6_IS_ADDR_LOOPBACK(
571 &xladdr->address.sin6.sin6_addr))
572 local_all_loopback = 0;
573 sockaddr(&laddr->address, AF_INET6,
574 &xladdr->address.sin6.sin6_addr,
575 htons(xstcb->local_port));
579 "address family %d not supported",
580 xladdr->address.sa.sa_family);
583 if (prev_laddr == NULL)
586 prev_laddr->next = laddr;
590 foreign_all_loopback = 1;
591 while (offset < len) {
592 xraddr = (struct xsctp_raddr *)(void *)(buf +
594 offset += sizeof(struct xsctp_raddr);
595 if (xraddr->last == 1)
599 faddr = calloc(1, sizeof(struct addr));
602 switch (xraddr->address.sa.sa_family) {
604 #define __IN_IS_ADDR_LOOPBACK(pina) \
605 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
606 if (!__IN_IS_ADDR_LOOPBACK(
607 &xraddr->address.sin.sin_addr))
608 foreign_all_loopback = 0;
609 #undef __IN_IS_ADDR_LOOPBACK
610 sockaddr(&faddr->address, AF_INET,
611 &xraddr->address.sin.sin_addr,
612 htons(xstcb->remote_port));
615 if (!IN6_IS_ADDR_LOOPBACK(
616 &xraddr->address.sin6.sin6_addr))
617 foreign_all_loopback = 0;
618 sockaddr(&faddr->address, AF_INET6,
619 &xraddr->address.sin6.sin6_addr,
620 htons(xstcb->remote_port));
624 "address family %d not supported",
625 xraddr->address.sa.sa_family);
627 faddr->encaps_port = xraddr->encaps_port;
628 faddr->state = xraddr->state;
630 if (prev_faddr == NULL)
633 prev_faddr->next = faddr;
637 if ((sock->vflag & vflag) &&
639 !(local_all_loopback ||
640 foreign_all_loopback))) {
641 RB_INSERT(socks_t, &socks, sock);
647 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
648 offset += sizeof(struct xsctp_inpcb);
654 gather_inet(int proto)
656 struct xinpgen *xig, *exig;
658 struct xtcpcb *xtp = NULL;
661 struct addr *laddr, *faddr;
662 const char *varname, *protoname;
675 varname = "net.inet.tcp.pcblist";
679 varname = "net.inet.udp.pcblist";
683 varname = "net.inet.divert.pcblist";
687 errx(1, "protocol %d not supported", proto);
695 if ((buf = realloc(buf, bufsize)) == NULL)
698 if (cap_sysctlbyname(capsysctl, varname, buf, &len,
703 if (errno != ENOMEM || len != bufsize)
704 err(1, "cap_sysctlbyname()");
707 xig = (struct xinpgen *)buf;
708 exig = (struct xinpgen *)(void *)
709 ((char *)buf + len - sizeof *exig);
710 enforce_ksize(xig->xig_len, struct xinpgen);
711 enforce_ksize(exig->xig_len, struct xinpgen);
712 } while (xig->xig_gen != exig->xig_gen && retry--);
714 if (xig->xig_gen != exig->xig_gen && opt_v)
715 warnx("warning: data may be inconsistent");
718 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
723 xtp = (struct xtcpcb *)xig;
725 if (!check_ksize(xtp->xt_len, struct xtcpcb))
727 protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
731 xip = (struct xinpcb *)xig;
732 if (!check_ksize(xip->xi_len, struct xinpcb))
736 errx(1, "protocol %d not supported", proto);
738 so = &xip->xi_socket;
739 if ((xip->inp_vflag & vflag) == 0)
741 if (xip->inp_vflag & INP_IPV4) {
742 if ((xip->inp_fport == 0 && !opt_l) ||
743 (xip->inp_fport != 0 && !opt_c))
745 #define __IN_IS_ADDR_LOOPBACK(pina) \
746 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
748 (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
749 __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
751 #undef __IN_IS_ADDR_LOOPBACK
752 } else if (xip->inp_vflag & INP_IPV6) {
753 if ((xip->inp_fport == 0 && !opt_l) ||
754 (xip->inp_fport != 0 && !opt_c))
757 (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
758 IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
762 warnx("invalid vflag 0x%x", xip->inp_vflag);
765 if ((sock = calloc(1, sizeof(*sock))) == NULL)
767 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
769 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
771 sock->socket = so->xso_so;
773 sock->inp_gencnt = xip->inp_gencnt;
774 if (xip->inp_vflag & INP_IPV4) {
775 sock->family = AF_INET;
776 sockaddr(&laddr->address, sock->family,
777 &xip->inp_laddr, xip->inp_lport);
778 sockaddr(&faddr->address, sock->family,
779 &xip->inp_faddr, xip->inp_fport);
780 } else if (xip->inp_vflag & INP_IPV6) {
781 sock->family = AF_INET6;
782 sockaddr(&laddr->address, sock->family,
783 &xip->in6p_laddr, xip->inp_lport);
784 sockaddr(&faddr->address, sock->family,
785 &xip->in6p_faddr, xip->inp_fport);
787 if (proto == IPPROTO_TCP)
788 faddr->encaps_port = xtp->xt_encaps_port;
793 sock->vflag = xip->inp_vflag;
794 if (proto == IPPROTO_TCP) {
795 sock->state = xtp->t_state;
796 memcpy(sock->stack, xtp->xt_stack,
797 TCP_FUNCTION_NAME_LEN_MAX);
798 memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX);
800 sock->protoname = protoname;
801 if (sock->socket != 0)
802 RB_INSERT(socks_t, &socks, sock);
804 SLIST_INSERT_HEAD(&nosocks, sock, socket_list);
811 gather_unix(int proto)
813 struct xunpgen *xug, *exug;
816 struct addr *laddr, *faddr;
817 const char *varname, *protoname;
824 varname = "net.local.stream.pcblist";
825 protoname = "stream";
828 varname = "net.local.dgram.pcblist";
832 varname = "net.local.seqpacket.pcblist";
833 protoname = "seqpac";
843 if ((buf = realloc(buf, bufsize)) == NULL)
846 if (cap_sysctlbyname(capsysctl, varname, buf, &len,
849 if (errno != ENOMEM || len != bufsize)
850 err(1, "cap_sysctlbyname()");
853 xug = (struct xunpgen *)buf;
854 exug = (struct xunpgen *)(void *)
855 ((char *)buf + len - sizeof(*exug));
856 if (!check_ksize(xug->xug_len, struct xunpgen) ||
857 !check_ksize(exug->xug_len, struct xunpgen))
859 } while (xug->xug_gen != exug->xug_gen && retry--);
861 if (xug->xug_gen != exug->xug_gen && opt_v)
862 warnx("warning: data may be inconsistent");
865 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
868 xup = (struct xunpcb *)xug;
869 if (!check_ksize(xup->xu_len, struct xunpcb))
871 if ((xup->unp_conn == 0 && !opt_l) ||
872 (xup->unp_conn != 0 && !opt_c))
874 if ((sock = calloc(1, sizeof(*sock))) == NULL)
876 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
878 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
880 sock->socket = xup->xu_socket.xso_so;
881 sock->pcb = xup->xu_unpp;
883 sock->family = AF_UNIX;
884 sock->protoname = protoname;
885 if (xup->xu_addr.sun_family == AF_UNIX)
887 *(struct sockaddr_storage *)(void *)&xup->xu_addr;
888 faddr->conn = xup->unp_conn;
889 faddr->firstref = xup->xu_firstref;
890 faddr->nextref = xup->xu_nextref;
895 RB_INSERT(socks_t, &socks, sock);
896 RB_INSERT(pcbs_t, &pcbs, sock);
905 struct xfile *xfiles;
908 olen = len = sizeof(*xfiles);
909 if ((xfiles = malloc(len)) == NULL)
911 while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0)
913 if (errno != ENOMEM || len != olen)
914 err(1, "cap_sysctlbyname()");
916 if ((xfiles = realloc(xfiles, len)) == NULL)
920 enforce_ksize(xfiles->xf_size, struct xfile);
921 nfiles = len / sizeof(*xfiles);
923 if ((files = malloc(nfiles * sizeof(struct file))) == NULL)
926 for (int i = 0; i < nfiles; i++) {
927 files[i].xf_data = xfiles[i].xf_data;
928 files[i].xf_pid = xfiles[i].xf_pid;
929 files[i].xf_uid = xfiles[i].xf_uid;
930 files[i].xf_fd = xfiles[i].xf_fd;
931 RB_INSERT(files_t, &ftree, &files[i]);
938 printaddr(struct sockaddr_storage *ss)
940 struct sockaddr_un *sun;
941 char addrstr[NI_MAXHOST] = { '\0', '\0' };
942 int error, off, port = 0;
944 switch (ss->ss_family) {
946 if (sstosin(ss)->sin_addr.s_addr == INADDR_ANY)
948 port = ntohs(sstosin(ss)->sin_port);
951 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
953 port = ntohs(sstosin6(ss)->sin6_port);
957 off = (int)((char *)&sun->sun_path - (char *)sun);
958 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
960 if (addrstr[0] == '\0') {
961 error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
962 addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
964 errx(1, "cap_getnameinfo()");
967 return xprintf("%s:*", addrstr);
969 return xprintf("%s:%d", addrstr, port);
973 getprocname(pid_t pid)
975 static struct kinfo_proc proc;
981 mib[2] = KERN_PROC_PID;
984 if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
986 /* Do not warn if the process exits before we get its name. */
988 warn("cap_sysctl()");
991 return (proc.ki_comm);
995 getprocjid(pid_t pid)
997 static struct kinfo_proc proc;
1003 mib[2] = KERN_PROC_PID;
1006 if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
1008 /* Do not warn if the process exits before we get its jid. */
1010 warn("cap_sysctl()");
1013 return (proc.ki_jid);
1017 check_ports(struct sock *s)
1024 if ((s->family != AF_INET) && (s->family != AF_INET6))
1026 for (addr = s->laddr; addr != NULL; addr = addr->next) {
1027 if (s->family == AF_INET)
1028 port = ntohs(sstosin(&addr->address)->sin_port);
1030 port = ntohs(sstosin6(&addr->address)->sin6_port);
1034 for (addr = s->faddr; addr != NULL; addr = addr->next) {
1035 if (s->family == AF_INET)
1036 port = ntohs(sstosin(&addr->address)->sin_port);
1038 port = ntohs(sstosin6(&addr->address)->sin6_port);
1046 sctp_conn_state(int state)
1058 case SCTP_COOKIE_WAIT:
1059 return "COOKIE_WAIT";
1061 case SCTP_COOKIE_ECHOED:
1062 return "COOKIE_ECHOED";
1064 case SCTP_ESTABLISHED:
1065 return "ESTABLISHED";
1067 case SCTP_SHUTDOWN_SENT:
1068 return "SHUTDOWN_SENT";
1070 case SCTP_SHUTDOWN_RECEIVED:
1071 return "SHUTDOWN_RECEIVED";
1073 case SCTP_SHUTDOWN_ACK_SENT:
1074 return "SHUTDOWN_ACK_SENT";
1076 case SCTP_SHUTDOWN_PENDING:
1077 return "SHUTDOWN_PENDING";
1086 sctp_path_state(int state)
1089 case SCTP_UNCONFIRMED:
1090 return "UNCONFIRMED";
1105 displaysock(struct sock *s, int pos)
1108 struct addr *laddr, *faddr;
1111 pos += xprintf(" ");
1112 pos += xprintf("%s", s->protoname);
1113 if (s->vflag & INP_IPV4)
1114 pos += xprintf("4");
1115 if (s->vflag & INP_IPV6)
1116 pos += xprintf("6");
1117 if (s->vflag & (INP_IPV4 | INP_IPV6))
1118 pos += xprintf(" ");
1122 while (laddr != NULL || faddr != NULL) {
1124 while (pos < offset)
1125 pos += xprintf(" ");
1126 switch (s->family) {
1129 if (laddr != NULL) {
1130 pos += printaddr(&laddr->address);
1131 if (s->family == AF_INET6 && pos >= 58)
1132 pos += xprintf(" ");
1134 offset += opt_w ? 46 : 22;
1135 while (pos < offset)
1136 pos += xprintf(" ");
1138 pos += printaddr(&faddr->address);
1139 offset += opt_w ? 46 : 22;
1142 if ((laddr == NULL) || (faddr == NULL))
1143 errx(1, "laddr = %p or faddr = %p is NULL",
1144 (void *)laddr, (void *)faddr);
1145 if (laddr->address.ss_len == 0 && faddr->conn == 0) {
1146 pos += xprintf("(not connected)");
1147 offset += opt_w ? 92 : 44;
1150 /* Local bind(2) address, if any. */
1151 if (laddr->address.ss_len > 0)
1152 pos += printaddr(&laddr->address);
1153 /* Remote peer we connect(2) to, if any. */
1154 if (faddr->conn != 0) {
1157 pos += xprintf("%s-> ",
1158 laddr->address.ss_len > 0 ? " " : "");
1159 p = RB_FIND(pcbs_t, &pcbs,
1160 &(struct sock){ .pcb = faddr->conn });
1161 if (__predict_false(p == NULL)) {
1162 /* XXGL: can this happen at all? */
1163 pos += xprintf("??");
1164 } else if (p->laddr->address.ss_len == 0) {
1167 f = RB_FIND(files_t, &ftree,
1168 &(struct file){ .xf_data =
1170 pos += xprintf("[%lu %d]",
1171 (u_long)f->xf_pid, f->xf_fd);
1173 pos += printaddr(&p->laddr->address);
1175 /* Remote peer(s) connect(2)ed to us, if any. */
1176 if (faddr->firstref != 0) {
1179 kvaddr_t ref = faddr->firstref;
1182 pos += xprintf(" <- ");
1184 while ((p = RB_FIND(pcbs_t, &pcbs,
1185 &(struct sock){ .pcb = ref })) != 0) {
1186 f = RB_FIND(files_t, &ftree,
1187 &(struct file){ .xf_data =
1189 pos += xprintf("%s[%lu %d]",
1191 (u_long)f->xf_pid, f->xf_fd);
1192 ref = p->faddr->nextref;
1196 offset += opt_w ? 92 : 44;
1202 if (s->proto == IPPROTO_TCP ||
1203 s->proto == IPPROTO_UDP) {
1204 while (pos < offset)
1205 pos += xprintf(" ");
1206 pos += xprintf("%" PRIu64, s->inp_gencnt);
1211 if (faddr != NULL &&
1212 ((s->proto == IPPROTO_SCTP &&
1213 s->state != SCTP_CLOSED &&
1214 s->state != SCTP_BOUND &&
1215 s->state != SCTP_LISTEN) ||
1216 (s->proto == IPPROTO_TCP &&
1217 s->state != TCPS_CLOSED &&
1218 s->state != TCPS_LISTEN))) {
1219 while (pos < offset)
1220 pos += xprintf(" ");
1221 pos += xprintf("%u",
1222 ntohs(faddr->encaps_port));
1227 if (faddr != NULL &&
1228 s->proto == IPPROTO_SCTP &&
1229 s->state != SCTP_CLOSED &&
1230 s->state != SCTP_BOUND &&
1231 s->state != SCTP_LISTEN) {
1232 while (pos < offset)
1233 pos += xprintf(" ");
1234 pos += xprintf("%s",
1235 sctp_path_state(faddr->state));
1241 if (s->proto == IPPROTO_SCTP ||
1242 s->proto == IPPROTO_TCP) {
1243 while (pos < offset)
1244 pos += xprintf(" ");
1247 pos += xprintf("%s",
1248 sctp_conn_state(s->state));
1251 if (s->state >= 0 &&
1252 s->state < TCP_NSTATES)
1253 pos += xprintf("%s",
1254 tcpstates[s->state]);
1256 pos += xprintf("?");
1263 if (s->proto == IPPROTO_TCP) {
1264 while (pos < offset)
1265 pos += xprintf(" ");
1266 pos += xprintf("%.*s",
1267 TCP_FUNCTION_NAME_LEN_MAX,
1270 offset += TCP_FUNCTION_NAME_LEN_MAX + 1;
1273 if (s->proto == IPPROTO_TCP) {
1274 while (pos < offset)
1275 pos += xprintf(" ");
1276 xprintf("%.*s", TCP_CA_NAME_MAX, s->cc);
1278 offset += TCP_CA_NAME_MAX + 1;
1282 laddr = laddr->next;
1284 faddr = faddr->next;
1285 if ((laddr != NULL) || (faddr != NULL)) {
1303 printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s",
1304 "USER", "COMMAND", "PID", "FD", "PROTO",
1305 opt_w ? 45 : 21, "LOCAL ADDRESS",
1306 opt_w ? 45 : 21, "FOREIGN ADDRESS");
1308 printf(" %-8s", "ID");
1310 printf(" %-6s", "ENCAPS");
1312 printf(" %-12s", "PATH STATE");
1313 printf(" %-12s", "CONN STATE");
1316 printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX,
1317 TCP_FUNCTION_NAME_LEN_MAX, "STACK");
1319 printf(" %-.*s", TCP_CA_NAME_MAX, "CC");
1322 cap_setpassent(cappwd, 1);
1323 for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
1324 if (xf->xf_data == 0)
1326 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1328 s = RB_FIND(socks_t, &socks,
1329 &(struct sock){ .socket = xf->xf_data});
1330 if (s != NULL && check_ports(s)) {
1334 (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
1335 pos += xprintf("%lu ", (u_long)xf->xf_uid);
1337 pos += xprintf("%s ", pwd->pw_name);
1339 pos += xprintf(" ");
1340 pos += xprintf("%.10s", getprocname(xf->xf_pid));
1342 pos += xprintf(" ");
1343 pos += xprintf("%5lu ", (u_long)xf->xf_pid);
1345 pos += xprintf(" ");
1346 pos += xprintf("%-3d ", xf->xf_fd);
1347 displaysock(s, pos);
1352 SLIST_FOREACH(s, &nosocks, socket_list) {
1353 if (!check_ports(s))
1355 pos = xprintf("%-8s %-10s %-5s %-2s ",
1356 "?", "?", "?", "?");
1357 displaysock(s, pos);
1359 RB_FOREACH(s, socks_t, &socks) {
1362 if (!check_ports(s))
1364 pos = xprintf("%-8s %-10s %-5s %-2s ",
1365 "?", "?", "?", "?");
1366 displaysock(s, pos);
1371 set_default_protos(void)
1373 struct protoent *prot;
1377 init_protos(default_numprotos);
1379 for (pindex = 0; pindex < default_numprotos; pindex++) {
1380 pname = default_protos[pindex];
1381 prot = cap_getprotobyname(capnetdb, pname);
1383 err(1, "cap_getprotobyname: %s", pname);
1384 protos[pindex] = prot->p_proto;
1391 * Return the vnet property of the jail, or -1 on error.
1394 jail_getvnet(int jid)
1396 struct iovec jiov[6];
1398 size_t len = sizeof(vnet);
1400 if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0)
1404 jiov[0].iov_base = __DECONST(char *, "jid");
1405 jiov[0].iov_len = sizeof("jid");
1406 jiov[1].iov_base = &jid;
1407 jiov[1].iov_len = sizeof(jid);
1408 jiov[2].iov_base = __DECONST(char *, "vnet");
1409 jiov[2].iov_len = sizeof("vnet");
1410 jiov[3].iov_base = &vnet;
1411 jiov[3].iov_len = sizeof(vnet);
1412 jiov[4].iov_base = __DECONST(char *, "errmsg");
1413 jiov[4].iov_len = sizeof("errmsg");
1414 jiov[5].iov_base = jail_errmsg;
1415 jiov[5].iov_len = JAIL_ERRMSGLEN;
1416 jail_errmsg[0] = '\0';
1417 if (jail_get(jiov, nitems(jiov), 0) < 0) {
1418 if (!jail_errmsg[0])
1419 snprintf(jail_errmsg, JAIL_ERRMSGLEN,
1420 "jail_get: %s", strerror(errno));
1430 "usage: sockstat [-46CciLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]\n");
1435 main(int argc, char *argv[])
1437 cap_channel_t *capcas;
1438 cap_net_limit_t *limit;
1439 const char *pwdcmds[] = { "setpassent", "getpwuid" };
1440 const char *pwdfields[] = { "pw_name" };
1441 int protos_defined = -1;
1445 while ((o = getopt(argc, argv, "46Ccij:Llnp:P:qSsUuvw")) != -1)
1463 opt_j = jail_getid(optarg);
1465 errx(1, "jail_getid: %s", jail_errmsg);
1477 parse_ports(optarg);
1480 protos_defined = parse_protos(optarg);
1514 switch (jail_getvnet(opt_j)) {
1516 errx(2, "jail_getvnet: %s", jail_errmsg);
1518 if (jail_attach(opt_j) < 0)
1519 err(3, "jail_attach()");
1520 /* Set back to -1 for normal output in vnet jail. */
1528 capcas = cap_init();
1530 err(1, "Unable to contact Casper");
1531 if (caph_enter_casper() < 0)
1532 err(1, "Unable to enter capability mode");
1533 capnet = cap_service_open(capcas, "system.net");
1535 err(1, "Unable to open system.net service");
1536 capnetdb = cap_service_open(capcas, "system.netdb");
1537 if (capnetdb == NULL)
1538 err(1, "Unable to open system.netdb service");
1539 capsysctl = cap_service_open(capcas, "system.sysctl");
1540 if (capsysctl == NULL)
1541 err(1, "Unable to open system.sysctl service");
1542 cappwd = cap_service_open(capcas, "system.pwd");
1544 err(1, "Unable to open system.pwd service");
1546 limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
1548 err(1, "Unable to init cap_net limits");
1549 if (cap_net_limit(limit) < 0)
1550 err(1, "Unable to apply limits");
1551 if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
1552 err(1, "Unable to apply pwd commands limits");
1553 if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
1554 err(1, "Unable to apply pwd commands limits");
1556 if ((!opt_4 && !opt_6) && protos_defined != -1)
1558 if (!opt_4 && !opt_6 && !opt_u)
1559 opt_4 = opt_6 = opt_u = 1;
1560 if ((opt_4 || opt_6) && protos_defined == -1)
1561 protos_defined = set_default_protos();
1562 if (!opt_c && !opt_l)
1565 if (opt_4 || opt_6) {
1566 for (i = 0; i < protos_defined; i++)
1567 if (protos[i] == IPPROTO_SCTP)
1570 gather_inet(protos[i]);
1573 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1574 gather_unix(SOCK_STREAM);
1575 gather_unix(SOCK_DGRAM);
1576 gather_unix(SOCK_SEQPACKET);