Minor fixes in defrag engine, shrink DefragTracker_ structure.

remotes/origin/master-1.1.x
Victor Julien 15 years ago
parent 0385f72669
commit 83c3f15812

@ -69,9 +69,9 @@ alert pkthdr any any -> any any (msg:"SURICATA GRE v1 header too big"; decode-ev
alert pkthdr any any -> any any (msg:"SURICATA VLAN header too small "; decode-event:vlan.header_too_small; sid:22000065; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA VLAN header too small "; decode-event:vlan.header_too_small; sid:22000065; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA VLAN unknown type"; decode-event:vlan.unknown_type; sid:22000066; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA VLAN unknown type"; decode-event:vlan.unknown_type; sid:22000066; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA IP raw invalid IP version "; decode-event:ipraw.invalid_ip_version; sid:22000067; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA IP raw invalid IP version "; decode-event:ipraw.invalid_ip_version; sid:22000067; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv4 Packet size too large"; decode-event:ipv4.frag.too_large; sid:22000067; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv4 Packet size too large"; decode-event:ipv4.frag_too_large; sid:22000068; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv4 Fragmentation overlap"; decode-event:ipv4.frag.overlap; sid:22000068; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv4 Fragmentation overlap"; decode-event:ipv4.frag_overlap; sid:22000069; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv6 Packet size too large"; decode-event:ipv6.frag.too_large; sid:22000069; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv6 Packet size too large"; decode-event:ipv6.frag_too_large; sid:22000070; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv6 Fragmentation overlap"; decode-event:ipv6.frag.overlap; sid:22000070; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv6 Fragmentation overlap"; decode-event:ipv6.frag_overlap; sid:22000071; rev:1;)

@ -145,32 +145,45 @@ typedef struct Frag_ {
TAILQ_ENTRY(Frag_) next; /**< Pointer to next fragment for tailq. */ TAILQ_ENTRY(Frag_) next; /**< Pointer to next fragment for tailq. */
} Frag; } Frag;
/** \brief Reset tracker fields except "dc" and "lock" */
#define DEFRAG_TRACKER_RESET(t) { \
(t)->timeout = 0; \
(t)->id = 0; \
(t)->policy = 0; \
(t)->af = 0; \
(t)->seen_last = 0; \
CLEAR_ADDR(&(t)->src_addr); \
CLEAR_ADDR(&(t)->dst_addr); \
(t)->frags.tqh_first = NULL; \
(t)->frags.tqh_last = NULL; \
}
/** /**
* A defragmentation tracker. Used to track fragments that make up a * A defragmentation tracker. Used to track fragments that make up a
* single packet. * single packet.
*/ */
typedef struct DefragTracker_ { typedef struct DefragTracker_ {
SCMutex lock; /**< Mutex for locking list operations on
* this tracker. */
DefragContext *dc; /**< The defragmentation context this tracker DefragContext *dc; /**< The defragmentation context this tracker
* was allocated under. */ * was allocated under. */
uint8_t policy; /**< Reassembly policy this tracker will use. */ uint32_t timeout; /**< When this tracker will timeout. */
struct timeval timeout; /**< When this tracker will timeout. */ uint32_t id; /**< IP ID for this tracker. 32 bits for IPv6, 16
* for IPv4. */
uint8_t policy; /**< Reassembly policy this tracker will use. */
uint8_t af; /**< Address family for this tracker, AF_INET or uint8_t af; /**< Address family for this tracker, AF_INET or
* AF_INET6. */ * AF_INET6. */
uint32_t id; /**< IP ID for this tracker. 32 bits for IPv6, 16 uint8_t seen_last; /**< Has this tracker seen the last fragment? */
* for IPv4. */
Address src_addr; /**< Source address for this tracker. */ Address src_addr; /**< Source address for this tracker. */
Address dst_addr; /**< Destination address for this tracker. */ Address dst_addr; /**< Destination address for this tracker. */
uint8_t seen_last; /**< Has this tracker seen the last fragment? */
SCMutex lock; /**< Mutex for locking list operations on
* this tracker. */
TAILQ_HEAD(frag_tailq, Frag_) frags; /**< Head of list of fragments. */ TAILQ_HEAD(frag_tailq, Frag_) frags; /**< Head of list of fragments. */
} DefragTracker; } DefragTracker;
@ -341,13 +354,8 @@ DefragTrackerFreeFrags(DefragTracker *tracker)
static void static void
DefragTrackerReset(DefragTracker *tracker) DefragTrackerReset(DefragTracker *tracker)
{ {
DefragContext *saved_dc = tracker->dc;
SCMutex saved_lock = tracker->lock;
DefragTrackerFreeFrags(tracker); DefragTrackerFreeFrags(tracker);
memset(tracker, 0, sizeof(*tracker)); DEFRAG_TRACKER_RESET(tracker);
tracker->dc = saved_dc;
tracker->lock = saved_lock;
TAILQ_INIT(&tracker->frags); TAILQ_INIT(&tracker->frags);
} }
@ -764,6 +772,9 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
/* Offset in the packet to the IPv6 frag header. IPv6 only. */ /* Offset in the packet to the IPv6 frag header. IPv6 only. */
uint16_t frag_hdr_offset = 0; uint16_t frag_hdr_offset = 0;
/* Address family */
int af = tracker->af;
#ifdef DEBUG #ifdef DEBUG
uint64_t pcap_cnt = p->pcap_cnt; uint64_t pcap_cnt = p->pcap_cnt;
#endif #endif
@ -781,7 +792,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
* maximum size of a packet. */ * maximum size of a packet. */
if (IPV4_HEADER_LEN + frag_offset + data_len > IPV4_MAXPACKET_LEN) { if (IPV4_HEADER_LEN + frag_offset + data_len > IPV4_MAXPACKET_LEN) {
DECODER_SET_EVENT(p, IPV4_FRAG_PKT_TOO_LARGE); DECODER_SET_EVENT(p, IPV4_FRAG_PKT_TOO_LARGE);
return NULL;; return NULL;
} }
} }
else if (tracker->af == AF_INET6) { else if (tracker->af == AF_INET6) {
@ -812,8 +823,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
SCMutexLock(&tracker->lock); SCMutexLock(&tracker->lock);
/* Update timeout. */ /* Update timeout. */
tracker->timeout = p->ts; tracker->timeout = p->ts.tv_sec + dc->timeout;
tracker->timeout.tv_sec += dc->timeout;
Frag *prev = NULL, *next; Frag *prev = NULL, *next;
int overlap = 0; int overlap = 0;
@ -916,8 +926,8 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
} }
} }
} }
insert:
insert:
if (data_len - ltrim <= 0) { if (data_len - ltrim <= 0) {
goto done; goto done;
} }
@ -983,7 +993,7 @@ insert:
done: done:
if (overlap) { if (overlap) {
if (tracker->af == AF_INET) { if (af == AF_INET) {
DECODER_SET_EVENT(p, IPV4_FRAG_OVERLAP); DECODER_SET_EVENT(p, IPV4_FRAG_OVERLAP);
} }
else { else {
@ -1010,14 +1020,12 @@ static void
DefragTimeoutTracker(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc, DefragTimeoutTracker(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
Packet *p) Packet *p)
{ {
struct timeval now = p->ts;
HashListTableBucket *next = HashListTableGetListHead(dc->frag_table); HashListTableBucket *next = HashListTableGetListHead(dc->frag_table);
DefragTracker *tracker; DefragTracker *tracker;
while (next != NULL) { while (next != NULL) {
tracker = HashListTableGetListData(next); tracker = HashListTableGetListData(next);
if (timercmp(&tracker->timeout, &now, <)) { if (tracker->timeout < (uint)p->ts.tv_sec) {
/* Tracker has timeout out. */ /* Tracker has timeout out. */
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker)); HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
DefragTrackerReset(tracker); DefragTrackerReset(tracker);
@ -2425,7 +2433,7 @@ DefragTimeoutTest(void)
if (p == NULL) if (p == NULL)
goto end; goto end;
p->ts.tv_sec += dc->timeout; p->ts.tv_sec += (dc->timeout + 1);
Packet *tp = Defrag(NULL, NULL, dc, p); Packet *tp = Defrag(NULL, NULL, dc, p);
SCFree(p); SCFree(p);

@ -110,10 +110,10 @@ struct DetectDecodeEvents_ {
{ "ipraw.invalid_ip_version",IPRAW_INVALID_IPV, }, { "ipraw.invalid_ip_version",IPRAW_INVALID_IPV, },
{ "vlan.header_too_small",VLAN_HEADER_TOO_SMALL, }, { "vlan.header_too_small",VLAN_HEADER_TOO_SMALL, },
{ "vlan.unknown_type",VLAN_UNKNOWN_TYPE, }, { "vlan.unknown_type",VLAN_UNKNOWN_TYPE, },
{ "ipv4.frag.too_large", IPV4_FRAG_PKT_TOO_LARGE, }, { "ipv4.frag_too_large", IPV4_FRAG_PKT_TOO_LARGE, },
{ "ipv4.frag.overlap", IPV4_FRAG_OVERLAP, }, { "ipv4.frag_overlap", IPV4_FRAG_OVERLAP, },
{ "ipv6.frag.too_large", IPV6_FRAG_PKT_TOO_LARGE, }, { "ipv6.frag_too_large", IPV6_FRAG_PKT_TOO_LARGE, },
{ "ipv6.frag.overlap", IPV6_FRAG_OVERLAP, }, { "ipv6.frag_overlap", IPV6_FRAG_OVERLAP, },
{ NULL, 0 }, { NULL, 0 },
}; };
#endif /* DETECT_EVENTS */ #endif /* DETECT_EVENTS */

Loading…
Cancel
Save