From 6547725b39b1d76b01fa23b68ff06ccce40ca8d3 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Wed, 6 Jan 2010 23:35:26 -0800 Subject: [PATCH] consolidate more common code between ipv4 and ipv6. --- src/decode-ipv4.c | 2 +- src/decode-ipv6.c | 2 +- src/defrag.c | 162 +++++++++++++++++----------------------------- src/defrag.h | 3 +- 4 files changed, 61 insertions(+), 108 deletions(-) diff --git a/src/decode-ipv4.c b/src/decode-ipv4.c index 9195b7f4f2..f957e5482a 100644 --- a/src/decode-ipv4.c +++ b/src/decode-ipv4.c @@ -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); diff --git a/src/decode-ipv6.c b/src/decode-ipv6.c index 6090879119..2ac05ff5ad 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -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. */ } diff --git a/src/defrag.c b/src/defrag.c index 71af595f31..8a8a0859ce 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -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); diff --git a/src/defrag.h b/src/defrag.h index d65f86d655..1e40b69dec 100644 --- a/src/defrag.h +++ b/src/defrag.h @@ -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__ */