• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.88
/src/detect-engine-iponly.c
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
 * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
23
 *
24
 * Signatures that only inspect IP addresses are processed here
25
 * We use radix trees for src dst ipv4 and ipv6 addresses
26
 * This radix trees hold information for subnets and hosts in a
27
 * hierarchical distribution
28
 */
29

30
#include "suricata-common.h"
31
#include "detect.h"
32
#include "decode.h"
33
#include "flow.h"
34

35
#include "detect-parse.h"
36
#include "detect-engine.h"
37

38
#include "detect-engine-siggroup.h"
39
#include "detect-engine-address.h"
40
#include "detect-engine-proto.h"
41
#include "detect-engine-port.h"
42
#include "detect-engine-mpm.h"
43
#include "detect-engine-build.h"
44

45
#include "detect-engine-threshold.h"
46
#include "detect-engine-iponly.h"
47
#include "detect-threshold.h"
48
#include "util-classification-config.h"
49
#include "util-rule-vars.h"
50
#include "detect-engine-alert.h"
51

52
#include "flow-util.h"
53
#include "util-debug.h"
54
#include "util-unittest.h"
55
#include "util-unittest-helper.h"
56
#include "util-print.h"
57
#include "util-byte.h"
58
#include "util-profiling.h"
59
#include "util-validate.h"
60
#include "util-cidr.h"
61

62
#ifdef OS_WIN32
63
#include <winsock.h>
64
#else
65
#include <netinet/in.h>
66
#endif /* OS_WIN32 */
67

68
/**
69
 * \brief This function creates a new IPOnlyCIDRItem
70
 *
71
 * \retval IPOnlyCIDRItem address of the new instance
72
 */
73
static IPOnlyCIDRItem *IPOnlyCIDRItemNew(void)
74
{
496,434✔
75
    SCEnter();
496,434✔
76
    IPOnlyCIDRItem *item = NULL;
496,434✔
77

78
    item = SCCalloc(1, sizeof(IPOnlyCIDRItem));
496,434✔
79
    if (unlikely(item == NULL))
496,434✔
80
        SCReturnPtr(NULL, "IPOnlyCIDRItem");
×
81

82
    SCReturnPtr(item, "IPOnlyCIDRItem");
496,434✔
83
}
496,434✔
84

85
/**
86
 * \brief Compares two list items
87
 *
88
 * \retval An integer less than, equal to, or greater than zero if lhs is
89
 *         considered to be respectively less than, equal to, or greater than
90
 *         rhs.
91
 */
92
static int IPOnlyCIDRItemCompareReal(const IPOnlyCIDRItem *lhs, const IPOnlyCIDRItem *rhs)
93
{
131,433✔
94
    if (lhs->netmask == rhs->netmask) {
131,433✔
95
        uint8_t i = 0;
76,703✔
96
        for (; i < lhs->netmask / 32 || i < 1; i++) {
175,971✔
97
            if (lhs->ip[i] < rhs->ip[i])
122,168✔
98
                return -1;
9,302✔
99
            if (lhs->ip[i] > rhs->ip[i])
112,866✔
100
                return 1;
13,598✔
101
        }
112,866✔
102
        return 0;
53,803✔
103
    }
76,703✔
104

105
    return lhs->netmask < rhs->netmask ? -1 : 1;
54,730✔
106
}
131,433✔
107

108
static int IPOnlyCIDRItemCompare(const void *lhsv, const void *rhsv)
109
{
131,433✔
110
    const IPOnlyCIDRItem *lhs = *(const IPOnlyCIDRItem **)lhsv;
131,433✔
111
    const IPOnlyCIDRItem *rhs = *(const IPOnlyCIDRItem **)rhsv;
131,433✔
112

113
    return IPOnlyCIDRItemCompareReal(lhs, rhs);
131,433✔
114
}
131,433✔
115

116
static void IPOnlyCIDRListQSort(IPOnlyCIDRItem **head)
117
{
70,876✔
118
    if (unlikely(head == NULL || *head == NULL))
70,876✔
119
        return;
64,964✔
120

121
    // First count the number of elements in the list
122
    size_t len = 0;
5,912✔
123
    IPOnlyCIDRItem *curr = *head;
5,912✔
124

125
    while (curr) {
43,212✔
126
        curr = curr->next;
37,300✔
127
        len++;
37,300✔
128
    }
37,300✔
129

130
    // Place a pointer to the list item in an array for sorting
131
    IPOnlyCIDRItem **tmp = SCMalloc(len * sizeof(IPOnlyCIDRItem *));
5,912✔
132

133
    if (unlikely(tmp == NULL)) {
5,912✔
134
        SCLogError("Failed to allocate enough memory to sort IP-only CIDR items.");
×
135
        return;
×
136
    }
×
137

138
    curr = *head;
5,912✔
139
    for (size_t i = 0; i < len; i++) {
43,212✔
140
        tmp[i] = curr;
37,300✔
141
        curr = curr->next;
37,300✔
142
    }
37,300✔
143

144
    // Perform the sort using the qsort algorithm
145
    qsort(tmp, len, sizeof(IPOnlyCIDRItem *), IPOnlyCIDRItemCompare);
5,912✔
146

147
    // Update the links to the next element
148
    *head = tmp[0];
5,912✔
149

150
    for (size_t i = 0; i + 1 < len; i++) {
37,300✔
151
        tmp[i]->next = tmp[i + 1];
31,388✔
152
    }
31,388✔
153

154
    tmp[len - 1]->next = NULL;
5,912✔
155

156
    SCFree(tmp);
5,912✔
157
}
5,912✔
158

159
//declaration for using it already
160
static IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head,
161
                                            IPOnlyCIDRItem *item);
162

163
static int InsertRange(
164
        IPOnlyCIDRItem **pdd, IPOnlyCIDRItem *dd, const uint32_t first_in, const uint32_t last_in)
165
{
1,367✔
166
    DEBUG_VALIDATE_BUG_ON(dd == NULL);
1,367✔
167
    DEBUG_VALIDATE_BUG_ON(pdd == NULL);
1,367✔
168

169
    uint32_t first = first_in;
1,367✔
170
    uint32_t last = last_in;
1,367✔
171

172
    dd->netmask = 32;
1,367✔
173
    /* Find the maximum netmask starting from current address first
174
     * and not crossing last.
175
     * To extend the mask, we need to start from a power of 2.
176
     * And we need to pay attention to unsigned overflow back to 0.0.0.0
177
     */
178
    while (dd->netmask > 0 && (first & (1UL << (32 - dd->netmask))) == 0 &&
3,971✔
179
            first + (1UL << (32 - (dd->netmask - 1))) - 1 <= last) {
3,971✔
180
        dd->netmask--;
2,604✔
181
    }
2,604✔
182
    dd->ip[0] = htonl(first);
1,367✔
183
    first += 1UL << (32 - dd->netmask);
1,367✔
184
    // case whatever-255.255.255.255 looping to 0.0.0.0/0
185
    while (first <= last && first != 0) {
21,719✔
186
        IPOnlyCIDRItem *new = IPOnlyCIDRItemNew();
20,352✔
187
        if (new == NULL)
20,352✔
188
            goto error;
×
189
        new->negated = dd->negated;
20,352✔
190
        new->family = dd->family;
20,352✔
191
        new->netmask = 32;
20,352✔
192
        while (new->netmask > 0 && (first & (1UL << (32 - new->netmask))) == 0 &&
261,082✔
193
                first + (1UL << (32 - (new->netmask - 1))) - 1 <= last) {
261,082✔
194
            new->netmask--;
240,730✔
195
        }
240,730✔
196
        new->ip[0] = htonl(first);
20,352✔
197
        first += 1UL << (32 - new->netmask);
20,352✔
198
        dd = IPOnlyCIDRItemInsert(dd, new);
20,352✔
199
    }
20,352✔
200
    // update head of list
201
    *pdd = dd;
1,367✔
202
    return 0;
1,367✔
203
error:
×
204
    return -1;
×
205
}
1,367✔
206

207
/**
208
 * \internal
209
 * \brief Parses an ipv4/ipv6 address string and updates the result into the
210
 *        IPOnlyCIDRItem instance sent as the argument.
211
 *
212
 * \param pdd Double pointer to the IPOnlyCIDRItem instance which should be updated
213
 *            with the address (in cidr) details from the parsed ip string.
214
 * \param str Pointer to address string that has to be parsed.
215
 *
216
 * \retval  0 On successfully parsing the address string.
217
 * \retval -1 On failure.
218
 */
219
static int IPOnlyCIDRItemParseSingle(IPOnlyCIDRItem **pdd, const char *str)
220
{
503,213✔
221
    char buf[256] = "";
503,213✔
222
    char *ip = NULL, *ip2 = NULL;
503,213✔
223
    char *mask = NULL;
503,213✔
224
    int r = 0;
503,213✔
225
    IPOnlyCIDRItem *dd = *pdd;
503,213✔
226

227
    while (*str != '\0' && *str == ' ')
506,536✔
228
        str++;
3,323✔
229

230
    SCLogDebug("str %s", str);
503,213✔
231
    strlcpy(buf, str, sizeof(buf));
503,213✔
232
    ip = buf;
503,213✔
233

234
    /* first handle 'any' */
235
    if (strcasecmp(str, "any") == 0) {
503,213✔
236
        /* if any, insert 0.0.0.0/0 and ::/0 as well */
237
        SCLogDebug("adding 0.0.0.0/0 and ::/0 as we\'re handling \'any\'");
27,131✔
238

239
        IPOnlyCIDRItemParseSingle(&dd, "0.0.0.0/0");
27,131✔
240
        BUG_ON(dd->family == 0);
27,131✔
241

242
        dd->next = IPOnlyCIDRItemNew();
27,131✔
243
        if (dd->next == NULL)
27,131✔
244
            goto error;
×
245

246
        IPOnlyCIDRItemParseSingle(&dd->next, "::/0");
27,131✔
247
        BUG_ON(dd->family == 0);
27,131✔
248

249
        SCLogDebug("address is \'any\'");
27,131✔
250
        return 0;
27,131✔
251
    }
27,131✔
252

253
    /* handle the negation case */
254
    if (ip[0] == '!') {
476,082✔
255
        dd->negated = (dd->negated)? 0 : 1;
1,011✔
256
        ip++;
1,011✔
257
    }
1,011✔
258

259
    /* see if the address is an ipv4 or ipv6 address */
260
    if ((strchr(str, ':')) == NULL) {
476,082✔
261
        /* IPv4 Address */
262
        struct in_addr in;
180,652✔
263

264
        dd->family = AF_INET;
180,652✔
265

266
        if ((mask = strchr(ip, '/')) != NULL) {
180,652✔
267
            /* 1.2.3.4/xxx format (either dotted or cidr notation */
268
            ip[mask - ip] = '\0';
158,073✔
269
            mask++;
158,073✔
270
            uint32_t netmask = 0;
158,073✔
271
            size_t u = 0;
158,073✔
272

273
            if ((strchr (mask, '.')) == NULL) {
158,073✔
274
                /* 1.2.3.4/24 format */
275

276
                for (u = 0; u < strlen(mask); u++) {
329,051✔
277
                    if(!isdigit((unsigned char)mask[u]))
171,308✔
278
                        goto error;
×
279
                }
171,308✔
280

281
                uint8_t cidr;
157,743✔
282
                if (StringParseU8RangeCheck(&cidr, 10, 0, (const char *)mask, 0, 32) <= 0)
157,743✔
283
                    goto error;
×
284

285
                dd->netmask = cidr;
157,743✔
286
                netmask = CIDRGet(cidr);
157,743✔
287
            } else {
157,743✔
288
                /* 1.2.3.4/255.255.255.0 format */
289
                r = inet_pton(AF_INET, mask, &in);
330✔
290
                if (r <= 0)
330✔
291
                    goto error;
×
292

293
                int cidr = CIDRFromMask(in.s_addr);
330✔
294
                if (cidr < 0)
330✔
UNCOV
295
                    goto error;
×
296

297
                dd->netmask = (uint8_t)cidr;
330✔
298
            }
330✔
299

300
            r = inet_pton(AF_INET, ip, &in);
158,073✔
301
            if (r <= 0)
158,073✔
302
                goto error;
10✔
303

304
            dd->ip[0] = in.s_addr & netmask;
158,063✔
305

306
        } else if ((ip2 = strchr(ip, '-')) != NULL) {
158,063✔
307
            /* 1.2.3.4-1.2.3.6 range format */
308
            ip[ip2 - ip] = '\0';
1,370✔
309
            ip2++;
1,370✔
310

311
            uint32_t first, last;
1,370✔
312

313
            r = inet_pton(AF_INET, ip, &in);
1,370✔
314
            if (r <= 0)
1,370✔
315
                goto error;
3✔
316
            first = SCNtohl(in.s_addr);
1,367✔
317

318
            r = inet_pton(AF_INET, ip2, &in);
1,367✔
319
            if (r <= 0)
1,367✔
320
                goto error;
×
321
            last = SCNtohl(in.s_addr);
1,367✔
322

323
            /* a > b is illegal, a = b is ok */
324
            if (first > last)
1,367✔
325
                goto error;
×
326

327
            SCLogDebug("Creating CIDR range for [%s - %s]", ip, ip2);
1,367✔
328
            return InsertRange(pdd, dd, first, last);
1,367✔
329
        } else {
21,209✔
330
            /* 1.2.3.4 format */
331
            r = inet_pton(AF_INET, ip, &in);
21,209✔
332
            if (r <= 0)
21,209✔
333
                goto error;
609✔
334

335
            /* single host */
336
            dd->ip[0] = in.s_addr;
20,600✔
337
            dd->netmask = 32;
20,600✔
338
        }
20,600✔
339
    } else {
295,430✔
340
        /* IPv6 Address */
341
        struct in6_addr in6, mask6;
295,430✔
342
        uint32_t ip6addr[4], netmask[4];
295,430✔
343

344
        dd->family = AF_INET6;
295,430✔
345

346
        if ((mask = strchr(ip, '/')) != NULL)  {
295,430✔
347
            mask[0] = '\0';
159,374✔
348
            mask++;
159,374✔
349

350
            r = inet_pton(AF_INET6, ip, &in6);
159,374✔
351
            if (r <= 0)
159,374✔
352
                goto error;
421✔
353

354
            /* Format is cidr val */
355
            if (StringParseU8RangeCheck(&dd->netmask, 10, 0,
158,953✔
356
                                        (const char *)mask, 0, 128) < 0) {
158,953✔
357
                goto error;
4,153✔
358
            }
4,153✔
359

360
            memcpy(&ip6addr, &in6.s6_addr, sizeof(ip6addr));
154,800✔
361
            CIDRGetIPv6(dd->netmask, &mask6);
154,800✔
362
            memcpy(&netmask, &mask6.s6_addr, sizeof(netmask));
154,800✔
363

364
            dd->ip[0] = ip6addr[0] & netmask[0];
154,800✔
365
            dd->ip[1] = ip6addr[1] & netmask[1];
154,800✔
366
            dd->ip[2] = ip6addr[2] & netmask[2];
154,800✔
367
            dd->ip[3] = ip6addr[3] & netmask[3];
154,800✔
368
        } else {
154,800✔
369
            r = inet_pton(AF_INET6, ip, &in6);
136,056✔
370
            if (r <= 0)
136,056✔
371
                goto error;
449✔
372

373
            memcpy(dd->ip, &in6.s6_addr, sizeof(dd->ip));
135,607✔
374
            dd->netmask = 128;
135,607✔
375
        }
135,607✔
376

377
    }
295,430✔
378

379
    BUG_ON(dd->family == 0);
469,070✔
380
    return 0;
469,070✔
381

382
error:
5,645✔
383
    return -1;
5,645✔
384
}
469,070✔
385

