From 79691f675add835ac9151b67f087b84072148911 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 4 Apr 2012 11:18:15 +0200 Subject: [PATCH] defrag: don't increment recursion level for reassembled packets. Fixes defragged packets not seeing the same flow. --- src/decode.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/decode.h | 3 ++- src/defrag.c | 4 ++-- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/decode.c b/src/decode.c index d345c84036..95b1c3d960 100644 --- a/src/decode.c +++ b/src/decode.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2012 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -125,7 +125,7 @@ Packet *PacketGetFromQueueOrAlloc(void) } /** - * \brief Setup a pseudo packet (tunnel or reassembled frags) + * \brief Setup a pseudo packet (tunnel) * * \param parent parent packet for this pseudo pkt * \param pkt raw packet data @@ -173,6 +173,58 @@ Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t SCReturnPtr(p, "Packet"); } +/** + * \brief Setup a pseudo packet (reassembled frags) + * + * Difference with PacketPseudoPktSetup is that this func doesn't increment + * the recursion level. It needs to be on the same level as the frags because + * we run the flow engine against this and we need to get the same flow. + * + * \param parent parent packet for this pseudo pkt + * \param pkt raw packet data + * \param len packet data length + * \param proto protocol of the tunneled packet + * + * \retval p the pseudo packet or NULL if out of memory + */ +Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto) { + SCEnter(); + + /* get us a packet */ + Packet *p = PacketGetFromQueueOrAlloc(); + if (p == NULL) { + SCReturnPtr(NULL, "Packet"); + } + + /* set the root ptr to the lowest layer */ + if (parent->root != NULL) + p->root = parent->root; + else + p->root = parent; + + /* copy packet and set lenght, proto */ + PacketCopyData(p, pkt, len); + p->recursion_level = parent->recursion_level; /* NOT incremented */ + p->ts.tv_sec = parent->ts.tv_sec; + p->ts.tv_usec = parent->ts.tv_usec; + + /* set tunnel flags */ + + /* tell new packet it's part of a tunnel */ + SET_TUNNEL_PKT(p); + /* tell parent packet it's part of a tunnel */ + SET_TUNNEL_PKT(parent); + + /* increment tunnel packet refcnt in the root packet */ + TUNNEL_INCR_PKT_TPR(p); + + /* disable payload (not packet) inspection on the parent, as the payload + * is the packet we will now run through the system separately. We do + * check it against the ip/port/other header checks though */ + DecodeSetNoPayloadInspectionFlag(parent); + SCReturnPtr(p, "Packet"); +} + void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) { /* register counters */ diff --git a/src/decode.h b/src/decode.h index e4228f04f9..42e3770569 100644 --- a/src/decode.h +++ b/src/decode.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2012 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -788,6 +788,7 @@ typedef struct DecodeThreadVars_ void DecodeRegisterPerfCounters(DecodeThreadVars *, ThreadVars *); Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto); +Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto); Packet *PacketGetFromQueueOrAlloc(void); Packet *PacketGetFromAlloc(void); int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen); diff --git a/src/defrag.c b/src/defrag.c index ee311bcf4d..0aafe4b84f 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -548,7 +548,7 @@ Defrag4Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker, /* Allocate a Packet for the reassembled packet. On failure we * SCFree all the resources held by this tracker. */ - rp = PacketPseudoPktSetup(p, NULL, 0, IPV4_GET_IPPROTO(p)); + rp = PacketDefragPktSetup(p, NULL, 0, IPV4_GET_IPPROTO(p)); if (rp == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for " "fragmentation re-assembly, dumping fragments."); @@ -668,7 +668,7 @@ Defrag6Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker, /* Allocate a Packet for the reassembled packet. On failure we * SCFree all the resources held by this tracker. */ - rp = PacketPseudoPktSetup(p, (uint8_t *)p->ip6h, + rp = PacketDefragPktSetup(p, (uint8_t *)p->ip6h, IPV6_GET_PLEN(p) + sizeof(IPV6Hdr), 0); if (rp == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for "