editcap: flag for ignore vlan duplication removal

Add additional --novlan flag for removing vlan tag info before checking for duplicates.
When capturing with -i any you could see packets more than once and some drivers include vlan info.
With the --novlan the vlan info is removed from the packet so that checksum duplication detection can be used,
if the rest of the packets are the same.

Change-Id: I5dca6e20259a0a396875919e9e60cc42291579d3
Reviewed-on: https://code.wireshark.org/review/13414
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Jonas Falkevik 2016-01-19 14:04:10 +01:00 committed by Anders Broman
parent 82bb9ebc01
commit 780f886d29
1 changed files with 45 additions and 0 deletions

View File

@ -60,6 +60,8 @@
#include <wiretap/wtap.h>
#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 <dup window> remove packet if duplicate; configurable <dup window>\n");
fprintf(output, " Valid <dup window> 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)) {