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