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