386
/**
387
 * \brief Setup a single address string, parse it and add the resulting
388
 *        Address items in cidr format to the list of gh
389
 *
390
 * \param gh Pointer to the IPOnlyCIDRItem list Head to which the
391
 *           resulting Address-Range(s) from the parsed ip string has to
392
 *           be added.
393
 * \param s  Pointer to the ip address string to be parsed.
394
 *
395
 * \retval  0 On success.
396
 * \retval -1 On failure.
397
 */
398
static int IPOnlyCIDRItemSetup(IPOnlyCIDRItem **gh, char *s)
399
{
448,951✔
400
    SCLogDebug("gh %p, s %s", *gh, s);
448,951✔
401

402
    /* parse the address */
403
    if (IPOnlyCIDRItemParseSingle(gh, s) == -1) {
448,951✔
404
        SCLogError("address parsing error \"%s\"", s);
5,645✔
405
        goto error;
5,645✔
406
    }
5,645✔
407

408
    return 0;
443,306✔
409

410
error:
5,645✔
411
    return -1;
5,645✔
412
}
448,951✔
413

414
/**
415
 * \brief This function insert a IPOnlyCIDRItem
416
 *        to a list of IPOnlyCIDRItems
417
 * \param head Pointer to the head of IPOnlyCIDRItems list
418
 * \param item Pointer to the item to insert in the list
419
 *
420
 * \retval IPOnlyCIDRItem address of the new head if apply
421
 */
422
static IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head,
423
                                         IPOnlyCIDRItem *item)
424
{
365,768✔
425
    if (item == NULL)
365,768✔
426
        return head;
×
427

428
    /* Always insert item as head */
429
    item->next = head;
365,768✔
430
    return item;
365,768✔
431
}
365,768✔
432

433
/**
434
 * \brief This function insert a IPOnlyCIDRItem list
435
 *        to a list of IPOnlyCIDRItems sorted by netmask
436
 *        ascending
437
 * \param head Pointer to the head of IPOnlyCIDRItems list
438
 * \param item Pointer to the list of items to insert in the list
439
 *
440
 * \retval IPOnlyCIDRItem address of the new head if apply
441
 */
442
static IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head,
443
                                     IPOnlyCIDRItem *item)
444
{
609,024✔
445
    IPOnlyCIDRItem *it, *prev = NULL;
609,024✔
446

447
    /* The first element */
448
    if (head == NULL) {
609,024✔
449
        SCLogDebug("Head is NULL to insert item (%p)",item);
302,300✔
450
        return item;
302,300✔
451
    }
302,300✔
452

453
    if (item == NULL) {
306,724✔
454
        SCLogDebug("Item is NULL");
×
455
        return head;
×
456
    }
×
457

458
    SCLogDebug("Inserting item(%p)->netmask %u head %p", item, item->netmask, head);
306,724✔
459

460
    prev = item;
306,724✔
461
    while (prev != NULL) {
672,492✔
462
        it = prev->next;
365,768✔
463

464
        /* Separate from the item list */
465
        prev->next = NULL;
365,768✔
466

467
        //SCLogDebug("Before:");
468
        //IPOnlyCIDRListPrint(head);
469
        head = IPOnlyCIDRItemInsertReal(head, prev);
365,768✔
470
        //SCLogDebug("After:");
471
        //IPOnlyCIDRListPrint(head);
472
        prev = it;
365,768✔
473
    }
365,768✔
474

475
    return head;
306,724✔
476
}
306,724✔
477

478
/**
479
 * \brief This function free a IPOnlyCIDRItem list
480
 * \param tmphead Pointer to the list
481
 */
482
void IPOnlyCIDRListFree(IPOnlyCIDRItem *tmphead)
483
{
156,667✔
484
    SCEnter();
156,667✔
485
#ifdef DEBUG
486
    uint32_t i = 0;
487
#endif
488
    IPOnlyCIDRItem *it, *next = NULL;
156,667✔
489

490
    if (tmphead == NULL) {
156,667✔
UNCOV
491
        SCLogDebug("temphead is NULL");
×
UNCOV
492
        return;
×
UNCOV
493
    }
×
494

495
    it = tmphead;
156,667✔
496
    next = it->next;
156,667✔
497

498
    while (it != NULL) {
615,801✔
499
#ifdef DEBUG
500
        i++;
501
        SCLogDebug("Item(%p) %"PRIu32" removed", it, i);
502
#endif
503
        SCFree(it);
459,134✔
504
        it = next;
459,134✔
505

506
        if (next != NULL)
459,134✔
507
            next = next->next;
302,467✔
508
    }
459,134✔
509
    SCReturn;
156,667✔
510
}
156,667✔
511

512
/**
513
 * \brief This function update a list of IPOnlyCIDRItems
514
 *        setting the signature internal id (signum) to "i"
515
 *
516
 * \param tmphead Pointer to the list
517
 * \param i number of signature internal id
518
 */
519
static void IPOnlyCIDRListSetSigNum(IPOnlyCIDRItem *tmphead, SigIntId i)
520
{
11,302✔
521
    while (tmphead != NULL) {
48,602✔
522
        tmphead->signum = i;
37,300✔
523
        tmphead = tmphead->next;
37,300✔
524
    }
37,300✔
525
}
11,302✔
526

527
#ifdef UNITTESTS
528
/**
529
 * \brief This function print a IPOnlyCIDRItem list
530
 * \param tmphead Pointer to the head of IPOnlyCIDRItems list
531
 */
532
static void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead)
533
{
534
#ifdef DEBUG
535
    uint32_t i = 0;
536

537
    while (tmphead != NULL) {
538
        i++;
539
        SCLogDebug("Item %"PRIu32" has netmask %"PRIu8" negated:"
540
                   " %s; IP: %s; signum: %"PRIu32, i, tmphead->netmask,
541
                   (tmphead->negated) ? "yes":"no",
542
                   inet_ntoa(*(struct in_addr*)&tmphead->ip[0]),
543
                   tmphead->signum);
544
        tmphead = tmphead->next;
545
    }
546
#endif
547
}
548
#endif
549

550
/** \brief user data for storing signature id's in the radix tree
551
 *
552
 *  Bit array representing signature internal id's (Signature::num).
553
 */
554
typedef struct SigNumArray_ {
555
    uint8_t *array; /* bit array of sig nums */
556
    uint32_t size;  /* size in bytes of the array */
557
} SigNumArray;
558

559
/**
560
 * \brief This function print a SigNumArray, it's used with the
561
 *        radix tree print function to help debugging
562
 * \param tmp Pointer to the head of SigNumArray
563
 */
564
static void SigNumArrayPrint(void *tmp)
565
{
×
566
    SigNumArray *sna = (SigNumArray *)tmp;
×
567
    for (uint32_t u = 0; u < sna->size; u++) {
×
568
        uint8_t bitarray = sna->array[u];
×
569
        for (uint8_t i = 0; i < 8; i++) {
×
570
            if (bitarray & 0x01)
×
571
                printf("%" PRIu32 " ", u * 8 + i);
×
572
            bitarray = bitarray >> 1;
×
573
        }
×
574
    }
×
575
}
×
576

577
/**
578
 * \brief This function creates a new SigNumArray with the
579
 *        size fixed to the io_ctx->max_idx
580
 * \param de_ctx Pointer to the current detection context
581
 * \param io_ctx Pointer to the current ip only context
582
 *
583
 * \retval SigNumArray address of the new instance
584
 */
585
static SigNumArray *SigNumArrayNew(DetectEngineCtx *de_ctx,
586
                            DetectEngineIPOnlyCtx *io_ctx)
587
{
13,184✔
588
    SigNumArray *new = SCCalloc(1, sizeof(SigNumArray));
13,184✔
589

590
    if (unlikely(new == NULL)) {
13,184✔
591
        FatalError("Fatal error encountered in SigNumArrayNew. Exiting...");
×
592
    }
×
593

594
    new->array = SCCalloc(1, io_ctx->max_idx / 8 + 1);
13,184✔
595
    if (new->array == NULL) {
13,184✔
596
       exit(EXIT_FAILURE);
×
597
    }
×
598

599
    new->size = io_ctx->max_idx / 8 + 1;
13,184✔
600

601
    SCLogDebug("max idx= %u", io_ctx->max_idx);
13,184✔
602

603
    return new;
13,184✔
604
}
13,184✔
605

606
/**
607
 * \brief This function creates a new SigNumArray with the
608
 *        same data as the argument
609
 *
610
 * \param orig Pointer to the original SigNumArray to copy
611
 *
612
 * \retval SigNumArray address of the new instance
613
 */
614
static SigNumArray *SigNumArrayCopy(SigNumArray *orig)
615
{
8,832✔
616
    SigNumArray *new = SCCalloc(1, sizeof(SigNumArray));
8,832✔
617

618
    if (unlikely(new == NULL)) {
8,832✔
619
        FatalError("Fatal error encountered in SigNumArrayCopy. Exiting...");
×
620
    }
×
621

622
    new->size = orig->size;
8,832✔
623

624
    new->array = SCMalloc(orig->size);
8,832✔
625
    if (new->array == NULL) {
8,832✔
626
        exit(EXIT_FAILURE);
×
627
    }
×
628

629
    memcpy(new->array, orig->array, orig->size);
8,832✔
630
    return new;
8,832✔
631
}
8,832✔
632

633
/**
634
 * \brief This function free() a SigNumArray
635
 * \param orig Pointer to the original SigNumArray to copy
636
 */
