Coverage Report

Created: 2026-11-12 07:01

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