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 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 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 Fragmentation overlap"; decode-event:ipv4.frag.overlap; sid:22000068; 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 Fragmentation overlap"; decode-event:ipv6.frag.overlap; sid:22000070; 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: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:22000071; rev:1;)

@ -145,32 +145,45 @@ typedef struct Frag_ {
TAILQ_ENTRY(Frag_) next; /**< Pointer to next fragment for tailq. */
} 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
* single packet.
*/
typedef struct DefragTracker_ {
SCMutex lock; /**< Mutex for locking list operations on
* this tracker. */
DefragContext *dc; /**< The defragmentation context this tracker
* 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
* AF_INET6. */
uint32_t id; /**< IP ID for this tracker. 32 bits for IPv6, 16
* for IPv4. */
uint8_t seen_last; /**< Has this tracker seen the last fragment? */
Address src_addr; /**< Source 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. */
} DefragTracker;
@ -341,13 +354,8 @@ DefragTrackerFreeFrags(DefragTracker *tracker)
static void
DefragTrackerReset(DefragTracker *tracker)
{
DefragContext *saved_dc = tracker->dc;
SCMutex saved_lock = tracker->lock;
DefragTrackerFreeFrags(tracker);
memset(tracker, 0, sizeof(*tracker));
tracker->dc = saved_dc;
tracker->lock = saved_lock;
DEFRAG_TRACKER_RESET(tracker);
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. */
uint16_t frag_hdr_offset = 0;
/* Address family */
int af = tracker->af;
#ifdef DEBUG
uint64_t pcap_cnt = p->pcap_cnt;
#endif
@ -781,7 +792,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
* maximum size of a packet. */
if (IPV4_HEADER_LEN + frag_offset + data_len > IPV4_MAXPACKET_LEN) {
DECODER_SET_EVENT(p, IPV4_FRAG_PKT_TOO_LARGE);
return NULL;;
return NULL;
}
}
else if (tracker->af == AF_INET6) {
@ -812,8 +823,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
SCMutexLock(&tracker->lock);
/* Update timeout. */
tracker->timeout = p->ts;
tracker->timeout.tv_sec += dc->timeout;
tracker->timeout = p->ts.tv_sec + dc->timeout;
Frag *prev = NULL, *next;
int overlap = 0;
@ -916,8 +926,8 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
}
}
}
insert:
insert:
if (data_len - ltrim <= 0) {
goto done;
}
@ -983,7 +993,7 @@ insert:
done:
if (overlap) {
if (tracker->af == AF_INET) {
if (af == AF_INET) {
DECODER_SET_EVENT(p, IPV4_FRAG_OVERLAP);
}
else {
@ -1010,14 +1020,12 @@ static void
DefragTimeoutTracker(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
Packet *p)
{
struct timeval now = p->ts;
HashListTableBucket *next = HashListTableGetListHead(dc->frag_table);
DefragTracker *tracker;
while (next != NULL) {
tracker = HashListTableGetListData(next);
if (timercmp(&tracker->timeout, &now, <)) {
if (tracker->timeout < (uint)p->ts.tv_sec) {
/* Tracker has timeout out. */
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
DefragTrackerReset(tracker);
@ -2425,7 +2433,7 @@ DefragTimeoutTest(void)
if (p == NULL)
goto end;
p->ts.tv_sec += dc->timeout;
p->ts.tv_sec += (dc->timeout + 1);
Packet *tp = Defrag(NULL, NULL, dc, p);
SCFree(p);

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

Loading…
Cancel
Save