summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ping/ping.813
-rw-r--r--sbin/ping/ping.c28
2 files changed, 31 insertions, 10 deletions
diff --git a/sbin/ping/ping.8 b/sbin/ping/ping.8
index 5aa26fa..5efdcdf 100644
--- a/sbin/ping/ping.8
+++ b/sbin/ping/ping.8
@@ -42,7 +42,7 @@
packets to network hosts
.Sh SYNOPSIS
.Nm
-.Op Fl ADQRadfnoqrv
+.Op Fl ADQRadfMnoqrv
.Op Fl c Ar count
.Op Fl i Ar wait
.Op Fl l Ar preload
@@ -152,14 +152,19 @@ is specified,
sends that many packets as fast as possible before falling into its normal
mode of behavior.
Only the super-user may use this option.
+.It Fl L
+Suppress loopback of multicast packets.
+This flag only applies if the ping destination is a multicast address.
.It Fl m Ar ttl
Set the IP Time To Live for outgoing packets.
If not specified, the kernel uses the value of the
.Va net.inet.ip.ttl
MIB variable.
-.It Fl L
-Suppress loopback of multicast packets.
-This flag only applies if the ping destination is a multicast address.
+.It Fl M
+Use ICMP_MASKREQ instead of ICMP_ECHO. Print the netmask of the remote
+machine. Set the
+.Va net.inet.icmp.maskrepl
+MIB variable to enable ICMP_MASKREPLY.
.It Fl n
Numeric output only.
No attempt will be made to lookup symbolic names for host addresses.
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
index 7953649..e9c739a 100644
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -104,6 +104,7 @@ static const char rcsid[] =
#define MAXIPLEN (sizeof(struct ip) + MAX_IPOPTLEN)
#define MAXICMPLEN (ICMP_ADVLENMIN + MAX_IPOPTLEN)
#define MINICMPLEN ICMP_MINLEN
+#define MASKLEN (options & F_MASK ? 4 : 0)
#define MAXWAIT 10 /* max seconds to wait for response */
#define MAXALARM (60 * 60) /* max seconds for alarm timeout */
#define MAXTOS 255
@@ -139,6 +140,7 @@ int options;
#define F_MISSED 0x10000
#define F_ONCE 0x20000
#define F_HDRINCL 0x40000
+#define F_MASK 0x80000
/*
* MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
@@ -249,7 +251,7 @@ main(argc, argv)
outpack = outpackhdr + sizeof(struct ip);
datap = &outpack[MINICMPLEN + PHDR_LEN];
while ((ch = getopt(argc, argv,
- "ADI:LQRS:T:c:adfi:l:m:nop:qrs:t:vz:"
+ "ADI:LQRS:T:c:adfi:l:m:Mnop:qrs:t:vz:"
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
"P:"
@@ -328,6 +330,9 @@ main(argc, argv)
ttl = ultmp;
options |= F_TTL;
break;
+ case 'M':
+ options |= F_MASK;
+ break;
case 'n':
options |= F_NUMERIC;
break;
@@ -479,7 +484,7 @@ main(argc, argv)
errx(EX_USAGE,
"-I, -L, -T flags cannot be used with unicast destination");
- if (datalen >= PHDR_LEN) /* can we time transfer */
+ if (datalen - MASKLEN >= PHDR_LEN) /* can we time transfer */
timing = 1;
packlen = MAXIPLEN + MAXICMPLEN + datalen;
packlen = packlen > IP_MAXPACKET ? IP_MAXPACKET : packlen;
@@ -805,7 +810,10 @@ pinger(void)
packet = outpack;
icp = (struct icmp *)outpack;
- icp->icmp_type = ICMP_ECHO;
+ if (options & F_MASK)
+ icp->icmp_type = ICMP_MASKREQ;
+ else
+ icp->icmp_type = ICMP_ECHO;
icp->icmp_code = 0;
icp->icmp_cksum = 0;
icp->icmp_seq = htons(ntransmitted);
@@ -814,8 +822,8 @@ pinger(void)
CLR(ntransmitted % mx_dup_ck);
if (timing)
- (void)gettimeofday((struct timeval *)&outpack[MINICMPLEN],
- NULL);
+ (void)gettimeofday((struct timeval *)&outpack[
+ MINICMPLEN + MASKLEN], NULL);
cc = MINICMPLEN + datalen;
@@ -886,7 +894,8 @@ pr_pack(buf, cc, from, tv)
/* Now the ICMP part */
cc -= hlen;
icp = (struct icmp *)(buf + hlen);
- if (icp->icmp_type == ICMP_ECHOREPLY) {
+ if ((icp->icmp_type == ICMP_ECHOREPLY) ||
+ ((icp->icmp_type == ICMP_MASKREPLY) && (options & F_MASK))) {
if (icp->icmp_id != ident)
return; /* 'Twas not our ECHO */
++nreceived;
@@ -898,6 +907,8 @@ pr_pack(buf, cc, from, tv)
#else
tp = icp->icmp_data;
#endif
+ tp+=MASKLEN;
+
/* Copy to avoid alignment problems: */
memcpy(&tv1, tp, sizeof(tv1));
tvsub(tv, &tv1);
@@ -938,6 +949,11 @@ pr_pack(buf, cc, from, tv)
(void)printf(" (DUP!)");
if (options & F_AUDIBLE)
(void)write(STDOUT_FILENO, &BBELL, 1);
+ if (options & F_MASK) {
+ /* Just prentend this cast isn't ugly */
+ (void)printf(" mask=%s",
+ pr_addr(*(struct in_addr *)&(icp->icmp_mask)));
+ }
/* check the data */
cp = (u_char*)&icp->icmp_data[PHDR_LEN];
dp = &outpack[MINICMPLEN + PHDR_LEN];
OpenPOWER on IntegriCloud