Coverage Report

Created: 2026-05-16 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/decode-ipv4.c
Line
Count
Source
1
/* Copyright (C) 2007-2013 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
 * \ingroup decode
20
 *
21
 * @{
22
 */
23
24
25
/**
26
 * \file
27
 *
28
 * \author Victor Julien <victor@inliniac.net>
29
 * \author Brian Rectanus <brectanu@gmail.com>
30
 *
31
 * Decode IPv4
32
 */
33
34
#include "suricata-common.h"
35
#include "decode-ipv4.h"
36
#include "decode.h"
37
#include "defrag.h"
38
#include "flow.h"
39
#include "util-print.h"
40
41
static bool g_ipv4_ipip_enabled = false;
42
static bool g_ipv4_ipip_parent_flow_enabled = false;
43
44
void DecodeIPV4IpInIpConfig(void)
45
33
{
46
33
    int enabled = 0;
47
48
33
    if (ConfGetBool("decoder.ipv4.ipip.enabled", &enabled) == 1) {
49
0
        if (enabled) {
50
0
            g_ipv4_ipip_enabled = true;
51
0
        } else {
52
0
            g_ipv4_ipip_enabled = false;
53
0
        }
54
0
        enabled = 0;
55
0
    }
56
33
    if (ConfGetBool("decoder.ipv4.ipip.track-parent-flow", &enabled) == 1) {
57
0
        if (enabled) {
58
0
            g_ipv4_ipip_parent_flow_enabled = true;
59
0
        } else {
60
0
            g_ipv4_ipip_parent_flow_enabled = false;
61
0
        }
62
0
    }
63
33
}
64
65
/* Generic validation
66
 *
67
 * [--type--][--len---]
68
 *
69
 * \todo This function needs removed in favor of specific validation.
70
 *
71
 * See: RFC 791
72
 */
73
static int IPV4OptValidateGeneric(Packet *p, const IPV4Opt *o)
74
84.4k
{
75
84.4k
    switch (o->type) {
76
        /* See: RFC 4782 */
77
5.30k
        case IPV4_OPT_QS:
78
5.30k
            if (o->len < IPV4_OPT_QS_MIN) {
79
4.07k
                ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
80
4.07k
                return -1;
81
4.07k
            }
82
1.23k
            break;
83
        /* See: RFC 1108 */
84
37.1k
        case IPV4_OPT_SEC:
85
38.6k
        case IPV4_OPT_ESEC:
86
38.6k
            if (unlikely(o->len < IPV4_OPT_SEC_MIN)) {
87
37.1k
                ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
88
37.1k
                return -1;
89
37.1k
            }
90
1.51k
            break;
91
16.3k
        case IPV4_OPT_SID:
92
16.3k
            if (o->len != IPV4_OPT_SID_LEN) {
93
15.1k
                ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
94
15.1k
                return -1;
95
15.1k
            }
96
1.22k
            break;
97
        /* See: RFC 2113 */
98
24.1k
        case IPV4_OPT_RTRALT:
99
24.1k
            if (o->len != IPV4_OPT_RTRALT_LEN) {
100
9.10k
                ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
101
9.10k
                return -1;
102
9.10k
            }
103
15.0k
            break;
104
15.0k
        default:
105
            /* Should never get here unless there is a coding error */
106
0
            ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_UNKNOWN);
107
0
            return -1;
108
84.4k
    }
109
110
19.0k
    return 0;
111
84.4k
}
112
113
/* Validate route type options
114
 *
115
 * [--type--][--len---][--ptr---][address1]...[addressN]
116
 *
117
 * See: RFC 791
118
 */
119
static int IPV4OptValidateRoute(Packet *p, const IPV4Opt *o)
120
136k
{
121
136k
    uint8_t ptr;
122
123
    /* Check length */
124
136k
    if (unlikely(o->len < IPV4_OPT_ROUTE_MIN)) {
125
115k
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
126
115k
        return -1;
127
115k
    }
128
129
    /* Data is required */
130
21.4k
    if (unlikely(o->data == NULL)) {
131
0
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
132
0
        return -1;
133
0
    }
134
21.4k
    ptr = *o->data;
135
136
    /* Address pointer is 1 based and points at least after type+len+ptr,
137
     * must be a incremented by 4 bytes (address size) and cannot extend
138
     * past option length.
139
     */
140
21.4k
    if (unlikely((ptr < 4) || (ptr % 4) || (ptr > o->len + 1))) {
141
16.0k
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
142
16.0k
        return -1;
143
16.0k
    }
144
145
5.41k
    return 0;
146
21.4k
}
147
148
/* Validate timestamp type options
149
 *
150
 * [--type--][--len---][--ptr---][ovfl][flag][rec1----...]...[recN----...]
151
 * NOTE: rec could be 4 (ts only) or 8 (ip+ts) bytes in length.
152
 *
153
 * See: RFC 781
154
 */
155
static int IPV4OptValidateTimestamp(Packet *p, const IPV4Opt *o)
156
14.5k
{
157
14.5k
    uint8_t ptr;
158
14.5k
    uint8_t flag;
159
14.5k
    uint8_t rec_size;
160
161
    /* Check length */
162
14.5k
    if (unlikely(o->len < IPV4_OPT_TS_MIN)) {
163
7.09k
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
164
7.09k
        return -1;
165
7.09k
    }
166
167
    /* Data is required */
168
7.41k
    if (unlikely(o->data == NULL)) {
169
0
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
170
0
        return -1;
171
0
    }
172
7.41k
    ptr = *o->data;
173
174
    /* We need the flag to determine what is in the option payload */
175
7.41k
    if (unlikely(ptr < 5)) {
176
2.54k
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
177
2.54k
        return -1;
178
2.54k
    }
179
4.86k
    flag = *(o->data + 1) & 0x0f;
180
181
    /* A flag of 1|3 means we have both the ip+ts in each record */
182
4.86k
    rec_size = ((flag == 1) || (flag == 3)) ? 8 : 4;
183
184
    /* Address pointer is 1 based and points at least after
185
     * type+len+ptr+ovfl+flag, must be incremented by by the rec_size
186
     * and cannot extend past option length.
187
     */
188
4.86k
    if (unlikely(((ptr - 5) % rec_size) || (ptr > o->len + 1))) {
189
3.12k
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
190
3.12k
        return -1;
191
3.12k
    }
192
193
1.74k
    return 0;
194
4.86k
}
195
196
/* Validate CIPSO option
197
 *
198
 * [--type--][--len---][--doi---][tags--...]
199
 *
200
 * See: draft-ietf-cipso-ipsecurity-01.txt
201
 * See: FIPS 188 (tags 6 & 7)
202
 */
