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