Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/wiretap/pcapng.c
Line
Count
Source
1
/* pcapng.c
2
 *
3
 * Wiretap Library
4
 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
5
 *
6
 * File format support for pcapng file format
7
 * Copyright (c) 2007 by Ulf Lamping <ulf.lamping@web.de>
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
/* File format specification:
13
 *   https://github.com/pcapng/pcapng
14
 * Related Wiki page:
15
 *   https://gitlab.com/wireshark/wireshark/-/wikis/Development/PcapNg
16
 */
17
18
#include "config.h"
19
0
#define WS_LOG_DOMAIN LOG_DOMAIN_WIRETAP
20
#include "pcapng.h"
21
22
#include "wtap_opttypes.h"
23
24
#include <stdlib.h>
25
#include <string.h>
26
#include <errno.h>
27
28
#include <wsutil/wslog.h>
29
#include <wsutil/strtoi.h>
30
#include <wsutil/glib-compat.h>
31
#include <wsutil/ws_assert.h>
32
#include <wsutil/ws_roundup.h>
33
#include <wsutil/ws_padding_to.h>
34
#include <wsutil/unicode-utils.h>
35
36
#include "wtap_module.h"
37
#include "file_wrappers.h"
38
#include "required_file_handlers.h"
39
#include "pcap-common.h"
40
#include "pcap-encap.h"
41
#include "pcapng_module.h"
42
#include "secrets-types.h"
43
#include "pcapng-darwin-custom.h"
44
45
0
#define NS_PER_S 1000000000U
46
47
static bool
48
pcapng_read(wtap *wth, wtap_rec *rec, int *err,
49
            char **err_info, int64_t *data_offset);
50
static bool
51
pcapng_seek_read(wtap *wth, int64_t seek_off,
52
                 wtap_rec *rec, int *err, char **err_info);
53
static void
54
pcapng_close(wtap *wth);
55
56
static bool
57
pcapng_encap_is_ft_specific(int encap);
58
59
static bool
60
pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data,
61
                            int *err, char **err_info);
62
63
/*
64
 * Minimum block size = size of block header + size of block trailer.
65
 */
66
0
#define MIN_BLOCK_SIZE  ((uint32_t)(sizeof(pcapng_block_header_t) + sizeof(uint32_t)))
67
68
/*
69
 * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
70
 */
71
0
#define MIN_SHB_SIZE    ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
72
73
/* pcapng: packet block file encoding (obsolete) */
74
typedef struct pcapng_packet_block_s {
75
    uint16_t interface_id;
76
    uint16_t drops_count;
77
    uint32_t timestamp_high;
78
    uint32_t timestamp_low;
79
    uint32_t captured_len;
80
    uint32_t packet_len;
81
    /* ... Packet Data ... */
82
    /* ... Padding ... */
83
    /* ... Options ... */
84
} pcapng_packet_block_t;
85
86
/* pcapng: enhanced packet block file encoding */
87
typedef struct pcapng_enhanced_packet_block_s {
88
    uint32_t interface_id;
89
    uint32_t timestamp_high;
90
    uint32_t timestamp_low;
91
    uint32_t captured_len;
92
    uint32_t packet_len;
93
    /* ... Packet Data ... */
94
    /* ... Padding ... */
95
    /* ... Options ... */
96
} pcapng_enhanced_packet_block_t;
97
98
/*
99
 * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
100
 */
101
0
#define MIN_EPB_SIZE    ((uint32_t)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
102
103
/* pcapng: simple packet block file encoding */
104
typedef struct pcapng_simple_packet_block_s {
105
    uint32_t packet_len;
106
    /* ... Packet Data ... */
107
    /* ... Padding ... */
108
} pcapng_simple_packet_block_t;
109
110
/* pcapng: name resolution block file encoding */
111
typedef struct pcapng_name_resolution_block_s {
112
    uint16_t record_type;
113
    uint16_t record_len;
114
    /* ... Record ... */
115
} pcapng_name_resolution_block_t;
116
117
/* pcapng: custom block file encoding */
118
typedef struct pcapng_custom_block_s {
119
    uint32_t pen;
120
    /* Custom data and options */
121
} pcapng_custom_block_t;
122
123
/* pcapng: legacy DPEB (Darwin Process Event Block) file encoding */
124
typedef struct pcapng_legacy_darwin_process_event_block_s {
125
    uint32_t process_id;
126
    /* Options */
127
}  pcapng_legacy_darwin_process_event_block_t;
128
129
130
/*
131
 * We require __REALTIME_TIMESTAMP in the Journal Export Format reader in
132
 * order to set each packet timestamp. Require it here as well, although
133
 * it's not strictly necessary.
134
 */
135
0
#define SDJ__REALTIME_TIMESTAMP "__REALTIME_TIMESTAMP="
136
0
#define MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE    23 // "__REALTIME_TIMESTAMP=0\n"
137
138
/* pcapng: common option header file encoding for every option type */
139
typedef struct pcapng_option_header_s {
140
    uint16_t option_code;
141
    uint16_t option_length;
142
    /* ... x bytes Option Body ... */
143
    /* ... Padding ... */
144
} pcapng_option_header_t;
145
146
struct pcapng_option {
147
    uint16_t type;
148
    uint16_t value_length;
149
};
150
151
/* MSBit of option code means "local type" */
152
#define OPT_LOCAL_FLAG       0x8000
153
154
/* OPT_EPB_VERDICT sub-types */
155
0
#define OPT_VERDICT_TYPE_HW  0
156
0
#define OPT_VERDICT_TYPE_TC  1
157
0
#define OPT_VERDICT_TYPE_XDP 2
158
159
/* OPT_EPB_HASH sub-types */
160
#define OPT_HASH_2COMP    0
161
#define OPT_HASH_XOR      1
162
0
#define OPT_HASH_CRC32    2
163
0
#define OPT_HASH_MD5      3
164
0
#define OPT_HASH_SHA1     4
165
0
#define OPT_HASH_TOEPLITZ 5
166
167
/*
168
 * In order to keep from trying to allocate large chunks of memory,
169
 * which could either fail or, even if it succeeds, chew up so much
170
 * address space or memory+backing store as not to leave room for
171
 * anything else, we impose upper limits on the size of blocks we're
172
 * willing to handle.
173
 *
174
 * We pick a limit of an EPB with a maximum-sized D-Bus packet and 128 KiB
175
 * worth of options; we use the maximum D-Bus packet size as that's larger
176
 * than the maximum packet size for other link-layer types, and the maximum
177
 * packet size for other link-layer types is currently small enough that
178
 * the resulting block size would be less than the previous 16 MiB limit.
179
 */
180
0
#define MAX_BLOCK_SIZE (MIN_EPB_SIZE + WTAP_MAX_PACKET_SIZE_DBUS + 131072)
181
182
/* Note: many of the defined structures for block data are defined in wtap.h */
183
184
/* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
185
typedef struct wtapng_packet_s {
186
    /* mandatory */
187
    uint32_t                        ts_high;        /* seconds since 1.1.1970 */
188
    uint32_t                        ts_low;         /* fraction of seconds, depends on if_tsresol */
189
    uint32_t                        cap_len;        /* data length in the file */
190
    uint32_t                        packet_len;     /* data length on the wire */
191
    uint32_t                        interface_id;   /* identifier of the interface. */
192
    uint16_t                        drops_count;    /* drops count, only valid for packet block */
193
    /* 0xffff if information no available */
194
    /* pack_hash */
195
    /* XXX - put the packet data / pseudo_header here as well? */
196
} wtapng_packet_t;
197
198
/* Simple Packet data */
199
typedef struct wtapng_simple_packet_s {
200
    /* mandatory */
201
    uint32_t                        cap_len;        /* data length in the file */
202
    uint32_t                        packet_len;     /* data length on the wire */
203
    /* XXX - put the packet data / pseudo_header here as well? */
204
} wtapng_simple_packet_t;
205
206
/* Interface data in private struct */
207
typedef struct interface_info_s {
208
    int wtap_encap;
209
    uint32_t snap_len;
210
    uint64_t time_units_per_second;
211
    int tsprecision;
212
    int64_t tsoffset;
213
    int fcslen;
214
    uint8_t tsresol_binary;
215
} interface_info_t;
216
217
typedef struct {
218
    unsigned current_section_number; /**< Section number of the current section being read sequentially */
219
    GArray *sections;             /**< Sections found in the capture file. */
220
} pcapng_t;
221
222
/*
223
 * Table for plugins to handle particular block types.
224
 *
225
 * A handler has a type, whether its internally handled and "read"
226
 * and "write" routines.
227
 *
228
 * A "read" routine returns a block as a libwiretap record, filling
229
 * in the wtap_rec structure with the appropriate record type and
230
 * other information, and filling in the structure's Buffer with
231
 * data for which there's no place in the wtap_rec structure.
232
 *
233
 * A "write" routine takes a libwiretap record and out a block.
234
 */
235
static GHashTable *block_handlers;
236
237
void
238
register_pcapng_block_type_information(pcapng_block_type_information_t* handler)
239
510
{
240
510
    if (handler == NULL) {
241
0
        ws_warning("Attempt to register NULL plugin block type handler");
242
0
        return;
243
0
    }
244
245
    /* Don't allow duplication of block types */
246
510
    if (g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(handler->type)) != NULL) {
247
248
0
        if (handler->type == BLOCK_TYPE_LEGACY_DPIB) {
249
250
            /* This special exception because stuff happened the way it had happened */
251
0
            g_hash_table_remove(block_handlers, GUINT_TO_POINTER(handler->type));
252
0
        }
253
0
        else {
254
0
            ws_warning("Attempt to register plugin for an existing block type 0x%08x not allowed",
255
0
                handler->type);
256
0
            return;
257
0
        }
258
0
    }
259
260
510
    g_hash_table_insert(block_handlers, GUINT_TO_POINTER(handler->type),
261
510
                              handler);
262
510
}
263
264
/*
265
 * Tables for plugins to handle particular options for particular block
266
 * types.
267
 *
268
 * An option has three handler routines:
269
 *
270
 *   An option parser, used when reading an option from a file:
271
 *
272
 *     The option parser is passed an indication of whether this section
273
 *     of the file is byte-swapped, the length of the option, the data of
274
 *     the option, a pointer to an error code, and a pointer to a pointer
275
 *     variable for an error string.
276
 *
277
 *     It checks whether the length and option are valid, and, if they
278
 *     aren't, returns false, setting the error code to the appropriate
279
 *     error (normally WTAP_ERR_BAD_FILE) and the error string to an
280
 *     appropriate string indicating the problem.
281
 *
282
 *     Otherwise, if this section of the file is byte-swapped, it byte-swaps
283
 *     multi-byte numerical values, so that it's in the host byte order.
284
 *
285
 *   An option sizer, used when writing an option to a file:
286
 *
287
 *     The option sizer is passed the option identifier for the option
288
 *     and a wtap_optval_t * that points to the data for the option.
289
 *
290
 *     It calculates how many bytes the option's data requires, not
291
 *     including any padding bytes, and returns that value.
292
 *
293
 *   An option writer, used when writing an option to a file:
294
 *
295
 *     The option writer is passed a wtap_dumper * to which the
296
 *     option data should be written, the option identifier for
297
 *     the option, a wtap_optval_t * that points to the data for
298
 *     the option, and an int * into which an error code should
299
 *     be stored if an error occurs when writing the option.
300
 *
301
 *     It returns a bool value of true if the attempt to
302
 *     write the option succeeds and false if the attempt to
303
 *     write the option gets an error.
304
 */
305
306
typedef struct {
307
    option_parser parser;
308
    option_sizer sizer;
309
    option_writer writer;
310
} option_handler;
311
312
static GHashTable *custom_enterprise_handlers;
313
314
/* Return whether this block type is handled interally, or
315
 * if it is returned to the caller in pcapng_read().
316
 * This is used by pcapng_open() to decide if it can process
317
 * the block.
318
 * Note that for block types that are registered from plugins,
319
 * we don't know the true answer without actually reading the block,
320
 * or even if there is a fixed answer for all blocks of that type,
321
 * so we err on the side of not processing.
322
 */
323
static bool
324
get_block_type_internal(unsigned block_type)
325
0
{
326
0
    pcapng_block_type_information_t *handler;
327
328
0
    handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(block_type));
329
330
0
    if (handler != NULL)
331
0
        return handler->internal;
332
0
    else
333
0
        return true;
334
0
}
335
336
GHashTable *
337
pcapng_create_option_handler_table(void)
338
120
{
339
120
    return g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
340
120
}
341
342
static GHashTable *
343
get_option_handlers(unsigned block_type)
344
150
{
345
150
    pcapng_block_type_information_t *block_handler;
346
347
150
    block_handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(block_type));
348
150
    if (block_handler == NULL) {
349
        /* No such block type. */
350
0
        return NULL;
351
0
    }
352
353
150
    if (block_handler->option_handlers == NULL) {
354
        /*
355
         * This block type doesn't support options other than
356
         * those supported by all blocks.
357
         */
358
0
        return NULL;
359
0
    }
360
361
150
    return block_handler->option_handlers;
362
150
}
363
364
void
365
register_pcapng_option_handler(unsigned block_type, unsigned option_code,
366
                               option_parser parser,
367
                               option_sizer sizer,
368
                               option_writer writer)
369
150
{
370
150
    GHashTable *option_handlers;
371
150
    option_handler *handler;
372
373
    /*
374
     * Get the table of option handlers for this block type.
375
     */
376
150
    option_handlers = get_option_handlers(block_type);
377
378
    /*
379
     * If there isn't one, the block only supports the standard options
380
     * (if it supports options at all; the SPB doesn't).
381
     */
382
150
    if (option_handlers == NULL)
383
0
        return;
384
385
    /*
386
     * Is this combination already registered?
387
     */
388
150
    handler = (option_handler *)g_hash_table_lookup(option_handlers,
389
150
                                                    GUINT_TO_POINTER(option_code));
390
150
    if (handler != NULL) {
391
0
        if (handler->parser == parser &&
392
0
            handler->sizer == sizer &&
393
0
            handler->writer == writer) {
394
            /*
395
             * Yes. This might be a case where multiple block types
396
             * share the same table, and some code registers the same
397
             * option for all of those blocks, which is OK. Just
398
             * ignore it.
399
             */
400
0
            return;
401
0
        }
402
403
        /*
404
         * No. XXX - report this.
405
         */
406
0
        return;
407
0
    }
408
409
    /*
410
     * No - register it.
411
     */
412
150
    handler = g_new(option_handler, 1);
413
150
    handler->parser = parser;
414
150
    handler->sizer = sizer;
415
150
    handler->writer = writer;
416
150
    g_hash_table_insert(option_handlers,
417
150
                        GUINT_TO_POINTER(option_code), handler);
418
150
}
419
420
void
421
pcapng_add_cb_section_info_data(section_info_t *section_info,
422
                                uint32_t pen, void *data)
423
0
{
424
0
    g_hash_table_insert(section_info->custom_block_data,
425
0
                        GUINT_TO_POINTER(pen), data);
426
0
}
427
428
void *
429
pcapng_get_cb_section_info_data(section_info_t *section_info, uint32_t pen,
430
                                const section_info_funcs_t *funcs)
431
0
{
432
0
    void *data;
433
434
0
    if (section_info->custom_block_data == NULL) {
435
        /*
436
         * Create the table of custom block data for this section_info_t.
437
         *
438
         * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
439
         * so we use "g_direct_hash()" and "g_direct_equal()".
440
         */
441
0
        section_info->custom_block_data = g_hash_table_new_full(g_direct_hash,
442
0
                                                                g_direct_equal,
443
0
                                                                NULL,
444
0
                                                                funcs->free);
445
446
        /*
447
         * The newly-created hash table is empty, so no point in looking
448
         * for an element in it.
449
         */
450
0
        data = NULL;
451
0
    } else {
452
        /*
453
         * We have the hash table; look for the entry.
454
         */
455
0
        data = g_hash_table_lookup(section_info->custom_block_data,
456
0
                                   GUINT_TO_POINTER(pen));
457
0
    }
458
0
    if (data == NULL) {
459
        /*
460
         * No entry found - create a new one, and add it to the
461
         * hash table.
462
         */
463
0
        data = funcs->provision();
464
0
        g_hash_table_insert(section_info->custom_block_data,
465
0
                            GUINT_TO_POINTER(pen), data);
466
0
    }
467
0
    return data;
468
0
}
469
470
static void
471
pcapng_destroy_section_info(section_info_t *section_info)
472
0
{
473
0
    if (section_info->interfaces != NULL)
474
0
        g_array_free(section_info->interfaces, true);
475
0
    if (section_info->custom_block_data != NULL)
476
0
        g_hash_table_destroy(section_info->custom_block_data);
477
0
    if (section_info->local_block_data != NULL)
478
0
        g_hash_table_destroy(section_info->local_block_data);
479
0
}
480
481
void *
482
pcapng_get_lb_section_info_data(section_info_t *section_info,
483
                                uint32_t block_type,
484
                                const section_info_funcs_t *funcs)
485
0
{
486
0
    void *data;
487
488
0
    if (section_info->local_block_data == NULL) {
489
        /*
490
         * Create the table of local block data for this section_info_t.
491
         *
492
         * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
493
         * so we use "g_direct_hash()" and "g_direct_equal()".
494
         */
495
0
        section_info->local_block_data = g_hash_table_new_full(g_direct_hash,
496
0
                                                               g_direct_equal,
497
0
                                                               NULL,
498
0
                                                               funcs->free);
499
500
        /*
501
         * The newly-created hash table is empty, so no point in looking
502
         * for an element in it.
503
         */
504
0
        data = NULL;
505
0
    } else {
506
        /*
507
         * We have the hash table; look for the entry.
508
         */
509
0
        data = g_hash_table_lookup(section_info->local_block_data,
510
0
                                   GUINT_TO_POINTER(block_type));
511
0
    }
512
0
    if (data == NULL) {
513
        /*
514
         * No entry found - create a new one, and add it to the
515
         * hash table.
516
         */
517
0
        data = funcs->provision();
518
0
        g_hash_table_insert(section_info->local_block_data,
519
0
                            GUINT_TO_POINTER(block_type), data);
520
0
    }
521
0
    return data;
522
0
}
523
524
void
525
pcapng_process_uint8_option(wtapng_block_t *wblock,
526
                            uint16_t option_code, uint16_t option_length,
527
                            const uint8_t *option_content)
528
0
{
529
0
    if (option_length == 1) {
530
        /*
531
         * If this option can appear only once in a block, this call
532
         * will fail on the second and later occurrences of the option;
533
         * we silently ignore the failure.
534
         */
535
0
        wtap_block_add_uint8_option(wblock->block, option_code, option_content[0]);
536
0
    }
537
0
}
538
539
void
540
pcapng_process_uint32_option(wtapng_block_t *wblock,
541
                             section_info_t *section_info,
542
                             pcapng_opt_byte_order_e byte_order,
543
                             uint16_t option_code, uint16_t option_length,
544
                             const uint8_t *option_content)
545
0
{
546
0
    uint32_t uint32;
547
548
0
    if (option_length == 4) {
549
        /*  Don't cast a uint8_t * into a uint32_t *--the
550
         *  uint8_t * may not point to something that's
551
         *  aligned correctly.
552
         *
553
         * XXX - options are aligned on 32-bit boundaries, so, while
554
         * it may be true that 64-bit options aren't guaranteed to be
555
         * aligned on 64-bit boundaries, it shouldn't be true that 32-bit
556
         * options aren't guaranteed to be aligned on 32-bit boundaries.
557
         */
558
0
        memcpy(&uint32, option_content, sizeof(uint32_t));
559
0
        switch (byte_order) {
560
561
0
        case OPT_SECTION_BYTE_ORDER:
562
0
            if (section_info->byte_swapped) {
563
0
                uint32 = GUINT32_SWAP_LE_BE(uint32);
564
0
            }
565
0
            break;
566
567
0
        case OPT_BIG_ENDIAN:
568
0
            uint32 = GUINT32_FROM_BE(uint32);
569
0
            break;
570
571
0
        case OPT_LITTLE_ENDIAN:
572
0
            uint32 = GUINT32_FROM_LE(uint32);
573
0
            break;
574
575
0
        default:
576
            /*
577
             * This should not happen - this is called by pcapng_process_options(),
578
             * which returns an error for an invalid byte_order argument, and
579
             * otherwise passes the known-to-be-valid byte_order argument to
580
             * us.
581
             *
582
             * Just ignore the option.
583
             */
584
0
            return;
585
0
        }
586
587
        /*
588
         * If this option can appear only once in a block, this call
589
         * will fail on the second and later occurrences of the option;
590
         * we silently ignore the failure.
591
         */
592
0
        wtap_block_add_uint32_option(wblock->block, option_code, uint32);
593
0
    }
594
0
}
595
596
void
597
pcapng_process_timestamp_option(wtapng_block_t *wblock,
598
                                section_info_t *section_info,
599
                                pcapng_opt_byte_order_e byte_order,
600
                                uint16_t option_code, uint16_t option_length,
601
                                const uint8_t *option_content)
602
0
{
603
0
    if (option_length == 8) {
604
0
        uint32_t high, low;
605
0
        uint64_t timestamp;
606
607
        /*  Don't cast a uint8_t * into a uint32_t *--the
608
         *  uint8_t * may not point to something that's
609
         *  aligned correctly.
610
         */
611
0
        memcpy(&high, option_content, sizeof(uint32_t));
612
0
        memcpy(&low, option_content + sizeof(uint32_t), sizeof(uint32_t));
613
0
        switch (byte_order) {
614
615
0
        case OPT_SECTION_BYTE_ORDER:
616
0
            if (section_info->byte_swapped) {
617
0
                high = GUINT32_SWAP_LE_BE(high);
618
0
                low = GUINT32_SWAP_LE_BE(low);
619
0
            }
620
0
            break;
621
622
0
        case OPT_BIG_ENDIAN:
623
0
            high = GUINT32_FROM_BE(high);
624
0
            low = GUINT32_FROM_BE(low);
625
0
            break;
626
627
0
        case OPT_LITTLE_ENDIAN:
628
0
            high = GUINT32_FROM_LE(high);
629
0
            low = GUINT32_FROM_LE(low);
630
0
            break;
631
632
0
        default:
633
            /*
634
             * This should not happen - this is called by pcapng_process_options(),
635
             * which returns an error for an invalid byte_order argument, and
636
             * otherwise passes the known-to-be-valid byte_order argument to
637
             * us.
638
             *
639
             * Just ignore the option.
640
             */
641
0
            return;
642
0
        }
643
0
        timestamp = (uint64_t)high;
644
0
        timestamp <<= 32;
645
0
        timestamp += (uint64_t)low;
646
        /*
647
         * If this option can appear only once in a block, this call
648
         * will fail on the second and later occurrences of the option;
649
         * we silently ignore the failure.
650
         */
651
0
        wtap_block_add_uint64_option(wblock->block, option_code, timestamp);
652
0
    }
653
0
}
654
655
void
656
pcapng_process_uint64_option(wtapng_block_t *wblock,
657
                             section_info_t *section_info,
658
                             pcapng_opt_byte_order_e byte_order,
659
                             uint16_t option_code, uint16_t option_length,
660
                             const uint8_t *option_content)
661
0
{
662
0
    uint64_t uint64;
663
664
0
    if (option_length == 8) {
665
        /*  Don't cast a uint8_t * into a uint64_t *--the
666
         *  uint8_t * may not point to something that's
667
         *  aligned correctly.
668
         */
669
0
        memcpy(&uint64, option_content, sizeof(uint64_t));
670
0
        switch (byte_order) {
671
672
0
        case OPT_SECTION_BYTE_ORDER:
673
0
            if (section_info->byte_swapped) {
674
0
                uint64 = GUINT64_SWAP_LE_BE(uint64);
675
0
            }
676
0
            break;
677
678
0
        case OPT_BIG_ENDIAN:
679
0
            uint64 = GUINT64_FROM_BE(uint64);
680
0
            break;
681
682
0
        case OPT_LITTLE_ENDIAN:
683
0
            uint64 = GUINT64_FROM_LE(uint64);
684
0
            break;
685
686
0
        default:
687
            /*
688
             * This should not happen - this is called by pcapng_process_options(),
689
             * which returns an error for an invalid byte_order argument, and
690
             * otherwise passes the known-to-be-valid byte_order argument to
691
             * us.
692
             *
693
             * Just ignore the option.
694
             */
695
0
            return;
696
0
        }
697
698
        /*
699
         * If this option can appear only once in a block, this call
700
         * will fail on the second and later occurrences of the option;
701
         * we silently ignore the failure.
702
         */
703
0
        wtap_block_add_uint64_option(wblock->block, option_code, uint64);
704
0
    }
705
0
}
706
707
void
708
pcapng_process_int64_option(wtapng_block_t *wblock,
709
                            section_info_t *section_info,
710
                            pcapng_opt_byte_order_e byte_order,
711
                            uint16_t option_code, uint16_t option_length,
712
                            const uint8_t *option_content)
713
0
{
714
0
    int64_t int64;
715
716
0
    if (option_length == 8) {
717
        /*  Don't cast a int8_t * into a int64_t *--the
718
         *  uint8_t * may not point to something that's
719
         *  aligned correctly.
720
         */
721
0
        memcpy(&int64, option_content, sizeof(int64_t));
722
0
        switch (byte_order) {
723
724
0
        case OPT_SECTION_BYTE_ORDER:
725
0
            if (section_info->byte_swapped) {
726
0
                int64 = GUINT64_SWAP_LE_BE(int64);
727
0
            }
728
0
            break;
729
730
0
        case OPT_BIG_ENDIAN:
731
0
            int64 = GUINT64_FROM_BE(int64);
732
0
            break;
733
734
0
        case OPT_LITTLE_ENDIAN:
735
0
            int64 = GUINT64_FROM_LE(int64);
736
0
            break;
737
738
0
        default:
739
            /*
740
             * This should not happen - this is called by pcapng_process_options(),
741
             * which returns an error for an invalid byte_order argument, and
742
             * otherwise passes the known-to-be-valid byte_order argument to
743
             * us.
744
             *
745
             * Just ignore the option.
746
             */
747
0
            return;
748
0
        }
749
750
        /*
751
         * If this option can appear only once in a block, this call
752
         * will fail on the second and later occurrences of the option;
753
         * we silently ignore the failure.
754
         */
755
0
        wtap_block_add_int64_option(wblock->block, option_code, int64);
756
0
    }
757
0
}
758
759
void
760
pcapng_process_string_option(wtapng_block_t *wblock, uint16_t option_code,
761
                             uint16_t option_length, const uint8_t *option_content)
762
0
{
763
0
    const uint8_t *opt = (const uint8_t*)option_content;
764
0
    size_t optlen = option_length;
765
0
    char *str;
766
767
    /* Validate UTF-8 encoding. */
768
0
    str = (char*)ws_utf8_make_valid(NULL, opt, optlen);
769
770
    /*
771
     * If this option can appear only once in a block, this call
772
     * will fail on the second and later occurrences of the option;
773
     * we silently ignore the failure.
774
     */
775
0
    if (wtap_block_add_string_option_owned(wblock->block, option_code, str) != WTAP_OPTTYPE_SUCCESS) {
776
0
        g_free(str);
777
0
    }
778
0
}
779
780
void
781
pcapng_process_bytes_option(wtapng_block_t *wblock, uint16_t option_code,
782
                            uint16_t option_length, const uint8_t *option_content)
783
0
{
784
0
    wtap_block_add_bytes_option(wblock->block, option_code, option_content, option_length);
785
0
}
786
787
static bool
788
pcapng_process_custom_option_common(section_info_t *section_info,
789
                                    uint16_t option_length,
790
                             const uint8_t *option_content,
791
                             pcapng_opt_byte_order_e byte_order,
792
                                    uint32_t *pen,
793
                             int *err, char **err_info)
794
0
{
795
0
    if (option_length < 4) {
796
0
        *err = WTAP_ERR_BAD_FILE;
797
0
        *err_info = ws_strdup_printf("pcapng: option length (%d) too small for custom option",
798
0
                                    option_length);
799
0
        return false;
800
0
    }
801
0
    memcpy(pen, option_content, sizeof(uint32_t));
802
0
    switch (byte_order) {
803
804
0
    case OPT_SECTION_BYTE_ORDER:
805
0
        if (section_info->byte_swapped) {
806
0
            *pen = GUINT32_SWAP_LE_BE(*pen);
807
0
        }
808
0
        break;
809
810
0
    case OPT_BIG_ENDIAN:
811
0
        *pen = GUINT32_FROM_BE(*pen);
812
0
        break;
813
814
0
    case OPT_LITTLE_ENDIAN:
815
0
        *pen = GUINT32_FROM_LE(*pen);
816
0
        break;
817
818
0
    default:
819
        /*
820
         * This should not happen - this is called by pcapng_process_options(),
821
         * which returns an error for an invalid byte_order argument, and
822
         * otherwise passes the known-to-be-valid byte_order argument to
823
         * us.
824
         */
825
0
        *err = WTAP_ERR_INTERNAL;
826
0
        *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_custom_option()",
827
0
                                    byte_order);
828
0
        return false;
829
0
    }
830
0
    return true;
831
0
}
832
833
static bool
834
pcapng_process_custom_string_option(wtapng_block_t *wblock,
835
                                    section_info_t *section_info,
836
                                    uint16_t option_code,
837
                                    uint16_t option_length,
838
                                    const uint8_t *option_content,
839
                                    pcapng_opt_byte_order_e byte_order,
840
                                    int *err, char **err_info)
841
0
{
842
0
    uint32_t pen;
843
0
    bool ret;
844
845
0
    if (!pcapng_process_custom_option_common(section_info, option_length,
846
0
                                             option_content, byte_order,
847
0
                                             &pen, err, err_info)) {
848
0
        return false;
849
0
    }
850
0
    ret = wtap_block_add_custom_string_option(wblock->block, option_code, pen, (const char*)(option_content + 4), option_length - 4) == WTAP_OPTTYPE_SUCCESS;
851
0
    ws_debug("returning %d", ret);
852
0
    return ret;
853
0
}
854
855
static bool
856
pcapng_process_custom_binary_option(wtapng_block_t *wblock,
857
                                    section_info_t *section_info,
858
                                    uint16_t option_code,
859
                                    uint16_t option_length,
860
                                    const uint8_t *option_content,
861
                                    pcapng_opt_byte_order_e byte_order,
862
                                    int *err, char **err_info)
863
0
{
864
0
    uint32_t pen;
865
0
    pcapng_custom_block_enterprise_handler_t const *pen_handler;
866
0
    bool ret;
867
868
0
    if (!pcapng_process_custom_option_common(section_info, option_length,
869
0
                                             option_content, byte_order,
870
0
                                             &pen, err, err_info)) {
871
0
        return false;
872
0
    }
873
874
0
    pen_handler = (pcapng_custom_block_enterprise_handler_t const *)g_hash_table_lookup(custom_enterprise_handlers, GUINT_TO_POINTER(pen));
875
876
0
    if (pen_handler != NULL)
877
0
    {
878
0
        ret = pen_handler->processor(wblock, section_info, option_code, option_content + 4, option_length - 4);
879
0
    }
880
0
    else
881
0
    {
882
0
        ret = wtap_block_add_custom_binary_option_from_data(wblock->block, option_code, pen, option_content + 4, option_length - 4) == WTAP_OPTTYPE_SUCCESS;
883
0
        ws_debug("Custom option type %u (0x%04x) with unknown pen %u with custom data of length %u", option_code, option_code, pen, option_length - 4);
884
0
    }
885
886
0
    ws_debug("returning %d", ret);
887
0
    return ret;
888
0
}
889
890
#ifdef HAVE_PLUGINS
891
static bool
892
pcapng_process_unhandled_option(wtapng_block_t *wblock,
893
                                section_info_t *section_info,
894
                                uint16_t option_code, uint16_t option_length,
895
                                const uint8_t *option_content,
896
                                int *err, char **err_info)
897
{
898
    GHashTable *option_handlers;
899
    option_handler *handler;
900
901
    /*
902
     * Get the table of option handlers for this block type.
903
     */
904
    option_handlers = get_option_handlers(wblock->type);
905
906
    /*
907
     * Do we have a handler for this packet block option code?
908
     */
909
    if (option_handlers != NULL &&
910
        (handler = (option_handler *)g_hash_table_lookup(option_handlers,
911
                                                         GUINT_TO_POINTER((unsigned)option_code))) != NULL) {
912
        /* Yes - call the handler. */
913
        if (!handler->parser(wblock->block, section_info->byte_swapped,
914
                             option_length, option_content, err, err_info))
915
            /* XXX - free anything? */
916
            return false;
917
    }
918
    return true;
919
}
920
#else
921
static bool
922
pcapng_process_unhandled_option(wtapng_block_t *wblock _U_,
923
                                section_info_t *section_info _U_,
924
                                uint16_t option_code _U_, uint16_t option_length _U_,
925
                                const uint8_t *option_content _U_,
926
                                int *err _U_, char **err_info _U_)
927
0
{
928
0
    return true;
929
0
}
930
#endif
931
932
bool
933
pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
934
                       section_info_t *section_info,
935
                       unsigned opt_cont_buf_len,
936
                       bool (*process_option)(wtapng_block_t *,
937
                                              section_info_t *,
938
                                              uint16_t, uint16_t,
939
                                              const uint8_t *,
940
                                              int *, char **),
941
                       pcapng_opt_byte_order_e byte_order,
942
                       int *err, char **err_info)
