Coverage Report

Created: 2026-06-07 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/detect-dsize.c
Line
Count
Source
1
/* Copyright (C) 2007-2022 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
 * Implements the dsize keyword
24
 */
25
26
#include "suricata-common.h"
27
#include "decode.h"
28
29
#include "detect.h"
30
#include "detect-parse.h"
31
#include "detect-engine-prefilter-common.h"
32
#include "detect-engine-build.h"
33
34
#include "flow-var.h"
35
36
#include "detect-content.h"
37
#include "detect-dsize.h"
38
39
#include "util-unittest.h"
40
#include "util-debug.h"
41
#include "util-byte.h"
42
43
#include "pkt-var.h"
44
#include "host.h"
45
#include "util-profiling.h"
46
47
static int DetectDsizeMatch (DetectEngineThreadCtx *, Packet *,
48
        const Signature *, const SigMatchCtx *);
49
static int DetectDsizeSetup (DetectEngineCtx *, Signature *s, const char *str);
50
#ifdef UNITTESTS
51
static void DsizeRegisterTests(void);
52
#endif
53
static void DetectDsizeFree(DetectEngineCtx *, void *);
54
55
static int PrefilterSetupDsize(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
56
static bool PrefilterDsizeIsPrefilterable(const Signature *s);
57
58
/**
59
 * \brief Registration function for dsize: keyword
60
 */
61
void DetectDsizeRegister (void)
62
75
{
63
75
    sigmatch_table[DETECT_DSIZE].name = "dsize";
64
75
    sigmatch_table[DETECT_DSIZE].desc = "match on the size of the packet payload";
65
75
    sigmatch_table[DETECT_DSIZE].url = "/rules/payload-keywords.html#dsize";
66
75
    sigmatch_table[DETECT_DSIZE].Match = DetectDsizeMatch;
67
75
    sigmatch_table[DETECT_DSIZE].Setup = DetectDsizeSetup;
68
75
    sigmatch_table[DETECT_DSIZE].Free  = DetectDsizeFree;
69
#ifdef UNITTESTS
70
    sigmatch_table[DETECT_DSIZE].RegisterTests = DsizeRegisterTests;
71
#endif
72
75
    sigmatch_table[DETECT_DSIZE].SupportsPrefilter = PrefilterDsizeIsPrefilterable;
73
75
    sigmatch_table[DETECT_DSIZE].SetupPrefilter = PrefilterSetupDsize;
74
75
}
75
76
/**
77
 * \internal
78
 * \brief This function is used to match flags on a packet with those passed via dsize:
79
 *
80
 * \param t pointer to thread vars
81
 * \param det_ctx pointer to the pattern matcher thread
82
 * \param p pointer to the current packet
83
 * \param s pointer to the Signature
84
 * \param m pointer to the sigmatch
85
 *
86
 * \retval 0 no match
87
 * \retval 1 match
88
 */
89
static int DetectDsizeMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
90
    const Signature *s, const SigMatchCtx *ctx)
91
5.36k
{
92
5.36k
    SCEnter();
93
5.36k
    int ret = 0;
94
95
5.36k
    if (PKT_IS_PSEUDOPKT(p)) {
96
128
        SCReturnInt(0);
97
128
    }
98
99
5.23k
    const DetectU16Data *dd = (const DetectU16Data *)ctx;
100
101
5.23k
    SCLogDebug("p->payload_len %"PRIu16"", p->payload_len);
102
103
5.23k
    ret = DetectU16Match(p->payload_len, dd);
104
105
5.23k
    SCReturnInt(ret);
106
5.36k
}
107
108
/**
109
 * \internal
110
 * \brief this function is used to add the parsed dsize into the current signature
111
 *
112
 * \param de_ctx pointer to the Detection Engine Context
113
 * \param s pointer to the Current Signature
114
 * \param rawstr pointer to the user provided flags options
115
 *
116
 * \retval 0 on Success
117
 * \retval -1 on Failure
118
 */
