ping: split the visual part of -f into a new option -.

After this, we'll be able to ping a host and not spam the terminal, and
no flooding will have to be involved. I've been doing this under Linux
as ping -fi1 host.

Reviewed by:	rpokala, Pau Amma
Differential Revision:	https://reviews.freebsd.org/D34882
This commit is contained in:
Piotr Pawel Stefaniak 2022-04-11 16:58:24 +02:00
parent 0a5c04a892
commit d399eb3ef7
4 changed files with 59 additions and 18 deletions

View File

@ -40,7 +40,7 @@
#else
#define PING4ADDOPTS
#endif
#define PING4OPTS "4AaC:c:DdfG:g:Hh:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:" PING4ADDOPTS
#define PING4OPTS ".::4AaC:c:DdfG:g:Hh:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:" PING4ADDOPTS
#if defined(INET6) && defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
#define PING6ADDOPTS "P:"
@ -49,7 +49,7 @@
#else
#define PING6ADDOPTS
#endif
#define PING6OPTS "6Aab:C:c:Dde:fHI:i:k:l:m:nNoOp:qS:s:t:uvyYW:z:" PING6ADDOPTS
#define PING6OPTS ".::6Aab:C:c:Dde:fHI:i:k:l:m:nNoOp:qS:s:t:uvyYW:z:" PING6ADDOPTS
void usage(void) __dead2;

View File

@ -41,6 +41,7 @@ packets to network hosts
.Sh SYNOPSIS
.Nm
.Op Fl 4AaDdfHnoQqRrv
.Op Fl .\& Ns Ar chars
.Op Fl C Ar pcp
.Op Fl c Ar count
.Op Fl G Ar sweepmaxsize
@ -60,6 +61,7 @@ packets to network hosts
.Ar IPv4-host
.Nm
.Op Fl 4AaDdfHLnoQqRrv
.Op Fl .\& Ns Ar chars
.Op Fl C Ar pcp
.Op Fl c Ar count
.Op Fl I Ar iface
@ -78,6 +80,7 @@ packets to network hosts
.Ar IPv4-mcast-group
.Nm
.Op Fl 6AaDdEfHNnOoquvYyZ
.Op Fl .\& Ns Ar chars
.Op Fl b Ar bufsiz
.Op Fl c Ar count
.Op Fl e Ar gateway
@ -145,6 +148,22 @@ as
.Nm ping6 .
.Ss Options common to both IPv4 and IPv6 targets
.Bl -tag -width indent
.It Fl .\& Ns Ar chars
By default, for every
.Tn ECHO_REQUEST
sent, a period
.Dq .\&
is printed, while for every
.Tn ECHO_REPLY
received, a backspace is printed.
This option takes an optional string argument listing characters
that will be printed one by one in the provided order
instead of the default period.
.Pp
Example usage:
.Bd -literal -offset indent
ping -.0123456789 freebsd.org
.Ed
.It Fl A
Audible.
Output a bell
@ -188,13 +207,13 @@ option on the socket being used.
Flood ping.
Outputs packets as fast as they come back or one hundred times per second,
whichever is more.
For every
Implies
.Fl .\&
to print a period for every
.Tn ECHO_REQUEST
sent a period
.Dq .\&
is printed, while for every
sent and a backspace for every
.Tn ECHO_REPLY
received a backspace is printed.
received.
This provides a rapid display of how many packets are being dropped.
Only the super-user may use this option.
.Bf -emphasis

View File

