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