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  }
187 
188  pkt += olen;
189  plen -= olen;
190  tcp_opt_cnt++;
191  }
192  }
193 }
194 
195 static int DecodeTCPPacket(ThreadVars *tv, Packet *p, const uint8_t *pkt, uint16_t len)
196 {
197  if (unlikely(len < TCP_HEADER_LEN)) {
199  return -1;
200  }
201 
202  p->tcph = (TCPHdr *)pkt;
203 
204  uint8_t hlen = TCP_GET_HLEN(p);
205  if (unlikely(len < hlen)) {
207  return -1;
208  }
209 
210  uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN;
211  if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) {
213  return -1;
214  }
215 
216  if (likely(tcp_opt_len > 0)) {
217  DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len);
218  }
219 
220  SET_TCP_SRC_PORT(p,&p->sp);
221  SET_TCP_DST_PORT(p,&p->dp);
222 
223  p->proto = IPPROTO_TCP;
224 
225  p->payload = (uint8_t *)pkt + hlen;
226  p->payload_len = len - hlen;
227 
228  return 0;
229 }
230 
232  const uint8_t *pkt, uint16_t len)
233 {
235 
236  if (unlikely(DecodeTCPPacket(tv, p, pkt,len) < 0)) {
237  SCLogDebug("invalid TCP packet");
238  CLEAR_TCP_PACKET(p);
239  return TM_ECODE_FAILED;
240  }
241 
242 #ifdef DEBUG
243  SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s",
245  TCP_HAS_SACKOK(p) ? "SACKOK " : "", TCP_HAS_SACK(p) ? "SACK " : "",
246  TCP_HAS_WSCALE(p) ? "WS " : "", TCP_HAS_TS(p) ? "TS " : "",
247  TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : "");
248 #endif
249 
250  FlowSetupPacket(p);
251 
252  return TM_ECODE_OK;
253 }
254 
255 #ifdef UNITTESTS
256 static int TCPCalculateValidChecksumtest01(void)
257 {
258  uint16_t csum = 0;
259 
260  uint8_t raw_ipshdr[] = {
261  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
262 
263  uint8_t raw_tcp[] = {
264  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
265  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
266  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
267  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
268  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02};
269 
270  csum = *( ((uint16_t *)raw_tcp) + 8);
271 
272  FAIL_IF(TCPChecksum((uint16_t *)raw_ipshdr,
273  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0);
274  PASS;
275 }
276 
277 static int TCPCalculateInvalidChecksumtest02(void)
278 {
279  uint16_t csum = 0;
280 
281  uint8_t raw_ipshdr[] = {
282  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
283 
284  uint8_t raw_tcp[] = {
285  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
286  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
287  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
288  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
289  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 03};
290 
291  csum = *( ((uint16_t *)raw_tcp) + 8);
292 
293  FAIL_IF(TCPChecksum((uint16_t *) raw_ipshdr,
294  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) == 0);
295  PASS;
296 }
297 
298 static int TCPV6CalculateValidChecksumtest03(void)
299 {
300  uint16_t csum = 0;
301 
302  static uint8_t raw_ipv6[] = {
303  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
304  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
305  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
306  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
307  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
308  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
309  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
310  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
311  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
312  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
313  0xca, 0x5a, 0x00, 0x01, 0x69, 0x27};
314 
315  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
316 
317  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
318  (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0);
319  PASS;
320 }
321 
322 static int TCPV6CalculateInvalidChecksumtest04(void)
323 {
324  uint16_t csum = 0;
325 
326  static uint8_t raw_ipv6[] = {
327  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
328  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
329  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
330  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
331  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
332  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
333  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
334  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
335  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
336  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
337  0xca, 0x5a, 0x00, 0x01, 0x69, 0x28};
338 
339  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
340 
341  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
342  (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0);
343  PASS;
344 }
345 
346 /** \test Get the wscale of 2 */
347 static int TCPGetWscaleTest01(void)
348 {
349  int retval = 0;
350  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
351  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
352  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
353  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
354  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
355  Packet *p = PacketGetFromAlloc();
356  if (unlikely(p == NULL))
357  return 0;
358  IPV4Hdr ip4h;
359  ThreadVars tv;
361 
362  memset(&tv, 0, sizeof(ThreadVars));
363  memset(&dtv, 0, sizeof(DecodeThreadVars));
364  memset(&ip4h, 0, sizeof(IPV4Hdr));
365 
366  p->src.family = AF_INET;
367  p->dst.family = AF_INET;
368  p->ip4h = &ip4h;
369 
370 
372  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
373 
374  if (p->tcph == NULL) {
375  printf("tcp packet decode failed: ");
376  goto end;
377  }
378 
379  uint8_t wscale = TCP_GET_WSCALE(p);
380  if (wscale != 2) {
381  printf("wscale %"PRIu8", expected 2: ", wscale);
382  goto end;
383  }
384 
385  retval = 1;
386 end:
387  PACKET_RECYCLE(p);
388  FlowShutdown();
389  SCFree(p);
390  return retval;
391 }
392 
393 /** \test Get the wscale of 15, so see if return 0 properly */
394 static int TCPGetWscaleTest02(void)
395 {
396  int retval = 0;
397  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
398  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
399  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
400  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
401  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f};
402  Packet *p = PacketGetFromAlloc();
403  if (unlikely(p == NULL))
404  return 0;
405  IPV4Hdr ip4h;
406  ThreadVars tv;
408 
409  memset(&tv, 0, sizeof(ThreadVars));
410  memset(&dtv, 0, sizeof(DecodeThreadVars));
411  memset(&ip4h, 0, sizeof(IPV4Hdr));
412 
413  p->src.family = AF_INET;
414  p->dst.family = AF_INET;
415  p->ip4h = &ip4h;
416 
418  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
419 
420  if (p->tcph == NULL) {
421  printf("tcp packet decode failed: ");
422  goto end;
423  }
424 
425  uint8_t wscale = TCP_GET_WSCALE(p);
426  if (wscale != 0) {
427  printf("wscale %"PRIu8", expected 0: ", wscale);
428  goto end;
429  }
430 
431  retval = 1;
432 end:
433  PACKET_RECYCLE(p);
434  FlowShutdown();
435  SCFree(p);
436  return retval;
437 }
438 
439 /** \test Get the wscale, but it's missing, so see if return 0 properly */
440 static int TCPGetWscaleTest03(void)
441 {
442  int retval = 0;
443  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59,
444  0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4,
445  0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
446  0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00};
447  Packet *p = PacketGetFromAlloc();
448  if (unlikely(p == NULL))
449  return 0;
450  IPV4Hdr ip4h;
451  ThreadVars tv;
453 
454  memset(&tv, 0, sizeof(ThreadVars));
455  memset(&dtv, 0, sizeof(DecodeThreadVars));
456  memset(&ip4h, 0, sizeof(IPV4Hdr));
457 
458  p->src.family = AF_INET;
459  p->dst.family = AF_INET;
460  p->ip4h = &ip4h;
461 
463  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
464 
465  if (p->tcph == NULL) {
466  printf("tcp packet decode failed: ");
467  goto end;
468  }
469 
470  uint8_t wscale = TCP_GET_WSCALE(p);
471  if (wscale != 0) {
472  printf("wscale %"PRIu8", expected 0: ", wscale);
473  goto end;
474  }
475 
476  retval = 1;
477 end:
478  PACKET_RECYCLE(p);
479  FlowShutdown();
480  SCFree(p);
481  return retval;
482 }
483 
484 static int TCPGetSackTest01(void)
485 {
486  int retval = 0;
487  static uint8_t raw_tcp[] = {
488  0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
489  0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
490  0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
491  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
492  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
493  static uint8_t raw_tcp_sack[] = {
494  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
495  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
496  Packet *p = PacketGetFromAlloc();
497  if (unlikely(p == NULL))
498  return 0;
499  IPV4Hdr ip4h;
500  ThreadVars tv;
502 
503  memset(&tv, 0, sizeof(ThreadVars));
504  memset(&dtv, 0, sizeof(DecodeThreadVars));
505  memset(&ip4h, 0, sizeof(IPV4Hdr));
506 
507  p->src.family = AF_INET;
508  p->dst.family = AF_INET;
509  p->ip4h = &ip4h;
510 
512  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp));
513 
514  if (p->tcph == NULL) {
515  printf("tcp packet decode failed: ");
516  goto end;
517  }
518 
519  if (!TCP_HAS_SACK(p)) {
520  printf("tcp packet sack not decoded: ");
521  goto end;
522  }
523 
524  int sack = TCP_GET_SACK_CNT(p);
525  if (sack != 2) {
526  printf("expected 2 sack records, got %u: ", TCP_GET_SACK_CNT(p));
527  goto end;
528  }
529 
530  const uint8_t *sackptr = TCP_GET_SACK_PTR(p);
531  if (sackptr == NULL) {
532  printf("no sack data: ");
533  goto end;
534  }
535 
536  if (memcmp(sackptr, raw_tcp_sack, 16) != 0) {
537  printf("malformed sack data: ");
538  goto end;
539  }
540 
541  retval = 1;
542 end:
543  PACKET_RECYCLE(p);
544  FlowShutdown();
545  SCFree(p);
546  return retval;
547 }
548 #endif /* UNITTESTS */
549 
551 {
552 #ifdef UNITTESTS
553  UtRegisterTest("TCPCalculateValidChecksumtest01",
554  TCPCalculateValidChecksumtest01);
555  UtRegisterTest("TCPCalculateInvalidChecksumtest02",
556  TCPCalculateInvalidChecksumtest02);
557  UtRegisterTest("TCPV6CalculateValidChecksumtest03",
558  TCPV6CalculateValidChecksumtest03);
559  UtRegisterTest("TCPV6CalculateInvalidChecksumtest04",
560  TCPV6CalculateInvalidChecksumtest04);
561  UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01);
562  UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02);
563  UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03);
564  UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01);
565 #endif /* UNITTESTS */
566 }
567 /**
568  * @}
569  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1015
host.h
decode-tcp.h
Packet_::proto
uint8_t proto
Definition: decode.h:437
len
uint8_t len
Definition: app-layer-dnp3.h:2
TCPOpt_
Definition: decode-tcp.h:128
TCP_OPT_WS_LEN
#define TCP_OPT_WS_LEN
Definition: decode-tcp.h:58
GET_TCP_DST_PORT
#define GET_TCP_DST_PORT(p)
Definition: decode.h:229
TCP_OPT_SACKOK
#define TCP_OPT_SACKOK
Definition: decode-tcp.h:50
TCPVars_::sackok
TCPOpt sackok
Definition: decode-tcp.h:159
GET_TCP_SRC_PORT
#define GET_TCP_SRC_PORT(p)
Definition: decode.h:228
TCPVars_::ts_set
bool ts_set
Definition: decode-tcp.h:155
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:95
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:552
TCP_OPT_SACKOK_LEN
#define TCP_OPT_SACKOK_LEN
Definition: decode-tcp.h:57
FlowInitConfig
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:516
TCP_OPT_EXP2
#define TCP_OPT_EXP2
Definition: decode-tcp.h:55
TCP_HAS_MSS
#define TCP_HAS_MSS(p)
Definition: decode-tcp.h:94
Packet_::tcpvars
TCPVars tcpvars
Definition: decode.h:524
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:553
TCP_OPT_EOL
#define TCP_OPT_EOL
Definition: decode-tcp.h:46
TCPOpt_::data
const uint8_t * data
Definition: decode-tcp.h:131
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:98
TCPVars_::tfo
TCPOpt tfo
Definition: decode-tcp.h:162
decode.h
TCPVars_::ts_ecr
uint32_t ts_ecr
Definition: decode-tcp.h:157
TCPOpt_::type
uint8_t type
Definition: decode-tcp.h:129
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:191
TCP_INVALID_OPTLEN
@ TCP_INVALID_OPTLEN
Definition: decode-events.h:96
TCP_OPT_SACK_MAX_LEN
#define TCP_OPT_SACK_MAX_LEN
Definition: decode-tcp.h:62
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
Packet_::sp
Port sp
Definition: decode.h:422
TCP_HLEN_TOO_SMALL
@ TCP_HLEN_TOO_SMALL
Definition: decode-events.h:95
TCPVars_::mss
TCPOpt mss
Definition: decode-tcp.h:161
TRUE
#define TRUE
Definition: suricata-common.h:33
util-profiling.h
Packet_
Definition: decode.h:415
TCP_GET_SACK_CNT
#define TCP_GET_SACK_CNT(p)
Definition: decode-tcp.h:104
TCP_OPT_SACK_MIN_LEN
#define TCP_OPT_SACK_MIN_LEN
Definition: decode-tcp.h:61
TCP_HAS_SACK
#define TCP_HAS_SACK(p)
Definition: decode-tcp.h:91
TCP_OPT_NOP
#define TCP_OPT_NOP
Definition: decode-tcp.h:47
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:510
TCP_HAS_TS
#define TCP_HAS_TS(p)
Definition: decode-tcp.h:93
TCPOpt_::len
uint8_t len
Definition: decode-tcp.h:130
DecodeTCPRegisterTests
void DecodeTCPRegisterTests(void)
Definition: decode-tcp.c:550
DecodeThreadVars_::counter_tcp
uint16_t counter_tcp
Definition: decode.h:652
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:231
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:156
TCPVars_::ws
TCPOpt ws
Definition: decode-tcp.h:160
TCP_HAS_SACKOK
#define TCP_HAS_SACKOK(p)
Definition: decode-tcp.h:92
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:395
suricata-common.h
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:532
TCP_OPTMAX
#define TCP_OPTMAX
Definition: decode-tcp.h:30
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:644
TCP_OPT_DUPLICATE
@ TCP_OPT_DUPLICATE
Definition: decode-events.h:100
CLEAR_TCP_PACKET
#define CLEAR_TCP_PACKET(p)
Definition: decode-tcp.h:165
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
TCP_OPT_SACK
#define TCP_OPT_SACK
Definition: decode-tcp.h:51
TCP_PKT_TOO_SMALL
@ TCP_PKT_TOO_SMALL
Definition: decode-events.h:94
TCP_OPT_INVALID_LEN
@ TCP_OPT_INVALID_LEN
Definition: decode-events.h:99
util-optimize.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:146
TCP_GET_SACK_PTR
#define TCP_GET_SACK_PTR(p)
Definition: decode-tcp.h:103
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:634
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:109
Address_::family
char family
Definition: decode.h:119
Packet_::dst
Address dst
Definition: decode.h:420
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1023
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:39
TCP_HAS_WSCALE
#define TCP_HAS_WSCALE(p)
Definition: decode-tcp.h:90
likely
#define likely(expr)
Definition: util-optimize.h:32
TCP_OPT_MSS_LEN
#define TCP_OPT_MSS_LEN
Definition: decode-tcp.h:60
TCPVars_::sack
TCPOpt sack
Definition: decode-tcp.h:158
TCP_OPT_TFO_MAX_LEN
#define TCP_OPT_TFO_MAX_LEN
Definition: decode-tcp.h:64
flow.h
Packet_::dp
Port dp
Definition: decode.h:430
TCP_OPT_TS_LEN
#define TCP_OPT_TS_LEN
Definition: decode-tcp.h:59
SET_TCP_DST_PORT
#define SET_TCP_DST_PORT(pkt, prt)
Definition: decode.h:195
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:419
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:836
TCP_OPT_TFO
#define TCP_OPT_TFO
Definition: decode-tcp.h:53
TCP_OPT_TS
#define TCP_OPT_TS
Definition: decode-tcp.h:52