1 /* $NetBSD: ping6.c,v 1.103 2018/04/24 07:22:32 maxv Exp $ */ 2 /* $KAME: ping6.c,v 1.164 2002/11/16 14:05:37 itojun Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 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. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* BSDI ping.c,v 2.3 1996/01/21 17:56:50 jch Exp */ 34 35 /* 36 * Copyright (c) 1989, 1993 37 * The Regents of the University of California. All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Mike Muuss. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. Neither the name of the University nor the names of its contributors 51 * may be used to endorse or promote products derived from this software 52 * without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 */ 66 67 #if 0 68 #ifndef lint 69 static char copyright[] = 70 "@(#) Copyright (c) 1989, 1993\n\ 71 The Regents of the University of California. All rights reserved.\n"; 72 #endif /* not lint */ 73 74 #ifndef lint 75 static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; 76 #endif /* not lint */ 77 #else 78 #include <sys/cdefs.h> 79 #ifndef lint 80 __RCSID("$NetBSD: ping6.c,v 1.103 2018/04/24 07:22:32 maxv Exp $"); 81 #endif 82 #endif 83 84 /* 85 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 86 * measure round-trip-delays and packet loss across network paths. 87 * 88 * Author - 89 * Mike Muuss 90 * U. S. Army Ballistic Research Laboratory 91 * December, 1983 92 * 93 * Status - 94 * Public Domain. Distribution Unlimited. 95 * Bugs - 96 * More statistics could always be gathered. 97 * This program has to run SUID to ROOT to access the ICMP socket. 98 */ 99 /* 100 * NOTE: 101 * USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics 102 * as IPV6_PKTINFO. Some people object it (sin6_scope_id specifies *link* 103 * while IPV6_PKTINFO specifies *interface*. Link is defined as collection of 104 * network attached to 1 or more interfaces) 105 */ 106 107 #include <sys/param.h> 108 #include <sys/uio.h> 109 #include <sys/socket.h> 110 #include <sys/time.h> 111 112 #include <net/if.h> 113 #include <net/route.h> 114 115 #include <netinet/in.h> 116 #include <netinet/ip6.h> 117 #include <netinet/icmp6.h> 118 #include <arpa/inet.h> 119 #include <arpa/nameser.h> 120 #include <netdb.h> 121 122 #include <ctype.h> 123 #include <err.h> 124 #include <errno.h> 125 #include <fcntl.h> 126 #include <math.h> 127 #include <signal.h> 128 #include <stdbool.h> 129 #include <stdio.h> 130 #include <stdlib.h> 131 #include <string.h> 132 #include <unistd.h> 133 #include <poll.h> 134 135 #ifdef IPSEC 136 #include <netipsec/ipsec.h> 137 #endif 138 139 #include <md5.h> 140 141 #include "prog_ops.h" 142 143 struct tv32 { 144 u_int32_t tv32_sec; 145 u_int32_t tv32_usec; 146 }; 147 148 #define MAXPACKETLEN 131072 149 #define IP6LEN 40 150 #define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ 151 #define ICMP6ECHOTMLEN sizeof(struct tv32) 152 #define ICMP6_NIQLEN (ICMP6ECHOLEN + 8) 153 /* FQDN case, 64 bits of nonce + 32 bits ttl */ 154 #define ICMP6_NIRLEN (ICMP6ECHOLEN + 12) 155 #define EXTRA 256 /* for AH and various other headers. weird. */ 156 #define DEFDATALEN ICMP6ECHOTMLEN 157 #define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN 158 #define NROUTES 9 /* number of record route slots */ 159 160 #define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ 161 #define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ 162 #define SET(bit) (A(bit) |= B(bit)) 163 #define CLR(bit) (A(bit) &= (~B(bit))) 164 #define TST(bit) (A(bit) & B(bit)) 165 166 #define F_FLOOD 0x0001 167 #define F_INTERVAL 0x0002 168 #define F_PINGFILLED 0x0008 169 #define F_QUIET 0x0010 170 #define F_SO_DEBUG 0x0040 171 #define F_VERBOSE 0x0100 172 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 173 #define F_POLICY 0x0400 174 #endif 175 #define F_NODEADDR 0x0800 176 #define F_FQDN 0x1000 177 #define F_INTERFACE 0x2000 178 #define F_SRCADDR 0x4000 179 #define F_HOSTNAME 0x10000 180 #define F_FQDNOLD 0x20000 181 #define F_NIGROUP 0x40000 182 #define F_SUPTYPES 0x80000 183 #define F_ONCE 0x200000 184 #define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES) 185 static u_int options; 186 187 #define DUMMY_PORT 10101 188 189 /* 190 * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum 191 * number of received sequence numbers we can keep track of. Change 128 192 * to 8192 for complete accuracy... 193 */ 194 #define MAX_DUP_CHK (8 * 8192) 195 static int mx_dup_ck = MAX_DUP_CHK; 196 static char rcvd_tbl[MAX_DUP_CHK / 8]; 197 198 static struct addrinfo *res; 199 static struct sockaddr_in6 dst; /* who to ping6 */ 200 static struct sockaddr_in6 src; /* src addr of this packet */ 201 static socklen_t srclen; 202 static int datalen = DEFDATALEN; 203 static int s; /* socket file descriptor */ 204 static u_char outpack[MAXPACKETLEN]; 205 static char BSPACE = '\b'; /* characters written for flood */ 206 static char DOT = '.'; 207 static char *hostname; 208 static int ident; /* process id to identify our packets */ 209 static u_int8_t nonce[8]; /* nonce field for node information */ 210 static int hoplimit = -1; /* hoplimit */ 211 212 /* counters */ 213 static long npackets; /* max packets to transmit */ 214 static long nreceived; /* # of packets we got back */ 215 static long nrepeats; /* number of duplicates */ 216 static long ntransmitted; /* sequence # for outbound packets = #sent */ 217 static struct timespec interval = {1, 0}; /* interval between packets */ 218 219 static struct timespec now, last_tx, next_tx, first_tx; 220 static int lastrcvd = 1; /* last ping sent has been received */ 221 222 /* timing */ 223 static int timing; /* flag to do timing */ 224 static double tmin = 999999999.0; /* minimum round trip time */ 225 static double tmax = 0.0; /* maximum round trip time */ 226 static double tsum = 0.0; /* sum of all times, for doing average */ 227 static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */ 228 static double maxwait = 0.0; /* maxwait for reply in ms */ 229 static double deadline = 0.0; /* max running time in seconds */ 230 231 /* for node addresses */ 232 static u_short naflags; 233 234 /* for ancillary data(advanced API) */ 235 static struct msghdr smsghdr; 236 static struct iovec smsgiov; 237 static char *scmsg = 0; 238 239 static volatile sig_atomic_t seenint; 240 #ifdef SIGINFO 241 static volatile sig_atomic_t seeninfo; 242 #endif 243 244 __dead static void doit(u_char *, u_int); 245 static void fill(char *, char *); 246 static int get_hoplim(struct msghdr *); 247 static int get_pathmtu(struct msghdr *); 248 static struct in6_pktinfo *get_rcvpktinfo(struct msghdr *); 249 static void onsignal(int); 250 __dead static void onsigexit(int); 251 static size_t pingerlen(void); 252 static void pinger(void); 253 static const char *pr_addr(struct sockaddr *, int); 254 static void pr_icmph(struct icmp6_hdr *, u_char *); 255 static void pr_iph(struct ip6_hdr *); 256 static void pr_suptypes(struct icmp6_nodeinfo *, size_t); 257 static void pr_nodeaddr(struct icmp6_nodeinfo *, int); 258 static int myechoreply(const struct icmp6_hdr *); 259 static int mynireply(const struct icmp6_nodeinfo *); 260 static char *dnsdecode(const u_char **, const u_char *, const u_char *, 261 char *, size_t); 262 static void pr_pack(u_char *, int, struct msghdr *); 263 static void pr_exthdrs(struct msghdr *); 264 static void pr_ip6opt(void *); 265 static void pr_rthdr(void *); 266 static int pr_bitrange(u_int32_t, int, int); 267 static void pr_retip(struct ip6_hdr *, u_char *); 268 static void summary(void); 269 static void tvsub(struct timeval *, struct timeval *); 270 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 271 static int setpolicy(int, char *); 272 #endif 273 static char *nigroup(char *); 274 static double timespec_to_sec(const struct timespec *tp); 275 static double diffsec(struct timespec *, struct timespec *); 276 __dead static void usage(void); 277 278 int 279 main(int argc, char *argv[]) 280 { 281 struct addrinfo hints; 282 u_int i, packlen; 283 long l; 284 int ch, hold, preload, optval, ret_ga; 285 u_char *datap, *packet; 286 char *e, *target, *ifname = NULL, *gateway = NULL; 287 int ip6optlen = 0; 288 struct cmsghdr *scmsgp = NULL; 289 u_long lsockbufsize; 290 int sockbufsize = 0; 291 int usepktinfo = 0; 292 struct in6_pktinfo *pktinfo = NULL; 293 struct ip6_rthdr *rthdr = NULL; 294 #ifdef IPSEC_POLICY_IPSEC 295 char *policy_in = NULL; 296 char *policy_out = NULL; 297 #endif 298 double intval; 299 int mflag = 0; 300 301 /* just to be sure */ 302 memset(&smsghdr, 0, sizeof(smsghdr)); 303 memset(&smsgiov, 0, sizeof(smsgiov)); 304 305 preload = 0; 306 datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN]; 307 308 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 309 #define ADDOPTS "P:" 310 #else 311 #define ADDOPTS 312 #endif 313 314 if (prog_init && prog_init() == -1) 315 err(EXIT_FAILURE, "init failed"); 316 317 while ((ch = getopt(argc, argv, 318 "a:b:c:dfHg:h:I:i:l:mnNop:qS:s:tvwWx:X:" ADDOPTS)) != -1) { 319 #undef ADDOPTS 320 switch (ch) { 321 case 'a': 322 { 323 char *cp; 324 325 options &= ~F_NOUSERDATA; 326 options |= F_NODEADDR; 327 for (cp = optarg; *cp != '\0'; cp++) { 328 switch (*cp) { 329 case 'a': 330 naflags |= NI_NODEADDR_FLAG_ALL; 331 break; 332 case 'c': 333 case 'C': 334 naflags |= NI_NODEADDR_FLAG_COMPAT; 335 break; 336 case 'l': 337 case 'L': 338 naflags |= NI_NODEADDR_FLAG_LINKLOCAL; 339 break; 340 case 's': 341 case 'S': 342 naflags |= NI_NODEADDR_FLAG_SITELOCAL; 343 break; 344 case 'g': 345 case 'G': 346 naflags |= NI_NODEADDR_FLAG_GLOBAL; 347 break; 348 case 'A': /* experimental. not in the spec */ 349 #ifdef NI_NODEADDR_FLAG_ANYCAST 350 naflags |= NI_NODEADDR_FLAG_ANYCAST; 351 break; 352 #else 353 errx(1, 354 "-a A is not supported on the platform"); 355 /*NOTREACHED*/ 356 #endif 357 default: 358 usage(); 359 /*NOTREACHED*/ 360 } 361 } 362 break; 363 } 364 case 'b': 365 errno = 0; 366 e = NULL; 367 lsockbufsize = strtoul(optarg, &e, 10); 368 sockbufsize = lsockbufsize; 369 if (errno || !*optarg || *e || 370 (u_long)sockbufsize != lsockbufsize) 371 errx(1, "invalid socket buffer size"); 372 break; 373 case 'c': 374 l = strtol(optarg, &e, 10); 375 if (l <= 0 || *optarg == '\0' || *e != '\0') 376 errx(1, 377 "illegal number of packets -- %s", optarg); 378 #if INT_MAX < LONG_MAX 379 if (l > INT_MAX) 380 errx(EXIT_FAILURE, 381 "Too many packets to count: %ld", l); 382 #endif 383 npackets = l; 384 break; 385 case 'd': 386 options |= F_SO_DEBUG; 387 break; 388 case 'f': 389 if (prog_getuid()) { 390 errno = EPERM; 391 errx(1, "Must be superuser to flood ping"); 392 } 393 options |= F_FLOOD; 394 setbuf(stdout, NULL); 395 interval.tv_sec = 0; 396 interval.tv_nsec = 10 * 1000 * 1000; /* 10 ms */ 397 break; 398 case 'g': 399 gateway = optarg; 400 break; 401 case 'H': 402 options |= F_HOSTNAME; 403 break; 404 case 'h': /* hoplimit */ 405 hoplimit = strtol(optarg, &e, 10); 406 if (*optarg == '\0' || *e != '\0') 407 errx(1, "illegal hoplimit %s", optarg); 408 if (255 < hoplimit || hoplimit < -1) 409 errx(1, 410 "illegal hoplimit -- %s", optarg); 411 break; 412 case 'I': 413 ifname = optarg; 414 options |= F_INTERFACE; 415 #ifndef USE_SIN6_SCOPE_ID 416 usepktinfo++; 417 #endif 418 break; 419 case 'i': /* wait between sending packets */ 420 intval = strtod(optarg, &e); 421 if (*optarg == '\0' || *e != '\0') 422 errx(1, "illegal timing interval %s", optarg); 423 if (intval < 1 && prog_getuid()) { 424 errx(1, "%s: only root may use interval < 1s", 425 strerror(EPERM)); 426 } 427 if (intval > INT_MAX/1000.0 - 1.0) { 428 errx(1, "Interval %s too large", optarg); 429 } 430 interval.tv_sec = (time_t)intval; 431 interval.tv_nsec = 432 (long)((intval - interval.tv_sec) * 1000000000); 433 if (interval.tv_sec < 0 || interval.tv_nsec < 0) 434 errx(1, "illegal timing interval %s", optarg); 435 /* less than 1/hz does not make sense */ 436 if (interval.tv_sec == 0 && 437 interval.tv_nsec < 10000000) { 438 warnx("Interval too small; raised to 0.01"); 439 interval.tv_nsec = 10000000; 440 } 441 options |= F_INTERVAL; 442 break; 443 case 'l': 444 if (prog_getuid()) { 445 errno = EPERM; 446 errx(1, "Must be superuser to preload"); 447 } 448 l = strtol(optarg, &e, 10); 449 if (l < 0 || *optarg == '\0' || *e != '\0') 450 errx(1, "illegal preload value -- %s", optarg); 451 #if INT_MAX < LONG_MAX 452 if (l > INT_MAX) 453 errx(EXIT_FAILURE, 454 "Too many preload packets: %ld", l); 455 #endif 456 preload = l; 457 break; 458 case 'm': 459 mflag++; 460 break; 461 case 'n': 462 options &= ~F_HOSTNAME; 463 break; 464 case 'N': 465 options |= F_NIGROUP; 466 break; 467 case 'o': 468 options |= F_ONCE; 469 break; 470 case 'p': /* fill buffer with user pattern */ 471 options |= F_PINGFILLED; 472 fill((char *)datap, optarg); 473 break; 474 case 'q': 475 options |= F_QUIET; 476 break; 477 case 'S': 478 memset(&hints, 0, sizeof(struct addrinfo)); 479 hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */ 480 hints.ai_family = AF_INET6; 481 hints.ai_socktype = SOCK_RAW; 482 hints.ai_protocol = IPPROTO_ICMPV6; 483 484 ret_ga = getaddrinfo(optarg, NULL, &hints, &res); 485 if (ret_ga) { 486 errx(1, "invalid source address: %s", 487 gai_strerror(ret_ga)); 488 } 489 /* 490 * res->ai_family must be AF_INET6 and res->ai_addrlen 491 * must be sizeof(src). 492 */ 493 memcpy(&src, res->ai_addr, res->ai_addrlen); 494 srclen = res->ai_addrlen; 495 freeaddrinfo(res); 496 options |= F_SRCADDR; 497 break; 498 case 's': /* size of packet to send */ 499 datalen = strtol(optarg, &e, 10); 500 if (datalen < 0 || *optarg == '\0' || *e != '\0') 501 errx(1, "illegal datalen value -- %s", optarg); 502 if (datalen > MAXDATALEN) { 503 errx(1, 504 "datalen value too large, maximum is %d", 505 MAXDATALEN); 506 } 507 break; 508 case 't': 509 options &= ~F_NOUSERDATA; 510 options |= F_SUPTYPES; 511 break; 512 case 'v': 513 options |= F_VERBOSE; 514 break; 515 case 'w': 516 options &= ~F_NOUSERDATA; 517 options |= F_FQDN; 518 break; 519 case 'W': 520 options &= ~F_NOUSERDATA; 521 options |= F_FQDNOLD; 522 break; 523 case 'x': 524 maxwait = strtod(optarg, &e); 525 if (*e != '\0' || maxwait <= 0) 526 errx(EXIT_FAILURE, "Bad/invalid maxwait time: " 527 "%s", optarg); 528 break; 529 case 'X': 530 deadline = strtod(optarg, &e); 531 if (*e != '\0' || deadline <= 0) 532 errx(EXIT_FAILURE, "Bad/invalid deadline time: " 533 "%s", optarg); 534 break; 535 536 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 537 case 'P': 538 options |= F_POLICY; 539 if (!strncmp("in", optarg, 2)) { 540 if ((policy_in = strdup(optarg)) == NULL) 541 errx(1, "strdup"); 542 } else if (!strncmp("out", optarg, 3)) { 543 if ((policy_out = strdup(optarg)) == NULL) 544 errx(1, "strdup"); 545 } else 546 errx(1, "invalid security policy"); 547 break; 548 #endif 549 default: 550 usage(); 551 /*NOTREACHED*/ 552 } 553 } 554 555 argc -= optind; 556 argv += optind; 557 558 if (argc != 1) { 559 usage(); 560 /*NOTREACHED*/ 561 } 562 563 if (options & F_NIGROUP) { 564 target = nigroup(argv[argc - 1]); 565 if (target == NULL) { 566 usage(); 567 /*NOTREACHED*/ 568 } 569 } else 570 target = argv[argc - 1]; 571 572 /* getaddrinfo */ 573 memset(&hints, 0, sizeof(struct addrinfo)); 574 hints.ai_flags = AI_CANONNAME; 575 hints.ai_family = AF_INET6; 576 hints.ai_socktype = SOCK_RAW; 577 hints.ai_protocol = IPPROTO_ICMPV6; 578 579 ret_ga = getaddrinfo(target, NULL, &hints, &res); 580 if (ret_ga) 581 errx(1, "%s", gai_strerror(ret_ga)); 582 if (res->ai_canonname) 583 hostname = res->ai_canonname; 584 else 585 hostname = target; 586 587 if (!res->ai_addr) 588 errx(1, "getaddrinfo failed"); 589 590 memcpy(&dst, res->ai_addr, res->ai_addrlen); 591 592 if ((s = prog_socket(res->ai_family, res->ai_socktype, 593 res->ai_protocol)) < 0) 594 err(1, "socket"); 595 596 /* set the source address if specified. */ 597 if ((options & F_SRCADDR) && 598 prog_bind(s, (struct sockaddr *)&src, srclen) != 0) { 599 err(1, "bind"); 600 } 601 602 /* set the gateway (next hop) if specified */ 603 if (gateway) { 604 struct addrinfo ghints, *gres; 605 int error; 606 607 memset(&ghints, 0, sizeof(ghints)); 608 ghints.ai_family = AF_INET6; 609 ghints.ai_socktype = SOCK_RAW; 610 ghints.ai_protocol = IPPROTO_ICMPV6; 611 612 error = getaddrinfo(gateway, NULL, &hints, &gres); 613 if (error) { 614 errx(1, "getaddrinfo for the gateway %s: %s", 615 gateway, gai_strerror(error)); 616 } 617 if (gres->ai_next && (options & F_VERBOSE)) 618 warnx("gateway resolves to multiple addresses"); 619 620 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_NEXTHOP, 621 gres->ai_addr, gres->ai_addrlen)) { 622 err(1, "setsockopt(IPV6_NEXTHOP)"); 623 } 624 625 freeaddrinfo(gres); 626 } 627 628 /* 629 * let the kernel pass extension headers of incoming packets, 630 * for privileged socket options 631 */ 632 if ((options & F_VERBOSE) != 0) { 633 int opton = 1; 634 635 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton, 636 sizeof(opton))) 637 err(1, "setsockopt(IPV6_RECVHOPOPTS)"); 638 639 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton, 640 sizeof(opton))) 641 err(1, "setsockopt(IPV6_RECVDSTOPTS)"); 642 643 #ifdef IPV6_RECVRTHDRDSTOPTS 644 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton, 645 sizeof(opton))) 646 err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)"); 647 #endif 648 } 649 650 /* revoke root privilege */ 651 prog_seteuid(prog_getuid()); 652 prog_setuid(prog_getuid()); 653 654 if ((options & F_FLOOD) && (options & F_INTERVAL)) 655 errx(1, "-f and -i incompatible options"); 656 657 if ((options & F_NOUSERDATA) == 0) { 658 if (datalen >= (int)sizeof(struct tv32)) { 659 /* we can time transfer */ 660 timing = 1; 661 } else 662 timing = 0; 663 /* in F_VERBOSE case, we may get non-echoreply packets*/ 664 if (options & F_VERBOSE) 665 packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; 666 else 667 packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA; 668 } else { 669 /* suppress timing for node information query */ 670 timing = 0; 671 datalen = 2048; 672 packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; 673 } 674 675 if (!(packet = (u_char *)malloc(packlen))) 676 err(1, "Unable to allocate packet"); 677 if (!(options & F_PINGFILLED)) 678 for (i = ICMP6ECHOLEN; i < packlen; ++i) 679 *datap++ = i; 680 681 ident = arc4random() & 0xFFFF; 682 memset(nonce, 0, sizeof(nonce)); 683 for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t)) { 684 uint32_t r = arc4random(); 685 memcpy(&nonce[i], &r, sizeof(r)); 686 } 687 688 hold = 1; 689 690 if (options & F_SO_DEBUG) 691 (void)prog_setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold, 692 sizeof(hold)); 693 optval = IPV6_DEFHLIM; 694 if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 695 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 696 &optval, sizeof(optval)) == -1) 697 err(1, "IPV6_MULTICAST_HOPS"); 698 699 if (mflag != 1) { 700 optval = mflag > 1 ? 0 : 1; 701 702 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU, 703 &optval, sizeof(optval)) == -1) 704 err(1, "setsockopt(IPV6_USE_MIN_MTU)"); 705 } else { 706 optval = 1; 707 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_RECVPATHMTU, 708 &optval, sizeof(optval)) == -1) 709 err(1, "setsockopt(IPV6_RECVPATHMTU)"); 710 } 711 712 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 713 if (options & F_POLICY) { 714 if (setpolicy(s, policy_in) < 0) 715 errx(1, "%s", ipsec_strerror()); 716 if (setpolicy(s, policy_out) < 0) 717 errx(1, "%s", ipsec_strerror()); 718 } 719 #endif 720 721 #ifdef ICMP6_FILTER 722 { 723 struct icmp6_filter filt; 724 if (!(options & F_VERBOSE)) { 725 ICMP6_FILTER_SETBLOCKALL(&filt); 726 if ((options & F_FQDN) || (options & F_FQDNOLD) || 727 (options & F_NODEADDR) || (options & F_SUPTYPES)) 728 ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt); 729 else 730 ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); 731 } else { 732 ICMP6_FILTER_SETPASSALL(&filt); 733 } 734 if (prog_setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, 735 sizeof(filt)) < 0) 736 err(1, "setsockopt(ICMP6_FILTER)"); 737 } 738 #endif /*ICMP6_FILTER*/ 739 740 /* let the kernel pass extension headers of incoming packets */ 741 if ((options & F_VERBOSE) != 0) { 742 int opton = 1; 743 744 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton, 745 sizeof(opton))) 746 err(1, "setsockopt(IPV6_RECVRTHDR)"); 747 } 748 749 /* 750 optval = 1; 751 if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 752 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 753 &optval, sizeof(optval)) == -1) 754 err(1, "IPV6_MULTICAST_LOOP"); 755 */ 756 757 /* Specify the outgoing interface and/or the source address */ 758 if (usepktinfo) 759 ip6optlen += CMSG_SPACE(sizeof(struct in6_pktinfo)); 760 761 if (hoplimit != -1) 762 ip6optlen += CMSG_SPACE(sizeof(int)); 763 764 /* set IP6 packet options */ 765 if (ip6optlen) { 766 if ((scmsg = (char *)malloc(ip6optlen)) == 0) 767 errx(1, "can't allocate enough memory"); 768 smsghdr.msg_control = (caddr_t)scmsg; 769 smsghdr.msg_controllen = ip6optlen; 770 scmsgp = (struct cmsghdr *)scmsg; 771 } 772 if (usepktinfo) { 773 pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp)); 774 memset(pktinfo, 0, sizeof(*pktinfo)); 775 scmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 776 scmsgp->cmsg_level = IPPROTO_IPV6; 777 scmsgp->cmsg_type = IPV6_PKTINFO; 778 scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 779 } 780 781 /* set the outgoing interface */ 782 if (ifname) { 783 #ifndef USE_SIN6_SCOPE_ID 784 /* pktinfo must have already been allocated */ 785 if ((pktinfo->ipi6_ifindex = if_nametoindex(ifname)) == 0) 786 errx(1, "%s: invalid interface name", ifname); 787 #else 788 if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0) 789 errx(1, "%s: invalid interface name", ifname); 790 #endif 791 } 792 if (hoplimit != -1) { 793 scmsgp->cmsg_len = CMSG_LEN(sizeof(int)); 794 scmsgp->cmsg_level = IPPROTO_IPV6; 795 scmsgp->cmsg_type = IPV6_HOPLIMIT; 796 *(int *)(CMSG_DATA(scmsgp)) = hoplimit; 797 798 scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 799 } 800 801 if (!(options & F_SRCADDR)) { 802 /* 803 * get the source address. XXX since we revoked the root 804 * privilege, we cannot use a raw socket for this. 805 */ 806 int dummy; 807 socklen_t len = sizeof(src); 808 809 if ((dummy = prog_socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 810 err(1, "UDP socket"); 811 812 src.sin6_family = AF_INET6; 813 src.sin6_addr = dst.sin6_addr; 814 src.sin6_port = ntohs(DUMMY_PORT); 815 src.sin6_scope_id = dst.sin6_scope_id; 816 817 if (pktinfo && 818 prog_setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO, 819 (void *)pktinfo, sizeof(*pktinfo))) 820 err(1, "UDP setsockopt(IPV6_PKTINFO)"); 821 822 if (hoplimit != -1 && 823 prog_setsockopt(dummy, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 824 (void *)&hoplimit, sizeof(hoplimit))) 825 err(1, "UDP setsockopt(IPV6_UNICAST_HOPS)"); 826 827 if (hoplimit != -1 && 828 prog_setsockopt(dummy, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 829 (void *)&hoplimit, sizeof(hoplimit))) 830 err(1, "UDP setsockopt(IPV6_MULTICAST_HOPS)"); 831 832 if (rthdr && 833 prog_setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR, 834 (void *)rthdr, (rthdr->ip6r_len + 1) << 3)) 835 err(1, "UDP setsockopt(IPV6_RTHDR)"); 836 837 if (prog_connect(dummy, (struct sockaddr *)&src, len) < 0) 838 err(1, "UDP connect"); 839 840 if (prog_getsockname(dummy, (struct sockaddr *)&src, &len) < 0) 841 err(1, "getsockname"); 842 843 prog_close(dummy); 844 } 845 846 if (sockbufsize) { 847 if (datalen > sockbufsize) 848 warnx("you need -b to increase socket buffer size"); 849 if (prog_setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize, 850 sizeof(sockbufsize)) < 0) 851 err(1, "setsockopt(SO_SNDBUF)"); 852 if (prog_setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize, 853 sizeof(sockbufsize)) < 0) 854 err(1, "setsockopt(SO_RCVBUF)"); 855 } else { 856 if (datalen > 8 * 1024) /*XXX*/ 857 warnx("you need -b to increase socket buffer size"); 858 /* 859 * When pinging the broadcast address, you can get a lot of 860 * answers. Doing something so evil is useful if you are trying 861 * to stress the ethernet, or just want to fill the arp cache 862 * to get some stuff for /etc/ethers. 863 */ 864 hold = 48 * 1024; 865 prog_setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold, 866 sizeof(hold)); 867 } 868 869 optval = 1; 870 #ifndef USE_SIN6_SCOPE_ID 871 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, 872 sizeof(optval)) < 0) 873 warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */ 874 #endif 875 876 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval, 877 sizeof(optval)) < 0) 878 warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */ 879 880 printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()), 881 (unsigned long)(pingerlen() - 8)); 882 printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); 883 printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); 884 885 while (preload--) /* Fire off them quickies. */ 886 pinger(); 887 888 (void)signal(SIGINT, onsignal); 889 #ifdef SIGINFO 890 (void)signal(SIGINFO, onsignal); 891 #endif 892 893 seenint = 0; 894 #ifdef SIGINFO 895 seeninfo = 0; 896 #endif 897 898 doit(packet, packlen); 899 /*NOTREACHED*/ 900 return 0; 901 } 902 903 static void 904 doit(u_char *packet, u_int packlen) 905 { 906 int cc; 907 struct pollfd fdmaskp[1]; 908 struct sockaddr_in6 from; 909 double sec, last, d_last; 910 long orig_npackets = npackets; 911 912 if (npackets == 0) 913 npackets = LONG_MAX; 914 915 clock_gettime(CLOCK_MONOTONIC, &now); 916 if (deadline > 0) { 917 last = timespec_to_sec(&now) + deadline; 918 d_last = 0; 919 } else { 920 last = 0; 921 d_last = 365*24*60*60; 922 } 923 924 for (;;) { 925 struct msghdr m; 926 u_char buf[1024]; 927 struct iovec iov[2]; 928 929 clock_gettime(CLOCK_MONOTONIC, &now); 930 931 if (seenint) { 932 onsigexit(SIGINT); 933 seenint = 0; 934 continue; 935 } 936 #ifdef SIGINFO 937 if (seeninfo) { 938 summary(); 939 seeninfo = 0; 940 continue; 941 } 942 #endif 943 if (last != 0) 944 d_last = last - timespec_to_sec(&now); 945 946 if (ntransmitted < npackets && d_last > 0) { 947 /* send if within 100 usec or late for next packet */ 948 sec = diffsec(&next_tx, &now); 949 if ((sec <= 0.0001 && (options & F_FLOOD) == 0) || 950 (lastrcvd && (options & F_FLOOD))) { 951 pinger(); 952 sec = diffsec(&next_tx, &now); 953 } 954 if (sec < 0.0) 955 sec = 0.0; 956 if (d_last < sec) 957 sec = d_last; 958 } else { 959 /* For the last response, wait twice as long as the 960 * worst case seen, or 10 times as long as the 961 * maximum interpacket interval, whichever is longer. 962 */ 963 sec = MAX(2 * tmax, 10 * interval.tv_sec) - 964 diffsec(&now, &last_tx); 965 if (d_last < sec) 966 sec = d_last; 967 if (sec <= 0) 968 break; 969 } 970 971 fdmaskp[0].fd = s; 972 fdmaskp[0].events = POLLIN; 973 cc = prog_poll(fdmaskp, 1, (int)(sec * 1000)); 974 if (cc < 0) { 975 if (errno != EINTR) { 976 warn("poll"); 977 sleep(1); 978 } 979 continue; 980 } else if (cc == 0) 981 continue; 982 983 m.msg_name = (caddr_t)&from; 984 m.msg_namelen = sizeof(from); 985 memset(&iov, 0, sizeof(iov)); 986 iov[0].iov_base = (caddr_t)packet; 987 iov[0].iov_len = packlen; 988 m.msg_iov = iov; 989 m.msg_iovlen = 1; 990 m.msg_control = (caddr_t)buf; 991 m.msg_controllen = sizeof(buf); 992 993 cc = prog_recvmsg(s, &m, 0); 994 if (cc < 0) { 995 if (errno != EINTR) { 996 warn("recvmsg"); 997 sleep(1); 998 } 999 continue; 1000 } else if (cc == 0) { 1001 int mtu; 1002 1003 /* 1004 * receive control messages only. Process the 1005 * exceptions (currently the only possiblity is 1006 * a path MTU notification.) 1007 */ 1008 if ((mtu = get_pathmtu(&m)) > 0) { 1009 if ((options & F_VERBOSE) != 0) { 1010 printf("new path MTU (%d) is " 1011 "notified\n", mtu); 1012 } 1013 } 1014 continue; 1015 } else { 1016 /* 1017 * an ICMPv6 message (probably an echoreply) arrived. 1018 */ 1019 pr_pack(packet, cc, &m); 1020 } 1021 if (npackets && nreceived >= npackets) 1022 break; 1023 if (nreceived != 0 && (options & F_ONCE)) 1024 break; 1025 } 1026 1027 summary(); 1028 1029 if (orig_npackets) 1030 exit(nreceived != orig_npackets); 1031 else 1032 exit(nreceived == 0); 1033 } 1034 1035 static void 1036 onsignal(int sig) 1037 { 1038 1039 switch (sig) { 1040 case SIGINT: 1041 seenint++; 1042 break; 1043 #ifdef SIGINFO 1044 case SIGINFO: 1045 seeninfo++; 1046 break; 1047 #endif 1048 } 1049 } 1050 1051 /* 1052 * pinger -- 1053 * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet 1054 * will be added on by the kernel. The ID field is our UNIX process ID, 1055 * and the sequence number is an ascending integer. The first 8 bytes 1056 * of the data portion are used to hold a UNIX "timeval" struct in VAX 1057 * byte-order, to compute the round-trip time. 1058 */ 1059 static size_t 1060 pingerlen(void) 1061 { 1062 size_t l; 1063 1064 if (options & F_FQDN) 1065 l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1066 else if (options & F_FQDNOLD) 1067 l = ICMP6_NIQLEN; 1068 else if (options & F_NODEADDR) 1069 l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1070 else if (options & F_SUPTYPES) 1071 l = ICMP6_NIQLEN; 1072 else 1073 l = ICMP6ECHOLEN + datalen; 1074 1075 return l; 1076 } 1077 1078 static void 1079 pinger(void) 1080 { 1081 struct icmp6_hdr *icp; 1082 struct iovec iov[2]; 1083 int i, cc; 1084 struct icmp6_nodeinfo *nip; 1085 uint16_t seq; 1086 1087 if (npackets && ntransmitted >= npackets) 1088 return; /* no more transmission */ 1089 1090 icp = (struct icmp6_hdr *)outpack; 1091 nip = (struct icmp6_nodeinfo *)outpack; 1092 memset(icp, 0, sizeof(*icp)); 1093 icp->icmp6_cksum = 0; 1094 seq = ntransmitted++; 1095 lastrcvd = 0; 1096 CLR(seq % mx_dup_ck); 1097 seq = ntohs(seq); 1098 1099 if (options & F_FQDN) { 1100 icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; 1101 nip->ni_qtype = htons(NI_QTYPE_FQDN); 1102 nip->ni_flags = htons(0); 1103 1104 memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 1105 sizeof(dst.sin6_addr)); 1106 cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1107 } else if (options & F_FQDNOLD) { 1108 /* packet format in 03 draft - no Subject data on queries */ 1109 icp->icmp6_code = 0; /* code field is always 0 */ 1110 nip->ni_qtype = htons(NI_QTYPE_FQDN); 1111 nip->ni_flags = htons(0); 1112 1113 cc = ICMP6_NIQLEN; 1114 } else if (options & F_NODEADDR) { 1115 icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; 1116 nip->ni_qtype = htons(NI_QTYPE_NODEADDR); 1117 nip->ni_flags = naflags; 1118 1119 memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 1120 sizeof(dst.sin6_addr)); 1121 cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 1122 } else if (options & F_SUPTYPES) { 1123 icp->icmp6_code = ICMP6_NI_SUBJ_FQDN; /*empty*/ 1124 nip->ni_qtype = htons(NI_QTYPE_SUPTYPES); 1125 /* we support compressed bitmap */ 1126 nip->ni_flags = NI_SUPTYPE_FLAG_COMPRESS; 1127 1128 cc = ICMP6_NIQLEN; 1129 } else 1130 cc = 0; /* XXX: gcc */ 1131 1132 if (options & (F_FQDN|F_FQDNOLD|F_NODEADDR|F_SUPTYPES)) { 1133 icp->icmp6_type = ICMP6_NI_QUERY; 1134 memcpy(nip->icmp6_ni_nonce, nonce, 1135 sizeof(nip->icmp6_ni_nonce)); 1136 memcpy(nip->icmp6_ni_nonce, &seq, sizeof(seq)); 1137 datalen = 0; 1138 } else { 1139 icp->icmp6_type = ICMP6_ECHO_REQUEST; 1140 icp->icmp6_code = 0; 1141 icp->icmp6_id = htons(ident); 1142 icp->icmp6_seq = seq; 1143 if (timing) { 1144 struct timeval tv; 1145 struct tv32 *tv32; 1146 (void)gettimeofday(&tv, NULL); 1147 tv32 = (struct tv32 *)&outpack[ICMP6ECHOLEN]; 1148 tv32->tv32_sec = htonl(tv.tv_sec); 1149 tv32->tv32_usec = htonl(tv.tv_usec); 1150 } 1151 cc = ICMP6ECHOLEN + datalen; 1152 } 1153 1154 #ifdef DIAGNOSTIC 1155 if (pingerlen() != cc) 1156 errx(1, "internal error; length mismatch"); 1157 #endif 1158 1159 smsghdr.msg_name = (caddr_t)&dst; 1160 smsghdr.msg_namelen = sizeof(dst); 1161 memset(&iov, 0, sizeof(iov)); 1162 iov[0].iov_base = (caddr_t)outpack; 1163 iov[0].iov_len = cc; 1164 smsghdr.msg_iov = iov; 1165 smsghdr.msg_iovlen = 1; 1166 1167 i = prog_sendmsg(s, &smsghdr, 0); 1168 1169 if (i < 0 || i != cc) { 1170 if (i < 0) 1171 warn("sendmsg"); 1172 printf("ping6: wrote %s %d chars, ret=%d\n", 1173 hostname, cc, i); 1174 } 1175 if (!(options & F_QUIET) && options & F_FLOOD) 1176 (void)write(STDOUT_FILENO, &DOT, 1); 1177 1178 last_tx = now; 1179 if (next_tx.tv_sec == 0) { 1180 first_tx = now; 1181 next_tx = now; 1182 } 1183 1184 /* Transmit regularly, at always the same microsecond in the 1185 * second when going at one packet per second. 1186 * If we are at most 100 ms behind, send extras to get caught up. 1187 * Otherwise, skip packets we were too slow to send. 1188 */ 1189 if (diffsec(&next_tx, &now) <= interval.tv_sec) { 1190 do { 1191 timespecadd(&next_tx, &interval, &next_tx); 1192 } while (diffsec(&next_tx, &now) < -0.1); 1193 } 1194 } 1195 1196 static int 1197 myechoreply(const struct icmp6_hdr *icp) 1198 { 1199 if (ntohs(icp->icmp6_id) == ident) 1200 return 1; 1201 else 1202 return 0; 1203 } 1204 1205 static int 1206 mynireply(const struct icmp6_nodeinfo *nip) 1207 { 1208 if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t), 1209 nonce + sizeof(u_int16_t), 1210 sizeof(nonce) - sizeof(u_int16_t)) == 0) 1211 return 1; 1212 else 1213 return 0; 1214 } 1215 1216 static char * 1217 dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf, 1218 size_t bufsiz) 1219 { 1220 int i; 1221 const u_char *cp; 1222 char cresult[MAXDNAME + 1]; 1223 const u_char *comp; 1224 int l; 1225 1226 i = 0; /* XXXGCC -Wuninitialized [sun2] */ 1227 1228 cp = *sp; 1229 *buf = '\0'; 1230 1231 if (cp >= ep) 1232 return NULL; 1233 while (cp < ep) { 1234 i = *cp; 1235 if (i == 0 || cp != *sp) { 1236 if (strlcat((char *)buf, ".", bufsiz) >= bufsiz) 1237 return NULL; /*result overrun*/ 1238 } 1239 if (i == 0) 1240 break; 1241 cp++; 1242 1243 if ((i & 0xc0) == 0xc0 && cp - base > (i & 0x3f)) { 1244 /* DNS compression */ 1245 if (!base) 1246 return NULL; 1247 1248 comp = base + (i & 0x3f); 1249 if (dnsdecode(&comp, cp, base, cresult, 1250 sizeof(cresult)) == NULL) 1251 return NULL; 1252 if (strlcat(buf, cresult, bufsiz) >= bufsiz) 1253 return NULL; /*result overrun*/ 1254 break; 1255 } else if ((i & 0x3f) == i) { 1256 if (i > ep - cp) 1257 return NULL; /*source overrun*/ 1258 while (i-- > 0 && cp < ep) { 1259 l = snprintf(cresult, sizeof(cresult), 1260 isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff); 1261 if (l >= (int)sizeof(cresult) || l < 0) 1262 return NULL; 1263 if (strlcat(buf, cresult, bufsiz) >= bufsiz) 1264 return NULL; /*result overrun*/ 1265 cp++; 1266 } 1267 } else 1268 return NULL; /*invalid label*/ 1269 } 1270 if (i != 0) 1271 return NULL; /*not terminated*/ 1272 cp++; 1273 *sp = cp; 1274 return buf; 1275 } 1276 1277 /* 1278 * pr_pack -- 1279 * Print out the packet, if it came from us. This logic is necessary 1280 * because ALL readers of the ICMP socket get a copy of ALL ICMP packets 1281 * which arrive ('tis only fair). This permits multiple copies of this 1282 * program to be run without having intermingled output (or statistics!). 1283 */ 1284 static void 1285 pr_pack(u_char *buf, int cc, struct msghdr *mhdr) 1286 { 1287 #define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c) 1288 struct icmp6_hdr *icp; 1289 struct icmp6_nodeinfo *ni; 1290 int i; 1291 int hoplim; 1292 struct sockaddr *from; 1293 int fromlen; 1294 u_char *cp = NULL, *dp, *end = buf + cc; 1295 struct in6_pktinfo *pktinfo = NULL; 1296 struct timeval tv, tp; 1297 struct tv32 *tpp; 1298 double triptime = 0; 1299 int dupflag; 1300 size_t off; 1301 int oldfqdn; 1302 u_int16_t seq; 1303 char dnsname[MAXDNAME + 1]; 1304 1305 (void)gettimeofday(&tv, NULL); 1306 1307 if (!mhdr || !mhdr->msg_name || 1308 mhdr->msg_namelen != sizeof(struct sockaddr_in6) || 1309 ((struct sockaddr *)mhdr->msg_name)->sa_family != AF_INET6) { 1310 if (options & F_VERBOSE) 1311 warnx("invalid peername"); 1312 return; 1313 } 1314 from = (struct sockaddr *)mhdr->msg_name; 1315 fromlen = mhdr->msg_namelen; 1316 if (cc < (int)sizeof(struct icmp6_hdr)) { 1317 if (options & F_VERBOSE) 1318 warnx("packet too short (%d bytes) from %s", cc, 1319 pr_addr(from, fromlen)); 1320 return; 1321 } 1322 icp = (struct icmp6_hdr *)buf; 1323 ni = (struct icmp6_nodeinfo *)buf; 1324 off = 0; 1325 1326 if ((hoplim = get_hoplim(mhdr)) == -1) { 1327 warnx("failed to get receiving hop limit"); 1328 return; 1329 } 1330 if ((pktinfo = get_rcvpktinfo(mhdr)) == NULL) { 1331 warnx("failed to get receiving packet information"); 1332 return; 1333 } 1334 1335 if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) { 1336 seq = ntohs(icp->icmp6_seq); 1337 ++nreceived; 1338 lastrcvd = 1; 1339 if (timing) { 1340 tpp = (struct tv32 *)(icp + 1); 1341 tp.tv_sec = ntohl(tpp->tv32_sec); 1342 tp.tv_usec = ntohl(tpp->tv32_usec); 1343 tvsub(&tv, &tp); 1344 triptime = ((double)tv.tv_sec) * 1000.0 + 1345 ((double)tv.tv_usec) / 1000.0; 1346 if (maxwait > 0 && triptime > maxwait) { 1347 nreceived--; 1348 return; /* DISCARD */ 1349 } 1350 tsum += triptime; 1351 tsumsq += triptime * triptime; 1352 if (triptime < tmin) 1353 tmin = triptime; 1354 if (triptime > tmax) 1355 tmax = triptime; 1356 } 1357 1358 if (TST(seq % mx_dup_ck)) { 1359 ++nrepeats; 1360 --nreceived; 1361 dupflag = 1; 1362 } else { 1363 SET(seq % mx_dup_ck); 1364 dupflag = 0; 1365 } 1366 1367 if (options & F_QUIET) 1368 return; 1369 1370 if (options & F_FLOOD) 1371 (void)write(STDOUT_FILENO, &BSPACE, 1); 1372 else { 1373 printf("%d bytes from %s, icmp_seq=%u", cc, 1374 pr_addr(from, fromlen), seq); 1375 printf(" hlim=%d", hoplim); 1376 if ((options & F_VERBOSE) != 0) { 1377 struct sockaddr_in6 dstsa; 1378 1379 memset(&dstsa, 0, sizeof(dstsa)); 1380 dstsa.sin6_family = AF_INET6; 1381 #ifdef SIN6_LEN 1382 dstsa.sin6_len = sizeof(dstsa); 1383 #endif 1384 dstsa.sin6_scope_id = pktinfo->ipi6_ifindex; 1385 dstsa.sin6_addr = pktinfo->ipi6_addr; 1386 printf(" dst=%s", 1387 pr_addr((struct sockaddr *)&dstsa, 1388 sizeof(dstsa))); 1389 } 1390 if (timing) 1391 printf(" time=%.3f ms", triptime); 1392 if (dupflag) 1393 printf("(DUP!)"); 1394 /* check the data */ 1395 cp = buf + off + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 1396 dp = outpack + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 1397 for (i = 8; cp < end; ++i, ++cp, ++dp) { 1398 if (*cp != *dp) { 1399 printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp); 1400 break; 1401 } 1402 } 1403 } 1404 } else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) { 1405 memcpy(&seq, ni->icmp6_ni_nonce, sizeof(seq)); 1406 seq = ntohs(seq); 1407 ++nreceived; 1408 if (TST(seq % mx_dup_ck)) { 1409 ++nrepeats; 1410 --nreceived; 1411 dupflag = 1; 1412 } else { 1413 SET(seq % mx_dup_ck); 1414 dupflag = 0; 1415 } 1416 1417 if (options & F_QUIET) 1418 return; 1419 1420 printf("%d bytes from %s: ", cc, pr_addr(from, fromlen)); 1421 1422 switch (ntohs(ni->ni_code)) { 1423 case ICMP6_NI_SUCCESS: 1424 break; 1425 case ICMP6_NI_REFUSED: 1426 printf("refused, type 0x%x", ntohs(ni->ni_type)); 1427 goto fqdnend; 1428 case ICMP6_NI_UNKNOWN: 1429 printf("unknown, type 0x%x", ntohs(ni->ni_type)); 1430 goto fqdnend; 1431 default: 1432 printf("unknown code 0x%x, type 0x%x", 1433 ntohs(ni->ni_code), ntohs(ni->ni_type)); 1434 goto fqdnend; 1435 } 1436 1437 switch (ntohs(ni->ni_qtype)) { 1438 case NI_QTYPE_NOOP: 1439 printf("NodeInfo NOOP"); 1440 break; 1441 case NI_QTYPE_SUPTYPES: 1442 pr_suptypes(ni, end - (u_char *)ni); 1443 break; 1444 case NI_QTYPE_NODEADDR: 1445 pr_nodeaddr(ni, end - (u_char *)ni); 1446 break; 1447 case NI_QTYPE_FQDN: 1448 default: /* XXX: for backward compatibility */ 1449 cp = (u_char *)ni + ICMP6_NIRLEN; 1450 if (buf[off + ICMP6_NIRLEN] == 1451 cc - off - ICMP6_NIRLEN - 1) 1452 oldfqdn = 1; 1453 else 1454 oldfqdn = 0; 1455 if (oldfqdn) { 1456 cp++; /* skip length */ 1457 while (cp < end) { 1458 safeputc(*cp & 0xff); 1459 cp++; 1460 } 1461 } else { 1462 i = 0; 1463 while (cp < end) { 1464 if (dnsdecode((void *)&cp, end, 1465 (const u_char *)(ni + 1), dnsname, 1466 sizeof(dnsname)) == NULL) { 1467 printf("???"); 1468 break; 1469 } 1470 /* 1471 * name-lookup special handling for 1472 * truncated name 1473 */ 1474 if (cp + 1 <= end && !*cp && 1475 strlen(dnsname) > 0) { 1476 dnsname[strlen(dnsname) - 1] = '\0'; 1477 cp++; 1478 } 1479 printf("%s%s", i > 0 ? "," : "", 1480 dnsname); 1481 } 1482 } 1483 if (options & F_VERBOSE) { 1484 int32_t ttl; 1485 int comma = 0; 1486 1487 printf(" ("); /*)*/ 1488 1489 switch (ni->ni_code) { 1490 case ICMP6_NI_REFUSED: 1491 printf("refused"); 1492 comma++; 1493 break; 1494 case ICMP6_NI_UNKNOWN: 1495 printf("unknown qtype"); 1496 comma++; 1497 break; 1498 } 1499 1500 if ((end - (u_char *)ni) < ICMP6_NIRLEN) { 1501 /* case of refusion, unknown */ 1502 /*(*/ 1503 putchar(')'); 1504 goto fqdnend; 1505 } 1506 ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]); 1507 if (comma) 1508 printf(","); 1509 if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) { 1510 printf("TTL=%d:meaningless", 1511 (int)ttl); 1512 } else { 1513 if (ttl < 0) { 1514 printf("TTL=%d:invalid", 1515 ttl); 1516 } else 1517 printf("TTL=%d", ttl); 1518 } 1519 comma++; 1520 1521 if (oldfqdn) { 1522 if (comma) 1523 printf(","); 1524 printf("03 draft"); 1525 comma++; 1526 } else { 1527 cp = (u_char *)ni + ICMP6_NIRLEN; 1528 if (cp == end) { 1529 if (comma) 1530 printf(","); 1531 printf("no name"); 1532 comma++; 1533 } 1534 } 1535 1536 if (buf[off + ICMP6_NIRLEN] != 1537 cc - off - ICMP6_NIRLEN - 1 && oldfqdn) { 1538 if (comma) 1539 printf(","); 1540 printf("invalid namelen:%d/%lu", 1541 buf[off + ICMP6_NIRLEN], 1542 (u_long)cc - off - ICMP6_NIRLEN - 1); 1543 comma++; 1544 } 1545 /*(*/ 1546 putchar(')'); 1547 } 1548 fqdnend: 1549 ; 1550 } 1551 } else { 1552 /* We've got something other than an ECHOREPLY */ 1553 if (!(options & F_VERBOSE)) 1554 return; 1555 printf("%d bytes from %s: ", cc, pr_addr(from, fromlen)); 1556 pr_icmph(icp, end); 1557 } 1558 1559 if (!(options & F_FLOOD)) { 1560 (void)putchar('\n'); 1561 if (options & F_VERBOSE) 1562 pr_exthdrs(mhdr); 1563 (void)fflush(stdout); 1564 } 1565 #undef safeputc 1566 } 1567 1568 static void 1569 pr_exthdrs(struct msghdr *mhdr) 1570 { 1571 struct cmsghdr *cm; 1572 1573 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1574 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1575 if (cm->cmsg_level != IPPROTO_IPV6) 1576 continue; 1577 1578 switch (cm->cmsg_type) { 1579 case IPV6_HOPOPTS: 1580 printf(" HbH Options: "); 1581 pr_ip6opt(CMSG_DATA(cm)); 1582 break; 1583 case IPV6_DSTOPTS: 1584 #ifdef IPV6_RTHDRDSTOPTS 1585 case IPV6_RTHDRDSTOPTS: 1586 #endif 1587 printf(" Dst Options: "); 1588 pr_ip6opt(CMSG_DATA(cm)); 1589 break; 1590 case IPV6_RTHDR: 1591 printf(" Routing: "); 1592 pr_rthdr(CMSG_DATA(cm)); 1593 break; 1594 } 1595 } 1596 } 1597 1598 static void 1599 pr_ip6opt(void *extbuf) 1600 { 1601 struct ip6_hbh *ext; 1602 int currentlen; 1603 u_int8_t type; 1604 size_t extlen; 1605 socklen_t len; 1606 void *databuf; 1607 size_t offset; 1608 u_int16_t value2; 1609 u_int32_t value4; 1610 1611 ext = (struct ip6_hbh *)extbuf; 1612 extlen = (ext->ip6h_len + 1) * 8; 1613 printf("nxt %u, len %u (%lu bytes)\n", ext->ip6h_nxt, 1614 (unsigned int)ext->ip6h_len, (unsigned long)extlen); 1615 1616 currentlen = 0; 1617 while (1) { 1618 currentlen = inet6_opt_next(extbuf, extlen, currentlen, 1619 &type, &len, &databuf); 1620 if (currentlen == -1) 1621 break; 1622 switch (type) { 1623 /* 1624 * Note that inet6_opt_next automatically skips any padding 1625 * optins. 1626 */ 1627 case IP6OPT_JUMBO: 1628 offset = 0; 1629 offset = inet6_opt_get_val(databuf, offset, 1630 &value4, sizeof(value4)); 1631 printf(" Jumbo Payload Opt: Length %u\n", 1632 (u_int32_t)ntohl(value4)); 1633 break; 1634 case IP6OPT_ROUTER_ALERT: 1635 offset = 0; 1636 offset = inet6_opt_get_val(databuf, offset, 1637 &value2, sizeof(value2)); 1638 printf(" Router Alert Opt: Type %u\n", 1639 ntohs(value2)); 1640 break; 1641 default: 1642 printf(" Received Opt %u len %lu\n", 1643 type, (unsigned long)len); 1644 break; 1645 } 1646 } 1647 return; 1648 } 1649 1650 static void 1651 pr_rthdr(void *extbuf) 1652 { 1653 struct in6_addr *in6; 1654 char ntopbuf[INET6_ADDRSTRLEN]; 1655 struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; 1656 int i, segments; 1657 1658 /* print fixed part of the header */ 1659 printf("nxt %u, len %u (%d bytes), type %u, ", rh->ip6r_nxt, 1660 rh->ip6r_len, (rh->ip6r_len + 1) << 3, rh->ip6r_type); 1661 if ((segments = inet6_rth_segments(extbuf)) >= 0) 1662 printf("%d segments, ", segments); 1663 else 1664 printf("segments unknown, "); 1665 printf("%d left\n", rh->ip6r_segleft); 1666 1667 for (i = 0; i < segments; i++) { 1668 in6 = inet6_rth_getaddr(extbuf, i); 1669 if (in6 == NULL) 1670 printf(" [%d]<NULL>\n", i); 1671 else { 1672 if (!inet_ntop(AF_INET6, in6, ntopbuf, 1673 sizeof(ntopbuf))) 1674 strlcpy(ntopbuf, "?", sizeof(ntopbuf)); 1675 printf(" [%d]%s\n", i, ntopbuf); 1676 } 1677 } 1678 1679 return; 1680 1681 } 1682 1683 static int 1684 pr_bitrange(u_int32_t v, int soff, int ii) 1685 { 1686 int off; 1687 int i; 1688 1689 off = 0; 1690 while (off < 32) { 1691 /* shift till we have 0x01 */ 1692 if ((v & 0x01) == 0) { 1693 if (ii > 1) 1694 printf("-%u", soff + off - 1); 1695 ii = 0; 1696 switch (v & 0x0f) { 1697 case 0x00: 1698 v >>= 4; 1699 off += 4; 1700 continue; 1701 case 0x08: 1702 v >>= 3; 1703 off += 3; 1704 continue; 1705 case 0x04: case 0x0c: 1706 v >>= 2; 1707 off += 2; 1708 continue; 1709 default: 1710 v >>= 1; 1711 off += 1; 1712 continue; 1713 } 1714 } 1715 1716 /* we have 0x01 with us */ 1717 for (i = 0; i < 32 - off; i++) { 1718 if ((v & (0x01 << i)) == 0) 1719 break; 1720 } 1721 if (!ii) 1722 printf(" %u", soff + off); 1723 ii += i; 1724 v >>= i; off += i; 1725 } 1726 return ii; 1727 } 1728 1729 static void 1730 pr_suptypes(struct icmp6_nodeinfo *ni /* ni->qtype must be SUPTYPES */, 1731 size_t nilen) 1732 { 1733 size_t clen; 1734 u_int32_t v; 1735 const u_char *cp, *end; 1736 u_int16_t cur; 1737 struct cbit { 1738 u_int16_t words; /*32bit count*/ 1739 u_int16_t skip; 1740 } cbit; 1741 #define MAXQTYPES (1 << 16) 1742 size_t off; 1743 int b; 1744 1745 cp = (u_char *)(ni + 1); 1746 end = ((u_char *)ni) + nilen; 1747 cur = 0; 1748 b = 0; 1749 1750 printf("NodeInfo Supported Qtypes"); 1751 if (options & F_VERBOSE) { 1752 if (ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) 1753 printf(", compressed bitmap"); 1754 else 1755 printf(", raw bitmap"); 1756 } 1757 1758 while (cp < end) { 1759 size_t skip = 0; 1760 clen = (size_t)(end - cp); 1761 if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) == 0) { 1762 if (clen == 0 || clen > MAXQTYPES / 8 || 1763 clen % sizeof(v)) { 1764 printf("???"); 1765 return; 1766 } 1767 } else { 1768 if (clen < sizeof(cbit) || clen % sizeof(v)) 1769 return; 1770 memcpy(&cbit, cp, sizeof(cbit)); 1771 if (sizeof(cbit) + ntohs(cbit.words) * sizeof(v) > 1772 clen) 1773 return; 1774 cp += sizeof(cbit); 1775 clen = ntohs(cbit.words) * sizeof(v); 1776 skip = (size_t)ntohs(cbit.skip) * 32; 1777 if (cur + clen * 8 + skip > MAXQTYPES) 1778 return; 1779 } 1780 1781 for (off = 0; off < clen; off += sizeof(v)) { 1782 memcpy(&v, cp + off, sizeof(v)); 1783 v = (u_int32_t)ntohl(v); 1784 b = pr_bitrange(v, (int)(cur + off * 8), b); 1785 } 1786 /* flush the remaining bits */ 1787 b = pr_bitrange(0, (int)(cur + off * 8), b); 1788 1789 cp += clen; 1790 cur += clen * 8 + skip; 1791 } 1792 } 1793 1794 static void 1795 pr_nodeaddr(struct icmp6_nodeinfo *ni, /* ni->qtype must be NODEADDR */ 1796 int nilen) 1797 { 1798 u_char *cp = (u_char *)(ni + 1); 1799 char ntop_buf[INET6_ADDRSTRLEN]; 1800 int withttl = 0; 1801 1802 nilen -= sizeof(struct icmp6_nodeinfo); 1803 1804 if (options & F_VERBOSE) { 1805 switch (ni->ni_code) { 1806 case ICMP6_NI_REFUSED: 1807 printf("refused"); 1808 break; 1809 case ICMP6_NI_UNKNOWN: 1810 printf("unknown qtype"); 1811 break; 1812 } 1813 if (ni->ni_flags & NI_NODEADDR_FLAG_TRUNCATE) 1814 printf(" truncated"); 1815 } 1816 putchar('\n'); 1817 if (nilen <= 0) 1818 printf(" no address\n"); 1819 1820 /* 1821 * In icmp-name-lookups 05 and later, TTL of each returned address 1822 * is contained in the resposne. We try to detect the version 1823 * by the length of the data, but note that the detection algorithm 1824 * is incomplete. We assume the latest draft by default. 1825 */ 1826 if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0) 1827 withttl = 1; 1828 while (nilen > 0) { 1829 u_int32_t ttl = 0; 1830 1831 if (withttl) { 1832 /* XXX: alignment? */ 1833 ttl = (u_int32_t)ntohl(*(u_int32_t *)cp); 1834 cp += sizeof(u_int32_t); 1835 nilen -= sizeof(u_int32_t); 1836 } 1837 1838 if (inet_ntop(AF_INET6, cp, ntop_buf, sizeof(ntop_buf)) == 1839 NULL) 1840 strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 1841 printf(" %s", ntop_buf); 1842 if (withttl) { 1843 if (ttl == 0xffffffff) { 1844 /* 1845 * XXX: can this convention be applied to all 1846 * type of TTL (i.e. non-ND TTL)? 1847 */ 1848 printf("(TTL=infty)"); 1849 } 1850 else 1851 printf("(TTL=%u)", ttl); 1852 } 1853 putchar('\n'); 1854 1855 nilen -= sizeof(struct in6_addr); 1856 cp += sizeof(struct in6_addr); 1857 } 1858 } 1859 1860 static int 1861 get_hoplim(struct msghdr *mhdr) 1862 { 1863 struct cmsghdr *cm; 1864 1865 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1866 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1867 if (cm->cmsg_len == 0) 1868 return(-1); 1869 1870 if (cm->cmsg_level == IPPROTO_IPV6 && 1871 cm->cmsg_type == IPV6_HOPLIMIT && 1872 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1873 return(*(int *)CMSG_DATA(cm)); 1874 } 1875 1876 return(-1); 1877 } 1878 1879 static struct in6_pktinfo * 1880 get_rcvpktinfo(struct msghdr *mhdr) 1881 { 1882 struct cmsghdr *cm; 1883 1884 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1885 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1886 if (cm->cmsg_len == 0) 1887 return(NULL); 1888 1889 if (cm->cmsg_level == IPPROTO_IPV6 && 1890 cm->cmsg_type == IPV6_PKTINFO && 1891 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) 1892 return((struct in6_pktinfo *)CMSG_DATA(cm)); 1893 } 1894 1895 return(NULL); 1896 } 1897 1898 static int 1899 get_pathmtu(struct msghdr *mhdr) 1900 { 1901 #ifdef IPV6_RECVPATHMTU 1902 struct cmsghdr *cm; 1903 struct ip6_mtuinfo *mtuctl = NULL; 1904 1905 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1906 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1907 if (cm->cmsg_len == 0) 1908 return(0); 1909 1910 if (cm->cmsg_level == IPPROTO_IPV6 && 1911 cm->cmsg_type == IPV6_PATHMTU && 1912 cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) { 1913 mtuctl = (struct ip6_mtuinfo *)CMSG_DATA(cm); 1914 1915 /* 1916 * If the notified destination is different from 1917 * the one we are pinging, just ignore the info. 1918 * We check the scope ID only when both notified value 1919 * and our own value have non-0 values, because we may 1920 * have used the default scope zone ID for sending, 1921 * in which case the scope ID value is 0. 1922 */ 1923 if (!IN6_ARE_ADDR_EQUAL(&mtuctl->ip6m_addr.sin6_addr, 1924 &dst.sin6_addr) || 1925 (mtuctl->ip6m_addr.sin6_scope_id && 1926 dst.sin6_scope_id && 1927 mtuctl->ip6m_addr.sin6_scope_id != 1928 dst.sin6_scope_id)) { 1929 if ((options & F_VERBOSE) != 0) { 1930 printf("path MTU for %s is notified. " 1931 "(ignored)\n", 1932 pr_addr((struct sockaddr *)&mtuctl->ip6m_addr, 1933 sizeof(mtuctl->ip6m_addr))); 1934 } 1935 return(0); 1936 } 1937 1938 /* 1939 * Ignore an invalid MTU. XXX: can we just believe 1940 * the kernel check? 1941 */ 1942 if (mtuctl->ip6m_mtu < IPV6_MMTU) 1943 return(0); 1944 1945 /* notification for our destination. return the MTU. */ 1946 return((int)mtuctl->ip6m_mtu); 1947 } 1948 } 1949 #endif 1950 return(0); 1951 } 1952 1953 /* 1954 * tvsub -- 1955 * Subtract 2 timeval structs: out = out - in. Out is assumed to 1956 * be >= in. 1957 */ 1958 static void 1959 tvsub(struct timeval *out, struct timeval *in) 1960 { 1961 if ((out->tv_usec -= in->tv_usec) < 0) { 1962 --out->tv_sec; 1963 out->tv_usec += 1000000; 1964 } 1965 out->tv_sec -= in->tv_sec; 1966 } 1967 1968 /* 1969 * onsigexit -- 1970 */ 1971 static void 1972 onsigexit(int sig) 1973 { 1974 summary(); 1975 1976 if (sig == SIGINT) { 1977 (void)signal(SIGINT, SIG_DFL); 1978 (void)kill(getpid(), SIGINT); 1979 } 1980 1981 exit(1); 1982 } 1983 1984 /* 1985 * summary -- 1986 * Print out statistics. 1987 */ 1988 static void 1989 summary(void) 1990 { 1991 1992 printf("\n--- %s ping6 statistics ---\n", hostname); 1993 printf("%ld packets transmitted, ", ntransmitted); 1994 printf("%ld packets received, ", nreceived); 1995 if (nrepeats) 1996 printf("+%ld duplicates, ", nrepeats); 1997 if (ntransmitted) { 1998 if (nreceived > ntransmitted) 1999 printf("-- somebody's duplicating packets!"); 2000 else 2001 printf("%.1f%% packet loss", 2002 ((((double)ntransmitted - nreceived) * 100.0) / 2003 ntransmitted)); 2004 } 2005 (void)putchar('\n'); 2006 if (nreceived && timing) { 2007 /* Only display average to microseconds */ 2008 double num = nreceived + nrepeats; 2009 double dev, avg; 2010 if (num > 1) { 2011 avg = tsum / num; 2012 dev = sqrt((tsumsq - num * avg * avg) / (num - 1)); 2013 } else { 2014 avg = tsum; 2015 dev = 0.0; 2016 } 2017 printf( 2018 "round-trip min/avg/max/std-dev = %.3f/%.3f/%.3f/%.3f ms\n", 2019 tmin, avg, tmax, dev); 2020 (void)fflush(stdout); 2021 } 2022 (void)fflush(stdout); 2023 } 2024 2025 /*subject type*/ 2026 static const char *niqcode[] = { 2027 "IPv6 address", 2028 "DNS label", /*or empty*/ 2029 "IPv4 address", 2030 }; 2031 2032 /*result code*/ 2033 static const char *nircode[] = { 2034 "Success", "Refused", "Unknown", 2035 }; 2036 2037 2038 /* 2039 * pr_icmph -- 2040 * Print a descriptive string about an ICMP header. 2041 */ 2042 static void 2043 pr_icmph(struct icmp6_hdr *icp, u_char *end) 2044 { 2045 char ntop_buf[INET6_ADDRSTRLEN]; 2046 struct nd_redirect *red; 2047 struct icmp6_nodeinfo *ni; 2048 char dnsname[MAXDNAME + 1]; 2049 const u_char *cp; 2050 size_t l; 2051 2052 switch (icp->icmp6_type) { 2053 case ICMP6_DST_UNREACH: 2054 switch (icp->icmp6_code) { 2055 case ICMP6_DST_UNREACH_NOROUTE: 2056 printf("No Route to Destination\n"); 2057 break; 2058 case ICMP6_DST_UNREACH_ADMIN: 2059 printf("Destination Administratively " 2060 "Unreachable\n"); 2061 break; 2062 case ICMP6_DST_UNREACH_BEYONDSCOPE: 2063 printf("Destination Unreachable Beyond Scope\n"); 2064 break; 2065 case ICMP6_DST_UNREACH_ADDR: 2066 printf("Destination Host Unreachable\n"); 2067 break; 2068 case ICMP6_DST_UNREACH_NOPORT: 2069 printf("Destination Port Unreachable\n"); 2070 break; 2071 default: 2072 printf("Destination Unreachable, Bad Code: %d\n", 2073 icp->icmp6_code); 2074 break; 2075 } 2076 /* Print returned IP header information */ 2077 pr_retip((struct ip6_hdr *)(icp + 1), end); 2078 break; 2079 case ICMP6_PACKET_TOO_BIG: 2080 printf("Packet too big mtu = %d\n", 2081 (int)ntohl(icp->icmp6_mtu)); 2082 pr_retip((struct ip6_hdr *)(icp + 1), end); 2083 break; 2084 case ICMP6_TIME_EXCEEDED: 2085 switch (icp->icmp6_code) { 2086 case ICMP6_TIME_EXCEED_TRANSIT: 2087 printf("Time to live exceeded\n"); 2088 break; 2089 case ICMP6_TIME_EXCEED_REASSEMBLY: 2090 printf("Frag reassembly time exceeded\n"); 2091 break; 2092 default: 2093 printf("Time exceeded, Bad Code: %d\n", 2094 icp->icmp6_code); 2095 break; 2096 } 2097 pr_retip((struct ip6_hdr *)(icp + 1), end); 2098 break; 2099 case ICMP6_PARAM_PROB: 2100 printf("Parameter problem: "); 2101 switch (icp->icmp6_code) { 2102 case ICMP6_PARAMPROB_HEADER: 2103 printf("Erroneous Header "); 2104 break; 2105 case ICMP6_PARAMPROB_NEXTHEADER: 2106 printf("Unknown Nextheader "); 2107 break; 2108 case ICMP6_PARAMPROB_OPTION: 2109 printf("Unrecognized Option "); 2110 break; 2111 case ICMP6_PARAMPROB_FRAGMENT: 2112 printf("First Fragment Has Incomplete Chain "); 2113 break; 2114 default: 2115 printf("Bad code(%d) ", icp->icmp6_code); 2116 break; 2117 } 2118 printf("pointer = 0x%02x\n", 2119 (u_int32_t)ntohl(icp->icmp6_pptr)); 2120 pr_retip((struct ip6_hdr *)(icp + 1), end); 2121 break; 2122 case ICMP6_ECHO_REQUEST: 2123 printf("Echo Request"); 2124 /* XXX ID + Seq + Data */ 2125 break; 2126 case ICMP6_ECHO_REPLY: 2127 printf("Echo Reply"); 2128 /* XXX ID + Seq + Data */ 2129 break; 2130 case ICMP6_MEMBERSHIP_QUERY: 2131 printf("Listener Query"); 2132 break; 2133 case ICMP6_MEMBERSHIP_REPORT: 2134 printf("Listener Report"); 2135 break; 2136 case ICMP6_MEMBERSHIP_REDUCTION: 2137 printf("Listener Done"); 2138 break; 2139 case ND_ROUTER_SOLICIT: 2140 printf("Router Solicitation"); 2141 break; 2142 case ND_ROUTER_ADVERT: 2143 printf("Router Advertisement"); 2144 break; 2145 case ND_NEIGHBOR_SOLICIT: 2146 printf("Neighbor Solicitation"); 2147 break; 2148 case ND_NEIGHBOR_ADVERT: 2149 printf("Neighbor Advertisement"); 2150 break; 2151 case ND_REDIRECT: 2152 red = (struct nd_redirect *)icp; 2153 printf("Redirect\n"); 2154 if (!inet_ntop(AF_INET6, &red->nd_rd_dst, ntop_buf, 2155 sizeof(ntop_buf))) 2156 strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 2157 printf("Destination: %s", ntop_buf); 2158 if (!inet_ntop(AF_INET6, &red->nd_rd_target, ntop_buf, 2159 sizeof(ntop_buf))) 2160 strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 2161 printf(" New Target: %s", ntop_buf); 2162 break; 2163 case ICMP6_NI_QUERY: 2164 printf("Node Information Query"); 2165 /* XXX ID + Seq + Data */ 2166 ni = (struct icmp6_nodeinfo *)icp; 2167 l = end - (u_char *)(ni + 1); 2168 printf(", "); 2169 switch (ntohs(ni->ni_qtype)) { 2170 case NI_QTYPE_NOOP: 2171 printf("NOOP"); 2172 break; 2173 case NI_QTYPE_SUPTYPES: 2174 printf("Supported qtypes"); 2175 break; 2176 case NI_QTYPE_FQDN: 2177 printf("DNS name"); 2178 break; 2179 case NI_QTYPE_NODEADDR: 2180 printf("nodeaddr"); 2181 break; 2182 case NI_QTYPE_IPV4ADDR: 2183 printf("IPv4 nodeaddr"); 2184 break; 2185 default: 2186 printf("unknown qtype"); 2187 break; 2188 } 2189 if (options & F_VERBOSE) { 2190 switch (ni->ni_code) { 2191 case ICMP6_NI_SUBJ_IPV6: 2192 if (l == sizeof(struct in6_addr) && 2193 inet_ntop(AF_INET6, ni + 1, ntop_buf, 2194 sizeof(ntop_buf)) != NULL) { 2195 printf(", subject=%s(%s)", 2196 niqcode[ni->ni_code], ntop_buf); 2197 } else { 2198 #if 1 2199 /* backward compat to -W */ 2200 printf(", oldfqdn"); 2201 #else 2202 printf(", invalid"); 2203 #endif 2204 } 2205 break; 2206 case ICMP6_NI_SUBJ_FQDN: 2207 if (end == (u_char *)(ni + 1)) { 2208 printf(", no subject"); 2209 break; 2210 } 2211 printf(", subject=%s", niqcode[ni->ni_code]); 2212 cp = (const u_char *)(ni + 1); 2213 if (dnsdecode(&cp, end, NULL, dnsname, 2214 sizeof(dnsname)) != NULL) 2215 printf("(%s)", dnsname); 2216 else 2217 printf("(invalid)"); 2218 break; 2219 case ICMP6_NI_SUBJ_IPV4: 2220 if (l == sizeof(struct in_addr) && 2221 inet_ntop(AF_INET, ni + 1, ntop_buf, 2222 sizeof(ntop_buf)) != NULL) { 2223 printf(", subject=%s(%s)", 2224 niqcode[ni->ni_code], ntop_buf); 2225 } else 2226 printf(", invalid"); 2227 break; 2228 default: 2229 printf(", invalid"); 2230 break; 2231 } 2232 } 2233 break; 2234 case ICMP6_NI_REPLY: 2235 printf("Node Information Reply"); 2236 /* XXX ID + Seq + Data */ 2237 ni = (struct icmp6_nodeinfo *)icp; 2238 printf(", "); 2239 switch (ntohs(ni->ni_qtype)) { 2240 case NI_QTYPE_NOOP: 2241 printf("NOOP"); 2242 break; 2243 case NI_QTYPE_SUPTYPES: 2244 printf("Supported qtypes"); 2245 break; 2246 case NI_QTYPE_FQDN: 2247 printf("DNS name"); 2248 break; 2249 case NI_QTYPE_NODEADDR: 2250 printf("nodeaddr"); 2251 break; 2252 case NI_QTYPE_IPV4ADDR: 2253 printf("IPv4 nodeaddr"); 2254 break; 2255 default: 2256 printf("unknown qtype"); 2257 break; 2258 } 2259 if (options & F_VERBOSE) { 2260 if (ni->ni_code >= sizeof(nircode) / sizeof(nircode[0])) 2261 printf(", invalid"); 2262 else 2263 printf(", %s", nircode[ni->ni_code]); 2264 } 2265 break; 2266 default: 2267 printf("Bad ICMP type: %d", icp->icmp6_type); 2268 } 2269 } 2270 2271 /* 2272 * pr_iph -- 2273 * Print an IP6 header. 2274 */ 2275 static void 2276 pr_iph(struct ip6_hdr *ip6) 2277 { 2278 u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; 2279 u_int8_t tc; 2280 char ntop_buf[INET6_ADDRSTRLEN]; 2281 2282 tc = *(&ip6->ip6_vfc + 1); /* XXX */ 2283 tc = (tc >> 4) & 0x0f; 2284 tc |= (ip6->ip6_vfc << 4); 2285 2286 printf("Vr TC Flow Plen Nxt Hlim\n"); 2287 printf(" %1x %02x %05x %04x %02x %02x\n", 2288 (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (u_int32_t)ntohl(flow), 2289 ntohs(ip6->ip6_plen), ip6->ip6_nxt, ip6->ip6_hlim); 2290 if (!inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf))) 2291 strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 2292 printf("%s->", ntop_buf); 2293 if (!inet_ntop(AF_INET6, &ip6->ip6_dst, ntop_buf, sizeof(ntop_buf))) 2294 strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 2295 printf("%s\n", ntop_buf); 2296 } 2297 2298 /* 2299 * pr_addr -- 2300 * Return an ascii host address as a dotted quad and optionally with 2301 * a hostname. 2302 */ 2303 static const char * 2304 pr_addr(struct sockaddr *addr, int addrlen) 2305 { 2306 static char buf[NI_MAXHOST]; 2307 int flag = 0; 2308 2309 if ((options & F_HOSTNAME) == 0) 2310 flag |= NI_NUMERICHOST; 2311 2312 if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, flag) == 0) 2313 return (buf); 2314 else 2315 return "?"; 2316 } 2317 2318 /* 2319 * pr_retip -- 2320 * Dump some info on a returned (via ICMPv6) IPv6 packet. 2321 */ 2322 static void 2323 pr_retip(struct ip6_hdr *ip6, u_char *end) 2324 { 2325 u_char *cp = (u_char *)ip6, nh; 2326 int hlen; 2327 2328 if (end - (u_char *)ip6 < (intptr_t)sizeof(*ip6)) { 2329 printf("IP6"); 2330 goto trunc; 2331 } 2332 pr_iph(ip6); 2333 hlen = sizeof(*ip6); 2334 2335 nh = ip6->ip6_nxt; 2336 cp += hlen; 2337 while (end - cp >= 8) { 2338 switch (nh) { 2339 case IPPROTO_HOPOPTS: 2340 printf("HBH "); 2341 hlen = (((struct ip6_hbh *)cp)->ip6h_len+1) << 3; 2342 nh = ((struct ip6_hbh *)cp)->ip6h_nxt; 2343 break; 2344 case IPPROTO_DSTOPTS: 2345 printf("DSTOPT "); 2346 hlen = (((struct ip6_dest *)cp)->ip6d_len+1) << 3; 2347 nh = ((struct ip6_dest *)cp)->ip6d_nxt; 2348 break; 2349 case IPPROTO_FRAGMENT: 2350 printf("FRAG "); 2351 hlen = sizeof(struct ip6_frag); 2352 nh = ((struct ip6_frag *)cp)->ip6f_nxt; 2353 break; 2354 case IPPROTO_ROUTING: 2355 printf("RTHDR "); 2356 hlen = (((struct ip6_rthdr *)cp)->ip6r_len+1) << 3; 2357 nh = ((struct ip6_rthdr *)cp)->ip6r_nxt; 2358 break; 2359 #ifdef IPSEC 2360 case IPPROTO_AH: 2361 printf("AH "); 2362 hlen = (((struct ip6_ext *)cp)->ip6e_len+2) << 2; 2363 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 2364 break; 2365 #endif 2366 case IPPROTO_ICMPV6: 2367 printf("ICMP6: type = %d, code = %d\n", 2368 *cp, *(cp + 1)); 2369 return; 2370 case IPPROTO_ESP: 2371 printf("ESP\n"); 2372 return; 2373 case IPPROTO_TCP: 2374 printf("TCP: from port %u, to port %u (decimal)\n", 2375 (*cp * 256 + *(cp + 1)), 2376 (*(cp + 2) * 256 + *(cp + 3))); 2377 return; 2378 case IPPROTO_UDP: 2379 printf("UDP: from port %u, to port %u (decimal)\n", 2380 (*cp * 256 + *(cp + 1)), 2381 (*(cp + 2) * 256 + *(cp + 3))); 2382 return; 2383 default: 2384 printf("Unknown Header(%d)\n", nh); 2385 return; 2386 } 2387 2388 if ((cp += hlen) >= end) 2389 goto trunc; 2390 } 2391 if (end - cp < 8) 2392 goto trunc; 2393 2394 putchar('\n'); 2395 return; 2396 2397 trunc: 2398 printf("...\n"); 2399 return; 2400 } 2401 2402 static void 2403 fill(char *bp, char *patp) 2404 { 2405 int ii, jj, kk; 2406 int pat[16]; 2407 char *cp; 2408 2409 for (cp = patp; *cp; cp++) 2410 if (!isxdigit((unsigned char)*cp)) 2411 errx(1, "patterns must be specified as hex digits"); 2412 ii = sscanf(patp, 2413 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 2414 &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6], 2415 &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12], 2416 &pat[13], &pat[14], &pat[15]); 2417 2418 /* xxx */ 2419 if (ii > 0) 2420 for (kk = 0; 2421 kk <= (int)(MAXDATALEN - (8 + sizeof(struct tv32) + ii)); 2422 kk += ii) 2423 for (jj = 0; jj < ii; ++jj) 2424 bp[jj + kk] = pat[jj]; 2425 if (!(options & F_QUIET)) { 2426 printf("PATTERN: 0x"); 2427 for (jj = 0; jj < ii; ++jj) 2428 printf("%02x", bp[jj] & 0xFF); 2429 printf("\n"); 2430 } 2431 } 2432 2433 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 2434 static int 2435 setpolicy(int so, char *policy) 2436 { 2437 char *buf; 2438 2439 if (policy == NULL) 2440 return 0; /* ignore */ 2441 2442 buf = ipsec_set_policy(policy, strlen(policy)); 2443 if (buf == NULL) 2444 errx(1, "%s", ipsec_strerror()); 2445 if (prog_setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf, 2446 ipsec_get_policylen(buf)) < 0) 2447 warnx("Unable to set IPsec policy"); 2448 free(buf); 2449 2450 return 0; 2451 } 2452 #endif 2453 2454 static char * 2455 nigroup(char *name) 2456 { 2457 char *p; 2458 char *q; 2459 MD5_CTX ctxt; 2460 u_int8_t digest[16]; 2461 u_int8_t c; 2462 size_t l; 2463 char hbuf[NI_MAXHOST]; 2464 struct in6_addr in6; 2465 2466 p = strchr(name, '.'); 2467 if (!p) 2468 p = name + strlen(name); 2469 l = p - name; 2470 if (l > 63 || l > sizeof(hbuf) - 1) 2471 return NULL; /*label too long*/ 2472 strncpy(hbuf, name, l); 2473 hbuf[(int)l] = '\0'; 2474 2475 for (q = name; *q; q++) { 2476 if (isupper(*(unsigned char *)q)) 2477 *q = tolower(*(unsigned char *)q); 2478 } 2479 2480 /* generate 8 bytes of pseudo-random value. */ 2481 memset(&ctxt, 0, sizeof(ctxt)); 2482 MD5Init(&ctxt); 2483 c = l & 0xff; 2484 MD5Update(&ctxt, &c, sizeof(c)); 2485 MD5Update(&ctxt, (unsigned char *)name, l); 2486 MD5Final(digest, &ctxt); 2487 2488 if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1) 2489 return NULL; /*XXX*/ 2490 bcopy(digest, &in6.s6_addr[12], 4); 2491 2492 if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL) 2493 return NULL; 2494 2495 return strdup(hbuf); 2496 } 2497 2498 static double 2499 timespec_to_sec(const struct timespec *tp) 2500 { 2501 return tp->tv_sec + tp->tv_nsec / 1000000000.0; 2502 } 2503 2504 /* 2505 * compute the difference of two timespecs in seconds 2506 */ 2507 static double 2508 diffsec(struct timespec *timenow, 2509 struct timespec *then) 2510 { 2511 if (timenow->tv_sec == 0) 2512 return -1; 2513 return (timenow->tv_sec - then->tv_sec) 2514 * 1.0 + (timenow->tv_nsec - then->tv_nsec) / 1000000000.0; 2515 } 2516 2517 static void 2518 usage(void) 2519 { 2520 fprintf(stderr, 2521 "usage: ping6 [-dfHmNnqtvWw] [-a addrtype] [-b bufsize]\n" 2522 "\t[-c count] [-g gateway] [-h hoplimit] [-I interface]\n" 2523 "\t[-i wait] [-l preload]" 2524 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 2525 " [-P policy]" 2526 #endif 2527 "\n" 2528 "\t[-p pattern] [-S sourceaddr] [-s packetsize] [-X deadline]\n" 2529 "\t[-x maxwait] host\n"); 2530 exit(1); 2531 } 2532