Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/ping PR/45257: Instead of passing a 32bit sec and 32 bi...



details:   https://anonhg.NetBSD.org/src/rev/5ef711ed478f
branches:  trunk
changeset: 769452:5ef711ed478f
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Sep 10 20:04:28 2011 +0000

description:
PR/45257: Instead of passing a 32bit sec and 32 bit usec timestamp in little
endian format by default, pass a struct timespec in native host format. Add
-C flag to produce a compatible timestamp like before.

diffstat:

 sbin/ping/ping.8 |   26 ++++++--
 sbin/ping/ping.c |  172 ++++++++++++++++++++++++++++++++----------------------
 2 files changed, 121 insertions(+), 77 deletions(-)

diffs (truncated from 513 to 300 lines):

diff -r 17454279dc4f -r 5ef711ed478f sbin/ping/ping.8
--- a/sbin/ping/ping.8  Sat Sep 10 19:26:18 2011 +0000
+++ b/sbin/ping/ping.8  Sat Sep 10 20:04:28 2011 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: ping.8,v 1.47 2006/03/21 22:54:46 pavel Exp $
+.\"    $NetBSD: ping.8,v 1.48 2011/09/10 20:04:28 christos Exp $
 .\"
 .\" Copyright (c) 1985, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)ping.8     8.2 (Berkeley) 12/11/93
 .\"
-.Dd March 21, 2006
+.Dd September 10, 2011
 .Dt PING 8
 .Os
 .Sh NAME
@@ -40,7 +40,7 @@
 .Sh SYNOPSIS
 .Nm
 .Bk -words
-.Op Fl adDfLnoPqQrRv
+.Op Fl aCdDfLnoPqQrRv
 .Ek
 .Bk -words
 .Op Fl c Ar count
@@ -93,7 +93,7 @@
 .Tn ICMP
 header,
 followed by a
-.Dq struct timeval
+.Dq struct timespec
 and then an arbitrary number of ``pad'' bytes used to fill out the
 packet.
 The options are as follows:
@@ -108,6 +108,10 @@
 .Ar count
 .Tn ECHO_RESPONSE
 packets.
+.It Fl C
+Send timestamps in compat format; two 32 bit words in little endian format,
+the first one representing seconds, and the second one representing
+microseconds.
 .It Fl d
 Set the
 .Dv SO_DEBUG
@@ -322,12 +326,20 @@
 .Tn ICMP
 header).
 .Pp
-If the data space is at least eight bytes large,
+If the data space is at least 
+.Dv sizeof(struct timespec)
+(16) large,
+.Nm
+uses the first
+.Dv sizeof(struct timespec)
+byres to include a timestamp to compute round trip times.
+Otherwise if the data space is at least eight bytes large (or the
+.Fl C
+flag is specified),
 .Nm
 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.
+If there are not enough bytes of pad no round trip times are given.
 .Sh DUPLICATE AND DAMAGED PACKETS
 .Nm
 will report duplicate and damaged packets.
diff -r 17454279dc4f -r 5ef711ed478f sbin/ping/ping.c
--- a/sbin/ping/ping.c  Sat Sep 10 19:26:18 2011 +0000
+++ b/sbin/ping/ping.c  Sat Sep 10 20:04:28 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ping.c,v 1.98 2011/08/27 18:40:18 joerg Exp $  */
+/*     $NetBSD: ping.c,v 1.99 2011/09/10 20:04:28 christos Exp $       */
 
 /*
  * Copyright (c) 1989, 1993
@@ -58,7 +58,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ping.c,v 1.98 2011/08/27 18:40:18 joerg Exp $");
+__RCSID("$NetBSD: ping.c,v 1.99 2011/09/10 20:04:28 christos Exp $");
 #endif
 
 #include <stdio.h>
@@ -113,6 +113,7 @@
 #define F_MCAST                0x2000          /* multicast target */
 #define F_MCAST_NOLOOP 0x4000          /* no multicast loopback */
 #define F_AUDIBLE      0x8000          /* audible output */
+#define F_TIMING64     0x10000         /* 64 bit time, nanoseconds */
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
 #define F_POLICY       0x10000