203
static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o)
204
17.1k
{
205
//    uint32_t doi;
206
17.1k
    const uint8_t *tag;
207
17.1k
    uint16_t len;
208
209
    /* Check length */
210
17.1k
    if (unlikely(o->len < IPV4_OPT_CIPSO_MIN)) {
211
6.21k
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
212
6.21k
        return -1;
213
6.21k
    }
214
215
    /* Data is required */
216
10.9k
    if (unlikely(o->data == NULL)) {
217
0
        ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
218
0
        return -1;
219
0
    }
220
//    doi = *o->data;
221
10.9k
    tag = o->data + 4;
222
10.9k
    len = o->len - 1 - 1 - 4; /* Length of tags after header */
223
224
225
#if 0
226
    /* Domain of Interest (DOI) of 0 is reserved and thus invalid */
227
    /** \todo Apparently a DOI of zero is fine in practice - verify. */
228
    if (doi == 0) {
229
        ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
230
        return -1;
231
    }
232
#endif
233
234
    /* NOTE: We know len has passed min tests prior to this call */
235
236
    /* Check that tags are formatted correctly
237
     * [-ttype--][--tlen--][-tagdata-...]
238
     */
239
13.3k
    while (len) {
240
11.7k
        uint8_t ttype;
241
11.7k
        uint8_t tlen;
242
243
        /* Tag header must fit within option length */
244
11.7k
        if (unlikely(len < 2)) {
245
            //printf("CIPSO tag header too large %" PRIu16 " < 2\n", len);
246
173
            ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
247
173
            return -1;
248
173
        }
249
250
        /* Tag header is type+len */
251
11.5k
        ttype = *(tag++);
252
11.5k
        tlen = *(tag++);
253
254
        /* Tag length must fit within the option length */
255
11.5k
        if (unlikely(tlen > len)) {
256
            //printf("CIPSO tag len too large %" PRIu8 " > %" PRIu16 "\n", tlen, len);
257
359
            ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
258
359
            return -1;
259
359
        }
260
261
11.2k
        switch(ttype) {
262
1.63k
            case 1:
263
3.32k
            case 2:
264
4.27k
            case 5:
265
8.46k
            case 6:
266
9.14k
            case 7:
267
                /* Tag is at least 4 and at most the remainder of option len */
268
9.14k
                if (unlikely((tlen < 4) || (tlen > len))) {
269
                    //printf("CIPSO tag %" PRIu8 " bad tlen=%" PRIu8 " len=%" PRIu8 "\n", ttype, tlen, len);
270
3.77k
                    ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
271
3.77k
                    return -1;
272
3.77k
                }
273
274
                /* The alignment octet is always 0 except tag
275
                 * type 7, which has no such field.
276
                 */
277
5.36k
                if (unlikely((ttype != 7) && (*tag != 0))) {
278
                    //printf("CIPSO tag %" PRIu8 " ao=%" PRIu8 "\n", ttype, tlen);
279
2.95k
                    ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
280
2.95k
                    return -1;
281
2.95k
                }
282
283
                /* Skip the rest of the tag payload */
284
2.41k
                tag += tlen - 2;
285
2.41k
                len -= tlen;
286
287
2.41k
                continue;
288
882
            case 0:
289
                /* Tag type 0 is reserved and thus invalid */
290
                /** \todo Wireshark marks this a padding, but spec says reserved. */
291
882
                ENGINE_SET_INVALID_EVENT(p,IPV4_OPT_MALFORMED);
292
882
                return -1;
293
1.17k
            default:
294
                //printf("CIPSO tag %" PRIu8 " unknown tag\n", ttype);
295
1.17k
                ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED);
296
                /** \todo May not want to return error here on unknown tag type (at least not for 3|4) */
297
1.17k
                return -1;
298
11.2k
        }
299
11.2k
    }
300
301
1.64k
    return 0;
302
10.9k
}
303
304
typedef struct IPV4Options_ {
305
    IPV4Opt o_rr;
306
    IPV4Opt o_qs;
307
    IPV4Opt o_ts;
308
    IPV4Opt o_sec;
309
    IPV4Opt o_lsrr;
310
    IPV4Opt o_esec;
311
    IPV4Opt o_cipso;
312
    IPV4Opt o_sid;
313
    IPV4Opt o_ssrr;
314
    IPV4Opt o_rtralt;
315
} IPV4Options;
316
317
/**
318
 * Decode/Validate IPv4 Options.
319
 */
320
static int DecodeIPV4Options(Packet *p, const uint8_t *pkt, uint16_t len, IPV4Options *opts)
321
104k
{
322
104k
    uint16_t plen = len;
323
324
#ifdef DEBUG
325
    if (SCLogDebugEnabled()) {
326
        uint16_t i;
327
        char buf[256] = "";
328
        int offset = 0;
329
330
        for (i = 0; i < len; i++) {
331
            offset += snprintf(buf + offset, (sizeof(buf) - offset), "%02" PRIx8 " ", pkt[i]);
332
        }
333
        SCLogDebug("IPV4OPTS: { %s}", buf);
334
    }
335
#endif
336
337
    /* Options length must be padded to 8byte boundary */
338
104k
    if (plen % 8) {
339
69.1k
        ENGINE_SET_EVENT(p,IPV4_OPT_PAD_REQUIRED);
340
        /* Warn - we can keep going */
341
69.1k
    }
342
343
765k
    while (plen)
344
729k
    {
345
729k
        p->ip4vars.opt_cnt++;
346
347
        /* single byte options */
348
729k
        if (*pkt == IPV4_OPT_EOL) {
349
            /** \todo What if more data exist after EOL (possible covert channel or data leakage)? */
350
32.3k
            SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
351
32.3k
                   *pkt, (len - plen), (len - 1));
352
32.3k
            p->ip4vars.opts_set |= IPV4_OPT_FLAG_EOL;
353
32.3k
            break;
354
697k
        } else if (*pkt == IPV4_OPT_NOP) {
355
7.30k
            SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
356
7.30k
                   *pkt, (len - plen), (len - 1));
357
7.30k
            pkt++;
358
7.30k
            plen--;
359
360
7.30k
            p->ip4vars.opts_set |= IPV4_OPT_FLAG_NOP;
361
362
        /* multibyte options */
363
690k
        } else {
364
690k
            if (unlikely(plen < 2)) {
365
                /** \todo What if padding is non-zero (possible covert channel or data leakage)? */
366
                /** \todo Spec seems to indicate EOL required if there is padding */
367
17.6k
                ENGINE_SET_EVENT(p,IPV4_OPT_EOL_REQUIRED);
368
17.6k
                break;
369
17.6k
            }
370
371
            /* Option length is too big for packet */
372
672k
            if (unlikely(*(pkt+1) > plen)) {
373
11.2k
                ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
374
11.2k
                return -1;
375
11.2k
            }
376
377
661k
            IPV4Opt opt = {*pkt, *(pkt+1), plen > 2 ? (pkt + 2) : NULL };
378
379
            /* we already know that the total options len is valid,
380
             * so here the len of the specific option must be bad.
381
             * Also check for invalid lengths 0 and 1. */
382
661k
            if (unlikely(opt.len > plen || opt.len < 2)) {
383
7.40k
                ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
384
7.40k
                return -1;
385
7.40k
            }
386
            /* we are parsing the most commonly used opts to prevent
387
             * us from having to walk the opts list for these all the
388
             * time. */
389
            /** \todo Figure out which IP options are more common and list them first */
390
654k
            switch (opt.type) {
391
16.0k
                case IPV4_OPT_TS:
392
16.0k
                    if (opts->o_ts.type != 0) {
393
1.56k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
394
                        /* Warn - we can keep going */
395
14.5k
                    } else if (IPV4OptValidateTimestamp(p, &opt) == 0) {
396
1.74k
                        opts->o_ts = opt;
397
1.74k
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_TS;
398
1.74k
                    }
399
16.0k
                    break;
400
10.6k
                case IPV4_OPT_RR:
401
10.6k
                    if (opts->o_rr.type != 0) {
402
311
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
403
                        /* Warn - we can keep going */
404
10.3k
                    } else if (IPV4OptValidateRoute(p, &opt) == 0) {
405
798
                        opts->o_rr = opt;
406
798
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_RR;
407
798
                    }
408
10.6k
                    break;
409
8.45k
                case IPV4_OPT_QS:
410
8.45k
                    if (opts->o_qs.type != 0) {
411
3.14k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
412
                        /* Warn - we can keep going */
413
5.30k
                    } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
414
1.23k
                        opts->o_qs = opt;
415
1.23k
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_QS;
416
1.23k
                    }
417
8.45k
                    break;
418
38.6k
                case IPV4_OPT_SEC:
419
38.6k
                    if (opts->o_sec.type != 0) {
420
1.50k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
421
                        /* Warn - we can keep going */
422
37.1k
                    } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
423
738
                        opts->o_sec = opt;
424
738
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_SEC;
425
738
                    }
426
38.6k
                    break;
427
39.1k
                case IPV4_OPT_LSRR:
428
39.1k
                    if (opts->o_lsrr.type != 0) {
429
4.31k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
430
                        /* Warn - we can keep going */
431
34.8k
                    } else if (IPV4OptValidateRoute(p, &opt) == 0) {
432
2.40k
                        opts->o_lsrr = opt;
433
2.40k
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_LSRR;
434
2.40k
                    }
