suricata
detect-engine-port.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2019 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  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Ports part of the detection engine.
24  *
25  * \todo more unit testing
26  *
27  */
28 
29 #include "suricata-common.h"
30 #include "decode.h"
31 #include "detect.h"
32 #include "flow-var.h"
33 
34 #include "util-cidr.h"
35 #include "util-unittest.h"
36 #include "util-unittest-helper.h"
37 #include "util-rule-vars.h"
38 
39 #include "detect-parse.h"
40 #include "detect-engine.h"
41 #include "detect-engine-mpm.h"
42 
43 #include "detect-engine-siggroup.h"
44 #include "detect-engine-port.h"
45 
46 #include "conf.h"
47 #include "util-debug.h"
48 #include "util-error.h"
49 
50 #include "pkt-var.h"
51 #include "host.h"
52 #include "util-profiling.h"
53 #include "util-var.h"
54 #include "util-byte.h"
55 
56 static int DetectPortCutNot(DetectPort *, DetectPort **);
57 static int DetectPortCut(DetectEngineCtx *, DetectPort *, DetectPort *,
58  DetectPort **);
59 DetectPort *PortParse(const char *str);
60 static bool DetectPortIsValidRange(char *, uint16_t *);
61 
62 /**
63  * \brief Alloc a DetectPort structure and update counters
64  *
65  * \retval dp newly created DetectPort on success; or NULL in case of error.
66  */
67 static DetectPort *DetectPortInit(void)
68 {
69  DetectPort *dp = SCCalloc(1, sizeof(DetectPort));
70  if (unlikely(dp == NULL))
71  return NULL;
72  return dp;
73 }
74 
75 /**
76  * \brief Free a DetectPort and its members
77  *
78  * \param dp Pointer to the DetectPort that has to be freed.
79  */
81 {
82  if (dp == NULL)
83  return;
84 
85  /* only free the head if we have the original */
86  if (dp->sh != NULL && !(dp->flags & PORT_SIGGROUPHEAD_COPY)) {
88  }
89  dp->sh = NULL;
90 
91  SCFree(dp);
92 }
93 
94 /**
95  * \brief Helper function used to print the list of ports
96  * present in this DetectPort list.
97  *
98  * \param head Pointer to the DetectPort list head
99  */
101 {
102  DetectPort *cur;
103 #ifdef DEBUG
104  uint16_t cnt = 0;
105 #endif
106  SCLogDebug("= list start:");
107  if (head != NULL) {
108  for (cur = head; cur != NULL; cur = cur->next) {
109  DetectPortPrint(cur);
110 #ifdef DEBUG
111  cnt++;
112 #endif
113  }
114  SCLogDebug(" ");
115  }
116  SCLogDebug("= list end (cnt %" PRIu32 ")", cnt);
117 }
118 
119 /**
120  * \brief Free a DetectPort list and each of its members
121  *
122  * \param head Pointer to the DetectPort list head
123  */
125 {
126  if (head == NULL)
127  return;
128 
129  DetectPort *cur, *next;
130 
131  for (cur = head; cur != NULL; ) {
132  next = cur->next;
133  cur->next = NULL;
134  DetectPortFree(de_ctx, cur);
135  cur = next;
136  }
137 }
138 
139 /**
140  * \brief function for inserting a port group object. This also makes sure
141  * SigGroupContainer lists are handled correctly.
142  *
143  * \param de_ctx Pointer to the current detection engine context
144  * \param head Pointer to the DetectPort list head
145  * \param dp DetectPort to search in the DetectPort list
146  *
147  * \retval 1 inserted
148  * \retval 0 not inserted, memory of new is freed
149  * \retval -1 error
150  *
151  * \todo rewrite to avoid recursive calls
152  * */
154  DetectPort *new)
155 {
156  if (new == NULL)
157  return 0;
158 
159  //BUG_ON(new->next != NULL);
160  //BUG_ON(new->prev != NULL);
161 
162  /* see if it already exists or overlaps with existing ports */
163  if (*head != NULL) {
164  DetectPort *cur = NULL;
165  int r = 0;
166 
167  for (cur = *head; cur != NULL; cur = cur->next) {
168  r = DetectPortCmp(new,cur);
169  BUG_ON(r == PORT_ER);
170 
171  /* if so, handle that */
172  if (r == PORT_EQ) {
173  SCLogDebug("PORT_EQ %p %p", cur, new);
174  /* exact overlap/match */
175  if (cur != new) {
176  SigGroupHeadCopySigs(de_ctx, new->sh, &cur->sh);
177  DetectPortFree(de_ctx, new);
178  return 0;
179  }
180  return 1;
181  } else if (r == PORT_GT) {
182  SCLogDebug("PORT_GT (cur->next %p)", cur->next);
183  /* only add it now if we are bigger than the last
184  * group. Otherwise we'll handle it later. */
185  if (cur->next == NULL) {
186  SCLogDebug("adding GT");
187  /* put in the list */
188  new->prev = cur;
189  cur->next = new;
190  return 1;
191  }
192  } else if (r == PORT_LT) {
193  SCLogDebug("PORT_LT");
194 
195  /* see if we need to insert the ag anywhere */
196  /* put in the list */
197  if (cur->prev != NULL)
198  cur->prev->next = new;
199  new->prev = cur->prev;
200  new->next = cur;
201  cur->prev = new;
202 
203  /* update head if required */
204  if (*head == cur) {
205  *head = new;
206  }
207  return 1;
208 
209  /* alright, those were the simple cases,
210  * lets handle the more complex ones now */
211 
212  } else {
213  DetectPort *c = NULL;
214  r = DetectPortCut(de_ctx, cur, new, &c);
215  if (r == -1)
216  goto error;
217 
218  r = DetectPortInsert(de_ctx, head, new);
219  if (r == -1) {
220  if (c != NULL) {
222  }
223  goto error;
224  }
225 
226  if (c != NULL) {
227  SCLogDebug("inserting C (%p)", c);
228  if (SCLogDebugEnabled()) {
229  DetectPortPrint(c);
230  }
231  r = DetectPortInsert(de_ctx, head, c);
232  if (r == -1)
233  goto error;
234  }
235  return 1;
236 
237  }
238  }
239 
240  /* head is NULL, so get a group and set head to it */
241  } else {
242  SCLogDebug("setting new head %p", new);
243  *head = new;
244  }
245 
246  return 1;
247 error:
248  /* XXX */
249  return -1;
250 }
251 
252 /**
253  * \brief Function that cuts port groups and merge them
254  *
255  * \param de_ctx Pointer to the current detection engine context
256  * \param a pointer to DetectPort "a"
257  * \param b pointer to DetectPort "b"
258  * \param c pointer to DetectPort "c"
259  *
260  * \retval 0 ok
261  * \retval -1 error
262  * */
263 static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a,
264  DetectPort *b, DetectPort **c)
265 {
266  uint16_t a_port1 = a->port;
267  uint16_t a_port2 = a->port2;
268  uint16_t b_port1 = b->port;
269  uint16_t b_port2 = b->port2;
270 
271  /* default to NULL */
272  *c = NULL;
273 
274  int r = DetectPortCmp(a,b);
275  BUG_ON(r != PORT_ES && r != PORT_EB && r != PORT_LE && r != PORT_GE);
276 
277  /* get a place to temporary put sigs lists */
278  DetectPort *tmp = DetectPortInit();
279  if (tmp == NULL) {
280  goto error;
281  }
282 
283  /**
284  * We have 3 parts: [aaa[abab]bbb]
285  * part a: a_port1 <-> b_port1 - 1
286  * part b: b_port1 <-> a_port2
287  * part c: a_port2 + 1 <-> b_port2
288  */
289  if (r == PORT_LE) {
290  SCLogDebug("cut r == PORT_LE");
291  a->port = a_port1;
292  a->port2 = b_port1 - 1;
293 
294  b->port = b_port1;
295  b->port2 = a_port2;
296 
297  DetectPort *tmp_c = DetectPortInit();
298  if (tmp_c == NULL) {
299  goto error;
300  }
301  *c = tmp_c;
302 
303  tmp_c->port = a_port2 + 1;
304  tmp_c->port2 = b_port2;
305 
306  SigGroupHeadCopySigs(de_ctx,b->sh,&tmp_c->sh); /* copy old b to c */
307  SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); /* copy a to b */
308 
309  /**
310  * We have 3 parts: [bbb[baba]aaa]
311  * part a: b_port1 <-> a_port1 - 1
312  * part b: a_port1 <-> b_port2
313  * part c: b_port2 + 1 <-> a_port2
314  */
315  } else if (r == PORT_GE) {
316  SCLogDebug("cut r == PORT_GE");
317  a->port = b_port1;
318  a->port2 = a_port1 - 1;
319 
320  b->port = a_port1;
321  b->port2 = b_port2;
322 
323  DetectPort *tmp_c = DetectPortInit();
324  if (tmp_c == NULL) {
325  goto error;
326  }
327  *c = tmp_c;
328 
329  tmp_c->port = b_port2 + 1;
330  tmp_c->port2 = a_port2;
331 
332  /**
333  * 'a' gets clean and then 'b' sigs
334  * 'b' gets clean, then 'a' then 'b' sigs
335  * 'c' gets 'a' sigs
336  */
337  SigGroupHeadCopySigs(de_ctx,a->sh,&tmp->sh); /* store old a list */
338  SigGroupHeadClearSigs(a->sh); /* clean a list */
339  SigGroupHeadCopySigs(de_ctx,tmp->sh,&tmp_c->sh); /* copy old b to c */
340  SigGroupHeadCopySigs(de_ctx,b->sh,&a->sh); /* copy old b to a */
341  SigGroupHeadCopySigs(de_ctx,tmp->sh,&b->sh);/* prepend old a before b */
342 
343  SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
344 
345  /**
346  * We have 2 or three parts:
347  *
348  * 2 part: [[abab]bbb] or [bbb[baba]]
349  * part a: a_port1 <-> a_port2
350  * part b: a_port2 + 1 <-> b_port2
351  *
352  * part a: b_port1 <-> a_port1 - 1
353  * part b: a_port1 <-> a_port2
354  *
355  * 3 part [bbb[aaa]bbb]
356  * becomes[aaa[bbb]ccc]
357  *
358  * part a: b_port1 <-> a_port1 - 1
359  * part b: a_port1 <-> a_port2
360  * part c: a_port2 + 1 <-> b_port2
361  */
362  } else if (r == PORT_ES) {
363  SCLogDebug("cut r == PORT_ES");
364  if (a_port1 == b_port1) {
365  SCLogDebug("1");
366  a->port = a_port1;
367  a->port2 = a_port2;
368 
369  b->port = a_port2 + 1;
370  b->port2 = b_port2;
371 
372  /** 'b' overlaps 'a' so 'a' needs the 'b' sigs */
374 
375  } else if (a_port2 == b_port2) {
376  SCLogDebug("2");
377  a->port = b_port1;
378  a->port2 = a_port1 - 1;
379 
380  b->port = a_port1;
381  b->port2 = a_port2;
382 
383  /* [bbb[baba]] will be transformed into
384  * [aaa][bbb]
385  * steps: copy b sigs to tmp
386  * a overlaps b, so copy a to b
387  * clear a
388  * copy tmp to a */
389  SigGroupHeadCopySigs(de_ctx,b->sh,&tmp->sh); /* store old a list */
391  SigGroupHeadClearSigs(a->sh); /* clean a list */
392  SigGroupHeadCopySigs(de_ctx,tmp->sh,&a->sh);/* merge old a with b */
393  SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
394  } else {
395  SCLogDebug("3");
396  a->port = b_port1;
397  a->port2 = a_port1 - 1;
398 
399  b->port = a_port1;
400  b->port2 = a_port2;
401 
402  DetectPort *tmp_c = DetectPortInit();
403  if (tmp_c == NULL) {
404  goto error;
405  }
406  *c = tmp_c;
407 
408  tmp_c->port = a_port2 + 1;
409  tmp_c->port2 = b_port2;
410 
411  /**
412  * 'a' gets clean and then 'b' sigs
413  * 'b' gets clean, then 'a' then 'b' sigs
414  * 'c' gets 'b' sigs
415  */
416  SigGroupHeadCopySigs(de_ctx,a->sh,&tmp->sh); /* store old a list */
417  SigGroupHeadClearSigs(a->sh); /* clean a list */
418  SigGroupHeadCopySigs(de_ctx,b->sh,&tmp_c->sh); /* copy old b to c */
419  SigGroupHeadCopySigs(de_ctx,b->sh,&a->sh); /* copy old b to a */
420  SigGroupHeadCopySigs(de_ctx,tmp->sh,&b->sh);/* merge old a with b */
421 
422  SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
423  }
424  /**
425  * We have 2 or three parts:
426  *
427  * 2 part: [[baba]aaa] or [aaa[abab]]
428  * part a: b_port1 <-> b_port2
429  * part b: b_port2 + 1 <-> a_port2
430  *
431  * part a: a_port1 <-> b_port1 - 1
432  * part b: b_port1 <-> b_port2
433  *
434  * 3 part [aaa[bbb]aaa]
435  * becomes[aaa[bbb]ccc]
436  *
437  * part a: a_port1 <-> b_port2 - 1
438  * part b: b_port1 <-> b_port2
439  * part c: b_port2 + 1 <-> a_port2
440  */
441  } else if (r == PORT_EB) {
442  SCLogDebug("cut r == PORT_EB");
443  if (a_port1 == b_port1) {
444  SCLogDebug("1");
445  a->port = b_port1;
446  a->port2 = b_port2;
447 
448  b->port = b_port2 + 1;
449  b->port2 = a_port2;
450 
451  /** 'b' overlaps 'a' so 'a' needs the 'b' sigs */
452  SigGroupHeadCopySigs(de_ctx,b->sh,&tmp->sh);
455  SigGroupHeadCopySigs(de_ctx,tmp->sh,&a->sh);
456 
458 
459  } else if (a_port2 == b_port2) {
460  SCLogDebug("2");
461 
462  a->port = a_port1;
463  a->port2 = b_port1 - 1;
464 
465  b->port = b_port1;
466  b->port2 = b_port2;
467 
468  /** 'a' overlaps 'b' so 'b' needs the 'a' sigs */
470 
471  } else {
472  SCLogDebug("3");
473  a->port = a_port1;
474  a->port2 = b_port1 - 1;
475 
476  b->port = b_port1;
477  b->port2 = b_port2;
478 
479  DetectPort *tmp_c = DetectPortInit();
480  if (tmp_c == NULL) {
481  goto error;
482  }
483  *c = tmp_c;
484 
485  tmp_c->port = b_port2 + 1;
486  tmp_c->port2 = a_port2;
487 
489  SigGroupHeadCopySigs(de_ctx,a->sh,&tmp_c->sh);
490  }
491  }
492 
493  if (tmp != NULL) {
494  DetectPortFree(de_ctx, tmp);
495  }
496  return 0;
497 
498 error:
499  if (tmp != NULL)
500  DetectPortFree(de_ctx, tmp);
501  return -1;
502 }
503 
504 /**
505  * \brief Function that cuts port groups implementing group negation
506  *
507  * \param a pointer to DetectPort "a"
508  * \param b pointer to DetectPort "b"
509  *
510  * \retval 0 ok
511  * \retval -1 error
512  * */
513 static int DetectPortCutNot(DetectPort *a, DetectPort **b)
514 {
515  uint16_t a_port1 = a->port;
516  uint16_t a_port2 = a->port2;
517 
518  /* default to NULL */
519  *b = NULL;
520 
521  if (a_port1 != 0x0000 && a_port2 != 0xFFFF) {
522  a->port = 0x0000;
523  a->port2 = a_port1 - 1;
524 
525  DetectPort *tmp_b;
526  tmp_b = DetectPortInit();
527  if (tmp_b == NULL) {
528  return -1;
529  }
530 
531  tmp_b->port = a_port2 + 1;
532  tmp_b->port2 = 0xFFFF;
533  *b = tmp_b;
534 
535  } else if (a_port1 == 0x0000 && a_port2 != 0xFFFF) {
536  a->port = a_port2 + 1;
537  a->port2 = 0xFFFF;
538 
539  } else if (a_port1 != 0x0000 && a_port2 == 0xFFFF) {
540  a->port = 0x0000;
541  a->port2 = a_port1 - 1;
542  } else {
543  return -1;
544  }
545 
546  return 0;
547 }
548 
549 /**
550  * \brief Function that compare port groups
551  *
552  * \param a pointer to DetectPort "a"
553  * \param b pointer to DetectPort "b"
554  *
555  * \retval PORT_XX (Port enum value, XX is EQ, ES, EB, LE, etc)
556  * \retval PORT_ER on error
557  * */
559 {
560  /* check any */
561  if ((a->flags & PORT_FLAG_ANY) && (b->flags & PORT_FLAG_ANY))
562  return PORT_EQ;
563  if ((a->flags & PORT_FLAG_ANY) && !(b->flags & PORT_FLAG_ANY))
564  return PORT_LT;
565  if (!(a->flags & PORT_FLAG_ANY) && (b->flags & PORT_FLAG_ANY))
566  return PORT_GT;
567 
568  uint16_t a_port1 = a->port;
569  uint16_t a_port2 = a->port2;
570  uint16_t b_port1 = b->port;
571  uint16_t b_port2 = b->port2;
572 
573  /* PORT_EQ */
574  if (a_port1 == b_port1 && a_port2 == b_port2) {
575  //SCLogDebug("PORT_EQ");
576  return PORT_EQ;
577  /* PORT_ES */
578  } else if (a_port1 >= b_port1 && a_port1 <= b_port2 && a_port2 <= b_port2) {
579  //SCLogDebug("PORT_ES");
580  return PORT_ES;
581  /* PORT_EB */
582  } else if (a_port1 <= b_port1 && a_port2 >= b_port2) {
583  //SCLogDebug("PORT_EB");
584  return PORT_EB;
585  } else if (a_port1 < b_port1 && a_port2 < b_port2 && a_port2 >= b_port1) {
586  //SCLogDebug("PORT_LE");
587  return PORT_LE;
588  } else if (a_port1 < b_port1 && a_port2 < b_port2) {
589  //SCLogDebug("PORT_LT");
590  return PORT_LT;
591  } else if (a_port1 > b_port1 && a_port1 <= b_port2 && a_port2 > b_port2) {
592  //SCLogDebug("PORT_GE");
593  return PORT_GE;
594  } else if (a_port1 > b_port2) {
595  //SCLogDebug("PORT_GT");
596  return PORT_GT;
597  } else {
598  /* should be unreachable */
599  BUG_ON(1);
600  }
601 
602  return PORT_ER;
603 }
604 
605 /**
606  * \brief Function that return a copy of DetectPort src sigs
607  *
608  * \param de_ctx Pointer to the current Detection Engine Context
609  * \param src Pointer to a DetectPort group to copy
610  *
611  * \retval Pointer to a DetectPort instance (copy of src)
612  * \retval NULL on error
613  * */
615 {
616  if (src == NULL)
617  return NULL;
618 
619  DetectPort *dst = DetectPortInit();
620  if (dst == NULL) {
621  return NULL;
622  }
623 
624  dst->port = src->port;
625  dst->port2 = src->port2;
626 
628  return dst;
629 }
630 
631 /**
632  * \brief Function Match to Match a port against a DetectPort group
633  *
634  * \param dp Pointer to DetectPort group where we try to match the port
635  * \param port To compare/match
636  *
637  * \retval 1 if port is in the range (it match)
638  * \retval 0 if port is not in the range
639  * */
640 static int DetectPortMatch(DetectPort *dp, uint16_t port)
641 {
642  if (port >= dp->port &&
643  port <= dp->port2) {
644  return 1;
645  }
646 
647  return 0;
648 }
649 
650 /**
651  * \brief Helper function that print the DetectPort info
652  * \retval none
653  */
655 {
656  if (dp == NULL)
657  return;
658 
659  if (dp->flags & PORT_FLAG_ANY) {
660  SCLogDebug("=> port %p: ANY", dp);
661 // printf("ANY");
662  } else {
663  SCLogDebug("=> port %p %" PRIu32 "-%" PRIu32 "", dp, dp->port, dp->port2);
664 // printf("%" PRIu32 "-%" PRIu32 "", dp->port, dp->port2);
665  }
666 }
667 
668 /**
669  * \brief Function that find the group matching address in a group head
670  *
671  * \param dp Pointer to DetectPort group where we try to find the group
672  * \param port port to search/lookup
673  *
674  * \retval Pointer to the DetectPort group of our port if it matched
675  * \retval NULL if port is not in the list
676  * */
678 {
679  if (dp == NULL)
680  return NULL;
681 
682  for (DetectPort *p = dp; p != NULL; p = p->next) {
683  if (DetectPortMatch(p, port) == 1) {
684  //SCLogDebug("match, port %" PRIu32 ", dp ", port);
685  //DetectPortPrint(p); SCLogDebug("");
686  return p;
687  }
688  }
689 
690  return NULL;
691 }
692 
693 /**
694  * \brief Checks if two port group lists are equal.
695  *
696  * \param list1 Pointer to the first port group list.
697  * \param list2 Pointer to the second port group list.
698  *
699  * \retval true On success.
700  * \retval false On failure.
701  */
703 {
704  DetectPort *item = list1;
705  DetectPort *it = list2;
706 
707  // First, compare items one by one.
708  while (item != NULL && it != NULL) {
709  if (DetectPortCmp(item, it) != PORT_EQ) {
710  return false;
711  }
712 
713  item = item->next;
714  it = it->next;
715  }
716 
717  // Are the lists of the same size?
718  if (!(item == NULL && it == NULL)) {
719  return false;
720  }
721 
722  return true;
723 }
724 
725 /******************* parsing routines ************************/
726 
727 /**
728  * \brief Wrapper function that call the internal/real function
729  * to insert the new DetectPort
730  * \param head Pointer to the head of the DetectPort group list
731  * \param new Pointer to the new DetectPort group list
732  *
733  * \retval 1 inserted
734  * \retval 0 not inserted, memory of new is freed
735  * \retval -1 error
736  */
737 static int DetectPortParseInsert(DetectPort **head, DetectPort *new)
738 {
739  return DetectPortInsert(NULL, head, new);
740 }
741 
742 /**
743  * \brief Function to parse and insert the string in the DetectPort head list
744  *
745  * \param head Pointer to the head of the DetectPort group list
746  * \param s Pointer to the port string
747  *
748  * \retval 0 on success
749  * \retval -1 on error
750  */
751 static int DetectPortParseInsertString(const DetectEngineCtx *de_ctx,
752  DetectPort **head, const char *s)
753 {
754  DetectPort *ad = NULL, *ad_any = NULL;
755  int r = 0;
756  bool port_any = false;
757 
758  SCLogDebug("head %p, *head %p, s %s", head, *head, s);
759 
760  /** parse the address */
761  ad = PortParse(s);
762  if (ad == NULL) {
763  SCLogError(" failed to parse port \"%s\"", s);
764  return -1;
765  }
766 
767  if (ad->flags & PORT_FLAG_ANY) {
768  port_any = true;
769  }
770 
771  /** handle the not case, we apply the negation then insert the part(s) */
772  if (ad->flags & PORT_FLAG_NOT) {
773  DetectPort *ad2 = NULL;
774 
775  if (DetectPortCutNot(ad, &ad2) < 0) {
776  goto error;
777  }
778 
779  /** normally a 'not' will result in two ad's unless the 'not' is on the
780  * start or end of the address space(e.g. 0.0.0.0 or 255.255.255.255)
781  */
782  if (ad2 != NULL) {
783  if (DetectPortParseInsert(head, ad2) < 0) {
784  if (ad2 != NULL) SCFree(ad2);
785  goto error;
786  }
787  }
788  }
789 
790  r = DetectPortParseInsert(head, ad);
791  if (r < 0)
792  goto error;
793 
794  /** if any, insert 0.0.0.0/0 and ::/0 as well */
795  if (r == 1 && port_any) {
796  SCLogDebug("inserting 0:65535 as port is \"any\"");
797 
798  ad_any = PortParse("0:65535");
799  if (ad_any == NULL)
800  goto error;
801 
802  if (DetectPortParseInsert(head, ad_any) < 0)
803  goto error;
804  }
805 
806  return 0;
807 
808 error:
809  SCLogError("DetectPortParseInsertString error");
810  if (ad != NULL)
812  if (ad_any != NULL)
813  DetectPortCleanupList(de_ctx, ad_any);
814  return -1;
815 }
816 
817 /**
818  * \brief Parses a port string and updates the 2 port heads with the
819  * port groups.
820  *
821  * \todo We don't seem to be handling negated cases, like [port,![!port,port]],
822  * since we pass around negate without keeping a count of ! with depth.
823  * Can solve this by keeping a count of the negations with depth, so that
824  * an even no of negations would count as no negation and an odd no of
825  * negations would count as a negation.
826  *
827  * \param gh Pointer to the port group head that should hold port ranges
828  * that are not negated.
829  * \param ghn Pointer to the port group head that should hold port ranges
830  * that are negated.
831  * \param s Pointer to the character string holding the port to be
832  * parsed.
833  * \param negate Flag that indicates if the received address string is negated
834  * or not. 0 if it is not, 1 it it is.
835  *
836  * \retval 0 On successfully parsing.
837  * \retval -1 On failure.
838  */
839 static int DetectPortParseDo(const DetectEngineCtx *de_ctx,
840  DetectPort **head, DetectPort **nhead,
841  const char *s, int negate,
842  ResolvedVariablesList *var_list, int recur)
843 {
844  size_t u = 0;
845  size_t x = 0;
846  int o_set = 0, n_set = 0, d_set = 0;
847  int range = 0;
848  int depth = 0;
849  size_t size = strlen(s);
850  char address[1024] = "";
851  const char *rule_var_port = NULL;
852  int r = 0;
853 
854  if (recur++ > 64) {
855  SCLogError("port block recursion "
856  "limit reached (max 64)");
857  goto error;
858  }
859 
860  SCLogDebug("head %p, *head %p, negate %d", head, *head, negate);
861 
862  for (u = 0, x = 0; u < size && x < sizeof(address); u++) {
863  address[x] = s[u];
864  x++;
865 
866  if (s[u] == ':')
867  range = 1;
868 
869  if (range == 1 && s[u] == '!') {
870  SCLogError("Can't have a negated value in a range.");
871  return -1;
872  } else if (!o_set && s[u] == '!') {
873  SCLogDebug("negation encountered");
874  n_set = 1;
875  x--;
876  } else if (s[u] == '[') {
877  if (!o_set) {
878  o_set = 1;
879  x = 0;
880  }
881  depth++;
882  } else if (s[u] == ']') {
883  if (depth == 1) {
884  address[x - 1] = '\0';
885  SCLogDebug("Parsed port from DetectPortParseDo - %s", address);
886  x = 0;
887 
888  r = DetectPortParseDo(de_ctx, head, nhead, address,
889  negate? negate: n_set, var_list, recur);
890  if (r == -1)
891  goto error;
892 
893  n_set = 0;
894  }
895  depth--;
896  range = 0;
897  } else if (depth == 0 && s[u] == ',') {
898  if (o_set == 1) {
899  o_set = 0;
900  } else if (d_set == 1) {
901  char *temp_rule_var_port = NULL,
902  *alloc_rule_var_port = NULL;
903 
904  address[x - 1] = '\0';
905 
906  rule_var_port = SCRuleVarsGetConfVar(de_ctx, address,
908  if (rule_var_port == NULL)
909  goto error;
910  if (strlen(rule_var_port) == 0) {
911  SCLogError("variable %s resolved "
912  "to nothing. This is likely a misconfiguration. "
913  "Note that a negated port needs to be quoted, "
914  "\"!$HTTP_PORTS\" instead of !$HTTP_PORTS. See issue #295.",
915  s);
916  goto error;
917  }
918  if (negate == 1 || n_set == 1) {
919  alloc_rule_var_port = SCMalloc(strlen(rule_var_port) + 3);
920  if (unlikely(alloc_rule_var_port == NULL))
921  goto error;
922  snprintf(alloc_rule_var_port, strlen(rule_var_port) + 3,
923  "[%s]", rule_var_port);
924  } else {
925  alloc_rule_var_port = SCStrdup(rule_var_port);
926  if (unlikely(alloc_rule_var_port == NULL))
927  goto error;
928  }
929  temp_rule_var_port = alloc_rule_var_port;
930  r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port,
931  (negate + n_set) % 2, var_list, recur);
932  if (r == -1) {
933  SCFree(alloc_rule_var_port);
934  goto error;
935  }
936  d_set = 0;
937  n_set = 0;
938  SCFree(alloc_rule_var_port);
939  } else {
940  address[x - 1] = '\0';
941  SCLogDebug("Parsed port from DetectPortParseDo - %s", address);
942 
943  if (negate == 0 && n_set == 0) {
944  r = DetectPortParseInsertString(de_ctx, head, address);
945  } else {
946  r = DetectPortParseInsertString(de_ctx, nhead, address);
947  }
948  if (r == -1)
949  goto error;
950 
951  n_set = 0;
952  }
953  x = 0;
954  range = 0;
955  } else if (depth == 0 && s[u] == '$') {
956  d_set = 1;
957  } else if (depth == 0 && u == size-1) {
958  range = 0;
959  if (x == 1024) {
960  address[x - 1] = '\0';
961  } else {
962  address[x] = '\0';
963  }
964  SCLogDebug("%s", address);
965 
966  if (AddVariableToResolveList(var_list, address) == -1) {
967  SCLogError("Found a loop in a port "
968  "groups declaration. This is likely a misconfiguration.");
969  goto error;
970  }
971 
972  x = 0;
973  if (d_set == 1) {
974  char *temp_rule_var_port = NULL,
975  *alloc_rule_var_port = NULL;
976 
977  rule_var_port = SCRuleVarsGetConfVar(de_ctx, address,
979  if (rule_var_port == NULL)
980  goto error;
981  if (strlen(rule_var_port) == 0) {
982  SCLogError("variable %s resolved "
983  "to nothing. This is likely a misconfiguration. "
984  "Note that a negated port needs to be quoted, "
985  "\"!$HTTP_PORTS\" instead of !$HTTP_PORTS. See issue #295.",
986  s);
987  goto error;
988  }
989  if ((negate + n_set) % 2) {
990  alloc_rule_var_port = SCMalloc(strlen(rule_var_port) + 3);
991  if (unlikely(alloc_rule_var_port == NULL))
992  goto error;
993  snprintf(alloc_rule_var_port, strlen(rule_var_port) + 3,
994  "[%s]", rule_var_port);
995  } else {
996  alloc_rule_var_port = SCStrdup(rule_var_port);
997  if (unlikely(alloc_rule_var_port == NULL))
998  goto error;
999  }
1000  temp_rule_var_port = alloc_rule_var_port;
1001  r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port,
1002  (negate + n_set) % 2, var_list, recur);
1003  SCFree(alloc_rule_var_port);
1004  if (r == -1)
1005  goto error;
1006 
1007  d_set = 0;
1008  } else {
1009  if (!((negate + n_set) % 2)) {
1010  r = DetectPortParseInsertString(de_ctx, head,address);
1011  } else {
1012  r = DetectPortParseInsertString(de_ctx, nhead,address);
1013  }
1014  if (r == -1)
1015  goto error;
1016  }
1017  n_set = 0;
1018  } else if (depth == 1 && s[u] == ',') {
1019  range = 0;
1020  }
1021  }
1022 
1023  if (depth > 0) {
1024  SCLogError("not every port block was "
1025  "properly closed in \"%s\", %d missing closing brackets (]). "
1026  "Note: problem might be in a variable.",
1027  s, depth);
1028  goto error;
1029  } else if (depth < 0) {
1030  SCLogError("not every port block was "
1031  "properly opened in \"%s\", %d missing opening brackets ([). "
1032  "Note: problem might be in a variable.",
1033  s, depth * -1);
1034  goto error;
1035  }
1036 
1037  return 0;
1038 error:
1039  return -1;
1040 }
1041 
1042 /**
1043  * \brief Check if the port group list covers the complete port space.
1044  * \retval 0 no
1045  * \retval 1 yes
1046  */
1047 static int DetectPortIsCompletePortSpace(DetectPort *p)
1048 {
1049  uint16_t next_port = 0;
1050 
1051  if (p == NULL)
1052  return 0;
1053 
1054  if (p->port != 0x0000)
1055  return 0;
1056 
1057  /* if we're ending with 0xFFFF while we know
1058  we started with 0x0000 it's the complete space */
1059  if (p->port2 == 0xFFFF)
1060  return 1;
1061 
1062  next_port = p->port2 + 1;
1063  p = p->next;
1064 
1065  for ( ; p != NULL; p = p->next) {
1066  if (p->port != next_port)
1067  return 0;
1068 
1069  if (p->port2 == 0xFFFF)
1070  return 1;
1071 
1072  next_port = p->port2 + 1;
1073  }
1074 
1075  return 0;
1076 }
1077 
1078 /**
1079  * \brief Helper function for the parsing process
1080  *
1081  * \param head Pointer to the head of the DetectPort group list
1082  * \param nhead Pointer to the new head of the DetectPort group list
1083  *
1084  * \retval 0 on success
1085  * \retval -1 on error
1086  */
1087 static int DetectPortParseMergeNotPorts(const DetectEngineCtx *de_ctx,
1088  DetectPort **head, DetectPort **nhead)
1089 {
1090  DetectPort *ad = NULL;
1091  DetectPort *ag, *ag2;
1092  int r = 0;
1093 
1094  /** check if the full port space is negated */
1095  if (DetectPortIsCompletePortSpace(*nhead) == 1) {
1096  SCLogError("Complete port space is negated");
1097  goto error;
1098  }
1099 
1100  /**
1101  * step 0: if the head list is empty, but the nhead list isn't
1102  * we have a pure not thingy. In that case we add a 0:65535
1103  * first.
1104  */
1105  if (*head == NULL && *nhead != NULL) {
1106  SCLogDebug("inserting 0:65535 into head");
1107  r = DetectPortParseInsertString(de_ctx, head,"0:65535");
1108  if (r < 0) {
1109  goto error;
1110  }
1111  }
1112 
1113  /** step 1: insert our ghn members into the gh list */
1114  for (ag = *nhead; ag != NULL; ag = ag->next) {
1115  /** work with a copy of the ad so we can easily clean up
1116  * the ghn group later.
1117  */
1118  ad = DetectPortCopySingle(NULL, ag);
1119  if (ad == NULL) {
1120  goto error;
1121  }
1122  r = DetectPortParseInsert(head, ad);
1123  if (r < 0) {
1124  goto error;
1125  }
1126  ad = NULL;
1127  }
1128 
1129  /** step 2: pull the address blocks that match our 'not' blocks */
1130  for (ag = *nhead; ag != NULL; ag = ag->next) {
1131  SCLogDebug("ag %p", ag);
1132  DetectPortPrint(ag);
1133 
1134  for (ag2 = *head; ag2 != NULL; ) {
1135  SCLogDebug("ag2 %p", ag2);
1136  DetectPortPrint(ag2);
1137 
1138  r = DetectPortCmp(ag, ag2);
1139  if (r == PORT_EQ || r == PORT_EB) { /* XXX more ??? */
1140  if (ag2->prev != NULL)
1141  ag2->prev->next = ag2->next;
1142  if (ag2->next != NULL)
1143  ag2->next->prev = ag2->prev;
1144  if (*head == ag2)
1145  *head = ag2->next;
1146  /** store the next ptr and remove the group */
1147  DetectPort *next_ag2 = ag2->next;
1148  DetectPortFree(de_ctx,ag2);
1149  ag2 = next_ag2;
1150  } else {
1151  ag2 = ag2->next;
1152  }
1153  }
1154  }
1155 
1156  for (ag2 = *head; ag2 != NULL; ag2 = ag2->next) {
1157  SCLogDebug("ag2 %p", ag2);
1158  DetectPortPrint(ag2);
1159  }
1160 
1161  if (*head == NULL) {
1162  SCLogError("no ports left after merging ports with negated ports");
1163  goto error;
1164  }
1165 
1166  return 0;
1167 error:
1168  if (ad != NULL)
1169  DetectPortFree(de_ctx, ad);
1170  return -1;
1171 }
1172 
1174 {
1175  SCLogDebug("Testing port conf vars for any misconfigured values");
1176 
1177  ResolvedVariablesList var_list = TAILQ_HEAD_INITIALIZER(var_list);
1178 
1179  ConfNode *port_vars_node = ConfGetNode("vars.port-groups");
1180  if (port_vars_node == NULL) {
1181  return 0;
1182  }
1183 
1184  ConfNode *seq_node;
1185  TAILQ_FOREACH(seq_node, &port_vars_node->head, next) {
1186  SCLogDebug("Testing %s - %s\n", seq_node->name, seq_node->val);
1187 
1188  DetectPort *gh = DetectPortInit();
1189  if (gh == NULL) {
1190  goto error;
1191  }
1192  DetectPort *ghn = NULL;
1193 
1194  if (seq_node->val == NULL) {
1195  SCLogError("Port var \"%s\" probably has a sequence(something "
1196  "in brackets) value set without any quotes. Please "
1197  "quote it using \"..\".",
1198  seq_node->name);
1199  DetectPortCleanupList(NULL, gh);
1200  goto error;
1201  }
1202 
1203  int r = DetectPortParseDo(NULL, &gh, &ghn, seq_node->val,
1204  /* start with negate no */0, &var_list, 0);
1205 
1206  CleanVariableResolveList(&var_list);
1207 
1208  if (r < 0) {
1209  DetectPortCleanupList(NULL, gh);
1210  SCLogError("failed to parse port var \"%s\" with value \"%s\". "
1211  "Please check its syntax",
1212  seq_node->name, seq_node->val);
1213  goto error;
1214  }
1215 
1216  if (DetectPortIsCompletePortSpace(ghn)) {
1217  SCLogError("Port var - \"%s\" has the complete Port range negated "
1218  "with its value \"%s\". Port space range is NIL. "
1219  "Probably have a !any or a port range that supplies "
1220  "a NULL address range",
1221  seq_node->name, seq_node->val);
1222  DetectPortCleanupList(NULL, gh);
1223  DetectPortCleanupList(NULL, ghn);
1224  goto error;
1225  }
1226 
1227  if (gh != NULL)
1228  DetectPortCleanupList(NULL, gh);
1229  if (ghn != NULL)
1230  DetectPortCleanupList(NULL, ghn);
1231  }
1232 
1233  return 0;
1234  error:
1235  return -1;
1236 }
1237 
1238 
1239 /**
1240  * \brief Function for parsing port strings
1241  *
1242  * \param de_ctx Pointer to the detection engine context
1243  * \param head Pointer to the head of the DetectPort group list
1244  * \param str Pointer to the port string
1245  *
1246  * \retval 0 on success
1247  * \retval -1 on error
1248  */
1250  DetectPort **head, const char *str)
1251 {
1252  SCLogDebug("Port string to be parsed - str %s", str);
1253 
1254  /* negate port list */
1255  DetectPort *nhead = NULL;
1256 
1257  int r = DetectPortParseDo(de_ctx, head, &nhead, str,
1258  /* start with negate no */ 0, NULL, 0);
1259  if (r < 0)
1260  goto error;
1261 
1262  SCLogDebug("head %p %p, nhead %p", head, *head, nhead);
1263 
1264  /* merge the 'not' address groups */
1265  if (DetectPortParseMergeNotPorts(de_ctx, head, &nhead) < 0)
1266  goto error;
1267 
1268  /* free the temp negate head */
1269  DetectPortCleanupList(de_ctx, nhead);
1270  return 0;
1271 
1272 error:
1273  DetectPortCleanupList(de_ctx, nhead);
1274  return -1;
1275 }
1276 
1277 /**
1278  * \brief Helper function for parsing port strings
1279  *
1280  * \param str Pointer to the port string
1281  *
1282  * \retval DetectPort pointer of the parse string on success
1283  * \retval NULL on error
1284  */
1285 DetectPort *PortParse(const char *str)
1286 {
1287  char *port2 = NULL;
1288  char portstr[16];
1289 
1290  /* strip leading spaces */
1291  while (isspace(*str))
1292  str++;
1293  if (strlen(str) >= 16)
1294  return NULL;
1295  strlcpy(portstr, str, sizeof(portstr));
1296 
1297  DetectPort *dp = DetectPortInit();
1298  if (dp == NULL)
1299  goto error;
1300 
1301  /* we dup so we can put a nul-termination in it later */
1302  char *port = portstr;
1303 
1304  /* handle the negation case */
1305  if (port[0] == '!') {
1306  dp->flags |= PORT_FLAG_NOT;
1307  port++;
1308  }
1309 
1310  /* see if the address is an ipv4 or ipv6 address */
1311  if ((port2 = strchr(port, ':')) != NULL) {
1312  /* 80:81 range format */
1313  port2[0] = '\0';
1314  port2++;
1315 
1316  if (strcmp(port, "") != 0) {
1317  if (!DetectPortIsValidRange(port, &dp->port))
1318  goto error;
1319  } else {
1320  dp->port = 0;
1321  }
1322 
1323  if (strcmp(port2, "") != 0) {
1324  if (!DetectPortIsValidRange(port2, &dp->port2))
1325  goto error;
1326  } else {
1327  dp->port2 = 65535;
1328  }
1329 
1330  /* a > b is illegal, a == b is ok */
1331  if (dp->port > dp->port2)
1332  goto error;
1333  } else {
1334  if (strcasecmp(port,"any") == 0) {
1335  dp->port = 0;
1336  dp->port2 = 65535;
1337  } else {
1338  if (!DetectPortIsValidRange(port, &dp->port))
1339  goto error;
1340  dp->port2 = dp->port;
1341  }
1342  }
1343 
1344  return dp;
1345 
1346 error:
1347  if (dp != NULL)
1348  DetectPortCleanupList(NULL, dp);
1349  return NULL;
1350 }
1351 
1352 /**
1353  * \brief Helper function to check if a parsed port is in the valid range
1354  * of available ports
1355  *
1356  * \param str Pointer to the port string
1357  *
1358  *
1359  * \retval true if port is in the valid range
1360  * \retval false if invalid
1361  */
1362 static bool DetectPortIsValidRange(char *port, uint16_t *port_val)
1363 {
1364  if (StringParseUint16(port_val, 10, 0, (const char *)port) < 0)
1365  return false;
1366 
1367  return true;
1368 }
1369 
1370 /********************** End parsing routines ********************/
1371 
1372 /* hash table */
1373 
1374 /**
1375  * \brief The hash function to be the used by the hash table -
1376  * DetectEngineCtx->dport_hash_table.
1377  *
1378  * \param ht Pointer to the hash table.
1379  * \param data Pointer to the DetectPort.
1380  * \param datalen Not used in our case.
1381  *
1382  * \retval hash The generated hash value.
1383  */
1384 static uint32_t DetectPortHashFunc(HashListTable *ht, void *data, uint16_t datalen)
1385 {
1386  DetectPort *p = (DetectPort *)data;
1387  SCLogDebug("hashing port %p", p);
1388 
1389  uint32_t hash = ((uint32_t)p->port << 16) | p->port2;
1390 
1391  hash %= ht->array_size;
1392  SCLogDebug("hash %"PRIu32, hash);
1393  return hash;
1394 }
1395 
1396 /**
1397  * \brief The Compare function to be used by the DetectPort hash table -
1398  * DetectEngineCtx->dport_hash_table.
1399  *
1400  * \param data1 Pointer to the first DetectPort.
1401  * \param len1 Not used.
1402  * \param data2 Pointer to the second DetectPort.
1403  * \param len2 Not used.
1404  *
1405  * \retval 1 If the 2 DetectPort sent as args match.
1406  * \retval 0 If the 2 DetectPort sent as args do not match.
1407  */
1408 static char DetectPortCompareFunc(void *data1, uint16_t len1,
1409  void *data2, uint16_t len2)
1410 {
1411  DetectPort *dp1 = (DetectPort *)data1;
1412  DetectPort *dp2 = (DetectPort *)data2;
1413 
1414  if (data1 == NULL || data2 == NULL)
1415  return 0;
1416 
1417  if (dp1->port == dp2->port && dp1->port2 == dp2->port2)
1418  return 1;
1419 
1420  return 0;
1421 }
1422 
1423 static void DetectPortHashFreeFunc(void *ptr)
1424 {
1425  DetectPort *p = ptr;
1426  DetectPortFree(NULL, p);
1427 }
1428 
1429 /**
1430  * \brief Initializes the hash table in the detection engine context to hold the
1431  * DetectPort hash.
1432  *
1433  * \param de_ctx Pointer to the detection engine context.
1434  *
1435  * \retval 0 On success.
1436  * \retval -1 On failure.
1437  */
1439 {
1440  de_ctx->dport_hash_table = HashListTableInit(4096, DetectPortHashFunc,
1441  DetectPortCompareFunc,
1442  DetectPortHashFreeFunc);
1443  if (de_ctx->dport_hash_table == NULL)
1444  return -1;
1445 
1446  return 0;
1447 }
1448 
1449 /**
1450  * \brief Adds a DetectPort to the detection engine context DetectPort
1451  * hash table.
1452  *
1453  * \param de_ctx Pointer to the detection engine context.
1454  * \param dp Pointer to the DetectPort.
1455  *
1456  * \retval ret 0 on Successfully adding the DetectPort; -1 on failure.
1457  */
1459 {
1460  int ret = HashListTableAdd(de_ctx->dport_hash_table, (void *)dp, 0);
1461  return ret;
1462 }
1463 
1464 /**
1465  * \brief Used to lookup a DetectPort hash from the detection engine context
1466  * DetectPort hash table.
1467  *
1468  * \param de_ctx Pointer to the detection engine context.
1469  * \param sgh Pointer to the DetectPort.
1470  *
1471  * \retval rsgh On success a pointer to the DetectPort if the DetectPort is
1472  * found in the hash table; NULL on failure.
1473  */
1475 {
1476  SCEnter();
1477 
1478  DetectPort *rdp = HashListTableLookup(de_ctx->dport_hash_table, (void *)dp, 0);
1479 
1480  SCReturnPtr(rdp, "DetectPort");
1481 }
1482 
1483 /**
1484  * \brief Frees the hash table - DetectEngineCtx->sgh_hash_table, allocated by
1485  * DetectPortInit() function.
1486  *
1487  * \param de_ctx Pointer to the detection engine context.
1488  */
1490 {
1491  if (de_ctx->sgh_hash_table == NULL)
1492  return;
1493 
1495  de_ctx->dport_hash_table = NULL;
1496 
1497  return;
1498 }
1499 
1500 /*---------------------- Unittests -------------------------*/
1501 
1502 #ifdef UNITTESTS
1503 #include "packet.h"
1504 
1505 /**
1506  * \brief Do a sorted insert, where the top of the list should be the biggest
1507  * port range.
1508  *
1509  * \todo XXX current sorting only works for overlapping ranges
1510  *
1511  * \param head Pointer to the DetectPort list head
1512  * \param dp Pointer to DetectPort to search in the DetectPort list
1513  * \retval 0 if dp is added correctly
1514  */
1515 static int PortTestDetectPortAdd(DetectPort **head, DetectPort *dp)
1516 {
1517  DetectPort *cur, *prev_cur = NULL;
1518 
1519  //SCLogDebug("DetectPortAdd: adding "); DetectPortPrint(ag); SCLogDebug("");
1520 
1521  if (*head != NULL) {
1522  for (cur = *head; cur != NULL; cur = cur->next) {
1523  prev_cur = cur;
1524  int r = DetectPortCmp(dp,cur);
1525  if (r == PORT_EB) {
1526  /* insert here */
1527  dp->prev = cur->prev;
1528  dp->next = cur;
1529 
1530  cur->prev = dp;
1531  if (*head == cur) {
1532  *head = dp;
1533  } else {
1534  dp->prev->next = dp;
1535  }
1536  return 0;
1537  }
1538  }
1539  dp->prev = prev_cur;
1540  if (prev_cur != NULL)
1541  prev_cur->next = dp;
1542  } else {
1543  *head = dp;
1544  }
1545 
1546  return 0;
1547 }
1548 
1549 
1550 /**
1551  * \test Check if a DetectPort is properly allocated
1552  */
1553 static int PortTestParse01 (void)
1554 {
1555  DetectPort *dd = NULL;
1556  int r = DetectPortParse(NULL,&dd,"80");
1557  FAIL_IF_NOT(r == 0);
1558  DetectPortFree(NULL, dd);
1559  PASS;
1560 }
1561 
1562 /**
1563  * \test Check if two ports are properly allocated in the DetectPort group
1564  */
1565 static int PortTestParse02 (void)
1566 {
1567  DetectPort *dd = NULL;
1568  int r = DetectPortParse(NULL,&dd,"80");
1569  FAIL_IF_NOT(r == 0);
1570  r = DetectPortParse(NULL,&dd,"22");
1571  FAIL_IF_NOT(r == 0);
1572  DetectPortCleanupList(NULL, dd);
1573  PASS;
1574 }
1575 
1576 /**
1577  * \test Check if two port ranges are properly allocated in the DetectPort group
1578  */
1579 static int PortTestParse03 (void)
1580 {
1581  DetectPort *dd = NULL;
1582  int r = DetectPortParse(NULL,&dd,"80:88");
1583  FAIL_IF_NOT(r == 0);
1584  r = DetectPortParse(NULL,&dd,"85:100");
1585  FAIL_IF_NOT(r == 0);
1586  DetectPortCleanupList(NULL, dd);
1587  PASS;
1588 }
1589 
1590 /**
1591  * \test Check if a negated port range is properly allocated in the DetectPort
1592  */
1593 static int PortTestParse04 (void)
1594 {
1595  DetectPort *dd = NULL;
1596  int r = DetectPortParse(NULL,&dd,"!80:81");
1597  FAIL_IF_NOT(r == 0);
1598  DetectPortCleanupList(NULL, dd);
1599  PASS;
1600 }
1601 
1602 /**
1603  * \test Check if a negated port range is properly fragmented in the allowed
1604  * real groups, ex !80:81 should allow 0:79 and 82:65535
1605  */
1606 static int PortTestParse05 (void)
1607 {
1608  DetectPort *dd = NULL;
1609  int r = DetectPortParse(NULL,&dd,"!80:81");
1610  FAIL_IF_NOT(r == 0);
1611  FAIL_IF_NULL(dd->next);
1612  FAIL_IF_NOT(dd->port == 0);
1613  FAIL_IF_NOT(dd->port2 == 79);
1614  FAIL_IF_NOT(dd->next->port == 82);
1615  FAIL_IF_NOT(dd->next->port2 == 65535);
1616  DetectPortCleanupList(NULL, dd);
1617  PASS;
1618 }
1619 
1620 /**
1621  * \test Check if a negated port range is properly fragmented in the allowed
1622  * real groups
1623  */
1624 static int PortTestParse07 (void)
1625 {
1626  DetectPort *dd = NULL;
1627 
1628  int r = DetectPortParse(NULL,&dd,"!21:902");
1629  FAIL_IF_NOT(r == 0);
1630  FAIL_IF_NULL(dd->next);
1631 
1632  FAIL_IF_NOT(dd->port == 0);
1633  FAIL_IF_NOT(dd->port2 == 20);
1634  FAIL_IF_NOT(dd->next->port == 903);
1635  FAIL_IF_NOT(dd->next->port2 == 65535);
1636 
1637  DetectPortCleanupList(NULL, dd);
1638  PASS;
1639 }
1640 
1641 /**
1642  * \test Check if we dont allow invalid port range specification
1643  */
1644 static int PortTestParse08 (void)
1645 {
1646  DetectPort *dd = NULL;
1647 
1648  int r = DetectPortParse(NULL,&dd,"[80:!80]");
1649  FAIL_IF(r == 0);
1650 
1651  DetectPortCleanupList(NULL, dd);
1652  PASS;
1653 }
1654 
1655 /**
1656  * \test Check if we autocomplete correctly an open range
1657  */
1658 static int PortTestParse09 (void)
1659 {
1660  DetectPort *dd = NULL;
1661 
1662  int r = DetectPortParse(NULL,&dd,"1024:");
1663  FAIL_IF_NOT(r == 0);
1664  FAIL_IF_NULL(dd);
1665 
1666  FAIL_IF_NOT(dd->port == 1024);
1667  FAIL_IF_NOT(dd->port2 == 0xffff);
1668 
1669  DetectPortCleanupList(NULL, dd);
1670  PASS;
1671 }
1672 
1673 /**
1674  * \test Test we don't allow a port that is too big
1675  */
1676 static int PortTestParse10 (void)
1677 {
1678  DetectPort *dd = NULL;
1679  int r = DetectPortParse(NULL,&dd,"77777777777777777777777777777777777777777777");
1680  FAIL_IF(r == 0);
1681  PASS;
1682 }
1683 
1684 /**
1685  * \test Test second port of range being too big
1686  */
1687 static int PortTestParse11 (void)
1688 {
1689  DetectPort *dd = NULL;
1690 
1691  int r = DetectPortParse(NULL,&dd,"1024:65536");
1692  FAIL_IF(r == 0);
1693  PASS;
1694 }
1695 
1696 /**
1697  * \test Test second port of range being just right
1698  */
1699 static int PortTestParse12 (void)
1700 {
1701  DetectPort *dd = NULL;
1702  int r = DetectPortParse(NULL,&dd,"1024:65535");
1703  FAIL_IF_NOT(r == 0);
1704  DetectPortFree(NULL, dd);
1705  PASS;
1706 }
1707 
1708 /**
1709  * \test Test first port of range being too big
1710  */
1711 static int PortTestParse13 (void)
1712 {
1713  DetectPort *dd = NULL;
1714  int r = DetectPortParse(NULL,&dd,"65536:65535");
1715  FAIL_IF(r == 0);
1716  PASS;
1717 }
1718 
1719 /**
1720  * \test Test merging port groups
1721  */
1722 static int PortTestParse14 (void)
1723 {
1724  DetectPort *dd = NULL;
1725 
1726  int r = DetectPortParseInsertString(NULL, &dd, "0:100");
1727  FAIL_IF_NOT(r == 0);
1728  r = DetectPortParseInsertString(NULL, &dd, "1000:65535");
1729  FAIL_IF_NOT(r == 0);
1730  FAIL_IF_NULL(dd->next);
1731 
1732  FAIL_IF_NOT(dd->port == 0);
1733  FAIL_IF_NOT(dd->port2 == 100);
1734  FAIL_IF_NOT(dd->next->port == 1000);
1735  FAIL_IF_NOT(dd->next->port2 == 65535);
1736 
1737  DetectPortCleanupList(NULL, dd);
1738  PASS;
1739 }
1740 
1741 /**
1742  * \test Test merging negated port groups
1743  */
1744 static int PortTestParse15 (void)
1745 {
1746  DetectPort *dd = NULL;
1747 
1748  int r = DetectPortParse(NULL,&dd,"![0:100,1000:3000]");
1749  FAIL_IF_NOT(r == 0);
1750  FAIL_IF_NULL(dd->next);
1751 
1752  FAIL_IF_NOT(dd->port == 101);
1753  FAIL_IF_NOT(dd->port2 == 999);
1754  FAIL_IF_NOT(dd->next->port == 3001);
1755  FAIL_IF_NOT(dd->next->port2 == 65535);
1756 
1757  DetectPortCleanupList(NULL, dd);
1758  PASS;
1759 }
1760 
1761 static int PortTestParse16 (void)
1762 {
1763  DetectPort *dd = NULL;
1764  int r = DetectPortParse(NULL,&dd,"\
1765 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\
1766 1:65535\
1767 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\
1768 ");
1769  FAIL_IF_NOT(r == 0);
1770  DetectPortFree(NULL, dd);
1771  dd = NULL;
1772  r = DetectPortParse(NULL,&dd,"\
1773 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\
1774 1:65535\
1775 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\
1776 ");
1777  FAIL_IF(r == 0);
1778  PASS;
1779 }
1780 
1781 /**
1782  * \test Test general functions
1783  */
1784 static int PortTestFunctions01(void)
1785 {
1786  DetectPort *head = NULL;
1787  DetectPort *dp1= NULL;
1788  int result = 0;
1789 
1790  /* Parse */
1791  int r = DetectPortParse(NULL,&head,"![0:100,1000:65535]");
1792  if (r != 0 || head->next != NULL)
1793  goto end;
1794 
1795  /* We should have only one DetectPort */
1796  if (!(head->port == 101))
1797  goto end;
1798  if (!(head->port2 == 999))
1799  goto end;
1800  if (!(head->next == NULL))
1801  goto end;
1802 
1803  r = DetectPortParse(NULL, &dp1,"2000:3000");
1804  if (r != 0 || dp1->next != NULL)
1805  goto end;
1806  if (!(dp1->port == 2000))
1807  goto end;
1808  if (!(dp1->port2 == 3000))
1809  goto end;
1810 
1811  /* Add */
1812  r = PortTestDetectPortAdd(&head, dp1);
1813  if (r != 0 || head->next == NULL)
1814  goto end;
1815  if (!(head->port == 101))
1816  goto end;
1817  if (!(head->port2 == 999))
1818  goto end;
1819  if (!(head->next->port == 2000))
1820  goto end;
1821  if (!(head->next->port2 == 3000))
1822  goto end;
1823 
1824  /* Match */
1825  if (!DetectPortMatch(head, 150))
1826  goto end;
1827  if (DetectPortMatch(head->next, 1500))
1828  goto end;
1829  if ((DetectPortMatch(head, 3500)))
1830  goto end;
1831  if ((DetectPortMatch(head, 50)))
1832  goto end;
1833 
1834  result = 1;
1835 end:
1836  if (dp1 != NULL)
1837  DetectPortFree(NULL, dp1);
1838  if (head != NULL)
1839  DetectPortFree(NULL, head);
1840  return result;
1841 }
1842 
1843 /**
1844  * \test Test general functions
1845  */
1846 static int PortTestFunctions02(void)
1847 {
1848  DetectPort *head = NULL;
1849  DetectPort *dp1= NULL;
1850  DetectPort *dp2= NULL;
1851  int result = 0;
1852 
1853  /* Parse */
1854  int r = DetectPortParse(NULL,&head, "![0:100,1000:65535]");
1855  if (r != 0 || head->next != NULL)
1856  goto end;
1857 
1858  r = DetectPortParse(NULL, &dp1, "!200:300");
1859  if (r != 0 || dp1->next == NULL)
1860  goto end;
1861 
1862  /* Merge Nots */
1863  r = DetectPortParseMergeNotPorts(NULL, &head, &dp1);
1864  if (r != 0 || head->next != NULL)
1865  goto end;
1866 
1867  r = DetectPortParse(NULL, &dp2, "!100:500");
1868  if (r != 0 || dp2->next == NULL)
1869  goto end;
1870 
1871  /* Merge Nots */
1872  r = DetectPortParseMergeNotPorts(NULL, &head, &dp2);
1873  if (r != 0 || head->next != NULL)
1874  goto end;
1875 
1876  if (!(head->port == 200))
1877  goto end;
1878  if (!(head->port2 == 300))
1879  goto end;
1880 
1881  result = 1;
1882 
1883 end:
1884  if (dp1 != NULL)
1885  DetectPortFree(NULL, dp1);
1886  if (dp2 != NULL)
1887  DetectPortFree(NULL, dp2);
1888  if (head != NULL)
1889  DetectPortFree(NULL, head);
1890  return result;
1891 }
1892 
1893 /**
1894  * \test Test general functions
1895  */
1896 static int PortTestFunctions03(void)
1897 {
1898  DetectPort *dp1= NULL;
1899  DetectPort *dp2= NULL;
1900  DetectPort *dp3= NULL;
1901  int result = 0;
1902 
1903  int r = DetectPortParse(NULL, &dp1, "200:300");
1904  if (r != 0)
1905  goto end;
1906 
1907  r = DetectPortParse(NULL, &dp2, "250:300");
1908  if (r != 0)
1909  goto end;
1910 
1911  /* Cut */
1912  DetectPortCut(NULL, dp1, dp2, &dp3);
1913  if (r != 0)
1914  goto end;
1915 
1916  if (!(dp1->port == 200))
1917  goto end;
1918  if (!(dp1->port2 == 249))
1919  goto end;
1920  if (!(dp2->port == 250))
1921  goto end;
1922  if (!(dp2->port2 == 300))
1923  goto end;
1924 
1925  dp1->port = 0;
1926  dp1->port2 = 500;
1927  dp2->port = 250;
1928  dp2->port2 = 750;
1929 
1930  /* Cut */
1931  DetectPortCut(NULL, dp1, dp2, &dp3);
1932  if (r != 0)
1933  goto end;
1934  if (!(dp1->port == 0))
1935  goto end;
1936  if (!(dp1->port2 == 249))
1937  goto end;
1938  if (!(dp2->port == 250))
1939  goto end;
1940  if (!(dp2->port2 == 500))
1941  goto end;
1942  if (!(dp3->port == 501))
1943  goto end;
1944  if (!(dp3->port2 == 750))
1945  goto end;
1946 
1947  result = 1;
1948 
1949 end:
1950  if (dp1 != NULL)
1951  DetectPortFree(NULL, dp1);
1952  if (dp2 != NULL)
1953  DetectPortFree(NULL, dp2);
1954  if (dp3 != NULL)
1955  DetectPortFree(NULL, dp3);
1956  return result;
1957 }
1958 
1959 /**
1960  * \test Test general functions
1961  */
1962 static int PortTestFunctions04(void)
1963 {
1964  DetectPort *dp1= NULL;
1965  DetectPort *dp2= NULL;
1966  int result = 0;
1967 
1968  int r = DetectPortParse(NULL, &dp1, "200:300");
1969  if (r != 0)
1970  goto end;
1971 
1972  dp2 = DetectPortInit();
1973 
1974  /* Cut Not */
1975  DetectPortCutNot(dp1, &dp2);
1976  if (r != 0)
1977  goto end;
1978 
1979  if (!(dp1->port == 0))
1980  goto end;
1981  if (!(dp1->port2 == 199))
1982  goto end;
1983  if (!(dp2->port == 301))
1984  goto end;
1985  if (!(dp2->port2 == 65535))
1986  goto end;
1987 
1988  result = 1;
1989 end:
1990  if (dp1 != NULL)
1991  DetectPortFree(NULL, dp1);
1992  if (dp2 != NULL)
1993  DetectPortFree(NULL, dp2);
1994  return result;
1995 }
1996 
1997 /**
1998  * \test Test general functions
1999  */
2000 static int PortTestFunctions05(void)
2001 {
2002  DetectPort *dp1 = NULL;
2003  DetectPort *dp2 = NULL;
2004  DetectPort *dp3 = NULL;
2005  int result = 0;
2006  int r = 0;
2007 
2009  Signature s[2];
2010  memset(s,0x00,sizeof(s));
2011 
2012  s[0].num = 0;
2013  s[1].num = 1;
2014 
2015  r = DetectPortParse(NULL, &dp1, "1024:65535");
2016  if (r != 0) {
2017  printf("r != 0 but %d: ", r);
2018  goto end;
2019  }
2020  SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]);
2021 
2022  r = DetectPortParse(NULL, &dp2, "any");
2023  if (r != 0) {
2024  printf("r != 0 but %d: ", r);
2025  goto end;
2026  }
2027  SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]);
2028 
2029  SCLogDebug("dp1");
2030  DetectPortPrint(dp1);
2031  SCLogDebug("dp2");
2032  DetectPortPrint(dp2);
2033 
2034  DetectPortInsert(de_ctx, &dp3, dp1);
2035  DetectPortInsert(de_ctx, &dp3, dp2);
2036 
2037  if (dp3 == NULL)
2038  goto end;
2039 
2040  SCLogDebug("dp3");
2041  DetectPort *x = dp3;
2042  for ( ; x != NULL; x = x->next) {
2043  DetectPortPrint(x);
2044  //SigGroupHeadPrintSigs(de_ctx, x->sh);
2045  }
2046 
2047  DetectPort *one = dp3;
2048  DetectPort *two = dp3->next;
2049 
2050  int sig = 0;
2051  if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2052  printf("sig %d part of 'one', but it shouldn't: ", sig);
2053  goto end;
2054  }
2055  sig = 1;
2056  if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2057  printf("sig %d part of 'one', but it shouldn't: ", sig);
2058  goto end;
2059  }
2060  sig = 1;
2061  if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2062  printf("sig %d part of 'two', but it shouldn't: ", sig);
2063  goto end;
2064  }
2065 
2066  result = 1;
2067 end:
2068  if (dp1 != NULL)
2069  DetectPortFree(NULL, dp1);
2070  if (dp2 != NULL)
2071  DetectPortFree(NULL, dp2);
2072  return result;
2073 }
2074 
2075 /**
2076  * \test Test general functions
2077  */
2078 static int PortTestFunctions06(void)
2079 {
2080  DetectPort *dp1 = NULL;
2081  DetectPort *dp2 = NULL;
2082  DetectPort *dp3 = NULL;
2083  int result = 0;
2084  int r = 0;
2085 
2087  Signature s[2];
2088  memset(s,0x00,sizeof(s));
2089 
2090  s[0].num = 0;
2091  s[1].num = 1;
2092 
2093  r = DetectPortParse(NULL, &dp1, "1024:65535");
2094  if (r != 0) {
2095  printf("r != 0 but %d: ", r);
2096  goto end;
2097  }
2098  SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]);
2099 
2100  r = DetectPortParse(NULL, &dp2, "any");
2101  if (r != 0) {
2102  printf("r != 0 but %d: ", r);
2103  goto end;
2104  }
2105  SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]);
2106 
2107  SCLogDebug("dp1");
2108  DetectPortPrint(dp1);
2109  SCLogDebug("dp2");
2110  DetectPortPrint(dp2);
2111 
2112  DetectPortInsert(de_ctx, &dp3, dp2);
2113  DetectPortInsert(de_ctx, &dp3, dp1);
2114 
2115  if (dp3 == NULL)
2116  goto end;
2117 
2118  SCLogDebug("dp3");
2119  DetectPort *x = dp3;
2120  for ( ; x != NULL; x = x->next) {
2121  DetectPortPrint(x);
2122  //SigGroupHeadPrintSigs(de_ctx, x->sh);
2123  }
2124 
2125  DetectPort *one = dp3;
2126  DetectPort *two = dp3->next;
2127 
2128  int sig = 0;
2129  if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2130  printf("sig %d part of 'one', but it shouldn't: ", sig);
2131  goto end;
2132  }
2133  sig = 1;
2134  if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2135  printf("sig %d part of 'one', but it shouldn't: ", sig);
2136  goto end;
2137  }
2138  sig = 1;
2139  if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2140  printf("sig %d part of 'two', but it shouldn't: ", sig);
2141  goto end;
2142  }
2143 
2144  result = 1;
2145 end:
2146  if (dp1 != NULL)
2147  DetectPortFree(NULL, dp1);
2148  if (dp2 != NULL)
2149  DetectPortFree(NULL, dp2);
2150  return result;
2151 }
2152 
2153 /**
2154  * \test Test general functions
2155  */
2156 static int PortTestFunctions07(void)
2157 {
2158  DetectPort *dd = NULL;
2159 
2160  // This one should fail due to negation in a range
2161  FAIL_IF(DetectPortParse(NULL, &dd, "[80:!99]") == 0);
2162 
2163  // Correct: from 80 till 100 but 99 excluded
2164  FAIL_IF_NOT(DetectPortParse(NULL, &dd, "[80:100,!99]") == 0);
2165  FAIL_IF_NULL(dd->next);
2166  FAIL_IF_NOT(dd->port == 80);
2167  FAIL_IF_NOT(dd->port2 == 98);
2168  FAIL_IF_NOT(dd->next->port == 100);
2169 
2170  // Also good: from 1 till 80 except of 2 and 4
2171  FAIL_IF_NOT(DetectPortParse(NULL, &dd, "[1:80,![2,4]]") == 0);
2172  FAIL_IF_NOT(dd->port == 1);
2176 
2177  DetectPortCleanupList(NULL, dd);
2178  PASS;
2179 }
2180 
2181 /**
2182  * \test Test packet Matches
2183  * \param raw_eth_pkt pointer to the ethernet packet
2184  * \param pktsize size of the packet
2185  * \param sig pointer to the signature to test
2186  * \param sid sid number of the signature
2187  * \retval return 1 if match
2188  * \retval return 0 if not
2189  */
2190 static int PortTestMatchReal(uint8_t *raw_eth_pkt, uint16_t pktsize, const char *sig,
2191  uint32_t sid)
2192 {
2193  int result = 0;
2195  Packet *p = UTHBuildPacketFromEth(raw_eth_pkt, pktsize);
2196  result = UTHPacketMatchSig(p, sig);
2197  PacketRecycle(p);
2198  FlowShutdown();
2199  return result;
2200 }
2201 
2202 /**
2203  * \brief Wrapper for PortTestMatchReal
2204  */
2205 static int PortTestMatchRealWrp(const char *sig, uint32_t sid)
2206 {
2207  /* Real HTTP packeth doing a GET method
2208  * tcp.sport=47370 tcp.dport=80
2209  * ip.src=192.168.28.131 ip.dst=192.168.1.1
2210  */
2211  uint8_t raw_eth_pkt[] = {
2212  0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
2213  0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
2214  0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
2215  0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
2216  0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
2217  0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
2218  0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
2219  0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
2220  0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
2221  0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
2222  0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
2223  0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
2224  0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
2225  0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
2226  0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
2227  0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
2228  0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
2229  0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
2230  0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
2231  0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
2232  0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
2233  0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
2234  0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
2235  0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
2236  0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
2237  0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
2238  0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
2239  0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
2240  0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
2241  0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
2242  0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
2243  0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
2244  0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
2245  0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
2246  0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
2247  0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
2248  0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
2249  0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
2250  0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
2251  0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
2252  0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
2253  0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
2254  0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
2255  0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
2256  0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
2257  0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
2258  0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
2259  0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
2260  0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
2261  0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
2262  0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
2263  0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
2264  0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
2265  0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
2266  0x76,0x65,0x0d,0x0a,0x0d,0x0a };
2267  /* end raw_eth_pkt */
2268 
2269  return PortTestMatchReal(raw_eth_pkt, (uint16_t)sizeof(raw_eth_pkt),
2270  sig, sid);
2271 }
2272 
2273 /**
2274  * \test Check if we match a dest port
2275  */
2276 static int PortTestMatchReal01(void)
2277 {
2278  /* tcp.sport=47370 tcp.dport=80 */
2279  const char *sig = "alert tcp any any -> any 80 (msg:\"Nothing..\"; content:\"GET\"; sid:1;)";
2280  return PortTestMatchRealWrp(sig, 1);
2281 }
2282 
2283 /**
2284  * \test Check if we match a source port
2285  */
2286 static int PortTestMatchReal02(void)
2287 {
2288  const char *sig = "alert tcp any 47370 -> any any (msg:\"Nothing..\";"
2289  " content:\"GET\"; sid:1;)";
2290  return PortTestMatchRealWrp(sig, 1);
2291 }
2292 
2293 /**
2294  * \test Check if we match both of them
2295  */
2296 static int PortTestMatchReal03(void)
2297 {
2298  const char *sig = "alert tcp any 47370 -> any 80 (msg:\"Nothing..\";"
2299  " content:\"GET\"; sid:1;)";
2300  return PortTestMatchRealWrp(sig, 1);
2301 }
2302 
2303 /**
2304  * \test Check if we negate dest ports correctly
2305  */
2306 static int PortTestMatchReal04(void)
2307 {
2308  const char *sig = "alert tcp any any -> any !80 (msg:\"Nothing..\";"
2309  " content:\"GET\"; sid:1;)";
2310  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2311 }
2312 
2313 /**
2314  * \test Check if we negate source ports correctly
2315  */
2316 static int PortTestMatchReal05(void)
2317 {
2318  const char *sig = "alert tcp any !47370 -> any any (msg:\"Nothing..\";"
2319  " content:\"GET\"; sid:1;)";
2320  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2321 }
2322 
2323 /**
2324  * \test Check if we negate both ports correctly
2325  */
2326 static int PortTestMatchReal06(void)
2327 {
2328  const char *sig = "alert tcp any !47370 -> any !80 (msg:\"Nothing..\";"
2329  " content:\"GET\"; sid:1;)";
2330  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2331 }
2332 
2333 /**
2334  * \test Check if we match a dest port range
2335  */
2336 static int PortTestMatchReal07(void)
2337 {
2338  const char *sig = "alert tcp any any -> any 70:100 (msg:\"Nothing..\";"
2339  " content:\"GET\"; sid:1;)";
2340  return PortTestMatchRealWrp(sig, 1);
2341 }
2342 
2343 /**
2344  * \test Check if we match a source port range
2345  */
2346 static int PortTestMatchReal08(void)
2347 {
2348  const char *sig = "alert tcp any 47000:50000 -> any any (msg:\"Nothing..\";"
2349  " content:\"GET\"; sid:1;)";
2350  return PortTestMatchRealWrp(sig, 1);
2351 }
2352 
2353 /**
2354  * \test Check if we match both port ranges
2355  */
2356 static int PortTestMatchReal09(void)
2357 {
2358  const char *sig = "alert tcp any 47000:50000 -> any 70:100 (msg:\"Nothing..\";"
2359  " content:\"GET\"; sid:1;)";
2360  return PortTestMatchRealWrp(sig, 1);
2361 }
2362 
2363 /**
2364  * \test Check if we negate a dest port range
2365  */
2366 static int PortTestMatchReal10(void)
2367 {
2368  const char *sig = "alert tcp any any -> any !70:100 (msg:\"Nothing..\";"
2369  " content:\"GET\"; sid:1;)";
2370  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2371 }
2372 
2373 /**
2374  * \test Check if we negate a source port range
2375  */
2376 static int PortTestMatchReal11(void)
2377 {
2378  const char *sig = "alert tcp any !47000:50000 -> any any (msg:\"Nothing..\";"
2379  " content:\"GET\"; sid:1;)";
2380  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2381 }
2382 
2383 /**
2384  * \test Check if we negate both port ranges
2385  */
2386 static int PortTestMatchReal12(void)
2387 {
2388  const char *sig = "alert tcp any !47000:50000 -> any !70:100 (msg:\"Nothing..\";"
2389  " content:\"GET\"; sid:1;)";
2390  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2391 }
2392 
2393 /**
2394  * \test Check if we autocomplete ranges correctly
2395  */
2396 static int PortTestMatchReal13(void)
2397 {
2398  const char *sig = "alert tcp any 47000:50000 -> any !81: (msg:\"Nothing..\";"
2399  " content:\"GET\"; sid:1;)";
2400  return PortTestMatchRealWrp(sig, 1);
2401 }
2402 
2403 /**
2404  * \test Check if we autocomplete ranges correctly
2405  */
2406 static int PortTestMatchReal14(void)
2407 {
2408  const char *sig = "alert tcp any !48000:50000 -> any :100 (msg:\"Nothing..\";"
2409  " content:\"GET\"; sid:1;)";
2410  return PortTestMatchRealWrp(sig, 1);
2411 }
2412 
2413 /**
2414  * \test Check if we autocomplete ranges correctly
2415  */
2416 static int PortTestMatchReal15(void)
2417 {
2418  const char *sig = "alert tcp any :50000 -> any 81:100 (msg:\"Nothing..\";"
2419  " content:\"GET\"; sid:1;)";
2420  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2421 }
2422 
2423 /**
2424  * \test Check if we separate ranges correctly
2425  */
2426 static int PortTestMatchReal16(void)
2427 {
2428  const char *sig = "alert tcp any 100: -> any ![0:79,81:65535] (msg:\"Nothing..\";"
2429  " content:\"GET\"; sid:1;)";
2430  return PortTestMatchRealWrp(sig, 1);
2431 }
2432 
2433 /**
2434  * \test Check if we separate ranges correctly
2435  */
2436 static int PortTestMatchReal17(void)
2437 {
2438  const char *sig = "alert tcp any ![0:39999,48000:50000] -> any ![0:80,82:65535] "
2439  "(msg:\"Nothing..\"; content:\"GET\"; sid:1;)";
2440  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2441 }
2442 
2443 /**
2444  * \test Check if we separate ranges correctly
2445  */
2446 static int PortTestMatchReal18(void)
2447 {
2448  const char *sig = "alert tcp any ![0:39999,48000:50000] -> any 80 (msg:\"Nothing"
2449  " at all\"; content:\"GET\"; sid:1;)";
2450  return PortTestMatchRealWrp(sig, 1);
2451 }
2452 
2453 /**
2454  * \test Check if we separate ranges correctly
2455  */
2456 static int PortTestMatchReal19(void)
2457 {
2458  const char *sig = "alert tcp any any -> any 80 (msg:\"Nothing..\";"
2459  " content:\"GET\"; sid:1;)";
2460  return PortTestMatchRealWrp(sig, 1);
2461 }
2462 
2463 static int PortTestMatchDoubleNegation(void)
2464 {
2465  int result = 0;
2466  DetectPort *head = NULL, *nhead = NULL;
2467 
2468  if (DetectPortParseDo(NULL, &head, &nhead, "![!80]", 0, NULL, 0) == -1)
2469  return result;
2470 
2471  result = (head != NULL);
2472  result = (nhead == NULL);
2473 
2474  return result;
2475 }
2476 
2477 // Test that negation is successfully parsed with whitespace for port strings of
2478 // length < 16
2479 static int DetectPortParseDoTest(void)
2480 {
2483  DetectPort *head = NULL;
2484  DetectPort *nhead = NULL;
2485  const char *str = "[30:50, !45]";
2486  int r = DetectPortParseDo(de_ctx, &head, &nhead, str, 0, NULL, 0);
2487 
2488  // Assertions
2489  FAIL_IF_NULL(head);
2490  FAIL_IF_NULL(nhead);
2491  FAIL_IF(r < 0);
2492  FAIL_IF(head->port != 30);
2493  FAIL_IF(head->port2 != 50);
2494  FAIL_IF(nhead->port != 45);
2495  FAIL_IF(nhead->port2 != 45);
2496  DetectPortCleanupList(NULL, head);
2497  DetectPortCleanupList(NULL, nhead);
2498  PASS;
2499 }
2500 
2501 static int DetectPortParseDoTest2(void)
2502 {
2505  DetectPort *head = NULL;
2506  DetectPort *nhead = NULL;
2507  const char *str = "[30:50, !45]";
2508  int r = DetectPortParseDo(de_ctx, &head, &nhead, str, 0, NULL, 0);
2509  FAIL_IF(r < 0);
2510  DetectPortCleanupList(NULL, head);
2511  DetectPortCleanupList(NULL, nhead);
2512  PASS;
2513 }
2514 
2515 // Verifies correct parsing when negation port string length < 16
2516 static int PortParseTestLessThan14Spaces(void)
2517 {
2518  const char *str = " 45";
2519  DetectPort *dp = PortParse(str);
2520  FAIL_IF_NULL(dp);
2521  FAIL_IF(dp->port != 45);
2522  FAIL_IF(dp->port2 != 45);
2523  DetectPortFree(NULL, dp);
2524  PASS;
2525 }
2526 
2527 // Verifies NULL returned when negation port string length == 16
2528 static int PortParseTest14Spaces(void)
2529 {
2530  const char *str = " 45";
2531  DetectPort *dp = PortParse(str);
2532  FAIL_IF_NULL(dp);
2533  FAIL_IF(dp->port != 45);
2534  FAIL_IF(dp->port2 != 45);
2535  DetectPortFree(NULL, dp);
2536  PASS;
2537 }
2538 
2539 // Verifies NULL returned when negation port string length >= 16
2540 static int PortParseTestMoreThan14Spaces(void)
2541 {
2542  const char *str = " 45";
2543  DetectPort *dp = PortParse(str);
2544  FAIL_IF_NULL(dp);
2545  FAIL_IF(dp->port != 45);
2546  FAIL_IF(dp->port2 != 45);
2547  DetectPortFree(NULL, dp);
2548  PASS;
2549 }
2550 
2551 void DetectPortTests(void)
2552 {
2553  UtRegisterTest("PortTestParse01", PortTestParse01);
2554  UtRegisterTest("PortTestParse02", PortTestParse02);
2555  UtRegisterTest("PortTestParse03", PortTestParse03);
2556  UtRegisterTest("PortTestParse04", PortTestParse04);
2557  UtRegisterTest("PortTestParse05", PortTestParse05);
2558  UtRegisterTest("PortTestParse07", PortTestParse07);
2559  UtRegisterTest("PortTestParse08", PortTestParse08);
2560  UtRegisterTest("PortTestParse09", PortTestParse09);
2561  UtRegisterTest("PortTestParse10", PortTestParse10);
2562  UtRegisterTest("PortTestParse11", PortTestParse11);
2563  UtRegisterTest("PortTestParse12", PortTestParse12);
2564  UtRegisterTest("PortTestParse13", PortTestParse13);
2565  UtRegisterTest("PortTestParse14", PortTestParse14);
2566  UtRegisterTest("PortTestParse15", PortTestParse15);
2567  UtRegisterTest("PortTestParse16", PortTestParse16);
2568  UtRegisterTest("PortTestFunctions01", PortTestFunctions01);
2569  UtRegisterTest("PortTestFunctions02", PortTestFunctions02);
2570  UtRegisterTest("PortTestFunctions03", PortTestFunctions03);
2571  UtRegisterTest("PortTestFunctions04", PortTestFunctions04);
2572  UtRegisterTest("PortTestFunctions05", PortTestFunctions05);
2573  UtRegisterTest("PortTestFunctions06", PortTestFunctions06);
2574  UtRegisterTest("PortTestFunctions07", PortTestFunctions07);
2575  UtRegisterTest("PortTestMatchReal01", PortTestMatchReal01);
2576  UtRegisterTest("PortTestMatchReal02", PortTestMatchReal02);
2577  UtRegisterTest("PortTestMatchReal03", PortTestMatchReal03);
2578  UtRegisterTest("PortTestMatchReal04", PortTestMatchReal04);
2579  UtRegisterTest("PortTestMatchReal05", PortTestMatchReal05);
2580  UtRegisterTest("PortTestMatchReal06", PortTestMatchReal06);
2581  UtRegisterTest("PortTestMatchReal07", PortTestMatchReal07);
2582  UtRegisterTest("PortTestMatchReal08", PortTestMatchReal08);
2583  UtRegisterTest("PortTestMatchReal09", PortTestMatchReal09);
2584  UtRegisterTest("PortTestMatchReal10", PortTestMatchReal10);
2585  UtRegisterTest("PortTestMatchReal11", PortTestMatchReal11);
2586  UtRegisterTest("PortTestMatchReal12", PortTestMatchReal12);
2587  UtRegisterTest("PortTestMatchReal13", PortTestMatchReal13);
2588  UtRegisterTest("PortTestMatchReal14", PortTestMatchReal14);
2589  UtRegisterTest("PortTestMatchReal15", PortTestMatchReal15);
2590  UtRegisterTest("PortTestMatchReal16", PortTestMatchReal16);
2591  UtRegisterTest("PortTestMatchReal17", PortTestMatchReal17);
2592  UtRegisterTest("PortTestMatchReal18", PortTestMatchReal18);
2593  UtRegisterTest("PortTestMatchReal19", PortTestMatchReal19);
2594  UtRegisterTest("PortTestMatchDoubleNegation", PortTestMatchDoubleNegation);
2595  UtRegisterTest("DetectPortParseDoTest", DetectPortParseDoTest);
2596  UtRegisterTest("DetectPortParseDoTest2", DetectPortParseDoTest2);
2597  UtRegisterTest("PortParseTestLessThan14Spaces", PortParseTestLessThan14Spaces);
2598  UtRegisterTest("PortParseTest14Spaces", PortParseTest14Spaces);
2599  UtRegisterTest("PortParseTestMoreThan14Spaces", PortParseTestMoreThan14Spaces);
2600 }
2601 
2602 #endif /* UNITTESTS */
2603 
DetectEngineCtx_::sgh_hash_table
HashListTable * sgh_hash_table
Definition: detect.h:863
util-byte.h
host.h
DetectPortCmp
int DetectPortCmp(DetectPort *a, DetectPort *b)
Function that compare port groups.
Definition: detect-engine-port.c:558
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DetectPortHashInit
int DetectPortHashInit(DetectEngineCtx *de_ctx)
Initializes the hash table in the detection engine context to hold the DetectPort hash.
Definition: detect-engine-port.c:1438
detect-engine-siggroup.h
DetectPortListsAreEqual
bool DetectPortListsAreEqual(DetectPort *list1, DetectPort *list2)
Checks if two port group lists are equal.
Definition: detect-engine-port.c:702
ConfNode_::val
char * val
Definition: conf.h:34
Signature_::num
SigIntId num
Definition: detect.h:594
DetectPortInsert
int DetectPortInsert(DetectEngineCtx *de_ctx, DetectPort **head, DetectPort *new)
function for inserting a port group object. This also makes sure SigGroupContainer lists are handled ...
Definition: detect-engine-port.c:153
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SigGroupHeadInitData_::sig_array
uint8_t * sig_array
Definition: detect.h:1398
DetectPortFree
void DetectPortFree(const DetectEngineCtx *de_ctx, DetectPort *dp)
Free a DetectPort and its members.
Definition: detect-engine-port.c:80
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
DetectPort_::port
uint16_t port
Definition: detect.h:213
PORT_SIGGROUPHEAD_COPY
#define PORT_SIGGROUPHEAD_COPY
Definition: detect.h:209
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:167
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:181
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:827
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:337
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
PORT_ER
@ PORT_ER
Definition: detect.h:197
DetectPort_::next
struct DetectPort_ * next
Definition: detect.h:226
UTHPacketMatchSig
int UTHPacketMatchSig(Packet *p, const char *sig)
Definition: util-unittest-helper.c:843
DetectEngineCtx_::dport_hash_table
HashListTable * dport_hash_table
Definition: detect.h:966
DetectPort_::sh
struct SigGroupHead_ * sh
Definition: detect.h:223
DetectPortPrintList
void DetectPortPrintList(DetectPort *head)
Helper function used to print the list of ports present in this DetectPort list.
Definition: detect-engine-port.c:100
HashListTableLookup
void * HashListTableLookup(HashListTable *ht, void *data, uint16_t datalen)
Definition: util-hashlist.c:256
CleanVariableResolveList
void CleanVariableResolveList(ResolvedVariablesList *var_list)
Definition: util-var.c:162
DetectPortTestConfVars
int DetectPortTestConfVars(void)
Definition: detect-engine-port.c:1173
util-var.h
PORT_EQ
@ PORT_EQ
Definition: detect.h:200
PortParse
DetectPort * PortParse(const char *str)
Helper function for parsing port strings.
Definition: detect-engine-port.c:1285
DetectPort_::port2
uint16_t port2
Definition: detect.h:214
util-unittest.h
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DetectPort_::flags
uint8_t flags
Definition: detect.h:216
DetectPortPrint
void DetectPortPrint(DetectPort *dp)
Helper function that print the DetectPort info.
Definition: detect-engine-port.c:654
HashListTableAdd
int HashListTableAdd(HashListTable *ht, void *data, uint16_t datalen)
Definition: util-hashlist.c:124
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
HashListTable_::array_size
uint32_t array_size
Definition: util-hashlist.h:41
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:543
DetectPortCopySingle
DetectPort * DetectPortCopySingle(DetectEngineCtx *de_ctx, DetectPort *src)
Function that return a copy of DetectPort src sigs.
Definition: detect-engine-port.c:614
util-cidr.h
DetectPortParse
int DetectPortParse(const DetectEngineCtx *de_ctx, DetectPort **head, const char *str)
Function for parsing port strings.
Definition: detect-engine-port.c:1249
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:236
HashListTableInit
HashListTable * HashListTableInit(uint32_t size, uint32_t(*Hash)(struct HashListTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
Definition: util-hashlist.c:35
PORT_FLAG_ANY
#define PORT_FLAG_ANY
Definition: detect.h:207
decode.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
SC_RULE_VARS_PORT_GROUPS
@ SC_RULE_VARS_PORT_GROUPS
Definition: util-rule-vars.h:32
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
PORT_GT
@ PORT_GT
Definition: detect.h:204
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect-engine-mpm.h
detect.h
StreamContentInspectEngineData::s
const Signature * s
Definition: detect-engine-payload.c:283
pkt-var.h
detect-engine-port.h
DetectPort_
Port structure for detection engine.
Definition: detect.h:212
SigGroupHead_::init
SigGroupHeadInitData * init
Definition: detect.h:1448
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:295
util-profiling.h
util-rule-vars.h
Packet_
Definition: decode.h:429
conf.h
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
PORT_LT
@ PORT_LT
Definition: detect.h:198
SigGroupHeadAppendSig
int SigGroupHeadAppendSig(const DetectEngineCtx *de_ctx, SigGroupHead **sgh, const Signature *s)
Add a Signature to a SigGroupHead.
Definition: detect-engine-siggroup.c:340
HashListTable_
Definition: util-hashlist.h:37
SigGroupHeadFree
void SigGroupHeadFree(const DetectEngineCtx *de_ctx, SigGroupHead *sgh)
Free a SigGroupHead and its members.
Definition: detect-engine-siggroup.c:163
Flow_::next
struct Flow_ * next
Definition: flow.h:388
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
PORT_LE
@ PORT_LE
Definition: detect.h:199
suricata-common.h
HashListTableFree
void HashListTableFree(HashListTable *ht)
Definition: util-hashlist.c:90
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:689
packet.h
ConfNode_::name
char * name
Definition: conf.h:33
DetectPort_::prev
struct DetectPort_ * prev
Definition: detect.h:225
PORT_ES
@ PORT_ES
Definition: detect.h:201
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:286
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
head
Flow * head
Definition: flow-hash.h:1
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
detect-parse.h
src
uint16_t src
Definition: app-layer-dnp3.h:5
Signature_
Signature container.
Definition: detect.h:582
AddVariableToResolveList
int AddVariableToResolveList(ResolvedVariablesList *list, const char *var)
Definition: util-var.c:133
address
uint8_t address
Definition: decode-ppp.h:0
UTHBuildPacketFromEth
Packet * UTHBuildPacketFromEth(uint8_t *raw_eth, uint16_t pktsize)
UTHBuildPacketFromEth is a wrapper that build a packet for the rawbytes.
Definition: util-unittest-helper.c:394
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2573
PORT_FLAG_NOT
#define PORT_FLAG_NOT
Definition: detect.h:208
DetectPortHashAdd
int DetectPortHashAdd(DetectEngineCtx *de_ctx, DetectPort *dp)
Adds a DetectPort to the detection engine context DetectPort hash table.
Definition: detect-engine-port.c:1458
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:41
DetectPortTests
void DetectPortTests(void)
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
DetectPortHashFree
void DetectPortHashFree(DetectEngineCtx *de_ctx)
Frees the hash table - DetectEngineCtx->sgh_hash_table, allocated by DetectPortInit() function.
Definition: detect-engine-port.c:1489
SCRuleVarsGetConfVar
const char * SCRuleVarsGetConfVar(const DetectEngineCtx *de_ctx, const char *conf_var_name, SCRuleVarsType conf_vars_type)
Definition: util-rule-vars.c:65
DetectPortHashLookup
DetectPort * DetectPortHashLookup(DetectEngineCtx *de_ctx, DetectPort *dp)
Used to lookup a DetectPort hash from the detection engine context DetectPort hash table.
Definition: detect-engine-port.c:1474
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
flow-var.h
DetectPortCleanupList
void DetectPortCleanupList(const DetectEngineCtx *de_ctx, DetectPort *head)
Free a DetectPort list and each of its members.
Definition: detect-engine-port.c:124
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:771
PORT_EB
@ PORT_EB
Definition: detect.h:202
DetectPortLookupGroup
DetectPort * DetectPortLookupGroup(DetectPort *dp, uint16_t port)
Function that find the group matching address in a group head.
Definition: detect-engine-port.c:677
SigGroupHeadCopySigs
int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHead **dst)
Copies the bitarray holding the sids from the source SigGroupHead to the destination SigGroupHead.
Definition: detect-engine-siggroup.c:393
SigGroupHeadClearSigs
int SigGroupHeadClearSigs(SigGroupHead *)
Clears the bitarray holding the sids for this SigGroupHead.
Definition: detect-engine-siggroup.c:369
PORT_GE
@ PORT_GE
Definition: detect.h:203