@@ -151,11 +152,13 @@
 static int s;                                  /* Socket file descriptor */
 static int sloop;                              /* Socket file descriptor/loopback */
 
-#define PHDR_LEN sizeof(struct tv32)   /* size of timestamp header */
+#define PHDR_LEN sizeof(struct tv32)           /* size of timestamp header */
+#define PHDR64_LEN sizeof(struct timespec)     /* size of timestamp header */
 static struct sockaddr_in whereto, send_addr;  /* Who to ping */
 static struct sockaddr_in src_addr;            /* from where */
 static struct sockaddr_in loc_addr;            /* 127.1 */
-static int datalen = 64 - PHDR_LEN;            /* How much data */
+static int datalen;                            /* How much data */
+static int phdrlen;
 
 #ifndef __NetBSD__
 static char *progname;
@@ -187,7 +190,7 @@
 static int nreceived;                          /* # of packets we got back */
 
 static double interval;                        /* interval between packets */
-static struct timeval interval_tv;
+static struct timespec interval_tv;
 static double tmin = 999999999.0;
 static double tmax = 0.0;
 static double tsum = 0.0;                      /* sum of all times */
@@ -196,11 +199,11 @@
 
 static int bufspace = IP_MAXPACKET;
 
-static struct timeval now, clear_cache, last_tx, next_tx, first_tx;
-static struct timeval last_rx, first_rx;
+static struct timespec now, clear_cache, last_tx, next_tx, first_tx;
+static struct timespec last_rx, first_rx;
 static int lastrcvd = 1;                       /* last ping sent has been received */
 
-static struct timeval jiggle_time;
+static struct timespec jiggle_time;
 static int jiggle_cnt, total_jiggled, jiggle_direction = -1;
 
 __dead static void doit(void);
@@ -211,10 +214,12 @@
 static void pinger(void);
 static void fill(void);
 static void rnd_fill(void);
-static double diffsec(struct timeval *, struct timeval *);
-static void timevaladd(struct timeval *, struct timeval *);
-static void sec_to_timeval(const double, struct timeval *);
-static double timeval_to_sec(const struct timeval *);
+static double diffsec(struct timespec *, struct timespec *);
+#if 0
+static void timespecadd(struct timespec *, struct timespec *);
+#endif
+static void sec_to_timespec(const double, struct timespec *);
+static double timespec_to_sec(const struct timespec *);
 static void pr_pack(u_char *, int, struct sockaddr_in *);
 static u_int16_t in_cksum(u_int16_t *, u_int);
 static void pr_saddr(u_char *);
