|
|
|
@ -55,6 +55,9 @@
|
|
|
|
#include "defrag-queue.h"
|
|
|
|
#include "defrag-queue.h"
|
|
|
|
#include "defrag-config.h"
|
|
|
|
#include "defrag-config.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "tmqh-packetpool.h"
|
|
|
|
|
|
|
|
#include "decode.h"
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
#include "util-unittest.h"
|
|
|
|
#include "util-unittest.h"
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
@ -466,7 +469,7 @@ done:
|
|
|
|
* \todo Allocate packet buffers from a pool.
|
|
|
|
* \todo Allocate packet buffers from a pool.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static Packet *
|
|
|
|
static Packet *
|
|
|
|
DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker, Packet *p)
|
|
|
|
DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker, Packet *p, PacketQueue *pq)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Packet *r = NULL;
|
|
|
|
Packet *r = NULL;
|
|
|
|
int ltrim = 0;
|
|
|
|
int ltrim = 0;
|
|
|
|
@ -714,6 +717,12 @@ insert:
|
|
|
|
if (r != NULL && tv != NULL && dtv != NULL) {
|
|
|
|
if (r != NULL && tv != NULL && dtv != NULL) {
|
|
|
|
SCPerfCounterIncr(dtv->counter_defrag_ipv4_reassembled,
|
|
|
|
SCPerfCounterIncr(dtv->counter_defrag_ipv4_reassembled,
|
|
|
|
tv->sc_perf_pca);
|
|
|
|
tv->sc_perf_pca);
|
|
|
|
|
|
|
|
if (pq && DecodeIPV4(tv, dtv, r, (void *)r->ip4h,
|
|
|
|
|
|
|
|
IPV4_GET_IPLEN(r), pq) != TM_ECODE_OK) {
|
|
|
|
|
|
|
|
TmqhOutputPacketpool(tv, r);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
PacketDefragPktFinishSetup(r, p);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (tracker->af == AF_INET6) {
|
|
|
|
else if (tracker->af == AF_INET6) {
|
|
|
|
@ -721,10 +730,18 @@ insert:
|
|
|
|
if (r != NULL && tv != NULL && dtv != NULL) {
|
|
|
|
if (r != NULL && tv != NULL && dtv != NULL) {
|
|
|
|
SCPerfCounterIncr(dtv->counter_defrag_ipv6_reassembled,
|
|
|
|
SCPerfCounterIncr(dtv->counter_defrag_ipv6_reassembled,
|
|
|
|
tv->sc_perf_pca);
|
|
|
|
tv->sc_perf_pca);
|
|
|
|
|
|
|
|
if (pq && DecodeIPV6(tv, dtv, r, (uint8_t *)r->ip6h,
|
|
|
|
|
|
|
|
IPV6_GET_PLEN(r) + IPV6_HEADER_LEN,
|
|
|
|
|
|
|
|
pq) != TM_ECODE_OK) {
|
|
|
|
|
|
|
|
TmqhOutputPacketpool(tv, r);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
PacketDefragPktFinishSetup(r, p);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
done:
|
|
|
|
if (overlap) {
|
|
|
|
if (overlap) {
|
|
|
|
if (af == AF_INET) {
|
|
|
|
if (af == AF_INET) {
|
|
|
|
@ -825,7 +842,7 @@ DefragGetTracker(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
|
|
|
|
* NULL is returned.
|
|
|
|
* NULL is returned.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
Packet *
|
|
|
|
Packet *
|
|
|
|
Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
|
|
|
|
Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, PacketQueue *pq)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16_t frag_offset;
|
|
|
|
uint16_t frag_offset;
|
|
|
|
uint8_t more_frags;
|
|
|
|
uint8_t more_frags;
|
|
|
|
@ -866,7 +883,7 @@ Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
|
|
|
|
if (tracker == NULL)
|
|
|
|
if (tracker == NULL)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
Packet *rp = DefragInsertFrag(tv, dtv, tracker, p);
|
|
|
|
Packet *rp = DefragInsertFrag(tv, dtv, tracker, p, pq);
|
|
|
|
DefragTrackerRelease(tracker);
|
|
|
|
DefragTrackerRelease(tracker);
|
|
|
|
|
|
|
|
|
|
|
|
return rp;
|
|
|
|
return rp;
|
|
|
|
@ -1076,12 +1093,12 @@ DefragInOrderSimpleTest(void)
|
|
|
|
if (p3 == NULL)
|
|
|
|
if (p3 == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
if (Defrag(NULL, NULL, p1) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p1, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if (Defrag(NULL, NULL, p2) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p2, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
reassembled = Defrag(NULL, NULL, p3);
|
|
|
|
reassembled = Defrag(NULL, NULL, p3, NULL);
|
|
|
|
if (reassembled == NULL) {
|
|
|
|
if (reassembled == NULL) {
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1153,12 +1170,12 @@ DefragReverseSimpleTest(void)
|
|
|
|
if (p3 == NULL)
|
|
|
|
if (p3 == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
if (Defrag(NULL, NULL, p3) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p3, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if (Defrag(NULL, NULL, p2) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p2, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
reassembled = Defrag(NULL, NULL, p1);
|
|
|
|
reassembled = Defrag(NULL, NULL, p1, NULL);
|
|
|
|
if (reassembled == NULL)
|
|
|
|
if (reassembled == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
@ -1225,11 +1242,11 @@ IPV6DefragInOrderSimpleTest(void)
|
|
|
|
if (p3 == NULL)
|
|
|
|
if (p3 == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
if (Defrag(NULL, NULL, p1) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p1, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if (Defrag(NULL, NULL, p2) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p2, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
reassembled = Defrag(NULL, NULL, p3);
|
|
|
|
reassembled = Defrag(NULL, NULL, p3, NULL);
|
|
|
|
if (reassembled == NULL)
|
|
|
|
if (reassembled == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
@ -1295,11 +1312,11 @@ IPV6DefragReverseSimpleTest(void)
|
|
|
|
if (p3 == NULL)
|
|
|
|
if (p3 == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
if (Defrag(NULL, NULL, p3) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p3, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if (Defrag(NULL, NULL, p2) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p2, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
reassembled = Defrag(NULL, NULL, p1);
|
|
|
|
reassembled = Defrag(NULL, NULL, p1, NULL);
|
|
|
|
if (reassembled == NULL)
|
|
|
|
if (reassembled == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
@ -1417,7 +1434,7 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
|
|
|
|
|
|
|
|
|
|
|
|
/* Send all but the last. */
|
|
|
|
/* Send all but the last. */
|
|
|
|
for (i = 0; i < 9; i++) {
|
|
|
|
for (i = 0; i < 9; i++) {
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i]);
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i], NULL);
|
|
|
|
if (tp != NULL) {
|
|
|
|
if (tp != NULL) {
|
|
|
|
SCFree(tp);
|
|
|
|
SCFree(tp);
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
@ -1428,7 +1445,7 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int overlap = 0;
|
|
|
|
int overlap = 0;
|
|
|
|
for (; i < 16; i++) {
|
|
|
|
for (; i < 16; i++) {
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i]);
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i], NULL);
|
|
|
|
if (tp != NULL) {
|
|
|
|
if (tp != NULL) {
|
|
|
|
SCFree(tp);
|
|
|
|
SCFree(tp);
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
@ -1442,7 +1459,7 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* And now the last one. */
|
|
|
|
/* And now the last one. */
|
|
|
|
Packet *reassembled = Defrag(NULL, NULL, packets[16]);
|
|
|
|
Packet *reassembled = Defrag(NULL, NULL, packets[16], NULL);
|
|
|
|
if (reassembled == NULL) {
|
|
|
|
if (reassembled == NULL) {
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1552,7 +1569,7 @@ IPV6DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
|
|
|
|
|
|
|
|
|
|
|
|
/* Send all but the last. */
|
|
|
|
/* Send all but the last. */
|
|
|
|
for (i = 0; i < 9; i++) {
|
|
|
|
for (i = 0; i < 9; i++) {
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i]);
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i], NULL);
|
|
|
|
if (tp != NULL) {
|
|
|
|
if (tp != NULL) {
|
|
|
|
SCFree(tp);
|
|
|
|
SCFree(tp);
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
@ -1563,7 +1580,7 @@ IPV6DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int overlap = 0;
|
|
|
|
int overlap = 0;
|
|
|
|
for (; i < 16; i++) {
|
|
|
|
for (; i < 16; i++) {
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i]);
|
|
|
|
Packet *tp = Defrag(NULL, NULL, packets[i], NULL);
|
|
|
|
if (tp != NULL) {
|
|
|
|
if (tp != NULL) {
|
|
|
|
SCFree(tp);
|
|
|
|
SCFree(tp);
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
@ -1576,7 +1593,7 @@ IPV6DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* And now the last one. */
|
|
|
|
/* And now the last one. */
|
|
|
|
Packet *reassembled = Defrag(NULL, NULL, packets[16]);
|
|
|
|
Packet *reassembled = Defrag(NULL, NULL, packets[16], NULL);
|
|
|
|
if (reassembled == NULL)
|
|
|
|
if (reassembled == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if (memcmp(GET_PKT_DATA(reassembled) + 40, expected, expected_len) != 0)
|
|
|
|
if (memcmp(GET_PKT_DATA(reassembled) + 40, expected, expected_len) != 0)
|
|
|
|
@ -2036,7 +2053,7 @@ DefragTimeoutTest(void)
|
|
|
|
if (p == NULL)
|
|
|
|
if (p == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
Packet *tp = Defrag(NULL, NULL, p);
|
|
|
|
Packet *tp = Defrag(NULL, NULL, p, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
SCFree(p);
|
|
|
|
SCFree(p);
|
|
|
|
|
|
|
|
|
|
|
|
@ -2053,7 +2070,7 @@ DefragTimeoutTest(void)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
p->ts.tv_sec += (defrag_context->timeout + 1);
|
|
|
|
p->ts.tv_sec += (defrag_context->timeout + 1);
|
|
|
|
Packet *tp = Defrag(NULL, NULL, p);
|
|
|
|
Packet *tp = Defrag(NULL, NULL, p, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
if (tp != NULL) {
|
|
|
|
if (tp != NULL) {
|
|
|
|
SCFree(tp);
|
|
|
|
SCFree(tp);
|
|
|
|
@ -2101,7 +2118,7 @@ DefragIPv4NoDataTest(void)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* We do not expect a packet returned. */
|
|
|
|
/* We do not expect a packet returned. */
|
|
|
|
if (Defrag(NULL, NULL, p) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* The fragment should have been ignored so no fragments should
|
|
|
|
/* The fragment should have been ignored so no fragments should
|
|
|
|
@ -2140,7 +2157,7 @@ DefragIPv4TooLargeTest(void)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* We do not expect a packet returned. */
|
|
|
|
/* We do not expect a packet returned. */
|
|
|
|
if (Defrag(NULL, NULL, p) != NULL)
|
|
|
|
if (Defrag(NULL, NULL, p, NULL) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if (!ENGINE_ISSET_EVENT(p, IPV4_FRAG_PKT_TOO_LARGE))
|
|
|
|
if (!ENGINE_ISSET_EVENT(p, IPV4_FRAG_PKT_TOO_LARGE))
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
@ -2181,18 +2198,18 @@ DefragVlanTest(void) {
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* With no VLAN IDs set, packets should re-assemble. */
|
|
|
|
/* With no VLAN IDs set, packets should re-assemble. */
|
|
|
|
if ((r = Defrag(NULL, NULL, p1)) != NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if ((r = Defrag(NULL, NULL, p2)) == NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p2, NULL)) == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
SCFree(r);
|
|
|
|
SCFree(r);
|
|
|
|
|
|
|
|
|
|
|
|
/* With mismatched VLANs, packets should not re-assemble. */
|
|
|
|
/* With mismatched VLANs, packets should not re-assemble. */
|
|
|
|
p1->vlan_id[0] = 1;
|
|
|
|
p1->vlan_id[0] = 1;
|
|
|
|
p2->vlan_id[0] = 2;
|
|
|
|
p2->vlan_id[0] = 2;
|
|
|
|
if ((r = Defrag(NULL, NULL, p1)) != NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if ((r = Defrag(NULL, NULL, p2)) != NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p2, NULL)) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* Pass. */
|
|
|
|
/* Pass. */
|
|
|
|
@ -2226,9 +2243,9 @@ DefragVlanQinQTest(void) {
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* With no VLAN IDs set, packets should re-assemble. */
|
|
|
|
/* With no VLAN IDs set, packets should re-assemble. */
|
|
|
|
if ((r = Defrag(NULL, NULL, p1)) != NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if ((r = Defrag(NULL, NULL, p2)) == NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p2, NULL)) == NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
SCFree(r);
|
|
|
|
SCFree(r);
|
|
|
|
|
|
|
|
|
|
|
|
@ -2237,9 +2254,9 @@ DefragVlanQinQTest(void) {
|
|
|
|
p2->vlan_id[0] = 1;
|
|
|
|
p2->vlan_id[0] = 1;
|
|
|
|
p1->vlan_id[1] = 1;
|
|
|
|
p1->vlan_id[1] = 1;
|
|
|
|
p2->vlan_id[1] = 2;
|
|
|
|
p2->vlan_id[1] = 2;
|
|
|
|
if ((r = Defrag(NULL, NULL, p1)) != NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
if ((r = Defrag(NULL, NULL, p2)) != NULL)
|
|
|
|
if ((r = Defrag(NULL, NULL, p2, NULL)) != NULL)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
|
|
/* Pass. */
|
|
|
|
/* Pass. */
|
|
|
|
|