From 3e2c04fe7839ec920efd3da309013b89a16cff60 Mon Sep 17 00:00:00 2001 From: Jonas Falkevik Date: Tue, 2 Nov 2021 16:04:46 +0100 Subject: [PATCH] editcap: flag to set unused bytes in SLL headers Unused bytes in SLL Link Layer address can be random bytes. Which makes the duplicate check think the packets are different. Even if the unused bytes was the only difference. This flag enables editcap to set the unused bytes to zeros to enable the duplicate check to detect duplicates. --- doc/editcap.adoc | 9 +++++++++ editcap.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/doc/editcap.adoc b/doc/editcap.adoc index 2dc96585ba..120c1c4082 100644 --- a/doc/editcap.adoc +++ b/doc/editcap.adoc @@ -45,6 +45,7 @@ __outfile__ [ *-V* ] [ *-I* ] [ *--skip-radiotap-header* ] +[ *--set-unused* ] __infile__ __outfile__ @@ -464,6 +465,14 @@ file. Does not discard comments added by *--capture-comment* in the same command line. -- +--set-unused:: ++ +-- +Set the unused bytes (if any) to zero in SLL link type. Useful when when checking for duplicates. +As the unused bytes can be anything. When the packet traverses the device stack +for bonded interfaces on Linux for example. +-- + include::diagnostic-options.adoc[] == EXAMPLES diff --git a/editcap.c b/editcap.c index e57e43d905..67cfc3bc89 100644 --- a/editcap.c +++ b/editcap.c @@ -156,6 +156,7 @@ static gboolean dup_detect_by_time = FALSE; static gboolean skip_radiotap = FALSE; static gboolean discard_all_secrets = FALSE; static gboolean discard_cap_comments = FALSE; +static gboolean set_unused = FALSE; static int do_strict_time_adjustment = FALSE; static struct time_adjustment strict_time_adj = {NSTIME_INIT_ZERO, 0}; /* strict time adjustment */ @@ -558,6 +559,23 @@ sll_remove_vlan_info(guint8* fd, guint32* len) { } } +#define LINUX_SLL_OFFSETLL 4 +#define SLL_ADDRLEN 8 /* length of address field */ +static void +sll_set_unused_info(guint8* fd) { + guint32 ha_len; + ha_len = pntoh16(fd + LINUX_SLL_OFFSETLL); + + if (ha_len < SLL_ADDRLEN) { + int unused; + unused = SLL_ADDRLEN - ha_len; + /* point to start of LL address offset plus addr len 2 bytes */ + fd = fd + LINUX_SLL_OFFSETLL + 2; + /* set zeros in the unused data */ + memset(fd + ha_len, 0, unused); + } +} + static void remove_vlan_info(const wtap_packet_header *phdr, guint8* fd, guint32* len) { switch (phdr->pkt_encap) { @@ -570,6 +588,18 @@ remove_vlan_info(const wtap_packet_header *phdr, guint8* fd, guint32* len) { } } +static void +set_unused_info(const wtap_packet_header *phdr, guint8* fd) { + switch (phdr->pkt_encap) { + case WTAP_ENCAP_SLL: + sll_set_unused_info(fd); + break; + default: + /* no support for current pkt_encap */ + break; + } +} + static gboolean is_duplicate(guint8* fd, guint32 len) { int i; @@ -768,6 +798,7 @@ print_usage(FILE *output) fprintf(output, " --skip-radiotap-header skip radiotap header when checking for packet duplicates.\n"); fprintf(output, " Useful when processing packets captured by multiple radios\n"); fprintf(output, " on the same channel in the vicinity of each other.\n"); + fprintf(output, " --set-unused set unused byts to zero in sll link addr.\n"); fprintf(output, "\n"); fprintf(output, "Packet manipulation:\n"); fprintf(output, " -s truncate each packet to max. bytes of data.\n"); @@ -1128,6 +1159,7 @@ main(int argc, char *argv[]) #define LONGOPT_DISCARD_ALL_SECRETS LONGOPT_BASE_APPLICATION+5 #define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+6 #define LONGOPT_DISCARD_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+7 +#define LONGOPT_SET_UNUSED LONGOPT_BASE_APPLICATION+8 static const struct ws_option long_options[] = { {"novlan", ws_no_argument, NULL, LONGOPT_NO_VLAN}, @@ -1139,6 +1171,7 @@ main(int argc, char *argv[]) {"version", ws_no_argument, NULL, 'v'}, {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT}, {"discard-capture-comment", ws_no_argument, NULL, LONGOPT_DISCARD_CAPTURE_COMMENT}, + {"set-unused", ws_no_argument, NULL, LONGOPT_SET_UNUSED}, {0, 0, 0, 0 } }; @@ -1317,6 +1350,12 @@ main(int argc, char *argv[]) break; } + case LONGOPT_SET_UNUSED: + { + set_unused = TRUE; + break; + } + case 'a': { guint frame_number; @@ -2065,6 +2104,12 @@ main(int argc, char *argv[]) adjlen); rec = &temp_rec; + /* set unused info */ + if (set_unused) { + /* set unused bytes to zero so that duplicates check ignores unused bytes */ + set_unused_info(&rec->rec_header.packet_header, buf); + } + /* remove vlan info */ if (rem_vlan) { /* Copy and change rather than modify returned rec */