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 (
tv != NULL &&
dtv != NULL) {
1088 if (
af == AF_INET) {
1091 else if (
af == AF_INET6) {
1097 tracker = DefragGetTracker(
tv,
dtv, p);
1098 if (tracker == NULL) {
1099 if (
tv != NULL &&
dtv != NULL) {
1105 Packet *rp = DefragInsertFrag(
tv,
dtv, tracker, p);
1114 intmax_t tracker_pool_size;
1115 if (!
SCConfGetInt(
"defrag.trackers", &tracker_pool_size)) {
1123 defrag_context = DefragContextNew();
1124 if (defrag_context == NULL) {
1125 FatalError(
"Failed to allocate memory for the Defrag module.");
1135 DefragContextDestroy(defrag_context);
1136 defrag_context = NULL;
1144 #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;
1417 memset(&
tv, 0,
sizeof(
tv));
1419 memset(&
dtv, 0,
sizeof(
dtv));
1423 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1425 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1427 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1440 for (
int i = 20; i < 20 + 8; i++) {
1445 for (
int i = 28; i < 28 + 8; i++) {
1450 for (
int i = 36; i < 36 + 3; i++) {
1466 static int DefragReverseSimpleTest(
void)
1468 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1469 Packet *reassembled = NULL;
1472 memset(&
tv, 0,
sizeof(
tv));
1474 memset(&
dtv, 0,
sizeof(
dtv));
1478 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1480 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1482 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1494 for (
int i = 20; i < 20 + 8; i++) {
1499 for (
int i = 28; i < 28 + 8; i++) {
1504 for (
int i = 36; i < 36 + 3; i++) {
1521 static int DefragInOrderSimpleIpv6Test(
void)
1523 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1524 Packet *reassembled = NULL;
1527 memset(&
tv, 0,
sizeof(
tv));
1529 memset(&
dtv, 0,
sizeof(
dtv));
1533 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1535 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1537 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1545 const IPV6Hdr *ip6h = PacketGetIPv6(reassembled);
1549 for (
int i = 40; i < 40 + 8; i++) {
1554 for (
int i = 48; i < 48 + 8; i++) {
1559 for (
int i = 56; i < 56 + 3; i++) {
1572 static int DefragReverseSimpleIpv6Test(
void)
1575 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1576 Packet *reassembled = NULL;
1579 memset(&
tv, 0,
sizeof(
tv));
1581 memset(&
dtv, 0,
sizeof(
dtv));
1585 dc = DefragContextNew();
1588 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1590 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1592 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1601 for (
int i = 40; i < 40 + 8; i++) {
1606 for (
int i = 48; i < 48 + 8; i++) {
1611 for (
int i = 56; i < 56 + 3; i++) {
1615 DefragContextDestroy(dc);
1625 static int DefragDoSturgesNovakTest(
int policy, uint8_t *expected,
size_t expected_len)
1629 memset(&
tv, 0,
sizeof(
tv));
1631 memset(&
dtv, 0,
sizeof(
dtv));
1641 memset(packets, 0x00,
sizeof(packets));
1648 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
1651 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 32 >> 3, 1,
'B', 16);
1654 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'C', 24);
1657 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 80 >> 3, 1,
'D', 8);
1660 packets[4] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 104 >> 3, 1,
'E', 16);
1663 packets[5] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 120 >> 3, 1,
'F', 24);
1666 packets[6] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 144 >> 3, 1,
'G', 16);
1669 packets[7] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'H', 16);
1672 packets[8] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 1,
'I', 8);
1679 packets[9] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 8 >> 3, 1,
'J', 32);
1682 packets[10] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'K', 24);
1685 packets[11] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 72 >> 3, 1,
'L', 24);
1688 packets[12] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 96 >> 3, 1,
'M', 24);
1691 packets[13] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 128 >> 3, 1,
'N', 8);
1694 packets[14] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 152 >> 3, 1,
'O', 8);
1697 packets[15] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'P', 8);
1700 packets[16] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 0,
'Q', 16);
1702 default_policy = policy;
1705 for (i = 0; i < 9; i++) {
1711 for (; i < 16; i++) {
1728 if (memcmp(expected,
GET_PKT_DATA(reassembled) + 20, expected_len) != 0) {
1729 printf(
"Expected:\n");
1740 for (i = 0; i < 17; i++) {
1747 static int DefragDoSturgesNovakIpv6Test(
int policy, uint8_t *expected,
size_t expected_len)
1751 memset(&
tv, 0,
sizeof(
tv));
1753 memset(&
dtv, 0,
sizeof(
dtv));
1763 memset(packets, 0x00,
sizeof(packets));
1770 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 24);
1773 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 32 >> 3, 1,
'B', 16);
1776 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'C', 24);
1779 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 80 >> 3, 1,
'D', 8);
1782 packets[4] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 104 >> 3, 1,
'E', 16);
1785 packets[5] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 120 >> 3, 1,
'F', 24);
1788 packets[6] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 144 >> 3, 1,
'G', 16);
1791 packets[7] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'H', 16);
1794 packets[8] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 1,
'I', 8);
1801 packets[9] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 8 >> 3, 1,
'J', 32);
1804 packets[10] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'K', 24);
1807 packets[11] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 72 >> 3, 1,
'L', 24);
1810 packets[12] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 96 >> 3, 1,
'M', 24);
1813 packets[13] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 128 >> 3, 1,
'N', 8);
1816 packets[14] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 152 >> 3, 1,
'O', 8);
1819 packets[15] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'P', 8);
1822 packets[16] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 0,
'Q', 16);
1824 default_policy = policy;
1827 for (i = 0; i < 9; i++) {
1833 for (; i < 16; i++) {
1854 for (i = 0; i < 17; i++) {
1869 #define D_1 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'
1870 #define D_2 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'
1871 #define D_3 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'
1872 #define D_3_1 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D'
1873 #define D_3_2 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'
1874 #define D_3_3 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'
1875 #define D_3_4 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'
1876 #define D_3_5 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H'
1877 #define D_3_6 'I', 'I', 'I', 'I', 'I', 'I', 'I', 'I'
1878 #define D_4 'J', 'J', 'J', 'J', 'J', 'J', 'J', 'J'
1879 #define D_5 'K', 'K', 'K', 'K', 'K', 'K', 'K', 'K'
1880 #define D_6 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'
1881 #define D_7 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M'
1882 #define D_8 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'
1883 #define D_9 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O'
1884 #define D_10 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'
1885 #define D_11 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q'
1888 DefragSturgesNovakBsdTest(
void)
1891 uint8_t expected[] = {
1923 static int DefragSturgesNovakBsdIpv6Test(
void)
1926 uint8_t expected[] = {
1957 static int DefragSturgesNovakLinuxIpv4Test(
void)
1960 uint8_t expected[] = {
1992 static int DefragSturgesNovakLinuxIpv6Test(
void)
1995 uint8_t expected[] = {
2026 static int DefragSturgesNovakWindowsIpv4Test(
void)
2029 uint8_t expected[] = {
2061 static int DefragSturgesNovakWindowsIpv6Test(
void)
2064 uint8_t expected[] = {
2095 static int DefragSturgesNovakSolarisTest(
void)
2098 uint8_t expected[] = {
2130 static int DefragSturgesNovakSolarisIpv6Test(
void)
2133 uint8_t expected[] = {
2164 static int DefragSturgesNovakFirstTest(
void)
2167 uint8_t expected[] = {
2199 static int DefragSturgesNovakFirstIpv6Test(
void)
2202 uint8_t expected[] = {
2233 DefragSturgesNovakLastTest(
void)
2236 uint8_t expected[] = {
2268 static int DefragSturgesNovakLastIpv6Test(
void)
2271 uint8_t expected[] = {
2302 static int DefragTimeoutTest(
void)
2306 memset(&
tv, 0,
sizeof(
tv));
2308 memset(&
dtv, 0,
sizeof(
dtv));
2316 for (i = 0; i < 16; i++) {
2317 Packet *p = BuildIpv4TestPacket(IPPROTO_ICMP, i, 0, 1,
'A' + i, 16);
2327 Packet *p = BuildIpv4TestPacket(IPPROTO_ICMP, 99, 0, 1,
'A' + i, 16);
2352 static int DefragNoDataIpv4Test(
void)
2358 memset(&
tv, 0,
sizeof(
tv));
2360 memset(&
dtv, 0,
sizeof(
dtv));
2364 dc = DefragContextNew();
2368 p = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 0,
'A', 0);
2378 DefragContextDestroy(dc);
2385 static int DefragTooLargeIpv4Test(
void)
2390 memset(&
tv, 0,
sizeof(
tv));
2392 memset(&
dtv, 0,
sizeof(
dtv));
2396 dc = DefragContextNew();
2401 p = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8183, 0,
'A', 71);
2414 DefragContextDestroy(dc);
2426 static int DefragVlanTest(
void)
2428 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2430 memset(&
tv, 0,
sizeof(
tv));
2432 memset(&
dtv, 0,
sizeof(
dtv));
2436 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2438 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2462 static int DefragVlanQinQTest(
void)
2464 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2466 memset(&
tv, 0,
sizeof(
tv));
2468 memset(&
dtv, 0,
sizeof(
dtv));
2472 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2474 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2500 static int DefragVlanQinQinQTest(
void)
2504 memset(&
tv, 0,
sizeof(
tv));
2506 memset(&
dtv, 0,
sizeof(
dtv));
2510 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2512 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2536 static int DefragTrackerReuseTest(
void)
2542 memset(&
tv, 0,
sizeof(
tv));
2544 memset(&
dtv, 0,
sizeof(
dtv));
2550 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 0,
'A', 8);
2554 tracker1 = DefragGetTracker(&
tv, &
dtv, p1);
2561 tracker2 = DefragGetTracker(&
tv, &
dtv, p1);
2563 FAIL_IF(tracker2 != tracker1);
2571 tracker2 = DefragGetTracker(&
tv, &
dtv, p1);
2576 FAIL_IF(tracker2 != tracker1);
2593 static int DefragMfIpv4Test(
void)
2598 memset(&
tv, 0,
sizeof(
tv));
2600 memset(&
dtv, 0,
sizeof(
dtv));
2604 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 2, 1,
'C', 8);
2605 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 0, 1,
'A', 8);
2606 Packet *p3 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 1, 0,
'B', 8);
2607 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2624 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2644 static int DefragMfIpv6Test(
void)
2649 memset(&
tv, 0,
sizeof(
tv));
2651 memset(&
dtv, 0,
sizeof(
dtv));
2655 Packet *p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 2, 1,
'C', 8);
2656 Packet *p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 0, 1,
'A', 8);
2657 Packet *p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 1, 0,
'B', 8);
2658 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2675 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2690 static int DefragTestBadProto(
void)
2692 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
2695 memset(&
tv, 0,
sizeof(
tv));
2697 memset(&
dtv, 0,
sizeof(
dtv));
2701 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
2703 p2 = BuildIpv4TestPacket(IPPROTO_UDP,
id, 1, 1,
'B', 8);
2705 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
2724 static int DefragTestJeremyLinux(
void)
2727 memset(&
tv, 0,
sizeof(
tv));
2729 memset(&
dtv, 0,
sizeof(
dtv));
2730 uint8_t expected[] =
"AAAAAAAA"
2751 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
2752 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 40 >> 3, 1,
'B', 48);
2753 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 24 >> 3, 1,
'C', 48);
2754 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 88 >> 3, 0,
'D', 14);
2770 for (i = 0; i < 4; i++) {
2789 static int DefragBsdFragmentAfterNoMfIpv4Test(
void)
2795 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2796 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2797 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2798 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2803 r =
Defrag(NULL, NULL, packets[1]);
2806 r =
Defrag(NULL, NULL, packets[2]);
2809 r =
Defrag(NULL, NULL, packets[3]);
2813 uint8_t expected[] = {
2814 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2815 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2816 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2817 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2818 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2822 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
2823 printf(
"Expected:\n");
2834 static int DefragBsdFragmentAfterNoMfIpv6Test(
void)
2840 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2841 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2842 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2843 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2848 r =
Defrag(NULL, NULL, packets[1]);
2851 r =
Defrag(NULL, NULL, packets[2]);
2854 r =
Defrag(NULL, NULL, packets[3]);
2858 uint8_t expected[] = {
2859 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2860 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2861 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2862 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2863 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2867 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
2868 printf(
"Expected:\n");
2879 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2(
void)
2887 &packets[0], IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
2891 &packets[1], IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16));
2895 &packets[2], IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
2899 &packets[3], IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
2904 r =
Defrag(NULL, NULL, packets[1]);
2907 r =
Defrag(NULL, NULL, packets[2]);
2910 r =
Defrag(NULL, NULL, packets[3]);
2914 const uint8_t expected[] = {
2919 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2920 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2921 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2922 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2932 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2(
void)
2939 packets[0] = BuildIpv6TestPacketWithContent(
2940 IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
2943 packets[1] = BuildIpv6TestPacketWithContent(
2944 IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16);
2947 packets[2] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
2951 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
2956 r =
Defrag(NULL, NULL, packets[1]);
2959 r =
Defrag(NULL, NULL, packets[2]);
2962 r =
Defrag(NULL, NULL, packets[3]);
2966 const uint8_t expected[] = {
2971 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2972 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2973 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2974 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2996 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test(
void)
3002 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
3003 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
3008 r =
Defrag(NULL, NULL, packets[1]);
3012 const uint8_t expected[] = {
3013 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3014 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3015 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3016 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
3020 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
3021 printf(
"Expected:\n");
3031 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test(
void)
3037 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
3038 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
3043 r =
Defrag(NULL, NULL, packets[1]);
3047 const uint8_t expected[] = {
3048 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3049 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3050 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3051 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
3055 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
3056 printf(
"Expected:\n");
3077 static int DefragBsdMissingFragmentIpv4Test(
void)
3084 &packets[0], IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
3087 &packets[1], IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8));
3090 &packets[2], IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16));
3094 &packets[3], IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
3097 &packets[4], IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
3102 r =
Defrag(NULL, NULL, packets[1]);
3105 r =
Defrag(NULL, NULL, packets[2]);
3108 r =
Defrag(NULL, NULL, packets[3]);
3111 r =
Defrag(NULL, NULL, packets[4]);
3118 for (
int i = 0; i < 5; i++) {
3127 static int DefragBsdMissingFragmentIpv6Test(
void)
3133 packets[0] = BuildIpv6TestPacketWithContent(
3134 IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
3137 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8);
3139 packets[2] = BuildIpv6TestPacketWithContent(
3140 IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16);
3143 packets[3] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
3146 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
3151 r =
Defrag(NULL, NULL, packets[1]);
3154 r =
Defrag(NULL, NULL, packets[2]);
3157 r =
Defrag(NULL, NULL, packets[3]);
3160 r =
Defrag(NULL, NULL, packets[4]);
3167 for (
int i = 0; i < 5; i++) {
3181 UtRegisterTest(
"DefragInOrderSimpleTest", DefragInOrderSimpleTest);
3182 UtRegisterTest(
"DefragReverseSimpleTest", DefragReverseSimpleTest);
3183 UtRegisterTest(
"DefragSturgesNovakBsdTest", DefragSturgesNovakBsdTest);
3185 DefragSturgesNovakLinuxIpv4Test);
3187 DefragSturgesNovakWindowsIpv4Test);
3189 DefragSturgesNovakSolarisTest);
3190 UtRegisterTest(
"DefragSturgesNovakFirstTest", DefragSturgesNovakFirstTest);
3191 UtRegisterTest(
"DefragSturgesNovakLastTest", DefragSturgesNovakLastTest);
3194 UtRegisterTest(
"DefragTooLargeIpv4Test", DefragTooLargeIpv4Test);
3196 UtRegisterTest(
"DefragInOrderSimpleIpv6Test", DefragInOrderSimpleIpv6Test);
3197 UtRegisterTest(
"DefragReverseSimpleIpv6Test", DefragReverseSimpleIpv6Test);
3198 UtRegisterTest(
"DefragSturgesNovakBsdIpv6Test", DefragSturgesNovakBsdIpv6Test);
3199 UtRegisterTest(
"DefragSturgesNovakLinuxIpv6Test", DefragSturgesNovakLinuxIpv6Test);
3200 UtRegisterTest(
"DefragSturgesNovakWindowsIpv6Test", DefragSturgesNovakWindowsIpv6Test);
3201 UtRegisterTest(
"DefragSturgesNovakSolarisIpv6Test", DefragSturgesNovakSolarisIpv6Test);
3202 UtRegisterTest(
"DefragSturgesNovakFirstIpv6Test", DefragSturgesNovakFirstIpv6Test);
3203 UtRegisterTest(
"DefragSturgesNovakLastIpv6Test", DefragSturgesNovakLastIpv6Test);
3208 UtRegisterTest(
"DefragTrackerReuseTest", DefragTrackerReuseTest);
3216 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv4Test", DefragBsdFragmentAfterNoMfIpv4Test);
3217 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv6Test", DefragBsdFragmentAfterNoMfIpv6Test);
3218 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test",
3219 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test);
3220 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test",
3221 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test);
3222 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2",
3223 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2);
3224 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2",
3225 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2);
3226 UtRegisterTest(
"DefragBsdMissingFragmentIpv4Test", DefragBsdMissingFragmentIpv4Test);
3227 UtRegisterTest(
"DefragBsdMissingFragmentIpv6Test", DefragBsdMissingFragmentIpv6Test);