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