65 #define DEFAULT_DEFRAG_HASH_SIZE 0xffff
66 #define DEFAULT_DEFRAG_POOL_SIZE 0xffff
72 #define TIMEOUT_DEFAULT 60
77 #define TIMEOUT_MAX (60 * 60 * 24)
109 DefragFragReset(
Frag *frag)
111 if (frag->
pkt != NULL)
113 memset(frag, 0,
sizeof(*frag));
120 DefragFragInit(
void *data,
void *initdata)
124 memset(frag, 0,
sizeof(*frag));
141 DefragFragReset(frag);
155 DefragContextNew(
void)
164 intmax_t tracker_pool_size;
165 if (!
SCConfGetInt(
"defrag.trackers", &tracker_pool_size) || tracker_pool_size == 0) {
170 intmax_t frag_pool_size;
171 if (!
SCConfGetInt(
"defrag.max-frags", &frag_pool_size) || frag_pool_size == 0 ||
172 frag_pool_size > UINT32_MAX) {
175 uint32_t frag_pool_prealloc = (uint32_t)frag_pool_size / 2;
177 DefragFragInit, dc, NULL, NULL);
179 FatalError(
"Defrag: Failed to initialize fragment pool.");
182 FatalError(
"Defrag: Failed to initialize frag pool mutex.");
191 FatalError(
"defrag: Timeout less than minimum allowed value.");
194 FatalError(
"defrag: Timeout greater than maximum allowed value.");
196 dc->
timeout = (uint32_t)timeout;
201 SCLogDebug(
"\tMaximum defrag trackers: %"PRIuMAX, tracker_pool_size);
202 SCLogDebug(
"\tPreallocated defrag trackers: %"PRIuMAX, tracker_pool_size);
203 SCLogDebug(
"\tMaximum fragments: %"PRIuMAX, (uintmax_t)frag_pool_size);
204 SCLogDebug(
"\tPreallocated fragments: %"PRIuMAX, (uintmax_t)frag_pool_prealloc);
238 }
else if (first->
offset != 0) {
243 goto error_remove_tracker;
262 const IPV4Hdr *oip4h = PacketGetIPv4(p);
268 goto error_remove_tracker;
274 int fragmentable_offset = 0;
275 uint16_t fragmentable_len = 0;
277 int ip_hdr_offset = 0;
280 uint16_t prev_offset = 0;
284 SCLogDebug(
"frag %p, data_len %u, offset %u, pcap_cnt %"PRIu64,
289 if (!more_frags && frag->
offset > prev_offset) {
300 goto error_remove_tracker;
312 int pkt_end = fragmentable_offset + frag->
offset + frag->
data_len;
315 "fragmented packet, exceeds size of packet buffer.");
316 goto error_remove_tracker;
322 goto error_remove_tracker;
326 "fragmentable_len exceeds UINT16_MAX");
327 goto error_remove_tracker;
342 prev_offset = frag->
offset;
345 SCLogDebug(
"ip_hdr_offset %u, hlen %" PRIu16
", fragmentable_len %" PRIu16, ip_hdr_offset, hlen,
351 ip4h->
ip_len = htons(fragmentable_len + hlen);
354 SET_PKT_LEN(rp, ip_hdr_offset + hlen + fragmentable_len);
361 error_remove_tracker:
387 }
else if (first->
offset != 0) {
392 goto error_remove_tracker;
422 const IPV6Hdr *oip6h = PacketGetIPv6(p);
429 goto error_remove_tracker;
435 uint16_t unfragmentable_len = 0;
436 int fragmentable_offset = 0;
437 uint16_t fragmentable_len = 0;
438 int ip_hdr_offset = 0;
439 uint8_t next_hdr = 0;
442 uint16_t prev_offset = 0;
446 if (!more_frags && frag->
offset > prev_offset) {
454 IPV6FragHdr *frag_hdr = (IPV6FragHdr *)(frag->
pkt +
456 next_hdr = frag_hdr->ip6fh_nxt;
462 goto error_remove_tracker;
466 goto error_remove_tracker;
480 unfragmentable_len = (uint16_t)(fragmentable_offset - ip_hdr_offset -
IPV6_HEADER_LEN);
481 if (unfragmentable_len >= fragmentable_offset)
482 goto error_remove_tracker;
488 goto error_remove_tracker;
502 prev_offset = frag->
offset;
507 ip6h->s_ip6_plen = htons(fragmentable_len + unfragmentable_len);
512 if (unfragmentable_len == 0)
513 ip6h->s_ip6_nxt = next_hdr;
515 unfragmentable_len + fragmentable_len);
522 error_remove_tracker:
556 uint16_t frag_offset;
563 uint16_t data_offset;
573 uint16_t ip_hdr_offset;
576 uint16_t frag_hdr_offset = 0;
579 int af = tracker->
af;
583 uint32_t ip6_nh_set_offset = 0;
584 uint8_t ip6_nh_set_value = 0;
590 if (tracker->
af == AF_INET) {
591 const IPV4Hdr *ip4h = PacketGetIPv4(p);
595 data_offset = (uint16_t)((uint8_t *)ip4h + hlen -
GET_PKT_DATA(p));
597 frag_end = frag_offset + data_len;
598 ip_hdr_offset = (uint16_t)((uint8_t *)ip4h -
GET_PKT_DATA(p));
607 else if (tracker->
af == AF_INET6) {
608 const IPV6Hdr *ip6h = PacketGetIPv6(p);
611 data_offset = p->
l3.
vars.
ip6.eh.fh_data_offset;
612 data_len = p->
l3.
vars.
ip6.eh.fh_data_len;
613 frag_end = frag_offset + data_len;
614 ip_hdr_offset = (uint16_t)((uint8_t *)ip6h -
GET_PKT_DATA(p));
615 frag_hdr_offset = p->
l3.
vars.
ip6.eh.fh_header_offset;
617 SCLogDebug(
"mf %s frag_offset %u data_offset %u, data_len %u, "
618 "frag_end %u, ip_hdr_offset %u, frag_hdr_offset %u",
619 more_frags ?
"true" :
"false", frag_offset, data_offset,
620 data_len, frag_end, ip_hdr_offset, frag_hdr_offset);
624 SCLogDebug(
"we have exthdrs before fraghdr %u bytes",
631 ip6_nh_set_offset = p->
l3.
vars.
ip6.eh.fh_prev_hdr_offset;
633 SCLogDebug(
"offset %d, value %u", ip6_nh_set_offset, ip6_nh_set_value);
652 bool overlap =
false;
657 .
offset = frag_offset - 1,
662 next = IP_FRAGMENTS_RB_NEXT(prev);
664 prev = IP_FRAGMENTS_RB_PREV(
next);
667 next = IP_FRAGMENTS_RB_NEXT(prev);
670 while (prev != NULL) {
678 switch (tracker->
policy) {
681 if (prev->
offset <= frag_offset) {
687 if (prev_end > frag_end) {
692 ltrim = prev_end - frag_offset;
694 if ((
next != NULL) && (frag_end >
next->offset)) {
695 next->ltrim = frag_end -
next->offset;
710 uint16_t prev_ltrim = frag_end - prev->
offset;
711 if (prev_ltrim > prev->
ltrim) {
712 prev->
ltrim = prev_ltrim;
716 if ((
next != NULL) && (frag_end >
next->offset)) {
717 next->ltrim = frag_end -
next->offset;
731 if (prev->
offset + prev->
ltrim < frag_offset + ltrim &&
744 if (frag_offset + ltrim < prev->
offset + prev->
ltrim &&
755 if (frag_offset + ltrim <= prev->
offset + prev->
ltrim &&
764 if (frag_offset + ltrim >= prev->
offset + ltrim &&
771 if (frag_offset + ltrim < prev->
offset + ltrim &&
784 if (frag_offset + ltrim > prev->
offset + prev->
ltrim &&
793 if (frag_offset + ltrim == prev->
offset + ltrim &&
801 if (frag_offset >= prev->
offset) {
804 if ((frag_offset < prev->
offset) &&
812 if ((frag_offset >= prev->
offset) &&
816 if (frag_offset < prev->
offset) {
825 if (frag_offset <= prev->
offset) {
826 if (frag_end > prev->
offset) {
849 DefragFragReset(prev);
858 if (ltrim >= data_len) {
874 if (
tv != NULL &&
dtv != NULL) {
877 goto error_remove_tracker;
880 if (new->pkt == NULL) {
889 goto error_remove_tracker;
896 if (ip6_nh_set_offset > 0 && frag_offset == 0 && ltrim == 0) {
897 if (new->len > ip6_nh_set_offset) {
898 SCLogDebug(
"updating frag to have 'correct' nh value: %u -> %u",
899 new->pkt[ip6_nh_set_offset], ip6_nh_set_value);
900 new->pkt[ip6_nh_set_offset] = ip6_nh_set_value;
905 new->offset = frag_offset + ltrim;
906 new->data_offset = data_offset;
907 new->data_len = data_len - ltrim;
908 new->frag_hdr_offset = frag_hdr_offset;
909 new->more_frags = more_frags;
911 new->pcap_cnt = pcap_cnt;
913 if (new->offset == 0) {
925 if (tracker->
af == AF_INET) {
926 r = Defrag4Reassemble(
tv, tracker, p);
927 if (r != NULL &&
tv != NULL &&
dtv != NULL) {
941 else if (tracker->
af == AF_INET6) {
942 r = Defrag6Reassemble(
tv, tracker, p);
943 if (r != NULL &&
tv != NULL &&
dtv != NULL) {
970 error_remove_tracker:
989 if (PacketIsIPv4(p)) {
991 }
else if (PacketIsIPv6(p)) {
996 return default_policy;
1039 return default_policy;
1065 uint16_t frag_offset;
1070 if (PacketIsIPv4(p)) {
1071 const IPV4Hdr *ip4h = PacketGetIPv4(p);
1075 }
else if (PacketIsIPv6(p)) {
1083 if (frag_offset == 0 && more_frags == 0) {
1087 if (
af == AF_INET) {
1089 }
else if (
af == AF_INET6) {
1094 tracker = DefragGetTracker(
tv,
dtv, p);
1095 if (tracker == NULL) {
1096 if (
tv != NULL &&
dtv != NULL) {
1102 Packet *rp = DefragInsertFrag(
tv,
dtv, tracker, p);
1111 intmax_t tracker_pool_size;
1112 if (!
SCConfGetInt(
"defrag.trackers", &tracker_pool_size)) {
1120 defrag_context = DefragContextNew();
1121 if (defrag_context == NULL) {
1122 FatalError(
"Failed to allocate memory for the Defrag module.");
1132 DefragContextDestroy(defrag_context);
1133 defrag_context = NULL;
1141 #define IP_MF 0x2000
1150 static Packet *BuildIpv4TestPacket(
1151 uint8_t
proto, uint16_t
id, uint16_t off,
int mf,
const char content,
int content_len)
1165 struct timeval tval;
1166 gettimeofday(&tval, NULL);
1171 ip4h.
ip_len = htons(hlen + content_len);
1172 ip4h.
ip_id = htons(
id);
1176 ip4h.
ip_off = htons(off);
1180 ip4h.s_ip_src.s_addr = 0x01010101;
1181 ip4h.s_ip_dst.s_addr = 0x02020202;
1189 pcontent =
SCCalloc(1, content_len);
1192 memset(pcontent, content, content_len);
1216 static int BuildIpv4TestPacketWithContent(
Packet **packet, uint8_t
proto, uint16_t
id, uint16_t off,
1217 int mf,
const uint8_t *content,
int content_len)
1229 struct timeval tval;
1230 gettimeofday(&tval, NULL);
1234 ip4h.
ip_len = htons(hlen + content_len);
1235 ip4h.
ip_id = htons(
id);
1239 ip4h.
ip_off = htons(off);
1243 ip4h.s_ip_src.s_addr = 0x01010101;
1244 ip4h.s_ip_dst.s_addr = 0x02020202;
1271 static Packet *BuildIpv6TestPacket(
1272 uint8_t
proto, uint32_t
id, uint16_t off,
int mf,
const uint8_t content,
int content_len)
1284 struct timeval tval;
1285 gettimeofday(&tval, NULL);
1288 ip6h.s_ip6_nxt = 44;
1289 ip6h.s_ip6_hlim = 2;
1292 ip6h.s_ip6_src[0] = 0x01010101;
1293 ip6h.s_ip6_src[1] = 0x01010101;
1294 ip6h.s_ip6_src[2] = 0x01010101;
1295 ip6h.s_ip6_src[3] = 0x01010101;
1296 ip6h.s_ip6_dst[0] = 0x02020202;
1297 ip6h.s_ip6_dst[1] = 0x02020202;
1298 ip6h.s_ip6_dst[2] = 0x02020202;
1299 ip6h.s_ip6_dst[3] = 0x02020202;
1308 fh->ip6fh_nxt =
proto;
1309 fh->ip6fh_ident = htonl(
id);
1310 fh->ip6fh_offlg = htons((off << 3) | mf);
1314 pcontent =
SCCalloc(1, content_len);
1317 memset(pcontent, content, content_len);
1322 ip6p->s_ip6_plen = htons(
sizeof(IPV6FragHdr) + content_len);
1342 static Packet *BuildIpv6TestPacketWithContent(
1343 uint8_t
proto, uint32_t
id, uint16_t off,
int mf,
const uint8_t *content,
int content_len)
1354 struct timeval tval;
1355 gettimeofday(&tval, NULL);
1358 ip6h.s_ip6_nxt = 44;
1359 ip6h.s_ip6_hlim = 2;
1362 ip6h.s_ip6_src[0] = 0x01010101;
1363 ip6h.s_ip6_src[1] = 0x01010101;
1364 ip6h.s_ip6_src[2] = 0x01010101;
1365 ip6h.s_ip6_src[3] = 0x01010101;
1366 ip6h.s_ip6_dst[0] = 0x02020202;
1367 ip6h.s_ip6_dst[1] = 0x02020202;
1368 ip6h.s_ip6_dst[2] = 0x02020202;
1369 ip6h.s_ip6_dst[3] = 0x02020202;
1378 fh->ip6fh_nxt =
proto;
1379 fh->ip6fh_ident = htonl(
id);
1380 fh->ip6fh_offlg = htons((off << 3) | mf);
1387 ip6p->s_ip6_plen = htons(
sizeof(IPV6FragHdr) + content_len);
1411 static int DefragInOrderSimpleTest(
void)
1413 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1414 Packet *reassembled = NULL;
1419 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1421 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1423 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1436 for (
int i = 20; i < 20 + 8; i++) {
1441 for (
int i = 28; i < 28 + 8; i++) {
1446 for (
int i = 36; i < 36 + 3; i++) {
1462 static int DefragReverseSimpleTest(
void)
1464 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1465 Packet *reassembled = NULL;
1470 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1472 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1474 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1486 for (
int i = 20; i < 20 + 8; i++) {
1491 for (
int i = 28; i < 28 + 8; i++) {
1496 for (
int i = 36; i < 36 + 3; i++) {
1513 static int DefragInOrderSimpleIpv6Test(
void)
1515 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1516 Packet *reassembled = NULL;
1521 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1523 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1525 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1533 const IPV6Hdr *ip6h = PacketGetIPv6(reassembled);
1537 for (
int i = 40; i < 40 + 8; i++) {
1542 for (
int i = 48; i < 48 + 8; i++) {
1547 for (
int i = 56; i < 56 + 3; i++) {
1560 static int DefragReverseSimpleIpv6Test(
void)
1563 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1564 Packet *reassembled = NULL;
1569 dc = DefragContextNew();
1572 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1574 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1576 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1585 for (
int i = 40; i < 40 + 8; i++) {
1590 for (
int i = 48; i < 48 + 8; i++) {
1595 for (
int i = 56; i < 56 + 3; i++) {
1599 DefragContextDestroy(dc);
1609 static int DefragDoSturgesNovakTest(
int policy, uint8_t *expected,
size_t expected_len)
1621 memset(packets, 0x00,
sizeof(packets));
1628 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
1631 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 32 >> 3, 1,
'B', 16);
1634 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'C', 24);
1637 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 80 >> 3, 1,
'D', 8);
1640 packets[4] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 104 >> 3, 1,
'E', 16);
1643 packets[5] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 120 >> 3, 1,
'F', 24);
1646 packets[6] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 144 >> 3, 1,
'G', 16);
1649 packets[7] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'H', 16);
1652 packets[8] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 1,
'I', 8);
1659 packets[9] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 8 >> 3, 1,
'J', 32);
1662 packets[10] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'K', 24);
1665 packets[11] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 72 >> 3, 1,
'L', 24);
1668 packets[12] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 96 >> 3, 1,
'M', 24);
1671 packets[13] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 128 >> 3, 1,
'N', 8);
1674 packets[14] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 152 >> 3, 1,
'O', 8);
1677 packets[15] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'P', 8);
1680 packets[16] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 0,
'Q', 16);
1682 default_policy = policy;
1685 for (i = 0; i < 9; i++) {
1691 for (; i < 16; i++) {
1708 if (memcmp(expected,
GET_PKT_DATA(reassembled) + 20, expected_len) != 0) {
1709 printf(
"Expected:\n");
1720 for (i = 0; i < 17; i++) {
1727 static int DefragDoSturgesNovakIpv6Test(
int policy, uint8_t *expected,
size_t expected_len)
1739 memset(packets, 0x00,
sizeof(packets));
1746 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 24);
1749 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 32 >> 3, 1,
'B', 16);
1752 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'C', 24);
1755 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 80 >> 3, 1,
'D', 8);
1758 packets[4] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 104 >> 3, 1,
'E', 16);
1761 packets[5] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 120 >> 3, 1,
'F', 24);
1764 packets[6] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 144 >> 3, 1,
'G', 16);
1767 packets[7] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'H', 16);
1770 packets[8] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 1,
'I', 8);
1777 packets[9] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 8 >> 3, 1,
'J', 32);
1780 packets[10] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'K', 24);
1783 packets[11] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 72 >> 3, 1,
'L', 24);
1786 packets[12] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 96 >> 3, 1,
'M', 24);
1789 packets[13] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 128 >> 3, 1,
'N', 8);
1792 packets[14] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 152 >> 3, 1,
'O', 8);
1795 packets[15] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'P', 8);
1798 packets[16] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 0,
'Q', 16);
1800 default_policy = policy;
1803 for (i = 0; i < 9; i++) {
1809 for (; i < 16; i++) {
1830 for (i = 0; i < 17; i++) {
1845 #define D_1 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'
1846 #define D_2 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'
1847 #define D_3 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'
1848 #define D_3_1 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D'
1849 #define D_3_2 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'
1850 #define D_3_3 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'
1851 #define D_3_4 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'
1852 #define D_3_5 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H'
1853 #define D_3_6 'I', 'I', 'I', 'I', 'I', 'I', 'I', 'I'
1854 #define D_4 'J', 'J', 'J', 'J', 'J', 'J', 'J', 'J'
1855 #define D_5 'K', 'K', 'K', 'K', 'K', 'K', 'K', 'K'
1856 #define D_6 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'
1857 #define D_7 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M'
1858 #define D_8 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'
1859 #define D_9 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O'
1860 #define D_10 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'
1861 #define D_11 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q'
1864 DefragSturgesNovakBsdTest(
void)
1867 uint8_t expected[] = {
1899 static int DefragSturgesNovakBsdIpv6Test(
void)
1902 uint8_t expected[] = {
1933 static int DefragSturgesNovakLinuxIpv4Test(
void)
1936 uint8_t expected[] = {
1968 static int DefragSturgesNovakLinuxIpv6Test(
void)
1971 uint8_t expected[] = {
2002 static int DefragSturgesNovakWindowsIpv4Test(
void)
2005 uint8_t expected[] = {
2037 static int DefragSturgesNovakWindowsIpv6Test(
void)
2040 uint8_t expected[] = {
2071 static int DefragSturgesNovakSolarisTest(
void)
2074 uint8_t expected[] = {
2106 static int DefragSturgesNovakSolarisIpv6Test(
void)
2109 uint8_t expected[] = {
2140 static int DefragSturgesNovakFirstTest(
void)
2143 uint8_t expected[] = {
2175 static int DefragSturgesNovakFirstIpv6Test(
void)
2178 uint8_t expected[] = {
2209 DefragSturgesNovakLastTest(
void)
2212 uint8_t expected[] = {
2244 static int DefragSturgesNovakLastIpv6Test(
void)
2247 uint8_t expected[] = {
2278 static int DefragTimeoutTest(
void)
2288 for (i = 0; i < 16; i++) {
2289 Packet *p = BuildIpv4TestPacket(IPPROTO_ICMP, i, 0, 1,
'A' + i, 16);
2299 Packet *p = BuildIpv4TestPacket(IPPROTO_ICMP, 99, 0, 1,
'A' + i, 16);
2324 static int DefragNoDataIpv4Test(
void)
2332 dc = DefragContextNew();
2336 p = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 0,
'A', 0);
2346 DefragContextDestroy(dc);
2353 static int DefragTooLargeIpv4Test(
void)
2360 dc = DefragContextNew();
2365 p = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8183, 0,
'A', 71);
2378 DefragContextDestroy(dc);
2390 static int DefragVlanTest(
void)
2392 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2396 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2398 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2422 static int DefragVlanQinQTest(
void)
2424 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2428 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2430 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2456 static int DefragVlanQinQinQTest(
void)
2462 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2464 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2488 static int DefragTrackerReuseTest(
void)
2498 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 0,
'A', 8);
2511 FAIL_IF(tracker2 != tracker1);
2524 FAIL_IF(tracker2 != tracker1);
2541 static int DefragMfIpv4Test(
void)
2548 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 2, 1,
'C', 8);
2549 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 0, 1,
'A', 8);
2550 Packet *p3 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 1, 0,
'B', 8);
2551 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2568 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2588 static int DefragMfIpv6Test(
void)
2595 Packet *p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 2, 1,
'C', 8);
2596 Packet *p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 0, 1,
'A', 8);
2597 Packet *p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 1, 0,
'B', 8);
2598 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2615 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2630 static int DefragTestBadProto(
void)
2632 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
2637 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
2639 p2 = BuildIpv4TestPacket(IPPROTO_UDP,
id, 1, 1,
'B', 8);
2641 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
2660 static int DefragTestJeremyLinux(
void)
2663 uint8_t expected[] =
"AAAAAAAA"
2684 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
2685 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 40 >> 3, 1,
'B', 48);
2686 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 24 >> 3, 1,
'C', 48);
2687 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 88 >> 3, 0,
'D', 14);
2703 for (i = 0; i < 4; i++) {
2722 static int DefragBsdFragmentAfterNoMfIpv4Test(
void)
2728 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2729 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2730 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2731 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2746 uint8_t expected[] = {
2747 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2748 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2749 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2750 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2751 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2755 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
2756 printf(
"Expected:\n");
2763 for (
int i = 0; i < 4; i++) {
2771 static int DefragBsdFragmentAfterNoMfIpv6Test(
void)
2777 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2778 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2779 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2780 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2795 uint8_t expected[] = {
2796 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2797 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2798 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2799 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2800 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2804 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
2805 printf(
"Expected:\n");
2812 for (
int i = 0; i < 4; i++) {
2820 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2(
void)
2828 &packets[0], IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
2832 &packets[1], IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16));
2836 &packets[2], IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
2840 &packets[3], IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
2855 const uint8_t expected[] = {
2860 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2861 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2862 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2863 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2869 for (
int i = 0; i < 4; i++) {
2877 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2(
void)
2884 packets[0] = BuildIpv6TestPacketWithContent(
2885 IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
2888 packets[1] = BuildIpv6TestPacketWithContent(
2889 IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16);
2892 packets[2] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
2896 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
2911 const uint8_t expected[] = {
2916 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2917 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2918 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2919 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2925 for (
int i = 0; i < 4; i++) {
2945 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test(
void)
2951 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
2952 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
2961 const uint8_t expected[] = {
2962 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
2963 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
2964 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
2965 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
2969 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
2970 printf(
"Expected:\n");
2977 for (
int i = 0; i < 2; i++) {
2985 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test(
void)
2991 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
2992 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
3001 const uint8_t expected[] = {
3002 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3003 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3004 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3005 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
3009 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
3010 printf(
"Expected:\n");
3017 for (
int i = 0; i < 2; i++) {
3036 static int DefragBsdMissingFragmentIpv4Test(
void)
3043 &packets[0], IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
3046 &packets[1], IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8));
3049 &packets[2], IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16));
3053 &packets[3], IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
3056 &packets[4], IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
3077 for (
int i = 0; i < 5; i++) {
3084 static int DefragBsdMissingFragmentIpv6Test(
void)
3090 packets[0] = BuildIpv6TestPacketWithContent(
3091 IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
3094 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8);
3096 packets[2] = BuildIpv6TestPacketWithContent(
3097 IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16);
3100 packets[3] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
3103 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
3124 for (
int i = 0; i < 5; i++) {
3136 UtRegisterTest(
"DefragInOrderSimpleTest", DefragInOrderSimpleTest);
3137 UtRegisterTest(
"DefragReverseSimpleTest", DefragReverseSimpleTest);
3138 UtRegisterTest(
"DefragSturgesNovakBsdTest", DefragSturgesNovakBsdTest);
3140 DefragSturgesNovakLinuxIpv4Test);
3142 DefragSturgesNovakWindowsIpv4Test);
3144 DefragSturgesNovakSolarisTest);
3145 UtRegisterTest(
"DefragSturgesNovakFirstTest", DefragSturgesNovakFirstTest);
3146 UtRegisterTest(
"DefragSturgesNovakLastTest", DefragSturgesNovakLastTest);
3149 UtRegisterTest(
"DefragTooLargeIpv4Test", DefragTooLargeIpv4Test);
3151 UtRegisterTest(
"DefragInOrderSimpleIpv6Test", DefragInOrderSimpleIpv6Test);
3152 UtRegisterTest(
"DefragReverseSimpleIpv6Test", DefragReverseSimpleIpv6Test);
3153 UtRegisterTest(
"DefragSturgesNovakBsdIpv6Test", DefragSturgesNovakBsdIpv6Test);
3154 UtRegisterTest(
"DefragSturgesNovakLinuxIpv6Test", DefragSturgesNovakLinuxIpv6Test);
3155 UtRegisterTest(
"DefragSturgesNovakWindowsIpv6Test", DefragSturgesNovakWindowsIpv6Test);
3156 UtRegisterTest(
"DefragSturgesNovakSolarisIpv6Test", DefragSturgesNovakSolarisIpv6Test);
3157 UtRegisterTest(
"DefragSturgesNovakFirstIpv6Test", DefragSturgesNovakFirstIpv6Test);
3158 UtRegisterTest(
"DefragSturgesNovakLastIpv6Test", DefragSturgesNovakLastIpv6Test);
3163 UtRegisterTest(
"DefragTrackerReuseTest", DefragTrackerReuseTest);
3171 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv4Test", DefragBsdFragmentAfterNoMfIpv4Test);
3172 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv6Test", DefragBsdFragmentAfterNoMfIpv6Test);
3173 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test",
3174 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test);
3175 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test",
3176 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test);
3177 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2",
3178 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2);
3179 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2",
3180 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2);
3181 UtRegisterTest(
"DefragBsdMissingFragmentIpv4Test", DefragBsdMissingFragmentIpv4Test);
3182 UtRegisterTest(
"DefragBsdMissingFragmentIpv6Test", DefragBsdMissingFragmentIpv6Test);