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

jasonish / suricata / 22873444665

08 Mar 2026 06:10PM UTC coverage: 79.306% (-0.009%) from 79.315%
22873444665

push

github

victorjulien
dpdk: adjust burst size to mempool size

When mempool size was configured really low (<32), Suricata exhausted
the mempool with the rx_burst call, which led to undefined behavior.
The current fix ensures the burst size is at most the size of the mempool,
if the mempool is smaller than BURST_SIZE macro.

3 of 3 new or added lines in 1 file covered. (100.0%)

678 existing lines in 28 files now uncovered.

265817 of 335177 relevant lines covered (79.31%)

4878829.65 hits per line

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

73.56
/src/source-pcap-file.c
1
/* Copyright (C) 2007-2016 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 * \file
20
 *
21
 * \author Victor Julien <victor@inliniac.net>
22
 *
23
 * File based pcap packet acquisition support
24
 */
25

26
#include "suricata-common.h"
27
#include "source-pcap-file.h"
28
#include "source-pcap-file-helper.h"
29
#include "source-pcap-file-directory-helper.h"
30
#include "flow-manager.h"
31
#include "util-checksum.h"
32
#include "runmode-unix-socket.h"
33
#include "suricata.h"
34
#include "conf.h"
35
#include "util-misc.h"
36
#include "capture-hooks.h"
37

38
extern uint32_t max_pending_packets;
39
PcapFileGlobalVars pcap_g;
40

41
/**
42
 * Union determining whether the behavior of the thread is file or directory
43
 */
44
typedef union PcapFileBehaviorVar_
45
{
46
    PcapFileDirectoryVars *directory;
47
    PcapFileFileVars *file;
48
} PcapFileBehaviorVar;
49

50
/**
51
 * Data specific to the thread
52
 */
53
typedef struct PcapFileThreadVars_
54
{
55
    PcapFileBehaviorVar behavior;
56
    bool is_directory;
57

58
    PcapFileSharedVars shared;
59
} PcapFileThreadVars;
60

61
static TmEcode ReceivePcapFileLoop(ThreadVars *, void *, void *);
62
static TmEcode ReceivePcapFileThreadInit(ThreadVars *, const void *, void **);
63
static void ReceivePcapFileThreadExitStats(ThreadVars *, void *);
64
static TmEcode ReceivePcapFileThreadDeinit(ThreadVars *, void *);
65

66
static TmEcode DecodePcapFile(ThreadVars *, Packet *, void *);
67
static TmEcode DecodePcapFileThreadInit(ThreadVars *, const void *, void **);
68
static TmEcode DecodePcapFileThreadDeinit(ThreadVars *tv, void *data);
69

70
static void CleanupPcapDirectoryFromThreadVars(PcapFileThreadVars *tv,
71
                                               PcapFileDirectoryVars *ptv);
72
static void CleanupPcapFileFromThreadVars(PcapFileThreadVars *tv, PcapFileFileVars *pfv);
73
static void CleanupPcapFileThreadVars(PcapFileThreadVars *tv);
74
static TmEcode PcapFileExit(TmEcode status, struct timespec *last_processed);
75

76
void CleanupPcapFileFromThreadVars(PcapFileThreadVars *tv, PcapFileFileVars *pfv)
77
{
13,141✔
78
    CleanupPcapFileFileVars(pfv);
13,141✔
79
    if (tv->is_directory == 0) {
13,141✔
80
        tv->behavior.file = NULL;
13,141✔
81
    }
13,141✔
82
}
13,141✔
83

84
void CleanupPcapDirectoryFromThreadVars(PcapFileThreadVars *tv, PcapFileDirectoryVars *ptv)
85
{
29✔
86
    CleanupPcapFileDirectoryVars(ptv);
29✔
87
    if (tv->is_directory == 1) {
29✔
88
        tv->behavior.directory = NULL;
29✔
89
    }
29✔
90
}
29✔
91

