void StreamTcpInitConfig(char);
int StreamTcpGetFlowState(void *);
void StreamTcpSetOSPolicy(TcpStream*, Packet*);
-void StreamTcpPseudoPacketCreateStreamEndPacket(ThreadVars *tv, StreamTcpThread *stt, Packet *p, TcpSession *ssn, PacketQueue *pq);
static int StreamTcpValidateTimestamp(TcpSession * , Packet *);
static int StreamTcpHandleTimestamp(TcpSession * , Packet *);
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
- */
-static void StreamTcpPseudoPacketSetupHeader(Packet *np, Packet *p)
-{
- /* Setup the IP header */
- if (PKT_IS_IPV4(p)) {
- np->ip4h = (IPV4Hdr *)((uint8_t *)GET_PKT_DATA(np) + (GET_PKT_LEN(np) - IPV4_GET_IPLEN(p)));
- PSEUDO_PKT_SET_IPV4HDR(np->ip4h, p->ip4h);
-
- /* Similarly setup the TCP header with ports in opposite direction */
- np->tcph = (TCPHdr *)((uint8_t *)np->ip4h + IPV4_GET_HLEN(np));
-
- PSEUDO_PKT_SET_TCPHDR(np->tcph, p->tcph);
-
- /* Setup the adress and port details */
- SET_IPV4_SRC_ADDR(p, &np->dst);
- SET_IPV4_DST_ADDR(p, &np->src);
- SET_TCP_SRC_PORT(p, &np->dp);
- SET_TCP_DST_PORT(p, &np->sp);
-
- } else if (PKT_IS_IPV6(p)) {
- np->ip6h = (IPV6Hdr *)((uint8_t *)GET_PKT_DATA(np) + (GET_PKT_LEN(np) - IPV6_GET_PLEN(p) - IPV6_HEADER_LEN));
- PSEUDO_PKT_SET_IPV6HDR(np->ip6h, p->ip6h);
-
- /* Similarly setup the TCP header with ports in opposite direction */
- np->tcph = (TCPHdr *)((uint8_t *)np->ip6h + IPV6_HEADER_LEN);
- PSEUDO_PKT_SET_TCPHDR(np->tcph, p->tcph);
-
- /* Setup the adress and port details */
- SET_IPV6_SRC_ADDR(p, &np->dst);
- SET_IPV6_DST_ADDR(p, &np->src);
- SET_TCP_SRC_PORT(p, &np->dp);
- SET_TCP_DST_PORT(p, &np->sp);
- }
-
- /* we don't need a payload (if any) */
- np->payload = NULL;
- np->payload_len = 0;
-}
-
-/** \brief Create a pseudo packet injected into the engine to signal the
- * opposing direction of this stream to wrap up stream reassembly.
- *
- * \param p real packet
- * \param pq packet queue to store the new pseudo packet in
- */
-void StreamTcpPseudoPacketCreateStreamEndPacket(ThreadVars *tv, StreamTcpThread *stt, Packet *p, TcpSession *ssn, PacketQueue *pq)
-{
- SCEnter();
-
- if (p->flags & PKT_PSEUDO_STREAM_END) {
- SCReturn;
- }
-
- /* no need for a pseudo packet if there is nothing left to reassemble */
- if (RB_EMPTY(&ssn->server.seg_tree) && RB_EMPTY(&ssn->client.seg_tree)) {
- SCReturn;
- }
-
- Packet *np = StreamTcpPseudoSetup(p, GET_PKT_DATA(p), GET_PKT_LEN(p));
- if (np == NULL) {
- SCLogDebug("The packet received from packet allocation is NULL");
- StatsIncr(tv, stt->counter_tcp_pseudo_failed);
- SCReturn;
- }
- PKT_SET_SRC(np, PKT_SRC_STREAM_TCP_STREAM_END_PSEUDO);
-
- /* Setup the IP and TCP headers */
- StreamTcpPseudoPacketSetupHeader(np,p);
-
- np->tenant_id = p->flow->tenant_id;
-
- np->flowflags = p->flowflags;
-
- np->flags |= PKT_STREAM_EST;
- np->flags |= PKT_STREAM_EOF;
- np->flags |= PKT_HAS_FLOW;
- np->flags |= PKT_PSEUDO_STREAM_END;
-
- if (p->flags & PKT_NOPACKET_INSPECTION) {
- DecodeSetNoPacketInspectionFlag(np);
- }
- if (p->flags & PKT_NOPAYLOAD_INSPECTION) {
- DecodeSetNoPayloadInspectionFlag(np);
- }
-
- if (PKT_IS_TOSERVER(p)) {
- SCLogDebug("original is to_server, so pseudo is to_client");
- np->flowflags &= ~FLOW_PKT_TOSERVER;
- np->flowflags |= FLOW_PKT_TOCLIENT;
-#ifdef DEBUG
- BUG_ON(!(PKT_IS_TOCLIENT(np)));
- BUG_ON((PKT_IS_TOSERVER(np)));
-#endif
- } else if (PKT_IS_TOCLIENT(p)) {
- SCLogDebug("original is to_client, so pseudo is to_server");
- np->flowflags &= ~FLOW_PKT_TOCLIENT;
- np->flowflags |= FLOW_PKT_TOSERVER;
-#ifdef DEBUG
- BUG_ON(!(PKT_IS_TOSERVER(np)));
- BUG_ON((PKT_IS_TOCLIENT(np)));
-#endif
- }
-
- PacketEnqueue(pq, np);
-
- StatsIncr(tv, stt->counter_tcp_pseudo);
- SCReturn;
-}
-
/** \brief Create a pseudo packet injected into the engine to signal the
* opposing direction of this stream trigger detection/logging.
*
return ret;
}
-static int StreamTcpTest40(void)
-{
- uint8_t raw_vlan[] = {
- 0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
- 0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
- 0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
- 0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
- 0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
- 0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
- 0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3
- };
- Packet *p = SCMalloc(SIZE_OF_PACKET);
- FAIL_IF(unlikely(p == NULL));
- ThreadVars tv;
- DecodeThreadVars dtv;
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(p, 0, SIZE_OF_PACKET);
- PACKET_INITIALIZE(p);
-
- SET_PKT_LEN(p, sizeof(raw_vlan));
- memcpy(GET_PKT_DATA(p), raw_vlan, sizeof(raw_vlan));
- memset(&dtv, 0, sizeof(DecodeThreadVars));
-
- FlowInitConfig(FLOW_QUIET);
-
- DecodeVLAN(&tv, &dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), NULL);
-
- FAIL_IF(p->vlan_id[0] == 0);
-
- FAIL_IF(p->tcph == NULL);
-
- Packet *np = StreamTcpPseudoSetup(p, GET_PKT_DATA(p), GET_PKT_LEN(p));
- FAIL_IF(np == NULL);
-
- StreamTcpPseudoPacketSetupHeader(np,p);
-
- FAIL_IF(((uint8_t *)p->tcph - (uint8_t *)p->ip4h) != ((uint8_t *)np->tcph - (uint8_t *)np->ip4h));
-
- PACKET_DESTRUCTOR(np);
- PACKET_DESTRUCTOR(p);
- FlowShutdown();
- PacketFree(np);
- PacketFree(p);
- PASS;
-}
-
-static int StreamTcpTest41(void)
-{
- /* IPV6/TCP/no eth header */
- uint8_t raw_ip[] = {
- 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40,
- 0x20, 0x01, 0x06, 0x18, 0x04, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x99, 0xcc, 0x70,
- 0x20, 0x01, 0x06, 0x18, 0x00, 0x01, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x8c, 0x9b, 0x00, 0x50, 0x6a, 0xe7, 0x07, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0x30,
- 0x29, 0x9c, 0x00, 0x00, 0x02, 0x04, 0x05, 0x8c,
- 0x04, 0x02, 0x08, 0x0a, 0x00, 0xdd, 0x1a, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02 };
- Packet *p = SCMalloc(SIZE_OF_PACKET);
- if (unlikely(p == NULL))
- return 0;
- ThreadVars tv;
- DecodeThreadVars dtv;
-
- memset(&dtv, 0, sizeof(DecodeThreadVars));
- memset(&tv, 0, sizeof(ThreadVars));
- memset(p, 0, SIZE_OF_PACKET);
- PACKET_INITIALIZE(p);
-
- if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) {
- PacketFree(p);
- return 1;
- }
-
- FlowInitConfig(FLOW_QUIET);
-
- DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL);
-
- if (p->ip6h == NULL) {
- printf("expected a valid ipv6 header but it was NULL: ");
- FlowShutdown();
- SCFree(p);
- return 1;
- }
-
- if(p->tcph == NULL) {
- SCFree(p);
- return 0;
- }
-
- Packet *np = StreamTcpPseudoSetup(p, GET_PKT_DATA(p), GET_PKT_LEN(p));
- if (np == NULL) {
- printf("the packet received from packet allocation is NULL: ");
- return 0;
- }
-
- StreamTcpPseudoPacketSetupHeader(np,p);
-
- if (((uint8_t *)p->tcph - (uint8_t *)p->ip6h) != ((uint8_t *)np->tcph - (uint8_t *)np->ip6h)) {
- return 0;
- }
-
- PACKET_RECYCLE(np);
- PACKET_RECYCLE(p);
- SCFree(p);
- FlowShutdown();
-
- return 1;
-}
-
/** \test multiple different SYN/ACK, pick first */
static int StreamTcpTest42 (void)
{
UtRegisterTest("StreamTcpTest38 -- validate ACK", StreamTcpTest38);
UtRegisterTest("StreamTcpTest39 -- update next_seq", StreamTcpTest39);
- UtRegisterTest("StreamTcpTest40 -- pseudo setup", StreamTcpTest40);
- UtRegisterTest("StreamTcpTest41 -- pseudo setup", StreamTcpTest41);
-
UtRegisterTest("StreamTcpTest42 -- SYN/ACK queue", StreamTcpTest42);
UtRegisterTest("StreamTcpTest43 -- SYN/ACK queue", StreamTcpTest43);
UtRegisterTest("StreamTcpTest44 -- SYN/ACK queue", StreamTcpTest44);