summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Roberts <vieuxtech@gmail.com>2010-02-22 17:10:43 -0800
committerSam Roberts <vieuxtech@gmail.com>2010-02-22 17:10:43 -0800
commit48687119988df2936588401e04034454f6f4598c (patch)
tree39b24070cedaa208ad7f39cea389c4ed69328836
parentef534a4eb3162c3b0b1ed3ea8e12e2d13e6228b5 (diff)
downloadlibnet-48687119988df2936588401e04034454f6f4598c.tar.gz
Roundtrip invalid packets with tcp reserved flags set, and short header lengths.
-rw-r--r--lua/libnet_decode.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/lua/libnet_decode.c b/lua/libnet_decode.c
index 4ae425d..7f3d7a5 100644
--- a/lua/libnet_decode.c
+++ b/lua/libnet_decode.c
@@ -52,7 +52,7 @@ int libnet_decode_tcp(const uint8_t* pkt, size_t pkt_s, libnet_t *l)
th_off = tcp_hdr->th_off * 4;
- if(pkt_s < th_off)
+ if(pkt_s < th_off || th_off < LIBNET_TCP_H)
return pushdata(pkt, pkt_s, l, 0);
payload = pkt + th_off;
@@ -79,6 +79,14 @@ int libnet_decode_tcp(const uint8_t* pkt, size_t pkt_s, libnet_t *l)
payload, payload_s,
l, 0);
+ if(ptag > 0) {
+ /* Patch the reserved flags to equal those in the original packet. Even
+ * though they should usually be zero.
+ */
+ struct libnet_tcp_hdr* hdr = (struct libnet_tcp_hdr*) libnet_pblock_find(l, ptag)->buf;
+ hdr->th_x2 = tcp_hdr->th_x2;
+ }
+
if(ptag > 0)
libnet_pblock_setflags(libnet_pblock_find(l, ptag), LIBNET_PBLOCK_DO_CHECKSUM);
@@ -124,7 +132,7 @@ int libnet_decode_ipv4(const uint8_t* pkt, size_t pkt_s, libnet_t *l)
ip_hl = ip_hdr->ip_hl * 4;
- if(pkt_s < ip_hl)
+ if(pkt_s < ip_hl || ip_hl < LIBNET_IPV4_H)
return pushdata(pkt, pkt_s, l, 0);
payload = pkt + ip_hl;