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