119
static int DetectDsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
120
46.1k
{
121
46.1k
    DetectU16Data *dd = NULL;
122
46.1k
    SigMatch *sm = NULL;
123
124
46.1k
    if (DetectGetLastSMFromLists(s, DETECT_DSIZE, -1)) {
125
543
        SCLogError("Can't use 2 or more dsizes in "
126
543
                   "the same sig.  Invalidating signature.");
127
543
        return -1;
128
543
    }
129
130
45.6k
    SCLogDebug("\'%s\'", rawstr);
131
132
45.6k
    dd = DetectU16Parse(rawstr);
133
45.6k
    if (dd == NULL) {
134
3.21k
        SCLogError("Parsing \'%s\' failed", rawstr);
135
3.21k
        return -1;
136
3.21k
    }
137
138
    /* Okay so far so good, lets get this into a SigMatch
139
     * and put it in the Signature. */
140
42.3k
    sm = SigMatchAlloc();
141
42.3k
    if (sm == NULL){
142
0
        SCLogError("Failed to allocate memory for SigMatch");
143
0
        rs_detect_u16_free(dd);
144
0
        return -1;
145
0
    }
146
147
42.3k
    sm->type = DETECT_DSIZE;
148
42.3k
    sm->ctx = (SigMatchCtx *)dd;
149
150
42.3k
    SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH);
151
152
42.3k
    SCLogDebug("dd->arg1 %" PRIu16 ", dd->arg2 %" PRIu16 ", dd->mode %" PRIu8 "", dd->arg1,
153
42.3k
            dd->arg2, dd->mode);
154
    /* tell the sig it has a dsize to speed up engine init */
155
42.3k
    s->flags |= SIG_FLAG_REQUIRE_PACKET;
156
42.3k
    s->flags |= SIG_FLAG_DSIZE;
157
158
42.3k
    if (s->init_data->dsize_sm == NULL) {
159
38.9k
        s->init_data->dsize_sm = sm;
160
38.9k
    }
161
162
42.3k
    return 0;
163
42.3k
}
164
165
/**
166
 * \internal
167
 * \brief this function will free memory associated with DetectU16Data
168
 *
169
 * \param de pointer to DetectU16Data
170
 */
171
void DetectDsizeFree(DetectEngineCtx *de_ctx, void *de_ptr)
172
42.3k
{
173
42.3k
    rs_detect_u16_free(de_ptr);
174
42.3k
}
175
176
/* prefilter code */
177
178
static void
179
PrefilterPacketDsizeMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
180
6.97k
{
181
6.97k
    if (PKT_IS_PSEUDOPKT(p)) {
182
218
        SCReturn;
183
218
    }
184
185
6.76k
    const PrefilterPacketHeaderCtx *ctx = pectx;
186
6.76k
    if (!PrefilterPacketHeaderExtraMatch(ctx, p))
187
2.38k
        return;
188
189
4.37k
    const uint16_t dsize = p->payload_len;
190
4.37k
    DetectU16Data du16;
191
4.37k
    du16.mode = ctx->v1.u8[0];
192
4.37k
    du16.arg1 = ctx->v1.u16[1];
193
4.37k
    du16.arg2 = ctx->v1.u16[2];
194
195
4.37k
    if (DetectU16Match(dsize, &du16)) {
196
1.90k
        SCLogDebug("packet matches dsize %u", dsize);
197
1.90k
        PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
198
1.90k
    }
199
4.37k
}
200
201
static int PrefilterSetupDsize(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
202
5.63k
{
203
5.63k
    return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_DSIZE, PrefilterPacketU16Set,
204
5.63k
            PrefilterPacketU16Compare, PrefilterPacketDsizeMatch);
205
5.63k
}
206
207
static bool PrefilterDsizeIsPrefilterable(const Signature *s)
208
0
{
209
0
    const SigMatch *sm;
210
0
    for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
211
0
        switch (sm->type) {
212
0
            case DETECT_DSIZE:
213
0
                return true;
214
0
        }
215
0
    }
216
0
    return false;
217
0
}
218
219
/** \brief get max dsize "depth"
220
 *  \param s signature to get dsize value from
221
 *  \retval depth or negative value
222
 */
