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