2006-01-09 21:14:32 +00:00
|
|
|
/* Edit capture files. We can delete packets, adjust timestamps, or
|
2001-07-12 08:16:45 +00:00
|
|
|
* simply convert from one format to another format.
|
1999-12-04 21:42:56 +00:00
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
1999-12-04 12:53:52 +00:00
|
|
|
*
|
|
|
|
* Originally written by Richard Sharpe.
|
|
|
|
* Improved by Guy Harris.
|
2000-01-17 20:21:40 +00:00
|
|
|
* Further improved by Richard Sharpe.
|
1999-12-04 12:53:52 +00:00
|
|
|
*/
|
|
|
|
|
2000-04-12 21:52:11 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
1999-12-04 12:53:52 +00:00
|
|
|
#include <stdio.h>
|
1999-12-12 21:04:29 +00:00
|
|
|
#include <stdlib.h>
|
2006-03-16 19:45:02 +00:00
|
|
|
#include <string.h>
|
2007-05-25 17:22:32 +00:00
|
|
|
#include <stdarg.h>
|
2007-01-16 19:13:09 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Just make sure we include the prototype for strptime as well
|
2007-04-22 20:04:34 +00:00
|
|
|
* (needed for glibc 2.2) but make sure we do this only if not
|
|
|
|
* yet defined.
|
2007-01-16 19:13:09 +00:00
|
|
|
*/
|
|
|
|
|
2007-04-22 20:04:34 +00:00
|
|
|
#ifndef __USE_XOPEN
|
|
|
|
# define __USE_XOPEN
|
|
|
|
#endif
|
|
|
|
|
2007-01-16 19:13:09 +00:00
|
|
|
#include <time.h>
|
1999-12-04 12:53:52 +00:00
|
|
|
#include <glib.h>
|
2000-04-12 21:52:11 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
1999-12-04 12:53:52 +00:00
|
|
|
#include <unistd.h>
|
2000-04-12 21:52:11 +00:00
|
|
|
#endif
|
|
|
|
|
2006-03-16 19:45:02 +00:00
|
|
|
|
|
|
|
|
2000-04-12 21:52:11 +00:00
|
|
|
#ifdef HAVE_SYS_TIME_H
|
1999-12-04 12:53:52 +00:00
|
|
|
#include <sys/time.h>
|
2000-04-12 21:52:11 +00:00
|
|
|
#endif
|
|
|
|
|
1999-12-04 12:53:52 +00:00
|
|
|
#include "wtap.h"
|
|
|
|
|
2000-04-12 21:52:11 +00:00
|
|
|
#ifdef NEED_GETOPT_H
|
|
|
|
#include "getopt.h"
|
|
|
|
#endif
|
|
|
|
|
2005-07-26 09:34:49 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <process.h> /* getpid */
|
2008-10-24 00:42:09 +00:00
|
|
|
#ifdef HAVE_WINSOCK2_H
|
|
|
|
#include <winsock2.h>
|
|
|
|
#endif
|
2005-07-26 09:34:49 +00:00
|
|
|
#endif
|
|
|
|
|
2006-03-13 22:20:07 +00:00
|
|
|
#ifdef NEED_STRPTIME_H
|
|
|
|
# include "strptime.h"
|
|
|
|
#endif
|
|
|
|
|
2007-01-02 22:49:57 +00:00
|
|
|
#include "epan/crypt/crypt-md5.h"
|
2007-05-25 17:22:32 +00:00
|
|
|
#include "epan/plugins.h"
|
|
|
|
#include "epan/report_err.h"
|
|
|
|
#include "epan/filesystem.h"
|
2008-06-30 17:16:29 +00:00
|
|
|
#include <wsutil/privileges.h>
|
2008-06-21 09:45:21 +00:00
|
|
|
#include "epan/nstime.h"
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2006-01-10 21:37:36 +00:00
|
|
|
#include "svnversion.h"
|
|
|
|
|
1999-12-04 12:53:52 +00:00
|
|
|
/*
|
|
|
|
* Some globals so we can pass things to various routines
|
|
|
|
*/
|
|
|
|
|
2000-01-17 08:06:03 +00:00
|
|
|
struct select_item {
|
|
|
|
|
|
|
|
int inclusive;
|
|
|
|
int first, second;
|
|
|
|
|
2002-03-14 04:32:35 +00:00
|
|
|
};
|
2000-01-17 08:06:03 +00:00
|
|
|
|
2006-07-27 17:53:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Duplicate frame detection
|
|
|
|
*/
|
|
|
|
typedef struct _fd_hash_t {
|
|
|
|
md5_byte_t digest[16];
|
|
|
|
guint32 len;
|
2009-04-17 15:21:46 +00:00
|
|
|
nstime_t time;
|
2006-07-27 17:53:29 +00:00
|
|
|
} fd_hash_t;
|
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
#define DEFAULT_DUP_DEPTH 5 /* Used with -d */
|
|
|
|
#define MAX_DUP_DEPTH 1000000 /* the maximum window (and actual size of fd_hash[]) for de-duplication */
|
|
|
|
|
|
|
|
fd_hash_t fd_hash[MAX_DUP_DEPTH];
|
|
|
|
int dup_window = DEFAULT_DUP_DEPTH;
|
|
|
|
int cur_dup_entry = 0;
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2001-07-12 08:16:45 +00:00
|
|
|
#define ONE_MILLION 1000000
|
2009-04-17 15:21:46 +00:00
|
|
|
#define ONE_BILLION 1000000000
|
2001-07-12 08:16:45 +00:00
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
/* Weights of different errors we can introduce */
|
|
|
|
/* We should probably make these command-line arguments */
|
|
|
|
/* XXX - Should we add a bit-level error? */
|
2005-05-30 16:49:47 +00:00
|
|
|
#define ERR_WT_BIT 5 /* Flip a random bit */
|
2005-04-10 23:12:48 +00:00
|
|
|
#define ERR_WT_BYTE 5 /* Substitute a random byte */
|
|
|
|
#define ERR_WT_ALNUM 5 /* Substitute a random character in [A-Za-z0-9] */
|
|
|
|
#define ERR_WT_FMT 2 /* Substitute "%s" */
|
|
|
|
#define ERR_WT_AA 1 /* Fill the remainder of the buffer with 0xAA */
|
2005-05-30 16:49:47 +00:00
|
|
|
#define ERR_WT_TOTAL (ERR_WT_BIT + ERR_WT_BYTE + ERR_WT_ALNUM + ERR_WT_FMT + ERR_WT_AA)
|
2005-04-10 23:12:48 +00:00
|
|
|
|
|
|
|
#define ALNUM_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
|
|
|
#define ALNUM_LEN (sizeof(ALNUM_CHARS) - 1)
|
|
|
|
|
|
|
|
|
2001-07-12 08:16:45 +00:00
|
|
|
struct time_adjustment {
|
|
|
|
struct timeval tv;
|
|
|
|
int is_negative;
|
|
|
|
};
|
|
|
|
|
2007-06-20 20:02:52 +00:00
|
|
|
#define MAX_SELECTIONS 512
|
|
|
|
static struct select_item selectfrm[MAX_SELECTIONS];
|
2002-06-30 20:28:54 +00:00
|
|
|
static int max_selected = -1;
|
1999-12-04 12:53:52 +00:00
|
|
|
static int keep_em = 0;
|
1999-12-12 21:04:29 +00:00
|
|
|
static int out_file_type = WTAP_FILE_PCAP; /* default to "libpcap" */
|
|
|
|
static int out_frame_type = -2; /* Leave frame type alone */
|
|
|
|
static int verbose = 0; /* Not so verbose */
|
2001-07-12 08:16:45 +00:00
|
|
|
static struct time_adjustment time_adj = {{0, 0}, 0}; /* no adjustment */
|
2009-04-17 15:21:46 +00:00
|
|
|
static nstime_t relative_time_window = {0, 0}; /* de-dup time window */
|
2005-04-10 23:12:48 +00:00
|
|
|
static double err_prob = 0.0;
|
2006-03-15 20:52:37 +00:00
|
|
|
static time_t starttime = 0;
|
2006-03-16 19:45:02 +00:00
|
|
|
static time_t stoptime = 0;
|
2006-03-13 22:20:07 +00:00
|
|
|
static gboolean check_startstop = FALSE;
|
2006-07-27 17:53:29 +00:00
|
|
|
static gboolean dup_detect = FALSE;
|
2009-04-17 15:21:46 +00:00
|
|
|
static gboolean dup_detect_by_time = FALSE;
|
1999-12-04 12:53:52 +00:00
|
|
|
|
2008-02-20 14:13:15 +00:00
|
|
|
static int find_dct2000_real_data(guint8 *buf);
|
|
|
|
|
2000-01-17 08:06:03 +00:00
|
|
|
/* Add a selection item, a simple parser for now */
|
2007-06-20 20:02:52 +00:00
|
|
|
static gboolean
|
|
|
|
add_selection(char *sel)
|
2000-01-17 08:06:03 +00:00
|
|
|
{
|
|
|
|
char *locn;
|
|
|
|
char *next;
|
|
|
|
|
2007-06-20 20:02:52 +00:00
|
|
|
if (++max_selected >= MAX_SELECTIONS) {
|
|
|
|
/* Let the user know we stopped selecting */
|
|
|
|
printf("Out of room for packet selections!\n");
|
|
|
|
return(FALSE);
|
|
|
|
}
|
2000-01-17 08:06:03 +00:00
|
|
|
|
|
|
|
printf("Add_Selected: %s\n", sel);
|
|
|
|
|
2000-01-17 20:21:40 +00:00
|
|
|
if ((locn = strchr(sel, '-')) == NULL) { /* No dash, so a single number? */
|
2000-01-17 08:06:03 +00:00
|
|
|
|
|
|
|
printf("Not inclusive ...");
|
|
|
|
|
|
|
|
selectfrm[max_selected].inclusive = 0;
|
|
|
|
selectfrm[max_selected].first = atoi(sel);
|
|
|
|
|
|
|
|
printf(" %i\n", selectfrm[max_selected].first);
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
printf("Inclusive ...");
|
|
|
|
|
|
|
|
next = locn + 1;
|
|
|
|
selectfrm[max_selected].inclusive = 1;
|
|
|
|
selectfrm[max_selected].first = atoi(sel);
|
|
|
|
selectfrm[max_selected].second = atoi(next);
|
|
|
|
|
|
|
|
printf(" %i, %i\n", selectfrm[max_selected].first, selectfrm[max_selected].second);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-06-20 20:02:52 +00:00
|
|
|
return(TRUE);
|
2000-01-17 08:06:03 +00:00
|
|
|
}
|
|
|
|
|
2006-01-09 21:14:32 +00:00
|
|
|
/* Was the packet selected? */
|
1999-12-04 12:53:52 +00:00
|
|
|
|
2007-06-20 20:02:52 +00:00
|
|
|
static int
|
|
|
|
selected(int recno)
|
1999-12-04 12:53:52 +00:00
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
for (i = 0; i<= max_selected; i++) {
|
|
|
|
|
2000-01-17 08:06:03 +00:00
|
|
|
if (selectfrm[i].inclusive) {
|
|
|
|
if (selectfrm[i].first <= recno && selectfrm[i].second >= recno)
|
2008-02-20 14:13:15 +00:00
|
|
|
return 1;
|
2000-01-17 08:06:03 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (recno == selectfrm[i].first)
|
2008-02-20 14:13:15 +00:00
|
|
|
return 1;
|
2000-01-17 08:06:03 +00:00
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-03-13 22:20:07 +00:00
|
|
|
/* is the packet in the selected timeframe */
|
2007-09-30 22:13:38 +00:00
|
|
|
static gboolean
|
|
|
|
check_timestamp(wtap *wth)
|
|
|
|
{
|
|
|
|
struct wtap_pkthdr* pkthdr = wtap_phdr(wth);
|
|
|
|
|
|
|
|
return ( pkthdr->ts.secs >= starttime ) && ( pkthdr->ts.secs <= stoptime );
|
2006-03-13 22:20:07 +00:00
|
|
|
}
|
|
|
|
|
2001-07-12 08:16:45 +00:00
|
|
|
static void
|
|
|
|
set_time_adjustment(char *optarg)
|
|
|
|
{
|
|
|
|
char *frac, *end;
|
|
|
|
long val;
|
2009-04-16 04:05:39 +00:00
|
|
|
size_t frac_digits;
|
2001-07-12 08:16:45 +00:00
|
|
|
|
|
|
|
if (!optarg)
|
|
|
|
return;
|
|
|
|
|
2001-07-13 07:55:13 +00:00
|
|
|
/* skip leading whitespace */
|
|
|
|
while (*optarg == ' ' || *optarg == '\t') {
|
|
|
|
optarg++;
|
2001-07-12 08:16:45 +00:00
|
|
|
}
|
2001-07-13 07:55:13 +00:00
|
|
|
|
|
|
|
/* check for a negative adjustment */
|
|
|
|
if (*optarg == '-') {
|
|
|
|
time_adj.is_negative = 1;
|
|
|
|
optarg++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* collect whole number of seconds, if any */
|
|
|
|
if (*optarg == '.') { /* only fractional (i.e., .5 is ok) */
|
|
|
|
val = 0;
|
|
|
|
frac = optarg;
|
|
|
|
} else {
|
|
|
|
val = strtol(optarg, &frac, 10);
|
|
|
|
if (frac == NULL || frac == optarg || val == LONG_MIN || val == LONG_MAX) {
|
2004-12-29 01:08:20 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n",
|
2001-07-13 07:55:13 +00:00
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (val < 0) { /* implies '--' since we caught '-' above */
|
2004-12-29 01:08:20 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n",
|
2001-07-13 07:55:13 +00:00
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
2001-07-12 08:16:45 +00:00
|
|
|
}
|
|
|
|
time_adj.tv.tv_sec = val;
|
|
|
|
|
|
|
|
/* now collect the partial seconds, if any */
|
2001-07-13 07:55:13 +00:00
|
|
|
if (*frac != '\0') { /* chars left, so get fractional part */
|
2001-07-12 08:16:45 +00:00
|
|
|
val = strtol(&(frac[1]), &end, 10);
|
|
|
|
if (*frac != '.' || end == NULL || end == frac
|
|
|
|
|| val < 0 || val > ONE_MILLION || val == LONG_MIN || val == LONG_MAX) {
|
2004-12-29 01:08:20 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n",
|
2001-07-12 08:16:45 +00:00
|
|
|
optarg);
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
time_adj.tv.tv_usec = val;
|
|
|
|
}
|
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
static void
|
|
|
|
set_rel_time(char *optarg)
|
|
|
|
{
|
|
|
|
char *frac, *end;
|
|
|
|
long val;
|
2009-04-17 16:21:33 +00:00
|
|
|
size_t frac_digits;
|
2009-04-17 15:21:46 +00:00
|
|
|
|
|
|
|
if (!optarg)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* skip leading whitespace */
|
|
|
|
while (*optarg == ' ' || *optarg == '\t') {
|
|
|
|
optarg++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ignore negative adjustment */
|
|
|
|
if (*optarg == '-') {
|
|
|
|
optarg++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* collect whole number of seconds, if any */
|
|
|
|
if (*optarg == '.') { /* only fractional (i.e., .5 is ok) */
|
|
|
|
val = 0;
|
|
|
|
frac = optarg;
|
|
|
|
} else {
|
|
|
|
val = strtol(optarg, &frac, 10);
|
|
|
|
if (frac == NULL || frac == optarg || val == LONG_MIN || val == LONG_MAX) {
|
|
|
|
fprintf(stderr, "1: editcap: \"%s\" isn't a valid rel time value\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (val < 0) { /* implies '--' since we caught '-' above */
|
|
|
|
fprintf(stderr, "2: editcap: \"%s\" isn't a valid rel time value\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
relative_time_window.secs = val;
|
|
|
|
|
|
|
|
/* now collect the partial seconds, if any */
|
|
|
|
if (*frac != '\0') { /* chars left, so get fractional part */
|
|
|
|
val = strtol(&(frac[1]), &end, 10);
|
|
|
|
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);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return; /* no fractional digits */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* adjust fractional portion from fractional to numerator
|
|
|
|
* e.g., in "1.5" from 5 to 500000000 since .5*10^9 = 500000000 */
|
|
|
|
if (frac && end) { /* both are valid */
|
|
|
|
frac_digits = end - frac - 1; /* fractional digit count (remember '.') */
|
|
|
|
while(frac_digits < 9) { /* this is frac of 10^9 */
|
|
|
|
val *= 10;
|
|
|
|
frac_digits++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
relative_time_window.nsecs = val;
|
|
|
|
}
|
|
|
|
|
2006-07-27 17:53:29 +00:00
|
|
|
static gboolean
|
|
|
|
is_duplicate(guint8* fd, guint32 len) {
|
|
|
|
int i;
|
|
|
|
md5_state_t ms;
|
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
cur_dup_entry++;
|
|
|
|
if (cur_dup_entry >= dup_window)
|
|
|
|
cur_dup_entry = 0;
|
2006-07-27 17:53:29 +00:00
|
|
|
|
|
|
|
/* Calculate our digest */
|
|
|
|
md5_init(&ms);
|
|
|
|
md5_append(&ms, fd, len);
|
2009-04-17 15:21:46 +00:00
|
|
|
md5_finish(&ms, fd_hash[cur_dup_entry].digest);
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
fd_hash[cur_dup_entry].len = len;
|
2006-07-27 17:53:29 +00:00
|
|
|
|
|
|
|
/* Look for duplicates */
|
2009-04-17 15:21:46 +00:00
|
|
|
for (i = 0; i < dup_window; i++) {
|
|
|
|
if (i == cur_dup_entry)
|
2006-07-27 17:53:29 +00:00
|
|
|
continue;
|
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
if (fd_hash[i].len == fd_hash[cur_dup_entry].len &&
|
|
|
|
memcmp(fd_hash[i].digest, fd_hash[cur_dup_entry].digest, 16) == 0) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
is_duplicate_rel_time(guint8* fd, guint32 len, const nstime_t *current) {
|
|
|
|
int i;
|
|
|
|
md5_state_t ms;
|
|
|
|
|
|
|
|
cur_dup_entry++;
|
|
|
|
if (cur_dup_entry >= dup_window)
|
|
|
|
cur_dup_entry = 0;
|
|
|
|
|
|
|
|
/* Calculate our digest */
|
|
|
|
md5_init(&ms);
|
|
|
|
md5_append(&ms, fd, len);
|
|
|
|
md5_finish(&ms, fd_hash[cur_dup_entry].digest);
|
|
|
|
|
|
|
|
fd_hash[cur_dup_entry].len = len;
|
|
|
|
fd_hash[cur_dup_entry].time.secs = current->secs;
|
|
|
|
fd_hash[cur_dup_entry].time.nsecs = current->nsecs;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Look for relative time related duplicates.
|
|
|
|
* This is hopefully a reasonably efficient mechanism for
|
|
|
|
* finding duplicates by rel time in the fd_hash[] cache.
|
|
|
|
* We check starting from the most recently added hash
|
|
|
|
* entries and work backwards towards older packets.
|
|
|
|
* This approach allows the dup test to be terminated
|
|
|
|
* when the relative time of a cached entry is found to
|
|
|
|
* be beyond the dup time window.
|
|
|
|
*
|
|
|
|
* Of course this assumes that the input trace file is
|
|
|
|
* "well-formed" in the sense that the packet timestamps are
|
|
|
|
* in strict chronologically increasing order (which is NOT
|
|
|
|
* always the case!!).
|
|
|
|
*
|
|
|
|
* The fd_hash[] table was deliberatly created large (1,000,000).
|
|
|
|
* Looking for time related duplicates in large trace files with
|
|
|
|
* non-fractional dup time window values can potentially take
|
|
|
|
* a long time to complete.
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (i = cur_dup_entry - 1;; i--) {
|
|
|
|
nstime_t delta;
|
|
|
|
int cmp;
|
|
|
|
|
|
|
|
if (i < 0) {
|
|
|
|
i = dup_window - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == cur_dup_entry) {
|
|
|
|
/*
|
|
|
|
* We've decremented back to where we started.
|
|
|
|
* Check no more!
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nstime_is_unset(&(fd_hash[i].time))) {
|
|
|
|
/*
|
|
|
|
* We've decremented to an unused fd_hash[] entry.
|
|
|
|
* Check no more!
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
nstime_delta(&delta, current, &fd_hash[i].time);
|
|
|
|
|
|
|
|
if(delta.secs < 0 || delta.nsecs < 0)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* A negative delta implies that the current packet
|
|
|
|
* has an absolute timestamp less than the cached packet
|
|
|
|
* that it is being compared to. This is NOT a normal
|
|
|
|
* situation since trace files usually have packets in
|
|
|
|
* chronological order (oldest to newest).
|
|
|
|
*
|
|
|
|
* There are several possible ways to deal with this:
|
|
|
|
* 1. 'continue' dup checking with the next cached frame.
|
|
|
|
* 2. 'break' from looking for a duplicate of the current frame.
|
|
|
|
* 3. Take the absolute value of the delta and see if that
|
|
|
|
* falls within the specifed dup time window.
|
|
|
|
*
|
|
|
|
* Currently this code does option 1. But it would pretty
|
|
|
|
* easy to add yet-another-editcap-option to select one of
|
|
|
|
* the other behaviors for dealing with out-of-sequence
|
|
|
|
* packets.
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmp = nstime_cmp(&delta, &relative_time_window);
|
|
|
|
|
|
|
|
if(cmp > 0) {
|
|
|
|
/*
|
|
|
|
* The delta time indicates that we are now looking at
|
|
|
|
* cached packets beyond the specified dup time window.
|
|
|
|
* Check no more!
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
} else if (fd_hash[i].len == fd_hash[cur_dup_entry].len &&
|
|
|
|
memcmp(fd_hash[i].digest, fd_hash[cur_dup_entry].digest, 16) == 0) {
|
2006-07-27 17:53:29 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2008-03-16 00:32:12 +00:00
|
|
|
static void
|
|
|
|
usage(void)
|
1999-12-04 12:53:52 +00:00
|
|
|
{
|
2006-01-10 21:37:36 +00:00
|
|
|
fprintf(stderr, "Editcap %s"
|
|
|
|
#ifdef SVNVERSION
|
|
|
|
" (" SVNVERSION ")"
|
|
|
|
#endif
|
|
|
|
"\n", VERSION);
|
|
|
|
fprintf(stderr, "Edit and/or translate the format of capture files.\n");
|
2006-05-28 20:28:20 +00:00
|
|
|
fprintf(stderr, "See http://www.wireshark.org for more information.\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf(stderr, "Usage: editcap [options] ... <infile> <outfile> [ <packet#>[-<packet#>] ... ]\n");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf(stderr, "A single packet or a range of packets can be selected.\n");
|
|
|
|
fprintf(stderr, "\n");
|
2008-01-12 18:31:07 +00:00
|
|
|
fprintf(stderr, "Packet selection:\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
fprintf(stderr, " -r keep the selected packets, default is to delete them\n");
|
2006-03-13 22:20:07 +00:00
|
|
|
fprintf(stderr, " -A <start time> don't output packets whose timestamp is before the\n");
|
2006-03-16 19:45:02 +00:00
|
|
|
fprintf(stderr, " given time (format as YYYY-MM-DD hh:mm:ss)\n");
|
2006-03-13 22:20:07 +00:00
|
|
|
fprintf(stderr, " -B <stop time> don't output packets whose timestamp is after the\n");
|
2006-03-16 19:45:02 +00:00
|
|
|
fprintf(stderr, " given time (format as YYYY-MM-DD hh:mm:ss)\n");
|
2009-04-17 15:21:46 +00:00
|
|
|
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 <dup window> remove packet if duplicate, configurable <dup window>.\n");
|
|
|
|
fprintf(stderr, " Valid <dup window> values are 0 to %d.\n", MAX_DUP_DEPTH);
|
|
|
|
fprintf(stderr, " NOTE: A <dup window> of 0 with -v (verbose option) is\n");
|
|
|
|
fprintf(stderr, " useful to print MD5 hashes.\n");
|
|
|
|
fprintf(stderr, " -w <dup time window> remove packet if duplicate packet is found EQUAL TO OR\n");
|
|
|
|
fprintf(stderr, " LESS THAN <dup time window> prior to current packet.\n");
|
|
|
|
fprintf(stderr, " A <dup time window> 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");
|
2008-01-12 18:31:07 +00:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf(stderr, "Packet manipulation:\n");
|
|
|
|
fprintf(stderr, " -s <snaplen> truncate each packet to max. <snaplen> bytes of data\n");
|
|
|
|
fprintf(stderr, " -C <choplen> chop each packet at the end by <choplen> bytes\n");
|
|
|
|
fprintf(stderr, " -t <time adjustment> adjust the timestamp of each packet,\n");
|
|
|
|
fprintf(stderr, " <time adjustment> is in relative seconds (e.g. -0.5)\n");
|
|
|
|
fprintf(stderr, " -E <error probability> set the probability (between 0.0 and 1.0 incl.)\n");
|
|
|
|
fprintf(stderr, " that a particular packet byte will be randomly changed\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf(stderr, "Output File(s):\n");
|
|
|
|
fprintf(stderr, " -c <packets per file> split the packet output to different files,\n");
|
2008-06-21 09:45:21 +00:00
|
|
|
fprintf(stderr, " based on uniform packet counts \n");
|
2006-01-10 21:37:36 +00:00
|
|
|
fprintf(stderr, " with a maximum of <packets per file> each\n");
|
2008-06-21 09:45:21 +00:00
|
|
|
fprintf(stderr, " -i <seconds per file> split the packet output to different files,\n");
|
|
|
|
fprintf(stderr, " based on uniform time intervals \n");
|
|
|
|
fprintf(stderr, " with a maximum of <seconds per file> each\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
fprintf(stderr, " -F <capture type> set the output file type, default is libpcap\n");
|
|
|
|
fprintf(stderr, " an empty \"-F\" option will list the file types\n");
|
|
|
|
fprintf(stderr, " -T <encap type> set the output file encapsulation type,\n");
|
|
|
|
fprintf(stderr, " default is the same as the input file\n");
|
|
|
|
fprintf(stderr, " an empty \"-T\" option will list the encapsulation types\n");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf(stderr, "Miscellaneous:\n");
|
|
|
|
fprintf(stderr, " -h display this help and exit\n");
|
|
|
|
fprintf(stderr, " -v verbose output\n");
|
2009-04-17 15:21:46 +00:00
|
|
|
fprintf(stderr, " If -v is used with any of the 'Duplicate Packet\n");
|
|
|
|
fprintf(stderr, " Removal' options (-d, -D or -w) then Packet lengths\n");
|
|
|
|
fprintf(stderr, " and MD5 hashes are printed to standard-out.\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
2008-03-16 00:32:12 +00:00
|
|
|
static void
|
|
|
|
list_capture_types(void) {
|
2006-01-10 22:00:37 +00:00
|
|
|
int i;
|
2006-01-10 21:37:36 +00:00
|
|
|
|
2006-01-10 22:00:37 +00:00
|
|
|
fprintf(stderr, "editcap: The available capture file types for \"F\":\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
|
|
|
|
if (wtap_dump_can_open(i))
|
|
|
|
fprintf(stderr, " %s - %s\n",
|
|
|
|
wtap_file_type_short_string(i), wtap_file_type_string(i));
|
|
|
|
}
|
2006-01-10 22:00:37 +00:00
|
|
|
}
|
|
|
|
|
2008-03-16 00:32:12 +00:00
|
|
|
static void
|
|
|
|
list_encap_types(void) {
|
2006-01-10 22:00:37 +00:00
|
|
|
int i;
|
|
|
|
const char *string;
|
|
|
|
|
|
|
|
fprintf(stderr, "editcap: The available encapsulation types for \"T\":\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
for (i = 0; i < WTAP_NUM_ENCAP_TYPES; i++) {
|
|
|
|
string = wtap_encap_short_string(i);
|
|
|
|
if (string != NULL)
|
|
|
|
fprintf(stderr, " %s - %s\n",
|
|
|
|
string, wtap_encap_string(i));
|
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-18 19:24:34 +00:00
|
|
|
#ifdef HAVE_PLUGINS
|
2008-03-16 00:58:15 +00:00
|
|
|
/*
|
|
|
|
* Don't report failures to load plugins because most (non-wiretap) plugins
|
|
|
|
* *should* fail to load (because we're not linked against libwireshark and
|
|
|
|
* dissector plugins need libwireshark).
|
|
|
|
*/
|
2007-05-25 17:22:32 +00:00
|
|
|
static void
|
2008-03-16 00:58:15 +00:00
|
|
|
failure_message(const char *msg_format _U_, va_list ap _U_)
|
2007-05-25 17:22:32 +00:00
|
|
|
{
|
2008-03-16 00:58:15 +00:00
|
|
|
return;
|
2007-05-25 17:22:32 +00:00
|
|
|
}
|
2008-12-18 19:24:34 +00:00
|
|
|
#endif
|
2007-05-25 17:22:32 +00:00
|
|
|
|
2008-03-16 00:32:12 +00:00
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
1999-12-04 12:53:52 +00:00
|
|
|
{
|
|
|
|
wtap *wth;
|
2005-04-10 23:12:48 +00:00
|
|
|
int i, j, err;
|
Have the Wiretap open, read, and seek-and-read routines return, in
addition to an error code, an error info string, for
WTAP_ERR_UNSUPPORTED, WTAP_ERR_UNSUPPORTED_ENCAP, and
WTAP_ERR_BAD_RECORD errors. Replace the error messages logged with
"g_message()" for those errors with g_strdup()ed or g_strdup_printf()ed
strings returned as the error info string, and change the callers of
those routines to, for those errors, put the info string into the
printed message or alert box for the error.
Add messages for cases where those errors were returned without printing
an additional message.
Nobody uses the error code from "cf_read()" - "cf_read()" puts up the
alert box itself for failures; get rid of the error code, so it just
returns a success/failure indication.
Rename "file_read_error_message()" to "cf_read_error_message()", as it
handles read errors from Wiretap, and have it take an error info string
as an argument. (That handles a lot of the work of putting the info
string into the error message.)
Make some variables in "ascend-grammar.y" static.
Check the return value of "erf_read_header()" in "erf_seek_read()".
Get rid of an unused #define in "i4btrace.c".
svn path=/trunk/; revision=9852
2004-01-25 21:55:17 +00:00
|
|
|
gchar *err_info;
|
1999-12-04 12:53:52 +00:00
|
|
|
extern char *optarg;
|
2000-04-17 14:52:32 +00:00
|
|
|
extern int optind;
|
2002-02-24 01:26:45 +00:00
|
|
|
int opt;
|
2000-04-27 00:31:30 +00:00
|
|
|
char *p;
|
2005-04-03 11:00:49 +00:00
|
|
|
unsigned int snaplen = 0; /* No limit */
|
2006-01-09 21:14:32 +00:00
|
|
|
unsigned int choplen = 0; /* No chop */
|
2005-04-03 11:00:49 +00:00
|
|
|
wtap_dumper *pdh;
|
|
|
|
int count = 1;
|
2009-04-17 15:21:46 +00:00
|
|
|
unsigned duplicate_count = 0;
|
2006-11-05 22:46:44 +00:00
|
|
|
gint64 data_offset;
|
2005-04-03 11:00:49 +00:00
|
|
|
struct wtap_pkthdr snap_phdr;
|
|
|
|
const struct wtap_pkthdr *phdr;
|
2005-04-10 23:12:48 +00:00
|
|
|
int err_type;
|
|
|
|
guint8 *buf;
|
2005-12-16 16:37:03 +00:00
|
|
|
int split_packet_count = 0;
|
|
|
|
int written_count = 0;
|
|
|
|
char *filename;
|
2008-02-06 12:01:48 +00:00
|
|
|
size_t filenamelen = 0;
|
2007-08-31 14:14:17 +00:00
|
|
|
gboolean check_ts;
|
2008-06-21 09:45:21 +00:00
|
|
|
int secs_per_block = 0;
|
|
|
|
int block_cnt = 0;
|
|
|
|
nstime_t block_start;
|
|
|
|
|
2007-06-17 04:58:16 +00:00
|
|
|
#ifdef HAVE_PLUGINS
|
2007-05-25 17:22:32 +00:00
|
|
|
char* init_progfile_dir_error;
|
2008-03-16 00:32:12 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get credential information for later use.
|
|
|
|
*/
|
|
|
|
get_credential_info();
|
2007-11-09 20:05:44 +00:00
|
|
|
|
2008-03-16 00:32:12 +00:00
|
|
|
#ifdef HAVE_PLUGINS
|
2007-05-25 17:22:32 +00:00
|
|
|
/* Register wiretap plugins */
|
2009-03-22 06:53:17 +00:00
|
|
|
if ((init_progfile_dir_error = init_progfile_dir(argv[0], main))) {
|
2008-02-20 14:13:15 +00:00
|
|
|
g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error);
|
|
|
|
g_free(init_progfile_dir_error);
|
|
|
|
} else {
|
2009-02-15 21:47:57 +00:00
|
|
|
init_report_err(failure_message,NULL,NULL,NULL);
|
2008-02-20 14:13:15 +00:00
|
|
|
init_plugins();
|
|
|
|
}
|
2007-06-17 04:58:16 +00:00
|
|
|
#endif
|
2007-11-09 20:05:44 +00:00
|
|
|
|
2007-05-25 17:22:32 +00:00
|
|
|
/* Process the options */
|
2009-04-17 15:21:46 +00:00
|
|
|
while ((opt = getopt(argc, argv, "A:B:c:C:dD:E:F:hrs:i:t:T:vw:")) !=-1) {
|
1999-12-04 12:53:52 +00:00
|
|
|
|
|
|
|
switch (opt) {
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
case 'E':
|
|
|
|
err_prob = strtod(optarg, &p);
|
|
|
|
if (p == optarg || err_prob < 0.0 || err_prob > 1.0) {
|
2008-02-20 14:13:15 +00:00
|
|
|
fprintf(stderr, "editcap: probability \"%s\" must be between 0.0 and 1.0\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
1999-12-05 01:27:14 +00:00
|
|
|
}
|
2007-03-21 23:14:23 +00:00
|
|
|
srand( (unsigned int) (time(NULL) + getpid()) );
|
1999-12-04 12:53:52 +00:00
|
|
|
break;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
1999-12-04 12:53:52 +00:00
|
|
|
case 'F':
|
1999-12-04 21:42:56 +00:00
|
|
|
out_file_type = wtap_short_string_to_file_type(optarg);
|
|
|
|
if (out_file_type < 0) {
|
2008-02-20 14:13:15 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid capture file type\n\n",
|
|
|
|
optarg);
|
2006-01-10 22:00:37 +00:00
|
|
|
list_capture_types();
|
2008-02-20 14:13:15 +00:00
|
|
|
exit(1);
|
1999-12-04 21:42:56 +00:00
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
break;
|
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
case 'c':
|
|
|
|
split_packet_count = strtol(optarg, &p, 10);
|
|
|
|
if (p == optarg || *p != '\0') {
|
2008-02-20 14:13:15 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid packet count\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
2005-12-16 16:37:03 +00:00
|
|
|
}
|
|
|
|
if (split_packet_count <= 0) {
|
2008-02-20 14:13:15 +00:00
|
|
|
fprintf(stderr, "editcap: \"%d\" packet count must be larger than zero\n",
|
|
|
|
split_packet_count);
|
|
|
|
exit(1);
|
2005-12-16 16:37:03 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2006-01-09 21:14:32 +00:00
|
|
|
case 'C':
|
|
|
|
choplen = strtol(optarg, &p, 10);
|
|
|
|
if (p == optarg || *p != '\0') {
|
2008-02-20 14:13:15 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid chop length\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
2006-01-09 21:14:32 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2006-07-27 17:53:29 +00:00
|
|
|
case 'd':
|
|
|
|
dup_detect = TRUE;
|
2009-04-17 15:21:46 +00:00
|
|
|
dup_detect_by_time = FALSE;
|
|
|
|
dup_window = DEFAULT_DUP_DEPTH;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'D':
|
|
|
|
dup_detect = TRUE;
|
|
|
|
dup_detect_by_time = FALSE;
|
|
|
|
dup_window = strtol(optarg, &p, 10);
|
|
|
|
if (p == optarg || *p != '\0') {
|
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid dupicate window value\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
2006-07-27 17:53:29 +00:00
|
|
|
}
|
2009-04-17 15:21:46 +00:00
|
|
|
if (dup_window < 0 || dup_window > MAX_DUP_DEPTH) {
|
|
|
|
fprintf(stderr, "editcap: \"%d\" duplicate window value must be between 0 and %d inclusive.\n",
|
|
|
|
dup_window, MAX_DUP_DEPTH);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'w':
|
|
|
|
dup_detect = FALSE;
|
|
|
|
dup_detect_by_time = TRUE;
|
|
|
|
dup_window = MAX_DUP_DEPTH;
|
|
|
|
set_rel_time(optarg);
|
2006-07-27 17:53:29 +00:00
|
|
|
break;
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
case '?': /* Bad options if GNU getopt */
|
2006-01-10 22:00:37 +00:00
|
|
|
switch(optopt) {
|
|
|
|
case'F':
|
|
|
|
list_capture_types();
|
|
|
|
break;
|
|
|
|
case'T':
|
|
|
|
list_encap_types();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
}
|
2006-01-10 21:37:36 +00:00
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'h':
|
2005-04-10 23:12:48 +00:00
|
|
|
usage();
|
|
|
|
exit(1);
|
1999-12-12 21:04:29 +00:00
|
|
|
break;
|
|
|
|
|
1999-12-04 12:53:52 +00:00
|
|
|
case 'r':
|
|
|
|
keep_em = !keep_em; /* Just invert */
|
|
|
|
break;
|
|
|
|
|
2000-04-27 00:31:30 +00:00
|
|
|
case 's':
|
|
|
|
snaplen = strtol(optarg, &p, 10);
|
|
|
|
if (p == optarg || *p != '\0') {
|
2008-02-20 14:13:15 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid snapshot length\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
2000-04-27 00:31:30 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2001-07-12 08:16:45 +00:00
|
|
|
case 't':
|
|
|
|
set_time_adjustment(optarg);
|
|
|
|
break;
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
case 'T':
|
|
|
|
out_frame_type = wtap_short_string_to_encap(optarg);
|
|
|
|
if (out_frame_type < 0) {
|
2006-01-10 22:00:37 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid encapsulation type\n\n",
|
2005-04-10 23:12:48 +00:00
|
|
|
optarg);
|
2006-01-10 22:00:37 +00:00
|
|
|
list_encap_types();
|
2005-04-10 23:12:48 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
1999-12-12 21:04:29 +00:00
|
|
|
break;
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
case 'v':
|
|
|
|
verbose = !verbose; /* Just invert */
|
1999-12-04 12:53:52 +00:00
|
|
|
break;
|
|
|
|
|
2008-06-21 09:45:21 +00:00
|
|
|
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;
|
|
|
|
|
2007-09-30 22:13:38 +00:00
|
|
|
case 'A':
|
|
|
|
{
|
|
|
|
struct tm starttm;
|
|
|
|
|
|
|
|
memset(&starttm,0,sizeof(struct tm));
|
|
|
|
|
2008-01-17 21:04:48 +00:00
|
|
|
if(!strptime(optarg,"%Y-%m-%d %T",&starttm)) {
|
2007-09-30 22:13:38 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid time format\n\n", optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
check_startstop = TRUE;
|
|
|
|
starttm.tm_isdst = -1;
|
|
|
|
|
|
|
|
starttime = mktime(&starttm);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 'B':
|
|
|
|
{
|
|
|
|
struct tm stoptm;
|
|
|
|
|
|
|
|
memset(&stoptm,0,sizeof(struct tm));
|
|
|
|
|
2008-01-17 21:04:48 +00:00
|
|
|
if(!strptime(optarg,"%Y-%m-%d %T",&stoptm)) {
|
2007-09-30 22:13:38 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid time format\n\n", optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
check_startstop = TRUE;
|
|
|
|
stoptm.tm_isdst = -1;
|
|
|
|
stoptime = mktime(&stoptm);
|
|
|
|
break;
|
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
#ifdef DEBUG
|
1999-12-04 12:53:52 +00:00
|
|
|
printf("Optind = %i, argc = %i\n", optind, argc);
|
1999-12-12 21:04:29 +00:00
|
|
|
#endif
|
1999-12-04 12:53:52 +00:00
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
if ((argc - optind) < 1) {
|
1999-12-04 12:53:52 +00:00
|
|
|
|
|
|
|
usage();
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-03-16 19:45:02 +00:00
|
|
|
if (check_startstop && !stoptime) {
|
2007-09-30 22:13:38 +00:00
|
|
|
struct tm stoptm;
|
|
|
|
/* XXX: will work until 2035 */
|
|
|
|
memset(&stoptm,0,sizeof(struct tm));
|
|
|
|
stoptm.tm_year = 135;
|
|
|
|
stoptm.tm_mday = 31;
|
|
|
|
stoptm.tm_mon = 11;
|
|
|
|
|
|
|
|
stoptime = mktime(&stoptm);
|
2006-03-16 19:45:02 +00:00
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2006-03-13 22:20:07 +00:00
|
|
|
if (starttime > stoptime) {
|
2007-09-30 22:13:38 +00:00
|
|
|
fprintf(stderr, "editcap: start time is after the stop time\n");
|
|
|
|
exit(1);
|
2006-03-13 22:20:07 +00:00
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2008-06-21 09:45:21 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
Have the Wiretap open, read, and seek-and-read routines return, in
addition to an error code, an error info string, for
WTAP_ERR_UNSUPPORTED, WTAP_ERR_UNSUPPORTED_ENCAP, and
WTAP_ERR_BAD_RECORD errors. Replace the error messages logged with
"g_message()" for those errors with g_strdup()ed or g_strdup_printf()ed
strings returned as the error info string, and change the callers of
those routines to, for those errors, put the info string into the
printed message or alert box for the error.
Add messages for cases where those errors were returned without printing
an additional message.
Nobody uses the error code from "cf_read()" - "cf_read()" puts up the
alert box itself for failures; get rid of the error code, so it just
returns a success/failure indication.
Rename "file_read_error_message()" to "cf_read_error_message()", as it
handles read errors from Wiretap, and have it take an error info string
as an argument. (That handles a lot of the work of putting the info
string into the error message.)
Make some variables in "ascend-grammar.y" static.
Check the return value of "erf_read_header()" in "erf_seek_read()".
Get rid of an unused #define in "i4btrace.c".
svn path=/trunk/; revision=9852
2004-01-25 21:55:17 +00:00
|
|
|
wth = wtap_open_offline(argv[optind], &err, &err_info, FALSE);
|
1999-12-04 12:53:52 +00:00
|
|
|
|
|
|
|
if (!wth) {
|
1999-12-04 21:42:56 +00:00
|
|
|
fprintf(stderr, "editcap: Can't open %s: %s\n", argv[optind],
|
1999-12-04 12:53:52 +00:00
|
|
|
wtap_strerror(err));
|
Have the Wiretap open, read, and seek-and-read routines return, in
addition to an error code, an error info string, for
WTAP_ERR_UNSUPPORTED, WTAP_ERR_UNSUPPORTED_ENCAP, and
WTAP_ERR_BAD_RECORD errors. Replace the error messages logged with
"g_message()" for those errors with g_strdup()ed or g_strdup_printf()ed
strings returned as the error info string, and change the callers of
those routines to, for those errors, put the info string into the
printed message or alert box for the error.
Add messages for cases where those errors were returned without printing
an additional message.
Nobody uses the error code from "cf_read()" - "cf_read()" puts up the
alert box itself for failures; get rid of the error code, so it just
returns a success/failure indication.
Rename "file_read_error_message()" to "cf_read_error_message()", as it
handles read errors from Wiretap, and have it take an error info string
as an argument. (That handles a lot of the work of putting the info
string into the error message.)
Make some variables in "ascend-grammar.y" static.
Check the return value of "erf_read_header()" in "erf_seek_read()".
Get rid of an unused #define in "i4btrace.c".
svn path=/trunk/; revision=9852
2004-01-25 21:55:17 +00:00
|
|
|
switch (err) {
|
|
|
|
|
|
|
|
case WTAP_ERR_UNSUPPORTED:
|
|
|
|
case WTAP_ERR_UNSUPPORTED_ENCAP:
|
|
|
|
case WTAP_ERR_BAD_RECORD:
|
|
|
|
fprintf(stderr, "(%s)\n", err_info);
|
2004-01-25 22:21:39 +00:00
|
|
|
g_free(err_info);
|
Have the Wiretap open, read, and seek-and-read routines return, in
addition to an error code, an error info string, for
WTAP_ERR_UNSUPPORTED, WTAP_ERR_UNSUPPORTED_ENCAP, and
WTAP_ERR_BAD_RECORD errors. Replace the error messages logged with
"g_message()" for those errors with g_strdup()ed or g_strdup_printf()ed
strings returned as the error info string, and change the callers of
those routines to, for those errors, put the info string into the
printed message or alert box for the error.
Add messages for cases where those errors were returned without printing
an additional message.
Nobody uses the error code from "cf_read()" - "cf_read()" puts up the
alert box itself for failures; get rid of the error code, so it just
returns a success/failure indication.
Rename "file_read_error_message()" to "cf_read_error_message()", as it
handles read errors from Wiretap, and have it take an error info string
as an argument. (That handles a lot of the work of putting the info
string into the error message.)
Make some variables in "ascend-grammar.y" static.
Check the return value of "erf_read_header()" in "erf_seek_read()".
Get rid of an unused #define in "i4btrace.c".
svn path=/trunk/; revision=9852
2004-01-25 21:55:17 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
if (verbose) {
|
|
|
|
fprintf(stderr, "File %s is a %s capture file.\n", argv[optind],
|
2008-02-20 14:13:15 +00:00
|
|
|
wtap_file_type_string(wtap_file_type(wth)));
|
1999-12-04 12:53:52 +00:00
|
|
|
}
|
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
/*
|
|
|
|
* Now, process the rest, if any ... we only write if there is an extra
|
|
|
|
* argument or so ...
|
|
|
|
*/
|
1999-12-04 12:53:52 +00:00
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
if ((argc - optind) >= 2) {
|
1999-12-04 12:53:52 +00:00
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
if (out_frame_type == -2)
|
|
|
|
out_frame_type = wtap_file_encap(wth);
|
1999-12-04 12:53:52 +00:00
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
if (split_packet_count > 0) {
|
2008-02-03 15:38:20 +00:00
|
|
|
filenamelen = strlen(argv[optind+1]) + 20;
|
|
|
|
filename = (char *) g_malloc(filenamelen);
|
2005-12-16 16:37:03 +00:00
|
|
|
if (!filename) {
|
2008-01-24 17:14:01 +00:00
|
|
|
exit(5);
|
2005-12-16 16:37:03 +00:00
|
|
|
}
|
2009-04-16 04:05:39 +00:00
|
|
|
g_snprintf(filename, (gulong) filenamelen, "%s-%05d", argv[optind+1], 0);
|
2005-12-16 16:37:03 +00:00
|
|
|
} else {
|
2008-06-21 09:45:21 +00:00
|
|
|
if (secs_per_block > 0) {
|
|
|
|
filenamelen = strlen(argv[optind+1]) + 7;
|
|
|
|
filename = (char *) g_malloc(filenamelen);
|
|
|
|
if (!filename) {
|
|
|
|
exit(5);
|
|
|
|
}
|
2009-04-16 04:05:39 +00:00
|
|
|
g_snprintf(filename, (gulong) filenamelen, "%s-%05d", argv[optind+1], block_cnt);
|
2008-06-21 09:45:21 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
filename = argv[optind+1];
|
|
|
|
}
|
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
pdh = wtap_dump_open(filename, out_file_type,
|
2008-01-24 17:14:01 +00:00
|
|
|
out_frame_type, wtap_snapshot_length(wth),
|
|
|
|
FALSE /* compressed */, &err);
|
2005-04-03 11:00:49 +00:00
|
|
|
if (pdh == NULL) {
|
1999-12-04 12:53:52 +00:00
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
|
2008-02-20 14:13:15 +00:00
|
|
|
wtap_strerror(err));
|
1999-12-12 21:04:29 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = optind + 2; i < argc; i++)
|
2007-06-20 20:02:52 +00:00
|
|
|
if (add_selection(argv[i]) == FALSE)
|
2008-01-24 17:14:01 +00:00
|
|
|
break;
|
1999-12-12 21:04:29 +00:00
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
if (dup_detect || dup_detect_by_time) {
|
|
|
|
for (i = 0; i < dup_window; i++) {
|
|
|
|
memset(&fd_hash[i].digest, 0, 16);
|
|
|
|
fd_hash[i].len = 0;
|
|
|
|
nstime_set_unset(&fd_hash[i].time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-03 11:00:49 +00:00
|
|
|
while (wtap_read(wth, &err, &err_info, &data_offset)) {
|
|
|
|
|
2008-06-21 09:45:21 +00:00
|
|
|
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;
|
2009-04-17 16:21:33 +00:00
|
|
|
block_start.nsecs = phdr->ts.nsecs;
|
|
|
|
}
|
2008-06-21 09:45:21 +00:00
|
|
|
|
2009-04-17 16:21:33 +00:00
|
|
|
while ((phdr->ts.secs - block_start.secs > secs_per_block) ||
|
|
|
|
(phdr->ts.secs - block_start.secs == secs_per_block &&
|
2008-06-21 09:45:21 +00:00
|
|
|
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 */
|
2009-04-16 04:05:39 +00:00
|
|
|
g_snprintf(filename, (gulong) filenamelen, "%s-%05d",argv[optind+1], ++block_cnt);
|
2008-06-21 09:45:21 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
if (split_packet_count > 0 && (written_count % split_packet_count == 0)) {
|
2008-01-24 17:14:01 +00:00
|
|
|
if (!wtap_dump_close(pdh, &err)) {
|
2005-12-16 16:37:03 +00:00
|
|
|
|
2008-01-24 17:14:01 +00:00
|
|
|
fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
|
|
|
|
wtap_strerror(err));
|
|
|
|
exit(1);
|
|
|
|
}
|
2005-12-16 16:37:03 +00:00
|
|
|
|
2009-04-16 04:05:39 +00:00
|
|
|
g_snprintf(filename, (gulong) filenamelen, "%s-%05d",argv[optind+1], count / split_packet_count);
|
2005-12-16 16:37:03 +00:00
|
|
|
|
2008-01-24 17:14:01 +00:00
|
|
|
if (verbose) {
|
|
|
|
fprintf(stderr, "Continuing writing in file %s\n", filename);
|
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2008-01-24 17:14:01 +00:00
|
|
|
pdh = wtap_dump_open(filename, out_file_type,
|
|
|
|
out_frame_type, wtap_snapshot_length(wth), FALSE /* compressed */, &err);
|
|
|
|
if (pdh == NULL) {
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2008-01-24 17:14:01 +00:00
|
|
|
fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
|
|
|
|
wtap_strerror(err));
|
|
|
|
exit(1);
|
|
|
|
}
|
2005-12-16 16:37:03 +00:00
|
|
|
}
|
2007-11-09 20:05:44 +00:00
|
|
|
|
2007-07-30 21:10:12 +00:00
|
|
|
check_ts = check_timestamp(wth);
|
2007-11-09 20:05:44 +00:00
|
|
|
|
2007-07-30 21:10:12 +00:00
|
|
|
if ( ((check_startstop && check_ts) || (!check_startstop && !check_ts)) && ((!selected(count) && !keep_em) ||
|
2006-03-13 22:20:07 +00:00
|
|
|
(selected(count) && keep_em)) ) {
|
2005-04-03 11:00:49 +00:00
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
if (verbose && !dup_detect && !dup_detect_by_time)
|
2006-01-09 21:14:32 +00:00
|
|
|
printf("Packet: %u\n", count);
|
2005-04-03 11:00:49 +00:00
|
|
|
|
|
|
|
/* We simply write it, perhaps after truncating it; we could do other
|
|
|
|
things, like modify it. */
|
|
|
|
|
|
|
|
phdr = wtap_phdr(wth);
|
|
|
|
|
2006-01-09 21:14:32 +00:00
|
|
|
if (choplen != 0 && phdr->caplen > choplen) {
|
|
|
|
snap_phdr = *phdr;
|
|
|
|
snap_phdr.caplen -= choplen;
|
|
|
|
phdr = &snap_phdr;
|
|
|
|
}
|
|
|
|
|
2005-04-03 11:00:49 +00:00
|
|
|
if (snaplen != 0 && phdr->caplen > snaplen) {
|
|
|
|
snap_phdr = *phdr;
|
|
|
|
snap_phdr.caplen = snaplen;
|
|
|
|
phdr = &snap_phdr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* assume that if the frame's tv_sec is 0, then
|
|
|
|
* the timestamp isn't supported */
|
2005-08-24 22:27:21 +00:00
|
|
|
if (phdr->ts.secs > 0 && time_adj.tv.tv_sec != 0) {
|
2005-04-03 11:00:49 +00:00
|
|
|
snap_phdr = *phdr;
|
|
|
|
if (time_adj.is_negative)
|
2005-08-24 22:27:21 +00:00
|
|
|
snap_phdr.ts.secs -= time_adj.tv.tv_sec;
|
2005-04-03 11:00:49 +00:00
|
|
|
else
|
2005-08-24 22:27:21 +00:00
|
|
|
snap_phdr.ts.secs += time_adj.tv.tv_sec;
|
2005-04-03 11:00:49 +00:00
|
|
|
phdr = &snap_phdr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* assume that if the frame's tv_sec is 0, then
|
|
|
|
* the timestamp isn't supported */
|
2005-08-24 22:27:21 +00:00
|
|
|
if (phdr->ts.secs > 0 && time_adj.tv.tv_usec != 0) {
|
2005-04-03 11:00:49 +00:00
|
|
|
snap_phdr = *phdr;
|
|
|
|
if (time_adj.is_negative) { /* subtract */
|
2005-08-24 22:27:21 +00:00
|
|
|
if (snap_phdr.ts.nsecs/1000 < time_adj.tv.tv_usec) { /* borrow */
|
|
|
|
snap_phdr.ts.secs--;
|
|
|
|
snap_phdr.ts.nsecs += ONE_MILLION * 1000;
|
2005-04-03 11:00:49 +00:00
|
|
|
}
|
2005-08-24 22:27:21 +00:00
|
|
|
snap_phdr.ts.nsecs -= time_adj.tv.tv_usec * 1000;
|
2005-04-03 11:00:49 +00:00
|
|
|
} else { /* add */
|
2005-08-24 22:27:21 +00:00
|
|
|
if (snap_phdr.ts.nsecs + time_adj.tv.tv_usec * 1000 > ONE_MILLION * 1000) {
|
2005-04-03 11:00:49 +00:00
|
|
|
/* carry */
|
2005-08-24 22:27:21 +00:00
|
|
|
snap_phdr.ts.secs++;
|
|
|
|
snap_phdr.ts.nsecs += (time_adj.tv.tv_usec - ONE_MILLION) * 1000;
|
2005-04-03 11:00:49 +00:00
|
|
|
} else {
|
2005-08-24 22:27:21 +00:00
|
|
|
snap_phdr.ts.nsecs += time_adj.tv.tv_usec * 1000;
|
2005-04-03 11:00:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
phdr = &snap_phdr;
|
|
|
|
}
|
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
/* suppress duplicates by packet window */
|
2008-01-24 17:14:01 +00:00
|
|
|
if (dup_detect) {
|
|
|
|
buf = wtap_buf_ptr(wth);
|
|
|
|
if (is_duplicate(buf, phdr->caplen)) {
|
2009-04-17 15:21:46 +00:00
|
|
|
if (verbose) {
|
|
|
|
fprintf(stdout, "Skipped: %u, Len: %u, MD5 Hash: ", count, phdr->caplen);
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
fprintf(stdout, "%02x", (unsigned char)fd_hash[cur_dup_entry].digest[i]);
|
|
|
|
}
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
}
|
|
|
|
duplicate_count++;
|
|
|
|
count++;
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if (verbose) {
|
|
|
|
fprintf(stdout, "Packet: %u, Len: %u, MD5 Hash: ", count, phdr->caplen);
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
fprintf(stdout, "%02x", (unsigned char)fd_hash[cur_dup_entry].digest[i]);
|
|
|
|
}
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* suppress duplicates by time window */
|
|
|
|
if (dup_detect_by_time) {
|
|
|
|
nstime_t current;
|
|
|
|
|
|
|
|
current.secs = phdr->ts.secs;
|
|
|
|
current.nsecs = phdr->ts.nsecs;
|
|
|
|
|
|
|
|
buf = wtap_buf_ptr(wth);
|
|
|
|
|
|
|
|
if (is_duplicate_rel_time(buf, phdr->caplen, ¤t)) {
|
|
|
|
if (verbose) {
|
|
|
|
fprintf(stdout, "Skipped: %u, Len: %u, MD5 Hash: ", count, phdr->caplen);
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
fprintf(stdout, "%02x", (unsigned char)fd_hash[cur_dup_entry].digest[i]);
|
|
|
|
}
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
}
|
|
|
|
duplicate_count++;
|
2006-07-27 17:53:29 +00:00
|
|
|
count++;
|
2008-01-24 17:14:01 +00:00
|
|
|
continue;
|
2009-04-17 15:21:46 +00:00
|
|
|
} else {
|
|
|
|
if (verbose) {
|
|
|
|
fprintf(stdout, "Packet: %u, Len: %u, MD5 Hash: ", count, phdr->caplen);
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
fprintf(stdout, "%02x", (unsigned char)fd_hash[cur_dup_entry].digest[i]);
|
|
|
|
}
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
}
|
2008-01-24 17:14:01 +00:00
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2008-01-24 17:14:01 +00:00
|
|
|
/* Random error mutation */
|
2005-04-10 23:12:48 +00:00
|
|
|
if (err_prob > 0.0) {
|
2008-02-20 14:13:15 +00:00
|
|
|
int real_data_start = 0;
|
2005-04-10 23:12:48 +00:00
|
|
|
buf = wtap_buf_ptr(wth);
|
2008-02-20 14:13:15 +00:00
|
|
|
/* Protect non-protocol data */
|
|
|
|
if (wtap_file_type(wth) == WTAP_FILE_CATAPULT_DCT2000) {
|
|
|
|
real_data_start = find_dct2000_real_data(buf);
|
|
|
|
}
|
|
|
|
for (i = real_data_start; i < (int) phdr->caplen; i++) {
|
2005-04-10 23:12:48 +00:00
|
|
|
if (rand() <= err_prob * RAND_MAX) {
|
|
|
|
err_type = rand() / (RAND_MAX / ERR_WT_TOTAL + 1);
|
|
|
|
|
2005-05-30 16:49:47 +00:00
|
|
|
if (err_type < ERR_WT_BIT) {
|
|
|
|
buf[i] ^= 1 << (rand() / (RAND_MAX / 8 + 1));
|
|
|
|
err_type = ERR_WT_TOTAL;
|
|
|
|
} else {
|
|
|
|
err_type -= ERR_WT_BYTE;
|
|
|
|
}
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
if (err_type < ERR_WT_BYTE) {
|
|
|
|
buf[i] = rand() / (RAND_MAX / 255 + 1);
|
|
|
|
err_type = ERR_WT_TOTAL;
|
|
|
|
} else {
|
|
|
|
err_type -= ERR_WT_BYTE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err_type < ERR_WT_ALNUM) {
|
|
|
|
buf[i] = ALNUM_CHARS[rand() / (RAND_MAX / ALNUM_LEN + 1)];
|
|
|
|
err_type = ERR_WT_TOTAL;
|
|
|
|
} else {
|
|
|
|
err_type -= ERR_WT_ALNUM;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err_type < ERR_WT_FMT) {
|
2005-07-26 09:34:49 +00:00
|
|
|
if ((unsigned int)i < phdr->caplen - 2)
|
2008-01-24 23:01:37 +00:00
|
|
|
strncpy((char*) &buf[i], "%s", 2);
|
2005-04-10 23:12:48 +00:00
|
|
|
err_type = ERR_WT_TOTAL;
|
|
|
|
} else {
|
|
|
|
err_type -= ERR_WT_FMT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err_type < ERR_WT_AA) {
|
|
|
|
for (j = i; j < (int) phdr->caplen; j++) {
|
|
|
|
buf[j] = 0xAA;
|
|
|
|
}
|
|
|
|
i = phdr->caplen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-03 11:00:49 +00:00
|
|
|
if (!wtap_dump(pdh, phdr, wtap_pseudoheader(wth), wtap_buf_ptr(wth),
|
|
|
|
&err)) {
|
|
|
|
fprintf(stderr, "editcap: Error writing to %s: %s\n",
|
2005-12-16 16:37:03 +00:00
|
|
|
filename, wtap_strerror(err));
|
2005-04-03 11:00:49 +00:00
|
|
|
exit(1);
|
2008-01-24 17:14:01 +00:00
|
|
|
}
|
|
|
|
written_count++;
|
2005-04-03 11:00:49 +00:00
|
|
|
}
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err != 0) {
|
Have the Wiretap open, read, and seek-and-read routines return, in
addition to an error code, an error info string, for
WTAP_ERR_UNSUPPORTED, WTAP_ERR_UNSUPPORTED_ENCAP, and
WTAP_ERR_BAD_RECORD errors. Replace the error messages logged with
"g_message()" for those errors with g_strdup()ed or g_strdup_printf()ed
strings returned as the error info string, and change the callers of
those routines to, for those errors, put the info string into the
printed message or alert box for the error.
Add messages for cases where those errors were returned without printing
an additional message.
Nobody uses the error code from "cf_read()" - "cf_read()" puts up the
alert box itself for failures; get rid of the error code, so it just
returns a success/failure indication.
Rename "file_read_error_message()" to "cf_read_error_message()", as it
handles read errors from Wiretap, and have it take an error info string
as an argument. (That handles a lot of the work of putting the info
string into the error message.)
Make some variables in "ascend-grammar.y" static.
Check the return value of "erf_read_header()" in "erf_seek_read()".
Get rid of an unused #define in "i4btrace.c".
svn path=/trunk/; revision=9852
2004-01-25 21:55:17 +00:00
|
|
|
/* Print a message noting that the read failed somewhere along the line. */
|
|
|
|
fprintf(stderr,
|
|
|
|
"editcap: An error occurred while reading \"%s\": %s.\n",
|
2008-02-20 14:13:15 +00:00
|
|
|
argv[optind], wtap_strerror(err));
|
Have the Wiretap open, read, and seek-and-read routines return, in
addition to an error code, an error info string, for
WTAP_ERR_UNSUPPORTED, WTAP_ERR_UNSUPPORTED_ENCAP, and
WTAP_ERR_BAD_RECORD errors. Replace the error messages logged with
"g_message()" for those errors with g_strdup()ed or g_strdup_printf()ed
strings returned as the error info string, and change the callers of
those routines to, for those errors, put the info string into the
printed message or alert box for the error.
Add messages for cases where those errors were returned without printing
an additional message.
Nobody uses the error code from "cf_read()" - "cf_read()" puts up the
alert box itself for failures; get rid of the error code, so it just
returns a success/failure indication.
Rename "file_read_error_message()" to "cf_read_error_message()", as it
handles read errors from Wiretap, and have it take an error info string
as an argument. (That handles a lot of the work of putting the info
string into the error message.)
Make some variables in "ascend-grammar.y" static.
Check the return value of "erf_read_header()" in "erf_seek_read()".
Get rid of an unused #define in "i4btrace.c".
svn path=/trunk/; revision=9852
2004-01-25 21:55:17 +00:00
|
|
|
switch (err) {
|
|
|
|
|
|
|
|
case WTAP_ERR_UNSUPPORTED:
|
|
|
|
case WTAP_ERR_UNSUPPORTED_ENCAP:
|
|
|
|
case WTAP_ERR_BAD_RECORD:
|
2008-01-24 17:14:01 +00:00
|
|
|
fprintf(stderr, "(%s)\n", err_info);
|
2008-05-30 02:44:02 +00:00
|
|
|
g_free(err_info);
|
2008-01-24 17:14:01 +00:00
|
|
|
break;
|
Have the Wiretap open, read, and seek-and-read routines return, in
addition to an error code, an error info string, for
WTAP_ERR_UNSUPPORTED, WTAP_ERR_UNSUPPORTED_ENCAP, and
WTAP_ERR_BAD_RECORD errors. Replace the error messages logged with
"g_message()" for those errors with g_strdup()ed or g_strdup_printf()ed
strings returned as the error info string, and change the callers of
those routines to, for those errors, put the info string into the
printed message or alert box for the error.
Add messages for cases where those errors were returned without printing
an additional message.
Nobody uses the error code from "cf_read()" - "cf_read()" puts up the
alert box itself for failures; get rid of the error code, so it just
returns a success/failure indication.
Rename "file_read_error_message()" to "cf_read_error_message()", as it
handles read errors from Wiretap, and have it take an error info string
as an argument. (That handles a lot of the work of putting the info
string into the error message.)
Make some variables in "ascend-grammar.y" static.
Check the return value of "erf_read_header()" in "erf_seek_read()".
Get rid of an unused #define in "i4btrace.c".
svn path=/trunk/; revision=9852
2004-01-25 21:55:17 +00:00
|
|
|
}
|
|
|
|
}
|
1999-12-12 21:04:29 +00:00
|
|
|
|
2005-04-03 11:00:49 +00:00
|
|
|
if (!wtap_dump_close(pdh, &err)) {
|
1999-12-12 21:04:29 +00:00
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
|
2008-02-20 14:13:15 +00:00
|
|
|
wtap_strerror(err));
|
1999-12-12 21:04:29 +00:00
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
}
|
1999-12-12 21:04:29 +00:00
|
|
|
|
2009-04-17 15:21:46 +00:00
|
|
|
if (dup_detect) {
|
|
|
|
fprintf(stdout, "%u packet%s seen, %u packet%s skipped with duplicate window of %u packets.\n",
|
|
|
|
count - 1, plurality(count - 1, "", "s"),
|
|
|
|
duplicate_count, plurality(duplicate_count, "", "s"), dup_window);
|
|
|
|
} else if (dup_detect_by_time) {
|
|
|
|
fprintf(stdout, "%u packet%s seen, %u packet%s skipped with duplicate time window equal to or less than %ld.%09ld seconds.\n",
|
|
|
|
count - 1, plurality(count - 1, "", "s"),
|
|
|
|
duplicate_count, plurality(duplicate_count, "", "s"),
|
|
|
|
(long)relative_time_window.secs, (long int)relative_time_window.nsecs);
|
|
|
|
}
|
|
|
|
|
2001-04-20 22:35:19 +00:00
|
|
|
return 0;
|
1999-12-04 12:53:52 +00:00
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2008-02-20 14:13:15 +00:00
|
|
|
/* Skip meta-information read from file to return offset of real
|
|
|
|
protocol data */
|
|
|
|
static int find_dct2000_real_data(guint8 *buf)
|
|
|
|
{
|
|
|
|
int n=0;
|
|
|
|
|
|
|
|
for (n=0; buf[n] != '\0'; n++); /* Context name */
|
|
|
|
n++;
|
|
|
|
n++; /* Context port number */
|
|
|
|
for (; buf[n] != '\0'; n++); /* Timestamp */
|
|
|
|
n++;
|
|
|
|
for (; buf[n] != '\0'; n++); /* Protocol name */
|
|
|
|
n++;
|
|
|
|
for (; buf[n] != '\0'; n++); /* Variant number (as string) */
|
|
|
|
n++;
|
|
|
|
for (; buf[n] != '\0'; n++); /* Outhdr (as string) */
|
|
|
|
n++;
|
|
|
|
n += 2; /* Direction & encap */
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|