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