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