223
int SigParseGetMaxDsize(const Signature *s)
224
19.9k
{
225
19.9k
    if (s->flags & SIG_FLAG_DSIZE && s->init_data->dsize_sm != NULL) {
226
19.9k
        const DetectU16Data *dd = (const DetectU16Data *)s->init_data->dsize_sm->ctx;
227
228
19.9k
        switch (dd->mode) {
229
1.67k
            case DETECT_UINT_LT:
230
17.5k
            case DETECT_UINT_EQ:
231
17.8k
            case DETECT_UINT_NE:
232
17.8k
                return dd->arg1;
233
416
            case DETECT_UINT_RA:
234
416
                return dd->arg2;
235
1.35k
            case DETECT_UINT_GT:
236
1.67k
            default:
237
1.67k
                SCReturnInt(-2);
238
19.9k
        }
239
19.9k
    }
240
19.9k
    SCReturnInt(-1);
241
19.9k
}
242
243
/** \brief set prefilter dsize pair
244
 *  \param s signature to get dsize value from
245
 */
246
void SigParseSetDsizePair(Signature *s)
247
3.09k
{
248
3.09k
    if (s->flags & SIG_FLAG_DSIZE && s->init_data->dsize_sm != NULL) {
249
3.09k
        DetectU16Data *dd = (DetectU16Data *)s->init_data->dsize_sm->ctx;
250
251
3.09k
        uint16_t low = 0;
252
3.09k
        uint16_t high = 65535;
253
254
3.09k
        switch (dd->mode) {
255
636
            case DETECT_UINT_LT:
256
636
                low = 0;
257
636
                high = dd->arg1;
258
636
                break;
259
116
            case DETECT_UINT_LTE:
260
116
                low = 0;
261
116
                high = dd->arg1 + 1;
262
116
                break;
263
1.59k
            case DETECT_UINT_EQ:
264
1.67k
            case DETECT_UINT_NE:
265
1.67k
                low = dd->arg1;
266
1.67k
                high = dd->arg1;
267
1.67k
                break;
268
82
            case DETECT_UINT_RA:
269
82
                low = dd->arg1;
270
82
                high = dd->arg2;
271
82
                break;
272
443
            case DETECT_UINT_GT:
273
443
                low = dd->arg1;
274
443
                high = 65535;
275
443
                break;
276
123
            case DETECT_UINT_GTE:
277
123
                low = dd->arg1 - 1;
278
123
                high = 65535;
279
123
                break;
280
3.09k
        }
281
3.09k
        s->dsize_mode = dd->mode;
282
3.09k
        s->dsize_low = low;
283
3.09k
        s->dsize_high = high;
284
285
3.09k
        SCLogDebug("low %u, high %u, mode %u", low, high, dd->mode);
286
3.09k
    }
287
3.09k
}
288
289
/**
290
 *  \brief Determine the required dsize for the signature
291
 *  \param s signature to get dsize value from
292
 *
293
 *  Note that negated content does not contribute to the maximum
294
 *  required dsize value. However, each negated content's values
295
 *  must not exceed the dsize value. See SigParseRequiredContentSize.
296
 *
297
 * \retval -1 Signature doesn't have a dsize keyword
298
 * \retval >= 0 Dsize value required to not exclude content matches
299
 */
300
int SigParseMaxRequiredDsize(const Signature *s)
301
7.94k
{
302
7.94k
    SCEnter();
303
304
7.94k
    if (!(s->flags & SIG_FLAG_DSIZE)) {
305
0
        SCReturnInt(-1);
306
0
    }
307
308
7.94k
    const int dsize = SigParseGetMaxDsize(s);
309
7.94k
    if (dsize < 0) {
310
        /* nothing to do */
311
0
        SCReturnInt(-1);
312
0
    }
313
314
7.94k
    int total_length, offset;
315
7.94k
    SigParseRequiredContentSize(
316
7.94k
            s, dsize, s->init_data->smlists[DETECT_SM_LIST_PMATCH], &total_length, &offset);
317
7.94k
    SCLogDebug("dsize: %d  len: %d; offset: %d [%s]", dsize, total_length, offset, s->sig_str);
318
319
7.94k
    if (total_length > dsize) {
320
2.35k
        SCLogDebug("required_dsize: %d exceeds dsize: %d", total_length, dsize);
321
2.35k
        return total_length;
322
2.35k
    }
323
324
5.58k
    if ((total_length + offset) > dsize) {
325
259
        SCLogDebug("length + offset: %d exceeds dsize: %d", total_length + offset, dsize);
326
259
        return total_length + offset;
327
259
    }
328
329
5.58k
    SCReturnInt(-1);
330
5.58k
}
331
332
/**
333
 *  \brief Apply dsize as depth to content matches in the rule
334
 *  \param s signature to get dsize value from
335
 */
