From 07354a18c10dfb6de9f9cf83ff6d4248eee31fb5 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Wed, 2 Jun 2010 00:30:25 +0000 Subject: [PATCH] From Jim Young via bug 4331: This patch adds a new '-S' option to editcap that will rewrite timestamps of packets to insure that the new capture file is in strict chronological order. This option's primary use case is to fixup the occasional timestamps that have a negative delta time relative to previous packet. This feature is related to (but does not depend on) capinfos enhancement submitted in bug #4315 which helps identify tracefiles with "out-of-order" packets. svn path=/trunk/; revision=33042 --- AUTHORS | 1 + doc/editcap.pod | 42 ++++++++++ docbook/release-notes.xml | 3 +- editcap.c | 156 +++++++++++++++++++++++++++++++++++++- 4 files changed, 199 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index 8106652a88..c5e74135d7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2483,6 +2483,7 @@ Jim Young { Improvements LLDP dissection (803.3 "PMD Auto-Negotiation Advertised Capability" and "Operational MAU Type") Capinfos time order checking + Editcap time order forcing } diff --git a/doc/editcap.pod b/doc/editcap.pod index 5499154731..f2cb2f7e34 100644 --- a/doc/editcap.pod +++ b/doc/editcap.pod @@ -17,6 +17,7 @@ S<[ B<-i> Eseconds per fileE ]> S<[ B<-r> ]> S<[ B<-s> EsnaplenE ]> S<[ B<-t> Etime adjustmentE ]> +S<[ B<-S> Estrict time adjustmentE ]> S<[ B<-T> Eencapsulation typeE ]> S<[ B<-v> ]> I @@ -204,6 +205,39 @@ This feature is useful when synchronizing dumps collected on different machines where the time difference between the two machines is known or can be estimated. +=item -S Estrict time adjustmentE + +Time adjust selected packets to insure strict chronological order. + +The value represents relative seconds +specified as [-]I[I<.fractional seconds>]. + +As the capture file is processed each packet's absolute time is +I adjusted to be equal to or greater than the previous +packet's absolute timestamp depending on the value. + +If value is 0 or greater (e.g. 0.000001) +then B packets with a timestamp less than the previous packet +will adjusted. The adjusted timestamp value will be set to be +equal to the timestamp value of the previous packet plus the value +of the value. A +value of 0 will adjust the minimum number of timestamp values +necessary to insure that the resulting capture file is in +strict chronological order. + +If value is specified as a +negative value, then the timestamp values of B +packets will be adjusted to be equal to the timestamp value +of the previous packet plus the absolute value of the +strict time adjustment value. A value of -0 will result in all packets +having the timestamp value of the first packet. + +This feature is useful when the trace file has an occasional +packet with a negative delta time relative to the previous +packet. + =item -T Eencapsulation typeE Sets the packet encapsulation type of the output capture file. @@ -288,6 +322,14 @@ or on Windows systems editcap -v -D 0 capture.pcap NUL +To advance the timestamps of each packet forward by 3.0827 seconds: + + editcap -t 3.0827 capture.pcap adjusted.pcap + +To insure all timestamps are in strict chronological order: + + editcap -S 0 capture.pcap adjusted.pcap + To introduce 5% random errors in a capture file use: =over 4 diff --git a/docbook/release-notes.xml b/docbook/release-notes.xml index 62cc6af4b2..ccba280ecd 100644 --- a/docbook/release-notes.xml +++ b/docbook/release-notes.xml @@ -137,7 +137,8 @@ Wireshark Info - Capinfos now checks the time order of capture files. + Capinfos and editcap now respectively support time order checking + and forcing. diff --git a/editcap.c b/editcap.c index 3492fb75cc..3cdfe59ce0 100644 --- a/editcap.c +++ b/editcap.c @@ -134,6 +134,10 @@ static gboolean check_startstop = FALSE; static gboolean dup_detect = FALSE; static gboolean dup_detect_by_time = FALSE; +static int do_strict_time_adjustment = FALSE; +static struct time_adjustment strict_time_adj = {{0, 0}, 0}; /* strict time adjustment */ +static nstime_t previous_time = {0, 0}; /* previous time */ + static int find_dct2000_real_data(guint8 *buf); static gchar * @@ -364,6 +368,81 @@ set_time_adjustment(char *optarg_str_p) time_adj.tv.tv_usec = val; } +static void +set_strict_time_adj(char *optarg) +{ + char *frac, *end; + long val; + size_t frac_digits; + + if (!optarg) + return; + + /* skip leading whitespace */ + while (*optarg == ' ' || *optarg == '\t') { + optarg++; + } + + /* + * check for a negative adjustment + * A negative strict adjustment value is a flag + * to adjust all frames by the specifed delta time. + */ + if (*optarg == '-') { + strict_time_adj.is_negative = 1; + optarg++; + } + + /* collect whole number of seconds, if any */ + if (*optarg == '.') { /* only fractional (i.e., .5 is ok) */ + val = 0; + frac = optarg; + } else { + val = strtol(optarg, &frac, 10); + if (frac == NULL || frac == optarg || val == LONG_MIN || val == LONG_MAX) { + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg); + exit(1); + } + if (val < 0) { /* implies '--' since we caught '-' above */ + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg); + exit(1); + } + } + strict_time_adj.tv.tv_sec = val; + + /* now collect the partial seconds, if any */ + if (*frac != '\0') { /* chars left, so get fractional part */ + val = strtol(&(frac[1]), &end, 10); + /* if more than 6 fractional digits truncate to 6 */ + if((end - &(frac[1])) > 6) { + frac[7] = 't'; /* 't' for truncate */ + val = strtol(&(frac[1]), &end, 10); + } + if (*frac != '.' || end == NULL || end == frac + || val < 0 || val > ONE_MILLION || val == LONG_MIN || val == LONG_MAX) { + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg); + exit(1); + } + } + else { + return; /* no fractional digits */ + } + + /* adjust fractional portion from fractional to numerator + * e.g., in "1.5" from 5 to 500000 since .5*10^6 = 500000 */ + if (frac && end) { /* both are valid */ + frac_digits = end - frac - 1; /* fractional digit count (remember '.') */ + while(frac_digits < 6) { /* this is frac of 10^6 */ + val *= 10; + frac_digits++; + } + } + strict_time_adj.tv.tv_usec = val; +} + static void set_rel_time(char *optarg_str_p) { @@ -613,7 +692,7 @@ usage(gboolean is_error) fprintf(output, "\n"); fprintf(output, " NOTE: The use of the 'Duplicate packet removal' options with\n"); fprintf(output, " other editcap options except -v may not always work as expected.\n"); - fprintf(output, " Specifically the -r and -t options will very likely NOT have the\n"); + fprintf(stderr, " Specifically the -r, -t or -S options will very likely NOT have the\n"); fprintf(output, " desired effect if combined with the -d, -D or -w.\n"); fprintf(output, "\n"); fprintf(output, "Packet manipulation:\n"); @@ -621,6 +700,14 @@ usage(gboolean is_error) fprintf(output, " -C chop each packet at the end by bytes.\n"); fprintf(output, " -t