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