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$"); 33 34 #include <sys/param.h> 35 #include <sys/file.h> 36 #include <sys/socket.h> 37 #include <sys/socketvar.h> 38 #include <sys/sysctl.h> 39 #include <sys/jail.h> 40 #include <sys/user.h> 41 42 #include <sys/un.h> 43 #define _WANT_UNPCB 44 #include <sys/unpcb.h> 45 46 #include <net/route.h> 47 48 #include <netinet/in.h> 49 #include <netinet/in_pcb.h> 50 #include <netinet/sctp.h> 51 #include <netinet/tcp.h> 52 #define TCPSTATES /* load state names */ 53 #include <netinet/tcp_fsm.h> 54 #include <netinet/tcp_seq.h> 55 #include <netinet/tcp_var.h> 56 #include <arpa/inet.h> 57 58 #include <ctype.h> 59 #include <err.h> 60 #include <errno.h> 61 #include <jail.h> 62 #include <netdb.h> 63 #include <pwd.h> 64 #include <stdarg.h> 65 #include <stdio.h> 66 #include <stdlib.h> 67 #include <string.h> 68 #include <unistd.h> 69 70 #define sstosin(ss) ((struct sockaddr_in *)(ss)) 71 #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) 72 #define sstosun(ss) ((struct sockaddr_un *)(ss)) 73 #define sstosa(ss) ((struct sockaddr *)(ss)) 74 75 static int opt_4; /* Show IPv4 sockets */ 76 static int opt_6; /* Show IPv6 sockets */ 77 static int opt_C; /* Show congestion control */ 78 static int opt_c; /* Show connected sockets */ 79 static int opt_j; /* Show specified jail */ 80 static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */ 81 static int opt_l; /* Show listening sockets */ 82 static int opt_n; /* Don't resolve UIDs to user names */ 83 static int opt_q; /* Don't show header */ 84 static int opt_S; /* Show protocol stack if applicable */ 85 static int opt_s; /* Show protocol state if applicable */ 86 static int opt_U; /* Show remote UDP encapsulation port number */ 87 static int opt_u; /* Show Unix domain sockets */ 88 static int opt_v; /* Verbose mode */ 89 static int opt_w; /* Wide print area for addresses */ 90 91 /* 92 * Default protocols to use if no -P was defined. 93 */ 94 static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" }; 95 static size_t default_numprotos = nitems(default_protos); 96 97 static int *protos; /* protocols to use */ 98 static size_t numprotos; /* allocated size of protos[] */ 99 100 static int *ports; 101 102 #define INT_BIT (sizeof(int)*CHAR_BIT) 103 #define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0) 104 #define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT))) 105 106 struct addr { 107 struct sockaddr_storage address; 108 unsigned int encaps_port; 109 int state; 110 struct addr *next; 111 }; 112 113 struct sock { 114 kvaddr_t socket; 115 kvaddr_t pcb; 116 int shown; 117 int vflag; 118 int family; 119 int proto; 120 int state; 121 const char *protoname; 122 char stack[TCP_FUNCTION_NAME_LEN_MAX]; 123 char cc[TCP_CA_NAME_MAX]; 124 struct addr *laddr; 125 struct addr *faddr; 126 struct sock *next; 127 }; 128 129 #define HASHSIZE 1009 130 static struct sock *sockhash[HASHSIZE]; 131 132 static struct xfile *xfiles; 133 static int nxfiles; 134 135 static int 136 xprintf(const char *fmt, ...) 137 { 138 va_list ap; 139 int len; 140 141 va_start(ap, fmt); 142 len = vprintf(fmt, ap); 143 va_end(ap); 144 if (len < 0) 145 err(1, "printf()"); 146 return (len); 147 } 148 149 static int 150 get_proto_type(const char *proto) 151 { 152 struct protoent *pent; 153 154 if (strlen(proto) == 0) 155 return (0); 156 pent = getprotobyname(proto); 157 if (pent == NULL) { 158 warn("getprotobyname"); 159 return (-1); 160 } 161 return (pent->p_proto); 162 } 163 164 static void 165 init_protos(int num) 166 { 167 int proto_count = 0; 168 169 if (num > 0) { 170 proto_count = num; 171 } else { 172 /* Find the maximum number of possible protocols. */ 173 while (getprotoent() != NULL) 174 proto_count++; 175 endprotoent(); 176 } 177 178 if ((protos = malloc(sizeof(int) * proto_count)) == NULL) 179 err(1, "malloc"); 180 numprotos = proto_count; 181 } 182 183 static int 184 parse_protos(char *protospec) 185 { 186 char *prot; 187 int proto_type, proto_index; 188 189 if (protospec == NULL) 190 return (-1); 191 192 init_protos(0); 193 proto_index = 0; 194 while ((prot = strsep(&protospec, ",")) != NULL) { 195 if (strlen(prot) == 0) 196 continue; 197 proto_type = get_proto_type(prot); 198 if (proto_type != -1) 199 protos[proto_index++] = proto_type; 200 } 201 numprotos = proto_index; 202 return (proto_index); 203 } 204 205 static void 206 parse_ports(const char *portspec) 207 { 208 const char *p, *q; 209 int port, end; 210 211 if (ports == NULL) 212 if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL) 213 err(1, "calloc()"); 214 p = portspec; 215 while (*p != '\0') { 216 if (!isdigit(*p)) 217 errx(1, "syntax error in port range"); 218 for (q = p; *q != '\0' && isdigit(*q); ++q) 219 /* nothing */ ; 220 for (port = 0; p < q; ++p) 221 port = port * 10 + digittoint(*p); 222 if (port < 0 || port > 65535) 223 errx(1, "invalid port number"); 224 SET_PORT(port); 225 switch (*p) { 226 case '-': 227 ++p; 228 break; 229 case ',': 230 ++p; 231 /* fall through */ 232 case '\0': 233 default: 234 continue; 235 } 236 for (q = p; *q != '\0' && isdigit(*q); ++q) 237 /* nothing */ ; 238 for (end = 0; p < q; ++p) 239 end = end * 10 + digittoint(*p); 240 if (end < port || end > 65535) 241 errx(1, "invalid port number"); 242 while (port++ < end) 243 SET_PORT(port); 244 if (*p == ',') 245 ++p; 246 } 247 } 248 249 static void 250 sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port) 251 { 252 struct sockaddr_in *sin4; 253 struct sockaddr_in6 *sin6; 254 255 bzero(ss, sizeof(*ss)); 256 switch (af) { 257 case AF_INET: 258 sin4 = sstosin(ss); 259 sin4->sin_len = sizeof(*sin4); 260 sin4->sin_family = af; 261 sin4->sin_port = port; 262 sin4->sin_addr = *(struct in_addr *)addr; 263 break; 264 case AF_INET6: 265 sin6 = sstosin6(ss); 266 sin6->sin6_len = sizeof(*sin6); 267 sin6->sin6_family = af; 268 sin6->sin6_port = port; 269 sin6->sin6_addr = *(struct in6_addr *)addr; 270 #define s6_addr16 __u6_addr.__u6_addr16 271 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 272 sin6->sin6_scope_id = 273 ntohs(sin6->sin6_addr.s6_addr16[1]); 274 sin6->sin6_addr.s6_addr16[1] = 0; 275 } 276 break; 277 default: 278 abort(); 279 } 280 } 281 282 static void 283 free_socket(struct sock *sock) 284 { 285 struct addr *cur, *next; 286 287 cur = sock->laddr; 288 while (cur != NULL) { 289 next = cur->next; 290 free(cur); 291 cur = next; 292 } 293 cur = sock->faddr; 294 while (cur != NULL) { 295 next = cur->next; 296 free(cur); 297 cur = next; 298 } 299 free(sock); 300 } 301 302 static void 303 gather_sctp(void) 304 { 305 struct sock *sock; 306 struct addr *laddr, *prev_laddr, *faddr, *prev_faddr; 307 struct xsctp_inpcb *xinpcb; 308 struct xsctp_tcb *xstcb; 309 struct xsctp_raddr *xraddr; 310 struct xsctp_laddr *xladdr; 311 const char *varname; 312 size_t len, offset; 313 char *buf; 314 int hash, vflag; 315 int no_stcb, local_all_loopback, foreign_all_loopback; 316 317 vflag = 0; 318 if (opt_4) 319 vflag |= INP_IPV4; 320 if (opt_6) 321 vflag |= INP_IPV6; 322 323 varname = "net.inet.sctp.assoclist"; 324 if (sysctlbyname(varname, 0, &len, 0, 0) < 0) { 325 if (errno != ENOENT) 326 err(1, "sysctlbyname()"); 327 return; 328 } 329 if ((buf = (char *)malloc(len)) == NULL) { 330 err(1, "malloc()"); 331 return; 332 } 333 if (sysctlbyname(varname, buf, &len, 0, 0) < 0) { 334 err(1, "sysctlbyname()"); 335 free(buf); 336 return; 337 } 338 xinpcb = (struct xsctp_inpcb *)(void *)buf; 339 offset = sizeof(struct xsctp_inpcb); 340 while ((offset < len) && (xinpcb->last == 0)) { 341 if ((sock = calloc(1, sizeof *sock)) == NULL) 342 err(1, "malloc()"); 343 sock->socket = xinpcb->socket; 344 sock->proto = IPPROTO_SCTP; 345 sock->protoname = "sctp"; 346 if (xinpcb->maxqlen == 0) 347 sock->state = SCTP_CLOSED; 348 else 349 sock->state = SCTP_LISTEN; 350 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 351 sock->family = AF_INET6; 352 /* 353 * Currently there is no way to distinguish between 354 * IPv6 only sockets or dual family sockets. 355 * So mark it as dual socket. 356 */ 357 sock->vflag = INP_IPV6 | INP_IPV4; 358 } else { 359 sock->family = AF_INET; 360 sock->vflag = INP_IPV4; 361 } 362 prev_laddr = NULL; 363 local_all_loopback = 1; 364 while (offset < len) { 365 xladdr = (struct xsctp_laddr *)(void *)(buf + offset); 366 offset += sizeof(struct xsctp_laddr); 367 if (xladdr->last == 1) 368 break; 369 if ((laddr = calloc(1, sizeof(struct addr))) == NULL) 370 err(1, "malloc()"); 371 switch (xladdr->address.sa.sa_family) { 372 case AF_INET: 373 #define __IN_IS_ADDR_LOOPBACK(pina) \ 374 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 375 if (!__IN_IS_ADDR_LOOPBACK( 376 &xladdr->address.sin.sin_addr)) 377 local_all_loopback = 0; 378 #undef __IN_IS_ADDR_LOOPBACK 379 sockaddr(&laddr->address, AF_INET, 380 &xladdr->address.sin.sin_addr, 381 htons(xinpcb->local_port)); 382 break; 383 case AF_INET6: 384 if (!IN6_IS_ADDR_LOOPBACK( 385 &xladdr->address.sin6.sin6_addr)) 386 local_all_loopback = 0; 387 sockaddr(&laddr->address, AF_INET6, 388 &xladdr->address.sin6.sin6_addr, 389 htons(xinpcb->local_port)); 390 break; 391 default: 392 errx(1, "address family %d not supported", 393 xladdr->address.sa.sa_family); 394 } 395 laddr->next = NULL; 396 if (prev_laddr == NULL) 397 sock->laddr = laddr; 398 else 399 prev_laddr->next = laddr; 400 prev_laddr = laddr; 401 } 402 if (sock->laddr == NULL) { 403 if ((sock->laddr = 404 calloc(1, sizeof(struct addr))) == NULL) 405 err(1, "malloc()"); 406 sock->laddr->address.ss_family = sock->family; 407 if (sock->family == AF_INET) 408 sock->laddr->address.ss_len = 409 sizeof(struct sockaddr_in); 410 else 411 sock->laddr->address.ss_len = 412 sizeof(struct sockaddr_in6); 413 local_all_loopback = 0; 414 } 415 if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL) 416 err(1, "malloc()"); 417 sock->faddr->address.ss_family = sock->family; 418 if (sock->family == AF_INET) 419 sock->faddr->address.ss_len = 420 sizeof(struct sockaddr_in); 421 else 422 sock->faddr->address.ss_len = 423 sizeof(struct sockaddr_in6); 424 no_stcb = 1; 425 while (offset < len) { 426 xstcb = (struct xsctp_tcb *)(void *)(buf + offset); 427 offset += sizeof(struct xsctp_tcb); 428 if (no_stcb) { 429 if (opt_l && (sock->vflag & vflag) && 430 (!opt_L || !local_all_loopback) && 431 ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) || 432 (xstcb->last == 1))) { 433 hash = (int)((uintptr_t)sock->socket % 434 HASHSIZE); 435 sock->next = sockhash[hash]; 436 sockhash[hash] = sock; 437 } else { 438 free_socket(sock); 439 } 440 } 441 if (xstcb->last == 1) 442 break; 443 no_stcb = 0; 444 if (opt_c) { 445 if ((sock = calloc(1, sizeof *sock)) == NULL) 446 err(1, "malloc()"); 447 sock->socket = xinpcb->socket; 448 sock->proto = IPPROTO_SCTP; 449 sock->protoname = "sctp"; 450 sock->state = (int)xstcb->state; 451 if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { 452 sock->family = AF_INET6; 453 /* 454 * Currently there is no way to distinguish 455 * between IPv6 only sockets or dual family 456 * sockets. So mark it as dual socket. 457 */ 458 sock->vflag = INP_IPV6 | INP_IPV4; 459 } else { 460 sock->family = AF_INET; 461 sock->vflag = INP_IPV4; 462 } 463 } 464 prev_laddr = NULL; 465 local_all_loopback = 1; 466 while (offset < len) { 467 xladdr = (struct xsctp_laddr *)(void *)(buf + 468 offset); 469 offset += sizeof(struct xsctp_laddr); 470 if (xladdr->last == 1) 471 break; 472 if (!opt_c) 473 continue; 474 laddr = calloc(1, sizeof(struct addr)); 475 if (laddr == NULL) 476 err(1, "malloc()"); 477 switch (xladdr->address.sa.sa_family) { 478 case AF_INET: 479 #define __IN_IS_ADDR_LOOPBACK(pina) \ 480 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 481 if (!__IN_IS_ADDR_LOOPBACK( 482 &xladdr->address.sin.sin_addr)) 483 local_all_loopback = 0; 484 #undef __IN_IS_ADDR_LOOPBACK 485 sockaddr(&laddr->address, AF_INET, 486 &xladdr->address.sin.sin_addr, 487 htons(xstcb->local_port)); 488 break; 489 case AF_INET6: 490 if (!IN6_IS_ADDR_LOOPBACK( 491 &xladdr->address.sin6.sin6_addr)) 492 local_all_loopback = 0; 493 sockaddr(&laddr->address, AF_INET6, 494 &xladdr->address.sin6.sin6_addr, 495 htons(xstcb->local_port)); 496 break; 497 default: 498 errx(1, 499 "address family %d not supported", 500 xladdr->address.sa.sa_family); 501 } 502 laddr->next = NULL; 503 if (prev_laddr == NULL) 504 sock->laddr = laddr; 505 else 506 prev_laddr->next = laddr; 507 prev_laddr = laddr; 508 } 509 prev_faddr = NULL; 510 foreign_all_loopback = 1; 511 while (offset < len) { 512 xraddr = (struct xsctp_raddr *)(void *)(buf + 513 offset); 514 offset += sizeof(struct xsctp_raddr); 515 if (xraddr->last == 1) 516 break; 517 if (!opt_c) 518 continue; 519 faddr = calloc(1, sizeof(struct addr)); 520 if (faddr == NULL) 521 err(1, "malloc()"); 522 switch (xraddr->address.sa.sa_family) { 523 case AF_INET: 524 #define __IN_IS_ADDR_LOOPBACK(pina) \ 525 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 526 if (!__IN_IS_ADDR_LOOPBACK( 527 &xraddr->address.sin.sin_addr)) 528 foreign_all_loopback = 0; 529 #undef __IN_IS_ADDR_LOOPBACK 530 sockaddr(&faddr->address, AF_INET, 531 &xraddr->address.sin.sin_addr, 532 htons(xstcb->remote_port)); 533 break; 534 case AF_INET6: 535 if (!IN6_IS_ADDR_LOOPBACK( 536 &xraddr->address.sin6.sin6_addr)) 537 foreign_all_loopback = 0; 538 sockaddr(&faddr->address, AF_INET6, 539 &xraddr->address.sin6.sin6_addr, 540 htons(xstcb->remote_port)); 541 break; 542 default: 543 errx(1, 544 "address family %d not supported", 545 xraddr->address.sa.sa_family); 546 } 547 faddr->encaps_port = xraddr->encaps_port; 548 faddr->state = xraddr->state; 549 faddr->next = NULL; 550 if (prev_faddr == NULL) 551 sock->faddr = faddr; 552 else 553 prev_faddr->next = faddr; 554 prev_faddr = faddr; 555 } 556 if (opt_c) { 557 if ((sock->vflag & vflag) && 558 (!opt_L || 559 !(local_all_loopback || 560 foreign_all_loopback))) { 561 hash = (int)((uintptr_t)sock->socket % 562 HASHSIZE); 563 sock->next = sockhash[hash]; 564 sockhash[hash] = sock; 565 } else { 566 free_socket(sock); 567 } 568 } 569 } 570 xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset); 571 offset += sizeof(struct xsctp_inpcb); 572 } 573 free(buf); 574 } 575 576 static void 577 gather_inet(int proto) 578 { 579 struct xinpgen *xig, *exig; 580 struct xinpcb *xip; 581 struct xtcpcb *xtp = NULL; 582 struct xsocket *so; 583 struct sock *sock; 584 struct addr *laddr, *faddr; 585 const char *varname, *protoname; 586 size_t len, bufsize; 587 void *buf; 588 int hash, retry, vflag; 589 590 vflag = 0; 591 if (opt_4) 592 vflag |= INP_IPV4; 593 if (opt_6) 594 vflag |= INP_IPV6; 595 596 switch (proto) { 597 case IPPROTO_TCP: 598 varname = "net.inet.tcp.pcblist"; 599 protoname = "tcp"; 600 break; 601 case IPPROTO_UDP: 602 varname = "net.inet.udp.pcblist"; 603 protoname = "udp"; 604 break; 605 case IPPROTO_DIVERT: 606 varname = "net.inet.divert.pcblist"; 607 protoname = "div"; 608 break; 609 default: 610 errx(1, "protocol %d not supported", proto); 611 } 612 613 buf = NULL; 614 bufsize = 8192; 615 retry = 5; 616 do { 617 for (;;) { 618 if ((buf = realloc(buf, bufsize)) == NULL) 619 err(1, "realloc()"); 620 len = bufsize; 621 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 622 break; 623 if (errno == ENOENT) 624 goto out; 625 if (errno != ENOMEM || len != bufsize) 626 err(1, "sysctlbyname()"); 627 bufsize *= 2; 628 } 629 xig = (struct xinpgen *)buf; 630 exig = (struct xinpgen *)(void *) 631 ((char *)buf + len - sizeof *exig); 632 if (xig->xig_len != sizeof *xig || 633 exig->xig_len != sizeof *exig) 634 errx(1, "struct xinpgen size mismatch"); 635 } while (xig->xig_gen != exig->xig_gen && retry--); 636 637 if (xig->xig_gen != exig->xig_gen && opt_v) 638 warnx("warning: data may be inconsistent"); 639 640 for (;;) { 641 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); 642 if (xig >= exig) 643 break; 644 switch (proto) { 645 case IPPROTO_TCP: 646 xtp = (struct xtcpcb *)xig; 647 xip = &xtp->xt_inp; 648 if (xtp->xt_len != sizeof(*xtp)) { 649 warnx("struct xtcpcb size mismatch"); 650 goto out; 651 } 652 protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp"; 653 break; 654 case IPPROTO_UDP: 655 case IPPROTO_DIVERT: 656 xip = (struct xinpcb *)xig; 657 if (xip->xi_len != sizeof(*xip)) { 658 warnx("struct xinpcb size mismatch"); 659 goto out; 660 } 661 break; 662 default: 663 errx(1, "protocol %d not supported", proto); 664 } 665 so = &xip->xi_socket; 666 if ((xip->inp_vflag & vflag) == 0) 667 continue; 668 if (xip->inp_vflag & INP_IPV4) { 669 if ((xip->inp_fport == 0 && !opt_l) || 670 (xip->inp_fport != 0 && !opt_c)) 671 continue; 672 #define __IN_IS_ADDR_LOOPBACK(pina) \ 673 ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 674 if (opt_L && 675 (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) || 676 __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr))) 677 continue; 678 #undef __IN_IS_ADDR_LOOPBACK 679 } else if (xip->inp_vflag & INP_IPV6) { 680 if ((xip->inp_fport == 0 && !opt_l) || 681 (xip->inp_fport != 0 && !opt_c)) 682 continue; 683 if (opt_L && 684 (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) || 685 IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr))) 686 continue; 687 } else { 688 if (opt_v) 689 warnx("invalid vflag 0x%x", xip->inp_vflag); 690 continue; 691 } 692 if ((sock = calloc(1, sizeof(*sock))) == NULL) 693 err(1, "malloc()"); 694 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 695 err(1, "malloc()"); 696 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 697 err(1, "malloc()"); 698 sock->socket = so->xso_so; 699 sock->proto = proto; 700 if (xip->inp_vflag & INP_IPV4) { 701 sock->family = AF_INET; 702 sockaddr(&laddr->address, sock->family, 703 &xip->inp_laddr, xip->inp_lport); 704 sockaddr(&faddr->address, sock->family, 705 &xip->inp_faddr, xip->inp_fport); 706 } else if (xip->inp_vflag & INP_IPV6) { 707 sock->family = AF_INET6; 708 sockaddr(&laddr->address, sock->family, 709 &xip->in6p_laddr, xip->inp_lport); 710 sockaddr(&faddr->address, sock->family, 711 &xip->in6p_faddr, xip->inp_fport); 712 } 713 laddr->next = NULL; 714 faddr->next = NULL; 715 sock->laddr = laddr; 716 sock->faddr = faddr; 717 sock->vflag = xip->inp_vflag; 718 if (proto == IPPROTO_TCP) { 719 sock->state = xtp->t_state; 720 memcpy(sock->stack, xtp->xt_stack, 721 TCP_FUNCTION_NAME_LEN_MAX); 722 memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX); 723 } 724 sock->protoname = protoname; 725 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 726 sock->next = sockhash[hash]; 727 sockhash[hash] = sock; 728 } 729 out: 730 free(buf); 731 } 732 733 static void 734 gather_unix(int proto) 735 { 736 struct xunpgen *xug, *exug; 737 struct xunpcb *xup; 738 struct sock *sock; 739 struct addr *laddr, *faddr; 740 const char *varname, *protoname; 741 size_t len, bufsize; 742 void *buf; 743 int hash, retry; 744 745 switch (proto) { 746 case SOCK_STREAM: 747 varname = "net.local.stream.pcblist"; 748 protoname = "stream"; 749 break; 750 case SOCK_DGRAM: 751 varname = "net.local.dgram.pcblist"; 752 protoname = "dgram"; 753 break; 754 case SOCK_SEQPACKET: 755 varname = "net.local.seqpacket.pcblist"; 756 protoname = "seqpac"; 757 break; 758 default: 759 abort(); 760 } 761 buf = NULL; 762 bufsize = 8192; 763 retry = 5; 764 do { 765 for (;;) { 766 if ((buf = realloc(buf, bufsize)) == NULL) 767 err(1, "realloc()"); 768 len = bufsize; 769 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) 770 break; 771 if (errno != ENOMEM || len != bufsize) 772 err(1, "sysctlbyname()"); 773 bufsize *= 2; 774 } 775 xug = (struct xunpgen *)buf; 776 exug = (struct xunpgen *)(void *) 777 ((char *)buf + len - sizeof(*exug)); 778 if (xug->xug_len != sizeof(*xug) || 779 exug->xug_len != sizeof(*exug)) { 780 warnx("struct xinpgen size mismatch"); 781 goto out; 782 } 783 } while (xug->xug_gen != exug->xug_gen && retry--); 784 785 if (xug->xug_gen != exug->xug_gen && opt_v) 786 warnx("warning: data may be inconsistent"); 787 788 for (;;) { 789 xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); 790 if (xug >= exug) 791 break; 792 xup = (struct xunpcb *)xug; 793 if (xup->xu_len != sizeof(*xup)) { 794 warnx("struct xunpcb size mismatch"); 795 goto out; 796 } 797 if ((xup->unp_conn == 0 && !opt_l) || 798 (xup->unp_conn != 0 && !opt_c)) 799 continue; 800 if ((sock = calloc(1, sizeof(*sock))) == NULL) 801 err(1, "malloc()"); 802 if ((laddr = calloc(1, sizeof *laddr)) == NULL) 803 err(1, "malloc()"); 804 if ((faddr = calloc(1, sizeof *faddr)) == NULL) 805 err(1, "malloc()"); 806 sock->socket = xup->xu_socket.xso_so; 807 sock->pcb = xup->xu_unpp; 808 sock->proto = proto; 809 sock->family = AF_UNIX; 810 sock->protoname = protoname; 811 if (xup->xu_addr.sun_family == AF_UNIX) 812 laddr->address = 813 *(struct sockaddr_storage *)(void *)&xup->xu_addr; 814 else if (xup->unp_conn != 0) 815 *(kvaddr_t*)&(faddr->address) = xup->unp_conn; 816 laddr->next = NULL; 817 faddr->next = NULL; 818 sock->laddr = laddr; 819 sock->faddr = faddr; 820 hash = (int)((uintptr_t)sock->socket % HASHSIZE); 821 sock->next = sockhash[hash]; 822 sockhash[hash] = sock; 823 } 824 out: 825 free(buf); 826 } 827 828 static void 829 getfiles(void) 830 { 831 size_t len, olen; 832 833 olen = len = sizeof(*xfiles); 834 if ((xfiles = malloc(len)) == NULL) 835 err(1, "malloc()"); 836 while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) { 837 if (errno != ENOMEM || len != olen) 838 err(1, "sysctlbyname()"); 839 olen = len *= 2; 840 if ((xfiles = realloc(xfiles, len)) == NULL) 841 err(1, "realloc()"); 842 } 843 if (len > 0 && xfiles->xf_size != sizeof(*xfiles)) 844 errx(1, "struct xfile size mismatch"); 845 nxfiles = len / sizeof(*xfiles); 846 } 847 848 static int 849 printaddr(struct sockaddr_storage *ss) 850 { 851 struct sockaddr_un *sun; 852 char addrstr[NI_MAXHOST] = { '\0', '\0' }; 853 int error, off, port = 0; 854 855 switch (ss->ss_family) { 856 case AF_INET: 857 if (inet_lnaof(sstosin(ss)->sin_addr) == INADDR_ANY) 858 addrstr[0] = '*'; 859 port = ntohs(sstosin(ss)->sin_port); 860 break; 861 case AF_INET6: 862 if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr)) 863 addrstr[0] = '*'; 864 port = ntohs(sstosin6(ss)->sin6_port); 865 break; 866 case AF_UNIX: 867 sun = sstosun(ss); 868 off = (int)((char *)&sun->sun_path - (char *)sun); 869 return (xprintf("%.*s", sun->sun_len - off, sun->sun_path)); 870 } 871 if (addrstr[0] == '\0') { 872 error = getnameinfo(sstosa(ss), ss->ss_len, addrstr, 873 sizeof(addrstr), NULL, 0, NI_NUMERICHOST); 874 if (error) 875 errx(1, "getnameinfo()"); 876 } 877 if (port == 0) 878 return xprintf("%s:*", addrstr); 879 else 880 return xprintf("%s:%d", addrstr, port); 881 } 882 883 static const char * 884 getprocname(pid_t pid) 885 { 886 static struct kinfo_proc proc; 887 size_t len; 888 int mib[4]; 889 890 mib[0] = CTL_KERN; 891 mib[1] = KERN_PROC; 892 mib[2] = KERN_PROC_PID; 893 mib[3] = (int)pid; 894 len = sizeof(proc); 895 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 896 /* Do not warn if the process exits before we get its name. */ 897 if (errno != ESRCH) 898 warn("sysctl()"); 899 return ("??"); 900 } 901 return (proc.ki_comm); 902 } 903 904 static int 905 getprocjid(pid_t pid) 906 { 907 static struct kinfo_proc proc; 908 size_t len; 909 int mib[4]; 910 911 mib[0] = CTL_KERN; 912 mib[1] = KERN_PROC; 913 mib[2] = KERN_PROC_PID; 914 mib[3] = (int)pid; 915 len = sizeof(proc); 916 if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { 917 /* Do not warn if the process exits before we get its jid. */ 918 if (errno != ESRCH) 919 warn("sysctl()"); 920 return (-1); 921 } 922 return (proc.ki_jid); 923 } 924 925 static int 926 check_ports(struct sock *s) 927 { 928 int port; 929 struct addr *addr; 930 931 if (ports == NULL) 932 return (1); 933 if ((s->family != AF_INET) && (s->family != AF_INET6)) 934 return (1); 935 for (addr = s->laddr; addr != NULL; addr = addr->next) { 936 if (s->family == AF_INET) 937 port = ntohs(sstosin(&addr->address)->sin_port); 938 else 939 port = ntohs(sstosin6(&addr->address)->sin6_port); 940 if (CHK_PORT(port)) 941 return (1); 942 } 943 for (addr = s->faddr; addr != NULL; addr = addr->next) { 944 if (s->family == AF_INET) 945 port = ntohs(sstosin(&addr->address)->sin_port); 946 else 947 port = ntohs(sstosin6(&addr->address)->sin6_port); 948 if (CHK_PORT(port)) 949 return (1); 950 } 951 return (0); 952 } 953 954 static const char * 955 sctp_conn_state(int state) 956 { 957 switch (state) { 958 case SCTP_CLOSED: 959 return "CLOSED"; 960 break; 961 case SCTP_BOUND: 962 return "BOUND"; 963 break; 964 case SCTP_LISTEN: 965 return "LISTEN"; 966 break; 967 case SCTP_COOKIE_WAIT: 968 return "COOKIE_WAIT"; 969 break; 970 case SCTP_COOKIE_ECHOED: 971 return "COOKIE_ECHOED"; 972 break; 973 case SCTP_ESTABLISHED: 974 return "ESTABLISHED"; 975 break; 976 case SCTP_SHUTDOWN_SENT: 977 return "SHUTDOWN_SENT"; 978 break; 979 case SCTP_SHUTDOWN_RECEIVED: 980 return "SHUTDOWN_RECEIVED"; 981 break; 982 case SCTP_SHUTDOWN_ACK_SENT: 983 return "SHUTDOWN_ACK_SENT"; 984 break; 985 case SCTP_SHUTDOWN_PENDING: 986 return "SHUTDOWN_PENDING"; 987 break; 988 default: 989 return "UNKNOWN"; 990 break; 991 } 992 } 993 994 static const char * 995 sctp_path_state(int state) 996 { 997 switch (state) { 998 case SCTP_UNCONFIRMED: 999 return "UNCONFIRMED"; 1000 break; 1001 case SCTP_ACTIVE: 1002 return "ACTIVE"; 1003 break; 1004 case SCTP_INACTIVE: 1005 return "INACTIVE"; 1006 break; 1007 default: 1008 return "UNKNOWN"; 1009 break; 1010 } 1011 } 1012 1013 static void 1014 displaysock(struct sock *s, int pos) 1015 { 1016 kvaddr_t p; 1017 int hash, first, offset; 1018 struct addr *laddr, *faddr; 1019 struct sock *s_tmp; 1020 1021 while (pos < 29) 1022 pos += xprintf(" "); 1023 pos += xprintf("%s", s->protoname); 1024 if (s->vflag & INP_IPV4) 1025 pos += xprintf("4"); 1026 if (s->vflag & INP_IPV6) 1027 pos += xprintf("6"); 1028 if (s->vflag & (INP_IPV4 | INP_IPV6)) 1029 pos += xprintf(" "); 1030 laddr = s->laddr; 1031 faddr = s->faddr; 1032 first = 1; 1033 while (laddr != NULL || faddr != NULL) { 1034 offset = 36; 1035 while (pos < offset) 1036 pos += xprintf(" "); 1037 switch (s->family) { 1038 case AF_INET: 1039 case AF_INET6: 1040 if (laddr != NULL) { 1041 pos += printaddr(&laddr->address); 1042 if (s->family == AF_INET6 && pos >= 58) 1043 pos += xprintf(" "); 1044 } 1045 offset += opt_w ? 46 : 22; 1046 while (pos < offset) 1047 pos += xprintf(" "); 1048 if (faddr != NULL) 1049 pos += printaddr(&faddr->address); 1050 offset += opt_w ? 46 : 22; 1051 break; 1052 case AF_UNIX: 1053 if ((laddr == NULL) || (faddr == NULL)) 1054 errx(1, "laddr = %p or faddr = %p is NULL", 1055 (void *)laddr, (void *)faddr); 1056 /* server */ 1057 if (laddr->address.ss_len > 0) { 1058 pos += printaddr(&laddr->address); 1059 break; 1060 } 1061 /* client */ 1062 p = *(kvaddr_t*)&(faddr->address); 1063 if (p == 0) { 1064 pos += xprintf("(not connected)"); 1065 offset += opt_w ? 92 : 44; 1066 break; 1067 } 1068 pos += xprintf("-> "); 1069 for (hash = 0; hash < HASHSIZE; ++hash) { 1070 for (s_tmp = sockhash[hash]; 1071 s_tmp != NULL; 1072 s_tmp = s_tmp->next) 1073 if (s_tmp->pcb == p) 1074 break; 1075 if (s_tmp != NULL) 1076 break; 1077 } 1078 if (s_tmp == NULL || s_tmp->laddr == NULL || 1079 s_tmp->laddr->address.ss_len == 0) 1080 pos += xprintf("??"); 1081 else 1082 pos += printaddr(&s_tmp->laddr->address); 1083 offset += opt_w ? 92 : 44; 1084 break; 1085 default: 1086 abort(); 1087 } 1088 if (opt_U) { 1089 if (faddr != NULL && 1090 s->proto == IPPROTO_SCTP && 1091 s->state != SCTP_CLOSED && 1092 s->state != SCTP_BOUND && 1093 s->state != SCTP_LISTEN) { 1094 while (pos < offset) 1095 pos += xprintf(" "); 1096 pos += xprintf("%u", 1097 ntohs(faddr->encaps_port)); 1098 } 1099 offset += 7; 1100 } 1101 if (opt_s) { 1102 if (faddr != NULL && 1103 s->proto == IPPROTO_SCTP && 1104 s->state != SCTP_CLOSED && 1105 s->state != SCTP_BOUND && 1106 s->state != SCTP_LISTEN) { 1107 while (pos < offset) 1108 pos += xprintf(" "); 1109 pos += xprintf("%s", 1110 sctp_path_state(faddr->state)); 1111 } 1112 offset += 13; 1113 } 1114 if (first) { 1115 if (opt_s) { 1116 if (s->proto == IPPROTO_SCTP || 1117 s->proto == IPPROTO_TCP) { 1118 while (pos < offset) 1119 pos += xprintf(" "); 1120 switch (s->proto) { 1121 case IPPROTO_SCTP: 1122 pos += xprintf("%s", 1123 sctp_conn_state(s->state)); 1124 break; 1125 case IPPROTO_TCP: 1126 if (s->state >= 0 && 1127 s->state < TCP_NSTATES) 1128 pos += xprintf("%s", 1129 tcpstates[s->state]); 1130 else 1131 pos += xprintf("?"); 1132 break; 1133 } 1134 } 1135 offset += 13; 1136 } 1137 if (opt_S) { 1138 if (s->proto == IPPROTO_TCP) { 1139 while (pos < offset) 1140 pos += xprintf(" "); 1141 pos += xprintf("%.*s", 1142 TCP_FUNCTION_NAME_LEN_MAX, 1143 s->stack); 1144 } 1145 offset += TCP_FUNCTION_NAME_LEN_MAX + 1; 1146 } 1147 if (opt_C) { 1148 if (s->proto == IPPROTO_TCP) { 1149 while (pos < offset) 1150 pos += xprintf(" "); 1151 xprintf("%.*s", TCP_CA_NAME_MAX, s->cc); 1152 } 1153 offset += TCP_CA_NAME_MAX + 1; 1154 } 1155 } 1156 if (laddr != NULL) 1157 laddr = laddr->next; 1158 if (faddr != NULL) 1159 faddr = faddr->next; 1160 if ((laddr != NULL) || (faddr != NULL)) { 1161 xprintf("\n"); 1162 pos = 0; 1163 } 1164 first = 0; 1165 } 1166 xprintf("\n"); 1167 } 1168 1169 static void 1170 display(void) 1171 { 1172 struct passwd *pwd; 1173 struct xfile *xf; 1174 struct sock *s; 1175 int hash, n, pos; 1176 1177 if (opt_q != 1) { 1178 printf("%-8s %-10s %-5s %-2s %-6s %-*s %-*s", 1179 "USER", "COMMAND", "PID", "FD", "PROTO", 1180 opt_w ? 45 : 21, "LOCAL ADDRESS", 1181 opt_w ? 45 : 21, "FOREIGN ADDRESS"); 1182 if (opt_U) 1183 printf(" %-6s", "ENCAPS"); 1184 if (opt_s) { 1185 printf(" %-12s", "PATH STATE"); 1186 printf(" %-12s", "CONN STATE"); 1187 } 1188 if (opt_S) 1189 printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX, 1190 TCP_FUNCTION_NAME_LEN_MAX, "STACK"); 1191 if (opt_C) 1192 printf(" %-.*s", TCP_CA_NAME_MAX, "CC"); 1193 printf("\n"); 1194 } 1195 setpassent(1); 1196 for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) { 1197 if (xf->xf_data == 0) 1198 continue; 1199 if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid)) 1200 continue; 1201 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE); 1202 for (s = sockhash[hash]; s != NULL; s = s->next) { 1203 if (s->socket != xf->xf_data) 1204 continue; 1205 if (!check_ports(s)) 1206 continue; 1207 s->shown = 1; 1208 pos = 0; 1209 if (opt_n || (pwd = getpwuid(xf->xf_uid)) == NULL) 1210 pos += xprintf("%lu ", (u_long)xf->xf_uid); 1211 else 1212 pos += xprintf("%s ", pwd->pw_name); 1213 while (pos < 9) 1214 pos += xprintf(" "); 1215 pos += xprintf("%.10s", getprocname(xf->xf_pid)); 1216 while (pos < 20) 1217 pos += xprintf(" "); 1218 pos += xprintf("%lu ", (u_long)xf->xf_pid); 1219 while (pos < 26) 1220 pos += xprintf(" "); 1221 pos += xprintf("%d ", xf->xf_fd); 1222 displaysock(s, pos); 1223 } 1224 } 1225 if (opt_j >= 0) 1226 return; 1227 for (hash = 0; hash < HASHSIZE; hash++) { 1228 for (s = sockhash[hash]; s != NULL; s = s->next) { 1229 if (s->shown) 1230 continue; 1231 if (!check_ports(s)) 1232 continue; 1233 pos = 0; 1234 pos += xprintf("%-8s %-10s %-5s %-2s ", 1235 "?", "?", "?", "?"); 1236 displaysock(s, pos); 1237 } 1238 } 1239 } 1240 1241 static int 1242 set_default_protos(void) 1243 { 1244 struct protoent *prot; 1245 const char *pname; 1246 size_t pindex; 1247 1248 init_protos(default_numprotos); 1249 1250 for (pindex = 0; pindex < default_numprotos; pindex++) { 1251 pname = default_protos[pindex]; 1252 prot = getprotobyname(pname); 1253 if (prot == NULL) 1254 err(1, "getprotobyname: %s", pname); 1255 protos[pindex] = prot->p_proto; 1256 } 1257 numprotos = pindex; 1258 return (pindex); 1259 } 1260 1261 /* 1262 * Return the vnet property of the jail, or -1 on error. 1263 */ 1264 static int 1265 jail_getvnet(int jid) 1266 { 1267 struct iovec jiov[6]; 1268 int vnet; 1269 1270 vnet = -1; 1271 jiov[0].iov_base = __DECONST(char *, "jid"); 1272 jiov[0].iov_len = sizeof("jid"); 1273 jiov[1].iov_base = &jid; 1274 jiov[1].iov_len = sizeof(jid); 1275 jiov[2].iov_base = __DECONST(char *, "vnet"); 1276 jiov[2].iov_len = sizeof("vnet"); 1277 jiov[3].iov_base = &vnet; 1278 jiov[3].iov_len = sizeof(vnet); 1279 jiov[4].iov_base = __DECONST(char *, "errmsg"); 1280 jiov[4].iov_len = sizeof("errmsg"); 1281 jiov[5].iov_base = jail_errmsg; 1282 jiov[5].iov_len = JAIL_ERRMSGLEN; 1283 jail_errmsg[0] = '\0'; 1284 if (jail_get(jiov, nitems(jiov), 0) < 0) { 1285 if (!jail_errmsg[0]) 1286 snprintf(jail_errmsg, JAIL_ERRMSGLEN, 1287 "jail_get: %s", strerror(errno)); 1288 return (-1); 1289 } 1290 return (vnet); 1291 } 1292 1293 static void 1294 usage(void) 1295 { 1296 fprintf(stderr, 1297 "usage: sockstat [-46cLlSsUuvw] [-j jid] [-p ports] [-P protocols]\n"); 1298 exit(1); 1299 } 1300 1301 int 1302 main(int argc, char *argv[]) 1303 { 1304 int protos_defined = -1; 1305 int o, i; 1306 1307 opt_j = -1; 1308 while ((o = getopt(argc, argv, "46Ccj:Llnp:P:qSsUuvw")) != -1) 1309 switch (o) { 1310 case '4': 1311 opt_4 = 1; 1312 break; 1313 case '6': 1314 opt_6 = 1; 1315 break; 1316 case 'C': 1317 opt_C = 1; 1318 break; 1319 case 'c': 1320 opt_c = 1; 1321 break; 1322 case 'j': 1323 opt_j = jail_getid(optarg); 1324 if (opt_j < 0) 1325 errx(1, "%s", jail_errmsg); 1326 break; 1327 case 'L': 1328 opt_L = 1; 1329 break; 1330 case 'l': 1331 opt_l = 1; 1332 break; 1333 case 'n': 1334 opt_n = 1; 1335 break; 1336 case 'p': 1337 parse_ports(optarg); 1338 break; 1339 case 'P': 1340 protos_defined = parse_protos(optarg); 1341 break; 1342 case 'q': 1343 opt_q = 1; 1344 break; 1345 case 'S': 1346 opt_S = 1; 1347 break; 1348 case 's': 1349 opt_s = 1; 1350 break; 1351 case 'U': 1352 opt_U = 1; 1353 break; 1354 case 'u': 1355 opt_u = 1; 1356 break; 1357 case 'v': 1358 ++opt_v; 1359 break; 1360 case 'w': 1361 opt_w = 1; 1362 break; 1363 default: 1364 usage(); 1365 } 1366 1367 argc -= optind; 1368 argv += optind; 1369 1370 if (argc > 0) 1371 usage(); 1372 1373 if (opt_j > 0) { 1374 switch (jail_getvnet(opt_j)) { 1375 case -1: 1376 errx(2, "%s", jail_errmsg); 1377 case JAIL_SYS_NEW: 1378 if (jail_attach(opt_j) < 0) 1379 err(3, "jail_attach()"); 1380 /* Set back to -1 for normal output in vnet jail. */ 1381 opt_j = -1; 1382 break; 1383 default: 1384 break; 1385 } 1386 } 1387 1388 if ((!opt_4 && !opt_6) && protos_defined != -1) 1389 opt_4 = opt_6 = 1; 1390 if (!opt_4 && !opt_6 && !opt_u) 1391 opt_4 = opt_6 = opt_u = 1; 1392 if ((opt_4 || opt_6) && protos_defined == -1) 1393 protos_defined = set_default_protos(); 1394 if (!opt_c && !opt_l) 1395 opt_c = opt_l = 1; 1396 1397 if (opt_4 || opt_6) { 1398 for (i = 0; i < protos_defined; i++) 1399 if (protos[i] == IPPROTO_SCTP) 1400 gather_sctp(); 1401 else 1402 gather_inet(protos[i]); 1403 } 1404 1405 if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) { 1406 gather_unix(SOCK_STREAM); 1407 gather_unix(SOCK_DGRAM); 1408 gather_unix(SOCK_SEQPACKET); 1409 } 1410 getfiles(); 1411 display(); 1412 exit(0); 1413 } 1414