]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Merge pull request #377 from msekletar/master
authorGuy Harris <[email protected]>
Wed, 25 Jun 2014 18:23:54 +0000 (11:23 -0700)
committerGuy Harris <[email protected]>
Wed, 25 Jun 2014 18:23:54 +0000 (11:23 -0700)
timestamps: make possible to request high precision timestamps

netdissect.h
tcpdump.1.in
tcpdump.c
util.c

index e94ca976740f16cfe68f36293a7d73e5888f27f7..1b11bf8e9f3ba19f0e6cd51448035757fce6dbb7 100644 (file)
@@ -126,6 +126,7 @@ struct netdissect_options {
   int ndo_Hflag;               /* dissect 802.11s draft mesh standard */
   int ndo_packet_number;       /* print a packet number in the beginning of line */
   int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */
+  int ndo_tstamp_precision;   /* requested time stamp precision */
   const char *ndo_dltname;
 
   char *ndo_espsecret;
index b1867419f5b95ebfd15aaa701c2d02a1c5df4d52..3cceb4683fba647570e997f6d6fa701db9f2fb6f 100644 (file)
@@ -432,6 +432,15 @@ List the supported time stamp types for the interface and exit.  If the
 time stamp type cannot be set for the interface, no time stamp types are
 listed.
 .TP
+.BI \-\-time\-stamp\-precision= tstamp_precision
+.PD
+Set the time stamp precision for the capture to
+\fItstamp_precision\fP. Currently supported are microseconds and
+nanoseconds. Note that availability of high precision time stamps (nanoseconds)
+and their actual accuracy is platform and HW dependent. Also note that when
+writing captures to the savefile, distinct magic number is used to distinguish
+savefiles which contains time stamps in nanoseconds.
+.TP
 .B \-K
 .PD 0
 .TP
index f41bf697bf90cc6757750766d51c4840d7150b43..d9f3e0fa96761fa993b0360fca4c53585c254d90 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -650,6 +650,7 @@ show_devices_and_exit (void)
  */
 #define OPTION_NUMBER  128
 #define OPTION_VERSION 129
+#define OPTION_TSTAMP_PRECISION 130
 
 static const struct option longopts[] = {
 #if defined(HAVE_PCAP_CREATE) || defined(WIN32)
@@ -665,6 +666,7 @@ static const struct option longopts[] = {
        { "time-stamp-type", required_argument, NULL, 'j' },
        { "list-time-stamp-types", no_argument, NULL, 'J' },
 #endif
+       { "time-stamp-precision", required_argument, NULL, OPTION_TSTAMP_PRECISION},
        { "dont-verify-checksums", no_argument, NULL, 'K' },
        { "list-data-link-types", no_argument, NULL, 'L' },
        { "no-optimize", no_argument, NULL, 'O' },
@@ -846,6 +848,18 @@ get_next_file(FILE *VFile, char *ptr)
        return ret;
 }
 
+static int
+tstamp_precision_from_string(const char *precision)
+{
+       if (strncmp(precision, "nano", strlen("nano")) == 0)
+               return PCAP_TSTAMP_PRECISION_NANO;
+
+       if (strncmp(precision, "micro", strlen("micro")) == 0)
+               return PCAP_TSTAMP_PRECISION_MICRO;
+
+       return -EINVAL;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -1281,6 +1295,12 @@ main(int argc, char **argv)
                        exit(0);
                        break;
 
+               case OPTION_TSTAMP_PRECISION:
+                       gndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg);
+                       if (gndo->ndo_tstamp_precision < 0)
+                               error("unsupported time stamp precision");
+                       break;
+
                default:
                        print_usage();
                        exit(1);
@@ -1372,7 +1392,11 @@ main(int argc, char **argv)
                        RFileName = VFileLine;
                }
 
-               pd = pcap_open_offline(RFileName, ebuf);
+               if (gndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO)
+                       pd = pcap_open_offline_with_tstamp_precision(RFileName, PCAP_TSTAMP_PRECISION_NANO, ebuf);
+               else
+                       pd = pcap_open_offline_with_tstamp_precision(RFileName, PCAP_TSTAMP_PRECISION_MICRO, ebuf);
+
                if (pd == NULL)
                        error("%s", ebuf);
                dlt = pcap_datalink(pd);
@@ -1419,6 +1443,13 @@ main(int argc, char **argv)
                if (Jflag)
                        show_tstamp_types_and_exit(device, pd);
 #endif
+               if (gndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
+                       status = pcap_set_tstamp_precision(pd, PCAP_TSTAMP_PRECISION_NANO);
+                       if (status != 0)
+                               error("%s: Can't set nanosecond time stamp precision: %s",
+                                       device, pcap_statustostr(status));
+                }
+
                /*
                 * Is this an interface that supports monitor mode?
                 */
diff --git a/util.c b/util.c
index 1ce46530cb3efd496cd7d33cae02ff60be6d9c25..ef9ed7bec50f9ca0c617b091bc89cd509c59e79a 100644 (file)
--- a/util.c
+++ b/util.c
@@ -135,11 +135,14 @@ fn_printzp(netdissect_options *ndo,
  * Format the timestamp
  */
 static char *
-ts_format(register int sec, register int usec)
+ts_format(netdissect_options *ndo, int sec, int usec)
 {
-        static char buf[sizeof("00:00:00.000000")];
-        (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u",
-               sec / 3600, (sec % 3600) / 60, sec % 60, usec);
+       static char buf[sizeof("00:00:00.000000000")];
+       const char *format = ndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ?
+                "%02d:%02d:%02d.%09u" : "%02d:%02d:%02d.%06u";
+
+       snprintf(buf, sizeof(buf), format,
+                 sec / 3600, (sec % 3600) / 60, sec % 60, usec);
 
         return buf;
 }
@@ -163,7 +166,7 @@ ts_print(netdissect_options *ndo,
 
        case 0: /* Default */
                s = (tvp->tv_sec + thiszone) % 86400;
-               ND_PRINT((ndo, "%s ", ts_format(s, tvp->tv_usec)));
+               ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec)));
                break;
 
        case 1: /* No time stamp */
@@ -191,7 +194,7 @@ ts_print(netdissect_options *ndo,
                     d_sec--;
                 }
 
-                ND_PRINT((ndo, "%s ", ts_format(d_sec, d_usec)));
+                ND_PRINT((ndo, "%s ", ts_format(ndo, d_sec, d_usec)));
 
                 if (ndo->ndo_tflag == 3) { /* set timestamp for last packet */
                     b_sec = tvp->tv_sec;
@@ -208,7 +211,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(s, tvp->tv_usec)));
+                               ts_format(ndo, s, tvp->tv_usec)));
                break;
        }
 }