336
void SigParseApplyDsizeToContent(Signature *s)
337
247k
{
338
247k
    SCEnter();
339
340
247k
    if (s->flags & SIG_FLAG_DSIZE) {
341
3.09k
        SigParseSetDsizePair(s);
342
343
3.09k
        int dsize = SigParseGetMaxDsize(s);
344
3.09k
        if (dsize < 0) {
345
            /* nothing to do */
346
696
            return;
347
696
        }
348
349
2.39k
        SigMatch *sm = s->init_data->smlists[DETECT_SM_LIST_PMATCH];
350
4.06k
        for ( ; sm != NULL;  sm = sm->next) {
351
1.66k
            if (sm->type != DETECT_CONTENT) {
352
489
                continue;
353
489
            }
354
355
1.17k
            DetectContentData *cd = (DetectContentData *)sm->ctx;
356
1.17k
            if (cd == NULL) {
357
0
                continue;
358
0
            }
359
360
1.17k
            if (cd->depth == 0 || cd->depth >= dsize) {
361
1.11k
                cd->flags |= DETECT_CONTENT_DEPTH;
362
1.11k
                cd->depth = (uint16_t)dsize;
363
1.11k
                SCLogDebug("updated %u, content %u to have depth %u "
364
1.11k
                        "because of dsize.", s->id, cd->id, cd->depth);
365
1.11k
            }
366
1.17k
        }
367
2.39k
    }
368
247k
}
369
370
/*
371
 * ONLY TESTS BELOW THIS COMMENT
372
 */
373
374
#ifdef UNITTESTS
375
#include "util-unittest-helper.h"
376
#include "detect-engine.h"
377
#include "detect-engine-alert.h"
378
#include "packet.h"
379
380
/**
381
 * \test this is a test for a valid dsize value 1
382
 *
383
 */
384
static int DsizeTestParse01(void)
385
{
386
    DetectU16Data *dd = DetectU16Parse("1");
387
    FAIL_IF_NULL(dd);
388
    FAIL_IF_NOT(dd->arg1 == 1);
389
    FAIL_IF_NOT(dd->arg2 == 0);
390
391
    DetectDsizeFree(NULL, dd);
392
    PASS;
393
}
394
395
/**
396
 * \test this is a test for a valid dsize value >10
397
 *
398
 */
399
static int DsizeTestParse02(void)
400
{
401
    DetectU16Data *dd = DetectU16Parse(">10");
402
    FAIL_IF_NULL(dd);
403
    FAIL_IF_NOT(dd->arg1 == 10);
404
    FAIL_IF_NOT(dd->mode == DETECT_UINT_GT);
405
    DetectDsizeFree(NULL, dd);
406
    PASS;
407
}
408
409
/**
410
 * \test this is a test for a valid dsize value <100
411
 *
412
 */
413
static int DsizeTestParse03(void)
414
{
415
    DetectU16Data *dd = DetectU16Parse("<100");
416
    FAIL_IF_NULL(dd);
417
    FAIL_IF_NOT(dd->arg1 == 100);
418
    FAIL_IF_NOT(dd->mode == DETECT_UINT_LT);
419
420
    DetectDsizeFree(NULL, dd);
421
    PASS;
422
}
423
424
/**
425
 * \test this is a test for a valid dsize value 1<>3
426
 *
427
 */
428
static int DsizeTestParse04(void)
429
{
430
    DetectU16Data *dd = DetectU16Parse("1<>3");
431
    FAIL_IF_NULL(dd);
432
    FAIL_IF_NOT(dd->arg1 == 1);
433
    FAIL_IF_NOT(dd->arg2 == 3);
434
    FAIL_IF_NOT(dd->mode == DETECT_UINT_RA);
435
436
    DetectDsizeFree(NULL, dd);
437
    PASS;
438
}
439
440
/**
441
 * \test this is a test for a valid dsize value 1 <> 3
442
 *
443
 */
