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 if (s->family == AF_INET6 && pos >= 58) 1135 pos += xprintf(" "); 1136 } 1137 offset += opt_w ? 46 : 22; 1138 while (pos < offset) 1139 pos += xprintf(" "); 1140 if (faddr != NULL) 1141 pos += printaddr(&faddr->address); 1142 offset += opt_w ? 46 : 22; 1143 break; 1144 case AF_UNIX: 1145 if ((laddr == NULL) || (faddr == NULL)) 1146 errx(1, "laddr = %p or faddr = %p is NULL", 1147 (void *)laddr, (void *)faddr); 1148 if (laddr->address.ss_len == 0 && faddr->conn == 0) { 1149 pos += xprintf("(not connected)"); 1150 offset += opt_w ? 92 : 44; 1151 break; 1152 } 1153 /* Local bind(2) address, if any. */ 1154 if (laddr->address.ss_len > 0) 1155 pos += printaddr(&laddr->address); 1156 /* Remote peer we connect(2) to, if any. */ 1157 if (faddr->conn != 0) { 1158 struct sock *p; 1159 1160 pos += xprintf("%s-> ", 1161 laddr->address.ss_len > 0 ? " " : ""); 1162 p = RB_FIND(pcbs_t, &pcbs, 1163 &(struct sock){ .pcb = faddr->conn }); 1164 if (__predict_false(p == NULL)) { 1165 /* XXGL: can this happen at all? */ 1166 pos += xprintf("??"); 1167 } else if (p->laddr->address.ss_len == 0) { 1168 struct file *f; 1169 1170 f = RB_FIND(files_t, &ftree, 1171 &(struct file){ .xf_data = 1172 p->socket }); 1173 if (f != NULL) { 1174 pos += xprintf("[%lu %d]", 1175 (u_long)f->xf_pid, 1176 f->xf_fd); 1177 } 1178 } else 1179 pos += printaddr(&p->laddr->address); 1180 } 1181 /* Remote peer(s) connect(2)ed to us, if any. */ 1182 if (faddr->firstref != 0) { 1183 struct sock *p; 1184 struct file *f; 1185 kvaddr_t ref = faddr->firstref; 1186 bool fref = true; 1187 1188 pos += xprintf(" <- "); 1189 1190 while ((p = RB_FIND(pcbs_t, &pcbs, 1191 &(struct sock){ .pcb = ref })) != 0) { 1192 f = RB_FIND(files_t, &ftree, 1193 &(struct file){ .xf_data = 1194 p->socket }); 1195 if (f != NULL) { 1196 pos += xprintf("%s[%lu %d]", 1197 fref ? "" : ",", 1198 (u_long)f->xf_pid, 1199 f->xf_fd); 1200 } 1201 ref = p->faddr->nextref; 1202 fref = false; 1203 } 1204 } 1205 offset += opt_w ? 92 : 44; 1206 break; 1207 default: 1208 abort(); 1209 } 1210 if (opt_f) { 1211 while (pos < offset) 1212 pos += xprintf(" "); 1213 pos += xprintf("%d", s->fibnum); 1214 offset += 7; 1215 } 1216 if (opt_I) { 1217 if (s->splice_socket != 0) { 1218 struct sock *sp; 1219 1220 sp = RB_FIND(socks_t, &socks, &(struct sock) 1221 { .socket = s->splice_socket }); 1222 if (sp != NULL) { 1223 while (pos < offset) 1224 pos += xprintf(" "); 1225 pos += printaddr(&sp->laddr->address); 1226 } else { 1227 while (pos < offset) 1228 pos += xprintf(" "); 1229 pos += xprintf("??"); 1230 offset += opt_w ? 46 : 22; 1231 } 1232 } 1233 offset += opt_w ? 46 : 22; 1234 } 1235 if (opt_i) { 1236 if (s->proto == IPPROTO_TCP || 1237 s->proto == IPPROTO_UDP) { 1238 while (pos < offset) 1239 pos += xprintf(" "); 1240 pos += xprintf("%" PRIu64, s->inp_gencnt); 1241 } 1242 offset += 9; 1243 } 1244 if (opt_U) { 1245 if (faddr != NULL && 1246 ((s->proto == IPPROTO_SCTP && 1247 s->state != SCTP_CLOSED && 1248 s->state != SCTP_BOUND && 1249 s->state != SCTP_LISTEN) || 1250 (s->proto == IPPROTO_TCP && 1251 s->state != TCPS_CLOSED && 1252 s->state != TCPS_LISTEN))) { 1253 while (pos < offset) 1254 pos += xprintf(" "); 1255 pos += xprintf("%u", 1256 ntohs(faddr->encaps_port)); 1257 } 1258 offset += 7; 1259 } 1260 if (opt_s) { 1261 if (faddr != NULL && 1262 s->proto == IPPROTO_SCTP && 1263 s->state != SCTP_CLOSED && 1264 s->state != SCTP_BOUND && 1265 s->state != SCTP_LISTEN) { 1266 while (pos < offset) 1267 pos += xprintf(" "); 1268 pos += xprintf("%s", 1269 sctp_path_state(faddr->state)); 1270 } 1271 offset += 13; 1272 } 1273 if (first) { 1274 if (opt_s) { 1275 if (s->proto == IPPROTO_SCTP || 1276 s->proto == IPPROTO_TCP) { 1277 while (pos < offset) 1278 pos += xprintf(" "); 1279 switch (s->proto) { 1280 case IPPROTO_SCTP: 1281 pos += xprintf("%s", 1282 sctp_conn_state(s->state)); 1283 break; 1284 case IPPROTO_TCP: 1285 if (s->state >= 0 && 1286 s->state < TCP_NSTATES) 1287 pos += xprintf("%s", 1288 tcpstates[s->state]); 1289 else 1290 pos += xprintf("?"); 1291 break; 1292 } 1293 } 1294 offset += 13; 1295 } 1296 if (opt_S) { 1297 if (s->proto == IPPROTO_TCP) { 1298 while (pos < offset) 1299 pos += xprintf(" "); 1300 pos += xprintf("%.*s", 1301 TCP_FUNCTION_NAME_LEN_MAX, 1302 s->stack); 1303 } 1304 offset += TCP_FUNCTION_NAME_LEN_MAX + 1; 1305 } 1306 if (opt_C) { 1307 if (s->proto == IPPROTO_TCP) { 1308 while (pos < offset) 1309 pos += xprintf(" "); 1310 xprintf("%.*s", TCP_CA_NAME_MAX, s->cc); 1311 } 1312 offset += TCP_CA_NAME_MAX + 1; 1313 } 1314 } 1315 if (laddr != NULL) 1316 laddr = laddr->next; 1317 if (faddr != NULL) 1318 faddr = faddr->next; 1319 if ((laddr != NULL) || (faddr != NULL)) { 1320 xprintf("\n"); 1321 pos = 0; 1322 } 1323 first = 0; 1324 } 1325 xprintf("\n"); 1326 } 1327 1328 static void 1329 display(void) 1330 { 1331 struct passwd *pwd; 1332 struct file *xf; 1333 struct sock *s; 1334 int n, pos; 1335 1336 if (opt_q != 1) { 1337 printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s", 1338 "USER", "COMMAND", "PID", "FD", "PROTO", 1339 opt_w ? 45 : 21, "LOCAL ADDRESS", 1340 opt_w ? 45 : 21, "FOREIGN ADDRESS"); 1341 if (opt_f) 1342 /* RT_MAXFIBS is 65535. */ 1343 printf(" %-6s", "FIB"); 1344 if (opt_I) 1345 printf(" %-*s", opt_w ? 45 : 21, "SPLICE ADDRESS"); 1346 if (opt_i) 1347 printf(" %-8s", "ID"); 1348 if (opt_U) 1349 printf(" %-6s", "ENCAPS"); 1350 if (opt_s) { 1351 printf(" %-12s", "PATH STATE"); 1352 printf(" %-12s", "CONN STATE"); 1353 } 1354 if (opt_S) 1355 printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX, 1356 TCP_FUNCTION_NAME_LEN_MAX, "STACK"); 1357 if (opt_C) 1358 printf(" %-.*s", TCP_CA_NAME_MAX, "CC"); 1359 printf("\n"); 1360 } 1361 cap_setpassent(cappwd, 1); 1362 for (xf = files, n = 0; n < nfiles; ++n, ++xf) { 1363 if (xf->xf_data == 0) 1364 continue; 1365 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid)) 1366 continue; 1367 s = RB_FIND(socks_t, &socks, 1368 &(struct sock){ .socket = xf->xf_data}); 1369 if (s != NULL && check_ports(s)) { 1370 s->shown = 1; 1371 pos = 0; 1372 if (opt_n || 1373 (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL) 1374 pos += xprintf("%lu ", (u_long)xf->xf_uid); 1375 else 1376 pos += xprintf("%s ", pwd->pw_name); 1377 while (pos < 9) 1378 pos += xprintf(" "); 1379 pos += xprintf("%.10s", getprocname(xf->xf_pid)); 1380 while (pos < 20) 1381 pos += xprintf(" "); 1382 pos += xprintf("%5lu ", (u_long)xf->xf_pid); 1383 while (pos < 26) 1384 pos += xprintf(" "); 1385 pos += xprintf("%-3d ", xf->xf_fd); 1386 displaysock(s, pos); 1387 } 1388 } 1389 if (opt_j >= 0) 1390 return; 1391 SLIST_FOREACH(s, &nosocks, socket_list) { 1392 if (!check_ports(s)) 1393 continue; 1394 pos = xprintf("%-8s %-10s %-5s %-2s ", 1395 "?", "?", "?", "?"); 1396 displaysock(s, pos); 1397 } 1398 RB_FOREACH(s, socks_t, &socks) { 1399 if (s->shown) 1400 continue; 1401 if (!check_ports(s)) 1402 continue; 1403 pos = xprintf("%-8s %-10s %-5s %-2s ", 1404 "?", "?", "?", "?"); 1405 displaysock(s, pos); 1406 } 1407 } 1408 1409 static int 1410 set_default_protos(void) 1411 { 1412 struct protoent *prot; 1413 const char *pname; 1414 size_t pindex; 1415 1416 init_protos(default_numprotos); 1417 1418 for (pindex = 0; pindex < default_numprotos; pindex++) { 1419 pname = default_protos[pindex]; 1420 prot = cap_getprotobyname(capnetdb, pname); 1421 if (prot == NULL) 1422 err(1, "cap_getprotobyname: %s", pname); 1423 protos[pindex] = prot->p_proto; 1424 } 1425 numprotos = pindex; 1426 return (pindex); 1427 } 1428 1429 /* 1430 * Return the vnet property of the jail, or -1 on error. 1431 */ 1432 static int 1433 jail_getvnet(int jid) 1434 { 1435 struct iovec jiov[6]; 1436 int vnet; 1437 size_t len = sizeof(vnet); 1438 1439 if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0) 1440 return (0); 1441 1442 vnet = -1; 1443 jiov[0].iov_base = __DECONST(char *, "jid"); 1444 jiov[0].iov_len = sizeof("jid"); 1445 jiov[1].iov_base = &jid; 1446 jiov[1].iov_len = sizeof(jid); 1447 jiov[2].iov_base = __DECONST(char *, "vnet"); 1448 jiov[2].iov_len = sizeof("vnet"); 1449 jiov[3].iov_base = &vnet; 1450 jiov[3].iov_len = sizeof(vnet); 1451 jiov[4].iov_base = __DECONST(char *, "errmsg"); 1452 jiov[4].iov_len = sizeof("errmsg"); 1453 jiov[5].iov_base = jail_errmsg; 1454 jiov[5].iov_len = JAIL_ERRMSGLEN; 1455 jail_errmsg[0] = '\0'; 1456 if (jail_get(jiov, nitems(jiov), 0) < 0) { 1457 if (!jail_errmsg[0]) 1458 snprintf(jail_errmsg, JAIL_ERRMSGLEN, 1459 "jail_get: %s", strerror(errno)); 1460 return (-1); 1461 } 1462 return (vnet); 1463 } 1464 1465 static void 1466 usage(void) 1467 { 1468 errx(1, 1469 "usage: sockstat [-46CcfIiLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]"); 1470 } 1471 1472 int 1473 main(int argc, char *argv[]) 1474 { 1475 cap_channel_t *capcas; 1476 cap_net_limit_t *limit; 1477 const char *pwdcmds[] = { "setpassent", "getpwuid" }; 1478 const char *pwdfields[] = { "pw_name" }; 1479 int protos_defined = -1; 1480 int o, i; 1481 1482 opt_j = -1; 1483 while ((o = getopt(argc, argv, "46CcfIij:Llnp:P:qSsUuvw")) != -1) 1484 switch (o) { 1485 case '4': 1486 opt_4 = 1; 1487 break; 1488 case '6': 1489 opt_6 = 1; 1490 break; 1491 case 'C': 1492 opt_C = 1; 1493 break; 1494 case 'c': 1495 opt_c = 1; 1496 break; 1497 case 'f': 1498 opt_f = 1; 1499 break; 1500 case 'I': 1501 opt_I = 1; 1502 break; 1503 case 'i': 1504 opt_i = 1; 1505 break; 1506 case 'j': 1507 opt_j = jail_getid(optarg); 1508 if (opt_j < 0) 1509 errx(1, "jail_getid: %s", jail_errmsg); 1510 break; 1511 case 'L': 1512 opt_L = 1; 1513 break; 1514 case 'l': 1515 opt_l = 1; 1516 break; 1517 case 'n': 1518 opt_n = 1; 1519 break; 1520 case 'p': 1521 parse_ports(optarg); 1522 break; 1523 case 'P': 1524 protos_defined = parse_protos(optarg); 1525 break; 1526 case 'q': 1527 opt_q = 1; 1528 break; 1529 case 'S': 1530 opt_S = 1; 1531 break; 1532 case 's': 1533 opt_s = 1; 1534 break; 1535 case 'U': 1536 opt_U = 1; 1537 break; 1538 case 'u': 1539 opt_u = 1; 1540 break; 1541 case 'v': 1542 ++opt_v; 1543 break; 1544 case 'w': 1545 opt_w = 1; 1546 break; 1547 default: 1548 usage(); 1549 } 1550 1551 argc -= optind; 1552 argv += optind; 1553 1554 if (argc > 0) 1555 usage(); 1556 1557 if (opt_j > 0) { 1558 switch (jail_getvnet(opt_j)) { 1559 case -1: 1560 errx(2, "jail_getvnet: %s", jail_errmsg); 1561 case JAIL_SYS_NEW: 1562 if (jail_attach(opt_j) < 0) 1563 err(3, "jail_attach()"); 1564 /* Set back to -1 for normal output in vnet jail. */ 1565 opt_j = -1; 1566 break; 1567 default: 1568 break; 1569 } 1570 } 1571 1572 capcas = cap_init(); 1573 if (capcas == NULL) 1574 err(1, "Unable to contact Casper"); 1575 if (caph_enter_casper() < 0) 1576 err(1, "Unable to enter capability mode"); 1577 capnet = cap_service_open(capcas, "system.net"); 1578 if (capnet == NULL) 1579 err(1, "Unable to open system.net service"); 1580 capnetdb = cap_service_open(capcas, "system.netdb"); 1581 if (capnetdb == NULL) 1582 err(1, "Unable to open system.netdb service"); 1583 capsysctl = cap_service_open(capcas, "system.sysctl"); 1584 if (capsysctl == NULL) 1585 err(1, "Unable to open system.sysctl service"); 1586 cappwd = cap_service_open(capcas, "system.pwd"); 1587 if (cappwd == NULL) 1588 err(1, "Unable to open system.pwd service"); 1589 cap_close(capcas); 1590 limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME); 1591 if (limit == NULL) 1592 err(1, "Unable to init cap_net limits"); 1593 if (cap_net_limit(limit) < 0) 1594 err(1, "Unable to apply limits"); 1595 if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0) 1596 err(1, "Unable to apply pwd commands limits"); 1597 if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0) 1598 err(1, "Unable to apply pwd commands limits"); 1599 1600 if ((!opt_4 && !opt_6) && protos_defined != -1) 1601 opt_4 = opt_6 = 1; 1602 if (!opt_4 && !opt_6 && !opt_u) 1603 opt_4 = opt_6 = opt_u = 1; 1604 if ((opt_4 || opt_6) && protos_defined == -1) 1605 protos_defined = set_default_protos(); 1606 if (!opt_c && !opt_l) 1607 opt_c = opt_l = 1; 1608 1609 if (opt_4 || opt_6) { 1610 for (i = 0; i < protos_defined; i++) 1611 if (protos[i] == IPPROTO_SCTP) 1612 gather_sctp(); 1613 else 1614 gather_inet(protos[i]); 1615 } 1616 1617 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) { 1618 gather_unix(SOCK_STREAM); 1619 gather_unix(SOCK_DGRAM); 1620 gather_unix(SOCK_SEQPACKET); 1621 } 1622 getfiles(); 1623 display(); 1624 exit(0); 1625 } 1626