]> The Tcpdump Group git mirrors - tcpdump/blobdiff - util.c
Fix display of timestamps with -ttt and -ttttt options
[tcpdump] / util.c
diff --git a/util.c b/util.c
index a5c969c0073eddabe33d1d69d0f084f2553ffe19..8f5d7283eeecdd92cc2fb9bba753c91afdf0e5e0 100644 (file)
--- a/util.c
+++ b/util.c
@@ -53,6 +53,7 @@
 #include <string.h>
 
 #include "interface.h"
+#include "timeval-operations.h"
 
 /*
  * timestamp display buffer size, the biggest size of both formats is needed
@@ -237,11 +238,11 @@ ts_print(netdissect_options *ndo,
        register int s;
        struct tm *tm;
        time_t Time;
-       static unsigned b_sec;
-       static unsigned b_usec;
-       int d_usec;
-       int d_sec;
        char buf[TS_BUF_SIZE];
+       static struct timeval tv_ref;
+       struct timeval tv_result;
+       int negative_offset;
+       int nano_prec;
 
        switch (ndo->ndo_tflag) {
 
@@ -258,28 +259,39 @@ ts_print(netdissect_options *ndo,
                          tvp->tv_sec, tvp->tv_usec, buf)));
                break;
 
-       case 3: /* Microseconds since previous packet */
-        case 5: /* Microseconds since first packet */
-               if (b_sec == 0) {
-                        /* init timestamp for first packet */
-                        b_usec = tvp->tv_usec;
-                        b_sec = tvp->tv_sec;
-                }
+       case 3: /* Microseconds/nanoseconds since previous packet */
+        case 5: /* Microseconds/nanoseconds since first packet */
+#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
+               switch (ndo->ndo_tstamp_precision) {
+               case PCAP_TSTAMP_PRECISION_MICRO:
+                       nano_prec = 0;
+                       break;
+               case PCAP_TSTAMP_PRECISION_NANO:
+                       nano_prec = 1;
+                       break;
+               default:
+                       nano_prec = 0;
+                       break;
+               }
+#else
+               nano_prec = 0;
+#endif
+               if (!(tcpdump_timevalisset(&tv_ref)))
+                       tv_ref = *tvp; /* set timestamp for first packet */
 
-                d_usec = tvp->tv_usec - b_usec;
-                d_sec = tvp->tv_sec - b_sec;
+               negative_offset = tcpdump_timevalcmp(tvp, &tv_ref, <);
+               if (negative_offset)
+                       tcpdump_timevalsub(&tv_ref, tvp, &tv_result, nano_prec);
+               else
+                       tcpdump_timevalsub(tvp, &tv_ref, &tv_result, nano_prec);
 
-                while (d_usec < 0) {
-                    d_usec += 1000000;
-                    d_sec--;
-                }
+               ND_PRINT((ndo, (negative_offset ? "-" : " ")));
 
-                ND_PRINT((ndo, "%s ", ts_format(ndo, d_sec, d_usec, buf)));
+               ND_PRINT((ndo, "%s ", ts_format(ndo,
+                         tv_result.tv_sec, tv_result.tv_usec, buf)));
 
-                if (ndo->ndo_tflag == 3) { /* set timestamp for last packet */
-                    b_sec = tvp->tv_sec;
-                    b_usec = tvp->tv_usec;
-                }
+                if (ndo->ndo_tflag == 3)
+                       tv_ref = *tvp; /* set timestamp for previous packet */
                break;
 
        case 4: /* Default + Date */