]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Fix handling of NTP time stamps.
authorGuy Harris <[email protected]>
Thu, 21 Sep 2017 02:17:22 +0000 (19:17 -0700)
committerGuy Harris <[email protected]>
Thu, 21 Sep 2017 02:17:22 +0000 (19:17 -0700)
The seconds value in a 64-bit NTP timestamp is unsigned.  Treat it as
such.

When converting it to a UN*X seconds-since-the-Epoch, cast the 32-bit
seconds value from an NTP timestap to a 64-bit signed value (which is
always possible), and then subtract the signed delta between 1900 and
1970, giving a signed seconds-since-the-Epoch value.

Then assign that to a time_t; if that variable doesn't have the same
value as the calculated 64-bit value, we can't represent it in a time_t,
so just report it as unrepresentable.

Otherwise, use that resulting value in a gmtime() call - and make sure
gmtime() doesn't return NULL, which it can do with some versions of the
Microsoft C runtime.  If it does, report the time as unrepresentable,
otherwise report it as YYYY-MM-DDTHH:MM:SS.

This fixes the 32-bit vs. 64-bit issue for tests.

It also changes the test output, so update that.

print-ntp.c
tests/64bit.sh [deleted file]
tests/TESTLIST
tests/ntp-v.out

index 3ccf9833bb2dce16d83000955e0fb68c980533e8..cf403c0c0472fa843efd028b0a18a05fc191a069 100644 (file)
@@ -48,7 +48,7 @@ static const char tstr[] = " [|ntp]";
 /*
  *  Definitions for the masses
  */
-#define        JAN_1970        2208988800U     /* 1970 - 1900 in seconds */
+#define        JAN_1970        2208988800      /* 1970 - 1900 in seconds */
 
 /*
  * Structure definitions for NTP fixed point values
@@ -498,7 +498,7 @@ static void
 p_ntp_time(netdissect_options *ndo,
            register const struct l_fixedpt *lfp)
 {
-       register int32_t i;
+       register uint32_t i;
        register uint32_t uf;
        register uint32_t f;
        register double ff;
@@ -517,14 +517,33 @@ p_ntp_time(netdissect_options *ndo,
         * print the UTC time in human-readable format.
         */
        if (i) {
-           time_t seconds = i - JAN_1970;
+           int64_t seconds_64bit = (int64_t)i - JAN_1970;
+           time_t seconds;
            struct tm *tm;
            char time_buf[128];
 
-           tm = gmtime(&seconds);
-           /* use ISO 8601 (RFC3339) format */
-           strftime(time_buf, sizeof (time_buf), "%Y-%m-%dT%H:%M:%S", tm);
-           ND_PRINT((ndo, " (%s)", time_buf));
+           seconds = (time_t)seconds_64bit;
+           if (seconds != seconds_64bit) {
+               /*
+                * It doesn't fit into a time_t, so we can't hand it
+                * to gmtime.
+                */
+               ND_PRINT((ndo, " (unrepresentable)"));
+           } else {
+               tm = gmtime(&seconds);
+               if (tm == NULL) {
+                   /*
+                    * gmtime() can't handle it.
+                    * (Yes, that might happen with some version of
+                    * Microsoft's C library.)
+                    */
+                   ND_PRINT((ndo, " (unrepresentable)"));
+               } else {
+                   /* use ISO 8601 (RFC3339) format */
+                   strftime(time_buf, sizeof (time_buf), "%Y-%m-%dT%H:%M:%S", tm);
+                   ND_PRINT((ndo, " (%s)", time_buf));
+               }
+           }
        }
 #endif
 }
diff --git a/tests/64bit.sh b/tests/64bit.sh
deleted file mode 100644 (file)
index 589458e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-
-exitcode=0
-passed=`cat .passed`
-failed=`cat .failed`
-
-# Only attempt tests with times outside the range of 32-bit time_t
-# when running on a 64-bit processor.
-
-if file ../tcpdump | egrep '64|PA-RISC2.0' >/dev/null
-then
-       #
-       # The file type of tcpdump contains the number 64 or the string
-       # "PA-RISC2.0"; we'll assume that means it's a 64-bit executable.
-       #
-       if ./TESTonce ntp ntp.pcap ntp.out ""
-       then
-               passed=`expr $passed + 1`
-               echo $passed >.passed
-       else
-               failed=`expr $failed + 1`
-               echo $failed >.failed
-               exitcode=1
-       fi
-       #
-       # The file type of tcpdump contains the number 64 or the string
-       # "PA-RISC2.0"; we'll assume that means it's a 64-bit executable.
-       #
-       if ./TESTonce ntp ntp.pcap ntp-v.out -v
-       then
-               passed=`expr $passed + 1`
-               echo $passed >.passed
-       else
-               failed=`expr $failed + 1`
-               echo $failed >.failed
-               exitcode=1
-       fi
-else
-       FORMAT='    %-35s: TEST SKIPPED (running 32-bit)\n'
-       printf "$FORMAT" ntp
-
-fi
-
-exit $exitcode
index 7c5c6dc8be991b56f3ddf769acf5209799a6ba2a..3df257b12fe5e9baf22f1b2dc8d782edd27a5585 100644 (file)
@@ -209,7 +209,9 @@ m3ua-vv isup.pcap isupvv.out -vv
 
 # NFLOG test case moved to nflog-e.sh
 
-# NTP tests moved to 64bit.sh
+# NTP tests
+ntp ntp.pcap ntp.out
+ntp ntp.pcap ntp-v.out -v
 
 # syslog test case
 syslog-v       syslog_udp.pcap         syslog-v.out            -v
index 3fe26c9860490eb2e6c841c767ff00eebc9b67d0..719b68847d0cb49e4fcb009499624d2c811bec38 100644 (file)
@@ -27,7 +27,7 @@ IP (tos 0x0, ttl 64, id 5777, offset 0, flags [DF], proto UDP (17), length 100)
        Root Delay: 0.000000, Root dispersion: 0.000000, Reference-ID: (unspec)
          Reference Timestamp:  0.000000000
          Originator Timestamp: 3706870757.473833108 (2017-06-19T14:19:17)
-         Receive Timestamp:    1802554105.693999877 (2093-03-22T03:56:41)
+         Receive Timestamp:    1802554105.693999877 (1957-02-13T21:28:25)
          Transmit Timestamp:   2929527464.107565978 (1992-10-31T13:37:44)
            Originator - Receive Timestamp:  -1904316651.779833231
            Originator - Transmit Timestamp: -777343293.366267130