Update from Vernon Schryver, fixing the kluge to flush the route cache.
This commit is contained in:
parent
079405ea2a
commit
01bf6a0596
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: ping.8,v 1.14 1997/04/10 06:16:06 mikel Exp $
|
||||
.\" $NetBSD: ping.8,v 1.15 1997/06/01 19:34:46 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1985, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -46,15 +46,14 @@ packets to network hosts
|
||||
.Op Fl dfnoqrvDPQRL
|
||||
.Op Fl c Ar count
|
||||
.Op Fl g Ar gateway
|
||||
.Op Fl i Ar wait
|
||||
.Op Fl i Ar interval
|
||||
.Op Fl I Ar ifaddr
|
||||
.Op Fl l Ar preload
|
||||
.Op Fl p Ar pattern
|
||||
.Op Fl s Ar packetsize
|
||||
.Op Fl t Ar ttl
|
||||
.Op Fl t Ar tos
|
||||
.Op Fl T Ar ttl
|
||||
.Op Fl w Ar maxwait
|
||||
.Op Fl I Ar ifaddr
|
||||
.Op Fl S Ar ifaddr
|
||||
.Op Fl T Ar tos
|
||||
.Ar host
|
||||
.Sh DESCRIPTION
|
||||
.Nm Ping
|
||||
@ -87,7 +86,8 @@ option on the socket being used.
|
||||
.It Fl D
|
||||
Set the
|
||||
.Dv Don't Fragment
|
||||
bit.
|
||||
bit in the IP header.
|
||||
This can be used to determine the path MTU.
|
||||
.It Fl f
|
||||
Flood ping.
|
||||
Outputs packets as fast as they come back or one hundred times per second,
|
||||
@ -102,9 +102,13 @@ Only the super-user may use this option.
|
||||
.Bf -emphasis
|
||||
This can be very hard on a network and should be used with caution.
|
||||
.Ef
|
||||
.It Fl i Ar wait
|
||||
.It Fl g Ar gateway
|
||||
Use Lose Source Routing to send the ECHO_REQUEST packets via
|
||||
.Ar gateway .
|
||||
.TP
|
||||
.It Fl i Ar internal
|
||||
Wait
|
||||
.Ar wait
|
||||
.Ar internal
|
||||
seconds
|
||||
.Em between sending each packet .
|
||||
The default is to wait for one second between each packet,
|
||||
@ -112,6 +116,9 @@ except when the -f option is used the wait interval is 0.01 seconds.
|
||||
.It Fl I Ar ifaddr
|
||||
Send multicast datagrams on the network interface specified by the
|
||||
interface's hostname or IP address.
|
||||
.It Fl h Ar host
|
||||
is an alternate way of specifying the target host instead of as the
|
||||
last argument.
|
||||
.It Fl l Ar preload
|
||||
If
|
||||
.Ar preload
|
||||
@ -119,9 +126,12 @@ is specified,
|
||||
.Nm ping
|
||||
sends that many packets as fast as possible before falling into its normal
|
||||
mode of behavior.
|
||||
.It Fl L
|
||||
Disable loopback when sending to multicast destinations,
|
||||
so the transmitting host doesn't see the ICMP requests.
|
||||
.It Fl n
|
||||
Numeric output only.
|
||||
No attempt will be made to lookup symbolic names for host addresses.
|
||||
No attempt will be made to look up symbolic names for host addresses.
|
||||
.It Fl o
|
||||
Exit successfully after receiving one reply packet.
|
||||
.It Fl p Ar pattern
|
||||
@ -131,10 +141,17 @@ For example,
|
||||
.Dq Li \-p ff
|
||||
will cause the sent packet to be filled with all
|
||||
ones.
|
||||
.It Fl P
|
||||
Use a psuedo-random sequence for the data instead of the default,
|
||||
fixed sequence of incrementing 8-bit integers.
|
||||
This is useful to foil compression on PPP and other links.
|
||||
.It Fl q
|
||||
Quiet output.
|
||||
Nothing is displayed except the summary lines at startup time and
|
||||
when finished.
|
||||
.It Fl Q
|
||||
Do not display responses such as Network Unreachable ICMP messages
|
||||
concerning the ECHO_REQUESTs sent.
|
||||
.It Fl R
|
||||
Record route.
|
||||
Includes the
|
||||
@ -152,9 +169,14 @@ If the host is not on a directly-attached network, an error is returned.
|
||||
This option can be used to ping a local host through an interface
|
||||
that has no route through it (e.g., after the interface was dropped by
|
||||
.Xr routed 8 ) .
|
||||
.It Fl S Ar ifaddr
|
||||
Specify the interface to transmit from on machines with multiple
|
||||
interfaces. For unicast pings.
|
||||
.It Fl R
|
||||
Record Route. Includes the RECORD_ROUTE option in the ECHO_REQUEST
|
||||
packet and displays the route buffer on returned packets.
|
||||
Note that the IP header is only large enough for eight such routes,
|
||||
and only six when using the
|
||||
.Fl g
|
||||
option.
|
||||
Many hosts ignore or discard this option.
|
||||
.It Fl s Ar packetsize
|
||||
Specifies the number of data bytes to be sent.
|
||||
The default is 56, which translates into 64
|
||||
@ -163,19 +185,10 @@ data bytes when combined
|
||||
with the 8 bytes of
|
||||
.Tn ICMP
|
||||
header data. The maximum allowed value is 65468 bytes.
|
||||
header data. If the
|
||||
.Fl D
|
||||
or
|
||||
.Fl T
|
||||
options are specified, or the
|
||||
.Fl t
|
||||
option to a unicast destination, a raw socket will be used and the 8 bytes of
|
||||
header data are included in
|
||||
.Ar packetsize .
|
||||
.It Fl t Ar ttl
|
||||
.It Fl T Ar ttl
|
||||
Use the specified time-to-live.
|
||||
.It Fl T Ar tos
|
||||
Use the specified type of service.
|
||||
.It Fl t Ar tos
|
||||
Use the specified hexadecimal type of service.
|
||||
.It Fl v
|
||||
Verbose output.
|
||||
.Tn ICMP
|
||||
@ -187,18 +200,6 @@ Specifies the number of seconds to wait for a response to a packet
|
||||
before transmitting the next one. The default is 10.
|
||||
.El
|
||||
.Pp
|
||||
In addition, the following options may be used for multicast pings:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl L
|
||||
Disable the loopback, so the transmitting host doesn't see the ICMP
|
||||
requests.
|
||||
.It Fl R
|
||||
Record Route. Includes the RECORD_ROUTE option in the ECHO_REQUEST
|
||||
packet and displays the route buffer on returned packets. Note that
|
||||
the IP header is only large enough for six such routes. Many hosts
|
||||
ignore or discard this option.
|
||||
.El
|
||||
.Pp
|
||||
When using
|
||||
.Nm ping
|
||||
for fault isolation, it should first be run on the local host, to verify
|
||||
@ -275,8 +276,8 @@ header).
|
||||
.Pp
|
||||
If the data space is at least eight bytes large,
|
||||
.Nm ping
|
||||
uses the first eight bytes of this space to include a timestamp which
|
||||
it uses in the computation of round trip times.
|
||||
uses the first eight bytes of this space to include a timestamp to compute
|
||||
round trip times.
|
||||
If less than eight bytes of pad are specified, no round trip times are
|
||||
given.
|
||||
.Sh DUPLICATE AND DAMAGED PACKETS
|
||||
@ -386,8 +387,8 @@ Others may use completely wild values.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
returns 0 on success (the host is alive), and non zero if the arguments are
|
||||
incorrect or the host is not responding.
|
||||
returns 0 on success (the host is alive),
|
||||
and non-zero if the arguments are incorrect or the host is not responding.
|
||||
.Sh BUGS
|
||||
Many Hosts and Gateways ignore the
|
||||
.Tn RECORD_ROUTE
|
||||
|
493
sbin/ping/ping.c
493
sbin/ping/ping.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ping.c,v 1.29 1997/04/02 09:22:01 augustss Exp $ */
|
||||
/* $NetBSD: ping.c,v 1.30 1997/06/01 19:34:49 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -60,7 +60,7 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$NetBSD: ping.c,v 1.29 1997/04/02 09:22:01 augustss Exp $";
|
||||
static char rcsid[] = "$NetBSD: ping.c,v 1.30 1997/06/01 19:34:49 christos Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -75,7 +75,6 @@ static char rcsid[] = "$NetBSD: ping.c,v 1.29 1997/04/02 09:22:01 augustss Exp $
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#ifdef sgi
|
||||
@ -107,14 +106,11 @@ static char rcsid[] = "$NetBSD: ping.c,v 1.29 1997/04/02 09:22:01 augustss Exp $
|
||||
#define F_PING_RANDOM 0x0080 /* use random data */
|
||||
#define F_NUMERIC 0x0100 /* do not do gethostbyaddr() calls */
|
||||
#define F_TIMING 0x0200 /* room for a timestamp */
|
||||
#define F_TTL 0x0400 /* Time to live */
|
||||
#define F_HDRINCL 0x0800 /* Include our ip headers */
|
||||
#define F_SOURCE_ADDR 0x1000 /* Source address */
|
||||
#define F_ONCE 0x2000 /* exit(0) after receiving 1 reply */
|
||||
|
||||
#define MULTICAST_NOLOOP 1 /* multicast options */
|
||||
#define MULTICAST_TTL 2
|
||||
#define MULTICAST_IF 4
|
||||
#define F_DF 0x0400 /* set IP DF bit */
|
||||
#define F_SOURCE_ADDR 0x0800 /* set source IP address/interface */
|
||||
#define F_ONCE 0x1000 /* exit(0) after receiving 1 reply */
|
||||
#define F_MCAST 0x2000 /* multicast target */
|
||||
#define F_MCAST_NOLOOP 0x4000 /* no multicast loopback */
|
||||
|
||||
/* MAX_DUP_CHK is the number of bits in received table, the
|
||||
* maximum number of received sequence numbers we can track to check
|
||||
@ -133,30 +129,40 @@ int nrepeats = 0;
|
||||
|
||||
u_char *packet;
|
||||
int packlen;
|
||||
int pingflags = 0, options, moptions;
|
||||
int pingflags = 0, options;
|
||||
char *fill_pat;
|
||||
|
||||
int s; /* Socket file descriptor */
|
||||
|
||||
#define PHDR_LEN sizeof(struct timeval) /* size of timestamp header */
|
||||
struct sockaddr_in whereto, send_addr; /* Who to ping */
|
||||
struct sockaddr_in src_addr; /* from where */
|
||||
struct sockaddr_in loc_addr; /* 127.1 */
|
||||
int datalen = 64-PHDR_LEN; /* How much data */
|
||||
|
||||
#ifdef sgi
|
||||
static char *__progname;
|
||||
#else
|
||||
extern char *__progname;
|
||||
#endif
|
||||
|
||||
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
|
||||
static struct {
|
||||
struct ip o_ip;
|
||||
char o_opt[MAX_IPOPTLEN];
|
||||
union {
|
||||
u_char u_buf[MAXPACKET - sizeof(struct ip)];
|
||||
struct icmp u_icmp;
|
||||
u_char u_buf[MAXPACKET];
|
||||
struct icmp u_icmp;
|
||||
} o_u;
|
||||
} out_pack;
|
||||
#define opack_icmp out_pack.o_u.u_icmp
|
||||
#define opack_ip out_pack.o_ip
|
||||
#define opack_icmp out_pack.o_u.u_icmp
|
||||
struct ip *opack_ip;
|
||||
|
||||
char optspace[MAX_IPOPTLEN]; /* record route space */
|
||||
int optlen;
|
||||
|
||||
|
||||
int npackets; /* total packets to send */
|
||||
int preload; /* number of packets to "preload" */
|
||||
@ -177,8 +183,6 @@ int reset_kerninfo;
|
||||
#endif
|
||||
|
||||
int bufspace = 60*1024;
|
||||
char optspace[MAX_IPOPTLEN]; /* record route space */
|
||||
int optlen;
|
||||
|
||||
struct timeval now, clear_cache, last_tx, next_tx, first_tx;
|
||||
struct timeval last_rx, first_rx;
|
||||
@ -207,32 +211,33 @@ static void pr_iph(struct icmp *, int);
|
||||
static void pr_retip(struct icmp *, int);
|
||||
static int pr_icmph(struct icmp *, struct sockaddr_in *, int);
|
||||
static void jiggle(int), jiggle_flush(int);
|
||||
static void gethost(const char *, struct sockaddr_in *, char *);
|
||||
static void gethost(const char *, const char *,
|
||||
struct sockaddr_in *, char *, int);
|
||||
static void usage(void);
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c, i, on = 1;
|
||||
struct sockaddr_in ifaddr;
|
||||
int c, i, on = 1, hostind = 0;
|
||||
long l;
|
||||
u_char ttl = 0;
|
||||
u_long tos = 0;
|
||||
char *p;
|
||||
u_char ttl = MAXTTL, loop = 1, df = 0;
|
||||
int tos = 0;
|
||||
int mcast;
|
||||
#ifdef SIGINFO
|
||||
struct termios ts;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SIGINFO
|
||||
#if defined(SIGINFO) && defined(NOKERNINFO)
|
||||
if (tcgetattr (0, &ts) != -1) {
|
||||
reset_kerninfo = !(ts.c_lflag & NOKERNINFO);
|
||||
ts.c_lflag |= NOKERNINFO;
|
||||
tcsetattr (0, TCSANOW, &ts);
|
||||
}
|
||||
#endif
|
||||
while ((c = getopt(argc, argv, "c:dDfg:h:i:I:l:Lnop:PqRQrs:t:T:vw:")) != -1) {
|
||||
while ((c = getopt(argc, argv,
|
||||
"c:dDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:")) != -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
npackets = strtol(optarg, &p, 0);
|
||||
@ -240,8 +245,7 @@ main(int argc, char *argv[])
|
||||
errx(1, "Bad/invalid number of packets");
|
||||
break;
|
||||
case 'D':
|
||||
options |= F_HDRINCL;
|
||||
df = -1;
|
||||
pingflags |= F_DF;
|
||||
break;
|
||||
case 'd':
|
||||
options |= SO_DEBUG;
|
||||
@ -249,15 +253,19 @@ main(int argc, char *argv[])
|
||||
case 'f':
|
||||
pingflags |= F_FLOOD;
|
||||
break;
|
||||
case 'h':
|
||||
hostind = optind-1;
|
||||
break;
|
||||
case 'i': /* wait between sending packets */
|
||||
interval = strtod(optarg, &p);
|
||||
if (*p != '\0' || interval <= 0)
|
||||
errx(1, "Bad/invalid interval");
|
||||
errx(1, "Bad/invalid interval %s", optarg);
|
||||
break;
|
||||
case 'l':
|
||||
preload = strtol(optarg, &p, 0);
|
||||
if (*p != '\0' || preload < 0)
|
||||
errx(1, "Bad/invalid preload value");
|
||||
errx(1, "Bad/invalid preload value %s",
|
||||
optarg);
|
||||
break;
|
||||
case 'n':
|
||||
pingflags |= F_NUMERIC;
|
||||
@ -288,7 +296,7 @@ main(int argc, char *argv[])
|
||||
case 's': /* size of packet to send */
|
||||
datalen = strtol(optarg, &p, 0);
|
||||
if (*p != '\0' || datalen <= 0)
|
||||
errx(1, "Bad/invalid packet size");
|
||||
errx(1, "Bad/invalid packet size %s", optarg);
|
||||
if (datalen > MAXPACKET)
|
||||
errx(1, "packet size is too large");
|
||||
break;
|
||||
@ -299,34 +307,31 @@ main(int argc, char *argv[])
|
||||
pingflags |= F_RECORD_ROUTE;
|
||||
break;
|
||||
case 'L':
|
||||
moptions |= MULTICAST_NOLOOP;
|
||||
loop = 0;
|
||||
pingflags |= F_MCAST_NOLOOP;
|
||||
break;
|
||||
case 't':
|
||||
options |= F_TTL;
|
||||
ttl = strtol(optarg, &p, 0);
|
||||
if (*p != '\0' || ttl > 255 || ttl <= 0)
|
||||
errx(1, "Bad/invalid ttl");
|
||||
break;
|
||||
case 'T':
|
||||
options |= F_HDRINCL;
|
||||
tos = strtoul(optarg, NULL, 0);
|
||||
if (tos > 0xFF)
|
||||
tos = strtoul(optarg, &p, 0);
|
||||
if (*p != '\0' || tos > 0xFF)
|
||||
errx(1, "bad tos value: %s", optarg);
|
||||
break;
|
||||
case 'T':
|
||||
l = strtol(optarg, &p, 0);
|
||||
if (*p != '\0' || l > 255 || l <= 0)
|
||||
errx(1, "ttl out of range");
|
||||
ttl = (u_char)l; /* cannot check >255 otherwise */
|
||||
break;
|
||||
case 'I':
|
||||
options |= F_SOURCE_ADDR;
|
||||
gethost(optarg, &ifaddr, NULL);
|
||||
|
||||
pingflags |= F_SOURCE_ADDR;
|
||||
gethost("-I", optarg, &src_addr, 0, 0);
|
||||
break;
|
||||
case 'g':
|
||||
pingflags |= F_SOURCE_ROUTE;
|
||||
gethost(optarg, &send_addr, NULL);
|
||||
gethost("-g", optarg, &send_addr, 0, 0);
|
||||
break;
|
||||
case 'w':
|
||||
maxwait = strtod(optarg, &p);
|
||||
if (*p != '\0' || maxwait <= 0)
|
||||
errx(1, "Bad/invalid maxwait time");
|
||||
errx(1, "Bad/invalid maxwait time %s", optarg);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
@ -348,33 +353,18 @@ main(int argc, char *argv[])
|
||||
npackets = INT_MAX;
|
||||
}
|
||||
|
||||
if (optind != argc-1)
|
||||
if (hostind == 0) {
|
||||
if (optind != argc-1)
|
||||
usage();
|
||||
else
|
||||
hostind = optind;
|
||||
}
|
||||
else if (hostind >= argc - 1)
|
||||
usage();
|
||||
|
||||
gethost(argv[optind], &whereto, hostname);
|
||||
|
||||
mcast = IN_MULTICAST(ntohl(whereto.sin_addr.s_addr));
|
||||
|
||||
if (options & F_SOURCE_ADDR) {
|
||||
if (mcast)
|
||||
moptions |= MULTICAST_IF;
|
||||
else {
|
||||
if (bind(s, (struct sockaddr*) &ifaddr,
|
||||
sizeof(ifaddr)) == -1)
|
||||
err(1, "bind failed");
|
||||
}
|
||||
}
|
||||
if (options & F_TTL) {
|
||||
if (mcast)
|
||||
moptions |= MULTICAST_TTL;
|
||||
else
|
||||
options |= F_HDRINCL;
|
||||
}
|
||||
|
||||
if (options & F_RECORD_ROUTE && options & F_HDRINCL)
|
||||
errx(1, "-R option and -D or -T, or -t to unicast destinations"
|
||||
" are incompatible");
|
||||
|
||||
gethost("", argv[hostind], &whereto, hostname, sizeof(hostname));
|
||||
if (IN_MULTICAST(ntohl(whereto.sin_addr.s_addr)))
|
||||
pingflags |= F_MCAST;
|
||||
if (!(pingflags & F_SOURCE_ROUTE))
|
||||
(void) memcpy(&send_addr, &whereto, sizeof(send_addr));
|
||||
|
||||
@ -398,80 +388,79 @@ main(int argc, char *argv[])
|
||||
|
||||
ident = getpid() & 0xFFFF;
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
|
||||
if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
|
||||
err(1, "Cannot create socket");
|
||||
|
||||
if (options & SO_DEBUG) {
|
||||
if (setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *) &on,
|
||||
sizeof(on)) == -1)
|
||||
err(1, "Can't turn on socket debugging");
|
||||
warn("Can't turn on socket debugging");
|
||||
}
|
||||
if (options & SO_DONTROUTE) {
|
||||
if (setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *) &on,
|
||||
sizeof(on)) == -1)
|
||||
err(1, "Can't turn off socket routing");
|
||||
warn("SO_DONTROUTE");
|
||||
}
|
||||
|
||||
if (options & F_HDRINCL) {
|
||||
if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *) &on,
|
||||
sizeof(on)) == -1)
|
||||
err(1, "Can't set option to include ip headers");
|
||||
|
||||
opack_ip.ip_v = IPVERSION;
|
||||
opack_ip.ip_hl = sizeof(struct ip) >> 2;
|
||||
opack_ip.ip_tos = tos;
|
||||
opack_ip.ip_id = 0;
|
||||
opack_ip.ip_off = (df?IP_DF:0);
|
||||
opack_ip.ip_ttl = ttl;
|
||||
opack_ip.ip_p = IPPROTO_ICMP;
|
||||
opack_ip.ip_src.s_addr = INADDR_ANY;
|
||||
opack_ip.ip_dst = whereto.sin_addr;
|
||||
if (pingflags & F_SOURCE_ROUTE) {
|
||||
optspace[IPOPT_OPTVAL] = IPOPT_LSRR;
|
||||
optspace[IPOPT_OLEN] = optlen = 7;
|
||||
optspace[IPOPT_OFFSET] = IPOPT_MINOFF;
|
||||
(void) memcpy(&whereto.sin_addr, &optspace[IPOPT_MINOFF-1],
|
||||
sizeof(whereto.sin_addr));
|
||||
optspace[optlen++] = IPOPT_NOP;
|
||||
}
|
||||
if (pingflags & F_RECORD_ROUTE) {
|
||||
optspace[optlen+IPOPT_OPTVAL] = IPOPT_RR;
|
||||
optspace[optlen+IPOPT_OLEN] = (MAX_IPOPTLEN -1-optlen);
|
||||
optspace[optlen+IPOPT_OFFSET] = IPOPT_MINOFF;
|
||||
optlen = MAX_IPOPTLEN;
|
||||
}
|
||||
/* this leaves opack_ip 0(mod 4) aligned */
|
||||
opack_ip = (struct ip *)((char *)&out_pack.o_ip
|
||||
+ sizeof(out_pack.o_opt)
|
||||
- optlen);
|
||||
(void) memcpy(opack_ip + 1, optspace, optlen);
|
||||
|
||||
/*
|
||||
* Loose Source Route and Record and Record Route options
|
||||
*/
|
||||
if (0 != (pingflags & (F_RECORD_ROUTE | F_SOURCE_ROUTE))) {
|
||||
if (pingflags & F_SOURCE_ROUTE) {
|
||||
optlen = 7+4;
|
||||
optspace[IPOPT_OPTVAL] = IPOPT_LSRR;
|
||||
optspace[IPOPT_OLEN] = optlen;
|
||||
optspace[IPOPT_OFFSET] = IPOPT_MINOFF;
|
||||
(void) memcpy(&optspace[IPOPT_MINOFF+4-1],
|
||||
&whereto.sin_addr, 4);
|
||||
optspace[optlen++] = IPOPT_NOP;
|
||||
if (setsockopt(s,IPPROTO_IP,IP_HDRINCL, (char *) &on, sizeof(on)) < 0)
|
||||
err(1, "Can't set special IP header");
|
||||
|
||||
opack_ip->ip_v = IPVERSION;
|
||||
opack_ip->ip_hl = (sizeof(struct ip)+optlen) >> 2;
|
||||
opack_ip->ip_tos = tos;
|
||||
opack_ip->ip_off = (pingflags & F_DF) ? IP_DF : 0;
|
||||
opack_ip->ip_ttl = ttl ? ttl : MAXTTL;
|
||||
opack_ip->ip_p = IPPROTO_ICMP;
|
||||
opack_ip->ip_src = src_addr.sin_addr;
|
||||
opack_ip->ip_dst = send_addr.sin_addr;
|
||||
|
||||
if (pingflags & F_MCAST) {
|
||||
if (pingflags & F_MCAST_NOLOOP) {
|
||||
u_char loop = 0;
|
||||
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP,
|
||||
(char *) &loop, 1) < 0)
|
||||
err(1, "Can't disable multicast loopback");
|
||||
}
|
||||
if (pingflags & F_RECORD_ROUTE) {
|
||||
optspace[optlen+IPOPT_OPTVAL] = IPOPT_RR;
|
||||
optspace[optlen+IPOPT_OLEN] = (sizeof(optspace)
|
||||
-1-optlen);
|
||||
optspace[optlen+IPOPT_OFFSET] = IPOPT_MINOFF;
|
||||
optlen = sizeof(optspace);
|
||||
}
|
||||
if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, optspace,
|
||||
optlen) == -1)
|
||||
err(1, "Can't set source/record routing");
|
||||
}
|
||||
|
||||
if (moptions & MULTICAST_NOLOOP) {
|
||||
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP,
|
||||
(char *) &loop, 1) == -1)
|
||||
err(1, "Can't disable multicast loopback");
|
||||
}
|
||||
if (moptions & MULTICAST_TTL) {
|
||||
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,
|
||||
(char *) &ttl, 1) == -1)
|
||||
if (ttl != 0
|
||||
&& setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,
|
||||
(char *) &ttl, 1) < 0)
|
||||
err(1, "Can't set multicast time-to-live");
|
||||
}
|
||||
if (moptions & MULTICAST_IF) {
|
||||
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *) &ifaddr.sin_addr, sizeof(ifaddr.sin_addr)) == -1)
|
||||
|
||||
if ((pingflags & F_SOURCE_ADDR)
|
||||
&& setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *) &src_addr.sin_addr,
|
||||
sizeof(src_addr.sin_addr)) < 0)
|
||||
err(1, "Can't set multicast source interface");
|
||||
|
||||
} else if (pingflags & F_SOURCE_ADDR) {
|
||||
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *) &src_addr.sin_addr,
|
||||
sizeof(src_addr.sin_addr)) < 0)
|
||||
err(1, "Can't set source interface/address");
|
||||
}
|
||||
|
||||
(void)printf("PING %s (%s): %d data bytes\n", hostname,
|
||||
inet_ntoa(whereto.sin_addr),
|
||||
datalen);
|
||||
inet_ntoa(whereto.sin_addr), datalen);
|
||||
|
||||
/* When pinging the broadcast address, you can get a lot
|
||||
* of answers. Doing something so evil is useful if you
|
||||
@ -484,10 +473,11 @@ main(int argc, char *argv[])
|
||||
err(1, "Cannot set the receive buffer size");
|
||||
}
|
||||
|
||||
/* make it possible to send giant probes */
|
||||
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&bufspace,
|
||||
sizeof(bufspace)) == -1)
|
||||
err(1, "Cannot set the send buffer size");
|
||||
/* make it possible to send giant probes, but do not worry now
|
||||
* if it fails, since we probably won't send giant probes.
|
||||
*/
|
||||
(void)setsockopt(s, SOL_SOCKET, SO_SNDBUF,
|
||||
(char*)&bufspace, sizeof(bufspace));
|
||||
|
||||
(void)signal(SIGINT, prefinish);
|
||||
#ifdef SIGINFO
|
||||
@ -499,7 +489,7 @@ main(int argc, char *argv[])
|
||||
|
||||
#ifdef sgi
|
||||
/* run with a non-degrading priority to improve the delay values. */
|
||||
(void)schedctl(NDPRI, 0, NDPHIMAX);
|
||||
(void) cap_schedctl(NDPRI, 0, NDPHIMAX);
|
||||
#endif
|
||||
|
||||
/* fire off them quickies */
|
||||
@ -519,50 +509,50 @@ doit(void)
|
||||
int cc;
|
||||
struct sockaddr_in from;
|
||||
int fromlen;
|
||||
double sec;
|
||||
double sec, last, d_last;
|
||||
struct timeval timeout;
|
||||
fd_set fdmask;
|
||||
double last = 0;
|
||||
|
||||
|
||||
(void)gettimeofday(&clear_cache, 0);
|
||||
(void)gettimeofday(&clear_cache,0);
|
||||
if (maxwait != 0) {
|
||||
last = timeval_to_sec(&clear_cache) + maxwait;
|
||||
d_last = 0;
|
||||
} else {
|
||||
last = 0;
|
||||
d_last = 365*24*60*60;
|
||||
}
|
||||
|
||||
FD_ZERO(&fdmask);
|
||||
for (;;) {
|
||||
(void)gettimeofday(&now, 0);
|
||||
do {
|
||||
(void)gettimeofday(&now,0);
|
||||
|
||||
if (maxwait != 0) {
|
||||
if (last == 0)
|
||||
last = timeval_to_sec(&now) + maxwait;
|
||||
else if (last <= timeval_to_sec(&now))
|
||||
finish(0);
|
||||
}
|
||||
if (last != 0)
|
||||
d_last = last - timeval_to_sec(&now);
|
||||
|
||||
if (ntransmitted < npackets) {
|
||||
if (ntransmitted < npackets && d_last > 0) {
|
||||
/* send if within 100 usec or late for next packet */
|
||||
sec = diffsec(&next_tx, &now);
|
||||
sec = diffsec(&next_tx,&now);
|
||||
if (sec <= 0.0001
|
||||
|| (lastrcvd && (pingflags & F_FLOOD))) {
|
||||
pinger();
|
||||
sec = diffsec(&next_tx, &now);
|
||||
sec = diffsec(&next_tx,&now);
|
||||
}
|
||||
if (sec < 0.0)
|
||||
sec = 0.0;
|
||||
if (d_last < sec)
|
||||
sec = d_last;
|
||||
|
||||
} else {
|
||||
/* For the last response, wait twice as long as the
|
||||
* worst case seen, or 10 times as long as the
|
||||
* maximum interpacket interval, whichever is longer.
|
||||
*/
|
||||
if (2 * tmax > 10 * interval)
|
||||
sec = 2 * tmax;
|
||||
else
|
||||
sec = 10 * interval;
|
||||
|
||||
sec -= diffsec(&now, &last_tx);
|
||||
|
||||
sec = MAX(2*tmax,10*interval) - diffsec(&now,&last_tx);
|
||||
if (d_last < sec)
|
||||
sec = d_last;
|
||||
if (sec <= 0)
|
||||
finish(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -575,7 +565,7 @@ doit(void)
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
jiggle_flush(1);
|
||||
err(1, "select failed");
|
||||
err(1, "select");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -587,19 +577,18 @@ doit(void)
|
||||
if (cc < 0) {
|
||||
if (errno != EINTR) {
|
||||
jiggle_flush(1);
|
||||
warn("recvfrom failed");
|
||||
warn("recvfrom");
|
||||
(void)fflush(stderr);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
(void)gettimeofday(&now, 0);
|
||||
pr_pack(packet, cc, &from);
|
||||
if (nreceived >= npackets)
|
||||
finish(0);
|
||||
if (nreceived > 0 && (pingflags & F_ONCE))
|
||||
finish(0);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
|
||||
} while (nreceived < npackets
|
||||
&& (nreceived == 0 || !(pingflags & F_ONCE)));
|
||||
|
||||
finish(0);
|
||||
}
|
||||
|
||||
|
||||
@ -672,64 +661,57 @@ jiggle(int delta)
|
||||
static void
|
||||
pinger(void)
|
||||
{
|
||||
int i, cc;
|
||||
void *packet = &opack_icmp;
|
||||
int i, cc, sw;
|
||||
|
||||
opack_icmp.icmp_code = 0;
|
||||
opack_icmp.icmp_seq = htons((u_short)(ntransmitted));
|
||||
|
||||
/* clear the cached route in the kernel after an ICMP
|
||||
* response such as a Redirect is seen to stop causing
|
||||
* more such packets. Also clear the cached route
|
||||
* periodically in case of routing changes that make
|
||||
* black holes come and go.
|
||||
*/
|
||||
if (clear_cache.tv_sec != now.tv_sec) {
|
||||
/* clear the cached route in the kernel after an ICMP
|
||||
* response such as a Redirect is seen to stop causing
|
||||
* more such packets. Also clear the cached route
|
||||
* periodically in case of routing changes that make
|
||||
* black holes come and go.
|
||||
*/
|
||||
opack_icmp.icmp_type = ICMP_ECHOREPLY;
|
||||
opack_icmp.icmp_id = ~ident;
|
||||
opack_icmp.icmp_cksum = 0;
|
||||
opack_icmp.icmp_cksum = in_cksum((u_short*)&opack_icmp,
|
||||
PHDR_LEN);
|
||||
if (optlen != 0 &&
|
||||
setsockopt(s, IPPROTO_IP, IP_OPTIONS, optspace, 0) == -1)
|
||||
err(1, "Record/Source Route");
|
||||
if (options & F_HDRINCL) {
|
||||
packet = &opack_ip;
|
||||
cc = sizeof(struct ip) + PHDR_LEN;
|
||||
opack_ip.ip_len = cc;
|
||||
opack_ip.ip_sum = in_cksum((u_short *)&opack_ip, cc);
|
||||
}
|
||||
else
|
||||
cc = PHDR_LEN;
|
||||
(void) sendto(s, packet, cc, MSG_DONTROUTE,
|
||||
(struct sockaddr *)&loc_addr, sizeof(struct sockaddr_in));
|
||||
if (optlen != 0 && setsockopt(s, IPPROTO_IP, IP_OPTIONS,
|
||||
optspace, optlen) == -1)
|
||||
err(1, "Record/Source Route");
|
||||
PHDR_LEN);
|
||||
sw = 0;
|
||||
if (setsockopt(s,IPPROTO_IP,IP_HDRINCL,
|
||||
(char *)&sw,sizeof(sw)) < 0)
|
||||
err(1, "Can't turn off special IP header");
|
||||
if (sendto(s, (char *) &opack_icmp, PHDR_LEN, MSG_DONTROUTE,
|
||||
(struct sockaddr *)&loc_addr,
|
||||
sizeof(struct sockaddr_in)) < 0)
|
||||
err(1, "failed to clear cached route");
|
||||
sw = 1;
|
||||
if (setsockopt(s,IPPROTO_IP,IP_HDRINCL,
|
||||
(char *)&sw, sizeof(sw)) < 0)
|
||||
err(1, "Can't set special IP header");
|
||||
|
||||
(void)gettimeofday(&clear_cache,0);
|
||||
}
|
||||
|
||||
opack_icmp.icmp_type = ICMP_ECHO;
|
||||
opack_icmp.icmp_id = ident;
|
||||
if (pingflags & F_TIMING)
|
||||
(void) memcpy(opack_icmp.icmp_data, &now, sizeof(now));
|
||||
(void) memcpy(&opack_icmp.icmp_data[0], &now, sizeof(now));
|
||||
cc = datalen+PHDR_LEN;
|
||||
opack_icmp.icmp_cksum = 0;
|
||||
opack_icmp.icmp_cksum = in_cksum((u_short*)&opack_icmp, cc);
|
||||
|
||||
if (options & F_HDRINCL) {
|
||||
packet = &opack_ip;
|
||||
cc += sizeof(struct ip);
|
||||
opack_ip.ip_len = cc;
|
||||
opack_ip.ip_sum = in_cksum((u_short *)&opack_ip, cc);
|
||||
}
|
||||
i = sendto(s, packet, cc, 0, (struct sockaddr *)&send_addr,
|
||||
sizeof(struct sockaddr_in));
|
||||
cc += opack_ip->ip_hl<<2;
|
||||
opack_ip->ip_len = cc;
|
||||
i = sendto(s, (char *) opack_ip, cc, 0,
|
||||
(struct sockaddr *)&send_addr, sizeof(struct sockaddr_in));
|
||||
if (i != cc) {
|
||||
jiggle_flush(1);
|
||||
if (i < 0)
|
||||
warn("sendto failed");
|
||||
warn("sendto");
|
||||
else
|
||||
(void) fprintf(stderr,
|
||||
"%s: wrote %s %d chars, ret=%d\n", __progname,
|
||||
hostname, cc, i);
|
||||
warnx("wrote %s %d chars, ret=%d", hostname, cc, i);
|
||||
(void)fflush(stderr);
|
||||
}
|
||||
lastrcvd = 0;
|
||||
@ -779,11 +761,11 @@ pr_pack_sub(int cc,
|
||||
return;
|
||||
|
||||
(void)printf("%d bytes from %s: icmp_seq=%u", cc, addr, seqno);
|
||||
if (dupflag)
|
||||
(void)printf(" DUP!");
|
||||
(void)printf(" ttl=%d", ttl);
|
||||
if (pingflags & F_TIMING)
|
||||
(void)printf(" time=%.3f ms", triptime*1000.0);
|
||||
if (dupflag)
|
||||
(void)printf(" (DUP!)");
|
||||
}
|
||||
|
||||
|
||||
@ -808,8 +790,8 @@ pr_pack(u_char *buf,
|
||||
double triptime = 0.0;
|
||||
#define PR_PACK_SUB() {if (!dumped) { \
|
||||
dumped = 1; \
|
||||
pr_pack_sub(cc, inet_ntoa(from->sin_addr), \
|
||||
ntohs((u_short)icp->icmp_seq), \
|
||||
pr_pack_sub(cc, inet_ntoa(from->sin_addr), \
|
||||
ntohs((u_short)icp->icmp_seq), \
|
||||
dupflag, ip->ip_ttl, triptime);}}
|
||||
|
||||
/* Check the IP header */
|
||||
@ -841,7 +823,6 @@ pr_pack(u_char *buf,
|
||||
struct timeval tv;
|
||||
(void) memcpy(&tv, icp->icmp_data, sizeof(tv));
|
||||
triptime = diffsec(&last_rx, &tv);
|
||||
|
||||
tsum += triptime;
|
||||
if (triptime < tmin)
|
||||
tmin = triptime;
|
||||
@ -852,8 +833,9 @@ pr_pack(u_char *buf,
|
||||
if (TST(ntohs((u_short)icp->icmp_seq))) {
|
||||
nrepeats++, nreceived--;
|
||||
dupflag=1;
|
||||
} else
|
||||
} else {
|
||||
SET(ntohs((u_short)icp->icmp_seq));
|
||||
}
|
||||
|
||||
if (pingflags & F_QUIET)
|
||||
return;
|
||||
@ -864,7 +846,7 @@ pr_pack(u_char *buf,
|
||||
/* check the data */
|
||||
if (datalen > PHDR_LEN
|
||||
&& !(pingflags & F_PING_RANDOM)
|
||||
&& bcmp(&icp->icmp_data[PHDR_LEN],
|
||||
&& memcmp(&icp->icmp_data[PHDR_LEN],
|
||||
&opack_icmp.icmp_data[PHDR_LEN],
|
||||
datalen-PHDR_LEN)) {
|
||||
for (i=PHDR_LEN; i<datalen; i++) {
|
||||
@ -880,7 +862,7 @@ pr_pack(u_char *buf,
|
||||
for (i=PHDR_LEN; i<datalen; i++) {
|
||||
if ((i%16) == PHDR_LEN)
|
||||
(void)printf("\n\t");
|
||||
(void)printf("%2x ", (u_char)icp->icmp_data[i]);
|
||||
(void)printf("%2x ",(u_char)icp->icmp_data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -933,7 +915,7 @@ pr_pack(u_char *buf,
|
||||
continue;
|
||||
if (dumped <= 1) {
|
||||
if (i == old_rrlen
|
||||
&& !bcmp(cp, old_rr, i)) {
|
||||
&& !memcmp(cp, old_rr, i)) {
|
||||
if (dumped)
|
||||
(void)printf("\t(same route)");
|
||||
j = ((i+3)/4)*4;
|
||||
@ -942,7 +924,7 @@ pr_pack(u_char *buf,
|
||||
break;
|
||||
}
|
||||
old_rrlen = i;
|
||||
bcopy(cp, old_rr, i);
|
||||
(void) memcpy(old_rr, cp, i);
|
||||
}
|
||||
if (!dumped) {
|
||||
jiggle_flush(1);
|
||||
@ -1059,7 +1041,7 @@ timevaladd(struct timeval *t1,
|
||||
static void
|
||||
sec_to_timeval(const double sec, struct timeval *tp)
|
||||
{
|
||||
tp->tv_sec = (long) sec;
|
||||
tp->tv_sec = sec;
|
||||
tp->tv_usec = (sec - tp->tv_sec) * 1000000.0;
|
||||
}
|
||||
|
||||
@ -1157,7 +1139,7 @@ prefinish(int s)
|
||||
static void
|
||||
finish(int s)
|
||||
{
|
||||
#ifdef SIGINFO
|
||||
#if defined(SIGINFO) && defined(NOKERNINFO)
|
||||
struct termios ts;
|
||||
|
||||
if (reset_kerninfo && tcgetattr (0, &ts) != -1) {
|
||||
@ -1170,7 +1152,7 @@ finish(int s)
|
||||
#endif
|
||||
|
||||
summary(1);
|
||||
exit(nreceived > 0 ? 0 : 1);
|
||||
exit(nreceived > 0 ? 0 : 2);
|
||||
}
|
||||
|
||||
|
||||
@ -1439,7 +1421,7 @@ pr_iph(struct icmp *icp,
|
||||
(void) memcpy(&ip, icp->icmp_data, sizeof(ip));
|
||||
|
||||
hlen = ip.ip_hl << 2;
|
||||
cp = &icp->icmp_data[20]; /* point to options */
|
||||
cp = (u_char *) &icp->icmp_data[20]; /* point to options */
|
||||
|
||||
(void)printf("\n Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n");
|
||||
(void)printf(" %1x %1x %02x %04x %04x",
|
||||
@ -1504,7 +1486,7 @@ pr_retip(struct icmp *icp,
|
||||
int cc)
|
||||
{
|
||||
int hlen;
|
||||
unsigned char *cp;
|
||||
u_char *cp;
|
||||
struct ip ip;
|
||||
|
||||
(void) memcpy(&ip, icp->icmp_data, sizeof(ip));
|
||||
@ -1513,7 +1495,7 @@ pr_retip(struct icmp *icp,
|
||||
pr_iph(icp, cc);
|
||||
|
||||
hlen = ip.ip_hl << 2;
|
||||
cp = &icp->icmp_data[hlen];
|
||||
cp = (u_char *) &icp->icmp_data[hlen];
|
||||
|
||||
if (ip.ip_p == IPPROTO_TCP) {
|
||||
if (pingflags & F_VERBOSE)
|
||||
@ -1551,9 +1533,9 @@ fill(void)
|
||||
}
|
||||
if (cp == fill_pat || *cp != '\0' || (cp-fill_pat) > 16*2) {
|
||||
(void)fflush(stdout);
|
||||
errx(1,
|
||||
"\"-p %s\": patterns must be specified with 1-32 hex digits\n",
|
||||
fill_pat);
|
||||
errx(1, "\"-p %s\": patterns must be specified with"
|
||||
" 1-32 hex digits\n",
|
||||
fill_pat);
|
||||
}
|
||||
|
||||
i = sscanf(fill_pat,
|
||||
@ -1593,46 +1575,59 @@ rnd_fill(void)
|
||||
}
|
||||
|
||||
static void
|
||||
gethost(const char *name, struct sockaddr_in *sa, char *realname)
|
||||
gethost(const char *arg,
|
||||
const char *name,
|
||||
struct sockaddr_in *sa,
|
||||
char *realname,
|
||||
int realname_len)
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct hostent *hp;
|
||||
|
||||
(void) memset(sa, 0, sizeof(*sa));
|
||||
sa->sin_family = AF_INET;
|
||||
bzero(sa, sizeof(*sa));
|
||||
sa->sin_family = AF_INET;
|
||||
|
||||
if (inet_aton(name, &sa->sin_addr) != 0) {
|
||||
if (realname == NULL)
|
||||
/* If it is an IP address, try to convert it to a name to
|
||||
* have something nice to display.
|
||||
*/
|
||||
if (inet_aton(name, &sa->sin_addr) != 0) {
|
||||
if (realname) {
|
||||
if (pingflags & F_NUMERIC)
|
||||
hp = 0;
|
||||
else
|
||||
hp = gethostbyaddr((char *)&sa->sin_addr,
|
||||
sizeof(sa->sin_addr),
|
||||
AF_INET);
|
||||
(void)strncpy(realname, hp ? hp->h_name : name,
|
||||
realname_len);
|
||||
realname[realname_len-1] = '\0';
|
||||
}
|
||||
return;
|
||||
if ((pingflags & F_NUMERIC)
|
||||
|| !(hp = gethostbyaddr((char *) &sa->sin_addr,
|
||||
sizeof(sa->sin_addr), AF_INET)))
|
||||
(void) strncpy(realname, name, MAXHOSTNAMELEN);
|
||||
else
|
||||
(void) strncpy(realname, hp->h_name, MAXHOSTNAMELEN);
|
||||
realname[MAXHOSTNAMELEN-1] = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hp = gethostbyname(name);
|
||||
if (hp) {
|
||||
if (hp->h_addrtype != AF_INET)
|
||||
errx(1, "`%s' only supported with IP", name);
|
||||
(void) memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
|
||||
if (realname == NULL)
|
||||
return;
|
||||
(void) strncpy(realname, hp->h_name, MAXHOSTNAMELEN);
|
||||
realname[MAXHOSTNAMELEN-1] = '\0';
|
||||
} else
|
||||
errx(1, "Cannot resolve host `%s' (%s)", name,
|
||||
hstrerror(h_errno));
|
||||
hp = gethostbyname(name);
|
||||
if (!hp)
|
||||
errx(1, "Cannot resolve \"%s\" (%s)",name,hstrerror(h_errno));
|
||||
|
||||
if (hp->h_addrtype != AF_INET)
|
||||
errx(1, "%s only supported with IP", arg);
|
||||
|
||||
bcopy(hp->h_addr, &sa->sin_addr, sizeof(sa->sin_addr));
|
||||
|
||||
if (realname) {
|
||||
(void)strncpy(realname, hp->h_name, realname_len);
|
||||
realname[realname_len-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr, "Usage: %s %s\n%s\n", __progname,
|
||||
"[-dfnoqrvRLP] [-c count] [-s size] [-l preload] [-p pattern]",
|
||||
"[-i interval] [-T ttl] [-I addr] [-g gateway] [-w maxwait] host");
|
||||
(void)fprintf(stderr, "Usage: \n"
|
||||
"%s [-dDfnqrvRLP] [-c count] [-s size] [-l preload]"
|
||||
" [-p pattern]\n"
|
||||
" [-i interval] [-i maxwait] [-t tos] [-T ttl]"
|
||||
" [-I addr] [-g gateway] host\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user