Editcap: Allow floating point split intervals.

Update the `-i` option to allow floating point values as suggested at
https://stackoverflow.com/questions/57004719/split-wireshark-to-miliseconds

Change-Id: I24028d409bc441ed3b45ac2179f7c42b2bc424bc
Reviewed-on: https://code.wireshark.org/review/33938
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Gerald Combs 2019-07-14 09:51:40 -07:00 committed by Anders Broman
parent 2377dff96c
commit 8147af211d
4 changed files with 34 additions and 18 deletions

View File

@ -178,9 +178,10 @@ Prints the version and options and exits.
=item -i E<lt>seconds per fileE<gt>
Splits the packet output to different files based on uniform time intervals
using a maximum interval of <seconds per file> each. Each output file will
be created with a suffix -nnnnn, starting with 00000. If packets for the specified
Splits the packet output to different files based on uniform time
intervals using a maximum interval of <seconds per file> each. Floating
point values (e.g. 0.5) are allowed. Each output file will be created
with a suffix -nnnnn, starting with 00000. If packets for the specified
time interval are written to the output file, the next output file is
opened. The default is to use a single output file.

View File

@ -44,6 +44,7 @@ since version 3.0.0:
* A new tap for extracting credentials from the capture file has been added.
It can be accessed through the "-z credentials" option in tshark or from the
"tools" menu in Wireshark.
* Editcap can now split files on floating point intervals.
// === Removed Features and Support

View File

@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
/*
* Just make sure we include the prototype for strptime as well
@ -88,6 +89,7 @@
#define CANT_EXTRACT_PREFIX 2
#define WRITE_ERROR 2
#define DUMP_ERROR 2
#define NANOSECS_PER_SEC 1000000000
/*
* Some globals so we can pass things to various routines
@ -1046,9 +1048,9 @@ main(int argc, char *argv[])
int written_count = 0;
char *filename = NULL;
gboolean ts_okay;
guint32 secs_per_block = 0;
nstime_t secs_per_block = NSTIME_INIT_UNSET;
int block_cnt = 0;
nstime_t block_start;
nstime_t block_next = NSTIME_INIT_UNSET;
gchar *fprefix = NULL;
gchar *fsuffix = NULL;
guint32 change_offset = 0;
@ -1312,7 +1314,19 @@ main(int argc, char *argv[])
break;
case 'i': /* break capture file based on time interval */
secs_per_block = get_nonzero_guint32(optarg, "time interval");
{
double spb = get_positive_double(optarg, "time interval");
if (spb == 0.0) {
cmdarg_err("The specified interval is zero");
ret = INVALID_OPTION;
goto clean_exit;
}
double spb_int, spb_frac;
spb_frac = modf(spb, &spb_int);
secs_per_block.secs = (time_t) spb_int;
secs_per_block.nsecs = (int) (NANOSECS_PER_SEC * spb_frac);
}
break;
case 'I': /* ignored_bytes at the beginning of the frame for duplications removal */
@ -1438,15 +1452,13 @@ main(int argc, char *argv[])
stoptime = mktime(&stoptm);
}
nstime_set_unset(&block_start);
if (starttime > stoptime) {
fprintf(stderr, "editcap: start time is after the stop time\n");
ret = INVALID_OPTION;
goto clean_exit;
}
if (split_packet_count != 0 && secs_per_block != 0) {
if (split_packet_count != 0 && !nstime_is_unset(&secs_per_block)) {
fprintf(stderr, "editcap: can't split on both packet count and time interval\n");
fprintf(stderr, "editcap: at the same time\n");
ret = INVALID_OPTION;
@ -1581,7 +1593,7 @@ main(int argc, char *argv[])
/* Extra actions for the first packet */
if (read_count == 1) {
if (split_packet_count != 0 || secs_per_block != 0) {
if (split_packet_count != 0 || !nstime_is_unset(&secs_per_block)) {
if (!fileset_extract_prefix_suffix(argv[optind+1], &fprefix, &fsuffix)) {
ret = CANT_EXTRACT_PREFIX;
goto clean_exit;
@ -1617,20 +1629,19 @@ main(int argc, char *argv[])
* stamp if we have one.
*/
if (rec->presence_flags & WTAP_HAS_TS) {
if (nstime_is_unset(&block_start)) {
block_start = rec->ts;
}
if (secs_per_block != 0) {
while (((guint32)(rec->ts.secs - block_start.secs) > secs_per_block)
|| ((guint32)(rec->ts.secs - block_start.secs) == secs_per_block
&& rec->ts.nsecs >= block_start.nsecs )) { /* time for the next file */
if (!nstime_is_unset(&secs_per_block)) {
if (nstime_is_unset(&block_next)) {
block_next = rec->ts;
nstime_add(&block_next, &secs_per_block);
}
while (nstime_cmp(&rec->ts, &block_next) > 0) { /* time for the next file */
if (!wtap_dump_close(pdh, &write_err)) {
cfile_close_failure_message(filename, write_err);
ret = WRITE_ERROR;
goto clean_exit;
}
block_start.secs = block_start.secs + secs_per_block; /* reset for next interval */
nstime_add(&block_next, &secs_per_block); /* reset for next interval */
g_free(filename);
filename = fileset_get_filename_by_pattern(block_cnt++, rec, fprefix, fsuffix);
g_assert(filename);

View File

@ -34,6 +34,9 @@ typedef struct {
/* Initialize to zero */
#define NSTIME_INIT_ZERO {0, 0}
/* Initialize to unset */
#define NSTIME_INIT_UNSET {0, G_MAXINT}
/* Initialize to a specified number of seconds and nanoseconds */
#define NSTIME_INIT_SECS_NSECS(secs, nsecs) {secs, nsecs}