Blame SOURCES/0001-Introduce-time-stamp-precision.patch

ac9b3d
From 9784ac1d98ae256e9e9f1830e7bab3b6bc20ec6c Mon Sep 17 00:00:00 2001
ac9b3d
From: Michal Sekletar <sekletar.m@gmail.com>
ac9b3d
Date: Wed, 19 Mar 2014 14:14:25 +0100
ac9b3d
Subject: [PATCH 1/4] Introduce --time-stamp-precision
ac9b3d
ac9b3d
A while ago we introduced new API in libpcap which made possible to
ac9b3d
request time stamps with higher precision (nanoseconds). This commit
ac9b3d
aims to move things forward and implement missing bits. It introduces
ac9b3d
new long option --time-stamp-precision. Note that there is no equivalent
ac9b3d
short option.
ac9b3d
ac9b3d
When used for a live capture tcpdump will ask the kernel for time stamp
ac9b3d
with desired precision and tcpdump will print fraction part of the time
ac9b3d
stamp using respective format. We currently support only microsecond and
ac9b3d
nanosecond precision. In the future we might support even more granular
ac9b3d
time stamp precision, but we should be fine to support only
ac9b3d
microseconds and nanoseconds for now. libpcap doesn't provide anything
ac9b3d
else at the moment anyway.
ac9b3d
ac9b3d
When used in combination with -r/-w options then we obtain time stamps
ac9b3d
appropriately scaled up or down from libpcap. Also note that distinct
ac9b3d
magic number is used for savefiles containing nanosecond time stamps.
ac9b3d
ac9b3d
(cherry picked from commit 52b27d11fc50ebc4f1fc54b53fd9437d62dd7f4a)
ac9b3d
ac9b3d
Conflicts:
ac9b3d
        netdissect.h
ac9b3d
        tcpdump.c
ac9b3d
---
ac9b3d
 netdissect.h |  1 +
ac9b3d
 tcpdump.1.in |  9 +++++++++
ac9b3d
 tcpdump.c    | 41 +++++++++++++++++++++++++++++++++++++++--
ac9b3d
 util.c       |  9 ++++++---
ac9b3d
 4 files changed, 55 insertions(+), 5 deletions(-)
ac9b3d
ac9b3d
diff --git a/netdissect.h b/netdissect.h
ac9b3d
index 4fd4726..e0146e7 100644
ac9b3d
--- a/netdissect.h
ac9b3d
+++ b/netdissect.h
ac9b3d
@@ -123,6 +123,7 @@ struct netdissect_options {
ac9b3d
   time_t ndo_Gflag_time;    /* The last time_t the dump file was rotated. */
ac9b3d
   int ndo_Wflag;          /* recycle output files after this number of files */
ac9b3d
   int ndo_WflagChars;
ac9b3d
+  int ndo_tstamp_precision;   /* requested time stamp precision */
ac9b3d
   int ndo_Hflag;		/* dissect 802.11s draft mesh standard */
ac9b3d
   int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */
ac9b3d
   const char *ndo_dltname;
ac9b3d
diff --git a/tcpdump.1.in b/tcpdump.1.in
ac9b3d
index a5a0e28..6083474 100644
ac9b3d
--- a/tcpdump.1.in
ac9b3d
+++ b/tcpdump.1.in
ac9b3d
@@ -399,6 +399,15 @@ List the supported time stamp types for the interface and exit.  If the
ac9b3d
 time stamp type cannot be set for the interface, no time stamp types are
ac9b3d
 listed.
ac9b3d
 .TP
ac9b3d
+.BI \-\-time\-stamp\-precision= tstamp_precision
ac9b3d
+.PD
ac9b3d
+Set the time stamp precision for the capture to
ac9b3d
+\fItstamp_precision\fP. Currently supported are microseconds and
ac9b3d
+nanoseconds. Note that availability of high precision time stamps (nanoseconds)
ac9b3d
+and their actual accuracy is platform and HW dependent. Also note that when
ac9b3d
+writing captures to the savefile, distinct magic number is used to distinguish
ac9b3d
+savefiles which contains time stamps in nanoseconds.
ac9b3d
+.TP
ac9b3d
 .B \-K
ac9b3d
 Don't attempt to verify IP, TCP, or UDP checksums.  This is useful for
ac9b3d
 interfaces that perform some or all of those checksum calculation in
ac9b3d
diff --git a/tcpdump.c b/tcpdump.c
ac9b3d
index 79db6d7..444e1e3 100644
ac9b3d
--- a/tcpdump.c
ac9b3d
+++ b/tcpdump.c
ac9b3d
@@ -73,6 +73,7 @@ extern int SIZE_BUF;
ac9b3d
 #include <grp.h>
ac9b3d
 #include <errno.h>
ac9b3d
 #endif /* WIN32 */
ac9b3d
+#include <getopt.h>
ac9b3d
 
ac9b3d
 /* capabilities convinience library */
ac9b3d
 #ifdef HAVE_CAP_NG_H
ac9b3d
@@ -529,6 +530,12 @@ show_dlts_and_exit(const char *device, pcap_t *pd)
ac9b3d
 #define P_FLAG
ac9b3d
 #endif
ac9b3d
 
ac9b3d
+#define OPTION_TSTAMP_PRECISION 130
ac9b3d
+
ac9b3d
+static struct option longopts[] = {
ac9b3d
+	{ "time-stamp-precision", required_argument, NULL, OPTION_TSTAMP_PRECISION},
ac9b3d
+};
ac9b3d
+
ac9b3d
 #ifndef WIN32
ac9b3d
 /* Drop root privileges and chroot if necessary */
ac9b3d
 static void
ac9b3d
@@ -682,6 +689,18 @@ get_next_file(FILE *VFile, char *ptr)
ac9b3d
 	return ret;
ac9b3d
 }