92
void CleanupPcapFileThreadVars(PcapFileThreadVars *ptv)
93
{
14,820✔
94
    if (ptv != NULL) {
14,820✔
95
        if (ptv->is_directory == 0) {
14,820✔
96
            if (ptv->behavior.file != NULL) {
14,791✔
97
                CleanupPcapFileFromThreadVars(ptv, ptv->behavior.file);
×
98
            }
×
99
            ptv->behavior.file = NULL;
14,791✔
100
        } else {
14,791✔
101
            if (ptv->behavior.directory != NULL) {
29✔
102
                CleanupPcapDirectoryFromThreadVars(ptv, ptv->behavior.directory);
×
103
            }
×
104
            ptv->behavior.directory = NULL;
29✔
105
        }
29✔
106
        if (ptv->shared.bpf_string != NULL) {
14,820✔
107
            SCFree(ptv->shared.bpf_string);
1✔
108
            ptv->shared.bpf_string = NULL;
1✔
109
        }
1✔
110
        SCFree(ptv);
14,820✔
111
    }
14,820✔
112
}
14,820✔
113

114
/**
115
 * Pcap File Functionality
116
 */
117
void TmModuleReceivePcapFileRegister (void)
118
{
2,221✔
119
    tmm_modules[TMM_RECEIVEPCAPFILE].name = "ReceivePcapFile";
2,221✔
120
    tmm_modules[TMM_RECEIVEPCAPFILE].ThreadInit = ReceivePcapFileThreadInit;
2,221✔
121
    tmm_modules[TMM_RECEIVEPCAPFILE].Func = NULL;
2,221✔
122
    tmm_modules[TMM_RECEIVEPCAPFILE].PktAcqLoop = ReceivePcapFileLoop;
2,221✔
123
    tmm_modules[TMM_RECEIVEPCAPFILE].PktAcqBreakLoop = NULL;
2,221✔
124
    tmm_modules[TMM_RECEIVEPCAPFILE].ThreadExitPrintStats = ReceivePcapFileThreadExitStats;
2,221✔
125
    tmm_modules[TMM_RECEIVEPCAPFILE].ThreadDeinit = ReceivePcapFileThreadDeinit;
2,221✔
126
    tmm_modules[TMM_RECEIVEPCAPFILE].cap_flags = 0;
2,221✔
127
    tmm_modules[TMM_RECEIVEPCAPFILE].flags = TM_FLAG_RECEIVE_TM;
2,221✔
128
}
2,221✔
129

130
void TmModuleDecodePcapFileRegister (void)
131
{
2,221✔
132
    tmm_modules[TMM_DECODEPCAPFILE].name = "DecodePcapFile";
2,221✔
133
    tmm_modules[TMM_DECODEPCAPFILE].ThreadInit = DecodePcapFileThreadInit;
2,221✔
134
    tmm_modules[TMM_DECODEPCAPFILE].Func = DecodePcapFile;
2,221✔
135
    tmm_modules[TMM_DECODEPCAPFILE].ThreadExitPrintStats = NULL;
2,221✔
136
    tmm_modules[TMM_DECODEPCAPFILE].ThreadDeinit = DecodePcapFileThreadDeinit;
2,221✔
137
    tmm_modules[TMM_DECODEPCAPFILE].cap_flags = 0;
2,221✔
138
    tmm_modules[TMM_DECODEPCAPFILE].flags = TM_FLAG_DECODE_TM;
2,221✔
139
}
2,221✔
140

141
#if defined(HAVE_SETVBUF) && defined(OS_LINUX)
142
#define PCAP_FILE_BUFFER_SIZE_DEFAULT 131072U   // 128 KiB
3,400✔
143
#define PCAP_FILE_BUFFER_SIZE_MIN     4096U     // 4 KiB
×
144
#define PCAP_FILE_BUFFER_SIZE_MAX     67108864U // 64MiB
×
145
#endif
146

147
void PcapFileGlobalInit(void)
148
{
3,400✔
149
    memset(&pcap_g, 0x00, sizeof(pcap_g));
3,400✔
150
    SC_ATOMIC_INIT(pcap_g.invalid_checksums);
3,400✔
151

152
    PcapFileInstallCaptureHooks();
3,400✔
153

154
#if defined(HAVE_SETVBUF) && defined(OS_LINUX)
3,400✔
155
    pcap_g.read_buffer_size = PCAP_FILE_BUFFER_SIZE_DEFAULT;
3,400✔
156

157
    const char *str = NULL;
3,400✔
158
    if (SCConfGet("pcap-file.buffer-size", &str) == 1) {
3,400✔
159
        uint32_t value = 0;
×
160
        if (ParseSizeStringU32(str, &value) < 0) {
×
161
            SCLogWarning("failed to parse pcap-file.buffer-size %s", str);
×
162
        }
×
163
        if (value >= PCAP_FILE_BUFFER_SIZE_MIN && value <= PCAP_FILE_BUFFER_SIZE_MAX) {
×
164
            SCLogInfo("Pcap-file will use %u buffer size", value);
×
165
            pcap_g.read_buffer_size = value;
×
166
        } else {
×
167
            SCLogWarning("pcap-file.buffer-size value of %u is invalid. Valid range is %u-%u",
×
168
                    value, PCAP_FILE_BUFFER_SIZE_MIN, PCAP_FILE_BUFFER_SIZE_MAX);
×
169
        }
×
170
    }
×
171
#endif
3,400✔
172
}
3,400✔
173