@@ -232,6 +237,7 @@
 {
        int c, i, on = 1, hostind = 0;
        long l;
+       int len = -1, compat = 0;
        u_char ttl = 0;
        u_long tos = 0;
        char *p;
@@ -275,12 +281,15 @@
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif
        while ((c = getopt(argc, argv,
-                          "ac:dDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:" IPSECOPT)) != -1) {
+                          "ac:CdDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:" IPSECOPT)) != -1) {
 #undef IPSECOPT
                switch (c) {
                case 'a':
                        pingflags |= F_AUDIBLE;
                        break;
+               case 'C':
+                       compat = 1;
+                       break;
                case 'c':
                        npackets = strtol(optarg, &p, 0);
                        if (*p != '\0' || npackets <= 0)
@@ -341,7 +350,7 @@
                                errx(1, "Bad/invalid packet size %s", optarg);
                        if (l > MAXPACKET)
                                errx(1, "packet size is too large");
-                       datalen = (int)l;
+                       len = (int)l;
                        break;
                case 'v':
                        pingflags |= F_VERBOSE;
@@ -416,7 +425,7 @@
        if (preload > 0 && prog_getuid())
                errx(1, "Must be superuser to use -l");
 #endif
-       sec_to_timeval(interval, &interval_tv);
+       sec_to_timespec(interval, &interval_tv);
 
        if ((pingflags & (F_AUDIBLE|F_FLOOD)) == (F_AUDIBLE|F_FLOOD))
                warnx("Sorry, no audible output for flood pings");
@@ -446,8 +455,20 @@
        loc_addr.sin_len = sizeof(struct sockaddr_in);
        loc_addr.sin_addr.s_addr = htonl((127 << 24) + 1);
 
-       if (datalen >= (int)PHDR_LEN)   /* can we time them? */
+       if (len != -1)
+               datalen = len;
+       else
+               datalen = 64;
+       if (!compat && datalen >= (int)PHDR64_LEN) { /* can we time them? */
+               pingflags |= F_TIMING64;
+               phdrlen = PHDR64_LEN;
+       } else if (datalen >= (int)PHDR_LEN) {  /* can we time them? */
                pingflags |= F_TIMING;
+               phdrlen = PHDR_LEN;
+       } else
+               phdrlen = 0;
+       datalen -= phdrlen;
+
        packlen = datalen + 60 + 76;    /* MAXIP + MAXICMP */
        if ((packet = malloc(packlen)) == NULL)
                err(1, "Out of memory");
@@ -457,7 +478,7 @@
        } else if (pingflags & F_PING_RANDOM) {
                rnd_fill();
        } else {
-               for (i = PHDR_LEN; i < datalen; i++)
+               for (i = phdrlen; i < datalen; i++)
                        opack_icmp.icmp_data[i] = i;
        }
 
@@ -649,7 +670,7 @@
 
        /* fire off them quickies */
        for (i = 0; i < preload; i++) {
-               (void)gettimeofday(&now, 0);
+               clock_gettime(CLOCK_MONOTONIC, &now);
                pinger();
        }
 
@@ -667,9 +688,9 @@
        double sec, last, d_last;
        struct pollfd fdmaskp[1];
 
-       (void)gettimeofday(&clear_cache,0);
+       (void)clock_gettime(CLOCK_MONOTONIC, &clear_cache);
        if (maxwait != 0) {
-               last = timeval_to_sec(&clear_cache) + maxwait;
+               last = timespec_to_sec(&clear_cache) + maxwait;
                d_last = 0;
        } else {
                last = 0;
@@ -677,10 +698,10 @@
        }
 
        do {
-               (void)gettimeofday(&now,0);
+               clock_gettime(CLOCK_MONOTONIC, &now);
 
                if (last != 0)
-                       d_last = last - timeval_to_sec(&now);
+                       d_last = last - timespec_to_sec(&now);
 
                if (ntransmitted < npackets && d_last > 0) {
                        /* send if within 100 usec or late for next packet */
@@ -708,7 +729,6 @@
                                break;
                }
 
-
                fdmaskp[0].fd = s;
                fdmaskp[0].events = POLLIN;
                cc = prog_poll(fdmaskp, 1, (int)(sec * 1000));
@@ -734,7 +754,7 @@
                        }
                        continue;
                }
-               (void)gettimeofday(&now, 0);
+               clock_gettime(CLOCK_MONOTONIC, &now);
                pr_pack(packet, cc, &from);
 
        } while (nreceived < npackets
@@ -806,9 +826,10 @@
 /*
  * Compose and transmit an ICMP ECHO REQUEST packet.  The IP packet
  * will be added on by the kernel.  The ID field is our UNIX process ID,
- * and the sequence number is an ascending integer.  The first PHDR_LEN bytes
+ * and the sequence number is an ascending integer.  The first phdrlen bytes
  * of the data portion are used to hold a UNIX "timeval" struct in VAX
- * byte-order, to compute the round-trip time.
+ * byte-order, to compute the round-trip time, or a UNIX "timespec" in native
+ * format.
  */
 static void
 pinger(void)
@@ -830,13 +851,13 @@
                opack_icmp.icmp_id = ~ident;
                opack_icmp.icmp_cksum = 0;
                opack_icmp.icmp_cksum = in_cksum((u_int16_t *)&opack_icmp,
-                   PHDR_LEN);
+                   phdrlen);
                sw = 0;
                if (prog_setsockopt(sloop,IPPROTO_IP,IP_HDRINCL,



Home | Main Index | Thread Index | Old Index