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