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