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 net.inet.ip.ttl hops & can be changed with the -m flag). 76 * Three probes (change with -q flag) are sent at each ttl setting and 77 * a 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), 64 hops max, 40 byte packets 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), 64 hops max, 40 byte packets 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@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 as_path; /* print as numbers for each hop */ 343 static int ecnflag; /* ECN bleaching detection flag */ 344 static char *as_server = NULL; 345 static void *asn; 346 347 int 348 main(int argc, char *argv[]) 349 { 350 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM }; 351 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep; 352 int ch, i, on = 1, seq, rcvcmsglen, error; 353 struct addrinfo hints, *res; 354 static u_char *rcvcmsgbuf; 355 u_long probe, hops, lport, ltclass; 356 struct hostent *hp; 357 size_t size, minlen; 358 uid_t uid; 359 u_char type, code, ecn; 360 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 361 char ipsec_inpolicy[] = "in bypass"; 362 char ipsec_outpolicy[] = "out bypass"; 363 #endif 364 cap_rights_t rights; 365 366 capdns_open(); 367 368 /* 369 * Receive ICMP 370 */ 371 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { 372 perror("socket(ICMPv6)"); 373 exit(5); 374 } 375 376 size = sizeof(i); 377 (void) sysctl(mib, sizeof(mib) / sizeof(mib[0]), &i, &size, NULL, 0); 378 max_hops = i; 379 380 /* specify to tell receiving interface */ 381 #ifdef IPV6_RECVPKTINFO 382 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, 383 sizeof(on)) < 0) 384 err(1, "setsockopt(IPV6_RECVPKTINFO)"); 385 #else /* old adv. API */ 386 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on, 387 sizeof(on)) < 0) 388 err(1, "setsockopt(IPV6_PKTINFO)"); 389 #endif 390 391 /* specify to tell value of hoplimit field of received IP6 hdr */ 392 #ifdef IPV6_RECVHOPLIMIT 393 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, 394 sizeof(on)) < 0) 395 err(1, "setsockopt(IPV6_RECVHOPLIMIT)"); 396 #else /* old adv. API */ 397 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, 398 sizeof(on)) < 0) 399 err(1, "setsockopt(IPV6_HOPLIMIT)"); 400 #endif 401 402 seq = 0; 403 ident = htons(getpid() & 0xffff); /* same as ping6 */ 404 405 while ((ch = getopt(argc, argv, "aA:dEf:g:Ilm:nNp:q:rs:St:TUvw:")) != -1) 406 switch (ch) { 407 case 'a': 408 as_path = 1; 409 break; 410 case 'A': 411 as_path = 1; 412 as_server = optarg; 413 break; 414 case 'd': 415 options |= SO_DEBUG; 416 break; 417 case 'E': 418 ecnflag = 1; 419 break; 420 case 'f': 421 ep = NULL; 422 errno = 0; 423 first_hop = strtoul(optarg, &ep, 0); 424 if (errno || !*optarg || *ep || first_hop > 255) { 425 fprintf(stderr, 426 "traceroute6: invalid min hoplimit.\n"); 427 exit(1); 428 } 429 break; 430 case 'g': 431 /* XXX use after capability mode is entered */ 432 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno); 433 if (hp == NULL) { 434 fprintf(stderr, 435 "traceroute6: unknown host %s\n", optarg); 436 exit(1); 437 } 438 if (rth == NULL) { 439 /* 440 * XXX: We can't detect the number of 441 * intermediate nodes yet. 442 */ 443 if ((rth = inet6_rth_init((void *)rtbuf, 444 sizeof(rtbuf), IPV6_RTHDR_TYPE_0, 445 0)) == NULL) { 446 fprintf(stderr, 447 "inet6_rth_init failed.\n"); 448 exit(1); 449 } 450 } 451 if (inet6_rth_add((void *)rth, 452 (struct in6_addr *)hp->h_addr)) { 453 fprintf(stderr, 454 "inet6_rth_add failed for %s\n", 455 optarg); 456 exit(1); 457 } 458 freehostent(hp); 459 break; 460 case 'I': 461 useproto = IPPROTO_ICMPV6; 462 break; 463 case 'l': 464 break; 465 case 'm': 466 ep = NULL; 467 errno = 0; 468 max_hops = strtoul(optarg, &ep, 0); 469 if (errno || !*optarg || *ep || max_hops > 255) { 470 fprintf(stderr, 471 "traceroute6: invalid max hoplimit.\n"); 472 exit(1); 473 } 474 break; 475 case 'n': 476 nflag++; 477 break; 478 case 'N': 479 useproto = IPPROTO_NONE; 480 break; 481 case 'p': 482 ep = NULL; 483 errno = 0; 484 lport = strtoul(optarg, &ep, 0); 485 if (errno || !*optarg || *ep) { 486 fprintf(stderr, "traceroute6: invalid port.\n"); 487 exit(1); 488 } 489 if (lport == 0 || lport != (lport & 0xffff)) { 490 fprintf(stderr, 491 "traceroute6: port out of range.\n"); 492 exit(1); 493 } 494 port = lport & 0xffff; 495 break; 496 case 'q': 497 ep = NULL; 498 errno = 0; 499 nprobes = strtoul(optarg, &ep, 0); 500 if (errno || !*optarg || *ep) { 501 fprintf(stderr, 502 "traceroute6: invalid nprobes.\n"); 503 exit(1); 504 } 505 if (nprobes < 1) { 506 fprintf(stderr, 507 "traceroute6: nprobes must be >0.\n"); 508 exit(1); 509 } 510 break; 511 case 'r': 512 options |= SO_DONTROUTE; 513 break; 514 case 's': 515 /* 516 * set the ip source address of the outbound 517 * probe (e.g., on a multi-homed host). 518 */ 519 source = optarg; 520 break; 521 case 'S': 522 useproto = IPPROTO_SCTP; 523 break; 524 case 't': 525 ep = NULL; 526 errno = 0; 527 ltclass = strtoul(optarg, &ep, 0); 528 if (errno || !*optarg || *ep || ltclass > 255) { 529 fprintf(stderr, 530 "traceroute6: invalid traffic class.\n"); 531 exit(1); 532 } 533 tclass = (int)ltclass; 534 break; 535 case 'T': 536 useproto = IPPROTO_TCP; 537 break; 538 case 'U': 539 useproto = IPPROTO_UDP; 540 break; 541 case 'v': 542 verbose++; 543 break; 544 case 'w': 545 ep = NULL; 546 errno = 0; 547 waittime = strtoul(optarg, &ep, 0); 548 if (errno || !*optarg || *ep) { 549 fprintf(stderr, 550 "traceroute6: invalid wait time.\n"); 551 exit(1); 552 } 553 if (waittime < 1) { 554 fprintf(stderr, 555 "traceroute6: wait must be >= 1 sec.\n"); 556 exit(1); 557 } 558 break; 559 default: 560 usage(); 561 } 562 argc -= optind; 563 argv += optind; 564 565 /* 566 * Open socket to send probe packets. 567 */ 568 switch (useproto) { 569 case IPPROTO_ICMPV6: 570 case IPPROTO_NONE: 571 case IPPROTO_SCTP: 572 case IPPROTO_TCP: 573 case IPPROTO_UDP: 574 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) { 575 perror("socket(SOCK_RAW)"); 576 exit(5); 577 } 578 break; 579 default: 580 fprintf(stderr, "traceroute6: unknown probe protocol %d\n", 581 useproto); 582 exit(5); 583 } 584 if (max_hops < first_hop) { 585 fprintf(stderr, 586 "traceroute6: max hoplimit must be larger than first hoplimit.\n"); 587 exit(1); 588 } 589 590 if (ecnflag) { 591 if (tclass != -1) { 592 tclass &= ~IPTOS_ECN_MASK; 593 } else { 594 tclass = 0; 595 } 596 tclass |= IPTOS_ECN_ECT1; 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, &ecn)) { 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 (ecnflag) { 973 switch (ecn) { 974 case IPTOS_ECN_ECT1: 975 printf(" (ecn=passed)"); 976 break; 977 case IPTOS_ECN_NOTECT: 978 printf(" (ecn=bleached)"); 979 break; 980 case IPTOS_ECN_CE: 981 printf(" (ecn=congested)"); 982 break; 983 default: 984 printf(" (ecn=mangled)"); 985 break; 986 } 987 } 988 if (type == ICMP6_DST_UNREACH) { 989 switch (code) { 990 case ICMP6_DST_UNREACH_NOROUTE: 991 ++unreachable; 992 printf(" !N"); 993 break; 994 case ICMP6_DST_UNREACH_ADMIN: 995 ++unreachable; 996 printf(" !P"); 997 break; 998 case ICMP6_DST_UNREACH_NOTNEIGHBOR: 999 ++unreachable; 1000 printf(" !S"); 1001 break; 1002 case ICMP6_DST_UNREACH_ADDR: 1003 ++unreachable; 1004 printf(" !A"); 1005 break; 1006 case ICMP6_DST_UNREACH_NOPORT: 1007 if (rcvhlim >= 0 && 1008 rcvhlim <= 1) 1009 printf(" !"); 1010 ++got_there; 1011 break; 1012 default: 1013 ++unreachable; 1014 printf(" !<%d>", code & 0xff); 1015 break; 1016 } 1017 } else if (type == ICMP6_PARAM_PROB && 1018 code == ICMP6_PARAMPROB_NEXTHEADER) { 1019 printf(" !H"); 1020 ++got_there; 1021 } else if (type == ICMP6_ECHO_REPLY) { 1022 if (rcvhlim >= 0 && 1023 rcvhlim <= 1) 1024 printf(" !"); 1025 ++got_there; 1026 } 1027 break; 1028 } else if (deltaT(&t1, &t2) > waittime * 1000) { 1029 cc = 0; 1030 break; 1031 } 1032 } 1033 if (cc == 0) 1034 printf(" *"); 1035 (void) fflush(stdout); 1036 } 1037 putchar('\n'); 1038 if (got_there || 1039 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) { 1040 exit(0); 1041 } 1042 } 1043 if (as_path) 1044 as_shutdown(asn); 1045 1046 exit(0); 1047 } 1048 1049 int 1050 wait_for_reply(int sock, struct msghdr *mhdr) 1051 { 1052 #ifdef HAVE_POLL 1053 struct pollfd pfd[1]; 1054 int cc = 0; 1055 1056 pfd[0].fd = sock; 1057 pfd[0].events = POLLIN; 1058 pfd[0].revents = 0; 1059 1060 if (poll(pfd, 1, waittime * 1000) > 0 && 1061 pfd[0].revents & POLLIN) 1062 cc = recvmsg(rcvsock, mhdr, 0); 1063 1064 return (cc); 1065 #else 1066 fd_set *fdsp; 1067 struct timeval wait; 1068 int cc = 0, fdsn; 1069 1070 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); 1071 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL) 1072 err(1, "malloc"); 1073 memset(fdsp, 0, fdsn); 1074 FD_SET(sock, fdsp); 1075 wait.tv_sec = waittime; wait.tv_usec = 0; 1076 1077 if (select(sock + 1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0) 1078 cc = recvmsg(rcvsock, mhdr, 0); 1079 1080 free(fdsp); 1081 return (cc); 1082 #endif 1083 } 1084 1085 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 1086 int 1087 setpolicy(int so, char *policy) 1088 { 1089 char *buf; 1090 1091 buf = ipsec_set_policy(policy, strlen(policy)); 1092 if (buf == NULL) { 1093 warnx("%s", ipsec_strerror()); 1094 return (-1); 1095 } 1096 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY, 1097 buf, ipsec_get_policylen(buf)); 1098 1099 free(buf); 1100 1101 return (0); 1102 } 1103 #endif 1104 1105 void 1106 send_probe(int seq, u_long hops) 1107 { 1108 struct icmp6_hdr *icp; 1109 struct sctphdr *sctp; 1110 struct udphdr *outudp; 1111 struct sctp_chunkhdr *chk; 1112 struct sctp_init_chunk *init; 1113 struct sctp_paramhdr *param; 1114 struct tcphdr *tcp; 1115 int i; 1116 1117 i = hops; 1118 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 1119 (char *)&i, sizeof(i)) < 0) { 1120 perror("setsockopt IPV6_UNICAST_HOPS"); 1121 } 1122 1123 Dst.sin6_port = htons(port + seq); 1124 1125 switch (useproto) { 1126 case IPPROTO_ICMPV6: 1127 icp = (struct icmp6_hdr *)outpacket; 1128 1129 icp->icmp6_type = ICMP6_ECHO_REQUEST; 1130 icp->icmp6_code = 0; 1131 icp->icmp6_cksum = 0; 1132 icp->icmp6_id = ident; 1133 icp->icmp6_seq = htons(seq); 1134 break; 1135 case IPPROTO_UDP: 1136 outudp = (struct udphdr *) outpacket; 1137 outudp->uh_sport = htons(ident); 1138 outudp->uh_dport = htons(port + seq); 1139 outudp->uh_ulen = htons(datalen); 1140 outudp->uh_sum = 0; 1141 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen); 1142 break; 1143 case IPPROTO_NONE: 1144 /* No space for anything. No harm as seq/tv32 are decorative. */ 1145 break; 1146 case IPPROTO_SCTP: 1147 sctp = (struct sctphdr *)outpacket; 1148 1149 sctp->src_port = htons(ident); 1150 sctp->dest_port = htons(port + seq); 1151 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1152 sizeof(struct sctp_init_chunk))) { 1153 sctp->v_tag = 0; 1154 } else { 1155 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port; 1156 } 1157 sctp->checksum = htonl(0); 1158 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1159 sizeof(struct sctp_init_chunk))) { 1160 /* 1161 * Send a packet containing an INIT chunk. This works 1162 * better in case of firewalls on the path, but 1163 * results in a probe packet containing at least 1164 * 32 bytes of payload. For shorter payloads, use 1165 * SHUTDOWN-ACK chunks. 1166 */ 1167 init = (struct sctp_init_chunk *)(sctp + 1); 1168 init->ch.chunk_type = SCTP_INITIATION; 1169 init->ch.chunk_flags = 0; 1170 init->ch.chunk_length = htons((u_int16_t)(datalen - 1171 sizeof(struct sctphdr))); 1172 init->init.initiate_tag = (sctp->src_port << 16) | 1173 sctp->dest_port; 1174 init->init.a_rwnd = htonl(1500); 1175 init->init.num_outbound_streams = htons(1); 1176 init->init.num_inbound_streams = htons(1); 1177 init->init.initial_tsn = htonl(0); 1178 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1179 sizeof(struct sctp_init_chunk) + 1180 sizeof(struct sctp_paramhdr))) { 1181 param = (struct sctp_paramhdr *)(init + 1); 1182 param->param_type = htons(SCTP_PAD); 1183 param->param_length = 1184 htons((u_int16_t)(datalen - 1185 sizeof(struct sctphdr) - 1186 sizeof(struct sctp_init_chunk))); 1187 } 1188 } else { 1189 /* 1190 * Send a packet containing a SHUTDOWN-ACK chunk, 1191 * possibly followed by a PAD chunk. 1192 */ 1193 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1194 sizeof(struct sctp_chunkhdr))) { 1195 chk = (struct sctp_chunkhdr *)(sctp + 1); 1196 chk->chunk_type = SCTP_SHUTDOWN_ACK; 1197 chk->chunk_flags = 0; 1198 chk->chunk_length = htons(4); 1199 } 1200 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1201 2 * sizeof(struct sctp_chunkhdr))) { 1202 chk = chk + 1; 1203 chk->chunk_type = SCTP_PAD_CHUNK; 1204 chk->chunk_flags = 0; 1205 chk->chunk_length = htons((u_int16_t)(datalen - 1206 sizeof(struct sctphdr) - 1207 sizeof(struct sctp_chunkhdr))); 1208 } 1209 } 1210 sctp->checksum = sctp_crc32c(outpacket, datalen); 1211 break; 1212 case IPPROTO_TCP: 1213 tcp = (struct tcphdr *)outpacket; 1214 1215 tcp->th_sport = htons(ident); 1216 tcp->th_dport = htons(port + seq); 1217 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport; 1218 tcp->th_ack = 0; 1219 tcp->th_off = 5; 1220 __tcp_set_flags(tcp, TH_SYN); 1221 tcp->th_sum = 0; 1222 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen); 1223 break; 1224 default: 1225 fprintf(stderr, "Unknown probe protocol %d.\n", useproto); 1226 exit(1); 1227 } 1228 1229 i = send(sndsock, (char *)outpacket, datalen, 0); 1230 if (i < 0 || (u_long)i != datalen) { 1231 if (i < 0) 1232 perror("send"); 1233 printf("traceroute6: wrote %s %lu chars, ret=%d\n", 1234 hostname, datalen, i); 1235 (void) fflush(stdout); 1236 } 1237 } 1238 1239 int 1240 get_hoplim(struct msghdr *mhdr) 1241 { 1242 struct cmsghdr *cm; 1243 1244 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1245 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1246 if (cm->cmsg_level == IPPROTO_IPV6 && 1247 cm->cmsg_type == IPV6_HOPLIMIT && 1248 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1249 return (*(int *)CMSG_DATA(cm)); 1250 } 1251 1252 return (-1); 1253 } 1254 1255 double 1256 deltaT(struct timeval *t1p, struct timeval *t2p) 1257 { 1258 double dt; 1259 1260 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + 1261 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; 1262 return (dt); 1263 } 1264 1265 /* 1266 * Convert an ICMP "type" field to a printable string. 1267 */ 1268 const char * 1269 pr_type(int t0) 1270 { 1271 u_char t = t0 & 0xff; 1272 const char *cp; 1273 1274 switch (t) { 1275 case ICMP6_DST_UNREACH: 1276 cp = "Destination Unreachable"; 1277 break; 1278 case ICMP6_PACKET_TOO_BIG: 1279 cp = "Packet Too Big"; 1280 break; 1281 case ICMP6_TIME_EXCEEDED: 1282 cp = "Time Exceeded"; 1283 break; 1284 case ICMP6_PARAM_PROB: 1285 cp = "Parameter Problem"; 1286 break; 1287 case ICMP6_ECHO_REQUEST: 1288 cp = "Echo Request"; 1289 break; 1290 case ICMP6_ECHO_REPLY: 1291 cp = "Echo Reply"; 1292 break; 1293 case ICMP6_MEMBERSHIP_QUERY: 1294 cp = "Group Membership Query"; 1295 break; 1296 case ICMP6_MEMBERSHIP_REPORT: 1297 cp = "Group Membership Report"; 1298 break; 1299 case ICMP6_MEMBERSHIP_REDUCTION: 1300 cp = "Group Membership Reduction"; 1301 break; 1302 case ND_ROUTER_SOLICIT: 1303 cp = "Router Solicitation"; 1304 break; 1305 case ND_ROUTER_ADVERT: 1306 cp = "Router Advertisement"; 1307 break; 1308 case ND_NEIGHBOR_SOLICIT: 1309 cp = "Neighbor Solicitation"; 1310 break; 1311 case ND_NEIGHBOR_ADVERT: 1312 cp = "Neighbor Advertisement"; 1313 break; 1314 case ND_REDIRECT: 1315 cp = "Redirect"; 1316 break; 1317 default: 1318 cp = "Unknown"; 1319 break; 1320 } 1321 return (cp); 1322 } 1323 1324 int 1325 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code, 1326 u_char *ecn) 1327 { 1328 struct icmp6_hdr *icp; 1329 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1330 char *buf = (char *)mhdr->msg_iov[0].iov_base; 1331 struct cmsghdr *cm; 1332 int *hlimp; 1333 char hbuf[NI_MAXHOST]; 1334 1335 #ifdef OLDRAWSOCKET 1336 int hlen; 1337 struct ip6_hdr *ip; 1338 #endif 1339 1340 #ifdef OLDRAWSOCKET 1341 ip = (struct ip6_hdr *) buf; 1342 hlen = sizeof(struct ip6_hdr); 1343 if (cc < hlen + sizeof(struct icmp6_hdr)) { 1344 if (verbose) { 1345 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1346 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1347 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1348 printf("packet too short (%d bytes) from %s\n", cc, 1349 hbuf); 1350 } 1351 return (0); 1352 } 1353 cc -= hlen; 1354 icp = (struct icmp6_hdr *)(buf + hlen); 1355 #else 1356 if (cc < (int)sizeof(struct icmp6_hdr)) { 1357 if (verbose) { 1358 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1359 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1360 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1361 printf("data too short (%d bytes) from %s\n", cc, hbuf); 1362 } 1363 return (0); 1364 } 1365 icp = (struct icmp6_hdr *)buf; 1366 #endif 1367 /* get optional information via advanced API */ 1368 rcvpktinfo = NULL; 1369 hlimp = NULL; 1370 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1371 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1372 if (cm->cmsg_level == IPPROTO_IPV6 && 1373 cm->cmsg_type == IPV6_PKTINFO && 1374 cm->cmsg_len == 1375 CMSG_LEN(sizeof(struct in6_pktinfo))) 1376 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm)); 1377 1378 if (cm->cmsg_level == IPPROTO_IPV6 && 1379 cm->cmsg_type == IPV6_HOPLIMIT && 1380 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1381 hlimp = (int *)CMSG_DATA(cm); 1382 } 1383 if (rcvpktinfo == NULL || hlimp == NULL) { 1384 warnx("failed to get received hop limit or packet info"); 1385 #if 0 1386 return (0); 1387 #else 1388 rcvhlim = 0; /*XXX*/ 1389 #endif 1390 } else 1391 rcvhlim = *hlimp; 1392 1393 *type = icp->icmp6_type; 1394 *code = icp->icmp6_code; 1395 if ((*type == ICMP6_TIME_EXCEEDED && 1396 *code == ICMP6_TIME_EXCEED_TRANSIT) || 1397 (*type == ICMP6_DST_UNREACH) || 1398 (*type == ICMP6_PARAM_PROB && 1399 *code == ICMP6_PARAMPROB_NEXTHEADER)) { 1400 struct ip6_hdr *hip; 1401 struct icmp6_hdr *icmp; 1402 struct sctp_init_chunk *init; 1403 struct sctphdr *sctp; 1404 struct tcphdr *tcp; 1405 struct udphdr *udp; 1406 void *up; 1407 1408 hip = (struct ip6_hdr *)(icp + 1); 1409 *ecn = ntohl(hip->ip6_flow & IPV6_ECN_MASK) >> 20; 1410 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) { 1411 if (verbose) 1412 warnx("failed to get upper layer header"); 1413 return (0); 1414 } 1415 switch (useproto) { 1416 case IPPROTO_ICMPV6: 1417 icmp = (struct icmp6_hdr *)up; 1418 if (icmp->icmp6_id == ident && 1419 icmp->icmp6_seq == htons(seq)) 1420 return (1); 1421 break; 1422 case IPPROTO_UDP: 1423 udp = (struct udphdr *)up; 1424 if (udp->uh_sport == htons(ident) && 1425 udp->uh_dport == htons(port + seq)) 1426 return (1); 1427 break; 1428 case IPPROTO_SCTP: 1429 sctp = (struct sctphdr *)up; 1430 if (sctp->src_port != htons(ident) || 1431 sctp->dest_port != htons(port + seq)) { 1432 break; 1433 } 1434 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1435 sizeof(struct sctp_init_chunk))) { 1436 if (sctp->v_tag != 0) { 1437 break; 1438 } 1439 init = (struct sctp_init_chunk *)(sctp + 1); 1440 /* Check the initiate tag, if available. */ 1441 if ((char *)&init->init.a_rwnd > buf + cc) { 1442 return (1); 1443 } 1444 if (init->init.initiate_tag == (u_int32_t) 1445 ((sctp->src_port << 16) | sctp->dest_port)) { 1446 return (1); 1447 } 1448 } else { 1449 if (sctp->v_tag == 1450 (u_int32_t)((sctp->src_port << 16) | 1451 sctp->dest_port)) { 1452 return (1); 1453 } 1454 } 1455 break; 1456 case IPPROTO_TCP: 1457 tcp = (struct tcphdr *)up; 1458 if (tcp->th_sport == htons(ident) && 1459 tcp->th_dport == htons(port + seq) && 1460 tcp->th_seq == 1461 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport)) 1462 return (1); 1463 break; 1464 case IPPROTO_NONE: 1465 return (1); 1466 default: 1467 fprintf(stderr, "Unknown probe proto %d.\n", useproto); 1468 break; 1469 } 1470 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) { 1471 if (icp->icmp6_id == ident && 1472 icp->icmp6_seq == htons(seq)) 1473 return (1); 1474 } 1475 if (verbose) { 1476 char sbuf[NI_MAXHOST + 1], dbuf[INET6_ADDRSTRLEN]; 1477 u_int8_t *p; 1478 int i; 1479 1480 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1481 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0) 1482 strlcpy(sbuf, "invalid", sizeof(sbuf)); 1483 printf("\n%d bytes from %s to %s", cc, sbuf, 1484 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1485 dbuf, sizeof(dbuf)) : "?"); 1486 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type), 1487 *code); 1488 p = (u_int8_t *)(icp + 1); 1489 #define WIDTH 16 1490 for (i = 0; i < cc; i++) { 1491 if (i % WIDTH == 0) 1492 printf("%04x:", i); 1493 if (i % 4 == 0) 1494 printf(" "); 1495 printf("%02x", p[i]); 1496 if (i % WIDTH == WIDTH - 1) 1497 printf("\n"); 1498 } 1499 if (cc % WIDTH != 0) 1500 printf("\n"); 1501 } 1502 return (0); 1503 } 1504 1505 /* 1506 * Increment pointer until find the UDP or ICMP header. 1507 */ 1508 void * 1509 get_uphdr(struct ip6_hdr *ip6, u_char *lim) 1510 { 1511 u_char *cp = (u_char *)ip6, nh; 1512 int hlen; 1513 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */ 1514 1515 if (cp + sizeof(*ip6) > lim) 1516 return (NULL); 1517 1518 nh = ip6->ip6_nxt; 1519 cp += sizeof(struct ip6_hdr); 1520 1521 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) { 1522 switch (nh) { 1523 case IPPROTO_ESP: 1524 return (NULL); 1525 case IPPROTO_ICMPV6: 1526 return (useproto == nh ? cp : NULL); 1527 case IPPROTO_SCTP: 1528 case IPPROTO_TCP: 1529 case IPPROTO_UDP: 1530 return (useproto == nh ? cp : NULL); 1531 case IPPROTO_NONE: 1532 return (useproto == nh ? none_hdr : NULL); 1533 case IPPROTO_FRAGMENT: 1534 hlen = sizeof(struct ip6_frag); 1535 nh = ((struct ip6_frag *)cp)->ip6f_nxt; 1536 break; 1537 case IPPROTO_AH: 1538 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2; 1539 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1540 break; 1541 default: 1542 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3; 1543 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1544 break; 1545 } 1546 1547 cp += hlen; 1548 } 1549 1550 return (NULL); 1551 } 1552 1553 void 1554 capdns_open(void) 1555 { 1556 #ifdef WITH_CASPER 1557 const char *types[] = { "NAME", "ADDR" }; 1558 int families[1]; 1559 cap_channel_t *casper; 1560 1561 casper = cap_init(); 1562 if (casper == NULL) 1563 errx(1, "unable to create casper process"); 1564 capdns = cap_service_open(casper, "system.dns"); 1565 if (capdns == NULL) 1566 errx(1, "unable to open system.dns service"); 1567 if (cap_dns_type_limit(capdns, types, nitems(types)) < 0) 1568 errx(1, "unable to limit access to system.dns service"); 1569 families[0] = AF_INET6; 1570 if (cap_dns_family_limit(capdns, families, nitems(families)) < 0) 1571 errx(1, "unable to limit access to system.dns service"); 1572 cap_close(casper); 1573 #endif /* WITH_CASPER */ 1574 } 1575 1576 void 1577 print(struct msghdr *mhdr, int cc) 1578 { 1579 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1580 char hbuf[NI_MAXHOST]; 1581 1582 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1583 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1584 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1585 if (as_path) 1586 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6)); 1587 if (nflag) 1588 printf(" %s", hbuf); 1589 else 1590 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf); 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 fprintf(stderr, 1826 "Usage: traceroute6 [-adEIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n" 1827 "\t[-m hoplimit] [-p port] [-q probes] [-s src] [-t tclass]\n" 1828 "\t[-w waittime] target [datalen]\n"); 1829 exit(1); 1830 } 1831