1 /* $NetBSD: ping.c,v 1.89 2009/04/11 06:49:50 lukem Exp $ */
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
39 * measure round-trip-delays and packet loss across network paths.
43 * U. S. Army Ballistic Research Laboratory
45 * Modified at Uc Berkeley
46 * Record Route and verbose headers - Phil Dykstra, BRL, March 1988.
47 * Multicast options (ttl, if, loop) - Steve Deering, Stanford, August 1988.
48 * ttl, duplicate detection - Cliff Frost, UCB, April 1989
49 * Pad pattern - Cliff Frost (from Tom Ferrin, UCSF), April 1989
52 * Public Domain. Distribution Unlimited.
55 * More statistics could always be gathered.
56 * This program has to run SUID to ROOT to access the ICMP socket.
59 #include <sys/cdefs.h>
61 __RCSID("$NetBSD: ping.c,v 1.89 2009/04/11 06:49:50 lukem Exp $");
69 #include <sys/types.h>
70 #include <sys/param.h>
71 #include <sys/socket.h>
82 #include <netinet/in_systm.h>
83 #include <netinet/in.h>
84 #include <netinet/ip.h>
85 #include <netinet/ip_icmp.h>
86 #include <netinet/ip_var.h>
87 #include <arpa/inet.h>
92 #include <netinet6/ipsec.h>
95 #define FLOOD_INTVL 0.01 /* default flood output interval */
96 #define MAXPACKET (IP_MAXPACKET-60-8) /* max packet size */
98 #define F_VERBOSE 0x0001
99 #define F_QUIET 0x0002 /* minimize all output */
100 #define F_SEMI_QUIET 0x0004 /* ignore our ICMP errors */
101 #define F_FLOOD 0x0008 /* flood-ping */
102 #define F_RECORD_ROUTE 0x0010 /* record route */
103 #define F_SOURCE_ROUTE 0x0020 /* loose source route */
104 #define F_PING_FILLED 0x0040 /* is buffer filled with user data? */
105 #define F_PING_RANDOM 0x0080 /* use random data */
106 #define F_NUMERIC 0x0100 /* do not do gethostbyaddr() calls */
107 #define F_TIMING 0x0200 /* room for a timestamp */
108 #define F_DF 0x0400 /* set IP DF bit */
109 #define F_SOURCE_ADDR 0x0800 /* set source IP address/interface */
110 #define F_ONCE 0x1000 /* exit(0) after receiving 1 reply */
111 #define F_MCAST 0x2000 /* multicast target */
112 #define F_MCAST_NOLOOP 0x4000 /* no multicast loopback */
113 #define F_AUDIBLE 0x8000 /* audible output */
115 #ifdef IPSEC_POLICY_IPSEC
116 #define F_POLICY 0x10000
118 #define F_AUTHHDR 0x10000
119 #define F_ENCRYPT 0x20000
120 #endif /*IPSEC_POLICY_IPSEC*/
124 /* MAX_DUP_CHK is the number of bits in received table, the
125 * maximum number of received sequence numbers we can track to check
128 #define MAX_DUP_CHK (8 * 2048)
129 u_char rcvd_tbl
[MAX_DUP_CHK
/8];
131 #define A(seq) rcvd_tbl[(seq/8)%sizeof(rcvd_tbl)] /* byte in array */
132 #define B(seq) (1 << (seq & 0x07)) /* bit in byte */
133 #define SET(seq) (A(seq) |= B(seq))
134 #define CLR(seq) (A(seq) &= (~B(seq)))
135 #define TST(seq) (A(seq) & B(seq))
145 int pingflags
= 0, options
;
149 int s
; /* Socket file descriptor */
150 int sloop
; /* Socket file descriptor/loopback */
152 #define PHDR_LEN sizeof(struct tv32) /* size of timestamp header */
153 struct sockaddr_in whereto
, send_addr
; /* Who to ping */
154 struct sockaddr_in src_addr
; /* from where */
155 struct sockaddr_in loc_addr
; /* 127.1 */
156 int datalen
= 64 - PHDR_LEN
; /* How much data */
159 static char *progname
;
160 #define getprogname() (progname)
161 #define setprogname(name) ((void)(progname = (name)))
164 char hostname
[MAXHOSTNAMELEN
];
168 char o_opt
[MAX_IPOPTLEN
];
170 u_char u_buf
[MAXPACKET
+offsetof(struct icmp
, icmp_data
)];
174 #define opack_icmp out_pack.o_u.u_icmp
177 char optspace
[MAX_IPOPTLEN
]; /* record route space */
181 int npackets
; /* total packets to send */
182 int preload
; /* number of packets to "preload" */
183 int ntransmitted
; /* output sequence # = #sent */
184 int ident
; /* our ID, in network byte order */
186 int nreceived
; /* # of packets we got back */
188 double interval
; /* interval between packets */
189 struct timeval interval_tv
;
190 double tmin
= 999999999.0;
192 double tsum
= 0.0; /* sum of all times */
194 double maxwait
= 0.0;
196 int bufspace
= IP_MAXPACKET
;
198 struct timeval now
, clear_cache
, last_tx
, next_tx
, first_tx
;
199 struct timeval last_rx
, first_rx
;
200 int lastrcvd
= 1; /* last ping sent has been received */
202 static struct timeval jiggle_time
;
203 static int jiggle_cnt
, total_jiggled
, jiggle_direction
= -1;
205 static void doit(void);
206 static void prefinish(int);
207 static void prtsig(int);
208 static void finish(int);
209 static void summary(int);
210 static void pinger(void);
211 static void fill(void);
212 static void rnd_fill(void);
213 static double diffsec(struct timeval
*, struct timeval
*);
214 static void timevaladd(struct timeval
*, struct timeval
*);
215 static void sec_to_timeval(const double, struct timeval
*);
216 static double timeval_to_sec(const struct timeval
*);
217 static void pr_pack(u_char
*, int, struct sockaddr_in
*);
218 static u_int16_t
in_cksum(u_int16_t
*, u_int
);
219 static void pr_saddr(u_char
*);
220 static char *pr_addr(struct in_addr
*);
221 static void pr_iph(struct icmp
*, int);
222 static void pr_retip(struct icmp
*, int);
223 static int pr_icmph(struct icmp
*, struct sockaddr_in
*, int);
224 static void jiggle(int), jiggle_flush(int);
225 static void gethost(const char *, const char *,
226 struct sockaddr_in
*, char *, int);
227 static void usage(void);
230 main(int argc
, char *argv
[])
232 int c
, i
, on
= 1, hostind
= 0;
238 #ifdef IPSEC_POLICY_IPSEC
239 char *policy_in
= NULL
;
240 char *policy_out
= NULL
;
247 if ((s
= socket(AF_INET
, SOCK_RAW
, IPPROTO_ICMP
)) < 0)
248 err(1, "Cannot create socket");
249 if ((sloop
= socket(AF_INET
, SOCK_RAW
, IPPROTO_ICMP
)) < 0)
250 err(1, "Cannot create socket");
253 * sloop is never read on. This prevents packets from
254 * queueing in its recv buffer.
256 if (shutdown(sloop
, SHUT_RD
) == -1)
257 warn("Cannot shutdown for read");
259 if (setuid(getuid()) == -1)
262 setprogname(argv
[0]);
267 #ifdef IPSEC_POLICY_IPSEC
268 #define IPSECOPT "E:"
270 #define IPSECOPT "AE"
271 #endif /*IPSEC_POLICY_IPSEC*/
273 while ((c
= getopt(argc
, argv
,
274 "ac:dDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:" IPSECOPT
)) != -1) {
278 pingflags
|= F_AUDIBLE
;
281 npackets
= strtol(optarg
, &p
, 0);
282 if (*p
!= '\0' || npackets
<= 0)
283 errx(1, "Bad/invalid number of packets");
292 pingflags
|= F_FLOOD
;
297 case 'i': /* wait between sending packets */
298 interval
= strtod(optarg
, &p
);
299 if (*p
!= '\0' || interval
<= 0)
300 errx(1, "Bad/invalid interval %s", optarg
);
303 preload
= strtol(optarg
, &p
, 0);
304 if (*p
!= '\0' || preload
< 0)
305 errx(1, "Bad/invalid preload value %s",
309 pingflags
|= F_NUMERIC
;
314 case 'p': /* fill buffer with user pattern */
315 if (pingflags
& F_PING_RANDOM
)
316 errx(1, "Only one of -P and -p allowed");
317 pingflags
|= F_PING_FILLED
;
321 if (pingflags
& F_PING_FILLED
)
322 errx(1, "Only one of -P and -p allowed");
323 pingflags
|= F_PING_RANDOM
;
326 pingflags
|= F_QUIET
;
329 pingflags
|= F_SEMI_QUIET
;
332 options
|= SO_DONTROUTE
;
334 case 's': /* size of packet to send */
335 l
= strtol(optarg
, &p
, 0);
336 if (*p
!= '\0' || l
< 0)
337 errx(1, "Bad/invalid packet size %s", optarg
);
339 errx(1, "packet size is too large");
343 pingflags
|= F_VERBOSE
;
346 pingflags
|= F_RECORD_ROUTE
;
349 pingflags
|= F_MCAST_NOLOOP
;
352 tos
= strtoul(optarg
, &p
, 0);
353 if (*p
!= '\0' || tos
> 0xFF)
354 errx(1, "bad tos value: %s", optarg
);
357 l
= strtol(optarg
, &p
, 0);
358 if (*p
!= '\0' || l
> 255 || l
<= 0)
359 errx(1, "ttl out of range");
360 ttl
= (u_char
)l
; /* cannot check >255 otherwise */
363 pingflags
|= F_SOURCE_ADDR
;
364 gethost("-I", optarg
, &src_addr
, 0, 0);
367 pingflags
|= F_SOURCE_ROUTE
;
368 gethost("-g", optarg
, &send_addr
, 0, 0);
371 maxwait
= strtod(optarg
, &p
);
372 if (*p
!= '\0' || maxwait
<= 0)
373 errx(1, "Bad/invalid maxwait time %s", optarg
);
376 #ifdef IPSEC_POLICY_IPSEC
378 pingflags
|= F_POLICY
;
379 if (!strncmp("in", optarg
, 2)) {
380 policy_in
= strdup(optarg
);
383 } else if (!strncmp("out", optarg
, 3)) {
384 policy_out
= strdup(optarg
);
388 errx(1, "invalid security policy");
392 pingflags
|= F_AUTHHDR
;
395 pingflags
|= F_ENCRYPT
;
397 #endif /*IPSEC_POLICY_IPSEC*/
406 interval
= (pingflags
& F_FLOOD
) ? FLOOD_INTVL
: 1.0;
408 if (pingflags
& F_FLOOD
&& getuid())
409 errx(1, "Must be superuser to use -f");
410 if (interval
< 1.0 && getuid())
411 errx(1, "Must be superuser to use < 1 sec ping interval");
412 if (preload
> 0 && getuid())
413 errx(1, "Must be superuser to use -l");
415 sec_to_timeval(interval
, &interval_tv
);
417 if ((pingflags
& (F_AUDIBLE
|F_FLOOD
)) == (F_AUDIBLE
|F_FLOOD
))
418 warnx("Sorry, no audible output for flood pings");
427 if (optind
!= argc
-1)
432 else if (hostind
>= argc
- 1)
435 gethost("", argv
[hostind
], &whereto
, hostname
, sizeof(hostname
));
436 if (IN_MULTICAST(ntohl(whereto
.sin_addr
.s_addr
)))
437 pingflags
|= F_MCAST
;
438 if (!(pingflags
& F_SOURCE_ROUTE
))
439 (void) memcpy(&send_addr
, &whereto
, sizeof(send_addr
));
441 loc_addr
.sin_family
= AF_INET
;
442 loc_addr
.sin_len
= sizeof(struct sockaddr_in
);
443 loc_addr
.sin_addr
.s_addr
= htonl((127<<24)+1);
445 if (datalen
>= (int)PHDR_LEN
) /* can we time them? */
446 pingflags
|= F_TIMING
;
447 packlen
= datalen
+ 60 + 76; /* MAXIP + MAXICMP */
448 if ((packet
= (u_char
*)malloc(packlen
)) == NULL
)
449 err(1, "Out of memory");
451 if (pingflags
& F_PING_FILLED
) {
453 } else if (pingflags
& F_PING_RANDOM
) {
456 for (i
= PHDR_LEN
; i
< datalen
; i
++)
457 opack_icmp
.icmp_data
[i
] = i
;
460 ident
= arc4random() & 0xFFFF;
462 if (options
& SO_DEBUG
) {
463 if (setsockopt(s
, SOL_SOCKET
, SO_DEBUG
,
464 (char *)&on
, sizeof(on
)) == -1)
465 warn("Can't turn on socket debugging");
467 if (options
& SO_DONTROUTE
) {
468 if (setsockopt(s
, SOL_SOCKET
, SO_DONTROUTE
,
469 (char *)&on
, sizeof(on
)) == -1)
470 warn("SO_DONTROUTE");
473 if (options
& SO_DEBUG
) {
474 if (setsockopt(sloop
, SOL_SOCKET
, SO_DEBUG
,
475 (char *)&on
, sizeof(on
)) == -1)
476 warn("Can't turn on socket debugging");
478 if (options
& SO_DONTROUTE
) {
479 if (setsockopt(sloop
, SOL_SOCKET
, SO_DONTROUTE
,
480 (char *)&on
, sizeof(on
)) == -1)
481 warn("SO_DONTROUTE");
484 if (pingflags
& F_SOURCE_ROUTE
) {
485 optspace
[IPOPT_OPTVAL
] = IPOPT_LSRR
;
486 optspace
[IPOPT_OLEN
] = optlen
= 7;
487 optspace
[IPOPT_OFFSET
] = IPOPT_MINOFF
;
488 (void)memcpy(&optspace
[IPOPT_MINOFF
-1], &whereto
.sin_addr
,
489 sizeof(whereto
.sin_addr
));
490 optspace
[optlen
++] = IPOPT_NOP
;
492 if (pingflags
& F_RECORD_ROUTE
) {
493 optspace
[optlen
+IPOPT_OPTVAL
] = IPOPT_RR
;
494 optspace
[optlen
+IPOPT_OLEN
] = (MAX_IPOPTLEN
-1-optlen
);
495 optspace
[optlen
+IPOPT_OFFSET
] = IPOPT_MINOFF
;
496 optlen
= MAX_IPOPTLEN
;
498 /* this leaves opack_ip 0(mod 4) aligned */
499 opack_ip
= (struct ip
*)((char *)&out_pack
.o_ip
500 + sizeof(out_pack
.o_opt
)
502 (void) memcpy(opack_ip
+ 1, optspace
, optlen
);
504 if (setsockopt(s
,IPPROTO_IP
,IP_HDRINCL
, (char *) &on
, sizeof(on
)) < 0)
505 err(1, "Can't set special IP header");
507 opack_ip
->ip_v
= IPVERSION
;
508 opack_ip
->ip_hl
= (sizeof(struct ip
)+optlen
) >> 2;
509 opack_ip
->ip_tos
= tos
;
510 opack_ip
->ip_off
= (pingflags
& F_DF
) ? IP_DF
: 0;
511 opack_ip
->ip_ttl
= ttl
? ttl
: MAXTTL
;
512 opack_ip
->ip_p
= IPPROTO_ICMP
;
513 opack_ip
->ip_src
= src_addr
.sin_addr
;
514 opack_ip
->ip_dst
= send_addr
.sin_addr
;
516 if (pingflags
& F_MCAST
) {
517 if (pingflags
& F_MCAST_NOLOOP
) {
519 if (setsockopt(s
, IPPROTO_IP
, IP_MULTICAST_LOOP
,
520 (char *) &loop
, 1) < 0)
521 err(1, "Can't disable multicast loopback");
525 && setsockopt(s
, IPPROTO_IP
, IP_MULTICAST_TTL
,
526 (char *) &ttl
, 1) < 0)
527 err(1, "Can't set multicast time-to-live");
529 if ((pingflags
& F_SOURCE_ADDR
)
530 && setsockopt(s
, IPPROTO_IP
, IP_MULTICAST_IF
,
531 (char *) &src_addr
.sin_addr
,
532 sizeof(src_addr
.sin_addr
)) < 0)
533 err(1, "Can't set multicast source interface");
535 } else if (pingflags
& F_SOURCE_ADDR
) {
536 if (setsockopt(s
, IPPROTO_IP
, IP_MULTICAST_IF
,
537 (char *) &src_addr
.sin_addr
,
538 sizeof(src_addr
.sin_addr
)) < 0)
539 err(1, "Can't set source interface/address");
542 #ifdef IPSEC_POLICY_IPSEC
545 if (pingflags
& F_POLICY
) {
546 if (policy_in
!= NULL
) {
547 buf
= ipsec_set_policy(policy_in
, strlen(policy_in
));
549 errx(1, "%s", ipsec_strerror());
550 if (setsockopt(s
, IPPROTO_IP
, IP_IPSEC_POLICY
,
551 buf
, ipsec_get_policylen(buf
)) < 0) {
552 err(1, "ipsec policy cannot be configured");
556 if (policy_out
!= NULL
) {
557 buf
= ipsec_set_policy(policy_out
, strlen(policy_out
));
559 errx(1, "%s", ipsec_strerror());
560 if (setsockopt(s
, IPPROTO_IP
, IP_IPSEC_POLICY
,
561 buf
, ipsec_get_policylen(buf
)) < 0) {
562 err(1, "ipsec policy cannot be configured");
567 buf
= ipsec_set_policy("out bypass", strlen("out bypass"));
569 errx(1, "%s", ipsec_strerror());
570 if (setsockopt(sloop
, IPPROTO_IP
, IP_IPSEC_POLICY
,
571 buf
, ipsec_get_policylen(buf
)) < 0) {
573 warnx("ipsec is not configured");
575 /* ignore it, should be okay */
583 if (pingflags
& F_AUTHHDR
) {
584 optval
= IPSEC_LEVEL_REQUIRE
;
585 #ifdef IP_AUTH_TRANS_LEVEL
586 (void)setsockopt(s
, IPPROTO_IP
, IP_AUTH_TRANS_LEVEL
,
587 (char *)&optval
, sizeof(optval
));
589 (void)setsockopt(s
, IPPROTO_IP
, IP_AUTH_LEVEL
,
590 (char *)&optval
, sizeof(optval
));
593 if (pingflags
& F_ENCRYPT
) {
594 optval
= IPSEC_LEVEL_REQUIRE
;
595 (void)setsockopt(s
, IPPROTO_IP
, IP_ESP_TRANS_LEVEL
,
596 (char *)&optval
, sizeof(optval
));
598 optval
= IPSEC_LEVEL_BYPASS
;
599 #ifdef IP_AUTH_TRANS_LEVEL
600 (void)setsockopt(sloop
, IPPROTO_IP
, IP_AUTH_TRANS_LEVEL
,
601 (char *)&optval
, sizeof(optval
));
603 (void)setsockopt(sloop
, IPPROTO_IP
, IP_AUTH_LEVEL
,
604 (char *)&optval
, sizeof(optval
));
606 (void)setsockopt(sloop
, IPPROTO_IP
, IP_ESP_TRANS_LEVEL
,
607 (char *)&optval
, sizeof(optval
));
609 #endif /*IPSEC_POLICY_IPSEC*/
612 (void)printf("PING %s (%s): %d data bytes\n", hostname
,
613 inet_ntoa(whereto
.sin_addr
), datalen
);
615 /* When pinging the broadcast address, you can get a lot
616 * of answers. Doing something so evil is useful if you
617 * are trying to stress the ethernet, or just want to
618 * fill the arp cache to get some stuff for /etc/ethers.
620 while (0 > setsockopt(s
, SOL_SOCKET
, SO_RCVBUF
,
621 (char*)&bufspace
, sizeof(bufspace
))) {
622 if ((bufspace
-= 4096) <= 0)
623 err(1, "Cannot set the receive buffer size");
626 /* make it possible to send giant probes, but do not worry now
627 * if it fails, since we probably won't send giant probes.
629 (void)setsockopt(s
, SOL_SOCKET
, SO_SNDBUF
,
630 (char*)&bufspace
, sizeof(bufspace
));
632 (void)signal(SIGINT
, prefinish
);
635 sa
.sa_handler
= prtsig
;
636 sa
.sa_flags
= SA_NOKERNINFO
;
637 sigemptyset(&sa
.sa_mask
);
638 (void)sigaction(SIGINFO
, &sa
, NULL
);
640 (void)signal(SIGQUIT
, prtsig
);
642 (void)signal(SIGCONT
, prtsig
);
644 /* fire off them quickies */
645 for (i
= 0; i
< preload
; i
++) {
646 (void)gettimeofday(&now
, 0);
659 struct sockaddr_in from
;
661 double sec
, last
, d_last
;
662 struct pollfd fdmaskp
[1];
664 (void)gettimeofday(&clear_cache
,0);
666 last
= timeval_to_sec(&clear_cache
) + maxwait
;
670 d_last
= 365*24*60*60;
674 (void)gettimeofday(&now
,0);
677 d_last
= last
- timeval_to_sec(&now
);
679 if (ntransmitted
< npackets
&& d_last
> 0) {
680 /* send if within 100 usec or late for next packet */
681 sec
= diffsec(&next_tx
,&now
);
683 (lastrcvd
&& (pingflags
& F_FLOOD
))) {
685 sec
= diffsec(&next_tx
,&now
);
693 /* For the last response, wait twice as long as the
694 * worst case seen, or 10 times as long as the
695 * maximum interpacket interval, whichever is longer.
697 sec
= MAX(2 * tmax
, 10 * interval
) -
698 diffsec(&now
, &last_tx
);
707 fdmaskp
[0].events
= POLLIN
;
708 cc
= poll(fdmaskp
, 1, (int)(sec
* 1000));
719 fromlen
= sizeof(from
);
720 cc
= recvfrom(s
, (char *) packet
, packlen
,
721 0, (struct sockaddr
*)&from
,
724 if (errno
!= EINTR
) {
727 (void)fflush(stderr
);
731 (void)gettimeofday(&now
, 0);
732 pr_pack(packet
, cc
, &from
);
734 } while (nreceived
< npackets
735 && (nreceived
== 0 || !(pingflags
& F_ONCE
)));
742 jiggle_flush(int nl
) /* new line if there are dots */
746 if (jiggle_cnt
> 0) {
747 total_jiggled
+= jiggle_cnt
;
748 jiggle_direction
= 1;
751 } while (--jiggle_cnt
> 0);
753 } else if (jiggle_cnt
< 0) {
754 total_jiggled
-= jiggle_cnt
;
755 jiggle_direction
= -1;
758 } while (++jiggle_cnt
< 0);
762 if (total_jiggled
!= 0)
765 jiggle_direction
= -1;
768 (void)fflush(stdout
);
769 (void)fflush(stderr
);
775 /* jiggle the cursor for flood-ping
782 if (pingflags
& F_QUIET
)
785 /* do not back up into messages */
786 if (total_jiggled
+jiggle_cnt
+delta
< 0)
791 /* flush the FLOOD dots when things are quiet
792 * or occassionally to make the cursor jiggle.
794 dt
= diffsec(&last_tx
, &jiggle_time
);
795 if (dt
> 0.2 || (dt
>= 0.15 && delta
*jiggle_direction
< 0))
801 * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
802 * will be added on by the kernel. The ID field is our UNIX process ID,
803 * and the sequence number is an ascending integer. The first PHDR_LEN bytes
804 * of the data portion are used to hold a UNIX "timeval" struct in VAX
805 * byte-order, to compute the round-trip time.
813 opack_icmp
.icmp_code
= 0;
814 opack_icmp
.icmp_seq
= htons((u_int16_t
)(ntransmitted
));
816 /* clear the cached route in the kernel after an ICMP
817 * response such as a Redirect is seen to stop causing
818 * more such packets. Also clear the cached route
819 * periodically in case of routing changes that make
820 * black holes come and go.
822 if (clear_cache
.tv_sec
!= now
.tv_sec
) {
823 opack_icmp
.icmp_type
= ICMP_ECHOREPLY
;
824 opack_icmp
.icmp_id
= ~ident
;
825 opack_icmp
.icmp_cksum
= 0;
826 opack_icmp
.icmp_cksum
= in_cksum((u_int16_t
*)&opack_icmp
,
829 if (setsockopt(sloop
,IPPROTO_IP
,IP_HDRINCL
,
830 (char *)&sw
,sizeof(sw
)) < 0)
831 err(1, "Can't turn off special IP header");
832 if (sendto(sloop
, (char *) &opack_icmp
, PHDR_LEN
, MSG_DONTROUTE
,
833 (struct sockaddr
*)&loc_addr
,
834 sizeof(struct sockaddr_in
)) < 0) {
836 * XXX: we only report this as a warning in verbose
837 * mode because people get confused when they see
838 * this error when they are running in single user
839 * mode and they have not configured lo0
841 if (pingflags
& F_VERBOSE
)
842 warn("failed to clear cached route");
845 if (setsockopt(sloop
,IPPROTO_IP
,IP_HDRINCL
,
846 (char *)&sw
, sizeof(sw
)) < 0)
847 err(1, "Can't set special IP header");
849 (void)gettimeofday(&clear_cache
,0);
852 opack_icmp
.icmp_type
= ICMP_ECHO
;
853 opack_icmp
.icmp_id
= ident
;
854 tv32
.tv32_sec
= htonl(now
.tv_sec
);
855 tv32
.tv32_usec
= htonl(now
.tv_usec
);
856 if (pingflags
& F_TIMING
)
857 (void) memcpy(&opack_icmp
.icmp_data
[0], &tv32
, sizeof(tv32
));
858 cc
= datalen
+ PHDR_LEN
;
859 opack_icmp
.icmp_cksum
= 0;
860 opack_icmp
.icmp_cksum
= in_cksum((u_int16_t
*)&opack_icmp
, cc
);
862 cc
+= opack_ip
->ip_hl
<<2;
863 opack_ip
->ip_len
= cc
;
864 i
= sendto(s
, (char *) opack_ip
, cc
, 0,
865 (struct sockaddr
*)&send_addr
, sizeof(struct sockaddr_in
));
871 warnx("wrote %s %d chars, ret=%d", hostname
, cc
, i
);
872 (void)fflush(stderr
);
880 if (next_tx
.tv_sec
== 0) {
885 /* Transmit regularly, at always the same microsecond in the
886 * second when going at one packet per second.
887 * If we are at most 100 ms behind, send extras to get caught up.
888 * Otherwise, skip packets we were too slow to send.
890 if (diffsec(&next_tx
, &now
) <= interval
) {
892 timevaladd(&next_tx
, &interval_tv
);
893 } while (diffsec(&next_tx
, &now
) < -0.1);
896 if (pingflags
& F_FLOOD
)
899 /* While the packet is going out, ready buffer for the next
900 * packet. Use a fast but not very good random number generator.
902 if (pingflags
& F_PING_RANDOM
)
917 if (pingflags
& F_FLOOD
)
920 (void)printf("%d bytes from %s: icmp_seq=%u", cc
, addr
, seqno
);
922 (void)printf(" DUP!");
923 (void)printf(" ttl=%d", ttl
);
924 if (pingflags
& F_TIMING
)
925 (void)printf(" time=%.3f ms", triptime
*1000.0);
928 * Send beep to stderr, since that's more likely than stdout
929 * to go to a terminal..
931 if (pingflags
& F_AUDIBLE
&& !dupflag
)
932 (void)fprintf(stderr
,"\a");
937 * Print out the packet, if it came from us. This logic is necessary
938 * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
939 * which arrive ('tis only fair). This permits multiple copies of this
940 * program to be run without having intermingled output (or statistics!).
945 struct sockaddr_in
*from
)
951 static int old_rrlen
;
952 static char old_rr
[MAX_IPOPTLEN
];
953 int hlen
, dupflag
= 0, dumped
;
954 double triptime
= 0.0;
955 #define PR_PACK_SUB() {if (!dumped) { \
957 pr_pack_sub(net_len, inet_ntoa(from->sin_addr), \
958 ntohs((u_int16_t)icp->icmp_seq), \
959 dupflag, ip->ip_ttl, triptime);}}
961 /* Check the IP header */
962 ip
= (struct ip
*) buf
;
963 hlen
= ip
->ip_hl
<< 2;
964 if (tot_len
< hlen
+ ICMP_MINLEN
) {
965 if (pingflags
& F_VERBOSE
) {
967 (void)printf("packet too short (%d bytes) from %s\n",
968 tot_len
, inet_ntoa(from
->sin_addr
));
973 /* Now the ICMP part */
975 net_len
= tot_len
- hlen
;
976 icp
= (struct icmp
*)(buf
+ hlen
);
977 if (icp
->icmp_type
== ICMP_ECHOREPLY
978 && icp
->icmp_id
== ident
) {
979 if (icp
->icmp_seq
== htons((u_int16_t
)(ntransmitted
-1)))
982 if (first_rx
.tv_sec
== 0)
985 if (pingflags
& F_TIMING
) {
989 (void) memcpy(&tv32
, icp
->icmp_data
, sizeof(tv32
));
990 tv
.tv_sec
= ntohl(tv32
.tv32_sec
);
991 tv
.tv_usec
= ntohl(tv32
.tv32_usec
);
992 triptime
= diffsec(&last_rx
, &tv
);
994 tsumsq
+= triptime
* triptime
;
1001 if (TST(ntohs((u_int16_t
)icp
->icmp_seq
))) {
1002 nrepeats
++, nreceived
--;
1005 SET(ntohs((u_int16_t
)icp
->icmp_seq
));
1008 if (tot_len
!= opack_ip
->ip_len
) {
1010 switch (opack_ip
->ip_len
- tot_len
) {
1012 if ((pongflags
& F_RECORD_ROUTE
) != 0)
1014 if ((pingflags
& F_RECORD_ROUTE
) == 0)
1016 pongflags
|= F_RECORD_ROUTE
;
1017 (void)printf("\nremote host does not "
1018 "support record route");
1021 if ((pongflags
& F_SOURCE_ROUTE
) != 0)
1023 if ((pingflags
& F_SOURCE_ROUTE
) == 0)
1025 pongflags
|= F_SOURCE_ROUTE
;
1026 (void)printf("\nremote host does not "
1027 "support source route");
1031 (void)printf("\nwrong total length %d "
1032 "instead of %d", tot_len
, opack_ip
->ip_len
);
1038 static u_int16_t last_seqno
= 0xffff;
1039 u_int16_t seqno
= ntohs((u_int16_t
)icp
->icmp_seq
);
1040 u_int16_t gap
= seqno
- (last_seqno
+ 1);
1041 if (gap
> 0 && gap
< 0x8000 &&
1042 (pingflags
& F_VERBOSE
)) {
1043 (void)printf("[*** sequence gap of %u "
1044 "packets from %u ... %u ***]\n", gap
,
1045 (u_int16_t
) (last_seqno
+ 1),
1046 (u_int16_t
) (seqno
- 1));
1047 if (pingflags
& F_QUIET
)
1055 if (pingflags
& F_QUIET
)
1058 if (!(pingflags
& F_FLOOD
))
1061 /* check the data */
1062 if (datalen
> (int)PHDR_LEN
1063 && !(pingflags
& F_PING_RANDOM
)
1064 && memcmp(&icp
->icmp_data
[PHDR_LEN
],
1065 &opack_icmp
.icmp_data
[PHDR_LEN
],
1066 datalen
-PHDR_LEN
)) {
1067 for (i
=PHDR_LEN
; i
<datalen
; i
++) {
1068 if (icp
->icmp_data
[i
] !=
1069 opack_icmp
.icmp_data
[i
])
1073 (void)printf("\nwrong data byte #%d should have been"
1074 " %#x but was %#x", i
,
1075 (u_char
)opack_icmp
.icmp_data
[i
],
1076 (u_char
)icp
->icmp_data
[i
]);
1077 for (i
=PHDR_LEN
; i
<datalen
; i
++) {
1078 if ((i
%16) == PHDR_LEN
)
1079 (void)printf("\n\t");
1080 (void)printf("%2x ",(u_char
)icp
->icmp_data
[i
]);
1085 if (!pr_icmph(icp
, from
, net_len
))
1090 /* Display any IP options */
1091 cp
= buf
+ sizeof(struct ip
);
1092 while (hlen
> (int)sizeof(struct ip
)) {
1111 (void)printf("\nLSRR: ");
1119 (void)putchar('\n');
1123 j
= *++cp
; /* get length */
1124 i
= *++cp
; /* and pointer */
1133 && !memcmp(cp
, old_rr
, i
)) {
1135 (void)printf("\t(same route)");
1142 (void) memcpy(old_rr
, cp
, i
);
1146 (void)printf("RR: ");
1149 (void)printf("\nRR: ");
1158 (void)putchar('\n');
1165 (void)printf("\nNOP");
1168 case IPOPT_SECURITY
: /* RFC 1108 RIPSO BSO */
1169 case IPOPT_ESO
: /* RFC 1108 RIPSO ESO */
1170 case IPOPT_CIPSO
: /* Commercial IPSO */
1171 if ((sysconf(_SC_IP_SECOPTS
)) > 0) {
1172 i
= (unsigned)cp
[1];
1175 (void)printf("\nSEC:");
1177 (void)printf(" %02x", *cp
++);
1185 (void)printf("\nunknown option 0x%x", *cp
);
1193 (void)putchar('\n');
1194 (void)fflush(stdout
);
1201 /* Compute the IP checksum
1202 * This assumes the packet is less than 32K long.
1205 in_cksum(u_int16_t
*p
, u_int len
)
1208 int nwords
= len
>> 1;
1210 while (nwords
-- != 0)
1218 u
.c
[0] = *(u_char
*)p
;
1223 /* end-around-carry */
1224 sum
= (sum
>> 16) + (sum
& 0xffff);
1231 * compute the difference of two timevals in seconds
1234 diffsec(struct timeval
*timenow
,
1235 struct timeval
*then
)
1237 return ((timenow
->tv_sec
- then
->tv_sec
)*1.0
1238 + (timenow
->tv_usec
- then
->tv_usec
)/1000000.0);
1243 timevaladd(struct timeval
*t1
,
1247 t1
->tv_sec
+= t2
->tv_sec
;
1248 if ((t1
->tv_usec
+= t2
->tv_usec
) >= 1000000) {
1250 t1
->tv_usec
-= 1000000;
1256 sec_to_timeval(const double sec
, struct timeval
*tp
)
1259 tp
->tv_usec
= (sec
- tp
->tv_sec
) * 1000000.0;
1264 timeval_to_sec(const struct timeval
*tp
)
1266 return tp
->tv_sec
+ tp
->tv_usec
/ 1000000.0;
1272 * Heavily buffered STDIO is used here, so that all the statistics
1273 * will be written with 1 sys-write call. This is nice when more
1274 * than one copy of the program is running on a terminal; it prevents
1275 * the statistics output from becomming intermingled.
1283 (void)printf("\n----%s PING Statistics----\n", hostname
);
1284 (void)printf("%d packets transmitted, ", ntransmitted
);
1285 (void)printf("%d packets received, ", nreceived
);
1287 (void)printf("+%d duplicates, ", nrepeats
);
1289 if (nreceived
> ntransmitted
)
1290 (void)printf("-- somebody's duplicating packets!");
1292 (void)printf("%.1f%% packet loss",
1293 (((ntransmitted
-nreceived
)*100.0) /
1297 if (nreceived
&& (pingflags
& F_TIMING
)) {
1298 double n
= nreceived
+ nrepeats
;
1299 double avg
= (tsum
/ n
);
1300 double variance
= 0.0;
1302 variance
= (tsumsq
- n
*avg
*avg
) /(n
-1);
1304 printf("round-trip min/avg/max/stddev = "
1305 "%.3f/%.3f/%.3f/%.3f ms\n",
1306 tmin
* 1000.0, avg
* 1000.0,
1307 tmax
* 1000.0, sqrt(variance
) * 1000.0);
1308 if (pingflags
& F_FLOOD
) {
1309 double r
= diffsec(&last_rx
, &first_rx
);
1310 double t
= diffsec(&last_tx
, &first_tx
);
1315 (void)printf(" %.1f packets/sec sent, "
1316 " %.1f packets/sec received\n",
1317 ntransmitted
/t
, nreceived
/r
);
1324 * Print statistics when SIGINFO is received.
1333 (void)signal(SIGQUIT
, prtsig
);
1339 * On the first SIGINT, allow any outstanding packets to dribble in
1342 prefinish(int dummy
)
1344 if (lastrcvd
/* quit now if caught up */
1345 || nreceived
== 0) /* or if remote is dead */
1348 (void)signal(dummy
, finish
); /* do this only the 1st time */
1350 if (npackets
> ntransmitted
) /* let the normal limit work */
1351 npackets
= ntransmitted
;
1355 * Print statistics and give up.
1362 (void)signal(SIGINFO
, SIG_DFL
);
1364 (void)signal(SIGQUIT
, SIG_DFL
);
1368 exit(nreceived
> 0 ? 0 : 2);
1372 static int /* 0=do not print it */
1373 ck_pr_icmph(struct icmp
*icp
,
1374 struct sockaddr_in
*from
,
1376 int override
) /* 1=override VERBOSE if interesting */
1379 struct ip ipb
, *ip
= &ipb
;
1380 struct icmp icp2b
, *icp2
= &icp2b
;
1383 if (pingflags
& F_VERBOSE
) {
1390 (void) memcpy(ip
, icp
->icmp_data
, sizeof(*ip
));
1391 hlen
= ip
->ip_hl
<< 2;
1392 if (ip
->ip_p
== IPPROTO_ICMP
1393 && hlen
+ 6 <= cc
) {
1394 (void) memcpy(icp2
, &icp
->icmp_data
[hlen
], sizeof(*icp2
));
1395 if (icp2
->icmp_id
== ident
) {
1396 /* remember to clear route cached in kernel
1397 * if this non-Echo-Reply ICMP message was for one
1400 clear_cache
.tv_sec
= 0;
1402 if (!res
&& override
1403 && (pingflags
& (F_QUIET
|F_SEMI_QUIET
)) == 0) {
1405 (void)printf("%d bytes from %s: ",
1406 cc
, pr_addr(&from
->sin_addr
));
1417 * Print a descriptive string about an ICMP header other than an echo reply.
1419 static int /* 0=printed nothing */
1420 pr_icmph(struct icmp
*icp
,
1421 struct sockaddr_in
*from
,
1424 switch (icp
->icmp_type
) {
1426 if (!ck_pr_icmph(icp
, from
, cc
, 1))
1428 switch (icp
->icmp_code
) {
1429 case ICMP_UNREACH_NET
:
1430 (void)printf("Destination Net Unreachable");
1432 case ICMP_UNREACH_HOST
:
1433 (void)printf("Destination Host Unreachable");
1435 case ICMP_UNREACH_PROTOCOL
:
1436 (void)printf("Destination Protocol Unreachable");
1438 case ICMP_UNREACH_PORT
:
1439 (void)printf("Destination Port Unreachable");
1441 case ICMP_UNREACH_NEEDFRAG
:
1442 (void)printf("frag needed and DF set. Next MTU=%d",
1443 ntohs(icp
->icmp_nextmtu
));
1445 case ICMP_UNREACH_SRCFAIL
:
1446 (void)printf("Source Route Failed");
1448 case ICMP_UNREACH_NET_UNKNOWN
:
1449 (void)printf("Unreachable unknown net");
1451 case ICMP_UNREACH_HOST_UNKNOWN
:
1452 (void)printf("Unreachable unknown host");
1454 case ICMP_UNREACH_ISOLATED
:
1455 (void)printf("Unreachable host isolated");
1457 case ICMP_UNREACH_NET_PROHIB
:
1458 (void)printf("Net prohibited access");
1460 case ICMP_UNREACH_HOST_PROHIB
:
1461 (void)printf("Host prohibited access");
1463 case ICMP_UNREACH_TOSNET
:
1464 (void)printf("Bad TOS for net");
1466 case ICMP_UNREACH_TOSHOST
:
1467 (void)printf("Bad TOS for host");
1470 (void)printf("Communication prohibited");
1473 (void)printf("Host precedence violation");
1476 (void)printf("Precedence cutoff");
1479 (void)printf("Bad Destination Unreachable Code: %d",
1483 /* Print returned IP header information */
1487 case ICMP_SOURCEQUENCH
:
1488 if (!ck_pr_icmph(icp
, from
, cc
, 1))
1490 (void)printf("Source Quench");
1495 if (!ck_pr_icmph(icp
, from
, cc
, 1))
1497 switch (icp
->icmp_code
) {
1498 case ICMP_REDIRECT_NET
:
1499 (void)printf("Redirect Network");
1501 case ICMP_REDIRECT_HOST
:
1502 (void)printf("Redirect Host");
1504 case ICMP_REDIRECT_TOSNET
:
1505 (void)printf("Redirect Type of Service and Network");
1507 case ICMP_REDIRECT_TOSHOST
:
1508 (void)printf("Redirect Type of Service and Host");
1511 (void)printf("Redirect--Bad Code: %d", icp
->icmp_code
);
1514 (void)printf(" New router addr: %s",
1515 pr_addr(&icp
->icmp_hun
.ih_gwaddr
));
1520 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1522 (void)printf("Echo Request: ID=%d seq=%d",
1523 ntohs(icp
->icmp_id
), ntohs(icp
->icmp_seq
));
1526 case ICMP_ECHOREPLY
:
1527 /* displaying other's pings is too noisey */
1529 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1531 (void)printf("Echo Reply: ID=%d seq=%d",
1532 ntohs(icp
->icmp_id
), ntohs(icp
->icmp_seq
));
1538 case ICMP_ROUTERADVERT
:
1539 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1541 (void)printf("Router Discovery Advert");
1544 case ICMP_ROUTERSOLICIT
:
1545 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1547 (void)printf("Router Discovery Solicit");
1551 if (!ck_pr_icmph(icp
, from
, cc
, 1))
1553 switch (icp
->icmp_code
) {
1554 case ICMP_TIMXCEED_INTRANS
:
1555 (void)printf("Time To Live exceeded");
1557 case ICMP_TIMXCEED_REASS
:
1558 (void)printf("Frag reassembly time exceeded");
1561 (void)printf("Time exceeded, Bad Code: %d",
1568 case ICMP_PARAMPROB
:
1569 if (!ck_pr_icmph(icp
, from
, cc
, 1))
1571 (void)printf("Parameter problem: pointer = 0x%02x",
1572 icp
->icmp_hun
.ih_pptr
);
1577 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1579 (void)printf("Timestamp");
1582 case ICMP_TSTAMPREPLY
:
1583 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1585 (void)printf("Timestamp Reply");
1589 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1591 (void)printf("Information Request");
1594 case ICMP_IREQREPLY
:
1595 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1597 (void)printf("Information Reply");
1601 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1603 (void)printf("Address Mask Request");
1606 case ICMP_MASKREPLY
:
1607 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1609 (void)printf("Address Mask Reply");
1613 if (!ck_pr_icmph(icp
, from
, cc
, 0))
1615 (void)printf("Bad ICMP type: %d", icp
->icmp_type
);
1616 if (pingflags
& F_VERBOSE
)
1625 * Print an IP header with options.
1628 pr_iph(struct icmp
*icp
,
1633 struct ip ipb
, *ip
= &ipb
;
1635 (void) memcpy(ip
, icp
->icmp_data
, sizeof(*ip
));
1637 hlen
= ip
->ip_hl
<< 2;
1638 cp
= (u_char
*) &icp
->icmp_data
[20]; /* point to options */
1640 (void)printf("\n Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n");
1641 (void)printf(" %1x %1x %02x %04x %04x",
1642 ip
->ip_v
, ip
->ip_hl
, ip
->ip_tos
, ip
->ip_len
, ip
->ip_id
);
1643 (void)printf(" %1x %04x",
1644 ((ip
->ip_off
)&0xe000)>>13, (ip
->ip_off
)&0x1fff);
1645 (void)printf(" %02x %02x %04x",
1646 ip
->ip_ttl
, ip
->ip_p
, ip
->ip_sum
);
1647 (void)printf(" %15s ",
1648 inet_ntoa(*(struct in_addr
*)&ip
->ip_src
.s_addr
));
1649 (void)printf(" %s ", inet_ntoa(*(struct in_addr
*)&ip
->ip_dst
.s_addr
));
1650 /* dump any option bytes */
1651 while (hlen
-- > 20 && cp
< (u_char
*)icp
+cc
) {
1652 (void)printf("%02x", *cp
++);
1657 * Print an ASCII host address starting from a string of bytes.
1660 pr_saddr(u_char
*cp
)
1663 struct in_addr addr
;
1666 l
= (l
<<8) + (u_char
)*++cp
;
1667 l
= (l
<<8) + (u_char
)*++cp
;
1668 l
= (l
<<8) + (u_char
)*++cp
;
1669 addr
.s_addr
= htonl(l
);
1670 (void)printf("\t%s", (l
== 0) ? "0.0.0.0" : pr_addr(&addr
));
1675 * Return an ASCII host address
1676 * as a dotted quad and optionally with a hostname
1679 pr_addr(struct in_addr
*addr
) /* in network order */
1682 static char buf
[MAXHOSTNAMELEN
+4+16+1];
1684 if ((pingflags
& F_NUMERIC
)
1685 || !(hp
= gethostbyaddr((char *)addr
, sizeof(*addr
), AF_INET
))) {
1686 (void)snprintf(buf
, sizeof(buf
), "%s", inet_ntoa(*addr
));
1688 (void)snprintf(buf
, sizeof(buf
), "%s (%s)", hp
->h_name
,
1696 * Dump some info on a returned (via ICMP) IP packet.
1699 pr_retip(struct icmp
*icp
,
1704 struct ip ipb
, *ip
= &ipb
;
1706 (void) memcpy(ip
, icp
->icmp_data
, sizeof(*ip
));
1708 if (pingflags
& F_VERBOSE
)
1711 hlen
= ip
->ip_hl
<< 2;
1712 cp
= (u_char
*) &icp
->icmp_data
[hlen
];
1714 if (ip
->ip_p
== IPPROTO_TCP
) {
1715 if (pingflags
& F_VERBOSE
)
1716 (void)printf("\n TCP: from port %u, to port %u",
1717 (*cp
*256+*(cp
+1)), (*(cp
+2)*256+*(cp
+3)));
1718 } else if (ip
->ip_p
== IPPROTO_UDP
) {
1719 if (pingflags
& F_VERBOSE
)
1720 (void)printf("\n UDP: from port %u, to port %u",
1721 (*cp
*256+*(cp
+1)), (*(cp
+2)*256+*(cp
+3)));
1722 } else if (ip
->ip_p
== IPPROTO_ICMP
) {
1724 (void) memcpy(&icp2
, cp
, sizeof(icp2
));
1725 if (icp2
.icmp_type
== ICMP_ECHO
) {
1726 if (pingflags
& F_VERBOSE
)
1727 (void)printf("\n ID=%u icmp_seq=%u",
1728 ntohs((u_int16_t
)icp2
.icmp_id
),
1729 ntohs((u_int16_t
)icp2
.icmp_seq
));
1731 (void)printf(" for icmp_seq=%u",
1732 ntohs((u_int16_t
)icp2
.icmp_seq
));
1744 for (cp
= fill_pat
; *cp
!= '\0'; cp
++) {
1745 if (!isxdigit((unsigned char)*cp
))
1748 if (cp
== fill_pat
|| *cp
!= '\0' || (cp
-fill_pat
) > 16*2) {
1749 (void)fflush(stdout
);
1750 errx(1, "\"-p %s\": patterns must be specified with"
1751 " 1-32 hex digits\n",
1755 i
= sscanf(fill_pat
,
1756 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
1757 &pat
[0], &pat
[1], &pat
[2], &pat
[3],
1758 &pat
[4], &pat
[5], &pat
[6], &pat
[7],
1759 &pat
[8], &pat
[9], &pat
[10], &pat
[11],
1760 &pat
[12], &pat
[13], &pat
[14], &pat
[15]);
1762 for (k
=PHDR_LEN
, j
= 0; k
<= datalen
; k
++) {
1763 opack_icmp
.icmp_data
[k
] = pat
[j
];
1768 if (!(pingflags
& F_QUIET
)) {
1769 (void)printf("PATTERN: 0x");
1771 (void)printf("%02x",
1772 (u_char
)opack_icmp
.icmp_data
[PHDR_LEN
+j
]);
1782 static u_int32_t rnd
;
1785 for (i
= PHDR_LEN
; i
< datalen
; i
++) {
1786 rnd
= (3141592621U * rnd
+ 663896637U);
1787 opack_icmp
.icmp_data
[i
] = rnd
>>24;
1793 gethost(const char *arg
,
1795 struct sockaddr_in
*sa
,
1801 (void)memset(sa
, 0, sizeof(*sa
));
1802 sa
->sin_family
= AF_INET
;
1803 sa
->sin_len
= sizeof(struct sockaddr_in
);
1805 /* If it is an IP address, try to convert it to a name to
1806 * have something nice to display.
1808 if (inet_aton(name
, &sa
->sin_addr
) != 0) {
1810 if (pingflags
& F_NUMERIC
)
1813 hp
= gethostbyaddr((char *)&sa
->sin_addr
,
1814 sizeof(sa
->sin_addr
),
1816 (void)strlcpy(realname
, hp
? hp
->h_name
: name
,
1822 hp
= gethostbyname(name
);
1824 errx(1, "Cannot resolve \"%s\" (%s)",name
,hstrerror(h_errno
));
1826 if (hp
->h_addrtype
!= AF_INET
)
1827 errx(1, "%s only supported with IP", arg
);
1829 (void)memcpy(&sa
->sin_addr
, hp
->h_addr
, sizeof(sa
->sin_addr
));
1832 (void)strlcpy(realname
, hp
->h_name
, realname_len
);
1840 #ifdef IPSEC_POLICY_IPSEC
1841 #define IPSECOPT "\n [-E policy] "
1843 #define IPSECOPT "\n [-AE] "
1844 #endif /*IPSEC_POLICY_IPSEC*/
1849 (void)fprintf(stderr
, "usage: \n"
1850 "%s [-adDfLnoPqQrRv] [-c count] [-g gateway] [-h host]"
1851 " [-i interval] [-I addr]\n"
1852 " [-l preload] [-p pattern] [-s size] [-t tos] [-T ttl]"
1853 " [-w maxwait] " IPSECOPT
"host\n",