@ -158,6 +158,7 @@ static int options;
#define F_SWEEP 0x200000
#define F_WAITTIME 0x400000
#define F_IP_VLAN_PCP 0x800000
#define F_DOT 0x1000000
/*
* MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
@ -176,7 +177,9 @@ static int srecv; /* receive socket file descriptor */
static u_char outpackhdr[IP_MAXPACKET], *outpack;
static char BBELL = '\a'; /* characters written for MISSED and AUDIBLE */
static char BSPACE = '\b'; /* characters written for flood */
static char DOT = '.';
static const char *DOT = ".";
static size_t DOTlen = 1;
static size_t DOTidx = 0;
static char *hostname;
static char *shostname;
static int ident; /* process id to identify our packets */
@ -303,6 +306,13 @@ ping(int argc, char *const *argv)
outpack = outpackhdr + sizeof(struct ip);
while ((ch = getopt(argc, argv, PING4OPTS)) != -1) {
switch(ch) {
case '.':
options |= F_DOT;
if (optarg != NULL) {
DOT = optarg;
DOTlen = strlen(optarg);
}
break;
case '4':
/* This option is processed in main(). */
break;
@ -340,6 +350,7 @@ ping(int argc, char *const *argv)
err(EX_NOPERM, "-f flag");
}
options |= F_FLOOD;
options |= F_DOT;
setbuf(stdout, (char *)NULL);
break;
case 'G': /* Maximum packet size for ping sweep */
@ -1114,8 +1125,8 @@ pinger(void)
}
ntransmitted++;
sntransmitted++;
if (!(options & F_QUIET) && options & F_FLOOD)
(void)write(STDOUT_FILENO, &DOT, 1);
if (!(options & F_QUIET) && options & F_DOT)
(void)write(STDOUT_FILENO, &DOT[DOTidx++ % DOTlen], 1);
}
/*
@ -1220,7 +1231,7 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
return;
}
if (options & F_FLOOD)
if (options & F_DOT)
(void)write(STDOUT_FILENO, &BSPACE, 1);
else {
(void)printf("%zd bytes from %s: icmp_seq=%u", cc,
@ -1361,7 +1372,7 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
}
if (i == old_rrlen
&& !bcmp((char *)cp, old_rr, i)
&& !(options & F_FLOOD)) {
&& !(options & F_DOT)) {
(void)printf("\t(same route)");
hlen -= i;
cp += i;
@ -1396,7 +1407,7 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
(void)printf("\nunknown option %x", *cp);
break;
}
if (!(options & F_FLOOD)) {
if (!(options & F_DOT)) {
(void)putchar('\n');
(void)fflush(stdout);
}

View File

@ -201,6 +201,7 @@ struct tv32 {
#define F_DONTFRAG 0x1000000
#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
#define F_WAITTIME 0x2000000
#define F_DOT 0x4000000
static u_int options;
#define IN6LEN sizeof(struct in6_addr)
@ -227,7 +228,9 @@ static int srecv; /* receive socket file descriptor */
static u_char outpack[MAXPACKETLEN];
static char BSPACE = '\b'; /* characters written for flood */
static char BBELL = '\a'; /* characters written for AUDIBLE */
static char DOT = '.';
static const char *DOT = ".";
static size_t DOTlen = 1;
static size_t DOTidx = 0;
static char *hostname;
static int ident; /* process id to identify our packets */
static u_int8_t nonce[8]; /* nonce field for node information */
@ -352,6 +355,13 @@ ping6(int argc, char *argv[])
while ((ch = getopt(argc, argv, PING6OPTS)) != -1) {
switch (ch) {
case '.':
options |= F_DOT;
if (optarg != NULL) {
DOT = optarg;
DOTlen = strlen(optarg);
}
break;
case '6':
/* This option is processed in main(). */
break;
@ -437,6 +447,7 @@ ping6(int argc, char *argv[])
errx(1, "Must be superuser to flood ping");
}
options |= F_FLOOD;
options |= F_DOT;
setbuf(stdout, (char *)NULL);
break;
case 'e':
@ -1463,8 +1474,8 @@ pinger(void)
(void)printf("ping6: wrote %s %d chars, ret=%d\n",
hostname, cc, i);
}
if (!(options & F_QUIET) && options & F_FLOOD)
(void)write(STDOUT_FILENO, &DOT, 1);
if (!(options & F_QUIET) && options & F_DOT)
(void)write(STDOUT_FILENO, &DOT[DOTidx++ % DOTlen], 1);
return(0);
}
@ -1661,7 +1672,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
return;
}
if (options & F_FLOOD)
if (options & F_DOT)
(void)write(STDOUT_FILENO, &BSPACE, 1);
else {
if (options & F_AUDIBLE)
@ -1853,7 +1864,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
pr_icmph(icp, end);
}
if (!(options & F_FLOOD)) {
if (!(options & F_DOT)) {
(void)putchar('\n');
if (options & F_VERBOSE)
pr_exthdrs(mhdr);