test: convert suite_nameres to use fixtures
[metze/wireshark/wip.git] / wiretap / pcapng.c
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://wiki.wireshark.org/Development/PcapNg
16  */
17
18 #include "config.h"
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23
24 #include <wsutil/ws_printf.h>
25
26 #include "wtap-int.h"
27 #include "file_wrappers.h"
28 #include "pcap-common.h"
29 #include "pcap-encap.h"
30 #include "pcapng.h"
31 #include "pcapng_module.h"
32
33 #if 0
34 #define pcapng_debug(...) g_warning(__VA_ARGS__)
35 #else
36 #define pcapng_debug(...)
37 #endif
38
39 static gboolean
40 pcapng_read(wtap *wth, int *err, gchar **err_info,
41             gint64 *data_offset);
42 static gboolean
43 pcapng_seek_read(wtap *wth, gint64 seek_off,
44                  wtap_rec *rec, Buffer *buf, int *err, gchar **err_info);
45 static void
46 pcapng_close(wtap *wth);
47
48 static gboolean
49 pcapng_encap_is_ft_specific(int encap);
50
51 /*
52  * Minimum block size = size of block header + size of block trailer.
53  */
54 #define MIN_BLOCK_SIZE  ((guint32)(sizeof(pcapng_block_header_t) + sizeof(guint32)))
55
56 /*
57  * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
58  */
59 #define MIN_SHB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
60
61 /* pcapng: packet block file encoding (obsolete) */
62 typedef struct pcapng_packet_block_s {
63     guint16 interface_id;
64     guint16 drops_count;
65     guint32 timestamp_high;
66     guint32 timestamp_low;
67     guint32 captured_len;
68     guint32 packet_len;
69     /* ... Packet Data ... */
70     /* ... Padding ... */
71     /* ... Options ... */
72 } pcapng_packet_block_t;
73
74 /*
75  * Minimum PB size = minimum block size + size of fixed length portion of PB.
76  */
77 #define MIN_PB_SIZE     ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
78
79 /* pcapng: enhanced packet block file encoding */
80 typedef struct pcapng_enhanced_packet_block_s {
81     guint32 interface_id;
82     guint32 timestamp_high;
83     guint32 timestamp_low;
84     guint32 captured_len;
85     guint32 packet_len;
86     /* ... Packet Data ... */
87     /* ... Padding ... */
88     /* ... Options ... */
89 } pcapng_enhanced_packet_block_t;
90
91 /*
92  * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
93  */
94 #define MIN_EPB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
95
96 /* pcapng: simple packet block file encoding */
97 typedef struct pcapng_simple_packet_block_s {
98     guint32 packet_len;
99     /* ... Packet Data ... */
100     /* ... Padding ... */
101 } pcapng_simple_packet_block_t;
102
103 /*
104  * Minimum SPB size = minimum block size + size of fixed length portion of SPB.
105  */
106 #define MIN_SPB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
107
108 /* pcapng: name resolution block file encoding */
109 typedef struct pcapng_name_resolution_block_s {
110     guint16 record_type;
111     guint16 record_len;
112     /* ... Record ... */
113 } pcapng_name_resolution_block_t;
114
115 /*
116  * Minimum NRB size = minimum block size + size of smallest NRB record
117  * (there must at least be an "end of records" record).
118  */
119 #define MIN_NRB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
120
121 /*
122  * Minimum ISB size = minimum block size + size of fixed length portion of ISB.
123  */
124 #define MIN_ISB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
125
126 /*
127  * Minimum Sysdig size = minimum block size + packed size of sysdig_event_phdr.
128  */
129 #define SYSDIG_EVENT_HEADER_SIZE ((16 + 64 + 64 + 32 + 16)/8) /* CPU ID + TS + TID + Event len + Event type */
130 #define MIN_SYSDIG_EVENT_SIZE    ((guint32)(MIN_BLOCK_SIZE + SYSDIG_EVENT_HEADER_SIZE))
131
132 /*
133  * We require __CURSOR + __REALTIME_TIMESTAMP + __MONOTONIC_TIMESTAMP in
134  * systemd journal export entries, which is 200 bytes or so (203 on a test
135  * system here).
136  */
137 #define SDJ__REALTIME_TIMESTAMP "__REALTIME_TIMESTAMP="
138 #define MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE    200
139 #define MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE    ((guint32)(MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE + MIN_BLOCK_SIZE))
140
141 /* pcapng: common option header file encoding for every option type */
142 typedef struct pcapng_option_header_s {
143     guint16 option_code;
144     guint16 option_length;
145     /* ... x bytes Option Body ... */
146     /* ... Padding ... */
147 } pcapng_option_header_t;
148
149 struct option {
150     guint16 type;
151     guint16 value_length;
152 };
153
154 /* Option codes: 16-bit field */
155 #define OPT_EPB_FLAGS        0x0002
156 #define OPT_EPB_HASH         0x0003
157 #define OPT_EPB_DROPCOUNT    0x0004
158
159 #define OPT_NRB_DNSNAME      0x0002
160 #define OPT_NRB_DNSV4ADDR    0x0003
161 #define OPT_NRB_DNSV6ADDR    0x0004
162
163 /* MSBit of option code means "local type" */
164 #define OPT_LOCAL_FLAG       0x8000
165
166 /*
167  * In order to keep from trying to allocate large chunks of memory,
168  * which could either fail or, even if it succeeds, chew up so much
169  * address space or memory+backing store as not to leave room for
170  * anything else, we impose upper limits on the size of blocks we're
171  * willing to handle.
172  *
173  * We pick a limit of an EPB with a maximum-sized D-Bus packet and 128 KiB
174  * worth of options; we use the maximum D-Bus packet size as that's larger
175  * than the maximum packet size for other link-layer types, and the maximum
176  * packet size for other link-layer types is currently small enough that
177  * the resulting block size would be less than the previous 16 MiB limit.
178  */
179 #define MAX_BLOCK_SIZE (MIN_EPB_SIZE + WTAP_MAX_PACKET_SIZE_DBUS + 131072)
180
181 /* Note: many of the defined structures for block data are defined in wtap.h */
182
183 /* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
184 typedef struct wtapng_packet_s {
185     /* mandatory */
186     guint32                         ts_high;        /* seconds since 1.1.1970 */
187     guint32                         ts_low;         /* fraction of seconds, depends on if_tsresol */
188     guint32                         cap_len;        /* data length in the file */
189     guint32                         packet_len;     /* data length on the wire */
190     guint32                         interface_id;   /* identifier of the interface. */
191     guint16                         drops_count;    /* drops count, only valid for packet block */
192     /* 0xffff if information no available */
193     /* pack_hash */
194     /* XXX - put the packet data / pseudo_header here as well? */
195 } wtapng_packet_t;
196
197 /* Simple Packet data */
198 typedef struct wtapng_simple_packet_s {
199     /* mandatory */
200     guint32                         cap_len;        /* data length in the file */
201     guint32                         packet_len;     /* data length on the wire */
202     /* XXX - put the packet data / pseudo_header here as well? */
203 } wtapng_simple_packet_t;
204
205 /* Interface data in private struct */
206 typedef struct interface_info_s {
207     int wtap_encap;
208     guint32 snap_len;
209     guint64 time_units_per_second;
210     int tsprecision;
211 } interface_info_t;
212
213 typedef struct {
214     gboolean shb_read;           /**< Set when first SHB read */
215     gboolean byte_swapped;
216     guint16 version_major;
217     guint16 version_minor;
218     GArray *interfaces;          /**< Interfaces found in the capture file. */
219     gint8 if_fcslen;
220     wtap_new_ipv4_callback_t add_new_ipv4;
221     wtap_new_ipv6_callback_t add_new_ipv6;
222 } pcapng_t;
223
224 #ifdef HAVE_PLUGINS
225 /*
226  * Table for plugins to handle particular block types.
227  *
228  * A handler has a "read" routine and a "write" routine.
229  *
230  * A "read" routine returns a block as a libwiretap record, filling
231  * in the wtap_pkthdr structure with the appropriate record type and
232  * other information, and filling in the supplied Buffer with
233  * data for which there's no place in the wtap_pkthdr structure.
234  *
235  * A "write" routine takes a libwiretap record and Buffer and writes
236  * out a block.
237  */
238 typedef struct {
239     block_reader reader;
240     block_writer writer;
241 } block_handler;
242
243 static GHashTable *block_handlers;
244
245 void
246 register_pcapng_block_type_handler(guint block_type, block_reader reader,
247                                    block_writer writer)
248 {
249     block_handler *handler;
250
251     /*
252      * Is this a known block type?
253      */
254     switch (block_type) {
255
256     case BLOCK_TYPE_SHB:
257     case BLOCK_TYPE_IDB:
258     case BLOCK_TYPE_PB:
259     case BLOCK_TYPE_SPB:
260     case BLOCK_TYPE_NRB:
261     case BLOCK_TYPE_ISB:
262     case BLOCK_TYPE_EPB:
263     case BLOCK_TYPE_SYSDIG_EVENT:
264     case BLOCK_TYPE_SYSTEMD_JOURNAL:
265         /*
266          * Yes; we already handle it, and don't allow a replacement to
267          * be registeted (if there's a bug in our code, or there's
268          * something we don't handle in that block, submit a change
269          * to the main Wireshark source).
270          */
271         g_warning("Attempt to register plugin for block type 0x%08x not allowed",
272                      block_type);
273         return;
274
275     case BLOCK_TYPE_IRIG_TS:
276     case BLOCK_TYPE_ARINC_429:
277     case BLOCK_TYPE_SYSDIG_EVF:
278         /*
279          * Yes, and we don't already handle it.  Allow a plugin to
280          * handle it.
281          *
282          * (But why not submit the plugin source to Wireshark?)
283          */
284         break;
285
286     default:
287         /*
288          * No; is it a local block type?
289          */
290          if (!(block_type & 0x80000000)) {
291              /*
292               * No; don't allow a plugin to be registered for it, as
293               * the block type needs to be registered before it's used.
294               */
295             g_warning("Attempt to register plugin for reserved block type 0x%08x not allowed",
296                          block_type);
297             return;
298          }
299
300          /*
301           * Yes; allow the registration.
302           */
303          break;
304     }
305
306     if (block_handlers == NULL) {
307         /*
308          * Create the table of block handlers.
309          *
310          * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
311          * so we use "g_direct_hash()" and "g_direct_equal()".
312          */
313         block_handlers = g_hash_table_new_full(g_direct_hash,
314                                                g_direct_equal,
315                                                NULL, g_free);
316     }
317     handler = g_new(block_handler, 1);
318     handler->reader = reader;
319     handler->writer = writer;
320     g_hash_table_insert(block_handlers, GUINT_TO_POINTER(block_type),
321                               handler);
322 }
323
324 /*
325  * Tables for plugins to handle particular options for particular block
326  * types.
327  *
328  * An option has a handler routine, which is passed an indication of
329  * whether this section of the file is byte-swapped, the length of the
330  * option, the data of the option, a pointer to an error code, and a
331  * pointer to a pointer variable for an error string.
332  *
333  * It checks whether the length and option are valid, and, if they aren't,
334  * returns FALSE, setting the error code to the appropriate error (normally
335  * WTAP_ERR_BAD_FILE) and the error string to an appropriate string
336  * indicating the problem.
337  *
338  * Otherwise, if this section of the file is byte-swapped, it byte-swaps
339  * multi-byte numerical values, so that it's in the host byte order.
340  */
341
342 /*
343  * Block types indices in the table of tables of option handlers.
344  *
345  * Block types are not guaranteed to be sequential, so we map the
346  * block types we support to a sequential set.  Furthermore, all
347  * packet block types have the same set of options.
348  */
349 #define BT_INDEX_SHB        0
350 #define BT_INDEX_IDB        1
351 #define BT_INDEX_PBS        2  /* all packet blocks */
352 #define BT_INDEX_NRB        3
353 #define BT_INDEX_ISB        4
354 #define BT_INDEX_EVT        5
355
356 #define NUM_BT_INDICES      6
357
358 typedef struct {
359     option_handler_fn hfunc;
360 } option_handler;
361
362 static GHashTable *option_handlers[NUM_BT_INDICES];
363
364 static gboolean
365 get_block_type_index(guint block_type, guint *bt_index)
366 {
367     g_assert(bt_index);
368
369     switch (block_type) {
370
371         case BLOCK_TYPE_SHB:
372             *bt_index = BT_INDEX_SHB;
373             break;
374
375         case BLOCK_TYPE_IDB:
376             *bt_index = BT_INDEX_IDB;
377             break;
378
379         case BLOCK_TYPE_PB:
380         case BLOCK_TYPE_EPB:
381         case BLOCK_TYPE_SPB:
382             *bt_index = BT_INDEX_PBS;
383             break;
384
385         case BLOCK_TYPE_NRB:
386             *bt_index = BT_INDEX_NRB;
387             break;
388
389         case BLOCK_TYPE_ISB:
390             *bt_index = BT_INDEX_ISB;
391             break;
392
393         case BLOCK_TYPE_SYSDIG_EVENT:
394         /* case BLOCK_TYPE_SYSDIG_EVF: */
395             *bt_index = BT_INDEX_EVT;
396             break;
397
398         default:
399             /*
400              * This is a block type we don't process; either we ignore it,
401              * in which case the options don't get processed, or there's
402              * a plugin routine to handle it, in which case that routine
403              * will do the option processing itself.
404              *
405              * XXX - report an error?
406              */
407             return FALSE;
408     }
409
410     return TRUE;
411 }
412
413 void
414 register_pcapng_option_handler(guint block_type, guint option_code,
415                                option_handler_fn hfunc)
416 {
417     guint bt_index;
418     option_handler *handler;
419
420     if (!get_block_type_index(block_type, &bt_index))
421         return;
422
423     if (option_handlers[bt_index] == NULL) {
424         /*
425          * Create the table of option handlers for this block type.
426          *
427          * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
428          * so we use "g_direct_hash()" and "g_direct_equal()".
429          */
430         option_handlers[bt_index] = g_hash_table_new_full(g_direct_hash,
431                                                           g_direct_equal,
432                                                           NULL, g_free);
433     }
434     handler = g_new(option_handler, 1);
435     handler->hfunc = hfunc;
436     g_hash_table_insert(option_handlers[bt_index],
437                               GUINT_TO_POINTER(option_code), handler);
438 }
439 #endif /* HAVE_PLUGINS */
440
441 static int
442 pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
443                    guint8 *content, guint len, guint to_read,
444                    int *err, gchar **err_info, gchar* block_name)
445 {
446     int     block_read;
447
448     /* sanity check: don't run past the end of the block */
449     if (to_read < sizeof (*oh)) {
450         *err = WTAP_ERR_BAD_FILE;
451         *err_info = g_strdup_printf("pcapng_read_option: Not enough data to read header of the %s block",
452                                     block_name);
453         return -1;
454     }
455
456     /* read option header */
457     if (!wtap_read_bytes(fh, oh, sizeof (*oh), err, err_info)) {
458         pcapng_debug("pcapng_read_option: failed to read option");
459         return -1;
460     }
461     block_read = sizeof (*oh);
462     if (pn->byte_swapped) {
463         oh->option_code      = GUINT16_SWAP_LE_BE(oh->option_code);
464         oh->option_length    = GUINT16_SWAP_LE_BE(oh->option_length);
465     }
466
467     /* sanity check: don't run past the end of the block */
468     if (to_read < sizeof (*oh) + oh->option_length) {
469         *err = WTAP_ERR_BAD_FILE;
470         *err_info = g_strdup_printf("pcapng_read_option: Not enough data to handle option length (%d) of the %s block",
471                                     oh->option_length, block_name);
472         return -1;
473     }
474
475     /* sanity check: option length */
476     if (len < oh->option_length) {
477         *err = WTAP_ERR_BAD_FILE;
478         *err_info = g_strdup_printf("pcapng_read_option: option length (%d) to long for %s block",
479                                     len, block_name);
480         return -1;
481     }
482
483     /* read option content */
484     if (!wtap_read_bytes(fh, content, oh->option_length, err, err_info)) {
485         pcapng_debug("pcapng_read_option: failed to read content of option %u", oh->option_code);
486         return -1;
487     }
488     block_read += oh->option_length;
489
490     /* jump over potential padding bytes at end of option */
491     if ( (oh->option_length % 4) != 0) {
492         if (!wtap_read_bytes(fh, NULL, 4 - (oh->option_length % 4), err, err_info))
493             return -1;
494         block_read += 4 - (oh->option_length % 4);
495     }
496
497     return block_read;
498 }
499
500 typedef enum {
501     PCAPNG_BLOCK_OK,
502     PCAPNG_BLOCK_NOT_SHB,
503     PCAPNG_BLOCK_ERROR
504 } block_return_val;
505
506 static block_return_val
507 pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
508                                  pcapng_t *pn, wtapng_block_t *wblock,
509                                  int *err, gchar **err_info)
510 {
511     int     bytes_read;
512     gboolean byte_swapped;
513     guint16 version_major;
514     guint16 version_minor;
515     guint to_read, opt_cont_buf_len;
516     pcapng_section_header_block_t shb;
517     pcapng_option_header_t oh;
518     wtapng_mandatory_section_t* section_data;
519     gchar* tmp_content;
520
521     guint8 *option_content = NULL; /* Allocate as large as the options block */
522
523     /* read fixed-length part of the block */
524     if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
525         if (*err == WTAP_ERR_SHORT_READ) {
526             /*
527              * This block is too short to be an SHB.
528              *
529              * If we're reading this as part of an open,
530              * the file is too short to be a pcapng file.
531              *
532              * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
533              * PCAPNG_BLOCK_ERROR the same, so we can just return
534              * PCAPNG_BLOCK_NOT_SHB in both cases.
535              */
536             return PCAPNG_BLOCK_NOT_SHB;
537         }
538         return PCAPNG_BLOCK_ERROR;
539     }
540
541     /* is the magic number one we expect? */
542     switch (shb.magic) {
543         case(0x1A2B3C4D):
544             /* this seems pcapng with correct byte order */
545             byte_swapped                = FALSE;
546             version_major               = shb.version_major;
547             version_minor               = shb.version_minor;
548
549             pcapng_debug("pcapng_read_section_header_block: SHB (our byte order) V%u.%u, len %u",
550                           version_major, version_minor, bh->block_total_length);
551             break;
552         case(0x4D3C2B1A):
553             /* this seems pcapng with swapped byte order */
554             byte_swapped                = TRUE;
555             version_major               = GUINT16_SWAP_LE_BE(shb.version_major);
556             version_minor               = GUINT16_SWAP_LE_BE(shb.version_minor);
557
558             /* tweak the block length to meet current swapping that we know now */
559             bh->block_total_length  = GUINT32_SWAP_LE_BE(bh->block_total_length);
560
561             pcapng_debug("pcapng_read_section_header_block: SHB (byte-swapped) V%u.%u, len %u",
562                           version_major, version_minor, bh->block_total_length);
563             break;
564         default:
565             /* Not a "pcapng" magic number we know about. */
566             *err = WTAP_ERR_BAD_FILE;
567             *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown byte-order magic number 0x%08x", shb.magic);
568
569             /*
570              * See above comment about PCAPNG_BLOCK_NOT_SHB.
571              */
572             return PCAPNG_BLOCK_NOT_SHB;
573     }
574
575     /*
576      * Is this block long enough to be an SHB?
577      */
578     if (bh->block_total_length < MIN_SHB_SIZE) {
579         /*
580          * No.
581          */
582         *err = WTAP_ERR_BAD_FILE;
583         *err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u of an SHB is less than the minimum SHB size %u",
584                                     bh->block_total_length, MIN_SHB_SIZE);
585         return PCAPNG_BLOCK_ERROR;
586     }
587
588     /* OK, at this point we assume it's a pcapng file.
589
590        Don't try to allocate memory for a huge number of options, as
591        that might fail and, even if it succeeds, it might not leave
592        any address space or memory+backing store for anything else.
593
594        We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
595        We check for this *after* checking the SHB for its byte
596        order magic number, so that non-pcapng files are less
597        likely to be treated as bad pcapng files. */
598     if (bh->block_total_length > MAX_BLOCK_SIZE) {
599         *err = WTAP_ERR_BAD_FILE;
600         *err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u is too large (> %u)",
601                                     bh->block_total_length, MAX_BLOCK_SIZE);
602         return PCAPNG_BLOCK_ERROR;
603     }
604
605     /* we currently only understand SHB V1.0 */
606     if (version_major != 1 || version_minor > 0) {
607         *err = WTAP_ERR_UNSUPPORTED;
608         *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
609                                     pn->version_major, pn->version_minor);
610         return PCAPNG_BLOCK_ERROR;
611     }
612
613     pn->byte_swapped  = byte_swapped;
614     pn->version_major = version_major;
615     pn->version_minor = version_minor;
616
617     wblock->block = wtap_block_create(WTAP_BLOCK_NG_SECTION);
618     section_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(wblock->block);
619     /* 64bit section_length (currently unused) */
620     if (pn->byte_swapped) {
621         section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
622     } else {
623         section_data->section_length = shb.section_length;
624     }
625
626     /* Options */
627     to_read = bh->block_total_length - MIN_SHB_SIZE;
628
629     /* Allocate enough memory to hold all options */
630     opt_cont_buf_len = to_read;
631     option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
632     if (opt_cont_buf_len != 0 && option_content == NULL) {
633         *err = ENOMEM;  /* we assume we're out of memory */
634         return PCAPNG_BLOCK_ERROR;
635     }
636     pcapng_debug("pcapng_read_section_header_block: Options %u bytes", to_read);
637     while (to_read != 0) {
638         /* read option */
639         pcapng_debug("pcapng_read_section_header_block: Options %u bytes remaining", to_read);
640         bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "section_header");
641         if (bytes_read <= 0) {
642             pcapng_debug("pcapng_read_section_header_block: failed to read option");
643             g_free(option_content);
644             return PCAPNG_BLOCK_ERROR;
645         }
646         to_read -= bytes_read;
647
648         /* handle option content */
649         switch (oh.option_code) {
650             case(OPT_EOFOPT):
651                 if (to_read != 0) {
652                     pcapng_debug("pcapng_read_section_header_block: %u bytes after opt_endofopt", to_read);
653                 }
654                 /* padding should be ok here, just get out of this */
655                 to_read = 0;
656                 break;
657             case(OPT_COMMENT):
658                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
659                     tmp_content = g_strndup((char *)option_content, oh.option_length);
660                     wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
661                     pcapng_debug("pcapng_read_section_header_block: opt_comment %s", tmp_content);
662                     g_free(tmp_content);
663                 } else {
664                     pcapng_debug("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
665                 }
666                 break;
667             case(OPT_SHB_HARDWARE):
668                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
669                     tmp_content = g_strndup((char *)option_content, oh.option_length);
670                     /* Fails with multiple options; we silently ignore the failure */
671                     wtap_block_add_string_option(wblock->block, OPT_SHB_HARDWARE, option_content, oh.option_length);
672                     pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", tmp_content);
673                     g_free(tmp_content);
674                 } else {
675                     pcapng_debug("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
676                 }
677                 break;
678             case(OPT_SHB_OS):
679                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
680                     tmp_content = g_strndup((char *)option_content, oh.option_length);
681                     /* Fails with multiple options; we silently ignore the failure */
682                     wtap_block_add_string_option(wblock->block, OPT_SHB_OS, option_content, oh.option_length);
683                     pcapng_debug("pcapng_read_section_header_block: shb_os %s", tmp_content);
684                     g_free(tmp_content);
685                 } else {
686                     pcapng_debug("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
687                 }
688                 break;
689             case(OPT_SHB_USERAPPL):
690                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
691                     tmp_content = g_strndup((char *)option_content, oh.option_length);
692                     /* Fails with multiple options; we silently ignore the failure */
693                     wtap_block_add_string_option(wblock->block, OPT_SHB_USERAPPL, option_content, oh.option_length);
694                     pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", tmp_content);
695                     g_free(tmp_content);
696                 } else {
697                     pcapng_debug("pcapng_read_section_header_block: shb_user_appl length %u seems strange", oh.option_length);
698                 }
699                 break;
700             default:
701                 pcapng_debug("pcapng_read_section_header_block: unknown option %u - ignoring %u bytes",
702                               oh.option_code, oh.option_length);
703         }
704     }
705     g_free(option_content);
706
707     /*
708      * We don't return these to the caller in pcapng_read().
709      */
710     wblock->internal = TRUE;
711
712     return PCAPNG_BLOCK_OK;
713 }
714
715
716 /* "Interface Description Block" */
717 static gboolean
718 pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
719                            pcapng_t *pn, wtapng_block_t *wblock, int *err,
720                            gchar **err_info)
721 {
722     guint64 time_units_per_second = 1000000; /* default = 10^6 */
723     int     tsprecision = WTAP_TSPREC_USEC;
724     int     bytes_read;
725     guint to_read, opt_cont_buf_len;
726     pcapng_interface_description_block_t idb;
727     wtapng_if_descr_mandatory_t* if_descr_mand;
728     guint   link_type;
729     pcapng_option_header_t oh;
730     guint8 *option_content = NULL; /* Allocate as large as the options block */
731     gchar* tmp_content;
732     guint64 tmp64;
733
734     /*
735      * Is this block long enough to be an IDB?
736      */
737     if (bh->block_total_length < MIN_IDB_SIZE) {
738         /*
739          * No.
740          */
741         *err = WTAP_ERR_BAD_FILE;
742         *err_info = g_strdup_printf("pcapng_read_if_descr_block: total block length %u of an IDB is less than the minimum IDB size %u",
743                                     bh->block_total_length, MIN_IDB_SIZE);
744         return FALSE;
745     }
746
747     /* read block content */
748     if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
749         pcapng_debug("pcapng_read_if_descr_block: failed to read IDB");
750         return FALSE;
751     }
752
753     /* mandatory values */
754     wblock->block = wtap_block_create(WTAP_BLOCK_IF_DESCR);
755     if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
756     if (pn->byte_swapped) {
757         link_type = GUINT16_SWAP_LE_BE(idb.linktype);
758         if_descr_mand->snap_len  = GUINT32_SWAP_LE_BE(idb.snaplen);
759     } else {
760         link_type = idb.linktype;
761         if_descr_mand->snap_len  = idb.snaplen;
762     }
763
764     if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(link_type);
765     if_descr_mand->time_units_per_second = time_units_per_second;
766     if_descr_mand->tsprecision = tsprecision;
767
768     pcapng_debug("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
769                   link_type,
770                   wtap_encap_string(if_descr_mand->wtap_encap),
771                   if_descr_mand->snap_len);
772
773     if (if_descr_mand->snap_len > wtap_max_snaplen_for_encap(if_descr_mand->wtap_encap)) {
774         /*
775          * We do not use this value, maybe we should check the
776          * snap_len of the packets against it. For now, only warn.
777          */
778         pcapng_debug("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
779                       if_descr_mand->snap_len);
780         /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;*/
781     }
782
783     /* Options */
784     to_read = bh->block_total_length - MIN_IDB_SIZE;
785
786     /* Allocate enough memory to hold all options */
787     opt_cont_buf_len = to_read;
788     option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
789     if (opt_cont_buf_len != 0 && option_content == NULL) {
790         *err = ENOMEM;  /* we assume we're out of memory */
791         return FALSE;
792     }
793
794     while (to_read != 0) {
795         /* read option */
796         bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "if_descr");
797         if (bytes_read <= 0) {
798             pcapng_debug("pcapng_read_if_descr_block: failed to read option");
799             g_free(option_content);
800             return FALSE;
801         }
802         to_read -= bytes_read;
803
804         /* handle option content */
805         switch (oh.option_code) {
806             case(OPT_EOFOPT): /* opt_endofopt */
807                 if (to_read != 0) {
808                     pcapng_debug("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read);
809                 }
810                 /* padding should be ok here, just get out of this */
811                 to_read = 0;
812                 break;
813             case(OPT_COMMENT): /* opt_comment */
814                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
815                     tmp_content = g_strndup((char *)option_content, oh.option_length);
816                     wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
817                     pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", tmp_content);
818                     g_free(tmp_content);
819                 } else {
820                     pcapng_debug("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
821                 }
822                 break;
823             case(OPT_IDB_NAME): /* if_name */
824                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
825                     tmp_content = g_strndup((char *)option_content, oh.option_length);
826                     /* Fails with multiple options; we silently ignore the failure */
827                     wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
828                     pcapng_debug("pcapng_read_if_descr_block: if_name %s", tmp_content);
829                     g_free(tmp_content);
830                 } else {
831                     pcapng_debug("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
832                 }
833                 break;
834             case(OPT_IDB_DESCR): /* if_description */
835                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
836                     tmp_content = g_strndup((char *)option_content, oh.option_length);
837                     /* Fails with multiple options; we silently ignore the failure */
838                     wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
839                     pcapng_debug("pcapng_read_if_descr_block: if_description %s", tmp_content);
840                     g_free(tmp_content);
841                 } else {
842                     pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
843                 }
844                 break;
845             case(OPT_IDB_SPEED): /* if_speed */
846                 if (oh.option_length == 8) {
847                     /*  Don't cast a guint8 * into a guint64 *--the
848                      *  guint8 * may not point to something that's
849                      *  aligned correctly.
850                      */
851                     memcpy(&tmp64, option_content, sizeof(guint64));
852                     if (pn->byte_swapped)
853                         tmp64 = GUINT64_SWAP_LE_BE(tmp64);
854                     /* Fails with multiple options; we silently ignore the failure */
855                     wtap_block_add_uint64_option(wblock->block, oh.option_code, tmp64);
856                     pcapng_debug("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", tmp64);
857                 } else {
858                     pcapng_debug("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
859                 }
860                 break;
861             case(OPT_IDB_TSRESOL): /* if_tsresol */
862                 if (oh.option_length == 1) {
863                     guint64 base;
864                     guint64 result;
865                     guint8 i, exponent, if_tsresol;
866
867                     if_tsresol = option_content[0];
868                     if (if_tsresol & 0x80) {
869                         base = 2;
870                     } else {
871                         base = 10;
872                     }
873                     exponent = (guint8)(if_tsresol & 0x7f);
874                     if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
875                         result = 1;
876                         for (i = 0; i < exponent; i++) {
877                             result *= base;
878                         }
879                         time_units_per_second = result;
880                     } else {
881                         time_units_per_second = G_MAXUINT64;
882                     }
883                     if (time_units_per_second > (((guint64)1) << 32)) {
884                         pcapng_debug("pcapng_open: time conversion might be inaccurate");
885                     }
886                     if_descr_mand->time_units_per_second = time_units_per_second;
887                     /* Fails with multiple options; we silently ignore the failure */
888                     wtap_block_add_uint8_option(wblock->block, oh.option_code, if_tsresol);
889                     if (time_units_per_second >= 1000000000)
890                         tsprecision = WTAP_TSPREC_NSEC;
891                     else if (time_units_per_second >= 1000000)
892                         tsprecision = WTAP_TSPREC_USEC;
893                     else if (time_units_per_second >= 1000)
894                         tsprecision = WTAP_TSPREC_MSEC;
895                     else if (time_units_per_second >= 100)
896                         tsprecision = WTAP_TSPREC_CSEC;
897                     else if (time_units_per_second >= 10)
898                         tsprecision = WTAP_TSPREC_DSEC;
899                     else
900                         tsprecision = WTAP_TSPREC_SEC;
901                     if_descr_mand->tsprecision = tsprecision;
902                     pcapng_debug("pcapng_read_if_descr_block: if_tsresol %u, units/s %" G_GINT64_MODIFIER "u, tsprecision %d", if_tsresol, if_descr_mand->time_units_per_second, tsprecision);
903                 } else {
904                     pcapng_debug("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
905                 }
906                 break;
907                 /*
908                  * if_tzone      10  Time zone for GMT support (TODO: specify better). TODO: give a good example
909                  */
910             case(OPT_IDB_FILTER): /* if_filter */
911                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
912                     wtapng_if_descr_filter_t if_filter;
913                     memset(&if_filter, 0, sizeof(if_filter));
914
915                     /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
916                      * or BPF bytecode.
917                      */
918                     if (option_content[0] == 0) {
919                         if_filter.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
920                         pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", if_filter.if_filter_str, oh.option_length);
921                     } else if (option_content[0] == 1) {
922                         if_filter.bpf_filter_len = oh.option_length-1;
923                         if_filter.if_filter_bpf_bytes = (guint8 *)option_content+1;
924                     }
925                     /* Fails with multiple options; we silently ignore the failure */
926                     wtap_block_add_custom_option(wblock->block, oh.option_code, &if_filter, sizeof if_filter);
927                     g_free(if_filter.if_filter_str);
928                 } else {
929                     pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
930                 }
931                 break;
932             case(OPT_IDB_OS): /* if_os */
933                 /*
934                  * if_os         12  A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
935                  * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
936                  * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
937                  */
938                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
939                     tmp_content = g_strndup((char *)option_content, oh.option_length);
940                     /* Fails with multiple options; we silently ignore the failure */
941                     wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
942                     pcapng_debug("pcapng_read_if_descr_block: if_os %s", tmp_content);
943                     g_free(tmp_content);
944                 } else {
945                     pcapng_debug("pcapng_read_if_descr_block: if_os length %u seems strange", oh.option_length);
946                 }
947                 break;
948             case(OPT_IDB_FCSLEN): /* if_fcslen */
949                 if (oh.option_length == 1) {
950                     /* Fails with multiple options; we silently ignore the failure */
951                     wtap_block_add_uint8_option(wblock->block, oh.option_code, option_content[0]);
952                     pn->if_fcslen = option_content[0];
953                     pcapng_debug("pcapng_read_if_descr_block: if_fcslen %u", pn->if_fcslen);
954                     /* XXX - add sanity check */
955                 } else {
956                     pcapng_debug("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
957                 }
958                 break;
959             case(OPT_IDB_HARDWARE): /* if_hardware */
960                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
961                     tmp_content = g_strndup((char *)option_content, oh.option_length);
962                     /* Fails with multiple options; we silently ignore the failure */
963                     wtap_block_add_string_option(wblock->block, oh.option_code, option_content, oh.option_length);
964                     pcapng_debug("pcapng_read_if_descr_block: if_hardware %s", tmp_content);
965                     g_free(tmp_content);
966                 } else {
967                     pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
968                 }
969                 break;
970
971             /* TODO: process these! */
972             case(OPT_IDB_IP4ADDR):
973                 /*
974                  * Interface network address and netmask. This option can be
975                  * repeated multiple times within the same Interface
976                  * Description Block when multiple IPv4 addresses are assigned
977                  * to the interface. 192 168 1 1 255 255 255 0
978                  */
979             case(OPT_IDB_IP6ADDR):
980                 /*
981                  * Interface network address and prefix length (stored in the
982                  * last byte). This option can be repeated multiple times
983                  * within the same Interface Description Block when multiple
984                  * IPv6 addresses are assigned to the interface.
985                  * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
986                  * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
987                  * 40"
988                  */
989             case(OPT_IDB_MACADDR):
990                 /*
991                  * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
992                  */
993             case(OPT_IDB_EUIADDR):
994                 /*
995                  * Interface Hardware EUI address (64 bits), if available.
996                  * TODO: give a good example
997                  */
998             case(OPT_IDB_TZONE):
999                 /*
1000                  * Time zone for GMT support. TODO: specify better.
1001                  * TODO: give a good example.
1002                  */
1003             case(OPT_IDB_TSOFFSET):
1004                 /*
1005                  * A 64 bits integer value that specifies an offset (in
1006                  * seconds) that must be added to the timestamp of each packet
1007                  * to obtain the absolute timestamp of a packet. If the option
1008                  * is missing, the timestamps stored in the packet must be
1009                  * considered absolute timestamps. The time zone of the offset
1010                  * can be specified with the option if_tzone.
1011                  *
1012                  * TODO: won't a if_tsoffset_low for fractional second offsets
1013                  * be useful for highly synchronized capture systems? 1234
1014                  */
1015             default:
1016                 pcapng_debug("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
1017                               oh.option_code, oh.option_length);
1018         }
1019     }
1020
1021     g_free(option_content);
1022
1023     /*
1024      * If the per-file encapsulation isn't known, set it to this
1025      * interface's encapsulation.
1026      *
1027      * If it *is* known, and it isn't this interface's encapsulation,
1028      * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
1029      * have a single encapsulation for all interfaces in the file,
1030      * so it probably doesn't have a single encapsulation for all
1031      * packets in the file.
1032      */
1033     if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
1034         wth->file_encap = if_descr_mand->wtap_encap;
1035     } else {
1036         if (wth->file_encap != if_descr_mand->wtap_encap) {
1037             wth->file_encap = WTAP_ENCAP_PER_PACKET;
1038         }
1039     }
1040
1041     /*
1042      * The same applies to the per-file time stamp resolution.
1043      */
1044     if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
1045         wth->file_tsprec = if_descr_mand->tsprecision;
1046     } else {
1047         if (wth->file_tsprec != if_descr_mand->tsprecision) {
1048             wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1049         }
1050     }
1051
1052     /*
1053      * We don't return these to the caller in pcapng_read().
1054      */
1055     wblock->internal = TRUE;
1056
1057     return TRUE;
1058 }
1059
1060
1061 static gboolean
1062 pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info, gboolean enhanced)
1063 {
1064     int bytes_read;
1065     guint block_read;
1066     guint to_read, opt_cont_buf_len;
1067     pcapng_enhanced_packet_block_t epb;
1068     pcapng_packet_block_t pb;
1069     wtapng_packet_t packet;
1070     guint32 block_total_length;
1071     guint32 padding;
1072     interface_info_t iface_info;
1073     guint64 ts;
1074     guint8 *opt_ptr;
1075     pcapng_option_header_t *oh;
1076     guint8 *option_content;
1077     int pseudo_header_len;
1078     int fcslen;
1079 #ifdef HAVE_PLUGINS
1080     option_handler *handler;
1081 #endif
1082
1083     /* "(Enhanced) Packet Block" read fixed part */
1084     if (enhanced) {
1085         /*
1086          * Is this block long enough to be an EPB?
1087          */
1088         if (bh->block_total_length < MIN_EPB_SIZE) {
1089             /*
1090              * No.
1091              */
1092             *err = WTAP_ERR_BAD_FILE;
1093             *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
1094                                         bh->block_total_length, MIN_EPB_SIZE);
1095             return FALSE;
1096         }
1097         if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
1098             pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1099             return FALSE;
1100         }
1101         block_read = (guint)sizeof epb;
1102
1103         if (pn->byte_swapped) {
1104             packet.interface_id        = GUINT32_SWAP_LE_BE(epb.interface_id);
1105             packet.drops_count         = -1; /* invalid */
1106             packet.ts_high             = GUINT32_SWAP_LE_BE(epb.timestamp_high);
1107             packet.ts_low              = GUINT32_SWAP_LE_BE(epb.timestamp_low);
1108             packet.cap_len             = GUINT32_SWAP_LE_BE(epb.captured_len);
1109             packet.packet_len          = GUINT32_SWAP_LE_BE(epb.packet_len);
1110         } else {
1111             packet.interface_id        = epb.interface_id;
1112             packet.drops_count         = -1; /* invalid */
1113             packet.ts_high             = epb.timestamp_high;
1114             packet.ts_low              = epb.timestamp_low;
1115             packet.cap_len             = epb.captured_len;
1116             packet.packet_len          = epb.packet_len;
1117         }
1118         pcapng_debug("pcapng_read_packet_block: EPB on interface_id %d, cap_len %d, packet_len %d",
1119                       packet.interface_id, packet.cap_len, packet.packet_len);
1120     } else {
1121         /*
1122          * Is this block long enough to be a PB?
1123          */
1124         if (bh->block_total_length < MIN_PB_SIZE) {
1125             /*
1126              * No.
1127              */
1128             *err = WTAP_ERR_BAD_FILE;
1129             *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
1130                                         bh->block_total_length, MIN_PB_SIZE);
1131             return FALSE;
1132         }
1133         if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
1134             pcapng_debug("pcapng_read_packet_block: failed to read packet data");
1135             return FALSE;
1136         }
1137         block_read = (guint)sizeof pb;
1138
1139         if (pn->byte_swapped) {
1140             packet.interface_id        = GUINT16_SWAP_LE_BE(pb.interface_id);
1141             packet.drops_count         = GUINT16_SWAP_LE_BE(pb.drops_count);
1142             packet.ts_high             = GUINT32_SWAP_LE_BE(pb.timestamp_high);
1143             packet.ts_low              = GUINT32_SWAP_LE_BE(pb.timestamp_low);
1144             packet.cap_len             = GUINT32_SWAP_LE_BE(pb.captured_len);
1145             packet.packet_len          = GUINT32_SWAP_LE_BE(pb.packet_len);
1146         } else {
1147             packet.interface_id        = pb.interface_id;
1148             packet.drops_count         = pb.drops_count;
1149             packet.ts_high             = pb.timestamp_high;
1150             packet.ts_low              = pb.timestamp_low;
1151             packet.cap_len             = pb.captured_len;
1152             packet.packet_len          = pb.packet_len;
1153         }
1154         pcapng_debug("pcapng_read_packet_block: PB on interface_id %d, cap_len %d, packet_len %d",
1155                       packet.interface_id, packet.cap_len, packet.packet_len);
1156     }
1157
1158     /*
1159      * How much padding is there at the end of the packet data?
1160      */
1161     if ((packet.cap_len % 4) != 0)
1162         padding = 4 - (packet.cap_len % 4);
1163     else
1164         padding = 0;
1165
1166     /* add padding bytes to "block total length" */
1167     /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1168     if (bh->block_total_length % 4) {
1169         block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1170     } else {
1171         block_total_length = bh->block_total_length;
1172     }
1173     pcapng_debug("pcapng_read_packet_block: block_total_length %d", block_total_length);
1174
1175     /*
1176      * Is this block long enough to hold the packet data?
1177      */
1178     if (enhanced) {
1179         if (block_total_length <
1180             MIN_EPB_SIZE + packet.cap_len + padding) {
1181             /*
1182              * No.
1183              */
1184             *err = WTAP_ERR_BAD_FILE;
1185             *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
1186                                         block_total_length, packet.cap_len);
1187             return FALSE;
1188         }
1189     } else {
1190         if (block_total_length <
1191             MIN_PB_SIZE + packet.cap_len + padding) {
1192             /*
1193              * No.
1194              */
1195             *err = WTAP_ERR_BAD_FILE;
1196             *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1197                                         block_total_length, packet.cap_len);
1198             return FALSE;
1199         }
1200     }
1201
1202     pcapng_debug("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
1203                   packet.packet_len,
1204                   packet.cap_len,
1205                   packet.interface_id);
1206
1207     if (packet.interface_id >= pn->interfaces->len) {
1208         *err = WTAP_ERR_BAD_FILE;
1209         *err_info = g_strdup_printf("pcapng_read_packet_block: interface index %u is not less than interface count %u",
1210                                     packet.interface_id, pn->interfaces->len);
1211         return FALSE;
1212     }
1213     iface_info = g_array_index(pn->interfaces, interface_info_t,
1214                                packet.interface_id);
1215
1216     if (packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
1217         *err = WTAP_ERR_BAD_FILE;
1218         *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than %u",
1219                                     packet.cap_len,
1220                                     wtap_max_snaplen_for_encap(iface_info.wtap_encap));
1221         return FALSE;
1222     }
1223
1224     wblock->rec->rec_type = REC_TYPE_PACKET;
1225     wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1226
1227     pcapng_debug("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
1228                   iface_info.wtap_encap,
1229                   wtap_encap_string(iface_info.wtap_encap),
1230                   pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
1231     wblock->rec->rec_header.packet_header.interface_id = packet.interface_id;
1232     wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
1233     wblock->rec->tsprec = iface_info.tsprecision;
1234
1235     memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
1236     pseudo_header_len = pcap_process_pseudo_header(fh,
1237                                                    WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1238                                                    iface_info.wtap_encap,
1239                                                    packet.cap_len,
1240                                                    wblock->rec,
1241                                                    err,
1242                                                    err_info);
1243     if (pseudo_header_len < 0) {
1244         return FALSE;
1245     }
1246     block_read += pseudo_header_len;
1247     wblock->rec->rec_header.packet_header.caplen = packet.cap_len - pseudo_header_len;
1248     wblock->rec->rec_header.packet_header.len = packet.packet_len - pseudo_header_len;
1249
1250     /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1251     ts = (((guint64)packet.ts_high) << 32) | ((guint64)packet.ts_low);
1252     wblock->rec->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
1253     wblock->rec->ts.nsecs = (int)(((ts % iface_info.time_units_per_second) * 1000000000) / iface_info.time_units_per_second);
1254
1255     /* "(Enhanced) Packet Block" read capture data */
1256     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1257                                 packet.cap_len - pseudo_header_len, err, err_info))
1258         return FALSE;
1259     block_read += packet.cap_len - pseudo_header_len;
1260
1261     /* jump over potential padding bytes at end of the packet data */
1262     if (padding != 0) {
1263         if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
1264             return FALSE;
1265         block_read += padding;
1266     }
1267
1268     /* Option defaults */
1269     wblock->rec->opt_comment = NULL;
1270     wblock->rec->rec_header.packet_header.drop_count  = -1;
1271     wblock->rec->rec_header.packet_header.pack_flags  = 0;
1272
1273     /* FCS length default */
1274     fcslen = pn->if_fcslen;
1275
1276     /* Options
1277      * opt_comment    1
1278      * epb_flags      2
1279      * epb_hash       3
1280      * epb_dropcount  4
1281      */
1282     to_read = block_total_length -
1283         (int)sizeof(pcapng_block_header_t) -
1284         block_read -    /* fixed and variable part, including padding */
1285         (int)sizeof(bh->block_total_length);
1286
1287     /* Allocate enough memory to hold all options */
1288     opt_cont_buf_len = to_read;
1289     ws_buffer_assure_space(&wblock->rec->options_buf, opt_cont_buf_len);
1290     opt_ptr = ws_buffer_start_ptr(&wblock->rec->options_buf);
1291
1292     while (to_read != 0) {
1293         /* read option */
1294         oh = (pcapng_option_header_t *)(void *)opt_ptr;
1295         option_content = opt_ptr + sizeof (pcapng_option_header_t);
1296         bytes_read = pcapng_read_option(fh, pn, oh, option_content, opt_cont_buf_len, to_read, err, err_info, "packet");
1297         if (bytes_read <= 0) {
1298             pcapng_debug("pcapng_read_packet_block: failed to read option");
1299             /* XXX - free anything? */
1300             return FALSE;
1301         }
1302         to_read -= bytes_read;
1303
1304         /* handle option content */
1305         switch (oh->option_code) {
1306             case(OPT_EOFOPT):
1307                 if (to_read != 0) {
1308                     pcapng_debug("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
1309                 }
1310                 /* padding should be ok here, just get out of this */
1311                 to_read = 0;
1312                 break;
1313             case(OPT_COMMENT):
1314                 if (oh->option_length > 0 && oh->option_length < opt_cont_buf_len) {
1315                     wblock->rec->presence_flags |= WTAP_HAS_COMMENTS;
1316                     wblock->rec->opt_comment = g_strndup((char *)option_content, oh->option_length);
1317                     pcapng_debug("pcapng_read_packet_block: length %u opt_comment '%s'", oh->option_length, wblock->rec->opt_comment);
1318                 } else {
1319                     pcapng_debug("pcapng_read_packet_block: opt_comment length %u seems strange", oh->option_length);
1320                 }
1321                 break;
1322             case(OPT_EPB_FLAGS):
1323                 if (oh->option_length != 4) {
1324                     *err = WTAP_ERR_BAD_FILE;
1325                     *err_info = g_strdup_printf("pcapng_read_packet_block: packet block flags option length %u is not 4",
1326                                                 oh->option_length);
1327                     /* XXX - free anything? */
1328                     return FALSE;
1329                 }
1330                 /*  Don't cast a guint8 * into a guint32 *--the
1331                  *  guint8 * may not point to something that's
1332                  *  aligned correctly.
1333                  */
1334                 wblock->rec->presence_flags |= WTAP_HAS_PACK_FLAGS;
1335                 memcpy(&wblock->rec->rec_header.packet_header.pack_flags, option_content, sizeof(guint32));
1336                 if (pn->byte_swapped) {
1337                     wblock->rec->rec_header.packet_header.pack_flags = GUINT32_SWAP_LE_BE(wblock->rec->rec_header.packet_header.pack_flags);
1338                     memcpy(option_content, &wblock->rec->rec_header.packet_header.pack_flags, sizeof(guint32));
1339                 }
1340                 if (wblock->rec->rec_header.packet_header.pack_flags & 0x000001E0) {
1341                     /* The FCS length is present */
1342                     fcslen = (wblock->rec->rec_header.packet_header.pack_flags & 0x000001E0) >> 5;
1343                 }
1344                 pcapng_debug("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->rec->rec_header.packet_header.pack_flags);
1345                 break;
1346             case(OPT_EPB_HASH):
1347                 pcapng_debug("pcapng_read_packet_block: epb_hash %u currently not handled - ignoring %u bytes",
1348                               oh->option_code, oh->option_length);
1349                 break;
1350             case(OPT_EPB_DROPCOUNT):
1351                 if (oh->option_length != 8) {
1352                     *err = WTAP_ERR_BAD_FILE;
1353                     *err_info = g_strdup_printf("pcapng_read_packet_block: packet block drop count option length %u is not 8",
1354                                                 oh->option_length);
1355                     /* XXX - free anything? */
1356                     return FALSE;
1357                 }
1358                 /*  Don't cast a guint8 * into a guint64 *--the
1359                  *  guint8 * may not point to something that's
1360                  *  aligned correctly.
1361                  */
1362                 wblock->rec->presence_flags |= WTAP_HAS_DROP_COUNT;
1363                 memcpy(&wblock->rec->rec_header.packet_header.drop_count, option_content, sizeof(guint64));
1364                 if (pn->byte_swapped) {
1365                     wblock->rec->rec_header.packet_header.drop_count = GUINT64_SWAP_LE_BE(wblock->rec->rec_header.packet_header.drop_count);
1366                     memcpy(option_content, &wblock->rec->rec_header.packet_header.drop_count, sizeof(guint64));
1367                 }
1368
1369                 pcapng_debug("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->rec->rec_header.packet_header.drop_count);
1370                 break;
1371             default:
1372 #ifdef HAVE_PLUGINS
1373                 /*
1374                  * Do we have a handler for this packet block option code?
1375                  */
1376                 if (option_handlers[BT_INDEX_PBS] != NULL &&
1377                     (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_PBS],
1378                                                                    GUINT_TO_POINTER((guint)oh->option_code))) != NULL) {
1379                     /* Yes - call the handler. */
1380                     if (!handler->hfunc(pn->byte_swapped, oh->option_length,
1381                                  option_content, err, err_info))
1382                         /* XXX - free anything? */
1383                         return FALSE;
1384                 } else
1385 #endif
1386                 {
1387                     pcapng_debug("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
1388                                   oh->option_code, oh->option_length);
1389                 }
1390         }
1391     }
1392
1393     pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1394                            wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
1395                            pn->byte_swapped, fcslen);
1396
1397     /*
1398      * We return these to the caller in pcapng_read().
1399      */
1400     wblock->internal = FALSE;
1401
1402     return TRUE;
1403 }
1404
1405
1406 static gboolean
1407 pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
1408 {
1409     interface_info_t iface_info;
1410     pcapng_simple_packet_block_t spb;
1411     wtapng_simple_packet_t simple_packet;
1412     guint32 block_total_length;
1413     guint32 padding;
1414     int pseudo_header_len;
1415
1416     /*
1417      * Is this block long enough to be an SPB?
1418      */
1419     if (bh->block_total_length < MIN_SPB_SIZE) {
1420         /*
1421          * No.
1422          */
1423         *err = WTAP_ERR_BAD_FILE;
1424         *err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u of an SPB is less than the minimum SPB size %u",
1425                                     bh->block_total_length, MIN_SPB_SIZE);
1426         return FALSE;
1427     }
1428
1429     /* "Simple Packet Block" read fixed part */
1430     if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
1431         pcapng_debug("pcapng_read_simple_packet_block: failed to read packet data");
1432         return FALSE;
1433     }
1434
1435     if (0 >= pn->interfaces->len) {
1436         *err = WTAP_ERR_BAD_FILE;
1437         *err_info = g_strdup("pcapng_read_simple_packet_block: SPB appeared before any IDBs");
1438         return FALSE;
1439     }
1440     iface_info = g_array_index(pn->interfaces, interface_info_t, 0);
1441
1442     if (pn->byte_swapped) {
1443         simple_packet.packet_len   = GUINT32_SWAP_LE_BE(spb.packet_len);
1444     } else {
1445         simple_packet.packet_len   = spb.packet_len;
1446     }
1447
1448     /*
1449      * The captured length is not a field in the SPB; it can be
1450      * calculated as the minimum of the snapshot length from the
1451      * IDB and the packet length, as per the pcapng spec. An IDB
1452      * snapshot length of 0 means no limit.
1453      */
1454     simple_packet.cap_len = simple_packet.packet_len;
1455     if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
1456         simple_packet.cap_len = iface_info.snap_len;
1457
1458     /*
1459      * How much padding is there at the end of the packet data?
1460      */
1461     if ((simple_packet.cap_len % 4) != 0)
1462         padding = 4 - (simple_packet.cap_len % 4);
1463     else
1464         padding = 0;
1465
1466     /* add padding bytes to "block total length" */
1467     /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1468     if (bh->block_total_length % 4) {
1469         block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1470     } else {
1471         block_total_length = bh->block_total_length;
1472     }
1473     pcapng_debug("pcapng_read_simple_packet_block: block_total_length %d", block_total_length);
1474
1475     /*
1476      * Is this block long enough to hold the packet data?
1477      */
1478     if (block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
1479         /*
1480          * No.  That means that the problem is with the packet
1481          * length; the snapshot length can be bigger than the amount
1482          * of packet data in the block, as it's a *maximum* length,
1483          * not a *minimum* length.
1484          */
1485         *err = WTAP_ERR_BAD_FILE;
1486         *err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1487                                     block_total_length, simple_packet.packet_len);
1488         return FALSE;
1489     }
1490
1491     if (simple_packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
1492         *err = WTAP_ERR_BAD_FILE;
1493         *err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than %u",
1494                                     simple_packet.cap_len,
1495                                     wtap_max_snaplen_for_encap(iface_info.wtap_encap));
1496         return FALSE;
1497     }
1498     pcapng_debug("pcapng_read_simple_packet_block: packet data: packet_len %u",
1499                   simple_packet.packet_len);
1500
1501     pcapng_debug("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
1502                   pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
1503
1504     /* No time stamp in a simple packet block; no options, either */
1505     wblock->rec->rec_type = REC_TYPE_PACKET;
1506     wblock->rec->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1507     wblock->rec->rec_header.packet_header.interface_id = 0;
1508     wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
1509     wblock->rec->tsprec = iface_info.tsprecision;
1510     wblock->rec->ts.secs = 0;
1511     wblock->rec->ts.nsecs = 0;
1512     wblock->rec->rec_header.packet_header.interface_id = 0;
1513     wblock->rec->opt_comment = NULL;
1514     wblock->rec->rec_header.packet_header.drop_count = 0;
1515     wblock->rec->rec_header.packet_header.pack_flags = 0;
1516
1517     memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
1518     pseudo_header_len = pcap_process_pseudo_header(fh,
1519                                                    WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1520                                                    iface_info.wtap_encap,
1521                                                    simple_packet.cap_len,
1522                                                    wblock->rec,
1523                                                    err,
1524                                                    err_info);
1525     if (pseudo_header_len < 0) {
1526         return FALSE;
1527     }
1528     wblock->rec->rec_header.packet_header.caplen = simple_packet.cap_len - pseudo_header_len;
1529     wblock->rec->rec_header.packet_header.len = simple_packet.packet_len - pseudo_header_len;
1530
1531     memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
1532
1533     /* "Simple Packet Block" read capture data */
1534     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1535                                 simple_packet.cap_len, err, err_info))
1536         return FALSE;
1537
1538     /* jump over potential padding bytes at end of the packet data */
1539     if ((simple_packet.cap_len % 4) != 0) {
1540         if (!wtap_read_bytes(fh, NULL, 4 - (simple_packet.cap_len % 4), err, err_info))
1541             return FALSE;
1542     }
1543
1544     pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, iface_info.wtap_encap,
1545                            wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
1546                            pn->byte_swapped, pn->if_fcslen);
1547
1548     /*
1549      * We return these to the caller in pcapng_read().
1550      */
1551     wblock->internal = FALSE;
1552
1553     return TRUE;
1554 }
1555
1556 #define NRES_ENDOFRECORD 0
1557 #define NRES_IP4RECORD 1
1558 #define NRES_IP6RECORD 2
1559 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
1560 /* IPv6 + MAXNAMELEN */
1561 #define INITIAL_NRB_REC_SIZE (16 + 64)
1562
1563 /*
1564  * Find the end of the NUL-terminated name the beginning of which is pointed
1565  * to by p; record_len is the number of bytes remaining in the record.
1566  *
1567  * Return the length of the name, including the terminating NUL.
1568  *
1569  * If we don't find a terminating NUL, return -1 and set *err and
1570  * *err_info appropriately.
1571  */
1572 static int
1573 name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
1574                                     gchar **err_info)
1575 {
1576     int namelen;
1577
1578     namelen = 0;
1579     for (;;) {
1580         if (record_len == 0) {
1581             /*
1582              * We ran out of bytes in the record without
1583              * finding a NUL.
1584              */
1585             *err = WTAP_ERR_BAD_FILE;
1586             *err_info = g_strdup("pcapng_read_name_resolution_block: NRB record has non-null-terminated host name");
1587             return -1;
1588         }
1589         if (*p == '\0')
1590             break;  /* that's the terminating NUL */
1591         p++;
1592         record_len--;
1593         namelen++;      /* count this byte */
1594     }
1595
1596     /* Include the NUL in the name length. */
1597     return namelen + 1;
1598 }
1599
1600 static gboolean
1601 pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
1602 {
1603     int block_read;
1604     int to_read;
1605     pcapng_name_resolution_block_t nrb;
1606     Buffer nrb_rec;
1607     guint32 v4_addr;
1608     guint record_len, opt_cont_buf_len;
1609     char *namep;
1610     int namelen;
1611     int bytes_read;
1612     pcapng_option_header_t oh;
1613     guint8 *option_content;
1614 #ifdef HAVE_PLUGINS
1615     option_handler *handler;
1616 #endif
1617     gchar* tmp_content;
1618
1619     /*
1620      * Is this block long enough to be an NRB?
1621      */
1622     if (bh->block_total_length < MIN_NRB_SIZE) {
1623         /*
1624          * No.
1625          */
1626         *err = WTAP_ERR_BAD_FILE;
1627         *err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u of an NRB is less than the minimum NRB size %u",
1628                                     bh->block_total_length, MIN_NRB_SIZE);
1629         return FALSE;
1630     }
1631
1632     to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
1633
1634     pcapng_debug("pcapng_read_name_resolution_block, total %d bytes", bh->block_total_length);
1635
1636     /* Ensure we have a name resolution block */
1637     if (wblock->block == NULL) {
1638         wblock->block = wtap_block_create(WTAP_BLOCK_NG_NRB);
1639     }
1640
1641     /*
1642      * Start out with a buffer big enough for an IPv6 address and one
1643      * 64-byte name; we'll make the buffer bigger if necessary.
1644      */
1645     ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
1646     block_read = 0;
1647     while (block_read < to_read) {
1648         /*
1649          * There must be at least one record's worth of data
1650          * here.
1651          */
1652         if ((size_t)(to_read - block_read) < sizeof nrb) {
1653             ws_buffer_free(&nrb_rec);
1654             *err = WTAP_ERR_BAD_FILE;
1655             *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
1656                                         to_read - block_read,
1657                                         (guint)sizeof nrb);
1658             return FALSE;
1659         }
1660         if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
1661             ws_buffer_free(&nrb_rec);
1662             pcapng_debug("pcapng_read_name_resolution_block: failed to read record header");
1663             return FALSE;
1664         }
1665         block_read += (int)sizeof nrb;
1666
1667         if (pn->byte_swapped) {
1668             nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
1669             nrb.record_len  = GUINT16_SWAP_LE_BE(nrb.record_len);
1670         }
1671
1672         if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
1673             ws_buffer_free(&nrb_rec);
1674             *err = WTAP_ERR_BAD_FILE;
1675             *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
1676                                         to_read - block_read,
1677                                         nrb.record_len + PADDING4(nrb.record_len));
1678             return FALSE;
1679         }
1680         switch (nrb.record_type) {
1681             case NRES_ENDOFRECORD:
1682                 /* There shouldn't be any more data - but there MAY be options */
1683                 goto read_options;
1684                 break;
1685             case NRES_IP4RECORD:
1686                 /*
1687                  * The smallest possible record must have
1688                  * a 4-byte IPv4 address, hence a minimum
1689                  * of 4 bytes.
1690                  *
1691                  * (The pcapng spec really indicates
1692                  * that it must be at least 5 bytes,
1693                  * as there must be at least one name,
1694                  * and it really must be at least 6
1695                  * bytes, as the name mustn't be null,
1696                  * but there's no need to fail if there
1697                  * aren't any names at all, and we
1698                  * should report a null name as such.)
1699                  */
1700                 if (nrb.record_len < 4) {
1701                     ws_buffer_free(&nrb_rec);
1702                     *err = WTAP_ERR_BAD_FILE;
1703                     *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
1704                                                 nrb.record_len);
1705                     return FALSE;
1706                 }
1707                 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1708                 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1709                                      nrb.record_len, err, err_info)) {
1710                     ws_buffer_free(&nrb_rec);
1711                     pcapng_debug("pcapng_read_name_resolution_block: failed to read IPv4 record data");
1712                     return FALSE;
1713                 }
1714                 block_read += nrb.record_len;
1715
1716                 if (pn->add_new_ipv4) {
1717                     /*
1718                      * Scan through all the names in
1719                      * the record and add them.
1720                      */
1721                     memcpy(&v4_addr,
1722                            ws_buffer_start_ptr(&nrb_rec), 4);
1723                     /* IPv4 address is in big-endian order in the file always, which is how we store
1724                        it internally as well, so don't byte-swap it */
1725                     for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
1726                          record_len != 0;
1727                          namep += namelen, record_len -= namelen) {
1728                         /*
1729                          * Scan forward for a null
1730                          * byte.
1731                          */
1732                         namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1733                         if (namelen == -1) {
1734                             ws_buffer_free(&nrb_rec);
1735                             return FALSE;      /* fail */
1736                         }
1737                         pn->add_new_ipv4(v4_addr, namep);
1738                     }
1739                 }
1740
1741                 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
1742                     ws_buffer_free(&nrb_rec);
1743                     return FALSE;
1744                 }
1745                 block_read += PADDING4(nrb.record_len);
1746                 break;
1747             case NRES_IP6RECORD:
1748                 /*
1749                  * The smallest possible record must have
1750                  * a 16-byte IPv6 address, hence a minimum
1751                  * of 16 bytes.
1752                  *
1753                  * (The pcapng spec really indicates
1754                  * that it must be at least 17 bytes,
1755                  * as there must be at least one name,
1756                  * and it really must be at least 18
1757                  * bytes, as the name mustn't be null,
1758                  * but there's no need to fail if there
1759                  * aren't any names at all, and we
1760                  * should report a null name as such.)
1761                  */
1762                 if (nrb.record_len < 16) {
1763                     ws_buffer_free(&nrb_rec);
1764                     *err = WTAP_ERR_BAD_FILE;
1765                     *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
1766                                                 nrb.record_len);
1767                     return FALSE;
1768                 }
1769                 if (to_read < nrb.record_len) {
1770                     ws_buffer_free(&nrb_rec);
1771                     *err = WTAP_ERR_BAD_FILE;
1772                     *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u > remaining data in NRB",
1773                                                 nrb.record_len);
1774                     return FALSE;
1775                 }
1776                 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
1777                 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
1778                                      nrb.record_len, err, err_info)) {
1779                     ws_buffer_free(&nrb_rec);
1780                     return FALSE;
1781                 }
1782                 block_read += nrb.record_len;
1783
1784                 if (pn->add_new_ipv6) {
1785                     for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
1786                          record_len != 0;
1787                          namep += namelen, record_len -= namelen) {
1788                         /*
1789                          * Scan forward for a null
1790                          * byte.
1791                          */
1792                         namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1793                         if (namelen == -1) {
1794                             ws_buffer_free(&nrb_rec);
1795                             return FALSE;      /* fail */
1796                         }
1797                         pn->add_new_ipv6(ws_buffer_start_ptr(&nrb_rec),
1798                                          namep);
1799                     }
1800                 }
1801
1802                 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
1803                     ws_buffer_free(&nrb_rec);
1804                     return FALSE;
1805                 }
1806                 block_read += PADDING4(nrb.record_len);
1807                 break;
1808             default:
1809                 pcapng_debug("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
1810                 if (!wtap_read_bytes(fh, NULL, nrb.record_len + PADDING4(nrb.record_len), err, err_info)) {
1811                     ws_buffer_free(&nrb_rec);
1812                     return FALSE;
1813                 }
1814                 block_read += nrb.record_len + PADDING4(nrb.record_len);
1815                 break;
1816         }
1817     }
1818
1819
1820 read_options:
1821     to_read -= block_read;
1822
1823     /* Options
1824      * opt_comment    1
1825      *
1826      * TODO:
1827      * ns_dnsname     2
1828      * ns_dnsIP4addr  3
1829      * ns_dnsIP6addr  4
1830      */
1831
1832     /* Allocate enough memory to hold all options */
1833     opt_cont_buf_len = to_read;
1834     option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1835     if (opt_cont_buf_len != 0 && option_content == NULL) {
1836         *err = ENOMEM;  /* we assume we're out of memory */
1837         ws_buffer_free(&nrb_rec);
1838         return FALSE;
1839     }
1840
1841     while (to_read != 0) {
1842         /* read option */
1843         bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "name_resolution");
1844         if (bytes_read <= 0) {
1845             pcapng_debug("pcapng_read_name_resolution_block: failed to read option");
1846             g_free(option_content);
1847             ws_buffer_free(&nrb_rec);
1848             return FALSE;
1849         }
1850         to_read -= bytes_read;
1851
1852         /* handle option content */
1853         switch (oh.option_code) {
1854             case(OPT_EOFOPT):
1855                 if (to_read != 0) {
1856                     pcapng_debug("pcapng_read_name_resolution_block: %u bytes after opt_endofopt", to_read);
1857                 }
1858                 /* padding should be ok here, just get out of this */
1859                 to_read = 0;
1860                 break;
1861             case(OPT_COMMENT):
1862                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1863                     tmp_content = g_strndup((char *)option_content, oh.option_length);
1864                     wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1865                     pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, tmp_content);
1866                     g_free(tmp_content);
1867                 } else {
1868                     pcapng_debug("pcapng_read_name_resolution_block: opt_comment length %u seems strange", oh.option_length);
1869                 }
1870                 break;
1871             default:
1872 #ifdef HAVE_PLUGINS
1873                 /*
1874                  * Do we have a handler for this network resolution block option code?
1875                  */
1876                 if (option_handlers[BT_INDEX_NRB] != NULL &&
1877                     (handler = (option_handler *)g_hash_table_lookup(option_handlers[BT_INDEX_NRB],
1878                                                                    GUINT_TO_POINTER((guint)oh.option_code))) != NULL) {
1879                     /* Yes - call the handler. */
1880                     if (!handler->hfunc(pn->byte_swapped, oh.option_length,
1881                                  option_content, err, err_info)) {
1882
1883                         g_free(option_content);
1884                         ws_buffer_free(&nrb_rec);
1885                         return FALSE;
1886                     }
1887                 } else
1888 #endif
1889                 {
1890                     pcapng_debug("pcapng_read_name_resolution_block: unknown option %u - ignoring %u bytes",
1891                                   oh.option_code, oh.option_length);
1892                 }
1893         }
1894     }
1895
1896     g_free(option_content);
1897     ws_buffer_free(&nrb_rec);
1898
1899     /*
1900      * We don't return these to the caller in pcapng_read().
1901      */
1902     wblock->internal = TRUE;
1903
1904     return TRUE;
1905 }
1906
1907 static gboolean
1908 pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock,int *err, gchar **err_info)
1909 {
1910     int bytes_read;
1911     guint to_read, opt_cont_buf_len;
1912     pcapng_interface_statistics_block_t isb;
1913     pcapng_option_header_t oh;
1914     guint8 *option_content = NULL; /* Allocate as large as the options block */
1915     wtapng_if_stats_mandatory_t* if_stats_mand;
1916     char* tmp_content;
1917
1918     /*
1919      * Is this block long enough to be an ISB?
1920      */
1921     if (bh->block_total_length < MIN_ISB_SIZE) {
1922         /*
1923          * No.
1924          */
1925         *err = WTAP_ERR_BAD_FILE;
1926         *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too small (< %u)",
1927                                     bh->block_total_length, MIN_ISB_SIZE);
1928         return FALSE;
1929     }
1930
1931     /* "Interface Statistics Block" read fixed part */
1932     if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
1933         pcapng_debug("pcapng_read_interface_statistics_block: failed to read packet data");
1934         return FALSE;
1935     }
1936
1937     wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATS);
1938     if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1939     if (pn->byte_swapped) {
1940         if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
1941         if_stats_mand->ts_high      = GUINT32_SWAP_LE_BE(isb.timestamp_high);
1942         if_stats_mand->ts_low       = GUINT32_SWAP_LE_BE(isb.timestamp_low);
1943     } else {
1944         if_stats_mand->interface_id = isb.interface_id;
1945         if_stats_mand->ts_high      = isb.timestamp_high;
1946         if_stats_mand->ts_low       = isb.timestamp_low;
1947     }
1948     pcapng_debug("pcapng_read_interface_statistics_block: interface_id %u", if_stats_mand->interface_id);
1949
1950     /* Options */
1951     to_read = bh->block_total_length -
1952         (MIN_BLOCK_SIZE + (guint)sizeof isb);    /* fixed and variable part, including padding */
1953
1954     /* Allocate enough memory to hold all options */
1955     opt_cont_buf_len = to_read;
1956     option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
1957     if (opt_cont_buf_len != 0 && option_content == NULL) {
1958         *err = ENOMEM;  /* we assume we're out of memory */
1959         return FALSE;
1960     }
1961
1962     while (to_read != 0) {
1963         /* read option */
1964         bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info, "interface_statistics");
1965         if (bytes_read <= 0) {
1966             pcapng_debug("pcapng_read_interface_statistics_block: failed to read option");
1967             g_free(option_content);
1968             return FALSE;
1969         }
1970         to_read -= bytes_read;
1971
1972         /* handle option content */
1973         switch (oh.option_code) {
1974             case(OPT_EOFOPT): /* opt_endofopt */
1975                 if (to_read != 0) {
1976                     pcapng_debug("pcapng_read_interface_statistics_block: %u bytes after opt_endofopt", to_read);
1977                 }
1978                 /* padding should be ok here, just get out of this */
1979                 to_read = 0;
1980                 break;
1981             case(OPT_COMMENT): /* opt_comment */
1982                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1983                     tmp_content = g_strndup((char *)option_content, oh.option_length);
1984                     wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length);
1985                     pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", tmp_content);
1986                     g_free(tmp_content);
1987                 } else {
1988                     pcapng_debug("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
1989                 }
1990                 break;
1991             case(OPT_ISB_STARTTIME): /* isb_starttime */
1992                 if (oh.option_length == 8) {
1993                     guint32 high, low;
1994                     guint64 starttime;
1995
1996                     /*  Don't cast a guint8 * into a guint32 *--the
1997                      *  guint8 * may not point to something that's
1998                      *  aligned correctly.
1999                      */
2000                     memcpy(&high, option_content, sizeof(guint32));
2001                     memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2002                     if (pn->byte_swapped) {
2003                         high = GUINT32_SWAP_LE_BE(high);
2004                         low = GUINT32_SWAP_LE_BE(low);
2005                     }
2006                     starttime = (guint64)high;
2007                     starttime <<= 32;
2008                     starttime += (guint64)low;
2009                     /* Fails with multiple options; we silently ignore the failure */
2010                     wtap_block_add_uint64_option(wblock->block, OPT_ISB_STARTTIME, starttime);
2011                     pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", starttime);
2012                 } else {
2013                     pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2014                 }
2015                 break;
2016             case(OPT_ISB_ENDTIME): /* isb_endtime */
2017                 if (oh.option_length == 8) {
2018                     guint32 high, low;
2019                     guint64 endtime;
2020
2021                     /*  Don't cast a guint8 * into a guint32 *--the
2022                      *  guint8 * may not point to something that's
2023                      *  aligned correctly.
2024                      */
2025                     memcpy(&high, option_content, sizeof(guint32));
2026                     memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
2027                     if (pn->byte_swapped) {
2028                         high = GUINT32_SWAP_LE_BE(high);
2029                         low = GUINT32_SWAP_LE_BE(low);
2030                     }
2031                     endtime = (guint64)high;
2032                     endtime <<= 32;
2033                     endtime += (guint64)low;
2034                     /* Fails with multiple options; we silently ignore the failure */
2035                     wtap_block_add_uint64_option(wblock->block, OPT_ISB_ENDTIME, endtime);
2036                     pcapng_debug("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", endtime);
2037                 } else {
2038                     pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
2039                 }
2040                 break;
2041             case(OPT_ISB_IFRECV): /* isb_ifrecv */
2042                 if (oh.option_length == 8) {
2043                     guint64 ifrecv;
2044                     /*  Don't cast a guint8 * into a guint64 *--the
2045                      *  guint8 * may not point to something that's
2046                      *  aligned correctly.
2047                      */
2048                     memcpy(&ifrecv, option_content, sizeof(guint64));
2049                     if (pn->byte_swapped)
2050                         ifrecv = GUINT64_SWAP_LE_BE(ifrecv);
2051                     /* Fails with multiple options; we silently ignore the failure */
2052                     wtap_block_add_uint64_option(wblock->block, OPT_ISB_IFRECV, ifrecv);
2053                     pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", ifrecv);
2054                 } else {
2055                     pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
2056                 }
2057                 break;
2058             case(OPT_ISB_IFDROP): /* isb_ifdrop */
2059                 if (oh.option_length == 8) {
2060                     guint64 ifdrop;
2061                     /*  Don't cast a guint8 * into a guint64 *--the
2062                      *  guint8 * may not point to something that's
2063                      *  aligned correctly.
2064                      */
2065                     memcpy(&ifdrop, option_content, sizeof(guint64));
2066                     if (pn->byte_swapped)
2067                         ifdrop = GUINT64_SWAP_LE_BE(ifdrop);
2068                     /* Fails with multiple options; we silently ignore the failure */
2069                     wtap_block_add_uint64_option(wblock->block, OPT_ISB_IFDROP, ifdrop);
2070                     pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", ifdrop);
2071                 } else {
2072                     pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
2073                 }
2074                 break;
2075             case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2076                 if (oh.option_length == 8) {
2077                     guint64 filteraccept;
2078                     /*  Don't cast a guint8 * into a guint64 *--the
2079                      *  guint8 * may not point to something that's
2080                      *  aligned correctly.
2081                      */
2082                     memcpy(&filteraccept, option_content, sizeof(guint64));
2083                     if (pn->byte_swapped)
2084                         filteraccept = GUINT64_SWAP_LE_BE(filteraccept);
2085                     /* Fails with multiple options; we silently ignore the failure */
2086                     wtap_block_add_uint64_option(wblock->block, OPT_ISB_FILTERACCEPT, filteraccept);
2087                     pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", filteraccept);
2088                 } else {
2089                     pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept length %u not 8 as expected", oh.option_length);
2090                 }
2091                 break;
2092             case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2093                 if (oh.option_length == 8) {
2094                     guint64 osdrop;
2095                     /*  Don't cast a guint8 * into a guint64 *--the
2096                      *  guint8 * may not point to something that's
2097                      *  aligned correctly.
2098                      */
2099                     memcpy(&osdrop, option_content, sizeof(guint64));
2100                     if (pn->byte_swapped)
2101                         osdrop = GUINT64_SWAP_LE_BE(osdrop);
2102                     /* Fails with multiple options; we silently ignore the failure */
2103                     wtap_block_add_uint64_option(wblock->block, OPT_ISB_OSDROP, osdrop);
2104                     pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", osdrop);
2105                 } else {
2106                     pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop length %u not 8 as expected", oh.option_length);
2107                 }
2108                 break;
2109             case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8  */
2110                 if (oh.option_length == 8) {
2111                     guint64 usrdeliv;
2112                     /*  Don't cast a guint8 * into a guint64 *--the
2113                      *  guint8 * may not point to something that's
2114                      *  aligned correctly.
2115                      */
2116                     memcpy(&usrdeliv, option_content, sizeof(guint64));
2117                     if (pn->byte_swapped)
2118                         usrdeliv = GUINT64_SWAP_LE_BE(usrdeliv);
2119                     /* Fails with multiple options; we silently ignore the failure */
2120                     wtap_block_add_uint64_option(wblock->block, OPT_ISB_USRDELIV, usrdeliv);
2121                     pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", usrdeliv);
2122                 } else {
2123                     pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv length %u not 8 as expected", oh.option_length);
2124                 }
2125                 break;
2126             default:
2127                 pcapng_debug("pcapng_read_interface_statistics_block: unknown option %u - ignoring %u bytes",
2128                               oh.option_code, oh.option_length);
2129         }
2130     }
2131
2132     g_free(option_content);
2133
2134     /*
2135      * We don't return these to the caller in pcapng_read().
2136      */
2137     wblock->internal = TRUE;
2138
2139     return TRUE;
2140 }
2141
2142 static gboolean
2143 pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2144 {
2145     unsigned block_read;
2146     guint32 block_total_length;
2147     guint16 cpu_id;
2148     guint64 wire_ts;
2149     guint64 ts;
2150     guint64 thread_id;
2151     guint32 event_len;
2152     guint16 event_type;
2153
2154     if (bh->block_total_length < MIN_SYSDIG_EVENT_SIZE) {
2155         *err = WTAP_ERR_BAD_FILE;
2156         *err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
2157                                     bh->block_total_length, MIN_SYSDIG_EVENT_SIZE);
2158         return FALSE;
2159     }
2160
2161     /* add padding bytes to "block total length" */
2162     /* (the "block total length" of some example files don't contain any padding bytes!) */
2163     if (bh->block_total_length % 4) {
2164         block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2165     } else {
2166         block_total_length = bh->block_total_length;
2167     }
2168
2169     pcapng_debug("pcapng_read_sysdig_event_block: block_total_length %u",
2170                   bh->block_total_length);
2171
2172     wblock->rec->rec_type = REC_TYPE_SYSCALL;
2173     wblock->rec->rec_header.syscall_header.record_type = BLOCK_TYPE_SYSDIG_EVENT;
2174     wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
2175     wblock->rec->tsprec = WTAP_TSPREC_NSEC;
2176
2177     block_read = block_total_length;
2178
2179     if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
2180         pcapng_debug("pcapng_read_packet_block: failed to read sysdig event cpu id");
2181         return FALSE;
2182     }
2183     if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
2184         pcapng_debug("pcapng_read_packet_block: failed to read sysdig event timestamp");
2185         return FALSE;
2186     }
2187     if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
2188         pcapng_debug("pcapng_read_packet_block: failed to read sysdig event thread id");
2189         return FALSE;
2190     }
2191     if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
2192         pcapng_debug("pcapng_read_packet_block: failed to read sysdig event length");
2193         return FALSE;
2194     }
2195     if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
2196         pcapng_debug("pcapng_read_packet_block: failed to read sysdig event type");
2197         return FALSE;
2198     }
2199
2200     block_read -= MIN_SYSDIG_EVENT_SIZE;
2201     wblock->rec->rec_header.syscall_header.byte_order = G_BYTE_ORDER;
2202
2203     /* XXX Use Gxxx_FROM_LE macros instead? */
2204     if (pn->byte_swapped) {
2205         wblock->rec->rec_header.syscall_header.byte_order =
2206 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2207             G_BIG_ENDIAN;
2208 #else
2209             G_LITTLE_ENDIAN;
2210 #endif
2211         wblock->rec->rec_header.syscall_header.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
2212         ts = GUINT64_SWAP_LE_BE(wire_ts);
2213         wblock->rec->rec_header.syscall_header.thread_id = GUINT64_SWAP_LE_BE(thread_id);
2214         wblock->rec->rec_header.syscall_header.event_len = GUINT32_SWAP_LE_BE(event_len);
2215         wblock->rec->rec_header.syscall_header.event_type = GUINT16_SWAP_LE_BE(event_type);
2216     } else {
2217         wblock->rec->rec_header.syscall_header.cpu_id = cpu_id;
2218         ts = wire_ts;
2219         wblock->rec->rec_header.syscall_header.thread_id = thread_id;
2220         wblock->rec->rec_header.syscall_header.event_len = event_len;
2221         wblock->rec->rec_header.syscall_header.event_type = event_type;
2222     }
2223
2224     wblock->rec->ts.secs = (time_t) (ts / 1000000000);
2225     wblock->rec->ts.nsecs = (int) (ts % 1000000000);
2226
2227     wblock->rec->rec_header.syscall_header.event_filelen = block_read;
2228
2229     /* "Sysdig Event Block" read event data */
2230     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2231                                 block_read, err, err_info))
2232         return FALSE;
2233
2234     /* XXX Read comment? */
2235
2236     /*
2237      * We return these to the caller in pcapng_read().
2238      */
2239     wblock->internal = FALSE;
2240
2241     return TRUE;
2242 }
2243
2244 static gboolean
2245 pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock, int *err, gchar **err_info)
2246 {
2247     guint32 entry_length;
2248     guint32 block_total_length;
2249     guint64 rt_ts;
2250
2251     if (bh->block_total_length < MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE) {
2252         *err = WTAP_ERR_BAD_FILE;
2253         *err_info = g_strdup_printf("%s: total block length %u is too small (< %u)", G_STRFUNC,
2254                                     bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE);
2255         return FALSE;
2256     }
2257
2258     /* add padding bytes to "block total length" */
2259     /* (the "block total length" of some example files don't contain any padding bytes!) */
2260     if (bh->block_total_length % 4) {
2261         block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2262     } else {
2263         block_total_length = bh->block_total_length;
2264     }
2265
2266     pcapng_debug("%s: block_total_length %u", G_STRFUNC, bh->block_total_length);
2267
2268     entry_length = block_total_length - MIN_BLOCK_SIZE;
2269
2270     /* Includes padding bytes. */
2271     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2272                                 entry_length, err, err_info)) {
2273         return FALSE;
2274     }
2275     ws_buffer_increase_length(wblock->frame_buffer, entry_length);
2276
2277     /* We don't have memmem available everywhere, so we get to use strstr. */
2278     ws_buffer_append(wblock->frame_buffer, (guint8 * ) "", 1);
2279
2280     gchar *buf_ptr = (gchar *) ws_buffer_start_ptr(wblock->frame_buffer);
2281     while (entry_length > 0 && buf_ptr[entry_length] == '\0') {
2282         entry_length--;
2283     }
2284
2285     if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE) {
2286         *err = WTAP_ERR_BAD_FILE;
2287         *err_info = g_strdup_printf("%s: entry length %u is too small (< %u)", G_STRFUNC,
2288                                     bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE);
2289         return FALSE;
2290     }
2291
2292     pcapng_debug("%s: entry_length %u", G_STRFUNC, entry_length);
2293
2294     size_t rt_ts_len = strlen(SDJ__REALTIME_TIMESTAMP);
2295     char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP);
2296
2297     if (!ts_pos) {
2298         *err = WTAP_ERR_BAD_FILE;
2299         *err_info = g_strdup_printf("%s: no timestamp", G_STRFUNC);
2300         return FALSE;
2301     }
2302
2303     if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) {
2304         *err = WTAP_ERR_BAD_FILE;
2305         *err_info = g_strdup_printf("%s: timestamp past end of buffer", G_STRFUNC);
2306         return FALSE;
2307     }
2308
2309     errno = 0;
2310     rt_ts = strtoul(ts_pos+rt_ts_len, NULL, 10);
2311     if (errno) {
2312         *err = WTAP_ERR_BAD_FILE;
2313         *err_info = g_strdup_printf("%s: invalid timestamp", G_STRFUNC);
2314         return FALSE;
2315     }
2316
2317     wblock->rec->rec_type = REC_TYPE_FT_SPECIFIC_EVENT;
2318     wblock->rec->rec_header.ft_specific_header.record_type = BLOCK_TYPE_SYSTEMD_JOURNAL;
2319     wblock->rec->rec_header.ft_specific_header.record_len = entry_length;
2320     wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
2321     wblock->rec->tsprec = WTAP_TSPREC_USEC;
2322
2323     wblock->rec->ts.secs = (time_t) rt_ts / 1000000;
2324     wblock->rec->ts.nsecs = (rt_ts % 1000000) * 1000;
2325
2326     /*
2327      * We return these to the caller in pcapng_read().
2328      */
2329     wblock->internal = FALSE;
2330
2331     if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
2332         /*
2333          * Nothing (most notably an IDB) has set a file encap at this point.
2334          * Do so here.
2335          * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate?
2336          */
2337         wth->file_encap = WTAP_ENCAP_PER_PACKET;
2338     }
2339
2340     return TRUE;
2341 }
2342
2343 static gboolean
2344 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
2345 #
2346 #ifdef HAVE_PLUGINS
2347     pcapng_t *pn,
2348 #else
2349     pcapng_t *pn _U_,
2350 #endif
2351     wtapng_block_t *wblock,
2352     int *err, gchar **err_info)
2353 {
2354     guint32 block_read;
2355     guint32 block_total_length;
2356 #ifdef HAVE_PLUGINS
2357     block_handler *handler;
2358 #endif
2359
2360     if (bh->block_total_length < MIN_BLOCK_SIZE) {
2361         *err = WTAP_ERR_BAD_FILE;
2362         *err_info = g_strdup_printf("pcapng_read_unknown_block: total block length %u of an unknown block type is less than the minimum block size %u",
2363                                     bh->block_total_length, MIN_BLOCK_SIZE);
2364         return FALSE;
2365     }
2366
2367     /* add padding bytes to "block total length" */
2368     /* (the "block total length" of some example files don't contain any padding bytes!) */
2369     if (bh->block_total_length % 4) {
2370         block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
2371     } else {
2372         block_total_length = bh->block_total_length;
2373     }
2374
2375     block_read = block_total_length - MIN_BLOCK_SIZE;
2376
2377 #ifdef HAVE_PLUGINS
2378     /*
2379      * Do we have a handler for this block type?
2380      */
2381     if (block_handlers != NULL &&
2382         (handler = (block_handler *)g_hash_table_lookup(block_handlers,
2383                                                         GUINT_TO_POINTER(bh->block_type))) != NULL) {
2384         /* Yes - call it to read this block type. */
2385         if (!handler->reader(fh, block_read, pn->byte_swapped, wblock,
2386                              err, err_info))
2387             return FALSE;
2388     } else
2389 #endif
2390     {
2391         /* No.  Skip over this unknown block. */
2392         if (!wtap_read_bytes(fh, NULL, block_read, err, err_info)) {
2393             return FALSE;
2394         }
2395
2396         /*
2397          * We're skipping this, so we won't return these to the caller
2398          * in pcapng_read().
2399          */
2400         wblock->internal = TRUE;
2401     }
2402
2403     return TRUE;
2404 }
2405
2406
2407 static block_return_val
2408 pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2409 {
2410     block_return_val ret;
2411     pcapng_block_header_t bh;
2412     guint32 block_total_length;
2413
2414     wblock->block = NULL;
2415
2416     /* Try to read the (next) block header */
2417     if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
2418         pcapng_debug("pcapng_read_block: wtap_read_bytes_or_eof() failed, err = %d.", *err);
2419         if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
2420             /*
2421              * Short read or EOF.
2422              *
2423              * If we're reading this as part of an open,
2424              * the file is too short to be a pcapng file.
2425              *
2426              * If we're not, we treat PCAPNG_BLOCK_NOT_SHB and
2427              * PCAPNG_BLOCK_ERROR the same, so we can just return
2428              * PCAPNG_BLOCK_NOT_SHB in both cases.
2429              */
2430             return PCAPNG_BLOCK_NOT_SHB;
2431         }
2432         return PCAPNG_BLOCK_ERROR;
2433     }
2434
2435     /*
2436      * SHBs have to be treated differently from other blocks, because
2437      * the byte order of the fields in the block can only be determined
2438      * by looking at the byte-order magic number inside the block, not
2439      * by using the byte order of the section to which it belongs, as
2440      * it is the block that *defines* the byte order of the section to
2441      * which it belongs.
2442      */
2443     if (bh.block_type == BLOCK_TYPE_SHB) {
2444         /*
2445          * BLOCK_TYPE_SHB has the same value regardless of byte order,
2446          * so we don't need to byte-swap it.
2447          *
2448          * We *might* need to byte-swap the total length, but we
2449          * can't determine whether we do until we look inside the
2450          * block and find the byte-order magic number, so we rely
2451          * on pcapng_read_section_header_block() to do that and
2452          * to swap the total length (as it needs to get the total
2453          * length in the right byte order in order to read the
2454          * entire block).
2455          */
2456         wblock->type = bh.block_type;
2457
2458         pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2459
2460         ret = pcapng_read_section_header_block(fh, &bh, pn, wblock, err, err_info);
2461         if (ret != PCAPNG_BLOCK_OK) {
2462             return ret;
2463         }
2464     } else {
2465         if (pn->byte_swapped) {
2466             bh.block_type         = GUINT32_SWAP_LE_BE(bh.block_type);
2467             bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
2468         }
2469
2470         wblock->type = bh.block_type;
2471
2472         pcapng_debug("pcapng_read_block: block_type 0x%x", bh.block_type);
2473
2474         if (!pn->shb_read) {
2475             /*
2476              * No SHB seen yet, so we're trying to read the first block
2477              * during an open, to see whether it's an SHB; if what we
2478              * read doesn't look like an SHB, this isn't a pcapng file.
2479              */
2480             *err = 0;
2481             *err_info = NULL;
2482             return PCAPNG_BLOCK_NOT_SHB;
2483         }
2484
2485         /* Don't try to allocate memory for a huge number of options, as
2486            that might fail and, even if it succeeds, it might not leave
2487            any address space or memory+backing store for anything else.
2488
2489            We do that by imposing a maximum block size of MAX_BLOCK_SIZE. */
2490         if (bh.block_total_length > MAX_BLOCK_SIZE) {
2491             *err = WTAP_ERR_BAD_FILE;
2492             *err_info = g_strdup_printf("pcapng_read_block: total block length %u is too large (> %u)",
2493                                         bh.block_total_length, MAX_BLOCK_SIZE);
2494             return PCAPNG_BLOCK_ERROR;
2495         }
2496
2497         switch (bh.block_type) {
2498             case(BLOCK_TYPE_IDB):
2499                 if (!pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info))
2500                     return PCAPNG_BLOCK_ERROR;
2501                 break;
2502             case(BLOCK_TYPE_PB):
2503                 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE))
2504                     return PCAPNG_BLOCK_ERROR;
2505                 break;
2506             case(BLOCK_TYPE_SPB):
2507                 if (!pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info))
2508                     return PCAPNG_BLOCK_ERROR;
2509                 break;
2510             case(BLOCK_TYPE_EPB):
2511                 if (!pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE))
2512                     return PCAPNG_BLOCK_ERROR;
2513                 break;
2514             case(BLOCK_TYPE_NRB):
2515                 if (!pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info))
2516                     return PCAPNG_BLOCK_ERROR;
2517                 break;
2518             case(BLOCK_TYPE_ISB):
2519                 if (!pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info))
2520                     return PCAPNG_BLOCK_ERROR;
2521                 break;
2522             case(BLOCK_TYPE_SYSDIG_EVENT):
2523             /* case(BLOCK_TYPE_SYSDIG_EVF): */
2524                 if (!pcapng_read_sysdig_event_block(fh, &bh, pn, wblock, err, err_info))
2525                     return PCAPNG_BLOCK_ERROR;
2526                 break;
2527         case(BLOCK_TYPE_SYSTEMD_JOURNAL):
2528             if (!pcapng_read_systemd_journal_export_block(wth, fh, &bh, pn, wblock, err, err_info))
2529                 return PCAPNG_BLOCK_ERROR;
2530             break;
2531             default:
2532                 pcapng_debug("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
2533                 if (!pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info))
2534                     return PCAPNG_BLOCK_ERROR;
2535                 break;
2536         }
2537     }
2538
2539     /* sanity check: first and second block lengths must match */
2540     if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
2541                          err, err_info)) {
2542         pcapng_debug("pcapng_check_block_trailer: couldn't read second block length");
2543         return PCAPNG_BLOCK_ERROR;
2544     }
2545
2546     if (pn->byte_swapped)
2547         block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
2548
2549     if (block_total_length != bh.block_total_length) {
2550         *err = WTAP_ERR_BAD_FILE;
2551         *err_info = g_strdup_printf("pcapng_check_block_trailer: total block lengths (first %u and second %u) don't match",
2552                                     bh.block_total_length, block_total_length);
2553         return PCAPNG_BLOCK_ERROR;
2554     }
2555     return PCAPNG_BLOCK_OK;
2556 }
2557
2558 /* Process an IDB that we've just read. The contents of wblock are copied as needed. */
2559 static void
2560 pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
2561 {
2562     wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_DESCR);
2563     interface_info_t iface_info;
2564     wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
2565                                 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
2566
2567     wtap_block_copy(int_data, wblock->block);
2568
2569     /* XXX if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
2570     /* Interface statistics */
2571     if_descr_mand->num_stat_entries = 0;
2572     if_descr_mand->interface_statistics = NULL;
2573
2574     g_array_append_val(wth->interface_data, int_data);
2575
2576     iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
2577     iface_info.snap_len = wblock_if_descr_mand->snap_len;
2578     iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
2579     iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
2580
2581     g_array_append_val(pcapng->interfaces, iface_info);
2582 }
2583
2584 /* classic wtap: open capture file */
2585 wtap_open_return_val
2586 pcapng_open(wtap *wth, int *err, gchar **err_info)
2587 {
2588     pcapng_t pn;
2589     wtapng_block_t wblock;
2590     pcapng_t *pcapng;
2591     pcapng_block_header_t bh;
2592     gint64 saved_offset;
2593
2594     pn.shb_read = FALSE;
2595     /* we don't know the byte swapping of the file yet */
2596     pn.byte_swapped = FALSE;
2597     pn.if_fcslen = -1;
2598     pn.version_major = -1;
2599     pn.version_minor = -1;
2600     pn.interfaces = NULL;
2601
2602     /* we don't expect any packet blocks yet */
2603     wblock.frame_buffer = NULL;
2604     wblock.rec = NULL;
2605
2606     pcapng_debug("pcapng_open: opening file");
2607     /* read first block */
2608     switch (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info)) {
2609
2610     case PCAPNG_BLOCK_OK:
2611         /* No problem */
2612         break;
2613
2614     case PCAPNG_BLOCK_NOT_SHB:
2615         /* This doesn't look like an SHB, so this isn't a pcapng file. */
2616         wtap_block_free(wblock.block);
2617         *err = 0;
2618         g_free(*err_info);
2619         *err_info = NULL;
2620         return WTAP_OPEN_NOT_MINE;
2621
2622     case PCAPNG_BLOCK_ERROR:
2623         /* An I/O error, or this probably *is* a pcapng file but not a valid one. */
2624         wtap_block_free(wblock.block);
2625         return WTAP_OPEN_ERROR;
2626     }
2627
2628     /* first block must be a "Section Header Block" */
2629     if (wblock.type != BLOCK_TYPE_SHB) {
2630         /*
2631          * XXX - check for damage from transferring a file
2632          * between Windows and UN*X as text rather than
2633          * binary data?
2634          */
2635         pcapng_debug("pcapng_open: first block type %u not SHB", wblock.type);
2636         wtap_block_free(wblock.block);
2637         return WTAP_OPEN_NOT_MINE;
2638     }
2639     pn.shb_read = TRUE;
2640
2641     /*
2642      * At this point, we've decided this is a pcapng file, not
2643      * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
2644      * past this point.
2645      */
2646     wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), wblock.block);
2647     wtap_block_free(wblock.block);
2648     wblock.block = NULL;
2649
2650     wth->file_encap = WTAP_ENCAP_UNKNOWN;
2651     wth->snapshot_length = 0;
2652     wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
2653     pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t));
2654     wth->priv = (void *)pcapng;
2655     *pcapng = pn;
2656     pcapng->interfaces = g_array_new(FALSE, FALSE, sizeof(interface_info_t));
2657
2658     wth->subtype_read = pcapng_read;
2659     wth->subtype_seek_read = pcapng_seek_read;
2660     wth->subtype_close = pcapng_close;
2661     wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
2662
2663     /* Loop over all IDB:s that appear before any packets */
2664     while (1) {
2665         /* peek at next block */
2666         /* Try to read the (next) block header */
2667         saved_offset = file_tell(wth->fh);
2668         if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
2669             if (*err == 0) {
2670                 /* EOF */
2671                 pcapng_debug("No more IDBs available...");
2672                 break;
2673             }
2674             pcapng_debug("pcapng_open:  Check for more IDB:s, wtap_read_bytes_or_eof() failed, err = %d.", *err);
2675             return WTAP_OPEN_ERROR;
2676         }
2677
2678         /* go back to where we were */
2679         file_seek(wth->fh, saved_offset, SEEK_SET, err);
2680
2681         if (pn.byte_swapped) {
2682             bh.block_type         = GUINT32_SWAP_LE_BE(bh.block_type);
2683         }
2684
2685         pcapng_debug("pcapng_open: Check for more IDB:s block_type 0x%x", bh.block_type);
2686
2687         if (bh.block_type != BLOCK_TYPE_IDB) {
2688             break;  /* No more IDB:s */
2689         }
2690         if (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2691             wtap_block_free(wblock.block);
2692             if (*err == 0) {
2693                 pcapng_debug("No more IDBs available...");
2694                 break;
2695             } else {
2696                 pcapng_debug("pcapng_open: couldn't read IDB");
2697                 return WTAP_OPEN_ERROR;
2698             }
2699         }
2700         pcapng_process_idb(wth, pcapng, &wblock);
2701         wtap_block_free(wblock.block);
2702         pcapng_debug("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i",
2703                       wth->interface_data->len, wth->file_encap);
2704     }
2705     return WTAP_OPEN_MINE;
2706 }
2707
2708
2709 /* classic wtap: read packet */
2710 static gboolean
2711 pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
2712 {
2713     pcapng_t *pcapng = (pcapng_t *)wth->priv;
2714     wtapng_block_t wblock;
2715     wtap_block_t wtapng_if_descr;
2716     wtap_block_t if_stats;
2717     wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
2718     wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
2719
2720     wblock.frame_buffer  = wth->rec_data;
2721     wblock.rec = &wth->rec;
2722
2723     pcapng->add_new_ipv4 = wth->add_new_ipv4;
2724     pcapng->add_new_ipv6 = wth->add_new_ipv6;
2725
2726     /* read next block */
2727     while (1) {
2728         *data_offset = file_tell(wth->fh);
2729         pcapng_debug("pcapng_read: data_offset is %" G_GINT64_MODIFIER "d", *data_offset);
2730         if (pcapng_read_block(wth, wth->fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2731             pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2732             pcapng_debug("pcapng_read: couldn't read packet block");
2733             wtap_block_free(wblock.block);
2734             return FALSE;
2735         }
2736
2737         if (!wblock.internal) {
2738             /*
2739              * This is a block type we return to the caller to process.
2740              */
2741             break;
2742         }
2743
2744         /*
2745          * This is a block type we process internally, rather than
2746          * returning it for the caller to process.
2747          */
2748         switch (wblock.type) {
2749
2750             case(BLOCK_TYPE_SHB):
2751                 pcapng_debug("pcapng_read: another section header block");
2752                 g_array_append_val(wth->shb_hdrs, wblock.block);
2753                 break;
2754
2755             case(BLOCK_TYPE_IDB):
2756                 /* A new interface */
2757                 pcapng_debug("pcapng_read: block type BLOCK_TYPE_IDB");
2758                 pcapng_process_idb(wth, pcapng, &wblock);
2759                 wtap_block_free(wblock.block);
2760                 break;
2761
2762             case(BLOCK_TYPE_NRB):
2763                 /* More name resolution entries */
2764                 pcapng_debug("pcapng_read: block type BLOCK_TYPE_NRB");
2765                 if (wth->nrb_hdrs == NULL) {
2766                     wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
2767                 }
2768                 g_array_append_val(wth->nrb_hdrs, wblock.block);
2769                 break;
2770
2771             case(BLOCK_TYPE_ISB):
2772                 /*
2773                  * Another interface statistics report
2774                  *
2775                  * XXX - given that they're reports, we should be
2776                  * supplying them in read calls, and displaying them
2777                  * in the "packet" list, so you can see what the
2778                  * statistics were *at the time when the report was
2779                  * made*.
2780                  *
2781                  * The statistics from the *last* ISB could be displayed
2782                  * in the summary, but if there are packets after the
2783                  * last ISB, that could be misleading.
2784                  *
2785                  * If we only display them if that ISB has an isb_endtime
2786                  * option, which *should* only appear when capturing ended
2787                  * on that interface (so there should be no more packet
2788                  * blocks or ISBs for that interface after that point,
2789                  * that would be the best way of showing "summary"
2790                  * statistics.
2791                  */
2792                 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB");
2793                 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock.block);
2794                 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
2795                     pcapng_debug("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces", if_stats_mand_block->interface_id);
2796                 } else {
2797                     /* Get the interface description */
2798                     wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id);
2799                     wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
2800                     if (wtapng_if_descr_mand->num_stat_entries == 0) {
2801                         /* First ISB found, no previous entry */
2802                         pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
2803                         wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
2804                     }
2805
2806                     if_stats = wtap_block_create(WTAP_BLOCK_IF_STATS);
2807                     if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
2808                     if_stats_mand->interface_id  = if_stats_mand_block->interface_id;
2809                     if_stats_mand->ts_high       = if_stats_mand_block->ts_high;
2810                     if_stats_mand->ts_low        = if_stats_mand_block->ts_low;
2811
2812                     wtap_block_copy(if_stats, wblock.block);
2813                     g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
2814                     wtapng_if_descr_mand->num_stat_entries++;
2815                 }
2816                 wtap_block_free(wblock.block);
2817                 break;
2818
2819             default:
2820                 /* XXX - improve handling of "unknown" blocks */
2821                 pcapng_debug("pcapng_read: Unknown block type 0x%08x", wblock.type);
2822                 break;
2823         }
2824     }
2825
2826     /*pcapng_debug("Read length: %u Packet length: %u", bytes_read, wth->rec.rec_header.packet_header.caplen);*/
2827     pcapng_debug("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2828
2829     return TRUE;
2830 }
2831
2832
2833 /* classic wtap: seek to file position and read packet */
2834 static gboolean
2835 pcapng_seek_read(wtap *wth, gint64 seek_off,
2836                  wtap_rec *rec, Buffer *buf,
2837                  int *err, gchar **err_info)
2838 {
2839     pcapng_t *pcapng = (pcapng_t *)wth->priv;
2840     wtapng_block_t wblock;
2841
2842
2843     /* seek to the right file position */
2844     if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
2845         return FALSE;   /* Seek error */
2846     }
2847     pcapng_debug("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
2848
2849     wblock.frame_buffer = buf;
2850     wblock.rec = rec;
2851
2852     /* read the block */
2853     if (pcapng_read_block(wth, wth->random_fh, pcapng, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
2854         pcapng_debug("pcapng_seek_read: couldn't read packet block (err=%d).",
2855                       *err);
2856         wtap_block_free(wblock.block);
2857         return FALSE;
2858     }
2859
2860     /* block must not be one we process internally rather than supplying */
2861     if (wblock.internal) {
2862         pcapng_debug("pcapng_seek_read: block type %u is not one we return",
2863                      wblock.type);
2864         wtap_block_free(wblock.block);
2865         return FALSE;
2866     }
2867
2868     wtap_block_free(wblock.block);
2869     return TRUE;
2870 }
2871
2872
2873 /* classic wtap: close capture file */
2874 static void
2875 pcapng_close(wtap *wth)
2876 {
2877     pcapng_t *pcapng = (pcapng_t *)wth->priv;
2878
2879     pcapng_debug("pcapng_close: closing file");
2880     g_array_free(pcapng->interfaces, TRUE);
2881 }
2882
2883 typedef struct pcapng_block_size_t
2884 {
2885     guint32 size;
2886 } pcapng_block_size_t;
2887
2888 static guint32 pcapng_compute_option_string_size(char *str)
2889 {
2890     guint32 size = 0, pad;
2891
2892     size = (guint32)strlen(str) & 0xffff;
2893     if ((size % 4)) {
2894         pad = 4 - (size % 4);
2895     } else {
2896         pad = 0;
2897     }
2898
2899     size += pad;
2900
2901     return size;
2902 }
2903
2904 static void compute_shb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
2905 {
2906     pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
2907     guint32 size = 0;
2908
2909     switch(option_id)
2910     {
2911     case OPT_COMMENT:
2912     case OPT_SHB_HARDWARE:
2913     case OPT_SHB_OS:
2914     case OPT_SHB_USERAPPL:
2915         size = pcapng_compute_option_string_size(optval->stringval);
2916         break;
2917     default:
2918         /* Unknown options - size by datatype? */
2919         break;
2920     }
2921
2922     block_size->size += size;
2923     /* Add bytes for option header if option should be written */
2924     if (size > 0) {
2925         /* Add optional padding to 32 bits */
2926         if ((block_size->size & 0x03) != 0)
2927         {
2928             block_size->size += 4 - (block_size->size & 0x03);
2929         }
2930         block_size->size += 4;
2931     }
2932 }
2933
2934 typedef struct pcapng_write_block_t
2935 {
2936     wtap_dumper *wdh;
2937     int *err;
2938     gboolean success;
2939 }
2940 pcapng_write_block_t;
2941
2942 static gboolean pcapng_write_option_string(wtap_dumper *wdh, guint option_id, char *str, int *err)
2943 {
2944     struct pcapng_option_header option_hdr;
2945     guint32 size = (guint32)strlen(str) & 0xffff;
2946     const guint32 zero_pad = 0;
2947     guint32 pad;
2948
2949     if (size == 0)
2950         return TRUE;
2951
2952     /* String options don't consider pad bytes part of the length */
2953     option_hdr.type         = (guint16)option_id;
2954     option_hdr.value_length = (guint16)size;
2955     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2956         return FALSE;
2957     wdh->bytes_dumped += 4;
2958
2959     if (!wtap_dump_file_write(wdh, str, size, err))
2960         return FALSE;
2961     wdh->bytes_dumped += size;
2962
2963     if ((size % 4)) {
2964         pad = 4 - (size % 4);
2965     } else {
2966         pad = 0;
2967     }
2968
2969     /* write padding (if any) */
2970     if (pad != 0) {
2971         if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
2972             return FALSE;
2973
2974         wdh->bytes_dumped += pad;
2975     }
2976
2977     return TRUE;
2978 }
2979
2980 static void write_wtap_shb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
2981 {
2982     pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
2983
2984     /* Don't continue if there has been an error */
2985     if (!write_block->success)
2986         return;
2987
2988     switch(option_id)
2989     {
2990     case OPT_COMMENT:
2991     case OPT_SHB_HARDWARE:
2992     case OPT_SHB_OS:
2993     case OPT_SHB_USERAPPL:
2994         if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
2995             write_block->success = FALSE;
2996             return;
2997         }
2998         break;
2999     default:
3000         /* Unknown options - write by datatype? */
3001         break;
3002     }
3003 }
3004
3005 /* Write a section header block.
3006  * If we don't have a section block header already, create a default
3007  * one with no options.
3008  */
3009 static gboolean
3010 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
3011 {
3012     pcapng_block_header_t bh;
3013     pcapng_section_header_block_t shb;
3014     pcapng_block_size_t block_size;
3015     struct pcapng_option_header option_hdr;
3016     wtap_block_t wdh_shb = NULL;
3017
3018     if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
3019         wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0);
3020     }
3021
3022     block_size.size = 0;
3023     bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + 4);
3024     if (wdh_shb) {
3025         pcapng_debug("pcapng_write_section_header_block: Have shb_hdr");
3026
3027         /* Compute block size */
3028         wtap_block_foreach_option(wdh_shb, compute_shb_option_size, &block_size);
3029
3030         if (block_size.size > 0) {
3031             /* End-of-options tag */
3032             block_size.size += 4;
3033         }
3034
3035         bh.block_total_length += block_size.size;
3036     }
3037
3038     pcapng_debug("pcapng_write_section_header_block: Total len %u", bh.block_total_length);
3039
3040     /* write block header */
3041     bh.block_type = BLOCK_TYPE_SHB;
3042
3043     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3044         return FALSE;
3045     wdh->bytes_dumped += sizeof bh;
3046
3047     /* write block fixed content */
3048     shb.magic = 0x1A2B3C4D;
3049     shb.version_major = 1;
3050     shb.version_minor = 0;
3051     if (wdh_shb) {
3052         wtapng_mandatory_section_t* section_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(wdh_shb);
3053         shb.section_length = section_data->section_length;
3054     } else {
3055         shb.section_length = -1;
3056     }
3057
3058     if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
3059         return FALSE;
3060     wdh->bytes_dumped += sizeof shb;
3061
3062     if (wdh_shb) {
3063         pcapng_write_block_t block_data;
3064
3065         if (block_size.size > 0) {
3066             /* Write options */
3067             block_data.wdh = wdh;
3068             block_data.err = err;
3069             block_data.success = TRUE;
3070             wtap_block_foreach_option(wdh_shb, write_wtap_shb_option, &block_data);
3071
3072             if (!block_data.success)
3073                 return FALSE;
3074
3075             /* Write end of options */
3076             option_hdr.type = OPT_EOFOPT;
3077             option_hdr.value_length = 0;
3078             if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3079                 return FALSE;
3080             wdh->bytes_dumped += 4;
3081         }
3082     }
3083
3084     /* write block footer */
3085     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3086                               sizeof bh.block_total_length, err))
3087         return FALSE;
3088     wdh->bytes_dumped += sizeof bh.block_total_length;
3089
3090     return TRUE;
3091 }
3092
3093 static gboolean
3094 pcapng_write_enhanced_packet_block(wtap_dumper *wdh, const wtap_rec *rec,
3095                                    const guint8 *pd, int *err)
3096 {
3097     const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
3098     pcapng_block_header_t bh;
3099     pcapng_enhanced_packet_block_t epb;
3100     guint64 ts;
3101     const guint32 zero_pad = 0;
3102     guint32 pad_len;
3103     guint32 phdr_len;
3104     gboolean have_options = FALSE;
3105     guint32 options_total_length = 0;
3106     struct option option_hdr;
3107     guint32 comment_len = 0, comment_pad_len = 0;
3108     wtap_block_t int_data;
3109     wtapng_if_descr_mandatory_t *int_data_mand;
3110
3111     /* Don't write anything we're not willing to read. */
3112     if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->encap)) {
3113         *err = WTAP_ERR_PACKET_TOO_LARGE;
3114         return FALSE;
3115     }
3116
3117     phdr_len = (guint32)pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
3118     if ((phdr_len + rec->rec_header.packet_header.caplen) % 4) {
3119         pad_len = 4 - ((phdr_len + rec->rec_header.packet_header.caplen) % 4);
3120     } else {
3121         pad_len = 0;
3122     }
3123
3124     /* Check if we should write comment option */
3125     if (rec->opt_comment) {
3126         have_options = TRUE;
3127         comment_len = (guint32)strlen(rec->opt_comment) & 0xffff;
3128         if ((comment_len % 4)) {
3129             comment_pad_len = 4 - (comment_len % 4);
3130         } else {
3131             comment_pad_len = 0;
3132         }
3133         options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3134     }
3135     if (rec->presence_flags & WTAP_HAS_PACK_FLAGS) {
3136         have_options = TRUE;
3137         options_total_length = options_total_length + 8;
3138     }
3139     if (have_options) {
3140         /* End-of options tag */
3141         options_total_length += 4;
3142     }
3143
3144     /* write (enhanced) packet block header */
3145     bh.block_type = BLOCK_TYPE_EPB;
3146     bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + options_total_length + 4;
3147
3148     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3149         return FALSE;
3150     wdh->bytes_dumped += sizeof bh;
3151
3152     /* write block fixed content */
3153     if (rec->presence_flags & WTAP_HAS_INTERFACE_ID)
3154         epb.interface_id        = rec->rec_header.packet_header.interface_id;
3155     else {
3156         /*
3157          * XXX - we should support writing WTAP_ENCAP_PER_PACKET
3158          * data to pcapng files even if we *don't* have interface
3159          * IDs.
3160          */
3161         epb.interface_id        = 0;
3162     }
3163     /*
3164      * Split the 64-bit timestamp into two 32-bit pieces, using
3165      * the time stamp resolution for the interface.
3166      */
3167     if (epb.interface_id >= wdh->interface_data->len) {
3168         /*
3169          * Our caller is doing something bad.
3170          */
3171         *err = WTAP_ERR_INTERNAL;
3172         return FALSE;
3173     }
3174     int_data = g_array_index(wdh->interface_data, wtap_block_t,
3175                              epb.interface_id);
3176     int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
3177     ts = ((guint64)rec->ts.secs) * int_data_mand->time_units_per_second +
3178         (((guint64)rec->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
3179     epb.timestamp_high      = (guint32)(ts >> 32);
3180     epb.timestamp_low       = (guint32)ts;
3181     epb.captured_len        = rec->rec_header.packet_header.caplen + phdr_len;
3182     epb.packet_len          = rec->rec_header.packet_header.len + phdr_len;
3183
3184     if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
3185         return FALSE;
3186     wdh->bytes_dumped += sizeof epb;
3187
3188     /* write pseudo header */
3189     if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
3190         return FALSE;
3191     }
3192     wdh->bytes_dumped += phdr_len;
3193
3194     /* write packet data */
3195     if (!wtap_dump_file_write(wdh, pd, rec->rec_header.packet_header.caplen, err))
3196         return FALSE;
3197     wdh->bytes_dumped += rec->rec_header.packet_header.caplen;
3198
3199     /* write padding (if any) */
3200     if (pad_len != 0) {
3201         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3202             return FALSE;
3203         wdh->bytes_dumped += pad_len;
3204     }
3205
3206     /* XXX - write (optional) block options */
3207     /* options defined in Section 2.5 (Options)
3208      * Name           Code Length     Description
3209      * opt_comment    1    variable   A UTF-8 string containing a comment that is associated to the current block.
3210      *
3211      * Enhanced Packet Block options
3212      * epb_flags      2    4          A flags word containing link-layer information. A complete specification of
3213      *                                the allowed flags can be found in Appendix A (Packet Block Flags Word).
3214      * epb_hash       3    variable   This option contains a hash of the packet. The first byte specifies the hashing algorithm,
3215      *                                while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
3216      *                                                                and hence from the value in the first bit. The hashing algorithm can be: 2s complement
3217      *                                                                (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
3218      *                                                                MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
3219      *                                                                The hash covers only the packet, not the header added by the capture driver:
3220      *                                                                this gives the possibility to calculate it inside the network card.
3221      *                                                                The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
3222      *                                                                data acquisition system and the capture library.
3223      * epb_dropcount   4   8          A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
3224      *                                between this packet and the preceding one.
3225      * opt_endofopt    0   0          It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
3226      */
3227     if (rec->opt_comment) {
3228         option_hdr.type         = OPT_COMMENT;
3229         option_hdr.value_length = comment_len;
3230         if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3231             return FALSE;
3232         wdh->bytes_dumped += 4;
3233
3234         /* Write the comments string */
3235         pcapng_debug("pcapng_write_enhanced_packet_block, comment:'%s' comment_len %u comment_pad_len %u" , rec->opt_comment, comment_len, comment_pad_len);
3236         if (!wtap_dump_file_write(wdh, rec->opt_comment, comment_len, err))
3237             return FALSE;
3238         wdh->bytes_dumped += comment_len;
3239
3240         /* write padding (if any) */
3241         if (comment_pad_len != 0) {
3242             if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
3243                 return FALSE;
3244             wdh->bytes_dumped += comment_pad_len;
3245         }
3246
3247         pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
3248                       comment_len,
3249                       comment_pad_len);
3250     }
3251     if (rec->presence_flags & WTAP_HAS_PACK_FLAGS) {
3252         option_hdr.type         = OPT_EPB_FLAGS;
3253         option_hdr.value_length = 4;
3254         if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3255             return FALSE;
3256         wdh->bytes_dumped += 4;
3257         if (!wtap_dump_file_write(wdh, &rec->rec_header.packet_header.pack_flags, 4, err))
3258             return FALSE;
3259         wdh->bytes_dumped += 4;
3260         pcapng_debug("pcapng_write_enhanced_packet_block: Wrote Options packet flags: %x", rec->rec_header.packet_header.pack_flags);
3261     }
3262     /* Write end of options if we have options */
3263     if (have_options) {
3264         if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
3265             return FALSE;
3266         wdh->bytes_dumped += 4;
3267     }
3268
3269     /* write block footer */
3270     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3271                               sizeof bh.block_total_length, err))
3272         return FALSE;
3273     wdh->bytes_dumped += sizeof bh.block_total_length;
3274
3275     return TRUE;
3276 }
3277
3278 static gboolean
3279 pcapng_write_sysdig_event_block(wtap_dumper *wdh, const wtap_rec *rec,
3280                                 const guint8 *pd, int *err)
3281 {
3282     pcapng_block_header_t bh;
3283     const guint32 zero_pad = 0;
3284     guint32 pad_len;
3285 #if 0
3286     gboolean have_options = FALSE;
3287     struct option option_hdr;
3288     guint32 comment_len = 0, comment_pad_len = 0;
3289 #endif
3290     guint32 options_total_length = 0;
3291     guint16 cpu_id;
3292     guint64 hdr_ts;
3293     guint64 ts;
3294     guint64 thread_id;
3295     guint32 event_len;
3296     guint16 event_type;
3297
3298     /* Don't write anything we're not willing to read. */
3299     if (rec->rec_header.syscall_header.event_filelen > WTAP_MAX_PACKET_SIZE_STANDARD) {
3300         *err = WTAP_ERR_PACKET_TOO_LARGE;
3301         return FALSE;
3302     }
3303
3304     if (rec->rec_header.syscall_header.event_filelen % 4) {
3305         pad_len = 4 - (rec->rec_header.syscall_header.event_filelen % 4);
3306     } else {
3307         pad_len = 0;
3308     }
3309
3310 #if 0
3311     /* Check if we should write comment option */
3312     if (rec->opt_comment) {
3313         have_options = TRUE;
3314         comment_len = (guint32)strlen(rec->opt_comment) & 0xffff;
3315         if ((comment_len % 4)) {
3316             comment_pad_len = 4 - (comment_len % 4);
3317         } else {
3318             comment_pad_len = 0;
3319         }
3320         options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
3321     }
3322     if (have_options) {
3323         /* End-of options tag */
3324         options_total_length += 4;
3325     }
3326 #endif
3327
3328     /* write sysdig event block header */
3329     bh.block_type = BLOCK_TYPE_SYSDIG_EVENT;
3330     bh.block_total_length = (guint32)sizeof(bh) + SYSDIG_EVENT_HEADER_SIZE + rec->rec_header.syscall_header.event_filelen + pad_len + options_total_length + 4;
3331
3332     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3333         return FALSE;
3334     wdh->bytes_dumped += sizeof bh;
3335
3336     /* Sysdig is always LE? */
3337     cpu_id = GUINT16_TO_LE(rec->rec_header.syscall_header.cpu_id);
3338     hdr_ts = (((guint64)rec->ts.secs) * 1000000000) + rec->ts.nsecs;
3339     ts = GUINT64_TO_LE(hdr_ts);
3340     thread_id = GUINT64_TO_LE(rec->rec_header.syscall_header.thread_id);
3341     event_len = GUINT32_TO_LE(rec->rec_header.syscall_header.event_len);
3342     event_type = GUINT16_TO_LE(rec->rec_header.syscall_header.event_type);
3343
3344     if (!wtap_dump_file_write(wdh, &cpu_id, sizeof cpu_id, err))
3345         return FALSE;
3346     wdh->bytes_dumped += sizeof cpu_id;
3347
3348     if (!wtap_dump_file_write(wdh, &ts, sizeof ts, err))
3349         return FALSE;
3350     wdh->bytes_dumped += sizeof ts;
3351
3352     if (!wtap_dump_file_write(wdh, &thread_id, sizeof thread_id, err))
3353         return FALSE;
3354     wdh->bytes_dumped += sizeof thread_id;
3355
3356     if (!wtap_dump_file_write(wdh, &event_len, sizeof event_len, err))
3357         return FALSE;
3358     wdh->bytes_dumped += sizeof event_len;
3359
3360     if (!wtap_dump_file_write(wdh, &event_type, sizeof event_type, err))
3361         return FALSE;
3362     wdh->bytes_dumped += sizeof event_type;
3363
3364     /* write event data */
3365     if (!wtap_dump_file_write(wdh, pd, rec->rec_header.syscall_header.event_filelen, err))
3366         return FALSE;
3367     wdh->bytes_dumped += rec->rec_header.syscall_header.event_filelen;
3368
3369     /* write padding (if any) */
3370     if (pad_len != 0) {
3371         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3372             return FALSE;
3373         wdh->bytes_dumped += pad_len;
3374     }
3375
3376     /* XXX Write comment? */
3377
3378     /* write block footer */
3379     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3380                               sizeof bh.block_total_length, err))
3381         return FALSE;
3382
3383     return TRUE;
3384
3385 }
3386
3387 static gboolean
3388 pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
3389                                 const guint8 *pd, int *err)
3390 {
3391     pcapng_block_header_t bh;
3392     const guint32 zero_pad = 0;
3393     guint32 pad_len;
3394
3395     /* Don't write anything we're not willing to read. */
3396     if (rec->rec_header.ft_specific_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
3397         *err = WTAP_ERR_PACKET_TOO_LARGE;
3398         return FALSE;
3399     }
3400
3401     if (rec->rec_header.ft_specific_header.record_len % 4) {
3402         pad_len = 4 - (rec->rec_header.ft_specific_header.record_len % 4);
3403     } else {
3404         pad_len = 0;
3405     }
3406
3407     /* write systemd journal export block header */
3408     bh.block_type = BLOCK_TYPE_SYSTEMD_JOURNAL;
3409     bh.block_total_length = (guint32)sizeof(bh) + rec->rec_header.ft_specific_header.record_len + pad_len + 4;
3410
3411     pcapng_debug("%s: writing %u bytes, %u padded", G_STRFUNC,
3412                  rec->rec_header.ft_specific_header.record_len,
3413                  bh.block_total_length);
3414
3415     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3416         return FALSE;
3417     wdh->bytes_dumped += sizeof bh;
3418
3419     /* write entry data */
3420     if (!wtap_dump_file_write(wdh, pd, rec->rec_header.ft_specific_header.record_len, err))
3421         return FALSE;
3422     wdh->bytes_dumped += rec->rec_header.ft_specific_header.record_len;
3423
3424     /* write padding (if any) */
3425     if (pad_len != 0) {
3426         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
3427             return FALSE;
3428         wdh->bytes_dumped += pad_len;
3429     }
3430
3431     /* write block footer */
3432     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
3433                               sizeof bh.block_total_length, err))
3434         return FALSE;
3435
3436     return TRUE;
3437
3438 }
3439
3440 /*
3441  * libpcap's maximum pcapng block size is currently 16MB.
3442  *
3443  * The maximum pcapng block size in macOS's private pcapng reading code
3444  * is 1MB.  (Yes, this means that a program using the standard pcap
3445  * code to read pcapng files can handle bigger blocks than can programs
3446  * using the private code, such as Apple's tcpdump, can handle.)
3447  *
3448  * The pcapng reading code here can handle NRBs of arbitrary size (less
3449  * than 4GB, obviously), as they read each NRB record independently,
3450  * rather than reading the entire block into memory.
3451  *
3452  * So, for now, we set the maximum NRB block size we write as 1 MB.
3453  *
3454  * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
3455  */
3456
3457 #define NRES_BLOCK_MAX_SIZE (1024*1024)
3458
3459 static void
3460 compute_nrb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
3461 {
3462     pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
3463     guint32 size = 0;
3464
3465     switch(option_id)
3466     {
3467     case OPT_COMMENT:
3468     case OPT_NS_DNSNAME:
3469         size = pcapng_compute_option_string_size(optval->stringval);
3470         break;
3471     case OPT_NS_DNSIP4ADDR:
3472         size = 4;
3473         break;
3474     case OPT_NS_DNSIP6ADDR:
3475         size = 16;
3476         break;
3477     default:
3478         /* Unknown options - size by datatype? */
3479         break;
3480     }
3481
3482     block_size->size += size;
3483     /* Add bytes for option header if option should be written */
3484     if (size > 0) {
3485         /* Add optional padding to 32 bits */
3486         if ((block_size->size & 0x03) != 0)
3487         {
3488             block_size->size += 4 - (block_size->size & 0x03);
3489         }
3490         block_size->size += 4;
3491     }
3492 }
3493
3494 static void
3495 put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
3496 {
3497     guint8 **opt_ptrp = (guint8 **)user_data;
3498     guint32 size = 0;
3499     struct pcapng_option_header option_hdr;
3500     guint32 pad;
3501
3502     switch(option_id)
3503     {
3504     case OPT_COMMENT:
3505     case OPT_NS_DNSNAME:
3506         /* String options don't consider pad bytes part of the length */
3507         size = (guint32)strlen(optval->stringval) & 0xffff;
3508         option_hdr.type         = (guint16)option_id;
3509         option_hdr.value_length = (guint16)size;
3510         memcpy(*opt_ptrp, &option_hdr, 4);
3511         *opt_ptrp += 4;
3512
3513         memcpy(*opt_ptrp, optval->stringval, size);
3514         *opt_ptrp += size;
3515
3516         if ((size % 4)) {
3517             pad = 4 - (size % 4);
3518         } else {
3519             pad = 0;
3520         }
3521
3522         /* put padding (if any) */
3523         if (pad != 0) {
3524             memset(*opt_ptrp, 0, pad);
3525             *opt_ptrp += pad;
3526         }
3527         break;
3528     case OPT_NS_DNSIP4ADDR:
3529         option_hdr.type         = (guint16)option_id;
3530         option_hdr.value_length = 4;
3531         memcpy(*opt_ptrp, &option_hdr, 4);
3532         *opt_ptrp += 4;
3533
3534         memcpy(*opt_ptrp, &optval->ipv4val, 4);
3535         *opt_ptrp += 4;
3536         break;
3537     case OPT_NS_DNSIP6ADDR:
3538         option_hdr.type         = (guint16)option_id;
3539         option_hdr.value_length = 16;
3540         memcpy(*opt_ptrp, &option_hdr, 4);
3541         *opt_ptrp += 4;
3542
3543         memcpy(*opt_ptrp, &optval->ipv6val, 16);
3544         *opt_ptrp += 16;
3545         break;
3546     default:
3547         /* Unknown options - size by datatype? */
3548         break;
3549     }
3550 }
3551
3552 static void
3553 put_nrb_options(wtap_dumper *wdh, guint8 *opt_ptr)
3554 {
3555     if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
3556         wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
3557         struct option option_hdr;
3558
3559         wtap_block_foreach_option(nrb_hdr, put_nrb_option, &opt_ptr);
3560
3561         /* Put end of options */
3562         option_hdr.type = OPT_EOFOPT;
3563         option_hdr.value_length = 0;
3564         memcpy(opt_ptr, &option_hdr, 4);
3565     }
3566 }
3567
3568 static gboolean
3569 pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
3570 {
3571     pcapng_block_header_t bh;
3572     pcapng_name_resolution_block_t nrb;
3573     pcapng_block_size_t opts_size;
3574     size_t max_rec_data_size;
3575     guint8 *block_data;
3576     guint32 block_off;
3577     size_t hostnamelen;
3578     guint16 namelen;
3579     guint32 tot_rec_len;
3580     hashipv4_t *ipv4_hash_list_entry;
3581     hashipv6_t *ipv6_hash_list_entry;
3582     int i;
3583
3584     if (wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
3585         /*
3586          * No name/address pairs to write.
3587          * XXX - what if we have options?
3588          */
3589         return TRUE;
3590     }
3591
3592     /* Calculate the space needed for options. */
3593     opts_size.size = 0;
3594     if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
3595         wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
3596
3597         wtap_block_foreach_option(nrb_hdr, compute_nrb_option_size, &opts_size);
3598         if (opts_size.size > 0) {
3599             /* End-of options tag */
3600             opts_size.size += 4;
3601         }
3602     }
3603
3604     /*
3605      * Make sure we can fit at least one maximum-sized record, plus
3606      * an end-of-records record, plus the options, into a maximum-sized
3607      * block.
3608      *
3609      * That requires that there be enough space for the block header
3610      * (8 bytes), a maximum-sized record (2 bytes of record type, 2
3611      * bytes of record value length, 65535 bytes of record value,
3612      * and 1 byte of padding), an end-of-records record (4 bytes),
3613      * the options (opts_size.size bytes), and the block trailer (4
3614      * bytes).
3615      */
3616     if (8 + 2 + 2 + 65535 + 1 + 4 + opts_size.size + 4 > NRES_BLOCK_MAX_SIZE) {
3617         /*
3618          * XXX - we can't even fit the options in the largest NRB size
3619          * we're willing to write and still have room enough for a
3620          * maximum-sized record.  Just discard the information for now.
3621          */
3622         return TRUE;
3623     }
3624
3625     /*
3626      * Allocate a buffer for the largest block we'll write.
3627      */
3628     block_data = (guint8 *)g_malloc(NRES_BLOCK_MAX_SIZE);
3629
3630     /*
3631      * Calculate the maximum amount of record data we'll be able to
3632      * fit into such a block, after taking into account the block header
3633      * (8 bytes), the end-of-records record (4 bytes), the options
3634      * (opts_size.size bytes), and the block trailer (4 bytes).
3635      */
3636     max_rec_data_size = NRES_BLOCK_MAX_SIZE - (8 + 4 + opts_size.size + 4);
3637
3638     block_off = 8; /* block type + block total length */
3639     bh.block_type = BLOCK_TYPE_NRB;
3640     bh.block_total_length = 12; /* block header + block trailer */
3641
3642     /*
3643      * Write out the IPv4 resolved addresses, if any.
3644      */
3645     if (wdh->addrinfo_lists->ipv4_addr_list){
3646         i = 0;
3647         ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3648         while(ipv4_hash_list_entry != NULL){
3649
3650             nrb.record_type = NRES_IP4RECORD;
3651             hostnamelen = strlen(ipv4_hash_list_entry->name);
3652             if (hostnamelen > (G_MAXUINT16 - 4) - 1) {
3653                 /*
3654                  * This won't fit in the largest possible NRB record;
3655                  * discard it.
3656                  */
3657                 i++;
3658                 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3659                 continue;
3660             }
3661             namelen = (guint16)(hostnamelen + 1);
3662             nrb.record_len = 4 + namelen;  /* 4 bytes IPv4 address length */
3663             /* 2 bytes record type, 2 bytes length field */
3664             tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3665
3666             if (block_off + tot_rec_len > max_rec_data_size) {
3667                 /*
3668                  * This record would overflow our maximum size for Name
3669                  * Resolution Blocks; write out all the records we created
3670                  * before it, and start a new NRB.
3671                  */
3672
3673                 /* Append the end-of-records record */
3674                 memset(block_data + block_off, 0, 4);
3675                 block_off += 4;
3676                 bh.block_total_length += 4;
3677
3678                 /*
3679                  * Put the options into the block.
3680                  *
3681                  * XXX - this puts the same options in all NRBs.
3682                  */
3683                 put_nrb_options(wdh, block_data + block_off);
3684                 block_off += opts_size.size;
3685                 bh.block_total_length += opts_size.size;
3686
3687                 /* Copy the block header. */
3688                 memcpy(block_data, &bh, sizeof(bh));
3689
3690                 /* Copy the block trailer. */
3691                 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3692
3693                 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3694
3695                 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3696                     g_free(block_data);
3697                     return FALSE;
3698                 }
3699                 wdh->bytes_dumped += bh.block_total_length;
3700
3701                 /*Start a new NRB */
3702                 block_off = 8; /* block type + block total length */
3703                 bh.block_type = BLOCK_TYPE_NRB;
3704                 bh.block_total_length = 12; /* block header + block trailer */
3705             }
3706
3707             bh.block_total_length += tot_rec_len;
3708             memcpy(block_data + block_off, &nrb, sizeof(nrb));
3709             block_off += 4;
3710             memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
3711             block_off += 4;
3712             memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
3713             block_off += namelen;
3714             memset(block_data + block_off, 0, PADDING4(namelen));
3715             block_off += PADDING4(namelen);
3716             pcapng_debug("NRB: added IPv4 record for %s", ipv4_hash_list_entry->name);
3717
3718             i++;
3719             ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
3720         }
3721         g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
3722         wdh->addrinfo_lists->ipv4_addr_list = NULL;
3723     }
3724
3725     if (wdh->addrinfo_lists->ipv6_addr_list){
3726         i = 0;
3727         ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3728         while(ipv6_hash_list_entry != NULL){
3729
3730             nrb.record_type = NRES_IP6RECORD;
3731             hostnamelen = strlen(ipv6_hash_list_entry->name);
3732             if (hostnamelen > (G_MAXUINT16 - 16) - 1) {
3733                 /*
3734                  * This won't fit in the largest possible NRB record;
3735                  * discard it.
3736                  */
3737                 i++;
3738                 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3739                 continue;
3740             }
3741             namelen = (guint16)(hostnamelen + 1);
3742             nrb.record_len = 16 + namelen;  /* 16 bytes IPv6 address length */
3743             /* 2 bytes record type, 2 bytes length field */
3744             tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
3745
3746             if (block_off + tot_rec_len > max_rec_data_size) {
3747                 /*
3748                  * This record would overflow our maximum size for Name
3749                  * Resolution Blocks; write out all the records we created
3750                  * before it, and start a new NRB.
3751                  */
3752
3753                 /* Append the end-of-records record */
3754                 memset(block_data + block_off, 0, 4);
3755                 block_off += 4;
3756                 bh.block_total_length += 4;
3757
3758                 /*
3759                  * Put the options into the block.
3760                  *
3761                  * XXX - this puts the same options in all NRBs.
3762                  */
3763                 put_nrb_options(wdh, block_data + block_off);
3764                 block_off += opts_size.size;
3765                 bh.block_total_length += opts_size.size;
3766
3767                 /* Copy the block header. */
3768                 memcpy(block_data, &bh, sizeof(bh));
3769
3770                 /* Copy the block trailer. */
3771                 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3772
3773                 pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3774
3775                 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3776                     g_free(block_data);
3777                     return FALSE;
3778                 }
3779                 wdh->bytes_dumped += bh.block_total_length;
3780
3781                 /*Start a new NRB */
3782                 block_off = 8; /* block type + block total length */
3783                 bh.block_type = BLOCK_TYPE_NRB;
3784                 bh.block_total_length = 12; /* block header + block trailer */
3785             }
3786
3787             bh.block_total_length += tot_rec_len;
3788             memcpy(block_data + block_off, &nrb, sizeof(nrb));
3789             block_off += 4;
3790             memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
3791             block_off += 16;
3792             memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
3793             block_off += namelen;
3794             memset(block_data + block_off, 0, PADDING4(namelen));
3795             block_off += PADDING4(namelen);
3796             pcapng_debug("NRB: added IPv6 record for %s", ipv6_hash_list_entry->name);
3797
3798             i++;
3799             ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
3800         }
3801         g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
3802         wdh->addrinfo_lists->ipv6_addr_list = NULL;
3803     }
3804
3805     /* Append the end-of-records record */
3806     memset(block_data + block_off, 0, 4);
3807     block_off += 4;
3808     bh.block_total_length += 4;
3809
3810     /*
3811      * Put the options into the block.
3812      */
3813     put_nrb_options(wdh, block_data + block_off);
3814     block_off += opts_size.size;
3815     bh.block_total_length += opts_size.size;
3816
3817     /* Copy the block header. */
3818     memcpy(block_data, &bh, sizeof(bh));
3819
3820     /* Copy the block trailer. */
3821     memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
3822
3823     pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off);
3824
3825     if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
3826         g_free(block_data);
3827         return FALSE;
3828     }
3829     wdh->bytes_dumped += bh.block_total_length;
3830
3831     g_free(block_data);
3832
3833     return TRUE;
3834 }
3835
3836 static void compute_isb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
3837 {
3838     pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
3839     guint32 size = 0;
3840
3841     switch(option_id)
3842     {
3843     case OPT_COMMENT:
3844         size = pcapng_compute_option_string_size(optval->stringval);
3845         break;
3846     case OPT_ISB_STARTTIME:
3847     case OPT_ISB_ENDTIME:
3848         size = 8;
3849         break;
3850     case OPT_ISB_IFRECV:
3851     case OPT_ISB_IFDROP:
3852     case OPT_ISB_FILTERACCEPT:
3853     case OPT_ISB_OSDROP:
3854     case OPT_ISB_USRDELIV:
3855         size = 8;
3856         break;
3857     default:
3858         /* Unknown options - size by datatype? */
3859         break;
3860     }
3861
3862     block_size->size += size;
3863     /* Add bytes for option header if option should be written */
3864     if (size > 0) {
3865         /* Add optional padding to 32 bits */
3866         if ((block_size->size & 0x03) != 0)
3867         {
3868             block_size->size += 4 - (block_size->size & 0x03);
3869         }
3870         block_size->size += 4;
3871     }
3872 }
3873
3874 static void write_wtap_isb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
3875 {
3876     pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
3877     struct pcapng_option_header option_hdr;
3878
3879     /* Don't continue if there has been an error */
3880     if (!write_block->success)
3881         return;
3882
3883     switch(option_id)
3884     {
3885     case OPT_COMMENT:
3886         if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
3887             write_block->success = FALSE;
3888             return;
3889         }
3890         break;
3891     case OPT_ISB_STARTTIME:
3892     case OPT_ISB_ENDTIME:
3893         {
3894             guint32 high, low;
3895
3896             option_hdr.type         = option_id;
3897             option_hdr.value_length = 8;
3898             if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3899                 write_block->success = FALSE;
3900                 return;
3901             }
3902             write_block->wdh->bytes_dumped += 4;
3903
3904             high = (guint32)(optval->uint64val >> 32);
3905             low = (guint32)(optval->uint64val >> 0);
3906             if (!wtap_dump_file_write(write_block->wdh, &high, sizeof(guint32), write_block->err)) {
3907                 write_block->success = FALSE;
3908                 return;
3909             }
3910             write_block->wdh->bytes_dumped += 4;
3911             if (!wtap_dump_file_write(write_block->wdh, &low, sizeof(guint32), write_block->err)) {
3912                 write_block->success = FALSE;
3913                 return;
3914             }
3915             write_block->wdh->bytes_dumped += 4;
3916         }
3917         break;
3918     case OPT_ISB_IFRECV:
3919     case OPT_ISB_IFDROP:
3920     case OPT_ISB_FILTERACCEPT:
3921     case OPT_ISB_OSDROP:
3922     case OPT_ISB_USRDELIV:
3923         {
3924             option_hdr.type         = option_id;
3925             option_hdr.value_length = 8;
3926             if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
3927                 write_block->success = FALSE;
3928                 return;
3929             }
3930             write_block->wdh->bytes_dumped += 4;
3931
3932             if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) {
3933                 write_block->success = FALSE;
3934                 return;
3935             }
3936             write_block->wdh->bytes_dumped += 8;
3937         }
3938         break;
3939     default:
3940         /* Unknown options - write by datatype? */
3941         break;
3942     }
3943 }
3944
3945 static gboolean
3946 pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_block_t if_stats, int *err)
3947 {
3948     pcapng_block_header_t bh;
3949     pcapng_interface_statistics_block_t isb;
3950     pcapng_block_size_t block_size;
3951     pcapng_write_block_t block_data;
3952     struct pcapng_option_header option_hdr;
3953     wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3954
3955     pcapng_debug("pcapng_write_interface_statistics_block");
3956
3957     /* Compute block size */
3958     block_size.size = 0;
3959     wtap_block_foreach_option(if_stats, compute_isb_option_size, &block_size);
3960
3961     if (block_size.size > 0) {
3962         /* End-of-options tag */
3963         block_size.size += 4;
3964     }
3965
3966     /* write block header */
3967     bh.block_type = BLOCK_TYPE_ISB;
3968     bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + block_size.size + 4);
3969     pcapng_debug("pcapng_write_interface_statistics_block: Total len %u", bh.block_total_length);
3970
3971     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
3972         return FALSE;
3973     wdh->bytes_dumped += sizeof bh;
3974
3975     /* write block fixed content */
3976     isb.interface_id                = mand_data->interface_id;
3977     isb.timestamp_high              = mand_data->ts_high;
3978     isb.timestamp_low               = mand_data->ts_low;
3979
3980     if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
3981         return FALSE;
3982     wdh->bytes_dumped += sizeof isb;
3983
3984     /* Write options */
3985     if (block_size.size > 0) {
3986         block_data.wdh = wdh;
3987         block_data.err = err;
3988         block_data.success = TRUE;
3989         wtap_block_foreach_option(if_stats, write_wtap_isb_option, &block_data);
3990
3991         if (!block_data.success)
3992             return FALSE;
3993
3994         /* Write end of options */
3995         option_hdr.type = OPT_EOFOPT;
3996         option_hdr.value_length = 0;
3997         if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
3998             return FALSE;
3999         wdh->bytes_dumped += 4;
4000     }
4001
4002     /* write block footer */
4003     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
4004                               sizeof bh.block_total_length, err))
4005         return FALSE;
4006     wdh->bytes_dumped += sizeof bh.block_total_length;
4007     return TRUE;
4008 }
4009
4010 static void compute_idb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
4011 {
4012     pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data;
4013     guint32 size = 0;
4014
4015     switch(option_id)
4016     {
4017     case OPT_COMMENT:
4018     case OPT_IDB_NAME:
4019     case OPT_IDB_DESCR:
4020     case OPT_IDB_OS:
4021     case OPT_IDB_HARDWARE:
4022         size = pcapng_compute_option_string_size(optval->stringval);
4023         break;
4024     case OPT_IDB_SPEED:
4025         size = 8;
4026         break;
4027     case OPT_IDB_TSRESOL:
4028         size = 1;
4029         break;
4030     case OPT_IDB_FILTER:
4031         {
4032             wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data;
4033             guint32 pad;
4034             if (filter->if_filter_str != NULL) {
4035                 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
4036                 if ((size % 4)) {
4037                     pad = 4 - (size % 4);
4038                 } else {
4039                     pad = 0;
4040                 }
4041
4042                 size += pad;
4043             }
4044         }
4045         break;
4046     case OPT_IDB_FCSLEN:
4047         /* XXX - Not currently writing value */
4048         break;
4049     default:
4050         /* Unknown options - size by datatype? */
4051         break;
4052     }
4053
4054     block_size->size += size;
4055     /* Add bytes for option header if option should be written */
4056     if (size > 0) {
4057         /* Add optional padding to 32 bits */
4058         if ((block_size->size & 0x03) != 0)
4059         {
4060             block_size->size += 4 - (block_size->size & 0x03);
4061         }
4062         block_size->size += 4;
4063     }
4064 }
4065
4066 static void write_wtap_idb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
4067 {
4068     pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data;
4069     struct pcapng_option_header option_hdr;
4070     const guint32 zero_pad = 0;
4071
4072     switch(option_id)
4073     {
4074     case OPT_COMMENT:
4075     case OPT_IDB_NAME:
4076     case OPT_IDB_DESCR:
4077     case OPT_IDB_OS:
4078     case OPT_IDB_HARDWARE:
4079         if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) {
4080             write_block->success = FALSE;
4081             return;
4082         }
4083         break;
4084     case OPT_IDB_SPEED:
4085         option_hdr.type         = option_id;
4086         option_hdr.value_length = 8;
4087         if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
4088             write_block->success = FALSE;
4089             return;
4090         }
4091         write_block->wdh->bytes_dumped += 4;
4092
4093         if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) {
4094             write_block->success = FALSE;
4095             return;
4096         }
4097         write_block->wdh->bytes_dumped += 8;
4098         break;
4099     case OPT_IDB_TSRESOL:
4100         option_hdr.type         = option_id;
4101         option_hdr.value_length = 1;
4102         if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
4103             write_block->success = FALSE;
4104             return;
4105         }
4106         write_block->wdh->bytes_dumped += 4;
4107
4108         if (!wtap_dump_file_write(write_block->wdh, &optval->uint8val, 1, write_block->err)) {
4109             write_block->success = FALSE;
4110             return;
4111         }
4112         write_block->wdh->bytes_dumped += 1;
4113
4114         if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 3, write_block->err)) {
4115             write_block->success = FALSE;
4116             return;
4117         }
4118         write_block->wdh->bytes_dumped += 3;
4119         break;
4120     case OPT_IDB_FILTER:
4121         {
4122             wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data;
4123             guint32 size, pad;
4124             if (filter->if_filter_str != NULL) {
4125                 size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
4126                 if ((size % 4)) {
4127                     pad = 4 - (size % 4);
4128                 } else {
4129                     pad = 0;
4130                 }
4131
4132                 option_hdr.type         = option_id;
4133                 option_hdr.value_length = size;
4134                 if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
4135                     write_block->success = FALSE;
4136                     return;
4137                 }
4138                 write_block->wdh->bytes_dumped += 4;
4139
4140                 /* Write the zero indicating libpcap filter variant */
4141                 if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 1, write_block->err)) {
4142                     write_block->success = FALSE;
4143                     return;
4144                 }
4145                 write_block->wdh->bytes_dumped += 1;
4146
4147                 /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
4148                 if (!wtap_dump_file_write(write_block->wdh, filter->if_filter_str, size-1, write_block->err)) {
4149                     write_block->success = FALSE;
4150                     return;
4151                 }
4152                 write_block->wdh->bytes_dumped += size - 1;
4153
4154                 /* write padding (if any) */
4155                 if (pad != 0) {
4156                     if (!wtap_dump_file_write(write_block->wdh, &zero_pad, pad, write_block->err)) {
4157                         write_block->success = FALSE;
4158                         return;
4159                     }
4160                     write_block->wdh->bytes_dumped += pad;
4161                 }
4162
4163             }
4164         }
4165         break;
4166     case OPT_IDB_FCSLEN:
4167         /* XXX - Not currently writing value */
4168         break;
4169     default:
4170         /* Unknown options - size by datatype? */
4171         break;
4172     }
4173 }
4174
4175 static gboolean
4176 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err)
4177 {
4178     pcapng_block_header_t bh;
4179     pcapng_interface_description_block_t idb;
4180     pcapng_block_size_t block_size;
4181     pcapng_write_block_t block_data;
4182     struct pcapng_option_header option_hdr;
4183     wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
4184     int link_type;
4185
4186     pcapng_debug("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
4187                   mand_data->wtap_encap,
4188                   wtap_encap_string(mand_data->wtap_encap),
4189                   mand_data->snap_len);
4190
4191     link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
4192     if (link_type == -1) {
4193         if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) {
4194             *err = WTAP_ERR_UNWRITABLE_ENCAP;
4195             return FALSE;
4196         }
4197     }
4198
4199     /* Compute block size */
4200     block_size.size = 0;
4201     wtap_block_foreach_option(int_data, compute_idb_option_size, &block_size);
4202
4203     if (block_size.size > 0) {
4204         /* End-of-options tag */
4205         block_size.size += 4;
4206     }
4207
4208     /* write block header */
4209     bh.block_type = BLOCK_TYPE_IDB;
4210     bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + block_size.size + 4);
4211     pcapng_debug("pcapng_write_if_descr_block: Total len %u", bh.block_total_length);
4212
4213     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
4214         return FALSE;
4215     wdh->bytes_dumped += sizeof bh;
4216
4217     /* write block fixed content */
4218     idb.linktype    = link_type;
4219     idb.reserved    = 0;
4220     idb.snaplen     = mand_data->snap_len;
4221
4222     if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
4223         return FALSE;
4224     wdh->bytes_dumped += sizeof idb;
4225
4226     if (block_size.size > 0) {
4227         /* Write options */
4228         block_data.wdh = wdh;
4229         block_data.err = err;
4230         block_data.success = TRUE;
4231         wtap_block_foreach_option(int_data, write_wtap_idb_option, &block_data);
4232
4233         if (!block_data.success)
4234             return FALSE;
4235
4236         /* Write end of options */
4237         option_hdr.type = OPT_EOFOPT;
4238         option_hdr.value_length = 0;
4239         if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4240             return FALSE;
4241         wdh->bytes_dumped += 4;
4242     }
4243
4244     /* write block footer */
4245     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
4246                               sizeof bh.block_total_length, err))
4247         return FALSE;
4248
4249     wdh->bytes_dumped += sizeof bh.block_total_length;
4250     return TRUE;
4251 }
4252
4253 static gboolean pcapng_dump(wtap_dumper *wdh,
4254                             const wtap_rec *rec,
4255                             const guint8 *pd, int *err, gchar **err_info _U_)
4256 {
4257 #ifdef HAVE_PLUGINS
4258     block_handler *handler;
4259 #endif
4260
4261     pcapng_debug("%s: encap = %d (%s) rec type = %u", G_STRFUNC,
4262                   rec->rec_header.packet_header.pkt_encap,
4263                   wtap_encap_string(rec->rec_header.packet_header.pkt_encap),
4264                   rec->rec_type);
4265
4266     switch (rec->rec_type) {
4267
4268         case REC_TYPE_PACKET:
4269             /*
4270              * XXX - write a Simple Packet Block if there's no time
4271              * stamp or other information that doesn't appear in an
4272              * SPB?
4273              */
4274             if (!pcapng_write_enhanced_packet_block(wdh, rec, pd, err)) {
4275                 return FALSE;
4276             }
4277             break;
4278
4279         case REC_TYPE_FT_SPECIFIC_EVENT:
4280         case REC_TYPE_FT_SPECIFIC_REPORT:
4281             if (rec->rec_header.ft_specific_header.record_type == WTAP_FILE_TYPE_SUBTYPE_SYSTEMD_JOURNAL) {
4282                 if (!pcapng_write_systemd_journal_export_block(wdh, rec, pd, err)) {
4283                     return FALSE;
4284                 }
4285                 return TRUE;
4286             }
4287 #ifdef HAVE_PLUGINS
4288             /*
4289              * Do we have a handler for this block type?
4290              */
4291             if (block_handlers != NULL &&
4292                 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
4293                                                                 GUINT_TO_POINTER(rec->rec_header.ft_specific_header.record_type))) != NULL) {
4294                 /* Yes. Call it to write out this record. */
4295                 if (!handler->writer(wdh, rec, pd, err))
4296                     return FALSE;
4297             } else
4298 #endif
4299             {
4300                 /* No. */
4301                 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
4302                 return FALSE;
4303             }
4304             break;
4305
4306         case REC_TYPE_SYSCALL:
4307             if (!pcapng_write_sysdig_event_block(wdh, rec, pd, err)) {
4308                 return FALSE;
4309             }
4310             break;
4311
4312         default:
4313             /* We don't support writing this record type. */
4314             *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
4315             return FALSE;
4316     }
4317
4318     return TRUE;
4319 }
4320
4321
4322 /* Finish writing to a dump file.
4323    Returns TRUE on success, FALSE on failure. */
4324 static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err)
4325 {
4326     guint i, j;
4327
4328     /* Flush any hostname resolution info we may have */
4329     pcapng_write_name_resolution_block(wdh, err);
4330
4331     for (i = 0; i < wdh->interface_data->len; i++) {
4332
4333         /* Get the interface description */
4334         wtap_block_t int_data;
4335         wtapng_if_descr_mandatory_t *int_data_mand;
4336
4337         int_data = g_array_index(wdh->interface_data, wtap_block_t, i);
4338         int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
4339
4340         for (j = 0; j < int_data_mand->num_stat_entries; j++) {
4341             wtap_block_t if_stats;
4342
4343             if_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j);
4344             pcapng_debug("pcapng_dump_finish: write ISB for interface %u", ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id);
4345             if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
4346                 return FALSE;
4347             }
4348         }
4349     }
4350
4351     pcapng_debug("pcapng_dump_finish");
4352     return TRUE;
4353 }
4354
4355
4356 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
4357    failure */
4358 gboolean
4359 pcapng_dump_open(wtap_dumper *wdh, int *err)
4360 {
4361     guint i;
4362
4363     pcapng_debug("pcapng_dump_open");
4364     /* This is a pcapng file */
4365     wdh->subtype_write = pcapng_dump;
4366     wdh->subtype_finish = pcapng_dump_finish;
4367
4368     // XXX IDBs should be optional.
4369     if (wdh->interface_data->len == 0) {
4370         pcapng_debug("There are no interfaces. Can't handle that...");
4371         *err = WTAP_ERR_INTERNAL;
4372         return FALSE;
4373     }
4374
4375     /* write the section header block */
4376     if (!pcapng_write_section_header_block(wdh, err)) {
4377         return FALSE;
4378     }
4379     pcapng_debug("pcapng_dump_open: wrote section header block.");
4380
4381     /* Write the Interface description blocks */
4382     pcapng_debug("pcapng_dump_open: Number of IDB:s to write (number of interfaces) %u",
4383                   wdh->interface_data->len);
4384
4385     for (i = 0; i < wdh->interface_data->len; i++) {
4386
4387         /* Get the interface description */
4388         wtap_block_t idb;
4389
4390         idb = g_array_index(wdh->interface_data, wtap_block_t, i);
4391
4392         if (!pcapng_write_if_descr_block(wdh, idb, err)) {
4393             return FALSE;
4394         }
4395
4396     }
4397
4398     return TRUE;
4399 }
4400
4401
4402 /* Returns 0 if we could write the specified encapsulation type,
4403    an error indication otherwise. */
4404 int pcapng_dump_can_write_encap(int wtap_encap)
4405 {
4406     pcapng_debug("pcapng_dump_can_write_encap: encap = %d (%s)",
4407                   wtap_encap,
4408                   wtap_encap_string(wtap_encap));
4409
4410     /* Per-packet encapsulation is supported. */
4411     if (wtap_encap == WTAP_ENCAP_PER_PACKET)
4412         return 0;
4413
4414     /* Is it a filetype-specific encapsulation that we support? */
4415     if (pcapng_encap_is_ft_specific(wtap_encap)) {
4416         return 0;
4417     }
4418
4419     /* Make sure we can figure out this DLT type */
4420     if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
4421         return WTAP_ERR_UNWRITABLE_ENCAP;
4422
4423     return 0;
4424 }
4425
4426 /*
4427  * Returns TRUE if the specified encapsulation type is filetype-specific
4428  * and one that we support.
4429  */
4430 gboolean pcapng_encap_is_ft_specific(int encap)
4431 {
4432     switch (encap) {
4433     case WTAP_ENCAP_SYSTEMD_JOURNAL:
4434         return TRUE;
4435     }
4436     return FALSE;
4437 }
4438
4439 /*
4440  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4441  *
4442  * Local variables:
4443  * c-basic-offset: 4
4444  * tab-width: 8
4445  * indent-tabs-mode: nil
4446  * End:
4447  *
4448  * vi: set shiftwidth=4 tabstop=8 expandtab:
4449  * :indentSize=4:tabSize=8:noTabs=true:
4450  */