]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
defrag: work around packet creation issues
authorVictor Julien <victor@inliniac.net>
Sun, 15 May 2016 18:05:44 +0000 (20:05 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 18 May 2016 15:38:20 +0000 (17:38 +0200)
Defrag tests set up packets but don't call Decode on them. Work
around failing IPv6 tests.

src/decode-ipv6.c
src/defrag.c

index c13b8806c9934ca531687d223d66cc350404cba4..9ca063065239b5722772d6410b63045b3c67646e 100644 (file)
@@ -101,6 +101,49 @@ static int DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint
     return TM_ECODE_OK;
 }
 
+#ifndef UNITTESTS // ugly, but we need this in defrag tests
+static inline
+#endif
+void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt,
+                          uint16_t hdrextlen, uint16_t plen,
+                          uint16_t ip6_exthdrs_cnt, IPV6GenOptHdr *ip6_exthdrs)
+{
+    uint16_t frag_offset = (*(pkt + 2) << 8 | *(pkt + 3)) & 0xFFF8;
+    int frag_morefrags   = (*(pkt + 2) << 8 | *(pkt + 3)) & 0x0001;
+
+    p->ip6eh.fh_offset = frag_offset;
+    p->ip6eh.fh_more_frags_set = frag_morefrags ? TRUE : FALSE;
+    p->ip6eh.fh_nh = *pkt;
+
+    uint32_t fh_id;
+    memcpy(&fh_id, pkt+4, 4);
+    p->ip6eh.fh_id = ntohl(fh_id);
+
+    SCLogDebug("IPV6 FH: offset %u, mf %s, nh %u, id %u/%x",
+            p->ip6eh.fh_offset,
+            p->ip6eh.fh_more_frags_set ? "true" : "false",
+            p->ip6eh.fh_nh,
+            p->ip6eh.fh_id, p->ip6eh.fh_id);
+
+    // store header offset, data offset
+    uint16_t frag_hdr_offset = (uint16_t)(pkt - GET_PKT_DATA(p));
+    uint16_t data_offset = (uint16_t)(frag_hdr_offset + hdrextlen);
+    uint16_t data_len = plen - hdrextlen;
+
+    p->ip6eh.fh_header_offset = frag_hdr_offset;
+    p->ip6eh.fh_data_offset = data_offset;
+    p->ip6eh.fh_data_len = data_len;
+
+    /* if we have a prev hdr, store the type and offset of it */
+    if (ip6_exthdrs_cnt > 1) {
+        p->ip6eh.fh_prev_hdr_offset = frag_hdr_offset - ip6_exthdrs[ip6_exthdrs_cnt - 1].len;
+    }
+
+    SCLogDebug("IPV6 FH: frag_hdr_offset %u, data_offset %u, data_len %u",
+            p->ip6eh.fh_header_offset, p->ip6eh.fh_data_offset,
+            p->ip6eh.fh_data_len);
+}
+
 static void
 DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
 {
@@ -429,46 +472,15 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
                 /* set the header flag first */
                 IPV6_EXTHDR_SET_FH(p);
 
-                uint16_t frag_offset = (*(pkt + 2) << 8 | *(pkt + 3)) & 0xFFF8;
-                int frag_morefrags   = (*(pkt + 2) << 8 | *(pkt + 3)) & 0x0001;
-
-                p->ip6eh.fh_offset = frag_offset;
-                p->ip6eh.fh_more_frags_set = frag_morefrags ? TRUE : FALSE;
-                p->ip6eh.fh_nh = *pkt;
-
-                uint32_t fh_id;
-                memcpy(&fh_id, pkt+4, 4);
-                p->ip6eh.fh_id = ntohl(fh_id);
-
-                SCLogDebug("IPV6 FH: offset %u, mf %s, nh %u, id %u/%x",
-                    p->ip6eh.fh_offset,
-                    p->ip6eh.fh_more_frags_set ? "true" : "false",
-                    p->ip6eh.fh_nh,
-                    p->ip6eh.fh_id, p->ip6eh.fh_id);
-
-                // store header offset, data offset
-                uint16_t frag_hdr_offset = (uint16_t)(pkt - GET_PKT_DATA(p));
-                uint16_t data_offset = (uint16_t)(frag_hdr_offset + hdrextlen);
-                uint16_t data_len = plen - hdrextlen;
-
-                p->ip6eh.fh_header_offset = frag_hdr_offset;
-                p->ip6eh.fh_data_offset = data_offset;
-                p->ip6eh.fh_data_len = data_len;
-
-                /* if we have a prev hdr, store the type and offset of it */
-                if (ip6_exthdrs_cnt > 1) {
-                    p->ip6eh.fh_prev_hdr_offset = frag_hdr_offset - ip6_exthdrs[ip6_exthdrs_cnt - 1].len;
-                }
-
-                SCLogDebug("IPV6 FH: frag_hdr_offset %u, data_offset %u, data_len %u",
-                    p->ip6eh.fh_header_offset, p->ip6eh.fh_data_offset,
-                    p->ip6eh.fh_data_len);
+                /* parse the header and setup the vars */
+                DecodeIPV6FragHeader(p, pkt, hdrextlen, plen,
+                        ip6_exthdrs_cnt, ip6_exthdrs);
 
                 /* if FH has offset 0 and no more fragments are coming, we
                  * parse this packet further right away, no defrag will be
                  * needed. It is a useless FH then though, so we do set an
                  * decoder event. */
-                if (frag_morefrags == 0 && frag_offset == 0) {
+                if (p->ip6eh.fh_more_frags_set == 0 && p->ip6eh.fh_offset == 0) {
                     ENGINE_SET_EVENT(p, IPV6_EXTHDR_USELESS_FH);
 
                     nh = *pkt;
index 488f9113ea930ec0cdeaa1a87e99a68ad7a52e65..fd89a757f57495c7686931301ad9a32cd9c68342 100644 (file)
@@ -1071,6 +1071,10 @@ error:
     return NULL;
 }
 
+void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt,
+                          uint16_t hdrextlen, uint16_t plen,
+                          uint16_t ip6_exthdrs_cnt, IPV6GenOptHdr *ip6_exthdrs);
+
 static Packet *
 IPV6BuildTestPacket(uint32_t id, uint16_t off, int mf, const char content,
     int content_len)
@@ -1111,6 +1115,8 @@ IPV6BuildTestPacket(uint32_t id, uint16_t off, int mf, const char content,
     fh->ip6fh_ident = htonl(id);
     fh->ip6fh_offlg = htons((off << 3) | mf);
 
+    DecodeIPV6FragHeader(p, (uint8_t *)fh, 8, 8 + content_len, 0, NULL);
+
     pcontent = SCCalloc(1, content_len);
     if (unlikely(pcontent == NULL))
         return NULL;