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; 565 struct inpcb *inp; 566 struct xsocket *so; 567 struct sock *sock; 568 struct addr *laddr, *faddr; 569 const char *varname, *protoname; 570 size_t len, bufsize; 571 void *buf; 572 int hash, retry, vflag; 573 574 vflag = 0; 575 if (opt_4) 576 vflag |= INP_IPV4; 577 if (opt_6) 578 vflag |= INP_IPV6; 579 580 switch (proto) { 581 case IPPROTO_TCP: 582 varname = "net.inet.tcp.pcblist"; 583 protoname = "tcp"; 584 break; 585 case IPPROTO_UDP: 586 varname = "net.inet.udp.pcblist"; 587 protoname = "udp"; 588 break; 589 case IPPROTO_DIVERT: 590 varname = "net.inet.divert.pcblist"; 591 protoname = "div"; 592 break; 593 default: 594 errx(1, "protocol %d not supported", proto); 595 } 596 597 buf = NULL; 598 bufsize = 8192; 599 retry = 5; 600 do { 601 for (;;) { 602 if ((buf = realloc(buf, bufsize)) == NULL) 603 err(1, "realloc()"); 604 len = bufsize; 605 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 606 break; 607 if (errno == ENOENT) 608 goto out; 609 if (errno != ENOMEM || len != bufsize) 610 err(1, "sysctlbyname()"); 611 bufsize *= 2; 612 } 613 xig = (struct xinpgen *)buf; 614 exig = (struct xinpgen *)(void *) 615 ((char *)buf + len - sizeof *exig); 616 if (xig->xig_len != sizeof *xig || 617 exig->xig_len != sizeof *exig) 618 errx(1, "struct xinpgen size mismatch"); 619 } while (xig->xig_gen != exig->xig_gen && retry--); 620 621 if (xig->xig_gen != exig->xig_gen && opt_v) 622 warnx("warning: data may be inconsistent"); 623 624 for (;;) { 625 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); 626 if (xig >= exig) 627 break; 628 xip = (struct xinpcb *)xig; 629 xtp = (struct xtcpcb *)xig; 630 switch (proto) { 631 case IPPROTO_TCP: 632 if (xtp->xt_len != sizeof(*xtp)) { 633 warnx("struct xtcpcb size mismatch"); 634 goto out; 635 } 636 inp = &xtp->xt_inp; 637 so = &xtp->xt_socket; 638 protoname = xtp->xt_tp.t_flags & TF_TOE ? "toe" : "tcp"; 639 break; 640 case IPPROTO_UDP: 641 case IPPROTO_DIVERT: 642 if (xip->xi_len != sizeof(*xip)) { 643 warnx("struct xinpcb size mismatch"); 644 goto out; 645 } 646 inp = &xip->xi_inp; 647 so = &xip->xi_socket; 648 break; 649 default: 650 errx(1, "protocol %d not supported", proto); 651 } 652 if ((inp->inp_vflag & vflag) == 0) 653 continue; 654 if (inp->inp_vflag & INP_IPV4) { 655 if ((inp->inp_fport == 0 && !opt_l) || 656 (inp->inp_fport != 0 && !opt_c)) 657 continue; 658 #define __IN_IS_ADDR_LOOPBACK(pina) \ 659 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 660 if (opt_L && 661 (__IN_IS_ADDR_LOOPBACK(&inp->inp_faddr) || 662 __IN_IS_ADDR_LOOPBACK(&inp->inp_laddr))) 663 continue; 664 #undef __IN_IS_ADDR_LOOPBACK 665 } else if (inp->inp_vflag & INP_IPV6) { 666 if ((inp->inp_fport == 0 && !opt_l) || 667 (inp->inp_fport != 0 && !opt_c)) 668 continue; 669 if (opt_L && 670 (IN6_IS_ADDR_LOOPBACK(&inp->in6p_faddr) || 671 IN6_IS_ADDR_LOOPBACK(&inp->in6p_laddr))) 672 continue; 673 } else { 674 if (opt_v) 675 warnx("invalid vflag 0x%x", inp->inp_vflag); 676 continue; 677 } 678 if ((sock = calloc(1, sizeof(*sock))) == NULL) 679 err(1, "malloc()"); 680 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 681 err(1, "malloc()"); 682 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 683 err(1, "malloc()"); 684 sock->socket = so->xso_so; 685 sock->proto = proto; 686 if (inp->inp_vflag & INP_IPV4) { 687 sock->family = AF_INET; 688 sockaddr(&laddr->address, sock->family, 689 &inp->inp_laddr, inp->inp_lport); 690 sockaddr(&faddr->address, sock->family, 691 &inp->inp_faddr, inp->inp_fport); 692 } else if (inp->inp_vflag & INP_IPV6) { 693 sock->family = AF_INET6; 694 sockaddr(&laddr->address, sock->family, 695 &inp->in6p_laddr, inp->inp_lport); 696 sockaddr(&faddr->address, sock->family, 697 &inp->in6p_faddr, inp->inp_fport); 698 } 699 laddr->next = NULL; 700 faddr->next = NULL; 701 sock->laddr = laddr; 702 sock->faddr = faddr; 703 sock->vflag = inp->inp_vflag; 704 if (proto == IPPROTO_TCP) 705 sock->state = xtp->xt_tp.t_state; 706 sock->protoname = protoname; 707 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 708 sock->next = sockhash[hash]; 709 sockhash[hash] = sock; 710 } 711 out: 712 free(buf); 713 } 714 715 static void 716 gather_unix(int proto) 717 { 718 struct xunpgen *xug, *exug; 719 struct xunpcb *xup; 720 struct sock *sock; 721 struct addr *laddr, *faddr; 722 const char *varname, *protoname; 723 size_t len, bufsize; 724 void *buf; 725 int hash, retry; 726 727 switch (proto) { 728 case SOCK_STREAM: 729 varname = "net.local.stream.pcblist"; 730 protoname = "stream"; 731 break; 732 case SOCK_DGRAM: 733 varname = "net.local.dgram.pcblist"; 734 protoname = "dgram"; 735 break; 736 case SOCK_SEQPACKET: 737 varname = "net.local.seqpacket.pcblist"; 738 protoname = "seqpac"; 739 break; 740 default: 741 abort(); 742 } 743 buf = NULL; 744 bufsize = 8192; 745 retry = 5; 746 do { 747 for (;;) { 748 if ((buf = realloc(buf, bufsize)) == NULL) 749 err(1, "realloc()"); 750 len = bufsize; 751 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 752 break; 753 if (errno != ENOMEM || len != bufsize) 754 err(1, "sysctlbyname()"); 755 bufsize *= 2; 756 } 757 xug = (struct xunpgen *)buf; 758 exug = (struct xunpgen *)(void *) 759 ((char *)buf + len - sizeof(*exug)); 760 if (xug->xug_len != sizeof(*xug) || 761 exug->xug_len != sizeof(*exug)) { 762 warnx("struct xinpgen size mismatch"); 763 goto out; 764 } 765 } while (xug->xug_gen != exug->xug_gen && retry--); 766 767 if (xug->xug_gen != exug->xug_gen && opt_v) 768 warnx("warning: data may be inconsistent"); 769 770 for (;;) { 771 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); 772 if (xug >= exug) 773 break; 774 xup = (struct xunpcb *)xug; 775 if (xup->xu_len != sizeof(*xup)) { 776 warnx("struct xunpcb size mismatch"); 777 goto out; 778 } 779 if ((xup->xu_unp.unp_conn == NULL && !opt_l) || 780 (xup->xu_unp.unp_conn != NULL && !opt_c)) 781 continue; 782 if ((sock = calloc(1, sizeof(*sock))) == NULL) 783 err(1, "malloc()"); 784 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 785 err(1, "malloc()"); 786 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 787 err(1, "malloc()"); 788 sock->socket = xup->xu_socket.xso_so; 789 sock->pcb = xup->xu_unpp; 790 sock->proto = proto; 791 sock->family = AF_UNIX; 792 sock->protoname = protoname; 793 if (xup->xu_unp.unp_addr != NULL) 794 laddr->address = 795 *(struct sockaddr_storage *)(void *)&xup->xu_addr; 796 else if (xup->xu_unp.unp_conn != NULL) 797 *(void **)&(faddr->address) = xup->xu_unp.unp_conn; 798 laddr->next = NULL; 799 faddr->next = NULL; 800 sock->laddr = laddr; 801 sock->faddr = faddr; 802 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 803 sock->next = sockhash[hash]; 804 sockhash[hash] = sock; 805 } 806 out: 807 free(buf); 808 } 809 810 static void 811 getfiles(void) 812 { 813 size_t len, olen; 814 815 olen = len = sizeof(*xfiles); 816 if ((xfiles = malloc(len)) == NULL) 817 err(1, "malloc()"); 818 while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) { 819 if (errno != ENOMEM || len != olen) 820 err(1, "sysctlbyname()"); 821 olen = len *= 2; 822 if ((xfiles = realloc(xfiles, len)) == NULL) 823 err(1, "realloc()"); 824 } 825 if (len > 0 && xfiles->xf_size != sizeof(*xfiles)) 826 errx(1, "struct xfile size mismatch"); 827 nxfiles = len / sizeof(*xfiles); 828 } 829 830 static int 831 printaddr(struct sockaddr_storage *ss) 832 { 833 struct sockaddr_un *sun; 834 char addrstr[NI_MAXHOST] = { '\0', '\0' }; 835 int error, off, port = 0; 836 837 switch (ss->ss_family) { 838 case AF_INET: 839 if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY) 840 addrstr[0] = '*'; 841 port = ntohs(sstosin(ss)->sin_port); 842 break; 843 case AF_INET6: 844 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr)) 845 addrstr[0] = '*'; 846 port = ntohs(sstosin6(ss)->sin6_port); 847 break; 848 case AF_UNIX: 849 sun = sstosun(ss); 850 off = (int)((char *)&sun->sun_path - (char *)sun); 851 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path)); 852 } 853 if (addrstr[0] == '\0') { 854 error = getnameinfo(sstosa(ss), ss->ss_len, addrstr, 855 sizeof(addrstr), NULL, 0, NI_NUMERICHOST); 856 if (error) 857 errx(1, "getnameinfo()"); 858 } 859 if (port == 0) 860 return xprintf("%s:*", addrstr); 861 else 862 return xprintf("%s:%d", addrstr, port); 863 } 864 865 static const char * 866 getprocname(pid_t pid) 867 { 868 static struct kinfo_proc proc; 869 size_t len; 870 int mib[4]; 871 872 mib[0] = CTL_KERN; 873 mib[1] = KERN_PROC; 874 mib[2] = KERN_PROC_PID; 875 mib[3] = (int)pid; 876 len = sizeof(proc); 877 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 878 /* Do not warn if the process exits before we get its name. */ 879 if (errno != ESRCH) 880 warn("sysctl()"); 881 return ("??"); 882 } 883 return (proc.ki_comm); 884 } 885 886 static int 887 getprocjid(pid_t pid) 888 { 889 static struct kinfo_proc proc; 890 size_t len; 891 int mib[4]; 892 893 mib[0] = CTL_KERN; 894 mib[1] = KERN_PROC; 895 mib[2] = KERN_PROC_PID; 896 mib[3] = (int)pid; 897 len = sizeof(proc); 898 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 899 /* Do not warn if the process exits before we get its jid. */ 900 if (errno != ESRCH) 901 warn("sysctl()"); 902 return (-1); 903 } 904 return (proc.ki_jid); 905 } 906 907 static int 908 check_ports(struct sock *s) 909 { 910 int port; 911 struct addr *addr; 912 913 if (ports == NULL) 914 return (1); 915 if ((s->family != AF_INET) && (s->family != AF_INET6)) 916 return (1); 917 for (addr = s->laddr; addr != NULL; addr = addr->next) { 918 if (s->family == AF_INET) 919 port = ntohs(sstosin(&addr->address)->sin_port); 920 else 921 port = ntohs(sstosin6(&addr->address)->sin6_port); 922 if (CHK_PORT(port)) 923 return (1); 924 } 925 for (addr = s->faddr; addr != NULL; addr = addr->next) { 926 if (s->family == AF_INET) 927 port = ntohs(sstosin(&addr->address)->sin_port); 928 else 929 port = ntohs(sstosin6(&addr->address)->sin6_port); 930 if (CHK_PORT(port)) 931 return (1); 932 } 933 return (0); 934 } 935 936 static const char * 937 sctp_state(int state) 938 { 939 switch (state) { 940 case SCTP_CLOSED: 941 return "CLOSED"; 942 break; 943 case SCTP_BOUND: 944 return "BOUND"; 945 break; 946 case SCTP_LISTEN: 947 return "LISTEN"; 948 break; 949 case SCTP_COOKIE_WAIT: 950 return "COOKIE_WAIT"; 951 break; 952 case SCTP_COOKIE_ECHOED: 953 return "COOKIE_ECHOED"; 954 break; 955 case SCTP_ESTABLISHED: 956 return "ESTABLISHED"; 957 break; 958 case SCTP_SHUTDOWN_SENT: 959 return "SHUTDOWN_SENT"; 960 break; 961 case SCTP_SHUTDOWN_RECEIVED: 962 return "SHUTDOWN_RECEIVED"; 963 break; 964 case SCTP_SHUTDOWN_ACK_SENT: 965 return "SHUTDOWN_ACK_SENT"; 966 break; 967 case SCTP_SHUTDOWN_PENDING: 968 return "SHUTDOWN_PENDING"; 969 break; 970 default: 971 return "UNKNOWN"; 972 break; 973 } 974 } 975 976 static void 977 displaysock(struct sock *s, int pos) 978 { 979 void *p; 980 int hash, first; 981 struct addr *laddr, *faddr; 982 struct sock *s_tmp; 983 984 while (pos < 29) 985 pos += xprintf(" "); 986 pos += xprintf("%s", s->protoname); 987 if (s->vflag & INP_IPV4) 988 pos += xprintf("4"); 989 if (s->vflag & INP_IPV6) 990 pos += xprintf("6"); 991 if (s->vflag & (INP_IPV4 | INP_IPV6)) 992 pos += xprintf(" "); 993 laddr = s->laddr; 994 faddr = s->faddr; 995 first = 1; 996 while (laddr != NULL || faddr != NULL) { 997 while (pos < 36) 998 pos += xprintf(" "); 999 switch (s->family) { 1000 case AF_INET: 1001 case AF_INET6: 1002 if (laddr != NULL) { 1003 pos += printaddr(&laddr->address); 1004 if (s->family == AF_INET6 && pos >= 58) 1005 pos += xprintf(" "); 1006 } 1007 while (pos < 58) 1008 pos += xprintf(" "); 1009 if (faddr != NULL) 1010 pos += printaddr(&faddr->address); 1011 break; 1012 case AF_UNIX: 1013 if ((laddr == NULL) || (faddr == NULL)) 1014 errx(1, "laddr = %p or faddr = %p is NULL", 1015 (void *)laddr, (void *)faddr); 1016 /* server */ 1017 if (laddr->address.ss_len > 0) { 1018 pos += printaddr(&laddr->address); 1019 break; 1020 } 1021 /* client */ 1022 p = *(void **)&(faddr->address); 1023 if (p == NULL) { 1024 pos += xprintf("(not connected)"); 1025 break; 1026 } 1027 pos += xprintf("-> "); 1028 for (hash = 0; hash < HASHSIZE; ++hash) { 1029 for (s_tmp = sockhash[hash]; 1030 s_tmp != NULL; 1031 s_tmp = s_tmp->next) 1032 if (s_tmp->pcb == p) 1033 break; 1034 if (s_tmp != NULL) 1035 break; 1036 } 1037 if (s_tmp == NULL || s_tmp->laddr == NULL || 1038 s_tmp->laddr->address.ss_len == 0) 1039 pos += xprintf("??"); 1040 else 1041 pos += printaddr(&s_tmp->laddr->address); 1042 break; 1043 default: 1044 abort(); 1045 } 1046 if (first && opt_s && 1047 (s->proto == IPPROTO_SCTP || s->proto == IPPROTO_TCP)) { 1048 while (pos < 80) 1049 pos += xprintf(" "); 1050 switch (s->proto) { 1051 case IPPROTO_SCTP: 1052 pos += xprintf("%s", sctp_state(s->state)); 1053 break; 1054 case IPPROTO_TCP: 1055 if (s->state >= 0 && s->state < TCP_NSTATES) 1056 pos += 1057 xprintf("%s", tcpstates[s->state]); 1058 else 1059 pos += xprintf("?"); 1060 break; 1061 } 1062 } 1063 if (laddr != NULL) 1064 laddr = laddr->next; 1065 if (faddr != NULL) 1066 faddr = faddr->next; 1067 if ((laddr != NULL) || (faddr != NULL)) { 1068 xprintf("\n"); 1069 pos = 0; 1070 } 1071 first = 0; 1072 } 1073 xprintf("\n"); 1074 } 1075 1076 static void 1077 display(void) 1078 { 1079 struct passwd *pwd; 1080 struct xfile *xf; 1081 struct sock *s; 1082 int hash, n, pos; 1083 1084 printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s", 1085 "USER", "COMMAND", "PID", "FD", "PROTO", 1086 "LOCAL ADDRESS", "FOREIGN ADDRESS"); 1087 if (opt_s) 1088 printf(" %-12s", "STATE"); 1089 printf("\n"); 1090 setpassent(1); 1091 for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) { 1092 if (xf->xf_data == NULL) 1093 continue; 1094 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid)) 1095 continue; 1096 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE); 1097 for (s = sockhash[hash]; s != NULL; s = s->next) { 1098 if ((void *)s->socket != xf->xf_data) 1099 continue; 1100 if (!check_ports(s)) 1101 continue; 1102 s->shown = 1; 1103 pos = 0; 1104 if ((pwd = getpwuid(xf->xf_uid)) == NULL) 1105 pos += xprintf("%lu ", (u_long)xf->xf_uid); 1106 else 1107 pos += xprintf("%s ", pwd->pw_name); 1108 while (pos < 9) 1109 pos += xprintf(" "); 1110 pos += xprintf("%.10s", getprocname(xf->xf_pid)); 1111 while (pos < 20) 1112 pos += xprintf(" "); 1113 pos += xprintf("%lu ", (u_long)xf->xf_pid); 1114 while (pos < 26) 1115 pos += xprintf(" "); 1116 pos += xprintf("%d ", xf->xf_fd); 1117 displaysock(s, pos); 1118 } 1119 } 1120 if (opt_j >= 0) 1121 return; 1122 for (hash = 0; hash < HASHSIZE; hash++) { 1123 for (s = sockhash[hash]; s != NULL; s = s->next) { 1124 if (s->shown) 1125 continue; 1126 if (!check_ports(s)) 1127 continue; 1128 pos = 0; 1129 pos += xprintf("%-8s %-10s %-5s %-2s ", 1130 "?", "?", "?", "?"); 1131 displaysock(s, pos); 1132 } 1133 } 1134 } 1135 1136 static int set_default_protos(void) 1137 { 1138 struct protoent *prot; 1139 const char *pname; 1140 size_t pindex; 1141 1142 init_protos(default_numprotos); 1143 1144 for (pindex = 0; pindex < default_numprotos; pindex++) { 1145 pname = default_protos[pindex]; 1146 prot = getprotobyname(pname); 1147 if (prot == NULL) 1148 err(1, "getprotobyname: %s", pname); 1149 protos[pindex] = prot->p_proto; 1150 } 1151 numprotos = pindex; 1152 return (pindex); 1153 } 1154 1155 static void 1156 usage(void) 1157 { 1158 fprintf(stderr, 1159 "usage: sockstat [-46cLlsu] [-j jid] [-p ports] [-P protocols]\n"); 1160 exit(1); 1161 } 1162 1163 int 1164 main(int argc, char *argv[]) 1165 { 1166 int protos_defined = -1; 1167 int o, i; 1168 1169 opt_j = -1; 1170 while ((o = getopt(argc, argv, "46cj:Llp:P:suv")) != -1) 1171 switch (o) { 1172 case '4': 1173 opt_4 = 1; 1174 break; 1175 case '6': 1176 opt_6 = 1; 1177 break; 1178 case 'c': 1179 opt_c = 1; 1180 break; 1181 case 'j': 1182 opt_j = atoi(optarg); 1183 break; 1184 case 'L': 1185 opt_L = 1; 1186 break; 1187 case 'l': 1188 opt_l = 1; 1189 break; 1190 case 'p': 1191 parse_ports(optarg); 1192 break; 1193 case 'P': 1194 protos_defined = parse_protos(optarg); 1195 break; 1196 case 's': 1197 opt_s = 1; 1198 break; 1199 case 'u': 1200 opt_u = 1; 1201 break; 1202 case 'v': 1203 ++opt_v; 1204 break; 1205 default: 1206 usage(); 1207 } 1208 1209 argc -= optind; 1210 argv += optind; 1211 1212 if (argc > 0) 1213 usage(); 1214 1215 if ((!opt_4 && !opt_6) && protos_defined != -1) 1216 opt_4 = opt_6 = 1; 1217 if (!opt_4 && !opt_6 && !opt_u) 1218 opt_4 = opt_6 = opt_u = 1; 1219 if ((opt_4 || opt_6) && protos_defined == -1) 1220 protos_defined = set_default_protos(); 1221 if (!opt_c && !opt_l) 1222 opt_c = opt_l = 1; 1223 1224 if (opt_4 || opt_6) { 1225 for (i = 0; i < protos_defined; i++) 1226 if (protos[i] == IPPROTO_SCTP) 1227 gather_sctp(); 1228 else 1229 gather_inet(protos[i]); 1230 } 1231 1232 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) { 1233 gather_unix(SOCK_STREAM); 1234 gather_unix(SOCK_DGRAM); 1235 gather_unix(SOCK_SEQPACKET); 1236 } 1237 getfiles(); 1238 display(); 1239 exit(0); 1240 } 1241