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 
84  /* we are parsing the most commonly used opts to prevent
85  * us from having to walk the opts list for these all the
86  * time. */
87  switch (type) {
88  case TCP_OPT_WS:
89  if (olen != TCP_OPT_WS_LEN) {
91  } else {
92  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
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  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
111  if (p->l4.vars.tcp.mss_set) {
113  } else {
114  p->l4.vars.tcp.mss_set = true;
115  p->l4.vars.tcp.mss = DecodeTCPGetU16(tcp_opts[tcp_opt_cnt].data);
116  }
117  }
118  break;
119  case TCP_OPT_SACKOK:
120  if (olen != TCP_OPT_SACKOK_LEN) {
122  } else {
123  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
124  if (TCP_GET_SACKOK(p)) {
126  } else {
127  p->l4.vars.tcp.sack_ok = true;
128  }
129  }
130  break;
131  case TCP_OPT_TS:
132  if (olen != TCP_OPT_TS_LEN) {
134  } else {
135  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
136  if (p->l4.vars.tcp.ts_set) {
138  } else {
139  uint32_t values[2];
140  memcpy(&values, tcp_opts[tcp_opt_cnt].data, sizeof(values));
141  p->l4.vars.tcp.ts_val = SCNtohl(values[0]);
142  p->l4.vars.tcp.ts_ecr = SCNtohl(values[1]);
143  p->l4.vars.tcp.ts_set = true;
144  }
145  }
146  break;
147  case TCP_OPT_SACK:
148  SCLogDebug("SACK option, len %u", olen);
149  if (olen == 2) {
150  /* useless, but common empty SACK record */
151  } else if (olen < TCP_OPT_SACK_MIN_LEN || olen > TCP_OPT_SACK_MAX_LEN ||
152  !((olen - 2) % 8 == 0)) {
154  } else {
155  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
156  if (p->l4.vars.tcp.sack_set) {
158  } else {
159  ptrdiff_t diff = tcp_opts[tcp_opt_cnt].data - (uint8_t *)tcph;
160  DEBUG_VALIDATE_BUG_ON(diff > UINT16_MAX);
161  p->l4.vars.tcp.sack_set = true;
162  p->l4.vars.tcp.sack_cnt = (olen - 2) / 8;
163  p->l4.vars.tcp.sack_offset = (uint16_t)diff;
164  }
165  }
166  break;
167  case TCP_OPT_TFO:
168  SCLogDebug("TFO option, len %u", olen);
169  if ((olen != 2) && (olen < TCP_OPT_TFO_MIN_LEN || olen > TCP_OPT_TFO_MAX_LEN ||
170  !(((olen - 2) & 0x1) == 0))) {
172  } else {
173  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
174  if (p->l4.vars.tcp.tfo_set) {
176  } else {
177  p->l4.vars.tcp.tfo_set = true;
178  }
179  }
180  break;
181  /* experimental options, could be TFO */
182  case TCP_OPT_EXP1:
183  case TCP_OPT_EXP2:
184  SCLogDebug("TCP EXP option, len %u", olen);
185  if (olen == 4 || olen == 12) {
186  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
187  uint16_t magic = DecodeTCPGetU16(tcp_opts[tcp_opt_cnt].data);
188  if (magic == 0xf989) {
189  if (p->l4.vars.tcp.tfo_set) {
191  } else {
192  p->l4.vars.tcp.tfo_set = true;
193  }
194  }
195  } else {
197  }
198  break;
199  /* RFC 2385 MD5 option */
200  case TCP_OPT_MD5:
201  SCLogDebug("MD5 option, len %u", olen);
202  if (olen != 18) {
204  } else {
205  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
206  /* we can't validate the option as the key is out of band */
207  p->l4.vars.tcp.md5_option_present = true;
208  }
209  break;
210  /* RFC 5925 AO option */
211  case TCP_OPT_AO:
212  SCLogDebug("AU option, len %u", olen);
213  if (olen < 4) {
215  } else {
216  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
217  /* we can't validate the option as the key is out of band */
218  p->l4.vars.tcp.ao_option_present = true;
219  }
220  break;
221  default:
222  if (olen > 2) {
223  tcp_opts[tcp_opt_cnt].data = (pkt + 2);
224  } else {
225 
226  tcp_opts[tcp_opt_cnt].data = NULL;
227  }
228  }
229 
230  pkt += olen;
231  plen -= olen;
232  tcp_opt_cnt++;
233  }
234  }
235 }
236 
237 static int DecodeTCPPacket(
238  ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
239 {
240  if (unlikely(len < TCP_HEADER_LEN)) {
242  return -1;
243  }
244 
245  TCPHdr *tcph = PacketSetTCP(p, pkt);
246 
247  uint8_t hlen = TCP_GET_RAW_HLEN(tcph);
248  if (unlikely(len < hlen)) {
250  return -1;
251  }
252 
253  uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN;
254  if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) {
256  return -1;
257  }
258 
259  if (likely(tcp_opt_len > 0)) {
260  DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len);
261  }
262 
263  p->sp = TCP_GET_RAW_SRC_PORT(tcph);
264  p->dp = TCP_GET_RAW_DST_PORT(tcph);
265 
266  p->proto = IPPROTO_TCP;
267 
268  p->payload = (uint8_t *)pkt + hlen;
269  p->payload_len = len - hlen;
270 
271  /* update counters */
272  if ((tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
274  } else if (tcph->th_flags & (TH_SYN)) {
276  }
277  if (tcph->th_flags & (TH_RST)) {
279  }
280  if (tcph->th_flags & (TH_URG)) {
282  }
283 
284 #ifdef DEBUG
285  SCLogDebug("TCP sp: %u -> dp: %u - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s", p->sp,
286  p->dp, TCP_GET_RAW_HLEN(tcph), len, TCP_GET_SACKOK(p) ? "SACKOK " : "",
287  TCP_HAS_SACK(p) ? "SACK " : "", TCP_HAS_WSCALE(p) ? "WS " : "",
288  TCP_HAS_TS(p) ? "TS " : "", TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : "");
289 #endif
290  return 0;
291 }
292 
293 int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
294 {
296 
297  if (unlikely(DecodeTCPPacket(tv, dtv, p, pkt, len) < 0)) {
298  SCLogDebug("invalid TCP packet");
299  PacketClearL4(p);
300  return TM_ECODE_FAILED;
301  }
302 
304 
305  return TM_ECODE_OK;
306 }
307 
308 #ifdef UNITTESTS
309 #include "util-unittest-helper.h"
310 #include "packet.h"
311 
312 static int TCPCalculateValidChecksumtest01(void)
313 {
314  uint16_t csum = 0;
315 
316  uint8_t raw_ipshdr[] = {
317  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
318 
319  uint8_t raw_tcp[] = {
320  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
321  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
322  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
323  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
324  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02};
325 
326  csum = *( ((uint16_t *)raw_tcp) + 8);
327 
328  FAIL_IF(TCPChecksum((uint16_t *)raw_ipshdr,
329  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0);
330  PASS;
331 }
332 
333 static int TCPCalculateInvalidChecksumtest02(void)
334 {
335  uint16_t csum = 0;
336 
337  uint8_t raw_ipshdr[] = {
338  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
339 
340  uint8_t raw_tcp[] = {
341  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
342  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
343  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
344  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
345  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 03};
346 
347  csum = *( ((uint16_t *)raw_tcp) + 8);
348 
349  FAIL_IF(TCPChecksum((uint16_t *) raw_ipshdr,
350  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) == 0);
351  PASS;
352 }
353 
354 static int TCPV6CalculateValidChecksumtest03(void)
355 {
356  uint16_t csum = 0;
357 
358  static uint8_t raw_ipv6[] = {
359  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
360  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
361  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
362  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
363  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
364  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
365  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
366  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
367  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
368  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
369  0xca, 0x5a, 0x00, 0x01, 0x69, 0x27};
370 
371  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
372 
373  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
374  (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0);
375  PASS;
376 }
377 
378 static int TCPV6CalculateInvalidChecksumtest04(void)
379 {
380  uint16_t csum = 0;
381 
382  static uint8_t raw_ipv6[] = {
383  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
384  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
385  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
386  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
387  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
388  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
389  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
390  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
391  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
392  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
393  0xca, 0x5a, 0x00, 0x01, 0x69, 0x28};
394 
395  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
396 
397  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
398  (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0);
399  PASS;
400 }
401 
402 /** \test Get the wscale of 2 */
403 static int TCPGetWscaleTest01(void)
404 {
405  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
406  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
407  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
408  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
409  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
411  FAIL_IF_NULL(p);
412  IPV4Hdr ip4h;
413  ThreadVars tv;
415  memset(&tv, 0, sizeof(ThreadVars));
416  memset(&dtv, 0, sizeof(DecodeThreadVars));
417  memset(&ip4h, 0, sizeof(IPV4Hdr));
418 
419  p->src.family = AF_INET;
420  p->dst.family = AF_INET;
421  UTHSetIPV4Hdr(p, &ip4h);
422 
424  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
425  FAIL_IF_NOT(PacketIsTCP(p));
426 
427  uint8_t wscale = TCP_GET_WSCALE(p);
428  FAIL_IF(wscale != 2);
429 
430  PacketFree(p);
431  FlowShutdown();
432  PASS;
433 }
434 
435 /** \test Get the wscale of 15, so see if return 0 properly */
436 static int TCPGetWscaleTest02(void)
437 {
438  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
439  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
440  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
441  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
442  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f};
444  FAIL_IF_NULL(p);
445  IPV4Hdr ip4h;
446  ThreadVars tv;
448 
449  memset(&tv, 0, sizeof(ThreadVars));
450  memset(&dtv, 0, sizeof(DecodeThreadVars));
451  memset(&ip4h, 0, sizeof(IPV4Hdr));
452 
453  p->src.family = AF_INET;
454  p->dst.family = AF_INET;
455  UTHSetIPV4Hdr(p, &ip4h);
456 
458  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
459  FAIL_IF_NOT(PacketIsTCP(p));
460 
461  uint8_t wscale = TCP_GET_WSCALE(p);
462  FAIL_IF(wscale != 0);
463 
464  PacketFree(p);
465  FlowShutdown();
466  PASS;
467 }
468 
469 /** \test Get the wscale, but it's missing, so see if return 0 properly */
470 static int TCPGetWscaleTest03(void)
471 {
472  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59,
473  0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4,
474  0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
475  0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00};
477  FAIL_IF_NULL(p);
478  IPV4Hdr ip4h;
479  ThreadVars tv;
481  memset(&tv, 0, sizeof(ThreadVars));
482  memset(&dtv, 0, sizeof(DecodeThreadVars));
483  memset(&ip4h, 0, sizeof(IPV4Hdr));
484 
485  p->src.family = AF_INET;
486  p->dst.family = AF_INET;
487  UTHSetIPV4Hdr(p, &ip4h);
488 
490  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
491  FAIL_IF_NOT(PacketIsTCP(p));
492 
493  uint8_t wscale = TCP_GET_WSCALE(p);
494  FAIL_IF(wscale != 0);
495 
496  PacketFree(p);
497  FlowShutdown();
498  PASS;
499 }
500 
501 static int TCPGetSackTest01(void)
502 {
503  static uint8_t raw_tcp[] = {
504  0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
505  0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
506  0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
507  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
508  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
509  static uint8_t raw_tcp_sack[] = {
510  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
511  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
513  FAIL_IF_NULL(p);
514 
515  IPV4Hdr ip4h;
516  ThreadVars tv;
518  memset(&tv, 0, sizeof(ThreadVars));
519  memset(&dtv, 0, sizeof(DecodeThreadVars));
520  memset(&ip4h, 0, sizeof(IPV4Hdr));
521 
522  p->src.family = AF_INET;
523  p->dst.family = AF_INET;
524  UTHSetIPV4Hdr(p, &ip4h);
525 
527  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
528 
529  FAIL_IF_NOT(PacketIsTCP(p));
530 
532 
533  int sack = TCP_GET_SACK_CNT(p);
534  FAIL_IF(sack != 2);
535 
536  const TCPHdr *tcph = PacketGetTCP(p);
537  const uint8_t *sackptr = TCP_GET_SACK_PTR(p, tcph);
538  FAIL_IF_NULL(sackptr);
539 
540  FAIL_IF(memcmp(sackptr, raw_tcp_sack, 16) != 0);
541 
542  PacketFree(p);
543  FlowShutdown();
544  PASS;
545 }
546 #endif /* UNITTESTS */
547 
549 {
550 #ifdef UNITTESTS
551  UtRegisterTest("TCPCalculateValidChecksumtest01",
552  TCPCalculateValidChecksumtest01);
553  UtRegisterTest("TCPCalculateInvalidChecksumtest02",
554  TCPCalculateInvalidChecksumtest02);
555  UtRegisterTest("TCPV6CalculateValidChecksumtest03",
556  TCPV6CalculateValidChecksumtest03);
557  UtRegisterTest("TCPV6CalculateInvalidChecksumtest04",
558  TCPV6CalculateInvalidChecksumtest04);
559  UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01);
560  UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02);
561  UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03);
562  UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01);
563 #endif /* UNITTESTS */
564 }
565 /**
566  * @}
567  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1230
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:537
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:619
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:253
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:1013
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_iprep.c:21
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:620
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:1012
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:577
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:490
Packet_::sp
Port sp
Definition: decode.h:522
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:222
DecodeThreadVars_::counter_tcp_urg
StatsCounterId counter_tcp_urg
Definition: decode.h:1016
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
Packet_
Definition: decode.h:515
TCP_GET_SACK_CNT
#define TCP_GET_SACK_CNT(p)
Definition: decode-tcp.h:104
Packet_::l4
struct PacketL4 l4
Definition: decode.h:615
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:548
DecodeThreadVars_::counter_tcp_rst
StatsCounterId counter_tcp_rst
Definition: decode.h:1015
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:293
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:1014
TCP_OPTMAX
#define TCP_OPTMAX
Definition: decode-tcp.h:30
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:721
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:261
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:438
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:994
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:520
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1238
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:530
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: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:516
TCPHdr_
Definition: decode-tcp.h:149
Packet_::src
Address src
Definition: decode.h:519
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