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 */
|
|
|
|
#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"
|
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;
|
|
|
|
} fd_hash_t;
|
|
|
|
|
|
|
|
#define DUP_DEPTH 5
|
|
|
|
fd_hash_t fd_hash[DUP_DEPTH];
|
|
|
|
int cur_dup = 0;
|
|
|
|
|
2001-07-12 08:16:45 +00:00
|
|
|
#define ONE_MILLION 1000000
|
|
|
|
|
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 */
|
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;
|
1999-12-04 12:53:52 +00:00
|
|
|
|
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)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (recno == selectfrm[i].first)
|
|
|
|
return 1;
|
|
|
|
}
|
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 */
|
|
|
|
static gboolean check_timestamp(wtap *wth) {
|
2007-07-30 21:10:12 +00:00
|
|
|
static int i = 0;
|
2006-03-13 22:20:07 +00:00
|
|
|
struct wtap_pkthdr* pkthdr = wtap_phdr(wth);
|
2007-07-30 21:17:03 +00:00
|
|
|
if (!((i++)%250)) printf("== %d starttime=%lu stoptime=%lu ts=%lu",i,starttime,stoptime,pkthdr->ts.secs);
|
2006-03-15 20:52:37 +00:00
|
|
|
return ( (time_t) pkthdr->ts.secs >= starttime ) && ( (time_t) 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;
|
|
|
|
int frac_digits;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2006-07-27 17:53:29 +00:00
|
|
|
static gboolean
|
|
|
|
is_duplicate(guint8* fd, guint32 len) {
|
|
|
|
int i;
|
|
|
|
md5_state_t ms;
|
|
|
|
|
|
|
|
cur_dup++;
|
|
|
|
if (cur_dup >= DUP_DEPTH)
|
|
|
|
cur_dup = 0;
|
|
|
|
|
|
|
|
/* Calculate our digest */
|
|
|
|
md5_init(&ms);
|
|
|
|
md5_append(&ms, fd, len);
|
|
|
|
md5_finish(&ms, fd_hash[cur_dup].digest);
|
|
|
|
|
|
|
|
fd_hash[cur_dup].len = len;
|
|
|
|
|
|
|
|
/* Look for duplicates */
|
|
|
|
for (i = 0; i < DUP_DEPTH; i++) {
|
|
|
|
if (i == cur_dup)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (fd_hash[i].len == fd_hash[cur_dup].len &&
|
|
|
|
memcmp(fd_hash[i].digest, fd_hash[cur_dup].digest, 16) == 0) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-01-18 16:21: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");
|
|
|
|
fprintf(stderr, "Packets:\n");
|
|
|
|
fprintf(stderr, " -C <choplen> chop each packet at the end by <choplen> bytes\n");
|
2006-07-27 17:53:29 +00:00
|
|
|
fprintf(stderr, " -d remove duplicate packets\n");
|
2006-01-10 21:37:36 +00:00
|
|
|
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");
|
|
|
|
fprintf(stderr, " -r keep the selected packets, default is to delete them\n");
|
|
|
|
fprintf(stderr, " -s <snaplen> truncate packets to max. <snaplen> bytes of data\n");
|
|
|
|
fprintf(stderr, " -t <time adjustment> adjust the timestamp of selected packets,\n");
|
|
|
|
fprintf(stderr, " <time adjustment> is in relative seconds (e.g. -0.5)\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");
|
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");
|
|
|
|
fprintf(stderr, " with a maximum of <packets per file> each\n");
|
|
|
|
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");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
2006-01-10 22:00:37 +00:00
|
|
|
static void list_capture_types(void) {
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
static void list_encap_types(void) {
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2007-05-25 17:22:32 +00:00
|
|
|
static void
|
|
|
|
failure_message(const char *msg_format, va_list ap)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "editcap: ");
|
|
|
|
vfprintf(stderr, msg_format, ap);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
1999-12-04 12:53:52 +00:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
|
|
|
|
{
|
|
|
|
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;
|
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;
|
2007-08-31 14:14:17 +00:00
|
|
|
gboolean check_ts;
|
2007-06-17 04:58:16 +00:00
|
|
|
#ifdef HAVE_PLUGINS
|
2007-05-25 17:22:32 +00:00
|
|
|
char* init_progfile_dir_error;
|
2007-07-30 21:10:12 +00:00
|
|
|
|
2007-05-25 17:22:32 +00:00
|
|
|
/* Register wiretap plugins */
|
2007-06-17 04:58:16 +00:00
|
|
|
if ((init_progfile_dir_error = init_progfile_dir(argv[0]))) {
|
|
|
|
g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error);
|
|
|
|
g_free(init_progfile_dir_error);
|
2007-05-25 17:22:32 +00:00
|
|
|
} else {
|
2007-06-17 04:58:16 +00:00
|
|
|
init_report_err(failure_message,NULL,NULL);
|
|
|
|
init_plugins();
|
2007-05-25 17:22:32 +00:00
|
|
|
}
|
2007-06-17 04:58:16 +00:00
|
|
|
#endif
|
2007-07-30 21:10:12 +00:00
|
|
|
|
2007-05-25 17:22:32 +00:00
|
|
|
/* Process the options */
|
2006-07-27 17:53:29 +00:00
|
|
|
while ((opt = getopt(argc, argv, "A:B:c:C:dE:F:hrs:t:T:v")) !=-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) {
|
|
|
|
fprintf(stderr, "editcap: probability \"%s\" must be between 0.0 and 1.0\n",
|
1999-12-05 01:27:14 +00:00
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
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) {
|
2006-01-10 22:00:37 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid capture file type\n\n",
|
1999-12-04 21:42:56 +00:00
|
|
|
optarg);
|
2006-01-10 22:00:37 +00:00
|
|
|
list_capture_types();
|
1999-12-04 21:42:56 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
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') {
|
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid packet count\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (split_packet_count <= 0) {
|
|
|
|
fprintf(stderr, "editcap: \"%d\" packet count must be larger than zero\n",
|
|
|
|
split_packet_count);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2006-01-09 21:14:32 +00:00
|
|
|
case 'C':
|
|
|
|
choplen = strtol(optarg, &p, 10);
|
|
|
|
if (p == optarg || *p != '\0') {
|
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid chop length\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2006-07-27 17:53:29 +00:00
|
|
|
case 'd':
|
|
|
|
dup_detect = TRUE;
|
|
|
|
for (i = 0; i < DUP_DEPTH; i++) {
|
|
|
|
memset(&fd_hash[i].digest, 0, 16);
|
|
|
|
fd_hash[i].len = 0;
|
|
|
|
}
|
|
|
|
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') {
|
2004-12-29 01:08:20 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid snapshot length\n",
|
2000-04-27 00:31:30 +00:00
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
|
2006-03-13 22:20:07 +00:00
|
|
|
case 'A':
|
|
|
|
{
|
2006-03-16 19:45:02 +00:00
|
|
|
struct tm starttm;
|
|
|
|
|
|
|
|
memset(&starttm,0,sizeof(struct tm));
|
2007-01-02 22:49:57 +00:00
|
|
|
|
2006-03-16 19:45:02 +00:00
|
|
|
if(!strptime(optarg,"%F %T",&starttm)) {
|
2006-03-13 22:20:07 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid time format\n\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2006-03-13 22:20:07 +00:00
|
|
|
check_startstop = TRUE;
|
2006-10-23 14:57:54 +00:00
|
|
|
starttm.tm_isdst = -1;
|
2007-01-02 22:49:57 +00:00
|
|
|
|
2006-03-16 19:45:02 +00:00
|
|
|
starttime = mktime(&starttm);
|
2007-07-30 21:10:12 +00:00
|
|
|
printf("=START=> given='%s' stoptime=%lu\n",optarg,starttime);
|
2006-03-13 22:20:07 +00:00
|
|
|
break;
|
2006-07-27 17:53:29 +00:00
|
|
|
}
|
2006-03-13 22:20:07 +00:00
|
|
|
case 'B':
|
|
|
|
{
|
2006-03-16 19:45:02 +00:00
|
|
|
struct tm stoptm;
|
|
|
|
|
|
|
|
memset(&stoptm,0,sizeof(struct tm));
|
2006-03-13 22:20:07 +00:00
|
|
|
|
2006-03-16 19:45:02 +00:00
|
|
|
if(!strptime(optarg,"%F %T",&stoptm)) {
|
2006-03-13 22:20:07 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid time format\n\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
check_startstop = TRUE;
|
2006-10-23 14:57:54 +00:00
|
|
|
stoptm.tm_isdst = -1;
|
2006-03-16 19:45:02 +00:00
|
|
|
stoptime = mktime(&stoptm);
|
2007-07-30 21:10:12 +00:00
|
|
|
printf("=STOP=> given='%s' stoptime=%lu\n",optarg,stoptime);
|
2006-03-13 22:20:07 +00:00
|
|
|
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) {
|
|
|
|
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;
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2006-03-16 19:45:02 +00:00
|
|
|
stoptime = mktime(&stoptm);
|
2007-07-30 21:10:12 +00:00
|
|
|
printf("=STOP=NEVER=> stoptime=%lu\n",stoptime);
|
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) {
|
|
|
|
fprintf(stderr, "editcap: start time is after the stop time\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2007-07-30 21:10:12 +00:00
|
|
|
printf("==> stoptime=%lu stoptime=%lu\n",starttime,stoptime);
|
2006-07-27 17:53:29 +00:00
|
|
|
|
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) {
|
1999-12-04 12:53:52 +00:00
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
fprintf(stderr, "File %s is a %s capture file.\n", argv[optind],
|
|
|
|
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) {
|
|
|
|
filename = (char *) malloc(strlen(argv[optind+1]) + 20);
|
|
|
|
if (!filename) {
|
|
|
|
exit(5);
|
|
|
|
}
|
|
|
|
sprintf(filename, "%s-%05d", argv[optind+1], 0);
|
|
|
|
} 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,
|
2005-09-14 21:57:30 +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,
|
1999-12-12 21:04:29 +00:00
|
|
|
wtap_strerror(err));
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = optind + 2; i < argc; i++)
|
2007-06-20 20:02:52 +00:00
|
|
|
if (add_selection(argv[i]) == FALSE)
|
|
|
|
break;
|
1999-12-12 21:04:29 +00:00
|
|
|
|
2005-04-03 11:00:49 +00:00
|
|
|
while (wtap_read(wth, &err, &err_info, &data_offset)) {
|
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
if (split_packet_count > 0 && (written_count % split_packet_count == 0)) {
|
|
|
|
if (!wtap_dump_close(pdh, &err)) {
|
|
|
|
|
|
|
|
fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
|
|
|
|
wtap_strerror(err));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(filename, "%s-%05d",argv[optind+1], count / split_packet_count);
|
|
|
|
|
|
|
|
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) {
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
|
|
|
|
wtap_strerror(err));
|
|
|
|
exit(1);
|
2006-07-27 17:53:29 +00:00
|
|
|
|
2005-12-16 16:37:03 +00:00
|
|
|
}
|
|
|
|
}
|
2007-07-30 21:10:12 +00:00
|
|
|
|
|
|
|
check_ts = check_timestamp(wth);
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
if (verbose)
|
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;
|
|
|
|
}
|
|
|
|
|
2006-07-27 17:53:29 +00:00
|
|
|
if (dup_detect) {
|
|
|
|
buf = wtap_buf_ptr(wth);
|
|
|
|
if (is_duplicate(buf, phdr->caplen)) {
|
|
|
|
if (verbose)
|
|
|
|
printf("Skipping duplicate: %u\n", count);
|
|
|
|
count++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
if (err_prob > 0.0) {
|
|
|
|
buf = wtap_buf_ptr(wth);
|
|
|
|
for (i = 0; i < (int) phdr->caplen; i++) {
|
|
|
|
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)
|
2006-03-13 22:20:07 +00:00
|
|
|
strcpy((char*) &buf[i], "%s");
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-12-16 16:37:03 +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",
|
|
|
|
argv[optind], wtap_strerror(err));
|
|
|
|
switch (err) {
|
|
|
|
|
|
|
|
case WTAP_ERR_UNSUPPORTED:
|
|
|
|
case WTAP_ERR_UNSUPPORTED_ENCAP:
|
|
|
|
case WTAP_ERR_BAD_RECORD:
|
|
|
|
fprintf(stderr, "(%s)\n", err_info);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
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,
|
1999-12-12 21:04:29 +00:00
|
|
|
wtap_strerror(err));
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
}
|
1999-12-12 21:04:29 +00:00
|
|
|
|
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
|
|
|
|