637
static void SigNumArrayFree(void *tmp)
638
{
22,016✔
639
    SigNumArray *sna = (SigNumArray *)tmp;
22,016✔
640

641
    if (sna == NULL)
22,016✔
642
        return;
×
643

644
    if (sna->array != NULL)
22,016✔
645
        SCFree(sna->array);
22,016✔
646

647
    SCFree(sna);
22,016✔
648
}
22,016✔
649

650
/**
651
 * \brief This function parses and return a list of IPOnlyCIDRItem
652
 *
653
 * \param s Pointer to the string of the addresses
654
 *          (in the format of signatures)
655
 * \param negate flag to indicate if all this string is negated or not
656
 *
657
 * \retval 0 if success
658
 * \retval -1 if fails
659
 */
660
static IPOnlyCIDRItem *IPOnlyCIDRListParse2(
661
        const DetectEngineCtx *de_ctx, const char *s, int negate)
662
{
299,236✔
663
    size_t x = 0;
299,236✔
664
    size_t u = 0;
299,236✔
665
    int o_set = 0, n_set = 0, d_set = 0;
299,236✔
666
    int depth = 0;
299,236✔
667
    size_t size = strlen(s);
299,236✔
668
    char address[8196] = "";
299,236✔
669
    const char *rule_var_address = NULL;
299,236✔
670
    char *temp_rule_var_address = NULL;
299,236✔
671
    IPOnlyCIDRItem *head;
299,236✔
672
    IPOnlyCIDRItem *subhead;
299,236✔
673
    head = subhead = NULL;
299,236✔
674

675
    SCLogDebug("s %s negate %s", s, negate ? "true" : "false");
299,236✔
676

677
    for (u = 0, x = 0; u < size && x < sizeof(address); u++) {
7,188,355✔
678
        address[x] = s[u];
6,895,351✔
679
        x++;
6,895,351✔
680

681
        if (!o_set && s[u] == '!') {
6,895,351✔
682
            n_set = 1;
530✔
683
            x--;
530✔
684
        } else if (s[u] == '[') {
6,894,821✔
685
            if (!o_set) {
187,466✔
686
                o_set = 1;
135,602✔
687
                x = 0;
135,602✔
688
            }
135,602✔
689
            depth++;
187,466✔
690
        } else if (s[u] == ']') {
6,707,355✔
691
            if (depth == 1) {
187,466✔
692
                address[x - 1] = '\0';
134,651✔
693
                x = 0;
134,651✔
694

695
                if ( (subhead = IPOnlyCIDRListParse2(de_ctx, address,
134,651✔
696
                                                (negate + n_set) % 2)) == NULL)
134,651✔
697
                    goto error;
587✔
698

699
                head = IPOnlyCIDRItemInsert(head, subhead);
134,064✔
700
                n_set = 0;
134,064✔
701
            }
134,064✔
702
            depth--;
186,879✔
703
        } else if (depth == 0 && s[u] == ',') {
6,519,889✔
704
            if (o_set == 1) {
291,332✔
705
                o_set = 0;
7,113✔
706
            } else if (d_set == 1) {
284,219✔
707
                address[x - 1] = '\0';
×
708

709
                rule_var_address = SCRuleVarsGetConfVar(de_ctx, address,
×
710
                                                  SC_RULE_VARS_ADDRESS_GROUPS);
×
711
                if (rule_var_address == NULL)
×
712
                    goto error;
×
713

714
                if ((negate + n_set) % 2) {
×
715
                    /* add +1 to safisfy gcc 15 + -Wformat-truncation=2 */
716
                    const size_t str_size = strlen(rule_var_address) + 3 + 1;
×
717
                    temp_rule_var_address = SCMalloc(str_size);
×
718
                    if (unlikely(temp_rule_var_address == NULL)) {
×
719
                        goto error;
×
720
                    }
×
721

722
                    snprintf(temp_rule_var_address, str_size, "[%s]", rule_var_address);
×
723
                } else {
×
724
                    temp_rule_var_address = SCStrdup(rule_var_address);
×
725
                    if (unlikely(temp_rule_var_address == NULL)) {
×
726
                        goto error;
×
727
                    }
×
728
                }
×
729

730
                subhead = IPOnlyCIDRListParse2(de_ctx, temp_rule_var_address,
×
731
                                               (negate + n_set) % 2);
×
732
                head = IPOnlyCIDRItemInsert(head, subhead);
×
733

734
                d_set = 0;
×
735
                n_set = 0;
×
736

737
                SCFree(temp_rule_var_address);
×
738

739
            } else {
284,219✔
740
                address[x - 1] = '\0';
284,219✔
741

742
                subhead = IPOnlyCIDRItemNew();
284,219✔
743
                if (subhead == NULL)
284,219✔
744
                    goto error;
×
745

746
                if (!((negate + n_set) % 2))
284,219✔
747
                    subhead->negated = 0;
284,219✔
748
                else
×
749
                    subhead->negated = 1;
×
750

751
                if (IPOnlyCIDRItemSetup(&subhead, address) < 0) {
284,219✔
752
                    IPOnlyCIDRListFree(subhead);
3,916✔
753
                    subhead = NULL;
3,916✔
754
                    goto error;
3,916✔
755
                }
3,916✔
756
                head = IPOnlyCIDRItemInsert(head, subhead);
280,303✔
757

758
                n_set = 0;
280,303✔
759
            }
280,303✔
760
            x = 0;
287,416✔
761
        } else if (depth == 0 && s[u] == '$') {
6,228,557✔
762
            d_set = 1;
1,891✔
763
        } else if (depth == 0 && u == size - 1) {
6,226,666✔
764
            if (x == sizeof(address)) {
164,732✔
765
                address[x - 1] = '\0';
×
766
            } else {
164,732✔
767
                address[x] = '\0';
164,732✔
768
            }
164,732✔
769
            x = 0;
164,732✔
770

771
            if (d_set == 1) {
164,732✔
UNCOV
772
                rule_var_address = SCRuleVarsGetConfVar(de_ctx, address,
×
UNCOV
773
                                                    SC_RULE_VARS_ADDRESS_GROUPS);
×
UNCOV
774
                if (rule_var_address == NULL)
×
775
                    goto error;
×
776

UNCOV
777
                if ((negate + n_set) % 2) {
×
778
                    /* add +1 to safisfy gcc 15 + -Wformat-truncation=2 */
779
                    const size_t str_size = strlen(rule_var_address) + 3 + 1;
×
780
                    temp_rule_var_address = SCMalloc(str_size);
×
781
                    if (unlikely(temp_rule_var_address == NULL)) {
×
782
                        goto error;
×
783
                    }
×
784
                    snprintf(temp_rule_var_address, str_size, "[%s]", rule_var_address);
×
UNCOV
785
                } else {
×
UNCOV
786
                    temp_rule_var_address = SCStrdup(rule_var_address);
×
UNCOV
787
                    if (unlikely(temp_rule_var_address == NULL)) {
×
788
                        goto error;
×
789
                    }
×
UNCOV
790
                }
×
UNCOV
791
                subhead = IPOnlyCIDRListParse2(de_ctx, temp_rule_var_address,
×
UNCOV
792
                                               (negate + n_set) % 2);
×
UNCOV
793
                head = IPOnlyCIDRItemInsert(head, subhead);
×
794

UNCOV
795
                d_set = 0;
×
796

UNCOV
797
                SCFree(temp_rule_var_address);
×
798
            } else {
164,732✔
799
                subhead = IPOnlyCIDRItemNew();
164,732✔
800
                if (subhead == NULL)
164,732✔
801
                    goto error;
×
802

803
                if (!((negate + n_set) % 2))
164,732✔
804
                    subhead->negated = 0;
164,732✔
805
                else
×
806
                    subhead->negated = 1;
×
807

808
                if (IPOnlyCIDRItemSetup(&subhead, address) < 0) {
164,732✔
809
                    IPOnlyCIDRListFree(subhead);
1,729✔
810
                    subhead = NULL;
1,729✔
811
                    goto error;
1,729✔
812
                }
1,729✔
813
                head = IPOnlyCIDRItemInsert(head, subhead);
163,003✔
814
            }
163,003✔
815
            n_set = 0;
163,003✔
816
        }
163,003✔
817
    }
6,895,351✔
818

819
    return head;
293,004✔
820

821
error:
6,232✔
822
    SCLogError("Error parsing addresses");
6,232✔
823
    return head;
6,232✔
824
}
299,236✔
825

826

827
/**
828
 * \brief Parses an address group sent as a character string and updates the
829
 *        IPOnlyCIDRItem list
830
 *
831
 * \param gh  Pointer to the IPOnlyCIDRItem list
832
 * \param str Pointer to the character string containing the address group
833
 *            that has to be parsed.
834
 *
835
 * \retval  0 On success.
836
 * \retval -1 On failure.
837
 */
838
static int IPOnlyCIDRListParse(const DetectEngineCtx *de_ctx, IPOnlyCIDRItem **gh, const char *str)
839
{
164,585✔
840
    SCLogDebug("gh %p, str %s", gh, str);
164,585✔
841

842
    if (gh == NULL)
164,585✔
843
        goto error;
×
844

845
    *gh = IPOnlyCIDRListParse2(de_ctx, str, 0);
164,585✔
846
    if (*gh == NULL) {
164,585✔
847
        SCLogDebug("IPOnlyCIDRListParse2 returned null");
2,261✔
848
        goto error;
2,261✔
849
    }
2,261✔
850

851
    return 0;
162,324✔
852

853
error:
2,261✔
854
    return -1;
2,261✔
855
}
164,585✔
856

857
/**
858
 * \brief Parses an address group sent as a character string and updates the
859
 *        IPOnlyCIDRItem lists src and dst of the Signature *s
860
 *
861
 * \param s Pointer to the signature structure
862
 * \param addrstr Pointer to the character string containing the address group
863
 *            that has to be parsed.
864
 * \param flag to indicate if we are parsing the src string or the dst string
865
 *
866
 * \retval  0 On success.
867
 * \retval -1 On failure.
868
 */
869
int IPOnlySigParseAddress(const DetectEngineCtx *de_ctx,
870
                          Signature *s, const char *addrstr, char flag)
871
{
164,585✔
872
    SCLogDebug("Address Group \"%s\" to be parsed now", addrstr);
164,585✔
873

874
    /* pass on to the address(list) parser */
875
    if (flag == 0) {
164,585✔
876
        if (strcasecmp(addrstr, "any") == 0) {
82,571✔
877
            s->flags |= SIG_FLAG_SRC_ANY;
58,460✔
878
            if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_src, "[0.0.0.0/0,::/0]") < 0)
58,460✔
879
                goto error;
×
880

881
        } else if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_src, (char *)addrstr) < 0) {
58,460✔
882
            goto error;
557✔
883
        }
557✔
884

885
        /* IPOnlyCIDRListPrint(s->CidrSrc); */
886
    } else {
82,571✔
887
        if (strcasecmp(addrstr, "any") == 0) {
82,014✔
888
            s->flags |= SIG_FLAG_DST_ANY;
57,084✔
889
            if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_dst, "[0.0.0.0/0,::/0]") < 0)
57,084✔
890
                goto error;
×
891

892
        } else if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_dst, (char *)addrstr) < 0) {
57,084✔
893
            goto error;
1,704✔
894
        }
1,704✔
895

896
        /* IPOnlyCIDRListPrint(s->CidrDst); */
897
    }
82,014✔
898

899
    return 0;
162,324✔
900

901
error:
2,261✔
902
    SCLogError("failed to parse addresses");
2,261✔
903
    return -1;
2,261✔
904
}
164,585✔
905

906
static const SCRadix4Config iponly_radix4_config = { SigNumArrayFree, SigNumArrayPrint };
907
static const SCRadix6Config iponly_radix6_config = { SigNumArrayFree, SigNumArrayPrint };
908

909
/**
910
 * \brief Setup the IP Only detection engine context
911
 *
912
 * \param de_ctx Pointer to the current detection engine
913
 * \param io_ctx Pointer to the current ip only detection engine
914
 */
915
void IPOnlyInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
916
{
35,438✔
917
    io_ctx->tree_ipv4src = SCRadix4TreeInitialize();
35,438✔
918
    io_ctx->tree_ipv4dst = SCRadix4TreeInitialize();
35,438✔
919
    io_ctx->tree_ipv6src = SCRadix6TreeInitialize();
35,438✔
920
    io_ctx->tree_ipv6dst = SCRadix6TreeInitialize();
35,438✔
921

922
    io_ctx->sig_mapping = SCCalloc(1, de_ctx->sig_array_len * sizeof(uint32_t));
35,438✔
923
    if (io_ctx->sig_mapping == NULL) {
35,438✔
924
        FatalError("Unable to allocate iponly signature tracking area");
×
925
    }
×
926
    io_ctx->sig_mapping_size = 0;
35,438✔
927
}
35,438✔
928

