From d6ac779170bc6ed8ba6900401fd858811287a4a2 Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Wed, 31 Jan 2024 17:16:43 -0500 Subject: [PATCH 1/7] add fixhdrlen option to turn on/off changing packet header length --- src/tcpedit/edit_packet.c | 9 +++++++-- src/tcpedit/parse_args.c | 8 ++++++++ src/tcpedit/tcpedit.c | 21 ++++++++++++++------- src/tcpedit/tcpedit_api.c | 11 +++++++++++ src/tcpedit/tcpedit_api.h | 1 + src/tcpedit/tcpedit_opts.def | 14 ++++++++++++++ src/tcpedit/tcpedit_types.h | 3 +++ src/tcpreplay_api.h | 3 +++ 8 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index 401fdd73..c4b54819 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -371,13 +371,17 @@ int fix_ipv4_length(struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr, int ip_len = (int)ntohs(ip_hdr->ip_len); int ip_len_want = (int)(pkthdr->len - l2len); - if (pkthdr->caplen < l2len + sizeof(*ip_hdr)) + if (pkthdr->caplen < l2len + sizeof(*ip_hdr)) { + ip_hdr->ip_len = htons(ip_len_want); return -1; + } if ((htons(ip_hdr->ip_off) & (IP_MF | IP_OFFMASK)) == 0 && ip_len != ip_len_want) { +// here is problem? ip_hdr->ip_len = htons(ip_len_want); return 1; +// return 0; } return 0; @@ -389,8 +393,9 @@ int fix_ipv6_length(struct pcap_pkthdr *pkthdr, ipv6_hdr_t *ip6_hdr, int ip_len = ntohs((uint16_t)ip6_hdr->ip_len); int ip_len_want = (int)(pkthdr->len - l2len - sizeof(*ip6_hdr)); - if (pkthdr->caplen < l2len + sizeof(*ip6_hdr)) + if (pkthdr->caplen < l2len + sizeof(*ip6_hdr)) { return -1; + } if (ip_len != ip_len_want) { ip6_hdr->ip_len = htons((uint16_t)ip_len_want); diff --git a/src/tcpedit/parse_args.c b/src/tcpedit/parse_args.c index ab012b3b..233b3582 100644 --- a/src/tcpedit/parse_args.c +++ b/src/tcpedit/parse_args.c @@ -102,6 +102,14 @@ 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 d5463959..206a1b65 100644 --- a/src/tcpedit/tcpedit.c +++ b/src/tcpedit/tcpedit.c @@ -326,7 +326,6 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, } } - /* do we need to spoof the src/dst IP address in IPv4 or ARP? */ if (tcpedit->seed) { /* IPv4 Packets */ @@ -356,12 +355,20 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, } } - /* ensure IP header length is correct */ - if (ip_hdr != NULL) { - needtorecalc |= 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) { + int changed = 0; + if (ip_hdr != NULL) { + changed = fix_ipv4_length(*pkthdr, ip_hdr, l2len); + } 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; + // needtorecalc = 1; + } } /* 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 a9509762..05fca102 100644 --- a/src/tcpedit/tcpedit_api.c +++ b/src/tcpedit/tcpedit_api.c @@ -140,6 +140,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 1a3a1ec7..8c92e1f5 100644 --- a/src/tcpedit/tcpedit_api.h +++ b/src/tcpedit/tcpedit_api.h @@ -42,6 +42,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..2597202c 100644 --- a/src/tcpedit/tcpedit_opts.def +++ b/src/tcpedit/tcpedit_opts.def @@ -170,6 +170,20 @@ fixed. Automatically enabled for packets modified with @samp{--seed}, EOText; }; +// CHUCK +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 19beb3cc..028ac4cb 100644 --- a/src/tcpedit/tcpedit_types.h +++ b/src/tcpedit/tcpedit_types.h @@ -161,6 +161,9 @@ typedef struct { uint32_t fuzz_seed; uint32_t fuzz_factor; + + /* fix header length */ + bool fixhdrlen; } tcpedit_t; diff --git a/src/tcpreplay_api.h b/src/tcpreplay_api.h index 7c4e94e9..e3412038 100644 --- a/src/tcpreplay_api.h +++ b/src/tcpreplay_api.h @@ -190,6 +190,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() */ From 69698236e1322e6546576337b120006e2ef84bb1 Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Wed, 31 Jan 2024 18:04:54 -0500 Subject: [PATCH 2/7] resolve merge conflict --- src/tcpedit/edit_packet.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index c4b54819..7de29fda 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -371,17 +371,15 @@ int fix_ipv4_length(struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr, int ip_len = (int)ntohs(ip_hdr->ip_len); int ip_len_want = (int)(pkthdr->len - l2len); + pkthdr->caplen, l2len, sizeof(*ip_hdr)); if (pkthdr->caplen < l2len + sizeof(*ip_hdr)) { ip_hdr->ip_len = htons(ip_len_want); return -1; } - if ((htons(ip_hdr->ip_off) & (IP_MF | IP_OFFMASK)) == 0 && - ip_len != ip_len_want) { -// here is problem? + if ((htons(ip_hdr->ip_off) & (IP_MF | IP_OFFMASK)) == 0 && ip_len != ip_len_want) { ip_hdr->ip_len = htons(ip_len_want); return 1; -// return 0; } return 0; From 5811d31224134e1e76233dfde2031fa069ab5d6e Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Wed, 31 Jan 2024 18:10:08 -0500 Subject: [PATCH 3/7] resolve merge conflict --- src/tcpedit/tcpedit.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tcpedit/tcpedit.c b/src/tcpedit/tcpedit.c index 206a1b65..b6707248 100644 --- a/src/tcpedit/tcpedit.c +++ b/src/tcpedit/tcpedit.c @@ -360,14 +360,14 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, if (tcpedit->fixhdrlen) { int changed = 0; if (ip_hdr != NULL) { - changed = fix_ipv4_length(*pkthdr, ip_hdr, l2len); + fix_ipv4_length(*pkthdr, ip_hdr, l2len); + changed = 1; } else if (ip6_hdr != NULL) { - changed |= fix_ipv6_length(*pkthdr, ip6_hdr, l2len); + changed = fix_ipv6_length(*pkthdr, ip6_hdr, l2len); } /* did the packet change? then needtorecalc checksum */ if (changed > 0) { - needtorecalc += changed; - // needtorecalc = 1; + needtorecalc |= changed; } } From fa37e0a00bb40104803f45b31696dedd20f1f2aa Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Wed, 31 Jan 2024 18:30:53 -0500 Subject: [PATCH 4/7] remove stray debug line --- src/tcpedit/edit_packet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index 7de29fda..95282eb5 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -371,7 +371,6 @@ int fix_ipv4_length(struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr, int ip_len = (int)ntohs(ip_hdr->ip_len); int ip_len_want = (int)(pkthdr->len - l2len); - pkthdr->caplen, l2len, sizeof(*ip_hdr)); if (pkthdr->caplen < l2len + sizeof(*ip_hdr)) { ip_hdr->ip_len = htons(ip_len_want); return -1; From 303cd76b90338030d08e8888bcb8ccfd947971dd Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Wed, 31 Jan 2024 22:28:49 -0500 Subject: [PATCH 5/7] remove comment --- src/tcpedit/tcpedit_opts.def | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tcpedit/tcpedit_opts.def b/src/tcpedit/tcpedit_opts.def index 2597202c..c2fdd340 100644 --- a/src/tcpedit/tcpedit_opts.def +++ b/src/tcpedit/tcpedit_opts.def @@ -170,7 +170,6 @@ fixed. Automatically enabled for packets modified with @samp{--seed}, EOText; }; -// CHUCK flag = { name = fixhdrlen; // value = C; From 35aebe8076c6e4c28ac76465746e2a2504c8f6f3 Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Thu, 8 Feb 2024 22:05:25 -0500 Subject: [PATCH 6/7] changes to address PR comment s --- src/tcpedit/edit_packet.c | 3 +-- src/tcpedit/parse_args.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index 68634d68..caefbbcc 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -381,9 +381,8 @@ fix_ipv6_length(struct pcap_pkthdr *pkthdr, ipv6_hdr_t *ip6_hdr, size_t l2len) int ip_len = ntohs((uint16_t)ip6_hdr->ip_len); int ip_len_want = (int)(pkthdr->len - l2len - sizeof(*ip6_hdr)); - if (pkthdr->caplen < l2len + sizeof(*ip6_hdr)) { + if (pkthdr->caplen < l2len + sizeof(*ip6_hdr)) return -1; - } if (ip_len != ip_len_want) { ip6_hdr->ip_len = htons((uint16_t)ip_len_want); diff --git a/src/tcpedit/parse_args.c b/src/tcpedit/parse_args.c index b18cb410..99a6583a 100644 --- a/src/tcpedit/parse_args.c +++ b/src/tcpedit/parse_args.c @@ -96,12 +96,10 @@ tcpedit_post_args(tcpedit_t *tcpedit) tcpedit->fixcsum = true; /* --fixhdrlen */ - if (HAVE_OPT(FIXHDRLEN)) { + if (HAVE_OPT(FIXHDRLEN)) tcpedit->fixhdrlen = true; - } - else { + else tcpedit->fixhdrlen = false; - } /* --efcs */ if (HAVE_OPT(EFCS)) From 4bbfd0c9737b257ed2b49385546aee7a54334eba Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Tue, 20 Feb 2024 11:14:36 -0500 Subject: [PATCH 7/7] changes from PR review --- src/tcpedit/edit_packet.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tcpedit/edit_packet.c b/src/tcpedit/edit_packet.c index caefbbcc..1025ff90 100644 --- a/src/tcpedit/edit_packet.c +++ b/src/tcpedit/edit_packet.c @@ -362,10 +362,8 @@ fix_ipv4_length(struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr, size_t l2len) int ip_len = (int)ntohs(ip_hdr->ip_len); int ip_len_want = (int)(pkthdr->len - l2len); - if (pkthdr->caplen < l2len + sizeof(*ip_hdr)) { - ip_hdr->ip_len = htons(ip_len_want); + if (pkthdr->caplen < l2len + sizeof(*ip_hdr)) return -1; - } if ((htons(ip_hdr->ip_off) & (IP_MF | IP_OFFMASK)) == 0 && ip_len != ip_len_want) { ip_hdr->ip_len = htons(ip_len_want);