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