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/capsicum.h> 253 #include <sys/time.h> 254 #include <sys/socket.h> 255 #include <sys/uio.h> 256 #include <sys/file.h> 257 #include <sys/ioctl.h> 258 #include <sys/sysctl.h> 259 260 #include <netinet/in.h> 261 262 #include <arpa/inet.h> 263 264 #include <libcasper.h> 265 #include <casper/cap_dns.h> 266 #include <capsicum_helpers.h> 267 268 #include <netdb.h> 269 #include <stdio.h> 270 #include <err.h> 271 #ifdef HAVE_POLL 272 #include <poll.h> 273 #endif 274 #include <errno.h> 275 #include <stdlib.h> 276 #include <string.h> 277 #include <unistd.h> 278 279 #include <netinet/ip6.h> 280 #include <netinet/icmp6.h> 281 #include <netinet/sctp.h> 282 #include <netinet/sctp_header.h> 283 #include <netinet/tcp.h> 284 #include <netinet/udp.h> 285 286 #ifdef IPSEC 287 #include <net/route.h> 288 #include <netipsec/ipsec.h> 289 #endif 290 291 #include "as.h" 292 293 #define DUMMY_PORT 10010 294 295 #define MAXPACKET 65535 /* max ip packet size */ 296 297 static u_char packet[512]; /* last inbound (icmp) packet */ 298 static char *outpacket; /* last output packet */ 299 300 int main(int, char *[]); 301 int wait_for_reply(int, struct msghdr *); 302 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 303 int setpolicy(int so, char *policy); 304 #endif 305 void send_probe(int, u_long); 306 void *get_uphdr(struct ip6_hdr *, u_char *); 307 void capdns_open(void); 308 int get_hoplim(struct msghdr *); 309 double deltaT(struct timeval *, struct timeval *); 310 const char *pr_type(int); 311 int packet_ok(struct msghdr *, int, int, u_char *, u_char *); 312 void print(struct msghdr *, int); 313 const char *inetname(struct sockaddr *); 314 u_int32_t sctp_crc32c(void *, u_int32_t); 315 u_int16_t in_cksum(u_int16_t *addr, int); 316 u_int16_t udp_cksum(struct sockaddr_in6 *, struct sockaddr_in6 *, 317 void *, u_int32_t); 318 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *, 319 void *, u_int32_t); 320 void usage(void); 321 322 static int rcvsock; /* receive (icmp) socket file descriptor */ 323 static int sndsock; /* send (raw/udp) socket file descriptor */ 324 325 static struct msghdr rcvmhdr; 326 static struct iovec rcviov[2]; 327 static int rcvhlim; 328 static struct in6_pktinfo *rcvpktinfo; 329 330 static struct sockaddr_in6 Src, Dst, Rcv; 331 static u_long datalen = 20; /* How much data */ 332 #define ICMP6ECHOLEN 8 333 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */ 334 static char rtbuf[2064]; 335 static struct ip6_rthdr *rth; 336 static struct cmsghdr *cmsg; 337 338 static char *source = NULL; 339 static char *hostname; 340 341 static cap_channel_t *capdns; 342 343 static u_long nprobes = 3; 344 static u_long first_hop = 1; 345 static u_long max_hops = 30; 346 static u_int16_t srcport; 347 static u_int16_t port = 32768+666; /* start udp dest port # for probe packets */ 348 static u_int16_t ident; 349 static int tclass = -1; 350 static int options; /* socket options */ 351 static int verbose; 352 static int waittime = 5; /* time to wait for response (in seconds) */ 353 static int nflag; /* print addresses numerically */ 354 static int useproto = IPPROTO_UDP; /* protocol to use to send packet */ 355 static int lflag; /* print both numerical address & hostname */ 356 static int as_path; /* print as numbers for each hop */ 357 static char *as_server = NULL; 358 static void *asn; 359 360 int 361 main(int argc, char *argv[]) 362 { 363 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM }; 364 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep; 365 int ch, i, on = 1, seq, rcvcmsglen, error; 366 struct addrinfo hints, *res; 367 static u_char *rcvcmsgbuf; 368 u_long probe, hops, lport, ltclass; 369 struct hostent *hp; 370 size_t size, minlen; 371 uid_t uid; 372 u_char type, code; 373 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 374 char ipsec_inpolicy[] = "in bypass"; 375 char ipsec_outpolicy[] = "out bypass"; 376 #endif 377 cap_rights_t rights; 378 379 capdns_open(); 380 381 /* 382 * Receive ICMP 383 */ 384 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { 385 perror("socket(ICMPv6)"); 386 exit(5); 387 } 388 389 size = sizeof(i); 390 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0); 391 max_hops = i; 392 393 /* specify to tell receiving interface */ 394 #ifdef IPV6_RECVPKTINFO 395 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, 396 sizeof(on)) < 0) 397 err(1, "setsockopt(IPV6_RECVPKTINFO)"); 398 #else /* old adv. API */ 399 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on, 400 sizeof(on)) < 0) 401 err(1, "setsockopt(IPV6_PKTINFO)"); 402 #endif 403 404 /* specify to tell value of hoplimit field of received IP6 hdr */ 405 #ifdef IPV6_RECVHOPLIMIT 406 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, 407 sizeof(on)) < 0) 408 err(1, "setsockopt(IPV6_RECVHOPLIMIT)"); 409 #else /* old adv. API */ 410 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, 411 sizeof(on)) < 0) 412 err(1, "setsockopt(IPV6_HOPLIMIT)"); 413 #endif 414 415 seq = 0; 416 ident = htons(getpid() & 0xffff); /* same as ping6 */ 417 418 while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:St:TUvw:")) != -1) 419 switch (ch) { 420 case 'a': 421 as_path = 1; 422 break; 423 case 'A': 424 as_path = 1; 425 as_server = optarg; 426 break; 427 case 'd': 428 options |= SO_DEBUG; 429 break; 430 case 'f': 431 ep = NULL; 432 errno = 0; 433 first_hop = strtoul(optarg, &ep, 0); 434 if (errno || !*optarg || *ep || first_hop > 255) { 435 fprintf(stderr, 436 "traceroute6: invalid min hoplimit.\n"); 437 exit(1); 438 } 439 break; 440 case 'g': 441 /* XXX use after capability mode is entered */ 442 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno); 443 if (hp == NULL) { 444 fprintf(stderr, 445 "traceroute6: unknown host %s\n", optarg); 446 exit(1); 447 } 448 if (rth == NULL) { 449 /* 450 * XXX: We can't detect the number of 451 * intermediate nodes yet. 452 */ 453 if ((rth = inet6_rth_init((void *)rtbuf, 454 sizeof(rtbuf), IPV6_RTHDR_TYPE_0, 455 0)) == NULL) { 456 fprintf(stderr, 457 "inet6_rth_init failed.\n"); 458 exit(1); 459 } 460 } 461 if (inet6_rth_add((void *)rth, 462 (struct in6_addr *)hp->h_addr)) { 463 fprintf(stderr, 464 "inet6_rth_add failed for %s\n", 465 optarg); 466 exit(1); 467 } 468 freehostent(hp); 469 break; 470 case 'I': 471 useproto = IPPROTO_ICMPV6; 472 break; 473 case 'l': 474 lflag++; 475 break; 476 case 'm': 477 ep = NULL; 478 errno = 0; 479 max_hops = strtoul(optarg, &ep, 0); 480 if (errno || !*optarg || *ep || max_hops > 255) { 481 fprintf(stderr, 482 "traceroute6: invalid max hoplimit.\n"); 483 exit(1); 484 } 485 break; 486 case 'n': 487 nflag++; 488 break; 489 case 'N': 490 useproto = IPPROTO_NONE; 491 break; 492 case 'p': 493 ep = NULL; 494 errno = 0; 495 lport = strtoul(optarg, &ep, 0); 496 if (errno || !*optarg || *ep) { 497 fprintf(stderr, "traceroute6: invalid port.\n"); 498 exit(1); 499 } 500 if (lport == 0 || lport != (lport & 0xffff)) { 501 fprintf(stderr, 502 "traceroute6: port out of range.\n"); 503 exit(1); 504 } 505 port = lport & 0xffff; 506 break; 507 case 'q': 508 ep = NULL; 509 errno = 0; 510 nprobes = strtoul(optarg, &ep, 0); 511 if (errno || !*optarg || *ep) { 512 fprintf(stderr, 513 "traceroute6: invalid nprobes.\n"); 514 exit(1); 515 } 516 if (nprobes < 1) { 517 fprintf(stderr, 518 "traceroute6: nprobes must be >0.\n"); 519 exit(1); 520 } 521 break; 522 case 'r': 523 options |= SO_DONTROUTE; 524 break; 525 case 's': 526 /* 527 * set the ip source address of the outbound 528 * probe (e.g., on a multi-homed host). 529 */ 530 source = optarg; 531 break; 532 case 'S': 533 useproto = IPPROTO_SCTP; 534 break; 535 case 't': 536 ep = NULL; 537 errno = 0; 538 ltclass = strtoul(optarg, &ep, 0); 539 if (errno || !*optarg || *ep || ltclass > 255) { 540 fprintf(stderr, 541 "traceroute6: invalid traffic class.\n"); 542 exit(1); 543 } 544 tclass = (int)ltclass; 545 break; 546 case 'T': 547 useproto = IPPROTO_TCP; 548 break; 549 case 'U': 550 useproto = IPPROTO_UDP; 551 break; 552 case 'v': 553 verbose++; 554 break; 555 case 'w': 556 ep = NULL; 557 errno = 0; 558 waittime = strtoul(optarg, &ep, 0); 559 if (errno || !*optarg || *ep) { 560 fprintf(stderr, 561 "traceroute6: invalid wait time.\n"); 562 exit(1); 563 } 564 if (waittime < 1) { 565 fprintf(stderr, 566 "traceroute6: wait must be >= 1 sec.\n"); 567 exit(1); 568 } 569 break; 570 default: 571 usage(); 572 } 573 argc -= optind; 574 argv += optind; 575 576 /* 577 * Open socket to send probe packets. 578 */ 579 switch (useproto) { 580 case IPPROTO_ICMPV6: 581 sndsock = rcvsock; 582 break; 583 case IPPROTO_NONE: 584 case IPPROTO_SCTP: 585 case IPPROTO_TCP: 586 case IPPROTO_UDP: 587 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) { 588 perror("socket(SOCK_RAW)"); 589 exit(5); 590 } 591 break; 592 default: 593 fprintf(stderr, "traceroute6: unknown probe protocol %d\n", 594 useproto); 595 exit(5); 596 } 597 if (max_hops < first_hop) { 598 fprintf(stderr, 599 "traceroute6: max hoplimit must be larger than first hoplimit.\n"); 600 exit(1); 601 } 602 603 /* revoke privs */ 604 uid = getuid(); 605 if (setresuid(uid, uid, uid) == -1) { 606 perror("setresuid"); 607 exit(1); 608 } 609 610 if (tclass != -1) { 611 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_TCLASS, &tclass, 612 sizeof(int)) == -1) { 613 perror("setsockopt(IPV6_TCLASS)"); 614 exit(7); 615 } 616 } 617 618 if (argc < 1 || argc > 2) 619 usage(); 620 621 #if 1 622 setvbuf(stdout, NULL, _IOLBF, BUFSIZ); 623 #else 624 setlinebuf(stdout); 625 #endif 626 627 memset(&hints, 0, sizeof(hints)); 628 hints.ai_family = PF_INET6; 629 hints.ai_socktype = SOCK_RAW; 630 hints.ai_protocol = IPPROTO_ICMPV6; 631 hints.ai_flags = AI_CANONNAME; 632 633 error = cap_getaddrinfo(capdns, *argv, NULL, &hints, &res); 634 635 if (error) { 636 fprintf(stderr, 637 "traceroute6: %s\n", gai_strerror(error)); 638 exit(1); 639 } 640 if (res->ai_addrlen != sizeof(Dst)) { 641 fprintf(stderr, 642 "traceroute6: size of sockaddr mismatch\n"); 643 exit(1); 644 } 645 memcpy(&Dst, res->ai_addr, res->ai_addrlen); 646 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv; 647 if (!hostname) { 648 fprintf(stderr, "traceroute6: not enough core\n"); 649 exit(1); 650 } 651 if (res->ai_next) { 652 if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hbuf, 653 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 654 strlcpy(hbuf, "?", sizeof(hbuf)); 655 fprintf(stderr, "traceroute6: Warning: %s has multiple " 656 "addresses; using %s\n", hostname, hbuf); 657 } 658 freeaddrinfo(res); 659 if (*++argv) { 660 ep = NULL; 661 errno = 0; 662 datalen = strtoul(*argv, &ep, 0); 663 if (errno || *ep) { 664 fprintf(stderr, 665 "traceroute6: invalid packet length.\n"); 666 exit(1); 667 } 668 } 669 switch (useproto) { 670 case IPPROTO_ICMPV6: 671 minlen = ICMP6ECHOLEN; 672 break; 673 case IPPROTO_UDP: 674 minlen = sizeof(struct udphdr); 675 break; 676 case IPPROTO_NONE: 677 minlen = 0; 678 datalen = 0; 679 break; 680 case IPPROTO_SCTP: 681 minlen = sizeof(struct sctphdr); 682 break; 683 case IPPROTO_TCP: 684 minlen = sizeof(struct tcphdr); 685 break; 686 default: 687 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n", 688 useproto); 689 exit(1); 690 } 691 if (datalen < minlen) 692 datalen = minlen; 693 else if (datalen >= MAXPACKET) { 694 fprintf(stderr, 695 "traceroute6: packet size must be %zu <= s < %d.\n", 696 minlen, MAXPACKET); 697 exit(1); 698 } 699 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) { 700 fprintf(stderr, 701 "traceroute6: packet size must be a multiple of 4.\n"); 702 exit(1); 703 } 704 outpacket = malloc(datalen); 705 if (!outpacket) { 706 perror("malloc"); 707 exit(1); 708 } 709 (void) bzero((char *)outpacket, datalen); 710 711 /* initialize msghdr for receiving packets */ 712 rcviov[0].iov_base = (caddr_t)packet; 713 rcviov[0].iov_len = sizeof(packet); 714 rcvmhdr.msg_name = (caddr_t)&Rcv; 715 rcvmhdr.msg_namelen = sizeof(Rcv); 716 rcvmhdr.msg_iov = rcviov; 717 rcvmhdr.msg_iovlen = 1; 718 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 719 CMSG_SPACE(sizeof(int)); 720 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) { 721 fprintf(stderr, "traceroute6: malloc failed\n"); 722 exit(1); 723 } 724 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; 725 rcvmhdr.msg_controllen = rcvcmsglen; 726 727 if (options & SO_DEBUG) 728 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, 729 (char *)&on, sizeof(on)); 730 if (options & SO_DONTROUTE) 731 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, 732 (char *)&on, sizeof(on)); 733 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 734 /* 735 * do not raise error even if setsockopt fails, kernel may have ipsec 736 * turned off. 737 */ 738 if (setpolicy(rcvsock, ipsec_inpolicy) < 0) 739 errx(1, "%s", ipsec_strerror()); 740 if (setpolicy(rcvsock, ipsec_outpolicy) < 0) 741 errx(1, "%s", ipsec_strerror()); 742 #else 743 { 744 int level = IPSEC_LEVEL_NONE; 745 746 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, 747 sizeof(level)); 748 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, 749 sizeof(level)); 750 #ifdef IP_AUTH_TRANS_LEVEL 751 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level, 752 sizeof(level)); 753 #else 754 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level, 755 sizeof(level)); 756 #endif 757 #ifdef IP_AUTH_NETWORK_LEVEL 758 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level, 759 sizeof(level)); 760 #endif 761 } 762 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */ 763 764 #ifdef SO_SNDBUF 765 i = datalen; 766 if (i == 0) 767 i = 1; 768 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i, 769 sizeof(i)) < 0) { 770 perror("setsockopt(SO_SNDBUF)"); 771 exit(6); 772 } 773 #endif /* SO_SNDBUF */ 774 if (options & SO_DEBUG) 775 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, 776 (char *)&on, sizeof(on)); 777 if (options & SO_DONTROUTE) 778 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, 779 (char *)&on, sizeof(on)); 780 if (rth) {/* XXX: there is no library to finalize the header... */ 781 rth->ip6r_len = rth->ip6r_segleft * 2; 782 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR, 783 (void *)rth, (rth->ip6r_len + 1) << 3)) { 784 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n", 785 strerror(errno)); 786 exit(1); 787 } 788 } 789 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 790 /* 791 * do not raise error even if setsockopt fails, kernel may have ipsec 792 * turned off. 793 */ 794 if (setpolicy(sndsock, ipsec_inpolicy) < 0) 795 errx(1, "%s", ipsec_strerror()); 796 if (setpolicy(sndsock, ipsec_outpolicy) < 0) 797 errx(1, "%s", ipsec_strerror()); 798 #else 799 { 800 int level = IPSEC_LEVEL_BYPASS; 801 802 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, 803 sizeof(level)); 804 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, 805 sizeof(level)); 806 #ifdef IP_AUTH_TRANS_LEVEL 807 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level, 808 sizeof(level)); 809 #else 810 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level, 811 sizeof(level)); 812 #endif 813 #ifdef IP_AUTH_NETWORK_LEVEL 814 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level, 815 sizeof(level)); 816 #endif 817 } 818 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */ 819 820 /* 821 * Source selection 822 */ 823 bzero(&Src, sizeof(Src)); 824 if (source) { 825 memset(&hints, 0, sizeof(hints)); 826 hints.ai_family = AF_INET6; 827 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 828 hints.ai_flags = AI_NUMERICHOST; 829 error = cap_getaddrinfo(capdns, source, "0", &hints, &res); 830 if (error) { 831 printf("traceroute6: %s: %s\n", source, 832 gai_strerror(error)); 833 exit(1); 834 } 835 if (res->ai_addrlen > sizeof(Src)) { 836 printf("traceroute6: %s: %s\n", source, 837 gai_strerror(error)); 838 exit(1); 839 } 840 memcpy(&Src, res->ai_addr, res->ai_addrlen); 841 freeaddrinfo(res); 842 } else { 843 struct sockaddr_in6 Nxt; 844 int dummy; 845 socklen_t len; 846 847 Nxt = Dst; 848 Nxt.sin6_port = htons(DUMMY_PORT); 849 if (cmsg != NULL) 850 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr, 851 sizeof(Nxt.sin6_addr)); 852 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 853 perror("socket"); 854 exit(1); 855 } 856 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) { 857 perror("connect"); 858 exit(1); 859 } 860 len = sizeof(Src); 861 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) { 862 perror("getsockname"); 863 exit(1); 864 } 865 if (cap_getnameinfo(capdns, (struct sockaddr *)&Src, Src.sin6_len, 866 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) { 867 fprintf(stderr, "getnameinfo failed for source\n"); 868 exit(1); 869 } 870 source = src0; 871 close(dummy); 872 } 873 874 Src.sin6_port = htons(0); 875 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) { 876 perror("bind"); 877 exit(1); 878 } 879 880 { 881 socklen_t len; 882 883 len = sizeof(Src); 884 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) { 885 perror("getsockname"); 886 exit(1); 887 } 888 srcport = ntohs(Src.sin6_port); 889 } 890 891 if (as_path) { 892 asn = as_setup(as_server); 893 if (asn == NULL) { 894 fprintf(stderr, 895 "traceroute6: as_setup failed, AS# lookups" 896 " disabled\n"); 897 (void)fflush(stderr); 898 as_path = 0; 899 } 900 } 901 902 /* 903 * Message to users 904 */ 905 if (cap_getnameinfo(capdns, (struct sockaddr *)&Dst, Dst.sin6_len, hbuf, 906 sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) 907 strlcpy(hbuf, "(invalid)", sizeof(hbuf)); 908 fprintf(stderr, "traceroute6"); 909 fprintf(stderr, " to %s (%s)", hostname, hbuf); 910 if (source) 911 fprintf(stderr, " from %s", source); 912 fprintf(stderr, ", %lu hops max, %lu byte packets\n", 913 max_hops, 914 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0)); 915 (void) fflush(stderr); 916 917 if (first_hop > 1) 918 printf("Skipping %lu intermediate hops\n", first_hop - 1); 919 920 if (connect(sndsock, (struct sockaddr *)&Dst, 921 sizeof(Dst)) != 0) { 922 fprintf(stderr, "connect: %s\n", strerror(errno)); 923 exit(1); 924 } 925 926 /* 927 * Here we enter capability mode. Further down access to global 928 * namespaces (e.g filesystem) is restricted (see capsicum(4)). 929 * We must connect(2) our socket before this point. 930 */ 931 932 if (caph_enter_casper() < 0) { 933 fprintf(stderr, "caph_enter_casper: %s\n", strerror(errno)); 934 exit(1); 935 } 936 937 cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT); 938 if (caph_rights_limit(sndsock, &rights) < 0) { 939 fprintf(stderr, "caph_rights_limit sndsock: %s\n", 940 strerror(errno)); 941 exit(1); 942 } 943 944 /* 945 * Main loop 946 */ 947 for (hops = first_hop; hops <= max_hops; ++hops) { 948 struct in6_addr lastaddr; 949 int got_there = 0; 950 unsigned unreachable = 0; 951 952 printf("%2lu ", hops); 953 bzero(&lastaddr, sizeof(lastaddr)); 954 for (probe = 0; probe < nprobes; ++probe) { 955 int cc; 956 struct timeval t1, t2; 957 958 (void) gettimeofday(&t1, NULL); 959 send_probe(++seq, hops); 960 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) { 961 (void) gettimeofday(&t2, NULL); 962 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) { 963 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr, 964 &lastaddr)) { 965 if (probe > 0) 966 fputs("\n ", stdout); 967 print(&rcvmhdr, cc); 968 lastaddr = Rcv.sin6_addr; 969 } 970 printf(" %.3f ms", deltaT(&t1, &t2)); 971 if (type == ICMP6_DST_UNREACH) { 972 switch (code) { 973 case ICMP6_DST_UNREACH_NOROUTE: 974 ++unreachable; 975 printf(" !N"); 976 break; 977 case ICMP6_DST_UNREACH_ADMIN: 978 ++unreachable; 979 printf(" !P"); 980 break; 981 case ICMP6_DST_UNREACH_NOTNEIGHBOR: 982 ++unreachable; 983 printf(" !S"); 984 break; 985 case ICMP6_DST_UNREACH_ADDR: 986 ++unreachable; 987 printf(" !A"); 988 break; 989 case ICMP6_DST_UNREACH_NOPORT: 990 if (rcvhlim >= 0 && 991 rcvhlim <= 1) 992 printf(" !"); 993 ++got_there; 994 break; 995 } 996 } else if (type == ICMP6_PARAM_PROB && 997 code == ICMP6_PARAMPROB_NEXTHEADER) { 998 printf(" !H"); 999 ++got_there; 1000 } else if (type == ICMP6_ECHO_REPLY) { 1001 if (rcvhlim >= 0 && 1002 rcvhlim <= 1) 1003 printf(" !"); 1004 ++got_there; 1005 } 1006 break; 1007 } else if (deltaT(&t1, &t2) > waittime * 1000) { 1008 cc = 0; 1009 break; 1010 } 1011 } 1012 if (cc == 0) 1013 printf(" *"); 1014 (void) fflush(stdout); 1015 } 1016 putchar('\n'); 1017 if (got_there || 1018 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) { 1019 exit(0); 1020 } 1021 } 1022 if (as_path) 1023 as_shutdown(asn); 1024 1025 exit(0); 1026 } 1027 1028 int 1029 wait_for_reply(int sock, struct msghdr *mhdr) 1030 { 1031 #ifdef HAVE_POLL 1032 struct pollfd pfd[1]; 1033 int cc = 0; 1034 1035 pfd[0].fd = sock; 1036 pfd[0].events = POLLIN; 1037 pfd[0].revents = 0; 1038 1039 if (poll(pfd, 1, waittime * 1000) > 0) 1040 cc = recvmsg(rcvsock, mhdr, 0); 1041 1042 return (cc); 1043 #else 1044 fd_set *fdsp; 1045 struct timeval wait; 1046 int cc = 0, fdsn; 1047 1048 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); 1049 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL) 1050 err(1, "malloc"); 1051 memset(fdsp, 0, fdsn); 1052 FD_SET(sock, fdsp); 1053 wait.tv_sec = waittime; wait.tv_usec = 0; 1054 1055 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0) 1056 cc = recvmsg(rcvsock, mhdr, 0); 1057 1058 free(fdsp); 1059 return (cc); 1060 #endif 1061 } 1062 1063 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 1064 int 1065 setpolicy(int so, char *policy) 1066 { 1067 char *buf; 1068 1069 buf = ipsec_set_policy(policy, strlen(policy)); 1070 if (buf == NULL) { 1071 warnx("%s", ipsec_strerror()); 1072 return -1; 1073 } 1074 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY, 1075 buf, ipsec_get_policylen(buf)); 1076 1077 free(buf); 1078 1079 return 0; 1080 } 1081 #endif 1082 1083 void 1084 send_probe(int seq, u_long hops) 1085 { 1086 struct icmp6_hdr *icp; 1087 struct sctphdr *sctp; 1088 struct udphdr *outudp; 1089 struct sctp_chunkhdr *chk; 1090 struct sctp_init_chunk *init; 1091 struct sctp_paramhdr *param; 1092 struct tcphdr *tcp; 1093 int i; 1094 1095 i = hops; 1096 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 1097 (char *)&i, sizeof(i)) < 0) { 1098 perror("setsockopt IPV6_UNICAST_HOPS"); 1099 } 1100 1101 Dst.sin6_port = htons(port + seq); 1102 1103 switch (useproto) { 1104 case IPPROTO_ICMPV6: 1105 icp = (struct icmp6_hdr *)outpacket; 1106 1107 icp->icmp6_type = ICMP6_ECHO_REQUEST; 1108 icp->icmp6_code = 0; 1109 icp->icmp6_cksum = 0; 1110 icp->icmp6_id = ident; 1111 icp->icmp6_seq = htons(seq); 1112 break; 1113 case IPPROTO_UDP: 1114 outudp = (struct udphdr *) outpacket; 1115 outudp->uh_sport = htons(ident); 1116 outudp->uh_dport = htons(port+seq); 1117 outudp->uh_ulen = htons(datalen); 1118 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen); 1119 break; 1120 case IPPROTO_NONE: 1121 /* No space for anything. No harm as seq/tv32 are decorative. */ 1122 break; 1123 case IPPROTO_SCTP: 1124 sctp = (struct sctphdr *)outpacket; 1125 1126 sctp->src_port = htons(ident); 1127 sctp->dest_port = htons(port + seq); 1128 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1129 sizeof(struct sctp_init_chunk))) { 1130 sctp->v_tag = 0; 1131 } else { 1132 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port; 1133 } 1134 sctp->checksum = htonl(0); 1135 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1136 sizeof(struct sctp_init_chunk))) { 1137 /* 1138 * Send a packet containing an INIT chunk. This works 1139 * better in case of firewalls on the path, but 1140 * results in a probe packet containing at least 1141 * 32 bytes of payload. For shorter payloads, use 1142 * SHUTDOWN-ACK chunks. 1143 */ 1144 init = (struct sctp_init_chunk *)(sctp + 1); 1145 init->ch.chunk_type = SCTP_INITIATION; 1146 init->ch.chunk_flags = 0; 1147 init->ch.chunk_length = htons((u_int16_t)(datalen - 1148 sizeof(struct sctphdr))); 1149 init->init.initiate_tag = (sctp->src_port << 16) | 1150 sctp->dest_port; 1151 init->init.a_rwnd = htonl(1500); 1152 init->init.num_outbound_streams = htons(1); 1153 init->init.num_inbound_streams = htons(1); 1154 init->init.initial_tsn = htonl(0); 1155 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1156 sizeof(struct sctp_init_chunk) + 1157 sizeof(struct sctp_paramhdr))) { 1158 param = (struct sctp_paramhdr *)(init + 1); 1159 param->param_type = htons(SCTP_PAD); 1160 param->param_length = 1161 htons((u_int16_t)(datalen - 1162 sizeof(struct sctphdr) - 1163 sizeof(struct sctp_init_chunk))); 1164 } 1165 } else { 1166 /* 1167 * Send a packet containing a SHUTDOWN-ACK chunk, 1168 * possibly followed by a PAD chunk. 1169 */ 1170 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1171 sizeof(struct sctp_chunkhdr))) { 1172 chk = (struct sctp_chunkhdr *)(sctp + 1); 1173 chk->chunk_type = SCTP_SHUTDOWN_ACK; 1174 chk->chunk_flags = 0; 1175 chk->chunk_length = htons(4); 1176 } 1177 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1178 2 * sizeof(struct sctp_chunkhdr))) { 1179 chk = chk + 1; 1180 chk->chunk_type = SCTP_PAD_CHUNK; 1181 chk->chunk_flags = 0; 1182 chk->chunk_length = htons((u_int16_t)(datalen - 1183 sizeof(struct sctphdr) - 1184 sizeof(struct sctp_chunkhdr))); 1185 } 1186 } 1187 sctp->checksum = sctp_crc32c(outpacket, datalen); 1188 break; 1189 case IPPROTO_TCP: 1190 tcp = (struct tcphdr *)outpacket; 1191 1192 tcp->th_sport = htons(ident); 1193 tcp->th_dport = htons(port + seq); 1194 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport; 1195 tcp->th_ack = 0; 1196 tcp->th_off = 5; 1197 tcp->th_flags = TH_SYN; 1198 tcp->th_sum = 0; 1199 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen); 1200 break; 1201 default: 1202 fprintf(stderr, "Unknown probe protocol %d.\n", useproto); 1203 exit(1); 1204 } 1205 1206 i = send(sndsock, (char *)outpacket, datalen, 0); 1207 if (i < 0 || (u_long)i != datalen) { 1208 if (i < 0) 1209 perror("send"); 1210 printf("traceroute6: wrote %s %lu chars, ret=%d\n", 1211 hostname, datalen, i); 1212 (void) fflush(stdout); 1213 } 1214 } 1215 1216 int 1217 get_hoplim(struct msghdr *mhdr) 1218 { 1219 struct cmsghdr *cm; 1220 1221 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1222 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1223 if (cm->cmsg_level == IPPROTO_IPV6 && 1224 cm->cmsg_type == IPV6_HOPLIMIT && 1225 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1226 return (*(int *)CMSG_DATA(cm)); 1227 } 1228 1229 return (-1); 1230 } 1231 1232 double 1233 deltaT(struct timeval *t1p, struct timeval *t2p) 1234 { 1235 double dt; 1236 1237 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + 1238 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; 1239 return (dt); 1240 } 1241 1242 /* 1243 * Convert an ICMP "type" field to a printable string. 1244 */ 1245 const char * 1246 pr_type(int t0) 1247 { 1248 u_char t = t0 & 0xff; 1249 const char *cp; 1250 1251 switch (t) { 1252 case ICMP6_DST_UNREACH: 1253 cp = "Destination Unreachable"; 1254 break; 1255 case ICMP6_PACKET_TOO_BIG: 1256 cp = "Packet Too Big"; 1257 break; 1258 case ICMP6_TIME_EXCEEDED: 1259 cp = "Time Exceeded"; 1260 break; 1261 case ICMP6_PARAM_PROB: 1262 cp = "Parameter Problem"; 1263 break; 1264 case ICMP6_ECHO_REQUEST: 1265 cp = "Echo Request"; 1266 break; 1267 case ICMP6_ECHO_REPLY: 1268 cp = "Echo Reply"; 1269 break; 1270 case ICMP6_MEMBERSHIP_QUERY: 1271 cp = "Group Membership Query"; 1272 break; 1273 case ICMP6_MEMBERSHIP_REPORT: 1274 cp = "Group Membership Report"; 1275 break; 1276 case ICMP6_MEMBERSHIP_REDUCTION: 1277 cp = "Group Membership Reduction"; 1278 break; 1279 case ND_ROUTER_SOLICIT: 1280 cp = "Router Solicitation"; 1281 break; 1282 case ND_ROUTER_ADVERT: 1283 cp = "Router Advertisement"; 1284 break; 1285 case ND_NEIGHBOR_SOLICIT: 1286 cp = "Neighbor Solicitation"; 1287 break; 1288 case ND_NEIGHBOR_ADVERT: 1289 cp = "Neighbor Advertisement"; 1290 break; 1291 case ND_REDIRECT: 1292 cp = "Redirect"; 1293 break; 1294 default: 1295 cp = "Unknown"; 1296 break; 1297 } 1298 return cp; 1299 } 1300 1301 int 1302 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code) 1303 { 1304 struct icmp6_hdr *icp; 1305 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1306 char *buf = (char *)mhdr->msg_iov[0].iov_base; 1307 struct cmsghdr *cm; 1308 int *hlimp; 1309 char hbuf[NI_MAXHOST]; 1310 1311 #ifdef OLDRAWSOCKET 1312 int hlen; 1313 struct ip6_hdr *ip; 1314 #endif 1315 1316 #ifdef OLDRAWSOCKET 1317 ip = (struct ip6_hdr *) buf; 1318 hlen = sizeof(struct ip6_hdr); 1319 if (cc < hlen + sizeof(struct icmp6_hdr)) { 1320 if (verbose) { 1321 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1322 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1323 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1324 printf("packet too short (%d bytes) from %s\n", cc, 1325 hbuf); 1326 } 1327 return (0); 1328 } 1329 cc -= hlen; 1330 icp = (struct icmp6_hdr *)(buf + hlen); 1331 #else 1332 if (cc < (int)sizeof(struct icmp6_hdr)) { 1333 if (verbose) { 1334 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1335 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1336 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1337 printf("data too short (%d bytes) from %s\n", cc, hbuf); 1338 } 1339 return (0); 1340 } 1341 icp = (struct icmp6_hdr *)buf; 1342 #endif 1343 /* get optional information via advanced API */ 1344 rcvpktinfo = NULL; 1345 hlimp = NULL; 1346 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1347 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1348 if (cm->cmsg_level == IPPROTO_IPV6 && 1349 cm->cmsg_type == IPV6_PKTINFO && 1350 cm->cmsg_len == 1351 CMSG_LEN(sizeof(struct in6_pktinfo))) 1352 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm)); 1353 1354 if (cm->cmsg_level == IPPROTO_IPV6 && 1355 cm->cmsg_type == IPV6_HOPLIMIT && 1356 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1357 hlimp = (int *)CMSG_DATA(cm); 1358 } 1359 if (rcvpktinfo == NULL || hlimp == NULL) { 1360 warnx("failed to get received hop limit or packet info"); 1361 #if 0 1362 return (0); 1363 #else 1364 rcvhlim = 0; /*XXX*/ 1365 #endif 1366 } 1367 else 1368 rcvhlim = *hlimp; 1369 1370 *type = icp->icmp6_type; 1371 *code = icp->icmp6_code; 1372 if ((*type == ICMP6_TIME_EXCEEDED && 1373 *code == ICMP6_TIME_EXCEED_TRANSIT) || 1374 (*type == ICMP6_DST_UNREACH) || 1375 (*type == ICMP6_PARAM_PROB && 1376 *code == ICMP6_PARAMPROB_NEXTHEADER)) { 1377 struct ip6_hdr *hip; 1378 struct icmp6_hdr *icmp; 1379 struct sctp_init_chunk *init; 1380 struct sctphdr *sctp; 1381 struct tcphdr *tcp; 1382 struct udphdr *udp; 1383 void *up; 1384 1385 hip = (struct ip6_hdr *)(icp + 1); 1386 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) { 1387 if (verbose) 1388 warnx("failed to get upper layer header"); 1389 return (0); 1390 } 1391 switch (useproto) { 1392 case IPPROTO_ICMPV6: 1393 icmp = (struct icmp6_hdr *)up; 1394 if (icmp->icmp6_id == ident && 1395 icmp->icmp6_seq == htons(seq)) 1396 return (1); 1397 break; 1398 case IPPROTO_UDP: 1399 udp = (struct udphdr *)up; 1400 if (udp->uh_sport == htons(ident) && 1401 udp->uh_dport == htons(port + seq)) 1402 return (1); 1403 break; 1404 case IPPROTO_SCTP: 1405 sctp = (struct sctphdr *)up; 1406 if (sctp->src_port != htons(ident) || 1407 sctp->dest_port != htons(port + seq)) { 1408 break; 1409 } 1410 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1411 sizeof(struct sctp_init_chunk))) { 1412 if (sctp->v_tag != 0) { 1413 break; 1414 } 1415 init = (struct sctp_init_chunk *)(sctp + 1); 1416 /* Check the initiate tag, if available. */ 1417 if ((char *)&init->init.a_rwnd > buf + cc) { 1418 return (1); 1419 } 1420 if (init->init.initiate_tag == (u_int32_t) 1421 ((sctp->src_port << 16) | sctp->dest_port)) { 1422 return (1); 1423 } 1424 } else { 1425 if (sctp->v_tag == 1426 (u_int32_t)((sctp->src_port << 16) | 1427 sctp->dest_port)) { 1428 return (1); 1429 } 1430 } 1431 break; 1432 case IPPROTO_TCP: 1433 tcp = (struct tcphdr *)up; 1434 if (tcp->th_sport == htons(ident) && 1435 tcp->th_dport == htons(port + seq) && 1436 tcp->th_seq == 1437 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport)) 1438 return (1); 1439 break; 1440 case IPPROTO_NONE: 1441 return (1); 1442 default: 1443 fprintf(stderr, "Unknown probe proto %d.\n", useproto); 1444 break; 1445 } 1446 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) { 1447 if (icp->icmp6_id == ident && 1448 icp->icmp6_seq == htons(seq)) 1449 return (1); 1450 } 1451 if (verbose) { 1452 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN]; 1453 u_int8_t *p; 1454 int i; 1455 1456 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1457 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0) 1458 strlcpy(sbuf, "invalid", sizeof(sbuf)); 1459 printf("\n%d bytes from %s to %s", cc, sbuf, 1460 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1461 dbuf, sizeof(dbuf)) : "?"); 1462 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type), 1463 *code); 1464 p = (u_int8_t *)(icp + 1); 1465 #define WIDTH 16 1466 for (i = 0; i < cc; i++) { 1467 if (i % WIDTH == 0) 1468 printf("%04x:", i); 1469 if (i % 4 == 0) 1470 printf(" "); 1471 printf("%02x", p[i]); 1472 if (i % WIDTH == WIDTH - 1) 1473 printf("\n"); 1474 } 1475 if (cc % WIDTH != 0) 1476 printf("\n"); 1477 } 1478 return (0); 1479 } 1480 1481 /* 1482 * Increment pointer until find the UDP or ICMP header. 1483 */ 1484 void * 1485 get_uphdr(struct ip6_hdr *ip6, u_char *lim) 1486 { 1487 u_char *cp = (u_char *)ip6, nh; 1488 int hlen; 1489 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */ 1490 1491 if (cp + sizeof(*ip6) > lim) 1492 return (NULL); 1493 1494 nh = ip6->ip6_nxt; 1495 cp += sizeof(struct ip6_hdr); 1496 1497 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) { 1498 switch (nh) { 1499 case IPPROTO_ESP: 1500 return (NULL); 1501 case IPPROTO_ICMPV6: 1502 return (useproto == nh ? cp : NULL); 1503 case IPPROTO_SCTP: 1504 case IPPROTO_TCP: 1505 case IPPROTO_UDP: 1506 return (useproto == nh ? cp : NULL); 1507 case IPPROTO_NONE: 1508 return (useproto == nh ? none_hdr : NULL); 1509 case IPPROTO_FRAGMENT: 1510 hlen = sizeof(struct ip6_frag); 1511 nh = ((struct ip6_frag *)cp)->ip6f_nxt; 1512 break; 1513 case IPPROTO_AH: 1514 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2; 1515 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1516 break; 1517 default: 1518 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3; 1519 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1520 break; 1521 } 1522 1523 cp += hlen; 1524 } 1525 1526 return (NULL); 1527 } 1528 1529 void 1530 capdns_open(void) 1531 { 1532 #ifdef WITH_CASPER 1533 const char *types[] = { "NAME", "ADDR" }; 1534 int families[1]; 1535 cap_channel_t *casper; 1536 1537 casper = cap_init(); 1538 if (casper == NULL) 1539 errx(1, "unable to create casper process"); 1540 capdns = cap_service_open(casper, "system.dns"); 1541 if (capdns == NULL) 1542 errx(1, "unable to open system.dns service"); 1543 if (cap_dns_type_limit(capdns, types, nitems(types)) < 0) 1544 errx(1, "unable to limit access to system.dns service"); 1545 families[0] = AF_INET6; 1546 if (cap_dns_family_limit(capdns, families, nitems(families)) < 0) 1547 errx(1, "unable to limit access to system.dns service"); 1548 cap_close(casper); 1549 #endif /* WITH_CASPER */ 1550 } 1551 1552 void 1553 print(struct msghdr *mhdr, int cc) 1554 { 1555 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1556 char hbuf[NI_MAXHOST]; 1557 1558 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1559 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1560 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1561 if (as_path) 1562 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6)); 1563 if (nflag) 1564 printf(" %s", hbuf); 1565 else if (lflag) 1566 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf); 1567 else 1568 printf(" %s", inetname((struct sockaddr *)from)); 1569 1570 if (verbose) { 1571 #ifdef OLDRAWSOCKET 1572 printf(" %d bytes to %s", cc, 1573 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1574 hbuf, sizeof(hbuf)) : "?"); 1575 #else 1576 printf(" %d bytes of data to %s", cc, 1577 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1578 hbuf, sizeof(hbuf)) : "?"); 1579 #endif 1580 } 1581 } 1582 1583 /* 1584 * Construct an Internet address representation. 1585 * If the nflag has been supplied, give 1586 * numeric value, otherwise try for symbolic name. 1587 */ 1588 const char * 1589 inetname(struct sockaddr *sa) 1590 { 1591 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1]; 1592 static int first = 1; 1593 char *cp; 1594 1595 if (first && !nflag) { 1596 first = 0; 1597 if (gethostname(domain, sizeof(domain)) == 0 && 1598 (cp = strchr(domain, '.'))) 1599 (void) strlcpy(domain, cp + 1, sizeof(domain)); 1600 else 1601 domain[0] = 0; 1602 } 1603 cp = NULL; 1604 if (!nflag) { 1605 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0, 1606 NI_NAMEREQD) == 0) { 1607 if ((cp = strchr(line, '.')) && 1608 !strcmp(cp + 1, domain)) 1609 *cp = 0; 1610 cp = line; 1611 } 1612 } 1613 if (cp) 1614 return cp; 1615 1616 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0, 1617 NI_NUMERICHOST) != 0) 1618 strlcpy(line, "invalid", sizeof(line)); 1619 return line; 1620 } 1621 1622 /* 1623 * CRC32C routine for the Stream Control Transmission Protocol 1624 */ 1625 1626 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF]) 1627 1628 static u_int32_t crc_c[256] = { 1629 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 1630 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 1631 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 1632 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 1633 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 1634 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, 1635 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 1636 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, 1637 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 1638 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, 1639 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 1640 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, 1641 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 1642 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, 1643 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 1644 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 1645 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 1646 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, 1647 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 1648 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, 1649 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 1650 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, 1651 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 1652 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, 1653 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 1654 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, 1655 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 1656 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, 1657 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 1658 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, 1659 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 1660 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, 1661 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 1662 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, 1663 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 1664 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, 1665 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 1666 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, 1667 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 1668 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, 1669 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 1670 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, 1671 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 1672 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, 1673 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 1674 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 1675 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 1676 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, 1677 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 1678 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, 1679 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 1680 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 1681 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 1682 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, 1683 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 1684 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, 1685 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 1686 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, 1687 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 1688 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, 1689 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 1690 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, 1691 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 1692 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 1693 }; 1694 1695 u_int32_t 1696 sctp_crc32c(void *pack, u_int32_t len) 1697 { 1698 u_int32_t i, crc32c; 1699 u_int8_t byte0, byte1, byte2, byte3; 1700 u_int8_t *buf = (u_int8_t *)pack; 1701 1702 crc32c = ~0; 1703 for (i = 0; i < len; i++) 1704 CRC32C(crc32c, buf[i]); 1705 crc32c = ~crc32c; 1706 byte0 = crc32c & 0xff; 1707 byte1 = (crc32c>>8) & 0xff; 1708 byte2 = (crc32c>>16) & 0xff; 1709 byte3 = (crc32c>>24) & 0xff; 1710 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); 1711 return htonl(crc32c); 1712 } 1713 1714 u_int16_t 1715 in_cksum(u_int16_t *addr, int len) 1716 { 1717 int nleft = len; 1718 u_int16_t *w = addr; 1719 u_int16_t answer; 1720 int sum = 0; 1721 1722 /* 1723 * Our algorithm is simple, using a 32 bit accumulator (sum), 1724 * we add sequential 16 bit words to it, and at the end, fold 1725 * back all the carry bits from the top 16 bits into the lower 1726 * 16 bits. 1727 */ 1728 while (nleft > 1) { 1729 sum += *w++; 1730 nleft -= 2; 1731 } 1732 1733 /* mop up an odd byte, if necessary */ 1734 if (nleft == 1) 1735 sum += *(u_char *)w; 1736 1737 /* 1738 * add back carry outs from top 16 bits to low 16 bits 1739 */ 1740 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 1741 sum += (sum >> 16); /* add carry */ 1742 answer = ~sum; /* truncate to 16 bits */ 1743 return (answer); 1744 } 1745 1746 u_int16_t 1747 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst, 1748 void *payload, u_int32_t len) 1749 { 1750 struct { 1751 struct in6_addr src; 1752 struct in6_addr dst; 1753 u_int32_t len; 1754 u_int8_t zero[3]; 1755 u_int8_t next; 1756 } pseudo_hdr; 1757 u_int16_t sum[2]; 1758 1759 pseudo_hdr.src = src->sin6_addr; 1760 pseudo_hdr.dst = dst->sin6_addr; 1761 pseudo_hdr.len = htonl(len); 1762 pseudo_hdr.zero[0] = 0; 1763 pseudo_hdr.zero[1] = 0; 1764 pseudo_hdr.zero[2] = 0; 1765 pseudo_hdr.next = IPPROTO_UDP; 1766 1767 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr)); 1768 sum[0] = in_cksum(payload, len); 1769 1770 return (~in_cksum(sum, sizeof(sum))); 1771 } 1772 1773 u_int16_t 1774 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst, 1775 void *payload, u_int32_t len) 1776 { 1777 struct { 1778 struct in6_addr src; 1779 struct in6_addr dst; 1780 u_int32_t len; 1781 u_int8_t zero[3]; 1782 u_int8_t next; 1783 } pseudo_hdr; 1784 u_int16_t sum[2]; 1785 1786 pseudo_hdr.src = src->sin6_addr; 1787 pseudo_hdr.dst = dst->sin6_addr; 1788 pseudo_hdr.len = htonl(len); 1789 pseudo_hdr.zero[0] = 0; 1790 pseudo_hdr.zero[1] = 0; 1791 pseudo_hdr.zero[2] = 0; 1792 pseudo_hdr.next = IPPROTO_TCP; 1793 1794 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr)); 1795 sum[0] = in_cksum(payload, len); 1796 1797 return (~in_cksum(sum, sizeof(sum))); 1798 } 1799 1800 void 1801 usage(void) 1802 { 1803 1804 fprintf(stderr, 1805 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n" 1806 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n" 1807 " [datalen]\n"); 1808 exit(1); 1809 } 1810