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