435
39.1k
                    break;
436
3.18k
                case IPV4_OPT_ESEC:
437
3.18k
                    if (opts->o_esec.type != 0) {
438
1.71k
                        ENGINE_SET_EVENT(p, IPV4_OPT_DUPLICATE);
439
                        /* Warn - we can keep going */
440
1.71k
                    } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
441
778
                        opts->o_esec = opt;
442
778
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_ESEC;
443
778
                    }
444
3.18k
                    break;
445
18.5k
                case IPV4_OPT_CIPSO:
446
18.5k
                    if (opts->o_cipso.type != 0) {
447
1.34k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
448
                        /* Warn - we can keep going */
449
17.1k
                    } else if (IPV4OptValidateCIPSO(p, &opt) == 0) {
450
1.64k
                        opts->o_cipso = opt;
451
1.64k
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_CIPSO;
452
1.64k
                    }
453
18.5k
                    break;
454
19.6k
                case IPV4_OPT_SID:
455
19.6k
                    if (opts->o_sid.type != 0) {
456
3.29k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
457
                        /* Warn - we can keep going */
458
16.3k
                    } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
459
1.22k
                        opts->o_sid = opt;
460
1.22k
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_SID;
461
1.22k
                    }
462
19.6k
                    break;
463
93.3k
                case IPV4_OPT_SSRR:
464
93.3k
                    if (opts->o_ssrr.type != 0) {
465
1.88k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
466
                        /* Warn - we can keep going */
467
91.4k
                    } else if (IPV4OptValidateRoute(p, &opt) == 0) {
468
2.20k
                        opts->o_ssrr = opt;
469
2.20k
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_SSRR;
470
2.20k
                    }
471
93.3k
                    break;
472
33.7k
                case IPV4_OPT_RTRALT:
473
33.7k
                    if (opts->o_rtralt.type != 0) {
474
9.60k
                        ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
475
                        /* Warn - we can keep going */
476
24.1k
                    } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
477
15.0k
                        opts->o_rtralt = opt;
478
15.0k
                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_RTRALT;
479
15.0k
                    }
480
33.7k
                    break;
481
372k
                default:
482
372k
                    SCLogDebug("IPV4OPT <unknown> (%" PRIu8 ") len %" PRIu8,
483
372k
                           opt.type, opt.len);
484
372k
                    ENGINE_SET_EVENT(p,IPV4_OPT_INVALID);
485
                    /* Warn - we can keep going */
486
372k
                    break;
487
654k
            }
488
489
654k
            pkt += opt.len;
490
654k
            plen -= opt.len;
491
654k
        }
492
729k
    }
493
494
85.8k
    return 0;
495
104k
}
496
497
static int DecodeIPV4Packet(Packet *p, const uint8_t *pkt, uint16_t len)
498
15.1M
{
499
15.1M
    if (unlikely(len < IPV4_HEADER_LEN)) {
500
49.6k
        ENGINE_SET_INVALID_EVENT(p, IPV4_PKT_TOO_SMALL);
501
49.6k
        return -1;
502
49.6k
    }
503
504
15.1M
    if (unlikely(IP_GET_RAW_VER(pkt) != 4)) {
505
63.9k
        SCLogDebug("wrong ip version %d",IP_GET_RAW_VER(pkt));
506
63.9k
        ENGINE_SET_INVALID_EVENT(p, IPV4_WRONG_IP_VER);
507
63.9k
        return -1;
508
63.9k
    }
509
510
15.0M
    p->ip4h = (IPV4Hdr *)pkt;
511
512
15.0M
    if (unlikely(IPV4_GET_HLEN(p) < IPV4_HEADER_LEN)) {
513
7.08k
        ENGINE_SET_INVALID_EVENT(p, IPV4_HLEN_TOO_SMALL);
514
7.08k
        return -1;
515
7.08k
    }
516
517
15.0M
    if (unlikely(IPV4_GET_IPLEN(p) < IPV4_GET_HLEN(p))) {
518
46.9k
        ENGINE_SET_INVALID_EVENT(p, IPV4_IPLEN_SMALLER_THAN_HLEN);
519
46.9k
        return -1;
520
46.9k
    }
521
522
14.9M
    if (unlikely(len < IPV4_GET_IPLEN(p))) {
523
576k
        ENGINE_SET_INVALID_EVENT(p, IPV4_TRUNC_PKT);
524
576k
        return -1;
525
576k
    }
526
527
    /* set the address struct */
528
14.4M
    SET_IPV4_SRC_ADDR(p,&p->src);
529
14.4M
    SET_IPV4_DST_ADDR(p,&p->dst);
530
531
    /* save the options len */
532
14.4M
    uint8_t ip_opt_len = IPV4_GET_HLEN(p) - IPV4_HEADER_LEN;
533
14.4M
    if (ip_opt_len > 0) {
534
104k
        IPV4Options opts;
535
104k
        memset(&opts, 0x00, sizeof(opts));
536
104k
        if (DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len, &opts) < 0) {
537
18.6k
            return -1;
538
18.6k
        }
539
104k
    }
540
541
14.3M
    return 0;
542
14.4M
}
543
544
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
545
        const uint8_t *pkt, uint16_t len)
546
7.42M
{
547
7.42M
    StatsIncr(tv, dtv->counter_ipv4);
548
549
7.42M
    SCLogDebug("pkt %p len %"PRIu16"", pkt, len);
550
551
7.42M
    if (!PacketIncreaseCheckLayers(p)) {
552
107
        return TM_ECODE_FAILED;
553
107
    }
554
    /* do the actual decoding */
555
7.42M
    if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) {
556
361k
        SCLogDebug("decoding IPv4 packet failed");
557
361k
        CLEAR_IPV4_PACKET((p));
558
361k
        return TM_ECODE_FAILED;
559
361k
    }
560
7.06M
    p->proto = IPV4_GET_IPPROTO(p);
561
562
    /* If a fragment, pass off for re-assembly. */
563
7.06M
    if (unlikely(IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1)) {
564
133k
        Packet *rp = Defrag(tv, dtv, p);
565
133k
        if (rp != NULL) {
566
656
            PacketEnqueueNoLock(&tv->decode_pq, rp);
567
656
        }
568
133k
        p->flags |= PKT_IS_FRAGMENT;
569
133k
        return TM_ECODE_OK;
570
133k
    }
571
572
    /* do hdr test, process hdr rules */
573
574
#ifdef DEBUG
575
    if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
576
        /* debug print */
577
        char s[16], d[16];
578
        PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), s, sizeof(s));
579
        PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), d, sizeof(d));
580
        SCLogDebug("IPV4 %s->%s PROTO: %" PRIu32 " OFFSET: %" PRIu32 " RF: %" PRIu32 " DF: %" PRIu32 " MF: %" PRIu32 " ID: %" PRIu32 "", s,d,
581
                IPV4_GET_IPPROTO(p), IPV4_GET_IPOFFSET(p), IPV4_GET_RF(p),
582
                IPV4_GET_DF(p), IPV4_GET_MF(p), IPV4_GET_IPID(p));
583
    }
584
#endif /* DEBUG */
585
586
    /* check what next decoder to invoke */