929
SigIntId IPOnlyTrackSigNum(DetectEngineIPOnlyCtx *io_ctx, SigIntId signum)
930
{
5,651✔
931
    SigIntId loc = io_ctx->sig_mapping_size;
5,651✔
932
    io_ctx->sig_mapping[loc] = signum;
5,651✔
933
    io_ctx->sig_mapping_size++;
5,651✔
934
    return loc;
5,651✔
935
}
5,651✔
936

937
/**
938
 * \brief Print stats of the IP Only engine
939
 *
940
 * \param de_ctx Pointer to the current detection engine
941
 * \param io_ctx Pointer to the current ip only detection engine
942
 */
943
void IPOnlyPrint(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
944
{
35,438✔
945
    /* XXX: how are we going to print the stats now? */
946
}
35,438✔
947

948
/**
949
 * \brief Deinitialize the IP Only detection engine context
950
 *
951
 * \param de_ctx Pointer to the current detection engine
952
 * \param io_ctx Pointer to the current ip only detection engine
953
 */
954
void IPOnlyDeinit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
955
{
35,466✔
956

957
    if (io_ctx == NULL)
35,466✔
958
        return;
×
959

960
    SCRadix4TreeRelease(&io_ctx->tree_ipv4src, &iponly_radix4_config);
35,466✔
961
    SCRadix4TreeRelease(&io_ctx->tree_ipv4dst, &iponly_radix4_config);
35,466✔
962

963
    SCRadix6TreeRelease(&io_ctx->tree_ipv6src, &iponly_radix6_config);
35,466✔
964
    SCRadix6TreeRelease(&io_ctx->tree_ipv6dst, &iponly_radix6_config);
35,466✔
965

966
    if (io_ctx->sig_mapping != NULL)
35,466✔
967
        SCFree(io_ctx->sig_mapping);
35,436✔
968
    io_ctx->sig_mapping = NULL;
35,466✔
969
}
35,466✔
970

971
static inline int IPOnlyMatchCompatSMs(
972
        ThreadVars *tv, DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p)
973
{
13,123✔
974
    KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_MATCH);
13,123✔
975
    const SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_MATCH];
13,123✔
976
    while (smd) {
13,123✔
977
        DEBUG_VALIDATE_BUG_ON(!(sigmatch_table[smd->type].flags & SIGMATCH_IPONLY_COMPAT));
139✔
978
        KEYWORD_PROFILING_START;
139✔
979
        if (sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx) > 0) {
139✔
980
            KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
2✔
981
            if (smd->is_last)
2✔
982
                break;
2✔
983
            smd++;
×
984
            continue;
×
985
        }
2✔
986
        KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
137✔
987
        return 0;
137✔
988
    }
139✔
989
    return 1;
12,986✔
990
}
13,123✔
991

992
/**
993
 * \brief Match a packet against the IP Only detection engine contexts
994
 *
995
 * \param de_ctx Pointer to the current detection engine
996
 * \param io_ctx Pointer to the current ip only detection engine
997
 * \param io_ctx Pointer to the current ip only thread detection engine
998
 * \param p Pointer to the Packet to match against
999
 */
1000
void IPOnlyMatchPacket(ThreadVars *tv, const DetectEngineCtx *de_ctx,
1001
        DetectEngineThreadCtx *det_ctx, const DetectEngineIPOnlyCtx *io_ctx, Packet *p)
1002
{
274,265✔
1003
    SigNumArray *src = NULL;
274,265✔
1004
    SigNumArray *dst = NULL;
274,265✔
1005
    void *user_data_src = NULL, *user_data_dst = NULL;
274,265✔
1006

1007
    SCEnter();
274,265✔
1008

1009
    if (p->src.family == AF_INET) {
274,265✔
1010
        (void)SCRadix4TreeFindBestMatch(
119,804✔
1011
                &io_ctx->tree_ipv4src, (uint8_t *)&GET_IPV4_SRC_ADDR_U32(p), &user_data_src);
119,804✔
1012
    } else if (p->src.family == AF_INET6) {
154,461✔
1013
        (void)SCRadix6TreeFindBestMatch(
10,732✔
1014
                &io_ctx->tree_ipv6src, (uint8_t *)&GET_IPV6_SRC_ADDR(p), &user_data_src);
10,732✔
1015
    }
10,732✔
1016

1017
    if (p->dst.family == AF_INET) {
274,265✔
1018
        (void)SCRadix4TreeFindBestMatch(
119,804✔
1019
                &io_ctx->tree_ipv4dst, (uint8_t *)&GET_IPV4_DST_ADDR_U32(p), &user_data_dst);
119,804✔
1020
    } else if (p->dst.family == AF_INET6) {
154,461✔
1021
        (void)SCRadix6TreeFindBestMatch(
10,732✔
1022
                &io_ctx->tree_ipv6dst, (uint8_t *)&GET_IPV6_DST_ADDR(p), &user_data_dst);
10,732✔
1023
    }
10,732✔
1024

1025
    src = user_data_src;
274,265✔
1026
    dst = user_data_dst;
274,265✔
1027

1028
    if (src == NULL || dst == NULL)
274,265✔
1029
        SCReturn;
262,315✔
1030

1031
    for (uint32_t u = 0; u < src->size; u++) {
24,092✔
1032
        SCLogDebug("And %"PRIu8" & %"PRIu8, src->array[u], dst->array[u]);
12,142✔
1033

1034
        uint8_t bitarray = dst->array[u] & src->array[u];
12,142✔
1035

1036
        /* We have to move the logic of the signature checking
1037
         * to the main detect loop, in order to apply the
1038
         * priority of actions (pass, drop, reject, alert) */
1039
        if (!bitarray)
12,142✔
1040
            continue;
1,089✔
1041

1042
        /* We have a match :) Let's see from which signum's */
1043

1044
        for (uint8_t i = 0; i < 8; i++, bitarray = bitarray >> 1) {
99,477✔
1045
            if (bitarray & 0x01) {
88,424✔
1046
                const Signature *s = de_ctx->sig_array[io_ctx->sig_mapping[u * 8 + i]];
18,335✔
1047

1048
                if ((s->proto.flags & DETECT_PROTO_IPV4) && !PacketIsIPv4(p)) {
18,335✔
1049
                    SCLogDebug("ip version didn't match");
6✔
1050
                    continue;
6✔
1051
                }
6✔
1052
                if ((s->proto.flags & DETECT_PROTO_IPV6) && !PacketIsIPv6(p)) {
18,329✔
1053
                    SCLogDebug("ip version didn't match");
1,014✔
1054
                    continue;
1,014✔
1055
                }
1,014✔
1056
                if (DetectProtoContainsProto(&s->proto, PacketGetIPProto(p)) == 0) {
17,315✔
1057
                    SCLogDebug("proto didn't match");
3,052✔
1058
                    continue;
3,052✔
1059
                }
3,052✔
1060

1061
                /* check the source & dst port in the sig */
1062
                if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP ||
14,263✔
1063
                        p->proto == IPPROTO_SCTP) {
14,263✔
1064
                    if (!(s->flags & SIG_FLAG_DP_ANY)) {
10,958✔
1065
                        if (p->flags & PKT_IS_FRAGMENT)
644✔
1066
                            continue;
32✔
1067

1068
                        const DetectPort *dport = DetectPortLookupGroup(s->dp, p->dp);
612✔
1069
                        if (dport == NULL) {
612✔
1070
                            SCLogDebug("dport didn't match.");
491✔
1071
                            continue;
491✔
1072
                        }
491✔
1073
                    }
612✔
1074
                    if (!(s->flags & SIG_FLAG_SP_ANY)) {
10,435✔
1075
                        if (p->flags & PKT_IS_FRAGMENT)
408✔
1076
                            continue;
27✔
1077

1078
                        const DetectPort *sport = DetectPortLookupGroup(s->sp, p->sp);
381✔
1079
                        if (sport == NULL) {
381✔
1080
                            SCLogDebug("sport didn't match.");
355✔
1081
                            continue;
355✔
1082
                        }
355✔
1083
                    }
381✔
1084
                } else if ((s->flags & (SIG_FLAG_DP_ANY | SIG_FLAG_SP_ANY)) !=
10,435✔
1085
                           (SIG_FLAG_DP_ANY | SIG_FLAG_SP_ANY)) {
3,305✔
1086
                    SCLogDebug("port-less protocol and sig needs ports");
235✔
1087
                    continue;
235✔
1088
                }
235✔
1089

1090
                if (!IPOnlyMatchCompatSMs(tv, det_ctx, s, p)) {
13,123✔
1091
                    continue;
137✔
1092
                }
137✔
1093

1094
                SCLogDebug("Signum %" PRIu32 " match (sid: %" PRIu32 ", msg: %s)", u * 8 + i, s->id,
12,986✔
1095
                        s->msg);
12,986✔
1096

1097
                if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) {
12,986✔
1098
                    KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_POSTMATCH);
3,014✔
1099
                    const SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH];
3,014✔
1100

1101
                    SCLogDebug("running match functions, sm %p", smd);
3,014✔
1102

1103
                    if (smd != NULL) {
3,014✔
1104
                        while (1) {
3,232✔
1105
                            KEYWORD_PROFILING_START;
3,232✔
1106
                            (void)sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx);
3,232✔
1107
                            KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
3,232✔
1108
                            if (smd->is_last)
3,232✔
1109
                                break;
3,014✔
1110
                            smd++;
218✔
1111
                        }
218✔
1112
                    }
3,014✔
1113
                }
3,014✔
1114
                AlertQueueAppend(det_ctx, s, p, 0, 0);
12,986✔
1115
            }
12,986✔
1116
        }
88,424✔
1117
    }
11,053✔
1118
    SCReturn;
11,950✔
1119
}
274,265✔
1120

1121
static void IPOnlyPrepareUpdateBitarray(const IPOnlyCIDRItem *src, SigNumArray *sna)
1122
{
37,300✔
1123
    uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
37,300✔
1124
    if (src->negated > 0)
37,300✔
1125
        /* Unset it */
1126
        sna->array[src->signum / 8] &= ~tmp;
220✔
1127
    else
37,080✔
1128
        /* Set it */
1129
        sna->array[src->signum / 8] |= tmp;
37,080✔
1130
}
37,300✔
1131

1132
/**
1133
 * \brief Build the radix trees from the lists of parsed addresses in CIDR format
1134
 *        the result should be 4 radix trees: src/dst ipv4 and src/dst ipv6
1135
 *        holding SigNumArrays, each of them with a hierarchical relation
1136
 *        of subnets and hosts
1137
 *
1138
 * \param de_ctx Pointer to the current detection engine
1139
 */
