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-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 #define SET_OPTS(dst, src) \
43  (dst).type = (src).type; \
44  (dst).len = (src).len; \
45  (dst).data = (src).data
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  uint16_t plen = pktlen;
53  while (plen)
54  {
55  const uint8_t type = *pkt;
56 
57  /* single byte options */
58  if (type == TCP_OPT_EOL) {
59  break;
60  } else if (type == TCP_OPT_NOP) {
61  pkt++;
62  plen--;
63 
64  /* multibyte options */
65  } else {
66  if (plen < 2) {
67  break;
68  }
69 
70  const uint8_t olen = *(pkt+1);
71 
72  /* we already know that the total options len is valid,
73  * so here the len of the specific option must be bad.
74  * Also check for invalid lengths 0 and 1. */
75  if (unlikely(olen > plen || olen < 2)) {
77  return;
78  }
79 
80  tcp_opts[tcp_opt_cnt].type = type;
81  tcp_opts[tcp_opt_cnt].len = olen;
82  tcp_opts[tcp_opt_cnt].data = (olen > 2) ? (pkt+2) : NULL;
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  if (p->tcpvars.ws.type != 0) {
94  } else {
95  SET_OPTS(p->tcpvars.ws, tcp_opts[tcp_opt_cnt]);
96  }
97  }
98  break;
99  case TCP_OPT_MSS:
100  if (olen != TCP_OPT_MSS_LEN) {
102  } else {
103  if (p->tcpvars.mss.type != 0) {
105  } else {
106  SET_OPTS(p->tcpvars.mss, tcp_opts[tcp_opt_cnt]);
107  }
108  }
109  break;
110  case TCP_OPT_SACKOK:
111  if (olen != TCP_OPT_SACKOK_LEN) {
113  } else {
114  if (p->tcpvars.sackok.type != 0) {
116  } else {
117  SET_OPTS(p->tcpvars.sackok, tcp_opts[tcp_opt_cnt]);
118  }
119  }
120  break;
121  case TCP_OPT_TS:
122  if (olen != TCP_OPT_TS_LEN) {
124  } else {
125  if (p->tcpvars.ts_set) {
127  } else {
128  uint32_t values[2];
129  memcpy(&values, tcp_opts[tcp_opt_cnt].data, sizeof(values));
130  p->tcpvars.ts_val = SCNtohl(values[0]);
131  p->tcpvars.ts_ecr = SCNtohl(values[1]);
132  p->tcpvars.ts_set = true;
133  }
134  }
135  break;
136  case TCP_OPT_SACK:
137  SCLogDebug("SACK option, len %u", olen);
138  if ((olen != 2) &&
139  (olen < TCP_OPT_SACK_MIN_LEN ||
140  olen > TCP_OPT_SACK_MAX_LEN ||
141  !((olen - 2) % 8 == 0)))
142  {
144  } else {
145  if (p->tcpvars.sack.type != 0) {
147  } else {
148  SET_OPTS(p->tcpvars.sack, tcp_opts[tcp_opt_cnt]);
149  }
150  }
151  break;
152  case TCP_OPT_TFO:
153  SCLogDebug("TFO option, len %u", olen);
154  if ((olen != 2) && (olen < TCP_OPT_TFO_MIN_LEN || olen > TCP_OPT_TFO_MAX_LEN ||
155  !(((olen - 2) & 0x1) == 0))) {
157  } else {
158  if (p->tcpvars.tfo.type != 0) {
160  } else {
161  SET_OPTS(p->tcpvars.tfo, tcp_opts[tcp_opt_cnt]);
162  }
163  }
164  break;
165  /* experimental options, could be TFO */
166  case TCP_OPT_EXP1:
167  case TCP_OPT_EXP2:
168  SCLogDebug("TCP EXP option, len %u", olen);
169  if (olen == 4 || olen == 12) {
170  uint16_t magic = SCNtohs(*(uint16_t *)tcp_opts[tcp_opt_cnt].data);
171  if (magic == 0xf989) {
172  if (p->tcpvars.tfo.type != 0) {
174  } else {
175  SET_OPTS(p->tcpvars.tfo, tcp_opts[tcp_opt_cnt]);
176  p->tcpvars.tfo.type = TCP_OPT_TFO; // treat as regular TFO
177  }
178  }
179  } else {
181  }
182  break;
183  /* RFC 2385 MD5 option */
184  case TCP_OPT_MD5:
185  SCLogDebug("MD5 option, len %u", olen);
186  if (olen != 18) {
188  } else {
189  /* we can't validate the option as the key is out of band */
190  p->tcpvars.md5_option_present = true;
191  }
192  break;
193  /* RFC 5925 AO option */
194  case TCP_OPT_AO:
195  SCLogDebug("AU option, len %u", olen);
196  if (olen < 4) {
198  } else {
199  /* we can't validate the option as the key is out of band */
200  p->tcpvars.ao_option_present = true;
201  }
202  break;
203  }
204 
205  pkt += olen;
206  plen -= olen;
207  tcp_opt_cnt++;
208  }
209  }
210 }
211 
212 static int DecodeTCPPacket(ThreadVars *tv, Packet *p, const uint8_t *pkt, uint16_t len)
213 {
214  if (unlikely(len < TCP_HEADER_LEN)) {
216  return -1;
217  }
218 
219  p->tcph = (TCPHdr *)pkt;
220 
221  uint8_t hlen = TCP_GET_HLEN(p);
222  if (unlikely(len < hlen)) {
224  return -1;
225  }
226 
227  uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN;
228  if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) {
230  return -1;
231  }
232 
233  if (likely(tcp_opt_len > 0)) {
234  DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len);
235  }
236 
237  SET_TCP_SRC_PORT(p,&p->sp);
238  SET_TCP_DST_PORT(p,&p->dp);
239 
240  p->proto = IPPROTO_TCP;
241 
242  p->payload = (uint8_t *)pkt + hlen;
243  p->payload_len = len - hlen;
244 
245  return 0;
246 }
247 
249  const uint8_t *pkt, uint16_t len)
250 {
252 
253  if (unlikely(DecodeTCPPacket(tv, p, pkt,len) < 0)) {
254  SCLogDebug("invalid TCP packet");
255  CLEAR_TCP_PACKET(p);
256  return TM_ECODE_FAILED;
257  }
258 
259 #ifdef DEBUG
260  SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s",
262  TCP_HAS_SACKOK(p) ? "SACKOK " : "", TCP_HAS_SACK(p) ? "SACK " : "",
263  TCP_HAS_WSCALE(p) ? "WS " : "", TCP_HAS_TS(p) ? "TS " : "",
264  TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : "");
265 #endif
266 
267  FlowSetupPacket(p);
268 
269  return TM_ECODE_OK;
270 }
271 
272 #ifdef UNITTESTS
273 #include "util-unittest-helper.h"
274 #include "packet.h"
275 
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  PacketRecycle(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  PacketRecycle(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  PacketRecycle(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  PacketRecycle(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  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:880
decode-tcp.h
Packet_::proto
uint8_t proto
Definition: decode.h:447
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:213
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:212
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:167
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:296
TCP_HEADER_LEN
#define TCP_HEADER_LEN
Definition: decode-tcp.h:28
Packet_::payload
uint8_t * payload
Definition: decode.h:567
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:168
TCP_OPT_SACKOK_LEN
#define TCP_OPT_SACKOK_LEN
Definition: decode-tcp.h:59
TCP_PKT_TOO_SMALL
@ TCP_PKT_TOO_SMALL
Definition: decode-events.h:94
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
TCP_OPT_INVALID_LEN
@ TCP_OPT_INVALID_LEN
Definition: decode-events.h:99
Packet_::tcpvars
TCPVars tcpvars
Definition: decode.h:539
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
TCPVars_::md5_option_present
bool md5_option_present
Definition: decode-tcp.h:157
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:568
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
util-unittest-helper.h
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:82
TCP_GET_WSCALE
#define TCP_GET_WSCALE(p)
Definition: decode-tcp.h:100
TCPVars_::tfo
TCPOpt tfo
Definition: decode-tcp.h:166
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:543
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:175
TCP_OPT_SACK_MAX_LEN
#define TCP_OPT_SACK_MAX_LEN
Definition: decode-tcp.h:64
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
Packet_::sp
Port sp
Definition: decode.h:432
TCPVars_::mss
TCPOpt mss
Definition: decode-tcp.h:165
Packet_
Definition: decode.h:425
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:525
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:677
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:248
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:160
TCPVars_::ws
TCPOpt ws
Definition: decode-tcp.h:164
TCP_OPT_DUPLICATE
@ TCP_OPT_DUPLICATE
Definition: decode-events.h:100
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:403
suricata-common.h
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:547
TCP_OPTMAX
#define TCP_OPTMAX
Definition: decode-tcp.h:30
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:690
packet.h
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: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:173
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:402
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:659
TCP_OPTLENMAX
#define TCP_OPTLENMAX
Definition: decode-tcp.h:29
SET_OPTS
#define SET_OPTS(dst, src)
Definition: decode-tcp.c:42
TCP_GET_HLEN
#define TCP_GET_HLEN(p)
Definition: decode-tcp.h:111
Address_::family
char family
Definition: decode.h:112
Packet_::dst
Address dst
Definition: decode.h:430
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:888
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:40
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_INVALID_OPTLEN
@ TCP_INVALID_OPTLEN
Definition: decode-events.h:96
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:440
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:179
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:424
Packet_::src
Address src
Definition: decode.h:429
TCP_OPT_TFO
#define TCP_OPT_TFO
Definition: decode-tcp.h:53
TCP_HLEN_TOO_SMALL
@ TCP_HLEN_TOO_SMALL
Definition: decode-events.h:95
TCP_OPT_TS
#define TCP_OPT_TS
Definition: decode-tcp.h:52