ac9b3d
 
ac9b3d
+static int
ac9b3d
+tstamp_precision_from_string(const char *precision)
ac9b3d
+{
ac9b3d
+	if (strncmp(precision, "nano", strlen("nano")) == 0)
ac9b3d
+		return PCAP_TSTAMP_PRECISION_NANO;
ac9b3d
+
ac9b3d
+	if (strncmp(precision, "micro", strlen("micro")) == 0)
ac9b3d
+		return PCAP_TSTAMP_PRECISION_MICRO;
ac9b3d
+
ac9b3d
+	return -EINVAL;
ac9b3d
+}
ac9b3d
+
ac9b3d
 int
ac9b3d
 main(int argc, char **argv)
ac9b3d
 {
ac9b3d
@@ -747,7 +766,7 @@ main(int argc, char **argv)
ac9b3d
 #endif
ac9b3d
 
ac9b3d
 	while (
ac9b3d
-	    (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOp" P_FLAG "qr:Rs:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:")) != -1)
ac9b3d
+               (op = getopt_long(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOp" P_FLAG "qr:Rs:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:", longopts, NULL)) != -1)
ac9b3d
 		switch (op) {
ac9b3d
 
ac9b3d
 		case 'a':
ac9b3d
@@ -1128,6 +1147,12 @@ main(int argc, char **argv)
ac9b3d
 			}
ac9b3d
 			break;
ac9b3d
 
ac9b3d
+		case OPTION_TSTAMP_PRECISION:
ac9b3d
+			gndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg);
ac9b3d
+			if (gndo->ndo_tstamp_precision < 0)
ac9b3d
+				error("unsupported time stamp precision");
ac9b3d
+			break;
ac9b3d
+
ac9b3d
 		default:
ac9b3d
 			usage();
ac9b3d
 			/* NOTREACHED */
ac9b3d
@@ -1213,7 +1238,12 @@ main(int argc, char **argv)
ac9b3d
 			RFileName = VFileLine;
ac9b3d
 		}
ac9b3d
 
ac9b3d
-		pd = pcap_open_offline(RFileName, ebuf);
ac9b3d
+                if (gndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO)
ac9b3d
+			pd = pcap_open_offline_with_tstamp_precision(RFileName, PCAP_TSTAMP_PRECISION_NANO, ebuf);
ac9b3d
+		else
ac9b3d
+			pd = pcap_open_offline_with_tstamp_precision(RFileName, PCAP_TSTAMP_PRECISION_MICRO, ebuf);
ac9b3d
+
ac9b3d
+
ac9b3d
 		if (pd == NULL)
ac9b3d
 			error("%s", ebuf);
ac9b3d
 		dlt = pcap_datalink(pd);
ac9b3d
@@ -1262,6 +1292,13 @@ main(int argc, char **argv)
ac9b3d
 		if (Jflag)
ac9b3d
 			show_tstamp_types_and_exit(device, pd);
ac9b3d
 #endif
ac9b3d
+                if (gndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
ac9b3d
+			status = pcap_set_tstamp_precision(pd, PCAP_TSTAMP_PRECISION_NANO);
ac9b3d
+			if (status != 0)
ac9b3d
+                                error("%s: Can't set nanosecond time stamp precision: %s",
ac9b3d
+                                      device, pcap_statustostr(status));
ac9b3d
+                }
ac9b3d
+
ac9b3d
 		/*
ac9b3d
 		 * Is this an interface that supports monitor mode?
ac9b3d
 		 */
ac9b3d
diff --git a/util.c b/util.c
ac9b3d
index a2ef36d..6bc05c0 100644
ac9b3d
--- a/util.c
ac9b3d
+++ b/util.c
ac9b3d
@@ -146,9 +146,12 @@ fn_printzp(register const u_char *s, register u_int n,
ac9b3d
 char *
ac9b3d
 ts_format(register int sec, register int usec)
ac9b3d
 {
ac9b3d
-        static char buf[sizeof("00:00:00.000000")];
ac9b3d
-        (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u",
ac9b3d
-               sec / 3600, (sec % 3600) / 60, sec % 60, usec);
ac9b3d
+	static char buf[sizeof("00:00:00.000000000")];
ac9b3d
+	const char *format = gndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ?
ac9b3d
+                "%02d:%02d:%02d.%09u" : "%02d:%02d:%02d.%06u";
ac9b3d
+
ac9b3d
+	snprintf(buf, sizeof(buf), format,
ac9b3d
+                 sec / 3600, (sec % 3600) / 60, sec % 60, usec);
ac9b3d
 
ac9b3d
         return buf;
ac9b3d
 }
ac9b3d
-- 
ac9b3d
2.4.3
ac9b3d