587
6.93M
    switch (IPV4_GET_IPPROTO(p)) {
588
6.62M
        case IPPROTO_TCP:
589
6.62M
            DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
590
6.62M
                      IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
591
6.62M
            break;
592
205k
        case IPPROTO_UDP:
593
205k
            DecodeUDP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
594
205k
                      IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
595
205k
            break;
596
42.6k
        case IPPROTO_ICMP:
597
42.6k
            DecodeICMPV4(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
598
42.6k
                         IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
599
42.6k
            break;
600
16.0k
        case IPPROTO_GRE:
601
16.0k
            DecodeGRE(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
602
16.0k
                      IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
603
16.0k
            break;
604
1.71k
        case IPPROTO_SCTP:
605
1.71k
            DecodeSCTP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
606
1.71k
                      IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
607
1.71k
            break;
608
609
1.48k
        case IPPROTO_ESP:
610
1.48k
            DecodeESP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
611
1.48k
            break;
612
302
        case IPPROTO_IPIP: {
613
            /* optional in Suricata 7 as it wasn't always present */
614
302
            if (g_ipv4_ipip_enabled) {
615
                /* spawn off tunnel packet */
616
0
                Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
617
0
                        IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), DECODE_TUNNEL_IPV4);
618
0
                if (tp != NULL) {
619
0
                    PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4);
620
0
                    PacketEnqueueNoLock(&tv->decode_pq, tp);
621
0
                    StatsIncr(tv, dtv->counter_ipv4inipv4);
622
0
                }
623
0
            }
624
302
            if (g_ipv4_ipip_parent_flow_enabled) {
625
0
                FlowSetupPacket(p);
626
0
            }
627
302
            break;
628
0
        }
629
934
        case IPPROTO_IPV6:
630
934
            {
631
                /* spawn off tunnel packet */
632
934
                Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
633
934
                        IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p),
634
934
                        DECODE_TUNNEL_IPV6);
635
934
                if (tp != NULL) {
636
197
                    PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4);
637
197
                    PacketEnqueueNoLock(&tv->decode_pq,tp);
638
197
                    StatsIncr(tv, dtv->counter_ipv6inipv4);
639
197
                }
640
934
                FlowSetupPacket(p);
641
934
                break;
642
0
            }
643
11.0k
        case IPPROTO_IP:
644
            /* check PPP VJ uncompressed packets and decode tcp dummy */
645
11.0k
            if (p->flags & PKT_PPP_VJ_UCOMP) {
646
206
                DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
647
206
                          IPV4_GET_IPLEN(p) -  IPV4_GET_HLEN(p));
648
206
            }
649
11.0k
            break;
650
3.37k
        case IPPROTO_ICMPV6:
651
3.37k
            ENGINE_SET_INVALID_EVENT(p, IPV4_WITH_ICMPV6);
652
3.37k
            break;
653
6.93M
    }
654
655
6.93M
    return TM_ECODE_OK;
656
6.93M
}
657
658
/* UNITTESTS */
659
#ifdef UNITTESTS
660
#include "packet.h"
661
662
/** \test IPV4 with no options. */
663
static int DecodeIPV4OptionsNONETest01(void)
664
{
665
    uint8_t raw_opts[] = { };
666
    Packet *p = PacketGetFromAlloc();
667
    FAIL_IF(unlikely(p == NULL));
668
669
    IPV4Options opts;
670
    memset(&opts, 0x00, sizeof(opts));
671
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
672
    FAIL_IF(p->flags & PKT_IS_INVALID);
673
674
    SCFree(p);
675
    PASS;
676
}
677
678
/** \test IPV4 with EOL option. */
679
static int DecodeIPV4OptionsEOLTest01(void)
680
{
681
    uint8_t raw_opts[] = {
682
        IPV4_OPT_EOL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
683
    };
684
    Packet *p = PacketGetFromAlloc();
685
    FAIL_IF(unlikely(p == NULL));
686
    IPV4Options opts;
687
    memset(&opts, 0x00, sizeof(opts));
688
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
689
    FAIL_IF(p->flags & PKT_IS_INVALID);
690
    SCFree(p);
691
    PASS;
692
}
693
694
/** \test IPV4 with NOP option. */
695
static int DecodeIPV4OptionsNOPTest01(void)
696
{
697
    uint8_t raw_opts[] = {
698
        IPV4_OPT_NOP, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
699
    };
700
    Packet *p = PacketGetFromAlloc();
701
    FAIL_IF(unlikely(p == NULL));
702
    IPV4Options opts;
703
    memset(&opts, 0x00, sizeof(opts));
704
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
705
    FAIL_IF(p->flags & PKT_IS_INVALID);
706
    SCFree(p);
707
    PASS;
708
}
709
710
/** \test IPV4 with RR option. */
711
static int DecodeIPV4OptionsRRTest01(void)
712
{
713
    uint8_t raw_opts[] = {
714
        IPV4_OPT_RR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
715
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
719
    };
720
    Packet *p = PacketGetFromAlloc();
721
    FAIL_IF(unlikely(p == NULL));
722
723
    IPV4Options opts;
724
    memset(&opts, 0x00, sizeof(opts));
725
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
726
    FAIL_IF(p->flags & PKT_IS_INVALID);
727
    FAIL_IF(opts.o_rr.type != IPV4_OPT_RR);
728
    SCFree(p);
729
    PASS;
730
}
731
732
/** \test IPV4 with RR option (len too large). */
733
static int DecodeIPV4OptionsRRTest02(void)
734
{
735
    uint8_t raw_opts[] = {
736
        IPV4_OPT_RR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
737
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
741
    };
742
    Packet *p = PacketGetFromAlloc();
743
    FAIL_IF(unlikely(p == NULL));
744
745
    IPV4Options opts;
746
    memset(&opts, 0x00, sizeof(opts));
747
    FAIL_IF(DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts) != -1);
748
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
749
    FAIL_IF(opts.o_rr.type != 0);
750
    SCFree(p);
751
    PASS;
