2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2002 Dag-Erling 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 #include <sys/param.h>
34 #include <sys/socket.h>
35 #include <sys/socketvar.h>
36 #include <sys/sysctl.h>
39 #include <sys/queue.h>
43 #include <sys/unpcb.h>
45 #include <net/route.h>
47 #include <netinet/in.h>
48 #include <netinet/in_pcb.h>
49 #include <netinet/sctp.h>
50 #include <netinet/tcp.h>
51 #define TCPSTATES /* load state names */
52 #include <netinet/tcp_fsm.h>
53 #include <netinet/tcp_seq.h>
54 #include <netinet/tcp_var.h>
55 #include <arpa/inet.h>
57 #include <capsicum_helpers.h>
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>
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))
82 static int opt_4; /* Show IPv4 sockets */
83 static int opt_6; /* Show IPv6 sockets */
84 static int opt_C; /* Show congestion control */
85 static int opt_c; /* Show connected sockets */
86 static int opt_i; /* Show inp_gencnt */
87 static int opt_j; /* Show specified jail */
88 static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */
89 static int opt_l; /* Show listening sockets */
90 static int opt_n; /* Don't resolve UIDs to user names */
91 static int opt_q; /* Don't show header */
92 static int opt_S; /* Show protocol stack if applicable */
93 static int opt_s; /* Show protocol state if applicable */
94 static int opt_U; /* Show remote UDP encapsulation port number */
95 static int opt_u; /* Show Unix domain sockets */
96 static int opt_v; /* Verbose mode */
97 static int opt_w; /* Wide print area for addresses */
100 * Default protocols to use if no -P was defined.
102 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
103 static size_t default_numprotos = nitems(default_protos);
105 static int *protos; /* protocols to use */
106 static size_t numprotos; /* allocated size of protos[] */
110 #define INT_BIT (sizeof(int)*CHAR_BIT)
111 #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
112 #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
116 struct sockaddr_storage address;
117 struct { /* unix(4) faddr */
123 unsigned int encaps_port;
130 RB_ENTRY(sock) socket_tree; /* tree of pcbs with socket */
131 SLIST_ENTRY(sock) socket_list; /* list of pcbs w/o socket */
133 RB_ENTRY(sock) pcb_tree;
142 const char *protoname;
143 char stack[TCP_FUNCTION_NAME_LEN_MAX];
144 char cc[TCP_CA_NAME_MAX];
149 static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks);
151 socket_compare(const struct sock *a, const struct sock *b)
153 return ((int64_t)(a->socket/2 - b->socket/2));
155 RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare);
157 static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs);
159 pcb_compare(const struct sock *a, const struct sock *b)
161 return ((int64_t)(a->pcb/2 - b->pcb/2));
163 RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare);
165 static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks);
168 RB_ENTRY(file) file_tree;
175 static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree);
177 file_compare(const struct file *a, const struct file *b)
179 return ((int64_t)(a->xf_data/2 - b->xf_data/2));
181 RB_GENERATE_STATIC(files_t, file, file_tree, file_compare);
183 static struct file *files;
186 static cap_channel_t *capnet;
187 static cap_channel_t *capnetdb;
188 static cap_channel_t *capsysctl;
189 static cap_channel_t *cappwd;
192 xprintf(const char *fmt, ...)
198 len = vprintf(fmt, ap);
206 _check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
208 if (received_size != expected_size) {
209 warnx("%s size mismatch: expected %zd, received %zd",
210 struct_name, expected_size, received_size);
215 #define check_ksize(_sz, _struct) (_check_ksize(_sz, sizeof(_struct), #_struct))
218 _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
220 if (received_size != expected_size) {
221 errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
222 struct_name, expected_size, received_size);
225 #define enforce_ksize(_sz, _struct) (_enforce_ksize(_sz, sizeof(_struct), #_struct))
228 get_proto_type(const char *proto)
230 struct protoent *pent;
232 if (strlen(proto) == 0)
234 if (capnetdb != NULL)
235 pent = cap_getprotobyname(capnetdb, proto);
237 pent = getprotobyname(proto);
239 warn("cap_getprotobyname");
242 return (pent->p_proto);
253 /* Find the maximum number of possible protocols. */
254 while (getprotoent() != NULL)
259 if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
261 numprotos = proto_count;
265 parse_protos(char *protospec)
268 int proto_type, proto_index;
270 if (protospec == NULL)
275 while ((prot = strsep(&protospec, ",")) != NULL) {
276 if (strlen(prot) == 0)
278 proto_type = get_proto_type(prot);
279 if (proto_type != -1)
280 protos[proto_index++] = proto_type;
282 numprotos = proto_index;
283 return (proto_index);
287 parse_ports(const char *portspec)
293 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
298 errx(1, "syntax error in port range");
299 for (q = p; *q != '\0' && isdigit(*q); ++q)
301 for (port = 0; p < q; ++p)
302 port = port * 10 + digittoint(*p);
303 if (port < 0 || port > 65535)
304 errx(1, "invalid port number");
317 for (q = p; *q != '\0' && isdigit(*q); ++q)
319 for (end = 0; p < q; ++p)
320 end = end * 10 + digittoint(*p);
321 if (end < port || end > 65535)
322 errx(1, "invalid port number");
331 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
333 struct sockaddr_in *sin4;
334 struct sockaddr_in6 *sin6;
336 bzero(ss, sizeof(*ss));
340 sin4->sin_len = sizeof(*sin4);
341 sin4->sin_family = af;
342 sin4->sin_port = port;
343 sin4->sin_addr = *(struct in_addr *)addr;
347 sin6->sin6_len = sizeof(*sin6);
348 sin6->sin6_family = af;
349 sin6->sin6_port = port;
350 sin6->sin6_addr = *(struct in6_addr *)addr;
351 #define s6_addr16 __u6_addr.__u6_addr16
352 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
353 sin6->sin6_scope_id =
354 ntohs(sin6->sin6_addr.s6_addr16[1]);
355 sin6->sin6_addr.s6_addr16[1] = 0;
364 free_socket(struct sock *sock)
366 struct addr *cur, *next;
369 while (cur != NULL) {
375 while (cur != NULL) {
387 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
388 struct xsctp_inpcb *xinpcb;
389 struct xsctp_tcb *xstcb;
390 struct xsctp_raddr *xraddr;
391 struct xsctp_laddr *xladdr;
396 int no_stcb, local_all_loopback, foreign_all_loopback;
404 varname = "net.inet.sctp.assoclist";
405 if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
407 err(1, "cap_sysctlbyname()");
410 if ((buf = (char *)malloc(len)) == NULL) {
414 if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
415 err(1, "cap_sysctlbyname()");
419 xinpcb = (struct xsctp_inpcb *)(void *)buf;
420 offset = sizeof(struct xsctp_inpcb);
421 while ((offset < len) && (xinpcb->last == 0)) {
422 if ((sock = calloc(1, sizeof *sock)) == NULL)
424 sock->socket = xinpcb->socket;
425 sock->proto = IPPROTO_SCTP;
426 sock->protoname = "sctp";
427 if (xinpcb->maxqlen == 0)
428 sock->state = SCTP_CLOSED;
430 sock->state = SCTP_LISTEN;
431 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
432 sock->family = AF_INET6;
434 * Currently there is no way to distinguish between
435 * IPv6 only sockets or dual family sockets.
436 * So mark it as dual socket.
438 sock->vflag = INP_IPV6 | INP_IPV4;
440 sock->family = AF_INET;
441 sock->vflag = INP_IPV4;
444 local_all_loopback = 1;
445 while (offset < len) {
446 xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
447 offset += sizeof(struct xsctp_laddr);
448 if (xladdr->last == 1)
450 if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
452 switch (xladdr->address.sa.sa_family) {
454 #define __IN_IS_ADDR_LOOPBACK(pina) \
455 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
456 if (!__IN_IS_ADDR_LOOPBACK(
457 &xladdr->address.sin.sin_addr))
458 local_all_loopback = 0;
459 #undef __IN_IS_ADDR_LOOPBACK
460 sockaddr(&laddr->address, AF_INET,
461 &xladdr->address.sin.sin_addr,
462 htons(xinpcb->local_port));
465 if (!IN6_IS_ADDR_LOOPBACK(
466 &xladdr->address.sin6.sin6_addr))
467 local_all_loopback = 0;
468 sockaddr(&laddr->address, AF_INET6,
469 &xladdr->address.sin6.sin6_addr,
470 htons(xinpcb->local_port));
473 errx(1, "address family %d not supported",
474 xladdr->address.sa.sa_family);
477 if (prev_laddr == NULL)
480 prev_laddr->next = laddr;
483 if (sock->laddr == NULL) {
485 calloc(1, sizeof(struct addr))) == NULL)
487 sock->laddr->address.ss_family = sock->family;
488 if (sock->family == AF_INET)
489 sock->laddr->address.ss_len =
490 sizeof(struct sockaddr_in);
492 sock->laddr->address.ss_len =
493 sizeof(struct sockaddr_in6);
494 local_all_loopback = 0;
496 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
498 sock->faddr->address.ss_family = sock->family;
499 if (sock->family == AF_INET)
500 sock->faddr->address.ss_len =
501 sizeof(struct sockaddr_in);
503 sock->faddr->address.ss_len =
504 sizeof(struct sockaddr_in6);
506 while (offset < len) {
507 xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
508 offset += sizeof(struct xsctp_tcb);
510 if (opt_l && (sock->vflag & vflag) &&
511 (!opt_L || !local_all_loopback) &&
512 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
513 (xstcb->last == 1))) {
514 RB_INSERT(socks_t, &socks, sock);
519 if (xstcb->last == 1)
523 if ((sock = calloc(1, sizeof *sock)) == NULL)
525 sock->socket = xinpcb->socket;
526 sock->proto = IPPROTO_SCTP;
527 sock->protoname = "sctp";
528 sock->state = (int)xstcb->state;
529 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
530 sock->family = AF_INET6;
532 * Currently there is no way to distinguish
533 * between IPv6 only sockets or dual family
534 * sockets. So mark it as dual socket.
536 sock->vflag = INP_IPV6 | INP_IPV4;
538 sock->family = AF_INET;
539 sock->vflag = INP_IPV4;
543 local_all_loopback = 1;
544 while (offset < len) {
545 xladdr = (struct xsctp_laddr *)(void *)(buf +
547 offset += sizeof(struct xsctp_laddr);
548 if (xladdr->last == 1)
552 laddr = calloc(1, sizeof(struct addr));
555 switch (xladdr->address.sa.sa_family) {
557 #define __IN_IS_ADDR_LOOPBACK(pina) \
558 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
559 if (!__IN_IS_ADDR_LOOPBACK(
560 &xladdr->address.sin.sin_addr))
561 local_all_loopback = 0;
562 #undef __IN_IS_ADDR_LOOPBACK
563 sockaddr(&laddr->address, AF_INET,
564 &xladdr->address.sin.sin_addr,
565 htons(xstcb->local_port));
568 if (!IN6_IS_ADDR_LOOPBACK(
569 &xladdr->address.sin6.sin6_addr))
570 local_all_loopback = 0;
571 sockaddr(&laddr->address, AF_INET6,
572 &xladdr->address.sin6.sin6_addr,
573 htons(xstcb->local_port));
577 "address family %d not supported",
578 xladdr->address.sa.sa_family);
581 if (prev_laddr == NULL)
584 prev_laddr->next = laddr;
588 foreign_all_loopback = 1;
589 while (offset < len) {
590 xraddr = (struct xsctp_raddr *)(void *)(buf +
592 offset += sizeof(struct xsctp_raddr);
593 if (xraddr->last == 1)
597 faddr = calloc(1, sizeof(struct addr));
600 switch (xraddr->address.sa.sa_family) {
602 #define __IN_IS_ADDR_LOOPBACK(pina) \
603 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
604 if (!__IN_IS_ADDR_LOOPBACK(
605 &xraddr->address.sin.sin_addr))
606 foreign_all_loopback = 0;
607 #undef __IN_IS_ADDR_LOOPBACK
608 sockaddr(&faddr->address, AF_INET,
609 &xraddr->address.sin.sin_addr,
610 htons(xstcb->remote_port));
613 if (!IN6_IS_ADDR_LOOPBACK(
614 &xraddr->address.sin6.sin6_addr))
615 foreign_all_loopback = 0;
616 sockaddr(&faddr->address, AF_INET6,
617 &xraddr->address.sin6.sin6_addr,
618 htons(xstcb->remote_port));
622 "address family %d not supported",
623 xraddr->address.sa.sa_family);
625 faddr->encaps_port = xraddr->encaps_port;
626 faddr->state = xraddr->state;
628 if (prev_faddr == NULL)
631 prev_faddr->next = faddr;
635 if ((sock->vflag & vflag) &&
637 !(local_all_loopback ||
638 foreign_all_loopback))) {
639 RB_INSERT(socks_t, &socks, sock);
645 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
646 offset += sizeof(struct xsctp_inpcb);
652 gather_inet(int proto)
654 struct xinpgen *xig, *exig;
656 struct xtcpcb *xtp = NULL;
659 struct addr *laddr, *faddr;
660 const char *varname, *protoname;
673 varname = "net.inet.tcp.pcblist";
677 varname = "net.inet.udp.pcblist";
681 varname = "net.inet.divert.pcblist";
685 errx(1, "protocol %d not supported", proto);
693 if ((buf = realloc(buf, bufsize)) == NULL)
696 if (cap_sysctlbyname(capsysctl, varname, buf, &len,
701 if (errno != ENOMEM || len != bufsize)
702 err(1, "cap_sysctlbyname()");
705 xig = (struct xinpgen *)buf;
706 exig = (struct xinpgen *)(void *)
707 ((char *)buf + len - sizeof *exig);
708 enforce_ksize(xig->xig_len, struct xinpgen);
709 enforce_ksize(exig->xig_len, struct xinpgen);
710 } while (xig->xig_gen != exig->xig_gen && retry--);
712 if (xig->xig_gen != exig->xig_gen && opt_v)
713 warnx("warning: data may be inconsistent");
716 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
721 xtp = (struct xtcpcb *)xig;
723 if (!check_ksize(xtp->xt_len, struct xtcpcb))
725 protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
729 xip = (struct xinpcb *)xig;
730 if (!check_ksize(xip->xi_len, struct xinpcb))
734 errx(1, "protocol %d not supported", proto);
736 so = &xip->xi_socket;
737 if ((xip->inp_vflag & vflag) == 0)
739 if (xip->inp_vflag & INP_IPV4) {
740 if ((xip->inp_fport == 0 && !opt_l) ||
741 (xip->inp_fport != 0 && !opt_c))
743 #define __IN_IS_ADDR_LOOPBACK(pina) \
744 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
746 (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
747 __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
749 #undef __IN_IS_ADDR_LOOPBACK
750 } else if (xip->inp_vflag & INP_IPV6) {
751 if ((xip->inp_fport == 0 && !opt_l) ||
752 (xip->inp_fport != 0 && !opt_c))
755 (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
756 IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
760 warnx("invalid vflag 0x%x", xip->inp_vflag);
763 if ((sock = calloc(1, sizeof(*sock))) == NULL)
765 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
767 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
769 sock->socket = so->xso_so;
771 sock->inp_gencnt = xip->inp_gencnt;
772 if (xip->inp_vflag & INP_IPV4) {
773 sock->family = AF_INET;
774 sockaddr(&laddr->address, sock->family,
775 &xip->inp_laddr, xip->inp_lport);
776 sockaddr(&faddr->address, sock->family,
777 &xip->inp_faddr, xip->inp_fport);
778 } else if (xip->inp_vflag & INP_IPV6) {
779 sock->family = AF_INET6;
780 sockaddr(&laddr->address, sock->family,
781 &xip->in6p_laddr, xip->inp_lport);
782 sockaddr(&faddr->address, sock->family,
783 &xip->in6p_faddr, xip->inp_fport);
785 if (proto == IPPROTO_TCP)
786 faddr->encaps_port = xtp->xt_encaps_port;
791 sock->vflag = xip->inp_vflag;
792 if (proto == IPPROTO_TCP) {
793 sock->state = xtp->t_state;
794 memcpy(sock->stack, xtp->xt_stack,
795 TCP_FUNCTION_NAME_LEN_MAX);
796 memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX);
798 sock->protoname = protoname;
799 if (sock->socket != 0)
800 RB_INSERT(socks_t, &socks, sock);
802 SLIST_INSERT_HEAD(&nosocks, sock, socket_list);
809 gather_unix(int proto)
811 struct xunpgen *xug, *exug;
814 struct addr *laddr, *faddr;
815 const char *varname, *protoname;
822 varname = "net.local.stream.pcblist";
823 protoname = "stream";
826 varname = "net.local.dgram.pcblist";
830 varname = "net.local.seqpacket.pcblist";
831 protoname = "seqpac";
841 if ((buf = realloc(buf, bufsize)) == NULL)
844 if (cap_sysctlbyname(capsysctl, varname, buf, &len,
847 if (errno != ENOMEM || len != bufsize)
848 err(1, "cap_sysctlbyname()");
851 xug = (struct xunpgen *)buf;
852 exug = (struct xunpgen *)(void *)
853 ((char *)buf + len - sizeof(*exug));
854 if (!check_ksize(xug->xug_len, struct xunpgen) ||
855 !check_ksize(exug->xug_len, struct xunpgen))
857 } while (xug->xug_gen != exug->xug_gen && retry--);
859 if (xug->xug_gen != exug->xug_gen && opt_v)
860 warnx("warning: data may be inconsistent");
863 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
866 xup = (struct xunpcb *)xug;
867 if (!check_ksize(xup->xu_len, struct xunpcb))
869 if ((xup->unp_conn == 0 && !opt_l) ||
870 (xup->unp_conn != 0 && !opt_c))
872 if ((sock = calloc(1, sizeof(*sock))) == NULL)
874 if ((laddr = calloc(1, sizeof *laddr)) == NULL)
876 if ((faddr = calloc(1, sizeof *faddr)) == NULL)
878 sock->socket = xup->xu_socket.xso_so;
879 sock->pcb = xup->xu_unpp;
881 sock->family = AF_UNIX;
882 sock->protoname = protoname;
883 if (xup->xu_addr.sun_family == AF_UNIX)
885 *(struct sockaddr_storage *)(void *)&xup->xu_addr;
886 faddr->conn = xup->unp_conn;
887 faddr->firstref = xup->xu_firstref;
888 faddr->nextref = xup->xu_nextref;
893 RB_INSERT(socks_t, &socks, sock);
894 RB_INSERT(pcbs_t, &pcbs, sock);
903 struct xfile *xfiles;
906 olen = len = sizeof(*xfiles);
907 if ((xfiles = malloc(len)) == NULL)
909 while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0)
911 if (errno != ENOMEM || len != olen)
912 err(1, "cap_sysctlbyname()");
914 if ((xfiles = realloc(xfiles, len)) == NULL)
918 enforce_ksize(xfiles->xf_size, struct xfile);
919 nfiles = len / sizeof(*xfiles);
921 if ((files = malloc(nfiles * sizeof(struct file))) == NULL)
924 for (int i = 0; i < nfiles; i++) {
925 files[i].xf_data = xfiles[i].xf_data;
926 files[i].xf_pid = xfiles[i].xf_pid;
927 files[i].xf_uid = xfiles[i].xf_uid;
928 files[i].xf_fd = xfiles[i].xf_fd;
929 RB_INSERT(files_t, &ftree, &files[i]);
936 printaddr(struct sockaddr_storage *ss)
938 struct sockaddr_un *sun;
939 char addrstr[NI_MAXHOST] = { '\0', '\0' };
940 int error, off, port = 0;
942 switch (ss->ss_family) {
944 if (sstosin(ss)->sin_addr.s_addr == INADDR_ANY)
946 port = ntohs(sstosin(ss)->sin_port);
949 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
951 port = ntohs(sstosin6(ss)->sin6_port);
955 off = (int)((char *)&sun->sun_path - (char *)sun);
956 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
958 if (addrstr[0] == '\0') {
959 error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
960 addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
962 errx(1, "cap_getnameinfo()");
965 return xprintf("%s:*", addrstr);
967 return xprintf("%s:%d", addrstr, port);
971 getprocname(pid_t pid)
973 static struct kinfo_proc proc;
979 mib[2] = KERN_PROC_PID;
982 if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
984 /* Do not warn if the process exits before we get its name. */
986 warn("cap_sysctl()");
989 return (proc.ki_comm);
993 getprocjid(pid_t pid)
995 static struct kinfo_proc proc;
1001 mib[2] = KERN_PROC_PID;
1004 if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
1006 /* Do not warn if the process exits before we get its jid. */
1008 warn("cap_sysctl()");
1011 return (proc.ki_jid);
1015 check_ports(struct sock *s)
1022 if ((s->family != AF_INET) && (s->family != AF_INET6))
1024 for (addr = s->laddr; addr != NULL; addr = addr->next) {
1025 if (s->family == AF_INET)
1026 port = ntohs(sstosin(&addr->address)->sin_port);
1028 port = ntohs(sstosin6(&addr->address)->sin6_port);
1032 for (addr = s->faddr; addr != NULL; addr = addr->next) {
1033 if (s->family == AF_INET)
1034 port = ntohs(sstosin(&addr->address)->sin_port);
1036 port = ntohs(sstosin6(&addr->address)->sin6_port);
1044 sctp_conn_state(int state)
1056 case SCTP_COOKIE_WAIT:
1057 return "COOKIE_WAIT";
1059 case SCTP_COOKIE_ECHOED:
1060 return "COOKIE_ECHOED";
1062 case SCTP_ESTABLISHED:
1063 return "ESTABLISHED";
1065 case SCTP_SHUTDOWN_SENT:
1066 return "SHUTDOWN_SENT";
1068 case SCTP_SHUTDOWN_RECEIVED:
1069 return "SHUTDOWN_RECEIVED";
1071 case SCTP_SHUTDOWN_ACK_SENT:
1072 return "SHUTDOWN_ACK_SENT";
1074 case SCTP_SHUTDOWN_PENDING:
1075 return "SHUTDOWN_PENDING";
1084 sctp_path_state(int state)
1087 case SCTP_UNCONFIRMED:
1088 return "UNCONFIRMED";
1103 displaysock(struct sock *s, int pos)
1106 struct addr *laddr, *faddr;
1109 pos += xprintf(" ");
1110 pos += xprintf("%s", s->protoname);
1111 if (s->vflag & INP_IPV4)
1112 pos += xprintf("4");
1113 if (s->vflag & INP_IPV6)
1114 pos += xprintf("6");
1115 if (s->vflag & (INP_IPV4 | INP_IPV6))
1116 pos += xprintf(" ");
1120 while (laddr != NULL || faddr != NULL) {
1122 while (pos < offset)
1123 pos += xprintf(" ");
1124 switch (s->family) {
1127 if (laddr != NULL) {
1128 pos += printaddr(&laddr->address);
1129 if (s->family == AF_INET6 && pos >= 58)
1130 pos += xprintf(" ");
1132 offset += opt_w ? 46 : 22;
1133 while (pos < offset)
1134 pos += xprintf(" ");
1136 pos += printaddr(&faddr->address);
1137 offset += opt_w ? 46 : 22;
1140 if ((laddr == NULL) || (faddr == NULL))
1141 errx(1, "laddr = %p or faddr = %p is NULL",
1142 (void *)laddr, (void *)faddr);
1143 if (laddr->address.ss_len == 0 && faddr->conn == 0) {
1144 pos += xprintf("(not connected)");
1145 offset += opt_w ? 92 : 44;
1148 /* Local bind(2) address, if any. */
1149 if (laddr->address.ss_len > 0)
1150 pos += printaddr(&laddr->address);
1151 /* Remote peer we connect(2) to, if any. */
1152 if (faddr->conn != 0) {
1155 pos += xprintf("%s-> ",
1156 laddr->address.ss_len > 0 ? " " : "");
1157 p = RB_FIND(pcbs_t, &pcbs,
1158 &(struct sock){ .pcb = faddr->conn });
1159 if (__predict_false(p == NULL)) {
1160 /* XXGL: can this happen at all? */
1161 pos += xprintf("??");
1162 } else if (p->laddr->address.ss_len == 0) {
1165 f = RB_FIND(files_t, &ftree,
1166 &(struct file){ .xf_data =
1168 pos += xprintf("[%lu %d]",
1169 (u_long)f->xf_pid, f->xf_fd);
1171 pos += printaddr(&p->laddr->address);
1173 /* Remote peer(s) connect(2)ed to us, if any. */
1174 if (faddr->firstref != 0) {
1177 kvaddr_t ref = faddr->firstref;
1180 pos += xprintf(" <- ");
1182 while ((p = RB_FIND(pcbs_t, &pcbs,
1183 &(struct sock){ .pcb = ref })) != 0) {
1184 f = RB_FIND(files_t, &ftree,
1185 &(struct file){ .xf_data =
1187 pos += xprintf("%s[%lu %d]",
1189 (u_long)f->xf_pid, f->xf_fd);
1190 ref = p->faddr->nextref;
1194 offset += opt_w ? 92 : 44;
1200 if (s->proto == IPPROTO_TCP ||
1201 s->proto == IPPROTO_UDP) {
1202 while (pos < offset)
1203 pos += xprintf(" ");
1204 pos += xprintf("%" PRIu64, s->inp_gencnt);
1209 if (faddr != NULL &&
1210 ((s->proto == IPPROTO_SCTP &&
1211 s->state != SCTP_CLOSED &&
1212 s->state != SCTP_BOUND &&
1213 s->state != SCTP_LISTEN) ||
1214 (s->proto == IPPROTO_TCP &&
1215 s->state != TCPS_CLOSED &&
1216 s->state != TCPS_LISTEN))) {
1217 while (pos < offset)
1218 pos += xprintf(" ");
1219 pos += xprintf("%u",
1220 ntohs(faddr->encaps_port));
1225 if (faddr != NULL &&
1226 s->proto == IPPROTO_SCTP &&
1227 s->state != SCTP_CLOSED &&
1228 s->state != SCTP_BOUND &&
1229 s->state != SCTP_LISTEN) {
1230 while (pos < offset)
1231 pos += xprintf(" ");
1232 pos += xprintf("%s",
1233 sctp_path_state(faddr->state));
1239 if (s->proto == IPPROTO_SCTP ||
1240 s->proto == IPPROTO_TCP) {
1241 while (pos < offset)
1242 pos += xprintf(" ");
1245 pos += xprintf("%s",
1246 sctp_conn_state(s->state));
1249 if (s->state >= 0 &&
1250 s->state < TCP_NSTATES)
1251 pos += xprintf("%s",
1252 tcpstates[s->state]);
1254 pos += xprintf("?");
1261 if (s->proto == IPPROTO_TCP) {
1262 while (pos < offset)
1263 pos += xprintf(" ");
1264 pos += xprintf("%.*s",
1265 TCP_FUNCTION_NAME_LEN_MAX,
1268 offset += TCP_FUNCTION_NAME_LEN_MAX + 1;
1271 if (s->proto == IPPROTO_TCP) {
1272 while (pos < offset)
1273 pos += xprintf(" ");
1274 xprintf("%.*s", TCP_CA_NAME_MAX, s->cc);
1276 offset += TCP_CA_NAME_MAX + 1;
1280 laddr = laddr->next;
1282 faddr = faddr->next;
1283 if ((laddr != NULL) || (faddr != NULL)) {
1301 printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s",
1302 "USER", "COMMAND", "PID", "FD", "PROTO",
1303 opt_w ? 45 : 21, "LOCAL ADDRESS",
1304 opt_w ? 45 : 21, "FOREIGN ADDRESS");
1306 printf(" %-8s", "ID");
1308 printf(" %-6s", "ENCAPS");
1310 printf(" %-12s", "PATH STATE");
1311 printf(" %-12s", "CONN STATE");
1314 printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX,
1315 TCP_FUNCTION_NAME_LEN_MAX, "STACK");
1317 printf(" %-.*s", TCP_CA_NAME_MAX, "CC");
1320 cap_setpassent(cappwd, 1);
1321 for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
1322 if (xf->xf_data == 0)
1324 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
1326 s = RB_FIND(socks_t, &socks,
1327 &(struct sock){ .socket = xf->xf_data});
1328 if (s != NULL && check_ports(s)) {
1332 (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
1333 pos += xprintf("%lu ", (u_long)xf->xf_uid);
1335 pos += xprintf("%s ", pwd->pw_name);
1337 pos += xprintf(" ");
1338 pos += xprintf("%.10s", getprocname(xf->xf_pid));
1340 pos += xprintf(" ");
1341 pos += xprintf("%5lu ", (u_long)xf->xf_pid);
1343 pos += xprintf(" ");
1344 pos += xprintf("%-3d ", xf->xf_fd);
1345 displaysock(s, pos);
1350 SLIST_FOREACH(s, &nosocks, socket_list) {
1351 if (!check_ports(s))
1353 pos = xprintf("%-8s %-10s %-5s %-2s ",
1354 "?", "?", "?", "?");
1355 displaysock(s, pos);
1357 RB_FOREACH(s, socks_t, &socks) {
1360 if (!check_ports(s))
1362 pos = xprintf("%-8s %-10s %-5s %-2s ",
1363 "?", "?", "?", "?");
1364 displaysock(s, pos);
1369 set_default_protos(void)
1371 struct protoent *prot;
1375 init_protos(default_numprotos);
1377 for (pindex = 0; pindex < default_numprotos; pindex++) {
1378 pname = default_protos[pindex];
1379 prot = cap_getprotobyname(capnetdb, pname);
1381 err(1, "cap_getprotobyname: %s", pname);
1382 protos[pindex] = prot->p_proto;
1389 * Return the vnet property of the jail, or -1 on error.
1392 jail_getvnet(int jid)
1394 struct iovec jiov[6];
1396 size_t len = sizeof(vnet);
1398 if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0)
1402 jiov[0].iov_base = __DECONST(char *, "jid");
1403 jiov[0].iov_len = sizeof("jid");
1404 jiov[1].iov_base = &jid;
1405 jiov[1].iov_len = sizeof(jid);
1406 jiov[2].iov_base = __DECONST(char *, "vnet");
1407 jiov[2].iov_len = sizeof("vnet");
1408 jiov[3].iov_base = &vnet;
1409 jiov[3].iov_len = sizeof(vnet);
1410 jiov[4].iov_base = __DECONST(char *, "errmsg");
1411 jiov[4].iov_len = sizeof("errmsg");
1412 jiov[5].iov_base = jail_errmsg;
1413 jiov[5].iov_len = JAIL_ERRMSGLEN;
1414 jail_errmsg[0] = '\0';
1415 if (jail_get(jiov, nitems(jiov), 0) < 0) {
1416 if (!jail_errmsg[0])
1417 snprintf(jail_errmsg, JAIL_ERRMSGLEN,
1418 "jail_get: %s", strerror(errno));
1428 "usage: sockstat [-46CciLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]\n");
1433 main(int argc, char *argv[])
1435 cap_channel_t *capcas;
1436 cap_net_limit_t *limit;
1437 const char *pwdcmds[] = { "setpassent", "getpwuid" };
1438 const char *pwdfields[] = { "pw_name" };
1439 int protos_defined = -1;
1443 while ((o = getopt(argc, argv, "46Ccij:Llnp:P:qSsUuvw")) != -1)
1461 opt_j = jail_getid(optarg);
1463 errx(1, "jail_getid: %s", jail_errmsg);
1475 parse_ports(optarg);
1478 protos_defined = parse_protos(optarg);
1512 switch (jail_getvnet(opt_j)) {
1514 errx(2, "jail_getvnet: %s", jail_errmsg);
1516 if (jail_attach(opt_j) < 0)
1517 err(3, "jail_attach()");
1518 /* Set back to -1 for normal output in vnet jail. */
1526 capcas = cap_init();
1528 err(1, "Unable to contact Casper");
1529 if (caph_enter_casper() < 0)
1530 err(1, "Unable to enter capability mode");
1531 capnet = cap_service_open(capcas, "system.net");
1533 err(1, "Unable to open system.net service");
1534 capnetdb = cap_service_open(capcas, "system.netdb");
1535 if (capnetdb == NULL)
1536 err(1, "Unable to open system.netdb service");
1537 capsysctl = cap_service_open(capcas, "system.sysctl");
1538 if (capsysctl == NULL)
1539 err(1, "Unable to open system.sysctl service");
1540 cappwd = cap_service_open(capcas, "system.pwd");
1542 err(1, "Unable to open system.pwd service");
1544 limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
1546 err(1, "Unable to init cap_net limits");
1547 if (cap_net_limit(limit) < 0)
1548 err(1, "Unable to apply limits");
1549 if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
1550 err(1, "Unable to apply pwd commands limits");
1551 if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
1552 err(1, "Unable to apply pwd commands limits");
1554 if ((!opt_4 && !opt_6) && protos_defined != -1)
1556 if (!opt_4 && !opt_6 && !opt_u)
1557 opt_4 = opt_6 = opt_u = 1;
1558 if ((opt_4 || opt_6) && protos_defined == -1)
1559 protos_defined = set_default_protos();
1560 if (!opt_c && !opt_l)
1563 if (opt_4 || opt_6) {
1564 for (i = 0; i < protos_defined; i++)
1565 if (protos[i] == IPPROTO_SCTP)
1568 gather_inet(protos[i]);
1571 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
1572 gather_unix(SOCK_STREAM);
1573 gather_unix(SOCK_DGRAM);
1574 gather_unix(SOCK_SEQPACKET);