if (frag->offset + frag->data_len > fragmentable_len)
fragmentable_len = frag->offset + frag->data_len;
}
+
+ if (!frag->more_frags) {
+ break;
+ }
}
SCLogDebug("ip_hdr_offset %u, hlen %u, fragmentable_len %u",
if (frag->offset + frag->data_len > fragmentable_len)
fragmentable_len = frag->offset + frag->data_len;
}
+
+ if (!frag->more_frags) {
+ break;
+ }
}
rp->ip6h = (IPV6Hdr *)(GET_PKT_DATA(rp) + ip_hdr_offset);
new->data_len = data_len - ltrim;
new->ip_hdr_offset = ip_hdr_offset;
new->frag_hdr_offset = frag_hdr_offset;
+ new->more_frags = more_frags;
#ifdef DEBUG
new->pcap_cnt = pcap_cnt;
#endif
return ret;
}
+/**
+ * IPV4: Test the case where you have a packet fragmented in 3 parts
+ * and send like:
+ * - Offset: 2; MF: 1
+ * - Offset: 0; MF: 1
+ * - Offset: 1; MF: 0
+ *
+ * Only the fragments with offset 0 and 1 should be reassembled.
+ */
+static int DefragMfIpv4Test(void)
+{
+ int retval = 0;
+ int ip_id = 9;
+
+ DefragInit();
+
+ Packet *p1 = BuildTestPacket(ip_id, 2, 1, 'C', 8);
+ Packet *p2 = BuildTestPacket(ip_id, 0, 1, 'A', 8);
+ Packet *p3 = BuildTestPacket(ip_id, 1, 0, 'B', 8);
+ if (p1 == NULL || p2 == NULL || p3 == NULL) {
+ goto end;
+ }
+
+ Packet *p = Defrag(NULL, NULL, p1, NULL);
+ if (p != NULL) {
+ goto end;
+ }
+
+ p = Defrag(NULL, NULL, p2, NULL);
+ if (p != NULL) {
+ goto end;
+ }
+
+ /* This should return a packet as MF=0. */
+ p = Defrag(NULL, NULL, p3, NULL);
+ if (p == NULL) {
+ goto end;
+ }
+
+ /* Expected IP length is 20 + 8 + 8 = 36 as only 2 of the
+ * fragments should be in the re-assembled packet. */
+ if (IPV4_GET_IPLEN(p) != 36) {
+ goto end;
+ }
+
+ retval = 1;
+end:
+ if (p1 != NULL) {
+ SCFree(p1);
+ }
+ if (p2 != NULL) {
+ SCFree(p2);
+ }
+ if (p3 != NULL) {
+ SCFree(p3);
+ }
+ if (p != NULL) {
+ SCFree(p);
+ }
+ DefragDestroy();
+ return retval;
+}
+
+/**
+ * IPV6: Test the case where you have a packet fragmented in 3 parts
+ * and send like:
+ * - Offset: 2; MF: 1
+ * - Offset: 0; MF: 1
+ * - Offset: 1; MF: 0
+ *
+ * Only the fragments with offset 0 and 1 should be reassembled.
+ */
+static int DefragMfIpv6Test(void)
+{
+ int retval = 0;
+ int ip_id = 9;
+
+ DefragInit();
+
+ Packet *p1 = IPV6BuildTestPacket(ip_id, 2, 1, 'C', 8);
+ Packet *p2 = IPV6BuildTestPacket(ip_id, 0, 1, 'A', 8);
+ Packet *p3 = IPV6BuildTestPacket(ip_id, 1, 0, 'B', 8);
+ if (p1 == NULL || p2 == NULL || p3 == NULL) {
+ goto end;
+ }
+
+ Packet *p = Defrag(NULL, NULL, p1, NULL);
+ if (p != NULL) {
+ goto end;
+ }
+
+ p = Defrag(NULL, NULL, p2, NULL);
+ if (p != NULL) {
+ goto end;
+ }
+
+ /* This should return a packet as MF=0. */
+ p = Defrag(NULL, NULL, p3, NULL);
+ if (p == NULL) {
+ goto end;
+ }
+
+ /* For IPv6 the expected length is just the length of the payload
+ * of 2 fragments, so 16. */
+ if (IPV6_GET_PLEN(p) != 16) {
+ goto end;
+ }
+
+ retval = 1;
+end:
+ if (p1 != NULL) {
+ SCFree(p1);
+ }
+ if (p2 != NULL) {
+ SCFree(p2);
+ }
+ if (p3 != NULL) {
+ SCFree(p3);
+ }
+ if (p != NULL) {
+ SCFree(p);
+ }
+ DefragDestroy();
+ return retval;
+}
+
#endif /* UNITTESTS */
void
UtRegisterTest("DefragVlanTest", DefragVlanTest, 1);
UtRegisterTest("DefragVlanQinQTest", DefragVlanQinQTest, 1);
-
UtRegisterTest("DefragTrackerReuseTest", DefragTrackerReuseTest, 1);
-
UtRegisterTest("DefragTimeoutTest",
DefragTimeoutTest, 1);
+ UtRegisterTest("DefragMfIpv4Test", DefragMfIpv4Test, 1);
+ UtRegisterTest("DefragMfIpv6Test", DefragMfIpv6Test, 1);
#endif /* UNITTESTS */
}