diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 5daa1e82d7..a0e1e36e14 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -2412,6 +2412,9 @@ int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ opposing_stream = &ssn->client; } + /* Create the pseudo packet from the reassembled stream to detect the attack */ + StreamTcpReassemblePseudoPacketCreate(opposing_stream, p, pq); + /* handle ack received */ if (StreamTcpReassembleHandleSegmentUpdateACK(ra_ctx, ssn, opposing_stream, p) != 0) { @@ -2435,6 +2438,95 @@ int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ SCReturnInt(0); } +/** + * \brief Function to fetch a packet from the packet allocation queue for + * creation of the pseudo packet from the reassembled stream. + * + * @param parent Pointer to the parent of the pseudo packet + * @param pkt pointer to the raw packet of the parent + * @param len length of the packet + * @return upon success returns the pointer to the new pseudo packet + * otherwise NULL + */ +Packet *StreamTcpReassemblePseudoSetup(Packet *parent, uint8_t *pkt, uint32_t len) +{ + Packet *p = PacketGetFromQueueOrAlloc(); + if (p == NULL || len == 0) { + return NULL; + } + + /* 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 */ + p->tunnel_proto = parent->proto; + p->pktlen = len; + memcpy(&p->pkt, pkt, (len - parent->payload_len)); + p->recursion_level = parent->recursion_level + 1; + 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); + + return p; +} + +/** + * \brief Function to setup the IP and TCP header of the pseudo packet from + * the newly copied raw packet contents of the parent. + * + * @param np pointer to the pseudo packet + * @param p pointer to the original packet + */ +void StreamTcpReassemblePseudoPacketSetupHeader(Packet *np, Packet *p) +{ + /* Setup the IP header */ + if (PKT_IS_IPV4(p)) { + np->ip4h = (IPV4Hdr *)(np->pkt + (np->pktlen - IPV4_GET_IPLEN(p))); + PSUEDO_PKT_SET_IPV4HDR(np->ip4h, p->ip4h); + + /* Similarly setup the TCP header with ports in opposite direction */ + np->tcph = (TCPHdr *)(np->ip4h + IPV4_GET_HLEN(p)); + PSUEDO_PKT_SET_TCPHDR(np->tcph, p->tcph); + + /* Setup the adress and port details */ + SET_IPV4_SRC_ADDR(np, &np->src); + SET_IPV4_DST_ADDR(np, &np->dst); + SET_TCP_SRC_PORT(np, &np->sp); + SET_TCP_DST_PORT(np, &np->dp); + + } else if (PKT_IS_IPV6(p)) { + np->ip6h = (IPV6Hdr *)(np->pkt + (np->pktlen - IPV6_GET_PLEN(p) - IPV6_HEADER_LEN)); + PSUEDO_PKT_SET_IPV6HDR(np->ip6h, p->ip6h); + + /* Similarly setup the TCP header with ports in opposite direction */ + np->tcph = (TCPHdr *)(np->ip6h + IPV6_HEADER_LEN); + PSUEDO_PKT_SET_TCPHDR(np->tcph, p->tcph); + + /* Setup the adress and port details */ + SET_IPV6_SRC_ADDR(np, &np->src); + SET_IPV6_DST_ADDR(np, &np->dst); + SET_TCP_SRC_PORT(np, &np->sp); + SET_TCP_DST_PORT(np, &np->dp); + } + + /* Setup the payload pointer to the starting of payload location as in the + original packet, so that we don't overwrite the protocols headers */ + np->payload = np->pkt + (np->pktlen - p->payload_len); + np->payload_len = 0; +} + /** * \brief Function to copy the reassembled stream segments in to the pseudo * packet payload. diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 05afe3a863..5df89a7c46 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -7771,6 +7771,7 @@ void StreamTcpRegisterTests (void) { /* set up the reassembly tests as well */ StreamTcpReassembleRegisterTests(); + #endif /* UNITTESTS */ }