From: Victor Julien Date: Wed, 3 Apr 2024 05:00:53 +0000 (+0200) Subject: decode/tcp: move tcph into L4 packet data X-Git-Tag: suricata-8.0.0-beta1~1369 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68804b8c4bcf044f5b63f2861496d273c92e9689;p=thirdparty%2Fsuricata.git decode/tcp: move tcph into L4 packet data To reduce Packet size. Ticket: #6938. --- diff --git a/src/alert-debuglog.c b/src/alert-debuglog.c index 600187f564..356cf86ef3 100644 --- a/src/alert-debuglog.c +++ b/src/alert-debuglog.c @@ -191,9 +191,11 @@ static TmEcode AlertDebugLogger(ThreadVars *tv, const Packet *p, void *thread_da "DST PORT: %" PRIu32 "\n", p->sp, p->dp); if (PacketIsTCP(p)) { - MemBufferWriteString(aft->buffer, "TCP SEQ: %"PRIu32"\n" - "TCP ACK: %"PRIu32"\n", - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + const TCPHdr *tcph = PacketGetTCP(p); + MemBufferWriteString(aft->buffer, + "TCP SEQ: %" PRIu32 "\n" + "TCP ACK: %" PRIu32 "\n", + TCP_GET_RAW_SEQ(tcph), TCP_GET_RAW_ACK(tcph)); } } diff --git a/src/app-layer.c b/src/app-layer.c index 2566861025..1dc72ed63d 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -1336,7 +1336,7 @@ void AppLayerDeSetupCounters(void) f.flags = FLOW_IPV4; \ f.proto = IPPROTO_TCP; \ p->flow = &f; \ - p->tcph = &tcph; \ + PacketSetTCP(p, (uint8_t *)&tcph); \ \ StreamTcpInitConfig(true); \ IPPairInitConfig(true); \ @@ -1364,8 +1364,8 @@ void AppLayerDeSetupCounters(void) FAIL_IF(ssn->data_first_seen_dir != 0); \ \ /* handshake */ \ - p->tcph->th_ack = htonl(1); \ - p->tcph->th_flags = TH_SYN | TH_ACK; \ + tcph.th_ack = htonl(1); \ + tcph.th_flags = TH_SYN | TH_ACK; \ p->flowflags = FLOW_PKT_TOCLIENT; \ p->payload_len = 0; \ p->payload = NULL; \ @@ -1383,9 +1383,9 @@ void AppLayerDeSetupCounters(void) FAIL_IF(ssn->data_first_seen_dir != 0); \ \ /* handshake */ \ - p->tcph->th_ack = htonl(1); \ - p->tcph->th_seq = htonl(1); \ - p->tcph->th_flags = TH_ACK; \ + tcph.th_ack = htonl(1); \ + tcph.th_seq = htonl(1); \ + tcph.th_flags = TH_ACK; \ p->flowflags = FLOW_PKT_TOSERVER; \ p->payload_len = 0; \ p->payload = NULL; \ @@ -1429,9 +1429,9 @@ static int AppLayerTest01(void) 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request); p->payload = request; @@ -1491,9 +1491,9 @@ static int AppLayerTest01(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -1511,9 +1511,9 @@ static int AppLayerTest01(void) FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -1543,9 +1543,9 @@ static int AppLayerTest02(void) /* partial request */ uint8_t request1[] = { 0x47, 0x45, }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request1); p->payload = request1; @@ -1563,9 +1563,9 @@ static int AppLayerTest02(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response ack against partial request */ - p->tcph->th_ack = htonl(3); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(3); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -1595,9 +1595,9 @@ static int AppLayerTest02(void) 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(3); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(3); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request2); p->payload = request2; @@ -1657,9 +1657,9 @@ static int AppLayerTest02(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -1677,9 +1677,9 @@ static int AppLayerTest02(void) FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -1720,9 +1720,9 @@ static int AppLayerTest03(void) 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request); p->payload = request; @@ -1782,9 +1782,9 @@ static int AppLayerTest03(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -1802,9 +1802,9 @@ static int AppLayerTest03(void) FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -1846,9 +1846,9 @@ static int AppLayerTest04(void) 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; PrintRawDataFp(stdout, request, sizeof(request)); - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request); p->payload = request; @@ -1868,9 +1868,9 @@ static int AppLayerTest04(void) /* partial response */ uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, }; PrintRawDataFp(stdout, response1, sizeof(response1)); - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response1); p->payload = response1; @@ -1888,9 +1888,9 @@ static int AppLayerTest04(void) FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer /* partial response ack */ - p->tcph->th_ack = htonl(5); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(5); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -1951,9 +1951,9 @@ static int AppLayerTest04(void) 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; PrintRawDataFp(stdout, response2, sizeof(response2)); - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(5); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response2); p->payload = response2; @@ -1971,9 +1971,9 @@ static int AppLayerTest04(void) FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2015,9 +2015,9 @@ static int AppLayerTest05(void) 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; PrintRawDataFp(stdout, request, sizeof(request)); - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request); p->payload = request; @@ -2078,9 +2078,9 @@ static int AppLayerTest05(void) 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; PrintRawDataFp(stdout, response, sizeof(response)); - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -2098,9 +2098,9 @@ static int AppLayerTest05(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2171,9 +2171,9 @@ static int AppLayerTest06(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -2203,9 +2203,9 @@ static int AppLayerTest06(void) 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request); p->payload = request; @@ -2222,9 +2222,9 @@ static int AppLayerTest06(void) FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); - p->tcph->th_ack = htonl(1 + sizeof(request)); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1 + sizeof(request)); + tcph.th_seq = htonl(328); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2265,9 +2265,9 @@ static int AppLayerTest07(void) 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request); p->payload = request; @@ -2307,9 +2307,9 @@ static int AppLayerTest07(void) 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -2327,9 +2327,9 @@ static int AppLayerTest07(void) FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2364,9 +2364,9 @@ static int AppLayerTest08(void) 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request); p->payload = request; @@ -2426,9 +2426,9 @@ static int AppLayerTest08(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -2446,9 +2446,9 @@ static int AppLayerTest08(void) FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2481,9 +2481,9 @@ static int AppLayerTest09(void) /* full request */ uint8_t request1[] = { 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request1); p->payload = request1; @@ -2501,9 +2501,9 @@ static int AppLayerTest09(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response - request ack */ - p->tcph->th_ack = htonl(9); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(9); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2523,9 +2523,9 @@ static int AppLayerTest09(void) /* full request */ uint8_t request2[] = { 0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(9); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(9); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request2); p->payload = request2; @@ -2585,9 +2585,9 @@ static int AppLayerTest09(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(18); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -2605,9 +2605,9 @@ static int AppLayerTest09(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(18); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2640,9 +2640,9 @@ static int AppLayerTest10(void) uint8_t request1[] = { 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request1); p->payload = request1; @@ -2660,9 +2660,9 @@ static int AppLayerTest10(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response - request ack */ - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(18); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2722,9 +2722,9 @@ static int AppLayerTest10(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(18); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -2742,9 +2742,9 @@ static int AppLayerTest10(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(18); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2778,9 +2778,9 @@ static int AppLayerTest11(void) uint8_t request1[] = { 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request1); p->payload = request1; @@ -2798,9 +2798,9 @@ static int AppLayerTest11(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response - request ack */ - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(18); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2820,9 +2820,9 @@ static int AppLayerTest11(void) /* full response - request ack */ uint8_t response1[] = { 0x55, 0x74, 0x54, 0x50, }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(18); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response1); p->payload = response1; @@ -2840,9 +2840,9 @@ static int AppLayerTest11(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response ack from request */ - p->tcph->th_ack = htonl(5); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(5); + tcph.th_seq = htonl(18); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2901,9 +2901,9 @@ static int AppLayerTest11(void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(18); + tcph.th_seq = htonl(5); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response2); p->payload = response2; @@ -2921,9 +2921,9 @@ static int AppLayerTest11(void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response ack from request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(18); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; diff --git a/src/decode-tcp.c b/src/decode-tcp.c index 61c5540f15..558d005605 100644 --- a/src/decode-tcp.c +++ b/src/decode-tcp.c @@ -44,6 +44,7 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) uint8_t tcp_opt_cnt = 0; TCPOpt tcp_opts[TCP_OPTMAX]; + const TCPHdr *tcph = PacketGetTCP(p); uint16_t plen = pktlen; while (plen) { @@ -84,15 +85,15 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) if (olen != TCP_OPT_WS_LEN) { ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); } else { - if (p->tcpvars.wscale_set != 0) { + if (p->l4.vars.tcp.wscale_set != 0) { ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); } else { - p->tcpvars.wscale_set = 1; + p->l4.vars.tcp.wscale_set = 1; const uint8_t wscale = *(tcp_opts[tcp_opt_cnt].data); if (wscale <= TCP_WSCALE_MAX) { - p->tcpvars.wscale = wscale; + p->l4.vars.tcp.wscale = wscale; } else { - p->tcpvars.wscale = 0; + p->l4.vars.tcp.wscale = 0; } } } @@ -101,11 +102,11 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) if (olen != TCP_OPT_MSS_LEN) { ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); } else { - if (p->tcpvars.mss_set) { + if (p->l4.vars.tcp.mss_set) { ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); } else { - p->tcpvars.mss_set = true; - p->tcpvars.mss = SCNtohs(*(uint16_t *)(tcp_opts[tcp_opt_cnt].data)); + p->l4.vars.tcp.mss_set = true; + p->l4.vars.tcp.mss = SCNtohs(*(uint16_t *)(tcp_opts[tcp_opt_cnt].data)); } } break; @@ -116,7 +117,7 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) if (TCP_GET_SACKOK(p)) { ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); } else { - p->tcpvars.sack_ok = true; + p->l4.vars.tcp.sack_ok = true; } } break; @@ -124,14 +125,14 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) if (olen != TCP_OPT_TS_LEN) { ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); } else { - if (p->tcpvars.ts_set) { + if (p->l4.vars.tcp.ts_set) { ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); } else { uint32_t values[2]; memcpy(&values, tcp_opts[tcp_opt_cnt].data, sizeof(values)); - p->tcpvars.ts_val = SCNtohl(values[0]); - p->tcpvars.ts_ecr = SCNtohl(values[1]); - p->tcpvars.ts_set = true; + p->l4.vars.tcp.ts_val = SCNtohl(values[0]); + p->l4.vars.tcp.ts_ecr = SCNtohl(values[1]); + p->l4.vars.tcp.ts_set = true; } } break; @@ -144,14 +145,14 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) { ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); } else { - if (p->tcpvars.sack_set) { + if (p->l4.vars.tcp.sack_set) { ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); } else { - ptrdiff_t diff = tcp_opts[tcp_opt_cnt].data - (uint8_t *)p->tcph; + ptrdiff_t diff = tcp_opts[tcp_opt_cnt].data - (uint8_t *)tcph; DEBUG_VALIDATE_BUG_ON(diff > UINT16_MAX); - p->tcpvars.sack_set = true; - p->tcpvars.sack_cnt = (olen - 2) / 8; - p->tcpvars.sack_offset = (uint16_t)diff; + p->l4.vars.tcp.sack_set = true; + p->l4.vars.tcp.sack_cnt = (olen - 2) / 8; + p->l4.vars.tcp.sack_offset = (uint16_t)diff; } } break; @@ -161,10 +162,10 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) !(((olen - 2) & 0x1) == 0))) { ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); } else { - if (p->tcpvars.tfo_set) { + if (p->l4.vars.tcp.tfo_set) { ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); } else { - p->tcpvars.tfo_set = true; + p->l4.vars.tcp.tfo_set = true; } } break; @@ -175,10 +176,10 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) if (olen == 4 || olen == 12) { uint16_t magic = SCNtohs(*(uint16_t *)tcp_opts[tcp_opt_cnt].data); if (magic == 0xf989) { - if (p->tcpvars.tfo_set) { + if (p->l4.vars.tcp.tfo_set) { ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); } else { - p->tcpvars.tfo_set = true; + p->l4.vars.tcp.tfo_set = true; } } } else { @@ -192,7 +193,7 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) ENGINE_SET_INVALID_EVENT(p,TCP_OPT_INVALID_LEN); } else { /* we can't validate the option as the key is out of band */ - p->tcpvars.md5_option_present = true; + p->l4.vars.tcp.md5_option_present = true; } break; /* RFC 5925 AO option */ @@ -202,7 +203,7 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) ENGINE_SET_INVALID_EVENT(p,TCP_OPT_INVALID_LEN); } else { /* we can't validate the option as the key is out of band */ - p->tcpvars.ao_option_present = true; + p->l4.vars.tcp.ao_option_present = true; } break; } @@ -214,16 +215,17 @@ static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen) } } -static int DecodeTCPPacket(ThreadVars *tv, Packet *p, const uint8_t *pkt, uint16_t len) +static int DecodeTCPPacket( + ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len) { if (unlikely(len < TCP_HEADER_LEN)) { ENGINE_SET_INVALID_EVENT(p, TCP_PKT_TOO_SMALL); return -1; } - p->tcph = (TCPHdr *)pkt; + TCPHdr *tcph = PacketSetTCP(p, pkt); - uint8_t hlen = TCP_GET_HLEN(p); + uint8_t hlen = TCP_GET_RAW_HLEN(tcph); if (unlikely(len < hlen)) { ENGINE_SET_INVALID_EVENT(p, TCP_HLEN_TOO_SMALL); return -1; @@ -239,46 +241,43 @@ static int DecodeTCPPacket(ThreadVars *tv, Packet *p, const uint8_t *pkt, uint16 DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len); } - SET_TCP_SRC_PORT(p,&p->sp); - SET_TCP_DST_PORT(p,&p->dp); + p->sp = TCP_GET_RAW_SRC_PORT(tcph); + p->dp = TCP_GET_RAW_DST_PORT(tcph); p->proto = IPPROTO_TCP; p->payload = (uint8_t *)pkt + hlen; p->payload_len = len - hlen; + /* update counters */ + if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { + StatsIncr(tv, dtv->counter_tcp_synack); + } else if (tcph->th_flags & (TH_SYN)) { + StatsIncr(tv, dtv->counter_tcp_syn); + } + if (tcph->th_flags & (TH_RST)) { + StatsIncr(tv, dtv->counter_tcp_rst); + } + +#ifdef DEBUG + SCLogDebug("TCP sp: %u -> dp: %u - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s", p->sp, + p->dp, TCP_GET_RAW_HLEN(tcph), len, TCP_GET_SACKOK(p) ? "SACKOK " : "", + TCP_HAS_SACK(p) ? "SACK " : "", TCP_HAS_WSCALE(p) ? "WS " : "", + TCP_HAS_TS(p) ? "TS " : "", TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : ""); +#endif return 0; } -int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, - const uint8_t *pkt, uint16_t len) +int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len) { StatsIncr(tv, dtv->counter_tcp); - if (unlikely(DecodeTCPPacket(tv, p, pkt,len) < 0)) { + if (unlikely(DecodeTCPPacket(tv, dtv, p, pkt, len) < 0)) { SCLogDebug("invalid TCP packet"); - CLEAR_TCP_PACKET(p); + PacketClearL4(p); return TM_ECODE_FAILED; } - /* update counters */ - if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { - StatsIncr(tv, dtv->counter_tcp_synack); - } else if (p->tcph->th_flags & (TH_SYN)) { - StatsIncr(tv, dtv->counter_tcp_syn); - } - if (p->tcph->th_flags & (TH_RST)) { - StatsIncr(tv, dtv->counter_tcp_rst); - } -#ifdef DEBUG - SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 - " %s%s%s%s%s%s", - GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_HLEN(p), len, - TCP_GET_SACKOK(p) ? "SACKOK " : "", TCP_HAS_SACK(p) ? "SACK " : "", - TCP_HAS_WSCALE(p) ? "WS " : "", TCP_HAS_TS(p) ? "TS " : "", - TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : ""); -#endif - FlowSetupPacket(p); return TM_ECODE_OK; @@ -508,14 +507,15 @@ static int TCPGetSackTest01(void) FlowInitConfig(FLOW_QUIET); DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp)); - FAIL_IF_NULL(p->tcph); + FAIL_IF_NOT(PacketIsTCP(p)); FAIL_IF(!TCP_HAS_SACK(p)); int sack = TCP_GET_SACK_CNT(p); FAIL_IF(sack != 2); - const uint8_t *sackptr = TCP_GET_SACK_PTR(p); + const TCPHdr *tcph = PacketGetTCP(p); + const uint8_t *sackptr = TCP_GET_SACK_PTR(p, tcph); FAIL_IF_NULL(sackptr); FAIL_IF(memcmp(sackptr, raw_tcp_sack, 16) != 0); diff --git a/src/decode-tcp.h b/src/decode-tcp.h index e549b96fa4..4b31514455 100644 --- a/src/decode-tcp.h +++ b/src/decode-tcp.h @@ -70,6 +70,7 @@ #define TCP_WSCALE_MAX 14 #define TCP_GET_RAW_OFFSET(tcph) (((tcph)->th_offx2 & 0xf0) >> 4) +#define TCP_GET_RAW_HLEN(tcph) ((uint8_t)(TCP_GET_RAW_OFFSET((tcph)) << 2)) #define TCP_GET_RAW_X2(tcph) (unsigned char)((tcph)->th_offx2 & 0x0f) #define TCP_GET_RAW_SRC_PORT(tcph) SCNtohs((tcph)->th_sport) #define TCP_GET_RAW_DST_PORT(tcph) SCNtohs((tcph)->th_dport) @@ -85,24 +86,24 @@ #define TCP_GET_RAW_SUM(tcph) SCNtohs((tcph)->th_sum) /** macro for getting the first timestamp from the packet in host order */ -#define TCP_GET_TSVAL(p) ((p)->tcpvars.ts_val) +#define TCP_GET_TSVAL(p) ((p)->l4.vars.tcp.ts_val) /** macro for getting the second timestamp from the packet in host order. */ -#define TCP_GET_TSECR(p) ((p)->tcpvars.ts_ecr) +#define TCP_GET_TSECR(p) ((p)->l4.vars.tcp.ts_ecr) -#define TCP_HAS_WSCALE(p) ((p)->tcpvars.wscale_set) -#define TCP_HAS_SACK(p) (p)->tcpvars.sack_set -#define TCP_HAS_TS(p) ((p)->tcpvars.ts_set) -#define TCP_HAS_MSS(p) ((p)->tcpvars.mss_set) -#define TCP_HAS_TFO(p) ((p)->tcpvars.tfo_set) +#define TCP_HAS_WSCALE(p) ((p)->l4.vars.tcp.wscale_set) +#define TCP_HAS_SACK(p) (p)->l4.vars.tcp.sack_set +#define TCP_HAS_TS(p) ((p)->l4.vars.tcp.ts_set) +#define TCP_HAS_MSS(p) ((p)->l4.vars.tcp.mss_set) +#define TCP_HAS_TFO(p) ((p)->l4.vars.tcp.tfo_set) /** macro for getting the wscale from the packet. */ -#define TCP_GET_WSCALE(p) (p)->tcpvars.wscale +#define TCP_GET_WSCALE(p) (p)->l4.vars.tcp.wscale -#define TCP_GET_SACKOK(p) (p)->tcpvars.sack_ok -#define TCP_GET_SACK_PTR(p) ((uint8_t *)(p)->tcph) + (p)->tcpvars.sack_offset -#define TCP_GET_SACK_CNT(p) (p)->tcpvars.sack_cnt -#define TCP_GET_MSS(p) (p)->tcpvars.mss +#define TCP_GET_SACKOK(p) (p)->l4.vars.tcp.sack_ok +#define TCP_GET_SACK_PTR(p, tcph) ((uint8_t *)(tcph)) + (p)->l4.vars.tcp.sack_offset +#define TCP_GET_SACK_CNT(p) (p)->l4.vars.tcp.sack_cnt +#define TCP_GET_MSS(p) (p)->l4.vars.tcp.mss #define TCP_GET_OFFSET(p) TCP_GET_RAW_OFFSET((p)->tcph) #define TCP_GET_X2(p) TCP_GET_RAW_X2((p)->tcph) @@ -116,6 +117,15 @@ #define TCP_GET_SUM(p) TCP_GET_RAW_SUM((p)->tcph) #define TCP_GET_FLAGS(p) (p)->tcph->th_flags +#define TCP_ISSET_FLAG_RAW_FIN(p) ((tcph)->th_flags & TH_FIN) +#define TCP_ISSET_FLAG_RAW_SYN(p) ((tcph)->th_flags & TH_SYN) +#define TCP_ISSET_FLAG_RAW_RST(p) ((tcph)->th_flags & TH_RST) +#define TCP_ISSET_FLAG_RAW_PUSH(p) ((tcph)->th_flags & TH_PUSH) +#define TCP_ISSET_FLAG_RAW_ACK(p) ((tcph)->th_flags & TH_ACK) +#define TCP_ISSET_FLAG_RAW_URG(p) ((tcph)->th_flags & TH_URG) +#define TCP_ISSET_FLAG_RAW_RES2(p) ((tcph)->th_flags & TH_RES2) +#define TCP_ISSET_FLAG_RAW_RES1(p) ((tcph)->th_flags & TH_RES1) + #define TCP_ISSET_FLAG_FIN(p) ((p)->tcph->th_flags & TH_FIN) #define TCP_ISSET_FLAG_SYN(p) ((p)->tcph->th_flags & TH_SYN) #define TCP_ISSET_FLAG_RST(p) ((p)->tcph->th_flags & TH_RST) @@ -169,12 +179,6 @@ typedef struct TCPVars_ uint16_t sack_offset; /**< offset relative to tcp header start */ } TCPVars; -#define CLEAR_TCP_PACKET(p) \ - { \ - PACKET_CLEAR_L4VARS((p)); \ - (p)->tcph = NULL; \ - } - void DecodeTCPRegisterTests(void); /** -------- Inline functions ------- */ diff --git a/src/decode.h b/src/decode.h index 0afd818364..b7d00ef3a5 100644 --- a/src/decode.h +++ b/src/decode.h @@ -439,6 +439,7 @@ struct PacketL3 { enum PacketL4Types { PACKET_L4_UNKNOWN = 0, + PACKET_L4_TCP, PACKET_L4_UDP, PACKET_L4_ICMPV4, PACKET_L4_ICMPV6, @@ -452,6 +453,7 @@ struct PacketL4 { bool csum_set; uint16_t csum; union L4Hdrs { + TCPHdr *tcph; UDPHdr *udph; ICMPV4Hdr *icmpv4h; ICMPV6Hdr *icmpv6h; @@ -460,6 +462,7 @@ struct PacketL4 { ESPHdr *esph; } hdrs; union L4Vars { + TCPVars tcp; ICMPV4Vars icmpv4; ICMPV6Vars icmpv6; } vars; @@ -586,14 +589,6 @@ typedef struct Packet_ struct PacketL3 l3; struct PacketL4 l4; - /* Can only be one of TCP, UDP, ICMP at any given time */ - union { - TCPVars tcpvars; - } l4vars; -#define tcpvars l4vars.tcpvars - - TCPHdr *tcph; - /* ptr to the payload of the packet * with it's length. */ uint8_t *payload; @@ -739,11 +734,6 @@ static inline uint8_t PacketGetIPv4IPProto(const Packet *p) return 0; } -static inline bool PacketIsIPv6(const Packet *p) -{ - return p->l3.type == PACKET_L3_IPV6; -} - static inline const IPV6Hdr *PacketGetIPv6(const Packet *p) { DEBUG_VALIDATE_BUG_ON(!PacketIsIPv6(p)); @@ -758,6 +748,11 @@ static inline IPV6Hdr *PacketSetIPV6(Packet *p, const uint8_t *buf) return p->l3.hdrs.ip6h; } +static inline bool PacketIsIPv6(const Packet *p) +{ + return p->l3.type == PACKET_L3_IPV6; +} + static inline void PacketClearL2(Packet *p) { memset(&p->l2, 0, sizeof(p->l2)); @@ -793,9 +788,23 @@ static inline void PacketClearL4(Packet *p) memset(&p->l4, 0, sizeof(p->l4)); } +static inline TCPHdr *PacketSetTCP(Packet *p, const uint8_t *buf) +{ + DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_UNKNOWN); + p->l4.type = PACKET_L4_TCP; + p->l4.hdrs.tcph = (TCPHdr *)buf; + return p->l4.hdrs.tcph; +} + +static inline const TCPHdr *PacketGetTCP(const Packet *p) +{ + DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_TCP); + return p->l4.hdrs.tcph; +} + static inline bool PacketIsTCP(const Packet *p) { - return PKT_IS_TCP(p); + return p->l4.type == PACKET_L4_TCP; } static inline UDPHdr *PacketSetUDP(Packet *p, const uint8_t *buf) diff --git a/src/detect-csum.c b/src/detect-csum.c index a43fbf1cff..c3f3ffd626 100644 --- a/src/detect-csum.c +++ b/src/detect-csum.c @@ -337,8 +337,9 @@ static int DetectTCPV4CsumMatch(DetectEngineThreadCtx *det_ctx, if (!p->l4.csum_set) { const IPV4Hdr *ip4h = PacketGetIPv4(p); - p->l4.csum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p)), p->tcph->th_sum); + const TCPHdr *tcph = PacketGetTCP(p); + p->l4.csum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)tcph, + (p->payload_len + TCP_GET_RAW_HLEN(tcph)), tcph->th_sum); p->l4.csum_set = true; } if (p->l4.csum == 0 && cd->valid == 1) @@ -426,8 +427,9 @@ static int DetectTCPV6CsumMatch(DetectEngineThreadCtx *det_ctx, if (!p->l4.csum_set) { const IPV6Hdr *ip6h = PacketGetIPv6(p); - p->l4.csum = TCPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p)), p->tcph->th_sum); + const TCPHdr *tcph = PacketGetTCP(p); + p->l4.csum = TCPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)tcph, + (p->payload_len + TCP_GET_RAW_HLEN(tcph)), tcph->th_sum); p->l4.csum_set = true; } diff --git a/src/detect-engine-build.c b/src/detect-engine-build.c index cd42296766..d150ddfba5 100644 --- a/src/detect-engine-build.c +++ b/src/detect-engine-build.c @@ -423,10 +423,11 @@ PacketCreateMask(Packet *p, SignatureMask *mask, AppProto alproto, } if (!(PKT_IS_PSEUDOPKT(p)) && PacketIsTCP(p)) { - if ((p->tcph->th_flags & MASK_TCP_INITDEINIT_FLAGS) != 0) { + const TCPHdr *tcph = PacketGetTCP(p); + if ((tcph->th_flags & MASK_TCP_INITDEINIT_FLAGS) != 0) { (*mask) |= SIG_MASK_REQUIRE_FLAGS_INITDEINIT; } - if ((p->tcph->th_flags & MASK_TCP_UNUSUAL_FLAGS) != 0) { + if ((tcph->th_flags & MASK_TCP_UNUSUAL_FLAGS) != 0) { (*mask) |= SIG_MASK_REQUIRE_FLAGS_UNUSUAL; } } diff --git a/src/detect-stream_size.c b/src/detect-stream_size.c index e8ce4336a3..f04a0c43f8 100644 --- a/src/detect-stream_size.c +++ b/src/detect-stream_size.c @@ -331,7 +331,7 @@ static int DetectStreamSizeParseTest03 (void) ssn.client = client; f.protoctx = &ssn; p->flow = &f; - p->tcph = &tcph; + PacketSetTCP(p, (uint8_t *)&tcph); sm.ctx = (SigMatchCtx*)sd; result = DetectStreamSizeMatch(&dtx, p, &s, sm.ctx); diff --git a/src/detect-tcp-ack.c b/src/detect-tcp-ack.c index e5d656954a..55a13b2816 100644 --- a/src/detect-tcp-ack.c +++ b/src/detect-tcp-ack.c @@ -92,7 +92,7 @@ static int DetectAckMatch(DetectEngineThreadCtx *det_ctx, return 0; } - return (data->ack == TCP_GET_ACK(p)) ? 1 : 0; + return (data->ack == TCP_GET_RAW_ACK(PacketGetTCP(p))) ? 1 : 0; } /** @@ -157,7 +157,7 @@ PrefilterPacketAckMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *p return; if (p->proto == IPPROTO_TCP && !(PKT_IS_PSEUDOPKT(p)) && PacketIsTCP(p) && - (TCP_GET_ACK(p) == ctx->v1.u32[0])) { + (TCP_GET_RAW_ACK(PacketGetTCP(p)) == ctx->v1.u32[0])) { SCLogDebug("packet matches TCP ack %u", ctx->v1.u32[0]); PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt); } @@ -218,11 +218,11 @@ static int DetectAckSigTest01(void) /* TCP w/ack=42 */ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p1->tcph->th_ack = htonl(42); + p1->l4.hdrs.tcph->th_ack = htonl(42); /* TCP w/ack=100 */ p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2->tcph->th_ack = htonl(100); + p2->l4.hdrs.tcph->th_ack = htonl(100); /* ICMP */ p3 = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); diff --git a/src/detect-tcp-flags.c b/src/detect-tcp-flags.c index 0dddd0dc00..267193fc75 100644 --- a/src/detect-tcp-flags.c +++ b/src/detect-tcp-flags.c @@ -156,7 +156,8 @@ static int DetectFlagsMatch (DetectEngineThreadCtx *det_ctx, Packet *p, } const DetectFlagsData *de = (const DetectFlagsData *)ctx; - const uint8_t flags = p->tcph->th_flags; + const TCPHdr *tcph = PacketGetTCP(p); + const uint8_t flags = tcph->th_flags; return FlagsMatch(flags, de->modifier, de->flags, de->ignored_flags); } @@ -560,7 +561,8 @@ PrefilterPacketFlagsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void if (!PrefilterPacketHeaderExtraMatch(ctx, p)) return; - const uint8_t flags = p->tcph->th_flags; + const TCPHdr *tcph = PacketGetTCP(p); + const uint8_t flags = tcph->th_flags; if (FlagsMatch(flags, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2])) { SCLogDebug("packet matches TCP flags %02x", ctx->v1.u8[1]); @@ -671,8 +673,8 @@ static int FlagsTestParse03 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST; + tcph.th_flags = TH_ACK | TH_PUSH | TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("AP+"); @@ -725,8 +727,8 @@ static int FlagsTestParse04 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN; + tcph.th_flags = TH_SYN; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("A"); @@ -780,8 +782,8 @@ static int FlagsTestParse05 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST; + tcph.th_flags = TH_ACK | TH_PUSH | TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("+AP,SR"); @@ -835,8 +837,8 @@ static int FlagsTestParse06 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST; + tcph.th_flags = TH_ACK | TH_PUSH | TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("+AP,UR"); @@ -889,8 +891,8 @@ static int FlagsTestParse07 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; + tcph.th_flags = TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("*AP"); @@ -944,8 +946,8 @@ static int FlagsTestParse08 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; + tcph.th_flags = TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("*SA"); @@ -998,8 +1000,8 @@ static int FlagsTestParse09 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; + tcph.th_flags = TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("!PA"); @@ -1052,8 +1054,8 @@ static int FlagsTestParse10 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; + tcph.th_flags = TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("!AP"); @@ -1106,8 +1108,8 @@ static int FlagsTestParse11 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST|TH_URG; + tcph.th_flags = TH_SYN | TH_RST | TH_URG; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("*AP,SR"); @@ -1161,8 +1163,8 @@ static int FlagsTestParse12 (void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN; + tcph.th_flags = TH_SYN; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("0"); @@ -1247,8 +1249,8 @@ static int FlagsTestParse15(void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_ECN | TH_CWR | TH_SYN | TH_RST; + tcph.th_flags = TH_ECN | TH_CWR | TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("EC+"); @@ -1299,8 +1301,8 @@ static int FlagsTestParse16(void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST; + tcph.th_flags = TH_ECN | TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("EC*"); @@ -1354,8 +1356,8 @@ static int FlagsTestParse17(void) memset(&tcph, 0, sizeof(TCPHdr)); UTHSetIPV4Hdr(p, &ipv4h); - p->tcph = &tcph; - p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST; + tcph.th_flags = TH_ECN | TH_SYN | TH_RST; + UTHSetTCPHdr(p, &tcph); de = DetectFlagsParse("EC+"); diff --git a/src/detect-tcp-seq.c b/src/detect-tcp-seq.c index 60c060d3f5..f26501db32 100644 --- a/src/detect-tcp-seq.c +++ b/src/detect-tcp-seq.c @@ -88,7 +88,7 @@ static int DetectSeqMatch(DetectEngineThreadCtx *det_ctx, return 0; } - return (data->seq == TCP_GET_SEQ(p)) ? 1 : 0; + return (data->seq == TCP_GET_RAW_SEQ(PacketGetTCP(p))) ? 1 : 0; } /** @@ -152,7 +152,7 @@ PrefilterPacketSeqMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *p return; if (p->proto == IPPROTO_TCP && !(PKT_IS_PSEUDOPKT(p)) && PacketIsTCP(p) && - (TCP_GET_SEQ(p) == ctx->v1.u32[0])) { + (TCP_GET_RAW_SEQ(PacketGetTCP(p)) == ctx->v1.u32[0])) { SCLogDebug("packet matches TCP seq %u", ctx->v1.u32[0]); PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt); } @@ -257,10 +257,10 @@ static int DetectSeqSigTest02(void) goto end; /* TCP w/seq=42 */ - p[0]->tcph->th_seq = htonl(42); + p[0]->l4.hdrs.tcph->th_seq = htonl(42); /* TCP w/seq=100 */ - p[1]->tcph->th_seq = htonl(100); + p[1]->l4.hdrs.tcph->th_seq = htonl(100); const char *sigs[2]; sigs[0]= "alert tcp any any -> any any (msg:\"Testing seq\"; seq:41; sid:1;)"; diff --git a/src/detect-tcp-window.c b/src/detect-tcp-window.c index 4714f6ba4a..38f2b5c680 100644 --- a/src/detect-tcp-window.c +++ b/src/detect-tcp-window.c @@ -91,7 +91,8 @@ static int DetectWindowMatch(DetectEngineThreadCtx *det_ctx, Packet *p, return 0; } - if ( (!wd->negated && wd->size == TCP_GET_WINDOW(p)) || (wd->negated && wd->size != TCP_GET_WINDOW(p))) { + const uint16_t window = TCP_GET_RAW_WINDOW(PacketGetTCP(p)); + if ((!wd->negated && wd->size == window) || (wd->negated && wd->size != window)) { return 1; } @@ -287,10 +288,10 @@ static int DetectWindowTestPacket01 (void) FAIL_IF(p[0] == NULL || p[1] == NULL || p[2] == NULL); /* TCP wwindow = 40 */ - p[0]->tcph->th_win = htons(40); + p[0]->l4.hdrs.tcph->th_win = htons(40); /* TCP window = 41 */ - p[1]->tcph->th_win = htons(41); + p[1]->l4.hdrs.tcph->th_win = htons(41); const char *sigs[2]; sigs[0]= "alert tcp any any -> any any (msg:\"Testing window 1\"; window:40; sid:1;)"; diff --git a/src/detect-tcphdr.c b/src/detect-tcphdr.c index 16a46a4b62..d5a29d093a 100644 --- a/src/detect-tcphdr.c +++ b/src/detect-tcphdr.c @@ -106,18 +106,17 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, // for instance with invalid header length return NULL; } - uint32_t hlen = TCP_GET_HLEN(p); - if (((uint8_t *)p->tcph + (ptrdiff_t)hlen) > - ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) - { - SCLogDebug("data out of range: %p > %p", - ((uint8_t *)p->tcph + (ptrdiff_t)hlen), + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t hlen = TCP_GET_RAW_HLEN(tcph); + if (((uint8_t *)tcph + (ptrdiff_t)hlen) > + ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) { + SCLogDebug("data out of range: %p > %p", ((uint8_t *)tcph + (ptrdiff_t)hlen), ((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))); return NULL; } const uint32_t data_len = hlen; - const uint8_t *data = (const uint8_t *)p->tcph; + const uint8_t *data = (const uint8_t *)tcph; InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); InspectionBufferApplyTransforms(buffer, transforms); diff --git a/src/detect.c b/src/detect.c index f7b2b79e71..5f36bba7e4 100644 --- a/src/detect.c +++ b/src/detect.c @@ -407,7 +407,7 @@ static inline void DetectPrefilterBuildNonPrefilterList( static inline void DetectPrefilterSetNonPrefilterList(const Packet *p, DetectEngineThreadCtx *det_ctx, DetectRunScratchpad *scratch) { - if ((p->proto == IPPROTO_TCP) && PacketIsTCP(p) && (p->tcph->th_flags & TH_SYN)) { + if ((p->proto == IPPROTO_TCP) && PacketIsTCP(p) && (PacketGetTCP(p)->th_flags & TH_SYN)) { det_ctx->non_pf_store_ptr = scratch->sgh->non_pf_syn_store_array; det_ctx->non_pf_store_cnt = scratch->sgh->non_pf_syn_store_cnt; } else { diff --git a/src/flow-hash.c b/src/flow-hash.c index 409b00f654..88d44d6fc2 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -552,7 +552,8 @@ static inline int FlowCreateCheck(const Packet *p, const bool emerg) * that is not a TCP SYN packet. */ if (emerg) { if (PacketIsTCP(p)) { - if (((p->tcph->th_flags & (TH_SYN | TH_ACK | TH_RST | TH_FIN)) == TH_SYN) || + const TCPHdr *tcph = PacketGetTCP(p); + if (((tcph->th_flags & (TH_SYN | TH_ACK | TH_RST | TH_FIN)) == TH_SYN) || !stream_config.midstream) { ; } else { diff --git a/src/flow-timeout.c b/src/flow-timeout.c index 2ec6b398de..1bfa18a1cb 100644 --- a/src/flow-timeout.c +++ b/src/flow-timeout.c @@ -151,7 +151,7 @@ static inline Packet *FlowForceReassemblyPseudoPacketSetup( } /* set the tcp header */ - p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 20); + PacketSetTCP(p, GET_PKT_DATA(p) + 20); SET_PKT_LEN(p, 40); /* ipv4 hdr + tcp hdr */ @@ -205,42 +205,43 @@ static inline Packet *FlowForceReassemblyPseudoPacketSetup( } /* set the tcp header */ - p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 40); + PacketSetTCP(p, GET_PKT_DATA(p) + 40); SET_PKT_LEN(p, 60); /* ipv6 hdr + tcp hdr */ } - p->tcph->th_offx2 = 0x50; - p->tcph->th_flags = 0; - p->tcph->th_win = 10; - p->tcph->th_urp = 0; + p->l4.hdrs.tcph->th_offx2 = 0x50; + p->l4.hdrs.tcph->th_flags = 0; + p->l4.hdrs.tcph->th_win = 10; + p->l4.hdrs.tcph->th_urp = 0; /* to server */ if (orig_dir == 0) { - p->tcph->th_sport = htons(f->sp); - p->tcph->th_dport = htons(f->dp); + p->l4.hdrs.tcph->th_sport = htons(f->sp); + p->l4.hdrs.tcph->th_dport = htons(f->dp); - p->tcph->th_seq = htonl(ssn->client.next_seq); - p->tcph->th_ack = htonl(ssn->server.last_ack); + p->l4.hdrs.tcph->th_seq = htonl(ssn->client.next_seq); + p->l4.hdrs.tcph->th_ack = htonl(ssn->server.last_ack); /* to client */ } else { - p->tcph->th_sport = htons(f->dp); - p->tcph->th_dport = htons(f->sp); + p->l4.hdrs.tcph->th_sport = htons(f->dp); + p->l4.hdrs.tcph->th_dport = htons(f->sp); - p->tcph->th_seq = htonl(ssn->server.next_seq); - p->tcph->th_ack = htonl(ssn->client.last_ack); + p->l4.hdrs.tcph->th_seq = htonl(ssn->server.next_seq); + p->l4.hdrs.tcph->th_ack = htonl(ssn->client.last_ack); } if (FLOW_IS_IPV4(f)) { IPV4Hdr *ip4h = p->l3.hdrs.ip4h; - p->tcph->th_sum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)p->tcph, 20, 0); + p->l4.hdrs.tcph->th_sum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)p->l4.hdrs.tcph, 20, 0); /* calc ipv4 csum as we may log it and barnyard might reject * a wrong checksum */ ip4h->ip_csum = IPV4Checksum((uint16_t *)ip4h, IPV4_GET_RAW_HLEN(ip4h), 0); } else if (FLOW_IS_IPV6(f)) { const IPV6Hdr *ip6h = PacketGetIPv6(p); - p->tcph->th_sum = TCPChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->tcph, 20, 0); + p->l4.hdrs.tcph->th_sum = + TCPChecksum(ip6h->s_ip6_addrs, (uint16_t *)p->l4.hdrs.tcph, 20, 0); } p->ts = TimeGet(); diff --git a/src/flow-util.c b/src/flow-util.c index d4cded6f58..7e11da41f5 100644 --- a/src/flow-util.c +++ b/src/flow-util.c @@ -170,10 +170,7 @@ void FlowInit(Flow *f, const Packet *p) DEBUG_VALIDATE_BUG_ON(1); } - if (PacketIsTCP(p)) { - SET_TCP_SRC_PORT(p,&f->sp); - SET_TCP_DST_PORT(p,&f->dp); - } else if (PacketIsUDP(p)) { + if (PacketIsTCP(p) || PacketIsUDP(p)) { f->sp = p->sp; f->dp = p->dp; } else if (PacketIsICMPv4(p)) { diff --git a/src/output-eve-stream.c b/src/output-eve-stream.c index 3fb906b3c5..a9fe09ce90 100644 --- a/src/output-eve-stream.c +++ b/src/output-eve-stream.c @@ -335,45 +335,46 @@ static int EveStreamLogger(ThreadVars *tv, void *thread_data, const Packet *p) jb_set_uint(js, "flowlbl", IPV6_GET_RAW_FLOW(ip6h)); } if (PacketIsTCP(p)) { - jb_set_uint(js, "tcpseq", TCP_GET_SEQ(p)); - jb_set_uint(js, "tcpack", TCP_GET_ACK(p)); - jb_set_uint(js, "tcpwin", TCP_GET_WINDOW(p)); - jb_set_bool(js, "syn", TCP_ISSET_FLAG_SYN(p) ? true : false); - jb_set_bool(js, "ack", TCP_ISSET_FLAG_ACK(p) ? true : false); - jb_set_bool(js, "psh", TCP_ISSET_FLAG_PUSH(p) ? true : false); - jb_set_bool(js, "rst", TCP_ISSET_FLAG_RST(p) ? true : false); - jb_set_bool(js, "urg", TCP_ISSET_FLAG_URG(p) ? true : false); - jb_set_bool(js, "fin", TCP_ISSET_FLAG_FIN(p) ? true : false); - jb_set_uint(js, "tcpres", TCP_GET_RAW_X2(p->tcph)); - jb_set_uint(js, "tcpurgp", TCP_GET_URG_POINTER(p)); + const TCPHdr *tcph = PacketGetTCP(p); + jb_set_uint(js, "tcpseq", TCP_GET_RAW_SEQ(tcph)); + jb_set_uint(js, "tcpack", TCP_GET_RAW_ACK(tcph)); + jb_set_uint(js, "tcpwin", TCP_GET_RAW_WINDOW(tcph)); + jb_set_bool(js, "syn", TCP_ISSET_FLAG_RAW_SYN(tcph) ? true : false); + jb_set_bool(js, "ack", TCP_ISSET_FLAG_RAW_ACK(tcph) ? true : false); + jb_set_bool(js, "psh", TCP_ISSET_FLAG_RAW_PUSH(tcph) ? true : false); + jb_set_bool(js, "rst", TCP_ISSET_FLAG_RAW_RST(tcph) ? true : false); + jb_set_bool(js, "urg", TCP_ISSET_FLAG_RAW_URG(tcph) ? true : false); + jb_set_bool(js, "fin", TCP_ISSET_FLAG_RAW_FIN(tcph) ? true : false); + jb_set_uint(js, "tcpres", TCP_GET_RAW_X2(tcph)); + jb_set_uint(js, "tcpurgp", TCP_GET_RAW_URG_POINTER(tcph)); jb_open_array(js, "flags"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_RETRANSMISSION) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_RETRANSMISSION) jb_append_string(js, "retransmission"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_SPURIOUS_RETRANSMISSION) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_SPURIOUS_RETRANSMISSION) jb_append_string(js, "spurious_retransmission"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_KEEPALIVE) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_KEEPALIVE) jb_append_string(js, "keepalive"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_KEEPALIVEACK) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_KEEPALIVEACK) jb_append_string(js, "keepalive_ack"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_WINDOWUPDATE) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_WINDOWUPDATE) jb_append_string(js, "window_update"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_EVENTSET) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_EVENTSET) jb_append_string(js, "event_set"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_STATE_UPDATE) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_STATE_UPDATE) jb_append_string(js, "state_update"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_DUP_ACK) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_DUP_ACK) jb_append_string(js, "dup_ack"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_DSACK) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_DSACK) jb_append_string(js, "dsack"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_ACK_UNSEEN_DATA) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_ACK_UNSEEN_DATA) jb_append_string(js, "ack_unseen_data"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_TCP_PORT_REUSE) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_TCP_PORT_REUSE) jb_append_string(js, "tcp_port_reuse"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE) jb_append_string(js, "zero_window_probe"); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE_ACK) + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE_ACK) jb_append_string(js, "zero_window_probe_ack"); jb_close(js); } @@ -385,7 +386,7 @@ static int EveStreamLogger(ThreadVars *tv, void *thread_data, const Packet *p) const char *tcp_state = StreamTcpStateAsString(ssn->state); if (tcp_state != NULL) jb_set_string(js, "state", tcp_state); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_STATE_UPDATE) { + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_STATE_UPDATE) { const char *tcp_pstate = StreamTcpStateAsString(ssn->pstate); if (tcp_pstate != NULL) jb_set_string(js, "pstate", tcp_pstate); @@ -401,7 +402,7 @@ static int EveStreamLogger(ThreadVars *tv, void *thread_data, const Packet *p) } jb_close(js); - if (p->tcpvars.stream_pkt_flags & STREAM_PKT_FLAG_EVENTSET) { + if (p->l4.vars.tcp.stream_pkt_flags & STREAM_PKT_FLAG_EVENTSET) { jb_open_array(js, "events"); for (int i = 0; i < p->events.cnt; i++) { uint8_t event_code = p->events.events[i]; @@ -447,7 +448,7 @@ static bool EveStreamLogCondition(ThreadVars *tv, void *data, const Packet *p) return (p->proto == IPPROTO_TCP && (ctx->trigger_flags == 0xffff || - (p->tcpvars.stream_pkt_flags & ctx->trigger_flags) != 0)); + (p->l4.vars.tcp.stream_pkt_flags & ctx->trigger_flags) != 0)); } void EveStreamLogRegister(void) diff --git a/src/output-json-drop.c b/src/output-json-drop.c index 03869e0bec..d4f2ac0a19 100644 --- a/src/output-json-drop.c +++ b/src/output-json-drop.c @@ -125,17 +125,18 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p) switch (proto) { case IPPROTO_TCP: if (PacketIsTCP(p)) { - jb_set_uint(js, "tcpseq", TCP_GET_SEQ(p)); - jb_set_uint(js, "tcpack", TCP_GET_ACK(p)); - jb_set_uint(js, "tcpwin", TCP_GET_WINDOW(p)); - jb_set_bool(js, "syn", TCP_ISSET_FLAG_SYN(p) ? true : false); - jb_set_bool(js, "ack", TCP_ISSET_FLAG_ACK(p) ? true : false); - jb_set_bool(js, "psh", TCP_ISSET_FLAG_PUSH(p) ? true : false); - jb_set_bool(js, "rst", TCP_ISSET_FLAG_RST(p) ? true : false); - jb_set_bool(js, "urg", TCP_ISSET_FLAG_URG(p) ? true : false); - jb_set_bool(js, "fin", TCP_ISSET_FLAG_FIN(p) ? true : false); - jb_set_uint(js, "tcpres", TCP_GET_RAW_X2(p->tcph)); - jb_set_uint(js, "tcpurgp", TCP_GET_URG_POINTER(p)); + const TCPHdr *tcph = PacketGetTCP(p); + jb_set_uint(js, "tcpseq", TCP_GET_RAW_SEQ(tcph)); + jb_set_uint(js, "tcpack", TCP_GET_RAW_ACK(tcph)); + jb_set_uint(js, "tcpwin", TCP_GET_RAW_WINDOW(tcph)); + jb_set_bool(js, "syn", TCP_ISSET_FLAG_RAW_SYN(tcph) ? true : false); + jb_set_bool(js, "ack", TCP_ISSET_FLAG_RAW_ACK(tcph) ? true : false); + jb_set_bool(js, "psh", TCP_ISSET_FLAG_RAW_PUSH(tcph) ? true : false); + jb_set_bool(js, "rst", TCP_ISSET_FLAG_RAW_RST(tcph) ? true : false); + jb_set_bool(js, "urg", TCP_ISSET_FLAG_RAW_URG(tcph) ? true : false); + jb_set_bool(js, "fin", TCP_ISSET_FLAG_RAW_FIN(tcph) ? true : false); + jb_set_uint(js, "tcpres", TCP_GET_RAW_X2(tcph)); + jb_set_uint(js, "tcpurgp", TCP_GET_RAW_URG_POINTER(tcph)); } break; case IPPROTO_UDP: diff --git a/src/packet.c b/src/packet.c index e0c3327c44..07f28b424f 100644 --- a/src/packet.c +++ b/src/packet.c @@ -115,9 +115,6 @@ void PacketReinit(Packet *p) PacketClearL2(p); PacketClearL3(p); PacketClearL4(p); - if (p->tcph != NULL) { - CLEAR_TCP_PACKET(p); - } p->payload = NULL; p->payload_len = 0; p->BypassPacketsFlow = NULL; diff --git a/src/respond-reject-libnet11.c b/src/respond-reject-libnet11.c index f53715654d..e3d3867fbf 100644 --- a/src/respond-reject-libnet11.c +++ b/src/respond-reject-libnet11.c @@ -133,6 +133,7 @@ void FreeCachedCtx(void) static inline void SetupTCP(Packet *p, Libnet11Packet *lpacket, enum RejectDirection dir) { + const TCPHdr *tcph = PacketGetTCP(p); switch (dir) { case REJECT_DIR_SRC: SCLogDebug("sending a tcp reset to src"); @@ -141,28 +142,28 @@ static inline void SetupTCP(Packet *p, Libnet11Packet *lpacket, enum RejectDirec * the normal way. If packet has a ACK, the seq of the RST packet * is equal to the ACK of incoming packet and the ACK is build * using packet sequence number and size of the data. */ - if (TCP_GET_ACK(p) == 0) { + if (TCP_GET_RAW_ACK(tcph) == 0) { lpacket->seq = 0; - lpacket->ack = TCP_GET_SEQ(p) + lpacket->dsize + 1; + lpacket->ack = TCP_GET_RAW_SEQ(tcph) + lpacket->dsize + 1; } else { - lpacket->seq = TCP_GET_ACK(p); - lpacket->ack = TCP_GET_SEQ(p) + lpacket->dsize; + lpacket->seq = TCP_GET_RAW_ACK(tcph); + lpacket->ack = TCP_GET_RAW_SEQ(tcph) + lpacket->dsize; } - lpacket->sp = TCP_GET_DST_PORT(p); - lpacket->dp = TCP_GET_SRC_PORT(p); + lpacket->sp = p->dp; + lpacket->dp = p->sp; break; case REJECT_DIR_DST: default: SCLogDebug("sending a tcp reset to dst"); - lpacket->seq = TCP_GET_SEQ(p); - lpacket->ack = TCP_GET_ACK(p); + lpacket->seq = TCP_GET_RAW_SEQ(tcph); + lpacket->ack = TCP_GET_RAW_ACK(tcph); - lpacket->sp = TCP_GET_SRC_PORT(p); - lpacket->dp = TCP_GET_DST_PORT(p); + lpacket->sp = p->sp; + lpacket->dp = p->dp; break; } - lpacket->window = TCP_GET_WINDOW(p); + lpacket->window = TCP_GET_RAW_WINDOW(tcph); //lpacket.seq += lpacket.dsize; } diff --git a/src/stream-tcp-inline.c b/src/stream-tcp-inline.c index 80783ef035..f440e1f7f4 100644 --- a/src/stream-tcp-inline.c +++ b/src/stream-tcp-inline.c @@ -63,7 +63,8 @@ int StreamTcpInlineSegmentCompare(const TcpStream *stream, if (seg_data == NULL || seg_datalen == 0) SCReturnInt(0); - const uint32_t pkt_seq = TCP_GET_SEQ(p); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t pkt_seq = TCP_GET_RAW_SEQ(tcph); if (SEQ_EQ(pkt_seq, seg->seq) && p->payload_len == seg_datalen) { int r = SCMemcmp(p->payload, seg_data, seg_datalen); @@ -122,7 +123,8 @@ void StreamTcpInlineSegmentReplacePacket(const TcpStream *stream, { SCEnter(); - uint32_t pseq = TCP_GET_SEQ(p); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t pseq = TCP_GET_RAW_SEQ(tcph); uint32_t tseq = seg->seq; /* check if segment is within the packet */ diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index 7321f941b7..6873a56b91 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -276,7 +276,7 @@ enum TcpState { } else { \ SCLogDebug("setting event %d on pkt %p (%" PRIu64 ")", (e), p, (p)->pcap_cnt); \ ENGINE_SET_EVENT((p), (e)); \ - p->tcpvars.stream_pkt_flags |= STREAM_PKT_FLAG_EVENTSET; \ + p->l4.vars.tcp.stream_pkt_flags |= STREAM_PKT_FLAG_EVENTSET; \ } \ } @@ -321,6 +321,6 @@ typedef struct TcpSession_ { #define STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE BIT_U16(11) #define STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE_ACK BIT_U16(12) -#define STREAM_PKT_FLAG_SET(p, f) (p)->tcpvars.stream_pkt_flags |= (f) +#define STREAM_PKT_FLAG_SET(p, f) (p)->l4.vars.tcp.stream_pkt_flags |= (f) #endif /* SURICATA_STREAM_TCP_PRIVATE_H */ diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 389e028ce4..080f679617 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -757,9 +757,12 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre SCReturnInt(0); } + const TCPHdr *tcph = PacketGetTCP(p); + /* If we have reached the defined depth for either of the stream, then stop reassembling the TCP session */ - uint32_t size = StreamTcpReassembleCheckDepth(ssn, stream, TCP_GET_SEQ(p), p->payload_len); + uint32_t size = + StreamTcpReassembleCheckDepth(ssn, stream, TCP_GET_RAW_SEQ(tcph), p->payload_len); SCLogDebug("ssn %p: check depth returned %"PRIu32, ssn, size); if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { @@ -787,10 +790,10 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre DEBUG_VALIDATE_BUG_ON(size > UINT16_MAX); TCP_SEG_LEN(seg) = (uint16_t)size; - seg->seq = TCP_GET_SEQ(p); + seg->seq = TCP_GET_RAW_SEQ(tcph); /* HACK: for TFO SYN packets the seq for data starts at + 1 */ - if (TCP_HAS_TFO(p) && p->payload_len && (p->tcph->th_flags & TH_SYN)) + if (TCP_HAS_TFO(p) && p->payload_len && (tcph->th_flags & TH_SYN)) seg->seq += 1; /* proto detection skipped, but now we do get data. Set event. */ @@ -802,7 +805,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre } int r = StreamTcpReassembleInsertSegment( - tv, ra_ctx, stream, seg, p, TCP_GET_SEQ(p), p->payload, p->payload_len); + tv, ra_ctx, stream, seg, p, TCP_GET_RAW_SEQ(tcph), p->payload, p->payload_len); if (r < 0) { if (r == -SC_ENOMEM) { ssn->flags |= STREAMTCP_FLAG_LOSSY_BE_LIBERAL; @@ -1595,7 +1598,9 @@ static int StreamReassembleRawInline(TcpSession *ssn, const Packet *p, p->payload_len, chunk_size); } - uint64_t packet_leftedge_abs = STREAM_BASE_OFFSET(stream) + (TCP_GET_SEQ(p) - stream->base_seq); + const TCPHdr *tcph = PacketGetTCP(p); + uint64_t packet_leftedge_abs = + STREAM_BASE_OFFSET(stream) + (TCP_GET_RAW_SEQ(tcph) - stream->base_seq); uint64_t packet_rightedge_abs = packet_leftedge_abs + p->payload_len; SCLogDebug("packet_leftedge_abs %"PRIu64", rightedge %"PRIu64, packet_leftedge_abs, packet_rightedge_abs); @@ -1959,6 +1964,7 @@ int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ SCEnter(); DEBUG_VALIDATE_BUG_ON(!PacketIsTCP(p)); + const TCPHdr *tcph = PacketGetTCP(p); SCLogDebug("ssn %p, stream %p, p %p, p->payload_len %"PRIu16"", ssn, stream, p, p->payload_len); @@ -1970,10 +1976,10 @@ int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ dir = UPDATE_DIR_PACKET; } else if (p->flags & PKT_PSEUDO_STREAM_END) { dir = UPDATE_DIR_PACKET; - } else if (p->tcph->th_flags & TH_RST) { // accepted rst + } else if (tcph->th_flags & TH_RST) { // accepted rst dir = UPDATE_DIR_PACKET; - } else if ((p->tcph->th_flags & TH_FIN) && ssn->state > TCP_TIME_WAIT) { - if (p->tcph->th_flags & TH_ACK) { + } else if ((tcph->th_flags & TH_FIN) && ssn->state > TCP_TIME_WAIT) { + if (tcph->th_flags & TH_ACK) { dir = UPDATE_DIR_BOTH; } else { dir = UPDATE_DIR_PACKET; @@ -2011,7 +2017,7 @@ int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ } /* if this segment contains data, insert it */ if (p->payload_len > 0 && !(stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) && - (p->tcph->th_flags & TH_RST) == 0) { + (tcph->th_flags & TH_RST) == 0) { SCLogDebug("calling StreamTcpReassembleHandleSegmentHandleData"); if (StreamTcpReassembleHandleSegmentHandleData(tv, ra_ctx, ssn, stream, p) != 0) { @@ -2392,30 +2398,30 @@ static int StreamTcpReassembleTest33(void) p->flow = &f; tcph.th_win = 5480; tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; p->payload = packet; - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(10); + tcph.th_ack = htonl(31); p->payload_len = 10; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(20); + tcph.th_ack = htonl(31); p->payload_len = 10; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(40); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(40); + tcph.th_ack = htonl(31); p->payload_len = 10; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(5); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(5); + tcph.th_ack = htonl(31); p->payload_len = 30; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); @@ -2452,31 +2458,31 @@ static int StreamTcpReassembleTest34(void) p->flow = &f; tcph.th_win = 5480; tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; p->payload = packet; SET_ISN(&ssn.client, 857961230); - p->tcph->th_seq = htonl(857961230); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(857961230); + tcph.th_ack = htonl(31); p->payload_len = 304; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(857961534); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(857961534); + tcph.th_ack = htonl(31); p->payload_len = 1460; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(857963582); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(857963582); + tcph.th_ack = htonl(31); p->payload_len = 1460; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(857960946); - p->tcph->th_ack = htonl(31); + tcph.th_seq = htonl(857960946); + tcph.th_ack = htonl(31); p->payload_len = 1460; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, &ssn.client, p) == -1); @@ -2514,7 +2520,7 @@ static int StreamTcpReassembleTest39 (void) f.flags = FLOW_IPV4; f.proto = IPPROTO_TCP; p->flow = &f; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); StreamTcpUTInit(&stt.ra_ctx); @@ -2544,8 +2550,8 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(ssn->data_first_seen_dir != 0); /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2565,9 +2571,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(ssn->data_first_seen_dir != 0); /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2588,9 +2594,9 @@ static int StreamTcpReassembleTest39 (void) /* partial request */ uint8_t request1[] = { 0x47, 0x45, }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request1); p->payload = request1; @@ -2611,9 +2617,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); /* response ack against partial request */ - p->tcph->th_ack = htonl(3); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(3); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2646,9 +2652,9 @@ static int StreamTcpReassembleTest39 (void) 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(3); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(3); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request2); p->payload = request2; @@ -2712,9 +2718,9 @@ static int StreamTcpReassembleTest39 (void) 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = sizeof(response); p->payload = response; @@ -2737,9 +2743,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)))); /* response ack from request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2762,9 +2768,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree))); /* response - acking */ - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(328); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2787,9 +2793,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree))); /* response ack from request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -2811,9 +2817,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree))); /* response - acking the request again*/ - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(88); + tcph.th_seq = htonl(328); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2837,9 +2843,9 @@ static int StreamTcpReassembleTest39 (void) /*** New Request ***/ /* partial request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(88); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request1); p->payload = request1; @@ -2862,9 +2868,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree))); /* response ack against partial request */ - p->tcph->th_ack = htonl(90); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(90); + tcph.th_seq = htonl(328); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2888,9 +2894,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree))); /* complete request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(90); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(90); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = sizeof(request2); p->payload = request2; @@ -2914,9 +2920,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree))); /* response ack against second partial request */ - p->tcph->th_ack = htonl(175); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(175); + tcph.th_seq = htonl(328); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2941,9 +2947,9 @@ static int StreamTcpReassembleTest39 (void) FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree))); /* response acking a request */ - p->tcph->th_ack = htonl(175); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(175); + tcph.th_seq = htonl(328); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; p->payload_len = 0; p->payload = NULL; @@ -2958,9 +2964,9 @@ static int StreamTcpReassembleTest39 (void) StreamTcpPruneSession(&f, STREAM_TOCLIENT); /* request acking a response */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(175); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(328); + tcph.th_seq = htonl(175); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; p->payload_len = 0; p->payload = NULL; @@ -3023,7 +3029,7 @@ static int StreamTcpReassembleTest40 (void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(10); tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; p->payload = httpbuf1; p->payload_len = httplen1; @@ -3234,6 +3240,7 @@ static int StreamTcpReassembleTest47 (void) TcpSession ssn; ThreadVars tv; memset(&tcph, 0, sizeof (TCPHdr)); + UTHSetTCPHdr(p, &tcph); memset(&tv, 0, sizeof (ThreadVars)); StreamTcpInitConfig(true); StreamTcpUTSetupSession(&ssn); @@ -3262,8 +3269,7 @@ static int StreamTcpReassembleTest47 (void) for (cnt=0; cnt < httplen1; cnt++) { tcph.th_seq = htonl(ssn.client.isn + 1 + cnt); tcph.th_ack = htonl(572799782UL); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; p->payload = &httpbuf1[cnt]; p->payload_len = 1; @@ -3277,7 +3283,6 @@ static int StreamTcpReassembleTest47 (void) tcph.th_seq = htonl(572799782UL); tcph.th_ack = htonl(ssn.client.isn + 1 + cnt); tcph.th_flags = TH_ACK; - p->tcph = &tcph; s = &ssn.server; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p) == -1); @@ -3316,7 +3321,7 @@ static int StreamTcpReassembleInlineTest01(void) printf("couldn't get a packet: "); goto end; } - p->tcph->th_seq = htonl(12); + p->l4.hdrs.tcph->th_seq = htonl(12); p->flow = &f; if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { @@ -3366,7 +3371,7 @@ static int StreamTcpReassembleInlineTest02(void) printf("couldn't get a packet: "); goto end; } - p->tcph->th_seq = htonl(12); + p->l4.hdrs.tcph->th_seq = htonl(12); p->flow = &f; if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { @@ -3424,7 +3429,7 @@ static int StreamTcpReassembleInlineTest03(void) printf("couldn't get a packet: "); goto end; } - p->tcph->th_seq = htonl(12); + p->l4.hdrs.tcph->th_seq = htonl(12); p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; @@ -3447,7 +3452,7 @@ static int StreamTcpReassembleInlineTest03(void) } ssn.client.next_seq = 22; - p->tcph->th_seq = htonl(17); + p->l4.hdrs.tcph->th_seq = htonl(17); ret = 1; end: FLOW_DESTROY(&f); @@ -3485,7 +3490,7 @@ static int StreamTcpReassembleInlineTest04(void) printf("couldn't get a packet: "); goto end; } - p->tcph->th_seq = htonl(12); + p->l4.hdrs.tcph->th_seq = htonl(12); p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; @@ -3508,7 +3513,7 @@ static int StreamTcpReassembleInlineTest04(void) } ssn.client.next_seq = 22; - p->tcph->th_seq = htonl(17); + p->l4.hdrs.tcph->th_seq = htonl(17); ret = 1; end: FLOW_DESTROY(&f); @@ -3542,7 +3547,7 @@ static int StreamTcpReassembleInlineTest08(void) uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); FAIL_IF(p == NULL); - p->tcph->th_seq = htonl(12); + p->l4.hdrs.tcph->th_seq = htonl(12); p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; @@ -3552,7 +3557,7 @@ static int StreamTcpReassembleInlineTest08(void) ssn.client.next_seq = 17; FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1); ssn.client.next_seq = 22; - p->tcph->th_seq = htonl(17); + p->l4.hdrs.tcph->th_seq = htonl(17); StreamTcpPruneSession(&f, STREAM_TOSERVER); TcpSegment *seg = RB_MIN(TCPSEG, &ssn.client.seg_tree); @@ -3595,7 +3600,7 @@ static int StreamTcpReassembleInlineTest09(void) printf("couldn't get a packet: "); goto end; } - p->tcph->th_seq = htonl(17); + p->l4.hdrs.tcph->th_seq = htonl(17); p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; @@ -3621,7 +3626,7 @@ static int StreamTcpReassembleInlineTest09(void) } ssn.client.next_seq = 22; - p->tcph->th_seq = htonl(12); + p->l4.hdrs.tcph->th_seq = htonl(12); TcpSegment *seg = RB_MIN(TCPSEG, &ssn.client.seg_tree); FAIL_IF_NULL(seg); @@ -3673,7 +3678,7 @@ static int StreamTcpReassembleInlineTest10(void) printf("couldn't get a packet: "); goto end; } - p->tcph->th_seq = htonl(7); + p->l4.hdrs.tcph->th_seq = htonl(7); p->flow = f; p->flowflags = FLOW_PKT_TOSERVER; @@ -3742,7 +3747,7 @@ static int StreamTcpReassembleInsertTest01(void) uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); FAIL_IF(p == NULL); - p->tcph->th_seq = htonl(12); + p->l4.hdrs.tcph->th_seq = htonl(12); p->flow = &f; FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1); diff --git a/src/stream-tcp-sack.c b/src/stream-tcp-sack.c index f97dfc4afd..5772b5898a 100644 --- a/src/stream-tcp-sack.c +++ b/src/stream-tcp-sack.c @@ -250,8 +250,9 @@ int StreamTcpSackUpdatePacket(TcpStream *stream, Packet *p) { SCEnter(); + const TCPHdr *tcph = PacketGetTCP(p); const int records = TCP_GET_SACK_CNT(p); - const uint8_t *data = TCP_GET_SACK_PTR(p); + const uint8_t *data = TCP_GET_SACK_PTR(p, tcph); if (records == 0 || data == NULL) SCReturnInt(0); @@ -272,18 +273,18 @@ int StreamTcpSackUpdatePacket(TcpStream *stream, Packet *p) first_re = re; SCLogDebug("%p last_ack %u, left edge %u, right edge %u pkt ACK %u", sack_rec, - stream->last_ack, le, re, TCP_GET_ACK(p)); + stream->last_ack, le, re, TCP_GET_RAW_ACK(tcph)); /* RFC 2883 D-SACK */ - if (SEQ_LT(le, TCP_GET_ACK(p))) { + if (SEQ_LT(le, TCP_GET_RAW_ACK(tcph))) { SCLogDebug("packet: %" PRIu64 ": D-SACK? %u-%u before ACK %u", p->pcap_cnt, le, re, - TCP_GET_ACK(p)); + TCP_GET_RAW_ACK(tcph)); STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_DSACK); goto next; } else if (record == 1) { // 2nd record if (SEQ_GEQ(first_le, le) && SEQ_LEQ(first_re, re)) { SCLogDebug("packet: %" PRIu64 ": D-SACK? %u-%u inside 2nd range %u-%u ACK %u", - p->pcap_cnt, first_le, first_re, le, re, TCP_GET_ACK(p)); + p->pcap_cnt, first_le, first_re, le, re, TCP_GET_RAW_ACK(tcph)); STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_DSACK); } goto next; @@ -355,8 +356,9 @@ static struct StreamTcpSackRecord *FindOverlap( bool StreamTcpSackPacketIsOutdated(TcpStream *stream, Packet *p) { + const TCPHdr *tcph = PacketGetTCP(p); const int records = TCP_GET_SACK_CNT(p); - const uint8_t *data = TCP_GET_SACK_PTR(p); + const uint8_t *data = TCP_GET_SACK_PTR(p, tcph); if (records > 0 && data != NULL) { int sack_outdated = 0; TCPOptSackRecord rec[records], *sack_rec = rec; diff --git a/src/stream-tcp-util.c b/src/stream-tcp-util.c index 4d8bf8a893..ea63578544 100644 --- a/src/stream-tcp-util.c +++ b/src/stream-tcp-util.c @@ -100,8 +100,8 @@ int StreamTcpUTAddPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSes if (p == NULL) { return -1; } - p->tcph->th_seq = htonl(seq); - p->tcph->th_ack = htonl(31); + p->l4.hdrs.tcph->th_seq = htonl(seq); + p->l4.hdrs.tcph->th_ack = htonl(31); if (StreamTcpReassembleHandleSegmentHandleData(tv, ra_ctx, ssn, stream, p) < 0) return -1; @@ -124,9 +124,10 @@ int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ if (p == NULL) { return -1; } - p->tcph->th_seq = htonl(seq); + p->l4.hdrs.tcph->th_seq = htonl(seq); - if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_SEQ(p), p->payload, p->payload_len) < 0) + if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_RAW_SEQ(p->l4.hdrs.tcph), + p->payload, p->payload_len) < 0) return -1; UTHFreePacket(p); @@ -149,9 +150,10 @@ int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx if (p == NULL) { return -1; } - p->tcph->th_seq = htonl(seq); + p->l4.hdrs.tcph->th_seq = htonl(seq); - if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_SEQ(p), p->payload, p->payload_len) < 0) + if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_RAW_SEQ(p->l4.hdrs.tcph), + p->payload, p->payload_len) < 0) return -1; UTHFreePacket(p); return 0; diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 7be5f9bef1..641a59cfac 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -882,9 +882,10 @@ static TcpSession *StreamTcpNewSession(ThreadVars *tv, StreamTcpThread *stt, Pac return NULL; } + const TCPHdr *tcph = PacketGetTCP(p); ssn->state = TCP_NONE; ssn->reassembly_depth = stream_config.reassembly_depth; - ssn->tcp_packet_flags = p->tcph ? p->tcph->th_flags : 0; + ssn->tcp_packet_flags = tcph->th_flags; ssn->server.flags = stream_config.stream_init_flags; ssn->client.flags = stream_config.stream_init_flags; @@ -893,10 +894,10 @@ static TcpSession *StreamTcpNewSession(ThreadVars *tv, StreamTcpThread *stt, Pac ssn->server.sb = x; if (PKT_IS_TOSERVER(p)) { - ssn->client.tcp_flags = p->tcph ? p->tcph->th_flags : 0; + ssn->client.tcp_flags = tcph->th_flags; ssn->server.tcp_flags = 0; } else if (PKT_IS_TOCLIENT(p)) { - ssn->server.tcp_flags = p->tcph ? p->tcph->th_flags : 0; + ssn->server.tcp_flags = tcph->th_flags; ssn->client.tcp_flags = 0; } } @@ -1062,27 +1063,28 @@ static int StreamTcpPacketIsRetransmission(TcpStream *stream, Packet *p) if (p->payload_len == 0) SCReturnInt(0); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); /* retransmission of already partially ack'd data */ - if (SEQ_LT(TCP_GET_SEQ(p), stream->last_ack) && SEQ_GT((TCP_GET_SEQ(p) + p->payload_len), stream->last_ack)) - { + if (SEQ_LT(seq, stream->last_ack) && SEQ_GT((seq + p->payload_len), stream->last_ack)) { StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION); SCReturnInt(1); } /* retransmission of already ack'd data */ - if (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), stream->last_ack)) { + if (SEQ_LEQ((seq + p->payload_len), stream->last_ack)) { StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION); SCReturnInt(1); } /* retransmission of in flight data */ - if (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), stream->next_seq)) { + if (SEQ_LEQ((seq + p->payload_len), stream->next_seq)) { StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION); SCReturnInt(2); } - SCLogDebug("seq %u payload_len %u => %u, last_ack %u, next_seq %u", TCP_GET_SEQ(p), - p->payload_len, (TCP_GET_SEQ(p) + p->payload_len), stream->last_ack, stream->next_seq); + SCLogDebug("seq %u payload_len %u => %u, last_ack %u, next_seq %u", seq, p->payload_len, + (seq + p->payload_len), stream->last_ack, stream->next_seq); SCReturnInt(0); } @@ -1102,12 +1104,13 @@ static int StreamTcpPacketIsRetransmission(TcpStream *stream, Packet *p) static int StreamTcpPacketStateNone( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { - if (p->tcph->th_flags & TH_RST) { + const TCPHdr *tcph = PacketGetTCP(p); + if (tcph->th_flags & TH_RST) { StreamTcpSetEvent(p, STREAM_RST_BUT_NO_SESSION); SCLogDebug("RST packet received, no session setup"); return -1; - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { /* Drop reason will only be used if midstream policy is set to fail closed */ ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM); StreamTcpMidstreamExceptionPolicyStatsIncr(tv, stt, stream_config.midstream_policy); @@ -1154,19 +1157,19 @@ static int StreamTcpPacketStateNone( ssn->server.wscale = TCP_WSCALE_MAX; /* set the sequence numbers and window */ - ssn->client.isn = TCP_GET_SEQ(p) - 1; + ssn->client.isn = TCP_GET_RAW_SEQ(tcph) - 1; STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1; - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - ssn->client.last_ack = TCP_GET_SEQ(p); + ssn->client.next_seq = TCP_GET_RAW_SEQ(tcph) + p->payload_len + 1; + ssn->client.window = TCP_GET_RAW_WINDOW(tcph) << ssn->client.wscale; + ssn->client.last_ack = TCP_GET_RAW_SEQ(tcph); ssn->client.next_win = ssn->client.last_ack + ssn->client.window; SCLogDebug("ssn %p: ssn->client.isn %u, ssn->client.next_seq %u", ssn, ssn->client.isn, ssn->client.next_seq); - ssn->server.isn = TCP_GET_ACK(p) - 1; + ssn->server.isn = TCP_GET_RAW_ACK(tcph) - 1; STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); ssn->server.next_seq = ssn->server.isn + 1; - ssn->server.last_ack = TCP_GET_ACK(p); + ssn->server.last_ack = TCP_GET_RAW_ACK(tcph); ssn->server.next_win = ssn->server.last_ack; SCLogDebug("ssn %p: ssn->client.next_win %" PRIu32 ", " @@ -1204,7 +1207,7 @@ static int StreamTcpPacketStateNone( SCLogDebug("ssn %p: assuming SACK permitted for both sides", ssn); /* SYN/ACK */ - } else if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { + } else if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { /* Drop reason will only be used if midstream policy is set to fail closed */ ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM); StreamTcpMidstreamExceptionPolicyStatsIncr(tv, stt, stream_config.midstream_policy); @@ -1249,18 +1252,18 @@ static int StreamTcpPacketStateNone( } /* sequence number & window */ - ssn->server.isn = TCP_GET_SEQ(p); + ssn->server.isn = TCP_GET_RAW_SEQ(tcph); STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); ssn->server.next_seq = ssn->server.isn + 1; - ssn->server.window = TCP_GET_WINDOW(p); + ssn->server.window = TCP_GET_RAW_WINDOW(tcph); SCLogDebug("ssn %p: server window %u", ssn, ssn->server.window); - ssn->client.isn = TCP_GET_ACK(p) - 1; + ssn->client.isn = TCP_GET_RAW_ACK(tcph) - 1; STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); ssn->client.next_seq = ssn->client.isn + 1; - ssn->client.last_ack = TCP_GET_ACK(p); - ssn->server.last_ack = TCP_GET_SEQ(p); + ssn->client.last_ack = TCP_GET_RAW_ACK(tcph); + ssn->server.last_ack = TCP_GET_RAW_SEQ(tcph); ssn->server.next_win = ssn->server.last_ack + ssn->server.window; @@ -1312,7 +1315,7 @@ static int StreamTcpPacketStateNone( } return 0; - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { if (ssn == NULL) { ssn = StreamTcpNewSession(tv, stt, p, stt->ssn_pool_id); if (ssn == NULL) { @@ -1334,7 +1337,7 @@ static int StreamTcpPacketStateNone( } /* set the sequence numbers and window */ - ssn->client.isn = TCP_GET_SEQ(p); + ssn->client.isn = TCP_GET_RAW_SEQ(tcph); STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); ssn->client.next_seq = ssn->client.isn + 1; @@ -1351,7 +1354,7 @@ static int StreamTcpPacketStateNone( ssn->client.flags |= STREAMTCP_STREAM_FLAG_TIMESTAMP; } - ssn->server.window = TCP_GET_WINDOW(p); + ssn->server.window = TCP_GET_RAW_WINDOW(tcph); if (TCP_HAS_WSCALE(p)) { ssn->flags |= STREAMTCP_FLAG_SERVER_WSCALE; ssn->server.wscale = TCP_GET_WSCALE(p); @@ -1378,7 +1381,7 @@ static int StreamTcpPacketStateNone( "%"PRIu32"", ssn, ssn->client.isn, ssn->client.next_seq, ssn->client.last_ack); - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { /* Drop reason will only be used if midstream policy is set to fail closed */ ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM); StreamTcpMidstreamExceptionPolicyStatsIncr(tv, stt, stream_config.midstream_policy); @@ -1422,19 +1425,19 @@ static int StreamTcpPacketStateNone( ssn->server.wscale = TCP_WSCALE_MAX; /* set the sequence numbers and window */ - ssn->client.isn = TCP_GET_SEQ(p) - 1; + ssn->client.isn = TCP_GET_RAW_SEQ(tcph) - 1; STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - ssn->client.last_ack = TCP_GET_SEQ(p); + ssn->client.next_seq = TCP_GET_RAW_SEQ(tcph) + p->payload_len; + ssn->client.window = TCP_GET_RAW_WINDOW(tcph) << ssn->client.wscale; + ssn->client.last_ack = TCP_GET_RAW_SEQ(tcph); ssn->client.next_win = ssn->client.last_ack + ssn->client.window; SCLogDebug("ssn %p: ssn->client.isn %u, ssn->client.next_seq %u", ssn, ssn->client.isn, ssn->client.next_seq); - ssn->server.isn = TCP_GET_ACK(p) - 1; + ssn->server.isn = TCP_GET_RAW_ACK(tcph) - 1; STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); ssn->server.next_seq = ssn->server.isn + 1; - ssn->server.last_ack = TCP_GET_ACK(p); + ssn->server.last_ack = TCP_GET_RAW_ACK(tcph); ssn->server.next_win = ssn->server.last_ack; SCLogDebug("ssn %p: ssn->client.next_win %"PRIu32", " @@ -1483,12 +1486,13 @@ static int StreamTcpPacketStateNone( */ static inline void StreamTcp3whsSynAckToStateQueue(Packet *p, TcpStateQueue *q) { + const TCPHdr *tcph = PacketGetTCP(p); q->flags = 0; q->wscale = 0; q->ts = 0; - q->win = TCP_GET_WINDOW(p); - q->seq = TCP_GET_SEQ(p); - q->ack = TCP_GET_ACK(p); + q->win = TCP_GET_RAW_WINDOW(tcph); + q->seq = TCP_GET_RAW_SEQ(tcph); + q->ack = TCP_GET_RAW_ACK(tcph); q->pkt_ts = SCTIME_SECS(p->ts); if (TCP_GET_SACKOK(p)) @@ -1568,8 +1572,9 @@ static int StreamTcp3whsQueueSynAck(TcpSession *ssn, Packet *p) * \retval q or NULL */ static TcpStateQueue *StreamTcp3whsFindSynAckByAck(TcpSession *ssn, Packet *p) { - uint32_t ack = TCP_GET_SEQ(p); - uint32_t seq = TCP_GET_ACK(p) - 1; + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t ack = TCP_GET_RAW_SEQ(tcph); + const uint32_t seq = TCP_GET_RAW_ACK(tcph) - 1; TcpStateQueue *q = ssn->queue; while (q != NULL) { @@ -1748,8 +1753,9 @@ static void TcpStateQueueInitFromPktSyn(const Packet *p, TcpStateQueue *q) BUG_ON(ssn->state != TCP_SYN_SENT); #endif memset(q, 0, sizeof(*q)); + const TCPHdr *tcph = PacketGetTCP(p); - q->win = TCP_GET_WINDOW(p); + q->win = TCP_GET_RAW_WINDOW(tcph); q->pkt_ts = SCTIME_SECS(p->ts); if (TCP_GET_SACKOK(p)) { @@ -1781,7 +1787,8 @@ static void TcpStateQueueInitFromPktSynAck(const Packet *p, TcpStateQueue *q) #endif memset(q, 0, sizeof(*q)); - q->win = TCP_GET_WINDOW(p); + const TCPHdr *tcph = PacketGetTCP(p); + q->win = TCP_GET_RAW_WINDOW(tcph); q->pkt_ts = SCTIME_SECS(p->ts); if (TCP_GET_SACKOK(p)) { @@ -1895,32 +1902,33 @@ static int StreamTcpPacketStateSynSent( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); SCLogDebug("ssn %p: pkt received: %s", ssn, PKT_IS_TOCLIENT(p) ? "toclient" : "toserver"); /* common case: SYN/ACK from server to client */ - if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK) && PKT_IS_TOCLIENT(p)) { + if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK) && PKT_IS_TOCLIENT(p)) { SCLogDebug("ssn %p: SYN/ACK on SYN_SENT state for packet %" PRIu64, ssn, p->pcap_cnt); if (!(TCP_HAS_TFO(p) || (ssn->flags & STREAMTCP_FLAG_TCP_FAST_OPEN))) { /* Check if the SYN/ACK packet ack's the earlier * received SYN packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.isn + 1))) { + if (!(SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->client.isn + 1))) { StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_WITH_WRONG_ACK); SCLogDebug("ssn %p: ACK mismatch, packet ACK %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); + "%" PRIu32 " from stream", + ssn, TCP_GET_RAW_ACK(tcph), ssn->client.isn + 1); return -1; } } else { - if (SEQ_EQ(TCP_GET_ACK(p), ssn->client.next_seq)) { + if (SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->client.next_seq)) { SCLogDebug("ssn %p: (TFO) ACK matches next_seq, packet ACK %" PRIu32 " == " "%" PRIu32 " from stream", - ssn, TCP_GET_ACK(p), ssn->client.next_seq); - } else if (SEQ_EQ(TCP_GET_ACK(p), ssn->client.isn + 1)) { + ssn, TCP_GET_RAW_ACK(tcph), ssn->client.next_seq); + } else if (SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->client.isn + 1)) { SCLogDebug("ssn %p: (TFO) ACK matches ISN+1, packet ACK %" PRIu32 " == " "%" PRIu32 " from stream", - ssn, TCP_GET_ACK(p), ssn->client.isn + 1); + ssn, TCP_GET_RAW_ACK(tcph), ssn->client.isn + 1); ssn->client.next_seq = ssn->client.isn; // reset to ISN SCLogDebug("ssn %p: (TFO) next_seq reset to isn (%u)", ssn, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_TFO_DATA_IGNORED); @@ -1928,8 +1936,8 @@ static int StreamTcpPacketStateSynSent( } else { StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_WITH_WRONG_ACK); SCLogDebug("ssn %p: (TFO) ACK mismatch, packet ACK %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.next_seq); + "%" PRIu32 " from stream", + ssn, TCP_GET_RAW_ACK(tcph), ssn->client.next_seq); return -1; } ssn->flags |= STREAMTCP_FLAG_TCP_FAST_OPEN; @@ -1968,7 +1976,7 @@ static int StreamTcpPacketStateSynSent( StreamTcp3whsSynAckUpdate(ssn, p, /* no queue override */NULL); return 0; - } else if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK) && PKT_IS_TOSERVER(p)) { + } else if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK) && PKT_IS_TOSERVER(p)) { if (!(ssn->flags & STREAMTCP_FLAG_4WHS)) { StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_IN_WRONG_DIRECTION); @@ -1980,23 +1988,23 @@ static int StreamTcpPacketStateSynSent( /* Check if the SYN/ACK packet ack's the earlier * received SYN packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->server.isn + 1))) { + if (!(SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->server.isn + 1))) { StreamTcpSetEvent(p, STREAM_4WHS_SYNACK_WITH_WRONG_ACK); SCLogDebug("ssn %p: 4WHS ACK mismatch, packet ACK %" PRIu32 "" " != %" PRIu32 " from stream", - ssn, TCP_GET_ACK(p), ssn->server.isn + 1); + ssn, TCP_GET_RAW_ACK(tcph), ssn->server.isn + 1); return -1; } /* Check if the SYN/ACK packet SEQ's the *FIRST* received SYN * packet. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn))) { + if (!(SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->client.isn))) { StreamTcpSetEvent(p, STREAM_4WHS_SYNACK_WITH_WRONG_SYN); SCLogDebug("ssn %p: 4WHS SEQ mismatch, packet SEQ %" PRIu32 "" " != %" PRIu32 " from *first* SYN pkt", - ssn, TCP_GET_SEQ(p), ssn->client.isn); + ssn, TCP_GET_RAW_SEQ(tcph), ssn->client.isn); return -1; } @@ -2005,11 +2013,11 @@ static int StreamTcpPacketStateSynSent( SCLogDebug("ssn %p: =~ 4WHS ssn state is now TCP_SYN_RECV", ssn); /* sequence number & window */ - ssn->client.isn = TCP_GET_SEQ(p); + ssn->client.isn = TCP_GET_RAW_SEQ(tcph); STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); ssn->client.next_seq = ssn->client.isn + 1; - ssn->server.window = TCP_GET_WINDOW(p); + ssn->server.window = TCP_GET_RAW_WINDOW(tcph); SCLogDebug("ssn %p: 4WHS window %" PRIu32 "", ssn, ssn->client.window); /* Set the timestamp values used to validate the timestamp of @@ -2029,7 +2037,7 @@ static int StreamTcpPacketStateSynSent( ssn->server.flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; } - ssn->server.last_ack = TCP_GET_ACK(p); + ssn->server.last_ack = TCP_GET_RAW_ACK(tcph); ssn->client.last_ack = ssn->client.isn + 1; /** check for the presense of the ws ptr to determine if we @@ -2067,14 +2075,15 @@ static int StreamTcpPacketStateSynSent( } /* RST */ - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; if (PKT_IS_TOSERVER(p)) { - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn) && SEQ_EQ(TCP_GET_WINDOW(p), 0) && - SEQ_EQ(TCP_GET_ACK(p), (ssn->client.isn + 1))) { + if (SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->client.isn) && + SEQ_EQ(TCP_GET_RAW_WINDOW(tcph), 0) && + SEQ_EQ(TCP_GET_RAW_ACK(tcph), (ssn->client.isn + 1))) { SCLogDebug("ssn->server.flags |= STREAMTCP_STREAM_FLAG_RST_RECV"); ssn->server.flags |= STREAMTCP_STREAM_FLAG_RST_RECV; StreamTcpCloseSsnWithReset(p, ssn); @@ -2088,10 +2097,10 @@ static int StreamTcpPacketStateSynSent( } /* FIN */ - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { /** \todo */ - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn %p: SYN packet on state SYN_SENT... resent", ssn); if (ssn->flags & STREAMTCP_FLAG_4WHS) { SCLogDebug("ssn %p: SYN packet on state SYN_SENT... resent of " @@ -2113,7 +2122,7 @@ static int StreamTcpPacketStateSynSent( * We leave the ssn->client.isn in place as we will * check the SYN/ACK pkt with that. */ - ssn->server.isn = TCP_GET_SEQ(p); + ssn->server.isn = TCP_GET_RAW_SEQ(tcph); STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); ssn->server.next_seq = ssn->server.isn + 1; @@ -2129,7 +2138,7 @@ static int StreamTcpPacketStateSynSent( ssn->server.flags |= STREAMTCP_STREAM_FLAG_TIMESTAMP; } - ssn->server.window = TCP_GET_WINDOW(p); + ssn->server.window = TCP_GET_RAW_WINDOW(tcph); if (TCP_HAS_WSCALE(p)) { ssn->flags |= STREAMTCP_FLAG_SERVER_WSCALE; ssn->server.wscale = TCP_GET_WSCALE(p); @@ -2172,7 +2181,7 @@ static int StreamTcpPacketStateSynSent( } StreamTcp3whsStoreSynApplyToSsn(ssn, &syn_pkt); } - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { /* Handle the asynchronous stream, when we receive a SYN packet and now instead of receiving a SYN/ACK we receive a ACK from the same host, which sent the SYN, this suggests the ASYNC streams.*/ @@ -2183,12 +2192,12 @@ static int StreamTcpPacketStateSynSent( /* one side async means we won't see a SYN/ACK, so we can * only check the SYN. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq))) { + if (!(SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq))) { StreamTcpSetEvent(p, STREAM_3WHS_ASYNC_WRONG_SEQ); SCLogDebug("ssn %p: SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream",ssn, TCP_GET_SEQ(p), - ssn->client.next_seq); + "%" PRIu32 " from stream", + ssn, TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq); return -1; } @@ -2197,22 +2206,22 @@ static int StreamTcpPacketStateSynSent( SCLogDebug("ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn); StreamTcp3wsFreeQueue(ssn); - ssn->client.window = TCP_GET_WINDOW(p); - ssn->client.last_ack = TCP_GET_SEQ(p); + ssn->client.window = TCP_GET_RAW_WINDOW(tcph); + ssn->client.last_ack = TCP_GET_RAW_SEQ(tcph); ssn->client.next_win = ssn->client.last_ack + ssn->client.window; /* Set the server side parameters */ - ssn->server.isn = TCP_GET_ACK(p) - 1; + ssn->server.isn = TCP_GET_RAW_ACK(tcph) - 1; STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); ssn->server.next_seq = ssn->server.isn + 1; ssn->server.last_ack = ssn->server.next_seq; ssn->server.next_win = ssn->server.last_ack; SCLogDebug("ssn %p: synsent => Asynchronous stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.next_seq %" PRIu32 "" - ,ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) - + p->payload_len, ssn->client.next_seq); + " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " + "ssn->client.next_seq %" PRIu32 "", + ssn, TCP_GET_RAW_SEQ(tcph), p->payload_len, TCP_GET_RAW_SEQ(tcph) + p->payload_len, + ssn->client.next_seq); /* if SYN had wscale, assume it to be supported. Otherwise * we know it not to be supported. */ @@ -2263,8 +2272,9 @@ static int StreamTcpPacketStateSynRecv( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; @@ -2305,7 +2315,7 @@ static int StreamTcpPacketStateSynRecv( } } - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { /* FIN is handled in the same way as in TCP_ESTABLISHED case */; if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) @@ -2316,7 +2326,7 @@ static int StreamTcpPacketStateSynRecv( return -1; /* SYN/ACK */ - } else if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { + } else if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { SCLogDebug("ssn %p: SYN/ACK packet on state SYN_RECV. resent", ssn); if (PKT_IS_TOSERVER(p)) { @@ -2328,10 +2338,10 @@ static int StreamTcpPacketStateSynRecv( /* Check if the SYN/ACK packets ACK matches the earlier * received SYN/ACK packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack))) { + if (!(SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->client.last_ack))) { SCLogDebug("ssn %p: ACK mismatch, packet ACK %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); + "%" PRIu32 " from stream", + ssn, TCP_GET_RAW_ACK(tcph), ssn->client.isn + 1); StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_RESEND_WITH_DIFFERENT_ACK); return -1; @@ -2339,17 +2349,17 @@ static int StreamTcpPacketStateSynRecv( /* Check if the SYN/ACK packet SEQ the earlier * received SYN/ACK packet, server resend with different ISN. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.isn))) { + if (!(SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->server.isn))) { SCLogDebug("ssn %p: SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_SEQ(p), - ssn->client.isn); + "%" PRIu32 " from stream", + ssn, TCP_GET_RAW_SEQ(tcph), ssn->client.isn); if (StreamTcp3whsQueueSynAck(ssn, p) == -1) return -1; SCLogDebug("ssn %p: queued different SYN/ACK", ssn); } - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn %p: SYN packet on state SYN_RECV... resent", ssn); if (PKT_IS_TOCLIENT(p)) { @@ -2359,14 +2369,14 @@ static int StreamTcpPacketStateSynRecv( return -1; } - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn))) { + if (!(SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->client.isn))) { SCLogDebug("ssn %p: SYN with different SEQ on SYN_RECV state", ssn); StreamTcpSetEvent(p, STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV); return -1; } - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { if (ssn->queue_len) { SCLogDebug("ssn %p: checking ACK against queued SYN/ACKs", ssn); TcpStateQueue *q = StreamTcp3whsFindSynAckByAck(ssn, p); @@ -2392,7 +2402,7 @@ static int StreamTcpPacketStateSynRecv( if ((ssn->flags & STREAMTCP_FLAG_4WHS) && PKT_IS_TOCLIENT(p)) { SCLogDebug("ssn %p: ACK received on 4WHS session",ssn); - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq))) { + if (!(SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->server.next_seq))) { SCLogDebug("ssn %p: 4WHS wrong seq nr on packet", ssn); StreamTcpSetEvent(p, STREAM_4WHS_WRONG_SEQ); return -1; @@ -2406,16 +2416,16 @@ static int StreamTcpPacketStateSynRecv( SCLogDebug("4WHS normal pkt"); SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, TCP_GET_RAW_SEQ(tcph), TCP_GET_RAW_ACK(tcph)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); } - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_RAW_ACK(tcph)); StreamTcpUpdateNextSeq(ssn, &ssn->server, (ssn->server.next_seq + p->payload_len)); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = TCP_GET_RAW_WINDOW(tcph) << ssn->client.wscale; ssn->client.next_win = ssn->client.last_ack + ssn->client.window; StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); @@ -2457,9 +2467,8 @@ static int StreamTcpPacketStateSynRecv( * careful. */ if (StreamTcpInlineMode()) { - if (p->payload_len > 0 && - SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack) && - SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq)) { + if (p->payload_len > 0 && SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->client.last_ack) && + SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->server.next_seq)) { /* packet loss is possible but unlikely here */ SCLogDebug("ssn %p: possible data injection", ssn); StreamTcpSetEvent(p, STREAM_3WHS_ACK_DATA_INJECT); @@ -2476,13 +2485,13 @@ static int StreamTcpPacketStateSynRecv( } SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 "" - ", ACK %" PRIu32 "", ssn, p->payload_len, TCP_GET_SEQ(p), - TCP_GET_ACK(p)); + ", ACK %" PRIu32 "", + ssn, p->payload_len, TCP_GET_RAW_SEQ(tcph), TCP_GET_RAW_ACK(tcph)); /* Check both seq and ack number before accepting the packet and changing to ESTABLISHED state */ - if ((SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)) && - SEQ_EQ(TCP_GET_ACK(p), ssn->server.next_seq)) { + if ((SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq)) && + SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->server.next_seq)) { SCLogDebug("normal pkt"); /* process the packet normal, No Async streams :) */ @@ -2491,14 +2500,14 @@ static int StreamTcpPacketStateSynRecv( StreamTcpHandleTimestamp(ssn, p); } - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_RAW_ACK(tcph)); StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len)); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = TCP_GET_RAW_WINDOW(tcph) << ssn->server.wscale; ssn->server.next_win = ssn->server.last_ack + ssn->server.window; if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) { - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = TCP_GET_RAW_WINDOW(tcph) << ssn->client.wscale; ssn->client.next_win = ssn->client.last_ack + ssn->client.window; ssn->server.next_win = ssn->server.last_ack + ssn->server.window; @@ -2518,22 +2527,23 @@ static int StreamTcpPacketStateSynRecv( /* If asynchronous stream handling is allowed then set the session, if packet's seq number is equal the expected seq no.*/ - } else if (stream_config.async_oneside && (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq))) { + } else if (stream_config.async_oneside && + (SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->server.next_seq))) { /*set the ASYNC flag used to indicate the session as async stream and helps in relaxing the windows checks.*/ ssn->flags |= STREAMTCP_FLAG_ASYNC; ssn->server.next_seq += p->payload_len; - ssn->server.last_ack = TCP_GET_SEQ(p); + ssn->server.last_ack = TCP_GET_RAW_SEQ(tcph); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - ssn->client.last_ack = TCP_GET_ACK(p); + ssn->client.window = TCP_GET_RAW_WINDOW(tcph) << ssn->client.wscale; + ssn->client.last_ack = TCP_GET_RAW_ACK(tcph); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); } if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) { - ssn->server.window = TCP_GET_WINDOW(p); + ssn->server.window = TCP_GET_RAW_WINDOW(tcph); ssn->server.next_win = ssn->server.last_ack + ssn->server.window; /* window scaling for midstream pickups, we can't do much * other than assume that it's set to the max value: 14 */ @@ -2543,10 +2553,10 @@ static int StreamTcpPacketStateSynRecv( } SCLogDebug("ssn %p: synrecv => Asynchronous stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->server.next_seq %" PRIu32 - , ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) - + p->payload_len, ssn->server.next_seq); + " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " + "ssn->server.next_seq %" PRIu32, + ssn, TCP_GET_RAW_SEQ(tcph), p->payload_len, + TCP_GET_RAW_SEQ(tcph) + p->payload_len, ssn->server.next_seq); StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); SCLogDebug("ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn); @@ -2556,7 +2566,7 @@ static int StreamTcpPacketStateSynRecv( ACK number, it causes the other end to send RST. But some target system (Linux & solaris) does not RST the connection, so it is likely to avoid the detection */ - } else if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)) { + } else if (SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq)) { ssn->flags |= STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT; SCLogDebug("ssn %p: wrong ack nr on packet, possible evasion!!", ssn); @@ -2566,24 +2576,24 @@ static int StreamTcpPacketStateSynRecv( /* SYN/ACK followed by more TOCLIENT suggesting packet loss */ } else if (PKT_IS_TOCLIENT(p) && !StreamTcpInlineMode() && - SEQ_GT(TCP_GET_SEQ(p), ssn->client.next_seq) && - SEQ_GT(TCP_GET_ACK(p), ssn->client.last_ack)) { + SEQ_GT(TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq) && + SEQ_GT(TCP_GET_RAW_ACK(tcph), ssn->client.last_ack)) { SCLogDebug("ssn %p: ACK for missing data", ssn); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); } - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_RAW_ACK(tcph)); - ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len; + ssn->server.next_seq = TCP_GET_RAW_SEQ(tcph) + p->payload_len; SCLogDebug("ssn %p: ACK for missing data: ssn->server.next_seq %u", ssn, ssn->server.next_seq); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = TCP_GET_RAW_WINDOW(tcph) << ssn->client.wscale; ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - ssn->client.window = TCP_GET_WINDOW(p); + ssn->client.window = TCP_GET_RAW_WINDOW(tcph); ssn->server.next_win = ssn->server.last_ack + ssn->server.window; StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); @@ -2593,24 +2603,24 @@ static int StreamTcpPacketStateSynRecv( /* if we get a packet with a proper ack, but a seq that is beyond * next_seq but in-window, we probably missed some packets */ - } else if (SEQ_GT(TCP_GET_SEQ(p), ssn->client.next_seq) && - SEQ_LEQ(TCP_GET_SEQ(p), ssn->client.next_win) && - SEQ_EQ(TCP_GET_ACK(p), ssn->server.next_seq)) { + } else if (SEQ_GT(TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq) && + SEQ_LEQ(TCP_GET_RAW_SEQ(tcph), ssn->client.next_win) && + SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->server.next_seq)) { SCLogDebug("ssn %p: ACK for missing data", ssn); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); } - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + ssn->client.next_seq = TCP_GET_RAW_SEQ(tcph) + p->payload_len; + StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_RAW_ACK(tcph)); SCLogDebug("ssn %p: ACK for missing data: ssn->client.next_seq %u", ssn, ssn->client.next_seq); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = TCP_GET_RAW_WINDOW(tcph) << ssn->server.wscale; ssn->server.next_win = ssn->server.last_ack + ssn->server.window; if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) { - ssn->client.window = TCP_GET_WINDOW(p); + ssn->client.window = TCP_GET_RAW_WINDOW(tcph); ssn->server.next_win = ssn->server.last_ack + ssn->server.window; /* window scaling for midstream pickups, we can't do much @@ -2628,17 +2638,17 @@ static int StreamTcpPacketStateSynRecv( /* toclient packet: after having missed the 3whs's final ACK */ } else if ((ack_indicates_missed_3whs_ack_packet || (ssn->flags & STREAMTCP_FLAG_TCP_FAST_OPEN)) && - SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack) && - SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq)) { + SEQ_EQ(TCP_GET_RAW_ACK(tcph), ssn->client.last_ack) && + SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->server.next_seq)) { if (ack_indicates_missed_3whs_ack_packet) { SCLogDebug("ssn %p: packet fits perfectly after a missed 3whs-ACK", ssn); } else { SCLogDebug("ssn %p: (TFO) expected packet fits perfectly after SYN/ACK", ssn); } - StreamTcpUpdateNextSeq(ssn, &ssn->server, (TCP_GET_SEQ(p) + p->payload_len)); + StreamTcpUpdateNextSeq(ssn, &ssn->server, (TCP_GET_RAW_SEQ(tcph) + p->payload_len)); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = TCP_GET_RAW_WINDOW(tcph) << ssn->server.wscale; ssn->server.next_win = ssn->server.last_ack + ssn->server.window; StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); @@ -2679,13 +2689,18 @@ static int StreamTcpPacketStateSynRecv( static int HandleEstablishedPacketToServer( ThreadVars *tv, TcpSession *ssn, Packet *p, StreamTcpThread *stt) { + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); + SCLogDebug("ssn %p: =+ pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 "," - "ACK %" PRIu32 ", WIN %"PRIu16"", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p)); + "ACK %" PRIu32 ", WIN %" PRIu16 "", + ssn, p->payload_len, seq, ack, window); - const bool has_ack = (p->tcph->th_flags & TH_ACK) != 0; + const bool has_ack = (tcph->th_flags & TH_ACK) != 0; if (has_ack) { - if ((ssn->flags & STREAMTCP_FLAG_ZWP_TC) && TCP_GET_ACK(p) == ssn->server.next_seq + 1) { + if ((ssn->flags & STREAMTCP_FLAG_ZWP_TC) && ack == ssn->server.next_seq + 1) { SCLogDebug("ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn); StreamTcpSetEvent(p, STREAM_EST_ACK_ZWP_DATA); @@ -2697,75 +2712,69 @@ static int HandleEstablishedPacketToServer( } /* check for Keep Alive */ - if ((p->payload_len == 0 || p->payload_len == 1) && - (TCP_GET_SEQ(p) == (ssn->client.next_seq - 1))) { + if ((p->payload_len == 0 || p->payload_len == 1) && (seq == (ssn->client.next_seq - 1))) { SCLogDebug("ssn %p: pkt is keep alive", ssn); /* normal pkt */ - } else if (!(SEQ_GEQ((TCP_GET_SEQ(p)+p->payload_len), ssn->client.last_ack))) { + } else if (!(SEQ_GEQ((seq + p->payload_len), ssn->client.last_ack))) { if (ssn->flags & STREAMTCP_FLAG_ASYNC) { SCLogDebug("ssn %p: server => Asynchronous stream, packet SEQ" " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," " ssn->client.last_ack %" PRIu32 ", ssn->client.next_win" "%" PRIu32 "(%" PRIu32 ")", - ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); + ssn, seq, p->payload_len, seq + p->payload_len, ssn->client.last_ack, + ssn->client.next_win, seq + p->payload_len - ssn->client.next_win); /* update the last_ack to current seq number as the session is * async and other stream is not updating it anymore :( */ - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_SEQ(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, seq); - } else if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p)) && stream_config.async_oneside && + } else if (SEQ_EQ(ssn->client.next_seq, seq) && stream_config.async_oneside && (ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) { SCLogDebug("ssn %p: server => Asynchronous stream, packet SEQ." - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); + " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " + "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " + "%" PRIu32 "(%" PRIu32 ")", + ssn, seq, p->payload_len, seq + p->payload_len, ssn->client.last_ack, + ssn->client.next_win, seq + p->payload_len - ssn->client.next_win); /* it seems we missed SYN and SYN/ACK packets of this session. * Update the last_ack to current seq number as the session * is async and other stream is not updating it anymore :( */ - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_SEQ(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, seq); ssn->flags |= STREAMTCP_FLAG_ASYNC; } else if (SEQ_EQ(ssn->client.last_ack, (ssn->client.isn + 1)) && stream_config.async_oneside && (ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) { SCLogDebug("ssn %p: server => Asynchronous stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); + " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " + "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " + "%" PRIu32 "(%" PRIu32 ")", + ssn, seq, p->payload_len, seq + p->payload_len, ssn->client.last_ack, + ssn->client.next_win, seq + p->payload_len - ssn->client.next_win); /* it seems we missed SYN and SYN/ACK packets of this session. * Update the last_ack to current seq number as the session * is async and other stream is not updating it anymore :(*/ - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_SEQ(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, seq); ssn->flags |= STREAMTCP_FLAG_ASYNC; /* if last ack is beyond next_seq, we have accepted ack's for missing data. * In this case we do accept the data before last_ack if it is (partly) * beyond next seq */ } else if (SEQ_GT(ssn->client.last_ack, ssn->client.next_seq) && - SEQ_GT((TCP_GET_SEQ(p) + p->payload_len), ssn->client.next_seq)) { + SEQ_GT((seq + p->payload_len), ssn->client.next_seq)) { SCLogDebug("ssn %p: PKT SEQ %" PRIu32 " payload_len %" PRIu16 " before last_ack %" PRIu32 ", after next_seq %" PRIu32 ":" " acked data that we haven't seen before", - ssn, TCP_GET_SEQ(p), p->payload_len, ssn->client.last_ack, - ssn->client.next_seq); + ssn, seq, p->payload_len, ssn->client.last_ack, ssn->client.next_seq); } else { SCLogDebug("ssn %p: server => SEQ before last_ack, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); + " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " + "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " + "%" PRIu32 "(%" PRIu32 ")", + ssn, seq, p->payload_len, seq + p->payload_len, ssn->client.last_ack, + ssn->client.next_win, seq + p->payload_len - ssn->client.next_win); SCLogDebug("ssn %p: rejecting because pkt before last_ack", ssn); StreamTcpSetEvent(p, STREAM_EST_PKT_BEFORE_LAST_ACK); @@ -2775,33 +2784,33 @@ static int HandleEstablishedPacketToServer( int zerowindowprobe = 0; /* zero window probe */ - if (p->payload_len == 1 && TCP_GET_SEQ(p) == ssn->client.next_seq && ssn->client.window == 0) { + if (p->payload_len == 1 && seq == ssn->client.next_seq && ssn->client.window == 0) { SCLogDebug("ssn %p: zero window probe", ssn); zerowindowprobe = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE); ssn->flags |= STREAMTCP_FLAG_ZWP_TS; StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); - } else if (SEQ_GEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_seq)) { - StreamTcpUpdateNextSeq(ssn, &ssn->client, (TCP_GET_SEQ(p) + p->payload_len)); + } else if (SEQ_GEQ(seq + p->payload_len, ssn->client.next_seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->client, (seq + p->payload_len)); } /* in window check */ if (zerowindowprobe) { SCLogDebug("ssn %p: zero window probe, skipping oow check", ssn); - } else if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || - (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM|STREAMTCP_FLAG_ASYNC))) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win); + } else if (SEQ_LEQ(seq + p->payload_len, ssn->client.next_win) || + (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM | STREAMTCP_FLAG_ASYNC))) { + SCLogDebug("ssn %p: seq %" PRIu32 " in window, ssn->client.next_win " + "%" PRIu32 "", + ssn, seq, ssn->client.next_win); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; SCLogDebug("ssn %p: ssn->server.window %"PRIu32"", ssn, ssn->server.window); /* Check if the ACK value is sane and inside the window limit */ - if (p->tcph->th_flags & TH_ACK) { - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) { + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); if ((ssn->flags & STREAMTCP_FLAG_ASYNC) == 0 && SEQ_GT(ssn->server.last_ack, ssn->server.next_seq)) { STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_ACK_UNSEEN_DATA); @@ -2809,7 +2818,8 @@ static int HandleEstablishedPacketToServer( } } - SCLogDebug("ack %u last_ack %u next_seq %u", TCP_GET_ACK(p), ssn->server.last_ack, ssn->server.next_seq); + SCLogDebug( + "ack %u last_ack %u next_seq %u", ack, ssn->server.last_ack, ssn->server.next_seq); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -2825,12 +2835,11 @@ static int HandleEstablishedPacketToServer( } else { SCLogDebug("ssn %p: toserver => SEQ out of window, packet SEQ " - "%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - (TCP_GET_SEQ(p) + p->payload_len) - ssn->client.next_win); + "%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," + "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " + "%" PRIu32 "(%" PRIu32 ")", + ssn, seq, p->payload_len, seq + p->payload_len, ssn->client.last_ack, + ssn->client.next_win, (seq + p->payload_len) - ssn->client.next_win); SCLogDebug("ssn %p: window %u sacked %u", ssn, ssn->client.window, StreamTcpSackedSize(&ssn->client)); StreamTcpSetEvent(p, STREAM_EST_PACKET_OUT_OF_WINDOW); @@ -2855,13 +2864,18 @@ static int HandleEstablishedPacketToServer( static int HandleEstablishedPacketToClient( ThreadVars *tv, TcpSession *ssn, Packet *p, StreamTcpThread *stt) { + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); + SCLogDebug("ssn %p: =+ pkt (%" PRIu32 ") is to client: SEQ %" PRIu32 "," - " ACK %" PRIu32 ", WIN %"PRIu16"", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p)); + " ACK %" PRIu32 ", WIN %" PRIu16 "", + ssn, p->payload_len, seq, ack, window); - const bool has_ack = (p->tcph->th_flags & TH_ACK) != 0; + const bool has_ack = (tcph->th_flags & TH_ACK) != 0; if (has_ack) { - if ((ssn->flags & STREAMTCP_FLAG_ZWP_TS) && TCP_GET_ACK(p) == ssn->client.next_seq + 1) { + if ((ssn->flags & STREAMTCP_FLAG_ZWP_TS) && ack == ssn->client.next_seq + 1) { SCLogDebug("ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn); StreamTcpSetEvent(p, STREAM_EST_ACK_ZWP_DATA); @@ -2877,7 +2891,7 @@ static int HandleEstablishedPacketToClient( if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) && (ssn->flags & STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED)) { - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; ssn->server.next_win = ssn->server.last_ack + ssn->server.window; ssn->flags &= ~STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED; SCLogDebug("ssn %p: adjusted midstream ssn->server.next_win to " @@ -2885,39 +2899,35 @@ static int HandleEstablishedPacketToClient( } /* check for Keep Alive */ - if ((p->payload_len == 0 || p->payload_len == 1) && - (TCP_GET_SEQ(p) == (ssn->server.next_seq - 1))) { + if ((p->payload_len == 0 || p->payload_len == 1) && (seq == (ssn->server.next_seq - 1))) { SCLogDebug("ssn %p: pkt is keep alive", ssn); /* normal pkt */ - } else if (!(SEQ_GEQ((TCP_GET_SEQ(p)+p->payload_len), ssn->server.last_ack))) { + } else if (!(SEQ_GEQ((seq + p->payload_len), ssn->server.last_ack))) { if (ssn->flags & STREAMTCP_FLAG_ASYNC) { SCLogDebug("ssn %p: client => Asynchronous stream, packet SEQ" " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," " ssn->client.last_ack %" PRIu32 ", ssn->client.next_win" " %" PRIu32 "(%" PRIu32 ")", - ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->server.last_ack, ssn->server.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win); + ssn, seq, p->payload_len, seq + p->payload_len, ssn->server.last_ack, + ssn->server.next_win, seq + p->payload_len - ssn->server.next_win); - ssn->server.last_ack = TCP_GET_SEQ(p); + ssn->server.last_ack = seq; - /* if last ack is beyond next_seq, we have accepted ack's for missing data. - * In this case we do accept the data before last_ack if it is (partly) - * beyond next seq */ + /* if last ack is beyond next_seq, we have accepted ack's for missing data. + * In this case we do accept the data before last_ack if it is (partly) + * beyond next seq */ } else if (SEQ_GT(ssn->server.last_ack, ssn->server.next_seq) && - SEQ_GT((TCP_GET_SEQ(p)+p->payload_len),ssn->server.next_seq)) - { + SEQ_GT((seq + p->payload_len), ssn->server.next_seq)) { SCLogDebug("ssn %p: PKT SEQ %" PRIu32 " payload_len %" PRIu16 " before last_ack %" PRIu32 ", after next_seq %" PRIu32 ":" " acked data that we haven't seen before", - ssn, TCP_GET_SEQ(p), p->payload_len, ssn->server.last_ack, - ssn->server.next_seq); + ssn, seq, p->payload_len, ssn->server.last_ack, ssn->server.next_seq); } else { - SCLogDebug("ssn %p: PKT SEQ %"PRIu32" payload_len %"PRIu16 - " before last_ack %"PRIu32". next_seq %"PRIu32, - ssn, TCP_GET_SEQ(p), p->payload_len, ssn->server.last_ack, ssn->server.next_seq); + SCLogDebug("ssn %p: PKT SEQ %" PRIu32 " payload_len %" PRIu16 + " before last_ack %" PRIu32 ". next_seq %" PRIu32, + ssn, seq, p->payload_len, ssn->server.last_ack, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_EST_PKT_BEFORE_LAST_ACK); return -1; } @@ -2925,7 +2935,7 @@ static int HandleEstablishedPacketToClient( int zerowindowprobe = 0; /* zero window probe */ - if (p->payload_len == 1 && TCP_GET_SEQ(p) == ssn->server.next_seq && ssn->server.window == 0) { + if (p->payload_len == 1 && seq == ssn->server.next_seq && ssn->server.window == 0) { SCLogDebug("ssn %p: zero window probe", ssn); zerowindowprobe = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE); @@ -2934,23 +2944,23 @@ static int HandleEstablishedPacketToClient( /* accept the segment */ StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); - } else if (SEQ_GEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_seq)) { - StreamTcpUpdateNextSeq(ssn, &ssn->server, (TCP_GET_SEQ(p) + p->payload_len)); + } else if (SEQ_GEQ(seq + p->payload_len, ssn->server.next_seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->server, (seq + p->payload_len)); } if (zerowindowprobe) { SCLogDebug("ssn %p: zero window probe, skipping oow check", ssn); - } else if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || - (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM|STREAMTCP_FLAG_ASYNC))) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + } else if (SEQ_LEQ(seq + p->payload_len, ssn->server.next_win) || + (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM | STREAMTCP_FLAG_ASYNC))) { + SCLogDebug("ssn %p: seq %" PRIu32 " in window, ssn->server.next_win " + "%" PRIu32 "", + ssn, seq, ssn->server.next_win); + ssn->client.window = window << ssn->client.wscale; SCLogDebug("ssn %p: ssn->client.window %"PRIu32"", ssn, ssn->client.window); - if (p->tcph->th_flags & TH_ACK) { - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) { + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); if ((ssn->flags & STREAMTCP_FLAG_ASYNC) == 0 && SEQ_GT(ssn->client.last_ack, ssn->client.next_seq)) { STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_ACK_UNSEEN_DATA); @@ -2971,10 +2981,9 @@ static int HandleEstablishedPacketToClient( SCLogDebug("ssn %p: client => SEQ out of window, packet SEQ" "%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," " ssn->server.last_ack %" PRIu32 ", ssn->server.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->server.last_ack, ssn->server.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win); + "%" PRIu32 "(%" PRIu32 ")", + ssn, seq, p->payload_len, seq + p->payload_len, ssn->server.last_ack, + ssn->server.next_win, seq + p->payload_len - ssn->server.next_win); StreamTcpSetEvent(p, STREAM_EST_PACKET_OUT_OF_WINDOW); return -1; } @@ -3009,11 +3018,12 @@ static inline uint32_t StreamTcpResetGetMaxAck(TcpStream *stream, uint32_t seq) static bool StreamTcpPacketIsZeroWindowProbeAck(const TcpSession *ssn, const Packet *p) { + const TCPHdr *tcph = PacketGetTCP(p); if (ssn->state < TCP_ESTABLISHED) return false; if (p->payload_len != 0) return false; - if ((p->tcph->th_flags & (TH_ACK | TH_SYN | TH_FIN | TH_RST)) != TH_ACK) + if ((tcph->th_flags & (TH_ACK | TH_SYN | TH_FIN | TH_RST)) != TH_ACK) return false; const TcpStream *snd, *rcv; @@ -3029,15 +3039,15 @@ static bool StreamTcpPacketIsZeroWindowProbeAck(const TcpSession *ssn, const Pac return false; } - const uint32_t pkt_win = TCP_GET_WINDOW(p) << snd->wscale; + const uint32_t pkt_win = TCP_GET_RAW_WINDOW(tcph) << snd->wscale; if (pkt_win != 0) return false; if (pkt_win != rcv->window) return false; - if (TCP_GET_SEQ(p) != snd->next_seq) + if (TCP_GET_RAW_SEQ(tcph) != snd->next_seq) return false; - if (TCP_GET_ACK(p) != rcv->last_ack) + if (TCP_GET_RAW_ACK(tcph) != rcv->last_ack) return false; SCLogDebug("ssn %p: packet %" PRIu64 " is a Zero Window Probe ACK", ssn, p->pcap_cnt); return true; @@ -3048,11 +3058,12 @@ static bool StreamTcpPacketIsZeroWindowProbeAck(const TcpSession *ssn, const Pac */ static bool StreamTcpPacketIsDupAck(const TcpSession *ssn, const Packet *p) { + const TCPHdr *tcph = PacketGetTCP(p); if (ssn->state < TCP_ESTABLISHED) return false; if (p->payload_len != 0) return false; - if ((p->tcph->th_flags & (TH_ACK | TH_SYN | TH_FIN | TH_RST)) != TH_ACK) + if ((tcph->th_flags & (TH_ACK | TH_SYN | TH_FIN | TH_RST)) != TH_ACK) return false; const TcpStream *snd, *rcv; @@ -3064,20 +3075,20 @@ static bool StreamTcpPacketIsDupAck(const TcpSession *ssn, const Packet *p) rcv = &ssn->server; } - const uint32_t pkt_win = TCP_GET_WINDOW(p) << snd->wscale; + const uint32_t pkt_win = TCP_GET_RAW_WINDOW(tcph) << snd->wscale; if (pkt_win == 0 || rcv->window == 0) return false; if (pkt_win != rcv->window) return false; - if (TCP_GET_SEQ(p) != snd->next_seq) + if (TCP_GET_RAW_SEQ(tcph) != snd->next_seq) return false; - if (TCP_GET_ACK(p) != rcv->last_ack) + if (TCP_GET_RAW_ACK(tcph) != rcv->last_ack) return false; SCLogDebug("ssn %p: packet:%" PRIu64 " seq:%u ack:%u win:%u snd %u:%u:%u rcv %u:%u:%u", ssn, - p->pcap_cnt, TCP_GET_SEQ(p), TCP_GET_ACK(p), pkt_win, snd->next_seq, snd->last_ack, - rcv->window, snd->next_seq, rcv->last_ack, rcv->window); + p->pcap_cnt, TCP_GET_RAW_SEQ(tcph), TCP_GET_RAW_ACK(tcph), pkt_win, snd->next_seq, + snd->last_ack, rcv->window, snd->next_seq, rcv->last_ack, rcv->window); return true; } @@ -3099,40 +3110,41 @@ static bool StreamTcpPacketIsDupAck(const TcpSession *ssn, const Packet *p) */ static bool StreamTcpPacketIsOutdatedAck(TcpSession *ssn, Packet *p) { + const TCPHdr *tcph = PacketGetTCP(p); if (ssn->state < TCP_ESTABLISHED) return false; if (p->payload_len != 0) return false; - if ((p->tcph->th_flags & (TH_ACK | TH_SYN | TH_FIN | TH_RST)) != TH_ACK) + if ((tcph->th_flags & (TH_ACK | TH_SYN | TH_FIN | TH_RST)) != TH_ACK) return false; /* lets see if this is a packet that is entirely eclipsed by earlier ACKs */ if (PKT_IS_TOSERVER(p)) { - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq) && - SEQ_LT(TCP_GET_ACK(p), ssn->server.last_ack)) { + if (SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq) && + SEQ_LT(TCP_GET_RAW_ACK(tcph), ssn->server.last_ack)) { if (!TCP_HAS_SACK(p)) { - SCLogDebug("outdated ACK (no SACK, SEQ %u vs next_seq %u)", TCP_GET_SEQ(p), + SCLogDebug("outdated ACK (no SACK, SEQ %u vs next_seq %u)", TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq); return true; } if (StreamTcpSackPacketIsOutdated(&ssn->server, p)) { - SCLogDebug("outdated ACK (have SACK, SEQ %u vs next_seq %u)", TCP_GET_SEQ(p), + SCLogDebug("outdated ACK (have SACK, SEQ %u vs next_seq %u)", TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq); return true; } } } else { - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq) && - SEQ_LT(TCP_GET_ACK(p), ssn->client.last_ack)) { + if (SEQ_EQ(TCP_GET_RAW_SEQ(tcph), ssn->server.next_seq) && + SEQ_LT(TCP_GET_RAW_ACK(tcph), ssn->client.last_ack)) { if (!TCP_HAS_SACK(p)) { - SCLogDebug("outdated ACK (no SACK, SEQ %u vs next_seq %u)", TCP_GET_SEQ(p), + SCLogDebug("outdated ACK (no SACK, SEQ %u vs next_seq %u)", TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq); return true; } if (StreamTcpSackPacketIsOutdated(&ssn->client, p)) { - SCLogDebug("outdated ACK (have SACK, SEQ %u vs next_seq %u)", TCP_GET_SEQ(p), + SCLogDebug("outdated ACK (have SACK, SEQ %u vs next_seq %u)", TCP_GET_RAW_SEQ(tcph), ssn->client.next_seq); return true; } @@ -3160,31 +3172,33 @@ static int StreamTcpPacketIsSpuriousRetransmission(const TcpSession *ssn, Packet if (p->payload_len == 0) return 0; + const TCPHdr *tcph = PacketGetTCP(p); /* take base_seq into account to avoid edge cases where last_ack might be * too far ahead during heavy packet loss */ if (!(stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - if ((SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, stream->base_seq))) { + if ((SEQ_LEQ(TCP_GET_RAW_SEQ(tcph) + p->payload_len, stream->base_seq))) { SCLogDebug( "ssn %p: spurious retransmission; packet entirely before base_seq: SEQ %u(%u) " "last_ack %u base_seq %u", - ssn, TCP_GET_SEQ(p), TCP_GET_SEQ(p) + p->payload_len, stream->last_ack, - stream->base_seq); + ssn, TCP_GET_RAW_SEQ(tcph), TCP_GET_RAW_SEQ(tcph) + p->payload_len, + stream->last_ack, stream->base_seq); STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_SPURIOUS_RETRANSMISSION); return 2; } } - if ((SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, stream->last_ack))) { + if ((SEQ_LEQ(TCP_GET_RAW_SEQ(tcph) + p->payload_len, stream->last_ack))) { SCLogDebug("ssn %p: spurious retransmission; packet entirely before last_ack: SEQ %u(%u) " "last_ack %u", - ssn, TCP_GET_SEQ(p), TCP_GET_SEQ(p) + p->payload_len, stream->last_ack); + ssn, TCP_GET_RAW_SEQ(tcph), TCP_GET_RAW_SEQ(tcph) + p->payload_len, + stream->last_ack); STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_SPURIOUS_RETRANSMISSION); return 1; } SCLogDebug("ssn %p: NOT spurious retransmission; packet NOT entirely before last_ack: SEQ " "%u(%u) last_ack %u, base_seq %u", - ssn, TCP_GET_SEQ(p), TCP_GET_SEQ(p) + p->payload_len, stream->last_ack, + ssn, TCP_GET_RAW_SEQ(tcph), TCP_GET_RAW_SEQ(tcph) + p->payload_len, stream->last_ack, stream->base_seq); return 0; } @@ -3204,26 +3218,29 @@ static int StreamTcpPacketStateEstablished( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; if (PKT_IS_TOSERVER(p)) { StreamTcpCloseSsnWithReset(p, ssn); - ssn->server.next_seq = TCP_GET_ACK(p); - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; + ssn->server.next_seq = ack; + ssn->client.next_seq = seq + p->payload_len; SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", ssn, ssn->server.next_seq); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, window)); - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -3240,19 +3257,18 @@ static int StreamTcpPacketStateEstablished( } else { StreamTcpCloseSsnWithReset(p, ssn); - ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1; - ssn->client.next_seq = TCP_GET_ACK(p); + ssn->server.next_seq = seq + p->payload_len + 1; + ssn->client.next_seq = ack; SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", ssn, ssn->server.next_seq); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -3268,7 +3284,7 @@ static int StreamTcpPacketStateEstablished( * cleanup. */ } - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -3284,7 +3300,7 @@ static int StreamTcpPacketStateEstablished( return -1; /* SYN/ACK */ - } else if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { + } else if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { SCLogDebug("ssn %p: SYN/ACK packet on state ESTABLISHED... resent", ssn); @@ -3297,10 +3313,10 @@ static int StreamTcpPacketStateEstablished( /* Check if the SYN/ACK packets ACK matches the earlier * received SYN/ACK packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack))) { + if (!(SEQ_EQ(ack, ssn->client.last_ack))) { SCLogDebug("ssn %p: ACK mismatch, packet ACK %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); + "%" PRIu32 " from stream", + ssn, ack, ssn->client.isn + 1); StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND_WITH_DIFFERENT_ACK); return -1; @@ -3308,10 +3324,10 @@ static int StreamTcpPacketStateEstablished( /* Check if the SYN/ACK packet SEQ the earlier * received SYN packet. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.isn))) { + if (!(SEQ_EQ(seq, ssn->server.isn))) { SCLogDebug("ssn %p: SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); + "%" PRIu32 " from stream", + ssn, ack, ssn->client.isn + 1); StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND_WITH_DIFF_SEQ); return -1; @@ -3327,7 +3343,7 @@ static int StreamTcpPacketStateEstablished( "Likely due server not receiving final ACK in 3whs", ssn); return 0; - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn %p: SYN packet on state ESTABLISHED... resent", ssn); if (PKT_IS_TOCLIENT(p)) { SCLogDebug("ssn %p: SYN-pkt to client in EST state", ssn); @@ -3336,7 +3352,7 @@ static int StreamTcpPacketStateEstablished( return -1; } - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn))) { + if (!(SEQ_EQ(ack, ssn->client.isn))) { SCLogDebug("ssn %p: SYN with different SEQ on SYN_RECV state", ssn); StreamTcpSetEvent(p, STREAM_EST_SYN_RESEND_DIFF_SEQ); @@ -3347,7 +3363,7 @@ static int StreamTcpPacketStateEstablished( StreamTcpSetEvent(p, STREAM_EST_SYN_RESEND); return -1; - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { /* Urgent pointer size can be more than the payload size, as it tells * the future coming data from the sender will be handled urgently * until data of size equal to urgent offset has been processed @@ -3406,10 +3422,15 @@ static int StreamTcpPacketStateEstablished( static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession *ssn, Packet *p) { + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); + if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 "," - " ACK %" PRIu32 "", ssn, p->payload_len, TCP_GET_SEQ(p), - TCP_GET_ACK(p)); + " ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); @@ -3417,22 +3438,21 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession * return -1; } - const uint32_t pkt_re = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: -> SEQ %u, re %u. last_ack %u next_win %u", ssn, TCP_GET_SEQ(p), pkt_re, + const uint32_t pkt_re = seq + p->payload_len; + SCLogDebug("ssn %p: -> SEQ %u, re %u. last_ack %u next_win %u", ssn, seq, pkt_re, ssn->client.last_ack, ssn->client.next_win); - if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.last_ack) && - SEQ_LEQ(pkt_re, ssn->client.next_win)) { + if (SEQ_GEQ(seq, ssn->client.last_ack) && SEQ_LEQ(pkt_re, ssn->client.next_win)) { // within expectations } else { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_SEQ(p), - ssn->client.next_seq); + "%" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_FIN_OUT_OF_WINDOW); return -1; } - if (p->tcph->th_flags & TH_SYN) { + if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn %p: FIN+SYN", ssn); StreamTcpSetEvent(p, STREAM_FIN_SYN); return -1; @@ -3441,11 +3461,11 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession * SCLogDebug("ssn %p: state changed to TCP_CLOSE_WAIT", ssn); /* if we accept the FIN, next_seq needs to reflect the FIN */ - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; + ssn->client.next_seq = seq + p->payload_len; SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "", ssn, ssn->client.next_seq); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -3453,11 +3473,11 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession * /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq, ack)) + ssn->server.next_seq = ack; - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); @@ -3465,8 +3485,8 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession * ssn, ssn->client.next_seq, ssn->server.last_ack); } else { /* implied to client */ SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ %" PRIu32 ", " - "ACK %" PRIu32 "", ssn, p->payload_len, TCP_GET_SEQ(p), - TCP_GET_ACK(p)); + "ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); @@ -3474,16 +3494,16 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession * return -1; } - const uint32_t pkt_re = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: -> SEQ %u, re %u. last_ack %u next_win %u", ssn, TCP_GET_SEQ(p), pkt_re, + const uint32_t pkt_re = seq + p->payload_len; + SCLogDebug("ssn %p: -> SEQ %u, re %u. last_ack %u next_win %u", ssn, seq, pkt_re, ssn->server.last_ack, ssn->server.next_win); - if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->server.last_ack) && - SEQ_LEQ(pkt_re, ssn->server.next_win)) { + if (SEQ_GEQ(seq, ssn->server.last_ack) && SEQ_LEQ(pkt_re, ssn->server.next_win)) { // within expectations } else { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream (last_ack %u win %u = %u)", ssn, TCP_GET_SEQ(p), - ssn->server.next_seq, ssn->server.last_ack, ssn->server.window, (ssn->server.last_ack + ssn->server.window)); + "%" PRIu32 " from stream (last_ack %u win %u = %u)", + ssn, seq, ssn->server.next_seq, ssn->server.last_ack, ssn->server.window, + (ssn->server.last_ack + ssn->server.window)); StreamTcpSetEvent(p, STREAM_FIN_OUT_OF_WINDOW); return -1; @@ -3493,10 +3513,10 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession * SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT1", ssn); /* if we accept the FIN, next_seq needs to reflect the FIN */ - ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1; + ssn->server.next_seq = seq + p->payload_len + 1; SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 " updated", ssn, ssn->server.next_seq); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -3504,11 +3524,11 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, TcpSession * /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq, ack)) + ssn->client.next_seq = ack; - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); @@ -3536,20 +3556,23 @@ static int StreamTcpPacketStateFinWait1( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; StreamTcpCloseSsnWithReset(p, ssn); if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -3557,12 +3580,11 @@ static int StreamTcpPacketStateFinWait1( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -3571,7 +3593,7 @@ static int StreamTcpPacketStateFinWait1( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); } - } else if ((p->tcph->th_flags & (TH_FIN|TH_ACK)) == (TH_FIN|TH_ACK)) { + } else if ((tcph->th_flags & (TH_FIN | TH_ACK)) == (TH_FIN | TH_ACK)) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -3579,8 +3601,8 @@ static int StreamTcpPacketStateFinWait1( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { @@ -3588,11 +3610,11 @@ static int StreamTcpPacketStateFinWait1( retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq - 1) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) { + } else if (SEQ_LT(seq, ssn->client.next_seq - 1) || + SEQ_GT(seq, (ssn->client.last_ack + ssn->client.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); return -1; } @@ -3607,7 +3629,7 @@ static int StreamTcpPacketStateFinWait1( StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -3616,14 +3638,14 @@ static int StreamTcpPacketStateFinWait1( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq - 1, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq - 1, ack)) + ssn->server.next_seq = ack; - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { - StreamTcpUpdateNextSeq(ssn, &ssn->client, (TCP_GET_SEQ(p) + p->payload_len)); + if (SEQ_EQ(ssn->client.next_seq, seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->client, (seq + p->payload_len)); } - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); @@ -3632,8 +3654,8 @@ static int StreamTcpPacketStateFinWait1( ssn->server.last_ack); } else { /* implied to client */ SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { @@ -3641,17 +3663,16 @@ static int StreamTcpPacketStateFinWait1( retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (SEQ_EQ(ssn->server.next_seq - 1, TCP_GET_SEQ(p)) && - SEQ_EQ(ssn->client.last_ack, TCP_GET_ACK(p))) { + } else if (SEQ_EQ(ssn->server.next_seq - 1, seq) && SEQ_EQ(ssn->client.last_ack, ack)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq - 1) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) { + } else if (SEQ_LT(seq, ssn->server.next_seq - 1) || + SEQ_GT(seq, (ssn->server.last_ack + ssn->server.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); return -1; } @@ -3670,18 +3691,18 @@ static int StreamTcpPacketStateFinWait1( StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq - 1, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq - 1, ack)) + ssn->client.next_seq = ack; - if (SEQ_EQ(ssn->server.next_seq - 1, TCP_GET_SEQ(p))) { - StreamTcpUpdateNextSeq(ssn, &ssn->server, (TCP_GET_SEQ(p) + p->payload_len)); + if (SEQ_EQ(ssn->server.next_seq - 1, seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->server, (seq + p->payload_len)); } - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); } StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); @@ -3691,7 +3712,7 @@ static int StreamTcpPacketStateFinWait1( ssn->client.last_ack); } - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -3699,8 +3720,8 @@ static int StreamTcpPacketStateFinWait1( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { @@ -3708,11 +3729,11 @@ static int StreamTcpPacketStateFinWait1( retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq - 1) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) { + } else if (SEQ_LT(seq, ssn->client.next_seq - 1) || + SEQ_GT(seq, (ssn->client.last_ack + ssn->client.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); return -1; } @@ -3727,7 +3748,7 @@ static int StreamTcpPacketStateFinWait1( StreamTcpPacketSetState(p, ssn, TCP_CLOSING); SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -3736,15 +3757,15 @@ static int StreamTcpPacketStateFinWait1( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq - 1, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq - 1, ack)) + ssn->server.next_seq = ack; - if (SEQ_EQ(ssn->client.next_seq - 1, TCP_GET_SEQ(p))) { - StreamTcpUpdateNextSeq(ssn, &ssn->client, (TCP_GET_SEQ(p) + p->payload_len)); + if (SEQ_EQ(ssn->client.next_seq - 1, seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->client, (seq + p->payload_len)); } - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); @@ -3753,8 +3774,8 @@ static int StreamTcpPacketStateFinWait1( ssn->server.last_ack); } else { /* implied to client */ SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; @@ -3763,11 +3784,11 @@ static int StreamTcpPacketStateFinWait1( retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq - 1) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) { + } else if (SEQ_LT(seq, ssn->server.next_seq - 1) || + SEQ_GT(seq, (ssn->server.last_ack + ssn->server.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); return -1; } @@ -3782,7 +3803,7 @@ static int StreamTcpPacketStateFinWait1( StreamTcpPacketSetState(p, ssn, TCP_CLOSING); SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -3791,15 +3812,15 @@ static int StreamTcpPacketStateFinWait1( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq - 1, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq - 1, ack)) + ssn->client.next_seq = ack; - if (SEQ_EQ(ssn->server.next_seq - 1, TCP_GET_SEQ(p))) { - StreamTcpUpdateNextSeq(ssn, &ssn->server, (TCP_GET_SEQ(p) + p->payload_len)); + if (SEQ_EQ(ssn->server.next_seq - 1, seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->server, (seq + p->payload_len)); } - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); @@ -3807,12 +3828,12 @@ static int StreamTcpPacketStateFinWait1( "%" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); } - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn (%p): SYN pkt on FinWait1", ssn); StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); return -1; - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -3820,8 +3841,8 @@ static int StreamTcpPacketStateFinWait1( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { @@ -3836,32 +3857,31 @@ static int StreamTcpPacketStateFinWait1( return -1; } - if (SEQ_LT(TCP_GET_ACK(p), ssn->server.next_seq)) { - SCLogDebug("ssn %p: ACK's older segment as %u < %u", ssn, TCP_GET_ACK(p), - ssn->server.next_seq); + if (SEQ_LT(ack, ssn->server.next_seq)) { + SCLogDebug( + "ssn %p: ACK's older segment as %u < %u", ssn, ack, ssn->server.next_seq); } else if (!retransmission) { - if (SEQ_EQ(TCP_GET_ACK(p), ssn->server.next_seq)) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || + if (SEQ_EQ(ack, ssn->server.next_seq)) { + if (SEQ_LEQ(seq + p->payload_len, ssn->client.next_win) || (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM | STREAMTCP_FLAG_ASYNC))) { SCLogDebug("ssn %p: seq %" PRIu32 " in window, ssn->client.next_win " "%" PRIu32 "", - ssn, TCP_GET_SEQ(p), ssn->client.next_win); - SCLogDebug( - "seq %u client.next_seq %u", TCP_GET_SEQ(p), ssn->client.next_seq); - if (TCP_GET_SEQ(p) == ssn->client.next_seq) { + ssn, seq, ssn->client.next_win); + SCLogDebug("seq %u client.next_seq %u", seq, ssn->client.next_seq); + if (seq == ssn->client.next_seq) { StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2); SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn); } } else { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" " != %" PRIu32 " from stream", - ssn, TCP_GET_SEQ(p), ssn->client.next_seq); + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ); return -1; } - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } } @@ -3871,14 +3891,14 @@ static int StreamTcpPacketStateFinWait1( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq - 1, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq - 1, ack)) + ssn->server.next_seq = ack; - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { - StreamTcpUpdateNextSeq(ssn, &ssn->client, (TCP_GET_SEQ(p) + p->payload_len)); + if (SEQ_EQ(ssn->client.next_seq, seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->client, (seq + p->payload_len)); } - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpSackUpdatePacket(&ssn->server, p); @@ -3894,8 +3914,8 @@ static int StreamTcpPacketStateFinWait1( } else { /* implied to client */ SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; @@ -3912,25 +3932,25 @@ static int StreamTcpPacketStateFinWait1( } if (!retransmission) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || - (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM|STREAMTCP_FLAG_ASYNC))) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); + if (SEQ_LEQ(seq + p->payload_len, ssn->server.next_win) || + (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM | STREAMTCP_FLAG_ASYNC))) { + SCLogDebug("ssn %p: seq %" PRIu32 " in window, ssn->server.next_win " + "%" PRIu32 "", + ssn, seq, ssn->server.next_win); - if (TCP_GET_SEQ(p) == ssn->server.next_seq - 1) { + if (seq == ssn->server.next_seq - 1) { StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2); SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn); } } else { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ); return -1; } - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -3939,14 +3959,14 @@ static int StreamTcpPacketStateFinWait1( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq - 1, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq - 1, ack)) + ssn->client.next_seq = ack; - if (SEQ_EQ(ssn->server.next_seq - 1, TCP_GET_SEQ(p))) { - StreamTcpUpdateNextSeq(ssn, &ssn->server, (TCP_GET_SEQ(p) + p->payload_len)); + if (SEQ_EQ(ssn->server.next_seq - 1, seq)) { + StreamTcpUpdateNextSeq(ssn, &ssn->server, (seq + p->payload_len)); } - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpSackUpdatePacket(&ssn->client, p); @@ -3980,20 +4000,23 @@ static int StreamTcpPacketStateFinWait2( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; StreamTcpCloseSsnWithReset(p, ssn); if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4001,12 +4024,11 @@ static int StreamTcpPacketStateFinWait2( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4015,7 +4037,7 @@ static int StreamTcpPacketStateFinWait2( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); } - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -4023,12 +4045,11 @@ static int StreamTcpPacketStateFinWait2( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq - 1) && - SEQ_EQ(TCP_GET_ACK(p), ssn->server.last_ack)) { + if (SEQ_EQ(seq, ssn->client.next_seq - 1) && SEQ_EQ(ack, ssn->server.last_ack)) { SCLogDebug("ssn %p: retransmission", ssn); retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); @@ -4037,12 +4058,11 @@ static int StreamTcpPacketStateFinWait2( retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { + } else if (SEQ_LT(seq, ssn->client.next_seq) || + SEQ_GT(seq, (ssn->client.last_ack + ssn->client.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ " - "%" PRIu32 " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + "%" PRIu32 " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_FIN2_FIN_WRONG_SEQ); return -1; } @@ -4057,11 +4077,11 @@ static int StreamTcpPacketStateFinWait2( StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { + if (SEQ_EQ(ssn->client.next_seq, seq)) { StreamTcpUpdateNextSeq( ssn, &ssn->client, (ssn->client.next_seq + p->payload_len)); } - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4070,11 +4090,11 @@ static int StreamTcpPacketStateFinWait2( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq, ack)) + ssn->server.next_seq = ack; - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); @@ -4083,12 +4103,11 @@ static int StreamTcpPacketStateFinWait2( ssn->server.last_ack); } else { /* implied to client */ SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq - 1) && - SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack)) { + if (SEQ_EQ(seq, ssn->server.next_seq - 1) && SEQ_EQ(ack, ssn->client.last_ack)) { SCLogDebug("ssn %p: retransmission", ssn); retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); @@ -4097,12 +4116,11 @@ static int StreamTcpPacketStateFinWait2( retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { + } else if (SEQ_LT(seq, ssn->server.next_seq) || + SEQ_GT(seq, (ssn->server.last_ack + ssn->server.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ " - "%" PRIu32 " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + "%" PRIu32 " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_FIN2_FIN_WRONG_SEQ); return -1; } @@ -4117,7 +4135,7 @@ static int StreamTcpPacketStateFinWait2( StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4126,11 +4144,11 @@ static int StreamTcpPacketStateFinWait2( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq, ack)) + ssn->client.next_seq = ack; - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4138,12 +4156,12 @@ static int StreamTcpPacketStateFinWait2( ssn->client.last_ack); } - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn (%p): SYN pkt on FinWait2", ssn); StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); return -1; - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -4151,8 +4169,8 @@ static int StreamTcpPacketStateFinWait2( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { @@ -4168,32 +4186,32 @@ static int StreamTcpPacketStateFinWait2( } if (!retransmission) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || - (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM|STREAMTCP_FLAG_ASYNC))) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win); + if (SEQ_LEQ(seq + p->payload_len, ssn->client.next_win) || + (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM | STREAMTCP_FLAG_ASYNC))) { + SCLogDebug("ssn %p: seq %" PRIu32 " in window, ssn->client.next_win " + "%" PRIu32 "", + ssn, seq, ssn->client.next_win); } else { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ); return -1; } - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); } - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { + if (SEQ_EQ(ssn->client.next_seq, seq)) { StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len)); } - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpSackUpdatePacket(&ssn->server, p); @@ -4207,8 +4225,8 @@ static int StreamTcpPacketStateFinWait2( ssn->server.last_ack); } else { /* implied to client */ SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { @@ -4224,31 +4242,31 @@ static int StreamTcpPacketStateFinWait2( } if (!retransmission) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || - (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM|STREAMTCP_FLAG_ASYNC))) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); + if (SEQ_LEQ(seq + p->payload_len, ssn->server.next_win) || + (ssn->flags & (STREAMTCP_FLAG_MIDSTREAM | STREAMTCP_FLAG_ASYNC))) { + SCLogDebug("ssn %p: seq %" PRIu32 " in window, ssn->server.next_win " + "%" PRIu32 "", + ssn, seq, ssn->server.next_win); } else { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ); return -1; } - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); } - if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { + if (SEQ_EQ(ssn->server.next_seq, seq)) { StreamTcpUpdateNextSeq(ssn, &ssn->server, (ssn->server.next_seq + p->payload_len)); } - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpSackUpdatePacket(&ssn->client, p); @@ -4282,20 +4300,23 @@ static int StreamTcpPacketStateClosing( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; StreamTcpCloseSsnWithReset(p, ssn); if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4303,12 +4324,11 @@ static int StreamTcpPacketStateClosing( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4317,12 +4337,12 @@ static int StreamTcpPacketStateClosing( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); } - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn (%p): SYN pkt on Closing", ssn); StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); return -1; - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -4330,8 +4350,8 @@ static int StreamTcpPacketStateClosing( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); @@ -4339,10 +4359,10 @@ static int StreamTcpPacketStateClosing( STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } - if (TCP_GET_SEQ(p) != ssn->client.next_seq) { + if (seq != ssn->client.next_seq) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_CLOSING_ACK_WRONG_SEQ); return -1; } @@ -4357,7 +4377,7 @@ static int StreamTcpPacketStateClosing( StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4365,10 +4385,10 @@ static int StreamTcpPacketStateClosing( } /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq, ack)) + ssn->server.next_seq = ack; - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4376,8 +4396,8 @@ static int StreamTcpPacketStateClosing( ssn->server.last_ack); } else { /* implied to client */ SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); @@ -4385,10 +4405,10 @@ static int StreamTcpPacketStateClosing( STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } - if (TCP_GET_SEQ(p) != ssn->server.next_seq) { + if (seq != ssn->server.next_seq) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_CLOSING_ACK_WRONG_SEQ); return -1; } @@ -4403,7 +4423,7 @@ static int StreamTcpPacketStateClosing( StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4412,10 +4432,10 @@ static int StreamTcpPacketStateClosing( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq, ack)) + ssn->client.next_seq = ack; - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("StreamTcpPacketStateClosing (%p): =+ next SEQ " @@ -4443,32 +4463,35 @@ static int StreamTcpPacketStateCloseWait( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { SCEnter(); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); DEBUG_VALIDATE_BUG_ON(ssn == NULL); if (PKT_IS_TOCLIENT(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); } else { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); } - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; StreamTcpCloseSsnWithReset(p, ssn); if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4476,12 +4499,11 @@ static int StreamTcpPacketStateCloseWait( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4490,7 +4512,7 @@ static int StreamTcpPacketStateCloseWait( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); } - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) SCReturnInt(-1); @@ -4498,8 +4520,8 @@ static int StreamTcpPacketStateCloseWait( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { @@ -4509,12 +4531,11 @@ static int StreamTcpPacketStateCloseWait( } if (!retransmission) { - if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { + if (SEQ_LT(seq, ssn->client.next_seq) || + SEQ_GT(seq, (ssn->client.last_ack + ssn->client.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_FIN_OUT_OF_WINDOW); SCReturnInt(-1); } @@ -4529,7 +4550,7 @@ static int StreamTcpPacketStateCloseWait( /* don't update to LAST_ACK here as we want a toclient FIN for that */ if (!retransmission) - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4537,11 +4558,11 @@ static int StreamTcpPacketStateCloseWait( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq, ack)) + ssn->server.next_seq = ack; - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4549,8 +4570,8 @@ static int StreamTcpPacketStateCloseWait( ssn->server.last_ack); } else { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { @@ -4560,12 +4581,11 @@ static int StreamTcpPacketStateCloseWait( } if (!retransmission) { - if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { + if (SEQ_LT(seq, ssn->server.next_seq) || + SEQ_GT(seq, (ssn->server.last_ack + ssn->server.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_FIN_OUT_OF_WINDOW); SCReturnInt(-1); } @@ -4581,7 +4601,7 @@ static int StreamTcpPacketStateCloseWait( StreamTcpPacketSetState(p, ssn, TCP_LAST_ACK); SCLogDebug("ssn %p: state changed to TCP_LAST_ACK", ssn); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4590,11 +4610,11 @@ static int StreamTcpPacketStateCloseWait( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq, ack)) + ssn->client.next_seq = ack; - if (p->tcph->th_flags & TH_ACK) - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + if (tcph->th_flags & TH_ACK) + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4602,12 +4622,12 @@ static int StreamTcpPacketStateCloseWait( ssn->client.last_ack); } - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn (%p): SYN pkt on CloseWait", ssn); StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); SCReturnInt(-1); - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) SCReturnInt(-1); @@ -4615,8 +4635,8 @@ static int StreamTcpPacketStateCloseWait( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { @@ -4625,16 +4645,15 @@ static int StreamTcpPacketStateCloseWait( STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } - if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->client.last_ack))) { + if (p->payload_len > 0 && (SEQ_LEQ((seq + p->payload_len), ssn->client.last_ack))) { SCLogDebug("ssn %p: -> retransmission", ssn); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK); SCReturnInt(-1); - } else if (SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { + } else if (SEQ_GT(seq, (ssn->client.last_ack + ssn->client.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_ACK_OUT_OF_WINDOW); SCReturnInt(-1); } @@ -4646,7 +4665,7 @@ static int StreamTcpPacketStateCloseWait( } if (!retransmission) { - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4655,13 +4674,13 @@ static int StreamTcpPacketStateCloseWait( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq, ack)) + ssn->server.next_seq = ack; - if (SEQ_EQ(TCP_GET_SEQ(p),ssn->client.next_seq)) + if (SEQ_EQ(seq, ssn->client.next_seq)) StreamTcpUpdateNextSeq(ssn, &ssn->client, (ssn->client.next_seq + p->payload_len)); - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4669,8 +4688,8 @@ static int StreamTcpPacketStateCloseWait( ssn->server.last_ack); } else { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); @@ -4678,16 +4697,15 @@ static int StreamTcpPacketStateCloseWait( STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } - if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->server.last_ack))) { + if (p->payload_len > 0 && (SEQ_LEQ((seq + p->payload_len), ssn->server.last_ack))) { SCLogDebug("ssn %p: -> retransmission", ssn); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK); SCReturnInt(-1); - } else if (SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { + } else if (SEQ_GT(seq, (ssn->server.last_ack + ssn->server.window))) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_CLOSEWAIT_ACK_OUT_OF_WINDOW); SCReturnInt(-1); } @@ -4699,7 +4717,7 @@ static int StreamTcpPacketStateCloseWait( } if (!retransmission) { - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4708,13 +4726,13 @@ static int StreamTcpPacketStateCloseWait( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq, ack)) + ssn->client.next_seq = ack; - if (SEQ_EQ(TCP_GET_SEQ(p),ssn->server.next_seq)) + if (SEQ_EQ(seq, ssn->server.next_seq)) StreamTcpUpdateNextSeq(ssn, &ssn->server, (ssn->server.next_seq + p->payload_len)); - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4742,20 +4760,23 @@ static int StreamTcpPacketStateLastAck( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; StreamTcpCloseSsnWithReset(p, ssn); if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4763,12 +4784,11 @@ static int StreamTcpPacketStateLastAck( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4777,16 +4797,16 @@ static int StreamTcpPacketStateLastAck( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); } - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { /** \todo */ SCLogDebug("ssn (%p): FIN pkt on LastAck", ssn); - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn (%p): SYN pkt on LastAck", ssn); StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); return -1; - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -4794,8 +4814,8 @@ static int StreamTcpPacketStateLastAck( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { @@ -4811,20 +4831,19 @@ static int StreamTcpPacketStateLastAck( } if (!retransmission) { - if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq)) { + if (SEQ_LT(seq, ssn->client.next_seq)) { SCLogDebug("ssn %p: not updating state as packet is before next_seq", ssn); - } else if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq + 1) { + } else if (seq != ssn->client.next_seq && seq != ssn->client.next_seq + 1) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_LASTACK_ACK_WRONG_SEQ); return -1; } else { StreamTcpPacketSetState(p, ssn, TCP_CLOSED); SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn); - } - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4833,10 +4852,10 @@ static int StreamTcpPacketStateLastAck( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq, ack)) + ssn->server.next_seq = ack; - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4864,20 +4883,23 @@ static int StreamTcpPacketStateTimeWait( ThreadVars *tv, Packet *p, StreamTcpThread *stt, TcpSession *ssn) { DEBUG_VALIDATE_BUG_ON(ssn == NULL); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); + const uint16_t window = TCP_GET_RAW_WINDOW(tcph); - if (p->tcph->th_flags & TH_RST) { + if (tcph->th_flags & TH_RST) { if (!StreamTcpValidateRst(ssn, p)) return -1; StreamTcpCloseSsnWithReset(p, ssn); if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4885,12 +4907,11 @@ static int StreamTcpPacketStateTimeWait( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); + if ((tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) + StreamTcpUpdateLastAck( + ssn, &ssn->client, StreamTcpResetGetMaxAck(&ssn->client, ack)); - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); + StreamTcpUpdateLastAck(ssn, &ssn->server, StreamTcpResetGetMaxAck(&ssn->server, seq)); if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { StreamTcpHandleTimestamp(ssn, p); @@ -4899,15 +4920,15 @@ static int StreamTcpPacketStateTimeWait( StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); } - } else if (p->tcph->th_flags & TH_FIN) { + } else if (tcph->th_flags & TH_FIN) { /** \todo */ - } else if (p->tcph->th_flags & TH_SYN) { + } else if (tcph->th_flags & TH_SYN) { SCLogDebug("ssn (%p): SYN pkt on TimeWait", ssn); StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); return -1; - } else if (p->tcph->th_flags & TH_ACK) { + } else if (tcph->th_flags & TH_ACK) { if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { if (!StreamTcpValidateTimestamp(ssn, p)) return -1; @@ -4915,18 +4936,18 @@ static int StreamTcpPacketStateTimeWait( if (PKT_IS_TOSERVER(p)) { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq+1) { + } else if (seq != ssn->client.next_seq && seq != ssn->client.next_seq + 1) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->client.next_seq); StreamTcpSetEvent(p, STREAM_TIMEWAIT_ACK_WRONG_SEQ); return -1; } @@ -4941,7 +4962,7 @@ static int StreamTcpPacketStateTimeWait( StreamTcpPacketSetState(p, ssn, TCP_CLOSED); SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; + ssn->server.window = window << ssn->server.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -4950,10 +4971,10 @@ static int StreamTcpPacketStateTimeWait( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->server.next_seq, ack)) + ssn->server.next_seq = ack; - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->server, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -4961,22 +4982,21 @@ static int StreamTcpPacketStateTimeWait( ssn->server.last_ack); } else { SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); + "%" PRIu32 ", ACK %" PRIu32 "", + ssn, p->payload_len, seq, ack); int retransmission = 0; if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); - } else if (TCP_GET_SEQ(p) != ssn->server.next_seq - 1 && - TCP_GET_SEQ(p) != ssn->server.next_seq) { - if (p->payload_len > 0 && TCP_GET_SEQ(p) == ssn->server.last_ack) { + } else if (seq != ssn->server.next_seq - 1 && seq != ssn->server.next_seq) { + if (p->payload_len > 0 && seq == ssn->server.last_ack) { SCLogDebug("ssn %p: -> retransmission", ssn); SCReturnInt(0); } else { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); + " != %" PRIu32 " from stream", + ssn, seq, ssn->server.next_seq); StreamTcpSetEvent(p, STREAM_TIMEWAIT_ACK_WRONG_SEQ); return -1; } @@ -4992,7 +5012,7 @@ static int StreamTcpPacketStateTimeWait( StreamTcpPacketSetState(p, ssn, TCP_CLOSED); SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; + ssn->client.window = window << ssn->client.wscale; } if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { @@ -5001,10 +5021,10 @@ static int StreamTcpPacketStateTimeWait( /* Update the next_seq, in case if we have missed the client packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); + if (SEQ_LT(ssn->client.next_seq, ack)) + ssn->client.next_seq = ack; - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); + StreamTcpUpdateLastAck(ssn, &ssn->client, ack); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -5024,7 +5044,8 @@ static int StreamTcpPacketStateClosed( { DEBUG_VALIDATE_BUG_ON(ssn == NULL); - if (p->tcph->th_flags & TH_RST) { + const TCPHdr *tcph = PacketGetTCP(p); + if (tcph->th_flags & TH_RST) { SCLogDebug("RST on closed state"); return 0; } @@ -5061,8 +5082,9 @@ static void StreamTcpPacketCheckPostRst(TcpSession *ssn, Packet *p) if (p->flags & PKT_PSEUDO_STREAM_END) { return; } + const TCPHdr *tcph = PacketGetTCP(p); /* more RSTs are not unusual */ - if ((p->tcph->th_flags & (TH_RST)) != 0) { + if ((tcph->th_flags & (TH_RST)) != 0) { return; } @@ -5102,7 +5124,8 @@ static int StreamTcpPacketIsKeepAlive(TcpSession *ssn, Packet *p) if (p->payload_len > 1) return 0; - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) { + const TCPHdr *tcph = PacketGetTCP(p); + if ((tcph->th_flags & (TH_SYN | TH_FIN | TH_RST)) != 0) { return 0; } @@ -5115,8 +5138,8 @@ static int StreamTcpPacketIsKeepAlive(TcpSession *ssn, Packet *p) ostream = &ssn->client; } - const uint32_t seq = TCP_GET_SEQ(p); - const uint32_t ack = TCP_GET_ACK(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); if (ack == ostream->last_ack && seq == (stream->next_seq - 1)) { SCLogDebug("packet is TCP keep-alive: %"PRIu64, p->pcap_cnt); stream->flags |= STREAMTCP_STREAM_FLAG_KEEPALIVE; @@ -5144,10 +5167,11 @@ static int StreamTcpPacketIsKeepAliveACK(TcpSession *ssn, Packet *p) if (p->payload_len > 0) return 0; - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) + const TCPHdr *tcph = PacketGetTCP(p); + if ((tcph->th_flags & (TH_SYN | TH_FIN | TH_RST)) != 0) return 0; - if (TCP_GET_WINDOW(p) == 0) + if (TCP_GET_RAW_WINDOW(tcph) == 0) return 0; if (PKT_IS_TOSERVER(p)) { @@ -5158,10 +5182,10 @@ static int StreamTcpPacketIsKeepAliveACK(TcpSession *ssn, Packet *p) ostream = &ssn->client; } - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); + seq = TCP_GET_RAW_SEQ(tcph); + ack = TCP_GET_RAW_ACK(tcph); - pkt_win = TCP_GET_WINDOW(p) << ostream->wscale; + pkt_win = TCP_GET_RAW_WINDOW(tcph) << ostream->wscale; if (pkt_win != ostream->window) return 0; @@ -5215,10 +5239,11 @@ static int StreamTcpPacketIsWindowUpdate(TcpSession *ssn, Packet *p) if (p->payload_len > 0) return 0; - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) + const TCPHdr *tcph = PacketGetTCP(p); + if ((tcph->th_flags & (TH_SYN | TH_FIN | TH_RST)) != 0) return 0; - if (TCP_GET_WINDOW(p) == 0) + if (TCP_GET_RAW_WINDOW(tcph) == 0) return 0; if (PKT_IS_TOSERVER(p)) { @@ -5229,10 +5254,10 @@ static int StreamTcpPacketIsWindowUpdate(TcpSession *ssn, Packet *p) ostream = &ssn->client; } - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); + seq = TCP_GET_RAW_SEQ(tcph); + ack = TCP_GET_RAW_ACK(tcph); - pkt_win = TCP_GET_WINDOW(p) << ostream->wscale; + pkt_win = TCP_GET_RAW_WINDOW(tcph) << ostream->wscale; if (pkt_win == ostream->window) return 0; @@ -5259,7 +5284,8 @@ static int StreamTcpPacketIsFinShutdownAck(TcpSession *ssn, Packet *p) return 0; if (!(ssn->state == TCP_TIME_WAIT || ssn->state == TCP_CLOSE_WAIT || ssn->state == TCP_LAST_ACK)) return 0; - if (p->tcph->th_flags != TH_ACK) + const TCPHdr *tcph = PacketGetTCP(p); + if (tcph->th_flags != TH_ACK) return 0; if (p->payload_len != 0) return 0; @@ -5272,8 +5298,8 @@ static int StreamTcpPacketIsFinShutdownAck(TcpSession *ssn, Packet *p) ostream = &ssn->client; } - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); + seq = TCP_GET_RAW_SEQ(tcph); + ack = TCP_GET_RAW_ACK(tcph); SCLogDebug("%"PRIu64", seq %u ack %u stream->next_seq %u ostream->next_seq %u", p->pcap_cnt, seq, ack, stream->next_seq, ostream->next_seq); @@ -5314,7 +5340,8 @@ static int StreamTcpPacketIsBadWindowUpdate(TcpSession *ssn, Packet *p) if (ssn->state < TCP_ESTABLISHED || ssn->state == TCP_CLOSED) return 0; - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) + const TCPHdr *tcph = PacketGetTCP(p); + if ((tcph->th_flags & (TH_SYN | TH_FIN | TH_RST)) != 0) return 0; if (PKT_IS_TOSERVER(p)) { @@ -5325,10 +5352,9 @@ static int StreamTcpPacketIsBadWindowUpdate(TcpSession *ssn, Packet *p) ostream = &ssn->client; } - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); - - pkt_win = TCP_GET_WINDOW(p) << ostream->wscale; + seq = TCP_GET_RAW_SEQ(tcph); + ack = TCP_GET_RAW_ACK(tcph); + pkt_win = TCP_GET_RAW_WINDOW(tcph) << ostream->wscale; if (pkt_win < ostream->window) { uint32_t diff = ostream->window - pkt_win; @@ -5477,14 +5503,15 @@ int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt, SCLogDebug("p->pcap_cnt %"PRIu64, p->pcap_cnt); TcpSession *ssn = (TcpSession *)p->flow->protoctx; + const TCPHdr *tcph = PacketGetTCP(p); /* track TCP flags */ if (ssn != NULL) { - ssn->tcp_packet_flags |= p->tcph->th_flags; + ssn->tcp_packet_flags |= tcph->th_flags; if (PKT_IS_TOSERVER(p)) - ssn->client.tcp_flags |= p->tcph->th_flags; + ssn->client.tcp_flags |= tcph->th_flags; else if (PKT_IS_TOCLIENT(p)) - ssn->server.tcp_flags |= p->tcph->th_flags; + ssn->server.tcp_flags |= tcph->th_flags; /* check if we need to unset the ASYNC flag */ if (ssn->flags & STREAMTCP_FLAG_ASYNC && @@ -5497,7 +5524,7 @@ int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt, } /* broken TCP http://ask.wireshark.org/questions/3183/acknowledgment-number-broken-tcp-the-acknowledge-field-is-nonzero-while-the-ack-flag-is-not-set */ - if (!(p->tcph->th_flags & TH_ACK) && TCP_GET_ACK(p) != 0) { + if (!(tcph->th_flags & TH_ACK) && TCP_GET_RAW_ACK(tcph) != 0) { StreamTcpSetEvent(p, STREAM_PKT_BROKEN_ACK); } @@ -5527,10 +5554,10 @@ int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt, * we care about reassembly here. */ if (p->flags & PKT_PSEUDO_STREAM_END) { if (PKT_IS_TOCLIENT(p)) { - ssn->client.last_ack = TCP_GET_ACK(p); + ssn->client.last_ack = TCP_GET_RAW_ACK(tcph); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p); } else { - ssn->server.last_ack = TCP_GET_ACK(p); + ssn->server.last_ack = TCP_GET_RAW_ACK(tcph); StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p); } /* straight to 'skip' as we already handled reassembly */ @@ -5680,15 +5707,16 @@ static inline int StreamTcpValidateChecksum(Packet *p) return ret; if (!p->l4.csum_set) { + const TCPHdr *tcph = PacketGetTCP(p); if (PacketIsIPv4(p)) { const IPV4Hdr *ip4h = PacketGetIPv4(p); - p->l4.csum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p)), p->tcph->th_sum); + p->l4.csum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)tcph, + (p->payload_len + TCP_GET_RAW_HLEN(tcph)), tcph->th_sum); p->l4.csum_set = true; } else if (PacketIsIPv6(p)) { const IPV6Hdr *ip6h = PacketGetIPv6(p); - p->l4.csum = TCPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p)), p->tcph->th_sum); + p->l4.csum = TCPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)tcph, + (p->payload_len + TCP_GET_RAW_HLEN(tcph)), tcph->th_sum); p->l4.csum_set = true; } } @@ -5710,18 +5738,20 @@ static inline int StreamTcpValidateChecksum(Packet *p) * \retval bool true/false */ static int TcpSessionPacketIsStreamStarter(const Packet *p) { - if (p->tcph->th_flags & (TH_RST | TH_FIN)) { + const TCPHdr *tcph = PacketGetTCP(p); + if (tcph->th_flags & (TH_RST | TH_FIN)) { return 0; } - if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == TH_SYN) { - SCLogDebug("packet %"PRIu64" is a stream starter: %02x", p->pcap_cnt, p->tcph->th_flags); + if ((tcph->th_flags & (TH_SYN | TH_ACK)) == TH_SYN) { + SCLogDebug("packet %" PRIu64 " is a stream starter: %02x", p->pcap_cnt, tcph->th_flags); return 1; } if (stream_config.midstream || stream_config.async_oneside) { - if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { - SCLogDebug("packet %"PRIu64" is a midstream stream starter: %02x", p->pcap_cnt, p->tcph->th_flags); + if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { + SCLogDebug("packet %" PRIu64 " is a midstream stream starter: %02x", p->pcap_cnt, + tcph->th_flags); return 1; } } @@ -5733,6 +5763,7 @@ static int TcpSessionPacketIsStreamStarter(const Packet *p) * \retval bool true yes reuse, false no keep tracking old ssn */ static int TcpSessionReuseDoneEnoughSyn(const Packet *p, const Flow *f, const TcpSession *ssn) { + const TCPHdr *tcph = PacketGetTCP(p); if (FlowGetPacketDirection(f, p) == TOSERVER) { if (ssn == NULL) { /* most likely a flow that was picked up after the 3whs, or a flow that @@ -5746,7 +5777,7 @@ static int TcpSessionReuseDoneEnoughSyn(const Packet *p, const Flow *f, const Tc p->pcap_cnt, ssn); return 1; } - if (SEQ_EQ(ssn->client.isn, TCP_GET_SEQ(p))) { + if (SEQ_EQ(ssn->client.isn, TCP_GET_RAW_SEQ(tcph))) { SCLogDebug("steam starter packet %"PRIu64", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->pcap_cnt, ssn); return 0; } @@ -5788,12 +5819,13 @@ static int TcpSessionReuseDoneEnoughSyn(const Packet *p, const Flow *f, const Tc */ static int TcpSessionReuseDoneEnoughSynAck(const Packet *p, const Flow *f, const TcpSession *ssn) { + const TCPHdr *tcph = PacketGetTCP(p); if (FlowGetPacketDirection(f, p) == TOCLIENT) { if (ssn == NULL) { SCLogDebug("steam starter packet %"PRIu64", ssn %p null. No reuse.", p->pcap_cnt, ssn); return 0; } - if (SEQ_EQ(ssn->server.isn, TCP_GET_SEQ(p))) { + if (SEQ_EQ(ssn->server.isn, TCP_GET_RAW_SEQ(tcph))) { SCLogDebug("steam starter packet %"PRIu64", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->pcap_cnt, ssn); return 0; } @@ -5836,12 +5868,13 @@ static int TcpSessionReuseDoneEnoughSynAck(const Packet *p, const Flow *f, const * \retval bool true if ssn can be reused, false if not */ static int TcpSessionReuseDoneEnough(const Packet *p, const Flow *f, const TcpSession *ssn) { - if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == TH_SYN) { + const TCPHdr *tcph = PacketGetTCP(p); + if ((tcph->th_flags & (TH_SYN | TH_ACK)) == TH_SYN) { return TcpSessionReuseDoneEnoughSyn(p, f, ssn); } if (stream_config.midstream || stream_config.async_oneside) { - if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { + if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { return TcpSessionReuseDoneEnoughSynAck(p, f, ssn); } } @@ -6028,6 +6061,8 @@ TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data) static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) { uint8_t os_policy; + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); if (ssn->flags & STREAMTCP_FLAG_LOSSY_BE_LIBERAL) { SCReturnInt(1); @@ -6062,8 +6097,8 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) os_policy = ssn->server.os_policy; - if (p->tcph->th_flags & TH_ACK && - TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { + if (tcph->th_flags & TH_ACK && TCP_GET_RAW_ACK(tcph) && + StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); StreamTcpSetEvent(p, STREAM_RST_INVALID_ACK); SCReturnInt(0); @@ -6075,8 +6110,8 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) os_policy = ssn->client.os_policy; - if (p->tcph->th_flags & TH_ACK && - TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { + if (tcph->th_flags & TH_ACK && TCP_GET_RAW_ACK(tcph) && + StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); StreamTcpSetEvent(p, STREAM_RST_INVALID_ACK); SCReturnInt(0); @@ -6087,7 +6122,7 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) * validate these (requires key that is set/transferred out of band), we can't know * if the RST will be accepted or rejected by the end host. We accept it, but keep * tracking if the sender of it ignores it, which would be a sign of injection. */ - if (p->tcpvars.md5_option_present || p->tcpvars.ao_option_present) { + if (p->l4.vars.tcp.md5_option_present || p->l4.vars.tcp.ao_option_present) { TcpStream *receiver_stream; if (PKT_IS_TOSERVER(p)) { receiver_stream = &ssn->server; @@ -6100,12 +6135,12 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) if (ssn->flags & STREAMTCP_FLAG_ASYNC) { if (PKT_IS_TOSERVER(p)) { - if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.next_seq)) { + if (SEQ_GEQ(seq, ssn->client.next_seq)) { SCLogDebug("ssn %p: ASYNC accept RST", ssn); return 1; } } else { - if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->server.next_seq)) { + if (SEQ_GEQ(seq, ssn->server.next_seq)) { SCLogDebug("ssn %p: ASYNC accept RST", ssn); return 1; } @@ -6117,25 +6152,23 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) switch (os_policy) { case OS_POLICY_HPUX11: if(PKT_IS_TOSERVER(p)){ - if(SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.next_seq)) { - SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); + if (SEQ_GEQ(seq, ssn->client.next_seq)) { + SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", seq); return 1; } else { SCLogDebug("reset is not Valid! Packet SEQ: %" PRIu32 " " - "and server SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->client.next_seq); + "and server SEQ: %" PRIu32 "", + seq, ssn->client.next_seq); return 0; } } else { /* implied to client */ - if(SEQ_GEQ(TCP_GET_SEQ(p), ssn->server.next_seq)) { - SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); + if (SEQ_GEQ(seq, ssn->server.next_seq)) { + SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 "", seq); return 1; } else { SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " " - "and client SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->server.next_seq); + "and client SEQ: %" PRIu32 "", + seq, ssn->server.next_seq); return 0; } } @@ -6144,37 +6177,29 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) case OS_POLICY_LINUX: case OS_POLICY_SOLARIS: if(PKT_IS_TOSERVER(p)){ - if(SEQ_GEQ((TCP_GET_SEQ(p)+p->payload_len), - ssn->client.last_ack)) - { /*window base is needed !!*/ - if(SEQ_LT(TCP_GET_SEQ(p), - (ssn->client.next_seq + ssn->client.window))) - { - SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); + if (SEQ_GEQ((seq + p->payload_len), + ssn->client.last_ack)) { /*window base is needed !!*/ + if (SEQ_LT(seq, (ssn->client.next_seq + ssn->client.window))) { + SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", seq); return 1; } } else { SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " and" - " server SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->client.next_seq); + " server SEQ: %" PRIu32 "", + seq, ssn->client.next_seq); return 0; } } else { /* implied to client */ - if(SEQ_GEQ((TCP_GET_SEQ(p) + p->payload_len), - ssn->server.last_ack)) - { /*window base is needed !!*/ - if(SEQ_LT(TCP_GET_SEQ(p), - (ssn->server.next_seq + ssn->server.window))) - { - SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); + if (SEQ_GEQ((seq + p->payload_len), + ssn->server.last_ack)) { /*window base is needed !!*/ + if (SEQ_LT(seq, (ssn->server.next_seq + ssn->server.window))) { + SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", seq); return 1; } } else { SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " and" - " client SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->server.next_seq); + " client SEQ: %" PRIu32 "", + seq, ssn->server.next_seq); return 0; } } @@ -6190,25 +6215,24 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) case OS_POLICY_WINDOWS2K3: case OS_POLICY_VISTA: if(PKT_IS_TOSERVER(p)) { - if(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)) { - SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); + if (SEQ_EQ(seq, ssn->client.next_seq)) { + SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 "", seq); return 1; } else { SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " " - "and server SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->client.next_seq); + "and server SEQ: %" PRIu32 "", + seq, ssn->client.next_seq); return 0; } } else { /* implied to client */ - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq)) { - SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 " Stream %u", - TCP_GET_SEQ(p), ssn->server.next_seq); + if (SEQ_EQ(seq, ssn->server.next_seq)) { + SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 " Stream %u", seq, + ssn->server.next_seq); return 1; } else { SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " and" " client SEQ: %" PRIu32 "", - TCP_GET_SEQ(p), ssn->server.next_seq); + seq, ssn->server.next_seq); return 0; } } @@ -6239,6 +6263,8 @@ static int StreamTcpValidateTimestamp (TcpSession *ssn, Packet *p) TcpStream *receiver_stream; uint8_t ret = 1; uint8_t check_ts = 1; + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); if (PKT_IS_TOSERVER(p)) { sender_stream = &ssn->client; @@ -6272,7 +6298,7 @@ static int StreamTcpValidateTimestamp (TcpSession *ssn, Packet *p) case OS_POLICY_OLD_LINUX: case OS_POLICY_WINDOWS: case OS_POLICY_VISTA: - if (SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) { + if (SEQ_EQ(sender_stream->next_seq, seq)) { last_ts = ts; check_ts = 0; /*next packet will be checked for validity and stream TS has been updated with this @@ -6284,7 +6310,7 @@ static int StreamTcpValidateTimestamp (TcpSession *ssn, Packet *p) if (receiver_stream->os_policy == OS_POLICY_HPUX11) { /* HPUX11 ignores the timestamp of out of order packets */ - if (!SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) + if (!SEQ_EQ(sender_stream->next_seq, seq)) check_ts = 0; } @@ -6344,7 +6370,7 @@ static int StreamTcpValidateTimestamp (TcpSession *ssn, Packet *p) /* if the timestamp of packet is not valid then, check if the * current stream timestamp is not so old. if so then we need to * accept the packet and update the stream->last_ts (RFC 1323)*/ - if ((SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) && + if ((SEQ_EQ(sender_stream->next_seq, seq)) && (((uint32_t)SCTIME_SECS(p->ts) > (last_pkt_ts + PAWS_24DAYS)))) { SCLogDebug("timestamp considered valid anyway"); } else { @@ -6379,6 +6405,8 @@ static int StreamTcpHandleTimestamp (TcpSession *ssn, Packet *p) TcpStream *receiver_stream; uint8_t ret = 1; uint8_t check_ts = 1; + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t seq = TCP_GET_RAW_SEQ(tcph); if (PKT_IS_TOSERVER(p)) { sender_stream = &ssn->client; @@ -6412,7 +6440,7 @@ static int StreamTcpHandleTimestamp (TcpSession *ssn, Packet *p) case OS_POLICY_WINDOWS: case OS_POLICY_VISTA: sender_stream->flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - if (SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) { + if (SEQ_EQ(sender_stream->next_seq, seq)) { sender_stream->last_ts = ts; check_ts = 0; /*next packet will be checked for validity and stream TS has been updated with this @@ -6426,7 +6454,7 @@ static int StreamTcpHandleTimestamp (TcpSession *ssn, Packet *p) if (receiver_stream->os_policy == OS_POLICY_HPUX11) { /*HPUX11 ignores the timestamp of out of order packets*/ - if (!SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) + if (!SEQ_EQ(sender_stream->next_seq, seq)) check_ts = 0; } @@ -6486,7 +6514,7 @@ static int StreamTcpHandleTimestamp (TcpSession *ssn, Packet *p) if (ret == 1) { /* Update the timestamp and last seen packet time for this * stream */ - if (SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) + if (SEQ_EQ(sender_stream->next_seq, seq)) sender_stream->last_ts = ts; sender_stream->last_pkt_ts = SCTIME_SECS(p->ts); @@ -6495,7 +6523,7 @@ static int StreamTcpHandleTimestamp (TcpSession *ssn, Packet *p) /* if the timestamp of packet is not valid then, check if the * current stream timestamp is not so old. if so then we need to * accept the packet and update the stream->last_ts (RFC 1323)*/ - if ((SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) && + if ((SEQ_EQ(sender_stream->next_seq, seq)) && (((uint32_t)SCTIME_SECS(p->ts) > (sender_stream->last_pkt_ts + PAWS_24DAYS)))) { sender_stream->last_ts = ts; @@ -6537,10 +6565,11 @@ static inline int StreamTcpValidateAck(TcpSession *ssn, TcpStream *stream, Packe { SCEnter(); - if (!(p->tcph->th_flags & TH_ACK)) - SCReturnInt(0); + const TCPHdr *tcph = PacketGetTCP(p); + const uint32_t ack = TCP_GET_RAW_ACK(tcph); - const uint32_t ack = TCP_GET_ACK(p); + if (!(tcph->th_flags & TH_ACK)) + SCReturnInt(0); /* fast track */ if (SEQ_GT(ack, stream->last_ack) && SEQ_LEQ(ack, stream->next_win)) @@ -6551,14 +6580,14 @@ static inline int StreamTcpValidateAck(TcpSession *ssn, TcpStream *stream, Packe } /* fast track */ else if (SEQ_EQ(ack, stream->last_ack)) { - SCLogDebug("ssn %p: pkt ACK %" PRIu32 " == stream last ACK %" PRIu32, ssn, TCP_GET_ACK(p), + SCLogDebug("ssn %p: pkt ACK %" PRIu32 " == stream last ACK %" PRIu32, ssn, ack, stream->last_ack); SCReturnInt(0); } /* exception handling */ if (SEQ_LT(ack, stream->last_ack)) { - SCLogDebug("pkt ACK %"PRIu32" < stream last ACK %"PRIu32, TCP_GET_ACK(p), stream->last_ack); + SCLogDebug("pkt ACK %" PRIu32 " < stream last ACK %" PRIu32, ack, stream->last_ack); /* This is an attempt to get a 'left edge' value that we can check against. * It doesn't work when the window is 0, need to think of a better way. */ @@ -6583,9 +6612,8 @@ static inline int StreamTcpValidateAck(TcpSession *ssn, TcpStream *stream, Packe goto invalid; /* a toclient RST as a response to SYN, next_win is 0, ack will be isn+1, just like * the syn ack */ - } else if (ssn->state == TCP_SYN_SENT && PKT_IS_TOCLIENT(p) && - p->tcph->th_flags & TH_RST && - SEQ_EQ(ack, stream->isn + 1)) { + } else if (ssn->state == TCP_SYN_SENT && PKT_IS_TOCLIENT(p) && tcph->th_flags & TH_RST && + SEQ_EQ(ack, stream->isn + 1)) { SCReturnInt(0); } @@ -6666,10 +6694,14 @@ static void StreamTcpPseudoPacketCreateDetectLogFlush(ThreadVars *tv, { SCEnter(); Flow *f = parent->flow; + TCPHdr *tcph = NULL; if (parent->flags & PKT_PSEUDO_DETECTLOG_FLUSH) { SCReturn; } + if ((f->flags & (FLOW_IPV4 | FLOW_IPV6)) == 0) { + SCReturn; + } Packet *np = PacketPoolGetPacket(); if (np == NULL) { @@ -6747,11 +6779,12 @@ static void StreamTcpPseudoPacketCreateDetectLogFlush(ThreadVars *tv, } /* set the tcp header */ - np->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(np) + 20); + tcph = PacketSetTCP(np, GET_PKT_DATA(np) + 20); SET_PKT_LEN(np, 40); /* ipv4 hdr + tcp hdr */ + } else { + /* implied IPv6 */ - } else if (FLOW_IS_IPV6(f)) { if (dir == 0) { FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, &np->src); FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, &np->dst); @@ -6801,31 +6834,31 @@ static void StreamTcpPseudoPacketCreateDetectLogFlush(ThreadVars *tv, } /* set the tcp header */ - np->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(np) + 40); + tcph = PacketSetTCP(np, GET_PKT_DATA(np) + 40); SET_PKT_LEN(np, 60); /* ipv6 hdr + tcp hdr */ } - np->tcph->th_offx2 = 0x50; - np->tcph->th_flags |= TH_ACK; - np->tcph->th_win = 10; - np->tcph->th_urp = 0; + tcph->th_offx2 = 0x50; + tcph->th_flags |= TH_ACK; + tcph->th_win = 10; + tcph->th_urp = 0; /* to server */ if (dir == 0) { - np->tcph->th_sport = htons(f->sp); - np->tcph->th_dport = htons(f->dp); + tcph->th_sport = htons(f->sp); + tcph->th_dport = htons(f->dp); - np->tcph->th_seq = htonl(ssn->client.next_seq); - np->tcph->th_ack = htonl(ssn->server.last_ack); + tcph->th_seq = htonl(ssn->client.next_seq); + tcph->th_ack = htonl(ssn->server.last_ack); - /* to client */ + /* to client */ } else { - np->tcph->th_sport = htons(f->dp); - np->tcph->th_dport = htons(f->sp); + tcph->th_sport = htons(f->dp); + tcph->th_dport = htons(f->sp); - np->tcph->th_seq = htonl(ssn->server.next_seq); - np->tcph->th_ack = htonl(ssn->client.last_ack); + tcph->th_seq = htonl(ssn->server.next_seq); + tcph->th_ack = htonl(ssn->client.last_ack); } /* use parent time stamp */ diff --git a/src/tests/detect-http-uri.c b/src/tests/detect-http-uri.c index 8c60d43058..b40889cbea 100644 --- a/src/tests/detect-http-uri.c +++ b/src/tests/detect-http-uri.c @@ -1571,7 +1571,7 @@ static int UriTestSig16(void) Packet *p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); FAIL_IF_NULL(p); - p->tcph->th_seq = htonl(1000); + p->l4.hdrs.tcph->th_seq = htonl(1000); Flow *f = UTHBuildFlow(AF_INET, "192.168.1.5", "192.168.1.1", 41424, 80); FAIL_IF_NULL(f); f->proto = IPPROTO_TCP; diff --git a/src/tests/detect.c b/src/tests/detect.c index 2476ac0966..be6fb91305 100644 --- a/src/tests/detect.c +++ b/src/tests/detect.c @@ -1715,7 +1715,7 @@ static int SigTest26TCPV4Keyword(void) PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); PacketSetIPV4(p1, GET_PKT_DATA(p1)); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); + PacketSetTCP(p1, (GET_PKT_DATA(p1) + sizeof(raw_ipv4))); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20; @@ -1723,7 +1723,7 @@ static int SigTest26TCPV4Keyword(void) p1->proto = IPPROTO_TCP; PacketSetIPV4(p2, GET_PKT_DATA(p2)); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); + PacketSetTCP(p2, (GET_PKT_DATA(p2) + sizeof(raw_ipv4))); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20; @@ -1811,7 +1811,7 @@ static int SigTest26TCPV4AndNegativeIPV4Keyword(void) PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); PacketSetIPV4(p1, GET_PKT_DATA(p1)); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); + PacketSetTCP(p1, (GET_PKT_DATA(p1) + sizeof(raw_ipv4))); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20; @@ -1819,7 +1819,7 @@ static int SigTest26TCPV4AndNegativeIPV4Keyword(void) p1->proto = IPPROTO_TCP; PacketSetIPV4(p2, GET_PKT_DATA(p2)); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); + PacketSetTCP(p2, (GET_PKT_DATA(p2) + sizeof(raw_ipv4))); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20; @@ -1933,7 +1933,7 @@ static int SigTest26TCPV4AndIPV4Keyword(void) PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); PacketSetIPV4(p1, GET_PKT_DATA(p1)); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); + PacketSetTCP(p1, (GET_PKT_DATA(p1) + sizeof(raw_ipv4))); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20 + 24; @@ -1941,7 +1941,7 @@ static int SigTest26TCPV4AndIPV4Keyword(void) p1->proto = IPPROTO_TCP; PacketSetIPV4(p2, GET_PKT_DATA(p2)); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); + PacketSetTCP(p2, (GET_PKT_DATA(p2) + sizeof(raw_ipv4))); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20 + 24; @@ -2042,7 +2042,7 @@ static int SigTest27NegativeTCPV4Keyword(void) PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); PacketSetIPV4(p1, GET_PKT_DATA(p1)); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); + PacketSetTCP(p1, (GET_PKT_DATA(p1) + sizeof(raw_ipv4))); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20; @@ -2050,7 +2050,7 @@ static int SigTest27NegativeTCPV4Keyword(void) p1->proto = IPPROTO_TCP; PacketSetIPV4(p2, GET_PKT_DATA(p2)); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); + PacketSetTCP(p2, (GET_PKT_DATA(p2) + sizeof(raw_ipv4))); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20; @@ -2158,26 +2158,26 @@ static int SigTest28TCPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PacketSetIPV6(p1, valid_raw_ipv6 + 14); - p1->tcph = (TCPHdr *) (valid_raw_ipv6 + 54); + PacketSetTCP(p1, (valid_raw_ipv6 + 54)); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = valid_raw_ipv6 + 54 + 20; p1->payload_len = 12; p1->proto = IPPROTO_TCP; - if (TCP_GET_HLEN(p1) != 20) { + if (TCP_GET_RAW_HLEN(PacketGetTCP(p1)) != 20) { BUG_ON(1); } PacketSetIPV6(p2, invalid_raw_ipv6 + 14); - p2->tcph = (TCPHdr *) (invalid_raw_ipv6 + 54); + PacketSetTCP(p2, (invalid_raw_ipv6 + 54)); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = invalid_raw_ipv6 + 54 + 20; p2->payload_len = 12; p2->proto = IPPROTO_TCP; - if (TCP_GET_HLEN(p2) != 20) { + if (TCP_GET_RAW_HLEN(PacketGetTCP(p2)) != 20) { BUG_ON(1); } @@ -2282,28 +2282,26 @@ static int SigTest29NegativeTCPV6Keyword(void) memset(&th_v, 0, sizeof(ThreadVars)); PacketSetIPV6(p1, valid_raw_ipv6 + 14); - p1->tcph = (TCPHdr *) (valid_raw_ipv6 + 54); + PacketSetTCP(p1, valid_raw_ipv6 + 54); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = valid_raw_ipv6 + 54 + 20; p1->payload_len = 12; p1->proto = IPPROTO_TCP; - if (TCP_GET_HLEN(p1) != 20) { + if (TCP_GET_RAW_HLEN(PacketGetTCP(p1)) != 20) { BUG_ON(1); } PacketSetIPV6(p2, invalid_raw_ipv6 + 14); - p2->tcph = (TCPHdr *) (invalid_raw_ipv6 + 54); + PacketSetTCP(p2, invalid_raw_ipv6 + 54); p2->src.family = AF_INET; p2->dst.family = AF_INET; p2->payload = invalid_raw_ipv6 + 54 + 20; p2->payload_len = 12; p2->proto = IPPROTO_TCP; - if (TCP_GET_HLEN(p2) != 20) { - BUG_ON(1); - } + FAIL_IF(TCP_GET_RAW_HLEN(PacketGetTCP(p2)) != 20); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { @@ -3075,7 +3073,7 @@ static int SigTest38(void) PacketSetEthernet(p1, raw_eth); PacketSetIPV4(p1, raw_ipv4); - p1->tcph = (TCPHdr *)raw_tcp; + PacketSetTCP(p1, raw_tcp); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = GET_PKT_DATA(p1) + ethlen + ipv4len + tcplen; @@ -3190,7 +3188,7 @@ static int SigTest39(void) PacketSetEthernet(p1, raw_eth); PacketSetIPV4(p1, raw_ipv4); - p1->tcph = (TCPHdr *)raw_tcp; + PacketSetTCP(p1, raw_tcp); p1->src.family = AF_INET; p1->dst.family = AF_INET; p1->payload = GET_PKT_DATA(p1) + ethlen + ipv4len + tcplen; @@ -3507,7 +3505,7 @@ static int SigTest40NoPacketInspection01(void) p->sp = 21; p->flowflags |= FLOW_PKT_TOSERVER; p->flags |= PKT_NOPACKET_INSPECTION; - p->tcph = &tcphdr; + PacketSetTCP(p, (uint8_t *)&tcphdr); p->flow = &f; FLOW_INITIALIZE(&f); diff --git a/src/tests/stream-tcp-inline.c b/src/tests/stream-tcp-inline.c index 410451a833..c0f0b4a725 100644 --- a/src/tests/stream-tcp-inline.c +++ b/src/tests/stream-tcp-inline.c @@ -63,8 +63,8 @@ static int VALIDATE(TcpStream *stream, uint8_t *data, uint32_t data_len) p = UTHBuildPacketReal( \ (uint8_t *)(seg), (seglen), IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); \ FAIL_IF(p == NULL); \ - p->tcph->th_seq = htonl(stream->isn + (rseq)); \ - p->tcph->th_ack = htonl(31); \ + p->l4.hdrs.tcph->th_seq = htonl(stream->isn + (rseq)); \ + p->l4.hdrs.tcph->th_ack = htonl(31); \ FAIL_IF(StreamTcpReassembleHandleSegmentHandleData(&tv, ra_ctx, &ssn, stream, p) < 0); \ FAIL_IF(memcmp(p->payload, packet, MIN((packetlen), p->payload_len)) != 0); \ UTHFreePacket(p); diff --git a/src/tests/stream-tcp-reassemble.c b/src/tests/stream-tcp-reassemble.c index 5f07f336c4..f001b879b3 100644 --- a/src/tests/stream-tcp-reassemble.c +++ b/src/tests/stream-tcp-reassemble.c @@ -88,23 +88,24 @@ static int TestReassembleRawValidate(TcpSession *ssn, Packet *p, StreamTcpUTDeinit(ra_ctx); \ PASS -#define RAWREASSEMBLY_STEP(seq, seg, seglen, buf, buflen) \ - p = PacketGetFromAlloc(); \ - FAIL_IF_NULL(p); \ - { \ - SCLogNotice("SEQ %u block of %u", (seq), (seglen)); \ - p->flowflags = FLOW_PKT_TOSERVER; \ - TCPHdr tcphdr; \ - memset(&tcphdr, 0, sizeof(tcphdr)); \ - p->tcph = &tcphdr; \ - p->tcph->th_seq = htonl((seq)); \ - p->tcph->th_ack = htonl(10); \ - p->payload_len = (seglen); \ - \ - FAIL_IF(StreamTcpUTAddPayload(&tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen)) != 0); \ - p->flags |= PKT_STREAM_ADD; \ - FAIL_IF(!(TestReassembleRawValidate(&ssn, p, (uint8_t *)(buf), (buflen)))); \ - }\ +#define RAWREASSEMBLY_STEP(seq, seg, seglen, buf, buflen) \ + p = PacketGetFromAlloc(); \ + FAIL_IF_NULL(p); \ + { \ + SCLogNotice("SEQ %u block of %u", (seq), (seglen)); \ + p->flowflags = FLOW_PKT_TOSERVER; \ + TCPHdr tcphdr; \ + memset(&tcphdr, 0, sizeof(tcphdr)); \ + UTHSetTCPHdr(p, &tcphdr); \ + tcphdr.th_seq = htonl((seq)); \ + tcphdr.th_ack = htonl(10); \ + p->payload_len = (seglen); \ + \ + FAIL_IF(StreamTcpUTAddPayload( \ + &tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen)) != 0); \ + p->flags |= PKT_STREAM_ADD; \ + FAIL_IF(!(TestReassembleRawValidate(&ssn, p, (uint8_t *)(buf), (buflen)))); \ + } \ PacketFree(p); #define RAWREASSEMBLY_STEP_WITH_PROGRESS(seq, seg, seglen, buf, buflen, lastack, progress) \ diff --git a/src/tests/stream-tcp.c b/src/tests/stream-tcp.c index 3dd1a6ea64..aad79597f7 100644 --- a/src/tests/stream-tcp.c +++ b/src/tests/stream-tcp.c @@ -41,8 +41,11 @@ static int StreamTcpTest01(void) { StreamTcpThread stt; + TCPHdr tcph; + memset(&tcph, 0, sizeof(TCPHdr)); Packet *p = PacketGetFromAlloc(); FAIL_IF_NULL(p); + UTHSetTCPHdr(p, &tcph); Flow f; memset(&f, 0, sizeof(Flow)); FLOW_INITIALIZE(&f); @@ -88,29 +91,29 @@ static int StreamTcpTest02(void) p->flow = &f; tcph.th_win = htons(5480); tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; StreamTcpUTInit(&stt.ra_ctx); FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(2); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -122,9 +125,9 @@ static int StreamTcpTest02(void) p->flowflags = FLOW_PKT_TOCLIENT; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(6); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -176,23 +179,23 @@ static int StreamTcpTest03(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_SYN | TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); int ret = 0; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK; + tcph.th_seq = htonl(20); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(19); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(19); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -250,16 +253,16 @@ static int StreamTcpTest04(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); int ret = 0; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(9); - p->tcph->th_ack = htonl(19); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(9); + tcph.th_ack = htonl(19); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -318,7 +321,7 @@ static int StreamTcpTest05(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ p->payload = payload; @@ -327,9 +330,9 @@ static int StreamTcpTest05(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(20); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -339,9 +342,9 @@ static int StreamTcpTest05(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(13); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(13); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, 4); /*CCC*/ @@ -351,9 +354,9 @@ static int StreamTcpTest05(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(19); - p->tcph->th_ack = htonl(16); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(19); + tcph.th_ack = htonl(16); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x44, 3, 4); /*DDD*/ @@ -415,7 +418,7 @@ static int StreamTcpTest06(void) StreamTcpUTInit(&stt.ra_ctx); tcph.th_flags = TH_FIN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); /* StreamTcpPacket returns -1 on unsolicited FIN */ if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) { @@ -428,7 +431,7 @@ static int StreamTcpTest06(void) goto end; } - p->tcph->th_flags = TH_RST; + tcph.th_flags = TH_RST; /* StreamTcpPacket returns -1 on unsolicited RST */ if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) { printf("StreamTcpPacket failed (2): "); @@ -480,23 +483,23 @@ static int StreamTcpTest07(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); - p->tcpvars.ts_set = true; - p->tcpvars.ts_val = 10; - p->tcpvars.ts_ecr = 11; + p->l4.vars.tcp.ts_set = true; + p->l4.vars.tcp.ts_val = 10; + p->l4.vars.tcp.ts_ecr = 11; p->payload = payload; p->payload_len = 1; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; - p->tcpvars.ts_val = 2; + p->l4.vars.tcp.ts_val = 2; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) != -1); @@ -541,23 +544,23 @@ static int StreamTcpTest08(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); - p->tcpvars.ts_set = true; - p->tcpvars.ts_val = 10; - p->tcpvars.ts_ecr = 11; + p->l4.vars.tcp.ts_set = true; + p->l4.vars.tcp.ts_val = 10; + p->l4.vars.tcp.ts_ecr = 11; p->payload = payload; p->payload_len = 1; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(20); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(20); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; - p->tcpvars.ts_val = 12; + p->l4.vars.tcp.ts_val = 12; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); @@ -603,16 +606,16 @@ static int StreamTcpTest09(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->payload = payload; p->payload_len = 1; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(12); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(12); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; FAIL_IF(p->flow->protoctx == NULL); @@ -621,9 +624,9 @@ static int StreamTcpTest09(void) FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); @@ -671,20 +674,20 @@ static int StreamTcpTest10(void) tcph.th_seq = htonl(10); tcph.th_ack = 0; tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -693,9 +696,9 @@ static int StreamTcpTest10(void) FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(6); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(6); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -750,20 +753,20 @@ static int StreamTcpTest11(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(1); tcph.th_flags = TH_SYN | TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(1); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -772,9 +775,9 @@ static int StreamTcpTest11(void) FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1); - p->tcph->th_seq = htonl(2); - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(2); + tcph.th_ack = htonl(1); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -828,15 +831,15 @@ static int StreamTcpTest12(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(11); tcph.th_flags = TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); int ret = 0; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(10); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -846,9 +849,9 @@ static int StreamTcpTest12(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(6); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(6); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -922,15 +925,15 @@ static int StreamTcpTest13(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(11); tcph.th_flags = TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); int ret = 0; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(10); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -940,9 +943,9 @@ static int StreamTcpTest13(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(6); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(6); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -967,9 +970,9 @@ static int StreamTcpTest13(void) goto end; } - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(9); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(9); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -1136,7 +1139,7 @@ static int StreamTcpTest14(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->dst.family = AF_INET; p->dst.address.address_un_data32[0] = addr.s_addr; UTHSetIPV4Hdr(p, &ipv4h); @@ -1148,9 +1151,9 @@ static int StreamTcpTest14(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(20); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ @@ -1160,9 +1163,9 @@ static int StreamTcpTest14(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(15); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1172,9 +1175,9 @@ static int StreamTcpTest14(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(14); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1185,9 +1188,9 @@ static int StreamTcpTest14(void) goto end; addr.s_addr = inet_addr("192.168.0.2"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(25); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; p->dst.address.address_un_data32[0] = addr.s_addr; @@ -1198,9 +1201,9 @@ static int StreamTcpTest14(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(24); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ @@ -1278,14 +1281,14 @@ static int StreamTcp4WHSTest01(void) tcph.th_seq = htonl(10); tcph.th_ack = 0; tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = 0; - p->tcph->th_flags = TH_SYN; + tcph.th_seq = htonl(20); + tcph.th_ack = 0; + tcph.th_flags = TH_SYN; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -1296,17 +1299,17 @@ static int StreamTcp4WHSTest01(void) goto end; } - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */ - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(10); + tcph.th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */ + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(21); - p->tcph->th_ack = htonl(10); - p->tcph->th_flags = TH_ACK; + tcph.th_seq = htonl(21); + tcph.th_ack = htonl(10); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -1358,14 +1361,14 @@ static int StreamTcp4WHSTest02(void) tcph.th_seq = htonl(10); tcph.th_ack = 0; tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = 0; - p->tcph->th_flags = TH_SYN; + tcph.th_seq = htonl(20); + tcph.th_ack = 0; + tcph.th_flags = TH_SYN; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -1376,9 +1379,9 @@ static int StreamTcp4WHSTest02(void) goto end; } - p->tcph->th_seq = htonl(30); - p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */ - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(30); + tcph.th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */ + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) { @@ -1427,14 +1430,14 @@ static int StreamTcp4WHSTest03(void) tcph.th_seq = htonl(10); tcph.th_ack = 0; tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = 0; - p->tcph->th_flags = TH_SYN; + tcph.th_seq = htonl(20); + tcph.th_ack = 0; + tcph.th_flags = TH_SYN; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -1445,17 +1448,17 @@ static int StreamTcp4WHSTest03(void) goto end; } - p->tcph->th_seq = htonl(30); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(30); + tcph.th_ack = htonl(11); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(31); - p->tcph->th_flags = TH_ACK; + tcph.th_seq = htonl(11); + tcph.th_ack = htonl(31); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -1526,7 +1529,7 @@ static int StreamTcpTest15(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->dst.family = AF_INET; p->dst.address.address_un_data32[0] = addr.s_addr; UTHSetIPV4Hdr(p, &ipv4h); @@ -1538,9 +1541,9 @@ static int StreamTcpTest15(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(20); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ @@ -1550,9 +1553,9 @@ static int StreamTcpTest15(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(15); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1562,9 +1565,9 @@ static int StreamTcpTest15(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(14); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1575,9 +1578,9 @@ static int StreamTcpTest15(void) goto end; addr.s_addr = inet_addr("192.168.1.20"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(25); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; p->dst.address.address_un_data32[0] = addr.s_addr; @@ -1588,9 +1591,9 @@ static int StreamTcpTest15(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(24); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ @@ -1688,7 +1691,7 @@ static int StreamTcpTest16(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->dst.family = AF_INET; p->dst.address.address_un_data32[0] = addr.s_addr; UTHSetIPV4Hdr(p, &ipv4h); @@ -1700,9 +1703,9 @@ static int StreamTcpTest16(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(20); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ @@ -1712,9 +1715,9 @@ static int StreamTcpTest16(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(15); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1724,9 +1727,9 @@ static int StreamTcpTest16(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(14); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1737,9 +1740,9 @@ static int StreamTcpTest16(void) goto end; addr.s_addr = inet_addr("192.168.1.1"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(25); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; p->dst.address.address_un_data32[0] = addr.s_addr; @@ -1750,9 +1753,9 @@ static int StreamTcpTest16(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(24); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ @@ -1851,7 +1854,7 @@ static int StreamTcpTest17(void) tcph.th_seq = htonl(10); tcph.th_ack = htonl(20); tcph.th_flags = TH_ACK | TH_PUSH; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->dst.family = AF_INET; p->dst.address.address_un_data32[0] = addr.s_addr; UTHSetIPV4Hdr(p, &ipv4h); @@ -1863,9 +1866,9 @@ static int StreamTcpTest17(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(20); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ @@ -1875,9 +1878,9 @@ static int StreamTcpTest17(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(15); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1887,9 +1890,9 @@ static int StreamTcpTest17(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(14); + tcph.th_ack = htonl(23); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ @@ -1900,9 +1903,9 @@ static int StreamTcpTest17(void) goto end; addr.s_addr = inet_addr("10.1.1.1"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(25); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; p->dst.address.address_un_data32[0] = addr.s_addr; @@ -1913,9 +1916,9 @@ static int StreamTcpTest17(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK | TH_PUSH; + tcph.th_seq = htonl(24); + tcph.th_ack = htonl(13); + tcph.th_flags = TH_ACK | TH_PUSH; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ @@ -2238,25 +2241,25 @@ static int StreamTcpTest23(void) p->flow = &f; tcph.th_win = 5480; tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; p->payload = packet; SET_ISN(&ssn.client, 3184324452UL); - p->tcph->th_seq = htonl(3184324453UL); - p->tcph->th_ack = htonl(3373419609UL); + tcph.th_seq = htonl(3184324453UL); + tcph.th_ack = htonl(3373419609UL); p->payload_len = 2; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(3184324455UL); - p->tcph->th_ack = htonl(3373419621UL); + tcph.th_seq = htonl(3184324455UL); + tcph.th_ack = htonl(3373419621UL); p->payload_len = 2; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(3184324453UL); - p->tcph->th_ack = htonl(3373419621UL); + tcph.th_seq = htonl(3184324453UL); + tcph.th_ack = htonl(3373419621UL); p->payload_len = 6; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1); @@ -2300,26 +2303,26 @@ static int StreamTcpTest24(void) p->flow = &f; tcph.th_win = 5480; tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; p->payload = packet; // ssn.client.ra_app_base_seq = ssn.client.ra_raw_base_seq = ssn.client.last_ack = 3184324453UL; SET_ISN(&ssn.client, 3184324453UL); - p->tcph->th_seq = htonl(3184324455UL); - p->tcph->th_ack = htonl(3373419621UL); + tcph.th_seq = htonl(3184324455UL); + tcph.th_ack = htonl(3373419621UL); p->payload_len = 4; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(3184324459UL); - p->tcph->th_ack = htonl(3373419633UL); + tcph.th_seq = htonl(3184324459UL); + tcph.th_ack = htonl(3373419633UL); p->payload_len = 2; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1); - p->tcph->th_seq = htonl(3184324459UL); - p->tcph->th_ack = htonl(3373419657UL); + tcph.th_seq = htonl(3184324459UL); + tcph.th_ack = htonl(3373419657UL); p->payload_len = 4; FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1); @@ -2363,31 +2366,31 @@ static int StreamTcpTest25(void) p->flow = &f; tcph.th_win = htons(5480); tcph.th_flags = TH_SYN | TH_CWR; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; StreamTcpUTInit(&stt.ra_ctx); if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(2); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2401,9 +2404,9 @@ static int StreamTcpTest25(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(6); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -2454,7 +2457,7 @@ static int StreamTcpTest26(void) p->flow = &f; tcph.th_win = htons(5480); tcph.th_flags = TH_SYN | TH_ECN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; StreamTcpUTInit(&stt.ra_ctx); @@ -2462,24 +2465,24 @@ static int StreamTcpTest26(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(2); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2493,9 +2496,9 @@ static int StreamTcpTest26(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(6); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -2546,7 +2549,7 @@ static int StreamTcpTest27(void) p->flow = &f; tcph.th_win = htons(5480); tcph.th_flags = TH_SYN | TH_CWR | TH_ECN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; StreamTcpUTInit(&stt.ra_ctx); @@ -2554,24 +2557,24 @@ static int StreamTcpTest27(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(2); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2585,9 +2588,9 @@ static int StreamTcpTest27(void) if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) goto end; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(6); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ @@ -2663,7 +2666,7 @@ static int StreamTcpTest37(void) p->flow = &f; tcph.th_win = htons(5480); tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; StreamTcpUTInit(&stt.ra_ctx); @@ -2673,8 +2676,8 @@ static int StreamTcpTest37(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { @@ -2682,9 +2685,9 @@ static int StreamTcpTest37(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { @@ -2697,9 +2700,9 @@ static int StreamTcpTest37(void) goto end; } - p->tcph->th_ack = htonl(2); - p->tcph->th_seq = htonl(4); - p->tcph->th_flags = TH_ACK | TH_FIN; + tcph.th_ack = htonl(2); + tcph.th_seq = htonl(4); + tcph.th_flags = TH_ACK | TH_FIN; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { @@ -2712,9 +2715,9 @@ static int StreamTcpTest37(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2726,9 +2729,9 @@ static int StreamTcpTest37(void) goto end; } - p->tcph->th_ack = htonl(4); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(4); + tcph.th_seq = htonl(2); + tcph.th_flags = TH_ACK; p->payload_len = 0; p->flowflags = FLOW_PKT_TOCLIENT; @@ -2780,7 +2783,7 @@ static int StreamTcpTest38(void) p->flow = &f; tcph.th_win = htons(5480); tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; StreamTcpUTInit(&stt.ra_ctx); @@ -2789,8 +2792,8 @@ static int StreamTcpTest38(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { @@ -2798,9 +2801,9 @@ static int StreamTcpTest38(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { @@ -2808,9 +2811,9 @@ static int StreamTcpTest38(void) goto end; } - p->tcph->th_ack = htonl(29847); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(29847); + tcph.th_seq = htonl(2); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2830,9 +2833,9 @@ static int StreamTcpTest38(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x41, 127, 128); /*AAA*/ @@ -2850,9 +2853,9 @@ static int StreamTcpTest38(void) goto end; } - p->tcph->th_ack = htonl(256); // in window, but beyond next_seq - p->tcph->th_seq = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(256); // in window, but beyond next_seq + tcph.th_seq = htonl(5); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2872,9 +2875,9 @@ static int StreamTcpTest38(void) goto end; } - p->tcph->th_ack = htonl(128); - p->tcph->th_seq = htonl(8); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(128); + tcph.th_seq = htonl(8); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2933,7 +2936,7 @@ static int StreamTcpTest39(void) p->flow = &f; tcph.th_win = htons(5480); tcph.th_flags = TH_SYN; - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); p->flowflags = FLOW_PKT_TOSERVER; int ret = 0; @@ -2944,8 +2947,8 @@ static int StreamTcpTest39(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { @@ -2953,9 +2956,9 @@ static int StreamTcpTest39(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { @@ -2963,9 +2966,9 @@ static int StreamTcpTest39(void) goto end; } - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(1); + tcph.th_seq = htonl(1); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -2983,9 +2986,9 @@ static int StreamTcpTest39(void) goto end; } - p->tcph->th_ack = htonl(4); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_ack = htonl(4); + tcph.th_seq = htonl(2); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -3005,9 +3008,9 @@ static int StreamTcpTest39(void) goto end; } - p->tcph->th_seq = htonl(4); - p->tcph->th_ack = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; + tcph.th_seq = htonl(4); + tcph.th_ack = htonl(5); + tcph.th_flags = TH_PUSH | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ @@ -3059,7 +3062,7 @@ static int StreamTcpTest42(void) StreamTcpUTInit(&stt.ra_ctx); FLOW_INITIALIZE(&f); - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); tcph.th_win = htons(5480); p->flow = &f; @@ -3072,27 +3075,27 @@ static int StreamTcpTest42(void) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(500); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(1000); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* ACK */ - p->tcph->th_ack = htonl(501); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(501); + tcph.th_seq = htonl(101); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -3146,7 +3149,7 @@ static int StreamTcpTest43(void) StreamTcpUTInit(&stt.ra_ctx); FLOW_INITIALIZE(&f); - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); tcph.th_win = htons(5480); p->flow = &f; @@ -3159,27 +3162,27 @@ static int StreamTcpTest43(void) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(500); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(1000); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* ACK */ - p->tcph->th_ack = htonl(1001); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1001); + tcph.th_seq = htonl(101); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) @@ -3233,7 +3236,7 @@ static int StreamTcpTest44(void) StreamTcpUTInit(&stt.ra_ctx); FLOW_INITIALIZE(&f); - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); tcph.th_win = htons(5480); p->flow = &f; @@ -3246,27 +3249,27 @@ static int StreamTcpTest44(void) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(500); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(1000); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* ACK */ - p->tcph->th_ack = htonl(3001); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(3001); + tcph.th_seq = htonl(101); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) @@ -3317,7 +3320,7 @@ static int StreamTcpTest45(void) stream_config.max_synack_queued = 2; FLOW_INITIALIZE(&f); - p->tcph = &tcph; + UTHSetTCPHdr(p, &tcph); tcph.th_win = htons(5480); p->flow = &f; @@ -3330,45 +3333,45 @@ static int StreamTcpTest45(void) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(500); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(1000); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(2000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(2000); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) goto end; /* SYN/ACK */ - p->tcph->th_seq = htonl(3000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; + tcph.th_seq = htonl(3000); + tcph.th_ack = htonl(101); + tcph.th_flags = TH_SYN | TH_ACK; p->flowflags = FLOW_PKT_TOCLIENT; if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) goto end; /* ACK */ - p->tcph->th_ack = htonl(1001); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; + tcph.th_ack = htonl(1001); + tcph.th_seq = htonl(101); + tcph.th_flags = TH_ACK; p->flowflags = FLOW_PKT_TOSERVER; if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) diff --git a/src/util-checksum.c b/src/util-checksum.c index 33cddbb5a5..ffb626fb7a 100644 --- a/src/util-checksum.c +++ b/src/util-checksum.c @@ -32,9 +32,9 @@ int ReCalculateChecksum(Packet *p) IPV4Hdr *ip4h = p->l3.hdrs.ip4h; if (PacketIsTCP(p)) { /* TCP */ - p->tcph->th_sum = 0; - p->tcph->th_sum = TCPChecksum( - ip4h->s_ip_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); + p->l4.hdrs.tcph->th_sum = 0; + p->l4.hdrs.tcph->th_sum = TCPChecksum(ip4h->s_ip_addrs, (uint16_t *)p->l4.hdrs.tcph, + (p->payload_len + TCP_GET_RAW_HLEN(p->l4.hdrs.tcph)), 0); } else if (PacketIsUDP(p)) { p->l4.hdrs.udph->uh_sum = 0; p->l4.hdrs.udph->uh_sum = UDPV4Checksum(ip4h->s_ip_addrs, (uint16_t *)p->l4.hdrs.udph, @@ -46,9 +46,9 @@ int ReCalculateChecksum(Packet *p) } else if (PacketIsIPv6(p)) { IPV6Hdr *ip6h = p->l3.hdrs.ip6h; if (PacketIsTCP(p)) { - p->tcph->th_sum = 0; - p->tcph->th_sum = TCPV6Checksum( - ip6h->s_ip6_addrs, (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p)), 0); + p->l4.hdrs.tcph->th_sum = 0; + p->l4.hdrs.tcph->th_sum = TCPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->l4.hdrs.tcph, + (p->payload_len + TCP_GET_RAW_HLEN(p->l4.hdrs.tcph)), 0); } else if (PacketIsUDP(p)) { p->l4.hdrs.udph->uh_sum = 0; p->l4.hdrs.udph->uh_sum = UDPV6Checksum(ip6h->s_ip6_addrs, (uint16_t *)p->l4.hdrs.udph, diff --git a/src/util-unittest-helper.c b/src/util-unittest-helper.c index 92c86ee49d..e6331a189f 100644 --- a/src/util-unittest-helper.c +++ b/src/util-unittest-helper.c @@ -133,6 +133,11 @@ void UTHSetIPV6Hdr(Packet *p, IPV6Hdr *ip6h) PacketSetIPV6(p, (uint8_t *)ip6h); } +void UTHSetTCPHdr(Packet *p, TCPHdr *tcph) +{ + PacketSetTCP(p, (uint8_t *)tcph); +} + /** * \brief return the uint32_t for a ipv4 address string * @@ -169,6 +174,7 @@ Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, uint16_t sport, uint16_t dport) { uint32_t in[4]; + TCPHdr *tcph = NULL; Packet *p = PacketGetFromAlloc(); if (unlikely(p == NULL)) @@ -213,12 +219,13 @@ Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, ip6h->s_ip6_dst[2] = in[2]; ip6h->s_ip6_dst[3] = in[3]; - p->tcph = SCMalloc(sizeof(TCPHdr)); - if (p->tcph == NULL) + tcph = SCMalloc(sizeof(TCPHdr)); + if (tcph == NULL) goto error; - memset(p->tcph, 0, sizeof(TCPHdr)); - p->tcph->th_sport = htons(sport); - p->tcph->th_dport = htons(dport); + memset(tcph, 0, sizeof(TCPHdr)); + tcph->th_sport = htons(sport); + tcph->th_dport = htons(dport); + UTHSetTCPHdr(p, tcph); SET_PKT_LEN(p, sizeof(IPV6Hdr) + sizeof(TCPHdr) + payload_len); return p; @@ -228,8 +235,8 @@ error: if (ip6h != NULL) { SCFree(ip6h); } - if (p->tcph != NULL) { - SCFree(p->tcph); + if (tcph != NULL) { + SCFree(tcph); } SCFree(p); } @@ -302,15 +309,16 @@ Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, hdr_offset += sizeof(UDPHdr); break; } - case IPPROTO_TCP: - p->tcph = (TCPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); - if (p->tcph == NULL) + case IPPROTO_TCP: { + TCPHdr *tcph = PacketSetTCP(p, GET_PKT_DATA(p) + sizeof(IPV4Hdr)); + if (tcph == NULL) goto error; - p->tcph->th_sport = htons(sport); - p->tcph->th_dport = htons(dport); + tcph->th_sport = htons(sport); + tcph->th_dport = htons(dport); hdr_offset += sizeof(TCPHdr); break; + } case IPPROTO_ICMP: { ICMPV4Hdr *icmpv4h = PacketSetICMPv4(p, (GET_PKT_DATA(p) + sizeof(IPV4Hdr))); if (icmpv4h == NULL) @@ -937,14 +945,16 @@ static int CheckUTHTestPacket(Packet *p, uint8_t ipproto) return 0; break; } - case IPPROTO_TCP: - if (p->tcph == NULL) + case IPPROTO_TCP: { + const TCPHdr *tcph = PacketGetTCP(p); + if (tcph == NULL) return 0; - if (SCNtohs(p->tcph->th_sport) != sport) + if (SCNtohs(tcph->th_sport) != sport) return 0; - if (SCNtohs(p->tcph->th_dport) != dport) + if (SCNtohs(tcph->th_dport) != dport) return 0; - break; + break; + } } return 1; } diff --git a/src/util-unittest-helper.h b/src/util-unittest-helper.h index 4d288f78aa..d064fe35f9 100644 --- a/src/util-unittest-helper.h +++ b/src/util-unittest-helper.h @@ -38,6 +38,7 @@ int TestHelperBufferToFile(const char *name, const uint8_t *data, size_t size); #ifdef UNITTESTS void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h); void UTHSetIPV6Hdr(Packet *p, IPV6Hdr *ip6h); +void UTHSetTCPHdr(Packet *p, TCPHdr *tcph); uint32_t UTHSetIPv4Address(const char *); diff --git a/src/util-validate.h b/src/util-validate.h index 8e7dc7bb38..cc9eac1041 100644 --- a/src/util-validate.h +++ b/src/util-validate.h @@ -73,7 +73,7 @@ } \ if (!((p)->flags & (PKT_IS_FRAGMENT | PKT_IS_INVALID))) { \ if ((p)->proto == IPPROTO_TCP) { \ - BUG_ON((p)->tcph == NULL); \ + BUG_ON(PacketGetTCP((p)) == NULL); \ } else if ((p)->proto == IPPROTO_UDP) { \ BUG_ON(PacketGetUDP((p)) == NULL); \ } else if ((p)->proto == IPPROTO_ICMP) { \