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/socket.h> 36 #include <sys/socketvar.h> 37 #include <sys/sysctl.h> 38 #include <sys/file.h> 39 #include <sys/user.h> 40 41 #include <sys/un.h> 42 #define _WANT_UNPCB 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 <ctype.h> 58 #include <err.h> 59 #include <errno.h> 60 #include <netdb.h> 61 #include <pwd.h> 62 #include <stdarg.h> 63 #include <stdio.h> 64 #include <stdlib.h> 65 #include <string.h> 66 #include <unistd.h> 67 68 #define sstosin(ss) ((struct sockaddr_in *)(ss)) 69 #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) 70 #define sstosun(ss) ((struct sockaddr_un *)(ss)) 71 #define sstosa(ss) ((struct sockaddr *)(ss)) 72 73 static int opt_4; /* Show IPv4 sockets */ 74 static int opt_6; /* Show IPv6 sockets */ 75 static int opt_c; /* Show connected sockets */ 76 static int opt_j; /* Show specified jail */ 77 static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */ 78 static int opt_l; /* Show listening sockets */ 79 static int opt_S; /* Show protocol stack if applicable */ 80 static int opt_s; /* Show protocol state if applicable */ 81 static int opt_U; /* Show remote UDP encapsulation port number */ 82 static int opt_u; /* Show Unix domain sockets */ 83 static int opt_v; /* Verbose mode */ 84 static int opt_w; /* Wide print area for addresses */ 85 86 /* 87 * Default protocols to use if no -P was defined. 88 */ 89 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" }; 90 static size_t default_numprotos = nitems(default_protos); 91 92 static int *protos; /* protocols to use */ 93 static size_t numprotos; /* allocated size of protos[] */ 94 95 static int *ports; 96 97 #define INT_BIT (sizeof(int)*CHAR_BIT) 98 #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0) 99 #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT))) 100 101 struct addr { 102 struct sockaddr_storage address; 103 unsigned int encaps_port; 104 int state; 105 struct addr *next; 106 }; 107 108 struct sock { 109 void *socket; 110 void *pcb; 111 int shown; 112 int vflag; 113 int family; 114 int proto; 115 int state; 116 const char *protoname; 117 char stack[TCP_FUNCTION_NAME_LEN_MAX]; 118 struct addr *laddr; 119 struct addr *faddr; 120 struct sock *next; 121 }; 122 123 #define HASHSIZE 1009 124 static struct sock *sockhash[HASHSIZE]; 125 126 static struct xfile *xfiles; 127 static int nxfiles; 128 129 static int 130 xprintf(const char *fmt, ...) 131 { 132 va_list ap; 133 int len; 134 135 va_start(ap, fmt); 136 len = vprintf(fmt, ap); 137 va_end(ap); 138 if (len < 0) 139 err(1, "printf()"); 140 return (len); 141 } 142 143 static int 144 get_proto_type(const char *proto) 145 { 146 struct protoent *pent; 147 148 if (strlen(proto) == 0) 149 return (0); 150 pent = getprotobyname(proto); 151 if (pent == NULL) { 152 warn("getprotobyname"); 153 return (-1); 154 } 155 return (pent->p_proto); 156 } 157 158 static void 159 init_protos(int num) 160 { 161 int proto_count = 0; 162 163 if (num > 0) { 164 proto_count = num; 165 } else { 166 /* Find the maximum number of possible protocols. */ 167 while (getprotoent() != NULL) 168 proto_count++; 169 endprotoent(); 170 } 171 172 if ((protos = malloc(sizeof(int) * proto_count)) == NULL) 173 err(1, "malloc"); 174 numprotos = proto_count; 175 } 176 177 static int 178 parse_protos(char *protospec) 179 { 180 char *prot; 181 int proto_type, proto_index; 182 183 if (protospec == NULL) 184 return (-1); 185 186 init_protos(0); 187 proto_index = 0; 188 while ((prot = strsep(&protospec, ",")) != NULL) { 189 if (strlen(prot) == 0) 190 continue; 191 proto_type = get_proto_type(prot); 192 if (proto_type != -1) 193 protos[proto_index++] = proto_type; 194 } 195 numprotos = proto_index; 196 return (proto_index); 197 } 198 199 static void 200 parse_ports(const char *portspec) 201 { 202 const char *p, *q; 203 int port, end; 204 205 if (ports == NULL) 206 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL) 207 err(1, "calloc()"); 208 p = portspec; 209 while (*p != '\0') { 210 if (!isdigit(*p)) 211 errx(1, "syntax error in port range"); 212 for (q = p; *q != '\0' && isdigit(*q); ++q) 213 /* nothing */ ; 214 for (port = 0; p < q; ++p) 215 port = port * 10 + digittoint(*p); 216 if (port < 0 || port > 65535) 217 errx(1, "invalid port number"); 218 SET_PORT(port); 219 switch (*p) { 220 case '-': 221 ++p; 222 break; 223 case ',': 224 ++p; 225 /* fall through */ 226 case '\0': 227 default: 228 continue; 229 } 230 for (q = p; *q != '\0' && isdigit(*q); ++q) 231 /* nothing */ ; 232 for (end = 0; p < q; ++p) 233 end = end * 10 + digittoint(*p); 234 if (end < port || end > 65535) 235 errx(1, "invalid port number"); 236 while (port++ < end) 237 SET_PORT(port); 238 if (*p == ',') 239 ++p; 240 } 241 } 242 243 static void 244 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port) 245 { 246 struct sockaddr_in *sin4; 247 struct sockaddr_in6 *sin6; 248 249 bzero(ss, sizeof(*ss)); 250 switch (af) { 251 case AF_INET: 252 sin4 = sstosin(ss); 253 sin4->sin_len = sizeof(*sin4); 254 sin4->sin_family = af; 255 sin4->sin_port = port; 256 sin4->sin_addr = *(struct in_addr *)addr; 257 break; 258 case AF_INET6: 259 sin6 = sstosin6(ss); 260 sin6->sin6_len = sizeof(*sin6); 261 sin6->sin6_family = af; 262 sin6->sin6_port = port; 263 sin6->sin6_addr = *(struct in6_addr *)addr; 264 #define s6_addr16 __u6_addr.__u6_addr16 265 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 266 sin6->sin6_scope_id = 267 ntohs(sin6->sin6_addr.s6_addr16[1]); 268 sin6->sin6_addr.s6_addr16[1] = 0; 269 } 270 break; 271 default: 272 abort(); 273 } 274 } 275 276 static void 277 free_socket(struct sock *sock) 278 { 279 struct addr *cur, *next; 280 281 cur = sock->laddr; 282 while (cur != NULL) { 283 next = cur->next; 284 free(cur); 285 cur = next; 286 } 287 cur = sock->faddr; 288 while (cur != NULL) { 289 next = cur->next; 290 free(cur); 291 cur = next; 292 } 293 free(sock); 294 } 295 296 static void 297 gather_sctp(void) 298 { 299 struct sock *sock; 300 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr; 301 struct xsctp_inpcb *xinpcb; 302 struct xsctp_tcb *xstcb; 303 struct xsctp_raddr *xraddr; 304 struct xsctp_laddr *xladdr; 305 const char *varname; 306 size_t len, offset; 307 char *buf; 308 int hash, vflag; 309 int no_stcb, local_all_loopback, foreign_all_loopback; 310 311 vflag = 0; 312 if (opt_4) 313 vflag |= INP_IPV4; 314 if (opt_6) 315 vflag |= INP_IPV6; 316 317 varname = "net.inet.sctp.assoclist"; 318 if (sysctlbyname(varname, 0, &len, 0, 0) < 0) { 319 if (errno != ENOENT) 320 err(1, "sysctlbyname()"); 321 return; 322 } 323 if ((buf = (char *)malloc(len)) == NULL) { 324 err(1, "malloc()"); 325 return; 326 } 327 if (sysctlbyname(varname, buf, &len, 0, 0) < 0) { 328 err(1, "sysctlbyname()"); 329 free(buf); 330 return; 331 } 332 xinpcb = (struct xsctp_inpcb *)(void *)buf; 333 offset = sizeof(struct xsctp_inpcb); 334 while ((offset < len) && (xinpcb->last == 0)) { 335 if ((sock = calloc(1, sizeof *sock)) == NULL) 336 err(1, "malloc()"); 337 sock->socket = xinpcb->socket; 338 sock->proto = IPPROTO_SCTP; 339 sock->protoname = "sctp"; 340 if (xinpcb->maxqlen == 0) 341 sock->state = SCTP_CLOSED; 342 else 343 sock->state = SCTP_LISTEN; 344 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 345 sock->family = AF_INET6; 346 /* 347 * Currently there is no way to distinguish between 348 * IPv6 only sockets or dual family sockets. 349 * So mark it as dual socket. 350 */ 351 sock->vflag = INP_IPV6 | INP_IPV4; 352 } else { 353 sock->family = AF_INET; 354 sock->vflag = INP_IPV4; 355 } 356 prev_laddr = NULL; 357 local_all_loopback = 1; 358 while (offset < len) { 359 xladdr = (struct xsctp_laddr *)(void *)(buf + offset); 360 offset += sizeof(struct xsctp_laddr); 361 if (xladdr->last == 1) 362 break; 363 if ((laddr = calloc(1, sizeof(struct addr))) == NULL) 364 err(1, "malloc()"); 365 switch (xladdr->address.sa.sa_family) { 366 case AF_INET: 367 #define __IN_IS_ADDR_LOOPBACK(pina) \ 368 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 369 if (!__IN_IS_ADDR_LOOPBACK( 370 &xladdr->address.sin.sin_addr)) 371 local_all_loopback = 0; 372 #undef __IN_IS_ADDR_LOOPBACK 373 sockaddr(&laddr->address, AF_INET, 374 &xladdr->address.sin.sin_addr, 375 htons(xinpcb->local_port)); 376 break; 377 case AF_INET6: 378 if (!IN6_IS_ADDR_LOOPBACK( 379 &xladdr->address.sin6.sin6_addr)) 380 local_all_loopback = 0; 381 sockaddr(&laddr->address, AF_INET6, 382 &xladdr->address.sin6.sin6_addr, 383 htons(xinpcb->local_port)); 384 break; 385 default: 386 errx(1, "address family %d not supported", 387 xladdr->address.sa.sa_family); 388 } 389 laddr->next = NULL; 390 if (prev_laddr == NULL) 391 sock->laddr = laddr; 392 else 393 prev_laddr->next = laddr; 394 prev_laddr = laddr; 395 } 396 if (sock->laddr == NULL) { 397 if ((sock->laddr = 398 calloc(1, sizeof(struct addr))) == NULL) 399 err(1, "malloc()"); 400 sock->laddr->address.ss_family = sock->family; 401 if (sock->family == AF_INET) 402 sock->laddr->address.ss_len = 403 sizeof(struct sockaddr_in); 404 else 405 sock->laddr->address.ss_len = 406 sizeof(struct sockaddr_in6); 407 local_all_loopback = 0; 408 } 409 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL) 410 err(1, "malloc()"); 411 sock->faddr->address.ss_family = sock->family; 412 if (sock->family == AF_INET) 413 sock->faddr->address.ss_len = 414 sizeof(struct sockaddr_in); 415 else 416 sock->faddr->address.ss_len = 417 sizeof(struct sockaddr_in6); 418 no_stcb = 1; 419 while (offset < len) { 420 xstcb = (struct xsctp_tcb *)(void *)(buf + offset); 421 offset += sizeof(struct xsctp_tcb); 422 if (no_stcb) { 423 if (opt_l && (sock->vflag & vflag) && 424 (!opt_L || !local_all_loopback) && 425 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) || 426 (xstcb->last == 1))) { 427 hash = (int)((uintptr_t)sock->socket % 428 HASHSIZE); 429 sock->next = sockhash[hash]; 430 sockhash[hash] = sock; 431 } else { 432 free_socket(sock); 433 } 434 } 435 if (xstcb->last == 1) 436 break; 437 no_stcb = 0; 438 if (opt_c) { 439 if ((sock = calloc(1, sizeof *sock)) == NULL) 440 err(1, "malloc()"); 441 sock->socket = xinpcb->socket; 442 sock->proto = IPPROTO_SCTP; 443 sock->protoname = "sctp"; 444 sock->state = (int)xstcb->state; 445 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 446 sock->family = AF_INET6; 447 /* 448 * Currently there is no way to distinguish 449 * between IPv6 only sockets or dual family 450 * sockets. So mark it as dual socket. 451 */ 452 sock->vflag = INP_IPV6 | INP_IPV4; 453 } else { 454 sock->family = AF_INET; 455 sock->vflag = INP_IPV4; 456 } 457 } 458 prev_laddr = NULL; 459 local_all_loopback = 1; 460 while (offset < len) { 461 xladdr = (struct xsctp_laddr *)(void *)(buf + 462 offset); 463 offset += sizeof(struct xsctp_laddr); 464 if (xladdr->last == 1) 465 break; 466 if (!opt_c) 467 continue; 468 laddr = calloc(1, sizeof(struct addr)); 469 if (laddr == NULL) 470 err(1, "malloc()"); 471 switch (xladdr->address.sa.sa_family) { 472 case AF_INET: 473 #define __IN_IS_ADDR_LOOPBACK(pina) \ 474 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 475 if (!__IN_IS_ADDR_LOOPBACK( 476 &xladdr->address.sin.sin_addr)) 477 local_all_loopback = 0; 478 #undef __IN_IS_ADDR_LOOPBACK 479 sockaddr(&laddr->address, AF_INET, 480 &xladdr->address.sin.sin_addr, 481 htons(xstcb->local_port)); 482 break; 483 case AF_INET6: 484 if (!IN6_IS_ADDR_LOOPBACK( 485 &xladdr->address.sin6.sin6_addr)) 486 local_all_loopback = 0; 487 sockaddr(&laddr->address, AF_INET6, 488 &xladdr->address.sin6.sin6_addr, 489 htons(xstcb->local_port)); 490 break; 491 default: 492 errx(1, 493 "address family %d not supported", 494 xladdr->address.sa.sa_family); 495 } 496 laddr->next = NULL; 497 if (prev_laddr == NULL) 498 sock->laddr = laddr; 499 else 500 prev_laddr->next = laddr; 501 prev_laddr = laddr; 502 } 503 prev_faddr = NULL; 504 foreign_all_loopback = 1; 505 while (offset < len) { 506 xraddr = (struct xsctp_raddr *)(void *)(buf + 507 offset); 508 offset += sizeof(struct xsctp_raddr); 509 if (xraddr->last == 1) 510 break; 511 if (!opt_c) 512 continue; 513 faddr = calloc(1, sizeof(struct addr)); 514 if (faddr == NULL) 515 err(1, "malloc()"); 516 switch (xraddr->address.sa.sa_family) { 517 case AF_INET: 518 #define __IN_IS_ADDR_LOOPBACK(pina) \ 519 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 520 if (!__IN_IS_ADDR_LOOPBACK( 521 &xraddr->address.sin.sin_addr)) 522 foreign_all_loopback = 0; 523 #undef __IN_IS_ADDR_LOOPBACK 524 sockaddr(&faddr->address, AF_INET, 525 &xraddr->address.sin.sin_addr, 526 htons(xstcb->remote_port)); 527 break; 528 case AF_INET6: 529 if (!IN6_IS_ADDR_LOOPBACK( 530 &xraddr->address.sin6.sin6_addr)) 531 foreign_all_loopback = 0; 532 sockaddr(&faddr->address, AF_INET6, 533 &xraddr->address.sin6.sin6_addr, 534 htons(xstcb->remote_port)); 535 break; 536 default: 537 errx(1, 538 "address family %d not supported", 539 xraddr->address.sa.sa_family); 540 } 541 faddr->encaps_port = xraddr->encaps_port; 542 faddr->state = xraddr->state; 543 faddr->next = NULL; 544 if (prev_faddr == NULL) 545 sock->faddr = faddr; 546 else 547 prev_faddr->next = faddr; 548 prev_faddr = faddr; 549 } 550 if (opt_c) { 551 if ((sock->vflag & vflag) && 552 (!opt_L || 553 !(local_all_loopback || 554 foreign_all_loopback))) { 555 hash = (int)((uintptr_t)sock->socket % 556 HASHSIZE); 557 sock->next = sockhash[hash]; 558 sockhash[hash] = sock; 559 } else { 560 free_socket(sock); 561 } 562 } 563 } 564 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset); 565 offset += sizeof(struct xsctp_inpcb); 566 } 567 free(buf); 568 } 569 570 static void 571 gather_inet(int proto) 572 { 573 struct xinpgen *xig, *exig; 574 struct xinpcb *xip; 575 struct xtcpcb *xtp = NULL; 576 struct xsocket *so; 577 struct sock *sock; 578 struct addr *laddr, *faddr; 579 const char *varname, *protoname; 580 size_t len, bufsize; 581 void *buf; 582 int hash, retry, vflag; 583 584 vflag = 0; 585 if (opt_4) 586 vflag |= INP_IPV4; 587 if (opt_6) 588 vflag |= INP_IPV6; 589 590 switch (proto) { 591 case IPPROTO_TCP: 592 varname = "net.inet.tcp.pcblist"; 593 protoname = "tcp"; 594 break; 595 case IPPROTO_UDP: 596 varname = "net.inet.udp.pcblist"; 597 protoname = "udp"; 598 break; 599 case IPPROTO_DIVERT: 600 varname = "net.inet.divert.pcblist"; 601 protoname = "div"; 602 break; 603 default: 604 errx(1, "protocol %d not supported", proto); 605 } 606 607 buf = NULL; 608 bufsize = 8192; 609 retry = 5; 610 do { 611 for (;;) { 612 if ((buf = realloc(buf, bufsize)) == NULL) 613 err(1, "realloc()"); 614 len = bufsize; 615 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 616 break; 617 if (errno == ENOENT) 618 goto out; 619 if (errno != ENOMEM || len != bufsize) 620 err(1, "sysctlbyname()"); 621 bufsize *= 2; 622 } 623 xig = (struct xinpgen *)buf; 624 exig = (struct xinpgen *)(void *) 625 ((char *)buf + len - sizeof *exig); 626 if (xig->xig_len != sizeof *xig || 627 exig->xig_len != sizeof *exig) 628 errx(1, "struct xinpgen size mismatch"); 629 } while (xig->xig_gen != exig->xig_gen && retry--); 630 631 if (xig->xig_gen != exig->xig_gen && opt_v) 632 warnx("warning: data may be inconsistent"); 633 634 for (;;) { 635 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); 636 if (xig >= exig) 637 break; 638 switch (proto) { 639 case IPPROTO_TCP: 640 xtp = (struct xtcpcb *)xig; 641 xip = &xtp->xt_inp; 642 if (xtp->xt_len != sizeof(*xtp)) { 643 warnx("struct xtcpcb size mismatch"); 644 goto out; 645 } 646 protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp"; 647 break; 648 case IPPROTO_UDP: 649 case IPPROTO_DIVERT: 650 xip = (struct xinpcb *)xig; 651 if (xip->xi_len != sizeof(*xip)) { 652 warnx("struct xinpcb size mismatch"); 653 goto out; 654 } 655 break; 656 default: 657 errx(1, "protocol %d not supported", proto); 658 } 659 so = &xip->xi_socket; 660 if ((xip->inp_vflag & vflag) == 0) 661 continue; 662 if (xip->inp_vflag & INP_IPV4) { 663 if ((xip->inp_fport == 0 && !opt_l) || 664 (xip->inp_fport != 0 && !opt_c)) 665 continue; 666 #define __IN_IS_ADDR_LOOPBACK(pina) \ 667 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 668 if (opt_L && 669 (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) || 670 __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr))) 671 continue; 672 #undef __IN_IS_ADDR_LOOPBACK 673 } else if (xip->inp_vflag & INP_IPV6) { 674 if ((xip->inp_fport == 0 && !opt_l) || 675 (xip->inp_fport != 0 && !opt_c)) 676 continue; 677 if (opt_L && 678 (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) || 679 IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr))) 680 continue; 681 } else { 682 if (opt_v) 683 warnx("invalid vflag 0x%x", xip->inp_vflag); 684 continue; 685 } 686 if ((sock = calloc(1, sizeof(*sock))) == NULL) 687 err(1, "malloc()"); 688 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 689 err(1, "malloc()"); 690 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 691 err(1, "malloc()"); 692 sock->socket = so->xso_so; 693 sock->proto = proto; 694 if (xip->inp_vflag & INP_IPV4) { 695 sock->family = AF_INET; 696 sockaddr(&laddr->address, sock->family, 697 &xip->inp_laddr, xip->inp_lport); 698 sockaddr(&faddr->address, sock->family, 699 &xip->inp_faddr, xip->inp_fport); 700 } else if (xip->inp_vflag & INP_IPV6) { 701 sock->family = AF_INET6; 702 sockaddr(&laddr->address, sock->family, 703 &xip->in6p_laddr, xip->inp_lport); 704 sockaddr(&faddr->address, sock->family, 705 &xip->in6p_faddr, xip->inp_fport); 706 } 707 laddr->next = NULL; 708 faddr->next = NULL; 709 sock->laddr = laddr; 710 sock->faddr = faddr; 711 sock->vflag = xip->inp_vflag; 712 if (proto == IPPROTO_TCP) { 713 sock->state = xtp->t_state; 714 memcpy(sock->stack, xtp->xt_stack, 715 TCP_FUNCTION_NAME_LEN_MAX); 716 } 717 sock->protoname = protoname; 718 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 719 sock->next = sockhash[hash]; 720 sockhash[hash] = sock; 721 } 722 out: 723 free(buf); 724 } 725 726 static void 727 gather_unix(int proto) 728 { 729 struct xunpgen *xug, *exug; 730 struct xunpcb *xup; 731 struct sock *sock; 732 struct addr *laddr, *faddr; 733 const char *varname, *protoname; 734 size_t len, bufsize; 735 void *buf; 736 int hash, retry; 737 738 switch (proto) { 739 case SOCK_STREAM: 740 varname = "net.local.stream.pcblist"; 741 protoname = "stream"; 742 break; 743 case SOCK_DGRAM: 744 varname = "net.local.dgram.pcblist"; 745 protoname = "dgram"; 746 break; 747 case SOCK_SEQPACKET: 748 varname = "net.local.seqpacket.pcblist"; 749 protoname = "seqpac"; 750 break; 751 default: 752 abort(); 753 } 754 buf = NULL; 755 bufsize = 8192; 756 retry = 5; 757 do { 758 for (;;) { 759 if ((buf = realloc(buf, bufsize)) == NULL) 760 err(1, "realloc()"); 761 len = bufsize; 762 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 763 break; 764 if (errno != ENOMEM || len != bufsize) 765 err(1, "sysctlbyname()"); 766 bufsize *= 2; 767 } 768 xug = (struct xunpgen *)buf; 769 exug = (struct xunpgen *)(void *) 770 ((char *)buf + len - sizeof(*exug)); 771 if (xug->xug_len != sizeof(*xug) || 772 exug->xug_len != sizeof(*exug)) { 773 warnx("struct xinpgen size mismatch"); 774 goto out; 775 } 776 } while (xug->xug_gen != exug->xug_gen && retry--); 777 778 if (xug->xug_gen != exug->xug_gen && opt_v) 779 warnx("warning: data may be inconsistent"); 780 781 for (;;) { 782 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); 783 if (xug >= exug) 784 break; 785 xup = (struct xunpcb *)xug; 786 if (xup->xu_len != sizeof(*xup)) { 787 warnx("struct xunpcb size mismatch"); 788 goto out; 789 } 790 if ((xup->unp_conn == NULL && !opt_l) || 791 (xup->unp_conn != NULL && !opt_c)) 792 continue; 793 if ((sock = calloc(1, sizeof(*sock))) == NULL) 794 err(1, "malloc()"); 795 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 796 err(1, "malloc()"); 797 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 798 err(1, "malloc()"); 799 sock->socket = xup->xu_socket.xso_so; 800 sock->pcb = xup->xu_unpp; 801 sock->proto = proto; 802 sock->family = AF_UNIX; 803 sock->protoname = protoname; 804 if (xup->xu_addr.sun_family == AF_UNIX) 805 laddr->address = 806 *(struct sockaddr_storage *)(void *)&xup->xu_addr; 807 else if (xup->unp_conn != NULL) 808 *(void **)&(faddr->address) = xup->unp_conn; 809 laddr->next = NULL; 810 faddr->next = NULL; 811 sock->laddr = laddr; 812 sock->faddr = faddr; 813 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 814 sock->next = sockhash[hash]; 815 sockhash[hash] = sock; 816 } 817 out: 818 free(buf); 819 } 820 821 static void 822 getfiles(void) 823 { 824 size_t len, olen; 825 826 olen = len = sizeof(*xfiles); 827 if ((xfiles = malloc(len)) == NULL) 828 err(1, "malloc()"); 829 while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) { 830 if (errno != ENOMEM || len != olen) 831 err(1, "sysctlbyname()"); 832 olen = len *= 2; 833 if ((xfiles = realloc(xfiles, len)) == NULL) 834 err(1, "realloc()"); 835 } 836 if (len > 0 && xfiles->xf_size != sizeof(*xfiles)) 837 errx(1, "struct xfile size mismatch"); 838 nxfiles = len / sizeof(*xfiles); 839 } 840 841 static int 842 printaddr(struct sockaddr_storage *ss) 843 { 844 struct sockaddr_un *sun; 845 char addrstr[NI_MAXHOST] = { '\0', '\0' }; 846 int error, off, port = 0; 847 848 switch (ss->ss_family) { 849 case AF_INET: 850 if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY) 851 addrstr[0] = '*'; 852 port = ntohs(sstosin(ss)->sin_port); 853 break; 854 case AF_INET6: 855 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr)) 856 addrstr[0] = '*'; 857 port = ntohs(sstosin6(ss)->sin6_port); 858 break; 859 case AF_UNIX: 860 sun = sstosun(ss); 861 off = (int)((char *)&sun->sun_path - (char *)sun); 862 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path)); 863 } 864 if (addrstr[0] == '\0') { 865 error = getnameinfo(sstosa(ss), ss->ss_len, addrstr, 866 sizeof(addrstr), NULL, 0, NI_NUMERICHOST); 867 if (error) 868 errx(1, "getnameinfo()"); 869 } 870 if (port == 0) 871 return xprintf("%s:*", addrstr); 872 else 873 return xprintf("%s:%d", addrstr, port); 874 } 875 876 static const char * 877 getprocname(pid_t pid) 878 { 879 static struct kinfo_proc proc; 880 size_t len; 881 int mib[4]; 882 883 mib[0] = CTL_KERN; 884 mib[1] = KERN_PROC; 885 mib[2] = KERN_PROC_PID; 886 mib[3] = (int)pid; 887 len = sizeof(proc); 888 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 889 /* Do not warn if the process exits before we get its name. */ 890 if (errno != ESRCH) 891 warn("sysctl()"); 892 return ("??"); 893 } 894 return (proc.ki_comm); 895 } 896 897 static int 898 getprocjid(pid_t pid) 899 { 900 static struct kinfo_proc proc; 901 size_t len; 902 int mib[4]; 903 904 mib[0] = CTL_KERN; 905 mib[1] = KERN_PROC; 906 mib[2] = KERN_PROC_PID; 907 mib[3] = (int)pid; 908 len = sizeof(proc); 909 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 910 /* Do not warn if the process exits before we get its jid. */ 911 if (errno != ESRCH) 912 warn("sysctl()"); 913 return (-1); 914 } 915 return (proc.ki_jid); 916 } 917 918 static int 919 check_ports(struct sock *s) 920 { 921 int port; 922 struct addr *addr; 923 924 if (ports == NULL) 925 return (1); 926 if ((s->family != AF_INET) && (s->family != AF_INET6)) 927 return (1); 928 for (addr = s->laddr; addr != NULL; addr = addr->next) { 929 if (s->family == AF_INET) 930 port = ntohs(sstosin(&addr->address)->sin_port); 931 else 932 port = ntohs(sstosin6(&addr->address)->sin6_port); 933 if (CHK_PORT(port)) 934 return (1); 935 } 936 for (addr = s->faddr; addr != NULL; addr = addr->next) { 937 if (s->family == AF_INET) 938 port = ntohs(sstosin(&addr->address)->sin_port); 939 else 940 port = ntohs(sstosin6(&addr->address)->sin6_port); 941 if (CHK_PORT(port)) 942 return (1); 943 } 944 return (0); 945 } 946 947 static const char * 948 sctp_conn_state(int state) 949 { 950 switch (state) { 951 case SCTP_CLOSED: 952 return "CLOSED"; 953 break; 954 case SCTP_BOUND: 955 return "BOUND"; 956 break; 957 case SCTP_LISTEN: 958 return "LISTEN"; 959 break; 960 case SCTP_COOKIE_WAIT: 961 return "COOKIE_WAIT"; 962 break; 963 case SCTP_COOKIE_ECHOED: 964 return "COOKIE_ECHOED"; 965 break; 966 case SCTP_ESTABLISHED: 967 return "ESTABLISHED"; 968 break; 969 case SCTP_SHUTDOWN_SENT: 970 return "SHUTDOWN_SENT"; 971 break; 972 case SCTP_SHUTDOWN_RECEIVED: 973 return "SHUTDOWN_RECEIVED"; 974 break; 975 case SCTP_SHUTDOWN_ACK_SENT: 976 return "SHUTDOWN_ACK_SENT"; 977 break; 978 case SCTP_SHUTDOWN_PENDING: 979 return "SHUTDOWN_PENDING"; 980 break; 981 default: 982 return "UNKNOWN"; 983 break; 984 } 985 } 986 987 static const char * 988 sctp_path_state(int state) 989 { 990 switch (state) { 991 case SCTP_UNCONFIRMED: 992 return "UNCONFIRMED"; 993 break; 994 case SCTP_ACTIVE: 995 return "ACTIVE"; 996 break; 997 case SCTP_INACTIVE: 998 return "INACTIVE"; 999 break; 1000 default: 1001 return "UNKNOWN"; 1002 break; 1003 } 1004 } 1005 1006 static void 1007 displaysock(struct sock *s, int pos) 1008 { 1009 void *p; 1010 int hash, first, offset; 1011 struct addr *laddr, *faddr; 1012 struct sock *s_tmp; 1013 1014 while (pos < 29) 1015 pos += xprintf(" "); 1016 pos += xprintf("%s", s->protoname); 1017 if (s->vflag & INP_IPV4) 1018 pos += xprintf("4"); 1019 if (s->vflag & INP_IPV6) 1020 pos += xprintf("6"); 1021 if (s->vflag & (INP_IPV4 | INP_IPV6)) 1022 pos += xprintf(" "); 1023 laddr = s->laddr; 1024 faddr = s->faddr; 1025 first = 1; 1026 while (laddr != NULL || faddr != NULL) { 1027 offset = 36; 1028 while (pos < offset) 1029 pos += xprintf(" "); 1030 switch (s->family) { 1031 case AF_INET: 1032 case AF_INET6: 1033 if (laddr != NULL) { 1034 pos += printaddr(&laddr->address); 1035 if (s->family == AF_INET6 && pos >= 58) 1036 pos += xprintf(" "); 1037 } 1038 offset += opt_w ? 46 : 22; 1039 while (pos < offset) 1040 pos += xprintf(" "); 1041 if (faddr != NULL) 1042 pos += printaddr(&faddr->address); 1043 offset += opt_w ? 46 : 22; 1044 break; 1045 case AF_UNIX: 1046 if ((laddr == NULL) || (faddr == NULL)) 1047 errx(1, "laddr = %p or faddr = %p is NULL", 1048 (void *)laddr, (void *)faddr); 1049 /* server */ 1050 if (laddr->address.ss_len > 0) { 1051 pos += printaddr(&laddr->address); 1052 break; 1053 } 1054 /* client */ 1055 p = *(void **)&(faddr->address); 1056 if (p == NULL) { 1057 pos += xprintf("(not connected)"); 1058 offset += opt_w ? 92 : 44; 1059 break; 1060 } 1061 pos += xprintf("-> "); 1062 for (hash = 0; hash < HASHSIZE; ++hash) { 1063 for (s_tmp = sockhash[hash]; 1064 s_tmp != NULL; 1065 s_tmp = s_tmp->next) 1066 if (s_tmp->pcb == p) 1067 break; 1068 if (s_tmp != NULL) 1069 break; 1070 } 1071 if (s_tmp == NULL || s_tmp->laddr == NULL || 1072 s_tmp->laddr->address.ss_len == 0) 1073 pos += xprintf("??"); 1074 else 1075 pos += printaddr(&s_tmp->laddr->address); 1076 offset += opt_w ? 92 : 44; 1077 break; 1078 default: 1079 abort(); 1080 } 1081 if (opt_U) { 1082 if (faddr != NULL && 1083 s->proto == IPPROTO_SCTP && 1084 s->state != SCTP_CLOSED && 1085 s->state != SCTP_BOUND && 1086 s->state != SCTP_LISTEN) { 1087 while (pos < offset) 1088 pos += xprintf(" "); 1089 pos += xprintf("%u", 1090 ntohs(faddr->encaps_port)); 1091 } 1092 offset += 7; 1093 } 1094 if (opt_s) { 1095 if (faddr != NULL && 1096 s->proto == IPPROTO_SCTP && 1097 s->state != SCTP_CLOSED && 1098 s->state != SCTP_BOUND && 1099 s->state != SCTP_LISTEN) { 1100 while (pos < offset) 1101 pos += xprintf(" "); 1102 pos += xprintf("%s", 1103 sctp_path_state(faddr->state)); 1104 } 1105 offset += 13; 1106 } 1107 if (first) { 1108 if (opt_s) { 1109 if (s->proto == IPPROTO_SCTP || 1110 s->proto == IPPROTO_TCP) { 1111 while (pos < offset) 1112 pos += xprintf(" "); 1113 switch (s->proto) { 1114 case IPPROTO_SCTP: 1115 pos += xprintf("%s", 1116 sctp_conn_state(s->state)); 1117 break; 1118 case IPPROTO_TCP: 1119 if (s->state >= 0 && 1120 s->state < TCP_NSTATES) 1121 pos += xprintf("%s", 1122 tcpstates[s->state]); 1123 else 1124 pos += xprintf("?"); 1125 break; 1126 } 1127 } 1128 offset += 13; 1129 } 1130 if (opt_S && s->proto == IPPROTO_TCP) { 1131 while (pos < offset) 1132 pos += xprintf(" "); 1133 xprintf("%.*s", TCP_FUNCTION_NAME_LEN_MAX, 1134 s->stack); 1135 } 1136 } 1137 if (laddr != NULL) 1138 laddr = laddr->next; 1139 if (faddr != NULL) 1140 faddr = faddr->next; 1141 if ((laddr != NULL) || (faddr != NULL)) { 1142 xprintf("\n"); 1143 pos = 0; 1144 } 1145 first = 0; 1146 } 1147 xprintf("\n"); 1148 } 1149 1150 static void 1151 display(void) 1152 { 1153 struct passwd *pwd; 1154 struct xfile *xf; 1155 struct sock *s; 1156 int hash, n, pos; 1157 1158 printf("%-8s %-10s %-5s %-2s %-6s %-*s %-*s", 1159 "USER", "COMMAND", "PID", "FD", "PROTO", 1160 opt_w ? 45 : 21, "LOCAL ADDRESS", 1161 opt_w ? 45 : 21, "FOREIGN ADDRESS"); 1162 if (opt_U) 1163 printf(" %-6s", "ENCAPS"); 1164 if (opt_s) { 1165 printf(" %-12s", "PATH STATE"); 1166 printf(" %-12s", "CONN STATE"); 1167 } 1168 if (opt_S) 1169 printf(" %.*s", TCP_FUNCTION_NAME_LEN_MAX, "STACK"); 1170 printf("\n"); 1171 setpassent(1); 1172 for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) { 1173 if (xf->xf_data == NULL) 1174 continue; 1175 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid)) 1176 continue; 1177 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE); 1178 for (s = sockhash[hash]; s != NULL; s = s->next) { 1179 if ((void *)s->socket != xf->xf_data) 1180 continue; 1181 if (!check_ports(s)) 1182 continue; 1183 s->shown = 1; 1184 pos = 0; 1185 if ((pwd = getpwuid(xf->xf_uid)) == NULL) 1186 pos += xprintf("%lu ", (u_long)xf->xf_uid); 1187 else 1188 pos += xprintf("%s ", pwd->pw_name); 1189 while (pos < 9) 1190 pos += xprintf(" "); 1191 pos += xprintf("%.10s", getprocname(xf->xf_pid)); 1192 while (pos < 20) 1193 pos += xprintf(" "); 1194 pos += xprintf("%lu ", (u_long)xf->xf_pid); 1195 while (pos < 26) 1196 pos += xprintf(" "); 1197 pos += xprintf("%d ", xf->xf_fd); 1198 displaysock(s, pos); 1199 } 1200 } 1201 if (opt_j >= 0) 1202 return; 1203 for (hash = 0; hash < HASHSIZE; hash++) { 1204 for (s = sockhash[hash]; s != NULL; s = s->next) { 1205 if (s->shown) 1206 continue; 1207 if (!check_ports(s)) 1208 continue; 1209 pos = 0; 1210 pos += xprintf("%-8s %-10s %-5s %-2s ", 1211 "?", "?", "?", "?"); 1212 displaysock(s, pos); 1213 } 1214 } 1215 } 1216 1217 static int set_default_protos(void) 1218 { 1219 struct protoent *prot; 1220 const char *pname; 1221 size_t pindex; 1222 1223 init_protos(default_numprotos); 1224 1225 for (pindex = 0; pindex < default_numprotos; pindex++) { 1226 pname = default_protos[pindex]; 1227 prot = getprotobyname(pname); 1228 if (prot == NULL) 1229 err(1, "getprotobyname: %s", pname); 1230 protos[pindex] = prot->p_proto; 1231 } 1232 numprotos = pindex; 1233 return (pindex); 1234 } 1235 1236 static void 1237 usage(void) 1238 { 1239 fprintf(stderr, 1240 "usage: sockstat [-46cLlSsUuvw] [-j jid] [-p ports] [-P protocols]\n"); 1241 exit(1); 1242 } 1243 1244 int 1245 main(int argc, char *argv[]) 1246 { 1247 int protos_defined = -1; 1248 int o, i; 1249 1250 opt_j = -1; 1251 while ((o = getopt(argc, argv, "46cj:Llp:P:SsUuvw")) != -1) 1252 switch (o) { 1253 case '4': 1254 opt_4 = 1; 1255 break; 1256 case '6': 1257 opt_6 = 1; 1258 break; 1259 case 'c': 1260 opt_c = 1; 1261 break; 1262 case 'j': 1263 opt_j = atoi(optarg); 1264 break; 1265 case 'L': 1266 opt_L = 1; 1267 break; 1268 case 'l': 1269 opt_l = 1; 1270 break; 1271 case 'p': 1272 parse_ports(optarg); 1273 break; 1274 case 'P': 1275 protos_defined = parse_protos(optarg); 1276 break; 1277 case 'S': 1278 opt_S = 1; 1279 break; 1280 case 's': 1281 opt_s = 1; 1282 break; 1283 case 'U': 1284 opt_U = 1; 1285 break; 1286 case 'u': 1287 opt_u = 1; 1288 break; 1289 case 'v': 1290 ++opt_v; 1291 break; 1292 case 'w': 1293 opt_w = 1; 1294 break; 1295 default: 1296 usage(); 1297 } 1298 1299 argc -= optind; 1300 argv += optind; 1301 1302 if (argc > 0) 1303 usage(); 1304 1305 if ((!opt_4 && !opt_6) && protos_defined != -1) 1306 opt_4 = opt_6 = 1; 1307 if (!opt_4 && !opt_6 && !opt_u) 1308 opt_4 = opt_6 = opt_u = 1; 1309 if ((opt_4 || opt_6) && protos_defined == -1) 1310 protos_defined = set_default_protos(); 1311 if (!opt_c && !opt_l) 1312 opt_c = opt_l = 1; 1313 1314 if (opt_4 || opt_6) { 1315 for (i = 0; i < protos_defined; i++) 1316 if (protos[i] == IPPROTO_SCTP) 1317 gather_sctp(); 1318 else 1319 gather_inet(protos[i]); 1320 } 1321 1322 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) { 1323 gather_unix(SOCK_STREAM); 1324 gather_unix(SOCK_DGRAM); 1325 gather_unix(SOCK_SEQPACKET); 1326 } 1327 getfiles(); 1328 display(); 1329 exit(0); 1330 } 1331