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