943
0
{
944
0
    uint8_t *option_content; /* Allocate as large as the options block */
945
0
    unsigned opt_bytes_remaining;
946
0
    const uint8_t *option_ptr;
947
0
    const pcapng_option_header_t *oh;
948
0
    uint16_t option_code, option_length;
949
0
    unsigned rounded_option_length;
950
951
0
    ws_debug("Options %u bytes", opt_cont_buf_len);
952
0
    if (opt_cont_buf_len == 0) {
953
        /* No options, so nothing to do */
954
0
        return true;
955
0
    }
956
957
    /* Allocate enough memory to hold all options */
958
0
    option_content = (uint8_t *)g_try_malloc(opt_cont_buf_len);
959
0
    if (option_content == NULL) {
960
0
        *err = ENOMEM;  /* we assume we're out of memory */
961
0
        return false;
962
0
    }
963
964
    /* Read all the options into the buffer */
965
0
    if (!wtap_read_bytes(fh, option_content, opt_cont_buf_len, err, err_info)) {
966
0
        ws_debug("failed to read options");
967
0
        g_free(option_content);
968
0
        return false;
969
0
    }
970
971
    /*
972
     * Now process them.
973
     * option_ptr starts out aligned on at least a 4-byte boundary, as
974
     * that's what g_try_malloc() gives us, and each option is padded
975
     * to a length that's a multiple of 4 bytes, so it remains aligned.
976
     */
977
0
    option_ptr = &option_content[0];
978
0
    opt_bytes_remaining = opt_cont_buf_len;
979
0
    while (opt_bytes_remaining != 0) {
980
        /* Get option header. */
981
0
        oh = (const pcapng_option_header_t *)(const void *)option_ptr;
982
        /* Sanity check: don't run past the end of the options. */
983
0
        if (sizeof (*oh) > opt_bytes_remaining) {
984
0
            *err = WTAP_ERR_BAD_FILE;
985
0
            *err_info = ws_strdup_printf("pcapng: Not enough data for option header");
986
0
            g_free(option_content);
987
0
            return false;
988
0
        }
989
0
        option_code = oh->option_code;
990
0
        option_length = oh->option_length;
991
0
        switch (byte_order) {
992
993
0
        case OPT_SECTION_BYTE_ORDER:
994
0
            if (section_info->byte_swapped) {
995
0
                option_code = GUINT16_SWAP_LE_BE(option_code);
996
0
                option_length = GUINT16_SWAP_LE_BE(option_length);
997
0
            }
998
0
            break;
999
1000
0
        case OPT_BIG_ENDIAN:
1001
0
            option_code = GUINT16_FROM_BE(option_code);
1002
0
            option_length = GUINT16_FROM_BE(option_length);
1003
0
            break;
1004
1005
0
        case OPT_LITTLE_ENDIAN:
1006
0
            option_code = GUINT16_FROM_LE(option_code);
1007
0
            option_length = GUINT16_FROM_LE(option_length);
1008
0
            break;
1009
1010
0
        default:
1011
            /* Don't do that. */
1012
0
            *err = WTAP_ERR_INTERNAL;
1013
0
            *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_options()",
1014
0
                                        byte_order);
1015
0
            g_free(option_content);
1016
0
            return false;
1017
0
        }
1018
0
        option_ptr += sizeof (*oh); /* 4 bytes, so it remains aligned */
1019
0
        opt_bytes_remaining -= sizeof (*oh);
1020
1021
        /* Round up option length to a multiple of 4. */
1022
0
        rounded_option_length = WS_ROUNDUP_4(option_length);
1023
1024
        /* Sanity check: don't run past the end of the options. */
1025
0
        if (rounded_option_length > opt_bytes_remaining) {
1026
0
            *err = WTAP_ERR_BAD_FILE;
1027
0
            *err_info = ws_strdup_printf("pcapng: Not enough data to handle option of length %u",
1028
0
                                        option_length);
1029
0
            g_free(option_content);
1030
0
            return false;
1031
0
        }
1032
1033
0
        switch (option_code) {
1034
0
            case(OPT_EOFOPT): /* opt_endofopt */
1035
0
                if (opt_bytes_remaining != 0) {
1036
0
                    ws_debug("%u bytes after opt_endofopt", opt_bytes_remaining);
1037
0
                }
1038
                /* padding should be ok here, just get out of this */
1039
0
                opt_bytes_remaining = rounded_option_length;
1040
0
                break;
1041
0
            case(OPT_COMMENT):
1042
0
                pcapng_process_string_option(wblock, option_code, option_length,
1043
0
                                             option_ptr);
1044
0
                break;
1045
0
            case(OPT_CUSTOM_STR_COPY):
1046
0
            case(OPT_CUSTOM_STR_NO_COPY):
1047
0
                if (!pcapng_process_custom_string_option(wblock, section_info,
1048
0
                                                         option_code,
1049
0
                                                         option_length,
1050
0
                                                         option_ptr,
1051
0
                                                         byte_order,
1052
0
                                                         err, err_info)) {
1053
0
                    g_free(option_content);
1054
0
                    return false;
1055
0
                }
1056
0
                break;
1057
0
            case(OPT_CUSTOM_BIN_COPY):
1058
0
            case(OPT_CUSTOM_BIN_NO_COPY):
1059
0
                if (!pcapng_process_custom_binary_option(wblock, section_info,
1060
0
                                                         option_code,
1061
0
                                                         option_length,
1062
0
                                                  option_ptr,
1063
0
                                                  byte_order,
1064
0
                                                  err, err_info)) {
1065
0
                    g_free(option_content);
1066
0
                    return false;
1067
0
                }
1068
0
                break;
1069
0
            default:
1070
0
                if (process_option == NULL ||
1071
0
                    !(*process_option)(wblock, section_info, option_code,
1072
0
                                       option_length, option_ptr,
1073
0
                                       err, err_info)) {
1074
0
                    g_free(option_content);
1075
0
                    return false;
1076
0
                }
1077
0
                break;
1078
0
        }
1079
0
        option_ptr += rounded_option_length; /* multiple of 4 bytes, so it remains aligned */
1080
0
        opt_bytes_remaining -= rounded_option_length;
1081
0
    }
1082
0
    g_free(option_content);
1083
0
    return true;
1084
0
}
1085
1086
typedef enum {
1087
    PCAPNG_BLOCK_OK,
1088
    PCAPNG_BLOCK_NOT_SHB,
1089
    PCAPNG_BLOCK_ERROR
1090
} block_return_val;
1091
1092
static bool
1093
pcapng_process_section_header_block_option(wtapng_block_t *wblock,
1094
                                           section_info_t *section_info,
1095
                                           uint16_t option_code,
1096
                                           uint16_t option_length,
1097
                                           const uint8_t *option_content,
1098
                                           int *err, char **err_info)
1099
0
{
1100
    /*
1101
     * Handle option content.
1102
     *
1103
     * ***DO NOT*** add any items to this table that are not
1104
     * standardized option codes in either section 3.5 "Options"
1105
     * of the current pcapng spec, at
1106
     *
1107
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1108
     *
1109
     * or in the list of options in section 4.1 "Section Header Block"
1110
     * of the current pcapng spec, at
1111
     *
1112
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
1113
     *
1114
     * All option codes in this switch statement here must be listed
1115
     * in one of those places as standardized option types.
1116
     */
1117
0
    switch (option_code) {
1118
0
        case(OPT_SHB_HARDWARE):
1119
0
            pcapng_process_string_option(wblock, option_code, option_length,
1120
0
                                         option_content);
1121
0
            break;
1122
0
        case(OPT_SHB_OS):
1123
0
            pcapng_process_string_option(wblock, option_code, option_length,
1124
0
                                         option_content);
1125
0
            break;
1126
0
        case(OPT_SHB_USERAPPL):
1127
0
            pcapng_process_string_option(wblock, option_code, option_length,
1128
0
                                         option_content);
1129
0
            break;
1130
0
        default:
1131
0
            if (!pcapng_process_unhandled_option(wblock, section_info,
1132
0
                                                 option_code, option_length,
1133
0
                                                 option_content,
1134
0
                                                 err, err_info))
1135
0
                return false;
1136
0
            break;
1137
0
    }
1138
0
    return true;
1139
0
}
1140
1141
static block_return_val
1142
pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
1143
                                 section_info_t *section_info,
1144
                                 wtapng_block_t *wblock,
1145
                                 int *err, char **err_info)
1146
0
{
1147
0
    bool byte_swapped;
1148
0
    uint16_t version_major;
1149
0
    uint16_t version_minor;
1150
0
    unsigned opt_cont_buf_len;
1151
0
    pcapng_section_header_block_t shb;
1152
0
    wtapng_section_mandatory_t* section_data;
1153
1154
    /* read fixed-length part of the block */
1155
0
    if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
1156
        /*
1157
         * Even if this is just a short read, report it as an error.
1158
         * It *is* a read error except when we're doing an open, in
1159
         * which case it's a "this isn't a pcapng file" indication.
1160
         * The open code will call us directly, and treat a short
1161
         * read error as such an indication.
1162
         */
1163
0
        return PCAPNG_BLOCK_ERROR;
1164
0
    }
1165
1166
    /* is the magic number one we expect? */
1167
0
    switch (shb.magic) {
1168
0
        case(0x1A2B3C4D):
1169
            /* this seems pcapng with correct byte order */
1170
0
            byte_swapped                = false;
1171
0
            version_major               = shb.version_major;
1172
0
            version_minor               = shb.version_minor;
1173
1174
0
            ws_debug("SHB (our byte order) V%u.%u, len %u",
1175
0
                     version_major, version_minor, bh->block_total_length);
1176
0
            break;
1177
0
        case(0x4D3C2B1A):
1178
            /* this seems pcapng with swapped byte order */
1179
0
            byte_swapped                = true;
1180
0
            version_major               = GUINT16_SWAP_LE_BE(shb.version_major);
1181
0
            version_minor               = GUINT16_SWAP_LE_BE(shb.version_minor);
1182
1183
            /* tweak the block length to meet current swapping that we know now */
1184
0
            bh->block_total_length  = GUINT32_SWAP_LE_BE(bh->block_total_length);
1185
1186
0
            ws_debug("SHB (byte-swapped) V%u.%u, len %u",
1187
0
                     version_major, version_minor, bh->block_total_length);
1188
0
            break;
1189
0
        default:
1190
            /* Not a "pcapng" magic number we know about. */
1191
0
            *err = WTAP_ERR_BAD_FILE;
1192
0
            *err_info = ws_strdup_printf("pcapng: unknown byte-order magic number 0x%08x", shb.magic);
1193
1194
            /*
1195
             * See above comment about PCAPNG_BLOCK_NOT_SHB.
1196
             */
1197
0
            return PCAPNG_BLOCK_NOT_SHB;
1198
0
    }
1199
1200
    /*
1201
     * Add padding bytes to the block total length.
1202
     *
1203
     * See the comment in pcapng_read_block() for a long discussion
1204
     * of this.
1205
     */
1206
0
    bh->block_total_length = WS_ROUNDUP_4(bh->block_total_length);
1207
1208
    /*
1209
     * Is this block long enough to be an SHB?
1210
     */
1211
0
    if (bh->block_total_length < MIN_SHB_SIZE) {
1212
        /*
1213
         * No.
1214
         */
1215
0
        *err = WTAP_ERR_BAD_FILE;
1216
0
        *err_info = ws_strdup_printf("pcapng: total block length %u of an SHB is less than the minimum SHB size %u",
1217
0
                                    bh->block_total_length, MIN_SHB_SIZE);
1218
0
        return PCAPNG_BLOCK_ERROR;
1219
0
    }
1220
1221
    /* OK, at this point we assume it's a pcapng file.
1222
1223
       Don't try to allocate memory for a huge number of options, as
1224
       that might fail and, even if it succeeds, it might not leave
1225
       any address space or memory+backing store for anything else.
1226
1227
       We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1228
       We check for this *after* checking the SHB for its byte
1229
       order magic number, so that non-pcapng files are less
1230
       likely to be treated as bad pcapng files. */
1231
0
    if (bh->block_total_length > MAX_BLOCK_SIZE) {
1232
0
        *err = WTAP_ERR_BAD_FILE;
1233
0
        *err_info = ws_strdup_printf("pcapng: total block length %u is too large (> %u)",
1234
0
                                    bh->block_total_length, MAX_BLOCK_SIZE);
1235
0
        return PCAPNG_BLOCK_ERROR;
1236
0
    }
1237
1238
    /* Currently only SHB versions 1.0 and 1.2 are supported;
1239
       version 1.2 is treated as being the same as version 1.0.
1240
       See the current version of the pcapng specification.
1241
1242
       Version 1.2 is written by some programs that write additional
1243
       block types (which can be read by any code that handles them,
1244
       regardless of whether the minor version if 0 or 2, so that's
1245
       not a reason to change the minor version number).
1246
1247
       XXX - the pcapng specification says that readers should
1248
       just ignore sections with an unsupported version number;
1249
       presumably they can also report an error if they skip
1250
       all the way to the end of the file without finding
1251
       any versions that they support. */
1252
0
    if (!(version_major == 1 &&
1253
0
          (version_minor == 0 || version_minor == 2))) {
1254
0
        *err = WTAP_ERR_UNSUPPORTED;
1255
0
        *err_info = ws_strdup_printf("pcapng: unknown SHB version %u.%u",
1256
0
                                    version_major, version_minor);
1257
0
        return PCAPNG_BLOCK_ERROR;
1258
0
    }
1259
1260
0
    memset(section_info, 0, sizeof(section_info_t));
1261
0
    section_info->byte_swapped  = byte_swapped;
1262
0
    section_info->version_major = version_major;
1263
0
    section_info->version_minor = version_minor;
1264
1265
    /*
1266
     * Set wblock->block to a newly-allocated section header block.
1267
     */
1268
0
    wblock->block = wtap_block_create(WTAP_BLOCK_SECTION);
1269
1270
    /*
1271
     * Set the mandatory values for the block.
1272
     */
1273
0
    section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1274
    /* 64bit section_length (currently unused) */
1275
0
    if (section_info->byte_swapped) {
1276
0
        section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
1277
0
    } else {
1278
0
        section_data->section_length = shb.section_length;
1279
0
    }
1280
1281
    /* Options */
1282
0
    opt_cont_buf_len = bh->block_total_length - MIN_SHB_SIZE;
1283
0
    if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1284
0
                                pcapng_process_section_header_block_option,
1285
0
                                OPT_SECTION_BYTE_ORDER, err, err_info)) {
1286
0
        pcapng_destroy_section_info(section_info);
1287
0
        return PCAPNG_BLOCK_ERROR;
1288
0
    }
1289
1290
    /*
1291
     * We don't return these to the caller in pcapng_read().
1292
     */
1293
0
    wblock->internal = true;
1294
1295
0
    return PCAPNG_BLOCK_OK;
1296
0
}
1297
1298
static bool
1299
pcapng_process_if_descr_block_option(wtapng_block_t *wblock,
1300
                                     section_info_t *section_info,
1301
                                     uint16_t option_code,
1302
                                     uint16_t option_length,
1303
                                     const uint8_t *option_content,
1304
                                     int *err, char **err_info)
1305
0
{
1306
0
    if_filter_opt_t if_filter;
1307
1308
    /*
1309
     * Handle option content.
1310
     *
1311
     * ***DO NOT*** add any items to this table that are not
1312
     * standardized option codes in either section 3.5 "Options"
1313
     * of the current pcapng spec, at
1314
     *
1315
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1316
     *
1317
     * or in the list of options in section 4.1 "Section Header Block"
1318
     * of the current pcapng spec, at
1319
     *
1320
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
1321
     *
1322
     * All option codes in this switch statement here must be listed
1323
     * in one of those places as standardized option types.
1324
     */
1325
0
    switch (option_code) {
1326
0
        case(OPT_IDB_NAME): /* if_name */
1327
0
            pcapng_process_string_option(wblock, option_code, option_length,
1328
0
                                         option_content);
1329
0
            break;
1330
0
        case(OPT_IDB_DESCRIPTION): /* if_description */
1331
0
            pcapng_process_string_option(wblock, option_code, option_length,
1332
0
                                         option_content);
1333
0
            break;
1334
0
        case(OPT_IDB_IP4ADDR):
1335
            /*
1336
             * Interface network address and netmask. This option can be
1337
             * repeated multiple times within the same Interface
1338
             * Description Block when multiple IPv4 addresses are assigned
1339
             * to the interface. 192 168 1 1 255 255 255 0
1340
             */
1341
0
            break;
1342
0
        case(OPT_IDB_IP6ADDR):
1343
            /*
1344
             * Interface network address and prefix length (stored in the
1345
             * last byte). This option can be repeated multiple times
1346
             * within the same Interface Description Block when multiple
1347
             * IPv6 addresses are assigned to the interface.
1348
             * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
1349
             * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
1350
             * 40"
1351
             */
1352
0
            break;
1353
0
        case(OPT_IDB_MACADDR):
1354
            /*
1355
             * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
1356
             */
1357
0
            break;
1358
0
        case(OPT_IDB_EUIADDR):
1359
            /*
1360
             * Interface Hardware EUI address (64 bits), if available.
1361
             * 02 34 56 FF FE 78 9A BC
1362
             */
1363
0
             break;
1364
0
        case(OPT_IDB_SPEED): /* if_speed */
1365
0
            pcapng_process_uint64_option(wblock, section_info,
1366
0
                                         OPT_SECTION_BYTE_ORDER,
1367
0
                                         option_code, option_length,
1368
0
                                         option_content);
1369
0
            break;
1370
0
        case(OPT_IDB_TSRESOL): /* if_tsresol */
1371
0
            pcapng_process_uint8_option(wblock, option_code, option_length,
1372
0
                                        option_content);
1373
0
            break;
1374
0
        case(OPT_IDB_TZONE): /* if_tzone */
1375
            /*
1376
             * Time zone for GMT support.  This option has never been
1377
             * specified in greater detail and, unless it were to identify
1378
             * something such as an IANA time zone database timezone,
1379
             * would be insufficient for converting between UTC and local
1380
             * time.  Therefore, it SHOULD NOT be used; instead, the
1381
             * if_iana_tzname option SHOULD be used if time zone
1382
             * information is to be specified.
1383
             *
1384
             * Given that, we don't do anything with it.
1385
             */
1386
0
             break;
1387
0
        case(OPT_IDB_FILTER): /* if_filter */
1388
0
            if (option_length < 1) {
1389
0
                *err = WTAP_ERR_BAD_FILE;
1390
0
                *err_info = ws_strdup_printf("pcapng: IDB interface filter option length %u is < 1",
1391
0
                                            option_length);
1392
                /* XXX - free anything? */
1393
0
                return false;
1394
0
            }
1395
            /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
1396
             * or BPF bytecode.
1397
             */
1398
0
            if (option_content[0] == 0) {
1399
0
                if_filter.type = if_filter_pcap;
1400
0
                if_filter.data.filter_str = g_strndup((char *)option_content+1, option_length-1);
1401
0
                ws_debug("filter_str %s option_length %u",
1402
0
                         if_filter.data.filter_str, option_length);
1403
                /* Fails with multiple options; we silently ignore the failure */
1404
0
                wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1405
0
                g_free(if_filter.data.filter_str);
1406
0
            } else if (option_content[0] == 1) {
1407
                /*
1408
                 * XXX - byte-swap the code and k fields
1409
                 * of each instruction as needed!
1410
                 *
1411
                 * XXX - what if option_length-1 is not a
1412
                 * multiple of the size of a BPF instruction?
1413
                 */
1414
0
                unsigned num_insns;
1415
0
                const uint8_t *insn_in;
1416
1417
0
                if_filter.type = if_filter_bpf;
1418
0
                num_insns = (option_length-1)/8;
1419
0
                insn_in = option_content+1;
1420
0
                if_filter.data.bpf_prog.bpf_prog_len = num_insns;
1421
0
                if_filter.data.bpf_prog.bpf_prog = g_new(wtap_bpf_insn_t, num_insns);
1422
0
                for (unsigned i = 0; i < num_insns; i++) {
1423
0
                    wtap_bpf_insn_t *insn = &if_filter.data.bpf_prog.bpf_prog[i];
1424
1425
0
                    memcpy(&insn->code, insn_in, 2);
1426
0
                    if (section_info->byte_swapped)
1427
0
                        insn->code = GUINT16_SWAP_LE_BE(insn->code);
1428
0
                    insn_in += 2;
1429
0
                    memcpy(&insn->jt, insn_in, 1);
1430
0
                    insn_in += 1;
1431
0
                    memcpy(&insn->jf, insn_in, 1);
1432
0
                    insn_in += 1;
1433
0
                    memcpy(&insn->k, insn_in, 4);
1434
0
                    if (section_info->byte_swapped)
1435
0
                        insn->k = GUINT32_SWAP_LE_BE(insn->k);
1436
0
                    insn_in += 4;
1437
0
                }
1438
                /* Fails with multiple options; we silently ignore the failure */
1439
0
                wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1440
0
                g_free(if_filter.data.bpf_prog.bpf_prog);
1441
0
            }
1442
0
            break;
1443
0
        case(OPT_IDB_OS): /* if_os */
1444
            /*
1445
             * if_os         12  A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
1446
             * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
1447
             * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
1448
             */
1449
0
            pcapng_process_string_option(wblock, option_code, option_length,
1450
0
                                         option_content);
1451
0
            break;
1452
0
        case(OPT_IDB_FCSLEN): /* if_fcslen */
1453
0
            pcapng_process_uint8_option(wblock, option_code, option_length,
1454
0
                                        option_content);
1455
0
            break;
1456
0
        case(OPT_IDB_TSOFFSET):
1457
            /*
1458
             * A 64-bit integer value that specifies an offset (in
1459
             * seconds) that must be added to the timestamp of each packet
1460
             * to obtain the absolute timestamp of a packet. If this option
1461
             * is not present, an offset of 0 is assumed (i.e., timestamps
1462
             * in blocks are absolute timestamps.)
1463
             */
1464
0
            pcapng_process_int64_option(wblock, section_info,
1465
0
                                        OPT_SECTION_BYTE_ORDER,
1466
0
                                        option_code, option_length,
1467
0
                                        option_content);
1468
0
             break;
1469
0
        case(OPT_IDB_HARDWARE): /* if_hardware */
1470
0
            pcapng_process_string_option(wblock, option_code, option_length,
1471
0
                                         option_content);
1472
0
            break;
1473
0
        case(OPT_IDB_TXSPEED): /* if_txspeed */
1474
0
            pcapng_process_uint64_option(wblock, section_info,
1475
0
                                         OPT_SECTION_BYTE_ORDER,
1476
0
                                         option_code, option_length,
1477
0
                                         option_content);
1478
0
            break;
1479
0
        case(OPT_IDB_RXSPEED): /* if_rxspeed */
1480
0
            pcapng_process_uint64_option(wblock, section_info,
1481
0
                                         OPT_SECTION_BYTE_ORDER,
1482
0
                                         option_code, option_length,
1483
0
                                         option_content);
1484
0
            break;
1485
0
        case(OPT_IDB_IANA_TZNAME): /* if_iana_tzname */
1486
0
            pcapng_process_string_option(wblock, option_code, option_length,
1487
0
                                         option_content);
1488
0
            break;
1489
0
        default:
1490
0
            if (!pcapng_process_unhandled_option(wblock, section_info,
1491
0
                                                 option_code, option_length,
1492
0
                                                 option_content,
1493
0
                                                 err, err_info))
1494
0
                return false;
1495
0
            break;
1496
0
    }
1497
0
    return true;
1498
0
}
1499
1500
/* "Interface Description Block" */
1501
static bool
1502
pcapng_read_if_descr_block(wtap *wth, FILE_T fh, uint32_t block_type _U_,
1503
                           uint32_t block_content_length,
1504
                           section_info_t *section_info,
1505
                           wtapng_block_t *wblock, int *err, char **err_info)
1506
0
{
1507
    /* Default time stamp resolution is 10^6 */
1508
0
    uint64_t time_units_per_second = 1000000;
1509
0
    int     tsprecision = 6;
1510
0
    unsigned   opt_cont_buf_len;
1511
0
    pcapng_interface_description_block_t idb;
1512
0
    wtapng_if_descr_mandatory_t* if_descr_mand;
1513
0
    unsigned   link_type;
1514
0
    uint8_t if_tsresol;
1515
1516
    /*
1517
     * Is this block long enough to be an IDB?
1518
     */
1519
0
    if (block_content_length < sizeof idb) {
1520
        /*
1521
         * No.
1522
         */
1523
0
        *err = WTAP_ERR_BAD_FILE;
1524
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of an IDB is less than the minimum IDB content size %zu",
1525
0
                                     block_content_length, sizeof idb);
1526
0
        return false;
1527
0
    }
1528
1529
    /* read block content */
1530
0
    if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
1531
0
        ws_debug("failed to read IDB");
1532
0
        return false;
1533
0
    }
1534
1535
    /*
1536
     * Set wblock->block to a newly-allocated interface ID and information
1537
     * block.
1538
     */
1539
0
    wblock->block = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
1540
1541
    /*
1542
     * Set the mandatory values for the block.
1543
     */
1544
0
    if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1545
0
    if (section_info->byte_swapped) {
1546
0
        link_type = GUINT16_SWAP_LE_BE(idb.linktype);
1547
0
        if_descr_mand->snap_len  = GUINT32_SWAP_LE_BE(idb.snaplen);
1548
0
    } else {
1549
0
        link_type = idb.linktype;
1550
0
        if_descr_mand->snap_len  = idb.snaplen;
1551
0
    }
1552
1553
0
    if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(link_type);
1554
1555
0
    ws_debug("IDB link_type %u (%s), snap %u",
1556
0
             link_type,
1557
0
             wtap_encap_description(if_descr_mand->wtap_encap),
1558
0
             if_descr_mand->snap_len);
1559
1560
0
    if (if_descr_mand->snap_len > wtap_max_snaplen_for_encap(if_descr_mand->wtap_encap)) {
1561
        /*
1562
         * We do not use this value, maybe we should check the
1563
         * snap_len of the packets against it. For now, only warn.
1564
         */
1565
0
        ws_debug("snapshot length %u unrealistic.",
1566
0
                 if_descr_mand->snap_len);
1567
        /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;*/
1568
0
    }
1569
1570
    /* Options */
1571
0
    opt_cont_buf_len = block_content_length - sizeof idb;
1572
0
    if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1573
0
                                pcapng_process_if_descr_block_option,
1574
0
                                OPT_SECTION_BYTE_ORDER, err, err_info))
1575
0
        return false;
1576
1577
    /*
1578
     * Did we get a time stamp precision option?
1579
     */
1580
0
    if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_TSRESOL,
1581
0
                                          &if_tsresol) == WTAP_OPTTYPE_SUCCESS) {
1582
        /*
1583
         * Yes.  Set time_units_per_second appropriately.
1584
         */
1585
0
        uint8_t exponent;
1586
1587
0
        exponent = (uint8_t)(if_tsresol & 0x7f);
1588
0
        if (if_tsresol & 0x80) {
1589
            /*
1590
             * 2^63 fits in a 64-bit unsigned number; 2^64 does not.
1591
             *
1592
             * ((2^64-1)/(2^63) is about 1.99, so, in practice, that
1593
             * fine a time stamp resolution works only if you start
1594
             * capturing at the Unix/POSIX epoch and capture for about
1595
             * 1.9 seconds, so the maximum useful power-of-2 exponent
1596
             * in a pcapng file is less than 63.)
1597
             */
1598
0
            if (exponent > 63) {
1599
                /*
1600
                 * Time units per second won't fit in a 64-bit integer,
1601
                 * so Wireshark's current code can't read the file.
1602
                 */
1603
0
                *err = WTAP_ERR_UNSUPPORTED;
1604
0
                *err_info = ws_strdup_printf("pcapng: IDB power-of-2 time stamp resolution %u > 63",
1605
0
                                             exponent);
1606
0
                return false;
1607
0
            }
1608
1609
            /* 2^exponent */
1610
0
            time_units_per_second = UINT64_C(1) << exponent;
1611
1612
            /*
1613
             * Set the display precision to a value large enough to
1614
             * show the fractional time units we get, so that we
1615
             * don't display more digits than are justified.
1616
             *
1617
             * (That's also used as the base-10 if_tsresol value we use
1618
             * if we write this file as a pcapng file.  Yes, that means
1619
             * that we won't write out the exact value we read in.
1620
             *
1621
             * Dealing with base-2 time stamps is a bit of a mess,
1622
             * thanks to humans counting with their fingers rather
1623
             * than their hands, and it applies to more files than
1624
             * pcapng files, e.g. ERF files.)
1625
             */
1626
0
            if (time_units_per_second >= NS_PER_S)
1627
0
                tsprecision = WTAP_TSPREC_NSEC;
1628
0
            else if (time_units_per_second >= 100000000)
1629
0
                tsprecision = WTAP_TSPREC_10_NSEC;
1630
0
            else if (time_units_per_second >= 10000000)
1631
0
                tsprecision = WTAP_TSPREC_100_NSEC;
1632
0
            else if (time_units_per_second >= 1000000)
1633
0
                tsprecision = WTAP_TSPREC_USEC;
1634
0
            else if (time_units_per_second >= 100000)
1635
0
                tsprecision = WTAP_TSPREC_10_USEC;
1636
0
            else if (time_units_per_second >= 10000)
1637
0
                tsprecision = WTAP_TSPREC_100_USEC;
1638
0
            else if (time_units_per_second >= 1000)
1639
0
                tsprecision = WTAP_TSPREC_MSEC;
1640
0
            else if (time_units_per_second >= 100)
1641
0
                tsprecision = WTAP_TSPREC_10_MSEC;
1642
0
            else if (time_units_per_second >= 10)
1643
0
                tsprecision = WTAP_TSPREC_100_MSEC;
1644
0
            else
1645
0
                tsprecision = WTAP_TSPREC_SEC;
1646
0
        } else {
1647
            /*
1648
             * 10^19 fits in a 64-bit unsigned number; 10^20 does not.
1649
             *
1650
             * ((2^64-1)/(10^19) is about 1.84, so, in practice, that
1651
             * fine a time stamp resolution works only if you start
1652
             * capturing at the Unix/POSIX epoch and capture for about
1653
             * 1.8 seconds, so the maximum useful power-of-10 exponent
1654
             * in a pcapng file is less than 19.)
1655
             */
1656
0
            uint64_t result;
1657
1658
0
            if (exponent > 19) {
1659
                /*
1660
                 * Time units per second won't fit in a 64-bit integer,
1661
                 * so Wireshark's current code can't read the file.
1662
                 */
1663
0
                *err = WTAP_ERR_UNSUPPORTED;
1664
0
                *err_info = ws_strdup_printf("pcapng: IDB power-of-10 time stamp resolution %u > 19",
1665
0
                                             exponent);
1666
0
                return false;
1667
0
            }
1668
1669
            /* 10^exponent */
1670
0
            result = 1;
1671
0
            for (unsigned i = 0; i < exponent; i++) {
1672
0
                result *= 10U;
1673
0
            }
1674
0
            time_units_per_second = result;
1675
1676
            /*
1677
             * Set the display precision to min(exponent, WS_TSPREC_MAX),
1678
             * so that we don't display more digits than are justified.
1679
             * (That's also used as the base-10 if_tsresol value we use
1680
             * if we write this file as a pcapng file.)
1681
             */
1682
0
            if (exponent <= WS_TSPREC_MAX) {
1683
0
                tsprecision = exponent;
1684
0
            } else {
1685
0
                tsprecision = WS_TSPREC_MAX;
1686
0
            }
1687
0
        }
1688
0
        if (time_units_per_second > (((uint64_t)1) << 32)) {
1689
0
            ws_debug("time conversion might be inaccurate");
1690
0
        }
1691
0
    }
1692
1693
    /*
1694
     * Set the time units per second for this interface.
1695
     */
1696
0
    if_descr_mand->time_units_per_second = time_units_per_second;
1697
1698
    /*
1699
     * Set the number of digits of precision to display (and the
1700
     * number to use for this interface if saving to a pcapng
1701
     * file).
1702
     */
1703
0
    if_descr_mand->tsprecision = tsprecision;
1704
1705
    /*
1706
     * If the per-file encapsulation isn't known, set it to this
1707
     * interface's encapsulation.
1708
     *
1709
     * If it *is* known, and it isn't this interface's encapsulation,
1710
     * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
1711
     * have a single encapsulation for all interfaces in the file,
1712
     * so it probably doesn't have a single encapsulation for all
1713
     * packets in the file.
1714
     */
1715
0
    if (wth->file_encap == WTAP_ENCAP_NONE) {
1716
0
        wth->file_encap = if_descr_mand->wtap_encap;
1717
0
    } else {
1718
0
        if (wth->file_encap != if_descr_mand->wtap_encap) {
1719
0
            wth->file_encap = WTAP_ENCAP_PER_PACKET;
1720
0
        }
1721
0
    }
1722
1723
    /*
1724
     * The same applies to the per-file time stamp resolution.
1725
     */
1726
0
    if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
1727
0
        wth->file_tsprec = if_descr_mand->tsprecision;
1728
0
    } else {
1729
0
        if (wth->file_tsprec != if_descr_mand->tsprecision) {
1730
0
            wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1731
0
        }
1732
0
    }
1733
1734
    /*
1735
     * We don't return these to the caller in pcapng_read().
1736
     */
1737
0
    wblock->internal = true;
1738
1739
0
    return true;
1740
0
}
1741
1742
static bool
1743
pcapng_read_decryption_secrets_block(wtap *wth _U_, FILE_T fh,
1744
                                     uint32_t block_read _U_,
1745
                                     uint32_t block_content_length,
1746
                                     section_info_t *section_info,
1747
                                     wtapng_block_t *wblock,
1748
                                     int *err, char **err_info)
1749
0
{
1750
0
    unsigned to_read;
1751
0
    pcapng_decryption_secrets_block_t dsb;
1752
0
    wtapng_dsb_mandatory_t *dsb_mand;
1753
1754
    /*
1755
     * Is this block long enough to be an DSB?
1756
     */
1757
0
    if (block_content_length < sizeof dsb) {
1758
        /*
1759
         * No.
1760
         */
1761
0
        *err = WTAP_ERR_BAD_FILE;
1762
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of an DSB is less than the minimum DSB content size %zu",
1763
0
                                     block_content_length, sizeof dsb);
1764
0
        return false;
1765
0
    }
