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