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