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