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