traceroute.c revision 1.69.4.2 1 /* traceroute.c,v 1.69.4.1 2008/01/09 02:02:35 matt Exp */
2
3 /*
4 * Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24 #include <sys/cdefs.h>
25 #ifndef lint
26 #if 0
27 static const char rcsid[] =
28 "@(#)Header: traceroute.c,v 1.49 97/06/13 02:30:23 leres Exp (LBL)";
29 #else
30 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997\n\
31 The Regents of the University of California. All rights reserved.\n");
32 __RCSID("traceroute.c,v 1.69.4.1 2008/01/09 02:02:35 matt Exp");
33 #endif
34 #endif
35
36 /*
37 * traceroute host - trace the route ip packets follow going to "host".
38 *
39 * Attempt to trace the route an ip packet would follow to some
40 * internet host. We find out intermediate hops by launching probe
41 * packets with a small ttl (time to live) then listening for an
42 * icmp "time exceeded" reply from a gateway. We start our probes
43 * with a ttl of one and increase by one until we get an icmp "port
44 * unreachable" (which means we got to "host") or hit a max (which
45 * defaults to 30 hops & can be changed with the -m flag). Three
46 * probes (change with -q flag) are sent at each ttl setting and a
47 * line is printed showing the ttl, address of the gateway and
48 * round trip time of each probe. If the probe answers come from
49 * different gateways, the address of each responding system will
50 * be printed. If there is no response within a 5 sec. timeout
51 * interval (changed with the -w flag), a "*" is printed for that
52 * probe.
53 *
54 * Probe packets are UDP format. We don't want the destination
55 * host to process them so the destination port is set to an
56 * unlikely value (if some clod on the destination is using that
57 * value, it can be changed with the -p flag).
58 *
59 * A sample use might be:
60 *
61 * [yak 71]% traceroute nis.nsf.net.
62 * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
63 * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
64 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
65 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
66 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
67 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
68 * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
69 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
70 * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
71 * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
72 * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
73 * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
74 *
75 * Note that lines 2 & 3 are the same. This is due to a buggy
76 * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
77 * packets with a zero ttl.
78 *
79 * A more interesting example is:
80 *
81 * [yak 72]% traceroute allspice.lcs.mit.edu.
82 * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
83 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
84 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
85 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
86 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
87 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
88 * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
89 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
90 * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
91 * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
92 * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
93 * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
94 * 12 * * *
95 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
96 * 14 * * *
97 * 15 * * *
98 * 16 * * *
99 * 17 * * *
100 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
101 *
102 * (I start to see why I'm having so much trouble with mail to
103 * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away
104 * either don't send ICMP "time exceeded" messages or send them
105 * with a ttl too small to reach us. 14 - 17 are running the
106 * MIT C Gateway code that doesn't send "time exceeded"s. God
107 * only knows what's going on with 12.
108 *
109 * The silent gateway 12 in the above may be the result of a bug in
110 * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
111 * sends an unreachable message using whatever ttl remains in the
112 * original datagram. Since, for gateways, the remaining ttl is
113 * zero, the icmp "time exceeded" is guaranteed to not make it back
114 * to us. The behavior of this bug is slightly more interesting
115 * when it appears on the destination system:
116 *
117 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
118 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
119 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
120 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
121 * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
122 * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
123 * 7 * * *
124 * 8 * * *
125 * 9 * * *
126 * 10 * * *
127 * 11 * * *
128 * 12 * * *
129 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
130 *
131 * Notice that there are 12 "gateways" (13 is the final
132 * destination) and exactly the last half of them are "missing".
133 * What's really happening is that rip (a Sun-3 running Sun OS3.5)
134 * is using the ttl from our arriving datagram as the ttl in its
135 * icmp reply. So, the reply will time out on the return path
136 * (with no notice sent to anyone since icmp's aren't sent for
137 * icmp's) until we probe with a ttl that's at least twice the path
138 * length. I.e., rip is really only 7 hops away. A reply that
139 * returns with a ttl of 1 is a clue this problem exists.
140 * Traceroute prints a "!" after the time if the ttl is <= 1.
141 * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
142 * non-standard (HPUX) software, expect to see this problem
143 * frequently and/or take care picking the target host of your
144 * probes.
145 *
146 * Other possible annotations after the time are !H, !N, !P (got a host,
147 * network or protocol unreachable, respectively), !S or !F (source
148 * route failed or fragmentation needed -- neither of these should
149 * ever occur and the associated gateway is busted if you see one). If
150 * almost all the probes result in some kind of unreachable, traceroute
151 * will give up and exit.
152 *
153 * Notes
154 * -----
155 * This program must be run by root or be setuid. (I suggest that
156 * you *don't* make it setuid -- casual use could result in a lot
157 * of unnecessary traffic on our poor, congested nets.)
158 *
159 * This program requires a kernel mod that does not appear in any
160 * system available from Berkeley: A raw ip socket using proto
161 * IPPROTO_RAW must interpret the data sent as an ip datagram (as
162 * opposed to data to be wrapped in a ip datagram). See the README
163 * file that came with the source to this program for a description
164 * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may
165 * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
166 * MODIFIED TO RUN THIS PROGRAM.
167 *
168 * The udp port usage may appear bizarre (well, ok, it is bizarre).
169 * The problem is that an icmp message only contains 8 bytes of
170 * data from the original datagram. 8 bytes is the size of a udp
171 * header so, if we want to associate replies with the original
172 * datagram, the necessary information must be encoded into the
173 * udp header (the ip id could be used but there's no way to
174 * interlock with the kernel's assignment of ip id's and, anyway,
175 * it would have taken a lot more kernel hacking to allow this
176 * code to set the ip id). So, to allow two or more users to
177 * use traceroute simultaneously, we use this task's pid as the
178 * source port (the high bit is set to move the port number out
179 * of the "likely" range). To keep track of which probe is being
180 * replied to (so times and/or hop counts don't get confused by a
181 * reply that was delayed in transit), we increment the destination
182 * port number before each probe.
183 *
184 * Don't use this as a coding example. I was trying to find a
185 * routing problem and this code sort-of popped out after 48 hours
186 * without sleep. I was amazed it ever compiled, much less ran.
187 *
188 * I stole the idea for this program from Steve Deering. Since
189 * the first release, I've learned that had I attended the right
190 * IETF working group meetings, I also could have stolen it from Guy
191 * Almes or Matt Mathis. I don't know (or care) who came up with
192 * the idea first. I envy the originators' perspicacity and I'm
193 * glad they didn't keep the idea a secret.
194 *
195 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
196 * enhancements to the original distribution.
197 *
198 * I've hacked up a round-trip-route version of this that works by
199 * sending a loose-source-routed udp datagram through the destination
200 * back to yourself. Unfortunately, SO many gateways botch source
201 * routing, the thing is almost worthless. Maybe one day...
202 *
203 * -- Van Jacobson (van (at) ee.lbl.gov)
204 * Tue Dec 20 03:50:13 PST 1988
205 */
206
207 #include <sys/param.h>
208 #include <sys/file.h>
209 #include <sys/ioctl.h>
210 #include <sys/socket.h>
211 #include <sys/time.h>
212 #include <sys/sysctl.h>
213
214 #include <netinet/in_systm.h>
215 #include <netinet/in.h>
216 #include <netinet/ip.h>
217 #include <netinet/ip_var.h>
218 #include <netinet/ip_icmp.h>
219 #include <netinet/udp.h>
220 #include <netinet/udp_var.h>
221
222 #include <arpa/inet.h>
223
224 #include <ctype.h>
225 #include <errno.h>
226 #ifdef HAVE_MALLOC_H
227 #include <malloc.h>
228 #endif
229 #include <memory.h>
230 #include <netdb.h>
231 #include <stdio.h>
232 #include <stdlib.h>
233 #include <string.h>
234 #include <unistd.h>
235 #include <poll.h>
236 #ifdef IPSEC
237 #include <net/route.h>
238 #include <netinet6/ipsec.h>
239 #endif
240
241 #include "gnuc.h"
242 #ifdef HAVE_OS_PROTO_H
243 #include "os-proto.h"
244 #endif
245
246 #include "ifaddrlist.h"
247 #include "as.h"
248
249 /* Maximum number of gateways (include room for one noop) */
250 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
251
252 #ifndef MAXHOSTNAMELEN
253 #define MAXHOSTNAMELEN 64
254 #endif
255
256 #define Fprintf (void)fprintf
257 #define Printf (void)printf
258
259 /* Host name and address list */
260 struct hostinfo {
261 char *name;
262 int n;
263 u_int32_t *addrs;
264 };
265
266 /* Data section of the probe packet */
267 struct outdata {
268 u_char seq; /* sequence number of this packet */
269 u_char ttl; /* ttl packet left with */
270 struct timeval tv; /* time packet left */
271 };
272
273 /*
274 * Support for ICMP extensions
275 *
276 * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
277 */
278 #define ICMP_EXT_OFFSET 8 /* ICMP type, code, checksum, unused */ + \
279 128 /* original datagram */
280 #define ICMP_EXT_VERSION 2
281 /*
282 * ICMP extensions, common header
283 */
284 struct icmp_ext_cmn_hdr {
285 #if BYTE_ORDER == BIG_ENDIAN
286 unsigned char version:4;
287 unsigned char reserved1:4;
288 #else
289 unsigned char reserved1:4;
290 unsigned char version:4;
291 #endif
292 unsigned char reserved2;
293 unsigned short checksum;
294 };
295
296 /*
297 * ICMP extensions, object header
298 */
299 struct icmp_ext_obj_hdr {
300 u_short length;
301 u_char class_num;
302 #define MPLS_STACK_ENTRY_CLASS 1
303 u_char c_type;
304 #define MPLS_STACK_ENTRY_C_TYPE 1
305 };
306
307 struct mpls_header {
308 #if BYTE_ORDER == BIG_ENDIAN
309 uint32_t label:20;
310 unsigned char exp:3;
311 unsigned char s:1;
312 unsigned char ttl:8;
313 #else
314 unsigned char ttl:8;
315 unsigned char s:1;
316 unsigned char exp:3;
317 uint32_t label:20;
318 #endif
319 };
320
321 u_char packet[512]; /* last inbound (icmp) packet */
322
323 struct ip *outip; /* last output (udp) packet */
324 struct udphdr *outudp; /* last output (udp) packet */
325 void *outmark; /* packed location of struct outdata */
326 struct outdata outsetup; /* setup and copy for alignment */
327
328 struct icmp *outicmp; /* last output (icmp) packet */
329
330 /* loose source route gateway list (including room for final destination) */
331 u_int32_t gwlist[NGATEWAYS + 1];
332
333 int s; /* receive (icmp) socket file descriptor */
334 int sndsock; /* send (udp/icmp) socket file descriptor */
335
336 struct sockaddr whereto; /* Who to try to reach */
337 struct sockaddr_in wherefrom; /* Who we are */
338 int packlen; /* total length of packet */
339 int minpacket; /* min ip packet size */
340 int maxpacket = 32 * 1024; /* max ip packet size */
341 int printed_ttl = 0;
342
343 const char *prog;
344 char *source;
345 char *hostname;
346 char *device;
347
348 int nprobes = 3;
349 int max_ttl = 30;
350 int first_ttl = 1;
351 u_int16_t ident;
352 in_port_t port = 32768 + 666; /* start udp dest port # for probe packets */
353
354 int options; /* socket options */
355 int verbose;
356 int waittime = 5; /* time to wait for response (in seconds) */
357 int nflag; /* print addresses numerically */
358 int dump;
359 int Mflag; /* show MPLS labels if any */
360 int as_path; /* print as numbers for each hop */
361 char *as_server = NULL;
362 void *asn;
363 int useicmp = 0; /* use icmp echo instead of udp packets */
364 #ifdef CANT_HACK_CKSUM
365 int docksum = 0; /* don't calculate checksums */
366 #else
367 int docksum = 1; /* calculate checksums */
368 #endif
369 int optlen; /* length of ip options */
370
371 int mtus[] = {
372 17914,
373 8166,
374 4464,
375 4352,
376 2048,
377 2002,
378 1536,
379 1500,
380 1492,
381 1480,
382 1280,
383 1006,
384 576,
385 552,
386 544,
387 512,
388 508,
389 296,
390 68,
391 0
392 };
393 int *mtuptr = &mtus[0];
394 int mtudisc = 0;
395 int nextmtu; /* from ICMP error, set by packet_ok(), might be 0 */
396
397 extern int optind;
398 extern int opterr;
399 extern char *optarg;
400
401 /* Forwards */
402 double deltaT(struct timeval *, struct timeval *);
403 void freehostinfo(struct hostinfo *);
404 void getaddr(u_int32_t *, char *);
405 struct hostinfo *gethostinfo(char *);
406 u_int16_t in_cksum(u_int16_t *, int);
407 u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
408 char *inetname(struct in_addr);
409 int main(int, char **);
410 int packet_ok(u_char *, int, struct sockaddr_in *, int);
411 char *pr_type(u_char);
412 void print(u_char *, int, struct sockaddr_in *);
413 void resize_packet(void);
414 void dump_packet(void);
415 void send_probe(int, int, struct timeval *);
416 void setsin(struct sockaddr_in *, u_int32_t);
417 int str2val(const char *, const char *, int, int);
418 void tvsub(struct timeval *, struct timeval *);
419 __dead void usage(void);
420 int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
421 void decode_extensions(unsigned char *buf, int ip_len);
422 void frag_err(void);
423 int find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
424 #ifdef IPSEC
425 #ifdef IPSEC_POLICY_IPSEC
426 int setpolicy(int so, char *policy);
427 #endif
428 #endif
429
430 int
431 main(int argc, char **argv)
432 {
433 int op, code, n;
434 u_char *outp;
435 u_int32_t *ap;
436 struct sockaddr_in *from = &wherefrom;
437 struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
438 struct hostinfo *hi;
439 int on = 1;
440 int ttl, probe, i;
441 int seq = 0;
442 int tos = 0, settos = 0, ttl_flag = 0;
443 int lsrr = 0;
444 u_int16_t off = 0;
445 struct ifaddrlist *al, *al2;
446 char errbuf[132];
447 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
448 size_t size = sizeof(max_ttl);
449
450 setprogname(argv[0]);
451 prog = getprogname();
452
453 if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
454 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
455 exit(1);
456 }
457
458 /*
459 * XXX 'useicmp' will always be zero here. I think the HP-UX users
460 * running our traceroute code will forgive us.
461 */
462 #ifndef __hpux
463 sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
464 #else
465 sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW
466 useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
467 #endif
468 if (sndsock < 0) {
469 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
470 exit(1);
471 }
472
473 /* Revert to non-privileged user after opening sockets */
474 setuid(getuid());
475
476 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
477 NULL, 0);
478
479 opterr = 0;
480 while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:")) != -1)
481 switch (op) {
482
483 case 'a':
484 as_path = 1;
485 break;
486
487 case 'A':
488 as_path = 1;
489 as_server = optarg;
490 break;
491
492 case 'd':
493 options |= SO_DEBUG;
494 break;
495
496 case 'D':
497 dump = 1;
498 break;
499
500 case 'f':
501 first_ttl = str2val(optarg, "first ttl", 1, 255);
502 break;
503
504 case 'F':
505 off = IP_DF;
506 break;
507
508 case 'g':
509 if (lsrr >= NGATEWAYS) {
510 Fprintf(stderr,
511 "%s: No more than %d gateways\n",
512 prog, NGATEWAYS);
513 exit(1);
514 }
515 getaddr(gwlist + lsrr, optarg);
516 ++lsrr;
517 break;
518
519 case 'i':
520 device = optarg;
521 break;
522
523 case 'I':
524 ++useicmp;
525 break;
526
527 case 'l':
528 ++ttl_flag;
529 break;
530
531 case 'm':
532 max_ttl = str2val(optarg, "max ttl", 1, 255);
533 break;
534
535 case 'M':
536 Mflag = 1;
537 break;
538
539 case 'n':
540 ++nflag;
541 break;
542
543 case 'p':
544 port = str2val(optarg, "port", 1, -1);
545 break;
546
547 case 'q':
548 nprobes = str2val(optarg, "nprobes", 1, -1);
549 break;
550
551 case 'r':
552 options |= SO_DONTROUTE;
553 break;
554
555 case 's':
556 /*
557 * set the ip source address of the outbound
558 * probe (e.g., on a multi-homed host).
559 */
560 source = optarg;
561 break;
562
563 case 't':
564 tos = str2val(optarg, "tos", 0, 255);
565 ++settos;
566 break;
567
568 case 'v':
569 ++verbose;
570 break;
571
572 case 'x':
573 docksum = (docksum == 0);
574 break;
575
576 case 'w':
577 waittime = str2val(optarg, "wait time", 2, 24 * 3600);
578 break;
579
580 case 'P':
581 off = IP_DF;
582 mtudisc = 1;
583 break;
584
585 default:
586 usage();
587 }
588
589 if (first_ttl > max_ttl) {
590 Fprintf(stderr,
591 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
592 prog, first_ttl, max_ttl);
593 exit(1);
594 }
595
596 if (!docksum)
597 Fprintf(stderr, "%s: Warning: ckecksums disabled\n", prog);
598
599 if (lsrr > 0)
600 optlen = (lsrr + 1) * sizeof(gwlist[0]);
601 minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
602 if (useicmp)
603 minpacket += 8; /* XXX magic number */
604 else
605 minpacket += sizeof(*outudp);
606 if (packlen == 0)
607 packlen = minpacket; /* minimum sized packet */
608 else if (minpacket > packlen || packlen > maxpacket) {
609 Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n",
610 prog, minpacket, maxpacket);
611 exit(1);
612 }
613
614 if (mtudisc)
615 packlen = *mtuptr++;
616
617 /* Process destination and optional packet size */
618 switch (argc - optind) {
619
620 case 2:
621 packlen = str2val(argv[optind + 1],
622 "packet length", minpacket, -1);
623 /* Fall through */
624
625 case 1:
626 hostname = argv[optind];
627 hi = gethostinfo(hostname);
628 setsin(to, hi->addrs[0]);
629 if (hi->n > 1)
630 Fprintf(stderr,
631 "%s: Warning: %s has multiple addresses; using %s\n",
632 prog, hostname, inet_ntoa(to->sin_addr));
633 hostname = hi->name;
634 hi->name = NULL;
635 freehostinfo(hi);
636 break;
637
638 default:
639 usage();
640 }
641
642 #ifdef HAVE_SETLINEBUF
643 setlinebuf (stdout);
644 #else
645 setvbuf(stdout, NULL, _IOLBF, 0);
646 #endif
647
648 outip = (struct ip *)malloc((unsigned)packlen);
649 if (outip == NULL) {
650 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
651 exit(1);
652 }
653 memset((char *)outip, 0, packlen);
654
655 outip->ip_v = IPVERSION;
656 if (settos)
657 outip->ip_tos = tos;
658 #ifdef BYTESWAP_IP_LEN
659 outip->ip_len = htons(packlen);
660 #else
661 outip->ip_len = packlen;
662 #endif
663 outip->ip_off = off;
664 outp = (u_char *)(outip + 1);
665 #ifdef HAVE_RAW_OPTIONS
666 if (lsrr > 0) {
667 u_char *optlist;
668
669 optlist = outp;
670 outp += optlen;
671
672 /* final hop */
673 gwlist[lsrr] = to->sin_addr.s_addr;
674
675 outip->ip_dst.s_addr = gwlist[0];
676
677 /* force 4 byte alignment */
678 optlist[0] = IPOPT_NOP;
679 /* loose source route option */
680 optlist[1] = IPOPT_LSRR;
681 i = lsrr * sizeof(gwlist[0]);
682 optlist[2] = i + 3;
683 /* Pointer to LSRR addresses */
684 optlist[3] = IPOPT_MINOFF;
685 memcpy(optlist + 4, gwlist + 1, i);
686 } else
687 #endif
688 outip->ip_dst = to->sin_addr;
689
690 outip->ip_hl = (outp - (u_char *)outip) >> 2;
691 ident = htons(arc4random() & 0xffff) | 0x8000;
692 if (useicmp) {
693 outip->ip_p = IPPROTO_ICMP;
694
695 outicmp = (struct icmp *)outp;
696 outicmp->icmp_type = ICMP_ECHO;
697 outicmp->icmp_id = htons(ident);
698
699 outmark = outp + 8; /* XXX magic number */
700 } else {
701 outip->ip_p = IPPROTO_UDP;
702
703 outudp = (struct udphdr *)outp;
704 outudp->uh_sport = htons(ident);
705 outudp->uh_ulen =
706 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
707 outmark = outudp + 1;
708 }
709
710 if (options & SO_DEBUG)
711 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
712 sizeof(on));
713 #ifdef IPSEC
714 #ifdef IPSEC_POLICY_IPSEC
715 /*
716 * do not raise error even if setsockopt fails, kernel may have ipsec
717 * turned off.
718 */
719 if (setpolicy(s, "in bypass") < 0)
720 exit(1);
721 if (setpolicy(s, "out bypass") < 0)
722 exit(1);
723 #else
724 {
725 int level = IPSEC_LEVEL_AVAIL;
726
727 (void)setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
728 sizeof(level));
729 (void)setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
730 sizeof(level));
731 #ifdef IP_AUTH_TRANS_LEVEL
732 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
733 sizeof(level));
734 #else
735 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
736 sizeof(level));
737 #endif
738 #ifdef IP_AUTH_NETWORK_LEVEL
739 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
740 sizeof(level));
741 #endif
742 }
743 #endif /*IPSEC_POLICY_IPSEC*/
744 #endif /*IPSEC*/
745
746 #ifdef IPSEC
747 #ifdef IPSEC_POLICY_IPSEC
748 /*
749 * do not raise error even if setsockopt fails, kernel may have ipsec
750 * turned off.
751 */
752 if (setpolicy(sndsock, "in bypass") < 0)
753 exit(1);
754 if (setpolicy(sndsock, "out bypass") < 0)
755 exit(1);
756 #else
757 {
758 int level = IPSEC_LEVEL_BYPASS;
759
760 (void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
761 sizeof(level));
762 (void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
763 sizeof(level));
764 #ifdef IP_AUTH_TRANS_LEVEL
765 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
766 sizeof(level));
767 #else
768 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
769 sizeof(level));
770 #endif
771 #ifdef IP_AUTH_NETWORK_LEVEL
772 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
773 sizeof(level));
774 #endif
775 }
776 #endif /*IPSEC_POLICY_IPSEC*/
777 #endif /*IPSEC*/
778
779 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
780 if (lsrr > 0) {
781 u_char optlist[MAX_IPOPTLEN];
782
783 /* final hop */
784 gwlist[lsrr] = to->sin_addr.s_addr;
785 ++lsrr;
786
787 /* force 4 byte alignment */
788 optlist[0] = IPOPT_NOP;
789 /* loose source route option */
790 optlist[1] = IPOPT_LSRR;
791 i = lsrr * sizeof(gwlist[0]);
792 optlist[2] = i + 3;
793 /* Pointer to LSRR addresses */
794 optlist[3] = IPOPT_MINOFF;
795 memcpy(optlist + 4, gwlist, i);
796
797 if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
798 i + sizeof(gwlist[0]))) < 0) {
799 Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
800 prog, strerror(errno));
801 exit(1);
802 }
803 }
804 #endif
805
806 #ifdef SO_SNDBUF
807 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
808 sizeof(packlen)) < 0) {
809 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
810 exit(1);
811 }
812 #endif
813 #ifdef IP_HDRINCL
814 if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
815 sizeof(on)) < 0) {
816 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
817 exit(1);
818 }
819 #else
820 #ifdef IP_TOS
821 if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
822 (char *)&tos, sizeof(tos)) < 0) {
823 Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
824 prog, tos, strerror(errno));
825 exit(1);
826 }
827 #endif
828 #endif
829 if (options & SO_DEBUG)
830 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
831 sizeof(on));
832 if (options & SO_DONTROUTE)
833 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
834 sizeof(on));
835
836 /* Get the interface address list */
837 n = ifaddrlist(&al, errbuf, sizeof errbuf);
838 al2 = al;
839 if (n < 0) {
840 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
841 exit(1);
842 }
843 if (n == 0) {
844 Fprintf(stderr,
845 "%s: Can't find any network interfaces\n", prog);
846 exit(1);
847 }
848
849 /* Look for a specific device */
850 if (device != NULL) {
851 for (i = n; i > 0; --i, ++al2)
852 if (strcmp(device, al2->device) == 0)
853 break;
854 if (i <= 0) {
855 Fprintf(stderr, "%s: Can't find interface %s\n",
856 prog, device);
857 exit(1);
858 }
859 }
860
861 /* Determine our source address */
862 if (source == NULL) {
863 /*
864 * If a device was specified, use the interface address.
865 * Otherwise, use the first interface found.
866 * Warn if there are more than one.
867 */
868 setsin(from, al2->addr);
869 if (n > 1 && device == NULL && !find_local_ip(from, to)) {
870 Fprintf(stderr,
871 "%s: Warning: Multiple interfaces found; using %s @ %s\n",
872 prog, inet_ntoa(from->sin_addr), al2->device);
873 }
874 } else {
875 hi = gethostinfo(source);
876 source = hi->name;
877 hi->name = NULL;
878 if (device == NULL) {
879 /*
880 * Use the first interface found.
881 * Warn if there are more than one.
882 */
883 setsin(from, hi->addrs[0]);
884 if (hi->n > 1)
885 Fprintf(stderr,
886 "%s: Warning: %s has multiple addresses; using %s\n",
887 prog, source, inet_ntoa(from->sin_addr));
888 } else {
889 /*
890 * Make sure the source specified matches the
891 * interface address.
892 */
893 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
894 if (*ap == al2->addr)
895 break;
896 if (i <= 0) {
897 Fprintf(stderr,
898 "%s: %s is not on interface %s\n",
899 prog, source, device);
900 exit(1);
901 }
902 setsin(from, *ap);
903 }
904 freehostinfo(hi);
905 }
906
907 /*
908 * If not root, make sure source address matches a local interface.
909 * (The list of addresses produced by ifaddrlist() automatically
910 * excludes interfaces that are marked down and/or loopback.)
911 */
912 if (getuid()) {
913 al2 = al;
914 for (i = n; i > 0; --i, ++al2)
915 if (from->sin_addr.s_addr == al2->addr)
916 break;
917 if (i <= 0) {
918 Fprintf(stderr, "%s: %s is not a valid local address "
919 "and you are not superuser.\n", prog,
920 inet_ntoa(from->sin_addr));
921 exit(1);
922 }
923 }
924
925 outip->ip_src = from->sin_addr;
926 #ifndef IP_HDRINCL
927 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
928 Fprintf(stderr, "%s: bind: %s\n",
929 prog, strerror(errno));
930 exit (1);
931 }
932 #endif
933
934 if (as_path) {
935 asn = as_setup(as_server);
936 if (asn == NULL) {
937 Fprintf(stderr, "%s: as_setup failed, AS# lookups disabled\n",
938 prog);
939 (void)fflush(stderr);
940 as_path = 0;
941 }
942 }
943
944 setuid(getuid());
945 Fprintf(stderr, "%s to %s (%s)",
946 prog, hostname, inet_ntoa(to->sin_addr));
947 if (source)
948 Fprintf(stderr, " from %s", source);
949 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
950 (void)fflush(stderr);
951
952 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
953 u_int32_t lastaddr = 0;
954 int got_there = 0;
955 int unreachable = 0;
956
957 again:
958 printed_ttl = 0;
959 for (probe = 0; probe < nprobes; ++probe) {
960 int cc;
961 struct timeval t1, t2;
962 struct ip *ip;
963 (void)gettimeofday(&t1, NULL);
964 if (!useicmp && htons(port + seq + 1) == 0)
965 seq++;
966 send_probe(++seq, ttl, &t1);
967 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
968 (void)gettimeofday(&t2, NULL);
969 /*
970 * Since we'll be receiving all ICMP
971 * messages to this host above, we may
972 * never end up with cc=0, so we need
973 * an additional termination check.
974 */
975 if (t2.tv_sec - t1.tv_sec > waittime) {
976 cc = 0;
977 break;
978 }
979 i = packet_ok(packet, cc, from, seq);
980 /* Skip short packet */
981 if (i == 0)
982 continue;
983 if (from->sin_addr.s_addr != lastaddr) {
984 print(packet, cc, from);
985 lastaddr = from->sin_addr.s_addr;
986 }
987 ip = (struct ip *)packet;
988 Printf(" %.3f ms", deltaT(&t1, &t2));
989 if (ttl_flag)
990 Printf(" (ttl = %d)", ip->ip_ttl);
991 if (i == -2) {
992 #ifndef ARCHAIC
993 if (ip->ip_ttl <= 1)
994 Printf(" !");
995 #endif
996 ++got_there;
997 break;
998 }
999
1000 /* time exceeded in transit */
1001 if (i == -1)
1002 break;
1003 code = i - 1;
1004 switch (code) {
1005
1006 case ICMP_UNREACH_PORT:
1007 #ifndef ARCHAIC
1008 if (ip->ip_ttl <= 1)
1009 Printf(" !");
1010 #endif
1011 ++got_there;
1012 break;
1013
1014 case ICMP_UNREACH_NET:
1015 ++unreachable;
1016 Printf(" !N");
1017 break;
1018
1019 case ICMP_UNREACH_HOST:
1020 ++unreachable;
1021 Printf(" !H");
1022 break;
1023
1024 case ICMP_UNREACH_PROTOCOL:
1025 ++got_there;
1026 Printf(" !P");
1027 break;
1028
1029 case ICMP_UNREACH_NEEDFRAG:
1030 if (mtudisc) {
1031 frag_err();
1032 goto again;
1033 } else {
1034 ++unreachable;
1035 Printf(" !F");
1036 }
1037 break;
1038
1039 case ICMP_UNREACH_SRCFAIL:
1040 ++unreachable;
1041 Printf(" !S");
1042 break;
1043
1044 /* rfc1716 */
1045 #ifndef ICMP_UNREACH_FILTER_PROHIB
1046 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
1047 #endif
1048 case ICMP_UNREACH_FILTER_PROHIB:
1049 ++unreachable;
1050 Printf(" !X");
1051 break;
1052
1053 default:
1054 ++unreachable;
1055 Printf(" !<%d>", code);
1056 break;
1057 }
1058 break;
1059 }
1060 if (cc == 0)
1061 Printf(" *");
1062 else if (cc && probe == nprobes - 1 && Mflag)
1063 decode_extensions(packet, cc);
1064 (void)fflush(stdout);
1065 }
1066 putchar('\n');
1067 if (got_there ||
1068 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
1069 break;
1070 }
1071
1072 if (as_path)
1073 as_shutdown(asn);
1074
1075 exit(0);
1076 }
1077
1078 int
1079 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp)
1080 {
1081 struct pollfd set[1];
1082 struct timeval now, wait;
1083 int cc = 0;
1084 socklen_t fromlen = sizeof(*fromp);
1085 int retval;
1086
1087 set[0].fd = sock;
1088 set[0].events = POLLIN;
1089
1090 wait.tv_sec = tp->tv_sec + waittime;
1091 wait.tv_usec = tp->tv_usec;
1092 (void)gettimeofday(&now, NULL);
1093 tvsub(&wait, &now);
1094
1095 if (wait.tv_sec < 0) {
1096 wait.tv_sec = 0;
1097 wait.tv_usec = 0;
1098 }
1099
1100 retval = poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000);
1101 if (retval < 0) {
1102 /* If we continue, we probably just flood the remote host. */
1103 Fprintf(stderr, "%s: poll: %s\n", prog, strerror(errno));
1104 exit(1);
1105 }
1106 if (retval > 0) {
1107 cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
1108 (struct sockaddr *)fromp, &fromlen);
1109 }
1110
1111 return(cc);
1112 }
1113
1114 void
1115 decode_extensions(unsigned char *buf, int ip_len)
1116 {
1117 struct icmp_ext_cmn_hdr *cmn_hdr;
1118 struct icmp_ext_obj_hdr *obj_hdr;
1119 union {
1120 struct mpls_header mpls;
1121 uint32_t mpls_h;
1122 } mpls;
1123 int datalen, obj_len;
1124 struct ip *ip;
1125
1126 ip = (struct ip *)buf;
1127
1128 if (ip_len <= sizeof(struct ip) + ICMP_EXT_OFFSET) {
1129 /*
1130 * No support for ICMP extensions on this host
1131 */
1132 return;
1133 }
1134
1135 /*
1136 * Move forward to the start of the ICMP extensions, if present
1137 */
1138 buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
1139 cmn_hdr = (struct icmp_ext_cmn_hdr *)buf;
1140
1141 if (cmn_hdr->version != ICMP_EXT_VERSION) {
1142 /*
1143 * Unknown version
1144 */
1145 return;
1146 }
1147
1148 datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
1149
1150 /*
1151 * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
1152 * done by sender.
1153 *
1154 * If the checksum is ok, we'll get 0, as the checksum is calculated
1155 * with the checksum field being 0'd.
1156 */
1157 if (ntohs(cmn_hdr->checksum) &&
1158 in_cksum((u_short *)cmn_hdr, datalen)) {
1159
1160 return;
1161 }
1162
1163 buf += sizeof(*cmn_hdr);
1164 datalen -= sizeof(*cmn_hdr);
1165
1166 while (datalen > 0) {
1167 obj_hdr = (struct icmp_ext_obj_hdr *)buf;
1168 obj_len = ntohs(obj_hdr->length);
1169
1170 /*
1171 * Sanity check the length field
1172 */
1173 if (obj_len > datalen) {
1174 return;
1175 }
1176
1177 datalen -= obj_len;
1178
1179 /*
1180 * Move past the object header
1181 */
1182 buf += sizeof(struct icmp_ext_obj_hdr);
1183 obj_len -= sizeof(struct icmp_ext_obj_hdr);
1184
1185 switch (obj_hdr->class_num) {
1186 case MPLS_STACK_ENTRY_CLASS:
1187 switch (obj_hdr->c_type) {
1188 case MPLS_STACK_ENTRY_C_TYPE:
1189 while (obj_len >= sizeof(uint32_t)) {
1190 mpls.mpls_h = ntohl(*(uint32_t *)buf);
1191
1192 buf += sizeof(uint32_t);
1193 obj_len -= sizeof(uint32_t);
1194
1195 printf(" [MPLS: Label %d Exp %d]",
1196 mpls.mpls.label, mpls.mpls.exp);
1197 }
1198 if (obj_len > 0) {
1199 /*
1200 * Something went wrong, and we're at
1201 * a unknown offset into the packet,
1202 * ditch the rest of it.
1203 */
1204 return;
1205 }
1206 break;
1207 default:
1208 /*
1209 * Unknown object, skip past it
1210 */
1211 buf += ntohs(obj_hdr->length) -
1212 sizeof(struct icmp_ext_obj_hdr);
1213 break;
1214 }
1215 break;
1216
1217 default:
1218 /*
1219 * Unknown object, skip past it
1220 */
1221 buf += ntohs(obj_hdr->length) -
1222 sizeof(struct icmp_ext_obj_hdr);
1223 break;
1224 }
1225 }
1226 }
1227
1228 void
1229 dump_packet()
1230 {
1231 u_char *p;
1232 int i;
1233
1234 Fprintf(stderr, "packet data:");
1235
1236 #ifdef __hpux
1237 for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i <
1238 i < packlen - (sizeof(*outip) + optlen); i++)
1239 #else
1240 for (p = (u_char *)outip, i = 0; i < packlen; i++)
1241 #endif
1242 {
1243 if ((i % 24) == 0)
1244 Fprintf(stderr, "\n ");
1245 Fprintf(stderr, " %02x", *p++);
1246 }
1247 Fprintf(stderr, "\n");
1248 }
1249
1250 void
1251 send_probe(int seq, int ttl, struct timeval *tp)
1252 {
1253 int cc;
1254 struct udpiphdr * ui;
1255 int oldmtu = packlen;
1256
1257 again:
1258 #ifdef BYTESWAP_IP_LEN
1259 outip->ip_len = htons(packlen);
1260 #else
1261 outip->ip_len = packlen;
1262 #endif
1263 outip->ip_ttl = ttl;
1264 #ifndef __hpux
1265 outip->ip_id = htons(ident + seq);
1266 #endif
1267
1268 /*
1269 * In most cases, the kernel will recalculate the ip checksum.
1270 * But we must do it anyway so that the udp checksum comes out
1271 * right.
1272 */
1273 if (docksum) {
1274 outip->ip_sum =
1275 in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
1276 if (outip->ip_sum == 0)
1277 outip->ip_sum = 0xffff;
1278 }
1279
1280 /* Payload */
1281 outsetup.seq = seq;
1282 outsetup.ttl = ttl;
1283 outsetup.tv = *tp;
1284 memcpy(outmark,&outsetup,sizeof(outsetup));
1285
1286 if (useicmp)
1287 outicmp->icmp_seq = htons(seq);
1288 else
1289 outudp->uh_dport = htons(port + seq);
1290
1291 /* (We can only do the checksum if we know our ip address) */
1292 if (docksum) {
1293 if (useicmp) {
1294 outicmp->icmp_cksum = 0;
1295 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1296 packlen - (sizeof(*outip) + optlen));
1297 if (outicmp->icmp_cksum == 0)
1298 outicmp->icmp_cksum = 0xffff;
1299 } else {
1300 u_int16_t sum;
1301 struct {
1302 struct in_addr src;
1303 struct in_addr dst;
1304 u_int8_t zero;
1305 u_int8_t protocol;
1306 u_int16_t len;
1307 } __packed phdr;
1308
1309 /* Checksum */
1310 ui = (struct udpiphdr *)outip;
1311 memset(&phdr, 0, sizeof(phdr));
1312 phdr.src = ui->ui_src;
1313 phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr;
1314 phdr.protocol = ui->ui_pr;
1315 phdr.len = outudp->uh_ulen;
1316 outudp->uh_sum = 0;
1317 sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr));
1318 sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen));
1319 outudp->uh_sum = ~sum;
1320 if (outudp->uh_sum == 0)
1321 outudp->uh_sum = 0xffff;
1322 }
1323 }
1324
1325 /* XXX undocumented debugging hack */
1326 if (verbose > 1) {
1327 const u_int16_t *sp;
1328 int nshorts, i;
1329
1330 sp = (u_int16_t *)outip;
1331 nshorts = (u_int)packlen / sizeof(u_int16_t);
1332 i = 0;
1333 Printf("[ %d bytes", packlen);
1334 while (--nshorts >= 0) {
1335 if ((i++ % 8) == 0)
1336 Printf("\n\t");
1337 Printf(" %04x", ntohs(*sp++));
1338 }
1339 if (packlen & 1) {
1340 if ((i % 8) == 0)
1341 Printf("\n\t");
1342 Printf(" %02x", *(u_char *)sp);
1343 }
1344 Printf("]\n");
1345 }
1346
1347 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1348 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1349 (char *)&ttl, sizeof(ttl)) < 0) {
1350 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1351 prog, ttl, strerror(errno));
1352 exit(1);
1353 }
1354 #endif
1355 if (dump)
1356 dump_packet();
1357
1358 #ifdef __hpux
1359 cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
1360 packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
1361 if (cc > 0)
1362 cc += sizeof(*outip) + optlen;
1363 #else
1364 cc = sendto(sndsock, (char *)outip,
1365 packlen, 0, &whereto, sizeof(whereto));
1366 #endif
1367 if (cc < 0 || cc != packlen) {
1368 if (cc < 0) {
1369 /*
1370 * An errno of EMSGSIZE means we're writing too big a
1371 * datagram for the interface. We have to just
1372 * decrease the packet size until we find one that
1373 * works.
1374 *
1375 * XXX maybe we should try to read the outgoing if's
1376 * mtu?
1377 */
1378 if (errno == EMSGSIZE) {
1379 packlen = *mtuptr++;
1380 resize_packet();
1381 goto again;
1382 } else
1383 Fprintf(stderr, "%s: sendto: %s\n",
1384 prog, strerror(errno));
1385 }
1386
1387 Printf("%s: wrote %s %d chars, ret=%d\n",
1388 prog, hostname, packlen, cc);
1389 (void)fflush(stdout);
1390 }
1391 if (oldmtu != packlen) {
1392 Printf("message too big, "
1393 "trying new MTU = %d\n", packlen);
1394 printed_ttl = 0;
1395 }
1396 if (!printed_ttl) {
1397 Printf("%2d ", ttl);
1398 printed_ttl = 1;
1399 }
1400
1401 }
1402
1403 double
1404 deltaT(struct timeval *t1p, struct timeval *t2p)
1405 {
1406 double dt;
1407
1408 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1409 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1410 return (dt);
1411 }
1412
1413 /*
1414 * Convert an ICMP "type" field to a printable string.
1415 */
1416 char *
1417 pr_type(u_char t)
1418 {
1419 static char *ttab[] = {
1420 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1421 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1422 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1423 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1424 "Info Reply"
1425 };
1426
1427 if (t > 16)
1428 return("OUT-OF-RANGE");
1429
1430 return(ttab[t]);
1431 }
1432
1433 int
1434 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq)
1435 {
1436 struct icmp *icp;
1437 u_char type, code;
1438 int hlen;
1439 #ifndef ARCHAIC
1440 struct ip *ip;
1441
1442 ip = (struct ip *) buf;
1443 hlen = ip->ip_hl << 2;
1444 if (cc < hlen + ICMP_MINLEN) {
1445 if (verbose)
1446 Printf("packet too short (%d bytes) from %s\n", cc,
1447 inet_ntoa(from->sin_addr));
1448 return (0);
1449 }
1450 cc -= hlen;
1451 icp = (struct icmp *)(buf + hlen);
1452 #else
1453 icp = (struct icmp *)buf;
1454 #endif
1455 type = icp->icmp_type;
1456 code = icp->icmp_code;
1457 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1458 type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1459 struct ip *hip;
1460 struct udphdr *up;
1461 struct icmp *hicmp;
1462
1463 hip = &icp->icmp_ip;
1464 hlen = hip->ip_hl << 2;
1465
1466 nextmtu = ntohs(icp->icmp_nextmtu); /* for frag_err() */
1467
1468 if (useicmp) {
1469 /* XXX */
1470 if (type == ICMP_ECHOREPLY &&
1471 icp->icmp_id == htons(ident) &&
1472 icp->icmp_seq == htons(seq))
1473 return (-2);
1474
1475 hicmp = (struct icmp *)((u_char *)hip + hlen);
1476 /* XXX 8 is a magic number */
1477 if (hlen + 8 <= cc &&
1478 hip->ip_p == IPPROTO_ICMP &&
1479 hicmp->icmp_id == htons(ident) &&
1480 hicmp->icmp_seq == htons(seq))
1481 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1482 } else {
1483 up = (struct udphdr *)((u_char *)hip + hlen);
1484 /* XXX 8 is a magic number */
1485 if (hlen + 12 <= cc &&
1486 hip->ip_p == IPPROTO_UDP &&
1487 up->uh_sport == htons(ident) &&
1488 up->uh_dport == htons(port + seq))
1489 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1490 }
1491 }
1492 #ifndef ARCHAIC
1493 if (verbose) {
1494 int i;
1495 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1496
1497 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1498 Printf("%s: icmp type %d (%s) code %d\n",
1499 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1500 for (i = 4; i < cc ; i += sizeof(*lp))
1501 Printf("%2d: x%8.8x\n", i, *lp++);
1502 }
1503 #endif
1504 return(0);
1505 }
1506
1507 void resize_packet(void)
1508 {
1509 if (useicmp) {
1510 outicmp->icmp_cksum = 0;
1511 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1512 packlen - (sizeof(*outip) + optlen));
1513 if (outicmp->icmp_cksum == 0)
1514 outicmp->icmp_cksum = 0xffff;
1515 } else {
1516 outudp->uh_ulen =
1517 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
1518 }
1519 }
1520
1521 void
1522 print(u_char *buf, int cc, struct sockaddr_in *from)
1523 {
1524 struct ip *ip;
1525 int hlen;
1526
1527 ip = (struct ip *) buf;
1528 hlen = ip->ip_hl << 2;
1529 cc -= hlen;
1530
1531 if (as_path)
1532 Printf(" [AS%d]", as_lookup(asn, &from->sin_addr));
1533
1534 if (nflag)
1535 Printf(" %s", inet_ntoa(from->sin_addr));
1536 else
1537 Printf(" %s (%s)", inetname(from->sin_addr),
1538 inet_ntoa(from->sin_addr));
1539
1540 if (verbose)
1541 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1542 }
1543
1544 u_int16_t
1545 in_cksum(u_int16_t *addr, int len)
1546 {
1547
1548 return ~in_cksum2(0, addr, len);
1549 }
1550
1551 /*
1552 * Checksum routine for Internet Protocol family headers (C Version)
1553 */
1554 u_int16_t
1555 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
1556 {
1557 int nleft = len;
1558 u_int16_t *w = addr;
1559 union {
1560 u_int16_t w;
1561 u_int8_t b[2];
1562 } answer;
1563 int32_t sum = seed;
1564
1565 /*
1566 * Our algorithm is simple, using a 32 bit accumulator (sum),
1567 * we add sequential 16 bit words to it, and at the end, fold
1568 * back all the carry bits from the top 16 bits into the lower
1569 * 16 bits.
1570 */
1571 while (nleft > 1) {
1572 sum += *w++;
1573 nleft -= 2;
1574 }
1575
1576 /* mop up an odd byte, if necessary */
1577 if (nleft == 1) {
1578 answer.b[0] = *(u_char *)w;
1579 answer.b[1] = 0;
1580 sum += answer.w;
1581 }
1582
1583 /*
1584 * add back carry outs from top 16 bits to low 16 bits
1585 */
1586 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1587 sum += (sum >> 16); /* add carry */
1588 answer.w = sum; /* truncate to 16 bits */
1589 return (answer.w);
1590 }
1591
1592 /*
1593 * Subtract 2 timeval structs: out = out - in.
1594 * Out is assumed to be >= in.
1595 */
1596 void
1597 tvsub(struct timeval *out, struct timeval *in)
1598 {
1599
1600 if ((out->tv_usec -= in->tv_usec) < 0) {
1601 --out->tv_sec;
1602 out->tv_usec += 1000000;
1603 }
1604 out->tv_sec -= in->tv_sec;
1605 }
1606
1607 /*
1608 * Construct an Internet address representation.
1609 * If the nflag has been supplied, give
1610 * numeric value, otherwise try for symbolic name.
1611 */
1612 char *
1613 inetname(struct in_addr in)
1614 {
1615 char *cp;
1616 struct hostent *hp;
1617 static int first = 1;
1618 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1619
1620 if (first && !nflag) {
1621 int rv;
1622
1623 first = 0;
1624 rv = gethostname(domain, sizeof domain);
1625 if (rv == 0 && (cp = strchr(domain, '.')) != NULL) {
1626 (void)strlcpy(domain, cp + 1, sizeof(domain));
1627 } else
1628 domain[0] = '\0';
1629 }
1630 if (!nflag && in.s_addr != INADDR_ANY) {
1631 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1632 if (hp != NULL) {
1633 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1634 strcmp(cp + 1, domain) == 0)
1635 *cp = '\0';
1636 (void)strlcpy(line, hp->h_name, sizeof(line));
1637 return (line);
1638 }
1639 }
1640 return (inet_ntoa(in));
1641 }
1642
1643 struct hostinfo *
1644 gethostinfo(char *hostname)
1645 {
1646 int n;
1647 struct hostent *hp;
1648 struct hostinfo *hi;
1649 char **p;
1650 u_int32_t *ap;
1651 struct in_addr addr;
1652
1653 hi = calloc(1, sizeof(*hi));
1654 if (hi == NULL) {
1655 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1656 exit(1);
1657 }
1658 if (inet_aton(hostname, &addr) != 0) {
1659 hi->name = strdup(hostname);
1660 if (!hi->name) {
1661 Fprintf(stderr, "%s: strdup %s\n", prog,
1662 strerror(errno));
1663 exit(1);
1664 }
1665 hi->n = 1;
1666 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1667 if (hi->addrs == NULL) {
1668 Fprintf(stderr, "%s: calloc %s\n",
1669 prog, strerror(errno));
1670 exit(1);
1671 }
1672 hi->addrs[0] = addr.s_addr;
1673 return (hi);
1674 }
1675
1676 hp = gethostbyname(hostname);
1677 if (hp == NULL) {
1678 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1679 exit(1);
1680 }
1681 if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1682 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1683 exit(1);
1684 }
1685 hi->name = strdup(hp->h_name);
1686 if (!hi->name) {
1687 Fprintf(stderr, "%s: strdup %s\n", prog, strerror(errno));
1688 exit(1);
1689 }
1690 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1691 continue;
1692 hi->n = n;
1693 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1694 if (hi->addrs == NULL) {
1695 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1696 exit(1);
1697 }
1698 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1699 memcpy(ap, *p, sizeof(*ap));
1700 return (hi);
1701 }
1702
1703 void
1704 freehostinfo(struct hostinfo *hi)
1705 {
1706 if (hi->name != NULL) {
1707 free(hi->name);
1708 hi->name = NULL;
1709 }
1710 free((char *)hi->addrs);
1711 free((char *)hi);
1712 }
1713
1714 void
1715 getaddr(u_int32_t *ap, char *hostname)
1716 {
1717 struct hostinfo *hi;
1718
1719 hi = gethostinfo(hostname);
1720 *ap = hi->addrs[0];
1721 freehostinfo(hi);
1722 }
1723
1724 void
1725 setsin(struct sockaddr_in *sin, u_int32_t addr)
1726 {
1727
1728 memset(sin, 0, sizeof(*sin));
1729 #ifdef HAVE_SOCKADDR_SA_LEN
1730 sin->sin_len = sizeof(*sin);
1731 #endif
1732 sin->sin_family = AF_INET;
1733 sin->sin_addr.s_addr = addr;
1734 }
1735
1736 /* String to value with optional min and max. Handles decimal and hex. */
1737 int
1738 str2val(const char *str, const char *what, int mi, int ma)
1739 {
1740 const char *cp;
1741 long val;
1742 char *ep;
1743
1744 errno = 0;
1745 ep = NULL;
1746 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1747 cp = str + 2;
1748 val = strtol(cp, &ep, 16);
1749 } else
1750 val = strtol(str, &ep, 10);
1751 if (errno || str[0] == '\0' || *ep != '\0') {
1752 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1753 prog, str, what);
1754 exit(1);
1755 }
1756 if (val < mi && mi >= 0) {
1757 if (mi == 0)
1758 Fprintf(stderr, "%s: %s must be >= %d\n",
1759 prog, what, mi);
1760 else
1761 Fprintf(stderr, "%s: %s must be > %d\n",
1762 prog, what, mi - 1);
1763 exit(1);
1764 }
1765 if (val > ma && ma >= 0) {
1766 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1767 exit(1);
1768 }
1769 return ((int)val);
1770 }
1771
1772 __dead void
1773 usage(void)
1774 {
1775 extern char version[];
1776
1777 Fprintf(stderr, "Version %s\n", version);
1778 Fprintf(stderr, "usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \
1779 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
1780 [-w waittime] [-A as_server] host [packetlen]\n",
1781 prog);
1782 exit(1);
1783 }
1784
1785 /*
1786 * Received ICMP unreachable (fragmentation required and DF set).
1787 * If the ICMP error was from a "new" router, it'll contain the next-hop
1788 * MTU that we should use next. Otherwise we'll just keep going in the
1789 * mtus[] table, trying until we hit a valid MTU.
1790 */
1791
1792
1793 void
1794 frag_err()
1795 {
1796 int i;
1797
1798 if (nextmtu > 0 && nextmtu < packlen) {
1799 Printf("\nfragmentation required and DF set, "
1800 "next hop MTU = %d\n",
1801 nextmtu);
1802 packlen = nextmtu;
1803 for (i = 0; mtus[i] > 0; i++) {
1804 if (mtus[i] < nextmtu) {
1805 mtuptr = &mtus[i]; /* next one to try */
1806 break;
1807 }
1808 }
1809 } else {
1810 Printf("\nfragmentation required and DF set. ");
1811 if (nextmtu)
1812 Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
1813 nextmtu, packlen);
1814 packlen = *mtuptr++;
1815 Printf("Trying new MTU = %d\n", packlen);
1816 }
1817 resize_packet();
1818 }
1819
1820 int
1821 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
1822 {
1823 int sock;
1824 struct sockaddr_in help;
1825 socklen_t help_len;
1826
1827 sock = socket(AF_INET, SOCK_DGRAM, 0);
1828 if (sock < 0) return (0);
1829
1830 help.sin_family = AF_INET;
1831 /*
1832 * At this point the port number doesn't matter
1833 * since it only has to be greater than zero.
1834 */
1835 help.sin_port = 42;
1836 help.sin_addr.s_addr = to->sin_addr.s_addr;
1837 if (connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
1838 (void)close(sock);
1839 return (0);
1840 }
1841
1842 help_len = sizeof(help);
1843 if (getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
1844 help_len != sizeof(help) ||
1845 help.sin_addr.s_addr == INADDR_ANY) {
1846 (void)close(sock);
1847 return (0);
1848 }
1849
1850 (void)close(sock);
1851 setsin(from, help.sin_addr.s_addr);
1852 return (1);
1853 }
1854
1855 #ifdef IPSEC
1856 #ifdef IPSEC_POLICY_IPSEC
1857 int
1858 setpolicy(so, policy)
1859 int so;
1860 char *policy;
1861 {
1862 char *buf;
1863
1864 buf = ipsec_set_policy(policy, strlen(policy));
1865 if (buf == NULL) {
1866 Fprintf(stderr, "%s: %s\n", prog, ipsec_strerror());
1867 return -1;
1868 }
1869 (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1870 buf, ipsec_get_policylen(buf));
1871
1872 free(buf);
1873
1874 return 0;
1875 }
1876 #endif
1877 #endif
1878
1879