174
TmEcode PcapFileExit(TmEcode status, struct timespec *last_processed)
175
{
13,172✔
176
    if(RunModeUnixSocketIsActive()) {
13,172✔
177
        status = UnixSocketPcapFile(status, last_processed);
1,394✔
178
        SCReturnInt(status);
1,394✔
179
    } else {
13,172✔
180
        EngineStop();
11,778✔
181
        SCReturnInt(status);
11,778✔
182
    }
11,778✔
183
}
13,172✔
184

185
TmEcode ReceivePcapFileLoop(ThreadVars *tv, void *data, void *slot)
186
{
13,172✔
187
    SCEnter();
13,172✔
188

189
    if(unlikely(data == NULL)) {
13,172✔
190
        SCLogError("pcap file reader thread failed to initialize");
2✔
191

192
        PcapFileExit(TM_ECODE_FAILED, NULL);
2✔
193

194
        SCReturnInt(TM_ECODE_DONE);
2✔
195
    }
2✔
196

197
    TmEcode status = TM_ECODE_OK;
13,170✔
198
    PcapFileThreadVars *ptv = (PcapFileThreadVars *) data;
13,170✔
199
    TmSlot *s = (TmSlot *)slot;
13,170✔
200

201
    ptv->shared.slot = s->slot_next;
13,170✔
202
    ptv->shared.cb_result = TM_ECODE_OK;
13,170✔
203

204
    // Indicate that the thread is actually running its application level code (i.e., it can poll
205
    // packets)
206
    TmThreadsSetFlag(tv, THV_RUNNING);
13,170✔
207

208
    if(ptv->is_directory == 0) {
13,170✔
209
        SCLogInfo("Starting file run for %s", ptv->behavior.file->filename);
13,141✔
210
        /* Hold a reference for the duration of file processing, including
211
         * post-dispatch flow draining during EngineStop, so deletion decision
212
         * is deferred until all pseudo packets have been processed. */
213
        SC_ATOMIC_ADD(ptv->behavior.file->ref_cnt, 1);
13,141✔
214
        status = PcapFileDispatch(ptv->behavior.file);
13,141✔
215
    } else {
13,141✔
216
        SCLogInfo("Starting directory run for %s", ptv->behavior.directory->filename);
29✔
217
        PcapDirectoryDispatch(ptv->behavior.directory);
29✔
218
        CleanupPcapDirectoryFromThreadVars(ptv, ptv->behavior.directory);
29✔
219
    }
29✔
220

221
    SCLogDebug("Pcap file loop complete with status %u", status);
13,170✔
222

223
    status = PcapFileExit(status, &ptv->shared.last_processed);
13,170✔
224

225
    /* Release the hold set before dispatch and trigger deferred cleanup
226
     * if requested and this was the final reference. */
227
    if (ptv->is_directory == 0) {
13,170✔
228
        /* Ensure current pfv global is set for any pseudo packets emitted
229
         * during EngineStop/flow drain. */
230
        PcapFileSetCurrentPfv(ptv->behavior.file);
13,141✔
231
        uint32_t prev = SC_ATOMIC_SUB(ptv->behavior.file->ref_cnt, 1);
13,141✔
232
        if (prev == 1 && ptv->behavior.file->cleanup_requested) {
13,141✔
233
            CleanupPcapFileFileVars(ptv->behavior.file);
×
234
            ptv->behavior.file = NULL;
×
235
        }
×
236
    }
13,141✔
237
    SCReturnInt(status);
13,170✔
238
}
13,172✔
239

