Skip to content

Commit

Permalink
#406 fix zero-length IP headers
Browse files Browse the repository at this point in the history
  • Loading branch information
fklassen committed Jan 22, 2018
1 parent e8d05fb commit 1b6fac9
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- heap-buffer-overflow in packet2tree (#409)
- heap-buffer-overflow in get_l2len (#408)
- heap-buffer-overflow in flow_decode (#407)
- Rewrite zero IP total length field to match the actual packet length (#406)
- stack-buffer-overflow in tcpcapinfo (#405)

05/10/2017 Version 4.2.6
Expand Down
17 changes: 16 additions & 1 deletion src/tcpedit/edit_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fix_ipv4_checksums(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr, ipv4_hdr_t *i
}

/**
* Returns ipv6 header length wth all ipv6 options on success
* Returns ipv6 header length with all ipv6 options on success
* -1 on error
*/
static int
Expand Down Expand Up @@ -146,6 +146,21 @@ fix_ipv6_checksums(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr, ipv6_hdr_t *i
return TCPEDIT_OK;
}

/*
* #406 fix IP headers which may be not be set properly due to TCP segmentation
*/
void fix_ipv4_length(struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr)
{
if (!ip_hdr->ip_len)
ip_hdr->ip_len = pkthdr->len;
}

void fix_ipv6_length(struct pcap_pkthdr *pkthdr, ipv6_hdr_t *ip6_hdr)
{
if (!ip6_hdr->ip_len)
ip6_hdr->ip_len = pkthdr->len;
}

static void ipv4_l34_csum_replace(uint8_t *data, uint8_t protocol,
uint32_t old, uint32_t new)
{
Expand Down
4 changes: 4 additions & 0 deletions src/tcpedit/edit_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ int fix_ipv4_checksums(tcpedit_t *tcpedit, struct pcap_pkthdr *pkdhdr,
int fix_ipv6_checksums(tcpedit_t *tcpedit, struct pcap_pkthdr *pkdhdr,
ipv6_hdr_t *ip_hdr);

void fix_ipv4_length(struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr);

void fix_ipv6_length(struct pcap_pkthdr *pkthdr, ipv6_hdr_t *ip6_hdr);

int extract_data(tcpedit_t *tcpedit, const u_char *pktdata,
int caplen, char *l7data[]);

Expand Down
10 changes: 10 additions & 0 deletions src/tcpedit/tcpedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,16 @@ tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr,
}
}

/*
* fix IP packet lengths in case they are corrupted by TCP segmentation
* offload
*/
if (ip_hdr != NULL) {
fix_ipv4_length(*pkthdr, ip_hdr);
} else if (ip6_hdr != NULL) {
fix_ipv6_length(*pkthdr, ip6_hdr);
}

/* do we need to fix checksums? -- must always do this last! */
if ((tcpedit->fixcsum || needtorecalc)) {
if (ip_hdr != NULL) {
Expand Down

0 comments on commit 1b6fac9

Please sign in to comment.