752
}
753
754
/** \test IPV4 with RR option (ptr too large). */
755
static int DecodeIPV4OptionsRRTest03(void)
756
{
757
    uint8_t raw_opts[] = {
758
        IPV4_OPT_RR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
759
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
763
    };
764
    Packet *p = PacketGetFromAlloc();
765
    FAIL_IF(unlikely(p == NULL));
766
767
    IPV4Options opts;
768
    memset(&opts, 0x00, sizeof(opts));
769
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
770
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
771
    FAIL_IF(opts.o_rr.type != 0);
772
    SCFree(p);
773
    PASS;
774
}
775
776
/** \test IPV4 with RR option (ptr not in 4 byte increment). */
777
static int DecodeIPV4OptionsRRTest04(void)
778
{
779
    uint8_t raw_opts[] = {
780
        IPV4_OPT_RR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
781
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
785
    };
786
    Packet *p = PacketGetFromAlloc();
787
    FAIL_IF(unlikely(p == NULL));
788
789
    IPV4Options opts;
790
    memset(&opts, 0x00, sizeof(opts));
791
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
792
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
793
    FAIL_IF(opts.o_rr.type != 0);
794
    SCFree(p);
795
    PASS;
796
}
797
798
/** \test IPV4 with QS option. */
799
static int DecodeIPV4OptionsQSTest01(void)
800
{
801
    uint8_t raw_opts[] = {
802
        IPV4_OPT_QS, 0x08, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
803
    };
804
    Packet *p = PacketGetFromAlloc();
805
    FAIL_IF(unlikely(p == NULL));
806
807
    IPV4Options opts;
808
    memset(&opts, 0x00, sizeof(opts));
809
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
810
    FAIL_IF(p->flags & PKT_IS_INVALID);
811
    FAIL_IF(opts.o_qs.type != IPV4_OPT_QS);
812
    SCFree(p);
813
    PASS;
814
}
815
816
/** \test IPV4 with QS option (len too small) */
817
static int DecodeIPV4OptionsQSTest02(void)
818
{
819
    uint8_t raw_opts[] = {
820
        IPV4_OPT_QS, 0x07, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
821
    };
822
    Packet *p = PacketGetFromAlloc();
823
    FAIL_IF(unlikely(p == NULL));
824
825
    IPV4Options opts;
826
    memset(&opts, 0x00, sizeof(opts));
827
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
828
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
829
    FAIL_IF(opts.o_qs.type != 0);
830
    SCFree(p);
831
    PASS;
832
}
833
834
/** \test IPV4 with TS option. */
835
static int DecodeIPV4OptionsTSTest01(void)
836
{
837
    uint8_t raw_opts[] = {
838
        IPV4_OPT_TS, 0x24, 0x0d, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
839
        0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
840
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
842
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
843
    };
844
    Packet *p = PacketGetFromAlloc();
845
    FAIL_IF(unlikely(p == NULL));
846
847
    IPV4Options opts;
848
    memset(&opts, 0x00, sizeof(opts));
849
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
850
    FAIL_IF(p->flags & PKT_IS_INVALID);
851
    FAIL_IF(opts.o_ts.type != IPV4_OPT_TS);
852
    SCFree(p);
853
    PASS;
854
}
855
856
/** \test IPV4 with TS option (ptr too small). */
857
static int DecodeIPV4OptionsTSTest02(void)
858
{
859
    uint8_t raw_opts[] = {
860
        IPV4_OPT_TS, 0x24, 0x04, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
861
        0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
862
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
863
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
864
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
865
    };
866
    Packet *p = PacketGetFromAlloc();
867
    FAIL_IF(unlikely(p == NULL));
868
869
    IPV4Options opts;
870
    memset(&opts, 0x00, sizeof(opts));
871
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
872
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
873
    FAIL_IF(opts.o_ts.type != 0);
874
    SCFree(p);
875
    PASS;
876
}
877
878
/** \test IPV4 with TS option (ptr too large). */
879
static int DecodeIPV4OptionsTSTest03(void)
880
{
881
    uint8_t raw_opts[] = {
882
        IPV4_OPT_TS, 0x24, 0xff, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
883
        0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
884
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
886
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
887
    };
888
    Packet *p = PacketGetFromAlloc();
889
    FAIL_IF(unlikely(p == NULL));
890
891
    IPV4Options opts;
892
    memset(&opts, 0x00, sizeof(opts));
893
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
894
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
895
    FAIL_IF(opts.o_ts.type != 0);
896
    SCFree(p);
897
    PASS;
898
}
899
900
/** \test IPV4 with TS option (ptr not valid). */
901
static int DecodeIPV4OptionsTSTest04(void)
902
{
903
    uint8_t raw_opts[] = {
904
        IPV4_OPT_TS, 0x24, 0x0a, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
905
        0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
906
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
907
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
908
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
909
    };
910
    Packet *p = PacketGetFromAlloc();
911
    FAIL_IF(unlikely(p == NULL));
912
913
    IPV4Options opts;
914
    memset(&opts, 0x00, sizeof(opts));
915
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
916
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
917
    FAIL_IF(opts.o_ts.type != 0);
918
    SCFree(p);
919
    PASS;
920
}
921
922
/** \test IPV4 with SEC option. */
923
static int DecodeIPV4OptionsSECTest01(void)
924
{
925
    uint8_t raw_opts[] = {
926
        IPV4_OPT_SEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
927
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
928
    };
929
    Packet *p = PacketGetFromAlloc();
930
    FAIL_IF(unlikely(p == NULL));
931
932
    IPV4Options opts;
933
    memset(&opts, 0x00, sizeof(opts));
934
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
935
    FAIL_IF(p->flags & PKT_IS_INVALID);
936
    FAIL_IF(opts.o_sec.type != IPV4_OPT_SEC);
937
    SCFree(p);
938
    PASS;
939
}
940
941
/** \test IPV4 with SEC option (invalid length). */
942
static int DecodeIPV4OptionsSECTest02(void)
943
{
944
    uint8_t raw_opts[] = { IPV4_OPT_SEC, 0x02, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
945
        0x00, 0x00, 0x00, 0x00, 0x00 };
946
    Packet *p = PacketGetFromAlloc();
947
    FAIL_IF(unlikely(p == NULL));
948
949
    IPV4Options opts;
950
    memset(&opts, 0x00, sizeof(opts));
951
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
952
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
953
    FAIL_IF(opts.o_sec.type != 0);
954
    SCFree(p);
955
    PASS;
956
}
957
958
/** \test IPV4 with ESEC option. */
959
static int DecodeIPV4OptionsESECTest01(void)
960
{
961
    uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
962
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
963
    Packet *p = PacketGetFromAlloc();
964
    FAIL_IF(unlikely(p == NULL));
965
966
    IPV4Options opts;
967
    memset(&opts, 0x00, sizeof(opts));
968
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
969
    FAIL_IF(p->flags & PKT_IS_INVALID);
970
    FAIL_IF(opts.o_esec.type != IPV4_OPT_ESEC);
971
    SCFree(p);
972
    PASS;
973
}
974
975
/** \test IPV4 with ESEC option (invalid length). */
976
static int DecodeIPV4OptionsESECTest02(void)
977
{
978
    uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x02, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
979
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
980
    Packet *p = PacketGetFromAlloc();
981
    FAIL_IF(unlikely(p == NULL));
982
983
    IPV4Options opts;
984
    memset(&opts, 0x00, sizeof(opts));
985
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
986
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
987
    FAIL_IF(opts.o_esec.type != 0);
988
    SCFree(p);
989
    PASS;
990
}
991
992
/** \test IPV4 with LSRR option. */
993
static int DecodeIPV4OptionsLSRRTest01(void)
994
{
995
    uint8_t raw_opts[] = {
996
        IPV4_OPT_LSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
997
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
998
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
999
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1000
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1001
    };
1002
    Packet *p = PacketGetFromAlloc();
1003
    FAIL_IF(unlikely(p == NULL));
1004
1005
    IPV4Options opts;
1006
    memset(&opts, 0x00, sizeof(opts));
1007
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1008
    FAIL_IF(p->flags & PKT_IS_INVALID);
1009
    FAIL_IF(opts.o_lsrr.type != IPV4_OPT_LSRR);
1010
    SCFree(p);
1011
    PASS;
1012
}
1013
1014
/** \test IPV4 with LSRR option (len too large). */
1015
static int DecodeIPV4OptionsLSRRTest02(void)
1016
{
1017
    uint8_t raw_opts[] = {
1018
        IPV4_OPT_LSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1019
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1023
    };
1024
    Packet *p = PacketGetFromAlloc();
1025
    FAIL_IF(unlikely(p == NULL));
1026
1027
    IPV4Options opts;
1028
    memset(&opts, 0x00, sizeof(opts));
1029
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1030
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1031
    FAIL_IF(opts.o_lsrr.type != 0);
1032
    SCFree(p);
1033
    PASS;
1034
}
1035
1036
/** \test IPV4 with LSRR option (ptr too large). */
1037
static int DecodeIPV4OptionsLSRRTest03(void)
1038
{
1039
    uint8_t raw_opts[] = {
1040
        IPV4_OPT_LSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1041
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1042
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1043
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1044
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1045
    };
1046
    Packet *p = PacketGetFromAlloc();
1047
    FAIL_IF(unlikely(p == NULL));
1048
1049
    IPV4Options opts;
1050
    memset(&opts, 0x00, sizeof(opts));
1051
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1052
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1053
    FAIL_IF(opts.o_lsrr.type != 0);
1054
    SCFree(p);
1055
    PASS;
1056
}
1057
1058
/** \test IPV4 with LSRR option (ptr not in 4 byte increment). */
1059
static int DecodeIPV4OptionsLSRRTest04(void)
1060
{
1061
    uint8_t raw_opts[] = {
1062
        IPV4_OPT_LSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1063
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1064
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1065
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1066
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1067
    };
1068
    Packet *p = PacketGetFromAlloc();
1069
    FAIL_IF(unlikely(p == NULL));
1070
1071
    IPV4Options opts;
1072
    memset(&opts, 0x00, sizeof(opts));
1073
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1074
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1075
    FAIL_IF(opts.o_lsrr.type != 0);
1076
    SCFree(p);
1077
    PASS;
1078
}
1079
1080
/** \test IPV4 with CIPSO option. */
1081
static int DecodeIPV4OptionsCIPSOTest01(void)
1082
{
1083
    uint8_t raw_opts[] = {
1084
        IPV4_OPT_CIPSO, 0x18, 0x00, 0x00, 0x00, 0x05, 0x05, 0x12,
1085
        0x00, 0x03, 0x00, 0xef, 0x00, 0xef, 0x00, 0x06,
1086
        0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
1087
    };
1088
    Packet *p = PacketGetFromAlloc();
1089
    FAIL_IF(unlikely(p == NULL));
1090
1091
    IPV4Options opts;
1092
    memset(&opts, 0x00, sizeof(opts));
1093
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1094
    FAIL_IF(p->flags & PKT_IS_INVALID);
1095
    FAIL_IF(opts.o_cipso.type != IPV4_OPT_CIPSO);
1096
    SCFree(p);
1097
    PASS;
1098
}
1099
1100
/** \test IPV4 with SID option. */
1101
static int DecodeIPV4OptionsSIDTest01(void)
1102
{
1103
    uint8_t raw_opts[] = {
1104
        IPV4_OPT_SID, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1105
    };
1106
    Packet *p = PacketGetFromAlloc();
1107
    FAIL_IF(unlikely(p == NULL));
1108
1109
    IPV4Options opts;
1110
    memset(&opts, 0x00, sizeof(opts));
1111
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1112
    FAIL_IF(p->flags & PKT_IS_INVALID);
1113
    FAIL_IF(opts.o_sid.type != IPV4_OPT_SID);
1114
    SCFree(p);
1115
    PASS;
1116
}
1117
1118
/** \test IPV4 with SID option (len invalid. */
1119
static int DecodeIPV4OptionsSIDTest02(void)
1120
{
1121
    uint8_t raw_opts[] = {
1122
        IPV4_OPT_SID, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1123
    };
1124
    Packet *p = PacketGetFromAlloc();
1125
    FAIL_IF(unlikely(p == NULL));
1126
1127
    IPV4Options opts;
1128
    memset(&opts, 0x00, sizeof(opts));
1129
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1130
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1131
    FAIL_IF(opts.o_sid.type != 0);
1132
    SCFree(p);
1133
    PASS;
1134
}
1135
1136
/** \test IPV4 with SSRR option. */
1137
static int DecodeIPV4OptionsSSRRTest01(void)
1138
{
1139
    uint8_t raw_opts[] = {
1140
        IPV4_OPT_SSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1141
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1145
    };
1146
    Packet *p = PacketGetFromAlloc();
1147
    FAIL_IF(unlikely(p == NULL));
1148
1149
    IPV4Options opts;
1150
    memset(&opts, 0x00, sizeof(opts));
1151
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1152
    FAIL_IF(p->flags & PKT_IS_INVALID);
1153
    FAIL_IF(opts.o_ssrr.type != IPV4_OPT_SSRR);
1154
    SCFree(p);
1155
    PASS;
1156
}
1157
1158
/** \test IPV4 with SSRR option (len too large). */
1159
static int DecodeIPV4OptionsSSRRTest02(void)
1160
{
1161
    uint8_t raw_opts[] = {
1162
        IPV4_OPT_SSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1163
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1164
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1165
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1166
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1167
    };
1168
    Packet *p = PacketGetFromAlloc();
1169
    FAIL_IF(unlikely(p == NULL));
1170
1171
    IPV4Options opts;
1172
    memset(&opts, 0x00, sizeof(opts));
1173
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1174
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1175
    FAIL_IF(opts.o_ssrr.type != 0);
1176
    SCFree(p);
1177
    PASS;
1178
}
1179
1180
/** \test IPV4 with SSRR option (ptr too large). */
1181
static int DecodeIPV4OptionsSSRRTest03(void)
1182
{
1183
    uint8_t raw_opts[] = {
1184
        IPV4_OPT_SSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1185
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1187
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1189
    };
1190
    Packet *p = PacketGetFromAlloc();
1191
    FAIL_IF(unlikely(p == NULL));
1192
1193
    IPV4Options opts;
1194
    memset(&opts, 0x00, sizeof(opts));
1195
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1196
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1197
    FAIL_IF(opts.o_ssrr.type != 0);
1198
    SCFree(p);
1199
    PASS;
1200
}
1201
1202
/** \test IPV4 with SSRR option (ptr not in 4 byte increment). */
1203
static int DecodeIPV4OptionsSSRRTest04(void)
1204
{
1205
    uint8_t raw_opts[] = {
1206
        IPV4_OPT_SSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1207
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1208
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1209
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1211
    };
1212
    Packet *p = PacketGetFromAlloc();
1213
    FAIL_IF(unlikely(p == NULL));
1214
1215
    IPV4Options opts;
1216
    memset(&opts, 0x00, sizeof(opts));
1217
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1218
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1219
    FAIL_IF(opts.o_ssrr.type != 0);
1220
    SCFree(p);
1221
    PASS;
1222
}
1223
1224
/** \test IPV4 with RTRALT option. */
1225
static int DecodeIPV4OptionsRTRALTTest01(void)
1226
{
1227
    uint8_t raw_opts[] = {
1228
        IPV4_OPT_RTRALT, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1229
    };
1230
    Packet *p = PacketGetFromAlloc();
1231
    FAIL_IF(unlikely(p == NULL));
1232
1233
    IPV4Options opts;
1234
    memset(&opts, 0x00, sizeof(opts));
1235
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1236
    FAIL_IF(p->flags & PKT_IS_INVALID);
1237
    FAIL_IF(opts.o_rtralt.type != IPV4_OPT_RTRALT);
1238
    SCFree(p);
1239
    PASS;
1240
}
1241
1242
/** \test IPV4 with RTRALT option (len invalid. */
1243
static int DecodeIPV4OptionsRTRALTTest02(void)
1244
{
1245
    uint8_t raw_opts[] = {
1246
        IPV4_OPT_RTRALT, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1247
    };
1248
    Packet *p = PacketGetFromAlloc();
1249
    FAIL_IF(unlikely(p == NULL));
1250
1251
    IPV4Options opts;
1252
    memset(&opts, 0x00, sizeof(opts));
1253
    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1254
    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1255
    FAIL_IF(opts.o_rtralt.type != 0);
1256
    SCFree(p);
1257
    PASS;
1258
}
1259
1260
static int IPV4CalculateValidChecksumtest01(void)
1261
{
1262
    uint16_t csum = 0;
1263
1264
    uint8_t raw_ipv4[] = {
1265
        0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1266
        0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1267
        0xc0, 0xa8, 0x01, 0x03};
1268
1269
    csum = *( ((uint16_t *)raw_ipv4) + 5);
1270
1271
    FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) != 0);