240
TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, const void *initdata, void **data)
241
{
14,820✔
242
    SCEnter();
14,820✔
243

244
    TmEcode status = TM_ECODE_OK;
14,820✔
245
    const char *tmpstring = NULL;
14,820✔
246
    const char *tmp_bpf_string = NULL;
14,820✔
247

248
    if (initdata == NULL) {
14,820✔
249
        SCLogError("error: initdata == NULL");
×
250

251
        SCReturnInt(TM_ECODE_OK);
×
252
    }
×
253

254
    PcapFileThreadVars *ptv = SCCalloc(1, sizeof(PcapFileThreadVars));
14,820✔
255
    if (unlikely(ptv == NULL)) {
14,820✔
256
        SCReturnInt(TM_ECODE_OK);
×
257
    }
×
258
    memset(&ptv->shared.last_processed, 0, sizeof(struct timespec));
14,820✔
259

260
    intmax_t tenant = 0;
14,820✔
261
    if (SCConfGetInt("pcap-file.tenant-id", &tenant) == 1) {
14,820✔
262
        if (tenant > 0 && tenant < UINT_MAX) {
×
263
            ptv->shared.tenant_id = (uint32_t)tenant;
×
264
            SCLogInfo("tenant %u", ptv->shared.tenant_id);
×
265
        } else {
×
266
            SCLogError("tenant out of range");
×
267
        }
×
268
    }
×
269

270
    if (SCConfGet("bpf-filter", &(tmp_bpf_string)) != 1) {
14,820✔
271
        SCLogDebug("could not get bpf or none specified");
14,819✔
272
    } else {
14,819✔
273
        ptv->shared.bpf_string = SCStrdup(tmp_bpf_string);
1✔
274
        if (unlikely(ptv->shared.bpf_string == NULL)) {
1✔
275
            SCLogError("Failed to allocate bpf_string");
×
276

277
            CleanupPcapFileThreadVars(ptv);
×
278

279
            SCReturnInt(TM_ECODE_OK);
×
280
        }
×
281
    }
1✔
282

283
    ptv->shared.delete_mode = PcapFileParseDeleteMode();
14,820✔
284

285
    DIR *directory = NULL;
14,820✔
286
    SCLogDebug("checking file or directory %s", (char*)initdata);
14,820✔
287
    if(PcapDetermineDirectoryOrFile((char *)initdata, &directory) == TM_ECODE_FAILED) {
14,820✔
288
        CleanupPcapFileThreadVars(ptv);
×
289
        SCReturnInt(TM_ECODE_OK);
×
290
    }
×
291

292
    if(directory == NULL) {
14,820✔
293
        SCLogDebug("argument %s was a file", (char *)initdata);
14,791✔
294
        const size_t toalloc = sizeof(PcapFileFileVars) + pcap_g.read_buffer_size;
14,791✔
295
        PcapFileFileVars *pv = SCCalloc(1, toalloc);
14,791✔
296
        if (unlikely(pv == NULL)) {
14,791✔
297
            SCLogError("Failed to allocate file vars");
×
298
            CleanupPcapFileThreadVars(ptv);
×
299
            SCReturnInt(TM_ECODE_OK);
×
300
        }
×
301

302
        pv->filename = SCStrdup((char *)initdata);
14,791✔
303
        if (unlikely(pv->filename == NULL)) {
14,791✔
304
            SCLogError("Failed to allocate filename");
×
305
            CleanupPcapFileFileVars(pv);
×
306
            CleanupPcapFileThreadVars(ptv);
×
307
            SCReturnInt(TM_ECODE_OK);
×
308
        }
×
309

310
        pv->shared = &ptv->shared;
14,791✔
311
        status = InitPcapFile(pv);
14,791✔
312
        if(status == TM_ECODE_OK) {
14,791✔
313
            ptv->is_directory = 0;
13,141✔
314
            ptv->behavior.file = pv;
13,141✔
315
        } else {
13,141✔
316
            SCLogWarning("Failed to init pcap file %s, skipping", pv->filename);
1,650✔
317
            CleanupPcapFileFileVars(pv);
1,650✔
318
            CleanupPcapFileThreadVars(ptv);
1,650✔
319
            SCReturnInt(TM_ECODE_OK);
1,650✔
320
        }
1,650✔
321
    } else {
14,791✔
322
        SCLogInfo("Argument %s was a directory", (char *)initdata);
29✔
323
        PcapFileDirectoryVars *pv = SCCalloc(1, sizeof(PcapFileDirectoryVars));
29✔
324
        if (unlikely(pv == NULL)) {
29✔
325
            SCLogError("Failed to allocate directory vars");
×
326
            closedir(directory);
×
327
            CleanupPcapFileThreadVars(ptv);
×
328
            SCReturnInt(TM_ECODE_OK);
×
329
        }
×
330

331
        pv->filename = SCStrdup((char*)initdata);
29✔
332
        if (unlikely(pv->filename == NULL)) {
29✔
333
            SCLogError("Failed to allocate filename");
×
334
            closedir(directory);
×
335
            CleanupPcapFileDirectoryVars(pv);
×
336
            CleanupPcapFileThreadVars(ptv);
×
337
            SCReturnInt(TM_ECODE_OK);
×
338
        }
×
339

340
        int should_recurse;
29✔
341
        pv->should_recurse = false;
29✔
342
        if (SCConfGetBool("pcap-file.recursive", &should_recurse) == 1) {
29✔
343
            pv->should_recurse = (should_recurse == 1);
×
344
        }
×
345

346
        int should_loop = 0;
29✔
347
        pv->should_loop = false;
29✔
348
        if (SCConfGetBool("pcap-file.continuous", &should_loop) == 1) {
29✔
349
            pv->should_loop = (should_loop == 1);
×
350
        }
×
351

352
        if (pv->should_recurse && pv->should_loop) {
29✔
353
            SCLogError("Error, --pcap-file-continuous and --pcap-file-recursive "
×
354
                       "cannot be used together.");
×
355
            closedir(directory);
×
356
            CleanupPcapFileDirectoryVars(pv);
×
357
            CleanupPcapFileThreadVars(ptv);
×
358
            SCReturnInt(TM_ECODE_FAILED);
×
359
        }
×
360

361
        pv->delay = 30;
29✔
362
        intmax_t delay = 0;
29✔
363
        if (SCConfGetInt("pcap-file.delay", &delay) == 1) {
29✔
364
            if (delay > 0 && delay < UINT_MAX) {
×
365
                pv->delay = (time_t)delay;
×
366
                SCLogDebug("delay %lu", pv->delay);
×
367
            } else {
×
368
                SCLogError("delay out of range");
×
369
            }
×
370
        }
×
371

372
        pv->poll_interval = 5;
29✔
373
        intmax_t poll_interval = 0;
29✔
374
        if (SCConfGetInt("pcap-file.poll-interval", &poll_interval) == 1) {
29✔
375
            if (poll_interval > 0 && poll_interval < UINT_MAX) {
×
376
                pv->poll_interval = (time_t)poll_interval;
×
377
                SCLogDebug("poll-interval %lu", pv->delay);
×
378
            } else {
×
379
                SCLogError("poll-interval out of range");
×
380
            }
×
381
        }
×
382

383
        pv->shared = &ptv->shared;
29✔
384
        pv->directory = directory;
29✔
385
        TAILQ_INIT(&pv->directory_content);
29✔
386

387
        ptv->is_directory = 1;
29✔
388
        ptv->behavior.directory = pv;
29✔
389
    }
29✔
390

391
    if (SCConfGet("pcap-file.checksum-checks", &tmpstring) != 1) {
13,170✔
392
        pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_AUTO;
601✔
393
    } else {
12,569✔
394
        if (strcmp(tmpstring, "auto") == 0) {
12,569✔
395
            pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_AUTO;
2,790✔
396
        } else if (SCConfValIsTrue(tmpstring)) {
12,563✔
397
            pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_ENABLE;
×
398
        } else if (SCConfValIsFalse(tmpstring)) {
9,779✔
399
            pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_DISABLE;
9,779✔
400
        }
9,779✔
401
    }
12,569✔
402
    pcap_g.checksum_mode = pcap_g.conf_checksum_mode;
13,170✔
403

404
    ptv->shared.tv = tv;
13,170✔
405
    *data = (void *)ptv;
13,170✔
406

407
    SCReturnInt(TM_ECODE_OK);
13,170✔
408
}
14,820✔
409

