suricata
detect-nfs-version.c
Go to the documentation of this file.
1 /* Copyright (C) 2017-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 
24 #include "suricata-common.h"
25 #include "threads.h"
26 #include "debug.h"
27 #include "decode.h"
28 #include "detect.h"
29 
30 #include "detect-parse.h"
31 #include "detect-engine.h"
32 #include "detect-engine-mpm.h"
33 #include "detect-content.h"
34 #include "detect-pcre.h"
35 #include "detect-nfs-version.h"
36 
37 #include "app-layer-parser.h"
38 
39 #include "flow.h"
40 #include "flow-util.h"
41 #include "flow-var.h"
42 
43 #include "util-unittest.h"
44 #include "util-unittest-helper.h"
45 
46 #include "app-layer-nfs-tcp.h"
47 #include "rust.h"
48 
49 /**
50  * [nfs_procedure]:[<|>]<proc>[<><proc>];
51  */
52 #define PARSE_REGEX "^\\s*(<=|>=|<|>)?\\s*([0-9]+)\\s*(?:(<>)\\s*([0-9]+))?\\s*$"
53 static pcre *parse_regex;
54 static pcre_extra *parse_regex_study;
55 
57  PROCEDURE_EQ = 1, /* equal */
58  PROCEDURE_LT, /* less than */
59  PROCEDURE_LE, /* less than */
60  PROCEDURE_GT, /* greater than */
61  PROCEDURE_GE, /* greater than */
62  PROCEDURE_RA, /* range */
63 };
64 
65 typedef struct DetectNfsVersionData_ {
66  uint32_t lo;
67  uint32_t hi;
70 
71 static DetectNfsVersionData *DetectNfsVersionParse (const char *);
72 static int DetectNfsVersionSetup (DetectEngineCtx *, Signature *s, const char *str);
73 static void DetectNfsVersionFree(void *);
74 static void DetectNfsVersionRegisterTests(void);
75 static int g_nfs_request_buffer_id = 0;
76 
77 static int DetectEngineInspectNfsRequestGeneric(ThreadVars *tv,
78  DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
79  const Signature *s, const SigMatchData *smd,
80  Flow *f, uint8_t flags, void *alstate,
81  void *txv, uint64_t tx_id);
82 
83 static int DetectNfsVersionMatch (DetectEngineThreadCtx *, Flow *,
84  uint8_t, void *, void *, const Signature *,
85  const SigMatchCtx *);
86 
87 /**
88  * \brief Registration function for nfs_procedure keyword.
89  */
91 {
92  sigmatch_table[DETECT_AL_NFS_VERSION].name = "nfs.version";
94  sigmatch_table[DETECT_AL_NFS_VERSION].desc = "match NFS version";
95  sigmatch_table[DETECT_AL_NFS_VERSION].url = DOC_URL DOC_VERSION "/rules/nfs-keywords.html#version";
96  sigmatch_table[DETECT_AL_NFS_VERSION].AppLayerTxMatch = DetectNfsVersionMatch;
97  sigmatch_table[DETECT_AL_NFS_VERSION].Setup = DetectNfsVersionSetup;
98  sigmatch_table[DETECT_AL_NFS_VERSION].Free = DetectNfsVersionFree;
99  sigmatch_table[DETECT_AL_NFS_VERSION].RegisterTests = DetectNfsVersionRegisterTests;
100 
101  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
102 
105  DetectEngineInspectNfsRequestGeneric);
106 
107  g_nfs_request_buffer_id = DetectBufferTypeGetByName("nfs_request");
108 
109  SCLogDebug("g_nfs_request_buffer_id %d", g_nfs_request_buffer_id);
110 }
111 
112 static int DetectEngineInspectNfsRequestGeneric(ThreadVars *tv,
113  DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
114  const Signature *s, const SigMatchData *smd,
115  Flow *f, uint8_t flags, void *alstate,
116  void *txv, uint64_t tx_id)
117 {
118  return DetectEngineInspectGenericList(tv, de_ctx, det_ctx, s, smd,
119  f, flags, alstate, txv, tx_id);
120 }
121 
122 static inline int
123 VersionMatch(const uint32_t version,
124  enum DetectNfsVersionMode mode, uint32_t lo, uint32_t hi)
125 {
126  switch (mode) {
127  case PROCEDURE_EQ:
128  if (version == lo)
129  SCReturnInt(1);
130  break;
131  case PROCEDURE_LT:
132  if (version < lo)
133  SCReturnInt(1);
134  break;
135  case PROCEDURE_LE:
136  if (version <= lo)
137  SCReturnInt(1);
138  break;
139  case PROCEDURE_GT:
140  if (version > lo)
141  SCReturnInt(1);
142  break;
143  case PROCEDURE_GE:
144  if (version >= lo)
145  SCReturnInt(1);
146  break;
147  case PROCEDURE_RA:
148  if (version >= lo && version <= hi)
149  SCReturnInt(1);
150  break;
151  }
152  SCReturnInt(0);
153 }
154 
155 /**
156  * \internal
157  * \brief Function to match version of a TX
158  *
159  * \param t Pointer to thread vars.
160  * \param det_ctx Pointer to the pattern matcher thread.
161  * \param f Pointer to the current flow.
162  * \param flags Flags.
163  * \param state App layer state.
164  * \param s Pointer to the Signature.
165  * \param m Pointer to the sigmatch that we will cast into
166  * DetectNfsVersionData.
167  *
168  * \retval 0 no match.
169  * \retval 1 match.
170  */
171 static int DetectNfsVersionMatch (DetectEngineThreadCtx *det_ctx,
172  Flow *f, uint8_t flags, void *state,
173  void *txv, const Signature *s,
174  const SigMatchCtx *ctx)
175 {
176  SCEnter();
177 
178  const DetectNfsVersionData *dd = (const DetectNfsVersionData *)ctx;
179  uint32_t version;
180  rs_nfs_tx_get_version(txv, &version);
181  SCLogDebug("version %u mode %u lo %u hi %u",
182  version, dd->mode, dd->lo, dd->hi);
183  if (VersionMatch(version, dd->mode, dd->lo, dd->hi))
184  SCReturnInt(1);
185  SCReturnInt(0);
186 }
187 
188 /**
189  * \internal
190  * \brief Function to parse options passed via tls validity keywords.
191  *
192  * \param rawstr Pointer to the user provided options.
193  *
194  * \retval dd pointer to DetectNfsVersionData on success.
195  * \retval NULL on failure.
196  */
197 static DetectNfsVersionData *DetectNfsVersionParse (const char *rawstr)
198 {
199  DetectNfsVersionData *dd = NULL;
200 #define MAX_SUBSTRINGS 30
201  int ret = 0, res = 0;
202  int ov[MAX_SUBSTRINGS];
203  char mode[2] = "";
204  char value1[20] = "";
205  char value2[20] = "";
206  char range[3] = "";
207 
208  ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0,
209  0, ov, MAX_SUBSTRINGS);
210  if (ret < 3 || ret > 5) {
211  SCLogError(SC_ERR_PCRE_MATCH, "Parse error %s", rawstr);
212  goto error;
213  }
214 
215  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, mode,
216  sizeof(mode));
217  if (res < 0) {
218  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
219  goto error;
220  }
221  SCLogDebug("mode \"%s\"", mode);
222 
223  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, value1,
224  sizeof(value1));
225  if (res < 0) {
226  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
227  goto error;
228  }
229  SCLogDebug("value1 \"%s\"", value1);
230 
231  if (ret > 3) {
232  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3,
233  range, sizeof(range));
234  if (res < 0) {
235  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
236  goto error;
237  }
238  SCLogDebug("range \"%s\"", range);
239 
240  if (ret > 4) {
241  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4,
242  value2, sizeof(value2));
243  if (res < 0) {
245  "pcre_copy_substring failed");
246  goto error;
247  }
248  SCLogDebug("value2 \"%s\"", value2);
249  }
250  }
251 
252  dd = SCCalloc(1, sizeof(DetectNfsVersionData));
253  if (unlikely(dd == NULL))
254  goto error;
255 
256  if (strlen(mode) == 1) {
257  if (mode[0] == '<')
258  dd->mode = PROCEDURE_LT;
259  else if (mode[0] == '>')
260  dd->mode = PROCEDURE_GT;
261  } else if (strlen(mode) == 2) {
262  if (strcmp(mode, "<=") == 0)
263  dd->mode = PROCEDURE_LE;
264  if (strcmp(mode, ">=") == 0)
265  dd->mode = PROCEDURE_GE;
266  }
267 
268  if (strlen(range) > 0) {
269  if (strcmp("<>", range) == 0)
270  dd->mode = PROCEDURE_RA;
271  }
272 
273  if (strlen(range) != 0 && strlen(mode) != 0) {
275  "Range specified but mode also set");
276  goto error;
277  }
278 
279  if (dd->mode == 0) {
280  dd->mode = PROCEDURE_EQ;
281  }
282 
283  /* set the first value */
284  dd->lo = atoi(value1); //TODO
285 
286  /* set the second value if specified */
287  if (strlen(value2) > 0) {
288  if (!(dd->mode == PROCEDURE_RA)) {
290  "Multiple tls validity values specified but mode is not range");
291  goto error;
292  }
293 
294  //
295  dd->hi = atoi(value2); // TODO
296 
297  if (dd->hi <= dd->lo) {
299  "Second value in range must not be smaller than the first");
300  goto error;
301  }
302  }
303  return dd;
304 
305 error:
306  if (dd)
307  SCFree(dd);
308  return NULL;
309 }
310 
311 
312 
313 /**
314  * \brief Function to add the parsed tls validity field into the current signature.
315  *
316  * \param de_ctx Pointer to the Detection Engine Context.
317  * \param s Pointer to the Current Signature.
318  * \param rawstr Pointer to the user provided flags options.
319  * \param type Defines if this is notBefore or notAfter.
320  *
321  * \retval 0 on Success.
322  * \retval -1 on Failure.
323  */
324 static int DetectNfsVersionSetup (DetectEngineCtx *de_ctx, Signature *s,
325  const char *rawstr)
326 {
327  SCLogDebug("\'%s\'", rawstr);
328 
330  return -1;
331 
332  DetectNfsVersionData *dd = DetectNfsVersionParse(rawstr);
333  if (dd == NULL) {
334  SCLogError(SC_ERR_INVALID_ARGUMENT,"Parsing \'%s\' failed", rawstr);
335  return -1;
336  }
337 
338  /* okay so far so good, lets get this into a SigMatch
339  * and put it in the Signature. */
340  SigMatch *sm = SigMatchAlloc();
341  if (sm == NULL)
342  goto error;
343 
345  sm->ctx = (void *)dd;
346 
347  SCLogDebug("low %u hi %u", dd->lo, dd->hi);
348  SigMatchAppendSMToList(s, sm, g_nfs_request_buffer_id);
349  return 0;
350 
351 error:
352  DetectNfsVersionFree(dd);
353  return -1;
354 }
355 
356 /**
357  * \internal
358  * \brief Function to free memory associated with DetectNfsVersionData.
359  *
360  * \param de_ptr Pointer to DetectNfsVersionData.
361  */
362 void DetectNfsVersionFree(void *ptr)
363 {
364  SCFree(ptr);
365 }
366 
367 #ifdef UNITTESTS
368 
369 /**
370  * \test This is a test for a valid value 1430000000.
371  *
372  * \retval 1 on success.
373  * \retval 0 on failure.
374  */
375 static int ValidityTestParse01 (void)
376 {
377  DetectNfsVersionData *dd = NULL;
378  dd = DetectNfsVersionParse("1430000000");
379  FAIL_IF_NULL(dd);
380  FAIL_IF_NOT(dd->lo == 1430000000 && dd->mode == PROCEDURE_EQ);
381  DetectNfsVersionFree(dd);
382  PASS;
383 }
384 
385 /**
386  * \test This is a test for a valid value >1430000000.
387  *
388  * \retval 1 on success.
389  * \retval 0 on failure.
390  */
391 static int ValidityTestParse02 (void)
392 {
393  DetectNfsVersionData *dd = NULL;
394  dd = DetectNfsVersionParse(">1430000000");
395  FAIL_IF_NULL(dd);
396  FAIL_IF_NOT(dd->lo == 1430000000 && dd->mode == PROCEDURE_GT);
397  DetectNfsVersionFree(dd);
398  PASS;
399 }
400 
401 /**
402  * \test This is a test for a valid value <1430000000.
403  *
404  * \retval 1 on success.
405  * \retval 0 on failure.
406  */
407 static int ValidityTestParse03 (void)
408 {
409  DetectNfsVersionData *dd = NULL;
410  dd = DetectNfsVersionParse("<1430000000");
411  FAIL_IF_NULL(dd);
412  FAIL_IF_NOT(dd->lo == 1430000000 && dd->mode == PROCEDURE_LT);
413  DetectNfsVersionFree(dd);
414  PASS;
415 }
416 
417 /**
418  * \test This is a test for a valid value 1430000000<>1470000000.
419  *
420  * \retval 1 on success.
421  * \retval 0 on failure.
422  */
423 static int ValidityTestParse04 (void)
424 {
425  DetectNfsVersionData *dd = NULL;
426  dd = DetectNfsVersionParse("1430000000<>1470000000");
427  FAIL_IF_NULL(dd);
428  FAIL_IF_NOT(dd->lo == 1430000000 && dd->hi == 1470000000 &&
429  dd->mode == PROCEDURE_RA);
430  DetectNfsVersionFree(dd);
431  PASS;
432 }
433 
434 /**
435  * \test This is a test for a invalid value A.
436  *
437  * \retval 1 on success.
438  * \retval 0 on failure.
439  */
440 static int ValidityTestParse05 (void)
441 {
442  DetectNfsVersionData *dd = NULL;
443  dd = DetectNfsVersionParse("A");
444  FAIL_IF_NOT_NULL(dd);
445  PASS;
446 }
447 
448 /**
449  * \test This is a test for a invalid value >1430000000<>1470000000.
450  *
451  * \retval 1 on success.
452  * \retval 0 on failure.
453  */
454 static int ValidityTestParse06 (void)
455 {
456  DetectNfsVersionData *dd = NULL;
457  dd = DetectNfsVersionParse(">1430000000<>1470000000");
458  FAIL_IF_NOT_NULL(dd);
459  PASS;
460 }
461 
462 /**
463  * \test This is a test for a invalid value 1430000000<>.
464  *
465  * \retval 1 on success.
466  * \retval 0 on failure.
467  */
468 static int ValidityTestParse07 (void)
469 {
470  DetectNfsVersionData *dd = NULL;
471  dd = DetectNfsVersionParse("1430000000<>");
472  FAIL_IF_NOT_NULL(dd);
473  PASS;
474 }
475 
476 /**
477  * \test This is a test for a invalid value <>1430000000.
478  *
479  * \retval 1 on success.
480  * \retval 0 on failure.
481  */
482 static int ValidityTestParse08 (void)
483 {
484  DetectNfsVersionData *dd = NULL;
485  dd = DetectNfsVersionParse("<>1430000000");
486  FAIL_IF_NOT_NULL(dd);
487  PASS;
488 }
489 
490 /**
491  * \test This is a test for a invalid value "".
492  *
493  * \retval 1 on success.
494  * \retval 0 on failure.
495  */
496 static int ValidityTestParse09 (void)
497 {
498  DetectNfsVersionData *dd = NULL;
499  dd = DetectNfsVersionParse("");
500  FAIL_IF_NOT_NULL(dd);
501  PASS;
502 }
503 
504 /**
505  * \test This is a test for a invalid value " ".
506  *
507  * \retval 1 on success.
508  * \retval 0 on failure.
509  */
510 static int ValidityTestParse10 (void)
511 {
512  DetectNfsVersionData *dd = NULL;
513  dd = DetectNfsVersionParse(" ");
514  FAIL_IF_NOT_NULL(dd);
515  PASS;
516 }
517 
518 /**
519  * \test This is a test for a invalid value 1490000000<>1430000000.
520  *
521  * \retval 1 on success.
522  * \retval 0 on failure.
523  */
524 static int ValidityTestParse11 (void)
525 {
526  DetectNfsVersionData *dd = NULL;
527  dd = DetectNfsVersionParse("1490000000<>1430000000");
528  FAIL_IF_NOT_NULL(dd);
529  PASS;
530 }
531 
532 /**
533  * \test This is a test for a valid value 1430000000 <> 1490000000.
534  *
535  * \retval 1 on success.
536  * \retval 0 on failure.
537  */
538 static int ValidityTestParse12 (void)
539 {
540  DetectNfsVersionData *dd = NULL;
541  dd = DetectNfsVersionParse("1430000000 <> 1490000000");
542  FAIL_IF_NULL(dd);
543  FAIL_IF_NOT(dd->lo == 1430000000 && dd->hi == 1490000000 &&
544  dd->mode == PROCEDURE_RA);
545  DetectNfsVersionFree(dd);
546  PASS;
547 }
548 
549 /**
550  * \test This is a test for a valid value > 1430000000.
551  *
552  * \retval 1 on success.
553  * \retval 0 on failure.
554  */
555 static int ValidityTestParse13 (void)
556 {
557  DetectNfsVersionData *dd = NULL;
558  dd = DetectNfsVersionParse("> 1430000000 ");
559  FAIL_IF_NULL(dd);
560  FAIL_IF_NOT(dd->lo == 1430000000 && dd->mode == PROCEDURE_GT);
561  DetectNfsVersionFree(dd);
562  PASS;
563 }
564 
565 /**
566  * \test This is a test for a valid value < 1490000000.
567  *
568  * \retval 1 on success.
569  * \retval 0 on failure.
570  */
571 static int ValidityTestParse14 (void)
572 {
573  DetectNfsVersionData *dd = NULL;
574  dd = DetectNfsVersionParse("< 1490000000 ");
575  FAIL_IF_NULL(dd);
576  FAIL_IF_NOT(dd->lo == 1490000000 && dd->mode == PROCEDURE_LT);
577  DetectNfsVersionFree(dd);
578  PASS;
579 }
580 
581 /**
582  * \test This is a test for a valid value 1490000000.
583  *
584  * \retval 1 on success.
585  * \retval 0 on failure.
586  */
587 static int ValidityTestParse15 (void)
588 {
589  DetectNfsVersionData *dd = NULL;
590  dd = DetectNfsVersionParse(" 1490000000 ");
591  FAIL_IF_NULL(dd);
592  FAIL_IF_NOT(dd->lo == 1490000000 && dd->mode == PROCEDURE_EQ);
593  DetectNfsVersionFree(dd);
594  PASS;
595 }
596 
597 #endif /* UNITTESTS */
598 
599 /**
600  * \brief Register unit tests for nfs_procedure.
601  */
602 void DetectNfsVersionRegisterTests(void)
603 {
604 #ifdef UNITTESTS /* UNITTESTS */
605  UtRegisterTest("ValidityTestParse01", ValidityTestParse01);
606  UtRegisterTest("ValidityTestParse02", ValidityTestParse02);
607  UtRegisterTest("ValidityTestParse03", ValidityTestParse03);
608  UtRegisterTest("ValidityTestParse04", ValidityTestParse04);
609  UtRegisterTest("ValidityTestParse05", ValidityTestParse05);
610  UtRegisterTest("ValidityTestParse06", ValidityTestParse06);
611  UtRegisterTest("ValidityTestParse07", ValidityTestParse07);
612  UtRegisterTest("ValidityTestParse08", ValidityTestParse08);
613  UtRegisterTest("ValidityTestParse09", ValidityTestParse09);
614  UtRegisterTest("ValidityTestParse10", ValidityTestParse10);
615  UtRegisterTest("ValidityTestParse11", ValidityTestParse11);
616  UtRegisterTest("ValidityTestParse12", ValidityTestParse12);
617  UtRegisterTest("ValidityTestParse13", ValidityTestParse13);
618  UtRegisterTest("ValidityTestParse14", ValidityTestParse14);
619  UtRegisterTest("ValidityTestParse15", ValidityTestParse15);
620 #endif /* UNITTESTS */
621 }
enum DetectNfsVersionMode mode
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define SCLogDebug(...)
Definition: util-debug.h:335
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
#define PASS
Pass the test.
#define unlikely(expr)
Definition: util-optimize.h:35
#define PARSE_REGEX
Data needed for Match()
Definition: detect.h:327
const char * name
Definition: detect.h:1200
int DetectEngineInspectGenericList(ThreadVars *tv, const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, const uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Signature container.
Definition: detect.h:522
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
main detection engine ctx
Definition: detect.h:761
int DetectBufferTypeGetByName(const char *name)
#define str(s)
#define SCCalloc(nm, a)
Definition: util-mem.h:253
void(* Free)(void *)
Definition: detect.h:1191
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
#define SIG_FLAG_TOSERVER
Definition: detect.h:236
#define SCEnter(...)
Definition: util-debug.h:337
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
uint8_t type
Definition: detect.h:319
#define SCReturnInt(x)
Definition: util-debug.h:341
void DetectNfsVersionRegister(void)
Registration function for nfs_procedure keyword.
const char * desc
Definition: detect.h:1202
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:346
SigMatchCtx * ctx
Definition: detect.h:321
const char * alias
Definition: detect.h:1201
uint8_t version
Definition: decode-gre.h:405
#define SCFree(a)
Definition: util-mem.h:322
DetectNfsVersionMode
PoolThreadReserved res
uint16_t tx_id
const char * url
Definition: detect.h:1203
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1173
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define DOC_URL
Definition: suricata.h:86
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
Per thread variable structure.
Definition: threadvars.h:57
#define DOC_VERSION
Definition: suricata.h:91
#define MAX_SUBSTRINGS
struct DetectNfsVersionData_ DetectNfsVersionData
Flow data structure.
Definition: flow.h:325
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback)
register inspect engine at start up time
void(* RegisterTests)(void)
Definition: detect.h:1192
a single match condition for a signature
Definition: detect.h:318
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82