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