444
static int DsizeTestParse05(void)
445
{
446
    DetectU16Data *dd = DetectU16Parse(" 1 <> 3 ");
447
    FAIL_IF_NULL(dd);
448
    FAIL_IF_NOT(dd->arg1 == 1);
449
    FAIL_IF_NOT(dd->arg2 == 3);
450
    FAIL_IF_NOT(dd->mode == DETECT_UINT_RA);
451
452
    DetectDsizeFree(NULL, dd);
453
    PASS;
454
}
455
456
/**
457
 * \test this is test for a valid dsize value > 2
458
 *
459
 */
460
static int DsizeTestParse06(void)
461
{
462
    DetectU16Data *dd = DetectU16Parse("> 2 ");
463
    FAIL_IF_NULL(dd);
464
    FAIL_IF_NOT(dd->arg1 == 2);
465
    FAIL_IF_NOT(dd->mode == DETECT_UINT_GT);
466
467
    DetectDsizeFree(NULL, dd);
468
    PASS;
469
}
470
471
/**
472
 * \test test for a valid dsize value <   12
473
 *
474
 */
475
static int DsizeTestParse07(void)
476
{
477
    DetectU16Data *dd = DetectU16Parse("<   12 ");
478
    FAIL_IF_NULL(dd);
479
    FAIL_IF_NOT(dd->arg1 == 12);
480
    FAIL_IF_NOT(dd->mode == DETECT_UINT_LT);
481
482
    DetectDsizeFree(NULL, dd);
483
    PASS;
484
}
485
486
/**
487
 * \test test for a valid dsize value    12
488
 *
489
 */
490
static int DsizeTestParse08(void)
491
{
492
    DetectU16Data *dd = DetectU16Parse("   12 ");
493
    FAIL_IF_NULL(dd);
494
    FAIL_IF_NOT(dd->arg1 == 12);
495
    FAIL_IF_NOT(dd->mode == DETECT_UINT_EQ);
496
497
    DetectDsizeFree(NULL, dd);
498
    PASS;
499
}
500
501
/**
502
 * \test this is a test for a valid dsize value !1
503
 *
504
 */
505
static int DsizeTestParse09(void)
506
{
507
    DetectU16Data *dd = DetectU16Parse("!1");
508
    FAIL_IF_NULL(dd);
509
    DetectDsizeFree(NULL, dd);
510
    PASS;
511
}
512
513
/**
514
 * \test this is a test for a valid dsize value ! 1
515
 *
516
 */
517
static int DsizeTestParse10(void)
518
{
519
    DetectU16Data *dd = DetectU16Parse("! 1");
520
    FAIL_IF_NULL(dd);
521
    DetectDsizeFree(NULL, dd);
522
    PASS;
523
}
524
525
/**
526
 * \test this is a test for invalid dsize values
527
 * A, >10<>10, <>10, 1<>, "", " ", 2<>1, 1!
528
 *
529
 */
530
static int DsizeTestParse11(void)
531
{
532
    const char *strings[] = { "A", ">10<>10", "<>10", "1<>", "", " ", "2<>1", "1!", NULL };
533
    for (int i = 0; strings[i]; i++) {
534
        DetectU16Data *dd = DetectU16Parse(strings[i]);
535
        FAIL_IF_NOT_NULL(dd);
536
    }
537
538
    PASS;
539
}
540
541
/**
542
 * \test this is a test for positive ! dsize matching
543
 *
544
 */
545
static int DsizeTestMatch01(void)
546
{
547
    uint16_t psize = 1;
548
    uint16_t dsizelow = 2;
549
    uint16_t dsizehigh = 0;
550
    DetectU16Data du16;
551
    du16.mode = DETECT_UINT_NE;
552
    du16.arg1 = dsizelow;
553
    du16.arg2 = dsizehigh;
554
    FAIL_IF_NOT(DetectU16Match(psize, &du16));
555
556
    PASS;
557
}
558
559
/**
560
 * \test this is a test for negative ! dsize matching
561
 *
562
 */