1272
    PASS;
1273
}
1274
1275
static int IPV4CalculateInvalidChecksumtest02(void)
1276
{
1277
    uint16_t csum = 0;
1278
1279
    uint8_t raw_ipv4[] = {
1280
        0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1281
        0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1282
        0xc0, 0xa8, 0x01, 0x07};
1283
1284
    csum = *( ((uint16_t *)raw_ipv4) + 5);
1285
1286
    FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) == 0);
1287
    PASS;
1288
}
1289
1290
/**
1291
 * \test IPV4 defrag and packet recursion level test
1292
 */
1293
static int DecodeIPV4DefragTest01(void)
1294
{
1295
    uint8_t pkt1[] = {
1296
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1297
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1298
        0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1299
        0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1300
        0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1301
        0x81, 0x5e
1302
    };
1303
    uint8_t pkt2[] = {
1304
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1305
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1306
        0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1307
        0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1308
        0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1309
        0x80, 0x00
1310
    };
1311
    uint8_t pkt3[] = {
1312
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1313
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1314
        0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1315
        0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1316
        0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1317
    };
1318
    uint8_t tunnel_pkt[] = {
1319
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1320
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1321
        0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1322
        0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1323
        0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1324
        0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1325
        0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1326
    };
1327
1328
    Packet *p = PacketGetFromAlloc();
1329
    if (unlikely(p == NULL))
1330
        return 0;
1331
    ThreadVars tv;
1332
    DecodeThreadVars dtv;
1333
    int result = 1;
1334
1335
    memset(&tv, 0, sizeof(ThreadVars));
1336
    memset(&dtv, 0, sizeof(DecodeThreadVars));
1337
1338
    FlowInitConfig(FLOW_QUIET);
1339
    DefragInit();
1340
1341
    PacketCopyData(p, pkt1, sizeof(pkt1));
1342
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1343
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1344
    if (p->tcph != NULL) {
1345
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1346
        result = 0;
1347
        goto end;
1348
    }
1349
    PacketRecycle(p);
1350
1351
    PacketCopyData(p, pkt2, sizeof(pkt2));
1352
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1353
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1354
    if (p->tcph != NULL) {
1355
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1356
        result = 0;
1357
        goto end;
1358
    }
1359
    PacketRecycle(p);
1360
1361
    PacketCopyData(p, pkt3, sizeof(pkt3));
1362
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1363
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1364
    if (p->tcph != NULL) {
1365
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1366
        result = 0;
1367
        goto end;
1368
    }
1369
    Packet *tp = PacketDequeueNoLock(&tv.decode_pq);
1370
    if (tp == NULL) {
1371
        printf("Failed to get defragged pseudo packet\n");
1372
        result = 0;
1373
        goto end;
1374
    }
1375
    if (tp->recursion_level != p->recursion_level) {
1376
        printf("defragged pseudo packet's and parent packet's recursion "
1377
               "level don't match\n %d != %d",
1378
               tp->recursion_level, p->recursion_level);
1379
        result = 0;
1380
        goto end;
1381
    }
1382
    if (tp->ip4h == NULL || tp->tcph == NULL) {
1383
        printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1384
               "but it is\n");
1385
        result = 0;
1386
        goto end;
1387
    }
