1 /* $KAME: traceroute6.c,v 1.68 2004/01/25 11:16:12 suz Exp $ */ 2 3 /*- 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 /*- 35 * Copyright (c) 1990, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * This code is derived from software contributed to Berkeley by 39 * Van Jacobson. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 */ 65 66 #ifndef lint 67 static const char copyright[] = 68 "@(#) Copyright (c) 1990, 1993\n\ 69 The Regents of the University of California. All rights reserved.\n"; 70 #endif /* not lint */ 71 72 #ifndef lint 73 #if 0 74 static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93"; 75 #endif 76 static const char rcsid[] = 77 "$FreeBSD$"; 78 #endif /* not lint */ 79 80 /* 81 * traceroute host - trace the route ip packets follow going to "host". 82 * 83 * Attempt to trace the route an ip packet would follow to some 84 * internet host. We find out intermediate hops by launching probe 85 * packets with a small ttl (time to live) then listening for an 86 * icmp "time exceeded" reply from a gateway. We start our probes 87 * with a ttl of one and increase by one until we get an icmp "port 88 * unreachable" (which means we got to "host") or hit a max (which 89 * defaults to 30 hops & can be changed with the -m flag). Three 90 * probes (change with -q flag) are sent at each ttl setting and a 91 * line is printed showing the ttl, address of the gateway and 92 * round trip time of each probe. If the probe answers come from 93 * different gateways, the address of each responding system will 94 * be printed. If there is no response within a 5 sec. timeout 95 * interval (changed with the -w flag), a "*" is printed for that 96 * probe. 97 * 98 * Probe packets are UDP format. We don't want the destination 99 * host to process them so the destination port is set to an 100 * unlikely value (if some clod on the destination is using that 101 * value, it can be changed with the -p flag). 102 * 103 * A sample use might be: 104 * 105 * [yak 71]% traceroute nis.nsf.net. 106 * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet 107 * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms 108 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms 109 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms 110 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms 111 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms 112 * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms 113 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms 114 * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms 115 * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms 116 * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms 117 * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms 118 * 119 * Note that lines 2 & 3 are the same. This is due to a buggy 120 * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards 121 * packets with a zero ttl. 122 * 123 * A more interesting example is: 124 * 125 * [yak 72]% traceroute allspice.lcs.mit.edu. 126 * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max 127 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms 128 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms 129 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms 130 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms 131 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms 132 * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms 133 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms 134 * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms 135 * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms 136 * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms 137 * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms 138 * 12 * * * 139 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms 140 * 14 * * * 141 * 15 * * * 142 * 16 * * * 143 * 17 * * * 144 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms 145 * 146 * (I start to see why I'm having so much trouble with mail to 147 * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away 148 * either don't send ICMP "time exceeded" messages or send them 149 * with a ttl too small to reach us. 14 - 17 are running the 150 * MIT C Gateway code that doesn't send "time exceeded"s. God 151 * only knows what's going on with 12. 152 * 153 * The silent gateway 12 in the above may be the result of a bug in 154 * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3) 155 * sends an unreachable message using whatever ttl remains in the 156 * original datagram. Since, for gateways, the remaining ttl is 157 * zero, the icmp "time exceeded" is guaranteed to not make it back 158 * to us. The behavior of this bug is slightly more interesting 159 * when it appears on the destination system: 160 * 161 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms 162 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms 163 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms 164 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms 165 * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms 166 * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms 167 * 7 * * * 168 * 8 * * * 169 * 9 * * * 170 * 10 * * * 171 * 11 * * * 172 * 12 * * * 173 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms ! 174 * 175 * Notice that there are 12 "gateways" (13 is the final 176 * destination) and exactly the last half of them are "missing". 177 * What's really happening is that rip (a Sun-3 running Sun OS3.5) 178 * is using the ttl from our arriving datagram as the ttl in its 179 * icmp reply. So, the reply will time out on the return path 180 * (with no notice sent to anyone since icmp's aren't sent for 181 * icmp's) until we probe with a ttl that's at least twice the path 182 * length. I.e., rip is really only 7 hops away. A reply that 183 * returns with a ttl of 1 is a clue this problem exists. 184 * Traceroute prints a "!" after the time if the ttl is <= 1. 185 * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or 186 * non-standard (HPUX) software, expect to see this problem 187 * frequently and/or take care picking the target host of your 188 * probes. 189 * 190 * Other possible annotations after the time are !H, !N, !P (got a host, 191 * network or protocol unreachable, respectively), !S or !F (source 192 * route failed or fragmentation needed -- neither of these should 193 * ever occur and the associated gateway is busted if you see one). If 194 * almost all the probes result in some kind of unreachable, traceroute 195 * will give up and exit. 196 * 197 * Notes 198 * ----- 199 * This program must be run by root or be setuid. (I suggest that 200 * you *don't* make it setuid -- casual use could result in a lot 201 * of unnecessary traffic on our poor, congested nets.) 202 * 203 * This program requires a kernel mod that does not appear in any 204 * system available from Berkeley: A raw ip socket using proto 205 * IPPROTO_RAW must interpret the data sent as an ip datagram (as 206 * opposed to data to be wrapped in an ip datagram). See the README 207 * file that came with the source to this program for a description 208 * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may 209 * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE 210 * MODIFIED TO RUN THIS PROGRAM. 211 * 212 * The udp port usage may appear bizarre (well, ok, it is bizarre). 213 * The problem is that an icmp message only contains 8 bytes of 214 * data from the original datagram. 8 bytes is the size of a udp 215 * header so, if we want to associate replies with the original 216 * datagram, the necessary information must be encoded into the 217 * udp header (the ip id could be used but there's no way to 218 * interlock with the kernel's assignment of ip id's and, anyway, 219 * it would have taken a lot more kernel hacking to allow this 220 * code to set the ip id). So, to allow two or more users to 221 * use traceroute simultaneously, we use this task's pid as the 222 * source port (the high bit is set to move the port number out 223 * of the "likely" range). To keep track of which probe is being 224 * replied to (so times and/or hop counts don't get confused by a 225 * reply that was delayed in transit), we increment the destination 226 * port number before each probe. 227 * 228 * Don't use this as a coding example. I was trying to find a 229 * routing problem and this code sort-of popped out after 48 hours 230 * without sleep. I was amazed it ever compiled, much less ran. 231 * 232 * I stole the idea for this program from Steve Deering. Since 233 * the first release, I've learned that had I attended the right 234 * IETF working group meetings, I also could have stolen it from Guy 235 * Almes or Matt Mathis. I don't know (or care) who came up with 236 * the idea first. I envy the originators' perspicacity and I'm 237 * glad they didn't keep the idea a secret. 238 * 239 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or 240 * enhancements to the original distribution. 241 * 242 * I've hacked up a round-trip-route version of this that works by 243 * sending a loose-source-routed udp datagram through the destination 244 * back to yourself. Unfortunately, SO many gateways botch source 245 * routing, the thing is almost worthless. Maybe one day... 246 * 247 * -- Van Jacobson (van@helios.ee.lbl.gov) 248 * Tue Dec 20 03:50:13 PST 1988 249 */ 250 251 #include <sys/param.h> 252 #include <sys/time.h> 253 #include <sys/socket.h> 254 #include <sys/uio.h> 255 #include <sys/file.h> 256 #include <sys/ioctl.h> 257 #include <sys/sysctl.h> 258 259 #include <netinet/in.h> 260 261 #include <arpa/inet.h> 262 263 #include <netdb.h> 264 #include <stdio.h> 265 #include <err.h> 266 #ifdef HAVE_POLL 267 #include <poll.h> 268 #endif 269 #include <errno.h> 270 #include <stdlib.h> 271 #include <string.h> 272 #include <unistd.h> 273 274 #include <netinet/ip6.h> 275 #include <netinet/icmp6.h> 276 #include <netinet/sctp.h> 277 #include <netinet/sctp_header.h> 278 #include <netinet/tcp.h> 279 #include <netinet/udp.h> 280 281 #ifdef IPSEC 282 #include <net/route.h> 283 #include <netipsec/ipsec.h> 284 #endif 285 286 #include "as.h" 287 288 #define DUMMY_PORT 10010 289 290 #define MAXPACKET 65535 /* max ip packet size */ 291 292 #ifndef HAVE_GETIPNODEBYNAME 293 #define getipnodebyname(x, y, z, u) gethostbyname2((x), (y)) 294 #define freehostent(x) 295 #endif 296 297 u_char packet[512]; /* last inbound (icmp) packet */ 298 char *outpacket; /* last output packet */ 299 300 int main(int, char *[]); 301 int wait_for_reply(int, struct msghdr *); 302 #ifdef IPSEC 303 #ifdef IPSEC_POLICY_IPSEC 304 int setpolicy(int so, char *policy); 305 #endif 306 #endif 307 void send_probe(int, u_long); 308 void *get_uphdr(struct ip6_hdr *, u_char *); 309 int get_hoplim(struct msghdr *); 310 double deltaT(struct timeval *, struct timeval *); 311 const char *pr_type(int); 312 int packet_ok(struct msghdr *, int, int, u_char *, u_char *); 313 void print(struct msghdr *, int); 314 const char *inetname(struct sockaddr *); 315 u_int32_t sctp_crc32c(void *, u_int32_t); 316 u_int16_t in_cksum(u_int16_t *addr, int); 317 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *, 318 void *, u_int32_t); 319 void usage(void); 320 321 int rcvsock; /* receive (icmp) socket file descriptor */ 322 int sndsock; /* send (raw/udp) socket file descriptor */ 323 324 struct msghdr rcvmhdr; 325 struct iovec rcviov[2]; 326 int rcvhlim; 327 struct in6_pktinfo *rcvpktinfo; 328 329 struct sockaddr_in6 Src, Dst, Rcv; 330 u_long datalen = 20; /* How much data */ 331 #define ICMP6ECHOLEN 8 332 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */ 333 char rtbuf[2064]; 334 struct ip6_rthdr *rth; 335 struct cmsghdr *cmsg; 336 337 char *source = NULL; 338 char *hostname; 339 340 u_long nprobes = 3; 341 u_long first_hop = 1; 342 u_long max_hops = 30; 343 u_int16_t srcport; 344 u_int16_t port = 32768+666; /* start udp dest port # for probe packets */ 345 u_int16_t ident; 346 int options; /* socket options */ 347 int verbose; 348 int waittime = 5; /* time to wait for response (in seconds) */ 349 int nflag; /* print addresses numerically */ 350 int useproto = IPPROTO_UDP; /* protocol to use to send packet */ 351 int lflag; /* print both numerical address & hostname */ 352 int as_path; /* print as numbers for each hop */ 353 char *as_server = NULL; 354 void *asn; 355 356 int 357 main(int argc, char *argv[]) 358 { 359 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM }; 360 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep; 361 int ch, i, on = 1, seq, rcvcmsglen, error; 362 struct addrinfo hints, *res; 363 static u_char *rcvcmsgbuf; 364 u_long probe, hops, lport; 365 struct hostent *hp; 366 size_t size, minlen; 367 uid_t uid; 368 u_char type, code; 369 370 /* 371 * Receive ICMP 372 */ 373 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { 374 perror("socket(ICMPv6)"); 375 exit(5); 376 } 377 378 size = sizeof(i); 379 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0); 380 max_hops = i; 381 382 /* specify to tell receiving interface */ 383 #ifdef IPV6_RECVPKTINFO 384 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, 385 sizeof(on)) < 0) 386 err(1, "setsockopt(IPV6_RECVPKTINFO)"); 387 #else /* old adv. API */ 388 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on, 389 sizeof(on)) < 0) 390 err(1, "setsockopt(IPV6_PKTINFO)"); 391 #endif 392 393 /* specify to tell value of hoplimit field of received IP6 hdr */ 394 #ifdef IPV6_RECVHOPLIMIT 395 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, 396 sizeof(on)) < 0) 397 err(1, "setsockopt(IPV6_RECVHOPLIMIT)"); 398 #else /* old adv. API */ 399 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, 400 sizeof(on)) < 0) 401 err(1, "setsockopt(IPV6_HOPLIMIT)"); 402 #endif 403 404 seq = 0; 405 ident = htons(getpid() & 0xffff); /* same as ping6 */ 406 407 while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1) 408 switch (ch) { 409 case 'a': 410 as_path = 1; 411 break; 412 case 'A': 413 as_path = 1; 414 as_server = optarg; 415 break; 416 case 'd': 417 options |= SO_DEBUG; 418 break; 419 case 'f': 420 ep = NULL; 421 errno = 0; 422 first_hop = strtoul(optarg, &ep, 0); 423 if (errno || !*optarg || *ep || first_hop > 255) { 424 fprintf(stderr, 425 "traceroute6: invalid min hoplimit.\n"); 426 exit(1); 427 } 428 break; 429 case 'g': 430 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno); 431 if (hp == NULL) { 432 fprintf(stderr, 433 "traceroute6: unknown host %s\n", optarg); 434 exit(1); 435 } 436 if (rth == NULL) { 437 /* 438 * XXX: We can't detect the number of 439 * intermediate nodes yet. 440 */ 441 if ((rth = inet6_rth_init((void *)rtbuf, 442 sizeof(rtbuf), IPV6_RTHDR_TYPE_0, 443 0)) == NULL) { 444 fprintf(stderr, 445 "inet6_rth_init failed.\n"); 446 exit(1); 447 } 448 } 449 if (inet6_rth_add((void *)rth, 450 (struct in6_addr *)hp->h_addr)) { 451 fprintf(stderr, 452 "inet6_rth_add failed for %s\n", 453 optarg); 454 exit(1); 455 } 456 freehostent(hp); 457 break; 458 case 'I': 459 useproto = IPPROTO_ICMPV6; 460 break; 461 case 'l': 462 lflag++; 463 break; 464 case 'm': 465 ep = NULL; 466 errno = 0; 467 max_hops = strtoul(optarg, &ep, 0); 468 if (errno || !*optarg || *ep || max_hops > 255) { 469 fprintf(stderr, 470 "traceroute6: invalid max hoplimit.\n"); 471 exit(1); 472 } 473 break; 474 case 'n': 475 nflag++; 476 break; 477 case 'N': 478 useproto = IPPROTO_NONE; 479 break; 480 case 'p': 481 ep = NULL; 482 errno = 0; 483 lport = strtoul(optarg, &ep, 0); 484 if (errno || !*optarg || *ep) { 485 fprintf(stderr, "traceroute6: invalid port.\n"); 486 exit(1); 487 } 488 if (lport == 0 || lport != (lport & 0xffff)) { 489 fprintf(stderr, 490 "traceroute6: port out of range.\n"); 491 exit(1); 492 } 493 port = lport & 0xffff; 494 break; 495 case 'q': 496 ep = NULL; 497 errno = 0; 498 nprobes = strtoul(optarg, &ep, 0); 499 if (errno || !*optarg || *ep) { 500 fprintf(stderr, 501 "traceroute6: invalid nprobes.\n"); 502 exit(1); 503 } 504 if (nprobes < 1) { 505 fprintf(stderr, 506 "traceroute6: nprobes must be >0.\n"); 507 exit(1); 508 } 509 break; 510 case 'r': 511 options |= SO_DONTROUTE; 512 break; 513 case 's': 514 /* 515 * set the ip source address of the outbound 516 * probe (e.g., on a multi-homed host). 517 */ 518 source = optarg; 519 break; 520 case 'S': 521 useproto = IPPROTO_SCTP; 522 break; 523 case 'T': 524 useproto = IPPROTO_TCP; 525 break; 526 case 'U': 527 useproto = IPPROTO_UDP; 528 break; 529 case 'v': 530 verbose++; 531 break; 532 case 'w': 533 ep = NULL; 534 errno = 0; 535 waittime = strtoul(optarg, &ep, 0); 536 if (errno || !*optarg || *ep) { 537 fprintf(stderr, 538 "traceroute6: invalid wait time.\n"); 539 exit(1); 540 } 541 if (waittime < 1) { 542 fprintf(stderr, 543 "traceroute6: wait must be >= 1 sec.\n"); 544 exit(1); 545 } 546 break; 547 default: 548 usage(); 549 } 550 argc -= optind; 551 argv += optind; 552 553 /* 554 * Open socket to send probe packets. 555 */ 556 switch (useproto) { 557 case IPPROTO_ICMPV6: 558 sndsock = rcvsock; 559 break; 560 case IPPROTO_UDP: 561 if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 562 perror("socket(SOCK_DGRAM)"); 563 exit(5); 564 } 565 break; 566 case IPPROTO_NONE: 567 case IPPROTO_SCTP: 568 case IPPROTO_TCP: 569 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) { 570 perror("socket(SOCK_RAW)"); 571 exit(5); 572 } 573 break; 574 default: 575 fprintf(stderr, "traceroute6: unknown probe protocol %d\n", 576 useproto); 577 exit(5); 578 } 579 if (max_hops < first_hop) { 580 fprintf(stderr, 581 "traceroute6: max hoplimit must be larger than first hoplimit.\n"); 582 exit(1); 583 } 584 585 /* revoke privs */ 586 uid = getuid(); 587 if (setresuid(uid, uid, uid) == -1) { 588 perror("setresuid"); 589 exit(1); 590 } 591 592 593 if (argc < 1 || argc > 2) 594 usage(); 595 596 #if 1 597 setvbuf(stdout, NULL, _IOLBF, BUFSIZ); 598 #else 599 setlinebuf(stdout); 600 #endif 601 602 memset(&hints, 0, sizeof(hints)); 603 hints.ai_family = PF_INET6; 604 hints.ai_socktype = SOCK_RAW; 605 hints.ai_protocol = IPPROTO_ICMPV6; 606 hints.ai_flags = AI_CANONNAME; 607 error = getaddrinfo(*argv, NULL, &hints, &res); 608 if (error) { 609 fprintf(stderr, 610 "traceroute6: %s\n", gai_strerror(error)); 611 exit(1); 612 } 613 if (res->ai_addrlen != sizeof(Dst)) { 614 fprintf(stderr, 615 "traceroute6: size of sockaddr mismatch\n"); 616 exit(1); 617 } 618 memcpy(&Dst, res->ai_addr, res->ai_addrlen); 619 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv; 620 if (!hostname) { 621 fprintf(stderr, "traceroute6: not enough core\n"); 622 exit(1); 623 } 624 if (res->ai_next) { 625 if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, 626 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 627 strlcpy(hbuf, "?", sizeof(hbuf)); 628 fprintf(stderr, "traceroute6: Warning: %s has multiple " 629 "addresses; using %s\n", hostname, hbuf); 630 } 631 632 if (*++argv) { 633 ep = NULL; 634 errno = 0; 635 datalen = strtoul(*argv, &ep, 0); 636 if (errno || *ep) { 637 fprintf(stderr, 638 "traceroute6: invalid packet length.\n"); 639 exit(1); 640 } 641 } 642 switch (useproto) { 643 case IPPROTO_ICMPV6: 644 minlen = ICMP6ECHOLEN; 645 break; 646 case IPPROTO_UDP: 647 minlen = sizeof(struct udphdr); 648 break; 649 case IPPROTO_NONE: 650 minlen = 0; 651 datalen = 0; 652 break; 653 case IPPROTO_SCTP: 654 minlen = sizeof(struct sctphdr); 655 break; 656 case IPPROTO_TCP: 657 minlen = sizeof(struct tcphdr); 658 break; 659 default: 660 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n", 661 useproto); 662 exit(1); 663 } 664 if (datalen < minlen) 665 datalen = minlen; 666 else if (datalen >= MAXPACKET) { 667 fprintf(stderr, 668 "traceroute6: packet size must be %zu <= s < %d.\n", 669 minlen, MAXPACKET); 670 exit(1); 671 } 672 if (useproto == IPPROTO_UDP) 673 datalen -= sizeof(struct udphdr); 674 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) { 675 fprintf(stderr, 676 "traceroute6: packet size must be a multiple of 4.\n"); 677 exit(1); 678 } 679 outpacket = malloc(datalen); 680 if (!outpacket) { 681 perror("malloc"); 682 exit(1); 683 } 684 (void) bzero((char *)outpacket, datalen); 685 686 /* initialize msghdr for receiving packets */ 687 rcviov[0].iov_base = (caddr_t)packet; 688 rcviov[0].iov_len = sizeof(packet); 689 rcvmhdr.msg_name = (caddr_t)&Rcv; 690 rcvmhdr.msg_namelen = sizeof(Rcv); 691 rcvmhdr.msg_iov = rcviov; 692 rcvmhdr.msg_iovlen = 1; 693 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 694 CMSG_SPACE(sizeof(int)); 695 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) { 696 fprintf(stderr, "traceroute6: malloc failed\n"); 697 exit(1); 698 } 699 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; 700 rcvmhdr.msg_controllen = rcvcmsglen; 701 702 if (options & SO_DEBUG) 703 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, 704 (char *)&on, sizeof(on)); 705 if (options & SO_DONTROUTE) 706 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, 707 (char *)&on, sizeof(on)); 708 #ifdef IPSEC 709 #ifdef IPSEC_POLICY_IPSEC 710 /* 711 * do not raise error even if setsockopt fails, kernel may have ipsec 712 * turned off. 713 */ 714 if (setpolicy(rcvsock, "in bypass") < 0) 715 errx(1, "%s", ipsec_strerror()); 716 if (setpolicy(rcvsock, "out bypass") < 0) 717 errx(1, "%s", ipsec_strerror()); 718 #else 719 { 720 int level = IPSEC_LEVEL_NONE; 721 722 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, 723 sizeof(level)); 724 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, 725 sizeof(level)); 726 #ifdef IP_AUTH_TRANS_LEVEL 727 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level, 728 sizeof(level)); 729 #else 730 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level, 731 sizeof(level)); 732 #endif 733 #ifdef IP_AUTH_NETWORK_LEVEL 734 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level, 735 sizeof(level)); 736 #endif 737 } 738 #endif /*IPSEC_POLICY_IPSEC*/ 739 #endif /*IPSEC*/ 740 741 #ifdef SO_SNDBUF 742 i = datalen; 743 if (i == 0) 744 i = 1; 745 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i, 746 sizeof(i)) < 0) { 747 perror("setsockopt(SO_SNDBUF)"); 748 exit(6); 749 } 750 #endif /* SO_SNDBUF */ 751 if (options & SO_DEBUG) 752 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, 753 (char *)&on, sizeof(on)); 754 if (options & SO_DONTROUTE) 755 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, 756 (char *)&on, sizeof(on)); 757 if (rth) {/* XXX: there is no library to finalize the header... */ 758 rth->ip6r_len = rth->ip6r_segleft * 2; 759 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR, 760 (void *)rth, (rth->ip6r_len + 1) << 3)) { 761 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n", 762 strerror(errno)); 763 exit(1); 764 } 765 } 766 #ifdef IPSEC 767 #ifdef IPSEC_POLICY_IPSEC 768 /* 769 * do not raise error even if setsockopt fails, kernel may have ipsec 770 * turned off. 771 */ 772 if (setpolicy(sndsock, "in bypass") < 0) 773 errx(1, "%s", ipsec_strerror()); 774 if (setpolicy(sndsock, "out bypass") < 0) 775 errx(1, "%s", ipsec_strerror()); 776 #else 777 { 778 int level = IPSEC_LEVEL_BYPASS; 779 780 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, 781 sizeof(level)); 782 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, 783 sizeof(level)); 784 #ifdef IP_AUTH_TRANS_LEVEL 785 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level, 786 sizeof(level)); 787 #else 788 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level, 789 sizeof(level)); 790 #endif 791 #ifdef IP_AUTH_NETWORK_LEVEL 792 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level, 793 sizeof(level)); 794 #endif 795 } 796 #endif /*IPSEC_POLICY_IPSEC*/ 797 #endif /*IPSEC*/ 798 799 /* 800 * Source selection 801 */ 802 bzero(&Src, sizeof(Src)); 803 if (source) { 804 struct addrinfo hints, *res; 805 int error; 806 807 memset(&hints, 0, sizeof(hints)); 808 hints.ai_family = AF_INET6; 809 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 810 hints.ai_flags = AI_NUMERICHOST; 811 error = getaddrinfo(source, "0", &hints, &res); 812 if (error) { 813 printf("traceroute6: %s: %s\n", source, 814 gai_strerror(error)); 815 exit(1); 816 } 817 if (res->ai_addrlen > sizeof(Src)) { 818 printf("traceroute6: %s: %s\n", source, 819 gai_strerror(error)); 820 exit(1); 821 } 822 memcpy(&Src, res->ai_addr, res->ai_addrlen); 823 freeaddrinfo(res); 824 } else { 825 struct sockaddr_in6 Nxt; 826 int dummy; 827 socklen_t len; 828 829 Nxt = Dst; 830 Nxt.sin6_port = htons(DUMMY_PORT); 831 if (cmsg != NULL) 832 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr, 833 sizeof(Nxt.sin6_addr)); 834 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 835 perror("socket"); 836 exit(1); 837 } 838 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) { 839 perror("connect"); 840 exit(1); 841 } 842 len = sizeof(Src); 843 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) { 844 perror("getsockname"); 845 exit(1); 846 } 847 if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len, 848 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) { 849 fprintf(stderr, "getnameinfo failed for source\n"); 850 exit(1); 851 } 852 source = src0; 853 close(dummy); 854 } 855 856 Src.sin6_port = htons(0); 857 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) { 858 perror("bind"); 859 exit(1); 860 } 861 862 { 863 socklen_t len; 864 865 len = sizeof(Src); 866 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) { 867 perror("getsockname"); 868 exit(1); 869 } 870 srcport = ntohs(Src.sin6_port); 871 } 872 873 if (as_path) { 874 asn = as_setup(as_server); 875 if (asn == NULL) { 876 fprintf(stderr, 877 "traceroute6: as_setup failed, AS# lookups" 878 " disabled\n"); 879 (void)fflush(stderr); 880 as_path = 0; 881 } 882 } 883 884 /* 885 * Message to users 886 */ 887 if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf, 888 sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) 889 strlcpy(hbuf, "(invalid)", sizeof(hbuf)); 890 fprintf(stderr, "traceroute6"); 891 fprintf(stderr, " to %s (%s)", hostname, hbuf); 892 if (source) 893 fprintf(stderr, " from %s", source); 894 fprintf(stderr, ", %lu hops max, %lu byte packets\n", 895 max_hops, 896 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0)); 897 (void) fflush(stderr); 898 899 if (first_hop > 1) 900 printf("Skipping %lu intermediate hops\n", first_hop - 1); 901 902 /* 903 * Main loop 904 */ 905 for (hops = first_hop; hops <= max_hops; ++hops) { 906 struct in6_addr lastaddr; 907 int got_there = 0; 908 unsigned unreachable = 0; 909 910 printf("%2lu ", hops); 911 bzero(&lastaddr, sizeof(lastaddr)); 912 for (probe = 0; probe < nprobes; ++probe) { 913 int cc; 914 struct timeval t1, t2; 915 916 (void) gettimeofday(&t1, NULL); 917 send_probe(++seq, hops); 918 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) { 919 (void) gettimeofday(&t2, NULL); 920 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) { 921 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr, 922 &lastaddr)) { 923 if (probe > 0) 924 fputs("\n ", stdout); 925 print(&rcvmhdr, cc); 926 lastaddr = Rcv.sin6_addr; 927 } 928 printf(" %.3f ms", deltaT(&t1, &t2)); 929 if (type == ICMP6_DST_UNREACH) { 930 switch (code) { 931 case ICMP6_DST_UNREACH_NOROUTE: 932 ++unreachable; 933 printf(" !N"); 934 break; 935 case ICMP6_DST_UNREACH_ADMIN: 936 ++unreachable; 937 printf(" !P"); 938 break; 939 case ICMP6_DST_UNREACH_NOTNEIGHBOR: 940 ++unreachable; 941 printf(" !S"); 942 break; 943 case ICMP6_DST_UNREACH_ADDR: 944 ++unreachable; 945 printf(" !A"); 946 break; 947 case ICMP6_DST_UNREACH_NOPORT: 948 if (rcvhlim >= 0 && 949 rcvhlim <= 1) 950 printf(" !"); 951 ++got_there; 952 break; 953 } 954 } else if (type == ICMP6_PARAM_PROB && 955 code == ICMP6_PARAMPROB_NEXTHEADER) { 956 printf(" !H"); 957 ++got_there; 958 } else if (type == ICMP6_ECHO_REPLY) { 959 if (rcvhlim >= 0 && 960 rcvhlim <= 1) 961 printf(" !"); 962 ++got_there; 963 } 964 break; 965 } else if (deltaT(&t1, &t2) > waittime * 1000) { 966 cc = 0; 967 break; 968 } 969 } 970 if (cc == 0) 971 printf(" *"); 972 (void) fflush(stdout); 973 } 974 putchar('\n'); 975 if (got_there || 976 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) { 977 exit(0); 978 } 979 } 980 if (as_path) 981 as_shutdown(asn); 982 983 exit(0); 984 } 985 986 int 987 wait_for_reply(int sock, struct msghdr *mhdr) 988 { 989 #ifdef HAVE_POLL 990 struct pollfd pfd[1]; 991 int cc = 0; 992 993 pfd[0].fd = sock; 994 pfd[0].events = POLLIN; 995 pfd[0].revents = 0; 996 997 if (poll(pfd, 1, waittime * 1000) > 0) 998 cc = recvmsg(rcvsock, mhdr, 0); 999 1000 return (cc); 1001 #else 1002 fd_set *fdsp; 1003 struct timeval wait; 1004 int cc = 0, fdsn; 1005 1006 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); 1007 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL) 1008 err(1, "malloc"); 1009 memset(fdsp, 0, fdsn); 1010 FD_SET(sock, fdsp); 1011 wait.tv_sec = waittime; wait.tv_usec = 0; 1012 1013 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0) 1014 cc = recvmsg(rcvsock, mhdr, 0); 1015 1016 free(fdsp); 1017 return (cc); 1018 #endif 1019 } 1020 1021 #ifdef IPSEC 1022 #ifdef IPSEC_POLICY_IPSEC 1023 int 1024 setpolicy(so, policy) 1025 int so; 1026 char *policy; 1027 { 1028 char *buf; 1029 1030 buf = ipsec_set_policy(policy, strlen(policy)); 1031 if (buf == NULL) { 1032 warnx("%s", ipsec_strerror()); 1033 return -1; 1034 } 1035 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY, 1036 buf, ipsec_get_policylen(buf)); 1037 1038 free(buf); 1039 1040 return 0; 1041 } 1042 #endif 1043 #endif 1044 1045 void 1046 send_probe(int seq, u_long hops) 1047 { 1048 struct icmp6_hdr *icp; 1049 struct sctphdr *sctp; 1050 struct sctp_chunkhdr *chk; 1051 struct sctp_init_chunk *init; 1052 struct sctp_paramhdr *param; 1053 struct tcphdr *tcp; 1054 int i; 1055 1056 i = hops; 1057 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 1058 (char *)&i, sizeof(i)) < 0) { 1059 perror("setsockopt IPV6_UNICAST_HOPS"); 1060 } 1061 1062 Dst.sin6_port = htons(port + seq); 1063 1064 switch (useproto) { 1065 case IPPROTO_ICMPV6: 1066 icp = (struct icmp6_hdr *)outpacket; 1067 1068 icp->icmp6_type = ICMP6_ECHO_REQUEST; 1069 icp->icmp6_code = 0; 1070 icp->icmp6_cksum = 0; 1071 icp->icmp6_id = ident; 1072 icp->icmp6_seq = htons(seq); 1073 break; 1074 case IPPROTO_UDP: 1075 break; 1076 case IPPROTO_NONE: 1077 /* No space for anything. No harm as seq/tv32 are decorative. */ 1078 break; 1079 case IPPROTO_SCTP: 1080 sctp = (struct sctphdr *)outpacket; 1081 1082 sctp->src_port = htons(ident); 1083 sctp->dest_port = htons(port + seq); 1084 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1085 sizeof(struct sctp_init_chunk))) { 1086 sctp->v_tag = 0; 1087 } else { 1088 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port; 1089 } 1090 sctp->checksum = htonl(0); 1091 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1092 sizeof(struct sctp_init_chunk))) { 1093 /* 1094 * Send a packet containing an INIT chunk. This works 1095 * better in case of firewalls on the path, but 1096 * results in a probe packet containing at least 1097 * 32 bytes of payload. For shorter payloads, use 1098 * SHUTDOWN-ACK chunks. 1099 */ 1100 init = (struct sctp_init_chunk *)(sctp + 1); 1101 init->ch.chunk_type = SCTP_INITIATION; 1102 init->ch.chunk_flags = 0; 1103 init->ch.chunk_length = htons((u_int16_t)(datalen - 1104 sizeof(struct sctphdr))); 1105 init->init.initiate_tag = (sctp->src_port << 16) | 1106 sctp->dest_port; 1107 init->init.a_rwnd = htonl(1500); 1108 init->init.num_outbound_streams = htons(1); 1109 init->init.num_inbound_streams = htons(1); 1110 init->init.initial_tsn = htonl(0); 1111 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1112 sizeof(struct sctp_init_chunk) + 1113 sizeof(struct sctp_paramhdr))) { 1114 param = (struct sctp_paramhdr *)(init + 1); 1115 param->param_type = htons(SCTP_PAD); 1116 param->param_length = 1117 htons((u_int16_t)(datalen - 1118 sizeof(struct sctphdr) - 1119 sizeof(struct sctp_init_chunk))); 1120 } 1121 } else { 1122 /* 1123 * Send a packet containing a SHUTDOWN-ACK chunk, 1124 * possibly followed by a PAD chunk. 1125 */ 1126 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1127 sizeof(struct sctp_chunkhdr))) { 1128 chk = (struct sctp_chunkhdr *)(sctp + 1); 1129 chk->chunk_type = SCTP_SHUTDOWN_ACK; 1130 chk->chunk_flags = 0; 1131 chk->chunk_length = htons(4); 1132 } 1133 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1134 2 * sizeof(struct sctp_chunkhdr))) { 1135 chk = chk + 1; 1136 chk->chunk_type = SCTP_PAD_CHUNK; 1137 chk->chunk_flags = 0; 1138 chk->chunk_length = htons((u_int16_t)(datalen - 1139 sizeof(struct sctphdr) - 1140 sizeof(struct sctp_chunkhdr))); 1141 } 1142 } 1143 sctp->checksum = sctp_crc32c(outpacket, datalen); 1144 break; 1145 case IPPROTO_TCP: 1146 tcp = (struct tcphdr *)outpacket; 1147 1148 tcp->th_sport = htons(ident); 1149 tcp->th_dport = htons(port + seq); 1150 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport; 1151 tcp->th_ack = 0; 1152 tcp->th_off = 5; 1153 tcp->th_flags = TH_SYN; 1154 tcp->th_sum = 0; 1155 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen); 1156 break; 1157 default: 1158 fprintf(stderr, "Unknown probe protocol %d.\n", useproto); 1159 exit(1); 1160 } 1161 1162 i = sendto(sndsock, (char *)outpacket, datalen, 0, 1163 (struct sockaddr *)&Dst, Dst.sin6_len); 1164 if (i < 0 || (u_long)i != datalen) { 1165 if (i < 0) 1166 perror("sendto"); 1167 printf("traceroute6: wrote %s %lu chars, ret=%d\n", 1168 hostname, datalen, i); 1169 (void) fflush(stdout); 1170 } 1171 } 1172 1173 int 1174 get_hoplim(struct msghdr *mhdr) 1175 { 1176 struct cmsghdr *cm; 1177 1178 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1179 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1180 if (cm->cmsg_level == IPPROTO_IPV6 && 1181 cm->cmsg_type == IPV6_HOPLIMIT && 1182 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1183 return (*(int *)CMSG_DATA(cm)); 1184 } 1185 1186 return (-1); 1187 } 1188 1189 double 1190 deltaT(struct timeval *t1p, struct timeval *t2p) 1191 { 1192 double dt; 1193 1194 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + 1195 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; 1196 return (dt); 1197 } 1198 1199 /* 1200 * Convert an ICMP "type" field to a printable string. 1201 */ 1202 const char * 1203 pr_type(int t0) 1204 { 1205 u_char t = t0 & 0xff; 1206 const char *cp; 1207 1208 switch (t) { 1209 case ICMP6_DST_UNREACH: 1210 cp = "Destination Unreachable"; 1211 break; 1212 case ICMP6_PACKET_TOO_BIG: 1213 cp = "Packet Too Big"; 1214 break; 1215 case ICMP6_TIME_EXCEEDED: 1216 cp = "Time Exceeded"; 1217 break; 1218 case ICMP6_PARAM_PROB: 1219 cp = "Parameter Problem"; 1220 break; 1221 case ICMP6_ECHO_REQUEST: 1222 cp = "Echo Request"; 1223 break; 1224 case ICMP6_ECHO_REPLY: 1225 cp = "Echo Reply"; 1226 break; 1227 case ICMP6_MEMBERSHIP_QUERY: 1228 cp = "Group Membership Query"; 1229 break; 1230 case ICMP6_MEMBERSHIP_REPORT: 1231 cp = "Group Membership Report"; 1232 break; 1233 case ICMP6_MEMBERSHIP_REDUCTION: 1234 cp = "Group Membership Reduction"; 1235 break; 1236 case ND_ROUTER_SOLICIT: 1237 cp = "Router Solicitation"; 1238 break; 1239 case ND_ROUTER_ADVERT: 1240 cp = "Router Advertisement"; 1241 break; 1242 case ND_NEIGHBOR_SOLICIT: 1243 cp = "Neighbor Solicitation"; 1244 break; 1245 case ND_NEIGHBOR_ADVERT: 1246 cp = "Neighbor Advertisement"; 1247 break; 1248 case ND_REDIRECT: 1249 cp = "Redirect"; 1250 break; 1251 default: 1252 cp = "Unknown"; 1253 break; 1254 } 1255 return cp; 1256 } 1257 1258 int 1259 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code) 1260 { 1261 struct icmp6_hdr *icp; 1262 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1263 char *buf = (char *)mhdr->msg_iov[0].iov_base; 1264 struct cmsghdr *cm; 1265 int *hlimp; 1266 char hbuf[NI_MAXHOST]; 1267 1268 #ifdef OLDRAWSOCKET 1269 int hlen; 1270 struct ip6_hdr *ip; 1271 #endif 1272 1273 #ifdef OLDRAWSOCKET 1274 ip = (struct ip6_hdr *) buf; 1275 hlen = sizeof(struct ip6_hdr); 1276 if (cc < hlen + sizeof(struct icmp6_hdr)) { 1277 if (verbose) { 1278 if (getnameinfo((struct sockaddr *)from, from->sin6_len, 1279 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1280 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1281 printf("packet too short (%d bytes) from %s\n", cc, 1282 hbuf); 1283 } 1284 return (0); 1285 } 1286 cc -= hlen; 1287 icp = (struct icmp6_hdr *)(buf + hlen); 1288 #else 1289 if (cc < (int)sizeof(struct icmp6_hdr)) { 1290 if (verbose) { 1291 if (getnameinfo((struct sockaddr *)from, from->sin6_len, 1292 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1293 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1294 printf("data too short (%d bytes) from %s\n", cc, hbuf); 1295 } 1296 return (0); 1297 } 1298 icp = (struct icmp6_hdr *)buf; 1299 #endif 1300 /* get optional information via advanced API */ 1301 rcvpktinfo = NULL; 1302 hlimp = NULL; 1303 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1304 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1305 if (cm->cmsg_level == IPPROTO_IPV6 && 1306 cm->cmsg_type == IPV6_PKTINFO && 1307 cm->cmsg_len == 1308 CMSG_LEN(sizeof(struct in6_pktinfo))) 1309 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm)); 1310 1311 if (cm->cmsg_level == IPPROTO_IPV6 && 1312 cm->cmsg_type == IPV6_HOPLIMIT && 1313 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1314 hlimp = (int *)CMSG_DATA(cm); 1315 } 1316 if (rcvpktinfo == NULL || hlimp == NULL) { 1317 warnx("failed to get received hop limit or packet info"); 1318 #if 0 1319 return (0); 1320 #else 1321 rcvhlim = 0; /*XXX*/ 1322 #endif 1323 } 1324 else 1325 rcvhlim = *hlimp; 1326 1327 *type = icp->icmp6_type; 1328 *code = icp->icmp6_code; 1329 if ((*type == ICMP6_TIME_EXCEEDED && 1330 *code == ICMP6_TIME_EXCEED_TRANSIT) || 1331 (*type == ICMP6_DST_UNREACH) || 1332 (*type == ICMP6_PARAM_PROB && 1333 *code == ICMP6_PARAMPROB_NEXTHEADER)) { 1334 struct ip6_hdr *hip; 1335 struct icmp6_hdr *icmp; 1336 struct sctp_init_chunk *init; 1337 struct sctphdr *sctp; 1338 struct tcphdr *tcp; 1339 struct udphdr *udp; 1340 void *up; 1341 1342 hip = (struct ip6_hdr *)(icp + 1); 1343 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) { 1344 if (verbose) 1345 warnx("failed to get upper layer header"); 1346 return (0); 1347 } 1348 switch (useproto) { 1349 case IPPROTO_ICMPV6: 1350 icmp = (struct icmp6_hdr *)up; 1351 if (icmp->icmp6_id == ident && 1352 icmp->icmp6_seq == htons(seq)) 1353 return (1); 1354 break; 1355 case IPPROTO_UDP: 1356 udp = (struct udphdr *)up; 1357 if (udp->uh_sport == htons(srcport) && 1358 udp->uh_dport == htons(port + seq)) 1359 return (1); 1360 break; 1361 case IPPROTO_SCTP: 1362 sctp = (struct sctphdr *)up; 1363 if (sctp->src_port != htons(ident) || 1364 sctp->dest_port != htons(port + seq)) { 1365 break; 1366 } 1367 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1368 sizeof(struct sctp_init_chunk))) { 1369 if (sctp->v_tag != 0) { 1370 break; 1371 } 1372 init = (struct sctp_init_chunk *)(sctp + 1); 1373 /* Check the initiate tag, if available. */ 1374 if ((char *)&init->init.a_rwnd > buf + cc) { 1375 return (1); 1376 } 1377 if (init->init.initiate_tag == (u_int32_t) 1378 ((sctp->src_port << 16) | sctp->dest_port)) { 1379 return (1); 1380 } 1381 } else { 1382 if (sctp->v_tag == 1383 (u_int32_t)((sctp->src_port << 16) | 1384 sctp->dest_port)) { 1385 return (1); 1386 } 1387 } 1388 break; 1389 case IPPROTO_TCP: 1390 tcp = (struct tcphdr *)up; 1391 if (tcp->th_sport == htons(ident) && 1392 tcp->th_dport == htons(port + seq) && 1393 tcp->th_seq == 1394 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport)) 1395 return (1); 1396 break; 1397 case IPPROTO_NONE: 1398 return (1); 1399 default: 1400 fprintf(stderr, "Unknown probe proto %d.\n", useproto); 1401 break; 1402 } 1403 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) { 1404 if (icp->icmp6_id == ident && 1405 icp->icmp6_seq == htons(seq)) 1406 return (1); 1407 } 1408 if (verbose) { 1409 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN]; 1410 u_int8_t *p; 1411 int i; 1412 1413 if (getnameinfo((struct sockaddr *)from, from->sin6_len, 1414 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0) 1415 strlcpy(sbuf, "invalid", sizeof(sbuf)); 1416 printf("\n%d bytes from %s to %s", cc, sbuf, 1417 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1418 dbuf, sizeof(dbuf)) : "?"); 1419 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type), 1420 *code); 1421 p = (u_int8_t *)(icp + 1); 1422 #define WIDTH 16 1423 for (i = 0; i < cc; i++) { 1424 if (i % WIDTH == 0) 1425 printf("%04x:", i); 1426 if (i % 4 == 0) 1427 printf(" "); 1428 printf("%02x", p[i]); 1429 if (i % WIDTH == WIDTH - 1) 1430 printf("\n"); 1431 } 1432 if (cc % WIDTH != 0) 1433 printf("\n"); 1434 } 1435 return (0); 1436 } 1437 1438 /* 1439 * Increment pointer until find the UDP or ICMP header. 1440 */ 1441 void * 1442 get_uphdr(struct ip6_hdr *ip6, u_char *lim) 1443 { 1444 u_char *cp = (u_char *)ip6, nh; 1445 int hlen; 1446 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */ 1447 1448 if (cp + sizeof(*ip6) > lim) 1449 return (NULL); 1450 1451 nh = ip6->ip6_nxt; 1452 cp += sizeof(struct ip6_hdr); 1453 1454 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) { 1455 switch (nh) { 1456 case IPPROTO_ESP: 1457 return (NULL); 1458 case IPPROTO_ICMPV6: 1459 return (useproto == nh ? cp : NULL); 1460 case IPPROTO_SCTP: 1461 case IPPROTO_TCP: 1462 case IPPROTO_UDP: 1463 return (useproto == nh ? cp : NULL); 1464 case IPPROTO_NONE: 1465 return (useproto == nh ? none_hdr : NULL); 1466 case IPPROTO_FRAGMENT: 1467 hlen = sizeof(struct ip6_frag); 1468 nh = ((struct ip6_frag *)cp)->ip6f_nxt; 1469 break; 1470 case IPPROTO_AH: 1471 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2; 1472 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1473 break; 1474 default: 1475 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3; 1476 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1477 break; 1478 } 1479 1480 cp += hlen; 1481 } 1482 1483 return (NULL); 1484 } 1485 1486 void 1487 print(struct msghdr *mhdr, int cc) 1488 { 1489 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1490 char hbuf[NI_MAXHOST]; 1491 1492 if (getnameinfo((struct sockaddr *)from, from->sin6_len, 1493 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1494 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1495 if (as_path) 1496 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6)); 1497 if (nflag) 1498 printf(" %s", hbuf); 1499 else if (lflag) 1500 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf); 1501 else 1502 printf(" %s", inetname((struct sockaddr *)from)); 1503 1504 if (verbose) { 1505 #ifdef OLDRAWSOCKET 1506 printf(" %d bytes to %s", cc, 1507 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1508 hbuf, sizeof(hbuf)) : "?"); 1509 #else 1510 printf(" %d bytes of data to %s", cc, 1511 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1512 hbuf, sizeof(hbuf)) : "?"); 1513 #endif 1514 } 1515 } 1516 1517 /* 1518 * Construct an Internet address representation. 1519 * If the nflag has been supplied, give 1520 * numeric value, otherwise try for symbolic name. 1521 */ 1522 const char * 1523 inetname(struct sockaddr *sa) 1524 { 1525 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1]; 1526 static int first = 1; 1527 char *cp; 1528 1529 if (first && !nflag) { 1530 first = 0; 1531 if (gethostname(domain, sizeof(domain)) == 0 && 1532 (cp = strchr(domain, '.'))) 1533 (void) strlcpy(domain, cp + 1, sizeof(domain)); 1534 else 1535 domain[0] = 0; 1536 } 1537 cp = NULL; 1538 if (!nflag) { 1539 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0, 1540 NI_NAMEREQD) == 0) { 1541 if ((cp = strchr(line, '.')) && 1542 !strcmp(cp + 1, domain)) 1543 *cp = 0; 1544 cp = line; 1545 } 1546 } 1547 if (cp) 1548 return cp; 1549 1550 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0, 1551 NI_NUMERICHOST) != 0) 1552 strlcpy(line, "invalid", sizeof(line)); 1553 return line; 1554 } 1555 1556 /* 1557 * CRC32C routine for the Stream Control Transmission Protocol 1558 */ 1559 1560 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF]) 1561 1562 static u_int32_t crc_c[256] = { 1563 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 1564 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 1565 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 1566 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 1567 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 1568 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, 1569 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 1570 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, 1571 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 1572 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, 1573 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 1574 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, 1575 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 1576 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, 1577 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 1578 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 1579 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 1580 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, 1581 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 1582 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, 1583 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 1584 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, 1585 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 1586 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, 1587 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 1588 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, 1589 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 1590 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, 1591 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 1592 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, 1593 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 1594 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, 1595 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 1596 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, 1597 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 1598 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, 1599 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 1600 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, 1601 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 1602 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, 1603 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 1604 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, 1605 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 1606 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, 1607 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 1608 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 1609 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 1610 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, 1611 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 1612 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, 1613 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 1614 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 1615 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 1616 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, 1617 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 1618 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, 1619 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 1620 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, 1621 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 1622 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, 1623 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 1624 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, 1625 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 1626 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 1627 }; 1628 1629 u_int32_t 1630 sctp_crc32c(void *packet, u_int32_t len) 1631 { 1632 u_int32_t i, crc32c; 1633 u_int8_t byte0, byte1, byte2, byte3; 1634 u_int8_t *buf = (u_int8_t *)packet; 1635 1636 crc32c = ~0; 1637 for (i = 0; i < len; i++) 1638 CRC32C(crc32c, buf[i]); 1639 crc32c = ~crc32c; 1640 byte0 = crc32c & 0xff; 1641 byte1 = (crc32c>>8) & 0xff; 1642 byte2 = (crc32c>>16) & 0xff; 1643 byte3 = (crc32c>>24) & 0xff; 1644 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); 1645 return htonl(crc32c); 1646 } 1647 1648 u_int16_t 1649 in_cksum(u_int16_t *addr, int len) 1650 { 1651 int nleft = len; 1652 u_int16_t *w = addr; 1653 u_int16_t answer; 1654 int sum = 0; 1655 1656 /* 1657 * Our algorithm is simple, using a 32 bit accumulator (sum), 1658 * we add sequential 16 bit words to it, and at the end, fold 1659 * back all the carry bits from the top 16 bits into the lower 1660 * 16 bits. 1661 */ 1662 while (nleft > 1) { 1663 sum += *w++; 1664 nleft -= 2; 1665 } 1666 1667 /* mop up an odd byte, if necessary */ 1668 if (nleft == 1) 1669 sum += *(u_char *)w; 1670 1671 /* 1672 * add back carry outs from top 16 bits to low 16 bits 1673 */ 1674 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 1675 sum += (sum >> 16); /* add carry */ 1676 answer = ~sum; /* truncate to 16 bits */ 1677 return (answer); 1678 } 1679 1680 u_int16_t 1681 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst, 1682 void *payload, u_int32_t len) 1683 { 1684 struct { 1685 struct in6_addr src; 1686 struct in6_addr dst; 1687 u_int32_t len; 1688 u_int8_t zero[3]; 1689 u_int8_t next; 1690 } pseudo_hdr; 1691 u_int16_t sum[2]; 1692 1693 pseudo_hdr.src = src->sin6_addr; 1694 pseudo_hdr.dst = dst->sin6_addr; 1695 pseudo_hdr.len = htonl(len); 1696 pseudo_hdr.zero[0] = 0; 1697 pseudo_hdr.zero[1] = 0; 1698 pseudo_hdr.zero[2] = 0; 1699 pseudo_hdr.next = IPPROTO_TCP; 1700 1701 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr)); 1702 sum[0] = in_cksum(payload, len); 1703 1704 return (~in_cksum(sum, sizeof(sum))); 1705 } 1706 1707 void 1708 usage(void) 1709 { 1710 1711 fprintf(stderr, 1712 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n" 1713 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n" 1714 " [datalen]\n"); 1715 exit(1); 1716 } 1717