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