1388
    if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1389
        printf("defragged pseudo packet's and parent packet's pkt lens "
1390
               "don't match\n %u != %"PRIuMAX,
1391
               GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1392
        result = 0;
1393
        goto end;
1394
    }
1395
    if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1396
            result = 0;
1397
            goto end;
1398
    }
1399
1400
    PacketRecycle(tp);
1401
    SCFree(tp);
1402
1403
end:
1404
    DefragDestroy();
1405
    PacketRecycle(p);
1406
    FlowShutdown();
1407
    SCFree(p);
1408
    return result;
1409
}
1410
1411
/**
1412
 * \test Don't send IPv4 fragments to the upper layer decoder and
1413
 *       and packet recursion level test.
1414
 */
1415
static int DecodeIPV4DefragTest02(void)
1416
{
1417
    uint8_t pkt1[] = {
1418
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1419
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1420
        0x00, 0x24, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1421
        0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1422
        0xe1, 0x0c,
1423
        /* first frag */
1424
        0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1425
        0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1426
        0x80, 0x00,
1427
    };
1428
    uint8_t pkt2[] = {
1429
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1430
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1431
        0x00, 0x2c, 0xe9, 0xef, 0x20, 0x02, 0x40, 0x06,
1432
        0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1433
        0xe1, 0x0c,
1434
        /* second frag */
1435
        0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1436
        0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1437
        0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04
1438
    };
1439
    uint8_t pkt3[] = {
1440
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1441
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1442
        0x00, 0x16, 0xe9, 0xef, 0x00, 0x05, 0x40, 0x06,
1443
        0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1444
        0xe1, 0x0c,
1445
        /* final frag */
1446
        0xb1, 0xa3,
1447
    };
1448
1449
    uint8_t tunnel_pkt[] = {
1450
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1451
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1452
        0x00, 0x3e, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1453
        0xba, 0xae, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1454
        0xe1, 0x0c,
1455
        0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, 0x81, 0x5e,
1456
        0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1457
        0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1458
        0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1459
        0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
1460
        0xb1, 0xa3,
1461
    };
1462
1463
    Packet *p = PacketGetFromAlloc();
1464
    if (unlikely(p == NULL))
1465
        return 0;
1466
    ThreadVars tv;
1467
    DecodeThreadVars dtv;
1468
    int result = 0;
1469
1470
    memset(&tv, 0, sizeof(ThreadVars));
1471
    memset(&dtv, 0, sizeof(DecodeThreadVars));
1472
1473
    FlowInitConfig(FLOW_QUIET);
1474
    DefragInit();
1475
1476
    PacketCopyData(p, pkt1, sizeof(pkt1));
1477
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1478
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1479
    if (p->tcph != NULL) {
1480
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1481
        goto end;
1482
    }
1483
    PacketRecycle(p);
1484
1485
    PacketCopyData(p, pkt2, sizeof(pkt2));
1486
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1487
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1488
    if (p->tcph != NULL) {
1489
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1490
        goto end;
1491
    }
1492
    PacketRecycle(p);
1493
1494
    p->recursion_level = 3;
1495
    PacketCopyData(p, pkt3, sizeof(pkt3));
1496
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1497
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1498
    if (p->tcph != NULL) {
1499
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1500
        goto end;
1501
    }
1502
    Packet *tp = PacketDequeueNoLock(&tv.decode_pq);
1503
    if (tp == NULL) {
1504
        printf("Failed to get defragged pseudo packet\n");
1505
        goto end;
1506
    }
1507
    if (tp->recursion_level != p->recursion_level) {
1508
        printf("defragged pseudo packet's and parent packet's recursion "
1509
               "level don't match %d != %d: ",
1510
               tp->recursion_level, p->recursion_level);
1511
        goto end;
1512
    }
1513
    if (tp->ip4h == NULL || tp->tcph == NULL) {
1514
        printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1515
               "but it is\n");
1516
        goto end;
1517
    }
1518
    if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1519
        printf("defragged pseudo packet's and parent packet's pkt lens "
1520
               "don't match %u != %"PRIuMAX": ",
1521
               GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1522
        goto end;
1523
    }
1524
1525
    if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1526
        goto end;
1527
    }
1528
1529
    result = 1;
1530
    PacketRecycle(tp);
1531
    SCFree(tp);
1532
1533
end:
1534
    DefragDestroy();
1535
    PacketRecycle(p);
1536
    FlowShutdown();
1537
    SCFree(p);
1538
    return result;
1539
}
1540
1541
/**
1542
 * \test IPV4 defrag and flow retrieval test.
1543
 */
1544
static int DecodeIPV4DefragTest03(void)
1545
{
1546
    uint8_t pkt[] = {
1547
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1548
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1549
        0x00, 0x28, 0xe9, 0xee, 0x00, 0x00, 0x40, 0x06,
1550
        0xba, 0xbd, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1551
        0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1552
        0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
1553
        0x80, 0x00, 0x0c, 0xee, 0x00, 0x00
1554
    };
1555
    uint8_t pkt1[] = {
1556
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1557
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1558
        0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1559
        0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1560
        0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1561
        0x81, 0x5e
1562
    };
1563
    uint8_t pkt2[] = {
1564
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1565
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1566
        0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1567
        0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1568
        0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1569
        0x80, 0x00
1570
    };
1571
    uint8_t pkt3[] = {
1572
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1573
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1574
        0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1575
        0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1576
        0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1577
    };
1578
    uint8_t tunnel_pkt[] = {
1579
        0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1580
        0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1581
        0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1582
        0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1583
        0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1584
        0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1585
        0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1586
    };
1587
1588
    Packet *p = PacketGetFromAlloc();
1589
    if (unlikely(p == NULL))
1590
        return 0;
1591
    ThreadVars tv;
1592
    DecodeThreadVars dtv;
1593
    int result = 1;
1594
1595
    memset(&tv, 0, sizeof(ThreadVars));
1596
    memset(&dtv, 0, sizeof(DecodeThreadVars));
1597
1598
    FlowInitConfig(FLOW_QUIET);
1599
    DefragInit();
1600
1601
    PacketCopyData(p, pkt, sizeof(pkt));
1602
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1603
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1604
    if (p->tcph == NULL) {
1605
        printf("tcp header shouldn't be NULL, but it is\n");
1606
        result = 0;
1607
        goto end;
1608
    }
1609
    if (!(p->flags & PKT_WANTS_FLOW)) {
1610
        printf("packet flow shouldn't be NULL\n");
1611
        result = 0;
1612
        goto end;
1613
    }
1614
    PacketRecycle(p);
1615
1616
    PacketCopyData(p, pkt1, sizeof(pkt1));
1617
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1618
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1619
    if (p->tcph != NULL) {
1620
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1621
        result = 0;
1622
        goto end;
1623
    }
1624
    PacketRecycle(p);
1625
1626
    PacketCopyData(p, pkt2, sizeof(pkt2));
1627
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1628
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1629
    if (p->tcph != NULL) {
1630
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1631
        result = 0;
1632
        goto end;
1633
    }
1634
    PacketRecycle(p);
1635
1636
    PacketCopyData(p, pkt3, sizeof(pkt3));
1637
    DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1638
               GET_PKT_LEN(p) - ETHERNET_HEADER_LEN);
