1 /*- 2 * Copyright (c) 2002 Dag-Erling Coïdan Smørgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include <sys/param.h> 33 #include <sys/socket.h> 34 #include <sys/socketvar.h> 35 #include <sys/sysctl.h> 36 #include <sys/file.h> 37 #include <sys/user.h> 38 39 #include <sys/un.h> 40 #include <sys/unpcb.h> 41 42 #include <net/route.h> 43 44 #include <netinet/in.h> 45 #include <netinet/in_pcb.h> 46 #include <netinet/sctp.h> 47 #include <netinet/tcp.h> 48 #define TCPSTATES /* load state names */ 49 #include <netinet/tcp_fsm.h> 50 #include <netinet/tcp_seq.h> 51 #include <netinet/tcp_var.h> 52 #include <arpa/inet.h> 53 54 #include <ctype.h> 55 #include <err.h> 56 #include <errno.h> 57 #include <netdb.h> 58 #include <pwd.h> 59 #include <stdarg.h> 60 #include <stdio.h> 61 #include <stdlib.h> 62 #include <string.h> 63 #include <unistd.h> 64 65 #define sstosin(ss) ((struct sockaddr_in *)(ss)) 66 #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) 67 #define sstosun(ss) ((struct sockaddr_un *)(ss)) 68 #define sstosa(ss) ((struct sockaddr *)(ss)) 69 70 static int opt_4; /* Show IPv4 sockets */ 71 static int opt_6; /* Show IPv6 sockets */ 72 static int opt_c; /* Show connected sockets */ 73 static int opt_j; /* Show specified jail */ 74 static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */ 75 static int opt_l; /* Show listening sockets */ 76 static int opt_s; /* Show protocol state if applicable */ 77 static int opt_u; /* Show Unix domain sockets */ 78 static int opt_v; /* Verbose mode */ 79 80 /* 81 * Default protocols to use if no -P was defined. 82 */ 83 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" }; 84 static size_t default_numprotos = nitems(default_protos); 85 86 static int *protos; /* protocols to use */ 87 static size_t numprotos; /* allocated size of protos[] */ 88 89 static int *ports; 90 91 #define INT_BIT (sizeof(int)*CHAR_BIT) 92 #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0) 93 #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT))) 94 95 struct addr { 96 struct sockaddr_storage address; 97 struct addr *next; 98 }; 99 100 struct sock { 101 void *socket; 102 void *pcb; 103 int shown; 104 int vflag; 105 int family; 106 int proto; 107 int state; 108 const char *protoname; 109 struct addr *laddr; 110 struct addr *faddr; 111 struct sock *next; 112 }; 113 114 #define HASHSIZE 1009 115 static struct sock *sockhash[HASHSIZE]; 116 117 static struct xfile *xfiles; 118 static int nxfiles; 119 120 static int 121 xprintf(const char *fmt, ...) 122 { 123 va_list ap; 124 int len; 125 126 va_start(ap, fmt); 127 len = vprintf(fmt, ap); 128 va_end(ap); 129 if (len < 0) 130 err(1, "printf()"); 131 return (len); 132 } 133 134 135 static int 136 get_proto_type(const char *proto) 137 { 138 struct protoent *pent; 139 140 if (strlen(proto) == 0) 141 return (0); 142 pent = getprotobyname(proto); 143 if (pent == NULL) { 144 warn("getprotobyname"); 145 return (-1); 146 } 147 return (pent->p_proto); 148 } 149 150 151 static void 152 init_protos(int num) 153 { 154 int proto_count = 0; 155 156 if (num > 0) { 157 proto_count = num; 158 } else { 159 /* Find the maximum number of possible protocols. */ 160 while (getprotoent() != NULL) 161 proto_count++; 162 endprotoent(); 163 } 164 165 if ((protos = malloc(sizeof(int) * proto_count)) == NULL) 166 err(1, "malloc"); 167 numprotos = proto_count; 168 } 169 170 171 static int 172 parse_protos(char *protospec) 173 { 174 char *prot; 175 int proto_type, proto_index; 176 177 if (protospec == NULL) 178 return (-1); 179 180 init_protos(0); 181 proto_index = 0; 182 while ((prot = strsep(&protospec, ",")) != NULL) { 183 if (strlen(prot) == 0) 184 continue; 185 proto_type = get_proto_type(prot); 186 if (proto_type != -1) 187 protos[proto_index++] = proto_type; 188 } 189 numprotos = proto_index; 190 return (proto_index); 191 } 192 193 194 static void 195 parse_ports(const char *portspec) 196 { 197 const char *p, *q; 198 int port, end; 199 200 if (ports == NULL) 201 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL) 202 err(1, "calloc()"); 203 p = portspec; 204 while (*p != '\0') { 205 if (!isdigit(*p)) 206 errx(1, "syntax error in port range"); 207 for (q = p; *q != '\0' && isdigit(*q); ++q) 208 /* nothing */ ; 209 for (port = 0; p < q; ++p) 210 port = port * 10 + digittoint(*p); 211 if (port < 0 || port > 65535) 212 errx(1, "invalid port number"); 213 SET_PORT(port); 214 switch (*p) { 215 case '-': 216 ++p; 217 break; 218 case ',': 219 ++p; 220 /* fall through */ 221 case '\0': 222 default: 223 continue; 224 } 225 for (q = p; *q != '\0' && isdigit(*q); ++q) 226 /* nothing */ ; 227 for (end = 0; p < q; ++p) 228 end = end * 10 + digittoint(*p); 229 if (end < port || end > 65535) 230 errx(1, "invalid port number"); 231 while (port++ < end) 232 SET_PORT(port); 233 if (*p == ',') 234 ++p; 235 } 236 } 237 238 static void 239 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port) 240 { 241 struct sockaddr_in *sin4; 242 struct sockaddr_in6 *sin6; 243 244 bzero(ss, sizeof(*ss)); 245 switch (af) { 246 case AF_INET: 247 sin4 = sstosin(ss); 248 sin4->sin_len = sizeof(*sin4); 249 sin4->sin_family = af; 250 sin4->sin_port = port; 251 sin4->sin_addr = *(struct in_addr *)addr; 252 break; 253 case AF_INET6: 254 sin6 = sstosin6(ss); 255 sin6->sin6_len = sizeof(*sin6); 256 sin6->sin6_family = af; 257 sin6->sin6_port = port; 258 sin6->sin6_addr = *(struct in6_addr *)addr; 259 #define s6_addr16 __u6_addr.__u6_addr16 260 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 261 sin6->sin6_scope_id = 262 ntohs(sin6->sin6_addr.s6_addr16[1]); 263 sin6->sin6_addr.s6_addr16[1] = 0; 264 } 265 break; 266 default: 267 abort(); 268 } 269 } 270 271 static void 272 free_socket(struct sock *sock) 273 { 274 struct addr *cur, *next; 275 276 cur = sock->laddr; 277 while (cur != NULL) { 278 next = cur->next; 279 free(cur); 280 cur = next; 281 } 282 cur = sock->faddr; 283 while (cur != NULL) { 284 next = cur->next; 285 free(cur); 286 cur = next; 287 } 288 free(sock); 289 } 290 291 static void 292 gather_sctp(void) 293 { 294 struct sock *sock; 295 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr; 296 struct xsctp_inpcb *xinpcb; 297 struct xsctp_tcb *xstcb; 298 struct xsctp_raddr *xraddr; 299 struct xsctp_laddr *xladdr; 300 const char *varname; 301 size_t len, offset; 302 char *buf; 303 int hash, vflag; 304 int no_stcb, local_all_loopback, foreign_all_loopback; 305 306 vflag = 0; 307 if (opt_4) 308 vflag |= INP_IPV4; 309 if (opt_6) 310 vflag |= INP_IPV6; 311 312 varname = "net.inet.sctp.assoclist"; 313 if (sysctlbyname(varname, 0, &len, 0, 0) < 0) { 314 if (errno != ENOENT) 315 err(1, "sysctlbyname()"); 316 return; 317 } 318 if ((buf = (char *)malloc(len)) == NULL) { 319 err(1, "malloc()"); 320 return; 321 } 322 if (sysctlbyname(varname, buf, &len, 0, 0) < 0) { 323 err(1, "sysctlbyname()"); 324 free(buf); 325 return; 326 } 327 xinpcb = (struct xsctp_inpcb *)(void *)buf; 328 offset = sizeof(struct xsctp_inpcb); 329 while ((offset < len) && (xinpcb->last == 0)) { 330 if ((sock = calloc(1, sizeof *sock)) == NULL) 331 err(1, "malloc()"); 332 sock->socket = xinpcb->socket; 333 sock->proto = IPPROTO_SCTP; 334 sock->protoname = "sctp"; 335 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 336 sock->family = AF_INET6; 337 sock->vflag = INP_IPV6; 338 } else { 339 sock->family = AF_INET; 340 sock->vflag = INP_IPV4; 341 } 342 prev_laddr = NULL; 343 local_all_loopback = 1; 344 while (offset < len) { 345 xladdr = (struct xsctp_laddr *)(void *)(buf + offset); 346 offset += sizeof(struct xsctp_laddr); 347 if (xladdr->last == 1) 348 break; 349 if ((laddr = calloc(1, sizeof(struct addr))) == NULL) 350 err(1, "malloc()"); 351 switch (xladdr->address.sa.sa_family) { 352 case AF_INET: 353 #define __IN_IS_ADDR_LOOPBACK(pina) \ 354 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 355 if (!__IN_IS_ADDR_LOOPBACK(&xladdr->address.sin.sin_addr)) 356 local_all_loopback = 0; 357 #undef __IN_IS_ADDR_LOOPBACK 358 sockaddr(&laddr->address, 359 AF_INET, 360 &xladdr->address.sin.sin_addr, 361 htons(xinpcb->local_port)); 362 break; 363 case AF_INET6: 364 if (!IN6_IS_ADDR_LOOPBACK(&xladdr->address.sin6.sin6_addr)) 365 local_all_loopback = 0; 366 sockaddr(&laddr->address, 367 AF_INET6, 368 &xladdr->address.sin6.sin6_addr, 369 htons(xinpcb->local_port)); 370 break; 371 default: 372 errx(1, "adress family %d not supported", 373 xladdr->address.sa.sa_family); 374 } 375 laddr->next = NULL; 376 if (prev_laddr == NULL) 377 sock->laddr = laddr; 378 else 379 prev_laddr->next = laddr; 380 prev_laddr = laddr; 381 } 382 if (sock->laddr == NULL) { 383 if ((sock->laddr = calloc(1, sizeof(struct addr))) == NULL) 384 err(1, "malloc()"); 385 sock->laddr->address.ss_family = sock->family; 386 if (sock->family == AF_INET) 387 sock->laddr->address.ss_len = sizeof(struct sockaddr_in); 388 else 389 sock->laddr->address.ss_len = sizeof(struct sockaddr_in); 390 local_all_loopback = 0; 391 } 392 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL) 393 err(1, "malloc()"); 394 sock->faddr->address.ss_family = sock->family; 395 if (sock->family == AF_INET) 396 sock->faddr->address.ss_len = sizeof(struct sockaddr_in); 397 else 398 sock->faddr->address.ss_len = sizeof(struct sockaddr_in); 399 no_stcb = 1; 400 while (offset < len) { 401 xstcb = (struct xsctp_tcb *)(void *)(buf + offset); 402 offset += sizeof(struct xsctp_tcb); 403 if (no_stcb) { 404 if (opt_l && 405 (!opt_L || !local_all_loopback) && 406 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) || 407 (xstcb->last == 1))) { 408 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 409 sock->next = sockhash[hash]; 410 sockhash[hash] = sock; 411 } else { 412 free_socket(sock); 413 } 414 } 415 if (xstcb->last == 1) 416 break; 417 no_stcb = 0; 418 if (opt_c) { 419 if ((sock = calloc(1, sizeof *sock)) == NULL) 420 err(1, "malloc()"); 421 sock->socket = xinpcb->socket; 422 sock->proto = IPPROTO_SCTP; 423 sock->protoname = "sctp"; 424 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 425 sock->family = AF_INET6; 426 sock->vflag = INP_IPV6; 427 } else { 428 sock->family = AF_INET; 429 sock->vflag = INP_IPV4; 430 } 431 } 432 prev_laddr = NULL; 433 local_all_loopback = 1; 434 while (offset < len) { 435 xladdr = (struct xsctp_laddr *)(void *)(buf + offset); 436 offset += sizeof(struct xsctp_laddr); 437 if (xladdr->last == 1) 438 break; 439 if (!opt_c) 440 continue; 441 if ((laddr = calloc(1, sizeof(struct addr))) == NULL) 442 err(1, "malloc()"); 443 switch (xladdr->address.sa.sa_family) { 444 case AF_INET: 445 #define __IN_IS_ADDR_LOOPBACK(pina) \ 446 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 447 if (!__IN_IS_ADDR_LOOPBACK(&xladdr->address.sin.sin_addr)) 448 local_all_loopback = 0; 449 #undef __IN_IS_ADDR_LOOPBACK 450 sockaddr(&laddr->address, 451 AF_INET, 452 &xladdr->address.sin.sin_addr, 453 htons(xstcb->local_port)); 454 break; 455 case AF_INET6: 456 if (!IN6_IS_ADDR_LOOPBACK(&xladdr->address.sin6.sin6_addr)) 457 local_all_loopback = 0; 458 sockaddr(&laddr->address, 459 AF_INET6, 460 &xladdr->address.sin6.sin6_addr, 461 htons(xstcb->local_port)); 462 break; 463 default: 464 errx(1, "adress family %d not supported", 465 xladdr->address.sa.sa_family); 466 } 467 laddr->next = NULL; 468 if (prev_laddr == NULL) 469 sock->laddr = laddr; 470 else 471 prev_laddr->next = laddr; 472 prev_laddr = laddr; 473 } 474 prev_faddr = NULL; 475 foreign_all_loopback = 1; 476 while (offset < len) { 477 xraddr = (struct xsctp_raddr *)(void *)(buf + offset); 478 offset += sizeof(struct xsctp_raddr); 479 if (xraddr->last == 1) 480 break; 481 if (!opt_c) 482 continue; 483 if ((faddr = calloc(1, sizeof(struct addr))) == NULL) 484 err(1, "malloc()"); 485 switch (xraddr->address.sa.sa_family) { 486 case AF_INET: 487 #define __IN_IS_ADDR_LOOPBACK(pina) \ 488 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 489 if (!__IN_IS_ADDR_LOOPBACK(&xraddr->address.sin.sin_addr)) 490 foreign_all_loopback = 0; 491 #undef __IN_IS_ADDR_LOOPBACK 492 sockaddr(&faddr->address, 493 AF_INET, 494 &xraddr->address.sin.sin_addr, 495 htons(xstcb->remote_port)); 496 break; 497 case AF_INET6: 498 if (!IN6_IS_ADDR_LOOPBACK(&xraddr->address.sin6.sin6_addr)) 499 foreign_all_loopback = 0; 500 sockaddr(&faddr->address, 501 AF_INET6, 502 &xraddr->address.sin6.sin6_addr, 503 htons(xstcb->remote_port)); 504 break; 505 default: 506 errx(1, "adress family %d not supported", 507 xraddr->address.sa.sa_family); 508 } 509 faddr->next = NULL; 510 if (prev_faddr == NULL) 511 sock->faddr = faddr; 512 else 513 prev_faddr->next = faddr; 514 prev_faddr = faddr; 515 } 516 if (opt_c) { 517 if (!opt_L || !(local_all_loopback || foreign_all_loopback)) { 518 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 519 sock->next = sockhash[hash]; 520 sockhash[hash] = sock; 521 } else { 522 free_socket(sock); 523 } 524 } 525 } 526 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset); 527 offset += sizeof(struct xsctp_inpcb); 528 } 529 free(buf); 530 } 531 532 static void 533 gather_inet(int proto) 534 { 535 struct xinpgen *xig, *exig; 536 struct xinpcb *xip; 537 struct xtcpcb *xtp; 538 struct inpcb *inp; 539 struct xsocket *so; 540 struct sock *sock; 541 struct addr *laddr, *faddr; 542 const char *varname, *protoname; 543 size_t len, bufsize; 544 void *buf; 545 int hash, retry, state, vflag; 546 547 state = vflag = 0; 548 if (opt_4) 549 vflag |= INP_IPV4; 550 if (opt_6) 551 vflag |= INP_IPV6; 552 553 switch (proto) { 554 case IPPROTO_TCP: 555 varname = "net.inet.tcp.pcblist"; 556 protoname = "tcp"; 557 break; 558 case IPPROTO_UDP: 559 varname = "net.inet.udp.pcblist"; 560 protoname = "udp"; 561 break; 562 case IPPROTO_DIVERT: 563 varname = "net.inet.divert.pcblist"; 564 protoname = "div"; 565 break; 566 default: 567 errx(1, "protocol %d not supported", proto); 568 } 569 570 buf = NULL; 571 bufsize = 8192; 572 retry = 5; 573 do { 574 for (;;) { 575 if ((buf = realloc(buf, bufsize)) == NULL) 576 err(1, "realloc()"); 577 len = bufsize; 578 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 579 break; 580 if (errno == ENOENT) 581 goto out; 582 if (errno != ENOMEM || len != bufsize) 583 err(1, "sysctlbyname()"); 584 bufsize *= 2; 585 } 586 xig = (struct xinpgen *)buf; 587 exig = (struct xinpgen *)(void *) 588 ((char *)buf + len - sizeof *exig); 589 if (xig->xig_len != sizeof *xig || 590 exig->xig_len != sizeof *exig) 591 errx(1, "struct xinpgen size mismatch"); 592 } while (xig->xig_gen != exig->xig_gen && retry--); 593 594 if (xig->xig_gen != exig->xig_gen && opt_v) 595 warnx("warning: data may be inconsistent"); 596 597 for (;;) { 598 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); 599 if (xig >= exig) 600 break; 601 xip = (struct xinpcb *)xig; 602 xtp = (struct xtcpcb *)xig; 603 switch (proto) { 604 case IPPROTO_TCP: 605 if (xtp->xt_len != sizeof(*xtp)) { 606 warnx("struct xtcpcb size mismatch"); 607 goto out; 608 } 609 inp = &xtp->xt_inp; 610 so = &xtp->xt_socket; 611 protoname = xtp->xt_tp.t_flags & TF_TOE ? "toe" : "tcp"; 612 state = xtp->xt_tp.t_state; 613 break; 614 case IPPROTO_UDP: 615 case IPPROTO_DIVERT: 616 if (xip->xi_len != sizeof(*xip)) { 617 warnx("struct xinpcb size mismatch"); 618 goto out; 619 } 620 inp = &xip->xi_inp; 621 so = &xip->xi_socket; 622 break; 623 default: 624 errx(1, "protocol %d not supported", proto); 625 } 626 if ((inp->inp_vflag & vflag) == 0) 627 continue; 628 if (inp->inp_vflag & INP_IPV4) { 629 if ((inp->inp_fport == 0 && !opt_l) || 630 (inp->inp_fport != 0 && !opt_c)) 631 continue; 632 #define __IN_IS_ADDR_LOOPBACK(pina) \ 633 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 634 if (opt_L && 635 (__IN_IS_ADDR_LOOPBACK(&inp->inp_faddr) || 636 __IN_IS_ADDR_LOOPBACK(&inp->inp_laddr))) 637 continue; 638 #undef __IN_IS_ADDR_LOOPBACK 639 } else if (inp->inp_vflag & INP_IPV6) { 640 if ((inp->inp_fport == 0 && !opt_l) || 641 (inp->inp_fport != 0 && !opt_c)) 642 continue; 643 if (opt_L && 644 (IN6_IS_ADDR_LOOPBACK(&inp->in6p_faddr) || 645 IN6_IS_ADDR_LOOPBACK(&inp->in6p_laddr))) 646 continue; 647 } else { 648 if (opt_v) 649 warnx("invalid vflag 0x%x", inp->inp_vflag); 650 continue; 651 } 652 if ((sock = calloc(1, sizeof(*sock))) == NULL) 653 err(1, "malloc()"); 654 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 655 err(1, "malloc()"); 656 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 657 err(1, "malloc()"); 658 sock->socket = so->xso_so; 659 sock->proto = proto; 660 if (inp->inp_vflag & INP_IPV4) { 661 sock->family = AF_INET; 662 sockaddr(&laddr->address, sock->family, 663 &inp->inp_laddr, inp->inp_lport); 664 sockaddr(&faddr->address, sock->family, 665 &inp->inp_faddr, inp->inp_fport); 666 } else if (inp->inp_vflag & INP_IPV6) { 667 sock->family = AF_INET6; 668 sockaddr(&laddr->address, sock->family, 669 &inp->in6p_laddr, inp->inp_lport); 670 sockaddr(&faddr->address, sock->family, 671 &inp->in6p_faddr, inp->inp_fport); 672 } 673 laddr->next = NULL; 674 faddr->next = NULL; 675 sock->laddr = laddr; 676 sock->faddr = faddr; 677 sock->vflag = inp->inp_vflag; 678 if (proto == IPPROTO_TCP) 679 sock->state = xtp->xt_tp.t_state; 680 sock->protoname = protoname; 681 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 682 sock->next = sockhash[hash]; 683 sockhash[hash] = sock; 684 } 685 out: 686 free(buf); 687 } 688 689 static void 690 gather_unix(int proto) 691 { 692 struct xunpgen *xug, *exug; 693 struct xunpcb *xup; 694 struct sock *sock; 695 struct addr *laddr, *faddr; 696 const char *varname, *protoname; 697 size_t len, bufsize; 698 void *buf; 699 int hash, retry; 700 701 switch (proto) { 702 case SOCK_STREAM: 703 varname = "net.local.stream.pcblist"; 704 protoname = "stream"; 705 break; 706 case SOCK_DGRAM: 707 varname = "net.local.dgram.pcblist"; 708 protoname = "dgram"; 709 break; 710 case SOCK_SEQPACKET: 711 varname = "net.local.seqpacket.pcblist"; 712 protoname = "seqpac"; 713 break; 714 default: 715 abort(); 716 } 717 buf = NULL; 718 bufsize = 8192; 719 retry = 5; 720 do { 721 for (;;) { 722 if ((buf = realloc(buf, bufsize)) == NULL) 723 err(1, "realloc()"); 724 len = bufsize; 725 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 726 break; 727 if (errno != ENOMEM || len != bufsize) 728 err(1, "sysctlbyname()"); 729 bufsize *= 2; 730 } 731 xug = (struct xunpgen *)buf; 732 exug = (struct xunpgen *)(void *) 733 ((char *)buf + len - sizeof(*exug)); 734 if (xug->xug_len != sizeof(*xug) || 735 exug->xug_len != sizeof(*exug)) { 736 warnx("struct xinpgen size mismatch"); 737 goto out; 738 } 739 } while (xug->xug_gen != exug->xug_gen && retry--); 740 741 if (xug->xug_gen != exug->xug_gen && opt_v) 742 warnx("warning: data may be inconsistent"); 743 744 for (;;) { 745 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); 746 if (xug >= exug) 747 break; 748 xup = (struct xunpcb *)xug; 749 if (xup->xu_len != sizeof(*xup)) { 750 warnx("struct xunpcb size mismatch"); 751 goto out; 752 } 753 if ((xup->xu_unp.unp_conn == NULL && !opt_l) || 754 (xup->xu_unp.unp_conn != NULL && !opt_c)) 755 continue; 756 if ((sock = calloc(1, sizeof(*sock))) == NULL) 757 err(1, "malloc()"); 758 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 759 err(1, "malloc()"); 760 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 761 err(1, "malloc()"); 762 sock->socket = xup->xu_socket.xso_so; 763 sock->pcb = xup->xu_unpp; 764 sock->proto = proto; 765 sock->family = AF_UNIX; 766 sock->protoname = protoname; 767 if (xup->xu_unp.unp_addr != NULL) 768 laddr->address = 769 *(struct sockaddr_storage *)(void *)&xup->xu_addr; 770 else if (xup->xu_unp.unp_conn != NULL) 771 *(void **)&(faddr->address) = xup->xu_unp.unp_conn; 772 laddr->next = NULL; 773 faddr->next = NULL; 774 sock->laddr = laddr; 775 sock->faddr = faddr; 776 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 777 sock->next = sockhash[hash]; 778 sockhash[hash] = sock; 779 } 780 out: 781 free(buf); 782 } 783 784 static void 785 getfiles(void) 786 { 787 size_t len, olen; 788 789 olen = len = sizeof(*xfiles); 790 if ((xfiles = malloc(len)) == NULL) 791 err(1, "malloc()"); 792 while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) { 793 if (errno != ENOMEM || len != olen) 794 err(1, "sysctlbyname()"); 795 olen = len *= 2; 796 if ((xfiles = realloc(xfiles, len)) == NULL) 797 err(1, "realloc()"); 798 } 799 if (len > 0 && xfiles->xf_size != sizeof(*xfiles)) 800 errx(1, "struct xfile size mismatch"); 801 nxfiles = len / sizeof(*xfiles); 802 } 803 804 static int 805 printaddr(struct sockaddr_storage *ss) 806 { 807 struct sockaddr_un *sun; 808 char addrstr[NI_MAXHOST] = { '\0', '\0' }; 809 int error, off, port = 0; 810 811 switch (ss->ss_family) { 812 case AF_INET: 813 if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY) 814 addrstr[0] = '*'; 815 port = ntohs(sstosin(ss)->sin_port); 816 break; 817 case AF_INET6: 818 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr)) 819 addrstr[0] = '*'; 820 port = ntohs(sstosin6(ss)->sin6_port); 821 break; 822 case AF_UNIX: 823 sun = sstosun(ss); 824 off = (int)((char *)&sun->sun_path - (char *)sun); 825 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path)); 826 } 827 if (addrstr[0] == '\0') { 828 error = getnameinfo(sstosa(ss), ss->ss_len, addrstr, 829 sizeof(addrstr), NULL, 0, NI_NUMERICHOST); 830 if (error) 831 errx(1, "getnameinfo()"); 832 } 833 if (port == 0) 834 return xprintf("%s:*", addrstr); 835 else 836 return xprintf("%s:%d", addrstr, port); 837 } 838 839 static const char * 840 getprocname(pid_t pid) 841 { 842 static struct kinfo_proc proc; 843 size_t len; 844 int mib[4]; 845 846 mib[0] = CTL_KERN; 847 mib[1] = KERN_PROC; 848 mib[2] = KERN_PROC_PID; 849 mib[3] = (int)pid; 850 len = sizeof(proc); 851 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 852 /* Do not warn if the process exits before we get its name. */ 853 if (errno != ESRCH) 854 warn("sysctl()"); 855 return ("??"); 856 } 857 return (proc.ki_comm); 858 } 859 860 static int 861 getprocjid(pid_t pid) 862 { 863 static struct kinfo_proc proc; 864 size_t len; 865 int mib[4]; 866 867 mib[0] = CTL_KERN; 868 mib[1] = KERN_PROC; 869 mib[2] = KERN_PROC_PID; 870 mib[3] = (int)pid; 871 len = sizeof(proc); 872 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 873 /* Do not warn if the process exits before we get its jid. */ 874 if (errno != ESRCH) 875 warn("sysctl()"); 876 return (-1); 877 } 878 return (proc.ki_jid); 879 } 880 881 static int 882 check_ports(struct sock *s) 883 { 884 int port; 885 struct addr *addr; 886 887 if (ports == NULL) 888 return (1); 889 if ((s->family != AF_INET) && (s->family != AF_INET6)) 890 return (1); 891 for (addr = s->laddr; addr != NULL; addr = addr->next) { 892 if (s->family == AF_INET) 893 port = ntohs(sstosin(&addr->address)->sin_port); 894 else 895 port = ntohs(sstosin6(&addr->address)->sin6_port); 896 if (CHK_PORT(port)) 897 return (1); 898 } 899 for (addr = s->faddr; addr != NULL; addr = addr->next) { 900 if (s->family == AF_INET) 901 port = ntohs(sstosin(&addr->address)->sin_port); 902 else 903 port = ntohs(sstosin6(&addr->address)->sin6_port); 904 if (CHK_PORT(port)) 905 return (1); 906 } 907 return (0); 908 } 909 910 static void 911 displaysock(struct sock *s, int pos) 912 { 913 void *p; 914 int hash; 915 struct addr *laddr, *faddr; 916 struct sock *s_tmp; 917 918 while (pos < 29) 919 pos += xprintf(" "); 920 pos += xprintf("%s", s->protoname); 921 if (s->vflag & INP_IPV4) 922 pos += xprintf("4 "); 923 if (s->vflag & INP_IPV6) 924 pos += xprintf("6 "); 925 laddr = s->laddr; 926 faddr = s->faddr; 927 while (laddr != NULL || faddr != NULL) { 928 while (pos < 36) 929 pos += xprintf(" "); 930 switch (s->family) { 931 case AF_INET: 932 case AF_INET6: 933 if (laddr != NULL) { 934 pos += printaddr(&laddr->address); 935 if (s->family == AF_INET6 && pos >= 58) 936 pos += xprintf(" "); 937 } 938 while (pos < 58) 939 pos += xprintf(" "); 940 if (faddr != NULL) 941 pos += printaddr(&faddr->address); 942 break; 943 case AF_UNIX: 944 if ((laddr == NULL) || (faddr == NULL)) 945 errx(1, "laddr = %p or faddr = %p is NULL", 946 (void *)laddr, (void *)faddr); 947 /* server */ 948 if (laddr->address.ss_len > 0) { 949 pos += printaddr(&laddr->address); 950 break; 951 } 952 /* client */ 953 p = *(void **)&(faddr->address); 954 if (p == NULL) { 955 pos += xprintf("(not connected)"); 956 break; 957 } 958 pos += xprintf("-> "); 959 for (hash = 0; hash < HASHSIZE; ++hash) { 960 for (s_tmp = sockhash[hash]; 961 s_tmp != NULL; 962 s_tmp = s_tmp->next) 963 if (s_tmp->pcb == p) 964 break; 965 if (s_tmp != NULL) 966 break; 967 } 968 if (s_tmp == NULL || 969 s_tmp->laddr == NULL || 970 s_tmp->laddr->address.ss_len == 0) 971 pos += xprintf("??"); 972 else 973 pos += printaddr(&s_tmp->laddr->address); 974 break; 975 default: 976 abort(); 977 } 978 if (laddr != NULL) 979 laddr = laddr->next; 980 if (faddr != NULL) 981 faddr = faddr->next; 982 if ((laddr != NULL) || (faddr != NULL)) { 983 xprintf("\n"); 984 pos = 0; 985 } 986 } 987 if (opt_s && s->proto == IPPROTO_TCP) { 988 while (pos < 80) 989 pos += xprintf(" "); 990 if (s->state >= 0 && s->state < TCP_NSTATES) 991 pos += xprintf("%s", tcpstates[s->state]); 992 else 993 pos += xprintf("?"); 994 } 995 } 996 997 static void 998 display(void) 999 { 1000 struct passwd *pwd; 1001 struct xfile *xf; 1002 struct sock *s; 1003 int hash, n, pos; 1004 1005 printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s", 1006 "USER", "COMMAND", "PID", "FD", "PROTO", 1007 "LOCAL ADDRESS", "FOREIGN ADDRESS"); 1008 if (opt_s) 1009 printf(" %-12s", "STATE"); 1010 printf("\n"); 1011 setpassent(1); 1012 for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) { 1013 if (xf->xf_data == NULL) 1014 continue; 1015 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid)) 1016 continue; 1017 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE); 1018 for (s = sockhash[hash]; s != NULL; s = s->next) { 1019 if ((void *)s->socket != xf->xf_data) 1020 continue; 1021 if (!check_ports(s)) 1022 continue; 1023 s->shown = 1; 1024 pos = 0; 1025 if ((pwd = getpwuid(xf->xf_uid)) == NULL) 1026 pos += xprintf("%lu ", (u_long)xf->xf_uid); 1027 else 1028 pos += xprintf("%s ", pwd->pw_name); 1029 while (pos < 9) 1030 pos += xprintf(" "); 1031 pos += xprintf("%.10s", getprocname(xf->xf_pid)); 1032 while (pos < 20) 1033 pos += xprintf(" "); 1034 pos += xprintf("%lu ", (u_long)xf->xf_pid); 1035 while (pos < 26) 1036 pos += xprintf(" "); 1037 pos += xprintf("%d ", xf->xf_fd); 1038 displaysock(s, pos); 1039 xprintf("\n"); 1040 } 1041 } 1042 if (opt_j >= 0) 1043 return; 1044 for (hash = 0; hash < HASHSIZE; hash++) { 1045 for (s = sockhash[hash]; s != NULL; s = s->next) { 1046 if (s->shown) 1047 continue; 1048 if (!check_ports(s)) 1049 continue; 1050 pos = 0; 1051 pos += xprintf("%-8s %-10s %-5s %-2s ", 1052 "?", "?", "?", "?"); 1053 displaysock(s, pos); 1054 xprintf("\n"); 1055 } 1056 } 1057 } 1058 1059 static int set_default_protos(void) 1060 { 1061 struct protoent *prot; 1062 const char *pname; 1063 size_t pindex; 1064 1065 init_protos(default_numprotos); 1066 1067 for (pindex = 0; pindex < default_numprotos; pindex++) { 1068 pname = default_protos[pindex]; 1069 prot = getprotobyname(pname); 1070 if (prot == NULL) 1071 err(1, "getprotobyname: %s", pname); 1072 protos[pindex] = prot->p_proto; 1073 } 1074 numprotos = pindex; 1075 return (pindex); 1076 } 1077 1078 1079 static void 1080 usage(void) 1081 { 1082 fprintf(stderr, 1083 "usage: sockstat [-46cLlsu] [-j jid] [-p ports] [-P protocols]\n"); 1084 exit(1); 1085 } 1086 1087 int 1088 main(int argc, char *argv[]) 1089 { 1090 int protos_defined = -1; 1091 int o, i; 1092 1093 opt_j = -1; 1094 while ((o = getopt(argc, argv, "46cj:Llp:P:suv")) != -1) 1095 switch (o) { 1096 case '4': 1097 opt_4 = 1; 1098 break; 1099 case '6': 1100 opt_6 = 1; 1101 break; 1102 case 'c': 1103 opt_c = 1; 1104 break; 1105 case 'j': 1106 opt_j = atoi(optarg); 1107 break; 1108 case 'L': 1109 opt_L = 1; 1110 break; 1111 case 'l': 1112 opt_l = 1; 1113 break; 1114 case 'p': 1115 parse_ports(optarg); 1116 break; 1117 case 'P': 1118 protos_defined = parse_protos(optarg); 1119 break; 1120 case 's': 1121 opt_s = 1; 1122 break; 1123 case 'u': 1124 opt_u = 1; 1125 break; 1126 case 'v': 1127 ++opt_v; 1128 break; 1129 default: 1130 usage(); 1131 } 1132 1133 argc -= optind; 1134 argv += optind; 1135 1136 if (argc > 0) 1137 usage(); 1138 1139 if ((!opt_4 && !opt_6) && protos_defined != -1) 1140 opt_4 = opt_6 = 1; 1141 if (!opt_4 && !opt_6 && !opt_u) 1142 opt_4 = opt_6 = opt_u = 1; 1143 if ((opt_4 || opt_6) && protos_defined == -1) 1144 protos_defined = set_default_protos(); 1145 if (!opt_c && !opt_l) 1146 opt_c = opt_l = 1; 1147 1148 if (opt_4 || opt_6) { 1149 for (i = 0; i < protos_defined; i++) 1150 if (protos[i] == IPPROTO_SCTP) 1151 gather_sctp(); 1152 else 1153 gather_inet(protos[i]); 1154 } 1155 1156 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) { 1157 gather_unix(SOCK_STREAM); 1158 gather_unix(SOCK_DGRAM); 1159 gather_unix(SOCK_SEQPACKET); 1160 } 1161 getfiles(); 1162 display(); 1163 exit(0); 1164 } 1165