X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=editcap.c;h=3332d5df6aaff02dafc741d3806e58c2c220f2ae;hb=6c65dd2b30dcab31f6fdc90bed309e6b9ca09d0e;hp=2cbf2387f02a6e31745edcdf88d825a6264c67c2;hpb=5ba1582dda65479e99565b74a0238c23c41ce838;p=metze%2Fwireshark%2Fwip.git diff --git a/editcap.c b/editcap.c index 2cbf2387f0..3332d5df6a 100644 --- a/editcap.c +++ b/editcap.c @@ -1,16 +1,34 @@ /* Edit capture files. We can delete packets, adjust timestamps, or * simply convert from one format to another format. * - * $Id$ - * * Originally written by Richard Sharpe. * Improved by Guy Harris. * Further improved by Richard Sharpe. + * + * Copyright 2013, Richard Sharpe + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include #include @@ -34,21 +52,19 @@ #include #endif - - #ifdef HAVE_SYS_TIME_H #include #endif #include "wtap.h" -#ifdef HAVE_GETOPT_H -#include -#else -#include "wsgetopt.h" +#ifndef HAVE_GETOPT +#include "wsutil/wsgetopt.h" #endif #ifdef _WIN32 +#include +#include #include /* getpid */ #ifdef HAVE_WINSOCK2_H #include @@ -56,18 +72,31 @@ #endif #ifdef NEED_STRPTIME_H -# include "strptime.h" +# include "wsutil/strptime.h" #endif -#include "epan/crypt/crypt-md5.h" +#include + +/* + * The symbols declared in the below are exported from libwireshark, + * but we don't want to link whole libwireshark to editcap. + * We link the object directly instead and this needs a little trick + * with the WS_BUILD_DLL #define. + */ +#define WS_BUILD_DLL +#define RESET_SYMBOL_EXPORT /* wsutil/wsgetopt.h set export behavior above. */ +#include "epan/crypt/md5.h" #include "epan/plugins.h" #include "epan/report_err.h" #include "epan/filesystem.h" -#include #include "epan/nstime.h" +#undef WS_BUILD_DLL +#define RESET_SYMBOL_EXPORT #include "svnversion.h" +#include "ringbuffer.h" /* For RINGBUFFER_MAX_NUM_FILES */ + /* * Some globals so we can pass things to various routines */ @@ -122,7 +151,11 @@ struct time_adjustment { static struct select_item selectfrm[MAX_SELECTIONS]; static int max_selected = -1; static int keep_em = 0; -static int out_file_type = WTAP_FILE_PCAP; /* default to "libpcap" */ +#ifdef PCAP_NG_DEFAULT +static int out_file_type = WTAP_FILE_PCAPNG; /* default to pcapng */ +#else +static int out_file_type = WTAP_FILE_PCAP; /* default to pcap */ +#endif static int out_frame_type = -2; /* Leave frame type alone */ static int verbose = 0; /* Not so verbose */ static struct time_adjustment time_adj = {{0, 0}, 0}; /* no adjustment */ @@ -134,15 +167,19 @@ static gboolean check_startstop = FALSE; static gboolean dup_detect = FALSE; static gboolean dup_detect_by_time = FALSE; +static int do_strict_time_adjustment = FALSE; +static struct time_adjustment strict_time_adj = {{0, 0}, 0}; /* strict time adjustment */ +static nstime_t previous_time = {0, 0}; /* previous time */ + static int find_dct2000_real_data(guint8 *buf); static gchar * abs_time_to_str_with_sec_resolution(const struct wtap_nstime *abs_time) { struct tm *tmp; - gchar *buf = g_malloc(16); - -#ifdef _MSC_VER + gchar *buf = (gchar *)g_malloc(16); + +#if (defined _WIN32) && (_MSC_VER < 1500) /* calling localtime() on MSVC 2005 with huge values causes it to crash */ /* XXX - find the exact value that still does work */ /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */ @@ -160,21 +197,21 @@ abs_time_to_str_with_sec_resolution(const struct wtap_nstime *abs_time) tmp->tm_min, tmp->tm_sec); } else - strcpy(buf, ""); + buf[0] = '\0'; return buf; } static gchar* -fileset_get_filename_by_pattern(guint idx, const struct wtap_nstime *time, - gchar *fprefix, gchar *fsuffix) +fileset_get_filename_by_pattern(guint idx, const struct wtap_nstime *time_val, + gchar *fprefix, gchar *fsuffix) { gchar filenum[5+1]; gchar *timestr; gchar *abs_str; - timestr = abs_time_to_str_with_sec_resolution(time); - g_snprintf(filenum, sizeof(filenum), "%05u", idx); + timestr = abs_time_to_str_with_sec_resolution(time_val); + g_snprintf(filenum, sizeof(filenum), "%05u", idx % RINGBUFFER_MAX_NUM_FILES); abs_str = g_strconcat(fprefix, "_", filenum, "_", timestr, fsuffix, NULL); g_free(timestr); @@ -290,44 +327,44 @@ check_timestamp(wtap *wth) { struct wtap_pkthdr* pkthdr = wtap_phdr(wth); - return ( pkthdr->ts.secs >= starttime ) && ( pkthdr->ts.secs <= stoptime ); + return ( pkthdr->ts.secs >= starttime ) && ( pkthdr->ts.secs < stoptime ); } static void -set_time_adjustment(char *optarg) +set_time_adjustment(char *optarg_str_p) { char *frac, *end; long val; size_t frac_digits; - if (!optarg) + if (!optarg_str_p) return; /* skip leading whitespace */ - while (*optarg == ' ' || *optarg == '\t') { - optarg++; + while (*optarg_str_p == ' ' || *optarg_str_p == '\t') { + optarg_str_p++; } /* check for a negative adjustment */ - if (*optarg == '-') { + if (*optarg_str_p == '-') { time_adj.is_negative = 1; - optarg++; + optarg_str_p++; } /* collect whole number of seconds, if any */ - if (*optarg == '.') { /* only fractional (i.e., .5 is ok) */ + if (*optarg_str_p == '.') { /* only fractional (i.e., .5 is ok) */ val = 0; - frac = optarg; + frac = optarg_str_p; } else { - val = strtol(optarg, &frac, 10); - if (frac == NULL || frac == optarg || val == LONG_MIN || val == LONG_MAX) { + val = strtol(optarg_str_p, &frac, 10); + if (frac == NULL || frac == optarg_str_p || val == LONG_MIN || val == LONG_MAX) { fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", - optarg); + optarg_str_p); exit(1); } if (val < 0) { /* implies '--' since we caught '-' above */ fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", - optarg); + optarg_str_p); exit(1); } } @@ -344,7 +381,7 @@ set_time_adjustment(char *optarg) if (*frac != '.' || end == NULL || end == frac || val < 0 || val > ONE_MILLION || val == LONG_MIN || val == LONG_MAX) { fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", - optarg); + optarg_str_p); exit(1); } } @@ -361,43 +398,118 @@ set_time_adjustment(char *optarg) frac_digits++; } } - time_adj.tv.tv_usec = val; + time_adj.tv.tv_usec = (int)val; } static void -set_rel_time(char *optarg) +set_strict_time_adj(char *optarg_str_p) { char *frac, *end; long val; size_t frac_digits; - if (!optarg) + if (!optarg_str_p) return; /* skip leading whitespace */ - while (*optarg == ' ' || *optarg == '\t') { - optarg++; + while (*optarg_str_p == ' ' || *optarg_str_p == '\t') { + optarg_str_p++; + } + + /* + * check for a negative adjustment + * A negative strict adjustment value is a flag + * to adjust all frames by the specifed delta time. + */ + if (*optarg_str_p == '-') { + strict_time_adj.is_negative = 1; + optarg_str_p++; + } + + /* collect whole number of seconds, if any */ + if (*optarg_str_p == '.') { /* only fractional (i.e., .5 is ok) */ + val = 0; + frac = optarg_str_p; + } else { + val = strtol(optarg_str_p, &frac, 10); + if (frac == NULL || frac == optarg_str_p || val == LONG_MIN || val == LONG_MAX) { + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg_str_p); + exit(1); + } + if (val < 0) { /* implies '--' since we caught '-' above */ + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg_str_p); + exit(1); + } + } + strict_time_adj.tv.tv_sec = val; + + /* now collect the partial seconds, if any */ + if (*frac != '\0') { /* chars left, so get fractional part */ + val = strtol(&(frac[1]), &end, 10); + /* if more than 6 fractional digits truncate to 6 */ + if((end - &(frac[1])) > 6) { + frac[7] = 't'; /* 't' for truncate */ + val = strtol(&(frac[1]), &end, 10); + } + if (*frac != '.' || end == NULL || end == frac + || val < 0 || val > ONE_MILLION || val == LONG_MIN || val == LONG_MAX) { + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg_str_p); + exit(1); + } + } + else { + return; /* no fractional digits */ + } + + /* adjust fractional portion from fractional to numerator + * e.g., in "1.5" from 5 to 500000 since .5*10^6 = 500000 */ + if (frac && end) { /* both are valid */ + frac_digits = end - frac - 1; /* fractional digit count (remember '.') */ + while(frac_digits < 6) { /* this is frac of 10^6 */ + val *= 10; + frac_digits++; + } + } + strict_time_adj.tv.tv_usec = (int)val; +} + +static void +set_rel_time(char *optarg_str_p) +{ + char *frac, *end; + long val; + size_t frac_digits; + + if (!optarg_str_p) + return; + + /* skip leading whitespace */ + while (*optarg_str_p == ' ' || *optarg_str_p == '\t') { + optarg_str_p++; } /* ignore negative adjustment */ - if (*optarg == '-') { - optarg++; + if (*optarg_str_p == '-') { + optarg_str_p++; } /* collect whole number of seconds, if any */ - if (*optarg == '.') { /* only fractional (i.e., .5 is ok) */ + if (*optarg_str_p == '.') { /* only fractional (i.e., .5 is ok) */ val = 0; - frac = optarg; + frac = optarg_str_p; } else { - val = strtol(optarg, &frac, 10); - if (frac == NULL || frac == optarg || val == LONG_MIN || val == LONG_MAX) { + val = strtol(optarg_str_p, &frac, 10); + if (frac == NULL || frac == optarg_str_p || val == LONG_MIN || val == LONG_MAX) { fprintf(stderr, "1: editcap: \"%s\" isn't a valid rel time value\n", - optarg); + optarg_str_p); exit(1); } if (val < 0) { /* implies '--' since we caught '-' above */ fprintf(stderr, "2: editcap: \"%s\" isn't a valid rel time value\n", - optarg); + optarg_str_p); exit(1); } } @@ -414,7 +526,7 @@ set_rel_time(char *optarg) if (*frac != '.' || end == NULL || end == frac || val < 0 || val > ONE_BILLION || val == LONG_MIN || val == LONG_MAX) { fprintf(stderr, "3: editcap: \"%s\" isn't a valid rel time value\n", - optarg); + optarg_str_p); exit(1); } } @@ -431,7 +543,7 @@ set_rel_time(char *optarg) frac_digits++; } } - relative_time_window.nsecs = val; + relative_time_window.nsecs = (int)val; } static gboolean @@ -571,98 +683,149 @@ is_duplicate_rel_time(guint8* fd, guint32 len, const nstime_t *current) { } static void -usage(void) +usage(gboolean is_error) { - fprintf(stderr, "Editcap %s" + FILE *output; + + if (!is_error) + output = stdout; + else + output = stderr; + + fprintf(output, "Editcap %s" #ifdef SVNVERSION - " (" SVNVERSION " from " SVNPATH ")" + " (" SVNVERSION " from " SVNPATH ")" #endif - "\n", VERSION); - fprintf(stderr, "Edit and/or translate the format of capture files.\n"); - fprintf(stderr, "See http://www.wireshark.org for more information.\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Usage: editcap [options] ... [ [-] ... ]\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " and must both be present.\n"); - fprintf(stderr, "A single packet or a range of packets can be selected.\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Packet selection:\n"); - fprintf(stderr, " -r keep the selected packets; default is to delete them.\n"); - fprintf(stderr, " -A don't output packets whose timestamp is before the\n"); - fprintf(stderr, " given time (format as YYYY-MM-DD hh:mm:ss).\n"); - fprintf(stderr, " -B don't output packets whose timestamp is after the\n"); - fprintf(stderr, " given time (format as YYYY-MM-DD hh:mm:ss).\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Duplicate packet removal:\n"); - fprintf(stderr, " -d remove packet if duplicate (window == %d).\n", DEFAULT_DUP_DEPTH); - fprintf(stderr, " -D remove packet if duplicate; configurable \n"); - fprintf(stderr, " Valid values are 0 to %d.\n", MAX_DUP_DEPTH); - fprintf(stderr, " NOTE: A of 0 with -v (verbose option) is\n"); - fprintf(stderr, " useful to print MD5 hashes.\n"); - fprintf(stderr, " -w remove packet if duplicate packet is found EQUAL TO OR\n"); - fprintf(stderr, " LESS THAN prior to current packet.\n"); - fprintf(stderr, " A is specified in relative seconds\n"); - fprintf(stderr, " (e.g. 0.000001).\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " NOTE: The use of the 'Duplicate packet removal' options with\n"); - fprintf(stderr, " other editcap options except -v may not always work as expected.\n"); - fprintf(stderr, " Specifically the -r and -t options will very likely NOT have the\n"); - fprintf(stderr, " desired effect if combined with the -d, -D or -w.\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Packet manipulation:\n"); - fprintf(stderr, " -s truncate each packet to max. bytes of data.\n"); - fprintf(stderr, " -C chop each packet at the end by bytes.\n"); - fprintf(stderr, " -t