1639
    if (p->tcph != NULL) {
1640
        printf("tcp header should be NULL for ip fragment, but it isn't\n");
1641
        result = 0;
1642
        goto end;
1643
    }
1644
1645
    Packet *tp = PacketDequeueNoLock(&tv.decode_pq);
1646
    if (tp == NULL) {
1647
        printf("Failed to get defragged pseudo packet\n");
1648
        result = 0;
1649
        goto end;
1650
    }
1651
    if (!(tp->flags & PKT_WANTS_FLOW)) {
1652
        result = 0;
1653
        goto end;
1654
    }
1655
    if (tp->flow_hash != p->flow_hash) {
1656
        result = 0;
1657
        goto end;
1658
    }
1659
    if (tp->recursion_level != p->recursion_level) {
1660
        printf("defragged pseudo packet's and parent packet's recursion "
1661
               "level don't match\n %d != %d",
1662
               tp->recursion_level, p->recursion_level);
1663
        result = 0;
1664
        goto end;
1665
    }
1666
    if (tp->ip4h == NULL || tp->tcph == NULL) {
1667
        printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1668
               "but it is\n");
1669
        result = 0;
1670
        goto end;
1671
    }
1672
    if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1673
        printf("defragged pseudo packet's and parent packet's pkt lens "
1674
               "don't match\n %u != %"PRIuMAX,
1675
               GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1676
        result = 0;
1677
        goto end;
1678
    }
1679
1680
    if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1681
            result = 0;
1682
            goto end;
1683
    }
1684
1685
    PacketRecycle(tp);
1686
    SCFree(tp);
1687
1688
end:
1689
    DefragDestroy();
1690
    PacketRecycle(p);
1691
    FlowShutdown();
1692
    SCFree(p);
1693
    return result;
1694
}
1695
1696
/**
1697
 */
1698
static int DecodeEthernetTestIPv4Opt(void)
1699
{
1700
    uint8_t raw_eth[] = {
1701
        0xae, 0x71, 0x00, 0x00, 0x00, 0x4b, 0x06, 0x90, 0x61, 0x02, 0x00, 0xcd, 0x88, 0x64, 0x11, 0x00,
1702
        0x15, 0x00, 0x80, 0x64, 0x00, 0x21, 0x4c, 0x00, 0x00, 0x30, 0x42, 0xd6, 0xff, 0xff, 0xbd, 0x2f,
1703
        0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1704
        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1705
        0x01, 0x44, 0x05, 0x22, 0x02, 0x01
1706
    };
1707
1708
    DefragInit();
1709
1710
    Packet *p = PacketGetFromAlloc();
1711
    FAIL_IF_NULL(p);
1712
    ThreadVars tv;
1713
    DecodeThreadVars dtv;
1714
1715
    memset(&dtv, 0, sizeof(DecodeThreadVars));
1716
    memset(&tv,  0, sizeof(ThreadVars));
1717
1718
    DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
1719
1720
    SCFree(p);
1721
    DefragDestroy();
1722
    PASS;
1723
}
1724
1725
#endif /* UNITTESTS */
1726
1727
void DecodeIPV4RegisterTests(void)
1728
0
{
1729
#ifdef UNITTESTS
1730
    UtRegisterTest("DecodeIPV4OptionsNONETest01", DecodeIPV4OptionsNONETest01);
1731
    UtRegisterTest("DecodeIPV4OptionsEOLTest01", DecodeIPV4OptionsEOLTest01);
1732
    UtRegisterTest("DecodeIPV4OptionsNOPTest01", DecodeIPV4OptionsNOPTest01);
1733
    UtRegisterTest("DecodeIPV4OptionsRRTest01", DecodeIPV4OptionsRRTest01);
1734
    UtRegisterTest("DecodeIPV4OptionsRRTest02", DecodeIPV4OptionsRRTest02);
1735
    UtRegisterTest("DecodeIPV4OptionsRRTest03", DecodeIPV4OptionsRRTest03);
1736
    UtRegisterTest("DecodeIPV4OptionsRRTest04", DecodeIPV4OptionsRRTest04);
1737
    UtRegisterTest("DecodeIPV4OptionsQSTest01", DecodeIPV4OptionsQSTest01);
1738
    UtRegisterTest("DecodeIPV4OptionsQSTest02", DecodeIPV4OptionsQSTest02);
1739
    UtRegisterTest("DecodeIPV4OptionsTSTest01", DecodeIPV4OptionsTSTest01);
1740
    UtRegisterTest("DecodeIPV4OptionsTSTest02", DecodeIPV4OptionsTSTest02);
1741
    UtRegisterTest("DecodeIPV4OptionsTSTest03", DecodeIPV4OptionsTSTest03);
1742
    UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04);
1743
    UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01);
1744
    UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02);
1745
    UtRegisterTest("DecodeIPV4OptionsESECTest01", DecodeIPV4OptionsESECTest01);
1746
    UtRegisterTest("DecodeIPV4OptionsESECTest02", DecodeIPV4OptionsESECTest02);
1747
    UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01);
1748
    UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02);
1749
    UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03);
1750
    UtRegisterTest("DecodeIPV4OptionsLSRRTest04", DecodeIPV4OptionsLSRRTest04);
1751
    UtRegisterTest("DecodeIPV4OptionsCIPSOTest01",
1752
                   DecodeIPV4OptionsCIPSOTest01);
1753
    UtRegisterTest("DecodeIPV4OptionsSIDTest01", DecodeIPV4OptionsSIDTest01);
1754
    UtRegisterTest("DecodeIPV4OptionsSIDTest02", DecodeIPV4OptionsSIDTest02);
1755
    UtRegisterTest("DecodeIPV4OptionsSSRRTest01", DecodeIPV4OptionsSSRRTest01);
1756
    UtRegisterTest("DecodeIPV4OptionsSSRRTest02", DecodeIPV4OptionsSSRRTest02);
1757
    UtRegisterTest("DecodeIPV4OptionsSSRRTest03", DecodeIPV4OptionsSSRRTest03);
1758
    UtRegisterTest("DecodeIPV4OptionsSSRRTest04", DecodeIPV4OptionsSSRRTest04);
1759
    UtRegisterTest("DecodeIPV4OptionsRTRALTTest01",
1760
                   DecodeIPV4OptionsRTRALTTest01);
1761
    UtRegisterTest("DecodeIPV4OptionsRTRALTTest02",
1762
                   DecodeIPV4OptionsRTRALTTest02);
1763
    UtRegisterTest("IPV4CalculateValidChecksumtest01",
1764
                   IPV4CalculateValidChecksumtest01);
1765
    UtRegisterTest("IPV4CalculateInvalidChecksumtest02",
1766
                   IPV4CalculateInvalidChecksumtest02);
1767
    UtRegisterTest("DecodeIPV4DefragTest01", DecodeIPV4DefragTest01);
1768
    UtRegisterTest("DecodeIPV4DefragTest02", DecodeIPV4DefragTest02);
1769
    UtRegisterTest("DecodeIPV4DefragTest03", DecodeIPV4DefragTest03);
1770
    UtRegisterTest("DecodeEthernetTestIPv4Opt", DecodeEthernetTestIPv4Opt);
1771
#endif /* UNITTESTS */
1772
0
}
1773
/**
1774
 * @}
1775
 */