1766
1767
    /* read block content */
1768
0
    if (!wtap_read_bytes(fh, &dsb, sizeof dsb, err, err_info)) {
1769
0
        ws_debug("failed to read DSB fixed portion");
1770
0
        return false;
1771
0
    }
1772
1773
    /*
1774
     * Set wblock->block to a newly-allocated decryption secrets block.
1775
     */
1776
0
    wblock->block = wtap_block_create(WTAP_BLOCK_DECRYPTION_SECRETS);
1777
1778
    /*
1779
     * Set the mandatory values for the block.
1780
     */
1781
0
    dsb_mand = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
1782
0
    if (section_info->byte_swapped) {
1783
0
      dsb_mand->secrets_type = GUINT32_SWAP_LE_BE(dsb.secrets_type);
1784
0
      dsb_mand->secrets_len = GUINT32_SWAP_LE_BE(dsb.secrets_len);
1785
0
    } else {
1786
0
      dsb_mand->secrets_type = dsb.secrets_type;
1787
0
      dsb_mand->secrets_len = dsb.secrets_len;
1788
0
    }
1789
1790
    /*
1791
     * Is this block long enough to contain the secrets?
1792
     */
1793
0
    if (block_content_length < sizeof dsb + dsb_mand->secrets_len) {
1794
        /*
1795
         * No.
1796
         */
1797
0
        *err = WTAP_ERR_BAD_FILE;
1798
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of an DSB is less the size needed for the secrets in the DSB %zu",
1799
0
                                     block_content_length,
1800
0
                                     sizeof dsb + dsb_mand->secrets_len);
1801
0
        return false;
1802
0
    }
1803
1804
    /*
1805
     * Sanity check: assume the secrets will never need to be larger
1806
     * than 1 GiB.
1807
     */
1808
0
    if (dsb_mand->secrets_len > 1024 * 1024 * 1024) {
1809
0
      *err = WTAP_ERR_BAD_FILE;
1810
0
      *err_info = ws_strdup_printf("pcapng: secrets block is too large: %u", dsb_mand->secrets_len);
1811
0
      return false;
1812
0
    }
1813
1814
0
    dsb_mand->secrets_data = (uint8_t *)g_malloc0(dsb_mand->secrets_len);
1815
0
    if (!wtap_read_bytes(fh, dsb_mand->secrets_data, dsb_mand->secrets_len, err, err_info)) {
1816
0
        ws_debug("failed to read DSB secrets");
1817
0
        return false;
1818
0
    }
1819
1820
    /* Skip past padding and discard options (not supported yet). */
1821
0
    to_read = block_content_length - sizeof dsb - dsb_mand->secrets_len;
1822
0
    if (!wtap_read_bytes(fh, NULL, to_read, err, err_info)) {
1823
0
        ws_debug("failed to read DSB options");
1824
0
        return false;
1825
0
    }
1826
1827
    /*
1828
     * We don't return these to the caller in pcapng_read().
1829
     */
1830
0
    wblock->internal = true;
1831
1832
0
    return true;
1833
0
}
1834
1835
static bool
1836
pcapng_process_packet_block_option(wtapng_block_t *wblock,
1837
                                   section_info_t *section_info,
1838
                                   uint16_t option_code,
1839
                                   uint16_t option_length,
1840
                                   const uint8_t *option_content,
1841
                                   int *err, char **err_info)
1842
0
{
1843
0
    uint64_t tmp64;
1844
0
    packet_verdict_opt_t packet_verdict;
1845
0
    packet_hash_opt_t packet_hash;
1846
1847
    /*
1848
     * Handle option content.
1849
     *
1850
     * ***DO NOT*** add any items to this table that are not
1851
     * standardized option codes in either section 3.5 "Options"
1852
     * of the current pcapng spec, at
1853
     *
1854
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
1855
     *
1856
     * or in the list of options in section 4.3 "Enhanced Packet Block"
1857
     * of the current pcapng spec, at
1858
     *
1859
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-enhanced-packet-block
1860
     *
1861
     * All option codes in this switch statement here must be listed
1862
     * in one of those places as standardized option types.
1863
     */
1864
0
    switch (option_code) {
1865
0
        case(OPT_PKT_FLAGS):
1866
0
            if (option_length != 4) {
1867
0
                *err = WTAP_ERR_BAD_FILE;
1868
0
                *err_info = ws_strdup_printf("pcapng: packet block flags option length %u is not 4",
1869
0
                                            option_length);
1870
                /* XXX - free anything? */
1871
0
                return false;
1872
0
            }
1873
0
            pcapng_process_uint32_option(wblock, section_info,
1874
0
                                         OPT_SECTION_BYTE_ORDER,
1875
0
                                         option_code, option_length,
1876
0
                                         option_content);
1877
0
            break;
1878
0
        case(OPT_PKT_HASH):
1879
0
            if (option_length < 1) {
1880
0
                *err = WTAP_ERR_BAD_FILE;
1881
0
                *err_info = ws_strdup_printf("pcapng: packet block hash option length %u is < 1",
1882
0
                                            option_length);
1883
                /* XXX - free anything? */
1884
0
                return false;
1885
0
            }
1886
0
            packet_hash.type = option_content[0];
1887
0
            packet_hash.hash_bytes =
1888
0
                g_byte_array_new_take((uint8_t *)g_memdup2(&option_content[1],
1889
0
                                                          option_length - 1),
1890
0
                                      option_length - 1);
1891
0
            wtap_block_add_packet_hash_option(wblock->block, option_code, &packet_hash);
1892
0
            wtap_packet_hash_free(&packet_hash);
1893
0
            ws_debug("hash type %u, data len %u",
1894
0
                     option_content[0], option_length - 1);
1895
0
            break;
1896
0
        case(OPT_PKT_DROPCOUNT):
1897
0
            if (option_length != 8) {
1898
0
                *err = WTAP_ERR_BAD_FILE;
1899
0
                *err_info = ws_strdup_printf("pcapng: packet block drop count option length %u is not 8",
1900
0
                                            option_length);
1901
                /* XXX - free anything? */
1902
0
                return false;
1903
0
            }
1904
0
            pcapng_process_uint64_option(wblock, section_info,
1905
0
                                         OPT_SECTION_BYTE_ORDER,
1906
0
                                         option_code, option_length,
1907
0
                                         option_content);
1908
0
            break;
1909
0
        case(OPT_PKT_PACKETID):
1910
0
            if (option_length != 8) {
1911
0
                *err = WTAP_ERR_BAD_FILE;
1912
0
                *err_info = ws_strdup_printf("pcapng: packet block packet id option length %u is not 8",
1913
0
                                            option_length);
1914
                /* XXX - free anything? */
1915
0
                return false;
1916
0
            }
1917
0
            pcapng_process_uint64_option(wblock, section_info,
1918
0
                                         OPT_SECTION_BYTE_ORDER,
1919
0
                                         option_code, option_length,
1920
0
                                         option_content);
1921
0
            break;
1922
0
        case(OPT_PKT_QUEUE):
1923
0
            if (option_length != 4) {
1924
0
                *err = WTAP_ERR_BAD_FILE;
1925
0
                *err_info = ws_strdup_printf("pcapng: packet block queue option length %u is not 4",
1926
0
                                            option_length);
1927
                /* XXX - free anything? */
1928
0
                return false;
1929
0
            }
1930
0
            pcapng_process_uint32_option(wblock, section_info,
1931
0
                                         OPT_SECTION_BYTE_ORDER,
1932
0
                                         option_code, option_length,
1933
0
                                         option_content);
1934
0
            break;
1935
0
        case(OPT_PKT_VERDICT):
1936
0
            if (option_length < 1) {
1937
0
                *err = WTAP_ERR_BAD_FILE;
1938
0
                *err_info = ws_strdup_printf("pcapng: packet block verdict option length %u is < 1",
1939
0
                                            option_length);
1940
                /* XXX - free anything? */
1941
0
                return false;
1942
0
            }
1943
0
            switch (option_content[0]) {
1944
1945
0
                case(OPT_VERDICT_TYPE_HW):
1946
0
                    packet_verdict.type = packet_verdict_hardware;
1947
0
                    packet_verdict.data.verdict_bytes =
1948
0
                        g_byte_array_new_take((uint8_t *)g_memdup2(&option_content[1],
1949
0
                                                                  option_length - 1),
1950
0
                                              option_length - 1);
1951
0
                    break;
1952
1953
0
                case(OPT_VERDICT_TYPE_TC):
1954
0
                    if (option_length != 9) {
1955
0
                        *err = WTAP_ERR_BAD_FILE;
1956
0
                        *err_info = ws_strdup_printf("pcapng: packet block TC verdict option length %u is != 9",
1957
0
                                                    option_length);
1958
                        /* XXX - free anything? */
1959
0
                        return false;
1960
0
                    }
1961
                    /*  Don't cast a uint8_t * into a uint64_t *--the
1962
                     *  uint8_t * may not point to something that's
1963
                     *  aligned correctly.
1964
                     */
1965
0
                    memcpy(&tmp64, &option_content[1], sizeof(uint64_t));
1966
0
                    if (section_info->byte_swapped)
1967
0
                        tmp64 = GUINT64_SWAP_LE_BE(tmp64);
1968
0
                    packet_verdict.type = packet_verdict_linux_ebpf_tc;
1969
0
                    packet_verdict.data.verdict_linux_ebpf_tc = tmp64;
1970
0
                    break;
1971
1972
0
                case(OPT_VERDICT_TYPE_XDP):
1973
0
                    if (option_length != 9) {
1974
0
                        *err = WTAP_ERR_BAD_FILE;
1975
0
                        *err_info = ws_strdup_printf("pcapng: packet block XDP verdict option length %u is != 9",
1976
0
                                                    option_length);
1977
                        /* XXX - free anything? */
1978
0
                        return false;
1979
0
                    }
1980
                    /*  Don't cast a uint8_t * into a uint64_t *--the
1981
                     *  uint8_t * may not point to something that's
1982
                     *  aligned correctly.
1983
                     */
1984
0
                    memcpy(&tmp64, &option_content[1], sizeof(uint64_t));
1985
0
                    if (section_info->byte_swapped)
1986
0
                        tmp64 = GUINT64_SWAP_LE_BE(tmp64);
1987
0
                    packet_verdict.type = packet_verdict_linux_ebpf_xdp;
1988
0
                    packet_verdict.data.verdict_linux_ebpf_xdp = tmp64;
1989
0
                    break;
1990
1991
0
                default:
1992
                    /* Silently ignore unknown verdict types */
1993
0
                    return true;
1994
0
            }
1995
0
            wtap_block_add_packet_verdict_option(wblock->block, option_code, &packet_verdict);
1996
0
            wtap_packet_verdict_free(&packet_verdict);
1997
0
            ws_debug("verdict type %u, data len %u",
1998
0
                     option_content[0], option_length - 1);
1999
0
            break;
2000
0
        case(OPT_PKT_PROCIDTHRDID):
2001
0
            if (option_length != 8) {
2002
0
                *err = WTAP_ERR_BAD_FILE;
2003
0
                *err_info = ws_strdup_printf("pcapng: packet block process id thread id option length %u is not 8",
2004
0
                                            option_length);
2005
                /* XXX - free anything? */
2006
0
                return false;
2007
0
            }
2008
            // XXX - It's two concatenated 32 bit unsigned integers
2009
0
            pcapng_process_uint64_option(wblock, section_info,
2010
0
                                         OPT_SECTION_BYTE_ORDER,
2011
0
                                         option_code, option_length,
2012
0
                                         option_content);
2013
0
            break;
2014
0
        default:
2015
0
            if (!pcapng_process_unhandled_option(wblock, section_info,
2016
0
                                                 option_code, option_length,
2017
0
                                                 option_content,
2018
0
                                                 err, err_info))
2019
0
                return false;
2020
0
            break;
2021
0
    }
2022
0
    return true;
2023
0
}
2024
2025
static bool
2026
pcapng_read_packet_block(wtap *wth _U_, FILE_T fh, uint32_t block_type,
2027
                         uint32_t block_content_length,
2028
                         section_info_t *section_info,
2029
                         wtapng_block_t *wblock,
2030
                         int *err, char **err_info)
2031
0
{
2032
0
    unsigned block_read;
2033
0
    unsigned opt_cont_buf_len;
2034
0
    pcapng_enhanced_packet_block_t epb;
2035
0
    pcapng_packet_block_t pb;
2036
0
    wtapng_packet_t packet;
2037
0
    uint32_t padding;
2038
0
    uint32_t flags;
2039
0
    uint64_t tmp64;
2040
0
    interface_info_t iface_info;
2041
0
    uint64_t ts;
2042
0
    int pseudo_header_len;
2043
0
    int fcslen;
2044
0
    bool enhanced = (block_type == BLOCK_TYPE_EPB);
2045
2046
0
    wblock->block = wtap_block_create(WTAP_BLOCK_PACKET);
2047
2048
0
    if (enhanced) {
2049
        /*
2050
         * Is this block long enough to be an EPB?
2051
         */
2052
0
        if (block_content_length < sizeof epb) {
2053
            /*
2054
             * No.
2055
             */
2056
0
            *err = WTAP_ERR_BAD_FILE;
2057
0
            *err_info = ws_strdup_printf("pcapng: block content length %u of an EPB is less than the minimum EPB content size %zu",
2058
0
                                         block_content_length, sizeof epb);
2059
0
            return false;
2060
0
        }
2061
2062
        /* "Enhanced Packet Block" read fixed part */
2063
0
        if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
2064
0
            ws_debug("failed to read EPB fixed portion");
2065
0
            return false;
2066
0
        }
2067
0
        block_read = (unsigned)sizeof epb;
2068
2069
0
        if (section_info->byte_swapped) {
2070
0
            packet.interface_id        = GUINT32_SWAP_LE_BE(epb.interface_id);
2071
0
            packet.drops_count         = 0xFFFF; /* invalid */
2072
0
            packet.ts_high             = GUINT32_SWAP_LE_BE(epb.timestamp_high);
2073
0
            packet.ts_low              = GUINT32_SWAP_LE_BE(epb.timestamp_low);
2074
0
            packet.cap_len             = GUINT32_SWAP_LE_BE(epb.captured_len);
2075
0
            packet.packet_len          = GUINT32_SWAP_LE_BE(epb.packet_len);
2076
0
        } else {
2077
0
            packet.interface_id        = epb.interface_id;
2078
0
            packet.drops_count         = 0xFFFF; /* invalid */
2079
0
            packet.ts_high             = epb.timestamp_high;
2080
0
            packet.ts_low              = epb.timestamp_low;
2081
0
            packet.cap_len             = epb.captured_len;
2082
0
            packet.packet_len          = epb.packet_len;
2083
0
        }
2084
0
        ws_debug("EPB on interface_id %d, cap_len %d, packet_len %d",
2085
0
                 packet.interface_id, packet.cap_len, packet.packet_len);
2086
0
    } else {
2087
        /*
2088
         * Is this block long enough to be a PB?
2089
         */
2090
0
        if (block_content_length < sizeof pb) {
2091
            /*
2092
             * No.
2093
             */
2094
0
            *err = WTAP_ERR_BAD_FILE;
2095
0
            *err_info = ws_strdup_printf("pcapng: block content length %u of a PB is less than the minimum PB content size %zu",
2096
0
                                         block_content_length, sizeof pb);
2097
0
            return false;
2098
0
        }
2099
2100
        /* "Packet Block" read fixed part */
2101
0
        if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
2102
0
            ws_debug("failed to read packet data");
2103
0
            return false;
2104
0
        }
2105
0
        block_read = (unsigned)sizeof pb;
2106
2107
0
        if (section_info->byte_swapped) {
2108
0
            packet.interface_id        = GUINT16_SWAP_LE_BE(pb.interface_id);
2109
0
            packet.drops_count         = GUINT16_SWAP_LE_BE(pb.drops_count);
2110
0
            packet.ts_high             = GUINT32_SWAP_LE_BE(pb.timestamp_high);
2111
0
            packet.ts_low              = GUINT32_SWAP_LE_BE(pb.timestamp_low);
2112
0
            packet.cap_len             = GUINT32_SWAP_LE_BE(pb.captured_len);
2113
0
            packet.packet_len          = GUINT32_SWAP_LE_BE(pb.packet_len);
2114
0
        } else {
2115
0
            packet.interface_id        = pb.interface_id;
2116
0
            packet.drops_count         = pb.drops_count;
2117
0
            packet.ts_high             = pb.timestamp_high;
2118
0
            packet.ts_low              = pb.timestamp_low;
2119
0
            packet.cap_len             = pb.captured_len;
2120
0
            packet.packet_len          = pb.packet_len;
2121
0
        }
2122
0
        ws_debug("PB on interface_id %d, cap_len %d, packet_len %d",
2123
0
                 packet.interface_id, packet.cap_len, packet.packet_len);
2124
0
    }
2125
0
    ws_debug("packet data: packet_len %u captured_len %u interface_id %u",
2126
0
             packet.packet_len,
2127
0
             packet.cap_len,
2128
0
             packet.interface_id);
2129
2130
0
    if (packet.interface_id >= section_info->interfaces->len) {
2131
0
        *err = WTAP_ERR_BAD_FILE;
2132
0
        *err_info = ws_strdup_printf("pcapng: interface index %u is not less than section interface count %u",
2133
0
                                     packet.interface_id,
2134
0
                                     section_info->interfaces->len);
2135
0
        return false;
2136
0
    }
2137
0
    iface_info = g_array_index(section_info->interfaces, interface_info_t,
2138
0
                               packet.interface_id);
2139
2140
0
    if (packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
2141
0
        *err = WTAP_ERR_BAD_FILE;
2142
0
        *err_info = ws_strdup_printf("pcapng: cap_len %u is larger than maximum supported length %u",
2143
0
                                     packet.cap_len,
2144
0
                                     wtap_max_snaplen_for_encap(iface_info.wtap_encap));
2145
0
        return false;
2146
0
    }
2147
2148
    /*
2149
     * How much padding is there at the end of the packet data?
2150
     */
2151
0
    padding = WS_PADDING_TO_4(packet.cap_len);
2152
2153
    /*
2154
     * Is this block long enough to hold the packet data?
2155
     */
2156
0
    if (enhanced) {
2157
0
        if (block_content_length < sizeof epb + packet.cap_len + padding) {
2158
            /*
2159
             * No.
2160
             */
2161
0
            *err = WTAP_ERR_BAD_FILE;
2162
0
            *err_info = ws_strdup_printf("pcapng: block content length %u of an EPB is too small for %u bytes of packet data",
2163
0
                                         block_content_length, packet.cap_len);
2164
0
            return false;
2165
0
        }
2166
0
    } else {
2167
0
        if (block_content_length < sizeof pb + packet.cap_len + padding) {
2168
            /*
2169
             * No.
2170
             */
2171
0
            *err = WTAP_ERR_BAD_FILE;
2172
0
            *err_info = ws_strdup_printf("pcapng: total block length %u of a PB is too small for %u bytes of packet data",
2173
0
                                         block_content_length, packet.cap_len);
2174
0
            return false;
2175
0
        }
2176
0
    }
2177
2178
0
    ws_debug("Need to read pseudo header of size %u",
2179
0
             pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
2180
2181
0
    wtap_setup_packet_rec(wblock->rec, iface_info.wtap_encap);
2182
0
    wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
2183
2184
0
    ws_debug("encapsulation = %d (%s), pseudo header size = %u.",
2185
0
             iface_info.wtap_encap,
2186
0
             wtap_encap_description(iface_info.wtap_encap),
2187
0
             pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
2188
0
    wblock->rec->rec_header.packet_header.interface_id = packet.interface_id;
2189
0
    wblock->rec->tsprec = iface_info.tsprecision;
2190
2191
0
    memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2192
0
    pseudo_header_len = pcap_process_pseudo_header(fh,
2193
0
                                                   false, /* not a Nokia pcap - not a pcap at all */
2194
0
                                                   iface_info.wtap_encap,
2195
0
                                                   packet.cap_len,
2196
0
                                                   wblock->rec,
2197
0
                                                   err,
2198
0
                                                   err_info);
2199
0
    if (pseudo_header_len < 0) {
2200
0
        return false;
2201
0
    }
2202
0
    block_read += pseudo_header_len;
2203
0
    if (ckd_sub(&wblock->rec->rec_header.packet_header.caplen, packet.cap_len, pseudo_header_len)) {
2204
        /* pcap_process_pseudo_header should never return a length greater
2205
         * than the cap_len it is given. */
2206
0
        *err = WTAP_ERR_INTERNAL;
2207
0
        *err_info = ws_strdup_printf("pcapng: pseudo_header_len (%u) > cap_len (%u)",
2208
0
                                    pseudo_header_len, packet.cap_len);
2209
0
        return false;
2210
0
    }
2211
0
    if (ckd_sub(&wblock->rec->rec_header.packet_header.len, packet.packet_len, pseudo_header_len)) {
2212
        /* This means that the reported length was less than the captured
2213
         * length. Set it to zero, and let the frame dissector fix it, which
2214
         * will add an expert warning. */
2215
0
        wblock->rec->rec_header.packet_header.len = 0;
2216
0
    }
2217
2218
    /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
2219
0
    ts = (((uint64_t)packet.ts_high) << 32) | ((uint64_t)packet.ts_low);
2220
2221
    /* Convert it to seconds and nanoseconds. */
2222
0
    wblock->rec->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
2223
    /* This can overflow if iface_info.time_units_per_seconds > (2^64 - 1) / 10^9;
2224
     * log10((2^64 - 1) / 10^9) ~ 10.266 and log2((2^64 - 1) / 10^9) ~ 32.103,
2225
     * so that's if the power of 10 exponent is greater than 10 or the power of 2
2226
     * exponent is greater than 32.
2227
     *
2228
     * We could test for and use 128 bit integers and platforms and compilers
2229
     * that have it (C23, and gcc, clang, and ICC on most 64-bit platforms).
2230
     * For C23, if we include <limits.h> and BITINT_MAXWIDTH is defined to be
2231
     * at least 128 (or even just 96) we could use unsigned _BitInt(128).
2232
     * If __SIZEOF_INT128__ is defined we can use unsigned __int128. Some
2233
     * testing (including with godbolt.org) suggests it's faster to check
2234
     * overflow and handle our two special cases.
2235
     */
2236
0
    uint64_t ts_frac = ts % iface_info.time_units_per_second;
2237
0
    uint64_t ts_ns;
2238
0
    if (ckd_mul(&ts_ns, ts_frac, NS_PER_S)) {
2239
        /* We have 10^N where N > 10 or 2^N where N > 32. */
2240
0
        if (!iface_info.tsresol_binary) {
2241
            /* 10^N where N > 10, so this divides evenly. */
2242
0
            ws_assert(iface_info.time_units_per_second > NS_PER_S);
2243
0
            wblock->rec->ts.nsecs = (int)(ts_frac / (iface_info.time_units_per_second / NS_PER_S));
2244
0
        } else {
2245
            /* Multiplying a 64 bit integer by a 32 bit integer, then dividing
2246
             * by 2^N, where N > 32. */
2247
0
            uint64_t ts_frac_low = (ts_frac & 0xFFFFFFFF) * NS_PER_S;
2248
0
            uint64_t ts_frac_high = (ts_frac >> 32) * NS_PER_S;
2249
            // Add the carry.
2250
0
            ts_frac_high += ts_frac_low >> 32;
2251
            //ts_frac_low &= 0xFFFFFFFF;
2252
0
            ws_assert(iface_info.tsresol_binary > 32);
2253
0
            uint8_t high_shift = iface_info.tsresol_binary - 32;
2254
0
            wblock->rec->ts.nsecs = (int)(ts_frac_high >> high_shift);
2255
0
        }
2256
0
    } else {
2257
0
        wblock->rec->ts.nsecs = (int)(ts_ns / iface_info.time_units_per_second);
2258
0
    }
2259
2260
    /* Add the time stamp offset. */
2261
0
    wblock->rec->ts.secs = (time_t)(wblock->rec->ts.secs + iface_info.tsoffset);
2262
2263
    /* "(Enhanced) Packet Block" read capture data */
2264
0
    if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2265
0
                                packet.cap_len - pseudo_header_len, err, err_info))
2266
0
        return false;
2267
0
    block_read += packet.cap_len - pseudo_header_len;
2268
2269
    /* jump over potential padding bytes at end of the packet data */
2270
0
    if (padding != 0) {
2271
0
        if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
2272
0
            return false;
2273
0
        block_read += padding;
2274
0
    }
2275
2276
    /* FCS length default */
2277
0
    fcslen = iface_info.fcslen;
2278
2279
    /* Options */
2280
0
    opt_cont_buf_len = block_content_length - block_read;
2281
0
    if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2282
0
                                pcapng_process_packet_block_option,
2283
0
                                OPT_SECTION_BYTE_ORDER, err, err_info))
2284
0
        return false;
2285
2286
    /*
2287
     * Did we get a packet flags option?
2288
     */
2289
0
    if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(wblock->block, OPT_PKT_FLAGS, &flags)) {
2290
0
        if (PACK_FLAGS_FCS_LENGTH(flags) != 0) {
2291
            /*
2292
             * The FCS length is present, but in units of octets, not
2293
             * bits; convert it to bits.
2294
             */
2295
0
            fcslen = PACK_FLAGS_FCS_LENGTH(flags)*8;
2296
0
        }
2297
0
    }
2298
    /*
2299
     * How about a drop_count option? If not, set it from other sources
2300
     */
2301
0
    if (WTAP_OPTTYPE_SUCCESS != wtap_block_get_uint64_option_value(wblock->block, OPT_PKT_DROPCOUNT, &tmp64) && packet.drops_count != 0xFFFF) {
2302
0
        wtap_block_add_uint64_option(wblock->block, OPT_PKT_DROPCOUNT, (uint64_t)packet.drops_count);
2303
0
    }
2304
2305
0
    pcap_read_post_process(false, iface_info.wtap_encap, wblock->rec,
2306
0
                           section_info->byte_swapped, fcslen);
2307
2308
    /*
2309
     * We return these to the caller in pcapng_read().
2310
     */
2311
0
    wblock->internal = false;
2312
2313
    /*
2314
     * We want dissectors (particularly packet_frame) to be able to
2315
     * access packet comments and whatnot that are in the block. wblock->block
2316
     * will be unref'd by pcapng_seek_read(), so move the block to where
2317
     * dissectors can find it.
2318
     */
2319
0
    wblock->rec->block = wblock->block;
2320
0
    wblock->block = NULL;
2321
2322
0
    return true;
2323
0
}
2324
2325
2326
static bool
2327
pcapng_read_simple_packet_block(wtap *wth _U_, FILE_T fh,
2328
                                uint32_t block_type _U_,
2329
                                uint32_t block_content_length,
2330
                                section_info_t *section_info,
2331
                                wtapng_block_t *wblock,
2332
                                int *err, char **err_info)
2333
0
{
2334
0
    pcapng_simple_packet_block_t spb;
2335
0
    wtapng_simple_packet_t simple_packet;
2336
0
    uint32_t padding;
2337
0
    interface_info_t iface_info;
2338
0
    int pseudo_header_len;
2339
2340
    /*
2341
     * Is this block long enough to be an SPB?
2342
     */
2343
0
    if (block_content_length < sizeof spb) {
2344
        /*
2345
         * No.
2346
         */
2347
0
        *err = WTAP_ERR_BAD_FILE;
2348
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of an SPB is less than the minimum SPB content size %zu",
2349
0
                                     block_content_length, sizeof spb);
2350
0
        return false;
2351
0
    }
2352
2353
    /* "Simple Packet Block" read fixed part */
2354
0
    if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
2355
0
        ws_debug("failed to read SPB fixed portion");
2356
0
        return false;
2357
0
    }
2358
2359
0
    if (section_info->byte_swapped) {
2360
0
        simple_packet.packet_len   = GUINT32_SWAP_LE_BE(spb.packet_len);
2361
0
    } else {
2362
0
        simple_packet.packet_len   = spb.packet_len;
2363
0
    }
2364
2365
0
    if (0 >= section_info->interfaces->len) {
2366
0
        *err = WTAP_ERR_BAD_FILE;
2367
0
        *err_info = g_strdup("pcapng: SPB appeared before any IDBs in the section");
2368
0
        return false;
2369
0
    }
2370
0
    iface_info = g_array_index(section_info->interfaces, interface_info_t, 0);
2371
2372
    /*
2373
     * The captured length is not a field in the SPB; it can be
2374
     * calculated as the minimum of the snapshot length from the
2375
     * IDB and the packet length, as per the pcapng spec. An IDB
2376
     * snapshot length of 0 means no limit.
2377
     */
2378
0
    simple_packet.cap_len = simple_packet.packet_len;
2379
0
    if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
2380
0
        simple_packet.cap_len = iface_info.snap_len;
2381
0
    ws_debug("packet data: packet_len %u",
2382
0
             simple_packet.packet_len);
2383
2384
0
    if (simple_packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
2385
0
        *err = WTAP_ERR_BAD_FILE;
2386
0
        *err_info = ws_strdup_printf("pcapng: cap_len %u is larger than maximum supported length %u",
2387
0
                                     simple_packet.cap_len,
2388
0
                                     wtap_max_snaplen_for_encap(iface_info.wtap_encap));
2389
0
        return false;
2390
0
    }
2391
2392
    /*
2393
     * How much padding is there at the end of the packet data?
2394
     */
2395
0
    padding = WS_PADDING_TO_4(simple_packet.cap_len);
2396
2397
    /*
2398
     * Is this block long enough to hold the packet data?
2399
     */
2400
0
    if (block_content_length < sizeof spb + simple_packet.cap_len + padding) {
2401
        /*
2402
         * No.  That means that the problem is with the packet
2403
         * length; the snapshot length can be bigger than the amount
2404
         * of packet data in the block, as it's a *maximum* length,
2405
         * not a *minimum* length.
2406
         */
2407
0
        *err = WTAP_ERR_BAD_FILE;
2408
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of an SPB is too small for %u bytes of packet data",
2409
0
                                     block_content_length, simple_packet.cap_len);
2410
0
        return false;
2411
0
    }
2412
2413
0
    ws_debug("Need to read pseudo header of size %u",
2414
0
             pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
2415
2416
    /* No time stamp in a simple packet block; no options, either */
2417
0
    wtap_setup_packet_rec(wblock->rec, iface_info.wtap_encap);
2418
0
    wblock->rec->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
2419
0
    wblock->rec->rec_header.packet_header.interface_id = 0;
2420
0
    wblock->rec->tsprec = iface_info.tsprecision;
2421
0
    wblock->rec->ts.secs = 0;
2422
0
    wblock->rec->ts.nsecs = 0;
2423
0
    wblock->rec->rec_header.packet_header.interface_id = 0;
2424
2425
0
    memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2426
0
    pseudo_header_len = pcap_process_pseudo_header(fh,
2427
0
                                                   false, /* not a Nokia pcap - not a pcap at all */
2428
0
                                                   iface_info.wtap_encap,
2429
0
                                                   simple_packet.cap_len,
2430
0
                                                   wblock->rec,
2431
0
                                                   err,
2432
0
                                                   err_info);
2433
0
    if (pseudo_header_len < 0) {
2434
0
        return false;
2435
0
    }
2436
0
    if (ckd_sub(&wblock->rec->rec_header.packet_header.caplen, simple_packet.cap_len, pseudo_header_len)) {
2437
        /* pcap_process_pseudo_header should never return a length greater
2438
         * than the cap_len it is given. */
2439
0
        *err = WTAP_ERR_INTERNAL;
2440
0
        *err_info = ws_strdup_printf("pcapng: pseudo_header_len (%u) > cap_len (%u)",
2441
0
                                    pseudo_header_len, simple_packet.cap_len);
2442
0
        return false;
2443
0
    }
2444
0
    if (ckd_sub(&wblock->rec->rec_header.packet_header.len, simple_packet.packet_len, pseudo_header_len)) {
2445
        /* This means that the reported length was less than the captured
2446
         * length. Set it to zero, and let the frame dissector fix it, which
2447
         * will add an expert warning. */
2448
0
        wblock->rec->rec_header.packet_header.len = 0;
2449
0
    }
2450
2451
    /* "Simple Packet Block" read capture data */
2452
0
    if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
2453
0
                                simple_packet.cap_len - pseudo_header_len, err, err_info))
2454
0
        return false;
2455
2456
    /* jump over potential padding bytes at end of the packet data */
2457
0
    if (padding != 0) {
2458
0
        if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
2459
0
            return false;
2460
0
    }
2461
2462
0
    pcap_read_post_process(false, iface_info.wtap_encap, wblock->rec,
2463
0
                           section_info->byte_swapped, iface_info.fcslen);
2464
2465
    /*
2466
     * We return these to the caller in pcapng_read().
2467
     */
2468
0
    wblock->internal = false;
2469
2470
    /*
2471
     * We want dissectors (particularly packet_frame) to be able to
2472
     * access packet comments and whatnot that are in the block
2473
     * (not that there will be any, as an SPB has no options). wblock->block
2474
     * will be unref'd by pcapng_seek_read(), so move the block to where
2475
     * dissectors can find it.
2476
     */
2477
0
    wblock->rec->block = wblock->block;
2478
0
    wblock->block = NULL;
2479
2480
0
    return true;
2481
0
}
2482
2483
0
#define NRES_ENDOFRECORD 0
2484
0
#define NRES_IP4RECORD 1
2485
0
#define NRES_IP6RECORD 2
2486
/* IPv6 + MAXDNSNAMELEN */
2487
0
#define INITIAL_NRB_REC_SIZE (16 + MAXDNSNAMELEN)
2488
2489
/*
2490
 * Find the end of the NUL-terminated name the beginning of which is pointed
2491
 * to by p; record_len is the number of bytes remaining in the record.
2492
 *
2493
 * Return the length of the name, including the terminating NUL.
2494
 *
2495
 * If we don't find a terminating NUL, return -1 and set *err and
2496
 * *err_info appropriately.
2497
 */