410
void ReceivePcapFileThreadExitStats(ThreadVars *tv, void *data)
411
{
3,399✔
412
    SCEnter();
3,399✔
413
    if(data != NULL) {
3,399✔
414
        PcapFileThreadVars *ptv = (PcapFileThreadVars *)data;
3,397✔
415

416
        if (pcap_g.conf_checksum_mode == CHECKSUM_VALIDATION_AUTO &&
3,397✔
417
            pcap_g.cnt < CHECKSUM_SAMPLE_COUNT &&
3,397✔
418
            SC_ATOMIC_GET(pcap_g.invalid_checksums)) {
3,397✔
419
            uint64_t chrate = pcap_g.cnt / SC_ATOMIC_GET(pcap_g.invalid_checksums);
10✔
420
            if (chrate < CHECKSUM_INVALID_RATIO)
10✔
421
                SCLogWarning("1/%" PRIu64 "th of packets have an invalid checksum,"
8✔
422
                             " consider setting pcap-file.checksum-checks variable to no"
10✔
423
                             " or use '-k none' option on command line.",
10✔
424
                        chrate);
10✔
425
            else
2✔
426
                SCLogInfo("1/%" PRIu64 "th of packets have an invalid checksum",
2✔
427
                      chrate);
10✔
428
        }
10✔
429
        SCLogNotice("read %" PRIu64 " file%s, %" PRIu64 " packets, %" PRIu64 " bytes",
3,397✔
430
                ptv->shared.files, ptv->shared.files == 1 ? "" : "s", ptv->shared.pkts,
3,397✔
431
                ptv->shared.bytes);
3,397✔
432
    }
3,397✔
433
}
3,399✔
434

