1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2002 Dag-Erling Coïdan 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/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/file.h> 36 #include <sys/socket.h> 37 #include <sys/socketvar.h> 38 #include <sys/sysctl.h> 39 #include <sys/jail.h> 40 #include <sys/user.h> 41 #include <sys/queue.h> 42 #include <sys/tree.h> 43 44 #include <sys/un.h> 45 #include <sys/unpcb.h> 46 47 #include <net/route.h> 48 49 #include <netinet/in.h> 50 #include <netinet/in_pcb.h> 51 #include <netinet/sctp.h> 52 #include <netinet/tcp.h> 53 #define TCPSTATES /* load state names */ 54 #include <netinet/tcp_fsm.h> 55 #include <netinet/tcp_seq.h> 56 #include <netinet/tcp_var.h> 57 #include <arpa/inet.h> 58 59 #include <capsicum_helpers.h> 60 #include <ctype.h> 61 #include <err.h> 62 #include <errno.h> 63 #include <inttypes.h> 64 #include <jail.h> 65 #include <netdb.h> 66 #include <pwd.h> 67 #include <stdarg.h> 68 #include <stdio.h> 69 #include <stdlib.h> 70 #include <string.h> 71 #include <unistd.h> 72 73 #include <libcasper.h> 74 #include <casper/cap_net.h> 75 #include <casper/cap_netdb.h> 76 #include <casper/cap_pwd.h> 77 #include <casper/cap_sysctl.h> 78 79 #define sstosin(ss) ((struct sockaddr_in *)(ss)) 80 #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) 81 #define sstosun(ss) ((struct sockaddr_un *)(ss)) 82 #define sstosa(ss) ((struct sockaddr *)(ss)) 83 84 static int opt_4; /* Show IPv4 sockets */ 85 static int opt_6; /* Show IPv6 sockets */ 86 static int opt_C; /* Show congestion control */ 87 static int opt_c; /* Show connected sockets */ 88 static int opt_i; /* Show inp_gencnt */ 89 static int opt_j; /* Show specified jail */ 90 static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */ 91 static int opt_l; /* Show listening sockets */ 92 static int opt_n; /* Don't resolve UIDs to user names */ 93 static int opt_q; /* Don't show header */ 94 static int opt_S; /* Show protocol stack if applicable */ 95 static int opt_s; /* Show protocol state if applicable */ 96 static int opt_U; /* Show remote UDP encapsulation port number */ 97 static int opt_u; /* Show Unix domain sockets */ 98 static int opt_v; /* Verbose mode */ 99 static int opt_w; /* Wide print area for addresses */ 100 101 /* 102 * Default protocols to use if no -P was defined. 103 */ 104 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" }; 105 static size_t default_numprotos = nitems(default_protos); 106 107 static int *protos; /* protocols to use */ 108 static size_t numprotos; /* allocated size of protos[] */ 109 110 static int *ports; 111 112 #define INT_BIT (sizeof(int)*CHAR_BIT) 113 #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0) 114 #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT))) 115 116 struct addr { 117 union { 118 struct sockaddr_storage address; 119 struct { /* unix(4) faddr */ 120 kvaddr_t conn; 121 kvaddr_t firstref; 122 kvaddr_t nextref; 123 }; 124 }; 125 unsigned int encaps_port; 126 int state; 127 struct addr *next; 128 }; 129 130 struct sock { 131 union { 132 RB_ENTRY(sock) socket_tree; /* tree of pcbs with socket */ 133 SLIST_ENTRY(sock) socket_list; /* list of pcbs w/o socket */ 134 }; 135 RB_ENTRY(sock) pcb_tree; 136 kvaddr_t socket; 137 kvaddr_t pcb; 138 uint64_t inp_gencnt; 139 int shown; 140 int vflag; 141 int family; 142 int proto; 143 int state; 144 const char *protoname; 145 char stack[TCP_FUNCTION_NAME_LEN_MAX]; 146 char cc[TCP_CA_NAME_MAX]; 147 struct addr *laddr; 148 struct addr *faddr; 149 }; 150 151 static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks); 152 static int64_t 153 socket_compare(const struct sock *a, const struct sock *b) 154 { 155 return ((int64_t)(a->socket/2 - b->socket/2)); 156 } 157 RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare); 158 159 static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs); 160 static int64_t 161 pcb_compare(const struct sock *a, const struct sock *b) 162 { 163 return ((int64_t)(a->pcb/2 - b->pcb/2)); 164 } 165 RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare); 166 167 static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks); 168 169 struct file { 170 RB_ENTRY(file) file_tree; 171 kvaddr_t xf_data; 172 pid_t xf_pid; 173 uid_t xf_uid; 174 int xf_fd; 175 }; 176 177 static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree); 178 static int64_t 179 file_compare(const struct file *a, const struct file *b) 180 { 181 return ((int64_t)(a->xf_data/2 - b->xf_data/2)); 182 } 183 RB_GENERATE_STATIC(files_t, file, file_tree, file_compare); 184 185 static struct file *files; 186 static int nfiles; 187 188 static cap_channel_t *capnet; 189 static cap_channel_t *capnetdb; 190 static cap_channel_t *capsysctl; 191 static cap_channel_t *cappwd; 192 193 static int 194 xprintf(const char *fmt, ...) 195 { 196 va_list ap; 197 int len; 198 199 va_start(ap, fmt); 200 len = vprintf(fmt, ap); 201 va_end(ap); 202 if (len < 0) 203 err(1, "printf()"); 204 return (len); 205 } 206 207 static bool 208 _check_ksize(size_t received_size, size_t expected_size, const char *struct_name) 209 { 210 if (received_size != expected_size) { 211 warnx("%s size mismatch: expected %zd, received %zd", 212 struct_name, expected_size, received_size); 213 return false; 214 } 215 return true; 216 } 217 #define check_ksize(_sz, _struct) (_check_ksize(_sz, sizeof(_struct), #_struct)) 218 219 static void 220 _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name) 221 { 222 if (received_size != expected_size) { 223 errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd", 224 struct_name, expected_size, received_size); 225 } 226 } 227 #define enforce_ksize(_sz, _struct) (_enforce_ksize(_sz, sizeof(_struct), #_struct)) 228 229 static int 230 get_proto_type(const char *proto) 231 { 232 struct protoent *pent; 233 234 if (strlen(proto) == 0) 235 return (0); 236 if (capnetdb != NULL) 237 pent = cap_getprotobyname(capnetdb, proto); 238 else 239 pent = getprotobyname(proto); 240 if (pent == NULL) { 241 warn("cap_getprotobyname"); 242 return (-1); 243 } 244 return (pent->p_proto); 245 } 246 247 static void 248 init_protos(int num) 249 { 250 int proto_count = 0; 251 252 if (num > 0) { 253 proto_count = num; 254 } else { 255 /* Find the maximum number of possible protocols. */ 256 while (getprotoent() != NULL) 257 proto_count++; 258 endprotoent(); 259 } 260 261 if ((protos = malloc(sizeof(int) * proto_count)) == NULL) 262 err(1, "malloc"); 263 numprotos = proto_count; 264 } 265 266 static int 267 parse_protos(char *protospec) 268 { 269 char *prot; 270 int proto_type, proto_index; 271 272 if (protospec == NULL) 273 return (-1); 274 275 init_protos(0); 276 proto_index = 0; 277 while ((prot = strsep(&protospec, ",")) != NULL) { 278 if (strlen(prot) == 0) 279 continue; 280 proto_type = get_proto_type(prot); 281 if (proto_type != -1) 282 protos[proto_index++] = proto_type; 283 } 284 numprotos = proto_index; 285 return (proto_index); 286 } 287 288 static void 289 parse_ports(const char *portspec) 290 { 291 const char *p, *q; 292 int port, end; 293 294 if (ports == NULL) 295 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL) 296 err(1, "calloc()"); 297 p = portspec; 298 while (*p != '\0') { 299 if (!isdigit(*p)) 300 errx(1, "syntax error in port range"); 301 for (q = p; *q != '\0' && isdigit(*q); ++q) 302 /* nothing */ ; 303 for (port = 0; p < q; ++p) 304 port = port * 10 + digittoint(*p); 305 if (port < 0 || port > 65535) 306 errx(1, "invalid port number"); 307 SET_PORT(port); 308 switch (*p) { 309 case '-': 310 ++p; 311 break; 312 case ',': 313 ++p; 314 /* fall through */ 315 case '\0': 316 default: 317 continue; 318 } 319 for (q = p; *q != '\0' && isdigit(*q); ++q) 320 /* nothing */ ; 321 for (end = 0; p < q; ++p) 322 end = end * 10 + digittoint(*p); 323 if (end < port || end > 65535) 324 errx(1, "invalid port number"); 325 while (port++ < end) 326 SET_PORT(port); 327 if (*p == ',') 328 ++p; 329 } 330 } 331 332 static void 333 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port) 334 { 335 struct sockaddr_in *sin4; 336 struct sockaddr_in6 *sin6; 337 338 bzero(ss, sizeof(*ss)); 339 switch (af) { 340 case AF_INET: 341 sin4 = sstosin(ss); 342 sin4->sin_len = sizeof(*sin4); 343 sin4->sin_family = af; 344 sin4->sin_port = port; 345 sin4->sin_addr = *(struct in_addr *)addr; 346 break; 347 case AF_INET6: 348 sin6 = sstosin6(ss); 349 sin6->sin6_len = sizeof(*sin6); 350 sin6->sin6_family = af; 351 sin6->sin6_port = port; 352 sin6->sin6_addr = *(struct in6_addr *)addr; 353 #define s6_addr16 __u6_addr.__u6_addr16 354 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 355 sin6->sin6_scope_id = 356 ntohs(sin6->sin6_addr.s6_addr16[1]); 357 sin6->sin6_addr.s6_addr16[1] = 0; 358 } 359 break; 360 default: 361 abort(); 362 } 363 } 364 365 static void 366 free_socket(struct sock *sock) 367 { 368 struct addr *cur, *next; 369 370 cur = sock->laddr; 371 while (cur != NULL) { 372 next = cur->next; 373 free(cur); 374 cur = next; 375 } 376 cur = sock->faddr; 377 while (cur != NULL) { 378 next = cur->next; 379 free(cur); 380 cur = next; 381 } 382 free(sock); 383 } 384 385 static void 386 gather_sctp(void) 387 { 388 struct sock *sock; 389 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr; 390 struct xsctp_inpcb *xinpcb; 391 struct xsctp_tcb *xstcb; 392 struct xsctp_raddr *xraddr; 393 struct xsctp_laddr *xladdr; 394 const char *varname; 395 size_t len, offset; 396 char *buf; 397 int vflag; 398 int no_stcb, local_all_loopback, foreign_all_loopback; 399 400 vflag = 0; 401 if (opt_4) 402 vflag |= INP_IPV4; 403 if (opt_6) 404 vflag |= INP_IPV6; 405 406 varname = "net.inet.sctp.assoclist"; 407 if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) { 408 if (errno != ENOENT) 409 err(1, "cap_sysctlbyname()"); 410 return; 411 } 412 if ((buf = (char *)malloc(len)) == NULL) { 413 err(1, "malloc()"); 414 return; 415 } 416 if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) { 417 err(1, "cap_sysctlbyname()"); 418 free(buf); 419 return; 420 } 421 xinpcb = (struct xsctp_inpcb *)(void *)buf; 422 offset = sizeof(struct xsctp_inpcb); 423 while ((offset < len) && (xinpcb->last == 0)) { 424 if ((sock = calloc(1, sizeof *sock)) == NULL) 425 err(1, "malloc()"); 426 sock->socket = xinpcb->socket; 427 sock->proto = IPPROTO_SCTP; 428 sock->protoname = "sctp"; 429 if (xinpcb->maxqlen == 0) 430 sock->state = SCTP_CLOSED; 431 else 432 sock->state = SCTP_LISTEN; 433 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 434 sock->family = AF_INET6; 435 /* 436 * Currently there is no way to distinguish between 437 * IPv6 only sockets or dual family sockets. 438 * So mark it as dual socket. 439 */ 440 sock->vflag = INP_IPV6 | INP_IPV4; 441 } else { 442 sock->family = AF_INET; 443 sock->vflag = INP_IPV4; 444 } 445 prev_laddr = NULL; 446 local_all_loopback = 1; 447 while (offset < len) { 448 xladdr = (struct xsctp_laddr *)(void *)(buf + offset); 449 offset += sizeof(struct xsctp_laddr); 450 if (xladdr->last == 1) 451 break; 452 if ((laddr = calloc(1, sizeof(struct addr))) == NULL) 453 err(1, "malloc()"); 454 switch (xladdr->address.sa.sa_family) { 455 case AF_INET: 456 #define __IN_IS_ADDR_LOOPBACK(pina) \ 457 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 458 if (!__IN_IS_ADDR_LOOPBACK( 459 &xladdr->address.sin.sin_addr)) 460 local_all_loopback = 0; 461 #undef __IN_IS_ADDR_LOOPBACK 462 sockaddr(&laddr->address, AF_INET, 463 &xladdr->address.sin.sin_addr, 464 htons(xinpcb->local_port)); 465 break; 466 case AF_INET6: 467 if (!IN6_IS_ADDR_LOOPBACK( 468 &xladdr->address.sin6.sin6_addr)) 469 local_all_loopback = 0; 470 sockaddr(&laddr->address, AF_INET6, 471 &xladdr->address.sin6.sin6_addr, 472 htons(xinpcb->local_port)); 473 break; 474 default: 475 errx(1, "address family %d not supported", 476 xladdr->address.sa.sa_family); 477 } 478 laddr->next = NULL; 479 if (prev_laddr == NULL) 480 sock->laddr = laddr; 481 else 482 prev_laddr->next = laddr; 483 prev_laddr = laddr; 484 } 485 if (sock->laddr == NULL) { 486 if ((sock->laddr = 487 calloc(1, sizeof(struct addr))) == NULL) 488 err(1, "malloc()"); 489 sock->laddr->address.ss_family = sock->family; 490 if (sock->family == AF_INET) 491 sock->laddr->address.ss_len = 492 sizeof(struct sockaddr_in); 493 else 494 sock->laddr->address.ss_len = 495 sizeof(struct sockaddr_in6); 496 local_all_loopback = 0; 497 } 498 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL) 499 err(1, "malloc()"); 500 sock->faddr->address.ss_family = sock->family; 501 if (sock->family == AF_INET) 502 sock->faddr->address.ss_len = 503 sizeof(struct sockaddr_in); 504 else 505 sock->faddr->address.ss_len = 506 sizeof(struct sockaddr_in6); 507 no_stcb = 1; 508 while (offset < len) { 509 xstcb = (struct xsctp_tcb *)(void *)(buf + offset); 510 offset += sizeof(struct xsctp_tcb); 511 if (no_stcb) { 512 if (opt_l && (sock->vflag & vflag) && 513 (!opt_L || !local_all_loopback) && 514 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) || 515 (xstcb->last == 1))) { 516 RB_INSERT(socks_t, &socks, sock); 517 } else { 518 free_socket(sock); 519 } 520 } 521 if (xstcb->last == 1) 522 break; 523 no_stcb = 0; 524 if (opt_c) { 525 if ((sock = calloc(1, sizeof *sock)) == NULL) 526 err(1, "malloc()"); 527 sock->socket = xinpcb->socket; 528 sock->proto = IPPROTO_SCTP; 529 sock->protoname = "sctp"; 530 sock->state = (int)xstcb->state; 531 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 532 sock->family = AF_INET6; 533 /* 534 * Currently there is no way to distinguish 535 * between IPv6 only sockets or dual family 536 * sockets. So mark it as dual socket. 537 */ 538 sock->vflag = INP_IPV6 | INP_IPV4; 539 } else { 540 sock->family = AF_INET; 541 sock->vflag = INP_IPV4; 542 } 543 } 544 prev_laddr = NULL; 545 local_all_loopback = 1; 546 while (offset < len) { 547 xladdr = (struct xsctp_laddr *)(void *)(buf + 548 offset); 549 offset += sizeof(struct xsctp_laddr); 550 if (xladdr->last == 1) 551 break; 552 if (!opt_c) 553 continue; 554 laddr = calloc(1, sizeof(struct addr)); 555 if (laddr == NULL) 556 err(1, "malloc()"); 557 switch (xladdr->address.sa.sa_family) { 558 case AF_INET: 559 #define __IN_IS_ADDR_LOOPBACK(pina) \ 560 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 561 if (!__IN_IS_ADDR_LOOPBACK( 562 &xladdr->address.sin.sin_addr)) 563 local_all_loopback = 0; 564 #undef __IN_IS_ADDR_LOOPBACK 565 sockaddr(&laddr->address, AF_INET, 566 &xladdr->address.sin.sin_addr, 567 htons(xstcb->local_port)); 568 break; 569 case AF_INET6: 570 if (!IN6_IS_ADDR_LOOPBACK( 571 &xladdr->address.sin6.sin6_addr)) 572 local_all_loopback = 0; 573 sockaddr(&laddr->address, AF_INET6, 574 &xladdr->address.sin6.sin6_addr, 575 htons(xstcb->local_port)); 576 break; 577 default: 578 errx(1, 579 "address family %d not supported", 580 xladdr->address.sa.sa_family); 581 } 582 laddr->next = NULL; 583 if (prev_laddr == NULL) 584 sock->laddr = laddr; 585 else 586 prev_laddr->next = laddr; 587 prev_laddr = laddr; 588 } 589 prev_faddr = NULL; 590 foreign_all_loopback = 1; 591 while (offset < len) { 592 xraddr = (struct xsctp_raddr *)(void *)(buf + 593 offset); 594 offset += sizeof(struct xsctp_raddr); 595 if (xraddr->last == 1) 596 break; 597 if (!opt_c) 598 continue; 599 faddr = calloc(1, sizeof(struct addr)); 600 if (faddr == NULL) 601 err(1, "malloc()"); 602 switch (xraddr->address.sa.sa_family) { 603 case AF_INET: 604 #define __IN_IS_ADDR_LOOPBACK(pina) \ 605 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 606 if (!__IN_IS_ADDR_LOOPBACK( 607 &xraddr->address.sin.sin_addr)) 608 foreign_all_loopback = 0; 609 #undef __IN_IS_ADDR_LOOPBACK 610 sockaddr(&faddr->address, AF_INET, 611 &xraddr->address.sin.sin_addr, 612 htons(xstcb->remote_port)); 613 break; 614 case AF_INET6: 615 if (!IN6_IS_ADDR_LOOPBACK( 616 &xraddr->address.sin6.sin6_addr)) 617 foreign_all_loopback = 0; 618 sockaddr(&faddr->address, AF_INET6, 619 &xraddr->address.sin6.sin6_addr, 620 htons(xstcb->remote_port)); 621 break; 622 default: 623 errx(1, 624 "address family %d not supported", 625 xraddr->address.sa.sa_family); 626 } 627 faddr->encaps_port = xraddr->encaps_port; 628 faddr->state = xraddr->state; 629 faddr->next = NULL; 630 if (prev_faddr == NULL) 631 sock->faddr = faddr; 632 else 633 prev_faddr->next = faddr; 634 prev_faddr = faddr; 635 } 636 if (opt_c) { 637 if ((sock->vflag & vflag) && 638 (!opt_L || 639 !(local_all_loopback || 640 foreign_all_loopback))) { 641 RB_INSERT(socks_t, &socks, sock); 642 } else { 643 free_socket(sock); 644 } 645 } 646 } 647 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset); 648 offset += sizeof(struct xsctp_inpcb); 649 } 650 free(buf); 651 } 652 653 static void 654 gather_inet(int proto) 655 { 656 struct xinpgen *xig, *exig; 657 struct xinpcb *xip; 658 struct xtcpcb *xtp = NULL; 659 struct xsocket *so; 660 struct sock *sock; 661 struct addr *laddr, *faddr; 662 const char *varname, *protoname; 663 size_t len, bufsize; 664 void *buf; 665 int retry, vflag; 666 667 vflag = 0; 668 if (opt_4) 669 vflag |= INP_IPV4; 670 if (opt_6) 671 vflag |= INP_IPV6; 672 673 switch (proto) { 674 case IPPROTO_TCP: 675 varname = "net.inet.tcp.pcblist"; 676 protoname = "tcp"; 677 break; 678 case IPPROTO_UDP: 679 varname = "net.inet.udp.pcblist"; 680 protoname = "udp"; 681 break; 682 case IPPROTO_DIVERT: 683 varname = "net.inet.divert.pcblist"; 684 protoname = "div"; 685 break; 686 default: 687 errx(1, "protocol %d not supported", proto); 688 } 689 690 buf = NULL; 691 bufsize = 8192; 692 retry = 5; 693 do { 694 for (;;) { 695 if ((buf = realloc(buf, bufsize)) == NULL) 696 err(1, "realloc()"); 697 len = bufsize; 698 if (cap_sysctlbyname(capsysctl, varname, buf, &len, 699 NULL, 0) == 0) 700 break; 701 if (errno == ENOENT) 702 goto out; 703 if (errno != ENOMEM || len != bufsize) 704 err(1, "cap_sysctlbyname()"); 705 bufsize *= 2; 706 } 707 xig = (struct xinpgen *)buf; 708 exig = (struct xinpgen *)(void *) 709 ((char *)buf + len - sizeof *exig); 710 enforce_ksize(xig->xig_len, struct xinpgen); 711 enforce_ksize(exig->xig_len, struct xinpgen); 712 } while (xig->xig_gen != exig->xig_gen && retry--); 713 714 if (xig->xig_gen != exig->xig_gen && opt_v) 715 warnx("warning: data may be inconsistent"); 716 717 for (;;) { 718 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); 719 if (xig >= exig) 720 break; 721 switch (proto) { 722 case IPPROTO_TCP: 723 xtp = (struct xtcpcb *)xig; 724 xip = &xtp->xt_inp; 725 if (!check_ksize(xtp->xt_len, struct xtcpcb)) 726 goto out; 727 protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp"; 728 break; 729 case IPPROTO_UDP: 730 case IPPROTO_DIVERT: 731 xip = (struct xinpcb *)xig; 732 if (!check_ksize(xip->xi_len, struct xinpcb)) 733 goto out; 734 break; 735 default: 736 errx(1, "protocol %d not supported", proto); 737 } 738 so = &xip->xi_socket; 739 if ((xip->inp_vflag & vflag) == 0) 740 continue; 741 if (xip->inp_vflag & INP_IPV4) { 742 if ((xip->inp_fport == 0 && !opt_l) || 743 (xip->inp_fport != 0 && !opt_c)) 744 continue; 745 #define __IN_IS_ADDR_LOOPBACK(pina) \ 746 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 747 if (opt_L && 748 (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) || 749 __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr))) 750 continue; 751 #undef __IN_IS_ADDR_LOOPBACK 752 } else if (xip->inp_vflag & INP_IPV6) { 753 if ((xip->inp_fport == 0 && !opt_l) || 754 (xip->inp_fport != 0 && !opt_c)) 755 continue; 756 if (opt_L && 757 (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) || 758 IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr))) 759 continue; 760 } else { 761 if (opt_v) 762 warnx("invalid vflag 0x%x", xip->inp_vflag); 763 continue; 764 } 765 if ((sock = calloc(1, sizeof(*sock))) == NULL) 766 err(1, "malloc()"); 767 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 768 err(1, "malloc()"); 769 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 770 err(1, "malloc()"); 771 sock->socket = so->xso_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 pos += xprintf("[%lu %d]", 1171 (u_long)f->xf_pid, f->xf_fd); 1172 } else 1173 pos += printaddr(&p->laddr->address); 1174 } 1175 /* Remote peer(s) connect(2)ed to us, if any. */ 1176 if (faddr->firstref != 0) { 1177 struct sock *p; 1178 struct file *f; 1179 kvaddr_t ref = faddr->firstref; 1180 bool fref = true; 1181 1182 pos += xprintf(" <- "); 1183 1184 while ((p = RB_FIND(pcbs_t, &pcbs, 1185 &(struct sock){ .pcb = ref })) != 0) { 1186 f = RB_FIND(files_t, &ftree, 1187 &(struct file){ .xf_data = 1188 p->socket }); 1189 pos += xprintf("%s[%lu %d]", 1190 fref ? "" : ",", 1191 (u_long)f->xf_pid, f->xf_fd); 1192 ref = p->faddr->nextref; 1193 fref = false; 1194 } 1195 } 1196 offset += opt_w ? 92 : 44; 1197 break; 1198 default: 1199 abort(); 1200 } 1201 if (opt_i) { 1202 if (s->proto == IPPROTO_TCP || 1203 s->proto == IPPROTO_UDP) { 1204 while (pos < offset) 1205 pos += xprintf(" "); 1206 pos += xprintf("%" PRIu64, s->inp_gencnt); 1207 } 1208 offset += 9; 1209 } 1210 if (opt_U) { 1211 if (faddr != NULL && 1212 ((s->proto == IPPROTO_SCTP && 1213 s->state != SCTP_CLOSED && 1214 s->state != SCTP_BOUND && 1215 s->state != SCTP_LISTEN) || 1216 (s->proto == IPPROTO_TCP && 1217 s->state != TCPS_CLOSED && 1218 s->state != TCPS_LISTEN))) { 1219 while (pos < offset) 1220 pos += xprintf(" "); 1221 pos += xprintf("%u", 1222 ntohs(faddr->encaps_port)); 1223 } 1224 offset += 7; 1225 } 1226 if (opt_s) { 1227 if (faddr != NULL && 1228 s->proto == IPPROTO_SCTP && 1229 s->state != SCTP_CLOSED && 1230 s->state != SCTP_BOUND && 1231 s->state != SCTP_LISTEN) { 1232 while (pos < offset) 1233 pos += xprintf(" "); 1234 pos += xprintf("%s", 1235 sctp_path_state(faddr->state)); 1236 } 1237 offset += 13; 1238 } 1239 if (first) { 1240 if (opt_s) { 1241 if (s->proto == IPPROTO_SCTP || 1242 s->proto == IPPROTO_TCP) { 1243 while (pos < offset) 1244 pos += xprintf(" "); 1245 switch (s->proto) { 1246 case IPPROTO_SCTP: 1247 pos += xprintf("%s", 1248 sctp_conn_state(s->state)); 1249 break; 1250 case IPPROTO_TCP: 1251 if (s->state >= 0 && 1252 s->state < TCP_NSTATES) 1253 pos += xprintf("%s", 1254 tcpstates[s->state]); 1255 else 1256 pos += xprintf("?"); 1257 break; 1258 } 1259 } 1260 offset += 13; 1261 } 1262 if (opt_S) { 1263 if (s->proto == IPPROTO_TCP) { 1264 while (pos < offset) 1265 pos += xprintf(" "); 1266 pos += xprintf("%.*s", 1267 TCP_FUNCTION_NAME_LEN_MAX, 1268 s->stack); 1269 } 1270 offset += TCP_FUNCTION_NAME_LEN_MAX + 1; 1271 } 1272 if (opt_C) { 1273 if (s->proto == IPPROTO_TCP) { 1274 while (pos < offset) 1275 pos += xprintf(" "); 1276 xprintf("%.*s", TCP_CA_NAME_MAX, s->cc); 1277 } 1278 offset += TCP_CA_NAME_MAX + 1; 1279 } 1280 } 1281 if (laddr != NULL) 1282 laddr = laddr->next; 1283 if (faddr != NULL) 1284 faddr = faddr->next; 1285 if ((laddr != NULL) || (faddr != NULL)) { 1286 xprintf("\n"); 1287 pos = 0; 1288 } 1289 first = 0; 1290 } 1291 xprintf("\n"); 1292 } 1293 1294 static void 1295 display(void) 1296 { 1297 struct passwd *pwd; 1298 struct file *xf; 1299 struct sock *s; 1300 int n, pos; 1301 1302 if (opt_q != 1) { 1303 printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s", 1304 "USER", "COMMAND", "PID", "FD", "PROTO", 1305 opt_w ? 45 : 21, "LOCAL ADDRESS", 1306 opt_w ? 45 : 21, "FOREIGN ADDRESS"); 1307 if (opt_i) 1308 printf(" %-8s", "ID"); 1309 if (opt_U) 1310 printf(" %-6s", "ENCAPS"); 1311 if (opt_s) { 1312 printf(" %-12s", "PATH STATE"); 1313 printf(" %-12s", "CONN STATE"); 1314 } 1315 if (opt_S) 1316 printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX, 1317 TCP_FUNCTION_NAME_LEN_MAX, "STACK"); 1318 if (opt_C) 1319 printf(" %-.*s", TCP_CA_NAME_MAX, "CC"); 1320 printf("\n"); 1321 } 1322 cap_setpassent(cappwd, 1); 1323 for (xf = files, n = 0; n < nfiles; ++n, ++xf) { 1324 if (xf->xf_data == 0) 1325 continue; 1326 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid)) 1327 continue; 1328 s = RB_FIND(socks_t, &socks, 1329 &(struct sock){ .socket = xf->xf_data}); 1330 if (s != NULL && check_ports(s)) { 1331 s->shown = 1; 1332 pos = 0; 1333 if (opt_n || 1334 (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL) 1335 pos += xprintf("%lu ", (u_long)xf->xf_uid); 1336 else 1337 pos += xprintf("%s ", pwd->pw_name); 1338 while (pos < 9) 1339 pos += xprintf(" "); 1340 pos += xprintf("%.10s", getprocname(xf->xf_pid)); 1341 while (pos < 20) 1342 pos += xprintf(" "); 1343 pos += xprintf("%5lu ", (u_long)xf->xf_pid); 1344 while (pos < 26) 1345 pos += xprintf(" "); 1346 pos += xprintf("%-3d ", xf->xf_fd); 1347 displaysock(s, pos); 1348 } 1349 } 1350 if (opt_j >= 0) 1351 return; 1352 SLIST_FOREACH(s, &nosocks, socket_list) { 1353 if (!check_ports(s)) 1354 continue; 1355 pos = xprintf("%-8s %-10s %-5s %-2s ", 1356 "?", "?", "?", "?"); 1357 displaysock(s, pos); 1358 } 1359 RB_FOREACH(s, socks_t, &socks) { 1360 if (s->shown) 1361 continue; 1362 if (!check_ports(s)) 1363 continue; 1364 pos = xprintf("%-8s %-10s %-5s %-2s ", 1365 "?", "?", "?", "?"); 1366 displaysock(s, pos); 1367 } 1368 } 1369 1370 static int 1371 set_default_protos(void) 1372 { 1373 struct protoent *prot; 1374 const char *pname; 1375 size_t pindex; 1376 1377 init_protos(default_numprotos); 1378 1379 for (pindex = 0; pindex < default_numprotos; pindex++) { 1380 pname = default_protos[pindex]; 1381 prot = cap_getprotobyname(capnetdb, pname); 1382 if (prot == NULL) 1383 err(1, "cap_getprotobyname: %s", pname); 1384 protos[pindex] = prot->p_proto; 1385 } 1386 numprotos = pindex; 1387 return (pindex); 1388 } 1389 1390 /* 1391 * Return the vnet property of the jail, or -1 on error. 1392 */ 1393 static int 1394 jail_getvnet(int jid) 1395 { 1396 struct iovec jiov[6]; 1397 int vnet; 1398 size_t len = sizeof(vnet); 1399 1400 if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0) 1401 return (0); 1402 1403 vnet = -1; 1404 jiov[0].iov_base = __DECONST(char *, "jid"); 1405 jiov[0].iov_len = sizeof("jid"); 1406 jiov[1].iov_base = &jid; 1407 jiov[1].iov_len = sizeof(jid); 1408 jiov[2].iov_base = __DECONST(char *, "vnet"); 1409 jiov[2].iov_len = sizeof("vnet"); 1410 jiov[3].iov_base = &vnet; 1411 jiov[3].iov_len = sizeof(vnet); 1412 jiov[4].iov_base = __DECONST(char *, "errmsg"); 1413 jiov[4].iov_len = sizeof("errmsg"); 1414 jiov[5].iov_base = jail_errmsg; 1415 jiov[5].iov_len = JAIL_ERRMSGLEN; 1416 jail_errmsg[0] = '\0'; 1417 if (jail_get(jiov, nitems(jiov), 0) < 0) { 1418 if (!jail_errmsg[0]) 1419 snprintf(jail_errmsg, JAIL_ERRMSGLEN, 1420 "jail_get: %s", strerror(errno)); 1421 return (-1); 1422 } 1423 return (vnet); 1424 } 1425 1426 static void 1427 usage(void) 1428 { 1429 fprintf(stderr, 1430 "usage: sockstat [-46CciLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]\n"); 1431 exit(1); 1432 } 1433 1434 int 1435 main(int argc, char *argv[]) 1436 { 1437 cap_channel_t *capcas; 1438 cap_net_limit_t *limit; 1439 const char *pwdcmds[] = { "setpassent", "getpwuid" }; 1440 const char *pwdfields[] = { "pw_name" }; 1441 int protos_defined = -1; 1442 int o, i; 1443 1444 opt_j = -1; 1445 while ((o = getopt(argc, argv, "46Ccij:Llnp:P:qSsUuvw")) != -1) 1446 switch (o) { 1447 case '4': 1448 opt_4 = 1; 1449 break; 1450 case '6': 1451 opt_6 = 1; 1452 break; 1453 case 'C': 1454 opt_C = 1; 1455 break; 1456 case 'c': 1457 opt_c = 1; 1458 break; 1459 case 'i': 1460 opt_i = 1; 1461 break; 1462 case 'j': 1463 opt_j = jail_getid(optarg); 1464 if (opt_j < 0) 1465 errx(1, "jail_getid: %s", jail_errmsg); 1466 break; 1467 case 'L': 1468 opt_L = 1; 1469 break; 1470 case 'l': 1471 opt_l = 1; 1472 break; 1473 case 'n': 1474 opt_n = 1; 1475 break; 1476 case 'p': 1477 parse_ports(optarg); 1478 break; 1479 case 'P': 1480 protos_defined = parse_protos(optarg); 1481 break; 1482 case 'q': 1483 opt_q = 1; 1484 break; 1485 case 'S': 1486 opt_S = 1; 1487 break; 1488 case 's': 1489 opt_s = 1; 1490 break; 1491 case 'U': 1492 opt_U = 1; 1493 break; 1494 case 'u': 1495 opt_u = 1; 1496 break; 1497 case 'v': 1498 ++opt_v; 1499 break; 1500 case 'w': 1501 opt_w = 1; 1502 break; 1503 default: 1504 usage(); 1505 } 1506 1507 argc -= optind; 1508 argv += optind; 1509 1510 if (argc > 0) 1511 usage(); 1512 1513 if (opt_j > 0) { 1514 switch (jail_getvnet(opt_j)) { 1515 case -1: 1516 errx(2, "jail_getvnet: %s", jail_errmsg); 1517 case JAIL_SYS_NEW: 1518 if (jail_attach(opt_j) < 0) 1519 err(3, "jail_attach()"); 1520 /* Set back to -1 for normal output in vnet jail. */ 1521 opt_j = -1; 1522 break; 1523 default: 1524 break; 1525 } 1526 } 1527 1528 capcas = cap_init(); 1529 if (capcas == NULL) 1530 err(1, "Unable to contact Casper"); 1531 if (caph_enter_casper() < 0) 1532 err(1, "Unable to enter capability mode"); 1533 capnet = cap_service_open(capcas, "system.net"); 1534 if (capnet == NULL) 1535 err(1, "Unable to open system.net service"); 1536 capnetdb = cap_service_open(capcas, "system.netdb"); 1537 if (capnetdb == NULL) 1538 err(1, "Unable to open system.netdb service"); 1539 capsysctl = cap_service_open(capcas, "system.sysctl"); 1540 if (capsysctl == NULL) 1541 err(1, "Unable to open system.sysctl service"); 1542 cappwd = cap_service_open(capcas, "system.pwd"); 1543 if (cappwd == NULL) 1544 err(1, "Unable to open system.pwd service"); 1545 cap_close(capcas); 1546 limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME); 1547 if (limit == NULL) 1548 err(1, "Unable to init cap_net limits"); 1549 if (cap_net_limit(limit) < 0) 1550 err(1, "Unable to apply limits"); 1551 if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0) 1552 err(1, "Unable to apply pwd commands limits"); 1553 if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0) 1554 err(1, "Unable to apply pwd commands limits"); 1555 1556 if ((!opt_4 && !opt_6) && protos_defined != -1) 1557 opt_4 = opt_6 = 1; 1558 if (!opt_4 && !opt_6 && !opt_u) 1559 opt_4 = opt_6 = opt_u = 1; 1560 if ((opt_4 || opt_6) && protos_defined == -1) 1561 protos_defined = set_default_protos(); 1562 if (!opt_c && !opt_l) 1563 opt_c = opt_l = 1; 1564 1565 if (opt_4 || opt_6) { 1566 for (i = 0; i < protos_defined; i++) 1567 if (protos[i] == IPPROTO_SCTP) 1568 gather_sctp(); 1569 else 1570 gather_inet(protos[i]); 1571 } 1572 1573 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) { 1574 gather_unix(SOCK_STREAM); 1575 gather_unix(SOCK_DGRAM); 1576 gather_unix(SOCK_SEQPACKET); 1577 } 1578 getfiles(); 1579 display(); 1580 exit(0); 1581 } 1582