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 unittesting
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  *head = ag2->next;
1142  } else {
1143  ag2->prev->next = ag2->next;
1144  }
1145 
1146  if (ag2->next != NULL) {
1147  ag2->next->prev = ag2->prev;
1148  }
1149  /** store the next ptr and remove the group */
1150  DetectPort *next_ag2 = ag2->next;
1151  DetectPortFree(de_ctx,ag2);
1152  ag2 = next_ag2;
1153  } else {
1154  ag2 = ag2->next;
1155  }
1156  }
1157  }
1158 
1159  for (ag2 = *head; ag2 != NULL; ag2 = ag2->next) {
1160  SCLogDebug("ag2 %p", ag2);
1161  DetectPortPrint(ag2);
1162  }
1163 
1164  if (*head == NULL) {
1165  SCLogError("no ports left after merging ports with negated ports");
1166  goto error;
1167  }
1168 
1169  return 0;
1170 error:
1171  if (ad != NULL)
1172  DetectPortFree(de_ctx, ad);
1173  return -1;
1174 }
1175 
1177 {
1178  SCLogDebug("Testing port conf vars for any misconfigured values");
1179 
1180  ResolvedVariablesList var_list = TAILQ_HEAD_INITIALIZER(var_list);
1181 
1182  ConfNode *port_vars_node = ConfGetNode("vars.port-groups");
1183  if (port_vars_node == NULL) {
1184  return 0;
1185  }
1186 
1187  ConfNode *seq_node;
1188  TAILQ_FOREACH(seq_node, &port_vars_node->head, next) {
1189  SCLogDebug("Testing %s - %s\n", seq_node->name, seq_node->val);
1190 
1191  DetectPort *gh = DetectPortInit();
1192  if (gh == NULL) {
1193  goto error;
1194  }
1195  DetectPort *ghn = NULL;
1196 
1197  if (seq_node->val == NULL) {
1198  SCLogError("Port var \"%s\" probably has a sequence(something "
1199  "in brackets) value set without any quotes. Please "
1200  "quote it using \"..\".",
1201  seq_node->name);
1202  DetectPortCleanupList(NULL, gh);
1203  goto error;
1204  }
1205 
1206  int r = DetectPortParseDo(NULL, &gh, &ghn, seq_node->val,
1207  /* start with negate no */0, &var_list, 0);
1208 
1209  CleanVariableResolveList(&var_list);
1210 
1211  if (r < 0) {
1212  DetectPortCleanupList(NULL, gh);
1213  SCLogError("failed to parse port var \"%s\" with value \"%s\". "
1214  "Please check its syntax",
1215  seq_node->name, seq_node->val);
1216  goto error;
1217  }
1218 
1219  if (DetectPortIsCompletePortSpace(ghn)) {
1220  SCLogError("Port var - \"%s\" has the complete Port range negated "
1221  "with its value \"%s\". Port space range is NIL. "
1222  "Probably have a !any or a port range that supplies "
1223  "a NULL address range",
1224  seq_node->name, seq_node->val);
1225  DetectPortCleanupList(NULL, gh);
1226  DetectPortCleanupList(NULL, ghn);
1227  goto error;
1228  }
1229 
1230  if (gh != NULL)
1231  DetectPortCleanupList(NULL, gh);
1232  if (ghn != NULL)
1233  DetectPortCleanupList(NULL, ghn);
1234  }
1235 
1236  return 0;
1237  error:
1238  return -1;
1239 }
1240 
1241 
1242 /**
1243  * \brief Function for parsing port strings
1244  *
1245  * \param de_ctx Pointer to the detection engine context
1246  * \param head Pointer to the head of the DetectPort group list
1247  * \param str Pointer to the port string
1248  *
1249  * \retval 0 on success
1250  * \retval -1 on error
1251  */
1253  DetectPort **head, const char *str)
1254 {
1255  SCLogDebug("Port string to be parsed - str %s", str);
1256 
1257  /* negate port list */
1258  DetectPort *nhead = NULL;
1259 
1260  int r = DetectPortParseDo(de_ctx, head, &nhead, str,
1261  /* start with negate no */ 0, NULL, 0);
1262  if (r < 0)
1263  goto error;
1264 
1265  SCLogDebug("head %p %p, nhead %p", head, *head, nhead);
1266 
1267  /* merge the 'not' address groups */
1268  if (DetectPortParseMergeNotPorts(de_ctx, head, &nhead) < 0)
1269  goto error;
1270 
1271  /* free the temp negate head */
1272  DetectPortCleanupList(de_ctx, nhead);
1273  return 0;
1274 
1275 error:
1276  DetectPortCleanupList(de_ctx, nhead);
1277  return -1;
1278 }
1279 
1280 /**
1281  * \brief Helper function for parsing port strings
1282  *
1283  * \param str Pointer to the port string
1284  *
1285  * \retval DetectPort pointer of the parse string on success
1286  * \retval NULL on error
1287  */
1288 DetectPort *PortParse(const char *str)
1289 {
1290  char *port2 = NULL;
1291  char portstr[16];
1292 
1293  /* strip leading spaces */
1294  while (isspace(*str))
1295  str++;
1296  if (strlen(str) >= 16)
1297  return NULL;
1298  strlcpy(portstr, str, sizeof(portstr));
1299 
1300  DetectPort *dp = DetectPortInit();
1301  if (dp == NULL)
1302  goto error;
1303 
1304  /* we dup so we can put a nul-termination in it later */
1305  char *port = portstr;
1306 
1307  /* handle the negation case */
1308  if (port[0] == '!') {
1309  dp->flags |= PORT_FLAG_NOT;
1310  port++;
1311  }
1312 
1313  /* see if the address is an ipv4 or ipv6 address */
1314  if ((port2 = strchr(port, ':')) != NULL) {
1315  /* 80:81 range format */
1316  port2[0] = '\0';
1317  port2++;
1318 
1319  if (strcmp(port, "") != 0) {
1320  if (!DetectPortIsValidRange(port, &dp->port))
1321  goto error;
1322  } else {
1323  dp->port = 0;
1324  }
1325 
1326  if (strcmp(port2, "") != 0) {
1327  if (!DetectPortIsValidRange(port2, &dp->port2))
1328  goto error;
1329  } else {
1330  dp->port2 = 65535;
1331  }
1332 
1333  /* a > b is illegal, a == b is ok */
1334  if (dp->port > dp->port2)
1335  goto error;
1336  } else {
1337  if (strcasecmp(port,"any") == 0) {
1338  dp->port = 0;
1339  dp->port2 = 65535;
1340  } else {
1341  if (!DetectPortIsValidRange(port, &dp->port))
1342  goto error;
1343  dp->port2 = dp->port;
1344  }
1345  }
1346 
1347  return dp;
1348 
1349 error:
1350  if (dp != NULL)
1351  DetectPortCleanupList(NULL, dp);
1352  return NULL;
1353 }
1354 
1355 /**
1356  * \brief Helper function to check if a parsed port is in the valid range
1357  * of available ports
1358  *
1359  * \param str Pointer to the port string
1360  *
1361  *
1362  * \retval true if port is in the valid range
1363  * \retval false if invalid
1364  */
1365 static bool DetectPortIsValidRange(char *port, uint16_t *port_val)
1366 {
1367  if (StringParseUint16(port_val, 10, 0, (const char *)port) < 0)
1368  return false;
1369 
1370  return true;
1371 }
1372 
1373 /********************** End parsing routines ********************/
1374 
1375 /* hash table */
1376 
1377 /**
1378  * \brief The hash function to be the used by the hash table -
1379  * DetectEngineCtx->dport_hash_table.
1380  *
1381  * \param ht Pointer to the hash table.
1382  * \param data Pointer to the DetectPort.
1383  * \param datalen Not used in our case.
1384  *
1385  * \retval hash The generated hash value.
1386  */
1387 static uint32_t DetectPortHashFunc(HashListTable *ht, void *data, uint16_t datalen)
1388 {
1389  DetectPort *p = (DetectPort *)data;
1390  SCLogDebug("hashing port %p", p);
1391 
1392  uint32_t hash = ((uint32_t)p->port << 16) | p->port2;
1393 
1394  hash %= ht->array_size;
1395  SCLogDebug("hash %"PRIu32, hash);
1396  return hash;
1397 }
1398 
1399 /**
1400  * \brief The Compare function to be used by the DetectPort hash table -
1401  * DetectEngineCtx->dport_hash_table.
1402  *
1403  * \param data1 Pointer to the first DetectPort.
1404  * \param len1 Not used.
1405  * \param data2 Pointer to the second DetectPort.
1406  * \param len2 Not used.
1407  *
1408  * \retval 1 If the 2 DetectPort sent as args match.
1409  * \retval 0 If the 2 DetectPort sent as args do not match.
1410  */
1411 static char DetectPortCompareFunc(void *data1, uint16_t len1,
1412  void *data2, uint16_t len2)
1413 {
1414  DetectPort *dp1 = (DetectPort *)data1;
1415  DetectPort *dp2 = (DetectPort *)data2;
1416 
1417  if (data1 == NULL || data2 == NULL)
1418  return 0;
1419 
1420  if (dp1->port == dp2->port && dp1->port2 == dp2->port2)
1421  return 1;
1422 
1423  return 0;
1424 }
1425 
1426 static void DetectPortHashFreeFunc(void *ptr)
1427 {
1428  DetectPort *p = ptr;
1429  DetectPortFree(NULL, p);
1430 }
1431 
1432 /**
1433  * \brief Initializes the hash table in the detection engine context to hold the
1434  * DetectPort hash.
1435  *
1436  * \param de_ctx Pointer to the detection engine context.
1437  *
1438  * \retval 0 On success.
1439  * \retval -1 On failure.
1440  */
1442 {
1443  de_ctx->dport_hash_table = HashListTableInit(4096, DetectPortHashFunc,
1444  DetectPortCompareFunc,
1445  DetectPortHashFreeFunc);
1446  if (de_ctx->dport_hash_table == NULL)
1447  return -1;
1448 
1449  return 0;
1450 }
1451 
1452 /**
1453  * \brief Adds a DetectPort to the detection engine context DetectPort
1454  * hash table.
1455  *
1456  * \param de_ctx Pointer to the detection engine context.
1457  * \param dp Pointer to the DetectPort.
1458  *
1459  * \retval ret 0 on Successfully adding the DetectPort; -1 on failure.
1460  */
1462 {
1463  int ret = HashListTableAdd(de_ctx->dport_hash_table, (void *)dp, 0);
1464  return ret;
1465 }
1466 
1467 /**
1468  * \brief Used to lookup a DetectPort hash from the detection engine context
1469  * DetectPort hash table.
1470  *
1471  * \param de_ctx Pointer to the detection engine context.
1472  * \param sgh Pointer to the DetectPort.
1473  *
1474  * \retval rsgh On success a pointer to the DetectPort if the DetectPort is
1475  * found in the hash table; NULL on failure.
1476  */
1478 {
1479  SCEnter();
1480 
1481  DetectPort *rdp = HashListTableLookup(de_ctx->dport_hash_table, (void *)dp, 0);
1482 
1483  SCReturnPtr(rdp, "DetectPort");
1484 }
1485 
1486 /**
1487  * \brief Frees the hash table - DetectEngineCtx->sgh_hash_table, allocated by
1488  * DetectPortInit() function.
1489  *
1490  * \param de_ctx Pointer to the detection engine context.
1491  */
1493 {
1494  if (de_ctx->sgh_hash_table == NULL)
1495  return;
1496 
1498  de_ctx->dport_hash_table = NULL;
1499 
1500  return;
1501 }
1502 
1503 /*---------------------- Unittests -------------------------*/
1504 
1505 #ifdef UNITTESTS
1506 #include "packet.h"
1507 
1508 /**
1509  * \brief Do a sorted insert, where the top of the list should be the biggest
1510  * port range.
1511  *
1512  * \todo XXX current sorting only works for overlapping ranges
1513  *
1514  * \param head Pointer to the DetectPort list head
1515  * \param dp Pointer to DetectPort to search in the DetectPort list
1516  * \retval 0 if dp is added correctly
1517  */
1518 static int PortTestDetectPortAdd(DetectPort **head, DetectPort *dp)
1519 {
1520  DetectPort *cur, *prev_cur = NULL;
1521 
1522  //SCLogDebug("DetectPortAdd: adding "); DetectPortPrint(ag); SCLogDebug("");
1523 
1524  if (*head != NULL) {
1525  for (cur = *head; cur != NULL; cur = cur->next) {
1526  prev_cur = cur;
1527  int r = DetectPortCmp(dp,cur);
1528  if (r == PORT_EB) {
1529  /* insert here */
1530  dp->prev = cur->prev;
1531  dp->next = cur;
1532 
1533  cur->prev = dp;
1534  if (*head == cur) {
1535  *head = dp;
1536  } else {
1537  dp->prev->next = dp;
1538  }
1539  return 0;
1540  }
1541  }
1542  dp->prev = prev_cur;
1543  if (prev_cur != NULL)
1544  prev_cur->next = dp;
1545  } else {
1546  *head = dp;
1547  }
1548 
1549  return 0;
1550 }
1551 
1552 
1553 /**
1554  * \test Check if a DetectPort is properly allocated
1555  */
1556 static int PortTestParse01 (void)
1557 {
1558  DetectPort *dd = NULL;
1559  int r = DetectPortParse(NULL,&dd,"80");
1560  FAIL_IF_NOT(r == 0);
1561  DetectPortFree(NULL, dd);
1562  PASS;
1563 }
1564 
1565 /**
1566  * \test Check if two ports are properly allocated in the DetectPort group
1567  */
1568 static int PortTestParse02 (void)
1569 {
1570  DetectPort *dd = NULL;
1571  int r = DetectPortParse(NULL,&dd,"80");
1572  FAIL_IF_NOT(r == 0);
1573  r = DetectPortParse(NULL,&dd,"22");
1574  FAIL_IF_NOT(r == 0);
1575  DetectPortCleanupList(NULL, dd);
1576  PASS;
1577 }
1578 
1579 /**
1580  * \test Check if two port ranges are properly allocated in the DetectPort group
1581  */
1582 static int PortTestParse03 (void)
1583 {
1584  DetectPort *dd = NULL;
1585  int r = DetectPortParse(NULL,&dd,"80:88");
1586  FAIL_IF_NOT(r == 0);
1587  r = DetectPortParse(NULL,&dd,"85:100");
1588  FAIL_IF_NOT(r == 0);
1589  DetectPortCleanupList(NULL, dd);
1590  PASS;
1591 }
1592 
1593 /**
1594  * \test Check if a negated port range is properly allocated in the DetectPort
1595  */
1596 static int PortTestParse04 (void)
1597 {
1598  DetectPort *dd = NULL;
1599  int r = DetectPortParse(NULL,&dd,"!80:81");
1600  FAIL_IF_NOT(r == 0);
1601  DetectPortCleanupList(NULL, dd);
1602  PASS;
1603 }
1604 
1605 /**
1606  * \test Check if a negated port range is properly fragmented in the allowed
1607  * real groups, ex !80:81 should allow 0:79 and 82:65535
1608  */
1609 static int PortTestParse05 (void)
1610 {
1611  DetectPort *dd = NULL;
1612  int r = DetectPortParse(NULL,&dd,"!80:81");
1613  FAIL_IF_NOT(r == 0);
1614  FAIL_IF_NULL(dd->next);
1615  FAIL_IF_NOT(dd->port == 0);
1616  FAIL_IF_NOT(dd->port2 == 79);
1617  FAIL_IF_NOT(dd->next->port == 82);
1618  FAIL_IF_NOT(dd->next->port2 == 65535);
1619  DetectPortCleanupList(NULL, dd);
1620  PASS;
1621 }
1622 
1623 /**
1624  * \test Check if a negated port range is properly fragmented in the allowed
1625  * real groups
1626  */
1627 static int PortTestParse07 (void)
1628 {
1629  DetectPort *dd = NULL;
1630 
1631  int r = DetectPortParse(NULL,&dd,"!21:902");
1632  FAIL_IF_NOT(r == 0);
1633  FAIL_IF_NULL(dd->next);
1634 
1635  FAIL_IF_NOT(dd->port == 0);
1636  FAIL_IF_NOT(dd->port2 == 20);
1637  FAIL_IF_NOT(dd->next->port == 903);
1638  FAIL_IF_NOT(dd->next->port2 == 65535);
1639 
1640  DetectPortCleanupList(NULL, dd);
1641  PASS;
1642 }
1643 
1644 /**
1645  * \test Check if we dont allow invalid port range specification
1646  */
1647 static int PortTestParse08 (void)
1648 {
1649  DetectPort *dd = NULL;
1650 
1651  int r = DetectPortParse(NULL,&dd,"[80:!80]");
1652  FAIL_IF(r == 0);
1653 
1654  DetectPortCleanupList(NULL, dd);
1655  PASS;
1656 }
1657 
1658 /**
1659  * \test Check if we autocomplete correctly an open range
1660  */
1661 static int PortTestParse09 (void)
1662 {
1663  DetectPort *dd = NULL;
1664 
1665  int r = DetectPortParse(NULL,&dd,"1024:");
1666  FAIL_IF_NOT(r == 0);
1667  FAIL_IF_NULL(dd);
1668 
1669  FAIL_IF_NOT(dd->port == 1024);
1670  FAIL_IF_NOT(dd->port2 == 0xffff);
1671 
1672  DetectPortCleanupList(NULL, dd);
1673  PASS;
1674 }
1675 
1676 /**
1677  * \test Test we don't allow a port that is too big
1678  */
1679 static int PortTestParse10 (void)
1680 {
1681  DetectPort *dd = NULL;
1682  int r = DetectPortParse(NULL,&dd,"77777777777777777777777777777777777777777777");
1683  FAIL_IF(r == 0);
1684  PASS;
1685 }
1686 
1687 /**
1688  * \test Test second port of range being too big
1689  */
1690 static int PortTestParse11 (void)
1691 {
1692  DetectPort *dd = NULL;
1693 
1694  int r = DetectPortParse(NULL,&dd,"1024:65536");
1695  FAIL_IF(r == 0);
1696  PASS;
1697 }
1698 
1699 /**
1700  * \test Test second port of range being just right
1701  */
1702 static int PortTestParse12 (void)
1703 {
1704  DetectPort *dd = NULL;
1705  int r = DetectPortParse(NULL,&dd,"1024:65535");
1706  FAIL_IF_NOT(r == 0);
1707  DetectPortFree(NULL, dd);
1708  PASS;
1709 }
1710 
1711 /**
1712  * \test Test first port of range being too big
1713  */
1714 static int PortTestParse13 (void)
1715 {
1716  DetectPort *dd = NULL;
1717  int r = DetectPortParse(NULL,&dd,"65536:65535");
1718  FAIL_IF(r == 0);
1719  PASS;
1720 }
1721 
1722 /**
1723  * \test Test merging port groups
1724  */
1725 static int PortTestParse14 (void)
1726 {
1727  DetectPort *dd = NULL;
1728 
1729  int r = DetectPortParseInsertString(NULL, &dd, "0:100");
1730  FAIL_IF_NOT(r == 0);
1731  r = DetectPortParseInsertString(NULL, &dd, "1000:65535");
1732  FAIL_IF_NOT(r == 0);
1733  FAIL_IF_NULL(dd->next);
1734 
1735  FAIL_IF_NOT(dd->port == 0);
1736  FAIL_IF_NOT(dd->port2 == 100);
1737  FAIL_IF_NOT(dd->next->port == 1000);
1738  FAIL_IF_NOT(dd->next->port2 == 65535);
1739 
1740  DetectPortCleanupList(NULL, dd);
1741  PASS;
1742 }
1743 
1744 /**
1745  * \test Test merging negated port groups
1746  */
1747 static int PortTestParse15 (void)
1748 {
1749  DetectPort *dd = NULL;
1750 
1751  int r = DetectPortParse(NULL,&dd,"![0:100,1000:3000]");
1752  FAIL_IF_NOT(r == 0);
1753  FAIL_IF_NULL(dd->next);
1754 
1755  FAIL_IF_NOT(dd->port == 101);
1756  FAIL_IF_NOT(dd->port2 == 999);
1757  FAIL_IF_NOT(dd->next->port == 3001);
1758  FAIL_IF_NOT(dd->next->port2 == 65535);
1759 
1760  DetectPortCleanupList(NULL, dd);
1761  PASS;
1762 }
1763 
1764 static int PortTestParse16 (void)
1765 {
1766  DetectPort *dd = NULL;
1767  int r = DetectPortParse(NULL,&dd,"\
1768 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\
1769 1:65535\
1770 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\
1771 ");
1772  FAIL_IF_NOT(r == 0);
1773  DetectPortFree(NULL, dd);
1774  dd = NULL;
1775  r = DetectPortParse(NULL,&dd,"\
1776 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\
1777 1:65535\
1778 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\
1779 ");
1780  FAIL_IF(r == 0);
1781  PASS;
1782 }
1783 
1784 /**
1785  * \test Test general functions
1786  */
1787 static int PortTestFunctions01(void)
1788 {
1789  DetectPort *head = NULL;
1790  DetectPort *dp1= NULL;
1791  int result = 0;
1792 
1793  /* Parse */
1794  int r = DetectPortParse(NULL,&head,"![0:100,1000:65535]");
1795  if (r != 0 || head->next != NULL)
1796  goto end;
1797 
1798  /* We should have only one DetectPort */
1799  if (!(head->port == 101))
1800  goto end;
1801  if (!(head->port2 == 999))
1802  goto end;
1803  if (!(head->next == NULL))
1804  goto end;
1805 
1806  r = DetectPortParse(NULL, &dp1,"2000:3000");
1807  if (r != 0 || dp1->next != NULL)
1808  goto end;
1809  if (!(dp1->port == 2000))
1810  goto end;
1811  if (!(dp1->port2 == 3000))
1812  goto end;
1813 
1814  /* Add */
1815  r = PortTestDetectPortAdd(&head, dp1);
1816  if (r != 0 || head->next == NULL)
1817  goto end;
1818  if (!(head->port == 101))
1819  goto end;
1820  if (!(head->port2 == 999))
1821  goto end;
1822  if (!(head->next->port == 2000))
1823  goto end;
1824  if (!(head->next->port2 == 3000))
1825  goto end;
1826 
1827  /* Match */
1828  if (!DetectPortMatch(head, 150))
1829  goto end;
1830  if (DetectPortMatch(head->next, 1500))
1831  goto end;
1832  if ((DetectPortMatch(head, 3500)))
1833  goto end;
1834  if ((DetectPortMatch(head, 50)))
1835  goto end;
1836 
1837  result = 1;
1838 end:
1839  if (dp1 != NULL)
1840  DetectPortFree(NULL, dp1);
1841  if (head != NULL)
1842  DetectPortFree(NULL, head);
1843  return result;
1844 }
1845 
1846 /**
1847  * \test Test general functions
1848  */
1849 static int PortTestFunctions02(void)
1850 {
1851  DetectPort *head = NULL;
1852  DetectPort *dp1= NULL;
1853  DetectPort *dp2= NULL;
1854  int result = 0;
1855 
1856  /* Parse */
1857  int r = DetectPortParse(NULL,&head, "![0:100,1000:65535]");
1858  if (r != 0 || head->next != NULL)
1859  goto end;
1860 
1861  r = DetectPortParse(NULL, &dp1, "!200:300");
1862  if (r != 0 || dp1->next == NULL)
1863  goto end;
1864 
1865  /* Merge Nots */
1866  r = DetectPortParseMergeNotPorts(NULL, &head, &dp1);
1867  if (r != 0 || head->next != NULL)
1868  goto end;
1869 
1870  r = DetectPortParse(NULL, &dp2, "!100:500");
1871  if (r != 0 || dp2->next == NULL)
1872  goto end;
1873 
1874  /* Merge Nots */
1875  r = DetectPortParseMergeNotPorts(NULL, &head, &dp2);
1876  if (r != 0 || head->next != NULL)
1877  goto end;
1878 
1879  if (!(head->port == 200))
1880  goto end;
1881  if (!(head->port2 == 300))
1882  goto end;
1883 
1884  result = 1;
1885 
1886 end:
1887  if (dp1 != NULL)
1888  DetectPortFree(NULL, dp1);
1889  if (dp2 != NULL)
1890  DetectPortFree(NULL, dp2);
1891  if (head != NULL)
1892  DetectPortFree(NULL, head);
1893  return result;
1894 }
1895 
1896 /**
1897  * \test Test general functions
1898  */
1899 static int PortTestFunctions03(void)
1900 {
1901  DetectPort *dp1= NULL;
1902  DetectPort *dp2= NULL;
1903  DetectPort *dp3= NULL;
1904  int result = 0;
1905 
1906  int r = DetectPortParse(NULL, &dp1, "200:300");
1907  if (r != 0)
1908  goto end;
1909 
1910  r = DetectPortParse(NULL, &dp2, "250:300");
1911  if (r != 0)
1912  goto end;
1913 
1914  /* Cut */
1915  DetectPortCut(NULL, dp1, dp2, &dp3);
1916  if (r != 0)
1917  goto end;
1918 
1919  if (!(dp1->port == 200))
1920  goto end;
1921  if (!(dp1->port2 == 249))
1922  goto end;
1923  if (!(dp2->port == 250))
1924  goto end;
1925  if (!(dp2->port2 == 300))
1926  goto end;
1927 
1928  dp1->port = 0;
1929  dp1->port2 = 500;
1930  dp2->port = 250;
1931  dp2->port2 = 750;
1932 
1933  /* Cut */
1934  DetectPortCut(NULL, dp1, dp2, &dp3);
1935  if (r != 0)
1936  goto end;
1937  if (!(dp1->port == 0))
1938  goto end;
1939  if (!(dp1->port2 == 249))
1940  goto end;
1941  if (!(dp2->port == 250))
1942  goto end;
1943  if (!(dp2->port2 == 500))
1944  goto end;
1945  if (!(dp3->port == 501))
1946  goto end;
1947  if (!(dp3->port2 == 750))
1948  goto end;
1949 
1950  result = 1;
1951 
1952 end:
1953  if (dp1 != NULL)
1954  DetectPortFree(NULL, dp1);
1955  if (dp2 != NULL)
1956  DetectPortFree(NULL, dp2);
1957  if (dp3 != NULL)
1958  DetectPortFree(NULL, dp3);
1959  return result;
1960 }
1961 
1962 /**
1963  * \test Test general functions
1964  */
1965 static int PortTestFunctions04(void)
1966 {
1967  DetectPort *dp1= NULL;
1968  DetectPort *dp2= NULL;
1969  int result = 0;
1970 
1971  int r = DetectPortParse(NULL, &dp1, "200:300");
1972  if (r != 0)
1973  goto end;
1974 
1975  dp2 = DetectPortInit();
1976 
1977  /* Cut Not */
1978  DetectPortCutNot(dp1, &dp2);
1979  if (r != 0)
1980  goto end;
1981 
1982  if (!(dp1->port == 0))
1983  goto end;
1984  if (!(dp1->port2 == 199))
1985  goto end;
1986  if (!(dp2->port == 301))
1987  goto end;
1988  if (!(dp2->port2 == 65535))
1989  goto end;
1990 
1991  result = 1;
1992 end:
1993  if (dp1 != NULL)
1994  DetectPortFree(NULL, dp1);
1995  if (dp2 != NULL)
1996  DetectPortFree(NULL, dp2);
1997  return result;
1998 }
1999 
2000 /**
2001  * \test Test general functions
2002  */
2003 static int PortTestFunctions05(void)
2004 {
2005  DetectPort *dp1 = NULL;
2006  DetectPort *dp2 = NULL;
2007  DetectPort *dp3 = NULL;
2008  int result = 0;
2009  int r = 0;
2010 
2012  Signature s[2];
2013  memset(s,0x00,sizeof(s));
2014 
2015  s[0].num = 0;
2016  s[1].num = 1;
2017 
2018  r = DetectPortParse(NULL, &dp1, "1024:65535");
2019  if (r != 0) {
2020  printf("r != 0 but %d: ", r);
2021  goto end;
2022  }
2023  SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]);
2024 
2025  r = DetectPortParse(NULL, &dp2, "any");
2026  if (r != 0) {
2027  printf("r != 0 but %d: ", r);
2028  goto end;
2029  }
2030  SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]);
2031 
2032  SCLogDebug("dp1");
2033  DetectPortPrint(dp1);
2034  SCLogDebug("dp2");
2035  DetectPortPrint(dp2);
2036 
2037  DetectPortInsert(de_ctx, &dp3, dp1);
2038  DetectPortInsert(de_ctx, &dp3, dp2);
2039 
2040  if (dp3 == NULL)
2041  goto end;
2042 
2043  SCLogDebug("dp3");
2044  DetectPort *x = dp3;
2045  for ( ; x != NULL; x = x->next) {
2046  DetectPortPrint(x);
2047  //SigGroupHeadPrintSigs(de_ctx, x->sh);
2048  }
2049 
2050  DetectPort *one = dp3;
2051  DetectPort *two = dp3->next;
2052 
2053  int sig = 0;
2054  if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2055  printf("sig %d part of 'one', but it shouldn't: ", sig);
2056  goto end;
2057  }
2058  sig = 1;
2059  if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2060  printf("sig %d part of 'one', but it shouldn't: ", sig);
2061  goto end;
2062  }
2063  sig = 1;
2064  if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2065  printf("sig %d part of 'two', but it shouldn't: ", sig);
2066  goto end;
2067  }
2068 
2069  result = 1;
2070 end:
2071  if (dp1 != NULL)
2072  DetectPortFree(NULL, dp1);
2073  if (dp2 != NULL)
2074  DetectPortFree(NULL, dp2);
2075  return result;
2076 }
2077 
2078 /**
2079  * \test Test general functions
2080  */
2081 static int PortTestFunctions06(void)
2082 {
2083  DetectPort *dp1 = NULL;
2084  DetectPort *dp2 = NULL;
2085  DetectPort *dp3 = NULL;
2086  int result = 0;
2087  int r = 0;
2088 
2090  Signature s[2];
2091  memset(s,0x00,sizeof(s));
2092 
2093  s[0].num = 0;
2094  s[1].num = 1;
2095 
2096  r = DetectPortParse(NULL, &dp1, "1024:65535");
2097  if (r != 0) {
2098  printf("r != 0 but %d: ", r);
2099  goto end;
2100  }
2101  SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]);
2102 
2103  r = DetectPortParse(NULL, &dp2, "any");
2104  if (r != 0) {
2105  printf("r != 0 but %d: ", r);
2106  goto end;
2107  }
2108  SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]);
2109 
2110  SCLogDebug("dp1");
2111  DetectPortPrint(dp1);
2112  SCLogDebug("dp2");
2113  DetectPortPrint(dp2);
2114 
2115  DetectPortInsert(de_ctx, &dp3, dp2);
2116  DetectPortInsert(de_ctx, &dp3, dp1);
2117 
2118  if (dp3 == NULL)
2119  goto end;
2120 
2121  SCLogDebug("dp3");
2122  DetectPort *x = dp3;
2123  for ( ; x != NULL; x = x->next) {
2124  DetectPortPrint(x);
2125  //SigGroupHeadPrintSigs(de_ctx, x->sh);
2126  }
2127 
2128  DetectPort *one = dp3;
2129  DetectPort *two = dp3->next;
2130 
2131  int sig = 0;
2132  if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2133  printf("sig %d part of 'one', but it shouldn't: ", sig);
2134  goto end;
2135  }
2136  sig = 1;
2137  if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2138  printf("sig %d part of 'one', but it shouldn't: ", sig);
2139  goto end;
2140  }
2141  sig = 1;
2142  if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
2143  printf("sig %d part of 'two', but it shouldn't: ", sig);
2144  goto end;
2145  }
2146 
2147  result = 1;
2148 end:
2149  if (dp1 != NULL)
2150  DetectPortFree(NULL, dp1);
2151  if (dp2 != NULL)
2152  DetectPortFree(NULL, dp2);
2153  return result;
2154 }
2155 
2156 /**
2157  * \test Test general functions
2158  */
2159 static int PortTestFunctions07(void)
2160 {
2161  DetectPort *dd = NULL;
2162 
2163  // This one should fail due to negation in a range
2164  FAIL_IF(DetectPortParse(NULL, &dd, "[80:!99]") == 0);
2165 
2166  // Correct: from 80 till 100 but 99 excluded
2167  FAIL_IF_NOT(DetectPortParse(NULL, &dd, "[80:100,!99]") == 0);
2168  FAIL_IF_NULL(dd->next);
2169  FAIL_IF_NOT(dd->port == 80);
2170  FAIL_IF_NOT(dd->port2 == 98);
2171  FAIL_IF_NOT(dd->next->port == 100);
2172 
2173  // Also good: from 1 till 80 except of 2 and 4
2174  FAIL_IF_NOT(DetectPortParse(NULL, &dd, "[1:80,![2,4]]") == 0);
2175  FAIL_IF_NOT(dd->port == 1);
2179 
2180  DetectPortCleanupList(NULL, dd);
2181  PASS;
2182 }
2183 
2184 /**
2185  * \test Test packet Matches
2186  * \param raw_eth_pkt pointer to the ethernet packet
2187  * \param pktsize size of the packet
2188  * \param sig pointer to the signature to test
2189  * \param sid sid number of the signature
2190  * \retval return 1 if match
2191  * \retval return 0 if not
2192  */
2193 static int PortTestMatchReal(uint8_t *raw_eth_pkt, uint16_t pktsize, const char *sig,
2194  uint32_t sid)
2195 {
2196  int result = 0;
2198  Packet *p = UTHBuildPacketFromEth(raw_eth_pkt, pktsize);
2199  result = UTHPacketMatchSig(p, sig);
2200  PacketRecycle(p);
2201  FlowShutdown();
2202  return result;
2203 }
2204 
2205 /**
2206  * \brief Wrapper for PortTestMatchReal
2207  */
2208 static int PortTestMatchRealWrp(const char *sig, uint32_t sid)
2209 {
2210  /* Real HTTP packeth doing a GET method
2211  * tcp.sport=47370 tcp.dport=80
2212  * ip.src=192.168.28.131 ip.dst=192.168.1.1
2213  */
2214  uint8_t raw_eth_pkt[] = {
2215  0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
2216  0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
2217  0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
2218  0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
2219  0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
2220  0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
2221  0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
2222  0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
2223  0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
2224  0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
2225  0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
2226  0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
2227  0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
2228  0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
2229  0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
2230  0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
2231  0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
2232  0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
2233  0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
2234  0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
2235  0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
2236  0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
2237  0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
2238  0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
2239  0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
2240  0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
2241  0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
2242  0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
2243  0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
2244  0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
2245  0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
2246  0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
2247  0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
2248  0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
2249  0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
2250  0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
2251  0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
2252  0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
2253  0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
2254  0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
2255  0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
2256  0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
2257  0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
2258  0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
2259  0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
2260  0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
2261  0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
2262  0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
2263  0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
2264  0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
2265  0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
2266  0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
2267  0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
2268  0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
2269  0x76,0x65,0x0d,0x0a,0x0d,0x0a };
2270  /* end raw_eth_pkt */
2271 
2272  return PortTestMatchReal(raw_eth_pkt, (uint16_t)sizeof(raw_eth_pkt),
2273  sig, sid);
2274 }
2275 
2276 /**
2277  * \test Check if we match a dest port
2278  */
2279 static int PortTestMatchReal01(void)
2280 {
2281  /* tcp.sport=47370 tcp.dport=80 */
2282  const char *sig = "alert tcp any any -> any 80 (msg:\"Nothing..\"; content:\"GET\"; sid:1;)";
2283  return PortTestMatchRealWrp(sig, 1);
2284 }
2285 
2286 /**
2287  * \test Check if we match a source port
2288  */
2289 static int PortTestMatchReal02(void)
2290 {
2291  const char *sig = "alert tcp any 47370 -> any any (msg:\"Nothing..\";"
2292  " content:\"GET\"; sid:1;)";
2293  return PortTestMatchRealWrp(sig, 1);
2294 }
2295 
2296 /**
2297  * \test Check if we match both of them
2298  */
2299 static int PortTestMatchReal03(void)
2300 {
2301  const char *sig = "alert tcp any 47370 -> any 80 (msg:\"Nothing..\";"
2302  " content:\"GET\"; sid:1;)";
2303  return PortTestMatchRealWrp(sig, 1);
2304 }
2305 
2306 /**
2307  * \test Check if we negate dest ports correctly
2308  */
2309 static int PortTestMatchReal04(void)
2310 {
2311  const char *sig = "alert tcp any any -> any !80 (msg:\"Nothing..\";"
2312  " content:\"GET\"; sid:1;)";
2313  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2314 }
2315 
2316 /**
2317  * \test Check if we negate source ports correctly
2318  */
2319 static int PortTestMatchReal05(void)
2320 {
2321  const char *sig = "alert tcp any !47370 -> any any (msg:\"Nothing..\";"
2322  " content:\"GET\"; sid:1;)";
2323  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2324 }
2325 
2326 /**
2327  * \test Check if we negate both ports correctly
2328  */
2329 static int PortTestMatchReal06(void)
2330 {
2331  const char *sig = "alert tcp any !47370 -> any !80 (msg:\"Nothing..\";"
2332  " content:\"GET\"; sid:1;)";
2333  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2334 }
2335 
2336 /**
2337  * \test Check if we match a dest port range
2338  */
2339 static int PortTestMatchReal07(void)
2340 {
2341  const char *sig = "alert tcp any any -> any 70:100 (msg:\"Nothing..\";"
2342  " content:\"GET\"; sid:1;)";
2343  return PortTestMatchRealWrp(sig, 1);
2344 }
2345 
2346 /**
2347  * \test Check if we match a source port range
2348  */
2349 static int PortTestMatchReal08(void)
2350 {
2351  const char *sig = "alert tcp any 47000:50000 -> any any (msg:\"Nothing..\";"
2352  " content:\"GET\"; sid:1;)";
2353  return PortTestMatchRealWrp(sig, 1);
2354 }
2355 
2356 /**
2357  * \test Check if we match both port ranges
2358  */
2359 static int PortTestMatchReal09(void)
2360 {
2361  const char *sig = "alert tcp any 47000:50000 -> any 70:100 (msg:\"Nothing..\";"
2362  " content:\"GET\"; sid:1;)";
2363  return PortTestMatchRealWrp(sig, 1);
2364 }
2365 
2366 /**
2367  * \test Check if we negate a dest port range
2368  */
2369 static int PortTestMatchReal10(void)
2370 {
2371  const char *sig = "alert tcp any any -> any !70:100 (msg:\"Nothing..\";"
2372  " content:\"GET\"; sid:1;)";
2373  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2374 }
2375 
2376 /**
2377  * \test Check if we negate a source port range
2378  */
2379 static int PortTestMatchReal11(void)
2380 {
2381  const char *sig = "alert tcp any !47000:50000 -> any any (msg:\"Nothing..\";"
2382  " content:\"GET\"; sid:1;)";
2383  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2384 }
2385 
2386 /**
2387  * \test Check if we negate both port ranges
2388  */
2389 static int PortTestMatchReal12(void)
2390 {
2391  const char *sig = "alert tcp any !47000:50000 -> any !70:100 (msg:\"Nothing..\";"
2392  " content:\"GET\"; sid:1;)";
2393  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2394 }
2395 
2396 /**
2397  * \test Check if we autocomplete ranges correctly
2398  */
2399 static int PortTestMatchReal13(void)
2400 {
2401  const char *sig = "alert tcp any 47000:50000 -> any !81: (msg:\"Nothing..\";"
2402  " content:\"GET\"; sid:1;)";
2403  return PortTestMatchRealWrp(sig, 1);
2404 }
2405 
2406 /**
2407  * \test Check if we autocomplete ranges correctly
2408  */
2409 static int PortTestMatchReal14(void)
2410 {
2411  const char *sig = "alert tcp any !48000:50000 -> any :100 (msg:\"Nothing..\";"
2412  " content:\"GET\"; sid:1;)";
2413  return PortTestMatchRealWrp(sig, 1);
2414 }
2415 
2416 /**
2417  * \test Check if we autocomplete ranges correctly
2418  */
2419 static int PortTestMatchReal15(void)
2420 {
2421  const char *sig = "alert tcp any :50000 -> any 81:100 (msg:\"Nothing..\";"
2422  " content:\"GET\"; sid:1;)";
2423  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2424 }
2425 
2426 /**
2427  * \test Check if we separate ranges correctly
2428  */
2429 static int PortTestMatchReal16(void)
2430 {
2431  const char *sig = "alert tcp any 100: -> any ![0:79,81:65535] (msg:\"Nothing..\";"
2432  " content:\"GET\"; sid:1;)";
2433  return PortTestMatchRealWrp(sig, 1);
2434 }
2435 
2436 /**
2437  * \test Check if we separate ranges correctly
2438  */
2439 static int PortTestMatchReal17(void)
2440 {
2441  const char *sig = "alert tcp any ![0:39999,48000:50000] -> any ![0:80,82:65535] "
2442  "(msg:\"Nothing..\"; content:\"GET\"; sid:1;)";
2443  return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0;
2444 }
2445 
2446 /**
2447  * \test Check if we separate ranges correctly
2448  */
2449 static int PortTestMatchReal18(void)
2450 {
2451  const char *sig = "alert tcp any ![0:39999,48000:50000] -> any 80 (msg:\"Nothing"
2452  " at all\"; content:\"GET\"; sid:1;)";
2453  return PortTestMatchRealWrp(sig, 1);
2454 }
2455 
2456 /**
2457  * \test Check if we separate ranges correctly
2458  */
2459 static int PortTestMatchReal19(void)
2460 {
2461  const char *sig = "alert tcp any any -> any 80 (msg:\"Nothing..\";"
2462  " content:\"GET\"; sid:1;)";
2463  return PortTestMatchRealWrp(sig, 1);
2464 }
2465 
2466 static int PortTestMatchDoubleNegation(void)
2467 {
2468  int result = 0;
2469  DetectPort *head = NULL, *nhead = NULL;
2470 
2471  if (DetectPortParseDo(NULL, &head, &nhead, "![!80]", 0, NULL, 0) == -1)
2472  return result;
2473 
2474  result = (head != NULL);
2475  result = (nhead == NULL);
2476 
2477  return result;
2478 }
2479 
2480 // Test that negation is successfully parsed with whitespace for port strings of
2481 // length < 16
2482 static int DetectPortParseDoTest(void)
2483 {
2486  DetectPort *head = NULL;
2487  DetectPort *nhead = NULL;
2488  const char *str = "[30:50, !45]";
2489  int r = DetectPortParseDo(de_ctx, &head, &nhead, str, 0, NULL, 0);
2490 
2491  // Assertions
2492  FAIL_IF_NULL(head);
2493  FAIL_IF_NULL(nhead);
2494  FAIL_IF(r < 0);
2495  FAIL_IF(head->port != 30);
2496  FAIL_IF(head->port2 != 50);
2497  FAIL_IF(nhead->port != 45);
2498  FAIL_IF(nhead->port2 != 45);
2499  DetectPortCleanupList(NULL, head);
2500  DetectPortCleanupList(NULL, nhead);
2501  PASS;
2502 }
2503 
2504 static int DetectPortParseDoTest2(void)
2505 {
2508  DetectPort *head = NULL;
2509  DetectPort *nhead = NULL;
2510  const char *str = "[30:50, !45]";
2511  int r = DetectPortParseDo(de_ctx, &head, &nhead, str, 0, NULL, 0);
2512  FAIL_IF(r < 0);
2513  DetectPortCleanupList(NULL, head);
2514  DetectPortCleanupList(NULL, nhead);
2515  PASS;
2516 }
2517 
2518 // Verifies correct parsing when negation port string length < 16
2519 static int PortParseTestLessThan14Spaces(void)
2520 {
2521  const char *str = " 45";
2522  DetectPort *dp = PortParse(str);
2523  FAIL_IF_NULL(dp);
2524  FAIL_IF(dp->port != 45);
2525  FAIL_IF(dp->port2 != 45);
2526  DetectPortFree(NULL, dp);
2527  PASS;
2528 }
2529 
2530 // Verifies NULL returned when negation port string length == 16
2531 static int PortParseTest14Spaces(void)
2532 {
2533  const char *str = " 45";
2534  DetectPort *dp = PortParse(str);
2535  FAIL_IF_NULL(dp);
2536  FAIL_IF(dp->port != 45);
2537  FAIL_IF(dp->port2 != 45);
2538  DetectPortFree(NULL, dp);
2539  PASS;
2540 }
2541 
2542 // Verifies NULL returned when negation port string length >= 16
2543 static int PortParseTestMoreThan14Spaces(void)
2544 {
2545  const char *str = " 45";
2546  DetectPort *dp = PortParse(str);
2547  FAIL_IF_NULL(dp);
2548  FAIL_IF(dp->port != 45);
2549  FAIL_IF(dp->port2 != 45);
2550  DetectPortFree(NULL, dp);
2551  PASS;
2552 }
2553 
2554 void DetectPortTests(void)
2555 {
2556  UtRegisterTest("PortTestParse01", PortTestParse01);
2557  UtRegisterTest("PortTestParse02", PortTestParse02);
2558  UtRegisterTest("PortTestParse03", PortTestParse03);
2559  UtRegisterTest("PortTestParse04", PortTestParse04);
2560  UtRegisterTest("PortTestParse05", PortTestParse05);
2561  UtRegisterTest("PortTestParse07", PortTestParse07);
2562  UtRegisterTest("PortTestParse08", PortTestParse08);
2563  UtRegisterTest("PortTestParse09", PortTestParse09);
2564  UtRegisterTest("PortTestParse10", PortTestParse10);
2565  UtRegisterTest("PortTestParse11", PortTestParse11);
2566  UtRegisterTest("PortTestParse12", PortTestParse12);
2567  UtRegisterTest("PortTestParse13", PortTestParse13);
2568  UtRegisterTest("PortTestParse14", PortTestParse14);
2569  UtRegisterTest("PortTestParse15", PortTestParse15);
2570  UtRegisterTest("PortTestParse16", PortTestParse16);
2571  UtRegisterTest("PortTestFunctions01", PortTestFunctions01);
2572  UtRegisterTest("PortTestFunctions02", PortTestFunctions02);
2573  UtRegisterTest("PortTestFunctions03", PortTestFunctions03);
2574  UtRegisterTest("PortTestFunctions04", PortTestFunctions04);
2575  UtRegisterTest("PortTestFunctions05", PortTestFunctions05);
2576  UtRegisterTest("PortTestFunctions06", PortTestFunctions06);
2577  UtRegisterTest("PortTestFunctions07", PortTestFunctions07);
2578  UtRegisterTest("PortTestMatchReal01", PortTestMatchReal01);
2579  UtRegisterTest("PortTestMatchReal02", PortTestMatchReal02);
2580  UtRegisterTest("PortTestMatchReal03", PortTestMatchReal03);
2581  UtRegisterTest("PortTestMatchReal04", PortTestMatchReal04);
2582  UtRegisterTest("PortTestMatchReal05", PortTestMatchReal05);
2583  UtRegisterTest("PortTestMatchReal06", PortTestMatchReal06);
2584  UtRegisterTest("PortTestMatchReal07", PortTestMatchReal07);
2585  UtRegisterTest("PortTestMatchReal08", PortTestMatchReal08);
2586  UtRegisterTest("PortTestMatchReal09", PortTestMatchReal09);
2587  UtRegisterTest("PortTestMatchReal10", PortTestMatchReal10);
2588  UtRegisterTest("PortTestMatchReal11", PortTestMatchReal11);
2589  UtRegisterTest("PortTestMatchReal12", PortTestMatchReal12);
2590  UtRegisterTest("PortTestMatchReal13", PortTestMatchReal13);
2591  UtRegisterTest("PortTestMatchReal14", PortTestMatchReal14);
2592  UtRegisterTest("PortTestMatchReal15", PortTestMatchReal15);
2593  UtRegisterTest("PortTestMatchReal16", PortTestMatchReal16);
2594  UtRegisterTest("PortTestMatchReal17", PortTestMatchReal17);
2595  UtRegisterTest("PortTestMatchReal18", PortTestMatchReal18);
2596  UtRegisterTest("PortTestMatchReal19", PortTestMatchReal19);
2597  UtRegisterTest("PortTestMatchDoubleNegation", PortTestMatchDoubleNegation);
2598  UtRegisterTest("DetectPortParseDoTest", DetectPortParseDoTest);
2599  UtRegisterTest("DetectPortParseDoTest2", DetectPortParseDoTest2);
2600  UtRegisterTest("PortParseTestLessThan14Spaces", PortParseTestLessThan14Spaces);
2601  UtRegisterTest("PortParseTest14Spaces", PortParseTest14Spaces);
2602  UtRegisterTest("PortParseTestMoreThan14Spaces", PortParseTestMoreThan14Spaces);
2603 }
2604 
2605 #endif /* UNITTESTS */
2606 
DetectEngineCtx_::sgh_hash_table
HashListTable * sgh_hash_table
Definition: detect.h:824
util-byte.h
host.h
DetectPortCmp
int DetectPortCmp(DetectPort *a, DetectPort *b)
Function that compare port groups.
Definition: detect-engine-port.c:558
PORT_EB
@ PORT_EB
Definition: detect.h:170
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:1441
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:551
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:1368
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:181
PORT_SIGGROUPHEAD_COPY
#define PORT_SIGGROUPHEAD_COPY
Definition: detect.h:177
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:785
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
DetectPort_::next
struct DetectPort_ * next
Definition: detect.h:194
UTHPacketMatchSig
int UTHPacketMatchSig(Packet *p, const char *sig)
Definition: util-unittest-helper.c:844
DetectEngineCtx_::dport_hash_table
HashListTable * dport_hash_table
Definition: detect.h:932
DetectPort_::sh
struct SigGroupHead_ * sh
Definition: detect.h:191
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:1176
util-var.h
PortParse
DetectPort * PortParse(const char *str)
Helper function for parsing port strings.
Definition: detect-engine-port.c:1288
DetectPort_::port2
uint16_t port2
Definition: detect.h:182
PORT_LE
@ PORT_LE
Definition: detect.h:167
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:184
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
PORT_ER
@ PORT_ER
Definition: detect.h:165
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:1252
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:175
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
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:180
SigGroupHead_::init
SigGroupHeadInitData * init
Definition: detect.h:1418
PORT_GE
@ PORT_GE
Definition: detect.h:171
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
util-profiling.h
util-rule-vars.h
Packet_
Definition: decode.h:428
conf.h
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
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:402
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
PORT_ES
@ PORT_ES
Definition: detect.h:169
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:193
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:280
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
PORT_GT
@ PORT_GT
Definition: detect.h:172
detect-parse.h
src
uint16_t src
Definition: app-layer-dnp3.h:5
Signature_
Signature container.
Definition: detect.h:540
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:2403
PORT_FLAG_NOT
#define PORT_FLAG_NOT
Definition: detect.h:176
DetectPortHashAdd
int DetectPortHashAdd(DetectEngineCtx *de_ctx, DetectPort *dp)
Adds a DetectPort to the detection engine context DetectPort hash table.
Definition: detect-engine-port.c:1461
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:41
PORT_LT
@ PORT_LT
Definition: detect.h:166
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:1492
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:1477
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:769
PORT_EQ
@ PORT_EQ
Definition: detect.h:168
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