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