2498
static int
2499
name_resolution_block_find_name_end(const char *p, unsigned record_len, int *err,
2500
                                    char **err_info)
2501
0
{
2502
0
    int namelen;
2503
2504
0
    namelen = 0;
2505
0
    for (;;) {
2506
0
        if (record_len == 0) {
2507
            /*
2508
             * We ran out of bytes in the record without
2509
             * finding a NUL.
2510
             */
2511
0
            *err = WTAP_ERR_BAD_FILE;
2512
0
            *err_info = g_strdup("pcapng: NRB record has non-null-terminated host name");
2513
0
            return -1;
2514
0
        }
2515
0
        if (*p == '\0')
2516
0
            break;  /* that's the terminating NUL */
2517
0
        p++;
2518
0
        record_len--;
2519
0
        namelen++;      /* count this byte */
2520
0
    }
2521
2522
    /* Include the NUL in the name length. */
2523
0
    return namelen + 1;
2524
0
}
2525
2526
static bool
2527
pcapng_process_name_resolution_block_option(wtapng_block_t *wblock,
2528
                                            section_info_t *section_info,
2529
                                            uint16_t option_code,
2530
                                            uint16_t option_length,
2531
                                            const uint8_t *option_content,
2532
                                            int *err, char **err_info)
2533
0
{
2534
    /*
2535
     * Handle option content.
2536
     *
2537
     * ***DO NOT*** add any items to this table that are not
2538
     * standardized option codes in either section 3.5 "Options"
2539
     * of the current pcapng spec, at
2540
     *
2541
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
2542
     *
2543
     * or in the list of options in section 4.1 "Section Header Block"
2544
     * of the current pcapng spec, at
2545
     *
2546
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
2547
     *
2548
     * All option codes in this switch statement here must be listed
2549
     * in one of those places as standardized option types.
2550
     */
2551
0
    switch (option_code) {
2552
        /* TODO:
2553
         * ns_dnsname     2
2554
         * ns_dnsIP4addr  3
2555
         * ns_dnsIP6addr  4
2556
         */
2557
0
        default:
2558
0
            if (!pcapng_process_unhandled_option(wblock, section_info,
2559
0
                                                 option_code, option_length,
2560
0
                                                 option_content,
2561
0
                                                 err, err_info))
2562
0
                return false;
2563
0
            break;
2564
0
    }
2565
0
    return true;
2566
0
}
2567
2568
static bool
2569
pcapng_read_name_resolution_block(wtap *wth _U_, FILE_T fh,
2570
                                  uint32_t block_type _U_,
2571
                                  uint32_t block_content_length,
2572
                                  section_info_t *section_info,
2573
                                  wtapng_block_t *wblock,
2574
                                  int *err, char **err_info)
2575
0
{
2576
0
    unsigned to_read;
2577
0
    pcapng_name_resolution_block_t nrb;
2578
0
    Buffer nrb_rec;
2579
0
    uint32_t v4_addr;
2580
0
    unsigned record_len, opt_cont_buf_len;
2581
0
    const char *namep;
2582
0
    int namelen;
2583
0
    wtapng_nrb_mandatory_t *nrb_mand;
2584
2585
    /*
2586
     * Is this block long enough to be an NRB?
2587
     * There must be at least an "end of records" record.
2588
     */
2589
0
    if (block_content_length < sizeof nrb) {
2590
        /*
2591
         * No.
2592
         */
2593
0
        *err = WTAP_ERR_BAD_FILE;
2594
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of an NRB is less than the minimum NRB content size %zu",
2595
0
                                     block_content_length, sizeof nrb);
2596
0
        return false;
2597
0
    }
2598
2599
0
    to_read = block_content_length;
2600
2601
0
    ws_debug("total content %u bytes", block_content_length);
2602
2603
    /* Ensure we have a name resolution block */
2604
0
    if (wblock->block == NULL) {
2605
0
        wblock->block = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
2606
0
    }
2607
2608
    /*
2609
     * Set the mandatory values for the block.
2610
     */
2611
0
    nrb_mand = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
2612
2613
    /*
2614
     * Start out with a buffer big enough for an IPv6 address and one
2615
     * 64-byte name; we'll make the buffer bigger if necessary.
2616
     */
2617
0
    ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
2618
0
    while (to_read != 0) {
2619
0
        unsigned padding;
2620
2621
        /*
2622
         * There must be at least one record's worth of data
2623
         * here.
2624
         */
2625
0
        if (to_read < sizeof nrb) {
2626
0
            ws_buffer_free(&nrb_rec);
2627
0
            *err = WTAP_ERR_BAD_FILE;
2628
0
            *err_info = ws_strdup_printf("pcapng: %u bytes left in the block < NRB record header size %zu",
2629
0
                                         to_read, sizeof nrb);
2630
0
            return false;
2631
0
        }
2632
0
        if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
2633
0
            ws_buffer_free(&nrb_rec);
2634
0
            ws_debug("failed to read record header");
2635
0
            return false;
2636
0
        }
2637
0
        to_read -= (unsigned)sizeof nrb;
2638
2639
0
        if (section_info->byte_swapped) {
2640
0
            nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
2641
0
            nrb.record_len  = GUINT16_SWAP_LE_BE(nrb.record_len);
2642
0
        }
2643
2644
0
        padding = WS_PADDING_TO_4(nrb.record_len); /* padding at end of record */
2645
0
        if (to_read < nrb.record_len + padding) {
2646
0
            ws_buffer_free(&nrb_rec);
2647
0
            *err = WTAP_ERR_BAD_FILE;
2648
0
            *err_info = ws_strdup_printf("pcapng: %u bytes left in the block < NRB record length + padding %u",
2649
0
                                         to_read, nrb.record_len + padding);
2650
0
            return false;
2651
0
        }
2652
0
        switch (nrb.record_type) {
2653
0
            case NRES_ENDOFRECORD:
2654
                /* There shouldn't be any more data - but there MAY be options */
2655
0
                goto read_options;
2656
0
                break;
2657
0
            case NRES_IP4RECORD:
2658
                /*
2659
                 * The smallest possible record must have
2660
                 * a 4-byte IPv4 address, hence a minimum
2661
                 * of 4 bytes.
2662
                 *
2663
                 * (The pcapng spec really indicates
2664
                 * that it must be at least 5 bytes,
2665
                 * as there must be at least one name,
2666
                 * and it really must be at least 6
2667
                 * bytes, as the name mustn't be null,
2668
                 * but there's no need to fail if there
2669
                 * aren't any names at all, and we
2670
                 * should report a null name as such.)
2671
                 */
2672
0
                if (nrb.record_len < 4) {
2673
0
                    ws_buffer_free(&nrb_rec);
2674
0
                    *err = WTAP_ERR_BAD_FILE;
2675
0
                    *err_info = ws_strdup_printf("pcapng: NRB IPv4 record length %u < minimum length 4",
2676
0
                                                 nrb.record_len);
2677
0
                    return false;
2678
0
                }
2679
0
                ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2680
0
                if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2681
0
                                     nrb.record_len, err, err_info)) {
2682
0
                    ws_buffer_free(&nrb_rec);
2683
0
                    ws_debug("failed to read IPv4 record data");
2684
0
                    return false;
2685
0
                }
2686
0
                to_read -= nrb.record_len;
2687
2688
                /*
2689
                 * Scan through all the names in
2690
                 * the record and add them.
2691
                 */
2692
0
                memcpy(&v4_addr,
2693
0
                       ws_buffer_start_ptr(&nrb_rec), 4);
2694
                /* IPv4 address is in big-endian order in the file always, which is how we store
2695
                   it internally as well, so don't byte-swap it */
2696
0
                for (namep = (const char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
2697
0
                     record_len != 0;
2698
0
                     namep += namelen, record_len -= namelen) {
2699
                    /*
2700
                     * Scan forward for a null byte.
2701
                     *
2702
                     * This will never return a value > record_len.
2703
                     */
2704
0
                    namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2705
0
                    if (namelen == -1) {
2706
0
                        ws_buffer_free(&nrb_rec);
2707
0
                        return false;      /* fail */
2708
0
                    }
2709
0
                    hashipv4_t *tp = g_new0(hashipv4_t, 1);
2710
0
                    tp->addr = v4_addr;
2711
0
                    (void) g_strlcpy(tp->name, namep, MAXDNSNAMELEN);
2712
0
                    nrb_mand->ipv4_addr_list = g_list_prepend(nrb_mand->ipv4_addr_list, tp);
2713
0
                }
2714
0
                break;
2715
0
            case NRES_IP6RECORD:
2716
                /*
2717
                 * The smallest possible record must have
2718
                 * a 16-byte IPv6 address, hence a minimum
2719
                 * of 16 bytes.
2720
                 *
2721
                 * (The pcapng spec really indicates
2722
                 * that it must be at least 17 bytes,
2723
                 * as there must be at least one name,
2724
                 * and it really must be at least 18
2725
                 * bytes, as the name mustn't be null,
2726
                 * but there's no need to fail if there
2727
                 * aren't any names at all, and we
2728
                 * should report a null name as such.)
2729
                 */
2730
0
                if (nrb.record_len < 16) {
2731
0
                    ws_buffer_free(&nrb_rec);
2732
0
                    *err = WTAP_ERR_BAD_FILE;
2733
0
                    *err_info = ws_strdup_printf("pcapng: NRB record length for IPv6 record %u < minimum length 16",
2734
0
                                                 nrb.record_len);
2735
0
                    return false;
2736
0
                }
2737
0
                ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2738
0
                if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2739
0
                                     nrb.record_len, err, err_info)) {
2740
0
                    ws_buffer_free(&nrb_rec);
2741
0
                    return false;
2742
0
                }
2743
0
                to_read -= nrb.record_len;
2744
2745
0
                for (namep = (const char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
2746
0
                     record_len != 0;
2747
0
                     namep += namelen, record_len -= namelen) {
2748
                    /*
2749
                     * Scan forward for a null byte.
2750
                     *
2751
                     * This will never return a value > record_len.
2752
                     */
2753
0
                    namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2754
0
                    if (namelen == -1) {
2755
0
                        ws_buffer_free(&nrb_rec);
2756
0
                        return false;      /* fail */
2757
0
                    }
2758
0
                    hashipv6_t *tp = g_new0(hashipv6_t, 1);
2759
0
                    memcpy(tp->addr, ws_buffer_start_ptr(&nrb_rec), sizeof tp->addr);
2760
0
                    (void) g_strlcpy(tp->name, namep, MAXDNSNAMELEN);
2761
0
                    nrb_mand->ipv6_addr_list = g_list_prepend(nrb_mand->ipv6_addr_list, tp);
2762
0
                }
2763
0
                break;
2764
0
            default:
2765
0
                ws_debug("unknown record type 0x%x", nrb.record_type);
2766
0
                if (!wtap_read_bytes(fh, NULL, nrb.record_len, err, err_info)) {
2767
0
                    ws_buffer_free(&nrb_rec);
2768
0
                    return false;
2769
0
                }
2770
0
                to_read -= nrb.record_len;
2771
0
                break;
2772
0
        }
2773
2774
        /* Skip padding */
2775
0
        if (!wtap_read_bytes(fh, NULL, padding, err, err_info)) {
2776
0
            ws_buffer_free(&nrb_rec);
2777
0
            return false;
2778
0
        }
2779
0
        to_read -= padding;
2780
0
    }
2781
2782
0
read_options:
2783
    /* Options */
2784
0
    opt_cont_buf_len = to_read;
2785
0
    if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2786
0
                                pcapng_process_name_resolution_block_option,
2787
0
                                OPT_SECTION_BYTE_ORDER, err, err_info)) {
2788
0
        ws_buffer_free(&nrb_rec);
2789
0
        return false;
2790
0
    }
2791
2792
0
    ws_buffer_free(&nrb_rec);
2793
2794
    /*
2795
     * We don't return these to the caller in pcapng_read().
2796
     */
2797
0
    wblock->internal = true;
2798
2799
0
    return true;
2800
0
}
2801
2802
static bool
2803
pcapng_process_interface_statistics_block_option(wtapng_block_t *wblock,
2804
                                                 section_info_t *section_info,
2805
                                                 uint16_t option_code,
2806
                                                 uint16_t option_length,
2807
                                                 const uint8_t *option_content,
2808
                                                 int *err, char **err_info)
2809
0
{
2810
    /*
2811
     * Handle option content.
2812
     *
2813
     * ***DO NOT*** add any items to this table that are not
2814
     * standardized option codes in either section 3.5 "Options"
2815
     * of the current pcapng spec, at
2816
     *
2817
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-options
2818
     *
2819
     * or in the list of options in section 4.1 "Section Header Block"
2820
     * of the current pcapng spec, at
2821
     *
2822
     *    https://pcapng.github.io/pcapng/draft-ietf-opsawg-pcapng.html#name-section-header-block
2823
     *
2824
     * All option codes in this switch statement here must be listed
2825
     * in one of those places as standardized option types.
2826
     */
2827
0
    switch (option_code) {
2828
0
        case(OPT_ISB_STARTTIME): /* isb_starttime */
2829
0
            pcapng_process_timestamp_option(wblock, section_info,
2830
0
                                            OPT_SECTION_BYTE_ORDER,
2831
0
                                            option_code, option_length,
2832
0
                                            option_content);
2833
0
            break;
2834
0
        case(OPT_ISB_ENDTIME): /* isb_endtime */
2835
0
            pcapng_process_timestamp_option(wblock, section_info,
2836
0
                                            OPT_SECTION_BYTE_ORDER,
2837
0
                                            option_code, option_length,
2838
0
                                            option_content);
2839
0
            break;
2840
0
        case(OPT_ISB_IFRECV): /* isb_ifrecv */
2841
0
            pcapng_process_uint64_option(wblock, section_info,
2842
0
                                         OPT_SECTION_BYTE_ORDER,
2843
0
                                         option_code, option_length,
2844
0
                                         option_content);
2845
0
            break;
2846
0
        case(OPT_ISB_IFDROP): /* isb_ifdrop */
2847
0
            pcapng_process_uint64_option(wblock, section_info,
2848
0
                                         OPT_SECTION_BYTE_ORDER,
2849
0
                                         option_code, option_length,
2850
0
                                         option_content);
2851
0
            break;
2852
0
        case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2853
0
            pcapng_process_uint64_option(wblock, section_info,
2854
0
                                         OPT_SECTION_BYTE_ORDER,
2855
0
                                         option_code, option_length,
2856
0
                                         option_content);
2857
0
            break;
2858
0
        case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2859
0
            pcapng_process_uint64_option(wblock, section_info,
2860
0
                                         OPT_SECTION_BYTE_ORDER,
2861
0
                                         option_code, option_length,
2862
0
                                         option_content);
2863
0
            break;
2864
0
        case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8  */
2865
0
            pcapng_process_uint64_option(wblock, section_info,
2866
0
                                         OPT_SECTION_BYTE_ORDER,
2867
0
                                         option_code, option_length,
2868
0
                                         option_content);
2869
0
            break;
2870
0
        default:
2871
0
            if (!pcapng_process_unhandled_option(wblock, section_info,
2872
0
                                                 option_code, option_length,
2873
0
                                                 option_content,
2874
0
                                                 err, err_info))
2875
0
                return false;
2876
0
            break;
2877
0
    }
2878
0
    return true;
2879
0
}
2880
2881
static bool
2882
pcapng_read_interface_statistics_block(wtap *wth _U_, FILE_T fh,
2883
                                       uint32_t block_type _U_,
2884
                                       uint32_t block_content_length,
2885
                                       section_info_t *section_info,
2886
                                       wtapng_block_t *wblock,
2887
                                       int *err, char **err_info)
2888
0
{
2889
0
    unsigned opt_cont_buf_len;
2890
0
    pcapng_interface_statistics_block_t isb;
2891
0
    wtapng_if_stats_mandatory_t* if_stats_mand;
2892
2893
    /*
2894
     * Is this block long enough to be an ISB?
2895
     */
2896
0
    if (block_content_length < sizeof isb) {
2897
        /*
2898
         * No.
2899
         */
2900
0
        *err = WTAP_ERR_BAD_FILE;
2901
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of an ISB is less than the minimum ISB content size %zu",
2902
0
                                     block_content_length, sizeof isb);
2903
0
        return false;
2904
0
    }
2905
2906
    /* "Interface Statistics Block" read fixed part */
2907
0
    if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
2908
0
        ws_debug("failed to read packet data");
2909
0
        return false;
2910
0
    }
2911
2912
    /*
2913
     * Set wblock->block to a newly-allocated interface statistics block.
2914
     */
2915
0
    wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
2916
2917
    /*
2918
     * Set the mandatory values for the block.
2919
     */
2920
0
    if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
2921
0
    if (section_info->byte_swapped) {
2922
0
        if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
2923
0
        if_stats_mand->ts_high      = GUINT32_SWAP_LE_BE(isb.timestamp_high);
2924
0
        if_stats_mand->ts_low       = GUINT32_SWAP_LE_BE(isb.timestamp_low);
2925
0
    } else {
2926
0
        if_stats_mand->interface_id = isb.interface_id;
2927
0
        if_stats_mand->ts_high      = isb.timestamp_high;
2928
0
        if_stats_mand->ts_low       = isb.timestamp_low;
2929
0
    }
2930
0
    ws_debug("interface_id %u", if_stats_mand->interface_id);
2931
2932
    /* Options */
2933
0
    opt_cont_buf_len = block_content_length - sizeof isb;
2934
0
    if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2935
0
                                pcapng_process_interface_statistics_block_option,
2936
0
                                OPT_SECTION_BYTE_ORDER, err, err_info))
2937
0
        return false;
2938
2939
    /*
2940
     * We don't return these to the caller in pcapng_read().
2941
     */
2942
0
    wblock->internal = true;
2943
2944
0
    return true;
2945
0
}
2946
2947
void
2948
register_pcapng_custom_block_enterprise_handler(unsigned enterprise_number, pcapng_custom_block_enterprise_handler_t const *handler)
2949
15
{
2950
15
    g_hash_table_insert(custom_enterprise_handlers, GUINT_TO_POINTER(enterprise_number), (void *)handler);
2951
15
}
2952
2953
static bool
2954
pcapng_read_custom_block(wtap *wth _U_, FILE_T fh, uint32_t block_type,
2955
                         uint32_t block_content_length,
2956
                         section_info_t *section_info, wtapng_block_t *wblock,
2957
                         int *err, char **err_info)
2958
0
{
2959
0
    pcapng_custom_block_t cb;
2960
0
    uint32_t pen;
2961
0
    pcapng_custom_block_enterprise_handler_t const *pen_handler;
2962
2963
    /* Is this block long enough to be an CB? */
2964
0
    if (block_content_length < sizeof cb) {
2965
        /*
2966
         * No.
2967
         */
2968
0
        *err = WTAP_ERR_BAD_FILE;
2969
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of a CB is less than the minimum CB content size %zu",
2970
0
                                     block_content_length, sizeof cb);
2971
0
        return false;
2972
0
    }
2973
2974
0
    wblock->block = wtap_block_create(WTAP_BLOCK_CUSTOM);
2975
2976
    /* Custom block read fixed part */
2977
0
    if (!wtap_read_bytes(fh, &cb, sizeof cb, err, err_info)) {
2978
0
        ws_debug("failed to read pen");
2979
0
        return false;
2980
0
    }
2981
0
    if (section_info->byte_swapped) {
2982
0
        pen = GUINT32_SWAP_LE_BE(cb.pen);
2983
0
    } else {
2984
0
        pen = cb.pen;
2985
0
    }
2986
0
    uint32_t block_payload_length = block_content_length - sizeof cb;
2987
0
    ws_debug("pen %u, custom data and option length %u", pen, block_payload_length);
2988
2989
0
    wtap_setup_custom_block_rec(wblock->rec, pen, block_payload_length,
2990
0
                                (block_type == BLOCK_TYPE_CB_COPY));
2991
2992
0
    pen_handler = (pcapng_custom_block_enterprise_handler_t const *)g_hash_table_lookup(custom_enterprise_handlers, GUINT_TO_POINTER(pen));
2993
2994
0
    if (pen_handler != NULL)
2995
0
    {
2996
0
        if (!pen_handler->parser(fh, section_info, wblock, err, err_info)) {
2997
0
            if (*err == WTAP_ERR_REC_MALFORMED) {
2998
                /* Allow the packet to be kept */
2999
0
                wblock->rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NULL;
3000
0
                *err = 0;
3001
0
                g_free(*err_info);
3002
0
                *err_info = NULL;
3003
0
            }
3004
0
            else {
3005
0
                return false;
3006
0
            }
3007
0
         }
3008
0
    }
3009
0
    else
3010
0
    {
3011
0
        ws_debug("unknown pen %u", pen);
3012
0
        if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
3013
0
                                    block_payload_length, err, err_info))
3014
0
            return false;
3015
0
    }
3016
3017
0
    wblock->rec->block = wblock->block;
3018
0
    wblock->block = NULL;
3019
    /*
3020
     * We return these to the caller in pcapng_read().
3021
     */
3022
0
    wblock->internal = false;
3023
3024
0
    return true;
3025
0
}
3026
3027
static bool
3028
pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh,
3029
                                         uint32_t block_type _U_,
3030
                                         uint32_t block_content_length,
3031
                                         section_info_t *section_info _U_,
3032
                                         wtapng_block_t *wblock,
3033
                                         int *err, char **err_info)
3034
0
{
3035
0
    uint32_t entry_length;
3036
0
    uint64_t rt_ts;
3037
0
    bool have_ts = false;
3038
3039
0
    if (block_content_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE) {
3040
0
        *err = WTAP_ERR_BAD_FILE;
3041
0
        *err_info = ws_strdup_printf("pcapng: block content length %u of a systemd journal export is less than the minimum systemd journal export content size %u",
3042
0
                                     block_content_length,
3043
0
                                     MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE);
3044
0
        return false;
3045
0
    }
3046
3047
0
    entry_length = block_content_length;
3048
3049
    /* Includes padding bytes. */
3050
0
    if (!wtap_read_bytes_buffer(fh, &wblock->rec->data,
3051
0
                                entry_length, err, err_info)) {
3052
0
        return false;
3053
0
    }
3054
3055
    /*
3056
     * We don't have memmem available everywhere, so we get to add space for
3057
     * a trailing \0 for strstr below.
3058
     */
3059
0
    ws_buffer_assure_space(&wblock->rec->data, entry_length+1);
3060
3061
0
    char *buf_ptr = (char *) ws_buffer_start_ptr(&wblock->rec->data);
3062
0
    while (entry_length > 0 && buf_ptr[entry_length-1] == '\0') {
3063
0
        entry_length--;
3064
0
    }
3065
3066
0
    if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE) {
3067
0
        *err = WTAP_ERR_BAD_FILE;
3068
0
        *err_info = ws_strdup_printf("pcapng: entry length %u is too small (< %u)",
3069
0
                                     entry_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE);
3070
0
        return false;
3071
0
    }
3072
3073
0
    ws_debug("entry_length %u", entry_length);
3074
3075
0
    size_t rt_ts_len = strlen(SDJ__REALTIME_TIMESTAMP);
3076
3077
0
    buf_ptr[entry_length] = '\0';
3078
0
    char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP);
3079
3080
0
    if (!ts_pos) {
3081
0
        ws_debug("no timestamp");
3082
0
    } else if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) {
3083
0
        ws_debug("timestamp past end of buffer");
3084
0
    } else {
3085
0
        const char *ts_end;
3086
0
        have_ts = ws_strtou64(ts_pos+rt_ts_len, &ts_end, &rt_ts);
3087
3088
0
        if (!have_ts) {
3089
0
            ws_debug("invalid timestamp");
3090
0
        }
3091
0
    }
3092
3093
0
    wtap_setup_systemd_journal_export_rec(wblock->rec);
3094
0
    wblock->rec->rec_header.systemd_journal_export_header.record_len = entry_length;
3095
0
    wblock->rec->presence_flags = WTAP_HAS_CAP_LEN;
3096
0
    if (have_ts) {
3097
0
        wblock->rec->presence_flags |= WTAP_HAS_TS;
3098
0
        wblock->rec->tsprec = WTAP_TSPREC_USEC;
3099
0
        wblock->rec->ts.secs = (time_t) (rt_ts / 1000000);
3100
0
        wblock->rec->ts.nsecs = (rt_ts % 1000000) * 1000;
3101
0
    }
3102
3103
    /*
3104
     * We return these to the caller in pcapng_read().
3105
     */
3106
0
    wblock->internal = false;
3107
3108
0
    if (wth->file_encap == WTAP_ENCAP_NONE) {
3109
        /*
3110
         * Nothing (most notably an IDB) has set a file encap at this point.
3111
         * Do so here.
3112
         * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate?
3113
         */
3114
0
        wth->file_encap = WTAP_ENCAP_PER_PACKET;
3115
0
    }
3116
3117
0
    return true;
3118
0
}
3119
3120
static bool
3121
pcapng_read_unknown_block(FILE_T fh, uint32_t block_content_length,
3122
    section_info_t *section_info _U_, wtapng_block_t *wblock,
3123
    int *err, char **err_info)
3124
0
{
3125
    /* Skip the block content. */
3126
0
    if (!wtap_read_bytes(fh, NULL, block_content_length, err, err_info)) {
3127
0
        return false;
3128
0
    }
3129
3130
    /*
3131
     * We're skipping this, so we won't return these to the caller
3132
     * in pcapng_read().
3133
     */
3134
0
    wblock->internal = true;
3135
3136
0
    return true;
3137
0
}
3138
3139
static bool
3140
pcapng_read_and_check_block_trailer(FILE_T fh, pcapng_block_header_t *bh,
3141
                                    section_info_t *section_info,
3142
                                    int *err, char **err_info)
3143
0
{
3144
0
    uint32_t block_total_length;
3145
3146
    /* sanity check: first and second block lengths must match */
3147
0
    if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
3148
0
                         err, err_info)) {
3149
0
        ws_debug("couldn't read second block length");
3150
0
        return false;
3151
0
    }
3152
3153
0
    if (section_info->byte_swapped)
3154
0
        block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
3155
3156
    /*
3157
     * According to the pcapng spec, this should equal the block total
3158
     * length value at the beginning of the block, which MUST (in the
3159
     * IANA sense) be a multiple of 4.
3160
     *
3161
     * We round the value at the beginning of the block to a multiple
3162
     * of 4, so do so with this value as well.  This *does* mean that
3163
     * the two values, if they're not both multiples of 4, can differ
3164
     * and this code won't detect that, but we're already not detecting
3165
     * non-multiple-of-4 total lengths.
3166
     */
3167
0
    block_total_length = WS_ROUNDUP_4(block_total_length);
3168
3169
0
    if (block_total_length != bh->block_total_length) {
3170
0
        *err = WTAP_ERR_BAD_FILE;
3171
0
        *err_info = ws_strdup_printf("pcapng: total block lengths (first %u and second %u) don't match",
3172
0
                                    bh->block_total_length, block_total_length);
3173
0
        return false;
3174
0
    }
3175
0
    return true;
3176
0
}
3177
3178
static bool
3179
pcapng_read_block(wtap *wth, FILE_T fh,
3180
                  section_info_t *section_info,
3181
                  section_info_t *new_section_info,
3182
                  wtapng_block_t *wblock,
3183
                  int *err, char **err_info)
3184
0
{
3185
0
    pcapng_block_type_information_t *handler;
3186
0
    block_return_val ret;
3187
0
    pcapng_block_header_t bh;
3188
0
    uint32_t block_padded_length;
3189
0
    uint32_t block_content_length;
3190
3191
0
    wblock->block = NULL;
3192
3193
    /* Try to read the (next) block header */
3194
0
    if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
3195
0
        ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
3196
0
        return false;
3197
0
    }
3198
3199
    /*
3200
     * SHBs have to be treated differently from other blocks, because
3201
     * the byte order of the fields in the block can only be determined
3202
     * by looking at the byte-order magic number inside the block, not
3203
     * by using the byte order of the section to which it belongs, as
3204
     * it is the block that *defines* the byte order of the section to
3205
     * which it belongs.
3206
     */
3207
0
    if (bh.block_type == BLOCK_TYPE_SHB) {
3208
        /*
3209
         * BLOCK_TYPE_SHB has the same value regardless of byte order,
3210
         * so we don't need to byte-swap it.
3211
         *
3212
         * We *might* need to byte-swap the total length, but we
3213
         * can't determine whether we do until we look inside the
3214
         * block and find the byte-order magic number, so we rely
3215
         * on pcapng_read_section_header_block() to do that and
3216
         * to swap the total length (as it needs to get the total
3217
         * length in the right byte order in order to read the
3218
         * entire block).
3219
         */
3220
0
        wblock->type = bh.block_type;
3221
3222
0
        ws_debug("block_type BLOCK_TYPE_SHB (0x%08x)", bh.block_type);
3223
3224
        /*
3225
         * Fill in the section_info_t passed to us for use when
3226
         * there's a new SHB; don't overwrite the existing SHB,
3227
         * if there is one.
3228
         */
3229
0
        ret = pcapng_read_section_header_block(fh, &bh, new_section_info,
3230
0
                                               wblock, err, err_info);
3231
0
        if (ret != PCAPNG_BLOCK_OK) {
3232
0
            return false;
3233
0
        }
3234
3235
        /*
3236
         * This is the current section; use its byte order, not that
3237
         * of the section pointed to by section_info (which could be
3238
         * null).
3239
         */
3240
0
        section_info = new_section_info;
3241
3242
0
    } else {
3243
        /*
3244
         * Not an SHB.
3245
         */
3246
0
        if (section_info->byte_swapped) {
3247
0
            bh.block_type         = GUINT32_SWAP_LE_BE(bh.block_type);
3248
0
            bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
3249
0
        }
3250
3251
0
        if (bh.block_total_length < MIN_BLOCK_SIZE) {
3252
0
            *err = WTAP_ERR_BAD_FILE;
3253
0
            *err_info = ws_strdup_printf("pcapng: total block length %u of block is less than the minimum block size %u",
3254
0
                                         bh.block_total_length, MIN_BLOCK_SIZE);
3255
0
            return false;
3256
0
        }
3257
3258
        /*
3259
         * Add padding bytes to the block total length.
3260
         * (The "block total length" fields of some example files
3261
         * don't contain the packet data padding bytes!)
3262
         *
3263
         * For all block types currently defined in the pcapng
3264
         * specification, the portion of the block that precedes
3265
         * the options is, if necessary, padded to be a multiple
3266
         * of 4 octets, the header of an option is 4 octets long,
3267
         * and the value of an option is also padded to be a
3268
         * multiple of 4 octets, so the total length of a block
3269
         * is always a multiple of 4 octets.
3270
         *
3271
         * If you have defined a block where that is not true, you
3272
         * have violated the pcapng specification - where it says
3273
         * that "[The value of the Block Total Length] MUST be a
3274
         * multiple of 4.", with MUST as described in BCP 14 (RFC 2119/
3275
         * RFC 8174).
3276
         *
3277
         * Therefore, if adjusting the block total length causes the
3278
         * code to read your block type not to work, that's your
3279
         * problem.  It's bad enough that some blocks were written
3280
         * out with the block total length not including the padding.
3281
         * (Please note that libpcap is less forgiving that we are;
3282
         * it reports an error if the block total length isn't a
3283
         * multiple of 4.)
3284
         */
3285
0
        block_padded_length = WS_ROUNDUP_4(bh.block_total_length);
3286
3287
0
        wblock->type = bh.block_type;
3288
3289
0
        ws_noisy("block_type 0x%08x", bh.block_type);
3290
3291
        /* Don't try to allocate memory for a huge number of options, as
3292
           that might fail and, even if it succeeds, it might not leave
3293
           any address space or memory+backing store for anything else.
3294
3295
           We do that by imposing a maximum block size of MAX_BLOCK_SIZE. */
3296
0
        if (block_padded_length < bh.block_total_length || block_padded_length > MAX_BLOCK_SIZE) {
3297
0
            *err = WTAP_ERR_BAD_FILE;
3298
0
            *err_info = ws_strdup_printf("pcapng: total block length %u is too large (> %u)",
3299
0
                                        bh.block_total_length, MAX_BLOCK_SIZE);
3300
0
            return false;
3301
0
        }
3302
3303
        /*
3304
         * Length of the contents of the block.
3305
         */
3306
0
        block_content_length = block_padded_length - MIN_BLOCK_SIZE;
3307
3308
        /*
3309
         * Do we have a handler for this block type?
3310
         */
3311
0
        handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(bh.block_type));
3312
0
        if (handler != NULL) {
3313
            /* Yes - call it to read this block type. */
3314
0
            if (!handler->reader(wth, fh, bh.block_type,
3315
0
                                 block_content_length, section_info,
3316
0
                                 wblock, err, err_info))
3317
0
                return false;
3318
0
        } else {
3319
0
            ws_debug("Unknown block_type: 0x%08x (block ignored), block total length %u",
3320
0
                     bh.block_type, block_padded_length);
3321
0
            if (!pcapng_read_unknown_block(fh, block_content_length,
3322
0
                                           section_info, wblock,
3323
0
                                           err, err_info))
3324
0
                return false;
3325
0
        }
3326
0
    }
3327
3328
    /*
3329
     * Read and check the block trailer.
3330
     */
3331
0
    if (!pcapng_read_and_check_block_trailer(fh, &bh, section_info, err, err_info)) {
3332
        /* Not readable or not valid. */
3333
0
        return false;
3334
0
    }
3335
3336
0
    return true;
