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