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 ```
This commit is contained in:
parent
0e84610676
commit
03baf65ae7
1
debian/libwsutil0.symbols
vendored
1
debian/libwsutil0.symbols
vendored
@ -186,6 +186,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||||||
type_util_gdouble_to_guint64@Base 1.10.0
|
type_util_gdouble_to_guint64@Base 1.10.0
|
||||||
type_util_guint64_to_gdouble@Base 1.10.0
|
type_util_guint64_to_gdouble@Base 1.10.0
|
||||||
ulaw2linear@Base 1.12.0~rc1
|
ulaw2linear@Base 1.12.0~rc1
|
||||||
|
unix_epoch_to_nstime@Base 3.5.0
|
||||||
update_adler32@Base 1.12.0~rc1
|
update_adler32@Base 1.12.0~rc1
|
||||||
update_crc10_by_bytes@Base 1.10.0
|
update_crc10_by_bytes@Base 1.10.0
|
||||||
ws_add_crash_info@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-DD HH:MM:SS[.nnnnnnnnn][Z|±hh:mm] or
|
||||||
YYYY-MM-DDTHH:MM:SS[.nnnnnnnnn][Z|±hh:mm] .
|
YYYY-MM-DDTHH:MM:SS[.nnnnnnnnn][Z|±hh:mm] .
|
||||||
The fractional seconds are optional, as is the time zone offset from UTC
|
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>
|
=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-DD HH:MM:SS[.nnnnnnnnn][Z|±hh:mm] or
|
||||||
YYYY-MM-DDTHH:MM:SS[.nnnnnnnnn][Z|±hh:mm] .
|
YYYY-MM-DDTHH:MM:SS[.nnnnnnnnn][Z|±hh:mm] .
|
||||||
The fractional seconds are optional, as is the time zone offset from UTC
|
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>
|
=item -c E<lt>packets per fileE<gt>
|
||||||
|
|
||||||
|
@ -764,6 +764,7 @@ print_usage(FILE *output)
|
|||||||
fprintf(output, " given time.\n");
|
fprintf(output, " given time.\n");
|
||||||
fprintf(output, " Time format for -A/-B options is\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, " YYYY-MM-DDThh:mm:ss[.nnnnnnnnn][Z|+-hh:mm]\n");
|
||||||
|
fprintf(output, " Unix epoch timestamps are also supported.\n");
|
||||||
fprintf(output, "\n");
|
fprintf(output, "\n");
|
||||||
fprintf(output, "Duplicate packet removal:\n");
|
fprintf(output, "Duplicate packet removal:\n");
|
||||||
fprintf(output, " --novlan remove vlan info from packets before checking for duplicates.\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;
|
nstime_t in_time;
|
||||||
|
|
||||||
check_startstop = TRUE;
|
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') {
|
if (opt == 'A') {
|
||||||
nstime_copy(&starttime, &in_time);
|
nstime_copy(&starttime, &in_time);
|
||||||
have_starttime = TRUE;
|
have_starttime = TRUE;
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#include "epochs.h"
|
#include "epochs.h"
|
||||||
#include "time_util.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
|
/* 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
|
zeros, rather than as a guard against the number of nanoseconds in a second
|
||||||
changing ;) */
|
changing ;) */
|
||||||
@ -453,6 +457,80 @@ iso8601_to_nstime(nstime_t *nstime, const char *ptr)
|
|||||||
return ret_val;
|
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
|
* 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 */
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user