suricata
decode-tcp.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2024 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \ingroup decode
20 *
21 * @{
22 */
23
24
25/**
26 * \file
27 *
28 * \author Victor Julien <victor@inliniac.net>
29 *
30 * Decode TCP
31 */
32
33#include "suricata-common.h"
34#include "decode-tcp.h"
35#include "decode.h"
36#include "decode-events.h"
37#include "util-unittest.h"
38#include "util-debug.h"
39#include "util-optimize.h"
40#include "flow.h"
41
42static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen)
43{
44 uint8_t tcp_opt_cnt = 0;
45 TCPOpt tcp_opts[TCP_OPTMAX];
46
47 const TCPHdr *tcph = PacketGetTCP(p);
48 uint16_t plen = pktlen;
49 while (plen)
50 {
51 const uint8_t type = *pkt;
52
53 /* single byte options */
54 if (type == TCP_OPT_EOL) {
55 break;
56 } else if (type == TCP_OPT_NOP) {
57 pkt++;
58 plen--;
59
60 /* multibyte options */
61 } else {
62 if (plen < 2) {
63 break;
64 }
65
66 const uint8_t olen = *(pkt+1);
67
68 /* we already know that the total options len is valid,
69 * so here the len of the specific option must be bad.
70 * Also check for invalid lengths 0 and 1. */
71 if (unlikely(olen > plen || olen < 2)) {
73 return;
74 }
75
76 tcp_opts[tcp_opt_cnt].type = type;
77 tcp_opts[tcp_opt_cnt].len = olen;
78 tcp_opts[tcp_opt_cnt].data = (olen > 2) ? (pkt+2) : NULL;
79
80 /* we are parsing the most commonly used opts to prevent
81 * us from having to walk the opts list for these all the
82 * time. */
83 switch (type) {
84 case TCP_OPT_WS:
85 if (olen != TCP_OPT_WS_LEN) {
87 } else {
88 if (p->l4.vars.tcp.wscale_set != 0) {
90 } else {
91 p->l4.vars.tcp.wscale_set = 1;
92 const uint8_t wscale = *(tcp_opts[tcp_opt_cnt].data);
93 if (wscale <= TCP_WSCALE_MAX) {
94 p->l4.vars.tcp.wscale = wscale;
95 } else {
96 p->l4.vars.tcp.wscale = 0;
97 }
98 }
99 }
100 break;
101 case TCP_OPT_MSS:
102 if (olen != TCP_OPT_MSS_LEN) {
104 } else {
105 if (p->l4.vars.tcp.mss_set) {
107 } else {
108 p->l4.vars.tcp.mss_set = true;
109 p->l4.vars.tcp.mss = SCNtohs(*(uint16_t *)(tcp_opts[tcp_opt_cnt].data));
110 }
111 }
112 break;
113 case TCP_OPT_SACKOK:
114 if (olen != TCP_OPT_SACKOK_LEN) {
116 } else {
117 if (TCP_GET_SACKOK(p)) {
119 } else {
120 p->l4.vars.tcp.sack_ok = true;
121 }
122 }
123 break;
124 case TCP_OPT_TS:
125 if (olen != TCP_OPT_TS_LEN) {
127 } else {
128 if (p->l4.vars.tcp.ts_set) {
130 } else {
131 uint32_t values[2];
132 memcpy(&values, tcp_opts[tcp_opt_cnt].data, sizeof(values));
133 p->l4.vars.tcp.ts_val = SCNtohl(values[0]);
134 p->l4.vars.tcp.ts_ecr = SCNtohl(values[1]);
135 p->l4.vars.tcp.ts_set = true;
136 }
137 }
138 break;
139 case TCP_OPT_SACK:
140 SCLogDebug("SACK option, len %u", olen);
141 if (olen == 2) {
142 /* useless, but common empty SACK record */
143 } else if (olen < TCP_OPT_SACK_MIN_LEN || olen > TCP_OPT_SACK_MAX_LEN ||
144 !((olen - 2) % 8 == 0)) {
146 } else {
147 if (p->l4.vars.tcp.sack_set) {
149 } else {
150 ptrdiff_t diff = tcp_opts[tcp_opt_cnt].data - (uint8_t *)tcph;
151 DEBUG_VALIDATE_BUG_ON(diff > UINT16_MAX);
152 p->l4.vars.tcp.sack_set = true;
153 p->l4.vars.tcp.sack_cnt = (olen - 2) / 8;
154 p->l4.vars.tcp.sack_offset = (uint16_t)diff;
155 }
156 }
157 break;
158 case TCP_OPT_TFO:
159 SCLogDebug("TFO option, len %u", olen);
160 if ((olen != 2) && (olen < TCP_OPT_TFO_MIN_LEN || olen > TCP_OPT_TFO_MAX_LEN ||
161 !(((olen - 2) & 0x1) == 0))) {
163 } else {
164 if (p->l4.vars.tcp.tfo_set) {
166 } else {
167 p->l4.vars.tcp.tfo_set = true;
168 }
169 }
170 break;
171 /* experimental options, could be TFO */
172 case TCP_OPT_EXP1:
173 case TCP_OPT_EXP2:
174 SCLogDebug("TCP EXP option, len %u", olen);
175 if (olen == 4 || olen == 12) {
176 uint16_t magic = SCNtohs(*(uint16_t *)tcp_opts[tcp_opt_cnt].data);
177 if (magic == 0xf989) {
178 if (p->l4.vars.tcp.tfo_set) {
180 } else {
181 p->l4.vars.tcp.tfo_set = true;
182 }
183 }
184 } else {
186 }
187 break;
188 /* RFC 2385 MD5 option */
189 case TCP_OPT_MD5:
190 SCLogDebug("MD5 option, len %u", olen);
191 if (olen != 18) {
193 } else {
194 /* we can't validate the option as the key is out of band */
195 p->l4.vars.tcp.md5_option_present = true;
196 }
197 break;
198 /* RFC 5925 AO option */
199 case TCP_OPT_AO:
200 SCLogDebug("AU option, len %u", olen);
201 if (olen < 4) {
203 } else {
204 /* we can't validate the option as the key is out of band */
205 p->l4.vars.tcp.ao_option_present = true;
206 }
207 break;
208 }
209
210 pkt += olen;
211 plen -= olen;
212 tcp_opt_cnt++;
213 }
214 }
215}
216
217static int DecodeTCPPacket(
218 ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
219{
220 if (unlikely(len < TCP_HEADER_LEN)) {
222 return -1;
223 }
224
225 TCPHdr *tcph = PacketSetTCP(p, pkt);
226
227 uint8_t hlen = TCP_GET_RAW_HLEN(tcph);
228 if (unlikely(len < hlen)) {
230 return -1;
231 }
232
233 uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN;
234 if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) {
236 return -1;
237 }
238
239 if (likely(tcp_opt_len > 0)) {
240 DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len);
241 }
242
243 p->sp = TCP_GET_RAW_SRC_PORT(tcph);
244 p->dp = TCP_GET_RAW_DST_PORT(tcph);
245
246 p->proto = IPPROTO_TCP;
247
248 p->payload = (uint8_t *)pkt + hlen;
249 p->payload_len = len - hlen;
250
251 /* update counters */
252 if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
254 } else if (tcph->th_flags & (TH_SYN)) {
256 }
257 if (tcph->th_flags & (TH_RST)) {
259 }
260 if (tcph->th_flags & (TH_URG)) {
262 }
263
264#ifdef DEBUG
265 SCLogDebug("TCP sp: %u -> dp: %u - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s", p->sp,
266 p->dp, TCP_GET_RAW_HLEN(tcph), len, TCP_GET_SACKOK(p) ? "SACKOK " : "",
267 TCP_HAS_SACK(p) ? "SACK " : "", TCP_HAS_WSCALE(p) ? "WS " : "",
268 TCP_HAS_TS(p) ? "TS " : "", TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : "");
269#endif
270 return 0;
271}
272
273int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
274{
276
277 if (unlikely(DecodeTCPPacket(tv, dtv, p, pkt, len) < 0)) {
278 SCLogDebug("invalid TCP packet");
279 PacketClearL4(p);
280 return TM_ECODE_FAILED;
281 }
282
284
285 return TM_ECODE_OK;
286}
287
288#ifdef UNITTESTS
289#include "util-unittest-helper.h"
290#include "packet.h"
291
292static int TCPCalculateValidChecksumtest01(void)
293{
294 uint16_t csum = 0;
295
296 uint8_t raw_ipshdr[] = {
297 0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
298
299 uint8_t raw_tcp[] = {
300 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
301 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
302 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
303 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
304 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02};
305
306 csum = *( ((uint16_t *)raw_tcp) + 8);
307
308 FAIL_IF(TCPChecksum((uint16_t *)raw_ipshdr,
309 (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0);
310 PASS;
311}
312
313static int TCPCalculateInvalidChecksumtest02(void)
314{
315 uint16_t csum = 0;
316
317 uint8_t raw_ipshdr[] = {
318 0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
319
320 uint8_t raw_tcp[] = {
321 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
322 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
323 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
324 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
325 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 03};
326
327 csum = *( ((uint16_t *)raw_tcp) + 8);
328
329 FAIL_IF(TCPChecksum((uint16_t *) raw_ipshdr,
330 (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) == 0);
331 PASS;
332}
333
334static int TCPV6CalculateValidChecksumtest03(void)
335{
336 uint16_t csum = 0;
337
338 static uint8_t raw_ipv6[] = {
339 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
340 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
341 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
342 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
343 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
344 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
345 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
346 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
347 0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
348 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
349 0xca, 0x5a, 0x00, 0x01, 0x69, 0x27};
350
351 csum = *( ((uint16_t *)(raw_ipv6 + 70)));
352
353 FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
354 (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0);
355 PASS;
356}
357
358static int TCPV6CalculateInvalidChecksumtest04(void)
359{
360 uint16_t csum = 0;
361
362 static uint8_t raw_ipv6[] = {
363 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
364 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
365 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
366 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
367 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
368 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
369 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
370 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
371 0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
372 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
373 0xca, 0x5a, 0x00, 0x01, 0x69, 0x28};
374
375 csum = *( ((uint16_t *)(raw_ipv6 + 70)));
376
377 FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
378 (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0);
379 PASS;
380}
381
382/** \test Get the wscale of 2 */
383static int TCPGetWscaleTest01(void)
384{
385 static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
386 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
387 0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
388 0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
389 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
391 FAIL_IF_NULL(p);
392 IPV4Hdr ip4h;
395 memset(&tv, 0, sizeof(ThreadVars));
396 memset(&dtv, 0, sizeof(DecodeThreadVars));
397 memset(&ip4h, 0, sizeof(IPV4Hdr));
398
399 p->src.family = AF_INET;
400 p->dst.family = AF_INET;
401 UTHSetIPV4Hdr(p, &ip4h);
402
404 DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
405 FAIL_IF_NOT(PacketIsTCP(p));
406
407 uint8_t wscale = TCP_GET_WSCALE(p);
408 FAIL_IF(wscale != 2);
409
410 PacketRecycle(p);
411 FlowShutdown();
412 SCFree(p);
413 PASS;
414}
415
416/** \test Get the wscale of 15, so see if return 0 properly */
417static int TCPGetWscaleTest02(void)
418{
419 static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
420 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
421 0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
422 0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
423 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f};
425 FAIL_IF_NULL(p);
426 IPV4Hdr ip4h;
429
430 memset(&tv, 0, sizeof(ThreadVars));
431 memset(&dtv, 0, sizeof(DecodeThreadVars));
432 memset(&ip4h, 0, sizeof(IPV4Hdr));
433
434 p->src.family = AF_INET;
435 p->dst.family = AF_INET;
436 UTHSetIPV4Hdr(p, &ip4h);
437
439 DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
440 FAIL_IF_NOT(PacketIsTCP(p));
441
442 uint8_t wscale = TCP_GET_WSCALE(p);
443 FAIL_IF(wscale != 0);
444
445 PacketRecycle(p);
446 FlowShutdown();
447 SCFree(p);
448 PASS;
449}
450
451/** \test Get the wscale, but it's missing, so see if return 0 properly */
452static int TCPGetWscaleTest03(void)
453{
454 static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59,
455 0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4,
456 0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
457 0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00};
459 FAIL_IF_NULL(p);
460 IPV4Hdr ip4h;
463 memset(&tv, 0, sizeof(ThreadVars));
464 memset(&dtv, 0, sizeof(DecodeThreadVars));
465 memset(&ip4h, 0, sizeof(IPV4Hdr));
466
467 p->src.family = AF_INET;
468 p->dst.family = AF_INET;
469 UTHSetIPV4Hdr(p, &ip4h);
470
472 DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
473 FAIL_IF_NOT(PacketIsTCP(p));
474
475 uint8_t wscale = TCP_GET_WSCALE(p);
476 FAIL_IF(wscale != 0);
477
478 PacketRecycle(p);
479 FlowShutdown();
480 SCFree(p);
481 PASS;
482}
483
484static int TCPGetSackTest01(void)
485{
486 static uint8_t raw_tcp[] = {
487 0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
488 0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
489 0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
490 0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
491 0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
492 static uint8_t raw_tcp_sack[] = {
493 0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
494 0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
496 FAIL_IF_NULL(p);
497
498 IPV4Hdr ip4h;
501 memset(&tv, 0, sizeof(ThreadVars));
502 memset(&dtv, 0, sizeof(DecodeThreadVars));
503 memset(&ip4h, 0, sizeof(IPV4Hdr));
504
505 p->src.family = AF_INET;
506 p->dst.family = AF_INET;
507 UTHSetIPV4Hdr(p, &ip4h);
508
510 DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
511
512 FAIL_IF_NOT(PacketIsTCP(p));
513
515
516 int sack = TCP_GET_SACK_CNT(p);
517 FAIL_IF(sack != 2);
518
519 const TCPHdr *tcph = PacketGetTCP(p);
520 const uint8_t *sackptr = TCP_GET_SACK_PTR(p, tcph);
521 FAIL_IF_NULL(sackptr);
522
523 FAIL_IF(memcmp(sackptr, raw_tcp_sack, 16) != 0);
524
525 PacketRecycle(p);
526 FlowShutdown();
527 SCFree(p);
528 PASS;
529}
530#endif /* UNITTESTS */
531
533{
534#ifdef UNITTESTS
535 UtRegisterTest("TCPCalculateValidChecksumtest01",
536 TCPCalculateValidChecksumtest01);
537 UtRegisterTest("TCPCalculateInvalidChecksumtest02",
538 TCPCalculateInvalidChecksumtest02);
539 UtRegisterTest("TCPV6CalculateValidChecksumtest03",
540 TCPV6CalculateValidChecksumtest03);
541 UtRegisterTest("TCPV6CalculateInvalidChecksumtest04",
542 TCPV6CalculateInvalidChecksumtest04);
543 UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01);
544 UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02);
545 UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03);
546 UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01);
547#endif /* UNITTESTS */
548}
549/**
550 * @}
551 */
uint8_t len
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition counters.c:166
@ TCP_OPT_INVALID_LEN
@ TCP_PKT_TOO_SMALL
@ TCP_OPT_DUPLICATE
@ TCP_INVALID_OPTLEN
@ TCP_HLEN_TOO_SMALL
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition decode-tcp.c:273
void DecodeTCPRegisterTests(void)
Definition decode-tcp.c:532
#define TCP_OPT_TS
Definition decode-tcp.h:52
#define TCP_OPT_WS
Definition decode-tcp.h:49
#define TCP_OPT_MSS_LEN
Definition decode-tcp.h:62
#define TCP_OPT_SACKOK_LEN
Definition decode-tcp.h:59
#define TCP_OPT_EXP2
Definition decode-tcp.h:55
#define TCP_OPT_EOL
Definition decode-tcp.h:46
#define TCP_HAS_SACK(p)
Definition decode-tcp.h:94
#define TCP_OPT_TS_LEN
Definition decode-tcp.h:61
#define TCP_OPT_MD5
Definition decode-tcp.h:56
#define TCP_HAS_MSS(p)
Definition decode-tcp.h:96
#define TCP_OPT_EXP1
Definition decode-tcp.h:54
#define TCP_OPT_TFO
Definition decode-tcp.h:53
#define TH_ACK
Definition decode-tcp.h:38
#define TCP_GET_RAW_DST_PORT(tcph)
Definition decode-tcp.h:75
#define TCP_WSCALE_MAX
Definition decode-tcp.h:69
#define TCP_GET_SACK_PTR(p, tcph)
Definition decode-tcp.h:103
#define TCP_OPT_TFO_MAX_LEN
Definition decode-tcp.h:66
#define TCP_OPT_MSS
Definition decode-tcp.h:48
#define TCP_GET_SACK_CNT(p)
Definition decode-tcp.h:104
#define TCP_GET_RAW_SRC_PORT(tcph)
Definition decode-tcp.h:74
#define TCP_HEADER_LEN
Definition decode-tcp.h:28
#define TCP_OPT_AO
Definition decode-tcp.h:57
#define TH_URG
Definition decode-tcp.h:39
#define TCP_HAS_TS(p)
Definition decode-tcp.h:95
#define TH_RST
Definition decode-tcp.h:36
#define TCP_GET_SACKOK(p)
Definition decode-tcp.h:102
#define TCP_OPT_SACK_MAX_LEN
Definition decode-tcp.h:64
#define TH_SYN
Definition decode-tcp.h:35
#define TCP_OPTMAX
Definition decode-tcp.h:30
#define TCP_GET_WSCALE(p)
Definition decode-tcp.h:100
#define TCP_OPT_WS_LEN
Definition decode-tcp.h:60
#define TCP_OPTLENMAX
Definition decode-tcp.h:29
#define TCP_HAS_WSCALE(p)
Definition decode-tcp.h:93
#define TCP_OPT_NOP
Definition decode-tcp.h:47
#define TCP_OPT_SACK
Definition decode-tcp.h:51
#define TCP_OPT_SACKOK
Definition decode-tcp.h:50
#define TCP_HAS_TFO(p)
Definition decode-tcp.h:97
#define TCP_GET_RAW_HLEN(tcph)
Definition decode-tcp.h:72
uint16_t type
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition decode.h:1194
#define ENGINE_SET_EVENT(p, e)
Definition decode.h:1186
void FlowSetupPacket(Packet *p)
prepare packet for a life with flow Set PKT_WANTS_FLOW flag to indicate workers should do a flow look...
Definition flow-hash.c:533
void FlowInitConfig(bool quiet)
initialize the configuration
Definition flow.c:547
void FlowShutdown(void)
shutdown the flow engine
Definition flow.c:691
#define FLOW_QUIET
Definition flow.h:43
DecodeThreadVars * dtv
ThreadVars * tv
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition decode.c:258
void PacketRecycle(Packet *p)
Definition packet.c:150
char family
Definition decode.h:113
Structure to hold thread specific data for all decode modules.
Definition decode.h:963
uint16_t counter_tcp
Definition decode.h:981
uint16_t counter_tcp_syn
Definition decode.h:982
uint16_t counter_tcp_synack
Definition decode.h:983
uint16_t counter_tcp_urg
Definition decode.h:985
uint16_t counter_tcp_rst
Definition decode.h:984
union PacketL4::L4Vars vars
struct PacketL4 l4
Definition decode.h:601
Address src
Definition decode.h:505
Port sp
Definition decode.h:508
uint8_t * payload
Definition decode.h:605
uint16_t payload_len
Definition decode.h:606
Address dst
Definition decode.h:506
uint8_t proto
Definition decode.h:523
Port dp
Definition decode.h:516
uint8_t th_flags
Definition decode-tcp.h:155
const uint8_t * data
Definition decode-tcp.h:140
uint8_t type
Definition decode-tcp.h:138
uint8_t len
Definition decode-tcp.h:139
uint16_t sack_offset
Definition decode-tcp.h:178
uint32_t ts_val
Definition decode-tcp.h:176
uint8_t sack_cnt
Definition decode-tcp.h:173
uint8_t sack_ok
Definition decode-tcp.h:167
uint8_t mss_set
Definition decode-tcp.h:168
uint8_t tfo_set
Definition decode-tcp.h:169
uint8_t wscale_set
Definition decode-tcp.h:170
uint32_t ts_ecr
Definition decode-tcp.h:177
uint8_t wscale
Definition decode-tcp.h:172
uint8_t md5_option_present
Definition decode-tcp.h:164
uint8_t sack_set
Definition decode-tcp.h:171
uint16_t mss
Definition decode-tcp.h:174
uint8_t ts_set
Definition decode-tcp.h:166
uint8_t ao_option_present
Definition decode-tcp.h:165
Per thread variable structure.
Definition threadvars.h:58
#define SCNtohs(x)
#define SCNtohl(x)
@ TM_ECODE_FAILED
@ TM_ECODE_OK
TCPVars tcp
Definition decode.h:478
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCFree(p)
Definition util-mem.h:61
#define likely(expr)
#define unlikely(expr)
void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h)
#define DEBUG_VALIDATE_BUG_ON(exp)