563
static int DsizeTestMatch02(void)
564
{
565
    uint16_t psize = 1;
566
    uint16_t dsizelow = 1;
567
    uint16_t dsizehigh = 0;
568
    DetectU16Data du16;
569
    du16.mode = DETECT_UINT_NE;
570
    du16.arg1 = dsizelow;
571
    du16.arg2 = dsizehigh;
572
    FAIL_IF(DetectU16Match(psize, &du16));
573
574
    PASS;
575
}
576
577
/**
578
 * \test DetectDsizeIcmpv6Test01 is a test for checking the working of
579
 *       dsize keyword by creating 2 rules and matching a crafted packet
580
 *       against them. Only the first one shall trigger.
581
 */
582
static int DetectDsizeIcmpv6Test01(void)
583
{
584
    static uint8_t raw_icmpv6[] = {
585
        0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff,
586
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588
        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
590
        0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00,
591
        0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff,
592
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594
        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
596
597
    Packet *p = PacketGetFromAlloc();
598
    FAIL_IF_NULL(p);
599
600
    IPV6Hdr ip6h;
601
    ThreadVars tv;
602
    DecodeThreadVars dtv;
603
    ThreadVars th_v;
604
    DetectEngineThreadCtx *det_ctx = NULL;
605
606
    memset(&tv, 0, sizeof(ThreadVars));
607
    memset(&dtv, 0, sizeof(DecodeThreadVars));
608
    memset(&ip6h, 0, sizeof(IPV6Hdr));
609
    memset(&th_v, 0, sizeof(ThreadVars));
610
611
    FlowInitConfig(FLOW_QUIET);
612
    p->src.family = AF_INET6;
613
    p->dst.family = AF_INET6;
614
    p->ip6h = &ip6h;
615
616
    DecodeIPV6(&tv, &dtv, p, raw_icmpv6, sizeof(raw_icmpv6));
617
618
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
619
    FAIL_IF_NULL(de_ctx);
620
621
    de_ctx->flags |= DE_QUIET;
622
623
    Signature *s = DetectEngineAppendSig(de_ctx,
624
            "alert icmp any any -> any any "
625
            "(msg:\"ICMP Large ICMP Packet\"; dsize:>8; sid:1; rev:4;)");
626
    FAIL_IF_NULL(s);
627
628
    s = DetectEngineAppendSig(de_ctx,
629
            "alert icmp any any -> any any "
630
            "(msg:\"ICMP Large ICMP Packet\"; dsize:>800; sid:2; rev:4;)");
631
    FAIL_IF_NULL(s);
632
633
    SigGroupBuild(de_ctx);
634
    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
635
636
    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
637
    FAIL_IF(PacketAlertCheck(p, 1) == 0);
638
    FAIL_IF(PacketAlertCheck(p, 2));
639
640
    DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
641
    DetectEngineCtxFree(de_ctx);
642
643
    PacketRecycle(p);
644
    FlowShutdown();
645
    SCFree(p);
646
647
    PASS;
648
}
649
650
/**
651
 * \brief this function registers unit tests for dsize
652
 */
653
static void DsizeRegisterTests(void)
654
{
655
    UtRegisterTest("DsizeTestParse01", DsizeTestParse01);
656
    UtRegisterTest("DsizeTestParse02", DsizeTestParse02);
657
    UtRegisterTest("DsizeTestParse03", DsizeTestParse03);
658
    UtRegisterTest("DsizeTestParse04", DsizeTestParse04);
659
    UtRegisterTest("DsizeTestParse05", DsizeTestParse05);
660
    UtRegisterTest("DsizeTestParse06", DsizeTestParse06);
661
    UtRegisterTest("DsizeTestParse07", DsizeTestParse07);
662
    UtRegisterTest("DsizeTestParse08", DsizeTestParse08);
663
    UtRegisterTest("DsizeTestParse09", DsizeTestParse09);
664
    UtRegisterTest("DsizeTestParse10", DsizeTestParse10);
665
    UtRegisterTest("DsizeTestParse11", DsizeTestParse11);
666
    UtRegisterTest("DsizeTestMatch01", DsizeTestMatch01);
667
    UtRegisterTest("DsizeTestMatch02", DsizeTestMatch02);
668
669
    UtRegisterTest("DetectDsizeIcmpv6Test01", DetectDsizeIcmpv6Test01);
670
}
671
#endif /* UNITTESTS */