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