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