diff options
author | David Perry <boolean263@protonmail.com> | 2020-08-05 13:20:07 -0400 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2020-08-05 21:32:45 +0000 |
commit | 555b89492a99f41b5347c0b2f6b4b9ecbd5fe22f (patch) | |
tree | e10b3ddcb1c23ba68bfea7e4e312a43485ac5786 /editcap.c | |
parent | e22da97fd159965069fccb4b62feb5c33e906075 (diff) |
editcap: support fractional seconds in -A/-B opts
Allow user to specify time resolutions as fine as 1 nanosecond for the
start and stop times (-A and -B options) for editcap. Uses `nstime_t`
for the user options and `nstime_cmp()` to compare with packet
timestamps.
Change-Id: I2340bc4830c7d9a6b17a5e53fa4e8837e231bcb6
Reviewed-on: https://code.wireshark.org/review/38057
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'editcap.c')
-rw-r--r-- | editcap.c | 96 |
1 files changed, 61 insertions, 35 deletions
@@ -161,8 +161,8 @@ static int verbose = 0; /* Not so verbose static struct time_adjustment time_adj = {NSTIME_INIT_ZERO, 0}; /* no adjustment */ static nstime_t relative_time_window = NSTIME_INIT_ZERO; /* de-dup time window */ static double err_prob = -1.0; -static time_t starttime = 0; -static time_t stoptime = 0; +static nstime_t starttime = NSTIME_INIT_ZERO; +static nstime_t stoptime = NSTIME_INIT_ZERO; static gboolean check_startstop = FALSE; static gboolean rem_vlan = FALSE; static gboolean dup_detect = FALSE; @@ -755,9 +755,9 @@ print_usage(FILE *output) fprintf(output, "Packet selection:\n"); fprintf(output, " -r keep the selected packets; default is to delete them.\n"); fprintf(output, " -A <start time> only output packets whose timestamp is after (or equal\n"); - fprintf(output, " to) the given time (format as YYYY-MM-DD hh:mm:ss).\n"); + fprintf(output, " to) the given time (format as YYYY-MM-DD hh:mm:ss[.nnnnnnnnn]).\n"); fprintf(output, " -B <stop time> only output packets whose timestamp is before the\n"); - fprintf(output, " given time (format as YYYY-MM-DD hh:mm:ss).\n"); + fprintf(output, " given time (format as YYYY-MM-DD hh:mm:ss[.nnnnnnnnn]).\n"); fprintf(output, "\n"); fprintf(output, "Duplicate packet removal:\n"); fprintf(output, " --novlan remove vlan info from packets before checking for duplicates.\n"); @@ -1184,41 +1184,66 @@ main(int argc, char *argv[]) } case 'A': + case 'B': { - struct tm starttm; +#define NSEC_MAXLEN 9 + struct tm st_tm; + int nsec = 0; + char *och; - memset(&starttm,0,sizeof(struct tm)); + memset(&st_tm,0,sizeof(struct tm)); - if (!strptime(optarg,"%Y-%m-%d %T", &starttm)) { - fprintf(stderr, "editcap: \"%s\" isn't a valid time format\n\n", - optarg); - ret = INVALID_OPTION; - goto clean_exit; + if (!(och=strptime(optarg,"%Y-%m-%d %T", &st_tm))) { + goto invalid_time; } - check_startstop = TRUE; - starttm.tm_isdst = -1; + /* Sub-second support: see if the time is followed by a '.' */ + if (och != NULL && *och != '\0') { + char *c; + char subsec[NSEC_MAXLEN+1] = ""; + int nchars; - starttime = mktime(&starttm); - break; - } + if (*och != '.') { + goto invalid_time; + } + och++; + c = subsec; - case 'B': - { - struct tm stoptm; + /* Ensure that only 1-9 digits follow the '.' */ + for (nchars = 0; *och != '\0' && nchars < NSEC_MAXLEN; nchars++) { + if (!g_ascii_isdigit(*och)) { + goto invalid_time; + } + *c++ = *och++; + } + if (*och != '\0') { + goto invalid_time; + } + /* Right-pad what we do have, so eg. 5 = 500,000,000 ns */ + for (; nchars < NSEC_MAXLEN; nchars++) { + *c++ = '0'; + } + *c = '\0'; + nsec = strtol(subsec, NULL, 10); + } - memset(&stoptm,0,sizeof(struct tm)); + check_startstop = TRUE; + st_tm.tm_isdst = -1; - if (!strptime(optarg,"%Y-%m-%d %T", &stoptm)) { - fprintf(stderr, "editcap: \"%s\" isn't a valid time format\n\n", - optarg); - ret = INVALID_OPTION; - goto clean_exit; + if (opt == 'A') { + starttime.secs = mktime(&st_tm); + starttime.nsecs = nsec; + } else { + stoptime.secs = mktime(&st_tm); + stoptime.nsecs = nsec; } - check_startstop = TRUE; - stoptm.tm_isdst = -1; - stoptime = mktime(&stoptm); break; + +invalid_time: + fprintf(stderr, "editcap: \"%s\" isn't a valid time format\n\n", + optarg); + ret = INVALID_OPTION; + goto clean_exit; } case 'c': @@ -1433,7 +1458,7 @@ main(int argc, char *argv[]) srand(seed); } - if (starttime > stoptime) { + if (nstime_cmp(&starttime, &stoptime) > 0) { fprintf(stderr, "editcap: start time is after the stop time\n"); ret = INVALID_OPTION; goto clean_exit; @@ -1677,12 +1702,13 @@ main(int argc, char *argv[]) * If the packet has no time stamp, the answer is "no". */ if (rec->presence_flags & WTAP_HAS_TS) { - if (starttime && stoptime) { - ts_okay = (rec->ts.secs >= starttime) && (rec->ts.secs < stoptime); - } else if (starttime) { - ts_okay = rec->ts.secs >= starttime; - } else if (stoptime) { - ts_okay = rec->ts.secs < stoptime; + if (!nstime_is_zero(&starttime) && !nstime_is_zero(&stoptime)) { + ts_okay = nstime_cmp(&rec->ts, &starttime) >= 0 && + nstime_cmp(&rec->ts, &stoptime) < 0; + } else if (!nstime_is_zero(&starttime)) { + ts_okay = nstime_cmp(&rec->ts, &starttime) >= 0; + } else if (!nstime_is_zero(&stoptime)) { + ts_okay = nstime_cmp(&rec->ts, &stoptime) < 0; } } } else { |