63 #define DEFAULT_DEFRAG_HASH_SIZE 0xffff
64 #define DEFAULT_DEFRAG_POOL_SIZE 0xffff
70 #define TIMEOUT_DEFAULT 60
75 #define TIMEOUT_MAX (60 * 60 * 24)
107 DefragFragReset(
Frag *frag)
109 if (frag->
pkt != NULL)
111 memset(frag, 0,
sizeof(*frag));
127 DefragFragReset(frag);
141 DefragContextNew(
void)
150 intmax_t tracker_pool_size;
151 if (!
SCConfGetInt(
"defrag.trackers", &tracker_pool_size) || tracker_pool_size == 0) {
156 intmax_t frag_pool_size;
157 if (!
SCConfGetInt(
"defrag.max-frags", &frag_pool_size) || frag_pool_size == 0 ||
158 frag_pool_size > UINT32_MAX) {
161 uint32_t frag_pool_prealloc = (uint32_t)frag_pool_size / 2;
163 PoolInit((uint32_t)frag_pool_size, frag_pool_prealloc,
sizeof(
Frag), NULL, NULL, NULL);
165 FatalError(
"Defrag: Failed to initialize fragment pool.");
168 FatalError(
"Defrag: Failed to initialize frag pool mutex.");
177 FatalError(
"defrag: Timeout less than minimum allowed value.");
180 FatalError(
"defrag: Timeout greater than maximum allowed value.");
182 dc->
timeout = (uint32_t)timeout;
187 SCLogDebug(
"\tMaximum defrag trackers: %"PRIuMAX, tracker_pool_size);
188 SCLogDebug(
"\tPreallocated defrag trackers: %"PRIuMAX, tracker_pool_size);
189 SCLogDebug(
"\tMaximum fragments: %"PRIuMAX, (uintmax_t)frag_pool_size);
190 SCLogDebug(
"\tPreallocated fragments: %"PRIuMAX, (uintmax_t)frag_pool_prealloc);
224 }
else if (first->
offset != 0) {
229 goto error_remove_tracker;
248 const IPV4Hdr *oip4h = PacketGetIPv4(
p);
254 goto error_remove_tracker;
260 int fragmentable_offset = 0;
261 uint16_t fragmentable_len = 0;
263 int ip_hdr_offset = 0;
266 uint16_t prev_offset = 0;
270 SCLogDebug(
"frag %p, data_len %u, offset %u, pcap_cnt %"PRIu64,
275 if (!more_frags && frag->
offset > prev_offset) {
286 goto error_remove_tracker;
298 int pkt_end = fragmentable_offset + frag->
offset + frag->
data_len;
301 "fragmented packet, exceeds size of packet buffer.");
302 goto error_remove_tracker;
308 goto error_remove_tracker;
312 "fragmentable_len exceeds UINT16_MAX");
313 goto error_remove_tracker;
328 prev_offset = frag->
offset;
331 SCLogDebug(
"ip_hdr_offset %u, hlen %" PRIu16
", fragmentable_len %" PRIu16, ip_hdr_offset, hlen,
334 const uint32_t packet_len = (uint32_t)hlen + fragmentable_len;
337 goto error_remove_tracker;
342 ip4h->
ip_len = htons((uint16_t)packet_len);
352 error_remove_tracker:
378 }
else if (first->
offset != 0) {
383 goto error_remove_tracker;
413 const IPV6Hdr *oip6h = PacketGetIPv6(
p);
420 goto error_remove_tracker;
426 uint16_t unfragmentable_len = 0;
427 int fragmentable_offset = 0;
428 uint16_t fragmentable_len = 0;
429 int ip_hdr_offset = 0;
430 uint8_t next_hdr = 0;
433 uint16_t prev_offset = 0;
437 if (!more_frags && frag->
offset > prev_offset) {
445 IPV6FragHdr *frag_hdr = (IPV6FragHdr *)(frag->
pkt +
447 next_hdr = frag_hdr->ip6fh_nxt;
453 goto error_remove_tracker;
457 goto error_remove_tracker;
471 unfragmentable_len = (uint16_t)(fragmentable_offset - ip_hdr_offset -
IPV6_HEADER_LEN);
472 if (unfragmentable_len >= fragmentable_offset)
473 goto error_remove_tracker;
479 goto error_remove_tracker;
493 prev_offset = frag->
offset;
496 const uint32_t
payload_len = (uint32_t)unfragmentable_len + fragmentable_len;
499 goto error_remove_tracker;
508 if (unfragmentable_len == 0)
509 ip6h->s_ip6_nxt = next_hdr;
517 error_remove_tracker:
551 uint16_t frag_offset;
558 uint16_t data_offset;
568 uint16_t ip_hdr_offset;
571 uint16_t frag_hdr_offset = 0;
574 int af = tracker->
af;
578 uint32_t ip6_nh_set_offset = 0;
579 uint8_t ip6_nh_set_value = 0;
585 if (tracker->
af == AF_INET) {
586 const IPV4Hdr *ip4h = PacketGetIPv4(
p);
590 data_offset = (uint16_t)((uint8_t *)ip4h + hlen -
GET_PKT_DATA(
p));
592 ip_hdr_offset = (uint16_t)((uint8_t *)ip4h -
GET_PKT_DATA(
p));
601 frag_end = (uint16_t)(frag_offset + data_len);
603 else if (tracker->
af == AF_INET6) {
604 const IPV6Hdr *ip6h = PacketGetIPv6(
p);
607 data_offset =
p->
l3.
vars.
ip6.eh.fh_data_offset;
617 frag_end = (uint16_t)(frag_offset + data_len);
618 ip_hdr_offset = (uint16_t)((uint8_t *)ip6h -
GET_PKT_DATA(
p));
619 frag_hdr_offset =
p->
l3.
vars.
ip6.eh.fh_header_offset;
621 SCLogDebug(
"mf %s frag_offset %u data_offset %u, data_len %u, "
622 "frag_end %u, ip_hdr_offset %u, frag_hdr_offset %u",
623 more_frags ?
"true" :
"false", frag_offset, data_offset,
624 data_len, frag_end, ip_hdr_offset, frag_hdr_offset);
628 SCLogDebug(
"we have exthdrs before fraghdr %u bytes",
635 ip6_nh_set_offset =
p->
l3.
vars.
ip6.eh.fh_prev_hdr_offset;
637 SCLogDebug(
"offset %d, value %u", ip6_nh_set_offset, ip6_nh_set_value);
649 bool overlap =
false;
654 .
offset = frag_offset ? frag_offset - 1 : 0,
659 next = IP_FRAGMENTS_RB_NEXT(prev);
661 prev = IP_FRAGMENTS_RB_PREV(
next);
664 next = IP_FRAGMENTS_RB_NEXT(prev);
667 while (prev != NULL) {
675 switch (tracker->
policy) {
678 if (prev->
offset <= frag_offset) {
684 if (prev_end > frag_end) {
689 ltrim = prev_end - frag_offset;
691 if ((
next != NULL) && (frag_end >
next->offset)) {
692 next->ltrim = frag_end -
next->offset;
707 uint16_t prev_ltrim = frag_end - prev->
offset;
708 if (prev_ltrim > prev->
ltrim) {
709 prev->
ltrim = prev_ltrim;
713 if ((
next != NULL) && (frag_end >
next->offset)) {
714 next->ltrim = frag_end -
next->offset;
728 if (prev->
offset + prev->
ltrim < frag_offset + ltrim &&
741 if (frag_offset + ltrim < prev->
offset + prev->
ltrim &&
752 if (frag_offset + ltrim <= prev->
offset + prev->
ltrim &&
761 if (frag_offset + ltrim >= prev->
offset + ltrim &&
768 if (frag_offset + ltrim < prev->
offset + ltrim &&
781 if (frag_offset + ltrim > prev->
offset + prev->
ltrim &&
790 if (frag_offset + ltrim == prev->
offset + ltrim &&
798 if (frag_offset >= prev->
offset) {
801 if ((frag_offset < prev->
offset) &&
809 if ((frag_offset >= prev->
offset) &&
813 if (frag_offset < prev->
offset) {
822 if (frag_offset <= prev->
offset) {
823 if (frag_end > prev->
offset) {
846 DefragFragReset(prev);
855 if (ltrim >= data_len) {
871 if (
tv != NULL &&
dtv != NULL) {
874 goto error_remove_tracker;
877 if (new->pkt == NULL) {
886 goto error_remove_tracker;
893 if (ip6_nh_set_offset > 0 && frag_offset == 0 && ltrim == 0) {
894 if (new->len > ip6_nh_set_offset) {
895 SCLogDebug(
"updating frag to have 'correct' nh value: %u -> %u",
896 new->pkt[ip6_nh_set_offset], ip6_nh_set_value);
897 new->pkt[ip6_nh_set_offset] = ip6_nh_set_value;
902 new->offset = frag_offset + ltrim;
903 new->data_offset = data_offset;
904 new->data_len = data_len - ltrim;
905 new->frag_hdr_offset = frag_hdr_offset;
906 new->more_frags = more_frags;
908 new->pcap_cnt = pcap_cnt;
910 if (new->offset == 0) {
922 if (tracker->
af == AF_INET) {
923 r = Defrag4Reassemble(
tv, tracker,
p);
924 if (r != NULL &&
tv != NULL &&
dtv != NULL) {
928 else if (tracker->
af == AF_INET6) {
929 r = Defrag6Reassemble(
tv, tracker,
p);
930 if (r != NULL &&
tv != NULL &&
dtv != NULL) {
947 error_remove_tracker:
966 if (PacketIsIPv4(
p)) {
968 }
else if (PacketIsIPv6(
p)) {
973 return default_policy;
1016 return default_policy;
1042 uint16_t frag_offset;
1047 if (PacketIsIPv4(
p)) {
1048 const IPV4Hdr *ip4h = PacketGetIPv4(
p);
1052 }
else if (PacketIsIPv6(
p)) {
1060 if (frag_offset == 0 && more_frags == 0) {
1064 if (
af == AF_INET) {
1066 }
else if (
af == AF_INET6) {
1071 tracker = DefragGetTracker(
tv,
dtv,
p);
1072 if (tracker == NULL) {
1073 if (
tv != NULL &&
dtv != NULL) {
1084 int tracker_af = tracker->
af;
1093 const uint32_t
len =
GET_PKT_LEN(rp) - (uint32_t)tracker_ip_hdr_offset;
1095 if (tracker_af == AF_INET) {
1117 intmax_t tracker_pool_size;
1118 if (!
SCConfGetInt(
"defrag.trackers", &tracker_pool_size)) {
1126 defrag_context = DefragContextNew();
1127 if (defrag_context == NULL) {
1128 FatalError(
"Failed to allocate memory for the Defrag module.");
1138 DefragContextDestroy(defrag_context);
1139 defrag_context = NULL;
1147 #define IP_MF 0x2000
1156 static Packet *BuildIpv4TestPacket(
1157 uint8_t
proto, uint16_t
id, uint16_t off,
int mf,
const char content,
int content_len)
1174 struct timeval tval;
1175 gettimeofday(&tval, NULL);
1180 ip4h.
ip_len = htons(hlen + content_len);
1181 ip4h.
ip_id = htons(
id);
1185 ip4h.
ip_off = htons(off);
1189 ip4h.s_ip_src.s_addr = 0x01010101;
1190 ip4h.s_ip_dst.s_addr = 0x02020202;
1198 pcontent =
SCCalloc(1, content_len);
1201 memset(pcontent, content, content_len);
1225 static int BuildIpv4TestPacketWithContent(
Packet **packet, uint8_t
proto, uint16_t
id, uint16_t off,
1226 int mf,
const uint8_t *content,
int content_len)
1238 struct timeval tval;
1239 gettimeofday(&tval, NULL);
1243 ip4h.
ip_len = htons(hlen + content_len);
1244 ip4h.
ip_id = htons(
id);
1248 ip4h.
ip_off = htons(off);
1252 ip4h.s_ip_src.s_addr = 0x01010101;
1253 ip4h.s_ip_dst.s_addr = 0x02020202;
1280 static Packet *BuildIpv6TestPacket(
1281 uint8_t
proto, uint32_t
id, uint16_t off,
int mf,
const uint8_t content,
int content_len)
1296 struct timeval tval;
1297 gettimeofday(&tval, NULL);
1300 ip6h.s_ip6_nxt = 44;
1301 ip6h.s_ip6_hlim = 2;
1304 ip6h.s_ip6_src[0] = 0x01010101;
1305 ip6h.s_ip6_src[1] = 0x01010101;
1306 ip6h.s_ip6_src[2] = 0x01010101;
1307 ip6h.s_ip6_src[3] = 0x01010101;
1308 ip6h.s_ip6_dst[0] = 0x02020202;
1309 ip6h.s_ip6_dst[1] = 0x02020202;
1310 ip6h.s_ip6_dst[2] = 0x02020202;
1311 ip6h.s_ip6_dst[3] = 0x02020202;
1320 fh->ip6fh_nxt =
proto;
1321 fh->ip6fh_ident = htonl(
id);
1322 fh->ip6fh_offlg = htons((off << 3) | mf);
1326 pcontent =
SCCalloc(1, content_len);
1329 memset(pcontent, content, content_len);
1334 ip6p->s_ip6_plen = htons(
sizeof(IPV6FragHdr) + content_len);
1354 static Packet *BuildIpv6TestPacketWithContent(
1355 uint8_t
proto, uint32_t
id, uint16_t off,
int mf,
const uint8_t *content,
int content_len)
1369 struct timeval tval;
1370 gettimeofday(&tval, NULL);
1373 ip6h.s_ip6_nxt = 44;
1374 ip6h.s_ip6_hlim = 2;
1377 ip6h.s_ip6_src[0] = 0x01010101;
1378 ip6h.s_ip6_src[1] = 0x01010101;
1379 ip6h.s_ip6_src[2] = 0x01010101;
1380 ip6h.s_ip6_src[3] = 0x01010101;
1381 ip6h.s_ip6_dst[0] = 0x02020202;
1382 ip6h.s_ip6_dst[1] = 0x02020202;
1383 ip6h.s_ip6_dst[2] = 0x02020202;
1384 ip6h.s_ip6_dst[3] = 0x02020202;
1393 fh->ip6fh_nxt =
proto;
1394 fh->ip6fh_ident = htonl(
id);
1395 fh->ip6fh_offlg = htons((off << 3) | mf);
1402 ip6p->s_ip6_plen = htons(
sizeof(IPV6FragHdr) + content_len);
1426 static int DefragInOrderSimpleTest(
void)
1428 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1429 Packet *reassembled = NULL;
1434 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1436 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1438 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1451 for (
int i = 20; i < 20 + 8; i++) {
1456 for (
int i = 28; i < 28 + 8; i++) {
1461 for (
int i = 36; i < 36 + 3; i++) {
1477 static int DefragReverseSimpleTest(
void)
1479 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1480 Packet *reassembled = NULL;
1485 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1487 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1489 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1501 for (
int i = 20; i < 20 + 8; i++) {
1506 for (
int i = 28; i < 28 + 8; i++) {
1511 for (
int i = 36; i < 36 + 3; i++) {
1528 static int DefragInOrderSimpleIpv6Test(
void)
1530 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1531 Packet *reassembled = NULL;
1536 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1538 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1540 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1548 const IPV6Hdr *ip6h = PacketGetIPv6(reassembled);
1552 for (
int i = 40; i < 40 + 8; i++) {
1557 for (
int i = 48; i < 48 + 8; i++) {
1562 for (
int i = 56; i < 56 + 3; i++) {
1575 static int DefragReverseSimpleIpv6Test(
void)
1578 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1579 Packet *reassembled = NULL;
1584 dc = DefragContextNew();
1587 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1589 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1591 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1600 for (
int i = 40; i < 40 + 8; i++) {
1605 for (
int i = 48; i < 48 + 8; i++) {
1610 for (
int i = 56; i < 56 + 3; i++) {
1614 DefragContextDestroy(dc);
1624 static int DefragDoSturgesNovakTest(
int policy, uint8_t *expected,
size_t expected_len)
1636 memset(packets, 0x00,
sizeof(packets));
1643 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
1646 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 32 >> 3, 1,
'B', 16);
1649 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'C', 24);
1652 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 80 >> 3, 1,
'D', 8);
1655 packets[4] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 104 >> 3, 1,
'E', 16);
1658 packets[5] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 120 >> 3, 1,
'F', 24);
1661 packets[6] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 144 >> 3, 1,
'G', 16);
1664 packets[7] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'H', 16);
1667 packets[8] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 1,
'I', 8);
1674 packets[9] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 8 >> 3, 1,
'J', 32);
1677 packets[10] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'K', 24);
1680 packets[11] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 72 >> 3, 1,
'L', 24);
1683 packets[12] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 96 >> 3, 1,
'M', 24);
1686 packets[13] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 128 >> 3, 1,
'N', 8);
1689 packets[14] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 152 >> 3, 1,
'O', 8);
1692 packets[15] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'P', 8);
1695 packets[16] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 0,
'Q', 16);
1697 default_policy = policy;
1700 for (i = 0; i < 9; i++) {
1706 for (; i < 16; i++) {
1723 if (memcmp(expected,
GET_PKT_DATA(reassembled) + 20, expected_len) != 0) {
1724 printf(
"Expected:\n");
1735 for (i = 0; i < 17; i++) {
1742 static int DefragDoSturgesNovakIpv6Test(
int policy, uint8_t *expected,
size_t expected_len)
1754 memset(packets, 0x00,
sizeof(packets));
1761 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 24);
1764 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 32 >> 3, 1,
'B', 16);
1767 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'C', 24);
1770 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 80 >> 3, 1,
'D', 8);
1773 packets[4] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 104 >> 3, 1,
'E', 16);
1776 packets[5] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 120 >> 3, 1,
'F', 24);
1779 packets[6] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 144 >> 3, 1,
'G', 16);
1782 packets[7] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'H', 16);
1785 packets[8] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 1,
'I', 8);
1792 packets[9] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 8 >> 3, 1,
'J', 32);
1795 packets[10] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'K', 24);
1798 packets[11] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 72 >> 3, 1,
'L', 24);
1801 packets[12] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 96 >> 3, 1,
'M', 24);
1804 packets[13] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 128 >> 3, 1,
'N', 8);
1807 packets[14] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 152 >> 3, 1,
'O', 8);
1810 packets[15] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'P', 8);
1813 packets[16] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 0,
'Q', 16);
1815 default_policy = policy;
1818 for (i = 0; i < 9; i++) {
1824 for (; i < 16; i++) {
1845 for (i = 0; i < 17; i++) {
1860 #define D_1 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'
1861 #define D_2 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'
1862 #define D_3 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'
1863 #define D_3_1 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D'
1864 #define D_3_2 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'
1865 #define D_3_3 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'
1866 #define D_3_4 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'
1867 #define D_3_5 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H'
1868 #define D_3_6 'I', 'I', 'I', 'I', 'I', 'I', 'I', 'I'
1869 #define D_4 'J', 'J', 'J', 'J', 'J', 'J', 'J', 'J'
1870 #define D_5 'K', 'K', 'K', 'K', 'K', 'K', 'K', 'K'
1871 #define D_6 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'
1872 #define D_7 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M'
1873 #define D_8 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'
1874 #define D_9 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O'
1875 #define D_10 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'
1876 #define D_11 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q'
1879 DefragSturgesNovakBsdTest(
void)
1882 uint8_t expected[] = {
1914 static int DefragSturgesNovakBsdIpv6Test(
void)
1917 uint8_t expected[] = {
1948 static int DefragSturgesNovakLinuxIpv4Test(
void)
1951 uint8_t expected[] = {
1983 static int DefragSturgesNovakLinuxIpv6Test(
void)
1986 uint8_t expected[] = {
2017 static int DefragSturgesNovakWindowsIpv4Test(
void)
2020 uint8_t expected[] = {
2052 static int DefragSturgesNovakWindowsIpv6Test(
void)
2055 uint8_t expected[] = {
2086 static int DefragSturgesNovakSolarisTest(
void)
2089 uint8_t expected[] = {
2121 static int DefragSturgesNovakSolarisIpv6Test(
void)
2124 uint8_t expected[] = {
2155 static int DefragSturgesNovakFirstTest(
void)
2158 uint8_t expected[] = {
2190 static int DefragSturgesNovakFirstIpv6Test(
void)
2193 uint8_t expected[] = {
2224 DefragSturgesNovakLastTest(
void)
2227 uint8_t expected[] = {
2259 static int DefragSturgesNovakLastIpv6Test(
void)
2262 uint8_t expected[] = {
2293 static int DefragTimeoutTest(
void)
2303 for (i = 0; i < 16; i++) {
2304 Packet *
p = BuildIpv4TestPacket(IPPROTO_ICMP, i, 0, 1,
'A' + i, 16);
2314 Packet *
p = BuildIpv4TestPacket(IPPROTO_ICMP, 99, 0, 1,
'A' + i, 16);
2339 static int DefragNoDataIpv4Test(
void)
2347 dc = DefragContextNew();
2351 p = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 0,
'A', 0);
2361 DefragContextDestroy(dc);
2368 static int DefragTooLargeIpv4Test(
void)
2375 dc = DefragContextNew();
2380 p = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8183, 0,
'A', 71);
2393 DefragContextDestroy(dc);
2405 static int DefragVlanTest(
void)
2407 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2411 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2413 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2437 static int DefragVlanQinQTest(
void)
2439 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2443 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2445 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2471 static int DefragVlanQinQinQTest(
void)
2477 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2479 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2503 static int DefragTrackerReuseTest(
void)
2513 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 0,
'A', 8);
2526 FAIL_IF(tracker2 != tracker1);
2539 FAIL_IF(tracker2 != tracker1);
2556 static int DefragMfIpv4Test(
void)
2563 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 2, 1,
'C', 8);
2564 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 0, 1,
'A', 8);
2565 Packet *p3 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 1, 0,
'B', 8);
2566 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2583 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2603 static int DefragMfIpv6Test(
void)
2610 Packet *p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 2, 1,
'C', 8);
2611 Packet *p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 0, 1,
'A', 8);
2612 Packet *p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 1, 0,
'B', 8);
2613 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2630 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2645 static int DefragTestBadProto(
void)
2647 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
2652 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
2654 p2 = BuildIpv4TestPacket(IPPROTO_UDP,
id, 1, 1,
'B', 8);
2656 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
2675 static int DefragTestJeremyLinux(
void)
2678 uint8_t expected[] =
"AAAAAAAA"
2699 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
2700 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 40 >> 3, 1,
'B', 48);
2701 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 24 >> 3, 1,
'C', 48);
2702 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 88 >> 3, 0,
'D', 14);
2718 for (i = 0; i < 4; i++) {
2737 static int DefragBsdFragmentAfterNoMfIpv4Test(
void)
2743 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2744 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2745 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2746 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2761 uint8_t expected[] = {
2762 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2763 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2764 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2765 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2766 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2770 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
2771 printf(
"Expected:\n");
2778 for (
int i = 0; i < 4; i++) {
2786 static int DefragBsdFragmentAfterNoMfIpv6Test(
void)
2792 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2793 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2794 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2795 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2810 uint8_t expected[] = {
2811 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2812 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2813 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2814 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2815 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2819 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
2820 printf(
"Expected:\n");
2827 for (
int i = 0; i < 4; i++) {
2835 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2(
void)
2843 &packets[0], IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
2847 &packets[1], IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16));
2851 &packets[2], IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
2855 &packets[3], IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
2870 const uint8_t expected[] = {
2875 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2876 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2877 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2878 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2884 for (
int i = 0; i < 4; i++) {
2892 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2(
void)
2899 packets[0] = BuildIpv6TestPacketWithContent(
2900 IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
2903 packets[1] = BuildIpv6TestPacketWithContent(
2904 IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16);
2907 packets[2] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
2911 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
2926 const uint8_t expected[] = {
2931 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2932 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2933 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2934 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2940 for (
int i = 0; i < 4; i++) {
2960 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test(
void)
2966 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
2967 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
2976 const uint8_t expected[] = {
2977 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
2978 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
2979 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
2980 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
2984 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
2985 printf(
"Expected:\n");
2992 for (
int i = 0; i < 2; i++) {
3000 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test(
void)
3006 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
3007 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
3016 const uint8_t expected[] = {
3017 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3018 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3019 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3020 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
3024 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
3025 printf(
"Expected:\n");
3032 for (
int i = 0; i < 2; i++) {
3051 static int DefragBsdMissingFragmentIpv4Test(
void)
3058 &packets[0], IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
3061 &packets[1], IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8));
3064 &packets[2], IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16));
3068 &packets[3], IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
3071 &packets[4], IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
3092 for (
int i = 0; i < 5; i++) {
3099 static int DefragBsdMissingFragmentIpv6Test(
void)
3105 packets[0] = BuildIpv6TestPacketWithContent(
3106 IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
3109 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8);
3111 packets[2] = BuildIpv6TestPacketWithContent(
3112 IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16);
3115 packets[3] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
3118 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
3139 for (
int i = 0; i < 5; i++) {
3151 static int DefragOutOfOrderFirstFragmentTest(
void)
3153 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
3154 Packet *reassembled = NULL;
3161 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 24 >> 3, 0,
'D', 8);
3163 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 8 >> 3, 1,
'B', 8);
3165 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 16 >> 3, 1,
'C', 8);
3167 p4 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
3180 for (
int i = 20 + 0; i < 20 + 8; i++)
3182 for (
int i = 20 + 8; i < 20 + 16; i++)
3184 for (
int i = 20 + 16; i < 20 + 24; i++)
3186 for (
int i = 20 + 24; i < 20 + 32; i++)
3205 static int DefragSameOffsetPrecedingOverlapTest(
void)
3207 Packet *packets[5] = { NULL };
3208 Packet *reassembled = NULL;
3217 &packets[0], IPPROTO_ICMP,
id, 8 >> 3, 1, (uint8_t *)
"BBBBBBBBBBBBBBBB", 16));
3220 &packets[1], IPPROTO_ICMP,
id, 0, 1, (uint8_t *)
"AAAAAAAAAAAAAAAA", 16));
3223 &packets[2], IPPROTO_ICMP,
id, 24 >> 3, 1, (uint8_t *)
"CCCCCCCC", 8));
3226 &packets[3], IPPROTO_ICMP,
id, 8 >> 3, 1, (uint8_t *)
"DDDDDDDDDDDDDDDD", 16));
3229 &packets[4], IPPROTO_ICMP,
id, 32 >> 3, 0, (uint8_t *)
"EEEEEEEE", 8));
3231 for (
int i = 0; i < 4; i++)
3239 const uint8_t expected[] = {
3240 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
3241 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
3242 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
3243 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
3244 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
3249 for (
int i = 0; i < 5; i++)
3262 UtRegisterTest(
"DefragInOrderSimpleTest", DefragInOrderSimpleTest);
3263 UtRegisterTest(
"DefragReverseSimpleTest", DefragReverseSimpleTest);
3264 UtRegisterTest(
"DefragSturgesNovakBsdTest", DefragSturgesNovakBsdTest);
3266 DefragSturgesNovakLinuxIpv4Test);
3268 DefragSturgesNovakWindowsIpv4Test);
3270 DefragSturgesNovakSolarisTest);
3271 UtRegisterTest(
"DefragSturgesNovakFirstTest", DefragSturgesNovakFirstTest);
3272 UtRegisterTest(
"DefragSturgesNovakLastTest", DefragSturgesNovakLastTest);
3275 UtRegisterTest(
"DefragTooLargeIpv4Test", DefragTooLargeIpv4Test);
3277 UtRegisterTest(
"DefragInOrderSimpleIpv6Test", DefragInOrderSimpleIpv6Test);
3278 UtRegisterTest(
"DefragReverseSimpleIpv6Test", DefragReverseSimpleIpv6Test);
3279 UtRegisterTest(
"DefragSturgesNovakBsdIpv6Test", DefragSturgesNovakBsdIpv6Test);
3280 UtRegisterTest(
"DefragSturgesNovakLinuxIpv6Test", DefragSturgesNovakLinuxIpv6Test);
3281 UtRegisterTest(
"DefragSturgesNovakWindowsIpv6Test", DefragSturgesNovakWindowsIpv6Test);
3282 UtRegisterTest(
"DefragSturgesNovakSolarisIpv6Test", DefragSturgesNovakSolarisIpv6Test);
3283 UtRegisterTest(
"DefragSturgesNovakFirstIpv6Test", DefragSturgesNovakFirstIpv6Test);
3284 UtRegisterTest(
"DefragSturgesNovakLastIpv6Test", DefragSturgesNovakLastIpv6Test);
3289 UtRegisterTest(
"DefragTrackerReuseTest", DefragTrackerReuseTest);
3297 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv4Test", DefragBsdFragmentAfterNoMfIpv4Test);
3298 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv6Test", DefragBsdFragmentAfterNoMfIpv6Test);
3299 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test",
3300 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test);
3301 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test",
3302 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test);
3303 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2",
3304 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2);
3305 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2",
3306 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2);
3307 UtRegisterTest(
"DefragBsdMissingFragmentIpv4Test", DefragBsdMissingFragmentIpv4Test);
3308 UtRegisterTest(
"DefragBsdMissingFragmentIpv6Test", DefragBsdMissingFragmentIpv6Test);
3309 UtRegisterTest(
"DefragOutOfOrderFirstFragmentTest", DefragOutOfOrderFirstFragmentTest);
3310 UtRegisterTest(
"DefragSameOffsetPrecedingOverlapTest", DefragSameOffsetPrecedingOverlapTest);