forked from osmocom/wireshark
editcap: add support for epoch timestamps in `-A` and `-B` options
Inspired in https://gitlab.com/wireshark/wireshark/-/merge_requests/1618. Tested: Timestamps on file used for comparison: ``` $ tshark -r test/captures/snakeoil-dtls.pcap -T fields -e frame.time_epoch 1150121069.248818000 1150121069.249193000 1150121069.251152000 1150121069.251384000 1150121069.293686000 1150121069.319315000 1150121075.230753000 1150121105.510885000 1150121105.510934000 ``` Before: ``` $ ./build/run/editcap -B 1150121069.3 test/captures/snakeoil-dtls.pcap - editcap: "1150121069.3" isn't a valid date and time $ ./build/run/editcap -A 1150121069.3 test/captures/snakeoil-dtls.pcap - editcap: "1150121069.3" isn't a valid date and time $ ./build/run/editcap -A 1150121069 test/captures/snakeoil-dtls.pcap - editcap: "1150121069" isn't a valid date and time $ ./build/run/editcap -B 1150121069 test/captures/snakeoil-dtls.pcap - editcap: "1150121069" isn't a valid date and time ``` After: ``` $ ./build/run/editcap -A 1150121069.3 test/captures/snakeoil-dtls.pcap - | tshark -r - -T fields -e frame.time_epoch 1150121069.319315000 1150121075.230753000 1150121105.510885000 1150121105.510934000 $ ./build/run/editcap -A 1150121069 test/captures/snakeoil-dtls.pcap - | tshark -r - -T fields -e frame.time_epoch 1150121069.248818000 1150121069.249193000 1150121069.251152000 1150121069.251384000 1150121069.293686000 1150121069.319315000 1150121075.230753000 1150121105.510885000 1150121105.510934000 $ ./build/run/editcap -B 1150121069.3 test/captures/snakeoil-dtls.pcap - | tshark -r - -T fields -e frame.time_epoch 1150121069.248818000 1150121069.249193000 1150121069.251152000 1150121069.251384000 1150121069.293686000 $ ./build/run/editcap -B 1150121069 test/captures/snakeoil-dtls.pcap - | tshark -r - -T fields -e frame.time_epoch ```pespin/rlcmac
parent
0e84610676
commit
03baf65ae7
|
@ -186,6 +186,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
type_util_gdouble_to_guint64@Base 1.10.0
|
||||
type_util_guint64_to_gdouble@Base 1.10.0
|
||||
ulaw2linear@Base 1.12.0~rc1
|
||||
unix_epoch_to_nstime@Base 3.5.0
|
||||
update_adler32@Base 1.12.0~rc1
|
||||
update_crc10_by_bytes@Base 1.10.0
|
||||
ws_add_crash_info@Base 1.10.0
|
||||
|
|
|
@ -105,7 +105,8 @@ The time is given in ISO 8601 format, either
|
|||
YYYY-MM-DD HH:MM:SS[.nnnnnnnnn][Z|±hh:mm] or
|
||||
YYYY-MM-DDTHH:MM:SS[.nnnnnnnnn][Z|±hh:mm] .
|
||||
The fractional seconds are optional, as is the time zone offset from UTC
|
||||
(in which case local time is assumed).
|
||||
(in which case local time is assumed). Unix epoch timestamps
|
||||
(floating point format) are also accepted.
|
||||
|
||||
=item -B E<lt>stop timeE<gt>
|
||||
|
||||
|
@ -114,7 +115,8 @@ The time is given in ISO 8601 format, either
|
|||
YYYY-MM-DD HH:MM:SS[.nnnnnnnnn][Z|±hh:mm] or
|
||||
YYYY-MM-DDTHH:MM:SS[.nnnnnnnnn][Z|±hh:mm] .
|
||||
The fractional seconds are optional, as is the time zone offset from UTC
|
||||
(in which case local time is assumed).
|
||||
(in which case local time is assumed). Unix epoch timestamps
|
||||
(floating point format) are also accepted.
|
||||
|
||||
=item -c E<lt>packets per fileE<gt>
|
||||
|
||||
|
|
|
@ -764,6 +764,7 @@ print_usage(FILE *output)
|
|||
fprintf(output, " given time.\n");
|
||||
fprintf(output, " Time format for -A/-B options is\n");
|
||||
fprintf(output, " YYYY-MM-DDThh:mm:ss[.nnnnnnnnn][Z|+-hh:mm]\n");
|
||||
fprintf(output, " Unix epoch timestamps are also supported.\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Duplicate packet removal:\n");
|
||||
fprintf(output, " --novlan remove vlan info from packets before checking for duplicates.\n");
|
||||
|
@ -1284,7 +1285,7 @@ main(int argc, char *argv[])
|
|||
nstime_t in_time;
|
||||
|
||||
check_startstop = TRUE;
|
||||
if (0 < iso8601_to_nstime(&in_time, optarg)) {
|
||||
if ((0 < iso8601_to_nstime(&in_time, optarg)) || (0 < unix_epoch_to_nstime(&in_time, optarg))) {
|
||||
if (opt == 'A') {
|
||||
nstime_copy(&starttime, &in_time);
|
||||
have_starttime = TRUE;
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#include "epochs.h"
|
||||
#include "time_util.h"
|
||||
|
||||
#ifndef HAVE_STRPTIME
|
||||
# include "wsutil/strptime.h"
|
||||
#endif
|
||||
|
||||
/* this is #defined so that we can clearly see that we have the right number of
|
||||
zeros, rather than as a guard against the number of nanoseconds in a second
|
||||
changing ;) */
|
||||
|
@ -453,6 +457,80 @@ iso8601_to_nstime(nstime_t *nstime, const char *ptr)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* function: unix_epoch_to_nstime
|
||||
* parses a character string for a date and time given in
|
||||
* a floating point number containing a Unix epoch date-time
|
||||
* format (e.g. 1600000000.000 for Sun Sep 13 05:26:40 AM PDT 2020)
|
||||
* and converts to an nstime_t
|
||||
* returns number of chars parsed on success, or 0 on failure
|
||||
*
|
||||
* Reference: https://en.wikipedia.org/wiki/Unix_time
|
||||
*/
|
||||
guint8
|
||||
unix_epoch_to_nstime(nstime_t *nstime, const char *ptr)
|
||||
{
|
||||
struct tm tm;
|
||||
char *ptr_new;
|
||||
|
||||
gint n_chars = 0;
|
||||
guint frac = 0;
|
||||
guint8 ret_val = 0;
|
||||
const char *start = ptr;
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
tm.tm_isdst = -1;
|
||||
nstime_set_unset(nstime);
|
||||
|
||||
if (!(ptr_new=strptime(ptr, "%s", &tm))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Validate what we got so far. mktime() doesn't care about strange
|
||||
values (and we use this to our advantage when calculating the
|
||||
time zone offset) but we should at least start with something valid */
|
||||
if (!tm_is_valid(&tm)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No UTC offset given; ISO 8601 says this means localtime */
|
||||
nstime->secs = mktime(&tm);
|
||||
|
||||
/* Now let's test for fractional seconds */
|
||||
if (*ptr_new == '.' || *ptr_new == ',') {
|
||||
/* Get fractional seconds */
|
||||
ptr_new++;
|
||||
if (1 <= sscanf(ptr_new, "%u%n", &frac, &n_chars)) {
|
||||
/* normalize frac to nanoseconds */
|
||||
if ((frac >= 1000000000) || (frac == 0)) {
|
||||
frac = 0;
|
||||
} else {
|
||||
switch (n_chars) { /* including leading zeros */
|
||||
case 1: frac *= 100000000; break;
|
||||
case 2: frac *= 10000000; break;
|
||||
case 3: frac *= 1000000; break;
|
||||
case 4: frac *= 100000; break;
|
||||
case 5: frac *= 10000; break;
|
||||
case 6: frac *= 1000; break;
|
||||
case 7: frac *= 100; break;
|
||||
case 8: frac *= 10; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
ptr_new += n_chars;
|
||||
}
|
||||
/* If we didn't get frac, it's still its default of 0 */
|
||||
}
|
||||
else {
|
||||
tm.tm_sec = 0;
|
||||
}
|
||||
nstime->nsecs = frac;
|
||||
|
||||
/* return pointer shift */
|
||||
ret_val = (guint)(ptr_new-start);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines
|
||||
*
|
||||
|
|
|
@ -128,6 +128,11 @@ WS_DLL_PUBLIC gboolean nsfiletime_to_nstime(nstime_t *nstime, guint64 nsfiletime
|
|||
Note that nstime is set to unset in the case of failure */
|
||||
WS_DLL_PUBLIC guint8 iso8601_to_nstime(nstime_t *nstime, const char *ptr);
|
||||
|
||||
/** parse an Unix epoch timestamp format datetime string to nstime, returns
|
||||
number of chars parsed on success, 0 on failure.
|
||||
Note that nstime is set to unset in the case of failure */
|
||||
WS_DLL_PUBLIC guint8 unix_epoch_to_nstime(nstime_t *nstime, const char *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
Loading…
Reference in New Issue