3337
0
}
3338
3339
static void
3340
pcapng_process_shb(wtap *wth, pcapng_t *pcapng, section_info_t new_section, wtapng_block_t *wblock, const int64_t *data_offset)
3341
0
{
3342
    /*
3343
     * Add this SHB to the table of SHBs.
3344
     */
3345
0
    g_array_append_val(wth->shb_hdrs, wblock->block);
3346
0
    g_array_append_val(wth->shb_iface_to_global, wth->interface_data->len);
3347
3348
    /*
3349
     * Update the current section number, and add
3350
     * the updated section_info_t to the array of
3351
     * section_info_t's for this file.
3352
     */
3353
0
    pcapng->current_section_number++;
3354
0
    new_section.interfaces = g_array_new(false, false, sizeof(interface_info_t));
3355
0
    new_section.shb_off = *data_offset;
3356
0
    g_array_append_val(pcapng->sections, new_section);
3357
0
}
3358
3359
/* Process an IDB that we've just read. The contents of wblock are copied as needed. */
3360
static bool
3361
pcapng_process_idb(wtap *wth, section_info_t *section_info,
3362
                   wtapng_block_t *wblock)
3363
0
{
3364
0
    wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
3365
0
    interface_info_t iface_info;
3366
0
    wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
3367
0
                                *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3368
0
    uint8_t if_fcslen;
3369
3370
0
    wtap_block_copy(int_data, wblock->block);
3371
3372
    /* Interface statistics */
3373
0
    if_descr_mand->num_stat_entries = 0;
3374
0
    if_descr_mand->interface_statistics = NULL;
3375
3376
0
    wtap_add_idb(wth, int_data);
3377
3378
0
    iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
3379
0
    iface_info.snap_len = wblock_if_descr_mand->snap_len;
3380
0
    iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
3381
0
    iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
3382
3383
    /*
3384
     * Did we get an FCS length option?
3385
     */
3386
0
    if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_FCSLEN,
3387
0
                                          &if_fcslen) == WTAP_OPTTYPE_SUCCESS) {
3388
        /*
3389
         * Yes.
3390
         */
3391
0
        iface_info.fcslen = if_fcslen;
3392
0
    } else {
3393
        /*
3394
         * No.  Mark the FCS length as unknown.
3395
         */
3396
0
        iface_info.fcslen = -1;
3397
0
    }
3398
3399
    /*
3400
     * Did we get a time stamp offset option?
3401
     */
3402
0
    if (wtap_block_get_int64_option_value(wblock->block, OPT_IDB_TSOFFSET,
3403
0
                                          &iface_info.tsoffset) != WTAP_OPTTYPE_SUCCESS) {
3404
        /*
3405
         * No.  Default to 0, meaning that time stamps in the file are
3406
         * absolute time stamps.
3407
         */
3408
0
        iface_info.tsoffset = 0;
3409
0
    }
3410
3411
    /*
3412
     * Did we get a time stamp precision option?
3413
     */
3414
0
    iface_info.tsresol_binary = 0;
3415
0
    uint8_t if_tsresol;
3416
0
    if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_TSRESOL,
3417
0
                                          &if_tsresol) == WTAP_OPTTYPE_SUCCESS) {
3418
        /* Is the timestamp resolution a power of two? */
3419
0
        if (if_tsresol & 0x80) {
3420
            /* Note that 0x80 and 0x80 mean the same thing, as 2^-0 == 10^-0 */
3421
0
            iface_info.tsresol_binary = if_tsresol & 0x7F;
3422
0
        }
3423
0
    }
3424
0
    g_array_append_val(section_info->interfaces, iface_info);
3425
3426
0
    wtap_block_unref(wblock->block);
3427
3428
0
    return true;
3429
0
}
3430
3431
/* Process an NRB that we have just read. */
3432
static bool
3433
pcapng_process_nrb(wtap *wth, section_info_t *section_info _U_,
3434
                   wtapng_block_t *wblock)
3435
0
{
3436
0
    wtapng_process_nrb(wth, wblock->block);
3437
3438
0
    if (wth->nrbs == NULL) {
3439
0
        wth->nrbs = g_array_new(false, false, sizeof(wtap_block_t));
3440
0
    }
3441
    /* Store NRB such that it can be saved by the dumper. */
3442
0
    g_array_append_val(wth->nrbs, wblock->block);
3443
    /* Do not free wblock->block, it is consumed above */
3444
3445
0
    return true;
3446
0
}
3447
3448
/* Process a DSB that we have just read. */
3449
static bool
3450
pcapng_process_dsb(wtap *wth, section_info_t *section_info _U_,
3451
                   wtapng_block_t *wblock)
3452
0
{
3453
0
    wtapng_process_dsb(wth, wblock->block);
3454
3455
    /* Store DSB such that it can be saved by the dumper. */
3456
0
    g_array_append_val(wth->dsbs, wblock->block);
3457
3458
    /* Do not free wblock->block, it is consumed above */
3459
3460
0
    return true;
3461
0
}
3462
3463
/* Process a ISB that we have just read. */
3464
static bool
3465
pcapng_process_isb(wtap *wth, section_info_t *section_info _U_,
3466
                   wtapng_block_t *wblock)
3467
0
{
3468
0
    wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
3469
0
    wtap_block_t if_stats;
3470
0
    wtap_block_t wtapng_if_descr;
3471
0
    wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
3472
3473
    /*
3474
     * Another interface statistics report
3475
     *
3476
     * XXX - given that they're reports, we should be
3477
     * supplying them in read calls, and displaying them
3478
     * in the "packet" list, so you can see what the
3479
     * statistics were *at the time when the report was
3480
     * made*.
3481
     *
3482
     * The statistics from the *last* ISB could be displayed
3483
     * in the summary, but if there are packets after the
3484
     * last ISB, that could be misleading.
3485
     *
3486
     * If we only display them if that ISB has an isb_endtime
3487
     * option, which *should* only appear when capturing ended
3488
     * on that interface (so there should be no more packet
3489
     * blocks or ISBs for that interface after that point,
3490
     * that would be the best way of showing "summary"
3491
     * statistics.
3492
     */
3493
0
    ws_debug("block type BLOCK_TYPE_ISB");
3494
0
    if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3495
0
    if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
3496
0
        ws_debug("BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces",
3497
0
                 if_stats_mand_block->interface_id);
3498
0
    } else {
3499
        /* Get the interface description */
3500
0
        wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id);
3501
0
        wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
3502
0
        if (wtapng_if_descr_mand->num_stat_entries == 0) {
3503
            /* First ISB found, no previous entry */
3504
0
            ws_debug("block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
3505
0
            wtapng_if_descr_mand->interface_statistics = g_array_new(false, false, sizeof(wtap_block_t));
3506
0
        }
3507
3508
0
        if_stats = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
3509
0
        if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3510
0
        if_stats_mand->interface_id  = if_stats_mand_block->interface_id;
3511
0
        if_stats_mand->ts_high       = if_stats_mand_block->ts_high;
3512
0
        if_stats_mand->ts_low        = if_stats_mand_block->ts_low;
3513
3514
0
        wtap_block_copy(if_stats, wblock->block);
3515
0
        g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
3516
0
        wtapng_if_descr_mand->num_stat_entries++;
3517
0
    }
3518
0
    wtap_block_unref(wblock->block);
3519
0
    return true;
3520
0
}
3521
3522
static void
3523
pcapng_process_internal_block(wtap *wth, pcapng_t *pcapng, section_info_t *section, section_info_t new_section, wtapng_block_t *wblock, const int64_t *data_offset)
3524
0
{
3525
0
    if (wblock->type == BLOCK_TYPE_SHB) {
3526
0
        pcapng_process_shb(wth, pcapng, new_section, wblock, data_offset);
3527
0
    } else {
3528
0
        pcapng_block_type_information_t* handler = g_hash_table_lookup(block_handlers, GUINT_TO_POINTER(wblock->type));
3529
3530
0
        if (handler != NULL) {
3531
            /* XXX - Is it okay to not have a processor? */
3532
0
            if (handler->processor != NULL) {
3533
0
                handler->processor(wth, section, wblock);
3534
0
            }
3535
0
        } else {
3536
            /* XXX - improve handling of "unknown" blocks */
3537
0
            ws_debug("Unknown block type 0x%08x", wblock->type);
3538
0
        }
3539
0
    }
3540
0
}
3541
3542
/* classic wtap: open capture file */
3543
wtap_open_return_val
3544
pcapng_open(wtap *wth, int *err, char **err_info)
3545
0
{
3546
0
    wtapng_block_t wblock;
3547
0
    pcapng_t *pcapng;
3548
0
    pcapng_block_header_t bh;
3549
0
    int64_t saved_offset;
3550
0
    section_info_t first_section, new_section, *current_section;
3551
3552
0
    ws_debug("opening file");
3553
    /*
3554
     * Read first block.
3555
     *
3556
     * First, try to read the block header.
3557
     */
3558
0
    if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3559
0
        ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
3560
0
        if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
3561
            /*
3562
             * Short read or EOF.
3563
             *
3564
             * We're reading this as part of an open, so
3565
             * the file is too short to be a pcapng file.
3566
             */
3567
0
            *err = 0;
3568
0
            g_free(*err_info);
3569
0
            *err_info = NULL;
3570
0
            return WTAP_OPEN_NOT_MINE;
3571
0
        }
3572
0
        return WTAP_OPEN_ERROR;
3573
0
    }
3574
3575
    /*
3576
     * If this is a pcapng file, the first block must be a
3577
     * Section Header Block.
3578
     */
3579
0
    if (bh.block_type != BLOCK_TYPE_SHB) {
3580
        /*
3581
         * Not an SHB, so this isn't a pcapng file.
3582
         *
3583
         * XXX - check for damage from transferring a file
3584
         * between Windows and UN*X as text rather than
3585
         * binary data?
3586
         */
3587
0
        ws_debug("first block type 0x%08x not SHB", bh.block_type);
3588
0
        return WTAP_OPEN_NOT_MINE;
3589
0
    }
3590
3591
0
    ws_debug("got an SHB");
3592
3593
    /*
3594
     * Now try to read the block body, filling in the section_info_t
3595
     * for the first section.
3596
     */
3597
0
    wblock.type = bh.block_type;
3598
0
    wblock.block = NULL;
3599
    /* we don't expect any packet blocks yet */
3600
0
    wblock.rec = NULL;
3601
3602
0
    switch (pcapng_read_section_header_block(wth->fh, &bh, &first_section,
3603
0
                                             &wblock, err, err_info)) {
3604
0
    case PCAPNG_BLOCK_OK:
3605
        /* No problem */
3606
0
        break;
3607
3608
0
    case PCAPNG_BLOCK_NOT_SHB:
3609
        /* This doesn't look like an SHB, so this isn't a pcapng file. */
3610
0
        wtap_block_unref(wblock.block);
3611
0
        *err = 0;
3612
0
        g_free(*err_info);
3613
0
        *err_info = NULL;
3614
0
        return WTAP_OPEN_NOT_MINE;
3615
3616
0
    case PCAPNG_BLOCK_ERROR:
3617
0
        wtap_block_unref(wblock.block);
3618
0
        if (*err == WTAP_ERR_SHORT_READ) {
3619
            /*
3620
             * Short read.
3621
             *
3622
             * We're reading this as part of an open, so
3623
             * the file is too short to be a pcapng file.
3624
             */
3625
0
            *err = 0;
3626
0
            g_free(*err_info);
3627
0
            *err_info = NULL;
3628
0
            return WTAP_OPEN_NOT_MINE;
3629
0
        }
3630
        /* An I/O error. */
3631
0
        return WTAP_OPEN_ERROR;
3632
0
    }
3633
3634
    /*
3635
     * Read and check the block trailer.
3636
     */
3637
0
    if (!pcapng_read_and_check_block_trailer(wth->fh, &bh, &first_section, err, err_info)) {
3638
        /* Not readable or not valid. */
3639
0
        wtap_block_unref(wblock.block);
3640
0
        return WTAP_OPEN_ERROR;
3641
0
    }
3642
3643
    /*
3644
     * At this point, we've decided this is a pcapng file, not
3645
     * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
3646
     * past this point.
3647
     *
3648
     * Copy the SHB that we just read to the first entry in the table of
3649
     * SHBs for this file.
3650
     */
3651
0
    wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), wblock.block);
3652
0
    wtap_block_unref(wblock.block);
3653
0
    wblock.block = NULL;
3654
3655
0
    wth->file_encap = WTAP_ENCAP_NONE;
3656
0
    wth->snapshot_length = 0;
3657
0
    wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
3658
0
    pcapng = g_new(pcapng_t, 1);
3659
0
    wth->priv = (void *)pcapng;
3660
    /*
3661
     * We're currently processing the first section; as this is written
3662
     * in C, that's section 0. :-)
3663
     */
3664
0
    pcapng->current_section_number = 0;
3665
3666
    /*
3667
     * Create the array of interfaces for the first section.
3668
     */
3669
0
    first_section.interfaces = g_array_new(false, false, sizeof(interface_info_t));
3670
3671
    /*
3672
     * The first section is at the very beginning of the file.
3673
     */
3674
0
    first_section.shb_off = 0;
3675
3676
    /*
3677
     * Allocate the sections table with space reserved for the first
3678
     * section, and add that section.
3679
     */
3680
0
    pcapng->sections = g_array_sized_new(false, false, sizeof(section_info_t), 1);
3681
0
    g_array_append_val(pcapng->sections, first_section);
3682
3683
0
    wth->subtype_read = pcapng_read;
3684
0
    wth->subtype_seek_read = pcapng_seek_read;
3685
0
    wth->subtype_close = pcapng_close;
3686
0
    wth->file_type_subtype = pcapng_file_type_subtype;
3687
3688
    /* Always initialize the lists of Decryption Secret Blocks, Name
3689
     * Resolution Blocks, Sysdig meta event blocks, and Darwin Process Event Blocks,
3690
     * such that a wtap_dumper can refer to them right after
3691
     * opening the capture file. */
3692
0
    wth->dsbs = g_array_new(false, false, sizeof(wtap_block_t));
3693
0
    wth->nrbs = g_array_new(false, false, sizeof(wtap_block_t));
3694
0
    wth->meta_events = g_array_new(false, false, sizeof(wtap_block_t));
3695
0
    wth->dpibs = g_array_new(false, false, sizeof(wtap_block_t));
3696
3697
    /* Most other capture types (such as pcap) support a single link-layer
3698
     * type, indicated in the header, and don't support WTAP_ENCAP_PER_PACKET.
3699
     * Most programs that write such capture files want to know the link-layer
3700
     * type when initially opening the destination file, and (unlike Wireshark)
3701
     * don't want to read the entire source file to find all the link-layer
3702
     * types before writing (particularly if reading from a pipe or FIFO.)
3703
     *
3704
     * In support of this, read all the internally-processed, non packet
3705
     * blocks that appear before the first packet block (EPB or SPB).
3706
     *
3707
     * Note that such programs will still have issues when trying to read
3708
     * a pcapng that has a new link-layer type in an IDB in the middle of
3709
     * the file, as they will discover in the middle that no, they can't
3710
     * successfully write the output file as desired.
3711
     *
3712
     * If this is a live capture, and we're reading the initially written
3713
     * header, we'll loop until we reach EOF. (If compressed, it might
3714
     * also set WTAP_ERR_SHORT_READ from the stream / frame end not being
3715
     * present until the file is closed.) So we'll need to clear that at
3716
     * some point before reading packets.
3717
     */
3718
0
    while (!file_eof(wth->fh)) {
3719
        /* peek at next block */
3720
        /* Try to read the (next) block header */
3721
0
        saved_offset = file_tell(wth->fh);
3722
0
        if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3723
0
            if (*err == 0) {
3724
                /* EOF */
3725
0
                ws_debug("No more blocks available...");
3726
0
                break;
3727
0
            }
3728
0
            ws_debug("Check for more initial blocks, wtap_read_bytes_or_eof() failed, err = %d.",
3729
0
                     *err);
3730
0
            return WTAP_OPEN_ERROR;
3731
0
        }
3732
3733
        /* go back to where we were */
3734
0
        if (file_seek(wth->fh, saved_offset, SEEK_SET, err) == -1) {
3735
0
            return WTAP_OPEN_ERROR;
3736
0
        }
3737
3738
        /*
3739
         * Get a pointer to the current section's section_info_t.
3740
         */
3741
0
        current_section = &g_array_index(pcapng->sections, section_info_t,
3742
0
                                         pcapng->current_section_number);
3743
3744
0
        if (current_section->byte_swapped) {
3745
0
            bh.block_type         = GUINT32_SWAP_LE_BE(bh.block_type);
3746
0
        }
3747
3748
0
        ws_debug("Check for more initial internal blocks, block_type 0x%08x",
3749
0
                 bh.block_type);
3750
3751
0
        if (!get_block_type_internal(bh.block_type)) {
3752
0
            break;  /* Next block has to be returned in pcap_read */
3753
0
        }
3754
        /* Note that some custom block types, unlike packet blocks,
3755
         * don't need to be preceded by an IDB and so theoretically
3756
         * we could skip past them here. However, then there's no good
3757
         * way to both later return those blocks in pcap_read() and
3758
         * ensure that we don't read and process the IDBs (and other
3759
         * internal block types) a second time.
3760
         *
3761
         * pcapng_read_systemd_journal_export_block() sets the file level
3762
         * link-layer type if it's still UNKNOWN. We could do the same here
3763
         * for it and possibly other types based on block type, even without
3764
         * reading them.
3765
         */
3766
0
        if (!pcapng_read_block(wth, wth->fh, current_section,
3767
0
                              &new_section, &wblock, err, err_info)) {
3768
0
            wtap_block_unref(wblock.block);
3769
0
            if (*err == 0) {
3770
0
                ws_debug("No more initial blocks available...");
3771
0
                break;
3772
0
            } else {
3773
0
                ws_debug("couldn't read block");
3774
0
                return WTAP_OPEN_ERROR;
3775
0
            }
3776
0
        }
3777
0
        pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, &saved_offset);
3778
0
        ws_debug("Read IDB number_of_interfaces %u, wtap_encap %i",
3779
0
                 wth->interface_data->len, wth->file_encap);
3780
0
    }
3781
0
    return WTAP_OPEN_MINE;
3782
0
}
3783
3784
/* classic wtap: read packet */
3785
static bool
3786
pcapng_read(wtap *wth, wtap_rec *rec, int *err, char **err_info,
3787
            int64_t *data_offset)
3788
0
{
3789
0
    pcapng_t *pcapng = (pcapng_t *)wth->priv;
3790
0
    section_info_t *current_section, new_section;
3791
0
    wtapng_block_t wblock;
3792
3793
0
    wblock.rec = rec;
3794
3795
    /* read next block */
3796
0
    while (1) {
3797
0
        *data_offset = file_tell(wth->fh);
3798
0
        ws_noisy("data_offset is %" PRId64, *data_offset);
3799
3800
        /*
3801
         * Get the section_info_t for the current section.
3802
         */
3803
0
        current_section = &g_array_index(pcapng->sections, section_info_t,
3804
0
                                         pcapng->current_section_number);
3805
3806
        /*
3807
         * Read the next block.
3808
         */
3809
0
        if (!pcapng_read_block(wth, wth->fh, current_section,
3810
0
                               &new_section, &wblock, err, err_info)) {
3811
0
            ws_noisy("data_offset is finally %" PRId64, *data_offset);
3812
0
            ws_debug("couldn't read packet block");
3813
0
            wtap_block_unref(wblock.block);
3814
0
            return false;
3815
0
        }
3816
3817
0
        if (!wblock.internal) {
3818
            /*
3819
             * This is a block type we return to the caller to process.
3820
             */
3821
0
            ws_noisy("rec_type %u", wblock.rec->rec_type);
3822
0
            break;
3823
0
        }
3824
3825
        /*
3826
         * This is a block type we process internally, rather than
3827
         * returning it for the caller to process.
3828
         */
3829
0
        pcapng_process_internal_block(wth, pcapng, current_section, new_section, &wblock, data_offset);
3830
0
    }
3831
3832
    /*ws_debug("Read length: %u Packet length: %u", bytes_read, rec->rec_header.packet_header.caplen);*/
3833
0
    ws_noisy("data_offset is finally %" PRId64, *data_offset);
3834
3835
    /* Provide the section number */
3836
0
    rec->presence_flags |= WTAP_HAS_SECTION_NUMBER;
3837
0
    rec->section_number = pcapng->current_section_number;
3838
3839
0
    return true;
3840
0
}
3841
3842
/* classic wtap: seek to file position and read packet */
3843
static bool
3844
pcapng_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec,
3845
                 int *err, char **err_info)
3846
0
{
3847
0
    pcapng_t *pcapng = (pcapng_t *)wth->priv;
3848
0
    section_info_t *section_info, new_section;
3849
0
    wtapng_block_t wblock;
3850
3851
3852
    /* seek to the right file position */
3853
0
    if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
3854
0
        return false;   /* Seek error */
3855
0
    }
3856
0
    ws_noisy("reading at offset %" PRIu64, seek_off);
3857
3858
    /*
3859
     * Find the section_info_t for the section in which this block
3860
     * appears.
3861
     *
3862
     * First, make sure we have at least one section; if we don't, that's
3863
     * an internal error.
3864
     */
3865
0
    ws_assert(pcapng->sections->len >= 1);
3866
3867
    /*
3868
     * Now scan backwards through the array to find the first section
3869
     * that begins at or before the offset of the block we're reading.
3870
     *
3871
     * Yes, that's O(n) in the number of blocks, but we're unlikely to
3872
     * have many sections and pretty unlikely to have more than one.
3873
     */
3874
0
    unsigned section_number = pcapng->sections->len - 1;
3875
0
    for (;;) {
3876
0
        section_info = &g_array_index(pcapng->sections, section_info_t,
3877
0
                                      section_number);
3878
0
        if (section_info->shb_off <= seek_off)
3879
0
            break;
3880
3881
        /*
3882
         * If that's section 0, something's wrong; that section should
3883
         * have an offset of 0.
3884
         */
3885
0
        ws_assert(section_number != 0);
3886
0
        section_number--;
3887
0
    }
3888
3889
0
    wblock.rec = rec;
3890
3891
    /* read the block */
3892
0
    if (!pcapng_read_block(wth, wth->random_fh, section_info,
3893
0
                           &new_section, &wblock, err, err_info)) {
3894
0
        ws_debug("couldn't read packet block (err=%d).", *err);
3895
0
        wtap_block_unref(wblock.block);
3896
0
        return false;
3897
0
    }
3898
3899
    /* block must not be one we process internally rather than supplying */
3900
0
    if (wblock.internal) {
3901
0
        ws_debug("block type 0x%08x is not one we return",
3902
0
                 wblock.type);
3903
0
        wtap_block_unref(wblock.block);
3904
0
        return false;
3905
0
    }
3906
3907
0
    wtap_block_unref(wblock.block);
3908
3909
    /* Provide the section number */
3910
0
    rec->presence_flags |= WTAP_HAS_SECTION_NUMBER;
3911
0
    rec->section_number = section_number;
3912
3913
0
    return true;
3914
0
}
3915
3916
/* classic wtap: close capture file */
3917
static void
3918
pcapng_close(wtap *wth)
3919
0
{
3920
0
    pcapng_t *pcapng = (pcapng_t *)wth->priv;
3921
3922
0
    ws_debug("closing file");
3923
3924
    /*
3925
     * Free up the interfaces tables for all the sections.
3926
     */
3927
0
    for (unsigned i = 0; i < pcapng->sections->len; i++) {
3928
0
        pcapng_destroy_section_info(&g_array_index(pcapng->sections,
3929
0
                                                   section_info_t, i));
3930
0
    }
3931
0
    g_array_free(pcapng->sections, true);
3932
0
}
3933
3934
/*
3935
 * As it says at the top of the file, an option sizer "calculates how many
3936
 * bytes the option's data requires, not including any padding bytes."
3937
 * Callers are responsible for rounding up to multiples of 4 bytes.
3938
 * compute_block_options_size() does that for each option in the block;
3939
 * option writers that call an option sizer (which helps ensure that the
3940
 * sizes are internally consistent) should do the same.
3941
 */
3942
3943
static uint32_t pcapng_compute_string_option_size(wtap_optval_t *optval)
3944
0
{
3945
0
    uint32_t size = 0;
3946
3947
0
    size = (uint32_t)strlen(optval->stringval);
3948
3949
0
    if (size > 65535) {
3950
        /*
3951
         * Too big to fit in the option.
3952
         * Don't write anything.
3953
         *
3954
         * XXX - truncate it?  Report an error?
3955
         */
3956
0
        size = 0;
3957
0
    }
3958
3959
0
    return size;
3960
0
}
3961
3962
#if 0
3963
static uint32_t pcapng_compute_bytes_option_size(wtap_optval_t *optval)
3964
{
3965
    uint32_t size = 0;
3966
3967
    size = (uint32_t)g_bytes_get_size(optval->byteval) & 0xffff;
3968
3969
    return size;
3970
}
3971
#endif
3972
3973
static uint32_t pcapng_compute_if_filter_option_size(wtap_optval_t *optval)
3974
0
{
3975
0
    if_filter_opt_t* filter = &optval->if_filterval;
3976
0
    uint32_t size;
3977
3978
0
    if (filter->type == if_filter_pcap) {
3979
0
        size = (uint32_t)(strlen(filter->data.filter_str) + 1) & 0xffff;
3980
0
    } else if (filter->type == if_filter_bpf) {
3981
0
        size = (uint32_t)((filter->data.bpf_prog.bpf_prog_len * 8) + 1) & 0xffff;
3982
0
    } else {
3983
        /* Unknown type; don't write it */
3984
0
        size = 0;
3985
0
    }
3986
0
    return size;
3987
0
}
3988
3989
static uint32_t pcapng_compute_custom_string_option_size(wtap_optval_t *optval)
3990
0
{
3991
0
    uint32_t size = 0;
3992
3993
    /* PEN */
3994
0
    size = sizeof(uint32_t) + (uint32_t)strlen(optval->custom_stringval.string);
3995
3996
    /* pcapng_write_custom_string_option writes nothing if size > 65535 */
3997
0
    return size <= 65535 ? size : 0;
3998
0
}
3999
4000
static uint32_t pcapng_compute_custom_binary_option_size(wtap_optval_t *optval)
4001
0
{
4002
0
    size_t size;
4003
4004
    /* PEN */
4005
0
    size = sizeof(uint32_t) + optval->custom_binaryval.data.custom_data_len;
4006
4007
0
    if (size > 65535) {
4008
0
        size = 65535;
4009
0
    }
4010
4011
0
    return (uint32_t)size;
4012
0
}
4013
4014
static uint32_t pcapng_compute_packet_hash_option_size(wtap_optval_t *optval)
4015
0
{
4016
0
    packet_hash_opt_t* hash = &optval->packet_hash;
4017
0
    uint32_t size;
4018
4019
0
    switch (hash->type) {
4020
0
    case OPT_HASH_CRC32:
4021
0
        size = 4;
4022
0
        break;
4023
0
    case OPT_HASH_MD5:
4024
0
        size = 16;
4025
0
        break;
4026
0
    case OPT_HASH_SHA1:
4027
0
        size = 20;
4028
0
        break;
4029
0
    case OPT_HASH_TOEPLITZ:
4030
0
        size = 4;
4031
0
        break;
4032
0
    default:
4033
        /* 2COMP and XOR size not defined in standard (yet) */
4034
0
        size = hash->hash_bytes->len;
4035
0
        break;
4036
0
    }
4037
    /* XXX - What if the size of the hash bytes doesn't match the
4038
     * expected size? We can:
4039
     * 1) Return 0, and omit it when writing
4040
     * 2) Return hash_bytes->len, and write it out exactly as we have it
4041
     * 3) Return the correct size here, and when writing err or possibly
4042
     * truncate.
4043
     */
4044
    /* Account for the size of the algorithm type field. */
4045
0
    size += 1;
4046
4047
0
    return size;
4048
0
}
4049
4050
static uint32_t pcapng_compute_packet_verdict_option_size(wtap_optval_t *optval)
4051
0
{
4052
0
    packet_verdict_opt_t* verdict = &optval->packet_verdictval;
4053
0
    uint32_t size;
4054
4055
0
    switch (verdict->type) {
4056
4057
0
    case packet_verdict_hardware:
4058
0
        size = verdict->data.verdict_bytes->len;
4059
0
        break;
4060
4061
0
    case packet_verdict_linux_ebpf_tc:
4062
0
        size = 8;
4063
0
        break;
4064
4065
0
    case packet_verdict_linux_ebpf_xdp:
4066
0
        size = 8;
4067
0
        break;
4068
4069
0
    default:
4070
0
        size = 0;
4071
0
        break;
4072
0
    }
4073
    /* Account for the type octet */
4074
0
    if (size) {
4075
0
        size += 1;
4076
0
    }
4077
4078
0
    return size;
4079
0
}
4080
4081
static bool
4082
compute_block_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type, wtap_optval_t *optval, void *user_data)
4083
0
{
4084
0
    compute_options_size_t* options_size = (compute_options_size_t*)user_data;
4085
0
    uint32_t size = 0;
4086
4087
    /*
4088
     * Process the option IDs that are the same for all block types here;
4089
     * call the block-type-specific compute_size function for others.
4090
     */
4091
0
    switch(option_id)
4092
0
    {
4093
0
    case OPT_COMMENT:
4094
0
        size = pcapng_compute_string_option_size(optval);
4095
0
        break;
4096
0
    case OPT_CUSTOM_STR_COPY:
4097
0
        size = pcapng_compute_custom_string_option_size(optval);
4098
0
        break;
4099
0
    case OPT_CUSTOM_BIN_COPY:
4100
0
        size = pcapng_compute_custom_binary_option_size(optval);
4101
0
        break;
4102
0
    case OPT_CUSTOM_STR_NO_COPY:
4103
0
    case OPT_CUSTOM_BIN_NO_COPY:
4104
        /*
4105
         * Do not count these, as they're not supposed to be copied to
4106
         * new files.
4107
         *
4108
         * XXX - what if we're writing out a file that's *not* based on
4109
         * another file, so that we're *not* copying it from that file?
4110
         */
4111
0
        break;
4112
0
    default:
4113
        /* Block-type dependent; call the callback. */
4114
0
        if (options_size->compute_option_size) {
4115
0
            size = (*options_size->compute_option_size)(block, option_id, option_type, optval);
4116
0
        }
4117
0
        break;
4118
0
    }
4119
4120
    /*
4121
     * Are we writing this option?
4122
     */
4123
    /*
4124
     * XXX: The option length field is 16 bits. If size > 65535 (how?
4125
     * was the block was obtained from some format other than pcapng?),
4126
     * are we going to silently omit the option (in which case we shouldn't
4127
     * add the size here), or err out when writing it (in which case
4128
     * it's probably fine to add the size or not?) Adding it here and
4129
     * then omitting it when writing, as some of the routines do, means
4130
     * creating a corrupt file.
4131
     */
4132
0
    if (size != 0) {
4133
        /*
4134
         * Yes. The length of this option is 4 bytes for the option
4135
         * header, plus the size of the option data, rounded up
4136
         * to a multiple of 4 bytes (32 bits).
4137
         */
4138
0
        options_size->size += WS_ROUNDUP_4(4 + size);
4139
0
    }
4140
0
    return true; /* we always succeed */
4141
0
}
4142
4143
uint32_t
4144
pcapng_compute_options_size(wtap_block_t block, compute_option_size_func compute_option_size)
4145
0
{
4146
0
    compute_options_size_t compute_options_size;
4147
4148
    /*
4149
     * Compute the total size of all the options in the block.
4150
     * This always succeeds, so we don't check the return value.
4151
     */
4152
0
    compute_options_size.size = 0;
4153
0
    compute_options_size.compute_option_size = compute_option_size;
4154
0
    wtap_block_foreach_option(block, compute_block_option_size, &compute_options_size);
4155
4156
    /* Are we writing any options? */
4157
0
    if (compute_options_size.size != 0) {
4158
        /* Yes, add the size of the End-of-options tag. */
4159
0
        compute_options_size.size += 4;
4160
0
    }
4161
0
    return compute_options_size.size;
4162
0
}
4163
4164
static uint32_t compute_shb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
4165
0
{
4166
0
    uint32_t size;
4167
4168
0
    switch(option_id)
4169
0
    {
4170
0
    case OPT_SHB_HARDWARE:
4171
0
    case OPT_SHB_OS:
4172
0
    case OPT_SHB_USERAPPL:
4173
0
        size = pcapng_compute_string_option_size(optval);
4174
0
        break;
4175
0
    default:
4176
        /* Unknown options - size by datatype? */
4177
0
        size = 0;
4178
0
        break;
4179
0
    }
4180
0
    return size;
4181
0
}
4182
4183
typedef struct write_options_t
4184
{
4185
    wtap_dumper *wdh;
4186
    pcapng_opt_byte_order_e byte_order;
4187
    write_option_func write_option;
4188
    int *err;
4189
    char **err_info;
4190
}
4191
write_options_t;
4192
4193
static bool pcapng_write_option_eofopt(wtap_dumper *wdh, int *err)
4194
0
{
4195
0
    struct pcapng_option_header option_hdr;
4196
4197
    /*
4198
     * Write end of options.
4199
     *
4200
     * OPT_EOFOPT is zero, so we don't need to know the byte order to
4201
     * be used, as both fields in the option header are zero and thus
4202
     * unchanged if byte-swapped.
4203
     */
4204
0
    option_hdr.type = OPT_EOFOPT;
4205
0
    option_hdr.value_length = 0;
4206
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4207
0
        return false;
4208
0
    return true;
4209
0
}
4210
4211
static bool pcapng_write_uint8_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4212
0
{
4213
0
    struct pcapng_option_header option_hdr;
4214
4215
0
    option_hdr.type         = (uint16_t)option_id;
4216
0
    option_hdr.value_length = (uint16_t)1;
4217
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4218
0
        return false;
4219
4220
0
    if (!wtap_dump_file_write(wdh, &optval->uint8val, 1, err))
4221
0
        return false;
4222
4223
0
    if (!pcapng_write_padding(wdh, 3, err))
4224
0
        return false;
4225
4226
0
    return true;
4227
0
}
4228
4229
static bool pcapng_write_uint32_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4230
0
{
4231
0
    struct pcapng_option_header option_hdr;
4232
4233
0
    option_hdr.type         = (uint16_t)option_id;
4234
0
    option_hdr.value_length = (uint16_t)4;
4235
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4236
0
        return false;
4237
4238
0
    if (!wtap_dump_file_write(wdh, &optval->uint32val, 4, err))
4239
0
        return false;
4240
4241
0
    return true;
4242
0
}
4243
4244
static bool pcapng_write_uint64_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4245
0
{
4246
0
    struct pcapng_option_header option_hdr;
4247
4248
0
    option_hdr.type         = (uint16_t)option_id;
4249
0
    option_hdr.value_length = (uint16_t)8;
4250
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4251
0
        return false;
4252
4253
0
    if (!wtap_dump_file_write(wdh, &optval->uint64val, 8, err))
4254
0
        return false;
4255
4256
0
    return true;
4257
0
}
4258
4259
static bool pcapng_write_timestamp_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4260
0
{
4261
0
    struct pcapng_option_header option_hdr;
4262
0
    uint32_t high, low;
4263
4264
0
    option_hdr.type         = (uint16_t)option_id;
4265
0
    option_hdr.value_length = (uint16_t)8;
4266
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4267
0
        return false;
4268
4269
0
    high = (uint32_t)(optval->uint64val >> 32);
4270
0
    low = (uint32_t)(optval->uint64val >> 0);
4271
0
    if (!wtap_dump_file_write(wdh, &high, 4, err))
4272
0
        return false;
4273
0
    if (!wtap_dump_file_write(wdh, &low, 4, err))
4274
0
        return false;
4275
4276
0
    return true;
4277
0
}
4278
4279
static bool pcapng_write_string_option(wtap_dumper *wdh,
4280
                                       pcapng_opt_byte_order_e byte_order,
4281
                                       unsigned option_id,
4282
                                       wtap_optval_t *optval,
4283
                                       int *err, char **err_info)
