#include <zlib.h> /* to get the libz version number */
#endif
-#include "wtap.h"
+#include <wiretap/wtap.h>
+
+#include "epan/etypes.h"
#ifndef HAVE_GETOPT_LONG
#include "wsutil/wsgetopt.h"
*/
struct select_item {
- int inclusive;
- int first, second;
+ gboolean inclusive;
+ guint first, second;
};
/*
#define MAX_SELECTIONS 512
static struct select_item selectfrm[MAX_SELECTIONS];
-static int max_selected = -1;
+static guint max_selected = 0;
static int keep_em = 0;
#ifdef PCAP_NG_DEFAULT
static int out_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG; /* default to pcapng */
static time_t starttime = 0;
static time_t stoptime = 0;
static gboolean check_startstop = FALSE;
+static gboolean rem_vlan = FALSE;
static gboolean dup_detect = FALSE;
static gboolean dup_detect_by_time = FALSE;
/* Add a selection item, a simple parser for now */
static gboolean
-add_selection(char *sel)
+add_selection(char *sel, guint* max_selection)
{
char *locn;
char *next;
- if (++max_selected >= MAX_SELECTIONS) {
+ if (max_selected >= MAX_SELECTIONS) {
/* Let the user know we stopped selecting */
fprintf(stderr, "Out of room for packet selections!\n");
return(FALSE);
if (verbose)
fprintf(stderr, "Not inclusive ...");
- selectfrm[max_selected].inclusive = 0;
- selectfrm[max_selected].first = atoi(sel);
+ selectfrm[max_selected].inclusive = FALSE;
+ selectfrm[max_selected].first = (guint)strtoul(sel, NULL, 10);
+ if (selectfrm[max_selected].first < *max_selection)
+ *max_selection = selectfrm[max_selected].first;
if (verbose)
fprintf(stderr, " %i\n", selectfrm[max_selected].first);
fprintf(stderr, "Inclusive ...");
next = locn + 1;
- selectfrm[max_selected].inclusive = 1;
- selectfrm[max_selected].first = atoi(sel);
- selectfrm[max_selected].second = atoi(next);
+ selectfrm[max_selected].inclusive = TRUE;
+ selectfrm[max_selected].first = (guint)strtoul(sel, NULL, 10);
+ selectfrm[max_selected].second = (guint)strtoul(next, NULL, 10);
+
+ if (selectfrm[max_selected].second == 0)
+ {
+ /* Not a valid number, presume all */
+ selectfrm[max_selected].second = *max_selection = G_MAXUINT;
+ }
+ else if (selectfrm[max_selected].second < *max_selection)
+ *max_selection = selectfrm[max_selected].second;
if (verbose)
fprintf(stderr, " %i, %i\n", selectfrm[max_selected].first,
selectfrm[max_selected].second);
}
+ max_selected++;
return(TRUE);
}
/* Was the packet selected? */
static int
-selected(int recno)
+selected(guint recno)
{
- int i;
+ guint i;
- for (i = 0; i <= max_selected; i++) {
+ for (i = 0; i < max_selected; i++) {
if (selectfrm[i].inclusive) {
if (selectfrm[i].first <= recno && selectfrm[i].second >= recno)
return 1;
relative_time_window.nsecs = (int)val;
}
+#define LINUX_SLL_OFFSETP 14
+#define VLAN_SIZE 4
+static void
+sll_remove_vlan_info(guint8* fd, guint32* len) {
+ if (g_ntohs(*(fd + LINUX_SLL_OFFSETP)) == ETHERTYPE_VLAN) {
+ int rest_len;
+ /* point to start of vlan */
+ fd = fd + LINUX_SLL_OFFSETP;
+ /* bytes to read after vlan info */
+ rest_len = *len - (LINUX_SLL_OFFSETP + VLAN_SIZE);
+ /* remove vlan info from packet */
+ memmove(fd, fd + VLAN_SIZE, rest_len);
+ *len -= 4;
+ }
+}
+
+static void
+remove_vlan_info(const struct wtap_pkthdr *phdr, guint8* fd, guint32* len) {
+ switch (phdr->pkt_encap) {
+ case WTAP_ENCAP_SLL:
+ sll_remove_vlan_info(fd, len);
+ break;
+ default:
+ /* no support for current pkt_encap */
+ break;
+ }
+}
+
static gboolean
is_duplicate(guint8* fd, guint32 len) {
int i;
fprintf(output, " given time (format as YYYY-MM-DD hh:mm:ss).\n");
fprintf(output, "\n");
fprintf(output, "Duplicate packet removal:\n");
+ fprintf(output, " --novlan remove vlan info from packets before checking for duplicates.\n");
fprintf(output, " -d remove packet if duplicate (window == %d).\n", DEFAULT_DUP_DEPTH);
fprintf(output, " -D <dup window> remove packet if duplicate; configurable <dup window>\n");
fprintf(output, " Valid <dup window> values are 0 to %d.\n", MAX_DUP_DEPTH);
fprintf(output, " all packets to the timestamp of the first packet.\n");
fprintf(output, " -E <error probability> set the probability (between 0.0 and 1.0 incl.) that\n");
fprintf(output, " a particular packet byte will be randomly changed.\n");
- fprintf(output, " -o <change offset> When used in conjuction with -E, skip some bytes from the\n");
- fprintf(output, " beginning of the packet. This allows to preserve some\n");
+ fprintf(output, " -o <change offset> When used in conjunction with -E, skip some bytes from the\n");
+ fprintf(output, " beginning of the packet. This allows one to preserve some\n");
fprintf(output, " bytes, in order to have some headers untouched.\n");
fprintf(output, "\n");
fprintf(output, "Output File(s):\n");
g_free(encaps);
}
-/* TODO: is there the equivalent of g_direct_equal? */
static int
-framenum_equal(gconstpointer a, gconstpointer b, gpointer user_data _U_)
+framenum_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_)
{
- return (a != b);
-}
+ if (GPOINTER_TO_UINT(a) < GPOINTER_TO_UINT(b))
+ return -1;
+ if (GPOINTER_TO_UINT(a) > GPOINTER_TO_UINT(b))
+ return 1;
+ return 0;
+}
#ifdef HAVE_PLUGINS
/*
int i, j, read_err, write_err;
gchar *read_err_info, *write_err_info;
int opt;
-DIAG_OFF(cast-qual)
static const struct option long_options[] = {
- {(char *)"help", no_argument, NULL, 'h'},
- {(char *)"version", no_argument, NULL, 'V'},
+ {"novlan", no_argument, NULL, 0x8100},
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'V'},
{0, 0, 0, 0 }
};
-DIAG_ON(cast-qual)
char *p;
guint32 snaplen = 0; /* No limit */
gchar *fprefix = NULL;
gchar *fsuffix = NULL;
guint32 change_offset = 0;
-
+ guint max_packet_number = G_MAXUINT;
const struct wtap_pkthdr *phdr;
struct wtap_pkthdr temp_phdr;
wtapng_iface_descriptions_t *idb_inf = NULL;
#ifdef HAVE_PLUGINS
/* Register wiretap plugins */
- if ((init_progfile_dir_error = init_progfile_dir(argv[0], (void *)main))) {
+ if ((init_progfile_dir_error = init_progfile_dir(argv[0], main))) {
g_warning("editcap: init_progfile_dir(): %s", init_progfile_dir_error);
g_free(init_progfile_dir_error);
} else {
/* Process the options */
while ((opt = getopt_long(argc, argv, "a:A:B:c:C:dD:E:F:hi:I:Lo:rs:S:t:T:vVw:", long_options, NULL)) != -1) {
switch (opt) {
+ case 0x8100:
+ {
+ rem_vlan = TRUE;
+ break;
+ }
+
case 'a':
{
guint frame_number;
/* Lazily create the table */
if (!frames_user_comments) {
- frames_user_comments = g_tree_new_full(framenum_equal, NULL, NULL, g_free);
+ frames_user_comments = g_tree_new_full(framenum_compare, NULL, NULL, g_free);
}
/* Insert this entry (framenum -> comment) */
case 'h':
printf("Editcap (Wireshark) %s\n"
"Edit and/or translate the format of capture files.\n"
- "See http://www.wireshark.org for more information.\n",
+ "See https://www.wireshark.org for more information.\n",
get_ws_vcs_version_info());
print_usage(stdout);
exit(0);
out_frame_type = wtap_file_encap(wth);
for (i = optind + 2; i < argc; i++)
- if (add_selection(argv[i]) == FALSE)
+ if (add_selection(argv[i], &max_packet_number) == FALSE)
break;
+ if (keep_em == FALSE)
+ max_packet_number = G_MAXUINT;
+
if (dup_detect || dup_detect_by_time) {
for (i = 0; i < dup_window; i++) {
memset(&fd_hash[i].digest, 0, 16);
/* Read all of the packets in turn */
while (wtap_read(wth, &read_err, &read_err_info, &data_offset)) {
+ if (max_packet_number <= read_count)
+ break;
+
read_count++;
phdr = wtap_phdr(wth);
*/
if (phdr->presence_flags & WTAP_HAS_TS) {
if (nstime_is_unset(&block_start)) {
- block_start.secs = phdr->ts.secs;
- block_start.nsecs = phdr->ts.nsecs;
+ block_start = phdr->ts;
}
if (secs_per_block > 0) {
nstime_t current;
nstime_t delta;
- current.secs = phdr->ts.secs;
- current.nsecs = phdr->ts.nsecs;
+ current = phdr->ts;
nstime_delta(&delta, ¤t, &previous_time);
phdr = &temp_phdr;
}
}
- previous_time.secs = phdr->ts.secs;
- previous_time.nsecs = phdr->ts.nsecs;
+ previous_time = phdr->ts;
}
- /* assume that if the frame's tv_sec is 0, then
- * the timestamp isn't supported */
- if (phdr->ts.secs > 0 && time_adj.tv.secs != 0) {
+ if (time_adj.tv.secs != 0) {
temp_phdr = *phdr;
if (time_adj.is_negative)
temp_phdr.ts.secs -= time_adj.tv.secs;
phdr = &temp_phdr;
}
- /* assume that if the frame's tv_sec is 0, then
- * the timestamp isn't supported */
- if (phdr->ts.secs > 0 && time_adj.tv.nsecs != 0) {
+ if (time_adj.tv.nsecs != 0) {
temp_phdr = *phdr;
if (time_adj.is_negative) { /* subtract */
if (temp_phdr.ts.nsecs < time_adj.tv.nsecs) { /* borrow */
}
} /* time stamp adjustment */
+ /* remove vlan info */
+ if (rem_vlan) {
+ /* TODO: keep casting const like this? change pointer instead of value? */
+ remove_vlan_info(phdr, buf, (guint32 *) &phdr->caplen);
+ }
+
/* suppress duplicates by packet window */
if (dup_detect) {
if (is_duplicate(buf, phdr->caplen)) {