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 } 1013 } else if (type == ICMP6_PARAM_PROB && 1014 code == ICMP6_PARAMPROB_NEXTHEADER) { 1015 printf(" !H"); 1016 ++got_there; 1017 } else if (type == ICMP6_ECHO_REPLY) { 1018 if (rcvhlim >= 0 && 1019 rcvhlim <= 1) 1020 printf(" !"); 1021 ++got_there; 1022 } 1023 break; 1024 } else if (deltaT(&t1, &t2) > waittime * 1000) { 1025 cc = 0; 1026 break; 1027 } 1028 } 1029 if (cc == 0) 1030 printf(" *"); 1031 (void) fflush(stdout); 1032 } 1033 putchar('\n'); 1034 if (got_there || 1035 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) { 1036 exit(0); 1037 } 1038 } 1039 if (as_path) 1040 as_shutdown(asn); 1041 1042 exit(0); 1043 } 1044 1045 int 1046 wait_for_reply(int sock, struct msghdr *mhdr) 1047 { 1048 #ifdef HAVE_POLL 1049 struct pollfd pfd[1]; 1050 int cc = 0; 1051 1052 pfd[0].fd = sock; 1053 pfd[0].events = POLLIN; 1054 pfd[0].revents = 0; 1055 1056 if (poll(pfd, 1, waittime * 1000) > 0 && 1057 pfd[0].revents & POLLIN) 1058 cc = recvmsg(rcvsock, mhdr, 0); 1059 1060 return (cc); 1061 #else 1062 fd_set *fdsp; 1063 struct timeval wait; 1064 int cc = 0, fdsn; 1065 1066 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask); 1067 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL) 1068 err(1, "malloc"); 1069 memset(fdsp, 0, fdsn); 1070 FD_SET(sock, fdsp); 1071 wait.tv_sec = waittime; wait.tv_usec = 0; 1072 1073 if (select(sock + 1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0) 1074 cc = recvmsg(rcvsock, mhdr, 0); 1075 1076 free(fdsp); 1077 return (cc); 1078 #endif 1079 } 1080 1081 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 1082 int 1083 setpolicy(int so, char *policy) 1084 { 1085 char *buf; 1086 1087 buf = ipsec_set_policy(policy, strlen(policy)); 1088 if (buf == NULL) { 1089 warnx("%s", ipsec_strerror()); 1090 return (-1); 1091 } 1092 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY, 1093 buf, ipsec_get_policylen(buf)); 1094 1095 free(buf); 1096 1097 return (0); 1098 } 1099 #endif 1100 1101 void 1102 send_probe(int seq, u_long hops) 1103 { 1104 struct icmp6_hdr *icp; 1105 struct sctphdr *sctp; 1106 struct udphdr *outudp; 1107 struct sctp_chunkhdr *chk; 1108 struct sctp_init_chunk *init; 1109 struct sctp_paramhdr *param; 1110 struct tcphdr *tcp; 1111 int i; 1112 1113 i = hops; 1114 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 1115 (char *)&i, sizeof(i)) < 0) { 1116 perror("setsockopt IPV6_UNICAST_HOPS"); 1117 } 1118 1119 Dst.sin6_port = htons(port + seq); 1120 1121 switch (useproto) { 1122 case IPPROTO_ICMPV6: 1123 icp = (struct icmp6_hdr *)outpacket; 1124 1125 icp->icmp6_type = ICMP6_ECHO_REQUEST; 1126 icp->icmp6_code = 0; 1127 icp->icmp6_cksum = 0; 1128 icp->icmp6_id = ident; 1129 icp->icmp6_seq = htons(seq); 1130 break; 1131 case IPPROTO_UDP: 1132 outudp = (struct udphdr *) outpacket; 1133 outudp->uh_sport = htons(ident); 1134 outudp->uh_dport = htons(port + seq); 1135 outudp->uh_ulen = htons(datalen); 1136 outudp->uh_sum = 0; 1137 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen); 1138 break; 1139 case IPPROTO_NONE: 1140 /* No space for anything. No harm as seq/tv32 are decorative. */ 1141 break; 1142 case IPPROTO_SCTP: 1143 sctp = (struct sctphdr *)outpacket; 1144 1145 sctp->src_port = htons(ident); 1146 sctp->dest_port = htons(port + seq); 1147 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1148 sizeof(struct sctp_init_chunk))) { 1149 sctp->v_tag = 0; 1150 } else { 1151 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port; 1152 } 1153 sctp->checksum = htonl(0); 1154 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1155 sizeof(struct sctp_init_chunk))) { 1156 /* 1157 * Send a packet containing an INIT chunk. This works 1158 * better in case of firewalls on the path, but 1159 * results in a probe packet containing at least 1160 * 32 bytes of payload. For shorter payloads, use 1161 * SHUTDOWN-ACK chunks. 1162 */ 1163 init = (struct sctp_init_chunk *)(sctp + 1); 1164 init->ch.chunk_type = SCTP_INITIATION; 1165 init->ch.chunk_flags = 0; 1166 init->ch.chunk_length = htons((u_int16_t)(datalen - 1167 sizeof(struct sctphdr))); 1168 init->init.initiate_tag = (sctp->src_port << 16) | 1169 sctp->dest_port; 1170 init->init.a_rwnd = htonl(1500); 1171 init->init.num_outbound_streams = htons(1); 1172 init->init.num_inbound_streams = htons(1); 1173 init->init.initial_tsn = htonl(0); 1174 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1175 sizeof(struct sctp_init_chunk) + 1176 sizeof(struct sctp_paramhdr))) { 1177 param = (struct sctp_paramhdr *)(init + 1); 1178 param->param_type = htons(SCTP_PAD); 1179 param->param_length = 1180 htons((u_int16_t)(datalen - 1181 sizeof(struct sctphdr) - 1182 sizeof(struct sctp_init_chunk))); 1183 } 1184 } else { 1185 /* 1186 * Send a packet containing a SHUTDOWN-ACK chunk, 1187 * possibly followed by a PAD chunk. 1188 */ 1189 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1190 sizeof(struct sctp_chunkhdr))) { 1191 chk = (struct sctp_chunkhdr *)(sctp + 1); 1192 chk->chunk_type = SCTP_SHUTDOWN_ACK; 1193 chk->chunk_flags = 0; 1194 chk->chunk_length = htons(4); 1195 } 1196 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1197 2 * sizeof(struct sctp_chunkhdr))) { 1198 chk = chk + 1; 1199 chk->chunk_type = SCTP_PAD_CHUNK; 1200 chk->chunk_flags = 0; 1201 chk->chunk_length = htons((u_int16_t)(datalen - 1202 sizeof(struct sctphdr) - 1203 sizeof(struct sctp_chunkhdr))); 1204 } 1205 } 1206 sctp->checksum = sctp_crc32c(outpacket, datalen); 1207 break; 1208 case IPPROTO_TCP: 1209 tcp = (struct tcphdr *)outpacket; 1210 1211 tcp->th_sport = htons(ident); 1212 tcp->th_dport = htons(port + seq); 1213 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport; 1214 tcp->th_ack = 0; 1215 tcp->th_off = 5; 1216 tcp->th_flags = TH_SYN; 1217 tcp->th_sum = 0; 1218 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen); 1219 break; 1220 default: 1221 fprintf(stderr, "Unknown probe protocol %d.\n", useproto); 1222 exit(1); 1223 } 1224 1225 i = send(sndsock, (char *)outpacket, datalen, 0); 1226 if (i < 0 || (u_long)i != datalen) { 1227 if (i < 0) 1228 perror("send"); 1229 printf("traceroute6: wrote %s %lu chars, ret=%d\n", 1230 hostname, datalen, i); 1231 (void) fflush(stdout); 1232 } 1233 } 1234 1235 int 1236 get_hoplim(struct msghdr *mhdr) 1237 { 1238 struct cmsghdr *cm; 1239 1240 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1241 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1242 if (cm->cmsg_level == IPPROTO_IPV6 && 1243 cm->cmsg_type == IPV6_HOPLIMIT && 1244 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1245 return (*(int *)CMSG_DATA(cm)); 1246 } 1247 1248 return (-1); 1249 } 1250 1251 double 1252 deltaT(struct timeval *t1p, struct timeval *t2p) 1253 { 1254 double dt; 1255 1256 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + 1257 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; 1258 return (dt); 1259 } 1260 1261 /* 1262 * Convert an ICMP "type" field to a printable string. 1263 */ 1264 const char * 1265 pr_type(int t0) 1266 { 1267 u_char t = t0 & 0xff; 1268 const char *cp; 1269 1270 switch (t) { 1271 case ICMP6_DST_UNREACH: 1272 cp = "Destination Unreachable"; 1273 break; 1274 case ICMP6_PACKET_TOO_BIG: 1275 cp = "Packet Too Big"; 1276 break; 1277 case ICMP6_TIME_EXCEEDED: 1278 cp = "Time Exceeded"; 1279 break; 1280 case ICMP6_PARAM_PROB: 1281 cp = "Parameter Problem"; 1282 break; 1283 case ICMP6_ECHO_REQUEST: 1284 cp = "Echo Request"; 1285 break; 1286 case ICMP6_ECHO_REPLY: 1287 cp = "Echo Reply"; 1288 break; 1289 case ICMP6_MEMBERSHIP_QUERY: 1290 cp = "Group Membership Query"; 1291 break; 1292 case ICMP6_MEMBERSHIP_REPORT: 1293 cp = "Group Membership Report"; 1294 break; 1295 case ICMP6_MEMBERSHIP_REDUCTION: 1296 cp = "Group Membership Reduction"; 1297 break; 1298 case ND_ROUTER_SOLICIT: 1299 cp = "Router Solicitation"; 1300 break; 1301 case ND_ROUTER_ADVERT: 1302 cp = "Router Advertisement"; 1303 break; 1304 case ND_NEIGHBOR_SOLICIT: 1305 cp = "Neighbor Solicitation"; 1306 break; 1307 case ND_NEIGHBOR_ADVERT: 1308 cp = "Neighbor Advertisement"; 1309 break; 1310 case ND_REDIRECT: 1311 cp = "Redirect"; 1312 break; 1313 default: 1314 cp = "Unknown"; 1315 break; 1316 } 1317 return (cp); 1318 } 1319 1320 int 1321 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code, 1322 u_char *ecn) 1323 { 1324 struct icmp6_hdr *icp; 1325 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1326 char *buf = (char *)mhdr->msg_iov[0].iov_base; 1327 struct cmsghdr *cm; 1328 int *hlimp; 1329 char hbuf[NI_MAXHOST]; 1330 1331 #ifdef OLDRAWSOCKET 1332 int hlen; 1333 struct ip6_hdr *ip; 1334 #endif 1335 1336 #ifdef OLDRAWSOCKET 1337 ip = (struct ip6_hdr *) buf; 1338 hlen = sizeof(struct ip6_hdr); 1339 if (cc < hlen + sizeof(struct icmp6_hdr)) { 1340 if (verbose) { 1341 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1342 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1343 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1344 printf("packet too short (%d bytes) from %s\n", cc, 1345 hbuf); 1346 } 1347 return (0); 1348 } 1349 cc -= hlen; 1350 icp = (struct icmp6_hdr *)(buf + hlen); 1351 #else 1352 if (cc < (int)sizeof(struct icmp6_hdr)) { 1353 if (verbose) { 1354 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1355 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1356 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1357 printf("data too short (%d bytes) from %s\n", cc, hbuf); 1358 } 1359 return (0); 1360 } 1361 icp = (struct icmp6_hdr *)buf; 1362 #endif 1363 /* get optional information via advanced API */ 1364 rcvpktinfo = NULL; 1365 hlimp = NULL; 1366 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1367 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1368 if (cm->cmsg_level == IPPROTO_IPV6 && 1369 cm->cmsg_type == IPV6_PKTINFO && 1370 cm->cmsg_len == 1371 CMSG_LEN(sizeof(struct in6_pktinfo))) 1372 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm)); 1373 1374 if (cm->cmsg_level == IPPROTO_IPV6 && 1375 cm->cmsg_type == IPV6_HOPLIMIT && 1376 cm->cmsg_len == CMSG_LEN(sizeof(int))) 1377 hlimp = (int *)CMSG_DATA(cm); 1378 } 1379 if (rcvpktinfo == NULL || hlimp == NULL) { 1380 warnx("failed to get received hop limit or packet info"); 1381 #if 0 1382 return (0); 1383 #else 1384 rcvhlim = 0; /*XXX*/ 1385 #endif 1386 } else 1387 rcvhlim = *hlimp; 1388 1389 *type = icp->icmp6_type; 1390 *code = icp->icmp6_code; 1391 if ((*type == ICMP6_TIME_EXCEEDED && 1392 *code == ICMP6_TIME_EXCEED_TRANSIT) || 1393 (*type == ICMP6_DST_UNREACH) || 1394 (*type == ICMP6_PARAM_PROB && 1395 *code == ICMP6_PARAMPROB_NEXTHEADER)) { 1396 struct ip6_hdr *hip; 1397 struct icmp6_hdr *icmp; 1398 struct sctp_init_chunk *init; 1399 struct sctphdr *sctp; 1400 struct tcphdr *tcp; 1401 struct udphdr *udp; 1402 void *up; 1403 1404 hip = (struct ip6_hdr *)(icp + 1); 1405 *ecn = ntohl(hip->ip6_flow & IPV6_ECN_MASK) >> 20; 1406 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) { 1407 if (verbose) 1408 warnx("failed to get upper layer header"); 1409 return (0); 1410 } 1411 switch (useproto) { 1412 case IPPROTO_ICMPV6: 1413 icmp = (struct icmp6_hdr *)up; 1414 if (icmp->icmp6_id == ident && 1415 icmp->icmp6_seq == htons(seq)) 1416 return (1); 1417 break; 1418 case IPPROTO_UDP: 1419 udp = (struct udphdr *)up; 1420 if (udp->uh_sport == htons(ident) && 1421 udp->uh_dport == htons(port + seq)) 1422 return (1); 1423 break; 1424 case IPPROTO_SCTP: 1425 sctp = (struct sctphdr *)up; 1426 if (sctp->src_port != htons(ident) || 1427 sctp->dest_port != htons(port + seq)) { 1428 break; 1429 } 1430 if (datalen >= (u_long)(sizeof(struct sctphdr) + 1431 sizeof(struct sctp_init_chunk))) { 1432 if (sctp->v_tag != 0) { 1433 break; 1434 } 1435 init = (struct sctp_init_chunk *)(sctp + 1); 1436 /* Check the initiate tag, if available. */ 1437 if ((char *)&init->init.a_rwnd > buf + cc) { 1438 return (1); 1439 } 1440 if (init->init.initiate_tag == (u_int32_t) 1441 ((sctp->src_port << 16) | sctp->dest_port)) { 1442 return (1); 1443 } 1444 } else { 1445 if (sctp->v_tag == 1446 (u_int32_t)((sctp->src_port << 16) | 1447 sctp->dest_port)) { 1448 return (1); 1449 } 1450 } 1451 break; 1452 case IPPROTO_TCP: 1453 tcp = (struct tcphdr *)up; 1454 if (tcp->th_sport == htons(ident) && 1455 tcp->th_dport == htons(port + seq) && 1456 tcp->th_seq == 1457 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport)) 1458 return (1); 1459 break; 1460 case IPPROTO_NONE: 1461 return (1); 1462 default: 1463 fprintf(stderr, "Unknown probe proto %d.\n", useproto); 1464 break; 1465 } 1466 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) { 1467 if (icp->icmp6_id == ident && 1468 icp->icmp6_seq == htons(seq)) 1469 return (1); 1470 } 1471 if (verbose) { 1472 char sbuf[NI_MAXHOST + 1], dbuf[INET6_ADDRSTRLEN]; 1473 u_int8_t *p; 1474 int i; 1475 1476 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1477 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0) 1478 strlcpy(sbuf, "invalid", sizeof(sbuf)); 1479 printf("\n%d bytes from %s to %s", cc, sbuf, 1480 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1481 dbuf, sizeof(dbuf)) : "?"); 1482 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type), 1483 *code); 1484 p = (u_int8_t *)(icp + 1); 1485 #define WIDTH 16 1486 for (i = 0; i < cc; i++) { 1487 if (i % WIDTH == 0) 1488 printf("%04x:", i); 1489 if (i % 4 == 0) 1490 printf(" "); 1491 printf("%02x", p[i]); 1492 if (i % WIDTH == WIDTH - 1) 1493 printf("\n"); 1494 } 1495 if (cc % WIDTH != 0) 1496 printf("\n"); 1497 } 1498 return (0); 1499 } 1500 1501 /* 1502 * Increment pointer until find the UDP or ICMP header. 1503 */ 1504 void * 1505 get_uphdr(struct ip6_hdr *ip6, u_char *lim) 1506 { 1507 u_char *cp = (u_char *)ip6, nh; 1508 int hlen; 1509 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */ 1510 1511 if (cp + sizeof(*ip6) > lim) 1512 return (NULL); 1513 1514 nh = ip6->ip6_nxt; 1515 cp += sizeof(struct ip6_hdr); 1516 1517 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) { 1518 switch (nh) { 1519 case IPPROTO_ESP: 1520 return (NULL); 1521 case IPPROTO_ICMPV6: 1522 return (useproto == nh ? cp : NULL); 1523 case IPPROTO_SCTP: 1524 case IPPROTO_TCP: 1525 case IPPROTO_UDP: 1526 return (useproto == nh ? cp : NULL); 1527 case IPPROTO_NONE: 1528 return (useproto == nh ? none_hdr : NULL); 1529 case IPPROTO_FRAGMENT: 1530 hlen = sizeof(struct ip6_frag); 1531 nh = ((struct ip6_frag *)cp)->ip6f_nxt; 1532 break; 1533 case IPPROTO_AH: 1534 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2; 1535 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1536 break; 1537 default: 1538 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3; 1539 nh = ((struct ip6_ext *)cp)->ip6e_nxt; 1540 break; 1541 } 1542 1543 cp += hlen; 1544 } 1545 1546 return (NULL); 1547 } 1548 1549 void 1550 capdns_open(void) 1551 { 1552 #ifdef WITH_CASPER 1553 const char *types[] = { "NAME", "ADDR" }; 1554 int families[1]; 1555 cap_channel_t *casper; 1556 1557 casper = cap_init(); 1558 if (casper == NULL) 1559 errx(1, "unable to create casper process"); 1560 capdns = cap_service_open(casper, "system.dns"); 1561 if (capdns == NULL) 1562 errx(1, "unable to open system.dns service"); 1563 if (cap_dns_type_limit(capdns, types, nitems(types)) < 0) 1564 errx(1, "unable to limit access to system.dns service"); 1565 families[0] = AF_INET6; 1566 if (cap_dns_family_limit(capdns, families, nitems(families)) < 0) 1567 errx(1, "unable to limit access to system.dns service"); 1568 cap_close(casper); 1569 #endif /* WITH_CASPER */ 1570 } 1571 1572 void 1573 print(struct msghdr *mhdr, int cc) 1574 { 1575 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; 1576 char hbuf[NI_MAXHOST]; 1577 1578 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len, 1579 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) 1580 strlcpy(hbuf, "invalid", sizeof(hbuf)); 1581 if (as_path) 1582 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6)); 1583 if (nflag) 1584 printf(" %s", hbuf); 1585 else 1586 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf); 1587 1588 if (verbose) { 1589 #ifdef OLDRAWSOCKET 1590 printf(" %d bytes to %s", cc, 1591 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1592 hbuf, sizeof(hbuf)) : "?"); 1593 #else 1594 printf(" %d bytes of data to %s", cc, 1595 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, 1596 hbuf, sizeof(hbuf)) : "?"); 1597 #endif 1598 } 1599 } 1600 1601 /* 1602 * Construct an Internet address representation. 1603 * If the nflag has been supplied, give 1604 * numeric value, otherwise try for symbolic name. 1605 */ 1606 const char * 1607 inetname(struct sockaddr *sa) 1608 { 1609 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1]; 1610 static int first = 1; 1611 char *cp; 1612 1613 if (first && !nflag) { 1614 first = 0; 1615 if (gethostname(domain, sizeof(domain)) == 0 && 1616 (cp = strchr(domain, '.'))) 1617 (void) strlcpy(domain, cp + 1, sizeof(domain)); 1618 else 1619 domain[0] = 0; 1620 } 1621 cp = NULL; 1622 if (!nflag) { 1623 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0, 1624 NI_NAMEREQD) == 0) { 1625 if ((cp = strchr(line, '.')) && 1626 !strcmp(cp + 1, domain)) 1627 *cp = 0; 1628 cp = line; 1629 } 1630 } 1631 if (cp) 1632 return (cp); 1633 1634 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0, 1635 NI_NUMERICHOST) != 0) 1636 strlcpy(line, "invalid", sizeof(line)); 1637 return (line); 1638 } 1639 1640 /* 1641 * CRC32C routine for the Stream Control Transmission Protocol 1642 */ 1643 1644 #define CRC32C(c, d) (c = (c >> 8) ^ crc_c[(c ^ (d)) & 0xFF]) 1645 1646 static u_int32_t crc_c[256] = { 1647 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 1648 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 1649 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 1650 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 1651 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 1652 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, 1653 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 1654 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, 1655 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 1656 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, 1657 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 1658 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, 1659 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 1660 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, 1661 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 1662 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 1663 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 1664 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, 1665 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 1666 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, 1667 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 1668 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, 1669 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 1670 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, 1671 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 1672 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, 1673 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 1674 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, 1675 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 1676 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, 1677 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 1678 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, 1679 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 1680 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, 1681 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 1682 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, 1683 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 1684 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, 1685 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 1686 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, 1687 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 1688 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, 1689 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 1690 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, 1691 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 1692 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 1693 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 1694 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, 1695 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 1696 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, 1697 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 1698 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 1699 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 1700 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, 1701 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 1702 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, 1703 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 1704 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, 1705 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 1706 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, 1707 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 1708 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, 1709 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 1710 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 1711 }; 1712 1713 u_int32_t 1714 sctp_crc32c(void *pack, u_int32_t len) 1715 { 1716 u_int32_t i, crc32c; 1717 u_int8_t byte0, byte1, byte2, byte3; 1718 u_int8_t *buf = (u_int8_t *)pack; 1719 1720 crc32c = ~0; 1721 for (i = 0; i < len; i++) 1722 CRC32C(crc32c, buf[i]); 1723 crc32c = ~crc32c; 1724 byte0 = crc32c & 0xff; 1725 byte1 = (crc32c >> 8) & 0xff; 1726 byte2 = (crc32c >> 16) & 0xff; 1727 byte3 = (crc32c >> 24) & 0xff; 1728 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); 1729 return (htonl(crc32c)); 1730 } 1731 1732 u_int16_t 1733 in_cksum(u_int16_t *addr, int len) 1734 { 1735 int nleft = len; 1736 u_int16_t *w = addr; 1737 u_int16_t answer; 1738 int sum = 0; 1739 1740 /* 1741 * Our algorithm is simple, using a 32 bit accumulator (sum), 1742 * we add sequential 16 bit words to it, and at the end, fold 1743 * back all the carry bits from the top 16 bits into the lower 1744 * 16 bits. 1745 */ 1746 while (nleft > 1) { 1747 sum += *w++; 1748 nleft -= 2; 1749 } 1750 1751 /* mop up an odd byte, if necessary */ 1752 if (nleft == 1) 1753 sum += *(u_char *)w; 1754 1755 /* 1756 * add back carry outs from top 16 bits to low 16 bits 1757 */ 1758 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 1759 sum += (sum >> 16); /* add carry */ 1760 answer = ~sum; /* truncate to 16 bits */ 1761 return (answer); 1762 } 1763 1764 u_int16_t 1765 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst, 1766 void *payload, u_int32_t len) 1767 { 1768 struct { 1769 struct in6_addr src; 1770 struct in6_addr dst; 1771 u_int32_t len; 1772 u_int8_t zero[3]; 1773 u_int8_t next; 1774 } pseudo_hdr; 1775 u_int16_t sum[2]; 1776 1777 pseudo_hdr.src = src->sin6_addr; 1778 pseudo_hdr.dst = dst->sin6_addr; 1779 pseudo_hdr.len = htonl(len); 1780 pseudo_hdr.zero[0] = 0; 1781 pseudo_hdr.zero[1] = 0; 1782 pseudo_hdr.zero[2] = 0; 1783 pseudo_hdr.next = IPPROTO_UDP; 1784 1785 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr)); 1786 sum[0] = in_cksum(payload, len); 1787 1788 return (~in_cksum(sum, sizeof(sum))); 1789 } 1790 1791 u_int16_t 1792 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst, 1793 void *payload, u_int32_t len) 1794 { 1795 struct { 1796 struct in6_addr src; 1797 struct in6_addr dst; 1798 u_int32_t len; 1799 u_int8_t zero[3]; 1800 u_int8_t next; 1801 } pseudo_hdr; 1802 u_int16_t sum[2]; 1803 1804 pseudo_hdr.src = src->sin6_addr; 1805 pseudo_hdr.dst = dst->sin6_addr; 1806 pseudo_hdr.len = htonl(len); 1807 pseudo_hdr.zero[0] = 0; 1808 pseudo_hdr.zero[1] = 0; 1809 pseudo_hdr.zero[2] = 0; 1810 pseudo_hdr.next = IPPROTO_TCP; 1811 1812 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr)); 1813 sum[0] = in_cksum(payload, len); 1814 1815 return (~in_cksum(sum, sizeof(sum))); 1816 } 1817 1818 void 1819 usage(void) 1820 { 1821 fprintf(stderr, 1822 "Usage: traceroute6 [-adEIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n" 1823 "\t[-m hoplimit] [-p port] [-q probes] [-s src] [-t tclass]\n" 1824 "\t[-w waittime] target [datalen]\n"); 1825 exit(1); 1826 } 1827