435
TmEcode ReceivePcapFileThreadDeinit(ThreadVars *tv, void *data)
436
{
13,172✔
437
    SCEnter();
13,172✔
438
    if(data != NULL) {
13,172✔
439
        PcapFileThreadVars *ptv = (PcapFileThreadVars *) data;
13,170✔
440

441
        if (!ptv->is_directory && ptv->behavior.file != NULL) {
13,170✔
442
            CleanupPcapFileFromThreadVars(ptv, ptv->behavior.file);
13,141✔
443
        }
13,141✔
444

445
        CleanupPcapFileThreadVars(ptv);
13,170✔
446
    }
13,170✔
447
    SCReturnInt(TM_ECODE_OK);
13,172✔
448
}
13,172✔
449

450
static TmEcode DecodePcapFile(ThreadVars *tv, Packet *p, void *data)
451
{
5,136,253✔
452
    SCEnter();
5,136,253✔
453
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;
5,136,253✔
454

455
    DEBUG_VALIDATE_BUG_ON(PKT_IS_PSEUDOPKT(p));
5,136,253✔
456

457
    /* update counters */
458
    DecodeUpdatePacketCounters(tv, dtv, p);
5,136,253✔
459

460
    DecoderFunc decoder;
5,136,253✔
461
    if(ValidateLinkType(p->datalink, &decoder) == TM_ECODE_OK) {
5,136,253✔
462

463
        /* call the decoder */
464
        decoder(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p));
5,136,218✔
465

466
#ifdef DEBUG
467
        BUG_ON(p->pkt_src != PKT_SRC_WIRE && p->pkt_src != PKT_SRC_FFR);
468
#endif
469
        DEBUG_VALIDATE_BUG_ON(p->proto != PacketGetIPProto(p));
5,136,218✔
470

471
        PacketDecodeFinalize(tv, dtv, p);
5,136,218✔
472

473
        SCReturnInt(TM_ECODE_OK);
5,136,218✔
474
    } else {
5,136,218✔
475
        SCReturnInt(TM_ECODE_FAILED);
35✔
476
    }
35✔
477
}
5,136,253✔
478

479
TmEcode DecodePcapFileThreadInit(ThreadVars *tv, const void *initdata, void **data)
480
{
3,400✔
481
    SCEnter();
3,400✔
482
    DecodeThreadVars *dtv = NULL;
3,400✔
483
    dtv = DecodeThreadVarsAlloc(tv);
3,400✔
484

485
    if (dtv == NULL)
3,400✔
UNCOV
486
        SCReturnInt(TM_ECODE_FAILED);
×
487

488
    DecodeRegisterPerfCounters(dtv, tv);
3,400✔
489

490
    *data = (void *)dtv;
3,400✔
491

492
    SCReturnInt(TM_ECODE_OK);
3,400✔
493
}
3,400✔
494

495
TmEcode DecodePcapFileThreadDeinit(ThreadVars *tv, void *data)
496
{
3,399✔
497
    if (data != NULL)
3,399✔
498
        DecodeThreadVarsFree(tv, data);
3,399✔
499
    SCReturnInt(TM_ECODE_OK);
3,399✔
500
}
3,399✔
501

502
void PcapIncreaseInvalidChecksum(void)
503
{
5,854✔
504
    (void) SC_ATOMIC_ADD(pcap_g.invalid_checksums, 1);
505
}
5,854✔
506

507
/* eof */
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