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