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