4284
0
{
4285
0
    struct pcapng_option_header option_hdr;
4286
0
    size_t size = strlen(optval->stringval);
4287
4288
0
    if (size == 0)
4289
0
        return true;
4290
0
    if (size > 65535) {
4291
        /*
4292
         * Too big to fit in the option.
4293
         * Don't write anything.
4294
         *
4295
         * XXX - truncate it?  Report an error?
4296
         */
4297
0
        return true;
4298
0
    }
4299
4300
    /* write option header */
4301
    /* String options don't consider pad bytes part of the length */
4302
0
    option_hdr.type         = (uint16_t)option_id;
4303
0
    option_hdr.value_length = (uint16_t)size;
4304
0
    switch (byte_order) {
4305
4306
0
    case OPT_SECTION_BYTE_ORDER:
4307
        /* This is host byte order when writing, so nothing to do. */
4308
0
        break;
4309
4310
0
    case OPT_BIG_ENDIAN:
4311
0
        option_hdr.type = GUINT16_TO_BE(option_hdr.type);
4312
0
        option_hdr.value_length = GUINT16_TO_BE(option_hdr.value_length);
4313
0
        break;
4314
4315
0
    case OPT_LITTLE_ENDIAN:
4316
0
        option_hdr.type = GUINT16_TO_LE(option_hdr.type);
4317
0
        option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length);
4318
0
        break;
4319
4320
0
    default:
4321
        /*
4322
         * This indicates somebody passed an invalid option to
4323
         * pcapng_write_options().
4324
         *
4325
         * Report this as an internal error.
4326
         */
4327
0
        *err = WTAP_ERR_INTERNAL;
4328
0
        *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_write_options()",
4329
0
                                     byte_order);
4330
0
        return true;
4331
0
    }
4332
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4333
0
        return false;
4334
4335
0
    if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4336
0
        return false;
4337
4338
    /* write padding (if any) */
4339
0
    return pcapng_write_padding(wdh, WS_PADDING_TO_4(size), err);
4340
0
}
4341
4342
#if 0
4343
static bool pcapng_write_bytes_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4344
{
4345
    struct pcapng_option_header option_hdr;
4346
    size_t size = g_bytes_get_size(optval->byteval);
4347
4348
    if (size == 0)
4349
        return true;
4350
    if (size > 65535) {
4351
        /*
4352
         * Too big to fit in the option.
4353
         * Don't write anything.
4354
         *
4355
         * XXX - truncate it?  Report an error?
4356
         */
4357
        return true;
4358
    }
4359
4360
    /* Bytes options don't consider pad bytes part of the length */
4361
    option_hdr.type         = (uint16_t)option_id;
4362
    option_hdr.value_length = (uint16_t)size;
4363
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4364
        return false;
4365
4366
    if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4367
        return false;
4368
4369
    /* write padding (if any) */
4370
    return pcapng_write_padding(wdh, WS_PADDING_TO_4(size), err);
4371
}
4372
4373
static bool pcapng_write_ipv4_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4374
{
4375
    struct pcapng_option_header option_hdr;
4376
4377
    option_hdr.type         = (uint16_t)option_id;
4378
    option_hdr.value_length = (uint16_t)4;
4379
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4380
        return false;
4381
4382
    if (!wtap_dump_file_write(wdh, &optval->ipv4val, 1, err))
4383
        return false;
4384
4385
    return true;
4386
}
4387
4388
static bool pcapng_write_ipv6_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4389
{
4390
    struct pcapng_option_header option_hdr;
4391
4392
    option_hdr.type         = (uint16_t)option_id;
4393
    option_hdr.value_length = (uint16_t)IPv6_ADDR_SIZE;
4394
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4395
        return false;
4396
4397
    if (!wtap_dump_file_write(wdh, &optval->ipv6val.bytes, IPv6_ADDR_SIZE, err))
4398
        return false;
4399
4400
    return true;
4401
}
4402
#endif
4403
4404
static bool pcapng_write_if_filter_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4405
0
{
4406
0
    if_filter_opt_t* filter = &optval->if_filterval;
4407
0
    uint32_t size;
4408
0
    uint8_t filter_type;
4409
0
    size_t filter_data_len;
4410
0
    struct pcapng_option_header option_hdr;
4411
4412
0
    switch (filter->type) {
4413
4414
0
    case if_filter_pcap:
4415
0
        filter_type = 0; /* pcap filter string */
4416
0
        filter_data_len = strlen(filter->data.filter_str);
4417
0
        if (filter_data_len > 65534) {
4418
            /*
4419
             * Too big to fit in the option.
4420
             * Don't write anything.
4421
             *
4422
             * XXX - truncate it?  Report an error?
4423
             */
4424
0
            return true;
4425
0
        }
4426
0
        break;
4427
4428
0
    case if_filter_bpf:
4429
0
        filter_type = 1; /* BPF filter program */
4430
0
        filter_data_len = filter->data.bpf_prog.bpf_prog_len*8;
4431
0
        if (filter_data_len > 65528) {
4432
            /*
4433
             * Too big to fit in the option.  (The filter length
4434
             * must be a multiple of 8, as that's the length
4435
             * of a BPF instruction.)  Don't write anything.
4436
             *
4437
             * XXX - truncate it?  Report an error?
4438
             */
4439
0
            return true;
4440
0
        }
4441
0
        break;
4442
4443
0
    default:
4444
        /* Unknown filter type; don't write anything. */
4445
0
        return true;
4446
0
    }
4447
0
    size = (uint32_t)(filter_data_len + 1);
4448
4449
0
    option_hdr.type         = option_id;
4450
0
    option_hdr.value_length = size;
4451
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4452
0
        return false;
4453
4454
    /* Write the filter type */
4455
0
    if (!wtap_dump_file_write(wdh, &filter_type, 1, err))
4456
0
        return false;
4457
4458
0
    switch (filter->type) {
4459
4460
0
    case if_filter_pcap:
4461
        /* Write the filter string */
4462
0
        if (!wtap_dump_file_write(wdh, filter->data.filter_str, filter_data_len, err))
4463
0
            return false;
4464
0
        break;
4465
4466
0
    case if_filter_bpf:
4467
0
        if (!wtap_dump_file_write(wdh, filter->data.bpf_prog.bpf_prog, filter_data_len, err))
4468
0
            return false;
4469
0
        break;
4470
4471
0
    default:
4472
0
        ws_assert_not_reached();
4473
0
        return true;
4474
0
    }
4475
4476
    /* write padding (if any) */
4477
0
    return pcapng_write_padding(wdh, WS_PADDING_TO_4(size), err);
4478
0
}
4479
4480
static bool pcapng_write_custom_string_option(wtap_dumper *wdh,
4481
                                       pcapng_opt_byte_order_e byte_order,
4482
                                       unsigned option_id,
4483
                                       wtap_optval_t *optval,
4484
                                       int *err, char **err_info)
4485
0
{
4486
0
    struct pcapng_option_header option_hdr;
4487
0
    size_t stringlen;
4488
0
    size_t size;
4489
0
    uint32_t pen;
4490
4491
0
    if (option_id == OPT_CUSTOM_STR_NO_COPY)
4492
0
        return true;
4493
0
    ws_debug("PEN %u", optval->custom_stringval.pen);
4494
0
    stringlen = strlen(optval->custom_stringval.string);
4495
0
    size = sizeof(uint32_t) + stringlen;
4496
0
    if (size > 65535) {
4497
        /*
4498
         * Too big to fit in the option.
4499
         * Don't write anything.
4500
         *
4501
         * XXX - truncate it?  Report an error?
4502
         */
4503
0
        return true;
4504
0
    }
4505
4506
    /* write option header and PEN */
4507
    /* String options don't consider pad bytes part of the length */
4508
0
    option_hdr.type         = (uint16_t)option_id;
4509
0
    option_hdr.value_length = (uint16_t)size;
4510
0
    pen                     = optval->custom_stringval.pen;
4511
0
    switch (byte_order) {
4512
4513
0
    case OPT_SECTION_BYTE_ORDER:
4514
        /* This is host byte order when writing, so nothing to do. */
4515
0
        break;
4516
4517
0
    case OPT_BIG_ENDIAN:
4518
0
        option_hdr.type = GUINT16_TO_BE(option_hdr.type);
4519
0
        option_hdr.value_length = GUINT16_TO_BE(option_hdr.value_length);
4520
0
        pen = GUINT32_TO_BE(pen);
4521
0
        break;
4522
4523
0
    case OPT_LITTLE_ENDIAN:
4524
0
        option_hdr.type = GUINT16_TO_LE(option_hdr.type);
4525
0
        option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length);
4526
0
        pen = GUINT32_TO_LE(pen);
4527
0
        break;
4528
4529
0
    default:
4530
        /*
4531
         * This indicates somebody passed an invalid option to
4532
         * pcapng_write_options().
4533
         *
4534
         * Report this as an internal error.
4535
         */
4536
0
        *err = WTAP_ERR_INTERNAL;
4537
0
        *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_write_options()",
4538
0
                                     byte_order);
4539
0
        return true;
4540
0
    }
4541
0
    if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4542
0
        return false;
4543
0
    if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err))
4544
0
        return false;
4545
4546
    /* write custom data */
4547
0
    if (!wtap_dump_file_write(wdh, optval->custom_stringval.string, stringlen, err)) {
4548
0
        return false;
4549
0
    }
4550
0
    ws_debug("Wrote custom option: type %u, length %u", option_hdr.type, option_hdr.value_length);
4551
4552
    /* write padding (if any) */
4553
0
    return pcapng_write_padding(wdh, WS_PADDING_TO_4(size), err);
4554
0
}
4555
4556
static bool pcapng_write_custom_binary_option(wtap_dumper *wdh,
4557
                                              pcapng_opt_byte_order_e byte_order,
4558
                                              unsigned option_id,
4559
                                              wtap_optval_t *optval,
4560
                                              int *err, char **err_info)
4561
0
{
4562
0
    struct pcapng_option_header option_hdr;
4563
0
    size_t size;
4564
0
    uint32_t pen;
4565
4566
0
    if (option_id == OPT_CUSTOM_BIN_NO_COPY)
4567
0
        return true;
4568
0
    ws_debug("PEN %u", optval->custom_binaryval.pen);
4569
0
    size = sizeof(uint32_t) + optval->custom_binaryval.data.custom_data_len;
4570
0
    if (size > 65535) {
4571
        /*
4572
         * Too big to fit in the option.
4573
         * Don't write anything.
4574
         *
4575
         * XXX - truncate it?  Report an error?
4576
         */
4577
0
        return true;
4578
0
    }
4579
4580
    /* write option header and PEN */
4581
0
    option_hdr.type         = (uint16_t)option_id;
4582
0
    option_hdr.value_length = (uint16_t)size;
4583
0
    pen                     = optval->custom_binaryval.pen;
4584
0
    switch (byte_order) {
4585
4586
0
    case OPT_SECTION_BYTE_ORDER:
4587
        /* This is host byte order when writing, so nothing to do. */
4588
0
        break;
4589
4590
0
    case OPT_BIG_ENDIAN:
4591
0
        option_hdr.type = GUINT16_TO_BE(option_hdr.type);
4592
0
        option_hdr.value_length = GUINT16_TO_BE(option_hdr.value_length);
4593
0
        pen = GUINT32_TO_BE(pen);
4594
0
        break;
4595
4596
0
    case OPT_LITTLE_ENDIAN:
4597
0
        option_hdr.type = GUINT16_TO_LE(option_hdr.type);
4598
0
        option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length);
4599
0
        pen = GUINT32_TO_LE(pen);
4600
0
        break;
4601
4602
0
    default:
4603
        /*
4604
         * This indicates somebody passed an invalid option to
4605
         * pcapng_write_options().
4606
         *
4607
         * Report this as an internal error.
4608
         */
4609
0
        *err = WTAP_ERR_INTERNAL;
4610
0
        *err_info = ws_strdup_printf("pcapng: invalid byte order %d passed to pcapng_write_options()",
4611
0
                                     byte_order);
4612
0
        return true;
4613
0
    }
4614
0
    if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4615
0
        return false;
4616
0
    if (!wtap_dump_file_write(wdh, &pen, sizeof(uint32_t), err))
4617
0
        return false;
4618
4619
    /* write custom data */
4620
0
    if (!wtap_dump_file_write(wdh, optval->custom_binaryval.data.custom_data, optval->custom_binaryval.data.custom_data_len, err)) {
4621
0
        return false;
4622
0
    }
4623
0
    ws_debug("Wrote custom option: type %u, length %u", option_hdr.type, option_hdr.value_length);
4624
4625
    /* write padding (if any) */
4626
0
    return pcapng_write_padding(wdh, WS_PADDING_TO_4(size), err);
4627
0
}
4628
4629
static bool pcapng_write_packet_verdict_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4630
0
{
4631
0
    packet_verdict_opt_t* verdict = &optval->packet_verdictval;
4632
0
    struct pcapng_option_header option_hdr;
4633
0
    uint8_t type;
4634
0
    size_t size;
4635
4636
0
    size = pcapng_compute_packet_verdict_option_size(optval);
4637
4638
0
    switch (verdict->type) {
4639
4640
0
    case packet_verdict_hardware:
4641
0
        if (size > 65535) {
4642
            /*
4643
             * Too big to fit in the option.
4644
             * Don't write anything.
4645
             *
4646
             * XXX - truncate it?  Report an error?
4647
             */
4648
0
            return true;
4649
0
        }
4650
0
        option_hdr.type         = option_id;
4651
0
        option_hdr.value_length = (uint16_t)size;
4652
0
        if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4653
0
            return false;
4654
4655
0
        type = packet_verdict_hardware;
4656
0
        if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4657
0
            return false;
4658
4659
0
        if (!wtap_dump_file_write(wdh, verdict->data.verdict_bytes->data,
4660
0
                                  verdict->data.verdict_bytes->len, err))
4661
0
            return false;
4662
0
        break;
4663
4664
0
    case packet_verdict_linux_ebpf_tc:
4665
0
        option_hdr.type         = option_id;
4666
0
        option_hdr.value_length = (uint16_t)size;
4667
0
        if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4668
0
            return false;
4669
4670
0
        type = packet_verdict_linux_ebpf_tc;
4671
0
        if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4672
0
            return false;
4673
4674
0
        if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_tc,
4675
0
                                  sizeof(uint64_t), err))
4676
0
            return false;
4677
0
        break;
4678
4679
0
    case packet_verdict_linux_ebpf_xdp:
4680
0
        option_hdr.type         = option_id;
4681
0
        option_hdr.value_length = (uint16_t)size;
4682
0
        if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4683
0
            return false;
4684
4685
0
        type = packet_verdict_linux_ebpf_xdp;
4686
0
        if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4687
0
            return false;
4688
4689
0
        if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_xdp,
4690
0
                                  sizeof(uint64_t), err))
4691
0
            return false;
4692
0
        break;
4693
4694
0
    default:
4695
        /* Unknown - don't write it out. */
4696
0
        return true;
4697
0
    }
4698
4699
    /* write padding (if any) */
4700
0
    return pcapng_write_padding(wdh, WS_PADDING_TO_4(size), err);
4701
0
}
4702
4703
static bool pcapng_write_packet_hash_option(wtap_dumper *wdh, unsigned option_id, wtap_optval_t *optval, int *err)
4704
0
{
4705
0
    packet_hash_opt_t* hash = &optval->packet_hash;
4706
0
    struct pcapng_option_header option_hdr;
4707
0
    uint8_t type;
4708
0
    size_t size;
4709
4710
0
    size = pcapng_compute_packet_hash_option_size(optval);
4711
4712
0
    if (size > 65535) {
4713
        /*
4714
         * Too big to fit in the option.
4715
         * Don't write anything.
4716
         *
4717
         * XXX - truncate it?  Report an error?
4718
         */
4719
0
        return true;
4720
0
    }
4721
4722
0
    if (size > hash->hash_bytes->len + 1) {
4723
        /*
4724
         * We don't have enough bytes to write.
4725
         * pcapng_compute_packet_hash_option_size() should return 0 if
4726
         * we want to silently omit the option instead, or should return
4727
         * the length if we want to blindly copy it.
4728
         * XXX - Is this the best error type?
4729
         */
4730
0
        *err = WTAP_ERR_UNWRITABLE_REC_DATA;
4731
0
        return false;
4732
0
    }
4733
4734
0
    type = hash->type;
4735
4736
0
    option_hdr.type         = option_id;
4737
    /* Include type byte */
4738
0
    option_hdr.value_length = (uint16_t)size;
4739
0
    if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4740
0
        return false;
4741
4742
0
    if (!wtap_dump_file_write(wdh, &type, sizeof(uint8_t), err))
4743
0
        return false;
4744
4745
0
    if (!wtap_dump_file_write(wdh, hash->hash_bytes->data, size - 1,
4746
0
                              err))
4747
0
        return false;
4748
4749
    /* write padding (if any) */
4750
0
    return pcapng_write_padding(wdh, WS_PADDING_TO_4(size), err);
4751
0
}
4752
4753
static bool write_block_option(wtap_block_t block,
4754
                               unsigned option_id,
4755
                               wtap_opttype_e option_type _U_,
4756
                               wtap_optval_t *optval, void* user_data)
4757
0
{
4758
0
    write_options_t* options = (write_options_t*)user_data;
4759
4760
    /*
4761
     * Process the option IDs that are the same for all block types here;
4762
     * call the block-type-specific write function for others.
4763
     */
4764
0
    switch(option_id)
4765
0
    {
4766
0
    case OPT_COMMENT:
4767
0
        if (!pcapng_write_string_option(options->wdh, options->byte_order,
4768
0
                                        option_id, optval,
4769
0
                                        options->err, options->err_info))
4770
0
            return false;
4771
0
        break;
4772
0
    case OPT_CUSTOM_STR_COPY:
4773
0
        if (!pcapng_write_custom_string_option(options->wdh,
4774
0
                                               options->byte_order,
4775
0
                                        option_id, optval,
4776
0
                                        options->err, options->err_info))
4777
0
            return false;
4778
0
        break;
4779
0
    case OPT_CUSTOM_BIN_COPY:
4780
0
        if (!pcapng_write_custom_binary_option(options->wdh,
4781
0
                                                options->byte_order,
4782
0
                                                option_id, optval,
4783
0
                                                options->err,
4784
0
                                                options->err_info))
4785
0
            return false;
4786
0
        break;
4787
0
    case OPT_CUSTOM_STR_NO_COPY:
4788
0
    case OPT_CUSTOM_BIN_NO_COPY:
4789
        /*
4790
         * Do not write these, as they're not supposed to be copied to
4791
         * new files.
4792
         *
4793
         * XXX - what if we're writing out a file that's *not* based on
4794
         * another file, so that we're *not* copying it from that file?
4795
         */
4796
0
        break;
4797
0
    default:
4798
        /* Block-type dependent; call the callback, if we have one. */
4799
0
        if (options->write_option != NULL &&
4800
0
            !(*options->write_option)(options->wdh, block, option_id,
4801
0
                                      option_type, optval,
4802
0
                                      options->err, options->err_info))
4803
0
            return false;
4804
0
        break;
4805
0
    }
4806
0
    return true;
4807
0
}
4808
4809
bool
4810
pcapng_write_options(wtap_dumper *wdh, pcapng_opt_byte_order_e byte_order,
4811
                     wtap_block_t block, write_option_func write_option,
4812
                     int *err, char **err_info)
4813
0
{
4814
0
    write_options_t options;
4815
4816
0
    options.wdh = wdh;
4817
0
    options.byte_order = byte_order;
4818
0
    options.write_option = write_option;
4819
0
    options.err = err;
4820
0
    options.err_info = err_info;
4821
0
    if (!wtap_block_foreach_option(block, write_block_option, &options))
4822
0
        return false;
4823
4824
    /* Write end of options */
4825
0
    return pcapng_write_option_eofopt(wdh, err);
4826
0
}
4827
4828
static bool write_wtap_shb_option(wtap_dumper *wdh, wtap_block_t block _U_,
4829
                                  unsigned option_id,
4830
                                  wtap_opttype_e option_type _U_,
4831
                                  wtap_optval_t *optval,
4832
                                  int *err, char **err_info)
4833
0
{
4834
0
    switch(option_id)
4835
0
    {
4836
0
    case OPT_SHB_HARDWARE:
4837
0
    case OPT_SHB_OS:
4838
0
    case OPT_SHB_USERAPPL:
4839
0
        if (!pcapng_write_string_option(wdh, OPT_SECTION_BYTE_ORDER,
4840
0
                                        option_id, optval, err, err_info))
4841
0
            return false;
4842
0
        break;
4843
0
    default:
4844
        /* Unknown options - write by datatype? */
4845
0
        break;
4846
0
    }
4847
0
    return true; /* success */
4848
0
}
4849
4850
/* Write a section header block.
4851
 * If we don't have a section block header already, create a default
4852
 * one with no options.
4853
 */
4854
static bool
4855
pcapng_write_section_header_block(wtap_dumper *wdh, int *err, char **err_info)
4856
0
{
4857
0
    uint32_t block_content_length;
4858
0
    pcapng_section_header_block_t shb;
4859
0
    uint32_t options_size;
4860
0
    wtap_block_t wdh_shb = NULL;
4861
4862
0
    if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
4863
0
        wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0);
4864
0
    }
4865
4866
0
    block_content_length = (uint32_t)sizeof(shb);
4867
0
    options_size = 0;
4868
0
    if (wdh_shb) {
4869
0
        ws_debug("Have shb_hdr");
4870
4871
        /* Compute size of all the options */
4872
0
        options_size = pcapng_compute_options_size(wdh_shb, compute_shb_option_size);
4873
4874
0
        block_content_length += options_size;
4875
0
    }
4876
4877
    /* write block header */
4878
0
    if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SHB, block_content_length,
4879
0
                                   err))
4880
0
        return false;
4881
4882
    /* write block fixed content */
4883
0
    shb.magic = 0x1A2B3C4D;
4884
0
    shb.version_major = 1;
4885
0
    shb.version_minor = 0;
4886
0
    if (wdh_shb) {
4887
0
        wtapng_section_mandatory_t* section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wdh_shb);
4888
0
        shb.section_length = section_data->section_length;
4889
0
    } else {
4890
0
        shb.section_length = -1;
4891
0
    }
4892
4893
0
    if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
4894
0
        return false;
4895
4896
0
    if (wdh_shb) {
4897
        /* Write options, if we have any */
4898
0
        if (options_size != 0) {
4899
0
            if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
4900
0
                                      wdh_shb, write_wtap_shb_option,
4901
0
                                      err, err_info))
4902
0
                return false;
4903
0
        }
4904
0
    }
4905
4906
    /* write block footer */
4907
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
4908
0
}
4909
4910
/* options defined in Section 2.5 (Options)
4911
 * Name           Code Length     Description
4912
 * opt_comment    1    variable   A UTF-8 string containing a comment that is associated to the current block.
4913
 *
4914
 * Enhanced Packet Block options
4915
 * epb_flags      2    4          A flags word containing link-layer information. A complete specification of
4916
 *                                the allowed flags can be found in Appendix A (Packet Block Flags Word).
4917
 * epb_hash       3    variable   This option contains a hash of the packet. The first byte specifies the hashing algorithm,
4918
 *                                while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
4919
 *                                                                and hence from the value in the first bit. The hashing algorithm can be: 2s complement
4920
 *                                                                (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
4921
 *                                                                MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
4922
 *                                                                The hash covers only the packet, not the header added by the capture driver:
4923
 *                                                                this gives the possibility to calculate it inside the network card.
4924
 *                                                                The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
4925
 *                                                                data acquisition system and the capture library.
4926
 * epb_dropcount   4   8          A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
4927
 *                                between this packet and the preceding one.
4928
 * epb_packetid    5   8          The epb_packetid option is a 64-bit unsigned integer that
4929
 *                                uniquely identifies the packet.  If the same packet is seen
4930
 *                                by multiple interfaces and there is a way for the capture
4931
 *                                application to correlate them, the same epb_packetid value
4932
 *                                must be used.  An example could be a router that captures
4933
 *                                packets on all its interfaces in both directions.  When a
4934
 *                                packet hits interface A on ingress, an EPB entry gets
4935
 *                                created, TTL gets decremented, and right before it egresses
4936
 *                                on interface B another EPB entry gets created in the trace
4937
 *                                file.  In this case, two packets are in the capture file,
4938
 *                                which are not identical but the epb_packetid can be used to
4939
 *                                correlate them.
4940
 * epb_queue       6   4          The epb_queue option is a 32-bit unsigned integer that
4941
 *                                identifies on which queue of the interface the specific
4942
 *                                packet was received.
4943
 * epb_verdict     7   variable   The epb_verdict option stores a verdict of the packet.  The
4944
 *                                verdict indicates what would be done with the packet after
4945
 *                                processing it.  For example, a firewall could drop the
4946
 *                                packet.  This verdict can be set by various components, i.e.
4947
 *                                Hardware, Linux's eBPF TC or XDP framework, etc.  etc.  The
4948
 *                                first octet specifies the verdict type, while the following
4949
 *                                octets contain the actual verdict data, whose size depends on
4950
 *                                the verdict type, and hence from the value in the first
4951
 *                                octet.  The verdict type can be: Hardware (type octet = 0,
4952
 *                                size = variable), Linux_eBPF_TC (type octet = 1, size = 8
4953
 *                                (64-bit unsigned integer), value = TC_ACT_* as defined in the
4954
 *                                Linux pck_cls.h include), Linux_eBPF_XDP (type octet = 2,
4955
 *                                size = 8 (64-bit unsigned integer), value = xdp_action as
4956
 *                                defined in the Linux pbf.h include).
4957
 * opt_endofopt    0   0          It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
4958
 */
4959
static uint32_t
4960
compute_epb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
4961
0
{
4962
0
    uint32_t size;
4963
4964
0
    switch(option_id)
4965
0
    {
4966
0
    case OPT_PKT_FLAGS:
4967
0
        size = 4;
4968
0
        break;
4969
0
    case OPT_PKT_HASH:
4970
0
        size = pcapng_compute_packet_hash_option_size(optval);
4971
0
        break;
4972
0
    case OPT_PKT_DROPCOUNT:
4973
0
        size = 8;
4974
0
        break;
4975
0
    case OPT_PKT_PACKETID:
4976
0
        size = 8;
4977
0
        break;
4978
0
    case OPT_PKT_QUEUE:
4979
0
        size = 4;
4980
0
        break;
4981
0
    case OPT_PKT_VERDICT:
4982
0
        size = pcapng_compute_packet_verdict_option_size(optval);
4983
0
        break;
4984
0
    case OPT_PKT_PROCIDTHRDID:
4985
0
        size = 8;
4986
0
        break;
4987
0
    default:
4988
        /* Unknown options - size by datatype? */
4989
0
        size = pcapng_compute_epb_legacy_darwin_size(option_id, optval);
4990
0
        break;
4991
0
    }
4992
0
    return size;
4993
0
}
4994
4995
static bool write_wtap_epb_option(wtap_dumper *wdh, wtap_block_t block _U_,
4996
                                  unsigned option_id,
4997
                                  wtap_opttype_e option_type _U_,
4998
                                  wtap_optval_t *optval,
4999
                                  int *err, char **err_info _U_)
5000
0
{
5001
0
    switch(option_id)
5002
0
    {
5003
0
    case OPT_PKT_FLAGS:
5004
0
        if (!pcapng_write_uint32_option(wdh, OPT_PKT_FLAGS, optval, err))
5005
0
            return false;
5006
0
        break;
5007
0
    case OPT_PKT_HASH:
5008
0
        if (!pcapng_write_packet_hash_option(wdh, OPT_PKT_HASH, optval, err))
5009
0
            return false;
5010
0
        break;
5011
0
    case OPT_PKT_DROPCOUNT:
5012
0
        if (!pcapng_write_uint64_option(wdh, OPT_PKT_DROPCOUNT, optval, err))
5013
0
            return false;
5014
0
        break;
5015
0
    case OPT_PKT_PACKETID:
5016
0
        if (!pcapng_write_uint64_option(wdh, OPT_PKT_PACKETID, optval, err))
5017
0
            return false;
5018
0
        break;
5019
0
    case OPT_PKT_QUEUE:
5020
0
        if (!pcapng_write_uint32_option(wdh, OPT_PKT_QUEUE, optval, err))
5021
0
            return false;
5022
0
        break;
5023
0
    case OPT_PKT_VERDICT:
5024
0
        if (!pcapng_write_packet_verdict_option(wdh, OPT_PKT_VERDICT, optval, err))
5025
0
            return false;
5026
0
        break;
5027
0
    case OPT_PKT_PROCIDTHRDID:
5028
0
        if (!pcapng_write_uint64_option(wdh, OPT_PKT_PROCIDTHRDID, optval, err))
5029
0
            return false;
5030
0
        break;
5031
0
    default: {
5032
        /* Check if this is legacy darwin option */
5033
0
        if (!pcapng_write_epb_legacy_darwin_option(wdh, block, option_id, option_type, optval, err, err_info))
5034
0
            return false;
5035
        /* Unknown options - write by datatype? */
5036
0
        break;
5037
0
    }
5038
0
    }
5039
0
    return true; /* success */
5040
0
}
5041
5042
static bool
5043
pcapng_write_simple_packet_block(wtap_dumper* wdh, const wtap_rec* rec,
5044
                                 int* err, char** err_info _U_)
5045
0
{
5046
0
    const union wtap_pseudo_header* pseudo_header = &rec->rec_header.packet_header.pseudo_header;
5047
0
    uint32_t block_content_length;
5048
0
    pcapng_simple_packet_block_t spb;
5049
0
    uint32_t pad_len;
5050
0
    uint32_t phdr_len;
5051
5052
    /* Don't write anything we're not willing to read. */
5053
0
    if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
5054
0
        *err = WTAP_ERR_PACKET_TOO_LARGE;
5055
0
        return false;
5056
0
    }
5057
5058
0
    phdr_len = pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
5059
0
    pad_len = WS_PADDING_TO_4(phdr_len + rec->rec_header.packet_header.caplen);
5060
5061
    /* write (simple) packet block header */
5062
0
    block_content_length = (uint32_t)sizeof(spb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len;
5063
0
    if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SPB, block_content_length,
5064
0
                                   err))
5065
0
        return false;
5066
5067
    /* write block fixed content */
5068
0
    spb.packet_len = rec->rec_header.packet_header.len + phdr_len;
5069
5070
0
    if (!wtap_dump_file_write(wdh, &spb, sizeof spb, err))
5071
0
        return false;
5072
5073
    /* write pseudo header */
5074
0
    if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5075
0
        return false;
5076
0
    }
5077
5078
    /* write packet data */
5079
0
    if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.packet_header.caplen, err))
5080
0
        return false;
5081
5082
    /* write padding (if any) */
5083
0
    if (!pcapng_write_padding(wdh, pad_len, err))
5084
0
        return false;
5085
5086
    /* write block footer */
5087
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
5088
0
}
5089
5090
static bool
5091
pcapng_write_enhanced_packet_block(wtap_dumper *wdh, const wtap_rec *rec,
5092
                                   int *err, char **err_info)
5093
0
{
5094
0
    const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
5095
0
    uint32_t block_content_length;
5096
0
    pcapng_enhanced_packet_block_t epb;
5097
0
    uint32_t options_size = 0;
5098
0
    uint64_t ts;
5099
0
    uint32_t pad_len;
5100
0
    uint32_t phdr_len;
5101
0
    wtap_block_t int_data;
5102
0
    wtapng_if_descr_mandatory_t *int_data_mand;
5103
5104
    /* Don't write anything we're not willing to read. */
5105
0
    if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->file_encap)) {
5106
0
        *err = WTAP_ERR_PACKET_TOO_LARGE;
5107
0
        return false;
5108
0
    }
5109
5110
0
    phdr_len = pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
5111
0
    pad_len = WS_PADDING_TO_4(phdr_len + rec->rec_header.packet_header.caplen);
