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));
129 DefragFragReset(frag);
143 DefragContextNew(
void)
152 intmax_t tracker_pool_size;
153 if (!
SCConfGetInt(
"defrag.trackers", &tracker_pool_size) || tracker_pool_size == 0) {
158 intmax_t frag_pool_size;
159 if (!
SCConfGetInt(
"defrag.max-frags", &frag_pool_size) || frag_pool_size == 0 ||
160 frag_pool_size > UINT32_MAX) {
163 uint32_t frag_pool_prealloc = (uint32_t)frag_pool_size / 2;
165 PoolInit((uint32_t)frag_pool_size, frag_pool_prealloc,
sizeof(
Frag), NULL, NULL, NULL);
167 FatalError(
"Defrag: Failed to initialize fragment pool.");
170 FatalError(
"Defrag: Failed to initialize frag pool mutex.");
179 FatalError(
"defrag: Timeout less than minimum allowed value.");
182 FatalError(
"defrag: Timeout greater than maximum allowed value.");
184 dc->
timeout = (uint32_t)timeout;
189 SCLogDebug(
"\tMaximum defrag trackers: %"PRIuMAX, tracker_pool_size);
190 SCLogDebug(
"\tPreallocated defrag trackers: %"PRIuMAX, tracker_pool_size);
191 SCLogDebug(
"\tMaximum fragments: %"PRIuMAX, (uintmax_t)frag_pool_size);
192 SCLogDebug(
"\tPreallocated fragments: %"PRIuMAX, (uintmax_t)frag_pool_prealloc);
226 }
else if (first->
offset != 0) {
231 goto error_remove_tracker;
250 const IPV4Hdr *oip4h = PacketGetIPv4(
p);
256 goto error_remove_tracker;
262 int fragmentable_offset = 0;
263 uint16_t fragmentable_len = 0;
265 int ip_hdr_offset = 0;
268 uint16_t prev_offset = 0;
272 SCLogDebug(
"frag %p, data_len %u, offset %u, pcap_cnt %"PRIu64,
277 if (!more_frags && frag->
offset > prev_offset) {
288 goto error_remove_tracker;
300 int pkt_end = fragmentable_offset + frag->
offset + frag->
data_len;
303 "fragmented packet, exceeds size of packet buffer.");
304 goto error_remove_tracker;
310 goto error_remove_tracker;
314 "fragmentable_len exceeds UINT16_MAX");
315 goto error_remove_tracker;
330 prev_offset = frag->
offset;
333 SCLogDebug(
"ip_hdr_offset %u, hlen %" PRIu16
", fragmentable_len %" PRIu16, ip_hdr_offset, hlen,
336 const uint32_t packet_len = (uint32_t)hlen + fragmentable_len;
339 goto error_remove_tracker;
344 ip4h->
ip_len = htons((uint16_t)packet_len);
354 error_remove_tracker:
380 }
else if (first->
offset != 0) {
385 goto error_remove_tracker;
415 const IPV6Hdr *oip6h = PacketGetIPv6(
p);
422 goto error_remove_tracker;
428 uint16_t unfragmentable_len = 0;
429 int fragmentable_offset = 0;
430 uint16_t fragmentable_len = 0;
431 int ip_hdr_offset = 0;
432 uint8_t next_hdr = 0;
435 uint16_t prev_offset = 0;
439 if (!more_frags && frag->
offset > prev_offset) {
447 IPV6FragHdr *frag_hdr = (IPV6FragHdr *)(frag->
pkt +
449 next_hdr = frag_hdr->ip6fh_nxt;
455 goto error_remove_tracker;
459 goto error_remove_tracker;
473 unfragmentable_len = (uint16_t)(fragmentable_offset - ip_hdr_offset -
IPV6_HEADER_LEN);
474 if (unfragmentable_len >= fragmentable_offset)
475 goto error_remove_tracker;
481 goto error_remove_tracker;
495 prev_offset = frag->
offset;
498 const uint32_t
payload_len = (uint32_t)unfragmentable_len + fragmentable_len;
501 goto error_remove_tracker;
510 if (unfragmentable_len == 0)
511 ip6h->s_ip6_nxt = next_hdr;
519 error_remove_tracker:
553 uint16_t frag_offset;
560 uint16_t data_offset;
570 uint16_t ip_hdr_offset;
573 uint16_t frag_hdr_offset = 0;
576 int af = tracker->
af;
580 uint32_t ip6_nh_set_offset = 0;
581 uint8_t ip6_nh_set_value = 0;
587 if (tracker->
af == AF_INET) {
588 const IPV4Hdr *ip4h = PacketGetIPv4(
p);
592 data_offset = (uint16_t)((uint8_t *)ip4h + hlen -
GET_PKT_DATA(
p));
594 frag_end = frag_offset + data_len;
595 ip_hdr_offset = (uint16_t)((uint8_t *)ip4h -
GET_PKT_DATA(
p));
604 else if (tracker->
af == AF_INET6) {
605 const IPV6Hdr *ip6h = PacketGetIPv6(
p);
608 data_offset =
p->
l3.
vars.
ip6.eh.fh_data_offset;
610 frag_end = frag_offset + data_len;
611 ip_hdr_offset = (uint16_t)((uint8_t *)ip6h -
GET_PKT_DATA(
p));
612 frag_hdr_offset =
p->
l3.
vars.
ip6.eh.fh_header_offset;
614 SCLogDebug(
"mf %s frag_offset %u data_offset %u, data_len %u, "
615 "frag_end %u, ip_hdr_offset %u, frag_hdr_offset %u",
616 more_frags ?
"true" :
"false", frag_offset, data_offset,
617 data_len, frag_end, ip_hdr_offset, frag_hdr_offset);
621 SCLogDebug(
"we have exthdrs before fraghdr %u bytes",
628 ip6_nh_set_offset =
p->
l3.
vars.
ip6.eh.fh_prev_hdr_offset;
630 SCLogDebug(
"offset %d, value %u", ip6_nh_set_offset, ip6_nh_set_value);
649 bool overlap =
false;
654 .
offset = frag_offset - 1,
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 UtRegisterTest(
"DefragInOrderSimpleTest", DefragInOrderSimpleTest);
3152 UtRegisterTest(
"DefragReverseSimpleTest", DefragReverseSimpleTest);
3153 UtRegisterTest(
"DefragSturgesNovakBsdTest", DefragSturgesNovakBsdTest);
3155 DefragSturgesNovakLinuxIpv4Test);
3157 DefragSturgesNovakWindowsIpv4Test);
3159 DefragSturgesNovakSolarisTest);
3160 UtRegisterTest(
"DefragSturgesNovakFirstTest", DefragSturgesNovakFirstTest);
3161 UtRegisterTest(
"DefragSturgesNovakLastTest", DefragSturgesNovakLastTest);
3164 UtRegisterTest(
"DefragTooLargeIpv4Test", DefragTooLargeIpv4Test);
3166 UtRegisterTest(
"DefragInOrderSimpleIpv6Test", DefragInOrderSimpleIpv6Test);
3167 UtRegisterTest(
"DefragReverseSimpleIpv6Test", DefragReverseSimpleIpv6Test);
3168 UtRegisterTest(
"DefragSturgesNovakBsdIpv6Test", DefragSturgesNovakBsdIpv6Test);
3169 UtRegisterTest(
"DefragSturgesNovakLinuxIpv6Test", DefragSturgesNovakLinuxIpv6Test);
3170 UtRegisterTest(
"DefragSturgesNovakWindowsIpv6Test", DefragSturgesNovakWindowsIpv6Test);
3171 UtRegisterTest(
"DefragSturgesNovakSolarisIpv6Test", DefragSturgesNovakSolarisIpv6Test);
3172 UtRegisterTest(
"DefragSturgesNovakFirstIpv6Test", DefragSturgesNovakFirstIpv6Test);
3173 UtRegisterTest(
"DefragSturgesNovakLastIpv6Test", DefragSturgesNovakLastIpv6Test);
3178 UtRegisterTest(
"DefragTrackerReuseTest", DefragTrackerReuseTest);
3186 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv4Test", DefragBsdFragmentAfterNoMfIpv4Test);
3187 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv6Test", DefragBsdFragmentAfterNoMfIpv6Test);
3188 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test",
3189 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test);
3190 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test",
3191 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test);
3192 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2",
3193 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2);
3194 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2",
3195 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2);
3196 UtRegisterTest(
"DefragBsdMissingFragmentIpv4Test", DefragBsdMissingFragmentIpv4Test);
3197 UtRegisterTest(
"DefragBsdMissingFragmentIpv6Test", DefragBsdMissingFragmentIpv6Test);