From ba4cd31243d4e2ad582dab1847098a1efcd21c06 Mon Sep 17 00:00:00 2001 From: Charles Cottrill Date: Mon, 2 Sep 2024 13:03:14 -0400 Subject: [PATCH] feature: fix/recalculate header checksum for ipv6-frag(mentation) packets --- src/tcpedit/checksum.c | 2 ++ src/tcpedit/plugins/dlt_en10mb/en10mb.c | 1 + src/tcpedit/tcpedit.c | 4 +++- src/tcpr.h | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tcpedit/checksum.c b/src/tcpedit/checksum.c index 52d9cb65..5b4a8a57 100644 --- a/src/tcpedit/checksum.c +++ b/src/tcpedit/checksum.c @@ -78,6 +78,7 @@ do_checksum(tcpedit_t *tcpedit, uint8_t *data, int proto, int len, const u_char switch (proto) { case IPPROTO_TCP: + case IPPROTO_TCP_V6FRAG: if (len < (int)sizeof(tcp_hdr_t)) { tcpedit_setwarn(tcpedit, "%s", "Unable to checksum TCP with insufficient L4 data"); return TCPEDIT_WARN; @@ -98,6 +99,7 @@ do_checksum(tcpedit_t *tcpedit, uint8_t *data, int proto, int len, const u_char } else { sum = do_checksum_math((uint16_t *)&ipv4->ip_src, 8); } + sum += ntohs(IPPROTO_TCP + len); sum += do_checksum_math((uint16_t *)tcp, len); tcp->th_sum = CHECKSUM_CARRY(sum); diff --git a/src/tcpedit/plugins/dlt_en10mb/en10mb.c b/src/tcpedit/plugins/dlt_en10mb/en10mb.c index 8a8b2330..f9f83e35 100644 --- a/src/tcpedit/plugins/dlt_en10mb/en10mb.c +++ b/src/tcpedit/plugins/dlt_en10mb/en10mb.c @@ -185,6 +185,7 @@ dlt_en10mb_parse_subsmac(tcpeditdlt_t *ctx, en10mb_config_t *config, const char size_t input_len = strlen(input); size_t possible_entries_number = (input_len / (SUBSMAC_ENTRY_LEN + 1)) + 1; size_t entry; + unsigned int entry; en10mb_sub_entry_t *entries = safe_malloc(possible_entries_number * sizeof(en10mb_sub_entry_t)); diff --git a/src/tcpedit/tcpedit.c b/src/tcpedit/tcpedit.c index 51b78bf1..9ef1e334 100644 --- a/src/tcpedit/tcpedit.c +++ b/src/tcpedit/tcpedit.c @@ -320,11 +320,13 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, u_char **pktdata /* do we need to fix checksums? -- must always do this last! */ if (tcpedit->fixhdrlen) { /* ensure IP header length is correct */ + /* when packet change? then needtorecalc checksum */ int changed = 0; if (ip_hdr != NULL) { + /* did the packet change? if so, checksum */ changed = fix_ipv4_length(*pkthdr, ip_hdr, l2len); } 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) { diff --git a/src/tcpr.h b/src/tcpr.h index 4da521a0..e8782c8b 100644 --- a/src/tcpr.h +++ b/src/tcpr.h @@ -652,6 +652,9 @@ struct tcpr_gre_hdr { #ifndef IPPROTO_GRE #define IPPROTO_GRE 47 #endif +#ifndef IPPROTO_TCP_V6FRAG +#define IPPROTO_TCP_V6FRAG 0x2c +#endif /* * Source Route Entries (SRE)