1140
void IPOnlyPrepare(DetectEngineCtx *de_ctx)
1141
{
35,438✔
1142
    SCLogDebug("Preparing Final Lists");
35,438✔
1143

1144
    /*
1145
       IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_src);
1146
       IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_dst);
1147
     */
1148

1149
    IPOnlyCIDRListQSort(&de_ctx->io_ctx.ip_src);
35,438✔
1150
    IPOnlyCIDRListQSort(&de_ctx->io_ctx.ip_dst);
35,438✔
1151

1152
    SCRadix4Node *node4 = NULL;
35,438✔
1153
    SCRadix6Node *node6 = NULL;
35,438✔
1154

1155
    /* Prepare Src radix trees */
1156
    for (IPOnlyCIDRItem *src = de_ctx->io_ctx.ip_src; src != NULL;) {
52,722✔
1157
        if (src->family == AF_INET) {
17,284✔
1158
        /*
1159
            SCLogDebug("To IPv4");
1160
            SCLogDebug("Item has netmask %"PRIu16" negated: %s; IP: %s; "
1161
                       "signum: %"PRIu16, src->netmask,
1162
                        (src->negated) ? "yes":"no",
1163
                        inet_ntoa( *(struct in_addr*)&src->ip[0]),
1164
                        src->signum);
1165
        */
1166

1167
            void *user_data = NULL;
7,542✔
1168
            if (src->netmask == 32)
7,542✔
1169
                (void)SCRadix4TreeFindExactMatch(
569✔
1170
                        &de_ctx->io_ctx.tree_ipv4src, (uint8_t *)&src->ip[0], &user_data);
569✔
1171
            else
6,973✔
1172
                (void)SCRadix4TreeFindNetblock(&de_ctx->io_ctx.tree_ipv4src, (uint8_t *)&src->ip[0],
6,973✔
1173
                        src->netmask, &user_data);
6,973✔
1174
            if (user_data == NULL) {
7,542✔
1175
                SCLogDebug("Exact match not found");
4,909✔
1176

1177
                /** Not found, look if there's a subnet of this range with
1178
                 * bigger netmask */
1179
                (void)SCRadix4TreeFindBestMatch(
4,909✔
1180
                        &de_ctx->io_ctx.tree_ipv4src, (uint8_t *)&src->ip[0], &user_data);
4,909✔
1181
                if (user_data == NULL) {
4,909✔
1182
                    SCLogDebug("best match not found");
3,669✔
1183

1184
                    /* Not found, insert a new one */
1185
                    SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
3,669✔
1186
                    IPOnlyPrepareUpdateBitarray(src, sna);
3,669✔
1187

1188
                    if (src->netmask == 32)
3,669✔
1189
                        node4 = SCRadix4AddKeyIPV4(&de_ctx->io_ctx.tree_ipv4src,
107✔
1190
                                &iponly_radix4_config, (uint8_t *)&src->ip[0], sna);
107✔
1191
                    else
3,562✔
1192
                        node4 = SCRadix4AddKeyIPV4Netblock(&de_ctx->io_ctx.tree_ipv4src,
3,562✔
1193
                                &iponly_radix4_config, (uint8_t *)&src->ip[0], src->netmask, sna);
3,562✔
1194
                    if (node4 == NULL)
3,669✔
1195
                        SCLogError("Error inserting in the "
×
1196
                                   "src ipv4 radix tree");
3,669✔
1197
                } else {
3,669✔
1198
                    SCLogDebug("Best match found");
1,240✔
1199

1200
                    /* Found, copy the sig num table, add this signum and insert */
1201
                    SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
1,240✔
1202
                    IPOnlyPrepareUpdateBitarray(src, sna);
1,240✔
1203

1204
                    if (src->netmask == 32)
1,240✔
1205
                        node4 = SCRadix4AddKeyIPV4(&de_ctx->io_ctx.tree_ipv4src,
255✔
1206
                                &iponly_radix4_config, (uint8_t *)&src->ip[0], sna);
255✔
1207
                    else
985✔
1208
                        node4 = SCRadix4AddKeyIPV4Netblock(&de_ctx->io_ctx.tree_ipv4src,
985✔
1209
                                &iponly_radix4_config, (uint8_t *)&src->ip[0], src->netmask, sna);
985✔
1210
                    if (node4 == NULL) {
1,240✔
1211
                        char tmpstr[64];
×
1212
                        PrintInet(src->family, &src->ip[0], tmpstr, sizeof(tmpstr));
×
1213
                        SCLogError("Error inserting in the"
×
1214
                                   " src ipv4 radix tree ip %s netmask %" PRIu8,
×
1215
                                tmpstr, src->netmask);
×
1216
                        exit(-1);
×
1217
                    }
×
1218
                }
1,240✔
1219
            } else {
4,909✔
1220
                SCLogDebug("Exact match found");
2,633✔
1221

1222
                /* it's already inserted. Update it */
1223
                SigNumArray *sna = (SigNumArray *)user_data;
2,633✔
1224
                IPOnlyPrepareUpdateBitarray(src, sna);
2,633✔
1225
            }
2,633✔
1226
        } else if (src->family == AF_INET6) {
9,742✔
1227
            SCLogDebug("To IPv6");
9,742✔
1228

1229
            void *user_data = NULL;
9,742✔
1230
            if (src->netmask == 128)
9,742✔
1231
                (void)SCRadix6TreeFindExactMatch(
3,905✔
1232
                        &de_ctx->io_ctx.tree_ipv6src, (uint8_t *)&src->ip[0], &user_data);
3,905✔
1233
            else
5,837✔
1234
                (void)SCRadix6TreeFindNetblock(&de_ctx->io_ctx.tree_ipv6src, (uint8_t *)&src->ip[0],
5,837✔
1235
                        src->netmask, &user_data);
5,837✔
1236
            if (user_data == NULL) {
9,742✔
1237
                /* Not found, look if there's a subnet of this range with bigger netmask */
1238
                (void)SCRadix6TreeFindBestMatch(
5,394✔
1239
                        &de_ctx->io_ctx.tree_ipv6src, (uint8_t *)&src->ip[0], &user_data);
5,394✔
1240
                if (user_data == NULL) {
5,394✔
1241
                    /* Not found, insert a new one */
1242
                    SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
2,613✔
1243
                    IPOnlyPrepareUpdateBitarray(src, sna);
2,613✔
1244

1245
                    if (src->netmask == 128)
2,613✔
1246
                        node6 = SCRadix6AddKeyIPV6(&de_ctx->io_ctx.tree_ipv6src,
90✔
1247
                                &iponly_radix6_config, (uint8_t *)&src->ip[0], sna);
90✔
1248
                    else
2,523✔
1249
                        node6 = SCRadix6AddKeyIPV6Netblock(&de_ctx->io_ctx.tree_ipv6src,
2,523✔
1250
                                &iponly_radix6_config, (uint8_t *)&src->ip[0], src->netmask, sna);
2,523✔
1251
                    if (node6 == NULL)
2,613✔
1252
                        SCLogError("Error inserting in the src "
×
1253
                                   "ipv6 radix tree");
2,613✔
1254
                } else {
2,781✔
1255
                    /* Found, copy the sig num table, add this signum and insert */
1256
                    SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
2,781✔
1257
                    IPOnlyPrepareUpdateBitarray(src, sna);
2,781✔
1258

1259
                    if (src->netmask == 128)
2,781✔
1260
                        node6 = SCRadix6AddKeyIPV6(&de_ctx->io_ctx.tree_ipv6src,
2,344✔
1261
                                &iponly_radix6_config, (uint8_t *)&src->ip[0], sna);
2,344✔
1262
                    else
437✔
1263
                        node6 = SCRadix6AddKeyIPV6Netblock(&de_ctx->io_ctx.tree_ipv6src,
437✔
1264
                                &iponly_radix6_config, (uint8_t *)&src->ip[0], src->netmask, sna);
437✔
1265
                    if (node6 == NULL)
2,781✔
1266
                        SCLogError("Error inserting in the src "
×
1267
                                   "ipv6 radix tree");
2,781✔
1268
                }
2,781✔
1269
            } else {
5,394✔
1270
                /* it's already inserted. Update it */
1271
                SigNumArray *sna = (SigNumArray *)user_data;
4,348✔
1272
                IPOnlyPrepareUpdateBitarray(src, sna);
4,348✔
1273
            }
4,348✔
1274
        }
9,742✔
1275
        IPOnlyCIDRItem *tmpaux = src;
17,284✔
1276
        src = src->next;
17,284✔
1277
        SCFree(tmpaux);
17,284✔
1278
    }
17,284✔
1279

1280
    SCLogDebug("dsts:");
35,438✔
1281

1282
    /* Prepare Dst radix trees */
1283
    for (IPOnlyCIDRItem *dst = de_ctx->io_ctx.ip_dst; dst != NULL;) {
55,454✔
1284
        if (dst->family == AF_INET) {
20,016✔
1285
            SCLogDebug("To IPv4");
9,017✔
1286
            SCLogDebug("Item has netmask %"PRIu8" negated: %s; IP: %s; signum:"
9,017✔
1287
                       " %"PRIu32"", dst->netmask, (dst->negated)?"yes":"no",
9,017✔
1288
                       inet_ntoa(*(struct in_addr*)&dst->ip[0]), dst->signum);
9,017✔
1289

1290
            void *user_data = NULL;
9,017✔
1291
            if (dst->netmask == 32)
9,017✔
1292
                (void)SCRadix4TreeFindExactMatch(
1,580✔
1293
                        &de_ctx->io_ctx.tree_ipv4dst, (uint8_t *)&dst->ip[0], &user_data);
1,580✔
1294
            else
7,437✔
1295
                (void)SCRadix4TreeFindNetblock(&de_ctx->io_ctx.tree_ipv4dst, (uint8_t *)&dst->ip[0],
7,437✔
1296
                        dst->netmask, &user_data);
7,437✔
1297
            if (user_data == NULL) {
9,017✔
1298
                SCLogDebug("Exact match not found");
6,044✔
1299

1300
                /**
1301
                 * Not found, look if there's a subnet of this range
1302
                 * with bigger netmask
1303
                 */
1304
                (void)SCRadix4TreeFindBestMatch(
6,044✔
1305
                        &de_ctx->io_ctx.tree_ipv4dst, (uint8_t *)&dst->ip[0], &user_data);
6,044✔
1306
                if (user_data == NULL) {
6,044✔
1307
                    SCLogDebug("Best match not found");
4,172✔
1308

1309
                    /** Not found, insert a new one */
1310
                    SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
4,172✔
1311
                    IPOnlyPrepareUpdateBitarray(dst, sna);
4,172✔
1312

1313
                    if (dst->netmask == 32)
4,172✔
1314
                        node4 = SCRadix4AddKeyIPV4(&de_ctx->io_ctx.tree_ipv4dst,
506✔
1315
                                &iponly_radix4_config, (uint8_t *)&dst->ip[0], sna);
506✔
1316
                    else
3,666✔
1317
                        node4 = SCRadix4AddKeyIPV4Netblock(&de_ctx->io_ctx.tree_ipv4dst,
3,666✔
1318
                                &iponly_radix4_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
3,666✔
1319
                    if (node4 == NULL)
4,172✔
1320
                        SCLogError("Error inserting in the dst "
×
1321
                                   "ipv4 radix tree");
4,172✔
1322
                } else {
4,172✔
1323
                    SCLogDebug("Best match found");
1,872✔
1324

1325
                    /* Found, copy the sig num table, add this signum and insert */
1326
                    SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
1,872✔
1327
                    IPOnlyPrepareUpdateBitarray(dst, sna);
1,872✔
1328

1329
                    if (dst->netmask == 32)
1,872✔
1330
                        node4 = SCRadix4AddKeyIPV4(&de_ctx->io_ctx.tree_ipv4dst,
720✔
1331
                                &iponly_radix4_config, (uint8_t *)&dst->ip[0], sna);
720✔
1332
                    else
1,152✔
1333
                        node4 = SCRadix4AddKeyIPV4Netblock(&de_ctx->io_ctx.tree_ipv4dst,
1,152✔
1334
                                &iponly_radix4_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
1,152✔
1335

1336
                    if (node4 == NULL)
1,872✔
1337
                        SCLogError("Error inserting in the dst "
×
1338
                                   "ipv4 radix tree");
1,872✔
1339
                }
1,872✔
1340
            } else {
6,044✔
1341
                SCLogDebug("Exact match found");
2,973✔
1342

1343
                /* it's already inserted. Update it */
1344
                SigNumArray *sna = (SigNumArray *)user_data;
2,973✔
1345
                IPOnlyPrepareUpdateBitarray(dst, sna);
2,973✔
1346
            }
2,973✔
1347
        } else if (dst->family == AF_INET6) {
10,999✔
1348
            SCLogDebug("To IPv6");
10,999✔
1349

1350
            void *user_data = NULL;
10,999✔
1351
            if (dst->netmask == 128)
10,999✔
1352
                (void)SCRadix6TreeFindExactMatch(
4,720✔
1353
                        &de_ctx->io_ctx.tree_ipv6dst, (uint8_t *)&dst->ip[0], &user_data);
4,720✔
1354
            else
6,279✔
1355
                (void)SCRadix6TreeFindNetblock(&de_ctx->io_ctx.tree_ipv6dst, (uint8_t *)&dst->ip[0],
6,279✔
1356
                        dst->netmask, &user_data);
6,279✔
1357
            if (user_data == NULL) {
10,999✔
1358
                /** Not found, look if there's a subnet of this range with
1359
                 * bigger netmask
1360
                 */
1361
                (void)SCRadix6TreeFindBestMatch(
5,669✔
1362
                        &de_ctx->io_ctx.tree_ipv6dst, (uint8_t *)&dst->ip[0], &user_data);
5,669✔
1363
                if (user_data == NULL) {
5,669✔
1364
                    /* Not found, insert a new one */
1365
                    SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
2,730✔
1366
                    IPOnlyPrepareUpdateBitarray(dst, sna);
2,730✔
1367

1368
                    if (dst->netmask == 128)
2,730✔
1369
                        node6 = SCRadix6AddKeyIPV6(&de_ctx->io_ctx.tree_ipv6dst,
127✔
1370
                                &iponly_radix6_config, (uint8_t *)&dst->ip[0], sna);
127✔
1371
                    else
2,603✔
1372
                        node6 = SCRadix6AddKeyIPV6Netblock(&de_ctx->io_ctx.tree_ipv6dst,
2,603✔
1373
                                &iponly_radix6_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
2,603✔
1374
                    if (node6 == NULL)
2,730✔
1375
                        SCLogError("Error inserting in the dst "
×
1376
                                   "ipv6 radix tree");
2,730✔
1377
                } else {
2,939✔
1378
                    /* Found, copy the sig num table, add this signum and insert */
1379
                    SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
2,939✔
1380
                    IPOnlyPrepareUpdateBitarray(dst, sna);
2,939✔
1381

1382
                    if (dst->netmask == 128)
2,939✔
1383
                        node6 = SCRadix6AddKeyIPV6(&de_ctx->io_ctx.tree_ipv6dst,
2,493✔
1384
                                &iponly_radix6_config, (uint8_t *)&dst->ip[0], sna);
2,493✔
1385
                    else
446✔
1386
                        node6 = SCRadix6AddKeyIPV6Netblock(&de_ctx->io_ctx.tree_ipv6dst,
446✔
1387
                                &iponly_radix6_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
446✔
1388
                    if (node6 == NULL)
2,939✔
1389
                        SCLogError("Error inserting in the dst "
×
1390
                                   "ipv6 radix tree");
2,939✔
1391
                }
2,939✔
1392
            } else {
5,669✔
1393
                /* it's already inserted. Update it */
1394
                SigNumArray *sna = (SigNumArray *)user_data;
5,330✔
1395
                IPOnlyPrepareUpdateBitarray(dst, sna);
5,330✔
1396
            }
5,330✔
1397
        }
10,999✔
1398
        IPOnlyCIDRItem *tmpaux = dst;
20,016✔
1399
        dst = dst->next;
20,016✔
1400
        SCFree(tmpaux);
20,016✔
1401
    }
20,016✔
1402
}
35,438✔
1403

1404
/**
1405
 * \brief Add a signature to the lists of Addresses in CIDR format (sorted)
1406
 *        this step is necessary to build the radix tree with a hierarchical
1407
 *        relation between nodes
1408
 * \param de_ctx Pointer to the current detection engine context
1409
 * \param de_ctx Pointer to the current ip only detection engine contest
1410
 * \param s Pointer to the current signature
1411
 */
1412
void IPOnlyAddSignature(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx,
1413
                        Signature *s)
1414
{
5,651✔
1415
    if (!(s->type == SIG_TYPE_IPONLY))
5,651✔
1416
        return;
×
1417

1418
    SigIntId mapped_signum = IPOnlyTrackSigNum(io_ctx, s->iid);
5,651✔
1419
    SCLogDebug("Adding IPs from rule: %" PRIu32 " (%s) as %" PRIu32 " mapped to %" PRIu32 "\n",
5,651✔
1420
            s->id, s->msg, s->iid, mapped_signum);
5,651✔
1421
    /* Set the internal signum to the list before merging */
1422
    IPOnlyCIDRListSetSigNum(s->init_data->cidr_src, mapped_signum);
5,651✔
1423

1424
    IPOnlyCIDRListSetSigNum(s->init_data->cidr_dst, mapped_signum);
5,651✔
1425

1426
    /**
1427
     * ipv4 and ipv6 are mixed, but later we will separate them into
1428
     * different trees
1429
     */
1430
    io_ctx->ip_src = IPOnlyCIDRItemInsert(io_ctx->ip_src, s->init_data->cidr_src);
5,651✔
1431
    io_ctx->ip_dst = IPOnlyCIDRItemInsert(io_ctx->ip_dst, s->init_data->cidr_dst);
5,651✔
1432

1433
    if (mapped_signum > io_ctx->max_idx)
5,651✔
1434
        io_ctx->max_idx = mapped_signum;
2,695✔
1435

1436
    /** no longer ref to this, it's in the table now */
1437
    s->init_data->cidr_src = NULL;
5,651✔
1438
    s->init_data->cidr_dst = NULL;
5,651✔
1439
}
5,651✔
1440

1441
#ifdef UNITTESTS
1442
/**
1443
 * \test check that we set a Signature as IPOnly because it has no rule
1444
 *       option appending a SigMatch and no port is fixed
1445
 */
1446

1447
static int IPOnlyTestSig01(void)
1448
{
1449
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1450
    FAIL_IF(de_ctx == NULL);
1451
    de_ctx->flags |= DE_QUIET;
1452

1453
    Signature *s = SigInit(de_ctx,"alert tcp any any -> any any (sid:400001; rev:1;)");
1454
    FAIL_IF(s == NULL);
1455

1456
    FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
1457
    SigFree(de_ctx, s);
1458
    DetectEngineCtxFree(de_ctx);
1459
    PASS;
1460
}
1461

1462
/**
1463
 * \test check that we don't set a Signature as IPOnly because it has no rule
1464
 *       option appending a SigMatch but a port is fixed
1465
 */
1466

1467
static int IPOnlyTestSig02 (void)
1468
{
1469
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1470
    FAIL_IF(de_ctx == NULL);
1471
    de_ctx->flags |= DE_QUIET;
1472

1473
    Signature *s = SigInit(de_ctx,"alert tcp any any -> any 80 (sid:400001; rev:1;)");
1474
    FAIL_IF(s == NULL);
1475

1476
    FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
1477
    SigFree(de_ctx, s);
1478
    DetectEngineCtxFree(de_ctx);
1479
    PASS;
1480
}
1481

1482
/**
1483
 * \test check that we set don't set a Signature as IPOnly
1484
 *  because it has rule options appending a SigMatch like content, and pcre
1485
 */
1486

1487
static int IPOnlyTestSig03 (void)
1488
{
1489
    int result = 1;
1490
    DetectEngineCtx *de_ctx;
1491
    Signature *s=NULL;
1492

1493
    de_ctx = DetectEngineCtxInit();
1494
    if (de_ctx == NULL)
1495
        goto end;
1496
    de_ctx->flags |= DE_QUIET;
1497

1498
    /* combination of pcre and content */
1499
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pcre and content) \"; content:\"php\"; pcre:\"/require(_once)?/i\"; classtype:misc-activity; sid:400001; rev:1;)");
1500
    if (s == NULL) {
1501
        goto end;
1502
    }
1503
    if(SignatureIsIPOnly(de_ctx, s))
1504
    {
1505
        printf("got a IPOnly signature (content): ");
1506
        result=0;
1507
    }
1508
    SigFree(de_ctx, s);
1509

1510
    /* content */
1511
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (content) \"; content:\"match something\"; classtype:misc-activity; sid:400001; rev:1;)");
1512
    if (s == NULL) {
1513
        goto end;
1514
    }
1515
    if(SignatureIsIPOnly(de_ctx, s))
1516
    {
1517
        printf("got a IPOnly signature (content): ");
1518
        result=0;
1519
    }
1520
    SigFree(de_ctx, s);
1521

1522
    /* uricontent */
1523
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (uricontent) \"; uricontent:\"match something\"; classtype:misc-activity; sid:400001; rev:1;)");
1524
    if (s == NULL) {
1525
        goto end;
1526
    }
1527
    if(SignatureIsIPOnly(de_ctx, s))
1528
    {
1529
        printf("got a IPOnly signature (uricontent): ");
1530
        result=0;
1531
    }
1532
    SigFree(de_ctx, s);
1533

1534
    /* pcre */
1535
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pcre) \"; pcre:\"/e?idps rule[sz]/i\"; classtype:misc-activity; sid:400001; rev:1;)");
1536
    if (s == NULL) {
1537
        goto end;
1538
    }
