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-debug.h"
38 #include "flow.h"
39 
40 static inline uint16_t DecodeTCPGetU16(const uint8_t *d)
41 {
42  return (uint16_t)(((uint16_t)d[0] << 8) | (uint16_t)d[1]);
43 }
44 
45 static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen)
46 {
47  uint8_t tcp_opt_cnt = 0;
48  TCPOpt tcp_opts[TCP_OPTMAX];
49 
50  const TCPHdr *tcph = PacketGetTCP(p);
51  uint16_t plen = pktlen;
52  while (plen)
53  {
54  const uint8_t type = *pkt;
55 
56  /* single byte options */
57  if (type == TCP_OPT_EOL) {
58  break;
59  } else if (type == TCP_OPT_NOP) {
60  pkt++;
61  plen--;
62 
63  /* multibyte options */
64  } else {
65  if (plen < 2) {
66  break;
67  }
68 
69  const uint8_t olen = *(pkt+1);
70 
71  /* we already know that the total options len is valid,
72  * so here the len of the specific option must be bad.
73  * Also check for invalid lengths 0 and 1. */
74  if (unlikely(olen > plen || olen < 2)) {
76  return;
77  }
78 
79  tcp_opts[tcp_opt_cnt].type = type;
80  tcp_opts[tcp_opt_cnt].len = olen;
81 
82  /* we are parsing the most commonly used opts to prevent
83  * us from having to walk the opts list for these all the
84  * time. */
85  switch (type) {
86  case TCP_OPT_WS:
87  if (olen != TCP_OPT_WS_LEN) {
89  } else {
90  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
91  if (p->l4.vars.tcp.wscale_set != 0) {
93  } else {
94  p->l4.vars.tcp.wscale_set = 1;
95  const uint8_t wscale = *(tcp_opts[tcp_opt_cnt].data);
96  if (wscale <= TCP_WSCALE_MAX) {
97  p->l4.vars.tcp.wscale = wscale;
98  } else {
99  p->l4.vars.tcp.wscale = 0;
100  }
101  }
102  }
103  break;
104  case TCP_OPT_MSS:
105  if (olen != TCP_OPT_MSS_LEN) {
107  } else {
108  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
109  if (p->l4.vars.tcp.mss_set) {
111  } else {
112  p->l4.vars.tcp.mss_set = true;
113  p->l4.vars.tcp.mss = DecodeTCPGetU16(tcp_opts[tcp_opt_cnt].data);
114  }
115  }
116  break;
117  case TCP_OPT_SACKOK:
118  if (olen != TCP_OPT_SACKOK_LEN) {
120  } else {
121  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
122  if (TCP_GET_SACKOK(p)) {
124  } else {
125  p->l4.vars.tcp.sack_ok = true;
126  }
127  }
128  break;
129  case TCP_OPT_TS:
130  if (olen != TCP_OPT_TS_LEN) {
132  } else {
133  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
134  if (p->l4.vars.tcp.ts_set) {
136  } else {
137  uint32_t values[2];
138  memcpy(&values, tcp_opts[tcp_opt_cnt].data, sizeof(values));
139  p->l4.vars.tcp.ts_val = SCNtohl(values[0]);
140  p->l4.vars.tcp.ts_ecr = SCNtohl(values[1]);
141  p->l4.vars.tcp.ts_set = true;
142  }
143  }
144  break;
145  case TCP_OPT_SACK:
146  SCLogDebug("SACK option, len %u", olen);
147  if (olen == 2) {
148  /* useless, but common empty SACK record */
149  } else if (olen < TCP_OPT_SACK_MIN_LEN || olen > TCP_OPT_SACK_MAX_LEN ||
150  !((olen - 2) % 8 == 0)) {
152  } else {
153  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
154  if (p->l4.vars.tcp.sack_set) {
156  } else {
157  ptrdiff_t diff = tcp_opts[tcp_opt_cnt].data - (uint8_t *)tcph;
158  DEBUG_VALIDATE_BUG_ON(diff > UINT16_MAX);
159  p->l4.vars.tcp.sack_set = true;
160  p->l4.vars.tcp.sack_cnt = (olen - 2) / 8;
161  p->l4.vars.tcp.sack_offset = (uint16_t)diff;
162  }
163  }
164  break;
165  case TCP_OPT_TFO:
166  SCLogDebug("TFO option, len %u", olen);
167  if ((olen != 2) && (olen < TCP_OPT_TFO_MIN_LEN || olen > TCP_OPT_TFO_MAX_LEN ||
168  !(((olen - 2) & 0x1) == 0))) {
170  } else {
171  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
172  if (p->l4.vars.tcp.tfo_set) {
174  } else {
175  p->l4.vars.tcp.tfo_set = true;
176  }
177  }
178  break;
179  /* experimental options, could be TFO */
180  case TCP_OPT_EXP1:
181  case TCP_OPT_EXP2:
182  SCLogDebug("TCP EXP option, len %u", olen);
183  if (olen == 4 || olen == 12) {
184  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
185  uint16_t magic = DecodeTCPGetU16(tcp_opts[tcp_opt_cnt].data);
186  if (magic == 0xf989) {
187  if (p->l4.vars.tcp.tfo_set) {
189  } else {
190  p->l4.vars.tcp.tfo_set = true;
191  }
192  }
193  } else {
195  }
196  break;
197  /* RFC 2385 MD5 option */
198  case TCP_OPT_MD5:
199  SCLogDebug("MD5 option, len %u", olen);
200  if (olen != 18) {
202  } else {
203  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
204  /* we can't validate the option as the key is out of band */
205  p->l4.vars.tcp.md5_option_present = true;
206  }
207  break;
208  /* RFC 5925 AO option */
209  case TCP_OPT_AO:
210  SCLogDebug("AU option, len %u", olen);
211  if (olen < 4) {
213  } else {
214  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
215  /* we can't validate the option as the key is out of band */
216  p->l4.vars.tcp.ao_option_present = true;
217  }
218  break;
219  default:
220  if (olen > 2) {
221  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
222  } else {
223 
224  tcp_opts[tcp_opt_cnt].data = NULL;
225  }
226  }
227 
228  pkt += olen;
229  plen -= olen;
230  tcp_opt_cnt++;
231  }
232  }
233 }
234 
235 static int DecodeTCPPacket(
236  ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
237 {
238  if (unlikely(len < TCP_HEADER_LEN)) {
240  return -1;
241  }
242 
243  TCPHdr *tcph = PacketSetTCP(p, pkt);
244 
245  uint8_t hlen = TCP_GET_RAW_HLEN(tcph);
246  if (unlikely(len < hlen)) {
248  return -1;
249  }
250 
251  uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN;
252  if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) {
254  return -1;
255  }
256 
257  if (likely(tcp_opt_len > 0)) {
258  DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len);
259  }
260 
261  p->sp = TCP_GET_RAW_SRC_PORT(tcph);
262  p->dp = TCP_GET_RAW_DST_PORT(tcph);
263 
264  p->proto = IPPROTO_TCP;
265 
266  p->payload = (uint8_t *)pkt + hlen;
267  p->payload_len = len - hlen;
268 
269  /* update counters */
270  if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
272  } else if (tcph->th_flags & (TH_SYN)) {
274  }
275  if (tcph->th_flags & (TH_RST)) {
277  }
278  if (tcph->th_flags & (TH_URG)) {
280  }
281 
282 #ifdef DEBUG
283  SCLogDebug("TCP sp: %u -> dp: %u - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s", p->sp,
284  p->dp, TCP_GET_RAW_HLEN(tcph), len, TCP_GET_SACKOK(p) ? "SACKOK " : "",
285  TCP_HAS_SACK(p) ? "SACK " : "", TCP_HAS_WSCALE(p) ? "WS " : "",
286  TCP_HAS_TS(p) ? "TS " : "", TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : "");
287 #endif
288  return 0;
289 }
290 
291 int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
292 {
294 
295  if (unlikely(DecodeTCPPacket(tv, dtv, p, pkt, len) < 0)) {
296  SCLogDebug("invalid TCP packet");
297  PacketClearL4(p);
298  return TM_ECODE_FAILED;
299  }
300 
302 
303  return TM_ECODE_OK;
304 }
305 
306 #ifdef UNITTESTS
307 #include "util-unittest-helper.h"
308 #include "packet.h"
309 
310 static int TCPCalculateValidChecksumtest01(void)
311 {
312  uint16_t csum = 0;
313 
314  uint8_t raw_ipshdr[] = {
315  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
316 
317  uint8_t raw_tcp[] = {
318  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
319  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
320  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
321  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
322  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02};
323 
324  csum = *( ((uint16_t *)raw_tcp) + 8);
325 
326  FAIL_IF(TCPChecksum((uint16_t *)raw_ipshdr,
327  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0);
328  PASS;
329 }
330 
331 static int TCPCalculateInvalidChecksumtest02(void)
332 {
333  uint16_t csum = 0;
334 
335  uint8_t raw_ipshdr[] = {
336  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
337 
338  uint8_t raw_tcp[] = {
339  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
340  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
341  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
342  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
343  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 03};
344 
345  csum = *( ((uint16_t *)raw_tcp) + 8);
346 
347  FAIL_IF(TCPChecksum((uint16_t *) raw_ipshdr,
348  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) == 0);
349  PASS;
350 }
351 
352 static int TCPV6CalculateValidChecksumtest03(void)
353 {
354  uint16_t csum = 0;
355 
356  static uint8_t raw_ipv6[] = {
357  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
358  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
359  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
360  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
361  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
362  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
363  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
364  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
365  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
366  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
367  0xca, 0x5a, 0x00, 0x01, 0x69, 0x27};
368 
369  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
370 
371  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
372  (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0);
373  PASS;
374 }
375 
376 static int TCPV6CalculateInvalidChecksumtest04(void)
377 {
378  uint16_t csum = 0;
379 
380  static uint8_t raw_ipv6[] = {
381  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
382  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
383  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
384  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
385  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
386  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
387  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
388  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
389  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
390  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
391  0xca, 0x5a, 0x00, 0x01, 0x69, 0x28};
392 
393  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
394 
395  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
396  (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0);
397  PASS;
398 }
399 
400 /** \test Get the wscale of 2 */
401 static int TCPGetWscaleTest01(void)
402 {
403  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
404  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
405  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
406  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
407  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
409  FAIL_IF_NULL(p);
410  IPV4Hdr ip4h;
411  ThreadVars tv;
413  memset(&tv, 0, sizeof(ThreadVars));
414  memset(&dtv, 0, sizeof(DecodeThreadVars));
415  memset(&ip4h, 0, sizeof(IPV4Hdr));
416 
417  p->src.family = AF_INET;
418  p->dst.family = AF_INET;
419  UTHSetIPV4Hdr(p, &ip4h);
420 
422  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
423  FAIL_IF_NOT(PacketIsTCP(p));
424 
425  uint8_t wscale = TCP_GET_WSCALE(p);
426  FAIL_IF(wscale != 2);
427 
428  PacketFree(p);
429  FlowShutdown();
430  PASS;
431 }
432 
433 /** \test Get the wscale of 15, so see if return 0 properly */
434 static int TCPGetWscaleTest02(void)
435 {
436  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
437  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
438  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
439  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
440  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f};
442  FAIL_IF_NULL(p);
443  IPV4Hdr ip4h;
444  ThreadVars tv;
446 
447  memset(&tv, 0, sizeof(ThreadVars));
448  memset(&dtv, 0, sizeof(DecodeThreadVars));
449  memset(&ip4h, 0, sizeof(IPV4Hdr));
450 
451  p->src.family = AF_INET;
452  p->dst.family = AF_INET;
453  UTHSetIPV4Hdr(p, &ip4h);
454 
456  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
457  FAIL_IF_NOT(PacketIsTCP(p));
458 
459  uint8_t wscale = TCP_GET_WSCALE(p);
460  FAIL_IF(wscale != 0);
461 
462  PacketFree(p);
463  FlowShutdown();
464  PASS;
465 }
466 
467 /** \test Get the wscale, but it's missing, so see if return 0 properly */
468 static int TCPGetWscaleTest03(void)
469 {
470  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59,
471  0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4,
472  0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
473  0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00};
475  FAIL_IF_NULL(p);
476  IPV4Hdr ip4h;
477  ThreadVars tv;
479  memset(&tv, 0, sizeof(ThreadVars));
480  memset(&dtv, 0, sizeof(DecodeThreadVars));
481  memset(&ip4h, 0, sizeof(IPV4Hdr));
482 
483  p->src.family = AF_INET;
484  p->dst.family = AF_INET;
485  UTHSetIPV4Hdr(p, &ip4h);
486 
488  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
489  FAIL_IF_NOT(PacketIsTCP(p));
490 
491  uint8_t wscale = TCP_GET_WSCALE(p);
492  FAIL_IF(wscale != 0);
493 
494  PacketFree(p);
495  FlowShutdown();
496  PASS;
497 }
498 
499 static int TCPGetSackTest01(void)
500 {
501  static uint8_t raw_tcp[] = {
502  0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
503  0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
504  0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
505  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
506  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
507  static uint8_t raw_tcp_sack[] = {
508  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
509  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
511  FAIL_IF_NULL(p);
512 
513  IPV4Hdr ip4h;
514  ThreadVars tv;
516  memset(&tv, 0, sizeof(ThreadVars));
517  memset(&dtv, 0, sizeof(DecodeThreadVars));
518  memset(&ip4h, 0, sizeof(IPV4Hdr));
519 
520  p->src.family = AF_INET;
521  p->dst.family = AF_INET;
522  UTHSetIPV4Hdr(p, &ip4h);
523 
525  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
526 
527  FAIL_IF_NOT(PacketIsTCP(p));
528 
530 
531  int sack = TCP_GET_SACK_CNT(p);
532  FAIL_IF(sack != 2);
533 
534  const TCPHdr *tcph = PacketGetTCP(p);
535  const uint8_t *sackptr = TCP_GET_SACK_PTR(p, tcph);
536  FAIL_IF_NULL(sackptr);
537 
538  FAIL_IF(memcmp(sackptr, raw_tcp_sack, 16) != 0);
539 
540  PacketFree(p);
541  FlowShutdown();
542  PASS;
543 }
544 #endif /* UNITTESTS */
545 
547 {
548 #ifdef UNITTESTS
549  UtRegisterTest("TCPCalculateValidChecksumtest01",
550  TCPCalculateValidChecksumtest01);
551  UtRegisterTest("TCPCalculateInvalidChecksumtest02",
552  TCPCalculateInvalidChecksumtest02);
553  UtRegisterTest("TCPV6CalculateValidChecksumtest03",
554  TCPV6CalculateValidChecksumtest03);
555  UtRegisterTest("TCPV6CalculateInvalidChecksumtest04",
556  TCPV6CalculateInvalidChecksumtest04);
557  UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01);
558  UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02);
559  UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03);
560  UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01);
561 #endif /* UNITTESTS */
562 }
563 /**
564  * @}
565  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1231
decode-tcp.h
TCPVars_::ao_option_present
uint8_t ao_option_present
Definition: decode-tcp.h:165
Packet_::proto
uint8_t proto
Definition: decode.h:538
len
uint8_t len
Definition: app-layer-dnp3.h:2
TCPOpt_
Definition: decode-tcp.h:137
TCP_OPT_WS_LEN
#define TCP_OPT_WS_LEN
Definition: decode-tcp.h:60
TCP_OPT_MD5
#define TCP_OPT_MD5
Definition: decode-tcp.h:56
TCP_OPT_SACKOK
#define TCP_OPT_SACKOK
Definition: decode-tcp.h:50
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
TCPVars_::mss_set
uint8_t mss_set
Definition: decode-tcp.h:168
TCP_HAS_TFO
#define TCP_HAS_TFO(p)
Definition: decode-tcp.h:97
TCPVars_::ts_set
uint8_t ts_set
Definition: decode-tcp.h:166
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
TCP_OPT_DUPLICATE
@ TCP_OPT_DUPLICATE
Definition: decode-events.h:104
TCP_HEADER_LEN
#define TCP_HEADER_LEN
Definition: decode-tcp.h:28
Packet_::payload
uint8_t * payload
Definition: decode.h:620
type
uint8_t type
Definition: decode-sctp.h:0
TH_RST
#define TH_RST
Definition: decode-tcp.h:36
TCP_WSCALE_MAX
#define TCP_WSCALE_MAX
Definition: decode-tcp.h:69
UTHSetIPV4Hdr
void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h)
Definition: util-unittest-helper.c:251
TCP_OPT_SACKOK_LEN
#define TCP_OPT_SACKOK_LEN
Definition: decode-tcp.h:59
TCP_GET_RAW_HLEN
#define TCP_GET_RAW_HLEN(tcph)
Definition: decode-tcp.h:72
DecodeThreadVars_::counter_tcp_syn
StatsCounterId counter_tcp_syn
Definition: decode.h:1014
TCP_OPT_EXP2
#define TCP_OPT_EXP2
Definition: decode-tcp.h:55
TCP_HAS_MSS
#define TCP_HAS_MSS(p)
Definition: decode-tcp.h:96
TCPVars_::sack_ok
uint8_t sack_ok
Definition: decode-tcp.h:167
p
Packet * p
Definition: fuzz_dataset.c:30
TCP_GET_SACKOK
#define TCP_GET_SACKOK(p)
Definition: decode-tcp.h:102
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:621
TCP_OPT_EOL
#define TCP_OPT_EOL
Definition: decode-tcp.h:46
TCPOpt_::data
const uint8_t * data
Definition: decode-tcp.h:140
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DecodeThreadVars_::counter_tcp
StatsCounterId counter_tcp
Definition: decode.h:1013
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
TCP_GET_WSCALE
#define TCP_GET_WSCALE(p)
Definition: decode-tcp.h:100
TCP_INVALID_OPTLEN
@ TCP_INVALID_OPTLEN
Definition: decode-events.h:100
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:574
TCPHdr_::th_flags
uint8_t th_flags
Definition: decode-tcp.h:155
decode.h
TCPVars_::ts_ecr
uint32_t ts_ecr
Definition: decode-tcp.h:177
TCPOpt_::type
uint8_t type
Definition: decode-tcp.h:138
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
TCP_OPT_MSS
#define TCP_OPT_MSS
Definition: decode-tcp.h:48
TCP_OPT_WS
#define TCP_OPT_WS
Definition: decode-tcp.h:49
TCPVars_::sack_offset
uint16_t sack_offset
Definition: decode-tcp.h:178
TCP_OPT_SACK_MAX_LEN
#define TCP_OPT_SACK_MAX_LEN
Definition: decode-tcp.h:64
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
PacketL4::L4Vars::tcp
TCPVars tcp
Definition: decode.h:491
Packet_::sp
Port sp
Definition: decode.h:523
TCP_GET_RAW_SRC_PORT
#define TCP_GET_RAW_SRC_PORT(tcph)
Definition: decode-tcp.h:74
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:163
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:221
DecodeThreadVars_::counter_tcp_urg
StatsCounterId counter_tcp_urg
Definition: decode.h:1017
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
Packet_
Definition: decode.h:516
TCP_GET_SACK_CNT
#define TCP_GET_SACK_CNT(p)
Definition: decode-tcp.h:104
Packet_::l4
struct PacketL4 l4
Definition: decode.h:616
TCP_HAS_SACK
#define TCP_HAS_SACK(p)
Definition: decode-tcp.h:94
TCP_OPT_NOP
#define TCP_OPT_NOP
Definition: decode-tcp.h:47
TCP_HAS_TS
#define TCP_HAS_TS(p)
Definition: decode-tcp.h:95
TCPOpt_::len
uint8_t len
Definition: decode-tcp.h:139
TCP_GET_SACK_PTR
#define TCP_GET_SACK_PTR(p, tcph)
Definition: decode-tcp.h:103
DecodeTCPRegisterTests
void DecodeTCPRegisterTests(void)
Definition: decode-tcp.c:546
DecodeThreadVars_::counter_tcp_rst
StatsCounterId counter_tcp_rst
Definition: decode.h:1016
TCPVars_::tfo_set
uint8_t tfo_set
Definition: decode-tcp.h:169
TH_URG
#define TH_URG
Definition: decode-tcp.h:39
TCPVars_::wscale
uint8_t wscale
Definition: decode-tcp.h:172
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:35
DecodeTCP
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-tcp.c:291
IPV4Hdr_
Definition: decode-ipv4.h:72
TCP_OPT_EXP1
#define TCP_OPT_EXP1
Definition: decode-tcp.h:54
TCPVars_::ts_val
uint32_t ts_val
Definition: decode-tcp.h:176
TCP_HLEN_TOO_SMALL
@ TCP_HLEN_TOO_SMALL
Definition: decode-events.h:99
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
TH_SYN
#define TH_SYN
Definition: decode-tcp.h:35
suricata-common.h
DecodeThreadVars_::counter_tcp_synack
StatsCounterId counter_tcp_synack
Definition: decode.h:1015
TCP_OPTMAX
#define TCP_OPTMAX
Definition: decode-tcp.h:30
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:718
packet.h
TCPVars_::md5_option_present
uint8_t md5_option_present
Definition: decode-tcp.h:164
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
TCP_OPT_SACK
#define TCP_OPT_SACK
Definition: decode-tcp.h:51
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:260
TCP_OPT_INVALID_LEN
@ TCP_OPT_INVALID_LEN
Definition: decode-events.h:103
TCP_GET_RAW_DST_PORT
#define TCP_GET_RAW_DST_PORT(tcph)
Definition: decode-tcp.h:75
SCNtohl
#define SCNtohl(x)
Definition: suricata-common.h:435
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:995
TCP_OPTLENMAX
#define TCP_OPTLENMAX
Definition: decode-tcp.h:29
Address_::family
char family
Definition: decode.h:114
Packet_::dst
Address dst
Definition: decode.h:521
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1239
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
TCP_HAS_WSCALE
#define TCP_HAS_WSCALE(p)
Definition: decode-tcp.h:93
TCP_OPT_AO
#define TCP_OPT_AO
Definition: decode-tcp.h:57
likely
#define likely(expr)
Definition: util-optimize.h:32
TCPVars_::sack_cnt
uint8_t sack_cnt
Definition: decode-tcp.h:173
TCP_OPT_MSS_LEN
#define TCP_OPT_MSS_LEN
Definition: decode-tcp.h:62
TCP_OPT_TFO_MAX_LEN
#define TCP_OPT_TFO_MAX_LEN
Definition: decode-tcp.h:66
flow.h
Packet_::dp
Port dp
Definition: decode.h:531
TCP_OPT_TS_LEN
#define TCP_OPT_TS_LEN
Definition: decode-tcp.h:61
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:120
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
FlowSetupPacket
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:531
TCPHdr_
Definition: decode-tcp.h:149
Packet_::src
Address src
Definition: decode.h:520
TCPVars_::sack_set
uint8_t sack_set
Definition: decode-tcp.h:171
PacketL4::vars
union PacketL4::L4Vars vars
TCP_PKT_TOO_SMALL
@ TCP_PKT_TOO_SMALL
Definition: decode-events.h:98
TCP_OPT_TFO
#define TCP_OPT_TFO
Definition: decode-tcp.h:53
TCPVars_::mss
uint16_t mss
Definition: decode-tcp.h:174
TCP_OPT_TS
#define TCP_OPT_TS
Definition: decode-tcp.h:52
TCPVars_::wscale_set
uint8_t wscale_set
Definition: decode-tcp.h:170