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  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 
273 int 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 
283  FlowSetupPacket(p);
284 
285  return TM_ECODE_OK;
286 }
287 
288 #ifdef UNITTESTS
289 #include "util-unittest-helper.h"
290 #include "packet.h"
291 
292 static 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 
313 static 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 
334 static 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 
358 static 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 */
383 static 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};
390  Packet *p = PacketGetFromAlloc();
391  FAIL_IF_NULL(p);
392  IPV4Hdr ip4h;
393  ThreadVars tv;
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 */
417 static 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};
424  Packet *p = PacketGetFromAlloc();
425  FAIL_IF_NULL(p);
426  IPV4Hdr ip4h;
427  ThreadVars tv;
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 */
452 static 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};
458  Packet *p = PacketGetFromAlloc();
459  FAIL_IF_NULL(p);
460  IPV4Hdr ip4h;
461  ThreadVars tv;
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 
484 static 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 };
495  Packet *p = PacketGetFromAlloc();
496  FAIL_IF_NULL(p);
497 
498  IPV4Hdr ip4h;
499  ThreadVars tv;
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 
514  FAIL_IF(!TCP_HAS_SACK(p));
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  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1150
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:498
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:574
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:952
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:575
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:953
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:453
Packet_::sp
Port sp
Definition: decode.h:483
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
DecodeThreadVars_::counter_tcp_urg
uint16_t counter_tcp_urg
Definition: decode.h:954
Packet_
Definition: decode.h:476
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:570
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:532
TCPVars_::tfo_set
uint8_t tfo_set
Definition: decode-tcp.h:169
DecodeThreadVars_::counter_tcp
uint16_t counter_tcp
Definition: decode.h:950
TH_URG
#define TH_URG
Definition: decode-tcp.h:39
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:273
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:932
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:481
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1158
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:951
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:491
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:480
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