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 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 
217 static 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 
261 #ifdef DEBUG
262  SCLogDebug("TCP sp: %u -> dp: %u - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s", p->sp,
263  p->dp, TCP_GET_RAW_HLEN(tcph), len, TCP_GET_SACKOK(p) ? "SACKOK " : "",
264  TCP_HAS_SACK(p) ? "SACK " : "", TCP_HAS_WSCALE(p) ? "WS " : "",
265  TCP_HAS_TS(p) ? "TS " : "", TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : "");
266 #endif
267  return 0;
268 }
269 
270 int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
271 {
273 
274  if (unlikely(DecodeTCPPacket(tv, dtv, p, pkt, len) < 0)) {
275  SCLogDebug("invalid TCP packet");
276  PacketClearL4(p);
277  return TM_ECODE_FAILED;
278  }
279 
280  FlowSetupPacket(p);
281 
282  return TM_ECODE_OK;
283 }
284 
285 #ifdef UNITTESTS
286 #include "util-unittest-helper.h"
287 #include "packet.h"
288 
289 static int TCPCalculateValidChecksumtest01(void)
290 {
291  uint16_t csum = 0;
292 
293  uint8_t raw_ipshdr[] = {
294  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
295 
296  uint8_t raw_tcp[] = {
297  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
298  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
299  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
300  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
301  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02};
302 
303  csum = *( ((uint16_t *)raw_tcp) + 8);
304 
305  FAIL_IF(TCPChecksum((uint16_t *)raw_ipshdr,
306  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0);
307  PASS;
308 }
309 
310 static int TCPCalculateInvalidChecksumtest02(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, 03};
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 TCPV6CalculateValidChecksumtest03(void)
332 {
333  uint16_t csum = 0;
334 
335  static uint8_t raw_ipv6[] = {
336  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
337  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
338  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
339  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
340  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
341  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
342  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
343  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
344  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
345  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
346  0xca, 0x5a, 0x00, 0x01, 0x69, 0x27};
347 
348  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
349 
350  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
351  (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0);
352  PASS;
353 }
354 
355 static int TCPV6CalculateInvalidChecksumtest04(void)
356 {
357  uint16_t csum = 0;
358 
359  static uint8_t raw_ipv6[] = {
360  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
361  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
362  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
363  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
364  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
365  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
366  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
367  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
368  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
369  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
370  0xca, 0x5a, 0x00, 0x01, 0x69, 0x28};
371 
372  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
373 
374  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
375  (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0);
376  PASS;
377 }
378 
379 /** \test Get the wscale of 2 */
380 static int TCPGetWscaleTest01(void)
381 {
382  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
383  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
384  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
385  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
386  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
387  Packet *p = PacketGetFromAlloc();
388  FAIL_IF_NULL(p);
389  IPV4Hdr ip4h;
390  ThreadVars tv;
392  memset(&tv, 0, sizeof(ThreadVars));
393  memset(&dtv, 0, sizeof(DecodeThreadVars));
394  memset(&ip4h, 0, sizeof(IPV4Hdr));
395 
396  p->src.family = AF_INET;
397  p->dst.family = AF_INET;
398  UTHSetIPV4Hdr(p, &ip4h);
399 
401  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
402  FAIL_IF_NOT(PacketIsTCP(p));
403 
404  uint8_t wscale = TCP_GET_WSCALE(p);
405  FAIL_IF(wscale != 2);
406 
407  PacketRecycle(p);
408  FlowShutdown();
409  SCFree(p);
410  PASS;
411 }
412 
413 /** \test Get the wscale of 15, so see if return 0 properly */
414 static int TCPGetWscaleTest02(void)
415 {
416  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
417  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
418  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
419  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
420  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f};
421  Packet *p = PacketGetFromAlloc();
422  FAIL_IF_NULL(p);
423  IPV4Hdr ip4h;
424  ThreadVars tv;
426 
427  memset(&tv, 0, sizeof(ThreadVars));
428  memset(&dtv, 0, sizeof(DecodeThreadVars));
429  memset(&ip4h, 0, sizeof(IPV4Hdr));
430 
431  p->src.family = AF_INET;
432  p->dst.family = AF_INET;
433  UTHSetIPV4Hdr(p, &ip4h);
434 
436  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
437  FAIL_IF_NOT(PacketIsTCP(p));
438 
439  uint8_t wscale = TCP_GET_WSCALE(p);
440  FAIL_IF(wscale != 0);
441 
442  PacketRecycle(p);
443  FlowShutdown();
444  SCFree(p);
445  PASS;
446 }
447 
448 /** \test Get the wscale, but it's missing, so see if return 0 properly */
449 static int TCPGetWscaleTest03(void)
450 {
451  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59,
452  0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4,
453  0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
454  0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00};
455  Packet *p = PacketGetFromAlloc();
456  FAIL_IF_NULL(p);
457  IPV4Hdr ip4h;
458  ThreadVars tv;
460  memset(&tv, 0, sizeof(ThreadVars));
461  memset(&dtv, 0, sizeof(DecodeThreadVars));
462  memset(&ip4h, 0, sizeof(IPV4Hdr));
463 
464  p->src.family = AF_INET;
465  p->dst.family = AF_INET;
466  UTHSetIPV4Hdr(p, &ip4h);
467 
469  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
470  FAIL_IF_NOT(PacketIsTCP(p));
471 
472  uint8_t wscale = TCP_GET_WSCALE(p);
473  FAIL_IF(wscale != 0);
474 
475  PacketRecycle(p);
476  FlowShutdown();
477  SCFree(p);
478  PASS;
479 }
480 
481 static int TCPGetSackTest01(void)
482 {
483  static uint8_t raw_tcp[] = {
484  0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
485  0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
486  0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
487  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
488  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
489  static uint8_t raw_tcp_sack[] = {
490  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
491  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
492  Packet *p = PacketGetFromAlloc();
493  FAIL_IF_NULL(p);
494 
495  IPV4Hdr ip4h;
496  ThreadVars tv;
498  memset(&tv, 0, sizeof(ThreadVars));
499  memset(&dtv, 0, sizeof(DecodeThreadVars));
500  memset(&ip4h, 0, sizeof(IPV4Hdr));
501 
502  p->src.family = AF_INET;
503  p->dst.family = AF_INET;
504  UTHSetIPV4Hdr(p, &ip4h);
505 
507  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
508 
509  FAIL_IF_NOT(PacketIsTCP(p));
510 
511  FAIL_IF(!TCP_HAS_SACK(p));
512 
513  int sack = TCP_GET_SACK_CNT(p);
514  FAIL_IF(sack != 2);
515 
516  const TCPHdr *tcph = PacketGetTCP(p);
517  const uint8_t *sackptr = TCP_GET_SACK_PTR(p, tcph);
518  FAIL_IF_NULL(sackptr);
519 
520  FAIL_IF(memcmp(sackptr, raw_tcp_sack, 16) != 0);
521 
522  PacketRecycle(p);
523  FlowShutdown();
524  SCFree(p);
525  PASS;
526 }
527 #endif /* UNITTESTS */
528 
530 {
531 #ifdef UNITTESTS
532  UtRegisterTest("TCPCalculateValidChecksumtest01",
533  TCPCalculateValidChecksumtest01);
534  UtRegisterTest("TCPCalculateInvalidChecksumtest02",
535  TCPCalculateInvalidChecksumtest02);
536  UtRegisterTest("TCPV6CalculateValidChecksumtest03",
537  TCPV6CalculateValidChecksumtest03);
538  UtRegisterTest("TCPV6CalculateInvalidChecksumtest04",
539  TCPV6CalculateInvalidChecksumtest04);
540  UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01);
541  UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02);
542  UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03);
543  UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01);
544 #endif /* UNITTESTS */
545 }
546 /**
547  * @}
548  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1146
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:495
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
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
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:269
TCP_HEADER_LEN
#define TCP_HEADER_LEN
Definition: decode-tcp.h:28
Packet_::payload
uint8_t * payload
Definition: decode.h:571
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:143
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
DecodeThreadVars_::counter_tcp_synack
uint16_t counter_tcp_synack
Definition: decode.h:949
TCP_GET_RAW_HLEN
#define TCP_GET_RAW_HLEN(tcph)
Definition: decode-tcp.h:72
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_OPT_INVALID_LEN
@ TCP_OPT_INVALID_LEN
Definition: decode-events.h:99
TCP_GET_SACKOK
#define TCP_GET_SACKOK(p)
Definition: decode-tcp.h:102
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:572
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
TCP_OPT_DUPLICATE
@ TCP_OPT_DUPLICATE
Definition: decode-events.h:100
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
TCP_GET_WSCALE
#define TCP_GET_WSCALE(p)
Definition: decode-tcp.h:100
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:533
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
TCP_HLEN_TOO_SMALL
@ TCP_HLEN_TOO_SMALL
Definition: decode-events.h:95
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
DecodeThreadVars_::counter_tcp_rst
uint16_t counter_tcp_rst
Definition: decode.h:950
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:450
Packet_::sp
Port sp
Definition: decode.h:480
TCP_GET_RAW_SRC_PORT
#define TCP_GET_RAW_SRC_PORT(tcph)
Definition: decode-tcp.h:74
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
Packet_
Definition: decode.h:473
TCP_GET_SACK_CNT
#define TCP_GET_SACK_CNT(p)
Definition: decode-tcp.h:104
type
uint16_t type
Definition: decode-vlan.c:107
Packet_::l4
struct PacketL4 l4
Definition: decode.h:567
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:529
TCPVars_::tfo_set
uint8_t tfo_set
Definition: decode-tcp.h:169
DecodeThreadVars_::counter_tcp
uint16_t counter_tcp
Definition: decode.h:947
TCPVars_::wscale
uint8_t wscale
Definition: decode-tcp.h:172
TCP_PKT_TOO_SMALL
@ TCP_PKT_TOO_SMALL
Definition: decode-events.h:94
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
DecodeTCP
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-tcp.c:270
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
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
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:414
suricata-common.h
TCP_OPTMAX
#define TCP_OPTMAX
Definition: decode-tcp.h:30
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:680
packet.h
TCPVars_::md5_option_present
uint8_t md5_option_present
Definition: decode-tcp.h:164
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
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:232
TCP_GET_RAW_DST_PORT
#define TCP_GET_RAW_DST_PORT(tcph)
Definition: decode-tcp.h:75
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SCNtohl
#define SCNtohl(x)
Definition: suricata-common.h:413
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:929
TCP_OPTLENMAX
#define TCP_OPTLENMAX
Definition: decode-tcp.h:29
Address_::family
char family
Definition: decode.h:109
Packet_::dst
Address dst
Definition: decode.h:478
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1154
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
DecodeThreadVars_::counter_tcp_syn
uint16_t counter_tcp_syn
Definition: decode.h:948
TCP_OPT_TFO_MAX_LEN
#define TCP_OPT_TFO_MAX_LEN
Definition: decode-tcp.h:66
flow.h
TCP_INVALID_OPTLEN
@ TCP_INVALID_OPTLEN
Definition: decode-events.h:96
Packet_::dp
Port dp
Definition: decode.h:488
TCP_OPT_TS_LEN
#define TCP_OPT_TS_LEN
Definition: decode-tcp.h:61
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:522
TCPHdr_
Definition: decode-tcp.h:149
Packet_::src
Address src
Definition: decode.h:477
TCPVars_::sack_set
uint8_t sack_set
Definition: decode-tcp.h:171
PacketL4::vars
union PacketL4::L4Vars vars
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