Project

General

Profile

Bug #82 ยป 0001-Issue-82-fragment-counters.patch

Jason Ish, 02/09/2010 12:57 AM

View differences:

src/decode-ipv4.c
/* 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);
src/decode-ipv6.c
/* 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);
src/decode.c
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);
src/decode.h
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
src/defrag.c
* \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;
......
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);
......
* \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;
}
......
}
static DefragTracker *
DefragGetTracker(DefragContext *dc, DefragTracker *lookup_key, Packet *p)
DefragGetTracker(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
DefragTracker *lookup_key, Packet *p)
{
DefragTracker *tracker;
......
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);
......
* 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;
......
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
......
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;
......
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;
......
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;
......
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;
......
/* 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;
......
}
/* 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;
......
/* 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)
......
if (p == NULL)
goto end;
Packet *tp = Defrag(NULL, dc, p);
Packet *tp = Defrag(NULL, NULL, dc, p);
free(p);
......
goto end;
p->ts.tv_sec += dc->timeout;
Packet *tp = Defrag(NULL, dc, p);
Packet *tp = Defrag(NULL, NULL, dc, p);
free(p);
......
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
......
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
src/defrag.h
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-1/1)