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