diff --git a/editcap.c b/editcap.c index 2cd4a1ceb8..fdb80c8d09 100644 --- a/editcap.c +++ b/editcap.c @@ -60,6 +60,8 @@ #include +#include "epan/etypes.h" + #ifndef HAVE_GETOPT_LONG #include "wsutil/wsgetopt.h" #endif @@ -167,6 +169,7 @@ static double err_prob = 0.0; 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; @@ -545,6 +548,34 @@ set_rel_time(char *optarg_str_p) 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; @@ -710,6 +741,7 @@ print_usage(FILE *output) 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 remove packet if duplicate; configurable \n"); fprintf(output, " Valid values are 0 to %d.\n", MAX_DUP_DEPTH); @@ -935,6 +967,7 @@ main(int argc, char *argv[]) gchar *read_err_info, *write_err_info; int opt; static const struct option long_options[] = { + {"novlan", no_argument, NULL, 0x8100}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0 } @@ -1020,6 +1053,12 @@ main(int argc, char *argv[]) /* 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; @@ -1592,6 +1631,12 @@ main(int argc, char *argv[]) } } /* 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)) {