5112
5113
0
    if (rec->block != NULL) {
5114
        /* Compute size of all the options */
5115
0
        options_size = pcapng_compute_options_size(rec->block, compute_epb_option_size);
5116
0
    }
5117
5118
    /*
5119
     * Check the interface ID. Do this before writing the header,
5120
     * in case we need to add a new IDB.
5121
     */
5122
0
    if (rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
5123
0
        epb.interface_id        = rec->rec_header.packet_header.interface_id;
5124
0
        if (rec->presence_flags & WTAP_HAS_SECTION_NUMBER && wdh->shb_iface_to_global) {
5125
            /*
5126
             * In the extremely unlikely event this overflows we give the
5127
             * wrong interface ID.
5128
             */
5129
0
            epb.interface_id += g_array_index(wdh->shb_iface_to_global, unsigned, rec->section_number);
5130
0
        }
5131
0
    } else {
5132
        /*
5133
         * The source isn't sending us IDBs. See if we already have a
5134
         * matching interface, and use it if so.
5135
         */
5136
0
        for (epb.interface_id = 0; epb.interface_id < wdh->interface_data->len; ++epb.interface_id) {
5137
0
            int_data = g_array_index(wdh->interface_data, wtap_block_t,
5138
0
                                     epb.interface_id);
5139
0
            int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5140
0
            if (int_data_mand->wtap_encap == rec->rec_header.packet_header.pkt_encap) {
5141
0
                if (int_data_mand->tsprecision == rec->tsprec || (!(rec->presence_flags & WTAP_HAS_TS))) {
5142
0
                    break;
5143
0
                }
5144
0
            }
5145
0
        }
5146
0
        if (epb.interface_id == wdh->interface_data->len) {
5147
            /*
5148
             * We don't have a matching IDB. Generate a new one
5149
             * and write it to the file.
5150
             */
5151
0
            int_data = wtap_rec_generate_idb(rec);
5152
0
            g_array_append_val(wdh->interface_data, int_data);
5153
0
            if (!pcapng_write_if_descr_block(wdh, int_data, err, err_info)) {
5154
0
                return false;
5155
0
            }
5156
0
        }
5157
0
    }
5158
0
    if (epb.interface_id >= wdh->interface_data->len) {
5159
        /*
5160
         * Our caller is doing something bad.
5161
         */
5162
0
        *err = WTAP_ERR_INTERNAL;
5163
0
        *err_info = ws_strdup_printf("pcapng: epb.interface_id (%u) >= wdh->interface_data->len (%u)",
5164
0
                                    epb.interface_id, wdh->interface_data->len);
5165
0
        return false;
5166
0
    }
5167
0
    int_data = g_array_index(wdh->interface_data, wtap_block_t,
5168
0
                             epb.interface_id);
5169
0
    int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5170
0
    if (int_data_mand->wtap_encap != rec->rec_header.packet_header.pkt_encap) {
5171
        /*
5172
         * Our caller is doing something bad.
5173
         */
5174
0
        *err = WTAP_ERR_INTERNAL;
5175
0
        *err_info = ws_strdup_printf("pcapng: interface %u encap %d != packet encap %d",
5176
0
                                    epb.interface_id,
5177
0
                                    int_data_mand->wtap_encap,
5178
0
                                    rec->rec_header.packet_header.pkt_encap);
5179
0
        return false;
5180
0
    }
5181
5182
    /* write (enhanced) packet block header */
5183
0
    block_content_length = (uint32_t)sizeof(epb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + options_size;
5184
0
    if (!pcapng_write_block_header(wdh, BLOCK_TYPE_EPB, block_content_length,
5185
0
                                   err))
5186
0
        return false;
5187
5188
    /* write block fixed content */
5189
    /* Calculate the time stamp as a 64-bit integer. */
5190
    /* TODO - This can't overflow currently because we don't allow greater
5191
     * than nanosecond resolution, but if and when we do, we need to check for
5192
     * overflow. Normally it shouldn't, but what if there was a time shift?
5193
     */
5194
0
    ts = ((uint64_t)rec->ts.secs) * int_data_mand->time_units_per_second +
5195
0
        (((uint64_t)rec->ts.nsecs) * int_data_mand->time_units_per_second) / NS_PER_S;
5196
    /*
5197
     * Split the 64-bit timestamp into two 32-bit pieces, using
5198
     * the time stamp resolution for the interface.
5199
     */
5200
0
    epb.timestamp_high      = (uint32_t)(ts >> 32);
5201
0
    epb.timestamp_low       = (uint32_t)ts;
5202
0
    epb.captured_len        = rec->rec_header.packet_header.caplen + phdr_len;
5203
0
    epb.packet_len          = rec->rec_header.packet_header.len + phdr_len;
5204
5205
0
    if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
5206
0
        return false;
5207
5208
    /* write pseudo header */
5209
0
    if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
5210
0
        return false;
5211
0
    }
5212
5213
    /* write packet data */
5214
0
    if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.packet_header.caplen, err))
5215
0
        return false;
5216
5217
    /* write padding (if any) */
5218
0
    if (!pcapng_write_padding(wdh, pad_len, err))
5219
0
        return false;
5220
5221
    /* Write options, if we have any */
5222
0
    if (options_size != 0) {
5223
0
        if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5224
0
                                  rec->block, write_wtap_epb_option,
5225
0
                                  err, err_info))
5226
0
            return false;
5227
0
    }
5228
5229
    /* write block footer */
5230
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
5231
0
}
5232
5233
static bool
5234
pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
5235
                                          int *err, char **err_info _U_)
5236
0
{
5237
0
    uint32_t block_content_length;
5238
0
    uint32_t pad_len;
5239
5240
    /* Don't write anything we're not willing to read. */
5241
0
    if (rec->rec_header.systemd_journal_export_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
5242
0
        *err = WTAP_ERR_PACKET_TOO_LARGE;
5243
0
        return false;
5244
0
    }
5245
5246
0
    pad_len = WS_PADDING_TO_4(rec->rec_header.systemd_journal_export_header.record_len);
5247
5248
    /* write systemd journal export block header */
5249
0
    block_content_length = rec->rec_header.systemd_journal_export_header.record_len + pad_len;
5250
0
    ws_debug("writing %u bytes, %u padded",
5251
0
             rec->rec_header.systemd_journal_export_header.record_len,
5252
0
             block_content_length);
5253
0
    if (!pcapng_write_block_header(wdh, BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT,
5254
0
                                   block_content_length, err))
5255
0
        return false;
5256
5257
    /* write entry data */
5258
0
    if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.systemd_journal_export_header.record_len, err))
5259
0
        return false;
5260
5261
    /* write padding (if any) */
5262
0
    if (!pcapng_write_padding(wdh, pad_len, err))
5263
0
        return false;
5264
5265
    /* write block footer */
5266
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
5267
0
}
5268
5269
static bool
5270
pcapng_write_custom_block_copy(wtap_dumper *wdh, const wtap_rec *rec,
5271
                               int *err, char **err_info _U_)
5272
0
{
5273
0
    pcapng_custom_block_enterprise_handler_t const *pen_handler;
5274
0
    uint32_t block_content_length;
5275
0
    pcapng_custom_block_t cb;
5276
0
    uint32_t pad_len;
5277
5278
    /* Don't write anything we are not supposed to. */
5279
0
    if (!rec->rec_header.custom_block_header.copy_allowed) {
5280
0
        return true;
5281
0
    }
5282
5283
0
    pen_handler = (pcapng_custom_block_enterprise_handler_t const *)g_hash_table_lookup(custom_enterprise_handlers, GUINT_TO_POINTER(rec->rec_header.custom_block_header.pen));
5284
0
    if (pen_handler != NULL)
5285
0
    {
5286
0
        if (!pen_handler->writer(wdh, rec, err, err_info))
5287
0
            return false;
5288
0
    }
5289
0
    else
5290
0
    {
5291
        /* Don't write anything we're not willing to read. */
5292
0
        if (rec->rec_header.custom_block_header.length > WTAP_MAX_PACKET_SIZE_STANDARD) {
5293
0
            *err = WTAP_ERR_PACKET_TOO_LARGE;
5294
0
            return false;
5295
0
        }
5296
5297
0
        pad_len = WS_PADDING_TO_4(rec->rec_header.custom_block_header.length);
5298
5299
        /* write block header */
5300
0
        block_content_length = (uint32_t)sizeof(cb) + rec->rec_header.custom_block_header.length + pad_len;
5301
0
        ws_debug("writing %u bytes, %u padded, PEN %u",
5302
0
                 (uint32_t)sizeof(cb) + rec->rec_header.custom_block_header.length,
5303
0
                 block_content_length, rec->rec_header.custom_block_header.pen);
5304
0
        if (!pcapng_write_block_header(wdh, BLOCK_TYPE_CB_COPY,
5305
0
                                       block_content_length, err))
5306
0
            return false;
5307
5308
        /* write custom block header */
5309
0
        cb.pen = rec->rec_header.custom_block_header.pen;
5310
0
        if (!wtap_dump_file_write(wdh, &cb, sizeof cb, err)) {
5311
0
            return false;
5312
0
        }
5313
0
        ws_debug("wrote PEN = %u", cb.pen);
5314
5315
        /* write custom data */
5316
0
        if (!wtap_dump_file_write(wdh, ws_buffer_start_ptr(&rec->data), rec->rec_header.custom_block_header.length, err)) {
5317
0
            return false;
5318
0
        }
5319
5320
        /* write padding (if any) */
5321
0
        if (!pcapng_write_padding(wdh, pad_len, err))
5322
0
            return false;
5323
5324
        /* write block footer */
5325
0
        return pcapng_write_block_footer(wdh, block_content_length, err);
5326
0
    }
5327
0
    return true;
5328
0
}
5329
5330
static bool
5331
pcapng_write_custom_block_no_copy(wtap_dumper *wdh _U_, const wtap_rec *rec _U_,
5332
                                  int *err _U_, char **err_info _U_)
5333
0
{
5334
    /* Don't write anything we are not supposed to. */
5335
0
    return true;
5336
0
}
5337
5338
static bool
5339
pcapng_write_decryption_secrets_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5340
0
{
5341
0
    uint32_t block_content_length;
5342
0
    pcapng_decryption_secrets_block_t dsb;
5343
0
    wtapng_dsb_mandatory_t *mand_data = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5344
0
    uint32_t pad_len;
5345
5346
0
    pad_len = WS_PADDING_TO_4(mand_data->secrets_len);
5347
5348
    /* write block header */
5349
0
    block_content_length = (uint32_t)sizeof(dsb) + mand_data->secrets_len + pad_len;
5350
0
    if (!pcapng_write_block_header(wdh, BLOCK_TYPE_DSB, block_content_length,
5351
0
                                   err))
5352
0
        return false;
5353
5354
    /* write block fixed content */
5355
0
    dsb.secrets_type = mand_data->secrets_type;
5356
0
    dsb.secrets_len = mand_data->secrets_len;
5357
0
    if (!wtap_dump_file_write(wdh, &dsb, sizeof dsb, err))
5358
0
        return false;
5359
5360
0
    if (!wtap_dump_file_write(wdh, mand_data->secrets_data, mand_data->secrets_len, err))
5361
0
        return false;
5362
5363
    /* write padding (if any) */
5364
0
    if (!pcapng_write_padding(wdh, pad_len, err))
5365
0
        return false;
5366
5367
    /* write block footer */
5368
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
5369
0
}
5370
5371
static bool
5372
pcapng_write_meta_event_block(wtap_dumper *wdh, wtap_block_t mev_data, int *err)
5373
0
{
5374
0
    uint32_t block_content_length;
5375
0
    wtapng_meta_event_mandatory_t *mand_data = (wtapng_meta_event_mandatory_t *)wtap_block_get_mandatory_data(mev_data);
5376
0
    uint32_t pad_len;
5377
5378
0
    pad_len = WS_PADDING_TO_4(mand_data->mev_data_len);
5379
5380
    /* write block header */
5381
0
    block_content_length = mand_data->mev_data_len + pad_len;
5382
0
    if (!pcapng_write_block_header(wdh, mand_data->mev_block_type,
5383
0
                                   block_content_length, err))
5384
0
        return false;
5385
0
    ws_debug("Sysdig mev len %u", block_content_length);
5386
5387
    /* write block fixed content */
5388
0
    if (!wtap_dump_file_write(wdh, mand_data->mev_data, mand_data->mev_data_len, err))
5389
0
        return false;
5390
5391
    /* write padding (if any) */
5392
0
    if (!pcapng_write_padding(wdh, pad_len, err))
5393
0
        return false;
5394
5395
    /* write block footer */
5396
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
5397
0
}
5398
5399
/*
5400
 * libpcap's maximum pcapng block size is currently 16MB.
5401
 *
5402
 * The maximum pcapng block size in macOS's private pcapng reading code
5403
 * is 1MB.  (Yes, this means that a program using the standard pcap
5404
 * code to read pcapng files can handle bigger blocks than can programs
5405
 * using the private code, such as Apple's tcpdump, can handle.)
5406
 *
5407
 * The pcapng reading code here can handle NRBs of arbitrary size (less
5408
 * than 4GB, obviously), as they read each NRB record independently,
5409
 * rather than reading the entire block into memory.
5410
 *
5411
 * So, for now, we set the maximum NRB block size we write as 1 MB.
5412
 *
5413
 * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
5414
 */
5415
5416
0
#define NRES_BLOCK_MAX_SIZE (1024*1024)
5417
5418
static uint32_t
5419
compute_nrb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
5420
0
{
5421
0
    uint32_t size;
5422
5423
0
    switch(option_id)
5424
0
    {
5425
0
    case OPT_NS_DNSNAME:
5426
0
        size = pcapng_compute_string_option_size(optval);
5427
0
        break;
5428
0
    case OPT_NS_DNSIP4ADDR:
5429
0
        size = 4;
5430
0
        break;
5431
0
    case OPT_NS_DNSIP6ADDR:
5432
0
        size = 16;
5433
0
        break;
5434
0
    default:
5435
        /* Unknown options - size by datatype? */
5436
0
        size = 0;
5437
0
        break;
5438
0
    }
5439
0
    return size;
5440
0
}
5441
5442
static bool
5443
put_nrb_option(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
5444
0
{
5445
0
    uint8_t **opt_ptrp = (uint8_t **)user_data;
5446
0
    size_t stringlen;
5447
0
    size_t size = 0;
5448
0
    struct pcapng_option_header option_hdr;
5449
0
    uint32_t pad;
5450
5451
0
    switch(option_id)
5452
0
    {
5453
0
    case OPT_COMMENT:
5454
0
    case OPT_NS_DNSNAME:
5455
0
        size = strlen(optval->stringval);
5456
0
        if (size > 65535) {
5457
            /*
5458
             * Too big to fit in the option.
5459
             * Don't write anything.
5460
             *
5461
             * XXX - truncate it?  Report an error?
5462
             */
5463
0
            return true;
5464
0
        }
5465
5466
        /* Put option header */
5467
        /* String options don't consider pad bytes part of the length */
5468
0
        option_hdr.type         = (uint16_t)option_id;
5469
0
        option_hdr.value_length = (uint16_t)size;
5470
0
        memcpy(*opt_ptrp, &option_hdr, 4);
5471
0
        *opt_ptrp += 4;
5472
5473
0
        memcpy(*opt_ptrp, optval->stringval, size);
5474
0
        *opt_ptrp += size;
5475
5476
        /* put padding (if any) */
5477
0
        pad = WS_PADDING_TO_4(size);
5478
0
        if (pad != 0) {
5479
0
            memset(*opt_ptrp, 0, pad);
5480
0
            *opt_ptrp += pad;
5481
0
        }
5482
0
        break;
5483
0
    case OPT_CUSTOM_STR_COPY:
5484
        /* String options don't consider pad bytes part of the length */
5485
0
        stringlen = strlen(optval->custom_stringval.string);
5486
0
        size = sizeof(uint32_t) + stringlen;
5487
0
        if (size > 65535) {
5488
            /*
5489
             * Too big to fit in the option.
5490
             * Don't write anything.
5491
             *
5492
             * XXX - truncate it?  Report an error?
5493
             */
5494
0
            return true;
5495
0
        }
5496
5497
        /* Put option header and PEN */
5498
        /* String options don't consider pad bytes part of the length */
5499
0
        option_hdr.type         = (uint16_t)option_id;
5500
0
        option_hdr.value_length = (uint16_t)size;
5501
0
        memcpy(*opt_ptrp, &option_hdr, 4);
5502
0
        *opt_ptrp += 4;
5503
5504
0
        memcpy(*opt_ptrp, &optval->custom_stringval.pen, sizeof(uint32_t));
5505
0
        *opt_ptrp += sizeof(uint32_t);
5506
0
        memcpy(*opt_ptrp, optval->custom_stringval.string, size);
5507
0
        *opt_ptrp += size;
5508
5509
        /* put padding (if any) */
5510
0
        pad = WS_PADDING_TO_4(size);
5511
0
        if (pad != 0) {
5512
0
            memset(*opt_ptrp, 0, pad);
5513
0
            *opt_ptrp += pad;
5514
0
        }
5515
0
        break;
5516
0
    case OPT_CUSTOM_BIN_COPY:
5517
        /* Custom options don't consider pad bytes part of the length */
5518
0
        size = (uint32_t)(optval->custom_binaryval.data.custom_data_len + sizeof(uint32_t)) & 0xffff;
5519
0
        option_hdr.type         = (uint16_t)option_id;
5520
0
        option_hdr.value_length = (uint16_t)size;
5521
0
        memcpy(*opt_ptrp, &option_hdr, 4);
5522
0
        *opt_ptrp += 4;
5523
5524
0
        memcpy(*opt_ptrp, &optval->custom_binaryval.pen, sizeof(uint32_t));
5525
0
        *opt_ptrp += sizeof(uint32_t);
5526
5527
0
        memcpy(*opt_ptrp, optval->custom_binaryval.data.custom_data, optval->custom_binaryval.data.custom_data_len);
5528
0
        *opt_ptrp += optval->custom_binaryval.data.custom_data_len;
5529
5530
        /* put padding (if any) */
5531
0
        pad = WS_PADDING_TO_4(size);
5532
0
        if (pad != 0) {
5533
0
            memset(*opt_ptrp, 0, pad);
5534
0
            *opt_ptrp += pad;
5535
0
        }
5536
0
        break;
5537
0
    case OPT_NS_DNSIP4ADDR:
5538
0
        option_hdr.type         = (uint16_t)option_id;
5539
0
        option_hdr.value_length = 4;
5540
0
        memcpy(*opt_ptrp, &option_hdr, 4);
5541
0
        *opt_ptrp += 4;
5542
5543
0
        memcpy(*opt_ptrp, &optval->ipv4val, 4);
5544
0
        *opt_ptrp += 4;
5545
0
        break;
5546
0
    case OPT_NS_DNSIP6ADDR:
5547
0
        option_hdr.type         = (uint16_t)option_id;
5548
0
        option_hdr.value_length = 16;
5549
0
        memcpy(*opt_ptrp, &option_hdr, 4);
5550
0
        *opt_ptrp += 4;
5551
5552
0
        memcpy(*opt_ptrp, &optval->ipv6val, 16);
5553
0
        *opt_ptrp += 16;
5554
0
        break;
5555
0
    default:
5556
        /* Unknown options - size by datatype? */
5557
0
        break;
5558
0
    }
5559
0
    return true; /* we always succeed */
5560
0
}
5561
5562
static void
5563
put_nrb_options(wtap_dumper *wdh _U_, wtap_block_t nrb, uint8_t *opt_ptr)
5564
0
{
5565
0
    struct pcapng_option option_hdr;
5566
5567
0
    wtap_block_foreach_option(nrb, put_nrb_option, &opt_ptr);
5568
5569
    /* Put end of options */
5570
0
    option_hdr.type = OPT_EOFOPT;
5571
0
    option_hdr.value_length = 0;
5572
0
    memcpy(opt_ptr, &option_hdr, 4);
5573
0
}
5574
5575
static bool
5576
pcapng_write_name_resolution_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5577
0
{
5578
0
    pcapng_block_header_t bh;
5579
0
    pcapng_name_resolution_block_t nrb;
5580
0
    wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5581
0
    uint32_t options_size;
5582
0
    size_t max_rec_data_size;
5583
0
    uint8_t *block_data;
5584
0
    uint32_t block_off;
5585
0
    size_t hostnamelen;
5586
0
    uint16_t namelen;
5587
0
    uint32_t tot_rec_len;
5588
0
    hashipv4_t *ipv4_hash_list_entry;
5589
0
    hashipv6_t *ipv6_hash_list_entry;
5590
0
    int i;
5591
5592
0
    if (!mand_data) {
5593
        /*
5594
         * No name/address pairs to write.
5595
         * XXX - what if we have options?
5596
         */
5597
0
        return true;
5598
0
    }
5599
5600
    /* Calculate the space needed for options. */
5601
0
    options_size = pcapng_compute_options_size(sdata, compute_nrb_option_size);
5602
5603
    /*
5604
     * Make sure we can fit at least one maximum-sized record, plus
5605
     * an end-of-records record, plus the options, into a maximum-sized
5606
     * block.
5607
     *
5608
     * That requires that there be enough space for the block header
5609
     * (8 bytes), a maximum-sized record (2 bytes of record type, 2
5610
     * bytes of record value length, 65535 bytes of record value,
5611
     * and 1 byte of padding), an end-of-records record (4 bytes),
5612
     * the options (options_size bytes), and the block trailer (4
5613
     * bytes).
5614
     */
5615
0
    if (8 + 2 + 2 + 65535 + 1 + 4 + options_size + 4 > NRES_BLOCK_MAX_SIZE) {
5616
        /*
5617
         * XXX - we can't even fit the options in the largest NRB size
5618
         * we're willing to write and still have room enough for a
5619
         * maximum-sized record.  Just discard the information for now.
5620
         */
5621
0
        return true;
5622
0
    }
5623
5624
    /*
5625
     * Allocate a buffer for the largest block we'll write.
5626
     */
5627
0
    block_data = (uint8_t *)g_malloc(NRES_BLOCK_MAX_SIZE);
5628
5629
    /*
5630
     * Calculate the maximum amount of record data we'll be able to
5631
     * fit into such a block, after taking into account the block header
5632
     * (8 bytes), the end-of-records record (4 bytes), the options
5633
     * (options_size bytes), and the block trailer (4 bytes).
5634
     */
5635
0
    max_rec_data_size = NRES_BLOCK_MAX_SIZE - (8 + 4 + options_size + 4);
5636
5637
0
    block_off = 8; /* block type + block total length */
5638
0
    bh.block_type = BLOCK_TYPE_NRB;
5639
0
    bh.block_total_length = 12; /* block header + block trailer */
5640
5641
    /*
5642
     * Write out the IPv4 resolved addresses, if any.
5643
     */
5644
0
    if (mand_data->ipv4_addr_list){
5645
0
        i = 0;
5646
0
        ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5647
0
        while(ipv4_hash_list_entry != NULL){
5648
5649
0
            nrb.record_type = NRES_IP4RECORD;
5650
0
            hostnamelen = strlen(ipv4_hash_list_entry->name);
5651
0
            if (hostnamelen > (UINT16_MAX - 4) - 1) {
5652
                /*
5653
                 * This won't fit in the largest possible NRB record;
5654
                 * discard it.
5655
                 */
5656
0
                i++;
5657
0
                ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5658
0
                continue;
5659
0
            }
5660
0
            namelen = (uint16_t)(hostnamelen + 1);
5661
0
            nrb.record_len = 4 + namelen;  /* 4 bytes IPv4 address length */
5662
            /* 2 bytes record type, 2 bytes length field */
5663
0
            tot_rec_len = 4 + nrb.record_len + WS_PADDING_TO_4(nrb.record_len);
5664
5665
0
            if (block_off + tot_rec_len > max_rec_data_size) {
5666
                /*
5667
                 * This record would overflow our maximum size for Name
5668
                 * Resolution Blocks; write out all the records we created
5669
                 * before it, and start a new NRB.
5670
                 */
5671
5672
                /* Append the end-of-records record */
5673
0
                memset(block_data + block_off, 0, 4);
5674
0
                block_off += 4;
5675
0
                bh.block_total_length += 4;
5676
5677
                /*
5678
                 * Put the options into the block.
5679
                 */
5680
0
                put_nrb_options(wdh, sdata, block_data + block_off);
5681
0
                block_off += options_size;
5682
0
                bh.block_total_length += options_size;
5683
5684
                /* Copy the block header. */
5685
0
                memcpy(block_data, &bh, sizeof(bh));
5686
5687
                /* Copy the block trailer. */
5688
0
                memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5689
5690
0
                ws_debug("Write bh.block_total_length bytes %d, block_off %u",
5691
0
                         bh.block_total_length, block_off);
5692
5693
0
                if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5694
0
                    g_free(block_data);
5695
0
                    return false;
5696
0
                }
5697
5698
                /*Start a new NRB */
5699
0
                block_off = 8; /* block type + block total length */
5700
0
                bh.block_type = BLOCK_TYPE_NRB;
5701
0
                bh.block_total_length = 12; /* block header + block trailer */
5702
0
            }
5703
5704
0
            bh.block_total_length += tot_rec_len;
5705
0
            memcpy(block_data + block_off, &nrb, sizeof(nrb));
5706
0
            block_off += 4;
5707
0
            memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
5708
0
            block_off += 4;
5709
0
            memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
5710
0
            block_off += namelen;
5711
0
            memset(block_data + block_off, 0, WS_PADDING_TO_4(namelen));
5712
0
            block_off += WS_PADDING_TO_4(namelen);
5713
0
            ws_debug("added IPv4 record for %s", ipv4_hash_list_entry->name);
5714
5715
0
            i++;
5716
0
            ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(mand_data->ipv4_addr_list, i);
5717
0
        }
5718
0
    }
5719
5720
0
    if (mand_data->ipv6_addr_list){
5721
0
        i = 0;
5722
0
        ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5723
0
        while(ipv6_hash_list_entry != NULL){
5724
5725
0
            nrb.record_type = NRES_IP6RECORD;
5726
0
            hostnamelen = strlen(ipv6_hash_list_entry->name);
5727
0
            if (hostnamelen > (UINT16_MAX - 16) - 1) {
5728
                /*
5729
                 * This won't fit in the largest possible NRB record;
5730
                 * discard it.
5731
                 */
5732
0
                i++;
5733
0
                ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5734
0
                continue;
5735
0
            }
5736
0
            namelen = (uint16_t)(hostnamelen + 1);
5737
0
            nrb.record_len = 16 + namelen;  /* 16 bytes IPv6 address length */
5738
            /* 2 bytes record type, 2 bytes length field */
5739
0
            tot_rec_len = 4 + nrb.record_len + WS_PADDING_TO_4(nrb.record_len);
5740
5741
0
            if (block_off + tot_rec_len > max_rec_data_size) {
5742
                /*
5743
                 * This record would overflow our maximum size for Name
5744
                 * Resolution Blocks; write out all the records we created
5745
                 * before it, and start a new NRB.
5746
                 */
5747
5748
                /* Append the end-of-records record */
5749
0
                memset(block_data + block_off, 0, 4);
5750
0
                block_off += 4;
5751
0
                bh.block_total_length += 4;
5752
5753
                /*
5754
                 * Put the options into the block.
5755
                 */
5756
0
                put_nrb_options(wdh, sdata, block_data + block_off);
5757
0
                block_off += options_size;
5758
0
                bh.block_total_length += options_size;
5759
5760
                /* Copy the block header. */
5761
0
                memcpy(block_data, &bh, sizeof(bh));
5762
5763
                /* Copy the block trailer. */
5764
0
                memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5765
5766
0
                ws_debug("write bh.block_total_length bytes %d, block_off %u",
5767
0
                         bh.block_total_length, block_off);
5768
5769
0
                if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5770
0
                    g_free(block_data);
5771
0
                    return false;
5772
0
                }
5773
5774
                /*Start a new NRB */
5775
0
                block_off = 8; /* block type + block total length */
5776
0
                bh.block_type = BLOCK_TYPE_NRB;
5777
0
                bh.block_total_length = 12; /* block header + block trailer */
5778
0
            }
5779
5780
0
            bh.block_total_length += tot_rec_len;
5781
0
            memcpy(block_data + block_off, &nrb, sizeof(nrb));
5782
0
            block_off += 4;
5783
0
            memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
5784
0
            block_off += 16;
5785
0
            memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
5786
0
            block_off += namelen;
5787
0
            memset(block_data + block_off, 0, WS_PADDING_TO_4(namelen));
5788
0
            block_off += WS_PADDING_TO_4(namelen);
5789
0
            ws_debug("added IPv6 record for %s", ipv6_hash_list_entry->name);
5790
5791
0
            i++;
5792
0
            ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(mand_data->ipv6_addr_list, i);
5793
0
        }
5794
0
    }
5795
5796
    /* Append the end-of-records record */
5797
0
    memset(block_data + block_off, 0, 4);
5798
0
    block_off += 4;
5799
0
    bh.block_total_length += 4;
5800
5801
    /*
5802
     * Put the options into the block.
5803
     */
5804
0
    put_nrb_options(wdh, sdata, block_data + block_off);
5805
0
    block_off += options_size;
5806
0
    bh.block_total_length += options_size;
5807
5808
    /* Copy the block header. */
5809
0
    memcpy(block_data, &bh, sizeof(bh));
5810
5811
    /* Copy the block trailer. */
5812
0
    memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5813
5814
0
    ws_debug("Write bh.block_total_length bytes %d, block_off %u",
5815
0
             bh.block_total_length, block_off);
5816
5817
0
    if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5818
0
        g_free(block_data);
5819
0
        return false;
5820
0
    }
5821
5822
0
    g_free(block_data);
5823
5824
0
    return true;
5825
0
}
5826
5827
static uint32_t compute_isb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval _U_)
5828
0
{
5829
0
    uint32_t size;
5830
5831
0
    switch(option_id)
5832
0
    {
5833
0
    case OPT_ISB_STARTTIME:
5834
0
    case OPT_ISB_ENDTIME:
5835
0
        size = 8;
5836
0
        break;
5837
0
    case OPT_ISB_IFRECV:
5838
0
    case OPT_ISB_IFDROP:
5839
0
    case OPT_ISB_FILTERACCEPT:
5840
0
    case OPT_ISB_OSDROP:
5841
0
    case OPT_ISB_USRDELIV:
5842
0
        size = 8;
5843
0
        break;
5844
0
    default:
5845
        /* Unknown options - size by datatype? */
5846
0
        size = 0;
5847
0
        break;
5848
0
    }
5849
0
    return size;
5850
0
}
5851
5852
static bool write_wtap_isb_option(wtap_dumper *wdh, wtap_block_t block _U_,
5853
                                  unsigned option_id,
5854
                                  wtap_opttype_e option_type _U_,
5855
                                  wtap_optval_t *optval,
5856
                                  int *err, char **err_info _U_)
5857
0
{
5858
0
    switch(option_id)
5859
0
    {
5860
0
    case OPT_ISB_STARTTIME:
5861
0
    case OPT_ISB_ENDTIME:
5862
0
        if (!pcapng_write_timestamp_option(wdh, option_id, optval, err))
5863
0
            return false;
5864
0
        break;
5865
0
    case OPT_ISB_IFRECV:
5866
0
    case OPT_ISB_IFDROP:
5867
0
    case OPT_ISB_FILTERACCEPT:
5868
0
    case OPT_ISB_OSDROP:
5869
0
    case OPT_ISB_USRDELIV:
5870
0
        if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5871
0
            return false;
5872
0
        break;
5873
0
    default:
5874
        /* Unknown options - write by datatype? */
5875
0
        break;
5876
0
    }
5877
0
    return true; /* success */
5878
0
}
5879
5880
static bool
5881
pcapng_write_interface_statistics_block(wtap_dumper *wdh,
5882
                                        wtap_block_t if_stats,
5883
                                        int *err, char **err_info)
5884
0
{
5885
0
    uint32_t block_content_length;
5886
0
    pcapng_interface_statistics_block_t isb;
5887
0
    uint32_t options_size;
5888
0
    wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
5889
5890
0
    ws_debug("entering function");
5891
5892
    /* Compute size of all the options */
5893
0
    options_size = pcapng_compute_options_size(if_stats, compute_isb_option_size);
5894
5895
    /* write block header */
5896
0
    block_content_length = (uint32_t)sizeof(isb) + options_size;
5897
0
    if (!pcapng_write_block_header(wdh, BLOCK_TYPE_ISB, block_content_length,
5898
0
                                   err))
5899
0
        return false;
5900
5901
    /* write block fixed content */
5902
0
    isb.interface_id                = mand_data->interface_id;
5903
0
    isb.timestamp_high              = mand_data->ts_high;
5904
0
    isb.timestamp_low               = mand_data->ts_low;
5905
5906
0
    if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
5907
0
        return false;
5908
5909
    /* Write options */
5910
0
    if (options_size != 0) {
5911
0
        if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
5912
0
                                  if_stats, write_wtap_isb_option,
5913
0
                                  err, err_info))
5914
0
            return false;
5915
0
    }
5916
5917
    /* write block footer */
