diff --git a/src/tcpedit/parse_args.c b/src/tcpedit/parse_args.c index 0ec4a176..99a6583a 100644 --- a/src/tcpedit/parse_args.c +++ b/src/tcpedit/parse_args.c @@ -95,6 +95,12 @@ tcpedit_post_args(tcpedit_t *tcpedit) if (HAVE_OPT(FIXCSUM)) tcpedit->fixcsum = true; + /* --fixhdrlen */ + if (HAVE_OPT(FIXHDRLEN)) + tcpedit->fixhdrlen = true; + else + tcpedit->fixhdrlen = false; + /* --efcs */ if (HAVE_OPT(EFCS)) tcpedit->efcs = true; diff --git a/src/tcpedit/tcpedit.c b/src/tcpedit/tcpedit.c index 23562b8c..b1af7b05 100644 --- a/src/tcpedit/tcpedit.c +++ b/src/tcpedit/tcpedit.c @@ -315,12 +315,21 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, u_char **pktdata } } - /* ensure IP header length is correct */ - if (ip_hdr != NULL) { - fix_ipv4_length(*pkthdr, ip_hdr, l2len); - needtorecalc = 1; - } else if (ip6_hdr != NULL) { - needtorecalc |= fix_ipv6_length(*pkthdr, ip6_hdr, l2len); + /* fixhdrlen option ensure IP header length is correct */ + /* do we need to fix checksums? -- must always do this last! */ + if (tcpedit->fixhdrlen) { + /* ensure IP header length is correct */ + int changed = 0; + if (ip_hdr != NULL) { + fix_ipv4_length(*pkthdr, ip_hdr, l2len); + changed = 1; + } else if (ip6_hdr != NULL) { + changed = fix_ipv6_length(*pkthdr, ip6_hdr, l2len); + } + /* did the packet change? then needtorecalc checksum */ + if (changed > 0) { + needtorecalc |= changed; + } } /* do we need to fix checksums? -- must always do this last! */ diff --git a/src/tcpedit/tcpedit_api.c b/src/tcpedit/tcpedit_api.c index 61d988fb..3f23d6ac 100644 --- a/src/tcpedit/tcpedit_api.c +++ b/src/tcpedit/tcpedit_api.c @@ -136,6 +136,17 @@ tcpedit_set_fixcsum(tcpedit_t *tcpedit, bool value) return TCPEDIT_OK; } +/** + * \brief should we fix(?) header length? + */ +int +tcpedit_set_fixhdrlen(tcpedit_t *tcpedit, bool value) +{ + assert(tcpedit); + tcpedit->fixhdrlen = value; + return TCPEDIT_OK; +} + /** * \brief should we remove the EFCS from the frame? */ diff --git a/src/tcpedit/tcpedit_api.h b/src/tcpedit/tcpedit_api.h index 50e93123..6547f262 100644 --- a/src/tcpedit/tcpedit_api.h +++ b/src/tcpedit/tcpedit_api.h @@ -40,6 +40,7 @@ int tcpedit_set_encoder_dltplugin_byname(tcpedit_t *, const char *); int tcpedit_set_skip_broadcast(tcpedit_t *, bool); int tcpedit_set_fixlen(tcpedit_t *, tcpedit_fixlen); int tcpedit_set_fixcsum(tcpedit_t *, bool); +int tcpedit_set_fixhdrlen(tcpedit_t *, bool); int tcpedit_set_efcs(tcpedit_t *, bool); int tcpedit_set_ttl_mode(tcpedit_t *, tcpedit_ttl_mode); int tcpedit_set_ttl_value(tcpedit_t *, uint8_t); diff --git a/src/tcpedit/tcpedit_opts.def b/src/tcpedit/tcpedit_opts.def index 3f8ee287..c2fdd340 100644 --- a/src/tcpedit/tcpedit_opts.def +++ b/src/tcpedit/tcpedit_opts.def @@ -170,6 +170,19 @@ fixed. Automatically enabled for packets modified with @samp{--seed}, EOText; }; +flag = { + name = fixhdrlen; + // value = C; + descrip = "fix IP/TCP header len"; + doc = <<- EOText +By default, tcpreplay will send packets with the original packet length, +However, you may want the packet length revised to minimum packet size. +Using this option, tcpreplay will rewrite (fix) the packet length, +and recalculate checksums. +Caution: undesired packet changes may occur when this option is specified. +EOText; +}; + flag = { name = mtu; value = m; diff --git a/src/tcpedit/tcpedit_types.h b/src/tcpedit/tcpedit_types.h index a0ef961b..7085d737 100644 --- a/src/tcpedit/tcpedit_types.h +++ b/src/tcpedit/tcpedit_types.h @@ -147,6 +147,9 @@ typedef struct { uint32_t fuzz_seed; uint32_t fuzz_factor; + + /* fix header length */ + bool fixhdrlen; } tcpedit_t; #ifdef __cplusplus diff --git a/src/tcpreplay_api.h b/src/tcpreplay_api.h index 88c03981..a4b5bd89 100644 --- a/src/tcpreplay_api.h +++ b/src/tcpreplay_api.h @@ -178,6 +178,9 @@ typedef struct tcpreplay_s { uint32_t skip_packets; bool first_time; + /* fix header length */ + bool fixhdrlen; + /* counter stats */ tcpreplay_stats_t stats; tcpreplay_stats_t static_stats; /* stats returned by tcpreplay_get_stats() */