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