1539
    if(SignatureIsIPOnly(de_ctx, s))
1540
    {
1541
        printf("got a IPOnly signature (pcre): ");
1542
        result=0;
1543
    }
1544
    SigFree(de_ctx, s);
1545

1546
    /* flow */
1547
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flow) \"; flow:to_server; classtype:misc-activity; sid:400001; rev:1;)");
1548
    if (s == NULL) {
1549
        goto end;
1550
    }
1551
    if(SignatureIsIPOnly(de_ctx, s))
1552
    {
1553
        printf("got a IPOnly signature (flow): ");
1554
        result=0;
1555
    }
1556
    SigFree(de_ctx, s);
1557

1558
    /* dsize */
1559
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (dsize) \"; dsize:100; classtype:misc-activity; sid:400001; rev:1;)");
1560
    if (s == NULL) {
1561
        goto end;
1562
    }
1563
    if(SignatureIsIPOnly(de_ctx, s))
1564
    {
1565
        printf("got a IPOnly signature (dsize): ");
1566
        result=0;
1567
    }
1568
    SigFree(de_ctx, s);
1569

1570
    /* flowbits */
1571
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flowbits) \"; flowbits:unset; classtype:misc-activity; sid:400001; rev:1;)");
1572
    if (s == NULL) {
1573
        goto end;
1574
    }
1575
    if(SignatureIsIPOnly(de_ctx, s))
1576
    {
1577
        printf("got a IPOnly signature (flowbits): ");
1578
        result=0;
1579
    }
1580
    SigFree(de_ctx, s);
1581

1582
    /* flowvar */
1583
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flowvar) \"; pcre:\"/(?<flow_var>.*)/i\"; flowvar:var,\"str\"; classtype:misc-activity; sid:400001; rev:1;)");
1584
    if (s == NULL) {
1585
        goto end;
1586
    }
1587
    if(SignatureIsIPOnly(de_ctx, s))
1588
    {
1589
        printf("got a IPOnly signature (flowvar): ");
1590
        result=0;
1591
    }
1592
    SigFree(de_ctx, s);
1593

1594
    /* pktvar */
1595
    s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pktvar) \"; pcre:\"/(?<pkt_var>.*)/i\"; pktvar:var,\"str\"; classtype:misc-activity; sid:400001; rev:1;)");
1596
    if (s == NULL) {
1597
        goto end;
1598
    }
1599
    if(SignatureIsIPOnly(de_ctx, s))
1600
    {
1601
        printf("got a IPOnly signature (pktvar): ");
1602
        result=0;
1603
    }
1604
    SigFree(de_ctx, s);
1605

1606
end:
1607
    if (de_ctx != NULL)
1608
        DetectEngineCtxFree(de_ctx);
1609
    return result;
1610
}
1611

1612
/**
1613
 * \test
1614
 */
1615
static int IPOnlyTestSig04 (void)
1616
{
1617
    int result = 1;
1618
    IPOnlyCIDRItem *head = NULL;
1619

1620
    // Test a linked list of size 0, 1, 2, ..., 5
1621
    for (int size = 0; size < 6; size++) {
1622
        IPOnlyCIDRItem *new = NULL;
1623

1624
        if (size > 0) {
1625
            new = IPOnlyCIDRItemNew();
1626
            new->netmask = 10;
1627
            new->ip[0] = 3;
1628

1629
            head = IPOnlyCIDRItemInsert(head, new);
1630
        }
1631

1632
        if (size > 1) {
1633
            new = IPOnlyCIDRItemNew();
1634
            new->netmask = 11;
1635

1636
            head = IPOnlyCIDRItemInsert(head, new);
1637
        }
1638

1639
        if (size > 2) {
1640
            new = IPOnlyCIDRItemNew();
1641
            new->netmask = 9;
1642

1643
            head = IPOnlyCIDRItemInsert(head, new);
1644
        }
1645

1646
        if (size > 3) {
1647
            new = IPOnlyCIDRItemNew();
1648
            new->netmask = 10;
1649
            new->ip[0] = 1;
1650

1651
            head = IPOnlyCIDRItemInsert(head, new);
1652
        }
1653

1654
        if (size > 4) {
1655
            new = IPOnlyCIDRItemNew();
1656
            new->netmask = 10;
1657
            new->ip[0] = 2;
1658

1659
            head = IPOnlyCIDRItemInsert(head, new);
1660
        }
1661

1662
        IPOnlyCIDRListPrint(head);
1663

1664
        IPOnlyCIDRListQSort(&head);
1665

1666
        if (size == 0) {
1667
            if (head != NULL) {
1668
                result = 0;
1669
                goto end;
1670
            }
1671
        }
1672

1673
        /**
1674
         * Validate the following list entries for each size
1675
         * 1 - 10
1676
         * 2 - 10<3> 11
1677
         * 3 - 9     10<3> 11
1678
         * 4 - 9     10<1> 10<3> 11
1679
         * 5 - 9     10<1> 10<2> 10<3> 11
1680
         */
1681
        new = head;
1682
        if (size >= 3) {
1683
            if (new->netmask != 9) {
1684
                result = 0;
1685
                goto end;
1686
            }
1687
            new = new->next;
1688
        }
1689

1690
        if (size >= 4) {
1691
            if (new->netmask != 10 || new->ip[0] != 1) {
1692
                result = 0;
1693
                goto end;
1694
            }
1695
            new = new->next;
1696
        }
1697

1698
        if (size >= 5) {
1699
            if (new->netmask != 10 || new->ip[0] != 2) {
1700
                result = 0;
1701
                goto end;
1702
            }
1703
            new = new->next;
1704
        }
1705

1706
        if (size >= 1) {
1707
            if (new->netmask != 10 || new->ip[0] != 3) {
1708
                result = 0;
1709
                goto end;
1710
            }
1711
            new = new->next;
1712
        }
1713

1714
        if (size >= 2) {
1715
            if (new->netmask != 11) {
1716
                result = 0;
1717
                goto end;
1718
            }
1719
            new = new->next;
1720
        }
1721

1722
        if (new != NULL) {
1723
            result = 0;
1724
            goto end;
1725
        }
1726

1727
        IPOnlyCIDRListFree(head);
1728
        head = NULL;
1729
    }
1730

1731
end:
1732
    if (head) {
1733
        IPOnlyCIDRListFree(head);
1734
        head = NULL;
1735
    }
1736
    return result;
1737
}
1738

