diff --git a/src/source-nfq.c b/src/source-nfq.c index 9e01754136..23167adfc0 100644 --- a/src/source-nfq.c +++ b/src/source-nfq.c @@ -573,7 +573,11 @@ void NFQSetVerdict(NFQThreadVars *t, Packet *p) { } SCMutexLock(&t->mutex_qh); - ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, 0, NULL); + if (p->flags & PKT_STREAM_MODIFIED) { + ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, GET_PKT_LEN(p), GET_PKT_DATA(p)); + } else { + ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, 0, NULL); + } SCMutexUnlock(&t->mutex_qh); if (ret < 0) { diff --git a/src/stream-tcp-inline.c b/src/stream-tcp-inline.c index 60f6d38b2d..0088a3f16a 100644 --- a/src/stream-tcp-inline.c +++ b/src/stream-tcp-inline.c @@ -180,6 +180,39 @@ void StreamTcpInlineSegmentReplacePacket(Packet *p, TcpSegment *seg) { } } +/** + * \brief Recalculate the csum for a modified packet + * + * \param p packet to inspect + */ +void StreamTcpInlineRecalcCsum(Packet *p) { + if (!(p->flags & PKT_STREAM_MODIFIED)) { + SCReturn; + } + + if (!(PKT_IS_TCP(p))) { + SCReturn; + } + + if (PKT_IS_IPV4(p)) { + /* TCP */ + p->tcph->th_sum = 0; + p->tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p->ip4h->ip_src), + (uint16_t *)p->tcph, (p->payload_len + p->tcpvars.hlen)); + /* IPV4 */ + p->ip4h->ip_csum = 0; + p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h, + IPV4_GET_RAW_HLEN(p->ip4h)); + } else if (PKT_IS_IPV6(p)) { + /* just TCP for IPV6 */ + p->tcph->th_sum = 0; + p->tcph->th_sum = TCPV6CalculateChecksum((uint16_t *)&(p->ip6h->ip6_src), + (uint16_t *)p->tcph, (p->payload_len + p->tcpvars.hlen)); + } + + SCReturn; +} + #ifdef UNITTESTS /** \test full overlap */ diff --git a/src/stream-tcp-inline.h b/src/stream-tcp-inline.h index 49d4978176..3b382c38ad 100644 --- a/src/stream-tcp-inline.h +++ b/src/stream-tcp-inline.h @@ -29,6 +29,7 @@ int StreamTcpInlineMode(void); int StreamTcpInlineSegmentCompare(TcpSegment *, TcpSegment *); void StreamTcpInlineSegmentReplacePacket(Packet *, TcpSegment *); +void StreamTcpInlineRecalcCsum(Packet *); void StreamTcpInlineRegisterTests(void); diff --git a/src/stream-tcp.c b/src/stream-tcp.c index f6a79985b4..2a6169c5f3 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -49,6 +49,7 @@ #include "stream-tcp-private.h" #include "stream-tcp-reassemble.h" #include "stream-tcp.h" +#include "stream-tcp-inline.h" #include "stream-tcp-util.h" #include "stream.h" @@ -3255,7 +3256,7 @@ static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt, SCLogDebug("reusing closed TCP session"); if (StreamTcpPacketStateNone(tv,p,stt,ssn, &stt->pseudo_queue)) { - SCReturnInt(-1); + goto error; } } else { SCLogDebug("packet received on closed state"); @@ -3304,6 +3305,11 @@ static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt, goto error; } + /* recalc the csum on the packet if it was modified */ + if (p->flags & PKT_STREAM_MODIFIED) { + StreamTcpInlineRecalcCsum(p); + } + SCReturnInt(0); error: @@ -3314,6 +3320,15 @@ error: PacketEnqueue(pq, np); } } + + /* recalc the csum on the packet if it was modified */ + if (p->flags & PKT_STREAM_MODIFIED) { + StreamTcpInlineRecalcCsum(p); + } + + if (StreamTcpInlineMode()) { + p->action |= ACTION_DROP; + } SCReturnInt(-1); }