2001-07-12 08:16:45 +00:00
|
|
|
/* Edit capture files. We can delete records, adjust timestamps, or
|
|
|
|
* 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>
|
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
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
#include <time.h>
|
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
|
|
|
|
|
2000-01-17 08:06:03 +00:00
|
|
|
#include <string.h>
|
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
|
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2002-06-30 20:28:54 +00:00
|
|
|
static struct select_item selectfrm[100];
|
|
|
|
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;
|
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 */
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
static void add_selection(char *sel)
|
2000-01-17 08:06:03 +00:00
|
|
|
{
|
|
|
|
char *locn;
|
|
|
|
char *next;
|
|
|
|
|
|
|
|
if (max_selected == (sizeof(selectfrm)/sizeof(struct select_item)) - 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
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 ...");
|
|
|
|
|
|
|
|
max_selected++;
|
|
|
|
selectfrm[max_selected].inclusive = 0;
|
|
|
|
selectfrm[max_selected].first = atoi(sel);
|
|
|
|
|
|
|
|
printf(" %i\n", selectfrm[max_selected].first);
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
printf("Inclusive ...");
|
|
|
|
|
|
|
|
next = locn + 1;
|
|
|
|
max_selected++;
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-12-04 12:53:52 +00:00
|
|
|
/* Was the record selected? */
|
|
|
|
|
2002-06-30 20:28:54 +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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2004-01-18 16:21:12 +00:00
|
|
|
static void usage(void)
|
1999-12-04 12:53:52 +00:00
|
|
|
{
|
1999-12-04 21:42:56 +00:00
|
|
|
int i;
|
1999-12-12 21:04:29 +00:00
|
|
|
const char *string;
|
1999-12-04 12:53:52 +00:00
|
|
|
|
2005-06-17 07:56:27 +00:00
|
|
|
fprintf(stderr, "Usage: editcap [-r] [-h] [-v] [-T <encap type>] [-E <probability>]\n");
|
|
|
|
fprintf(stderr, " [-F <capture type>] [-s <snaplen>] [-t <time adjustment>]\n");
|
2001-07-13 07:55:13 +00:00
|
|
|
fprintf(stderr, " <infile> <outfile> [ <record#>[-<record#>] ... ]\n");
|
2005-04-10 23:12:48 +00:00
|
|
|
fprintf(stderr, " where\n");
|
|
|
|
fprintf(stderr, " \t-E <probability> specifies the probability (between 0 and 1)\n");
|
|
|
|
fprintf(stderr, " \t that a particular byte will will have an error.\n");
|
1999-12-05 01:27:14 +00:00
|
|
|
fprintf(stderr, " \t-F <capture type> specifies the capture file type to write:\n");
|
1999-12-04 21:42:56 +00:00
|
|
|
for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
|
|
|
|
if (wtap_dump_can_open(i))
|
|
|
|
fprintf(stderr, " \t %s - %s\n",
|
|
|
|
wtap_file_type_short_string(i), wtap_file_type_string(i));
|
|
|
|
}
|
1999-12-12 21:04:29 +00:00
|
|
|
fprintf(stderr, " \t default is libpcap\n");
|
2005-04-10 23:12:48 +00:00
|
|
|
fprintf(stderr, " \t-h produces this help listing.\n");
|
|
|
|
fprintf(stderr, " \t-r specifies that the records specified should be kept, not deleted, \n");
|
|
|
|
fprintf(stderr, " default is to delete\n");
|
2000-12-03 21:11:05 +00:00
|
|
|
fprintf(stderr, " \t-s <snaplen> specifies that packets should be truncated to\n");
|
|
|
|
fprintf(stderr, " \t <snaplen> bytes of data\n");
|
2001-07-12 08:16:45 +00:00
|
|
|
fprintf(stderr, " \t-t <time adjustment> specifies the time adjustment\n");
|
|
|
|
fprintf(stderr, " \t to be applied to selected packets\n");
|
2005-04-10 23:12:48 +00:00
|
|
|
fprintf(stderr, " \t-T <encap type> specifies the encapsulation type to use:\n");
|
|
|
|
for (i = 0; i < WTAP_NUM_ENCAP_TYPES; i++) {
|
|
|
|
string = wtap_encap_short_string(i);
|
|
|
|
if (string != NULL)
|
|
|
|
fprintf(stderr, " \t %s - %s\n",
|
|
|
|
string, wtap_encap_string(i));
|
|
|
|
}
|
|
|
|
fprintf(stderr, " \t default is the same as the input file\n");
|
|
|
|
fprintf(stderr, " \t-v specifies verbose operation, default is silent\n");
|
2000-01-17 08:06:03 +00:00
|
|
|
fprintf(stderr, "\n \t A range of records can be specified as well\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 */
|
|
|
|
wtap_dumper *pdh;
|
|
|
|
int count = 1;
|
|
|
|
long data_offset;
|
|
|
|
struct wtap_pkthdr snap_phdr;
|
|
|
|
const struct wtap_pkthdr *phdr;
|
2005-04-10 23:12:48 +00:00
|
|
|
int err_type;
|
|
|
|
guint8 *buf;
|
1999-12-04 12:53:52 +00:00
|
|
|
|
|
|
|
/* Process the options first */
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
while ((opt = getopt(argc, argv, "E: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);
|
|
|
|
}
|
2005-04-10 23:12:48 +00:00
|
|
|
srand(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) {
|
2004-12-29 01:08:20 +00:00
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid capture file type\n",
|
1999-12-04 21:42:56 +00:00
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
1999-12-04 12:53:52 +00:00
|
|
|
break;
|
|
|
|
|
2005-04-10 23:12:48 +00:00
|
|
|
case 'h':
|
|
|
|
case '?': /* Bad options if GNU getopt */
|
|
|
|
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) {
|
|
|
|
fprintf(stderr, "editcap: \"%s\" isn't a valid encapsulation type\n",
|
|
|
|
optarg);
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
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-04-03 11:00:49 +00:00
|
|
|
pdh = wtap_dump_open(argv[optind + 1], out_file_type,
|
|
|
|
out_frame_type, wtap_snapshot_length(wth), &err);
|
|
|
|
if (pdh == NULL) {
|
1999-12-04 12:53:52 +00:00
|
|
|
|
1999-12-12 21:04:29 +00:00
|
|
|
fprintf(stderr, "editcap: Can't open or create %s: %s\n", argv[optind+1],
|
|
|
|
wtap_strerror(err));
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = optind + 2; i < argc; i++)
|
2000-01-17 08:06:03 +00:00
|
|
|
add_selection(argv[i]);
|
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)) {
|
|
|
|
|
|
|
|
if ((!selected(count) && !keep_em) ||
|
|
|
|
(selected(count) && keep_em)) {
|
|
|
|
|
|
|
|
if (verbose)
|
|
|
|
printf("Record: %u\n", count);
|
|
|
|
|
|
|
|
/* We simply write it, perhaps after truncating it; we could do other
|
|
|
|
things, like modify it. */
|
|
|
|
|
|
|
|
phdr = wtap_phdr(wth);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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)
|
2005-04-10 23:12:48 +00:00
|
|
|
strcpy(&buf[i], "%s");
|
|
|
|
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",
|
|
|
|
argv[optind + 1], wtap_strerror(err));
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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-04-03 11:00:49 +00:00
|
|
|
fprintf(stderr, "editcap: Error writing to %s: %s\n", argv[optind + 1],
|
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
|
|
|
|