]> The Tcpdump Group git mirrors - tcpdump/blobdiff - util.c
Fix the pcap version in tests/cve2015-0261-crash.pcap
[tcpdump] / util.c
diff --git a/util.c b/util.c
index 6a827dce71405a7618976e9a0dd9e509aa866ffd..8f5d7283eeecdd92cc2fb9bba753c91afdf0e5e0 100644 (file)
--- a/util.c
+++ b/util.c
 #include <string.h>
 
 #include "interface.h"
+#include "timeval-operations.h"
+
+/*
+ * timestamp display buffer size, the biggest size of both formats is needed
+ * sizeof("0000000000.000000000") > sizeof("00:00:00.000000000")
+ */
+#define TS_BUF_SIZE sizeof("0000000000.000000000")
 
 /*
  * Print out a null-terminated filename (or other ascii string).
@@ -155,9 +162,8 @@ ts_format(netdissect_options *ndo
 #ifndef HAVE_PCAP_SET_TSTAMP_PRECISION
 _U_
 #endif
-, int sec, int usec)
+, int sec, int usec, char *buf)
 {
-       static char buf[sizeof("00:00:00.000000000")];
        const char *format;
 
 #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
@@ -172,19 +178,56 @@ _U_
                break;
 
        default:
-               format = "%02d:%02d:%02d.{unknown precision}";
+               format = "%02d:%02d:%02d.{unknown}";
                break;
        }
 #else
        format = "%02d:%02d:%02d.%06u";
 #endif
 
-       snprintf(buf, sizeof(buf), format,
+       snprintf(buf, TS_BUF_SIZE, format,
                  sec / 3600, (sec % 3600) / 60, sec % 60, usec);
 
         return buf;
 }
 
+/*
+ * Format the timestamp - Unix timeval style
+ */
+static char *
+ts_unix_format(netdissect_options *ndo
+#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION
+_U_
+#endif
+, int sec, int usec, char *buf)
+{
+       const char *format;
+
+#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
+       switch (ndo->ndo_tstamp_precision) {
+
+       case PCAP_TSTAMP_PRECISION_MICRO:
+               format = "%u.%06u";
+               break;
+
+       case PCAP_TSTAMP_PRECISION_NANO:
+               format = "%u.%09u";
+               break;
+
+       default:
+               format = "%u.{unknown}";
+               break;
+       }
+#else
+       format = "%u.%06u";
+#endif
+
+       snprintf(buf, TS_BUF_SIZE, format,
+                (unsigned)sec, (unsigned)usec);
+
+       return buf;
+}
+
 /*
  * Print the timestamp
  */
@@ -195,52 +238,63 @@ 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) {
 
        case 0: /* Default */
                s = (tvp->tv_sec + thiszone) % 86400;
-               ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec)));
+               ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec, buf)));
                break;
 
        case 1: /* No time stamp */
                break;
 
        case 2: /* Unix timeval style */
-               ND_PRINT((ndo, "%u.%06u ",
-                            (unsigned)tvp->tv_sec,
-                            (unsigned)tvp->tv_usec));
+               ND_PRINT((ndo, "%s ", ts_unix_format(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)));
+               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*/
+       case 4: /* Default + Date */
                s = (tvp->tv_sec + thiszone) % 86400;
                Time = (tvp->tv_sec + thiszone) - s;
                tm = gmtime (&Time);
@@ -249,7 +303,7 @@ ts_print(netdissect_options *ndo,
                else
                        ND_PRINT((ndo, "%04d-%02d-%02d %s ",
                                tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
-                               ts_format(ndo, s, tvp->tv_usec)));
+                               ts_format(ndo, s, tvp->tv_usec, buf)));
                break;
        }
 }
@@ -337,7 +391,7 @@ tok2strbuf(register const struct tok *lp, register const char *fmt,
  */
 const char *
 tok2str(register const struct tok *lp, register const char *fmt,
-       register int v)
+       register u_int v)
 {
        static char buf[4][128];
        static int idx = 0;
@@ -355,12 +409,12 @@ tok2str(register const struct tok *lp, register const char *fmt,
  */
 static char *
 bittok2str_internal(register const struct tok *lp, register const char *fmt,
-          register int v, register int sep)
+          register u_int v, const char *sep)
 {
         static char buf[256]; /* our stringbuffer */
         int buflen=0;
-        register int rotbit; /* this is the bit we rotate through all bitpositions */
-        register int tokval;
+        register u_int rotbit; /* this is the bit we rotate through all bitpositions */
+        register u_int tokval;
         const char * sepstr = "";
 
        while (lp != NULL && lp->s != NULL) {
@@ -375,7 +429,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt,
                     /* ok we have found something */
                     buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
                                      sepstr, lp->s);
-                    sepstr = sep ? ", " : "";
+                    sepstr = sep;
                     break;
                 }
                 rotbit=rotbit<<1; /* no match - lets shift and try again */
@@ -385,7 +439,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt,
 
         if (buflen == 0)
             /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
-            (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%d" : fmt, v);
+            (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
         return (buf);
 }
 
@@ -395,9 +449,9 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt,
  */
 char *
 bittok2str_nosep(register const struct tok *lp, register const char *fmt,
-          register int v)
+          register u_int v)
 {
-    return (bittok2str_internal(lp, fmt, v, 0));
+    return (bittok2str_internal(lp, fmt, v, ""));
 }
 
 /*
@@ -406,9 +460,9 @@ bittok2str_nosep(register const struct tok *lp, register const char *fmt,
  */
 char *
 bittok2str(register const struct tok *lp, register const char *fmt,
-          register int v)
+          register u_int v)
 {
-    return (bittok2str_internal(lp, fmt, v, 1));
+    return (bittok2str_internal(lp, fmt, v, ", "));
 }
 
 /*
@@ -633,6 +687,7 @@ print_txt_line(netdissect_options *ndo, const char *protoname,
         * in the buffer; treat this as if it were truncated.
         */
 trunc:
+       linelen = idx - startidx;
        ND_PRINT((ndo, "%s%.*s[!%s]", prefix, (int)linelen, pptr + startidx,
            protoname));
        return (0);