1739
/**
1740
 * \test Test a set of ip only signatures making use a lot of
1741
 * addresses for src and dst (all should match)
1742
 */
1743
static int IPOnlyTestSig05(void)
1744
{
1745
    int result = 0;
1746
    uint8_t *buf = (uint8_t *)"Hi all!";
1747
    uint16_t buflen = strlen((char *)buf);
1748

1749
    uint8_t numpkts = 1;
1750
    uint8_t numsigs = 7;
1751

1752
    Packet *p[1];
1753

1754
    p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1755

1756
    const char *sigs[numsigs];
1757
    sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1758
    sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1759
    sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1760
    sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1761
    sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1762
    sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1763
    sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1764

1765
    /* Sid numbers (we could extract them from the sig) */
1766
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1767
    uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1768

1769
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1770

1771
    UTHFreePackets(p, numpkts);
1772

1773
    return result;
1774
}
1775

1776
/**
1777
 * \test Test a set of ip only signatures making use a lot of
1778
 * addresses for src and dst (none should match)
1779
 */
1780
static int IPOnlyTestSig06(void)
1781
{
1782
    int result = 0;
1783
    uint8_t *buf = (uint8_t *)"Hi all!";
1784
    uint16_t buflen = strlen((char *)buf);
1785

1786
    uint8_t numpkts = 1;
1787
    uint8_t numsigs = 7;
1788

1789
    Packet *p[1];
1790

1791
    p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "80.58.0.33", "195.235.113.3");
1792

1793
    const char *sigs[numsigs];
1794
    sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1795
    sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1796
    sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1797
    sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1798
    sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1799
    sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1800
    sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1801

1802
    /* Sid numbers (we could extract them from the sig) */
1803
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1804
    uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1805

1806
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1807

1808
    UTHFreePackets(p, numpkts);
1809

1810
    return result;
1811
}
1812

1813
/* \todo fix it.  We have disabled this unittest because 599 exposes 608,
1814
 * which is why these unittests fail.  When we fix 608, we need to renable
1815
 * these sigs */
1816
#if 0
1817
/**
1818
 * \test Test a set of ip only signatures making use a lot of
1819
 * addresses for src and dst (all should match)
1820
 */
1821
static int IPOnlyTestSig07(void)
1822
{
1823
    int result = 0;
1824
    uint8_t *buf = (uint8_t *)"Hi all!";
1825
    uint16_t buflen = strlen((char *)buf);
1826

1827
    uint8_t numpkts = 1;
1828
    uint8_t numsigs = 7;
1829

1830
    Packet *p[1];
1831

1832
    p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1833

1834
    char *sigs[numsigs];
1835
    sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1836
    sigs[1]= "alert tcp [192.168.1.2,192.168.1.5,192.168.1.4] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
1837
    sigs[2]= "alert tcp [192.168.1.0/24,!192.168.1.1] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1838
    sigs[3]= "alert tcp [192.0.0.0/8,!192.168.0.0/16,192.168.1.0/24,!192.168.1.1] any -> [192.168.1.0/24,!192.168.1.5] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1839
    sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1840
    sigs[5]= "alert tcp any any -> [192.168.0.0/16,!192.168.1.0/24,192.168.1.1] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1841
    sigs[6]= "alert tcp [78.129.202.0/24,192.168.1.5,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> 192.168.1.1 any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
1842

1843
    /* Sid numbers (we could extract them from the sig) */
1844
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1845
    uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1846

1847
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1848

1849
    UTHFreePackets(p, numpkts);
1850

1851
    return result;
1852
}
1853
#endif
1854

1855
/**
1856
 * \test Test a set of ip only signatures making use a lot of
1857
 * addresses for src and dst (none should match)
1858
 */
1859
static int IPOnlyTestSig08(void)
1860
{
1861
    int result = 0;
1862
    uint8_t *buf = (uint8_t *)"Hi all!";
1863
    uint16_t buflen = strlen((char *)buf);
1864

1865
    uint8_t numpkts = 1;
1866
    uint8_t numsigs = 7;
1867

1868
    Packet *p[1];
1869

1870
    p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5");
1871

1872
    const char *sigs[numsigs];
1873
    sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1874
    sigs[1]= "alert tcp [192.168.1.2,192.168.1.5,192.168.1.4] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
1875
    sigs[2]= "alert tcp [192.168.1.0/24,!192.168.1.1] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1876
    sigs[3]= "alert tcp [192.0.0.0/8,!192.168.0.0/16,192.168.1.0/24,!192.168.1.1] any -> [192.168.1.0/24,!192.168.1.5] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1877
    sigs[4]= "alert tcp any any -> !192.168.1.5 any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1878
    sigs[5]= "alert tcp any any -> [192.168.0.0/16,!192.168.1.0/24,192.168.1.1] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1879
    sigs[6]= "alert tcp [78.129.202.0/24,192.168.1.5,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> 192.168.1.1 any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
1880

1881
    /* Sid numbers (we could extract them from the sig) */
1882
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1883
    uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1884

1885
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1886

1887
    UTHFreePackets(p, numpkts);
1888

1889
    return result;
1890
}
1891

1892
/**
1893
 * \test Test a set of ip only signatures making use a lot of
1894
 * addresses for src and dst (all should match)
1895
 */
1896
static int IPOnlyTestSig09(void)
1897
{
1898
    int result = 0;
1899
    uint8_t *buf = (uint8_t *)"Hi all!";
1900
    uint16_t buflen = strlen((char *)buf);
1901

1902
    uint8_t numpkts = 1;
1903
    uint8_t numsigs = 7;
1904

1905
    Packet *p[1];
1906

1907
    p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562");
1908

1909
    const char *sigs[numsigs];
1910
    sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1911
    sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1912
    sigs[2]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1913
    sigs[3]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:0/96 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1914
    sigs[4]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1915
    sigs[5]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1916
    sigs[6]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1917

1918
    /* Sid numbers (we could extract them from the sig) */
1919
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1920
    uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1921

1922
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1923

1924
    UTHFreePackets(p, numpkts);
1925

1926
    return result;
1927
}
1928

1929
/**
1930
 * \test Test a set of ip only signatures making use a lot of
1931
 * addresses for src and dst (none should match)
1932
 */
1933
static int IPOnlyTestSig10(void)
1934
{
1935
    int result = 0;
1936
    uint8_t *buf = (uint8_t *)"Hi all!";
1937
    uint16_t buflen = strlen((char *)buf);
1938

1939
    uint8_t numpkts = 1;
1940
    uint8_t numsigs = 7;
1941

1942
    Packet *p[1];
1943

1944
    p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565");
1945

1946
    const char *sigs[numsigs];
1947
    sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1948
    sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1949
    sigs[2]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1950
    sigs[3]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> !3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562/96 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1951
    sigs[4]= "alert tcp !3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1952
    sigs[5]= "alert tcp any any -> !3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1953
    sigs[6]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> 3FFE:FFFF:7654:FEDB:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1954

1955
    /* Sid numbers (we could extract them from the sig) */
1956
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1957
    uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1958

1959
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1960

1961
    UTHFreePackets(p, numpkts);
1962

1963
    return result;
1964
}
1965

1966
/* \todo fix it.  We have disabled this unittest because 599 exposes 608,
1967
 * which is why these unittests fail.  When we fix 608, we need to renable
1968
 * these sigs */
1969
#if 0
1970
/**
1971
 * \test Test a set of ip only signatures making use a lot of
1972
 * addresses for src and dst (all should match) with ipv4 and ipv6 mixed
1973
 */
1974
static int IPOnlyTestSig11(void)
1975
{
1976
    int result = 0;
1977
    uint8_t *buf = (uint8_t *)"Hi all!";
1978
    uint16_t buflen = strlen((char *)buf);
1979

1980
    uint8_t numpkts = 2;
1981
    uint8_t numsigs = 7;
1982

1983
    Packet *p[2];
1984

1985
    p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562");
1986
    p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5");
1987

1988
    char *sigs[numsigs];
1989
    sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.5 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1990
    sigs[1]= "alert tcp [192.168.1.1,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.4,192.168.1.5,!192.168.1.0/24] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.0/24] any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
1991
    sigs[2]= "alert tcp [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1992
    sigs[3]= "alert tcp [3FFE:FFFF:0:0:0:0:0:0/32,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.0/24,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1993
    sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1994
    sigs[5]= "alert tcp any any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1995
    sigs[6]= "alert tcp [78.129.202.0/24,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.0.0.0/8] any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
1996

1997
    /* Sid numbers (we could extract them from the sig) */
1998
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1999
    uint32_t results[2][7] = {{ 1, 1, 1, 1, 1, 1, 1}, { 1, 1, 1, 1, 1, 1, 1}};
2000

2001
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2002

2003
    UTHFreePackets(p, numpkts);
2004

2005
    return result;
2006
}
2007
#endif
2008

2009
/**
2010
 * \test Test a set of ip only signatures making use a lot of
2011
 * addresses for src and dst (none should match) with ipv4 and ipv6 mixed
2012
 */
2013
static int IPOnlyTestSig12(void)
2014
{
2015
    int result = 0;
2016
    uint8_t *buf = (uint8_t *)"Hi all!";
2017
    uint16_t buflen = strlen((char *)buf);
2018

2019
    uint8_t numpkts = 2;
2020
    uint8_t numsigs = 7;
2021

2022
    Packet *p[2];
2023

2024
    p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"3FBE:FFFF:7654:FEDA:1245:BA98:3210:4562","3FBE:FFFF:7654:FEDA:1245:BA98:3210:4565");
2025
    p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"195.85.1.1","80.198.1.5");
2026

2027
    const char *sigs[numsigs];
2028
    sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.5 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
2029
    sigs[1]= "alert tcp [192.168.1.1,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.4,192.168.1.5,!192.168.1.0/24] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.0/24] any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
2030
    sigs[2]= "alert tcp [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
2031
    sigs[3]= "alert tcp [3FFE:FFFF:0:0:0:0:0:0/32,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.0/24,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
2032
    sigs[4]= "alert tcp any any -> [!3FBE:FFFF:7654:FEDA:1245:BA98:3210:4565,!80.198.1.5] any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
2033
    sigs[5]= "alert tcp any any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
2034
    sigs[6]= "alert tcp [78.129.202.0/24,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.0.0.0/8] any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
2035

2036
    /* Sid numbers (we could extract them from the sig) */
2037
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2038
    uint32_t results[2][7] = {{ 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}};
2039

2040
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2041

2042
    UTHFreePackets(p, numpkts);
2043

2044
    return result;
2045
}
2046

2047
static int IPOnlyTestSig13(void)
2048
{
2049
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2050
    FAIL_IF(de_ctx == NULL);
2051
    de_ctx->flags |= DE_QUIET;
2052

2053
    Signature *s = SigInit(de_ctx,
2054
                           "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; "
2055
                           "flowbits:set,myflow1; sid:1; rev:1;)");
2056
    FAIL_IF(s == NULL);
2057

2058
    FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
2059
    SigFree(de_ctx, s);
2060
    DetectEngineCtxFree(de_ctx);
2061
    PASS;
2062
}
2063

2064
static int IPOnlyTestSig14(void)
2065
{
2066
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2067
    FAIL_IF(de_ctx == NULL);
2068
    de_ctx->flags |= DE_QUIET;
2069

2070
    Signature *s = SigInit(de_ctx,
2071
                           "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; "
2072
                           "flowbits:set,myflow1; flowbits:isset,myflow2; sid:1; rev:1;)");
2073
    FAIL_IF(s == NULL);
2074

2075
    FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 1);
2076
    SigFree(de_ctx, s);
2077
    DetectEngineCtxFree(de_ctx);
2078
    PASS;
2079
}
2080

