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