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 (!
ConfGetInt(
"defrag.trackers", &tracker_pool_size) || tracker_pool_size == 0) {
170 intmax_t frag_pool_size;
171 if (!
ConfGetInt(
"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.");
187 if (!
ConfGetInt(
"defrag.timeout", &timeout)) {
192 FatalError(
"defrag: Timeout less than minimum allowed value.");
195 FatalError(
"defrag: Timeout greater than maximum allowed value.");
197 dc->
timeout = (uint32_t)timeout;
202 SCLogDebug(
"\tMaximum defrag trackers: %"PRIuMAX, tracker_pool_size);
203 SCLogDebug(
"\tPreallocated defrag trackers: %"PRIuMAX, tracker_pool_size);
204 SCLogDebug(
"\tMaximum fragments: %"PRIuMAX, (uintmax_t)frag_pool_size);
205 SCLogDebug(
"\tPreallocated fragments: %"PRIuMAX, (uintmax_t)frag_pool_prealloc);
239 }
else if (first->
offset != 0) {
244 goto error_remove_tracker;
263 const IPV4Hdr *oip4h = PacketGetIPv4(p);
269 goto error_remove_tracker;
275 int fragmentable_offset = 0;
276 uint16_t fragmentable_len = 0;
278 int ip_hdr_offset = 0;
281 uint16_t prev_offset = 0;
285 SCLogDebug(
"frag %p, data_len %u, offset %u, pcap_cnt %"PRIu64,
290 if (!more_frags && frag->
offset > prev_offset) {
301 goto error_remove_tracker;
313 int pkt_end = fragmentable_offset + frag->
offset + frag->
data_len;
316 "fragmented packet, exceeds size of packet buffer.");
317 goto error_remove_tracker;
323 goto error_remove_tracker;
327 "fragmentable_len exceeds UINT16_MAX");
328 goto error_remove_tracker;
343 prev_offset = frag->
offset;
346 SCLogDebug(
"ip_hdr_offset %u, hlen %" PRIu16
", fragmentable_len %" PRIu16, ip_hdr_offset, hlen,
352 ip4h->
ip_len = htons(fragmentable_len + hlen);
355 SET_PKT_LEN(rp, ip_hdr_offset + hlen + fragmentable_len);
362 error_remove_tracker:
388 }
else if (first->
offset != 0) {
393 goto error_remove_tracker;
423 const IPV6Hdr *oip6h = PacketGetIPv6(p);
430 goto error_remove_tracker;
436 uint16_t unfragmentable_len = 0;
437 int fragmentable_offset = 0;
438 uint16_t fragmentable_len = 0;
439 int ip_hdr_offset = 0;
440 uint8_t next_hdr = 0;
443 uint16_t prev_offset = 0;
447 if (!more_frags && frag->
offset > prev_offset) {
455 IPV6FragHdr *frag_hdr = (IPV6FragHdr *)(frag->
pkt +
457 next_hdr = frag_hdr->ip6fh_nxt;
463 goto error_remove_tracker;
467 goto error_remove_tracker;
481 unfragmentable_len = (uint16_t)(fragmentable_offset - ip_hdr_offset -
IPV6_HEADER_LEN);
482 if (unfragmentable_len >= fragmentable_offset)
483 goto error_remove_tracker;
489 goto error_remove_tracker;
503 prev_offset = frag->
offset;
508 ip6h->s_ip6_plen = htons(fragmentable_len + unfragmentable_len);
513 if (unfragmentable_len == 0)
514 ip6h->s_ip6_nxt = next_hdr;
516 unfragmentable_len + fragmentable_len);
523 error_remove_tracker:
557 uint16_t frag_offset;
564 uint16_t data_offset;
574 uint16_t ip_hdr_offset;
577 uint16_t frag_hdr_offset = 0;
580 int af = tracker->
af;
584 uint32_t ip6_nh_set_offset = 0;
585 uint8_t ip6_nh_set_value = 0;
591 if (tracker->
af == AF_INET) {
592 const IPV4Hdr *ip4h = PacketGetIPv4(p);
596 data_offset = (uint16_t)((uint8_t *)ip4h + hlen -
GET_PKT_DATA(p));
598 frag_end = frag_offset + data_len;
599 ip_hdr_offset = (uint16_t)((uint8_t *)ip4h -
GET_PKT_DATA(p));
608 else if (tracker->
af == AF_INET6) {
609 const IPV6Hdr *ip6h = PacketGetIPv6(p);
612 data_offset = p->
l3.
vars.
ip6.eh.fh_data_offset;
613 data_len = p->
l3.
vars.
ip6.eh.fh_data_len;
614 frag_end = frag_offset + data_len;
615 ip_hdr_offset = (uint16_t)((uint8_t *)ip6h -
GET_PKT_DATA(p));
616 frag_hdr_offset = p->
l3.
vars.
ip6.eh.fh_header_offset;
618 SCLogDebug(
"mf %s frag_offset %u data_offset %u, data_len %u, "
619 "frag_end %u, ip_hdr_offset %u, frag_hdr_offset %u",
620 more_frags ?
"true" :
"false", frag_offset, data_offset,
621 data_len, frag_end, ip_hdr_offset, frag_hdr_offset);
625 SCLogDebug(
"we have exthdrs before fraghdr %u bytes",
632 ip6_nh_set_offset = p->
l3.
vars.
ip6.eh.fh_prev_hdr_offset;
634 SCLogDebug(
"offset %d, value %u", ip6_nh_set_offset, ip6_nh_set_value);
653 bool overlap =
false;
658 .
offset = frag_offset - 1,
663 next = IP_FRAGMENTS_RB_NEXT(prev);
665 prev = IP_FRAGMENTS_RB_PREV(
next);
668 next = IP_FRAGMENTS_RB_NEXT(prev);
671 while (prev != NULL) {
679 switch (tracker->
policy) {
682 if (prev->
offset <= frag_offset) {
688 if (prev_end > frag_end) {
693 ltrim = prev_end - frag_offset;
695 if ((
next != NULL) && (frag_end >
next->offset)) {
696 next->ltrim = frag_end -
next->offset;
711 uint16_t prev_ltrim = frag_end - prev->
offset;
712 if (prev_ltrim > prev->
ltrim) {
713 prev->
ltrim = prev_ltrim;
717 if ((
next != NULL) && (frag_end >
next->offset)) {
718 next->ltrim = frag_end -
next->offset;
732 if (prev->
offset + prev->
ltrim < frag_offset + ltrim &&
745 if (frag_offset + ltrim < prev->
offset + prev->
ltrim &&
756 if (frag_offset + ltrim <= prev->
offset + prev->
ltrim &&
765 if (frag_offset + ltrim >= prev->
offset + ltrim &&
772 if (frag_offset + ltrim < prev->
offset + ltrim &&
785 if (frag_offset + ltrim > prev->
offset + prev->
ltrim &&
794 if (frag_offset + ltrim == prev->
offset + ltrim &&
802 if (frag_offset >= prev->
offset) {
805 if ((frag_offset < prev->
offset) &&
813 if ((frag_offset >= prev->
offset) &&
817 if (frag_offset < prev->
offset) {
826 if (frag_offset <= prev->
offset) {
827 if (frag_end > prev->
offset) {
850 DefragFragReset(prev);
859 if (ltrim >= data_len) {
875 if (
tv != NULL &&
dtv != NULL) {
878 goto error_remove_tracker;
881 if (new->pkt == NULL) {
890 goto error_remove_tracker;
897 if (ip6_nh_set_offset > 0 && frag_offset == 0 && ltrim == 0) {
898 if (new->len > ip6_nh_set_offset) {
899 SCLogDebug(
"updating frag to have 'correct' nh value: %u -> %u",
900 new->pkt[ip6_nh_set_offset], ip6_nh_set_value);
901 new->pkt[ip6_nh_set_offset] = ip6_nh_set_value;
906 new->offset = frag_offset + ltrim;
907 new->data_offset = data_offset;
908 new->data_len = data_len - ltrim;
909 new->frag_hdr_offset = frag_hdr_offset;
910 new->more_frags = more_frags;
912 new->pcap_cnt = pcap_cnt;
914 if (new->offset == 0) {
926 if (tracker->
af == AF_INET) {
927 r = Defrag4Reassemble(
tv, tracker, p);
928 if (r != NULL &&
tv != NULL &&
dtv != NULL) {
942 else if (tracker->
af == AF_INET6) {
943 r = Defrag6Reassemble(
tv, tracker, p);
944 if (r != NULL &&
tv != NULL &&
dtv != NULL) {
971 error_remove_tracker:
990 if (PacketIsIPv4(p)) {
992 }
else if (PacketIsIPv6(p)) {
997 return default_policy;
1040 return default_policy;
1066 uint16_t frag_offset;
1071 if (PacketIsIPv4(p)) {
1072 const IPV4Hdr *ip4h = PacketGetIPv4(p);
1076 }
else if (PacketIsIPv6(p)) {
1084 if (frag_offset == 0 && more_frags == 0) {
1088 if (
tv != NULL &&
dtv != NULL) {
1089 if (
af == AF_INET) {
1092 else if (
af == AF_INET6) {
1098 tracker = DefragGetTracker(
tv,
dtv, p);
1099 if (tracker == NULL) {
1100 if (
tv != NULL &&
dtv != NULL) {
1106 Packet *rp = DefragInsertFrag(
tv,
dtv, tracker, p);
1115 intmax_t tracker_pool_size;
1116 if (!
ConfGetInt(
"defrag.trackers", &tracker_pool_size)) {
1124 defrag_context = DefragContextNew();
1125 if (defrag_context == NULL) {
1126 FatalError(
"Failed to allocate memory for the Defrag module.");
1136 DefragContextDestroy(defrag_context);
1137 defrag_context = NULL;
1145 #define IP_MF 0x2000
1151 static Packet *BuildIpv4TestPacket(
1152 uint8_t
proto, uint16_t
id, uint16_t off,
int mf,
const char content,
int content_len)
1166 struct timeval tval;
1167 gettimeofday(&tval, NULL);
1172 ip4h.
ip_len = htons(hlen + content_len);
1173 ip4h.
ip_id = htons(
id);
1177 ip4h.
ip_off = htons(off);
1181 ip4h.s_ip_src.s_addr = 0x01010101;
1182 ip4h.s_ip_dst.s_addr = 0x02020202;
1190 pcontent =
SCCalloc(1, content_len);
1193 memset(pcontent, content, content_len);
1217 static int BuildIpv4TestPacketWithContent(
Packet **packet, uint8_t
proto, uint16_t
id, uint16_t off,
1218 int mf,
const uint8_t *content,
int content_len)
1230 struct timeval tval;
1231 gettimeofday(&tval, NULL);
1235 ip4h.
ip_len = htons(hlen + content_len);
1236 ip4h.
ip_id = htons(
id);
1240 ip4h.
ip_off = htons(off);
1244 ip4h.s_ip_src.s_addr = 0x01010101;
1245 ip4h.s_ip_dst.s_addr = 0x02020202;
1272 static Packet *BuildIpv6TestPacket(
1273 uint8_t
proto, uint32_t
id, uint16_t off,
int mf,
const uint8_t content,
int content_len)
1285 struct timeval tval;
1286 gettimeofday(&tval, NULL);
1289 ip6h.s_ip6_nxt = 44;
1290 ip6h.s_ip6_hlim = 2;
1293 ip6h.s_ip6_src[0] = 0x01010101;
1294 ip6h.s_ip6_src[1] = 0x01010101;
1295 ip6h.s_ip6_src[2] = 0x01010101;
1296 ip6h.s_ip6_src[3] = 0x01010101;
1297 ip6h.s_ip6_dst[0] = 0x02020202;
1298 ip6h.s_ip6_dst[1] = 0x02020202;
1299 ip6h.s_ip6_dst[2] = 0x02020202;
1300 ip6h.s_ip6_dst[3] = 0x02020202;
1309 fh->ip6fh_nxt =
proto;
1310 fh->ip6fh_ident = htonl(
id);
1311 fh->ip6fh_offlg = htons((off << 3) | mf);
1315 pcontent =
SCCalloc(1, content_len);
1318 memset(pcontent, content, content_len);
1323 ip6p->s_ip6_plen = htons(
sizeof(IPV6FragHdr) + content_len);
1343 static Packet *BuildIpv6TestPacketWithContent(
1344 uint8_t
proto, uint32_t
id, uint16_t off,
int mf,
const uint8_t *content,
int content_len)
1355 struct timeval tval;
1356 gettimeofday(&tval, NULL);
1359 ip6h.s_ip6_nxt = 44;
1360 ip6h.s_ip6_hlim = 2;
1363 ip6h.s_ip6_src[0] = 0x01010101;
1364 ip6h.s_ip6_src[1] = 0x01010101;
1365 ip6h.s_ip6_src[2] = 0x01010101;
1366 ip6h.s_ip6_src[3] = 0x01010101;
1367 ip6h.s_ip6_dst[0] = 0x02020202;
1368 ip6h.s_ip6_dst[1] = 0x02020202;
1369 ip6h.s_ip6_dst[2] = 0x02020202;
1370 ip6h.s_ip6_dst[3] = 0x02020202;
1379 fh->ip6fh_nxt =
proto;
1380 fh->ip6fh_ident = htonl(
id);
1381 fh->ip6fh_offlg = htons((off << 3) | mf);
1388 ip6p->s_ip6_plen = htons(
sizeof(IPV6FragHdr) + content_len);
1412 static int DefragInOrderSimpleTest(
void)
1414 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1415 Packet *reassembled = NULL;
1418 memset(&
tv, 0,
sizeof(
tv));
1420 memset(&
dtv, 0,
sizeof(
dtv));
1424 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1426 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1428 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1441 for (
int i = 20; i < 20 + 8; i++) {
1446 for (
int i = 28; i < 28 + 8; i++) {
1451 for (
int i = 36; i < 36 + 3; i++) {
1467 static int DefragReverseSimpleTest(
void)
1469 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1470 Packet *reassembled = NULL;
1473 memset(&
tv, 0,
sizeof(
tv));
1475 memset(&
dtv, 0,
sizeof(
dtv));
1479 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
1481 p2 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 1,
'B', 8);
1483 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
1495 for (
int i = 20; i < 20 + 8; i++) {
1500 for (
int i = 28; i < 28 + 8; i++) {
1505 for (
int i = 36; i < 36 + 3; i++) {
1522 static int DefragInOrderSimpleIpv6Test(
void)
1524 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1525 Packet *reassembled = NULL;
1528 memset(&
tv, 0,
sizeof(
tv));
1530 memset(&
dtv, 0,
sizeof(
dtv));
1534 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1536 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1538 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1546 const IPV6Hdr *ip6h = PacketGetIPv6(reassembled);
1550 for (
int i = 40; i < 40 + 8; i++) {
1555 for (
int i = 48; i < 48 + 8; i++) {
1560 for (
int i = 56; i < 56 + 3; i++) {
1573 static int DefragReverseSimpleIpv6Test(
void)
1576 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1577 Packet *reassembled = NULL;
1580 memset(&
tv, 0,
sizeof(
tv));
1582 memset(&
dtv, 0,
sizeof(
dtv));
1586 dc = DefragContextNew();
1589 p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 8);
1591 p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 1, 1,
'B', 8);
1593 p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 2, 0,
'C', 3);
1602 for (
int i = 40; i < 40 + 8; i++) {
1607 for (
int i = 48; i < 48 + 8; i++) {
1612 for (
int i = 56; i < 56 + 3; i++) {
1616 DefragContextDestroy(dc);
1626 static int DefragDoSturgesNovakTest(
int policy, uint8_t *expected,
size_t expected_len)
1630 memset(&
tv, 0,
sizeof(
tv));
1632 memset(&
dtv, 0,
sizeof(
dtv));
1642 memset(packets, 0x00,
sizeof(packets));
1649 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
1652 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 32 >> 3, 1,
'B', 16);
1655 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'C', 24);
1658 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 80 >> 3, 1,
'D', 8);
1661 packets[4] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 104 >> 3, 1,
'E', 16);
1664 packets[5] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 120 >> 3, 1,
'F', 24);
1667 packets[6] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 144 >> 3, 1,
'G', 16);
1670 packets[7] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'H', 16);
1673 packets[8] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 1,
'I', 8);
1680 packets[9] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 8 >> 3, 1,
'J', 32);
1683 packets[10] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 48 >> 3, 1,
'K', 24);
1686 packets[11] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 72 >> 3, 1,
'L', 24);
1689 packets[12] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 96 >> 3, 1,
'M', 24);
1692 packets[13] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 128 >> 3, 1,
'N', 8);
1695 packets[14] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 152 >> 3, 1,
'O', 8);
1698 packets[15] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 160 >> 3, 1,
'P', 8);
1701 packets[16] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 176 >> 3, 0,
'Q', 16);
1703 default_policy = policy;
1706 for (i = 0; i < 9; i++) {
1712 for (; i < 16; i++) {
1729 if (memcmp(expected,
GET_PKT_DATA(reassembled) + 20, expected_len) != 0) {
1730 printf(
"Expected:\n");
1741 for (i = 0; i < 17; i++) {
1748 static int DefragDoSturgesNovakIpv6Test(
int policy, uint8_t *expected,
size_t expected_len)
1752 memset(&
tv, 0,
sizeof(
tv));
1754 memset(&
dtv, 0,
sizeof(
dtv));
1764 memset(packets, 0x00,
sizeof(packets));
1771 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 0, 1,
'A', 24);
1774 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 32 >> 3, 1,
'B', 16);
1777 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'C', 24);
1780 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 80 >> 3, 1,
'D', 8);
1783 packets[4] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 104 >> 3, 1,
'E', 16);
1786 packets[5] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 120 >> 3, 1,
'F', 24);
1789 packets[6] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 144 >> 3, 1,
'G', 16);
1792 packets[7] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'H', 16);
1795 packets[8] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 1,
'I', 8);
1802 packets[9] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 8 >> 3, 1,
'J', 32);
1805 packets[10] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 48 >> 3, 1,
'K', 24);
1808 packets[11] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 72 >> 3, 1,
'L', 24);
1811 packets[12] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 96 >> 3, 1,
'M', 24);
1814 packets[13] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 128 >> 3, 1,
'N', 8);
1817 packets[14] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 152 >> 3, 1,
'O', 8);
1820 packets[15] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 160 >> 3, 1,
'P', 8);
1823 packets[16] = BuildIpv6TestPacket(IPPROTO_ICMPV6,
id, 176 >> 3, 0,
'Q', 16);
1825 default_policy = policy;
1828 for (i = 0; i < 9; i++) {
1834 for (; i < 16; i++) {
1855 for (i = 0; i < 17; i++) {
1870 #define D_1 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'
1871 #define D_2 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'
1872 #define D_3 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'
1873 #define D_3_1 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D'
1874 #define D_3_2 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'
1875 #define D_3_3 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'
1876 #define D_3_4 'G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'
1877 #define D_3_5 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H'
1878 #define D_3_6 'I', 'I', 'I', 'I', 'I', 'I', 'I', 'I'
1879 #define D_4 'J', 'J', 'J', 'J', 'J', 'J', 'J', 'J'
1880 #define D_5 'K', 'K', 'K', 'K', 'K', 'K', 'K', 'K'
1881 #define D_6 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'
1882 #define D_7 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M'
1883 #define D_8 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'
1884 #define D_9 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O'
1885 #define D_10 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'
1886 #define D_11 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q'
1889 DefragSturgesNovakBsdTest(
void)
1892 uint8_t expected[] = {
1924 static int DefragSturgesNovakBsdIpv6Test(
void)
1927 uint8_t expected[] = {
1958 static int DefragSturgesNovakLinuxIpv4Test(
void)
1961 uint8_t expected[] = {
1993 static int DefragSturgesNovakLinuxIpv6Test(
void)
1996 uint8_t expected[] = {
2027 static int DefragSturgesNovakWindowsIpv4Test(
void)
2030 uint8_t expected[] = {
2062 static int DefragSturgesNovakWindowsIpv6Test(
void)
2065 uint8_t expected[] = {
2096 static int DefragSturgesNovakSolarisTest(
void)
2099 uint8_t expected[] = {
2131 static int DefragSturgesNovakSolarisIpv6Test(
void)
2134 uint8_t expected[] = {
2165 static int DefragSturgesNovakFirstTest(
void)
2168 uint8_t expected[] = {
2200 static int DefragSturgesNovakFirstIpv6Test(
void)
2203 uint8_t expected[] = {
2234 DefragSturgesNovakLastTest(
void)
2237 uint8_t expected[] = {
2269 static int DefragSturgesNovakLastIpv6Test(
void)
2272 uint8_t expected[] = {
2303 static int DefragTimeoutTest(
void)
2307 memset(&
tv, 0,
sizeof(
tv));
2309 memset(&
dtv, 0,
sizeof(
dtv));
2317 for (i = 0; i < 16; i++) {
2318 Packet *p = BuildIpv4TestPacket(IPPROTO_ICMP, i, 0, 1,
'A' + i, 16);
2328 Packet *p = BuildIpv4TestPacket(IPPROTO_ICMP, 99, 0, 1,
'A' + i, 16);
2353 static int DefragNoDataIpv4Test(
void)
2359 memset(&
tv, 0,
sizeof(
tv));
2361 memset(&
dtv, 0,
sizeof(
dtv));
2365 dc = DefragContextNew();
2369 p = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 1, 0,
'A', 0);
2379 DefragContextDestroy(dc);
2386 static int DefragTooLargeIpv4Test(
void)
2391 memset(&
tv, 0,
sizeof(
tv));
2393 memset(&
dtv, 0,
sizeof(
dtv));
2397 dc = DefragContextNew();
2402 p = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8183, 0,
'A', 71);
2415 DefragContextDestroy(dc);
2427 static int DefragVlanTest(
void)
2429 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2431 memset(&
tv, 0,
sizeof(
tv));
2433 memset(&
dtv, 0,
sizeof(
dtv));
2437 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2439 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2463 static int DefragVlanQinQTest(
void)
2465 Packet *p1 = NULL, *p2 = NULL, *r = NULL;
2467 memset(&
tv, 0,
sizeof(
tv));
2469 memset(&
dtv, 0,
sizeof(
dtv));
2473 p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2475 p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2501 static int DefragVlanQinQinQTest(
void)
2505 memset(&
tv, 0,
sizeof(
tv));
2507 memset(&
dtv, 0,
sizeof(
dtv));
2511 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'A', 8);
2513 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 1, 0,
'B', 8);
2537 static int DefragTrackerReuseTest(
void)
2543 memset(&
tv, 0,
sizeof(
tv));
2545 memset(&
dtv, 0,
sizeof(
dtv));
2551 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 0,
'A', 8);
2555 tracker1 = DefragGetTracker(&
tv, &
dtv, p1);
2562 tracker2 = DefragGetTracker(&
tv, &
dtv, p1);
2564 FAIL_IF(tracker2 != tracker1);
2572 tracker2 = DefragGetTracker(&
tv, &
dtv, p1);
2577 FAIL_IF(tracker2 != tracker1);
2594 static int DefragMfIpv4Test(
void)
2599 memset(&
tv, 0,
sizeof(
tv));
2601 memset(&
dtv, 0,
sizeof(
dtv));
2605 Packet *p1 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 2, 1,
'C', 8);
2606 Packet *p2 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 0, 1,
'A', 8);
2607 Packet *p3 = BuildIpv4TestPacket(IPPROTO_ICMP, ip_id, 1, 0,
'B', 8);
2608 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2625 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2645 static int DefragMfIpv6Test(
void)
2650 memset(&
tv, 0,
sizeof(
tv));
2652 memset(&
dtv, 0,
sizeof(
dtv));
2656 Packet *p1 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 2, 1,
'C', 8);
2657 Packet *p2 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 0, 1,
'A', 8);
2658 Packet *p3 = BuildIpv6TestPacket(IPPROTO_ICMPV6, ip_id, 1, 0,
'B', 8);
2659 FAIL_IF(p1 == NULL || p2 == NULL || p3 == NULL);
2676 uint8_t expected_payload[] =
"AAAAAAAABBBBBBBB";
2691 static int DefragTestBadProto(
void)
2693 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
2696 memset(&
tv, 0,
sizeof(
tv));
2698 memset(&
dtv, 0,
sizeof(
dtv));
2702 p1 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 8);
2704 p2 = BuildIpv4TestPacket(IPPROTO_UDP,
id, 1, 1,
'B', 8);
2706 p3 = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 2, 0,
'C', 3);
2725 static int DefragTestJeremyLinux(
void)
2728 memset(&
tv, 0,
sizeof(
tv));
2730 memset(&
dtv, 0,
sizeof(
dtv));
2731 uint8_t expected[] =
"AAAAAAAA"
2752 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 0, 1,
'A', 24);
2753 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 40 >> 3, 1,
'B', 48);
2754 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 24 >> 3, 1,
'C', 48);
2755 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP,
id, 88 >> 3, 0,
'D', 14);
2771 for (i = 0; i < 4; i++) {
2790 static int DefragBsdFragmentAfterNoMfIpv4Test(
void)
2796 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2797 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2798 packets[2] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2799 packets[3] = BuildIpv4TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2804 r =
Defrag(NULL, NULL, packets[1]);
2807 r =
Defrag(NULL, NULL, packets[2]);
2810 r =
Defrag(NULL, NULL, packets[3]);
2814 uint8_t expected[] = {
2815 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2816 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2817 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2818 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2819 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2823 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
2824 printf(
"Expected:\n");
2835 static int DefragBsdFragmentAfterNoMfIpv6Test(
void)
2841 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 24 >> 3, 0,
'A', 16);
2842 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 8 >> 3, 1,
'B', 16);
2843 packets[2] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 16 >> 3, 1,
'C', 16);
2844 packets[3] = BuildIpv6TestPacket(IPPROTO_ICMP, 0x96, 0, 1,
'D', 8);
2849 r =
Defrag(NULL, NULL, packets[1]);
2852 r =
Defrag(NULL, NULL, packets[2]);
2855 r =
Defrag(NULL, NULL, packets[3]);
2859 uint8_t expected[] = {
2860 'D',
'D',
'D',
'D',
'D',
'D',
'D',
'D',
2861 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2862 'B',
'B',
'B',
'B',
'B',
'B',
'B',
'B',
2863 'C',
'C',
'C',
'C',
'C',
'C',
'C',
'C',
2864 'A',
'A',
'A',
'A',
'A',
'A',
'A',
'A',
2868 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
2869 printf(
"Expected:\n");
2880 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2(
void)
2888 &packets[0], IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
2892 &packets[1], IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16));
2896 &packets[2], IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
2900 &packets[3], IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
2905 r =
Defrag(NULL, NULL, packets[1]);
2908 r =
Defrag(NULL, NULL, packets[2]);
2911 r =
Defrag(NULL, NULL, packets[3]);
2915 const uint8_t expected[] = {
2920 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2921 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2922 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2923 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2933 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2(
void)
2940 packets[0] = BuildIpv6TestPacketWithContent(
2941 IPPROTO_ICMP, 6, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
2944 packets[1] = BuildIpv6TestPacketWithContent(
2945 IPPROTO_ICMP, 6, 8 >> 3, 1, (uint8_t *)
"AACCBBDDAACCDDBB", 16);
2948 packets[2] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
2952 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 6, 32 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
2957 r =
Defrag(NULL, NULL, packets[1]);
2960 r =
Defrag(NULL, NULL, packets[2]);
2963 r =
Defrag(NULL, NULL, packets[3]);
2967 const uint8_t expected[] = {
2972 'A',
'A',
'C',
'C',
'B',
'B',
'D',
'D',
2973 'A',
'A',
'C',
'C',
'D',
'D',
'B',
'B',
2974 'A',
'A',
'B',
'B',
'D',
'D',
'C',
'C',
2975 'D',
'D',
'C',
'C',
'B',
'B',
'A',
'A',
2997 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test(
void)
3003 packets[0] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
3004 packets[1] = BuildIpv4TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
3009 r =
Defrag(NULL, NULL, packets[1]);
3013 const uint8_t expected[] = {
3014 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3015 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3016 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3017 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
3021 if (memcmp(expected,
GET_PKT_DATA(r) + 20,
sizeof(expected)) != 0) {
3022 printf(
"Expected:\n");
3032 static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test(
void)
3038 packets[0] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 8 >> 3, 0,
'E', 24);
3039 packets[1] = BuildIpv6TestPacket(IPPROTO_ICMP, 1, 0, 1,
'M', 24);
3044 r =
Defrag(NULL, NULL, packets[1]);
3048 const uint8_t expected[] = {
3049 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3050 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3051 'M',
'M',
'M',
'M',
'M',
'M',
'M',
'M',
3052 'E',
'E',
'E',
'E',
'E',
'E',
'E',
'E',
3056 if (memcmp(expected,
GET_PKT_DATA(r) + 40,
sizeof(expected)) != 0) {
3057 printf(
"Expected:\n");
3078 static int DefragBsdMissingFragmentIpv4Test(
void)
3085 &packets[0], IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16));
3088 &packets[1], IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8));
3091 &packets[2], IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16));
3095 &packets[3], IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8));
3098 &packets[4], IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8));
3103 r =
Defrag(NULL, NULL, packets[1]);
3106 r =
Defrag(NULL, NULL, packets[2]);
3109 r =
Defrag(NULL, NULL, packets[3]);
3112 r =
Defrag(NULL, NULL, packets[4]);
3119 for (
int i = 0; i < 5; i++) {
3128 static int DefragBsdMissingFragmentIpv6Test(
void)
3134 packets[0] = BuildIpv6TestPacketWithContent(
3135 IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)
"AABBCCDDAABBDDCC", 16);
3138 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)
"AACCBBDD", 8);
3140 packets[2] = BuildIpv6TestPacketWithContent(
3141 IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)
"AACCDDBBAADDBBCC", 16);
3144 packets[3] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 0, 1, (uint8_t *)
"ZZZZZZZZ", 8);
3147 BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)
"DDCCBBAA", 8);
3152 r =
Defrag(NULL, NULL, packets[1]);
3155 r =
Defrag(NULL, NULL, packets[2]);
3158 r =
Defrag(NULL, NULL, packets[3]);
3161 r =
Defrag(NULL, NULL, packets[4]);
3168 for (
int i = 0; i < 5; i++) {
3182 UtRegisterTest(
"DefragInOrderSimpleTest", DefragInOrderSimpleTest);
3183 UtRegisterTest(
"DefragReverseSimpleTest", DefragReverseSimpleTest);
3184 UtRegisterTest(
"DefragSturgesNovakBsdTest", DefragSturgesNovakBsdTest);
3186 DefragSturgesNovakLinuxIpv4Test);
3188 DefragSturgesNovakWindowsIpv4Test);
3190 DefragSturgesNovakSolarisTest);
3191 UtRegisterTest(
"DefragSturgesNovakFirstTest", DefragSturgesNovakFirstTest);
3192 UtRegisterTest(
"DefragSturgesNovakLastTest", DefragSturgesNovakLastTest);
3195 UtRegisterTest(
"DefragTooLargeIpv4Test", DefragTooLargeIpv4Test);
3197 UtRegisterTest(
"DefragInOrderSimpleIpv6Test", DefragInOrderSimpleIpv6Test);
3198 UtRegisterTest(
"DefragReverseSimpleIpv6Test", DefragReverseSimpleIpv6Test);
3199 UtRegisterTest(
"DefragSturgesNovakBsdIpv6Test", DefragSturgesNovakBsdIpv6Test);
3200 UtRegisterTest(
"DefragSturgesNovakLinuxIpv6Test", DefragSturgesNovakLinuxIpv6Test);
3201 UtRegisterTest(
"DefragSturgesNovakWindowsIpv6Test", DefragSturgesNovakWindowsIpv6Test);
3202 UtRegisterTest(
"DefragSturgesNovakSolarisIpv6Test", DefragSturgesNovakSolarisIpv6Test);
3203 UtRegisterTest(
"DefragSturgesNovakFirstIpv6Test", DefragSturgesNovakFirstIpv6Test);
3204 UtRegisterTest(
"DefragSturgesNovakLastIpv6Test", DefragSturgesNovakLastIpv6Test);
3209 UtRegisterTest(
"DefragTrackerReuseTest", DefragTrackerReuseTest);
3217 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv4Test", DefragBsdFragmentAfterNoMfIpv4Test);
3218 UtRegisterTest(
"DefragBsdFragmentAfterNoMfIpv6Test", DefragBsdFragmentAfterNoMfIpv6Test);
3219 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test",
3220 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test);
3221 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test",
3222 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test);
3223 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2",
3224 DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2);
3225 UtRegisterTest(
"DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2",
3226 DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2);
3227 UtRegisterTest(
"DefragBsdMissingFragmentIpv4Test", DefragBsdMissingFragmentIpv4Test);
3228 UtRegisterTest(
"DefragBsdMissingFragmentIpv6Test", DefragBsdMissingFragmentIpv6Test);