consolidate more common code between ipv4 and ipv6.

remotes/origin/master-1.0.x
Jason Ish 16 years ago committed by Victor Julien
parent 176c6e5668
commit 6547725b39

@ -613,7 +613,7 @@ void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
/* If a fragment, pass off for re-assembly. */
if (IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1) {
Packet *rp = Defrag4(tv, NULL, p);
Packet *rp = Defrag(tv, NULL, p);
if (rp != NULL) {
/* Got re-assembled packet, re-run through decoder. */
DecodeIPV4(tv, dtv, rp, rp->pkt, rp->pktlen, pq);

@ -410,7 +410,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
#if 0
/* Pass to defragger if a fragment. */
if (IPV6_EXTHDR_ISSET_FH(p)) {
Packet *rp = Defrag6(tv, NULL, p);
Packet *rp = Defrag(tv, NULL, p);
if (rp != NULL) {
/* Reinject. */
}

@ -36,8 +36,6 @@
#include "util-unittest.h"
#endif
#define MAX(a, b) (a > b ? a : b)
#define DEFAULT_DEFRAG_HASH_SIZE 0xffff
/**
@ -723,13 +721,6 @@ Defrag4Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
}
if (rp == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for fragmentation re-assembly, dumping fragments.");
SCMutexLock(&dc->frag_table_lock);
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
SCMutexUnlock(&dc->frag_table_lock);
DefragTrackerReset(tracker);
SCMutexLock(&dc->tracker_pool_lock);
PoolReturn(dc->tracker_pool, tracker);
SCMutexUnlock(&dc->tracker_pool_lock);
goto done;
}
@ -773,14 +764,16 @@ Defrag4Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
rp->pktlen = pktlen + payload_len;
done:
/* Remove the frag tracker. */
SCMutexLock(&dc->frag_table_lock);
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
SCMutexUnlock(&dc->frag_table_lock);
DefragTrackerReset(tracker);
SCMutexLock(&dc->tracker_pool_lock);
PoolReturn(dc->tracker_pool, tracker);
SCMutexUnlock(&dc->tracker_pool_lock);
done:
SCMutexUnlock(&tracker->lock);
return rp;
}
@ -843,13 +836,6 @@ Defrag6Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
}
if (rp == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for fragmentation re-assembly, dumping fragments.");
SCMutexLock(&dc->frag_table_lock);
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
SCMutexUnlock(&dc->frag_table_lock);
DefragTrackerReset(tracker);
SCMutexLock(&dc->tracker_pool_lock);
PoolReturn(dc->tracker_pool, tracker);
SCMutexUnlock(&dc->tracker_pool_lock);
goto done;
}
@ -890,20 +876,20 @@ Defrag6Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
rp->ip6h->s_ip6_plen = htons(payload_len);
rp->pktlen = pktlen + payload_len;
done:
/* Remove the frag tracker. */
SCMutexLock(&dc->frag_table_lock);
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
SCMutexUnlock(&dc->frag_table_lock);
DefragTrackerReset(tracker);
SCMutexLock(&dc->tracker_pool_lock);
PoolReturn(dc->tracker_pool, tracker);
SCMutexUnlock(&dc->tracker_pool_lock);
done:
SCMutexUnlock(&tracker->lock);
return rp;
}
/**
* \brief Timeout a tracker.
*
@ -985,7 +971,7 @@ DefragGetTracker(DefragContext *dc, DefragTracker *lookup_key, Packet *p)
}
/**
* \brief Entry point for IPv4 fragments.
* \brief Entry point for IPv4 and IPv6 fragments.
*
* \param tv ThreadVars for the calling decoder.
* \param dc A DefragContext to use, may be NULL for the default.
@ -996,76 +982,41 @@ DefragGetTracker(DefragContext *dc, DefragTracker *lookup_key, Packet *p)
* NULL is returned.
*/
Packet *
Defrag4(ThreadVars *tv, DefragContext *dc, Packet *p)
Defrag(ThreadVars *tv, DefragContext *dc, Packet *p)
{
uint16_t frag_offset;
int more_frags;
uint8_t more_frags;
DefragTracker *tracker, lookup;
uint32_t id;
int af;
/* If no DefragContext was passed in, use the global one. Passing
* one in is primarily useful for unit tests. */
if (dc == NULL)
dc = defrag_context;
more_frags = IPV4_GET_MF(p);
frag_offset = IPV4_GET_IPOFFSET(p);
if (frag_offset == 0 && more_frags == 0) {
if (PKT_IS_IPV4(p)) {
af = AF_INET;
more_frags = IPV4_GET_MF(p);
frag_offset = IPV4_GET_IPOFFSET(p);
id = IPV4_GET_IPID(p);
}
else if (PKT_IS_IPV6(p)) {
af = AF_INET6;
frag_offset = IPV6_EXTHDR_GET_FH_OFFSET(p);
more_frags = IPV6_EXTHDR_GET_FH_FLAG(p);
id = IPV6_EXTHDR_GET_FH_ID(p);
}
else {
return NULL;
}
/* Create a lookup key. */
lookup.family = AF_INET;
lookup.id = IPV4_GET_IPID(p);
lookup.src_addr = p->src;
lookup.dst_addr = p->dst;
tracker = DefragGetTracker(dc, &lookup, p);
if (tracker == NULL)
if (frag_offset == 0 && more_frags == 0) {
return NULL;
if (!more_frags) {
tracker->seen_last = 1;
}
DefragInsertFrag(dc, tracker, p);
if (tracker->seen_last) {
Packet *rp = Defrag4Reassemble(tv, dc, tracker, p);
return rp;
}
return NULL;
}
/**
* \brief Entry point for IPv4 fragments.
*
* \param tv ThreadVars for the calling decoder.
* \param dc A DefragContext to use, may be NULL for the default.
* \param p The packet fragment.
*
* \retval A new Packet resembling the re-assembled packet if the most
* recent fragment allowed the packet to be re-assembled, otherwise
* NULL is returned.
*/
Packet *
Defrag6(ThreadVars *tv, DefragContext *dc, Packet *p)
{
uint16_t frag_offset;
uint8_t more_frags;
uint32_t id;
DefragTracker *tracker, lookup;
/* If no DefragContext was passed in, use the global one. Passing
* one in is primarily useful for unit tests. */
if (dc == NULL)
dc = defrag_context;
frag_offset = IPV6_EXTHDR_GET_FH_OFFSET(p);
more_frags = IPV6_EXTHDR_GET_FH_FLAG(p);
id = IPV6_EXTHDR_GET_FH_ID(p);
/* Create a lookup key. */
lookup.family = AF_INET6;
lookup.family = af;
lookup.id = id;
lookup.src_addr = p->src;
lookup.dst_addr = p->dst;
@ -1079,11 +1030,14 @@ Defrag6(ThreadVars *tv, DefragContext *dc, Packet *p)
}
DefragInsertFrag(dc, tracker, p);
if (tracker->seen_last) {
Packet *rp = Defrag6Reassemble(tv, dc, tracker, p);
Packet *rp = NULL;
if (af == AF_INET)
rp = Defrag4Reassemble(tv, dc, tracker, p);
else if (af == AF_INET6)
rp = Defrag6Reassemble(tv, dc, tracker, p);
return rp;
}
return NULL;
}
@ -1266,12 +1220,12 @@ DefragInOrderSimpleTest(void)
if (p3 == NULL)
goto end;
if (Defrag4(NULL, dc, p1) != NULL)
if (Defrag(NULL, dc, p1) != NULL)
goto end;
if (Defrag4(NULL, dc, p2) != NULL)
if (Defrag(NULL, dc, p2) != NULL)
goto end;
reassembled = Defrag4(NULL, dc, p3);
reassembled = Defrag(NULL, dc, p3);
if (reassembled == NULL)
goto end;
@ -1341,11 +1295,11 @@ IPV6DefragInOrderSimpleTest(void)
if (p3 == NULL)
goto end;
if (Defrag6(NULL, dc, p1) != NULL)
if (Defrag(NULL, dc, p1) != NULL)
goto end;
if (Defrag6(NULL, dc, p2) != NULL)
if (Defrag(NULL, dc, p2) != NULL)
goto end;
reassembled = Defrag6(NULL, dc, p3);
reassembled = Defrag(NULL, dc, p3);
if (reassembled == NULL)
goto end;
@ -1467,7 +1421,7 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
/* Send all but the last. */
for (i = 0; i < 16; i++) {
Packet *tp = Defrag4(NULL, dc, packets[i]);
Packet *tp = Defrag(NULL, dc, packets[i]);
if (tp != NULL) {
free(tp);
goto end;
@ -1475,7 +1429,7 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
}
/* And now the last one. */
Packet *reassembled = Defrag4(NULL, dc, packets[16]);
Packet *reassembled = Defrag(NULL, dc, packets[16]);
if (reassembled == NULL)
goto end;
if (memcmp(reassembled->pkt + 20, expected, expected_len) != 0)
@ -1576,89 +1530,89 @@ IPV6DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
/* Send all but the last. */
Packet *tp;
tp = Defrag6(NULL, dc, packets[0]);
tp = Defrag(NULL, dc, packets[0]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[1]);
tp = Defrag(NULL, dc, packets[1]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[2]);
tp = Defrag(NULL, dc, packets[2]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[3]);
tp = Defrag(NULL, dc, packets[3]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[4]);
tp = Defrag(NULL, dc, packets[4]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[5]);
tp = Defrag(NULL, dc, packets[5]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[6]);
tp = Defrag(NULL, dc, packets[6]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[7]);
tp = Defrag(NULL, dc, packets[7]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[8]);
tp = Defrag(NULL, dc, packets[8]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[9]);
tp = Defrag(NULL, dc, packets[9]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[10]);
tp = Defrag(NULL, dc, packets[10]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[11]);
tp = Defrag(NULL, dc, packets[11]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[12]);
tp = Defrag(NULL, dc, packets[12]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[13]);
tp = Defrag(NULL, dc, packets[13]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[14]);
tp = Defrag(NULL, dc, packets[14]);
if (tp != NULL) {
free(tp);
goto end;
}
tp = Defrag6(NULL, dc, packets[15]);
tp = Defrag(NULL, dc, packets[15]);
if (tp != NULL) {
free(tp);
goto end;
}
/* And now the last one. */
Packet *reassembled = Defrag6(NULL, dc, packets[16]);
Packet *reassembled = Defrag(NULL, dc, packets[16]);
if (reassembled == NULL)
goto end;
if (memcmp(reassembled->pkt + 40, expected, expected_len) != 0)
@ -2111,7 +2065,7 @@ DefragTimeoutTest(void)
if (p == NULL)
goto end;
Packet *tp = Defrag4(NULL, dc, p);
Packet *tp = Defrag(NULL, dc, p);
free(p);
@ -2128,7 +2082,7 @@ DefragTimeoutTest(void)
goto end;
p->ts.tv_sec += dc->timeout;
Packet *tp = Defrag4(NULL, dc, p);
Packet *tp = Defrag(NULL, dc, p);
free(p);

@ -14,8 +14,7 @@
typedef struct _DefragContext DefragContext;
void DefragInit(void);
Packet *Defrag4(ThreadVars *, DefragContext *, Packet *);
Packet *Defrag6(ThreadVars *, DefragContext *, Packet *);
Packet *Defrag(ThreadVars *, DefragContext *, Packet *);
void DefragRegisterTests(void);
#endif /* __DEFRAG_H__ */

Loading…
Cancel
Save