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, 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 < TCP_OPT_SACK_MIN_LEN ||
142  olen > TCP_OPT_SACK_MAX_LEN ||
143  !((olen - 2) % 8 == 0))
144  {
146  } else {
147  if (p->tcpvars.sack.type != 0) {
149  } else {
150  SET_OPTS(p->tcpvars.sack, tcp_opts[tcp_opt_cnt]);
151  }
152  }
153  break;
154  }
155 
156  pkt += olen;
157  plen -= olen;
158  tcp_opt_cnt++;
159  }
160  }
161 }
162 
163 static int DecodeTCPPacket(ThreadVars *tv, Packet *p, uint8_t *pkt, uint16_t len)
164 {
165  if (unlikely(len < TCP_HEADER_LEN)) {
167  return -1;
168  }
169 
170  p->tcph = (TCPHdr *)pkt;
171 
172  uint8_t hlen = TCP_GET_HLEN(p);
173  if (unlikely(len < hlen)) {
175  return -1;
176  }
177 
178  uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN;
179  if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) {
181  return -1;
182  }
183 
184  if (likely(tcp_opt_len > 0)) {
185  DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len);
186  }
187 
188  SET_TCP_SRC_PORT(p,&p->sp);
189  SET_TCP_DST_PORT(p,&p->dp);
190 
191  p->proto = IPPROTO_TCP;
192 
193  p->payload = pkt + hlen;
194  p->payload_len = len - hlen;
195 
196  return 0;
197 }
198 
199 int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
200 {
201  StatsIncr(tv, dtv->counter_tcp);
202 
203  if (unlikely(DecodeTCPPacket(tv, p,pkt,len) < 0)) {
204  SCLogDebug("invalid TCP packet");
205  p->tcph = NULL;
206  return TM_ECODE_FAILED;
207  }
208 
209 #ifdef DEBUG
210  SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s",
212  TCP_HAS_SACKOK(p) ? "SACKOK " : "", TCP_HAS_SACK(p) ? "SACK " : "",
213  TCP_HAS_WSCALE(p) ? "WS " : "", TCP_HAS_TS(p) ? "TS " : "",
214  TCP_HAS_MSS(p) ? "MSS " : "");
215 #endif
216 
217  FlowSetupPacket(p);
218 
219  return TM_ECODE_OK;
220 }
221 
222 #ifdef UNITTESTS
223 static int TCPCalculateValidChecksumtest01(void)
224 {
225  uint16_t csum = 0;
226 
227  uint8_t raw_ipshdr[] = {
228  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
229 
230  uint8_t raw_tcp[] = {
231  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
232  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
233  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
234  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
235  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02};
236 
237  csum = *( ((uint16_t *)raw_tcp) + 8);
238 
239  FAIL_IF(TCPChecksum((uint16_t *)raw_ipshdr,
240  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) != 0);
241  PASS;
242 }
243 
244 static int TCPCalculateInvalidChecksumtest02(void)
245 {
246  uint16_t csum = 0;
247 
248  uint8_t raw_ipshdr[] = {
249  0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03};
250 
251  uint8_t raw_tcp[] = {
252  0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c,
253  0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0,
254  0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
255  0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73,
256  0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 03};
257 
258  csum = *( ((uint16_t *)raw_tcp) + 8);
259 
260  FAIL_IF(TCPChecksum((uint16_t *) raw_ipshdr,
261  (uint16_t *)raw_tcp, sizeof(raw_tcp), csum) == 0);
262  PASS;
263 }
264 
265 static int TCPV6CalculateValidChecksumtest03(void)
266 {
267  uint16_t csum = 0;
268 
269  static uint8_t raw_ipv6[] = {
270  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
271  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
272  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
273  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
274  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
275  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
276  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
277  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
278  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
279  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
280  0xca, 0x5a, 0x00, 0x01, 0x69, 0x27};
281 
282  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
283 
284  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
285  (uint16_t *)(raw_ipv6 + 54), 32, csum) != 0);
286  PASS;
287 }
288 
289 static int TCPV6CalculateInvalidChecksumtest04(void)
290 {
291  uint16_t csum = 0;
292 
293  static uint8_t raw_ipv6[] = {
294  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
295  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
296  0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe,
297  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
298  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
299  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
300  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe,
301  0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a,
302  0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1,
303  0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08,
304  0xca, 0x5a, 0x00, 0x01, 0x69, 0x28};
305 
306  csum = *( ((uint16_t *)(raw_ipv6 + 70)));
307 
308  FAIL_IF(TCPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
309  (uint16_t *)(raw_ipv6 + 54), 32, csum) == 0);
310  PASS;
311 }
312 
313 /** \test Get the wscale of 2 */
314 static int TCPGetWscaleTest01(void)
315 {
316  int retval = 0;
317  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
318  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
319  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
320  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
321  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02};
322  Packet *p = PacketGetFromAlloc();
323  if (unlikely(p == NULL))
324  return 0;
325  IPV4Hdr ip4h;
326  ThreadVars tv;
327  DecodeThreadVars dtv;
328 
329  memset(&tv, 0, sizeof(ThreadVars));
330  memset(&dtv, 0, sizeof(DecodeThreadVars));
331  memset(&ip4h, 0, sizeof(IPV4Hdr));
332 
333  p->src.family = AF_INET;
334  p->dst.family = AF_INET;
335  p->ip4h = &ip4h;
336 
337 
339  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL);
340 
341  if (p->tcph == NULL) {
342  printf("tcp packet decode failed: ");
343  goto end;
344  }
345 
346  uint8_t wscale = TCP_GET_WSCALE(p);
347  if (wscale != 2) {
348  printf("wscale %"PRIu8", expected 2: ", wscale);
349  goto end;
350  }
351 
352  retval = 1;
353 end:
354  PACKET_RECYCLE(p);
355  FlowShutdown();
356  SCFree(p);
357  return retval;
358 }
359 
360 /** \test Get the wscale of 15, so see if return 0 properly */
361 static int TCPGetWscaleTest02(void)
362 {
363  int retval = 0;
364  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58,
365  0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0,
366  0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4,
367  0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28,
368  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f};
369  Packet *p = PacketGetFromAlloc();
370  if (unlikely(p == NULL))
371  return 0;
372  IPV4Hdr ip4h;
373  ThreadVars tv;
374  DecodeThreadVars dtv;
375 
376  memset(&tv, 0, sizeof(ThreadVars));
377  memset(&dtv, 0, sizeof(DecodeThreadVars));
378  memset(&ip4h, 0, sizeof(IPV4Hdr));
379 
380  p->src.family = AF_INET;
381  p->dst.family = AF_INET;
382  p->ip4h = &ip4h;
383 
385  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL);
386 
387  if (p->tcph == NULL) {
388  printf("tcp packet decode failed: ");
389  goto end;
390  }
391 
392  uint8_t wscale = TCP_GET_WSCALE(p);
393  if (wscale != 0) {
394  printf("wscale %"PRIu8", expected 0: ", wscale);
395  goto end;
396  }
397 
398  retval = 1;
399 end:
400  PACKET_RECYCLE(p);
401  FlowShutdown();
402  SCFree(p);
403  return retval;
404 }
405 
406 /** \test Get the wscale, but it's missing, so see if return 0 properly */
407 static int TCPGetWscaleTest03(void)
408 {
409  int retval = 0;
410  static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59,
411  0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4,
412  0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
413  0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00};
414  Packet *p = PacketGetFromAlloc();
415  if (unlikely(p == NULL))
416  return 0;
417  IPV4Hdr ip4h;
418  ThreadVars tv;
419  DecodeThreadVars dtv;
420 
421  memset(&tv, 0, sizeof(ThreadVars));
422  memset(&dtv, 0, sizeof(DecodeThreadVars));
423  memset(&ip4h, 0, sizeof(IPV4Hdr));
424 
425  p->src.family = AF_INET;
426  p->dst.family = AF_INET;
427  p->ip4h = &ip4h;
428 
430  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL);
431 
432  if (p->tcph == NULL) {
433  printf("tcp packet decode failed: ");
434  goto end;
435  }
436 
437  uint8_t wscale = TCP_GET_WSCALE(p);
438  if (wscale != 0) {
439  printf("wscale %"PRIu8", expected 0: ", wscale);
440  goto end;
441  }
442 
443  retval = 1;
444 end:
445  PACKET_RECYCLE(p);
446  FlowShutdown();
447  SCFree(p);
448  return retval;
449 }
450 
451 static int TCPGetSackTest01(void)
452 {
453  int retval = 0;
454  static uint8_t raw_tcp[] = {
455  0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5,
456  0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc,
457  0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12,
458  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
459  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
460  static uint8_t raw_tcp_sack[] = {
461  0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64,
462  0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 };
463  Packet *p = PacketGetFromAlloc();
464  if (unlikely(p == NULL))
465  return 0;
466  IPV4Hdr ip4h;
467  ThreadVars tv;
468  DecodeThreadVars dtv;
469 
470  memset(&tv, 0, sizeof(ThreadVars));
471  memset(&dtv, 0, sizeof(DecodeThreadVars));
472  memset(&ip4h, 0, sizeof(IPV4Hdr));
473 
474  p->src.family = AF_INET;
475  p->dst.family = AF_INET;
476  p->ip4h = &ip4h;
477 
479  DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL);
480 
481  if (p->tcph == NULL) {
482  printf("tcp packet decode failed: ");
483  goto end;
484  }
485 
486  if (!TCP_HAS_SACK(p)) {
487  printf("tcp packet sack not decoded: ");
488  goto end;
489  }
490 
491  int sack = TCP_GET_SACK_CNT(p);
492  if (sack != 2) {
493  printf("expected 2 sack records, got %u: ", TCP_GET_SACK_CNT(p));
494  goto end;
495  }
496 
497  uint8_t *sackptr = TCP_GET_SACK_PTR(p);
498  if (sackptr == NULL) {
499  printf("no sack data: ");
500  goto end;
501  }
502 
503  if (memcmp(sackptr, raw_tcp_sack, 16) != 0) {
504  printf("malformed sack data: ");
505  goto end;
506  }
507 
508  retval = 1;
509 end:
510  PACKET_RECYCLE(p);
511  FlowShutdown();
512  SCFree(p);
513  return retval;
514 }
515 #endif /* UNITTESTS */
516 
518 {
519 #ifdef UNITTESTS
520  UtRegisterTest("TCPCalculateValidChecksumtest01",
521  TCPCalculateValidChecksumtest01);
522  UtRegisterTest("TCPCalculateInvalidChecksumtest02",
523  TCPCalculateInvalidChecksumtest02);
524  UtRegisterTest("TCPV6CalculateValidChecksumtest03",
525  TCPV6CalculateValidChecksumtest03);
526  UtRegisterTest("TCPV6CalculateInvalidChecksumtest04",
527  TCPV6CalculateInvalidChecksumtest04);
528  UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01);
529  UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02);
530  UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03);
531  UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01);
532 #endif /* UNITTESTS */
533 }
534 /**
535  * @}
536  */
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:152
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:989
#define SCLogDebug(...)
Definition: util-debug.h:335
#define TCP_OPT_WS_LEN
Definition: decode-tcp.h:56
uint8_t len
Definition: decode-tcp.h:125
#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 PACKET_RECYCLE(p)
Definition: decode.h:814
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-tcp.c:199
#define TCP_HAS_MSS(p)
Definition: decode-tcp.h:90
#define TCP_HEADER_LEN
Definition: decode-tcp.h:28
TCPHdr * tcph
Definition: decode.h:522
uint32_t ts_val
Definition: decode-tcp.h:151
#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:55
TCPOpt sackok
Definition: decode-tcp.h:154
uint8_t type
Definition: decode-tcp.h:124
#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:59
#define TCP_OPT_SACK_MAX_LEN
Definition: decode-tcp.h:60
#define TCP_HAS_SACK(p)
Definition: decode-tcp.h:87
#define TCP_OPT_NOP
Definition: decode-tcp.h:48
#define TCP_HAS_TS(p)
Definition: decode-tcp.h:89
uint8_t type
#define TCP_GET_WSCALE(p)
Definition: decode-tcp.h:93
void DecodeTCPRegisterTests(void)
Definition: decode-tcp.c:517
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
uint8_t * data
Definition: decode-tcp.h:126
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:163
#define TCP_OPTMAX
Definition: decode-tcp.h:30
#define SCNtohl(x)
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:99
#define TCP_GET_SACK_PTR(p)
Definition: decode-tcp.h:98
#define SCFree(a)
Definition: util-mem.h:322
TCPOpt mss
Definition: decode-tcp.h:156
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:667
#define TCP_HAS_SACKOK(p)
Definition: decode-tcp.h:88
#define GET_TCP_DST_PORT(p)
Definition: decode.h:222
#define TCP_OPT_TS_LEN
Definition: decode-tcp.h:57
#define TCP_OPTLENMAX
Definition: decode-tcp.h:29
#define TCP_GET_HLEN(p)
Definition: decode-tcp.h:104
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:58
#define likely(expr)
Definition: util-optimize.h:32
_Bool ts_set
Definition: decode-tcp.h:150
TCPOpt sack
Definition: decode-tcp.h:153
#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:997
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:86
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:512
TCPOpt ws
Definition: decode-tcp.h:155