Don't set ip{4,6} header on reassembled ip packet until we know for sure what buffer the packet is stored in.

remotes/origin/master-1.1.x
Victor Julien 14 years ago
parent f5674eff74
commit 03ea563e93

@ -138,6 +138,10 @@ typedef struct Frag_ {
int8_t skip; /**< Skip this fragment during re-assembly. */
#ifdef DEBUG
uint64_t pcap_cnt; /* pcap_cnt of original packet */
#endif
TAILQ_ENTRY(Frag_) next; /**< Pointer to next fragment for tailq. */
} Frag;
@ -539,6 +543,9 @@ Defrag4Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
int hlen = 0;
int ip_hdr_offset = 0;
TAILQ_FOREACH(frag, &tracker->frags, next) {
SCLogDebug("frag %p, data_len %u, offset %u, pcap_cnt %"PRIu64,
frag, frag->data_len, frag->offset, frag->pcap_cnt);
if (frag->skip)
continue;
if (frag->data_len - frag->ltrim <= 0)
@ -556,7 +563,6 @@ Defrag4Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
SCLogDebug("Packet rp %p, p %p, rp->root %p", rp, p, rp->root);
rp->recursion_level = p->recursion_level;
rp->ip4h = (IPV4Hdr *)(GET_PKT_DATA(rp) + frag->ip_hdr_offset);
hlen = frag->hlen;
ip_hdr_offset = frag->ip_hdr_offset;
@ -569,7 +575,8 @@ Defrag4Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
else {
int pkt_end = fragmentable_offset + frag->offset + frag->data_len;
if (pkt_end > (int)MAX_PAYLOAD_SIZE) {
SCLogWarning(SC_ERR_REASSEMBLY, "Failed re-assemble fragmented packet, exceeds size of packet buffer.");
SCLogWarning(SC_ERR_REASSEMBLY, "Failed re-assemble "
"fragmented packet, exceeds size of packet buffer.");
goto remove_tracker;
}
if (PacketCopyDataOffset(rp, fragmentable_offset + frag->offset + frag->ltrim,
@ -581,8 +588,11 @@ Defrag4Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
fragmentable_len = frag->offset + frag->data_len;
}
}
BUG_ON(rp->ip4h == NULL);
SCLogDebug("ip_hdr_offset %u, hlen %u, fragmentable_len %u",
ip_hdr_offset, hlen, fragmentable_len);
rp->ip4h = (IPV4Hdr *)(GET_PKT_DATA(rp) + ip_hdr_offset);
int old = rp->ip4h->ip_len + rp->ip4h->ip_off;
rp->ip4h->ip_len = htons(fragmentable_len + hlen);
rp->ip4h->ip_off = 0;
@ -679,7 +689,6 @@ Defrag6Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
frag->pkt + frag->frag_hdr_offset + sizeof(IPV6FragHdr),
frag->data_len) == -1)
goto remove_tracker;
rp->ip6h = (IPV6Hdr *)(GET_PKT_DATA(rp) + frag->ip_hdr_offset);
ip_hdr_offset = frag->ip_hdr_offset;
/* This is the start of the fragmentable portion of the
@ -697,7 +706,8 @@ Defrag6Reassemble(ThreadVars *tv, DefragContext *dc, DefragTracker *tracker,
fragmentable_len = frag->offset + frag->data_len;
}
}
BUG_ON(rp->ip6h == NULL);
rp->ip6h = (IPV6Hdr *)(GET_PKT_DATA(rp) + ip_hdr_offset);
rp->ip6h->s_ip6_plen = htons(fragmentable_len);
rp->ip6h->s_ip6_nxt = next_hdr;
SET_PKT_LEN(rp, ip_hdr_offset + sizeof(IPV6Hdr) + fragmentable_len);
@ -752,6 +762,10 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
/* Offset in the packet to the IPv6 frag header. IPv6 only. */
uint16_t frag_hdr_offset = 0;
#ifdef DEBUG
uint64_t pcap_cnt = p->pcap_cnt;
#endif
if (tracker->af == AF_INET) {
more_frags = IPV4_GET_MF(p);
frag_offset = IPV4_GET_IPOFFSET(p) << 3;
@ -911,6 +925,9 @@ insert:
new->data_len = data_len - ltrim;
new->ip_hdr_offset = ip_hdr_offset;
new->frag_hdr_offset = frag_hdr_offset;
#ifdef DEBUG
new->pcap_cnt = pcap_cnt;
#endif
Frag *frag;
TAILQ_FOREACH(frag, &tracker->frags, next) {

Loading…
Cancel
Save