suricata
decode-tcp.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 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.h"
35 #include "decode-tcp.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 #include "util-profiling.h"
42 #include "pkt-var.h"
43 #include "host.h"
44 
45 #define SET_OPTS(dst, src) \
46  (dst).type = (src).type; \
47  (dst).len = (src).len; \
48  (dst).data = (src).data
49 
50 static void DecodeTCPOptions(Packet *p, const uint8_t *pkt, uint16_t pktlen)
51 {
52  uint8_t tcp_opt_cnt = 0;
53  TCPOpt tcp_opts[TCP_OPTMAX];
54 
55  uint16_t plen = pktlen;
56  while (plen)
57  {
58  const uint8_t type = *pkt;
59 
60  /* single byte options */
61  if (type == TCP_OPT_EOL) {
62  break;
63  } else if (type == TCP_OPT_NOP) {
64  pkt++;
65  plen--;
66 
67  /* multibyte options */
68  } else {
69  if (plen < 2) {
70  break;
71  }
72 
73  const uint8_t olen = *(pkt+1);
74 
75  /* we already know that the total options len is valid,
76  * so here the len of the specific option must be bad.
77  * Also check for invalid lengths 0 and 1. */
78  if (unlikely(olen > plen || olen < 2)) {
80  return;
81  }
82 
83  tcp_opts[tcp_opt_cnt].type = type;
84  tcp_opts[tcp_opt_cnt].len = olen;
85  tcp_opts[tcp_opt_cnt].data = (olen > 2) ? (pkt+2) : NULL;
86 
87  /* we are parsing the most commonly used opts to prevent
88  * us from having to walk the opts list for these all the
89  * time. */
90  switch (type) {
91  case TCP_OPT_WS:
92  if (olen != TCP_OPT_WS_LEN) {
94  } else {
95  if (p->tcpvars.ws.type != 0) {
97  } else {
98  SET_OPTS(p->tcpvars.ws, tcp_opts[tcp_opt_cnt]);
99  }
100  }
101  break;
102  case TCP_OPT_MSS:
103  if (olen != TCP_OPT_MSS_LEN) {
105  } else {
106  if (p->tcpvars.mss.type != 0) {
108  } else {
109  SET_OPTS(p->tcpvars.mss, tcp_opts[tcp_opt_cnt]);
110  }
111  }
112  break;
113  case TCP_OPT_SACKOK:
114  if (olen != TCP_OPT_SACKOK_LEN) {
116  } else {
117  if (p->tcpvars.sackok.type != 0) {
119  } else {
120  SET_OPTS(p->tcpvars.sackok, tcp_opts[tcp_opt_cnt]);
121  }
122  }
123  break;
124  case TCP_OPT_TS:
125  if (olen != TCP_OPT_TS_LEN) {
127  } else {
128  if (p->tcpvars.ts_set) {
130  } else {
131  uint32_t values[2];
132  memcpy(&values, tcp_opts[tcp_opt_cnt].data, sizeof(values));
133  p->tcpvars.ts_val = SCNtohl(values[0]);
134  p->tcpvars.ts_ecr = SCNtohl(values[1]);
135  p->tcpvars.ts_set = true;
136  }
137  }
138  break;
139  case TCP_OPT_SACK:
140  SCLogDebug("SACK option, len %u", olen);
141  if ((olen != 2) &&
142  (olen < TCP_OPT_SACK_MIN_LEN ||
143  olen > TCP_OPT_SACK_MAX_LEN ||
144  !((olen - 2) % 8 == 0)))
145  {
147  } else {
148  if (p->tcpvars.sack.type != 0) {
150  } else {
151  SET_OPTS(p->tcpvars.sack, tcp_opts[tcp_opt_cnt]);
152  }
153  }
154  break;
155  case TCP_OPT_TFO:
156  SCLogDebug("TFO option, len %u", olen);
157  if ((olen != 2) && (olen < TCP_OPT_TFO_MIN_LEN || olen > TCP_OPT_TFO_MAX_LEN ||
158  !(((olen - 2) & 0x1) == 0))) {
160  } else {
161  if (p->tcpvars.tfo.type != 0) {
163  } else {
164  SET_OPTS(p->tcpvars.tfo, tcp_opts[tcp_opt_cnt]);
165  }
166  }
167  break;
168  /* experimental options, could be TFO */
169  case TCP_OPT_EXP1:
170  case TCP_OPT_EXP2:
171  SCLogDebug("TCP EXP option, len %u", olen);
172  if (olen == 4 || olen == 12) {
173  uint16_t magic = SCNtohs(*(uint16_t *)tcp_opts[tcp_opt_cnt].data);
174  if (magic == 0xf989) {
175  if (p->tcpvars.tfo.type != 0) {
177  } else {
178  SET_OPTS(p->tcpvars.tfo, tcp_opts[tcp_opt_cnt]);
179  p->tcpvars.tfo.type = TCP_OPT_TFO; // treat as regular TFO
180  }
181  }
182  } else {
184  }
185  break;
186  /* RFC 2385 MD5 option */
187  case TCP_OPT_MD5:
188  SCLogDebug("MD5 option, len %u", olen);
189  if (olen != 18) {
191  } else {
192  /* we can't validate the option as the key is out of band */
193  p->tcpvars.md5_option_present = true;
194  }
195  break;
196  /* RFC 5925 AO option */
197  case TCP_OPT_AO:
198  SCLogDebug("AU option, len %u", olen);
199  if (olen < 4) {
201  } else {
202  /* we can't validate the option as the key is out of band */
203  p->tcpvars.ao_option_present = true;
204  }
205  break;
206  }
207 
208  pkt += olen;
209  plen -= olen;
210  tcp_opt_cnt++;
211  }
212  }
213 }
214 
215 static int DecodeTCPPacket(ThreadVars *tv, Packet *p, const uint8_t *pkt, uint16_t len)
216 {
217  if (unlikely(len < TCP_HEADER_LEN)) {
219  return -1;
220  }
221 
222  p->tcph = (TCPHdr *)pkt;
223 
224  uint8_t hlen = TCP_GET_HLEN(p);
225  if (unlikely(len < hlen)) {
227  return -1;
228  }
229 
230  uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN;
231  if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) {
233  return -1;
234  }
235 
236  if (likely(tcp_opt_len > 0)) {
237  DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len);
238  }
239 
240  SET_TCP_SRC_PORT(p,&p->sp);
241  SET_TCP_DST_PORT(p,&p->dp);
242 
243  p->proto = IPPROTO_TCP;
244 
245  p->payload = (uint8_t *)pkt + hlen;
246  p->payload_len = len - hlen;
247 
248  return 0;
249 }
250 
252  const uint8_t *pkt, uint16_t len)
253 {
255 
256  if (unlikely(DecodeTCPPacket(tv, p, pkt,len) < 0)) {
257  SCLogDebug("invalid TCP packet");
258  CLEAR_TCP_PACKET(p);
259  return TM_ECODE_FAILED;
260  }
261 
262 #ifdef DEBUG
263  SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s",
265  TCP_HAS_SACKOK(p) ? "SACKOK " : "", TCP_HAS_SACK(p) ? "SACK " : "",
266  TCP_HAS_WSCALE(p) ? "WS " : "", TCP_HAS_TS(p) ? "TS " : "",
267  TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : "");
268 #endif
269 
270  FlowSetupPacket(p);
271 
272  return TM_ECODE_OK;
273 }
274 
275 #ifdef UNITTESTS
276 static int TCPCalculateValidChecksumtest01(void)
277 {
278  uint16_t csum = 0;
279 
280  uint8_t raw_ipshdr[] = {
281  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
282 
283  uint8_t raw_tcp[] = {
284  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
285  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
286  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
287  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
288  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02};
289 
290  csum = *( ((uint16_t *)raw_tcp) + 8);
291 
292  FAIL_IF(TCPChecksum((uint16_t *)raw_ipshdr,
293  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0);
294  PASS;
295 }
296 
297 static int TCPCalculateInvalidChecksumtest02(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, 03};
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 TCPV6CalculateValidChecksumtest03(void)
319 {
320  uint16_t csum = 0;
321 
322  static uint8_t raw_ipv6[] = {
323  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
324  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
325  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
326  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
327  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
328  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
329  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
330  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
331  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
332  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
333  0xca, 0x5a, 0x00, 0x01, 0x69, 0x27};
334 
335  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
336 
337  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
338  (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0);
339  PASS;
340 }
341 
342 static int TCPV6CalculateInvalidChecksumtest04(void)
343 {
344  uint16_t csum = 0;
345 
346  static uint8_t raw_ipv6[] = {
347  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
348  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
349  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
350  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
351  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
352  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
353  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
354  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
355  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
356  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
357  0xca, 0x5a, 0x00, 0x01, 0x69, 0x28};
358 
359  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
360 
361  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
362  (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0);
363  PASS;
364 }
365 
366 /** \test Get the wscale of 2 */
367 static int TCPGetWscaleTest01(void)
368 {
369  int retval = 0;
370  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
371  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
372  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
373  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
374  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
375  Packet *p = PacketGetFromAlloc();
376  if (unlikely(p == NULL))
377  return 0;
378  IPV4Hdr ip4h;
379  ThreadVars tv;
381 
382  memset(&tv, 0, sizeof(ThreadVars));
383  memset(&dtv, 0, sizeof(DecodeThreadVars));
384  memset(&ip4h, 0, sizeof(IPV4Hdr));
385 
386  p->src.family = AF_INET;
387  p->dst.family = AF_INET;
388  p->ip4h = &ip4h;
389 
390 
392  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
393 
394  if (p->tcph == NULL) {
395  printf("tcp packet decode failed: ");
396  goto end;
397  }
398 
399  uint8_t wscale = TCP_GET_WSCALE(p);
400  if (wscale != 2) {
401  printf("wscale %"PRIu8", expected 2: ", wscale);
402  goto end;
403  }
404 
405  retval = 1;
406 end:
407  PACKET_RECYCLE(p);
408  FlowShutdown();
409  SCFree(p);
410  return retval;
411 }
412 
413 /** \test Get the wscale of 15, so see if return 0 properly */
414 static int TCPGetWscaleTest02(void)
415 {
416  int retval = 0;
417  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
418  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
419  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
420  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
421  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f};
422  Packet *p = PacketGetFromAlloc();
423  if (unlikely(p == NULL))
424  return 0;
425  IPV4Hdr ip4h;
426  ThreadVars tv;
428 
429  memset(&tv, 0, sizeof(ThreadVars));
430  memset(&dtv, 0, sizeof(DecodeThreadVars));
431  memset(&ip4h, 0, sizeof(IPV4Hdr));
432 
433  p->src.family = AF_INET;
434  p->dst.family = AF_INET;
435  p->ip4h = &ip4h;
436 
438  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
439 
440  if (p->tcph == NULL) {
441  printf("tcp packet decode failed: ");
442  goto end;
443  }
444 
445  uint8_t wscale = TCP_GET_WSCALE(p);
446  if (wscale != 0) {
447  printf("wscale %"PRIu8", expected 0: ", wscale);
448  goto end;
449  }
450 
451  retval = 1;
452 end:
453  PACKET_RECYCLE(p);
454  FlowShutdown();
455  SCFree(p);
456  return retval;
457 }
458 
459 /** \test Get the wscale, but it's missing, so see if return 0 properly */
460 static int TCPGetWscaleTest03(void)
461 {
462  int retval = 0;
463  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59,
464  0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4,
465  0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
466  0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00};
467  Packet *p = PacketGetFromAlloc();
468  if (unlikely(p == NULL))
469  return 0;
470  IPV4Hdr ip4h;
471  ThreadVars tv;
473 
474  memset(&tv, 0, sizeof(ThreadVars));
475  memset(&dtv, 0, sizeof(DecodeThreadVars));
476  memset(&ip4h, 0, sizeof(IPV4Hdr));
477 
478  p->src.family = AF_INET;
479  p->dst.family = AF_INET;
480  p->ip4h = &ip4h;
481 
483  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
484 
485  if (p->tcph == NULL) {
486  printf("tcp packet decode failed: ");
487  goto end;
488  }
489 
490  uint8_t wscale = TCP_GET_WSCALE(p);
491  if (wscale != 0) {
492  printf("wscale %"PRIu8", expected 0: ", wscale);
493  goto end;
494  }
495 
496  retval = 1;
497 end:
498  PACKET_RECYCLE(p);
499  FlowShutdown();
500  SCFree(p);
501  return retval;
502 }
503 
504 static int TCPGetSackTest01(void)
505 {
506  int retval = 0;
507  static uint8_t raw_tcp[] = {
508  0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
509  0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
510  0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
511  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
512  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
513  static uint8_t raw_tcp_sack[] = {
514  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
515  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
516  Packet *p = PacketGetFromAlloc();
517  if (unlikely(p == NULL))
518  return 0;
519  IPV4Hdr ip4h;
520  ThreadVars tv;
522 
523  memset(&tv, 0, sizeof(ThreadVars));
524  memset(&dtv, 0, sizeof(DecodeThreadVars));
525  memset(&ip4h, 0, sizeof(IPV4Hdr));
526 
527  p->src.family = AF_INET;
528  p->dst.family = AF_INET;
529  p->ip4h = &ip4h;
530 
532  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
533 
534  if (p->tcph == NULL) {
535  printf("tcp packet decode failed: ");
536  goto end;
537  }
538 
539  if (!TCP_HAS_SACK(p)) {
540  printf("tcp packet sack not decoded: ");
541  goto end;
542  }
543 
544  int sack = TCP_GET_SACK_CNT(p);
545  if (sack != 2) {
546  printf("expected 2 sack records, got %u: ", TCP_GET_SACK_CNT(p));
547  goto end;
548  }
549 
550  const uint8_t *sackptr = TCP_GET_SACK_PTR(p);
551  if (sackptr == NULL) {
552  printf("no sack data: ");
553  goto end;
554  }
555 
556  if (memcmp(sackptr, raw_tcp_sack, 16) != 0) {
557  printf("malformed sack data: ");
558  goto end;
559  }
560 
561  retval = 1;
562 end:
563  PACKET_RECYCLE(p);
564  FlowShutdown();
565  SCFree(p);
566  return retval;
567 }
568 #endif /* UNITTESTS */
569 
571 {
572 #ifdef UNITTESTS
573  UtRegisterTest("TCPCalculateValidChecksumtest01",
574  TCPCalculateValidChecksumtest01);
575  UtRegisterTest("TCPCalculateInvalidChecksumtest02",
576  TCPCalculateInvalidChecksumtest02);
577  UtRegisterTest("TCPV6CalculateValidChecksumtest03",
578  TCPV6CalculateValidChecksumtest03);
579  UtRegisterTest("TCPV6CalculateInvalidChecksumtest04",
580  TCPV6CalculateInvalidChecksumtest04);
581  UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01);
582  UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02);
583  UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03);
584  UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01);
585 #endif /* UNITTESTS */
586 }
587 /**
588  * @}
589  */
TCP_PKT_TOO_SMALL
@ TCP_PKT_TOO_SMALL
Definition: decode-events.h:94
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1036
host.h
decode-tcp.h
Packet_::proto
uint8_t proto
Definition: decode.h:436
len
uint8_t len
Definition: app-layer-dnp3.h:2
TCPOpt_
Definition: decode-tcp.h:130
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
GET_TCP_DST_PORT
#define GET_TCP_DST_PORT(p)
Definition: decode.h:230
TCP_OPT_SACKOK
#define TCP_OPT_SACKOK
Definition: decode-tcp.h:50
TCPVars_::sackok
TCPOpt sackok
Definition: decode-tcp.h:163
GET_TCP_SRC_PORT
#define GET_TCP_SRC_PORT(p)
Definition: decode.h:229
TCPVars_::ts_set
bool ts_set
Definition: decode-tcp.h:159
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:169
TCP_HAS_TFO
#define TCP_HAS_TFO(p)
Definition: decode-tcp.h:97
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:298
TCP_HEADER_LEN
#define TCP_HEADER_LEN
Definition: decode-tcp.h:28
Packet_::payload
uint8_t * payload
Definition: decode.h:551
TCP_OPT_SACKOK_LEN
#define TCP_OPT_SACKOK_LEN
Definition: decode-tcp.h:59
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
Packet_::tcpvars
TCPVars tcpvars
Definition: decode.h:523
TCP_INVALID_OPTLEN
@ TCP_INVALID_OPTLEN
Definition: decode-events.h:96
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
TCPVars_::md5_option_present
bool md5_option_present
Definition: decode-tcp.h:157
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:552
TCP_OPT_EOL
#define TCP_OPT_EOL
Definition: decode-tcp.h:46
TCPOpt_::data
const uint8_t * data
Definition: decode-tcp.h:133
util-unittest.h
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
TCP_HLEN_TOO_SMALL
@ TCP_HLEN_TOO_SMALL
Definition: decode-events.h:95
TCPVars_::tfo
TCPOpt tfo
Definition: decode-tcp.h:166
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:523
decode.h
TCPVars_::ts_ecr
uint32_t ts_ecr
Definition: decode-tcp.h:161
TCPOpt_::type
uint8_t type
Definition: decode-tcp.h:131
util-debug.h
type
uint8_t type
Definition: decode-icmpv4.h:0
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
SET_TCP_SRC_PORT
#define SET_TCP_SRC_PORT(pkt, prt)
Definition: decode.h:192
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
pkt-var.h
Packet_::sp
Port sp
Definition: decode.h:421
TCP_OPT_DUPLICATE
@ TCP_OPT_DUPLICATE
Definition: decode-events.h:100
TCPVars_::mss
TCPOpt mss
Definition: decode-tcp.h:165
util-profiling.h
Packet_
Definition: decode.h:414
TCP_GET_SACK_CNT
#define TCP_GET_SACK_CNT(p)
Definition: decode-tcp.h:106
TCP_OPT_SACK_MIN_LEN
#define TCP_OPT_SACK_MIN_LEN
Definition: decode-tcp.h:63
TCP_HAS_SACK
#define TCP_HAS_SACK(p)
Definition: decode-tcp.h:93
TCP_OPT_NOP
#define TCP_OPT_NOP
Definition: decode-tcp.h:47
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:509
TCP_HAS_TS
#define TCP_HAS_TS(p)
Definition: decode-tcp.h:95
TCPOpt_::len
uint8_t len
Definition: decode-tcp.h:132
DecodeTCPRegisterTests
void DecodeTCPRegisterTests(void)
Definition: decode-tcp.c:570
DecodeThreadVars_::counter_tcp
uint16_t counter_tcp
Definition: decode.h:656
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
DecodeTCP
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-tcp.c:251
IPV4Hdr_
Definition: decode-ipv4.h:71
TCP_OPT_EXP1
#define TCP_OPT_EXP1
Definition: decode-tcp.h:54
TCPVars_::ts_val
uint32_t ts_val
Definition: decode-tcp.h:160
TCPVars_::ws
TCPOpt ws
Definition: decode-tcp.h:164
TCP_HAS_SACKOK
#define TCP_HAS_SACKOK(p)
Definition: decode-tcp.h:94
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:395
suricata-common.h
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:531
TCP_OPTMAX
#define TCP_OPTMAX
Definition: decode-tcp.h:30
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:651
TCPVars_::ao_option_present
bool ao_option_present
Definition: decode-tcp.h:158
CLEAR_TCP_PACKET
#define CLEAR_TCP_PACKET(p)
Definition: decode-tcp.h:169
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
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:151
TCP_GET_SACK_PTR
#define TCP_GET_SACK_PTR(p)
Definition: decode-tcp.h:105
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SCNtohl
#define SCNtohl(x)
Definition: suricata-common.h:394
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:638
TCP_OPTLENMAX
#define TCP_OPTLENMAX
Definition: decode-tcp.h:29
SET_OPTS
#define SET_OPTS(dst, src)
Definition: decode-tcp.c:45
TCP_GET_HLEN
#define TCP_GET_HLEN(p)
Definition: decode-tcp.h:111
Address_::family
char family
Definition: decode.h:120
Packet_::dst
Address dst
Definition: decode.h:419
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1044
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:42
TCP_OPT_INVALID_LEN
@ TCP_OPT_INVALID_LEN
Definition: decode-events.h:99
TCP_HAS_WSCALE
#define TCP_HAS_WSCALE(p)
Definition: decode-tcp.h:92
TCP_OPT_AO
#define TCP_OPT_AO
Definition: decode-tcp.h:57
likely
#define likely(expr)
Definition: util-optimize.h:32
TCP_OPT_MSS_LEN
#define TCP_OPT_MSS_LEN
Definition: decode-tcp.h:62
TCPVars_::sack
TCPOpt sack
Definition: decode-tcp.h:162
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:429
TCP_OPT_TS_LEN
#define TCP_OPT_TS_LEN
Definition: decode-tcp.h:61
SET_TCP_DST_PORT
#define SET_TCP_DST_PORT(pkt, prt)
Definition: decode.h:196
FlowSetupPacket
void FlowSetupPacket(Packet *p)
prepare packet for a life with flow Set PKT_WANTS_FLOW flag to incidate workers should do a flow look...
Definition: flow-hash.c:431
Packet_::src
Address src
Definition: decode.h:418
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:842
TCP_OPT_TFO
#define TCP_OPT_TFO
Definition: decode-tcp.h:53
TCP_OPT_TS
#define TCP_OPT_TS
Definition: decode-tcp.h:52