5918
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
5919
0
}
5920
5921
static uint32_t compute_idb_option_size(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval)
5922
0
{
5923
0
    uint32_t size;
5924
5925
0
    switch(option_id)
5926
0
    {
5927
0
    case OPT_IDB_NAME:
5928
0
    case OPT_IDB_DESCRIPTION:
5929
0
    case OPT_IDB_OS:
5930
0
    case OPT_IDB_HARDWARE:
5931
0
        size = pcapng_compute_string_option_size(optval);
5932
0
        break;
5933
0
    case OPT_IDB_SPEED:
5934
0
        size = 8;
5935
0
        break;
5936
0
    case OPT_IDB_TSRESOL:
5937
0
        size = 1;
5938
0
        break;
5939
0
    case OPT_IDB_FILTER:
5940
0
        size = pcapng_compute_if_filter_option_size(optval);
5941
0
        break;
5942
0
    case OPT_IDB_FCSLEN:
5943
0
        size = 1;
5944
0
        break;
5945
0
    case OPT_IDB_TSOFFSET:
5946
0
        size = 8;
5947
0
        break;
5948
0
    default:
5949
        /* Unknown options - size by datatype? */
5950
0
        size = 0;
5951
0
        break;
5952
0
    }
5953
0
    return size;
5954
0
}
5955
5956
static bool write_wtap_idb_option(wtap_dumper *wdh, wtap_block_t block _U_,
5957
                                  unsigned option_id,
5958
                                  wtap_opttype_e option_type _U_,
5959
                                  wtap_optval_t *optval,
5960
                                  int *err, char **err_info)
5961
0
{
5962
0
    switch(option_id)
5963
0
    {
5964
0
    case OPT_IDB_NAME:
5965
0
    case OPT_IDB_DESCRIPTION:
5966
0
    case OPT_IDB_OS:
5967
0
    case OPT_IDB_HARDWARE:
5968
0
        if (!pcapng_write_string_option(wdh, OPT_SECTION_BYTE_ORDER,
5969
0
                                        option_id, optval, err, err_info))
5970
0
            return false;
5971
0
        break;
5972
0
    case OPT_IDB_SPEED:
5973
0
        if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5974
0
            return false;
5975
0
        break;
5976
0
    case OPT_IDB_TSRESOL:
5977
0
        if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5978
0
            return false;
5979
0
        break;
5980
0
    case OPT_IDB_FILTER:
5981
0
        if (!pcapng_write_if_filter_option(wdh, option_id, optval, err))
5982
0
            return false;
5983
0
        break;
5984
0
    case OPT_IDB_FCSLEN:
5985
0
        if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5986
0
            return false;
5987
0
        break;
5988
0
    case OPT_IDB_TSOFFSET:
5989
0
        if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5990
0
            return false;
5991
0
        break;
5992
0
        break;
5993
0
    default:
5994
        /* Unknown options - size by datatype? */
5995
0
        break;
5996
0
    }
5997
0
    return true;
5998
0
}
5999
6000
static bool
6001
pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data,
6002
                            int *err, char **err_info)
6003
0
{
6004
0
    uint32_t block_content_length;
6005
0
    pcapng_interface_description_block_t idb;
6006
0
    uint32_t options_size;
6007
0
    wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
6008
0
    int link_type;
6009
6010
0
    ws_debug("encap = %d (%s), snaplen = %d",
6011
0
             mand_data->wtap_encap,
6012
0
             wtap_encap_description(mand_data->wtap_encap),
6013
0
             mand_data->snap_len);
6014
6015
0
    link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
6016
0
    if (link_type == -1) {
6017
0
        if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) {
6018
0
            *err = WTAP_ERR_UNWRITABLE_ENCAP;
6019
0
            return false;
6020
0
        }
6021
0
    }
6022
6023
    /* Compute size of all the options */
6024
0
    options_size = pcapng_compute_options_size(int_data, compute_idb_option_size);
6025
6026
    /* write block header */
6027
0
    block_content_length = (uint32_t)sizeof(idb) + options_size;
6028
0
    if (!pcapng_write_block_header(wdh, BLOCK_TYPE_IDB, block_content_length,
6029
0
                                   err))
6030
0
        return false;
6031
6032
    /* write block fixed content */
6033
0
    idb.linktype    = link_type;
6034
0
    idb.reserved    = 0;
6035
0
    idb.snaplen     = mand_data->snap_len;
6036
6037
0
    if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
6038
0
        return false;
6039
6040
0
    if (options_size != 0) {
6041
        /* Write options */
6042
0
        if (!pcapng_write_options(wdh, OPT_SECTION_BYTE_ORDER,
6043
0
                                  int_data, write_wtap_idb_option,
6044
0
                                  err, err_info))
6045
0
            return false;
6046
0
    }
6047
6048
    /* write block footer */
6049
0
    return pcapng_write_block_footer(wdh, block_content_length, err);
6050
0
}
6051
6052
static bool pcapng_add_idb(wtap_dumper *wdh, wtap_block_t idb,
6053
                               int *err, char **err_info)
6054
0
{
6055
    /*
6056
     * Write it to the output file.
6057
     */
6058
0
    return pcapng_write_if_descr_block(wdh, idb, err, err_info);
6059
0
}
6060
6061
static bool pcapng_write_internal_blocks(wtap_dumper *wdh, int *err)
6062
0
{
6063
6064
    /* Write (optional) Decryption Secrets Blocks that were collected while
6065
     * reading packet blocks. */
6066
0
    if (wdh->dsbs_growing) {
6067
0
        for (unsigned i = wdh->dsbs_growing_written; i < wdh->dsbs_growing->len; i++) {
6068
0
            ws_debug("writing DSB %u", i);
6069
0
            wtap_block_t dsb = g_array_index(wdh->dsbs_growing, wtap_block_t, i);
6070
0
            if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6071
0
                return false;
6072
0
            }
6073
0
            ++wdh->dsbs_growing_written;
6074
0
        }
6075
0
    }
6076
6077
    /* Write (optional) Sysdig Meta Event Blocks that were collected while
6078
     * reading packet blocks. */
6079
0
    if (wdh->mevs_growing) {
6080
0
        for (unsigned i = wdh->mevs_growing_written; i < wdh->mevs_growing->len; i++) {
6081
0
            ws_debug("writing Sysdig mev %u", i);
6082
0
            wtap_block_t mev = g_array_index(wdh->mevs_growing, wtap_block_t, i);
6083
0
            if (!pcapng_write_meta_event_block(wdh, mev, err)) {
6084
0
                return false;
6085
0
            }
6086
0
            ++wdh->mevs_growing_written;
6087
0
        }
6088
0
    }
6089
6090
    /* Write any hostname resolution info from wtap_dump_set_addrinfo_list() */
6091
0
    if (!wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
6092
        /*
6093
         * XXX: get_addrinfo_list() returns a list of all known and used
6094
         * resolved addresses, regardless of origin: existing NRBs, externally
6095
         * resolved, DNS packet data, a hosts file, and manual host resolution
6096
         * through the GUI. It does not include the source for each.
6097
         *
6098
         * If it did, we could instead create multiple NRBs, one for each
6099
         * server (as the options can only be included once per block.)
6100
         * Instead, we copy the options from the first already existing NRB
6101
         * (if there is one), since some of the name resolutions may be
6102
         * from that block.
6103
         */
6104
0
        wtap_block_t nrb;
6105
0
        if (wdh->nrbs_growing && wdh->nrbs_growing->len) {
6106
0
            nrb = wtap_block_make_copy(g_array_index(wdh->nrbs_growing, wtap_block_t, 0));
6107
0
        } else {
6108
0
            nrb = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
6109
0
        }
6110
0
        wtapng_nrb_mandatory_t *mand_data = (wtapng_nrb_mandatory_t *)wtap_block_get_mandatory_data(nrb);
6111
0
        mand_data->ipv4_addr_list = wdh->addrinfo_lists->ipv4_addr_list;
6112
0
        mand_data->ipv6_addr_list = wdh->addrinfo_lists->ipv6_addr_list;
6113
6114
0
        if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6115
0
            return false;
6116
0
        }
6117
0
        mand_data->ipv4_addr_list = NULL;
6118
0
        mand_data->ipv6_addr_list = NULL;
6119
0
        wtap_block_unref(nrb);
6120
0
        g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
6121
0
        wdh->addrinfo_lists->ipv4_addr_list = NULL;
6122
0
        g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
6123
0
        wdh->addrinfo_lists->ipv6_addr_list = NULL;
6124
        /* Since the addrinfo lists include information from existing NRBs,
6125
         * avoid writing them to avoid duplication.
6126
         *
6127
         * XXX: Perhaps we don't want to include information from the NRBs
6128
         * in get_addrinfo_list at all, so that we could write existing
6129
         * NRBs as-is.
6130
         *
6131
         * This is still not well oriented for one-pass programs, where we
6132
         * don't have addrinfo_lists until we've already written the
6133
         * NRBs. We should not write both in such a situation. See bug 15502.
6134
         */
6135
0
        wtap_dump_discard_name_resolution(wdh);
6136
0
    }
6137
6138
    /* Write (optional) Name Resolution Blocks that were collected while
6139
     * reading packet blocks. */
6140
0
    if (wdh->nrbs_growing) {
6141
0
        for (unsigned i = wdh->nrbs_growing_written; i < wdh->nrbs_growing->len; i++) {
6142
0
            wtap_block_t nrb = g_array_index(wdh->nrbs_growing, wtap_block_t, i);
6143
0
            if (!pcapng_write_name_resolution_block(wdh, nrb, err)) {
6144
0
                return false;
6145
0
            }
6146
0
            ++wdh->nrbs_growing_written;
6147
0
        }
6148
0
    }
6149
6150
    /* Write (optional) Darwin Process Event Blocks that were collected while
6151
     * reading packet blocks. */
6152
0
     if (wdh->dpibs_growing) {
6153
0
        ws_noisy("writing internal blocks: dpibs_growing: written: %u len: %u",
6154
0
            wdh->dpibs_growing_written, wdh->dpibs_growing->len);
6155
0
        for (unsigned i = wdh->dpibs_growing_written; i < wdh->dpibs_growing->len; i++) {
6156
6157
0
            wtap_block_t dpib = g_array_index(wdh->dpibs_growing, wtap_block_t, i);
6158
0
            if (!pcapng_write_legacy_darwin_process_event_block(wdh, dpib, err)) {
6159
0
                return false;
6160
0
            }
6161
0
            ++wdh->dpibs_growing_written;
6162
0
        }
6163
0
    }
6164
6165
0
    return true;
6166
0
}
6167
6168
static bool pcapng_dump(wtap_dumper *wdh, const wtap_rec *rec,
6169
                        int *err, char **err_info)
6170
0
{
6171
0
    uint32_t block_type;
6172
0
    pcapng_block_type_information_t* handler;
6173
6174
0
    if (!pcapng_write_internal_blocks(wdh, err)) {
6175
0
        return false;
6176
0
    }
6177
6178
0
    ws_debug("encap = %d (%s) rec type = %u",
6179
0
             rec->rec_header.packet_header.pkt_encap,
6180
0
             wtap_encap_description(rec->rec_header.packet_header.pkt_encap),
6181
0
             rec->rec_type);
6182
6183
0
    switch (rec->rec_type) {
6184
6185
0
        case REC_TYPE_PACKET:
6186
            /* Write Simple Packet Block if appropriate, Enhanced Packet Block otherwise. */
6187
0
            if (!(rec->presence_flags & WTAP_HAS_TS) &&
6188
0
                (!(rec->presence_flags & WTAP_HAS_INTERFACE_ID) || rec->rec_header.packet_header.interface_id == 0) &&
6189
0
                (!(rec->presence_flags & WTAP_HAS_CAP_LEN) || rec->rec_header.packet_header.len == rec->rec_header.packet_header.caplen) &&
6190
0
                (rec->block == NULL || pcapng_compute_options_size(rec->block, compute_epb_option_size) == 0)) {
6191
0
                block_type = BLOCK_TYPE_SPB;
6192
0
            }
6193
0
            else {
6194
0
                block_type = BLOCK_TYPE_EPB;
6195
0
            }
6196
0
            break;
6197
6198
0
        case REC_TYPE_FT_SPECIFIC_EVENT:
6199
0
        case REC_TYPE_FT_SPECIFIC_REPORT:
6200
            /*
6201
             * Is this an event or report for our file type?
6202
             */
6203
0
            if (rec->rec_header.ft_specific_header.file_type_subtype != pcapng_file_type_subtype) {
6204
                /*
6205
                 * No. We can't write that.
6206
                 */
6207
0
                *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
6208
0
                *err_info = g_strdup_printf("%s records for \"%s\" files aren't supported for this file type",
6209
0
                    rec->rec_type_name,
6210
0
                    wtap_file_type_subtype_name(rec->rec_header.ft_specific_header.file_type_subtype));
6211
0
                return false;
6212
0
            }
6213
6214
0
            block_type = rec->rec_header.ft_specific_header.record_type;
6215
0
            break;
6216
6217
0
        case REC_TYPE_SYSCALL:
6218
0
            block_type = rec->rec_header.syscall_header.record_type;
6219
0
            break;
6220
6221
0
        case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
6222
0
            block_type = BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT;
6223
0
            break;
6224
6225
0
        case REC_TYPE_CUSTOM_BLOCK:
6226
0
        {
6227
            /* Don't write anything we are not supposed to. */
6228
0
            if (!rec->rec_header.custom_block_header.copy_allowed) {
6229
0
                return true;
6230
0
            }
6231
0
            block_type = BLOCK_TYPE_CB_COPY;
6232
0
            break;
6233
0
        }
6234
6235
0
        default:
6236
            /* We don't support writing this record type. */
6237
0
            *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
6238
0
            *err_info = wtap_unwritable_rec_type_err_string(rec);
6239
0
            return false;
6240
0
    }
6241
6242
    /*
6243
     * Do we have a handler for this block type?
6244
     */
6245
0
    handler = (pcapng_block_type_information_t*)g_hash_table_lookup(block_handlers,
6246
0
                                                                        GUINT_TO_POINTER(block_type));
6247
0
    if (handler == NULL) {
6248
        /* No. We can't write that. */
6249
0
        *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
6250
0
        *err_info = g_strdup_printf("Pcapng blocks of type 0x%8x aren't supported",
6251
0
                                    rec->rec_header.ft_specific_header.record_type);
6252
0
        return false;
6253
0
    }
6254
6255
    /* Yes. Call it to write out this record. */
6256
0
    return handler->writer(wdh, rec, err, err_info);
6257
0
}
6258
6259
/*
6260
 * Write block header.
6261
 */
6262
bool
6263
pcapng_write_block_header(wtap_dumper *wdh, uint32_t block_type,
6264
                          uint32_t block_content_length, int *err)
6265
0
{
6266
0
    pcapng_block_header_t bh;
6267
6268
0
    bh.block_type = block_type;
6269
    /*
6270
     * Total block length is the length of the header plus the length
6271
     * of the block content (which is padded to a multiple of 4 bytes)
6272
     * plus the length of the trailer.
6273
     */
6274
0
    bh.block_total_length = (uint32_t)sizeof(pcapng_block_header_t) + block_content_length + 4;
6275
0
    ws_debug("Total len %u", bh.block_total_length);
6276
0
    return wtap_dump_file_write(wdh, &bh, sizeof bh, err);
6277
0
}
6278
6279
/*
6280
 * Write block footer.
6281
 */
6282
bool
6283
pcapng_write_block_footer(wtap_dumper *wdh, uint32_t block_content_length,
6284
                          int *err)
6285
0
{
6286
0
    uint32_t bf;
6287
6288
0
    bf = (uint32_t)sizeof(pcapng_block_header_t) + block_content_length + 4;
6289
0
    return wtap_dump_file_write(wdh, &bf, sizeof bf, err);
6290
0
}
6291
6292
/* Finish writing to a dump file.
6293
   Returns true on success, false on failure. */
6294
static bool pcapng_dump_finish(wtap_dumper *wdh, int *err, char **err_info)
6295
0
{
6296
0
    unsigned i, j;
6297
6298
    /* Flush any hostname resolution or decryption secrets info we may have */
6299
0
    if (!pcapng_write_internal_blocks(wdh, err)) {
6300
0
        return false;
6301
0
    }
6302
6303
0
    for (i = 0; i < wdh->interface_data->len; i++) {
6304
6305
        /* Get the interface description */
6306
0
        wtap_block_t int_data;
6307
0
        wtapng_if_descr_mandatory_t *int_data_mand;
6308
6309
0
        int_data = g_array_index(wdh->interface_data, wtap_block_t, i);
6310
0
        int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
6311
6312
0
        for (j = 0; j < int_data_mand->num_stat_entries; j++) {
6313
0
            wtap_block_t if_stats;
6314
6315
0
            if_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j);
6316
0
            ws_debug("write ISB for interface %u",
6317
0
                     ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id);
6318
0
            if (!pcapng_write_interface_statistics_block(wdh, if_stats,
6319
0
                                                         err, err_info)) {
6320
0
                return false;
6321
0
            }
6322
0
        }
6323
0
    }
6324
6325
0
    ws_debug("leaving function");
6326
0
    return true;
6327
0
}
6328
6329
/* Returns true on success, false on failure; sets "*err" to an error code on
6330
   failure */
6331
static bool
6332
pcapng_dump_open(wtap_dumper *wdh, int *err, char **err_info)
6333
0
{
6334
0
    unsigned i;
6335
6336
0
    ws_debug("entering function");
6337
    /* This is a pcapng file */
6338
0
    wdh->subtype_add_idb = pcapng_add_idb;
6339
0
    wdh->subtype_write = pcapng_dump;
6340
0
    wdh->subtype_finish = pcapng_dump_finish;
6341
6342
    /* write the section header block */
6343
0
    if (!pcapng_write_section_header_block(wdh, err, err_info)) {
6344
0
        return false;
6345
0
    }
6346
0
    ws_debug("wrote section header block.");
6347
6348
    /* Write the Interface description blocks */
6349
0
    ws_debug("Number of IDBs to write (number of interfaces) %u",
6350
0
             wdh->interface_data->len);
6351
6352
0
    for (i = 0; i < wdh->interface_data->len; i++) {
6353
6354
        /* Get the interface description */
6355
0
        wtap_block_t idb;
6356
6357
0
        idb = g_array_index(wdh->interface_data, wtap_block_t, i);
6358
6359
0
        if (!pcapng_write_if_descr_block(wdh, idb, err, err_info)) {
6360
0
            return false;
6361
0
        }
6362
6363
0
    }
6364
6365
    /* Write (optional) fixed Decryption Secrets Blocks. */
6366
0
    if (wdh->dsbs_initial) {
6367
0
        for (i = 0; i < wdh->dsbs_initial->len; i++) {
6368
0
            wtap_block_t dsb = g_array_index(wdh->dsbs_initial, wtap_block_t, i);
6369
0
            if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6370
0
                return false;
6371
0
            }
6372
0
        }
6373
0
    }
6374
6375
0
    return true;
6376
0
}
6377
6378
/* Returns 0 if we could write the specified encapsulation type,
6379
   an error indication otherwise. */
6380
static int pcapng_dump_can_write_encap(int wtap_encap)
6381
0
{
6382
0
    ws_debug("encap = %d (%s)",
6383
0
             wtap_encap,
6384
0
             wtap_encap_description(wtap_encap));
6385
6386
    /* Per-packet encapsulation is supported. */
6387
0
    if (wtap_encap == WTAP_ENCAP_PER_PACKET)
6388
0
        return 0;
6389
6390
    /* No encapsulation type (yet) is supported. */
6391
0
    if (wtap_encap == WTAP_ENCAP_NONE)
6392
0
        return 0;
6393
6394
    /* Is it a filetype-specific encapsulation that we support? */
6395
0
    if (pcapng_encap_is_ft_specific(wtap_encap)) {
6396
0
        return 0;
6397
0
    }
6398
6399
    /* Make sure we can figure out this DLT type */
6400
0
    if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
6401
0
        return WTAP_ERR_UNWRITABLE_ENCAP;
6402
6403
0
    return 0;
6404
0
}
6405
6406
/*
6407
 * Returns true if the specified encapsulation type is filetype-specific
6408
 * and one that we support.
6409
 */
6410
bool pcapng_encap_is_ft_specific(int encap)
6411
0
{
6412
0
    switch (encap) {
6413
0
    case WTAP_ENCAP_SYSTEMD_JOURNAL:
6414
0
        return true;
6415
0
    }
6416
0
    return false;
6417
0
}
6418
6419
/*
6420
 * pcapng supports several block types, and supports more than one
6421
 * of them.
6422
 *
6423
 * It also supports comments for many block types, as well as other
6424
 * option types.
6425
 */
6426
6427
/* Options for section blocks. */
6428
static const struct supported_option_type section_block_options_supported[] = {
6429
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6430
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6431
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6432
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6433
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6434
    { OPT_SHB_HARDWARE, ONE_OPTION_SUPPORTED },
6435
    { OPT_SHB_USERAPPL, ONE_OPTION_SUPPORTED }
6436
};
6437
6438
/* Options for interface blocks. */
6439
static const struct supported_option_type interface_block_options_supported[] = {
6440
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6441
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6442
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6443
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6444
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6445
    { OPT_IDB_NAME, ONE_OPTION_SUPPORTED },
6446
    { OPT_IDB_DESCRIPTION, ONE_OPTION_SUPPORTED },
6447
    { OPT_IDB_IP4ADDR, MULTIPLE_OPTIONS_SUPPORTED },
6448
    { OPT_IDB_IP6ADDR, MULTIPLE_OPTIONS_SUPPORTED },
6449
    { OPT_IDB_MACADDR, ONE_OPTION_SUPPORTED },
6450
    { OPT_IDB_EUIADDR, ONE_OPTION_SUPPORTED },
6451
    { OPT_IDB_SPEED, ONE_OPTION_SUPPORTED },
6452
    { OPT_IDB_TSRESOL, ONE_OPTION_SUPPORTED },
6453
    { OPT_IDB_TZONE, ONE_OPTION_SUPPORTED },
6454
    { OPT_IDB_FILTER, ONE_OPTION_SUPPORTED },
6455
    { OPT_IDB_OS, ONE_OPTION_SUPPORTED },
6456
    { OPT_IDB_FCSLEN, ONE_OPTION_SUPPORTED },
6457
    { OPT_IDB_TSOFFSET, ONE_OPTION_SUPPORTED },
6458
    { OPT_IDB_HARDWARE, ONE_OPTION_SUPPORTED },
6459
    { OPT_IDB_TXSPEED, ONE_OPTION_SUPPORTED },
6460
    { OPT_IDB_RXSPEED, ONE_OPTION_SUPPORTED },
6461
    { OPT_IDB_IANA_TZNAME, ONE_OPTION_SUPPORTED }
6462
};
6463
6464
/* Options for name resolution blocks. */
6465
static const struct supported_option_type name_resolution_block_options_supported[] = {
6466
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6467
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6468
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6469
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6470
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6471
    { OPT_NS_DNSNAME, ONE_OPTION_SUPPORTED },
6472
    { OPT_NS_DNSIP4ADDR, ONE_OPTION_SUPPORTED },
6473
    { OPT_NS_DNSIP6ADDR, ONE_OPTION_SUPPORTED }
6474
};
6475
6476
/* Options for interface statistics blocks. */
6477
static const struct supported_option_type interface_statistics_block_options_supported[] = {
6478
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6479
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6480
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6481
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6482
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6483
    { OPT_ISB_STARTTIME, ONE_OPTION_SUPPORTED },
6484
    { OPT_ISB_ENDTIME, ONE_OPTION_SUPPORTED },
6485
    { OPT_ISB_IFRECV, ONE_OPTION_SUPPORTED },
6486
    { OPT_ISB_IFDROP, ONE_OPTION_SUPPORTED },
6487
    { OPT_ISB_FILTERACCEPT, ONE_OPTION_SUPPORTED },
6488
    { OPT_ISB_OSDROP, ONE_OPTION_SUPPORTED },
6489
    { OPT_ISB_USRDELIV, ONE_OPTION_SUPPORTED }
6490
};
6491
6492
/* Options for decryption secrets blocks. */
6493
static const struct supported_option_type decryption_secrets_block_options_supported[] = {
6494
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6495
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6496
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6497
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6498
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6499
};
6500
6501
/* Options for meta event blocks. */
6502
static const struct supported_option_type meta_events_block_options_supported[] = {
6503
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6504
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6505
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6506
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6507
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6508
};
6509
6510
/* Options for packet blocks. */
6511
static const struct supported_option_type packet_block_options_supported[] = {
6512
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6513
    { OPT_PKT_FLAGS, ONE_OPTION_SUPPORTED },
6514
    { OPT_PKT_HASH, MULTIPLE_OPTIONS_SUPPORTED },
6515
    { OPT_PKT_DROPCOUNT, ONE_OPTION_SUPPORTED },
6516
    { OPT_PKT_PACKETID, ONE_OPTION_SUPPORTED },
6517
    { OPT_PKT_QUEUE, ONE_OPTION_SUPPORTED },
6518
    { OPT_PKT_VERDICT, MULTIPLE_OPTIONS_SUPPORTED },
6519
    { OPT_PKT_PROCIDTHRDID, ONE_OPTION_SUPPORTED },
6520
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6521
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6522
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6523
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6524
};
6525
6526
/* Options for file-type-specific reports. */
6527
static const struct supported_option_type ft_specific_report_block_options_supported[] = {
6528
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6529
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6530
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6531
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6532
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6533
};
6534
6535
/* Options for file-type-specific event. */
6536
static const struct supported_option_type ft_specific_event_block_options_supported[] = {
6537
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6538
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6539
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6540
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6541
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6542
};
6543
6544
/* Options for systemd journal entry. */
6545
static const struct supported_option_type systemd_journal_export_block_options_supported[] = {
6546
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6547
    { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6548
    { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6549
    { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6550
    { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6551
};
6552
6553
/* Options for file-type-specific information. */
6554
static const struct supported_option_type ftr_specific_information_block_options_supported[] = {
6555
    { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6556
    { OPT_DPIB_NAME, ONE_OPTION_SUPPORTED },
6557
    { OPT_DPIB_UUID, ONE_OPTION_SUPPORTED },
6558
};
6559
6560
static const struct supported_block_type pcapng_blocks_supported[] = {
6561
    /* Multiple sections. */
6562
    { WTAP_BLOCK_SECTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(section_block_options_supported) },
6563
6564
    /* Multiple interfaces. */
6565
    { WTAP_BLOCK_IF_ID_AND_INFO, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_block_options_supported) },
6566
6567
    /* Multiple blocks of name resolution information */
6568
    { WTAP_BLOCK_NAME_RESOLUTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(name_resolution_block_options_supported) },
6569
6570
    /* Multiple blocks of interface statistics. */
6571
    { WTAP_BLOCK_IF_STATISTICS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_statistics_block_options_supported) },
6572
6573
    /* Multiple blocks of decryption secrets. */
6574
    { WTAP_BLOCK_DECRYPTION_SECRETS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(decryption_secrets_block_options_supported) },
6575
6576
    /* Multiple blocks of meta evens.. */
6577
    { WTAP_BLOCK_META_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(meta_events_block_options_supported) },
6578
6579
    /* And, obviously, multiple packets. */
6580
    { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(packet_block_options_supported) },
6581
6582
    /* Multiple file-type specific reports (including local ones). */
6583
    { WTAP_BLOCK_FT_SPECIFIC_REPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_report_block_options_supported) },
6584
6585
    /* Multiple file-type specific events (including local ones). */
6586
    { WTAP_BLOCK_FT_SPECIFIC_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_event_block_options_supported) },
6587
6588
    /* Multiple systemd journal export records. */
6589
    { WTAP_BLOCK_SYSTEMD_JOURNAL_EXPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(systemd_journal_export_block_options_supported) },
6590
6591
    /* Multiple custom blocks. */
6592
    { WTAP_BLOCK_CUSTOM, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED },
6593
6594
    /* Multiple file-type-specific information blocks. */
6595
    { WTAP_BLOCK_FT_SPECIFIC_INFORMATION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ftr_specific_information_block_options_supported) },
6596
};
6597
6598
static const struct file_type_subtype_info wireshark_pcapng_info = {
6599
    "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
6600
    false, BLOCKS_SUPPORTED(pcapng_blocks_supported),
6601
    pcapng_dump_can_write_encap, pcapng_dump_open, NULL
6602
};
6603
6604
static const struct file_type_subtype_info stratoshark_pcapng_info = {
6605
    "Stratoshark/... - scap", "scap", "scap", "scap",
6606
    false, BLOCKS_SUPPORTED(pcapng_blocks_supported),
6607
    pcapng_dump_can_write_encap, pcapng_dump_open, NULL
6608
};
6609
6610
void register_pcapng(const char* app_env_var_prefix)
6611
15
{
6612
15
    if (app_env_var_prefix != NULL) {
6613
        /* XXX - It would be great if this could be refactored out of the wiretap library,
6614
          but dependencies currently look daunting */
6615
6616
15
        if (strcmp(app_env_var_prefix, "WIRESHARK") == 0)
6617
15
            pcapng_file_type_subtype = wtap_register_file_type_subtype(&wireshark_pcapng_info);
6618
0
        else if (strcmp(app_env_var_prefix, "STRATOSHARK") == 0)
6619
0
            pcapng_file_type_subtype = wtap_register_file_type_subtype(&stratoshark_pcapng_info);
6620
0
        else
6621
0
        {
6622
            /* XXX - Allow support of applications that use wiretap, but not pcapNG */
6623
0
            return;
6624
0
        }
6625
15
    }
6626
6627
15
    wtap_register_backwards_compatibility_lua_name("PCAPNG",
6628
15
                                                   pcapng_file_type_subtype);
6629
6630
    /* Setup the tables that will be used to handle custom block options */
6631
6632
    /*
6633
     * Create the table of option handlers for this block type.
6634
     *
6635
     * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
6636
     * so we use "g_direct_hash()" and "g_direct_equal()".
6637
    */
6638
15
    block_handlers = g_hash_table_new_full(g_direct_hash,
6639
15
        g_direct_equal,
6640
15
        NULL, g_free);
6641
6642
15
    custom_enterprise_handlers = g_hash_table_new_full(g_direct_hash,
6643
15
        g_direct_equal,
6644
15
        NULL, g_free);
6645
6646
    /* SHBs require special handling, so they don't have handlers here. */
6647
15
    static pcapng_block_type_information_t SHB = { BLOCK_TYPE_SHB, NULL, NULL, NULL, true, NULL };
6648
15
    SHB.option_handlers = pcapng_create_option_handler_table();
6649
15
    register_pcapng_block_type_information(&SHB);
6650
6651
15
    static pcapng_block_type_information_t IDB = { BLOCK_TYPE_IDB, pcapng_read_if_descr_block, pcapng_process_idb, NULL, true, NULL };
6652
15
    IDB.option_handlers = pcapng_create_option_handler_table();
6653
15
    register_pcapng_block_type_information(&IDB);
6654
6655
15
    static pcapng_block_type_information_t EPB = { BLOCK_TYPE_EPB, pcapng_read_packet_block, NULL, pcapng_write_enhanced_packet_block, false, NULL };
6656
15
    EPB.option_handlers = pcapng_create_option_handler_table();
6657
15
    register_pcapng_block_type_information(&EPB);
6658
6659
15
    static pcapng_block_type_information_t PB = { BLOCK_TYPE_PB, pcapng_read_packet_block, NULL, NULL, false, NULL };
6660
    /* PBs and EPBs have the same options. */
6661
15
    PB.option_handlers = EPB.option_handlers;
6662
15
    register_pcapng_block_type_information(&PB);
6663
6664
15
    static pcapng_block_type_information_t SPB = { BLOCK_TYPE_SPB, pcapng_read_simple_packet_block, NULL, pcapng_write_simple_packet_block, false, NULL };
6665
    /* SPBs don't support options */
6666
15
    register_pcapng_block_type_information(&SPB);
6667
6668
15
    static pcapng_block_type_information_t NRB = { BLOCK_TYPE_NRB, pcapng_read_name_resolution_block, pcapng_process_nrb, NULL, true, NULL };
6669
15
    NRB.option_handlers = pcapng_create_option_handler_table();
6670
15
    register_pcapng_block_type_information(&NRB);
6671
6672
15
    static pcapng_block_type_information_t ISB = { BLOCK_TYPE_ISB, pcapng_read_interface_statistics_block, pcapng_process_isb, NULL, true, NULL };
6673
15
    ISB.option_handlers = pcapng_create_option_handler_table();
6674
15
    register_pcapng_block_type_information(&ISB);
6675
6676
15
    static pcapng_block_type_information_t DSB = { BLOCK_TYPE_DSB, pcapng_read_decryption_secrets_block, pcapng_process_dsb, NULL, true, NULL };
6677
15
    DSB.option_handlers = pcapng_create_option_handler_table();
6678
15
    register_pcapng_block_type_information(&DSB);
6679
6680
15
    static pcapng_block_type_information_t CB_COPY = { BLOCK_TYPE_CB_COPY, pcapng_read_custom_block, NULL, pcapng_write_custom_block_copy, false, NULL };
6681
15
    CB_COPY.option_handlers = pcapng_create_option_handler_table();
6682
15
    register_pcapng_block_type_information(&CB_COPY);
6683
6684
15
    static pcapng_block_type_information_t CB_NO_COPY = { BLOCK_TYPE_CB_NO_COPY, pcapng_read_custom_block, NULL, pcapng_write_custom_block_no_copy, false, NULL };
6685
    /* Copy and no-copy and CBs have the same options. */
6686
15
    CB_NO_COPY.option_handlers = CB_COPY.option_handlers;
6687
15
    register_pcapng_block_type_information(&CB_NO_COPY);
6688
6689
15
    static pcapng_block_type_information_t SYSTEMD_JOURNAL_EXPORT = { BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT, pcapng_read_systemd_journal_export_block, NULL, pcapng_write_systemd_journal_export_block, false, NULL };
6690
15
    SYSTEMD_JOURNAL_EXPORT.option_handlers = pcapng_create_option_handler_table();
6691
15
    register_pcapng_block_type_information(&SYSTEMD_JOURNAL_EXPORT);
6692
15
}
6693
6694
/*
6695
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
6696
 *
6697
 * Local variables:
6698
 * c-basic-offset: 4
6699
 * tab-width: 8
6700
 * indent-tabs-mode: nil
6701
 * End:
6702
 *
6703
 * vi: set shiftwidth=4 tabstop=8 expandtab:
6704
 * :indentSize=4:tabSize=8:noTabs=true:
6705
 */