2081
static int IPOnlyTestSig15(void)
2082
{
2083
    int result = 0;
2084
    uint8_t *buf = (uint8_t *)"Hi all!";
2085
    uint16_t buflen = strlen((char *)buf);
2086

2087
    uint8_t numpkts = 1;
2088
    uint8_t numsigs = 7;
2089

2090
    Packet *p[1];
2091
    Flow f;
2092
    GenericVar flowvar;
2093
    memset(&f, 0, sizeof(Flow));
2094
    memset(&flowvar, 0, sizeof(GenericVar));
2095
    FLOW_INITIALIZE(&f);
2096

2097
    p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
2098

2099
    p[0]->flow = &f;
2100
    p[0]->flow->flowvar = &flowvar;
2101
    p[0]->flags |= PKT_HAS_FLOW;
2102
    p[0]->flowflags |= (FLOW_PKT_TOSERVER | FLOW_PKT_TOSERVER_FIRST);
2103

2104
    const char *sigs[numsigs];
2105
    sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; "
2106
        "flowbits:set,one; sid:1;)";
2107
    sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; "
2108
        "flowbits:set,two; sid:2;)";
2109
    sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; "
2110
        "flowbits:set,three; sid:3;)";
2111
    sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; "
2112
        "flowbits:set,four; sid:4;)";
2113
    sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; "
2114
        "flowbits:set,five; sid:5;)";
2115
    sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; "
2116
        "flowbits:set,six; sid:6;)";
2117
    sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; "
2118
        "flowbits:set,seven; content:\"Hi all\"; sid:7;)";
2119

2120
    /* Sid numbers (we could extract them from the sig) */
2121
    uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2122
    uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
2123

2124
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2125

2126
    UTHFreePackets(p, numpkts);
2127

2128
    FLOW_DESTROY(&f);
2129
    return result;
2130
}
2131

2132
/**
2133
 * \brief Unittest to show #599.  We fail to match if we have negated addresses.
2134
 */
2135
static int IPOnlyTestSig16(void)
2136
{
2137
    int result = 0;
2138
    uint8_t *buf = (uint8_t *)"Hi all!";
2139
    uint16_t buflen = strlen((char *)buf);
2140

2141
    uint8_t numpkts = 1;
2142
    uint8_t numsigs = 2;
2143

2144
    Packet *p[1];
2145

2146
    p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "100.100.0.0", "50.0.0.0");
2147

2148
    const char *sigs[numsigs];
2149
    sigs[0]= "alert tcp !100.100.0.1 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
2150
    sigs[1]= "alert tcp any any -> !50.0.0.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
2151

2152
    /* Sid numbers (we could extract them from the sig) */
2153
    uint32_t sid[2] = { 1, 2};
2154
    uint32_t results[2] = { 1, 1};
2155

2156
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2157

2158
    UTHFreePackets(p, numpkts);
2159

2160
    return result;
2161
}
2162

2163
/**
2164
 * \brief Unittest to show #611. Ports on portless protocols.
2165
 */
2166
static int IPOnlyTestSig17(void)
2167
{
2168
    int result = 0;
2169
    uint8_t *buf = (uint8_t *)"Hi all!";
2170
    uint16_t buflen = strlen((char *)buf);
2171

2172
    uint8_t numpkts = 1;
2173
    uint8_t numsigs = 2;
2174

2175
    Packet *p[1];
2176

2177
    p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_ICMP, "100.100.0.0", "50.0.0.0");
2178

2179
    const char *sigs[numsigs];
2180
    sigs[0]= "alert ip 100.100.0.0 80 -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
2181
    sigs[1]= "alert ip any any -> 50.0.0.0 123 (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
2182

2183
    uint32_t sid[2] = { 1, 2};
2184
    uint32_t results[2] = { 0, 0}; /* neither should match */
2185

2186
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2187

2188
    UTHFreePackets(p, numpkts);
2189

2190
    return result;
2191
}
2192

2193
/**
2194
 * \brief Unittest to show #3568 -- IP address range handling
2195
 */
2196
static int IPOnlyTestSig18(void)
2197
{
2198
    int result = 0;
2199
    uint8_t *buf = (uint8_t *)"Hi all!";
2200
    uint16_t buflen = strlen((char *)buf);
2201

2202
    uint8_t numpkts = 4;
2203
    uint8_t numsigs = 4;
2204

2205
    Packet *p[4];
2206

2207
    p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "10.10.10.1", "50.0.0.1");
2208
    p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "220.10.10.1", "5.0.0.1");
2209
    p[2] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "0.0.0.1", "50.0.0.1");
2210
    p[3] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "255.255.255.254", "5.0.0.1");
2211

2212
    const char *sigs[numsigs];
2213
    // really many IP addresses
2214
    sigs[0]= "alert ip 1.2.3.4-219.6.7.8 any -> any any (sid:1;)";
2215
    sigs[1]= "alert ip 51.2.3.4-253.1.2.3 any -> any any (sid:2;)";
2216
    sigs[2]= "alert ip 0.0.0.0-50.0.0.2 any -> any any (sid:3;)";
2217
    sigs[3]= "alert ip 50.0.0.0-255.255.255.255 any -> any any (sid:4;)";
2218

2219
    uint32_t sid[4] = { 1, 2, 3, 4, };
2220
    uint32_t results[4][4] = {
2221
        { 1, 0, 1, 0, }, { 0, 1, 0, 1}, { 0, 0, 1, 0 }, { 0, 0, 0, 1}};
2222

2223
    result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2224

2225
    UTHFreePackets(p, numpkts);
2226

2227
    FAIL_IF(result != 1);
2228

2229
    PASS;
2230
}
2231

2232
/** \test build IP-only tree */
2233
static int IPOnlyTestBug5066v1(void)
2234
{
2235
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2236
    FAIL_IF(de_ctx == NULL);
2237
    de_ctx->flags |= DE_QUIET;
2238

2239
    Signature *s = DetectEngineAppendSig(
2240
            de_ctx, "alert ip [1.2.3.4/24,1.2.3.64/27] any -> any any (sid:1;)");
2241
    FAIL_IF_NULL(s);
2242
    s = DetectEngineAppendSig(de_ctx, "alert ip [1.2.3.4/24] any -> any any (sid:2;)");
2243
    FAIL_IF_NULL(s);
2244

2245
    SigGroupBuild(de_ctx);
2246

2247
    DetectEngineCtxFree(de_ctx);
2248
    PASS;
2249
}
2250

2251
static int IPOnlyTestBug5066v2(void)
2252
{
2253
    IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2254
    FAIL_IF_NULL(x);
2255

2256
    FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.4/24") != 0);
2257

2258
    char ip[16];
2259
    PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2260
    SCLogDebug("ip %s netmask %d", ip, x->netmask);
2261

2262
    FAIL_IF_NOT(strcmp(ip, "1.2.3.0") == 0);
2263
    FAIL_IF_NOT(x->netmask == 24);
2264

2265
    IPOnlyCIDRListFree(x);
2266
    PASS;
2267
}
2268

2269
static int IPOnlyTestBug5066v3(void)
2270
{
2271
    IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2272
    FAIL_IF_NULL(x);
2273

2274
    FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.64/26") != 0);
2275

2276
    char ip[16];
2277
    PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2278
    SCLogDebug("ip %s netmask %d", ip, x->netmask);
2279

2280
    FAIL_IF_NOT(strcmp(ip, "1.2.3.64") == 0);
2281
    FAIL_IF_NOT(x->netmask == 26);
2282

2283
    IPOnlyCIDRListFree(x);
2284
    PASS;
2285
}
2286

2287
static int IPOnlyTestBug5066v4(void)
2288
{
2289
    IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2290
    FAIL_IF_NULL(x);
2291

2292
    FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "2000::1:1/122") != 0);
2293

2294
    char ip[64];
2295
    PrintInet(AF_INET6, (const void *)&x->ip, ip, sizeof(ip));
2296
    SCLogDebug("ip %s netmask %d", ip, x->netmask);
2297

2298
    FAIL_IF_NOT(strcmp(ip, "2000:0000:0000:0000:0000:0000:0001:0000") == 0);
2299
    FAIL_IF_NOT(x->netmask == 122);
2300

2301
    IPOnlyCIDRListFree(x);
2302
    PASS;
2303
}
2304

2305
static int IPOnlyTestBug5066v5(void)
2306
{
2307
    IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2308
    FAIL_IF_NULL(x);
2309

2310
    FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "2000::1:40/122") != 0);
2311

2312
    char ip[64];
2313
    PrintInet(AF_INET6, (const void *)&x->ip, ip, sizeof(ip));
2314
    SCLogDebug("ip %s netmask %d", ip, x->netmask);
2315

2316
    FAIL_IF_NOT(strcmp(ip, "2000:0000:0000:0000:0000:0000:0001:0040") == 0);
2317
    FAIL_IF_NOT(x->netmask == 122);
2318

2319
    IPOnlyCIDRListFree(x);
2320
    PASS;
2321
}
2322

2323
static int IPOnlyTestBug5168v1(void)
2324
{
2325
    IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2326
    FAIL_IF_NULL(x);
2327

2328
    FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.64/0.0.0.0") != 0);
2329

2330
    char ip[16];
2331
    PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2332
    SCLogDebug("ip %s netmask %d", ip, x->netmask);
2333

2334
    FAIL_IF_NOT(strcmp(ip, "0.0.0.0") == 0);
2335
    FAIL_IF_NOT(x->netmask == 0);
2336

2337
    IPOnlyCIDRListFree(x);
2338
    PASS;
2339
}
2340

2341
static int IPOnlyTestBug5168v2(void)
2342
{
2343
    IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2344
    FAIL_IF_NULL(x);
2345
    FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "0.0.0.5/0.0.0.5") != -1);
2346
    IPOnlyCIDRListFree(x);
2347
    PASS;
2348
}
2349

2350
#endif /* UNITTESTS */
2351

2352
void IPOnlyRegisterTests(void)
UNCOV
2353
{
×
2354
#ifdef UNITTESTS
2355
    UtRegisterTest("IPOnlyTestSig01", IPOnlyTestSig01);
2356
    UtRegisterTest("IPOnlyTestSig02", IPOnlyTestSig02);
2357
    UtRegisterTest("IPOnlyTestSig03", IPOnlyTestSig03);
2358
    UtRegisterTest("IPOnlyTestSig04", IPOnlyTestSig04);
2359

2360
    UtRegisterTest("IPOnlyTestSig05", IPOnlyTestSig05);
2361
    UtRegisterTest("IPOnlyTestSig06", IPOnlyTestSig06);
2362
/* \todo fix it.  We have disabled this unittest because 599 exposes 608,
2363
 * which is why these unittests fail.  When we fix 608, we need to renable
2364
 * these sigs */
2365
#if 0
2366
    UtRegisterTest("IPOnlyTestSig07", IPOnlyTestSig07, 1);
2367
#endif
2368
    UtRegisterTest("IPOnlyTestSig08", IPOnlyTestSig08);
2369

2370
    UtRegisterTest("IPOnlyTestSig09", IPOnlyTestSig09);
2371
    UtRegisterTest("IPOnlyTestSig10", IPOnlyTestSig10);
2372
/* \todo fix it.  We have disabled this unittest because 599 exposes 608,
2373
 * which is why these unittests fail.  When we fix 608, we need to renable
2374
 * these sigs */
2375
#if 0
2376
    UtRegisterTest("IPOnlyTestSig11", IPOnlyTestSig11, 1);
2377
#endif
2378
    UtRegisterTest("IPOnlyTestSig12", IPOnlyTestSig12);
2379
    UtRegisterTest("IPOnlyTestSig13", IPOnlyTestSig13);
2380
    UtRegisterTest("IPOnlyTestSig14", IPOnlyTestSig14);
2381
    UtRegisterTest("IPOnlyTestSig15", IPOnlyTestSig15);
2382
    UtRegisterTest("IPOnlyTestSig16", IPOnlyTestSig16);
2383

2384
    UtRegisterTest("IPOnlyTestSig17", IPOnlyTestSig17);
2385
    UtRegisterTest("IPOnlyTestSig18", IPOnlyTestSig18);
2386

2387
    UtRegisterTest("IPOnlyTestBug5066v1", IPOnlyTestBug5066v1);
2388
    UtRegisterTest("IPOnlyTestBug5066v2", IPOnlyTestBug5066v2);
2389
    UtRegisterTest("IPOnlyTestBug5066v3", IPOnlyTestBug5066v3);
2390
    UtRegisterTest("IPOnlyTestBug5066v4", IPOnlyTestBug5066v4);
2391
    UtRegisterTest("IPOnlyTestBug5066v5", IPOnlyTestBug5066v5);
2392

2393
    UtRegisterTest("IPOnlyTestBug5168v1", IPOnlyTestBug5168v1);
2394
    UtRegisterTest("IPOnlyTestBug5168v2", IPOnlyTestBug5168v2);
2395
#endif
UNCOV
2396
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc