From 70ec244f8f81c7da84bef51d0c7adac343592c0a Mon Sep 17 00:00:00 2001 From: Sake Blok Date: Sat, 21 Jun 2008 09:45:21 +0000 Subject: [PATCH] From Ken Smith (bug 2574): Allow editcap to parse files into even time intervals A few changes from me: - make use of nstime_set_unset and nstime_is_unset i.s.o. extra variable first_pass - change 'if' to 'while' to allow intervals with no packets - remove 'unused' variable current_pkt_ts svn path=/trunk/; revision=25499 --- Makefile.common | 1 + editcap.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Makefile.common b/Makefile.common index d0266d4462..b51e048d46 100644 --- a/Makefile.common +++ b/Makefile.common @@ -207,6 +207,7 @@ mergecap_SOURCES = \ editcap_SOURCES = \ editcap.c \ epan/crypt/crypt-md5.c \ + epan/nstime.c \ $(WTAP_PLUGIN_SOURCES) capinfos_SOURCES = \ diff --git a/editcap.c b/editcap.c index 8628c50e35..57f1e0a4a3 100644 --- a/editcap.c +++ b/editcap.c @@ -59,6 +59,7 @@ #include "epan/report_err.h" #include "epan/filesystem.h" #include +#include "epan/nstime.h" #include "svnversion.h" @@ -325,7 +326,11 @@ usage(void) fprintf(stderr, "\n"); fprintf(stderr, "Output File(s):\n"); fprintf(stderr, " -c split the packet output to different files,\n"); + fprintf(stderr, " based on uniform packet counts \n"); fprintf(stderr, " with a maximum of each\n"); + fprintf(stderr, " -i split the packet output to different files,\n"); + fprintf(stderr, " based on uniform time intervals \n"); + fprintf(stderr, " with a maximum of each\n"); fprintf(stderr, " -F set the output file type, default is libpcap\n"); fprintf(stderr, " an empty \"-F\" option will list the file types\n"); fprintf(stderr, " -T set the output file encapsulation type,\n"); @@ -399,6 +404,10 @@ main(int argc, char *argv[]) char *filename; size_t filenamelen = 0; gboolean check_ts; + int secs_per_block = 0; + int block_cnt = 0; + nstime_t block_start; + #ifdef HAVE_PLUGINS char* init_progfile_dir_error; #endif @@ -420,7 +429,7 @@ main(int argc, char *argv[]) #endif /* Process the options */ - while ((opt = getopt(argc, argv, "A:B:c:C:dE:F:hrs:t:T:v")) !=-1) { + while ((opt = getopt(argc, argv, "A:B:c:C:dE:F:hrs:i:t:T:v")) !=-1) { switch (opt) { @@ -525,6 +534,15 @@ main(int argc, char *argv[]) verbose = !verbose; /* Just invert */ break; + case 'i': /* break capture file based on time interval */ + secs_per_block = atoi(optarg); + nstime_set_unset(&block_start); + if(secs_per_block <= 0) { + fprintf(stderr, "editcap: \"%s\" isn't a valid time interval\n\n", optarg); + exit(1); + } + break; + case 'A': { struct tm starttm; @@ -589,6 +607,12 @@ main(int argc, char *argv[]) exit(1); } + if (split_packet_count > 0 && secs_per_block > 0) { + fprintf(stderr, "editcap: can't split on both packet count and time interval\n"); + fprintf(stderr, "editcap: at the same time\n"); + exit(1); + } + wth = wtap_open_offline(argv[optind], &err, &err_info, FALSE); if (!wth) { @@ -630,8 +654,18 @@ main(int argc, char *argv[]) } g_snprintf(filename, filenamelen, "%s-%05d", argv[optind+1], 0); } else { - filename = argv[optind+1]; - } + if (secs_per_block > 0) { + filenamelen = strlen(argv[optind+1]) + 7; + filename = (char *) g_malloc(filenamelen); + if (!filename) { + exit(5); + } + g_snprintf(filename, filenamelen, "%s-%05d", argv[optind+1], block_cnt); + } + else { + filename = argv[optind+1]; + } + } pdh = wtap_dump_open(filename, out_file_type, out_frame_type, wtap_snapshot_length(wth), @@ -649,6 +683,41 @@ main(int argc, char *argv[]) while (wtap_read(wth, &err, &err_info, &data_offset)) { + if (secs_per_block > 0) { + phdr = wtap_phdr(wth); + + if (nstime_is_unset(&block_start)) { /* should only be the first packet */ + block_start.secs = phdr->ts.secs; + block_start.nsecs = phdr->ts.nsecs; + } + + while ((phdr->ts.secs - block_start.secs > secs_per_block) || + (phdr->ts.secs - block_start.secs == secs_per_block && + phdr->ts.nsecs >= block_start.nsecs )) { /* time for the next file */ + + if (!wtap_dump_close(pdh, &err)) { + fprintf(stderr, "editcap: Error writing to %s: %s\n", filename, + wtap_strerror(err)); + exit(1); + } + block_start.secs = block_start.secs + secs_per_block; /* reset for next interval */ + g_snprintf(filename, filenamelen, "%s-%05d",argv[optind+1], ++block_cnt); + + if (verbose) { + fprintf(stderr, "Continuing writing in file %s\n", filename); + } + + pdh = wtap_dump_open(filename, out_file_type, + out_frame_type, wtap_snapshot_length(wth), FALSE /* compressed */, &err); + + if (pdh == NULL) { + fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename, + wtap_strerror(err)); + exit(1); + } + } + } + if (split_packet_count > 0 && (written_count % split_packet_count == 0)) { if (!wtap_dump_close(pdh, &err)) {