From dcb81c0edc8840a2db8282e057fa96052be747f2 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Mon, 8 Feb 2010 23:23:12 -0800 Subject: [PATCH] Issue 82 - fragment counters. - number of fragments - number reassembled - number of timeouts --- src/decode-ipv4.c | 2 +- src/decode-ipv6.c | 2 +- src/decode.c | 8 ++++ src/decode.h | 5 +++ src/defrag.c | 103 ++++++++++++++++++++++++++++++----------------------- src/defrag.h | 2 +- 6 files changed, 74 insertions(+), 48 deletions(-) diff --git a/src/decode-ipv4.c b/src/decode-ipv4.c index e220815..f08c7f6 100644 --- a/src/decode-ipv4.c +++ b/src/decode-ipv4.c @@ -619,7 +619,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 = Defrag(tv, NULL, p); + Packet *rp = Defrag(tv, dtv, 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 5390825..e066957 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -416,7 +416,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, /* Pass to defragger if a fragment. */ if (IPV6_EXTHDR_ISSET_FH(p)) { - Packet *rp = Defrag(tv, NULL, p); + Packet *rp = Defrag(tv, dtv, NULL, p); if (rp != NULL) { DecodeIPV6(tv, dtv, rp, rp->pkt, rp->pktlen, pq); PacketEnqueue(pq, rp); diff --git a/src/decode.c b/src/decode.c index 99ef9e3..979ab22 100644 --- a/src/decode.c +++ b/src/decode.c @@ -87,6 +87,14 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_defrag_fragments = SCPerfTVRegisterCounter("defrag.fragments", + tv, SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_defrag_reassembled = + SCPerfTVRegisterCounter("defrag.reassembled", tv, SC_PERF_TYPE_UINT64, + "NULL"); + dtv->counter_defrag_timeouts = SCPerfTVRegisterCounter("defrag.timeouts", + tv, SC_PERF_TYPE_UINT64, "NULL"); + tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); diff --git a/src/decode.h b/src/decode.h index 7064679..bd5f840 100644 --- a/src/decode.h +++ b/src/decode.h @@ -351,6 +351,11 @@ typedef struct DecodeThreadVars_ uint16_t counter_pppoe; uint16_t counter_avg_pkt_size; uint16_t counter_max_pkt_size; + + /** frag stats - defrag runs in the context of the decoder. */ + uint16_t counter_defrag_fragments; + uint16_t counter_defrag_reassembled; + uint16_t counter_defrag_timeouts; } DecodeThreadVars; /* clear key vars so we don't need to call the expensive diff --git a/src/defrag.c b/src/defrag.c index b0d878d..848413a 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -715,8 +715,8 @@ done: * \todo Allocate packet buffers from a pool. */ static Packet * -DefragInsertFrag(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker, - Packet *p) +DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc, + DefragTracker *tracker, Packet *p) { Packet *r = NULL; int ltrim = 0; @@ -926,6 +926,9 @@ insert: else if (tracker->af == AF_INET6) r = Defrag6Reassemble(tv, dc, tracker, p); } + if (r != NULL && tv != NULL && dtv != NULL) { + SCPerfCounterIncr(dtv->counter_defrag_reassembled, tv->sc_perf_pca); + } done: SCMutexUnlock(&tracker->lock); @@ -945,20 +948,25 @@ done: * \param p Packet that triggered this timeout run, used for timestamp. */ static void -DefragTimeoutTracker(DefragContext *dc, Packet *p) +DefragTimeoutTracker(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc, + Packet *p) { - struct timeval tv = p->ts; + struct timeval now = p->ts; HashListTableBucket *next = HashListTableGetListHead(dc->frag_table); DefragTracker *tracker; while (next != NULL) { tracker = HashListTableGetListData(next); - if (timercmp(&tracker->timeout, &tv, <)) { + if (timercmp(&tracker->timeout, &now, <)) { /* Tracker has timeout out. */ HashListTableRemove(dc->frag_table, tracker, sizeof(tracker)); DefragTrackerReset(tracker); PoolReturn(dc->tracker_pool, tracker); + if (tv != NULL && dtv != NULL) { + SCPerfCounterIncr(dtv->counter_defrag_timeouts, + tv->sc_perf_pca); + } return; } @@ -967,7 +975,8 @@ DefragTimeoutTracker(DefragContext *dc, Packet *p) } static DefragTracker * -DefragGetTracker(DefragContext *dc, DefragTracker *lookup_key, Packet *p) +DefragGetTracker(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc, + DefragTracker *lookup_key, Packet *p) { DefragTracker *tracker; @@ -979,7 +988,7 @@ DefragGetTracker(DefragContext *dc, DefragTracker *lookup_key, Packet *p) tracker = PoolGet(dc->tracker_pool); if (tracker == NULL) { /* Timeout trackers and try again. */ - DefragTimeoutTracker(dc, p); + DefragTimeoutTracker(tv, dtv, dc, p); tracker = PoolGet(dc->tracker_pool); } SCMutexUnlock(&dc->tracker_pool_lock); @@ -1025,7 +1034,7 @@ done: * NULL is returned. */ Packet * -Defrag(ThreadVars *tv, DefragContext *dc, Packet *p) +Defrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc, Packet *p) { uint16_t frag_offset; uint8_t more_frags; @@ -1058,17 +1067,21 @@ Defrag(ThreadVars *tv, DefragContext *dc, Packet *p) return NULL; } + if (tv != NULL && dtv != NULL) { + SCPerfCounterIncr(dtv->counter_defrag_fragments, tv->sc_perf_pca); + } + /* Create a lookup key. */ lookup.af = af; lookup.id = id; lookup.src_addr = p->src; lookup.dst_addr = p->dst; - tracker = DefragGetTracker(dc, &lookup, p); + tracker = DefragGetTracker(tv, dtv, dc, &lookup, p); if (tracker == NULL) return NULL; - return DefragInsertFrag(tv, dc, tracker, p); + return DefragInsertFrag(tv, dtv, dc, tracker, p); } void @@ -1250,12 +1263,12 @@ DefragInOrderSimpleTest(void) if (p3 == NULL) goto end; - if (Defrag(NULL, dc, p1) != NULL) + if (Defrag(NULL, NULL, dc, p1) != NULL) goto end; - if (Defrag(NULL, dc, p2) != NULL) + if (Defrag(NULL, NULL, dc, p2) != NULL) goto end; - reassembled = Defrag(NULL, dc, p3); + reassembled = Defrag(NULL, NULL, dc, p3); if (reassembled == NULL) goto end; @@ -1329,12 +1342,12 @@ DefragReverseSimpleTest(void) if (p3 == NULL) goto end; - if (Defrag(NULL, dc, p3) != NULL) + if (Defrag(NULL, NULL, dc, p3) != NULL) goto end; - if (Defrag(NULL, dc, p2) != NULL) + if (Defrag(NULL, NULL, dc, p2) != NULL) goto end; - reassembled = Defrag(NULL, dc, p1); + reassembled = Defrag(NULL, NULL, dc, p1); if (reassembled == NULL) goto end; @@ -1409,11 +1422,11 @@ IPV6DefragInOrderSimpleTest(void) if (p3 == NULL) goto end; - if (Defrag(NULL, dc, p1) != NULL) + if (Defrag(NULL, NULL, dc, p1) != NULL) goto end; - if (Defrag(NULL, dc, p2) != NULL) + if (Defrag(NULL, NULL, dc, p2) != NULL) goto end; - reassembled = Defrag(NULL, dc, p3); + reassembled = Defrag(NULL, NULL, dc, p3); if (reassembled == NULL) goto end; @@ -1481,11 +1494,11 @@ IPV6DefragReverseSimpleTest(void) if (p3 == NULL) goto end; - if (Defrag(NULL, dc, p3) != NULL) + if (Defrag(NULL, NULL, dc, p3) != NULL) goto end; - if (Defrag(NULL, dc, p2) != NULL) + if (Defrag(NULL, NULL, dc, p2) != NULL) goto end; - reassembled = Defrag(NULL, dc, p1); + reassembled = Defrag(NULL, NULL, dc, p1); if (reassembled == NULL) goto end; @@ -1607,7 +1620,7 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len) /* Send all but the last. */ for (i = 0; i < 16; i++) { - Packet *tp = Defrag(NULL, dc, packets[i]); + Packet *tp = Defrag(NULL, NULL, dc, packets[i]); if (tp != NULL) { free(tp); goto end; @@ -1615,7 +1628,7 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len) } /* And now the last one. */ - Packet *reassembled = Defrag(NULL, dc, packets[16]); + Packet *reassembled = Defrag(NULL, NULL, dc, packets[16]); if (reassembled == NULL) goto end; @@ -1730,89 +1743,89 @@ IPV6DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len) /* Send all but the last. */ Packet *tp; - tp = Defrag(NULL, dc, packets[0]); + tp = Defrag(NULL, NULL, dc, packets[0]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[1]); + tp = Defrag(NULL, NULL, dc, packets[1]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[2]); + tp = Defrag(NULL, NULL, dc, packets[2]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[3]); + tp = Defrag(NULL, NULL, dc, packets[3]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[4]); + tp = Defrag(NULL, NULL, dc, packets[4]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[5]); + tp = Defrag(NULL, NULL, dc, packets[5]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[6]); + tp = Defrag(NULL, NULL, dc, packets[6]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[7]); + tp = Defrag(NULL, NULL, dc, packets[7]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[8]); + tp = Defrag(NULL, NULL, dc, packets[8]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[9]); + tp = Defrag(NULL, NULL, dc, packets[9]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[10]); + tp = Defrag(NULL, NULL, dc, packets[10]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[11]); + tp = Defrag(NULL, NULL, dc, packets[11]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[12]); + tp = Defrag(NULL, NULL, dc, packets[12]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[13]); + tp = Defrag(NULL, NULL, dc, packets[13]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[14]); + tp = Defrag(NULL, NULL, dc, packets[14]); if (tp != NULL) { free(tp); goto end; } - tp = Defrag(NULL, dc, packets[15]); + tp = Defrag(NULL, NULL, dc, packets[15]); if (tp != NULL) { free(tp); goto end; } /* And now the last one. */ - Packet *reassembled = Defrag(NULL, dc, packets[16]); + Packet *reassembled = Defrag(NULL, NULL, dc, packets[16]); if (reassembled == NULL) goto end; if (memcmp(reassembled->pkt + 40, expected, expected_len) != 0) @@ -2277,7 +2290,7 @@ DefragTimeoutTest(void) if (p == NULL) goto end; - Packet *tp = Defrag(NULL, dc, p); + Packet *tp = Defrag(NULL, NULL, dc, p); free(p); @@ -2294,7 +2307,7 @@ DefragTimeoutTest(void) goto end; p->ts.tv_sec += dc->timeout; - Packet *tp = Defrag(NULL, dc, p); + Packet *tp = Defrag(NULL, NULL, dc, p); free(p); @@ -2356,7 +2369,7 @@ DefragIPv4NoDataTest(void) goto end; /* We do not expect a packet returned. */ - if (Defrag(NULL, dc, p) != NULL) + if (Defrag(NULL, NULL, dc, p) != NULL) goto end; /* The fragment should have been ignored so no fragments should @@ -2395,7 +2408,7 @@ DefragIPv4TooLargeTest(void) goto end; /* We do not expect a packet returned. */ - if (Defrag(NULL, dc, p) != NULL) + if (Defrag(NULL, NULL, dc, p) != NULL) goto end; /* The fragment should have been ignored so no fragments should have diff --git a/src/defrag.h b/src/defrag.h index 1e40b69..b1a39a1 100644 --- a/src/defrag.h +++ b/src/defrag.h @@ -14,7 +14,7 @@ typedef struct _DefragContext DefragContext; void DefragInit(void); -Packet *Defrag(ThreadVars *, DefragContext *, Packet *); +Packet *Defrag(ThreadVars *, DecodeThreadVars *, DefragContext *, Packet *); void DefragRegisterTests(void); #endif /* __DEFRAG_H__ */ -- 1.6.6