The "file types" we have are actually combinations of types and
[metze/wireshark/wip.git] / wiretap / pcapng.c
1 /* pcapng.c
2  *
3  * $Id$
4  *
5  * Wiretap Library
6  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
7  *
8  * File format support for pcap-ng file format
9  * Copyright (c) 2007 by Ulf Lamping <ulf.lamping@web.de>
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 /* File format reference:
27  *   http://www.winpcap.org/ntar/draft/PCAP-DumpFileFormat.html
28  * Related Wiki page:
29  *   http://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 "buffer.h"
43 #include "libpcap.h"
44 #include "pcap-common.h"
45 #include "pcap-encap.h"
46 #include "pcapng.h"
47
48 #if 0
49 #define pcapng_debug0(str) g_warning(str)
50 #define pcapng_debug1(str,p1) g_warning(str,p1)
51 #define pcapng_debug2(str,p1,p2) g_warning(str,p1,p2)
52 #define pcapng_debug3(str,p1,p2,p3) g_warning(str,p1,p2,p3)
53 #else
54 #define pcapng_debug0(str)
55 #define pcapng_debug1(str,p1)
56 #define pcapng_debug2(str,p1,p2)
57 #define pcapng_debug3(str,p1,p2,p3)
58 #endif
59
60 static gboolean
61 pcapng_read(wtap *wth, int *err, gchar **err_info,
62     gint64 *data_offset);
63 static gboolean
64 pcapng_seek_read(wtap *wth, gint64 seek_off,
65     struct wtap_pkthdr *phdr, Buffer *buf, int length,
66     int *err, gchar **err_info);
67 static void
68 pcapng_close(wtap *wth);
69
70
71 /* pcapng: common block header for every block type */
72 typedef struct pcapng_block_header_s {
73         guint32 block_type;
74         guint32 block_total_length;
75         /* x bytes block_body */
76         /* guint32 block_total_length */
77 } pcapng_block_header_t;
78
79 /*
80  * Minimum block size = size of block header + size of block trailer.
81  */
82 #define MIN_BLOCK_SIZE  ((guint32)(sizeof(pcapng_block_header_t) + sizeof(guint32)))
83
84 /*
85  * In order to keep from trying to allocate large chunks of memory,
86  * which could either fail or, even if it succeeds, chew up so much
87  * address space or memory+backing store as not to leave room for
88  * anything else, we impose an upper limit on the size of blocks
89  * we're willing to handle.
90  *
91  * For now, we pick an arbitrary limit of 16MB (OK, fine, 16MiB, but
92  * don't try saying that on Wikipedia :-) :-) :-)).
93  */
94 #define MAX_BLOCK_SIZE  (16*1024*1024)
95
96 /* pcapng: section header block */
97 typedef struct pcapng_section_header_block_s {
98         /* pcapng_block_header_t */
99         guint32 magic;
100         guint16 version_major;
101         guint16 version_minor;
102         guint64 section_length; /* might be -1 for unknown */
103         /* ... Options ... */
104 } pcapng_section_header_block_t;
105
106 /*
107  * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
108  */
109 #define MIN_SHB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
110
111 /* pcapng: interface description block */
112 typedef struct pcapng_interface_description_block_s {
113         guint16 linktype;
114         guint16 reserved;
115         guint32 snaplen;
116         /* ... Options ... */
117 } pcapng_interface_description_block_t;
118
119 /*
120  * Minimum IDB size = minimum block size + size of fixed length portion of IDB.
121  */
122 #define MIN_IDB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_description_block_t)))
123
124 /* pcapng: packet block (obsolete) */
125 typedef struct pcapng_packet_block_s {
126         guint16 interface_id;
127         guint16 drops_count;
128         guint32 timestamp_high;
129         guint32 timestamp_low;
130         guint32 captured_len;
131         guint32 packet_len;
132         /* ... Packet Data ... */
133         /* ... Padding ... */
134         /* ... Options ... */
135 } pcapng_packet_block_t;
136
137 /*
138  * Minimum PB size = minimum block size + size of fixed length portion of PB.
139  */
140 #define MIN_PB_SIZE     ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
141
142 /* pcapng: enhanced packet block */
143 typedef struct pcapng_enhanced_packet_block_s {
144         guint32 interface_id;
145         guint32 timestamp_high;
146         guint32 timestamp_low;
147         guint32 captured_len;
148         guint32 packet_len;
149         /* ... Packet Data ... */
150         /* ... Padding ... */
151         /* ... Options ... */
152 } pcapng_enhanced_packet_block_t;
153
154 /*
155  * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
156  */
157 #define MIN_EPB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
158
159 /* pcapng: simple packet block */
160 typedef struct pcapng_simple_packet_block_s {
161         guint32 packet_len;
162         /* ... Packet Data ... */
163         /* ... Padding ... */
164 } pcapng_simple_packet_block_t;
165
166 /*
167  * Minimum SPB size = minimum block size + size of fixed length portion of SPB.
168  */
169 #define MIN_SPB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
170
171 /* pcapng: name resolution block */
172 typedef struct pcapng_name_resolution_block_s {
173         guint16 record_type;
174         guint16 record_len;
175         /* ... Record ... */
176 } pcapng_name_resolution_block_t;
177
178 /*
179  * Minimum NRB size = minimum block size + size of smallest NRB record
180  * (there must at least be an "end of records" record).
181  */
182 #define MIN_NRB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
183
184 /* pcapng: interface statistics block */
185 typedef struct pcapng_interface_statistics_block_s {
186         guint32 interface_id;
187         guint32 timestamp_high;
188         guint32 timestamp_low;
189         /* ... Options ... */
190 } pcapng_interface_statistics_block_t;
191
192 /*
193  * Minimum ISB size = minimum block size + size of fixed length portion of ISB.
194  */
195 #define MIN_ISB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
196
197 /* pcapng: common option header for every option type */
198 typedef struct pcapng_option_header_s {
199         guint16 option_code;
200         guint16 option_length;
201         /* ... x bytes Option Body ... */
202         /* ... Padding ... */
203 } pcapng_option_header_t;
204
205 struct option {
206         guint16 type;
207         guint16 value_length;
208 };
209
210 /* Block types */
211 #define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */
212 #define BLOCK_TYPE_PB  0x00000002 /* Packet Block (obsolete) */
213 #define BLOCK_TYPE_SPB 0x00000003 /* Simple Packet Block */
214 #define BLOCK_TYPE_NRB 0x00000004 /* Name Resolution Block */
215 #define BLOCK_TYPE_ISB 0x00000005 /* Interface Statistics Block */
216 #define BLOCK_TYPE_EPB 0x00000006 /* Enhanced Packet Block */
217 #define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */
218
219 /* Options */
220 #define OPT_EOFOPT        0
221 #define OPT_COMMENT       1
222 #define OPT_SHB_HARDWARE  2
223 #define OPT_SHB_OS        3
224 #define OPT_SHB_USERAPPL  4
225 #define OPT_EPB_FLAGS     2
226 #define OPT_EPB_HASH      3
227 #define OPT_EPB_DROPCOUNT 4
228
229 /* Capture section */
230 #if 0
231 /* Moved to wtap.h */
232 typedef struct wtapng_section_s {
233         /* mandatory */
234         guint64                         section_length;
235         /* options */
236         gchar                           *opt_comment;   /* NULL if not available */
237         gchar                           *shb_hardware;  /* NULL if not available */
238         gchar                           *shb_os;                /* NULL if not available */
239         gchar                           *shb_user_appl; /* NULL if not available */
240 } wtapng_section_t;
241 #endif
242
243 #if 0
244 /* Moved to wtap.h */
245
246 /* Interface Description
247  *
248  * Options:
249  * 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}" / ...
250  * if_description 3  A UTF-8 string containing the description of the device used to capture data. "Broadcom NetXtreme" / "First Ethernet Interface" / ...
251  * 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
252  * 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"
253  * if_MACaddr     6  Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
254  * if_EUIaddr     7  Interface Hardware EUI address (64 bits), if available. TODO: give a good example
255  * if_speed       8  Interface speed (in bps). 100000000 for 100Mbps
256  * 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
257  * if_tzone      10  Time zone for GMT support (TODO: specify better). TODO: give a good example
258  * 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"
259  * 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" / ...
260  * 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
261  * 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
262  */
263
264 typedef struct wtapng_if_descr_s {
265         /* mandatory */
266         guint16                         link_type;
267         guint                           encap;
268         guint32                         snap_len;
269         /* options */
270         gchar                           *opt_comment;   /* NULL if not available */
271         gchar                           *if_name;               /* NULL if not available, opt 2 A UTF-8 string containing the name of the device used to capture data. */
272         gchar                           *if_description;/* NULL if not available, opt 3 A UTF-8 string containing the description of the device used to capture data. */
273         /* XXX: if_IPv4addr opt 4  Interface network address and netmask.*/
274         /* XXX: if_IPv6addr opt 5  Interface network address and prefix length (stored in the last byte).*/
275         /* XXX: if_MACaddr  opt 6  Interface Hardware MAC address (48 bits).*/
276         /* XXX: if_EUIaddr  opt 7  Interface Hardware EUI address (64 bits)*/
277         guint64                         if_speed;       /* 0 if unknown, opt 8  Interface speed (in bps). 100000000 for 100Mbps */
278         guint8                          if_tsresol;     /* default is 6 for microsecond resolution, opt 9  Resolution of timestamps.
279                                                                          * 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
280                                                                          */
281         /* XXX: if_tzone      10  Time zone for GMT support (TODO: specify better). */
282         gchar                           *if_filter;     /* NULL if not available, opt 11  The filter (e.g. "capture only TCP traffic") used to capture traffic.
283                                                                          * 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).
284                                                                          */
285         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. */
286         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. */
287         /* XXX: guint64 if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
288 } wtapng_if_descr_t;
289 #endif
290
291 /* Packets */
292 typedef struct wtapng_packet_s {
293         /* mandatory */
294         guint32                         ts_high;        /* seconds since 1.1.1970 */
295         guint32                         ts_low;         /* fraction of seconds, depends on if_tsresol */
296         guint32                         cap_len;        /* data length in the file */
297         guint32                         packet_len;     /* data length on the wire */
298         guint32                         interface_id;   /* identifier of the interface. */
299         guint16                         drops_count;    /* drops count, only valid for packet block */
300                                                                                 /* 0xffff if information no available */
301         /* pack_hash */
302         /* XXX - put the packet data / pseudo_header here as well? */
303 } wtapng_packet_t;
304
305 /* Simple Packets */
306 typedef struct wtapng_simple_packet_s {
307         /* mandatory */
308         guint32                         cap_len;        /* data length in the file */
309         guint32                         packet_len;     /* data length on the wire */
310         guint32                         pseudo_header_len;
311         int                             wtap_encap;
312         /* XXX - put the packet data / pseudo_header here as well? */
313 } wtapng_simple_packet_t;
314
315 /* Name Resolution */
316 typedef struct wtapng_name_res_s {
317         /* options */
318         gchar                           *opt_comment;   /* NULL if not available */
319         /* XXX */
320 } wtapng_name_res_t;
321
322 #if 0
323 /* Interface Statistics moved to wtap.h*/
324 typedef struct wtapng_if_stats_s {
325         /* mandatory */
326         guint32                         interface_id;
327         guint32                         ts_high;
328         guint32                         ts_low;
329         /* options */
330         gchar                           *opt_comment;   /* NULL if not available */
331         guint64                         isb_starttime;
332         guint64                         isb_endtime;
333         guint64                         isb_ifrecv;
334         guint64                         isb_ifdrop;
335         guint64                         isb_filteraccept;
336         guint64                         isb_osdrop;
337         guint64                         isb_usrdeliv;
338 } wtapng_if_stats_t;
339 #endif
340
341 typedef struct wtapng_block_s {
342         guint32                                 type;           /* block_type as defined by pcapng */
343         union {
344                 wtapng_section_t        section;
345                 wtapng_if_descr_t       if_descr;
346                 wtapng_name_res_t       name_res;
347                 wtapng_if_stats_t       if_stats;
348         } data;
349
350         /*
351          * XXX - currently don't know how to handle these!
352          *
353          * For one thing, when we're reading a block, they must be
354          * writable, i.e. not const, so that we can read into them,
355          * but, when we're writing a block, they can be const, and,
356          * in fact, they sometimes point to const values.
357          */
358         struct wtap_pkthdr *packet_header;
359         Buffer *frame_buffer;
360         int *file_encap;
361 } wtapng_block_t;
362
363 /* Interface data in private struct */
364 typedef struct interface_data_s {
365         int wtap_encap;
366         guint32 snap_len;
367         guint64 time_units_per_second;
368 } interface_data_t;
369
370 typedef struct {
371         gboolean shb_read;                                              /**< Set when first SHB read, second read will fail */
372         gboolean byte_swapped;
373         guint16 version_major;
374         guint16 version_minor;
375         GArray *interface_data;
376         guint number_of_interfaces;
377         gint8 if_fcslen;
378         wtap_new_ipv4_callback_t add_new_ipv4;
379         wtap_new_ipv6_callback_t add_new_ipv6;
380 } pcapng_t;
381
382 static int
383 pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
384                    char *content, guint len, guint to_read,
385                    int *err, gchar **err_info)
386 {
387         int     bytes_read;
388         int     block_read;
389         guint64 file_offset64;
390
391         /* sanity check: don't run past the end of the block */
392         if (to_read < sizeof (*oh)) {
393                 *err = WTAP_ERR_BAD_FILE;
394                 *err_info = g_strdup("pcapng_read_option: option goes past the end of the block");
395                 return -1;
396         }
397
398         /* read option header */
399         errno = WTAP_ERR_CANT_READ;
400         bytes_read = file_read(oh, sizeof (*oh), fh);
401         if (bytes_read != sizeof (*oh)) {
402                 pcapng_debug0("pcapng_read_option: failed to read option");
403                 *err = file_error(fh, err_info);
404                 if (*err != 0)
405                         return -1;
406                 return 0;
407         }
408         block_read = sizeof (*oh);
409         if (pn->byte_swapped) {
410                 oh->option_code      = BSWAP16(oh->option_code);
411                 oh->option_length    = BSWAP16(oh->option_length);
412         }
413
414         /* sanity check: don't run past the end of the block */
415         if (to_read < sizeof (*oh) + oh->option_length) {
416                 *err = WTAP_ERR_BAD_FILE;
417                 *err_info = g_strdup("pcapng_read_option: option goes past the end of the block");
418                 return -1;
419         }
420
421         /* sanity check: option length */
422         if (oh->option_length > len) {
423                 pcapng_debug2("pcapng_read_option: option_length %u larger than buffer (%u)",
424                               oh->option_length, len);
425                 return 0;
426         }
427
428         /* read option content */
429         errno = WTAP_ERR_CANT_READ;
430         bytes_read = file_read(content, oh->option_length, fh);
431         if (bytes_read != oh->option_length) {
432                 pcapng_debug1("pcapng_read_option: failed to read content of option %u", oh->option_code);
433                 *err = file_error(fh, err_info);
434                 if (*err != 0)
435                         return -1;
436                 return 0;
437         }
438         block_read += oh->option_length;
439
440         /* jump over potential padding bytes at end of option */
441         if ( (oh->option_length % 4) != 0) {
442                 file_offset64 = file_seek(fh, 4 - (oh->option_length % 4), SEEK_CUR, err);
443                 if (file_offset64 <= 0) {
444                         if (*err != 0)
445                                 return -1;
446                         return 0;
447                 }
448                 block_read += 4 - (oh->option_length % 4);
449         }
450
451         return block_read;
452 }
453
454
455 static int
456 pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
457                                  pcapng_block_header_t *bh, pcapng_t *pn,
458                                  wtapng_block_t *wblock, int *err,
459                                  gchar **err_info)
460 {
461         int     bytes_read;
462         guint   block_read;
463         guint to_read, opt_cont_buf_len;
464         pcapng_section_header_block_t shb;
465         pcapng_option_header_t oh;
466         char *option_content = NULL; /* Allocate as large as the options block */
467
468         /*
469          * Is this block long enough to be an SHB?
470          */
471         if (bh->block_total_length < MIN_SHB_SIZE) {
472                 /*
473                  * No.
474                  */
475                 if (first_block)
476                         return 0;       /* probably not a pcap-ng file */
477                 *err = WTAP_ERR_BAD_FILE;
478                 *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",
479                               bh->block_total_length, MIN_SHB_SIZE);
480                 return -1;
481         }
482
483         /* read block content */
484         errno = WTAP_ERR_CANT_READ;
485         bytes_read = file_read(&shb, sizeof shb, fh);
486         if (bytes_read != sizeof shb) {
487                 *err = file_error(fh, err_info);
488                 if (*err == 0) {
489                         if (first_block) {
490                                 /*
491                                  * We're reading this as part of an open,
492                                  * and this block is too short to be
493                                  * an SHB, so the file is too short
494                                  * to be a pcap-ng file.
495                                  */
496                                 return 0;
497                         }
498
499                         /*
500                          * Otherwise, just report this as an error.
501                          */
502                         *err = WTAP_ERR_SHORT_READ;
503                 }
504                 return -1;
505         }
506         block_read = bytes_read;
507
508         /* is the magic number one we expect? */
509         switch (shb.magic) {
510             case(0x1A2B3C4D):
511                 /* this seems pcapng with correct byte order */
512                 pn->byte_swapped                = FALSE;
513                 pn->version_major               = shb.version_major;
514                 pn->version_minor               = shb.version_minor;
515
516                 pcapng_debug3("pcapng_read_section_header_block: SHB (little endian) V%u.%u, len %u",
517                                 pn->version_major, pn->version_minor, bh->block_total_length);
518                 break;
519             case(0x4D3C2B1A):
520                 /* this seems pcapng with swapped byte order */
521                 pn->byte_swapped                = TRUE;
522                 pn->version_major               = BSWAP16(shb.version_major);
523                 pn->version_minor               = BSWAP16(shb.version_minor);
524
525                 /* tweak the block length to meet current swapping that we know now */
526                 bh->block_total_length  = BSWAP32(bh->block_total_length);
527
528                 pcapng_debug3("pcapng_read_section_header_block: SHB (big endian) V%u.%u, len %u",
529                                 pn->version_major, pn->version_minor, bh->block_total_length);
530                 break;
531             default:
532                 /* Not a "pcapng" magic number we know about. */
533                 if (first_block) {
534                         /* Not a pcap-ng file. */
535                         return 0;
536                 }
537
538                 /* A bad block */
539                 *err = WTAP_ERR_BAD_FILE;
540                 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown byte-order magic number 0x%08x", shb.magic);
541                 return 0;
542         }
543
544         /* OK, at this point we assume it's a pcap-ng file.
545
546            Don't try to allocate memory for a huge number of options, as
547            that might fail and, even if it succeeds, it might not leave
548            any address space or memory+backing store for anything else.
549
550            We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
551            We check for this *after* checking the SHB for its byte
552            order magic number, so that non-pcap-ng files are less
553            likely to be treated as bad pcap-ng files. */
554         if (bh->block_total_length > MAX_BLOCK_SIZE) {
555                 *err = WTAP_ERR_BAD_FILE;
556                 *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
557                               bh->block_total_length, MAX_BLOCK_SIZE);
558                 return -1;
559         }
560
561         /* We currently only suport one SHB */
562         if (pn->shb_read == TRUE) {
563                 *err = WTAP_ERR_UNSUPPORTED;
564                 *err_info = g_strdup_printf("pcapng: multiple section header blocks not supported.");
565                 return 0;
566         }
567
568         /* we currently only understand SHB V1.0 */
569         if (pn->version_major != 1 || pn->version_minor > 0) {
570                 *err = WTAP_ERR_UNSUPPORTED;
571                 *err_info = g_strdup_printf("pcapng_read_section_header_block: unknown SHB version %u.%u",
572                               pn->version_major, pn->version_minor);
573                 return -1;
574         }
575
576
577         /* 64bit section_length (currently unused) */
578         if (pn->byte_swapped) {
579                 wblock->data.section.section_length = BSWAP64(shb.section_length);
580         } else {
581                 wblock->data.section.section_length = shb.section_length;
582         }
583
584         /* Option defaults */
585         wblock->data.section.opt_comment        = NULL;
586         wblock->data.section.shb_hardware       = NULL;
587         wblock->data.section.shb_os                     = NULL;
588         wblock->data.section.shb_user_appl      = NULL;
589
590         /* Options */
591         errno = WTAP_ERR_CANT_READ;
592         to_read = bh->block_total_length - MIN_SHB_SIZE;
593
594         /* Allocate enough memory to hold all options */
595         opt_cont_buf_len = to_read;
596         option_content = (char *)g_try_malloc(opt_cont_buf_len);
597         if (opt_cont_buf_len != 0 && option_content == NULL) {
598                 *err = ENOMEM;  /* we assume we're out of memory */
599                 return -1;
600         }
601         pcapng_debug1("pcapng_read_section_header_block: Options %u bytes", to_read);
602         while (to_read != 0) {
603                 /* read option */
604                 pcapng_debug1("pcapng_read_section_header_block: Options %u bytes remaining", to_read);
605                 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
606                 if (bytes_read <= 0) {
607                         pcapng_debug0("pcapng_read_section_header_block: failed to read option");
608                         return bytes_read;
609                 }
610                 block_read += bytes_read;
611                 to_read -= bytes_read;
612
613                 /* handle option content */
614                 switch (oh.option_code) {
615                     case(OPT_EOFOPT):
616                         if (to_read != 0) {
617                                 pcapng_debug1("pcapng_read_section_header_block: %u bytes after opt_endofopt", to_read);
618                         }
619                         /* padding should be ok here, just get out of this */
620                         to_read = 0;
621                         break;
622                     case(OPT_COMMENT):
623                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
624                                 wblock->data.section.opt_comment = g_strndup(option_content, oh.option_length);
625                                 pcapng_debug1("pcapng_read_section_header_block: opt_comment %s", wblock->data.section.opt_comment);
626                         } else {
627                                 pcapng_debug1("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
628                         }
629                         break;
630                     case(OPT_SHB_HARDWARE):
631                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
632                                 wblock->data.section.shb_hardware = g_strndup(option_content, oh.option_length);
633                                 pcapng_debug1("pcapng_read_section_header_block: shb_hardware %s", wblock->data.section.shb_hardware);
634                         } else {
635                                 pcapng_debug1("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
636                         }
637                         break;
638                     case(OPT_SHB_OS):
639                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
640                                 wblock->data.section.shb_os = g_strndup(option_content, oh.option_length);
641                                 pcapng_debug1("pcapng_read_section_header_block: shb_os %s", wblock->data.section.shb_os);
642                         } else {
643                                 pcapng_debug2("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
644                         }
645                         break;
646                     case(OPT_SHB_USERAPPL):
647                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
648                                 wblock->data.section.shb_user_appl = g_strndup(option_content, oh.option_length);
649                                 pcapng_debug1("pcapng_read_section_header_block: shb_user_appl %s", wblock->data.section.shb_user_appl);
650                         } else {
651                                 pcapng_debug1("pcapng_read_section_header_block: shb_user_appl length %u seems strange", oh.option_length);
652                         }
653                         break;
654                     default:
655                         pcapng_debug2("pcapng_read_section_header_block: unknown option %u - ignoring %u bytes",
656                                       oh.option_code, oh.option_length);
657                 }
658         }
659         g_free(option_content);
660
661         return block_read;
662 }
663
664
665 /* "Interface Description Block" */
666 static int
667 pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn,
668                            wtapng_block_t *wblock, int *err, gchar **err_info)
669 {
670         guint64 time_units_per_second = 1000000; /* default */
671         int     bytes_read;
672         guint   block_read;
673         guint to_read, opt_cont_buf_len;
674         pcapng_interface_description_block_t idb;
675         pcapng_option_header_t oh;
676         char *option_content = NULL; /* Allocate as large as the options block */
677
678         /*
679          * Is this block long enough to be an IDB?
680          */
681         if (bh->block_total_length < MIN_IDB_SIZE) {
682                 /*
683                  * No.
684                  */
685                 *err = WTAP_ERR_BAD_FILE;
686                 *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",
687                               bh->block_total_length, MIN_IDB_SIZE);
688                 return -1;
689         }
690
691         /* Don't try to allocate memory for a huge number of options, as
692            that might fail and, even if it succeeds, it might not leave
693            any address space or memory+backing store for anything else.
694
695            We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
696            We check for this *after* checking the SHB for its byte
697            order magic number, so that non-pcap-ng files are less
698            likely to be treated as bad pcap-ng files. */
699         if (bh->block_total_length > MAX_BLOCK_SIZE) {
700                 *err = WTAP_ERR_BAD_FILE;
701                 *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
702                               bh->block_total_length, MAX_BLOCK_SIZE);
703                 return -1;
704         }
705
706         /* read block content */
707         errno = WTAP_ERR_CANT_READ;
708         bytes_read = file_read(&idb, sizeof idb, fh);
709         if (bytes_read != sizeof idb) {
710                 pcapng_debug0("pcapng_read_if_descr_block: failed to read IDB");
711                 *err = file_error(fh, err_info);
712                 if (*err != 0)
713                         return -1;
714                 return 0;
715         }
716         block_read = bytes_read;
717
718         /* mandatory values */
719         if (pn->byte_swapped) {
720                 wblock->data.if_descr.link_type = BSWAP16(idb.linktype);
721                 wblock->data.if_descr.snap_len  = BSWAP32(idb.snaplen);
722         } else {
723                 wblock->data.if_descr.link_type = idb.linktype;
724                 wblock->data.if_descr.snap_len  = idb.snaplen;
725         }
726
727         wblock->data.if_descr.wtap_encap = wtap_pcap_encap_to_wtap_encap(wblock->data.if_descr.link_type);
728         wblock->data.if_descr.time_units_per_second = time_units_per_second;
729
730         pcapng_debug3("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
731                       wblock->data.if_descr.link_type,
732                       wtap_encap_string(wblock->data.if_descr.wtap_encap),
733                       wblock->data.if_descr.snap_len);
734
735         if (wblock->data.if_descr.snap_len > WTAP_MAX_PACKET_SIZE) {
736                 /* This is unrealistic, but text2pcap currently uses 102400.
737                  * We do not use this value, maybe we should check the
738                  * snap_len of the packets against it. For now, only warn.
739                  */
740                 pcapng_debug1("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
741                               wblock->data.if_descr.snap_len);
742                 /*wblock->data.if_descr.snap_len = WTAP_MAX_PACKET_SIZE;*/
743         }
744
745         /* Option defaults */
746         wblock->data.if_descr.opt_comment = NULL;
747         wblock->data.if_descr.if_name = NULL;
748         wblock->data.if_descr.if_description = NULL;
749         /* XXX: if_IPv4addr */
750         /* XXX: if_IPv6addr */
751         /* XXX: if_MACaddr */
752         /* XXX: if_EUIaddr */
753         wblock->data.if_descr.if_speed = 0;                     /* "unknown" */
754         wblock->data.if_descr.if_tsresol = 6;                   /* default is 6 for microsecond resolution */
755         wblock->data.if_descr.if_filter_str = NULL;
756         wblock->data.if_descr.bpf_filter_len = 0;
757         wblock->data.if_descr.if_filter_bpf_bytes = NULL;
758         wblock->data.if_descr.if_os = NULL;
759         wblock->data.if_descr.if_fcslen = -1;                   /* unknown or changes between packets */
760         /* XXX: guint64 if_tsoffset; */
761
762
763         /* Options */
764         errno = WTAP_ERR_CANT_READ;
765         to_read = bh->block_total_length - MIN_IDB_SIZE;
766
767         /* Allocate enough memory to hold all options */
768         opt_cont_buf_len = to_read;
769         option_content = (char *)g_try_malloc(opt_cont_buf_len);
770         if (opt_cont_buf_len != 0 && option_content == NULL) {
771                 *err = ENOMEM;  /* we assume we're out of memory */
772                 return -1;
773         }
774
775         while (to_read != 0) {
776                 /* read option */
777                 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
778                 if (bytes_read <= 0) {
779                         pcapng_debug0("pcapng_read_if_descr_block: failed to read option");
780                         return bytes_read;
781                 }
782                 block_read += bytes_read;
783                 to_read -= bytes_read;
784
785                 /* handle option content */
786                 switch (oh.option_code) {
787                     case(0): /* opt_endofopt */
788                         if (to_read != 0) {
789                                 pcapng_debug1("pcapng_read_if_descr_block: %u bytes after opt_endofopt", to_read);
790                         }
791                         /* padding should be ok here, just get out of this */
792                         to_read = 0;
793                         break;
794                     case(1): /* opt_comment */
795                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
796                                 wblock->data.if_descr.opt_comment = g_strndup(option_content, oh.option_length);
797                                 pcapng_debug1("pcapng_read_if_descr_block: opt_comment %s", wblock->data.if_descr.opt_comment);
798                         } else {
799                                 pcapng_debug1("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
800                         }
801                         break;
802                     case(2): /* if_name */
803                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
804                                 wblock->data.if_descr.if_name = g_strndup(option_content, oh.option_length);
805                                 pcapng_debug1("pcapng_read_if_descr_block: if_name %s", wblock->data.if_descr.if_name);
806                         } else {
807                                 pcapng_debug1("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
808                         }
809                         break;
810                     case(3): /* if_description */
811                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
812                             wblock->data.if_descr.if_description = g_strndup(option_content, oh.option_length);
813                                 pcapng_debug1("pcapng_read_if_descr_block: if_description %s", wblock->data.if_descr.if_description);
814                         } else {
815                                 pcapng_debug1("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
816                         }
817                         break;
818                         /*
819                          * 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
820                          * 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"
821                          * if_MACaddr     6  Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
822                          * if_EUIaddr     7  Interface Hardware EUI address (64 bits), if available. TODO: give a good example
823                          */
824                     case(8): /* if_speed */
825                         if (oh.option_length == 8) {
826                                 /*  Don't cast a char[] into a guint64--the
827                                  *  char[] may not be aligned correctly.
828                                  */
829                                 memcpy(&wblock->data.if_descr.if_speed, option_content, sizeof(guint64));
830                                 if (pn->byte_swapped)
831                                         wblock->data.if_descr.if_speed = BSWAP64(wblock->data.if_descr.if_speed);
832                                 pcapng_debug1("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", wblock->data.if_descr.if_speed);
833                         } else {
834                                     pcapng_debug1("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
835                         }
836                         break;
837                     case(9): /* if_tsresol */
838                         if (oh.option_length == 1) {
839                                 guint64 base;
840                                 guint64 result;
841                                 guint8 i, exponent, if_tsresol;
842
843                                 if_tsresol = option_content[0];
844                                 if (if_tsresol & 0x80) {
845                                         base = 2;
846                                 } else {
847                                         base = 10;
848                                 }
849                                 exponent = (guint8)(if_tsresol & 0x7f);
850                                 if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
851                                         result = 1;
852                                         for (i = 0; i < exponent; i++) {
853                                                 result *= base;
854                                         }
855                                         time_units_per_second = result;
856                                 } else {
857                                         time_units_per_second = G_MAXUINT64;
858                                 }
859                                 if (time_units_per_second > (((guint64)1) << 32)) {
860                                         pcapng_debug0("pcapng_open: time conversion might be inaccurate");
861                                 }
862                                 wblock->data.if_descr.time_units_per_second = time_units_per_second;
863                                 wblock->data.if_descr.if_tsresol = if_tsresol;
864                                 pcapng_debug2("pcapng_read_if_descr_block: if_tsresol %u, units/s %" G_GINT64_MODIFIER "u", wblock->data.if_descr.if_tsresol, wblock->data.if_descr.time_units_per_second);
865                         } else {
866                                 pcapng_debug1("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
867                         }
868                         break;
869                         /*
870                          * if_tzone      10  Time zone for GMT support (TODO: specify better). TODO: give a good example
871                          */
872                     case(11): /* if_filter */
873                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
874                                 /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
875                                  * or BPF bytecode.
876                                  */
877                                 if (option_content[0] == 0) {
878                                         wblock->data.if_descr.if_filter_str = g_strndup(option_content+1, oh.option_length-1);
879                                         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);
880                                 } else if (option_content[0] == 1) {
881                                         wblock->data.if_descr.bpf_filter_len = oh.option_length-1;
882                                         wblock->data.if_descr.if_filter_bpf_bytes = (gchar *)g_malloc(oh.option_length-1);
883                                         memcpy(&wblock->data.if_descr.if_filter_bpf_bytes, option_content+1, oh.option_length-1);
884                                 }
885                         } else {
886                                 pcapng_debug1("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
887                         }
888                         break;
889                     case(12): /* if_os */
890                         /*
891                          * if_os         12  A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
892                          * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
893                          * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
894                          */
895                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
896                             wblock->data.if_descr.if_os = g_strndup(option_content, oh.option_length);
897                                 pcapng_debug1("pcapng_read_if_descr_block: if_os %s", wblock->data.if_descr.if_os);
898                         } else {
899                                 pcapng_debug1("pcapng_read_if_descr_block: if_os length %u seems strange", oh.option_length);
900                         }
901                         break;
902                     case(13): /* if_fcslen */
903                         if (oh.option_length == 1) {
904                                 wblock->data.if_descr.if_fcslen = option_content[0];
905                                 pn->if_fcslen = wblock->data.if_descr.if_fcslen;
906                                 pcapng_debug1("pcapng_read_if_descr_block: if_fcslen %u", wblock->data.if_descr.if_fcslen);
907                                 /* XXX - add sanity check */
908                         } else {
909                                 pcapng_debug1("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
910                         }
911                         break;
912                         /*
913                          * if_tsoffset   14  A 64 bits integer value that specifies an offset (in seconds) that must be added to the timestamp of each packet
914                          * to obtain the absolute timestamp of a packet. If the option is missing, the timestamps stored in the packet must be considered absolute timestamps.
915                          * The time zone of the offset can be specified with the option if_tzone.
916                          * TODO: won't a if_tsoffset_low for fractional second offsets be useful for highly synchronized capture systems? 1234
917                          */
918                     default:
919                         pcapng_debug2("pcapng_read_if_descr_block: unknown option %u - ignoring %u bytes",
920                                       oh.option_code, oh.option_length);
921                 }
922         }
923
924         g_free(option_content);
925
926         if (*wblock->file_encap == WTAP_ENCAP_UNKNOWN) {
927                 *wblock->file_encap = wblock->data.if_descr.wtap_encap;
928         } else {
929                 if (*wblock->file_encap != wblock->data.if_descr.wtap_encap) {
930                         *wblock->file_encap = WTAP_ENCAP_PER_PACKET;
931                 }
932         }
933
934         return block_read;
935 }
936
937
938 static int
939 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)
940 {
941         int bytes_read;
942         guint block_read;
943         guint to_read, opt_cont_buf_len;
944         guint64 file_offset64;
945         pcapng_enhanced_packet_block_t epb;
946         pcapng_packet_block_t pb;
947         wtapng_packet_t packet;
948         guint32 block_total_length;
949         guint32 padding;
950         interface_data_t int_data;
951         guint64 ts;
952         pcapng_option_header_t oh;
953         int pseudo_header_len;
954         char *option_content = NULL; /* Allocate as large as the options block */
955         int fcslen;
956
957         /* Don't try to allocate memory for a huge number of options, as
958            that might fail and, even if it succeeds, it might not leave
959            any address space or memory+backing store for anything else.
960
961            We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
962            We check for this *after* checking the SHB for its byte
963            order magic number, so that non-pcap-ng files are less
964            likely to be treated as bad pcap-ng files. */
965         if (bh->block_total_length > MAX_BLOCK_SIZE) {
966                 *err = WTAP_ERR_BAD_FILE;
967                 *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
968                               bh->block_total_length, MAX_BLOCK_SIZE);
969                 return -1;
970         }
971
972         /* "(Enhanced) Packet Block" read fixed part */
973         errno = WTAP_ERR_CANT_READ;
974         if (enhanced) {
975                 /*
976                  * Is this block long enough to be an EPB?
977                  */
978                 if (bh->block_total_length < MIN_EPB_SIZE) {
979                         /*
980                          * No.
981                          */
982                         *err = WTAP_ERR_BAD_FILE;
983                         *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
984                                       bh->block_total_length, MIN_EPB_SIZE);
985                         return -1;
986                 }
987                 bytes_read = file_read(&epb, sizeof epb, fh);
988                 if (bytes_read != sizeof epb) {
989                         pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
990                         *err = file_error(fh, err_info);
991                         return 0;
992                 }
993                 block_read = bytes_read;
994
995                 if (pn->byte_swapped) {
996                         packet.interface_id        = BSWAP32(epb.interface_id);
997                         packet.drops_count         = -1; /* invalid */
998                         packet.ts_high             = BSWAP32(epb.timestamp_high);
999                         packet.ts_low              = BSWAP32(epb.timestamp_low);
1000                         packet.cap_len             = BSWAP32(epb.captured_len);
1001                         packet.packet_len          = BSWAP32(epb.packet_len);
1002                 } else {
1003                         packet.interface_id        = epb.interface_id;
1004                         packet.drops_count         = -1; /* invalid */
1005                         packet.ts_high             = epb.timestamp_high;
1006                         packet.ts_low              = epb.timestamp_low;
1007                         packet.cap_len             = epb.captured_len;
1008                         packet.packet_len          = epb.packet_len;
1009                 }
1010                 pcapng_debug3("pcapng_read_packet_block: EPB on interface_id %d, cap_len %d, packet_len %d",
1011                               packet.interface_id, packet.cap_len, packet.packet_len);
1012         } else {
1013                 /*
1014                  * Is this block long enough to be a PB?
1015                  */
1016                 if (bh->block_total_length < MIN_PB_SIZE) {
1017                         /*
1018                          * No.
1019                          */
1020                         *err = WTAP_ERR_BAD_FILE;
1021                         *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
1022                                       bh->block_total_length, MIN_PB_SIZE);
1023                         return -1;
1024                 }
1025                 bytes_read = file_read(&pb, sizeof pb, fh);
1026                 if (bytes_read != sizeof pb) {
1027                         pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
1028                         *err = file_error(fh, err_info);
1029                         return 0;
1030                 }
1031                 block_read = bytes_read;
1032
1033                 if (pn->byte_swapped) {
1034                         packet.interface_id        = BSWAP16(pb.interface_id);
1035                         packet.drops_count         = BSWAP16(pb.drops_count);
1036                         packet.ts_high             = BSWAP32(pb.timestamp_high);
1037                         packet.ts_low              = BSWAP32(pb.timestamp_low);
1038                         packet.cap_len             = BSWAP32(pb.captured_len);
1039                         packet.packet_len          = BSWAP32(pb.packet_len);
1040                 } else {
1041                         packet.interface_id        = pb.interface_id;
1042                         packet.drops_count         = pb.drops_count;
1043                         packet.ts_high             = pb.timestamp_high;
1044                         packet.ts_low              = pb.timestamp_low;
1045                         packet.cap_len             = pb.captured_len;
1046                         packet.packet_len          = pb.packet_len;
1047                 }
1048                 pcapng_debug3("pcapng_read_packet_block: PB on interface_id %d, cap_len %d, packet_len %d",
1049                               packet.interface_id, packet.cap_len, packet.packet_len);
1050         }
1051
1052         /*
1053          * How much padding is there at the end of the packet data?
1054          */
1055         if ((packet.cap_len % 4) != 0)
1056                 padding = 4 - (packet.cap_len % 4);
1057         else
1058                 padding = 0;
1059
1060         /* add padding bytes to "block total length" */
1061         /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1062         if (bh->block_total_length % 4) {
1063                 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1064         } else {
1065                 block_total_length = bh->block_total_length;
1066         }
1067         pcapng_debug1("pcapng_read_packet_block: block_total_length %d", block_total_length);
1068
1069         /*
1070          * Is this block long enough to hold the packet data?
1071          */
1072         if (enhanced) {
1073                 if (block_total_length <
1074                     MIN_EPB_SIZE + packet.cap_len + padding) {
1075                         /*
1076                          * No.
1077                          */
1078                         *err = WTAP_ERR_BAD_FILE;
1079                         *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
1080                                       block_total_length, packet.cap_len);
1081                         return -1;
1082                 }
1083         } else {
1084                 if (block_total_length <
1085                     MIN_PB_SIZE + packet.cap_len + padding) {
1086                         /*
1087                          * No.
1088                          */
1089                         *err = WTAP_ERR_BAD_FILE;
1090                         *err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
1091                                       block_total_length, packet.cap_len);
1092                         return -1;
1093                 }
1094         }
1095
1096         if (packet.cap_len > packet.packet_len) {
1097                 *err = WTAP_ERR_BAD_FILE;
1098                 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than packet_len %u.",
1099                     packet.cap_len, packet.packet_len);
1100                 return 0;
1101         }
1102         if (packet.cap_len > WTAP_MAX_PACKET_SIZE) {
1103                 *err = WTAP_ERR_BAD_FILE;
1104                 *err_info = g_strdup_printf("pcapng_read_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u.",
1105                     packet.cap_len, WTAP_MAX_PACKET_SIZE);
1106                 return 0;
1107         }
1108         pcapng_debug3("pcapng_read_packet_block: packet data: packet_len %u captured_len %u interface_id %u",
1109                       packet.packet_len,
1110                       packet.cap_len,
1111                       packet.interface_id);
1112
1113         if (packet.interface_id >= pn->number_of_interfaces) {
1114                 *err = WTAP_ERR_BAD_FILE;
1115                 *err_info = g_strdup_printf("pcapng: interface index %u is not less than interface count %u.",
1116                     packet.interface_id, pn->number_of_interfaces);
1117                 return 0;
1118         }
1119         int_data = g_array_index(pn->interface_data, interface_data_t,
1120             packet.interface_id);
1121
1122         wblock->packet_header->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1123
1124         pcapng_debug3("pcapng_read_packet_block: encapsulation = %d (%s), pseudo header size = %d.",
1125                        int_data.wtap_encap,
1126                        wtap_encap_string(int_data.wtap_encap),
1127                        pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header));
1128         wblock->packet_header->interface_id = packet.interface_id;
1129         wblock->packet_header->pkt_encap = int_data.wtap_encap;
1130
1131         memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1132         pseudo_header_len = pcap_process_pseudo_header(fh,
1133                                                        WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1134                                                        int_data.wtap_encap,
1135                                                        packet.cap_len,
1136                                                        TRUE,
1137                                                        wblock->packet_header,
1138                                                        err,
1139                                                        err_info);
1140         if (pseudo_header_len < 0) {
1141                 return 0;
1142         }
1143         block_read += pseudo_header_len;
1144         if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header)) {
1145                 pcapng_debug1("pcapng_read_packet_block: Could only read %d bytes for pseudo header.",
1146                               pseudo_header_len);
1147         }
1148         wblock->packet_header->caplen = packet.cap_len - pseudo_header_len;
1149         wblock->packet_header->len = packet.packet_len - pseudo_header_len;
1150
1151         /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1152         ts = (((guint64)packet.ts_high) << 32) | ((guint64)packet.ts_low);
1153         wblock->packet_header->ts.secs = (time_t)(ts / int_data.time_units_per_second);
1154         wblock->packet_header->ts.nsecs = (int)(((ts % int_data.time_units_per_second) * 1000000000) / int_data.time_units_per_second);
1155
1156         /* "(Enhanced) Packet Block" read capture data */
1157         errno = WTAP_ERR_CANT_READ;
1158         if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1159             packet.cap_len - pseudo_header_len, err, err_info))
1160                 return 0;
1161         block_read += packet.cap_len - pseudo_header_len;
1162
1163         /* jump over potential padding bytes at end of the packet data */
1164         if (padding != 0) {
1165                 file_offset64 = file_seek(fh, padding, SEEK_CUR, err);
1166                 if (file_offset64 <= 0) {
1167                         if (*err != 0)
1168                                 return -1;
1169                         return 0;
1170                 }
1171                 block_read += padding;
1172         }
1173
1174         /* Option defaults */
1175         wblock->packet_header->opt_comment = NULL;
1176         wblock->packet_header->drop_count  = -1;
1177         wblock->packet_header->pack_flags  = 0;
1178
1179         /* FCS length default */
1180         fcslen = pn->if_fcslen;
1181
1182         /* Options
1183          * opt_comment    1
1184          * epb_flags      2
1185          * epb_hash       3
1186          * epb_dropcount  4
1187          */
1188         errno = WTAP_ERR_CANT_READ;
1189         to_read = block_total_length -
1190                   (int)sizeof(pcapng_block_header_t) -
1191                   block_read -    /* fixed and variable part, including padding */
1192                   (int)sizeof(bh->block_total_length);
1193
1194         /* Allocate enough memory to hold all options */
1195         opt_cont_buf_len = to_read;
1196         option_content = (char *)g_try_malloc(opt_cont_buf_len);
1197         if (opt_cont_buf_len != 0 && option_content == NULL) {
1198                 *err = ENOMEM;  /* we assume we're out of memory */
1199                 return -1;
1200         }
1201
1202         while (to_read != 0) {
1203                 /* read option */
1204                 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
1205                 if (bytes_read <= 0) {
1206                         pcapng_debug0("pcapng_read_packet_block: failed to read option");
1207                         return bytes_read;
1208                 }
1209                 block_read += bytes_read;
1210                 to_read -= bytes_read;
1211
1212                 /* handle option content */
1213                 switch (oh.option_code) {
1214                     case(OPT_EOFOPT):
1215                         if (to_read != 0) {
1216                                 pcapng_debug1("pcapng_read_packet_block: %u bytes after opt_endofopt", to_read);
1217                         }
1218                         /* padding should be ok here, just get out of this */
1219                         to_read = 0;
1220                         break;
1221                     case(OPT_COMMENT):
1222                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1223                                 wblock->packet_header->presence_flags |= WTAP_HAS_COMMENTS;
1224                                 wblock->packet_header->opt_comment = g_strndup(option_content, oh.option_length);
1225                                 pcapng_debug2("pcapng_read_packet_block: length %u opt_comment '%s'", oh.option_length, wblock->packet_header->opt_comment);
1226                         } else {
1227                                 pcapng_debug1("pcapng_read_packet_block: opt_comment length %u seems strange", oh.option_length);
1228                         }
1229                         break;
1230                     case(OPT_EPB_FLAGS):
1231                         if (oh.option_length == 4) {
1232                                 /*  Don't cast a char[] into a guint32--the
1233                                  *  char[] may not be aligned correctly.
1234                                  */
1235                                 wblock->packet_header->presence_flags |= WTAP_HAS_PACK_FLAGS;
1236                                 memcpy(&wblock->packet_header->pack_flags, option_content, sizeof(guint32));
1237                                 if (pn->byte_swapped)
1238                                         wblock->packet_header->pack_flags = BSWAP32(wblock->packet_header->pack_flags);
1239                                 if (wblock->packet_header->pack_flags & 0x000001E0) {
1240                                         /* The FCS length is present */
1241                                         fcslen = (wblock->packet_header->pack_flags & 0x000001E0) >> 5;
1242                                 }
1243                                 pcapng_debug1("pcapng_read_packet_block: pack_flags %u (ignored)", wblock->packet_header->pack_flags);
1244                         } else {
1245                                 pcapng_debug1("pcapng_read_packet_block: pack_flags length %u not 4 as expected", oh.option_length);
1246                         }
1247                         break;
1248                     case(OPT_EPB_HASH):
1249                         pcapng_debug2("pcapng_read_packet_block: epb_hash %u currently not handled - ignoring %u bytes",
1250                                       oh.option_code, oh.option_length);
1251                         break;
1252                     case(OPT_EPB_DROPCOUNT):
1253                         if (oh.option_length == 8) {
1254                                 /*  Don't cast a char[] into a guint32--the
1255                                  *  char[] may not be aligned correctly.
1256                                  */
1257                                 wblock->packet_header->presence_flags |= WTAP_HAS_DROP_COUNT;
1258                                 memcpy(&wblock->packet_header->drop_count, option_content, sizeof(guint64));
1259                                 if (pn->byte_swapped)
1260                                         wblock->packet_header->drop_count = BSWAP64(wblock->packet_header->drop_count);
1261
1262                                 pcapng_debug1("pcapng_read_packet_block: drop_count %" G_GINT64_MODIFIER "u", wblock->packet_header->drop_count);
1263                         } else {
1264                                 pcapng_debug1("pcapng_read_packet_block: drop_count length %u not 8 as expected", oh.option_length);
1265                         }
1266                         break;
1267                     default:
1268                         pcapng_debug2("pcapng_read_packet_block: unknown option %u - ignoring %u bytes",
1269                                       oh.option_code, oh.option_length);
1270                 }
1271         }
1272
1273         g_free(option_content);
1274
1275         pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, int_data.wtap_encap,
1276             (union wtap_pseudo_header *)&wblock->packet_header->pseudo_header,
1277             buffer_start_ptr(wblock->frame_buffer),
1278             (int) (packet.cap_len - pseudo_header_len),
1279             pn->byte_swapped, fcslen);
1280         return block_read;
1281 }
1282
1283
1284 static int
1285 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)
1286 {
1287         int bytes_read;
1288         guint block_read;
1289         guint64 file_offset64;
1290         interface_data_t int_data;
1291         pcapng_simple_packet_block_t spb;
1292         wtapng_simple_packet_t simple_packet;
1293         guint32 block_total_length;
1294         guint32 padding;
1295         int pseudo_header_len;
1296
1297         /*
1298          * Is this block long enough to be an SPB?
1299          */
1300         if (bh->block_total_length < MIN_SPB_SIZE) {
1301                 /*
1302                  * No.
1303                  */
1304                 *err = WTAP_ERR_BAD_FILE;
1305                 *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",
1306                               bh->block_total_length, MIN_SPB_SIZE);
1307                 return -1;
1308         }
1309
1310         /* Don't try to allocate memory for a huge number of options, as
1311            that might fail and, even if it succeeds, it might not leave
1312            any address space or memory+backing store for anything else.
1313
1314            We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1315            We check for this *after* checking the SHB for its byte
1316            order magic number, so that non-pcap-ng files are less
1317            likely to be treated as bad pcap-ng files. */
1318         if (bh->block_total_length > MAX_BLOCK_SIZE) {
1319                 *err = WTAP_ERR_BAD_FILE;
1320                 *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
1321                               bh->block_total_length, MAX_BLOCK_SIZE);
1322                 return -1;
1323         }
1324
1325         /* "Simple Packet Block" read fixed part */
1326         errno = WTAP_ERR_CANT_READ;
1327         bytes_read = file_read(&spb, sizeof spb, fh);
1328         if (bytes_read != sizeof spb) {
1329                 pcapng_debug0("pcapng_read_simple_packet_block: failed to read packet data");
1330                 *err = file_error(fh, err_info);
1331                 return 0;
1332         }
1333         block_read = bytes_read;
1334
1335         if (0 >= pn->number_of_interfaces) {
1336                 *err = WTAP_ERR_BAD_FILE;
1337                 *err_info = g_strdup_printf("pcapng: SPB appeared before any IDBs");
1338                 return 0;
1339         }
1340         int_data = g_array_index(pn->interface_data, interface_data_t, 0);
1341
1342         if (pn->byte_swapped) {
1343                 simple_packet.packet_len   = BSWAP32(spb.packet_len);
1344         } else {
1345                 simple_packet.packet_len   = spb.packet_len;
1346         }
1347
1348         /*
1349          * The captured length is not a field in the SPB; it can be
1350          * calculated as the minimum of the snapshot length from the
1351          * IDB and the packet length, as per the pcap-ng spec.
1352          */
1353         simple_packet.cap_len = simple_packet.packet_len;
1354         if (simple_packet.cap_len > int_data.snap_len)
1355                 simple_packet.cap_len = int_data.snap_len;
1356
1357         /*
1358          * How much padding is there at the end of the packet data?
1359          */
1360         if ((simple_packet.cap_len % 4) != 0)
1361                 padding = 4 - (simple_packet.cap_len % 4);
1362         else
1363                 padding = 0;
1364
1365         /* add padding bytes to "block total length" */
1366         /* (the "block total length" of some example files don't contain the packet data padding bytes!) */
1367         if (bh->block_total_length % 4) {
1368                 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1369         } else {
1370                 block_total_length = bh->block_total_length;
1371         }
1372         pcapng_debug1("pcapng_read_simple_packet_block: block_total_length %d", block_total_length);
1373
1374         /*
1375          * Is this block long enough to hold the packet data?
1376          */
1377         if (block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
1378                 /*
1379                  * No.  That means that the problem is with the packet
1380                  * length; the snapshot length can be bigger than the amount
1381                  * of packet data in the block, as it's a *maximum* length,
1382                  * not a *minimum* length.
1383                  */
1384                 *err = WTAP_ERR_BAD_FILE;
1385                 *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",
1386                               block_total_length, simple_packet.packet_len);
1387                 return -1;
1388         }
1389
1390         if (simple_packet.cap_len > WTAP_MAX_PACKET_SIZE) {
1391                 *err = WTAP_ERR_BAD_FILE;
1392                 *err_info = g_strdup_printf("pcapng_read_simple_packet_block: cap_len %u is larger than WTAP_MAX_PACKET_SIZE %u.",
1393                     simple_packet.cap_len, WTAP_MAX_PACKET_SIZE);
1394                 return 0;
1395         }
1396         pcapng_debug1("pcapng_read_simple_packet_block: packet data: packet_len %u",
1397                        simple_packet.packet_len);
1398
1399         pcapng_debug1("pcapng_read_simple_packet_block: Need to read pseudo header of size %d",
1400                       pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header));
1401
1402         /* No time stamp in a simple packet block; no options, either */
1403         wblock->packet_header->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1404         wblock->packet_header->interface_id = 0;
1405         wblock->packet_header->pkt_encap = int_data.wtap_encap;
1406         wblock->packet_header->ts.secs = 0;
1407         wblock->packet_header->ts.nsecs = 0;
1408         wblock->packet_header->interface_id = 0;
1409         wblock->packet_header->opt_comment = NULL;
1410         wblock->packet_header->drop_count = 0;
1411         wblock->packet_header->pack_flags = 0;
1412
1413         memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1414         pseudo_header_len = pcap_process_pseudo_header(fh,
1415                                                        WTAP_FILE_TYPE_SUBTYPE_PCAPNG,
1416                                                        int_data.wtap_encap,
1417                                                        simple_packet.cap_len,
1418                                                        TRUE,
1419                                                        wblock->packet_header,
1420                                                        err,
1421                                                        err_info);
1422         if (pseudo_header_len < 0) {
1423                 return 0;
1424         }
1425         wblock->packet_header->caplen = simple_packet.cap_len - pseudo_header_len;
1426         wblock->packet_header->len = simple_packet.packet_len - pseudo_header_len;
1427         block_read += pseudo_header_len;
1428         if (pseudo_header_len != pcap_get_phdr_size(int_data.wtap_encap, &wblock->packet_header->pseudo_header)) {
1429                 pcapng_debug1("pcapng_read_simple_packet_block: Could only read %d bytes for pseudo header.",
1430                               pseudo_header_len);
1431         }
1432
1433         memset((void *)&wblock->packet_header->pseudo_header, 0, sizeof(union wtap_pseudo_header));
1434
1435         /* "Simple Packet Block" read capture data */
1436         errno = WTAP_ERR_CANT_READ;
1437         if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1438             simple_packet.cap_len, err, err_info))
1439                 return 0;
1440         block_read += simple_packet.cap_len;
1441
1442         /* jump over potential padding bytes at end of the packet data */
1443         if ((simple_packet.cap_len % 4) != 0) {
1444                 file_offset64 = file_seek(fh, 4 - (simple_packet.cap_len % 4), SEEK_CUR, err);
1445                 if (file_offset64 <= 0) {
1446                         if (*err != 0)
1447                                 return -1;
1448                         return 0;
1449                 }
1450                 block_read += 4 - (simple_packet.cap_len % 4);
1451         }
1452
1453         pcap_read_post_process(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, int_data.wtap_encap,
1454             (union wtap_pseudo_header *)&wblock->packet_header->pseudo_header,
1455             buffer_start_ptr(wblock->frame_buffer),
1456             (int) simple_packet.cap_len,
1457             pn->byte_swapped, pn->if_fcslen);
1458         return block_read;
1459 }
1460
1461 #define NRES_ENDOFRECORD 0
1462 #define NRES_IP4RECORD 1
1463 #define NRES_IP6RECORD 2
1464 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
1465 /* IPv6 + MAXNAMELEN */
1466 #define INITIAL_NRB_REC_SIZE (16 + 64)
1467
1468 /*
1469  * Find the end of the NUL-terminated name the beginning of which is pointed
1470  * to by p; record_len is the number of bytes remaining in the record.
1471  *
1472  * Return the length of the name, including the terminating NUL.
1473  *
1474  * If we don't find a terminating NUL, return -1 and set *err and
1475  * *err_info appropriately.
1476  */
1477 static int
1478 name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
1479     gchar **err_info)
1480 {
1481         int namelen;
1482
1483         namelen = 0;
1484         for (;;) {
1485                 if (record_len == 0) {
1486                         /*
1487                          * We ran out of bytes in the record without
1488                          * finding a NUL.
1489                          */
1490                         *err = WTAP_ERR_BAD_FILE;
1491                         *err_info = g_strdup("pcapng_read_name_resolution_block: NRB record has non-null-terminated host name");
1492                         return -1;
1493                 }
1494                 if (*p == '\0')
1495                         break;  /* that's the terminating NUL */
1496                 p++;
1497                 record_len--;
1498                 namelen++;      /* count this byte */
1499         }
1500
1501         /* Include the NUL in the name length. */
1502         return namelen + 1;
1503 }
1504
1505 static int
1506 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)
1507 {
1508         int bytes_read = 0;
1509         int block_read = 0;
1510         int to_read;
1511         guint64 file_offset64;
1512         pcapng_name_resolution_block_t nrb;
1513         Buffer nrb_rec;
1514         guint32 v4_addr;
1515         guint record_len;
1516         char *namep;
1517         int namelen;
1518
1519         /*
1520          * Is this block long enough to be an NRB?
1521          */
1522         if (bh->block_total_length < MIN_NRB_SIZE) {
1523                 /*
1524                  * No.
1525                  */
1526                 *err = WTAP_ERR_BAD_FILE;
1527                 *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",
1528                               bh->block_total_length, MIN_NRB_SIZE);
1529                 return -1;
1530         }
1531
1532         /* Don't try to allocate memory for a huge number of options, as
1533            that might fail and, even if it succeeds, it might not leave
1534            any address space or memory+backing store for anything else.
1535
1536            We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1537            We check for this *after* checking the SHB for its byte
1538            order magic number, so that non-pcap-ng files are less
1539            likely to be treated as bad pcap-ng files. */
1540         if (bh->block_total_length > MAX_BLOCK_SIZE) {
1541                 *err = WTAP_ERR_BAD_FILE;
1542                 *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
1543                               bh->block_total_length, MAX_BLOCK_SIZE);
1544                 return -1;
1545         }
1546
1547         errno = WTAP_ERR_CANT_READ;
1548         to_read = bh->block_total_length - 8 - 4; /* We have read the header adn should not read the final block_total_length */
1549
1550         pcapng_debug1("pcapng_read_name_resolution_block, total %d bytes", bh->block_total_length);
1551
1552         /*
1553          * Start out with a buffer big enough for an IPv6 address and one
1554          * 64-byte name; we'll make the buffer bigger if necessary.
1555          */
1556         buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
1557         while (block_read < to_read) {
1558                 /*
1559                  * There must be at least one record's worth of data
1560                  * here.
1561                  */
1562                 if ((size_t)(to_read - block_read) < sizeof nrb) {
1563                         buffer_free(&nrb_rec);
1564                         *err = WTAP_ERR_BAD_FILE;
1565                         *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
1566                                       to_read - block_read,
1567                                       (guint)sizeof nrb);
1568                         return -1;
1569                 }
1570                 bytes_read = file_read(&nrb, sizeof nrb, fh);
1571                 if (bytes_read != sizeof nrb) {
1572                         buffer_free(&nrb_rec);
1573                         pcapng_debug0("pcapng_read_name_resolution_block: failed to read record header");
1574                         *err = file_error(fh, err_info);
1575                         return 0;
1576                 }
1577                 block_read += bytes_read;
1578
1579                 if (pn->byte_swapped) {
1580                         nrb.record_type = BSWAP16(nrb.record_type);
1581                         nrb.record_len  = BSWAP16(nrb.record_len);
1582                 }
1583
1584                 if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
1585                         buffer_free(&nrb_rec);
1586                         *err = WTAP_ERR_BAD_FILE;
1587                         *err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
1588                                       to_read - block_read,
1589                                       nrb.record_len + PADDING4(nrb.record_len));
1590                         return -1;
1591                 }
1592                 switch (nrb.record_type) {
1593                         case NRES_ENDOFRECORD:
1594                                 /* There shouldn't be any more data */
1595                                 to_read = 0;
1596                                 break;
1597                         case NRES_IP4RECORD:
1598                                 /*
1599                                  * The smallest possible record must have
1600                                  * a 4-byte IPv4 address, hence a minimum
1601                                  * of 4 bytes.
1602                                  *
1603                                  * (The pcap-NG spec really indicates
1604                                  * that it must be at least 5 bytes,
1605                                  * as there must be at least one name,
1606                                  * and it really must be at least 6
1607                                  * bytes, as the name mustn't be null,
1608                                  * but there's no need to fail if there
1609                                  * aren't any names at all, and we
1610                                  * should report a null name as such.)
1611                                  */
1612                                 if (nrb.record_len < 4) {
1613                                         buffer_free(&nrb_rec);
1614                                         *err = WTAP_ERR_BAD_FILE;
1615                                         *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
1616                                                       nrb.record_len);
1617                                         return -1;
1618                                 }
1619                                 buffer_assure_space(&nrb_rec, nrb.record_len);
1620                                 bytes_read = file_read(buffer_start_ptr(&nrb_rec),
1621                                     nrb.record_len, fh);
1622                                 if (bytes_read != nrb.record_len) {
1623                                         buffer_free(&nrb_rec);
1624                                         pcapng_debug0("pcapng_read_name_resolution_block: failed to read IPv4 record data");
1625                                         *err = file_error(fh, err_info);
1626                                         return 0;
1627                                 }
1628                                 block_read += bytes_read;
1629
1630                                 if (pn->add_new_ipv4) {
1631                                         /*
1632                                          * Scan through all the names in
1633                                          * the record and add them.
1634                                          */
1635                                         memcpy(&v4_addr,
1636                                             buffer_start_ptr(&nrb_rec), 4);
1637                                         if (pn->byte_swapped)
1638                                                 v4_addr = BSWAP32(v4_addr);
1639                                         for (namep = (char *)buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
1640                                             record_len != 0;
1641                                             namep += namelen, record_len -= namelen) {
1642                                                 /*
1643                                                  * Scan forward for a null
1644                                                  * byte.
1645                                                  */
1646                                                 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1647                                                 if (namelen == -1) {
1648                                                         buffer_free(&nrb_rec);
1649                                                         return -1;      /* fail */
1650                                                 }
1651                                                 pn->add_new_ipv4(v4_addr, namep);
1652                                         }
1653                                 }
1654
1655                                 file_offset64 = file_seek(fh, PADDING4(nrb.record_len), SEEK_CUR, err);
1656                                 if (file_offset64 <= 0) {
1657                                         buffer_free(&nrb_rec);
1658                                         if (*err != 0)
1659                                                 return -1;
1660                                         return 0;
1661                                 }
1662                                 block_read += PADDING4(nrb.record_len);
1663                                 break;
1664                         case NRES_IP6RECORD:
1665                                 /*
1666                                  * The smallest possible record must have
1667                                  * a 16-byte IPv6 address, hence a minimum
1668                                  * of 16 bytes.
1669                                  *
1670                                  * (The pcap-NG spec really indicates
1671                                  * that it must be at least 17 bytes,
1672                                  * as there must be at least one name,
1673                                  * and it really must be at least 18
1674                                  * bytes, as the name mustn't be null,
1675                                  * but there's no need to fail if there
1676                                  * aren't any names at all, and we
1677                                  * should report a null name as such.)
1678                                  */
1679                                 if (nrb.record_len < 16) {
1680                                         buffer_free(&nrb_rec);
1681                                         *err = WTAP_ERR_BAD_FILE;
1682                                         *err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
1683                                                       nrb.record_len);
1684                                         return -1;
1685                                 }
1686                                 if (to_read < nrb.record_len) {
1687                                         buffer_free(&nrb_rec);
1688                                         pcapng_debug0("pcapng_read_name_resolution_block: insufficient data for IPv6 record");
1689                                         return 0;
1690                                 }
1691                                 buffer_assure_space(&nrb_rec, nrb.record_len);
1692                                 bytes_read = file_read(buffer_start_ptr(&nrb_rec),
1693                                     nrb.record_len, fh);
1694                                 if (bytes_read != nrb.record_len) {
1695                                         buffer_free(&nrb_rec);
1696                                         pcapng_debug0("pcapng_read_name_resolution_block: failed to read IPv6 record data");
1697                                         *err = file_error(fh, err_info);
1698                                         return 0;
1699                                 }
1700                                 block_read += bytes_read;
1701
1702                                 if (pn->add_new_ipv6) {
1703                                         for (namep = (char *)buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
1704                                             record_len != 0;
1705                                             namep += namelen, record_len -= namelen) {
1706                                                 /*
1707                                                  * Scan forward for a null
1708                                                  * byte.
1709                                                  */
1710                                                 namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
1711                                                 if (namelen == -1) {
1712                                                         buffer_free(&nrb_rec);
1713                                                         return -1;      /* fail */
1714                                                 }
1715                                                 pn->add_new_ipv6(buffer_start_ptr(&nrb_rec),
1716                                                     namep);
1717                                         }
1718                                 }
1719
1720                                 file_offset64 = file_seek(fh, PADDING4(nrb.record_len), SEEK_CUR, err);
1721                                 if (file_offset64 <= 0) {
1722                                         buffer_free(&nrb_rec);
1723                                         if (*err != 0)
1724                                                 return -1;
1725                                         return 0;
1726                                 }
1727                                 block_read += PADDING4(nrb.record_len);
1728                                 break;
1729                         default:
1730                                 pcapng_debug1("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
1731                                 file_offset64 = file_seek(fh, nrb.record_len + PADDING4(nrb.record_len), SEEK_CUR, err);
1732                                 if (file_offset64 <= 0) {
1733                                         buffer_free(&nrb_rec);
1734                                         if (*err != 0)
1735                                                 return -1;
1736                                         return 0;
1737                                 }
1738                                 block_read += nrb.record_len + PADDING4(nrb.record_len);
1739                                 break;
1740                 }
1741         }
1742
1743         buffer_free(&nrb_rec);
1744         return block_read;
1745 }
1746
1747 static int
1748 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)
1749 {
1750         int bytes_read;
1751         guint block_read;
1752         guint to_read, opt_cont_buf_len;
1753         pcapng_interface_statistics_block_t isb;
1754         pcapng_option_header_t oh;
1755         char *option_content = NULL; /* Allocate as large as the options block */
1756
1757         /*
1758          * Is this block long enough to be an ISB?
1759          */
1760         if (bh->block_total_length < MIN_ISB_SIZE) {
1761                 /*
1762                  * No.
1763                  */
1764                 *err = WTAP_ERR_BAD_FILE;
1765                 *err_info = g_strdup_printf("pcapng_read_interface_statistics_block: total block length %u is too small (< %u)",
1766                               bh->block_total_length, MIN_ISB_SIZE);
1767                 return -1;
1768         }
1769
1770         /* Don't try to allocate memory for a huge number of options, as
1771            that might fail and, even if it succeeds, it might not leave
1772            any address space or memory+backing store for anything else.
1773
1774            We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1775            We check for this *after* checking the SHB for its byte
1776            order magic number, so that non-pcap-ng files are less
1777            likely to be treated as bad pcap-ng files. */
1778         if (bh->block_total_length > MAX_BLOCK_SIZE) {
1779                 *err = WTAP_ERR_BAD_FILE;
1780                 *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
1781                               bh->block_total_length, MAX_BLOCK_SIZE);
1782                 return -1;
1783         }
1784
1785         /* "Interface Statistics Block" read fixed part */
1786         errno = WTAP_ERR_CANT_READ;
1787         bytes_read = file_read(&isb, sizeof isb, fh);
1788         if (bytes_read != sizeof isb) {
1789                 pcapng_debug0("pcapng_read_interface_statistics_block: failed to read packet data");
1790                 *err = file_error(fh, err_info);
1791                 return 0;
1792         }
1793         block_read = bytes_read;
1794
1795         if (pn->byte_swapped) {
1796                 wblock->data.if_stats.interface_id = BSWAP32(isb.interface_id);
1797                 wblock->data.if_stats.ts_high      = BSWAP32(isb.timestamp_high);
1798                 wblock->data.if_stats.ts_low       = BSWAP32(isb.timestamp_low);
1799         } else {
1800                 wblock->data.if_stats.interface_id = isb.interface_id;
1801                 wblock->data.if_stats.ts_high      = isb.timestamp_high;
1802                 wblock->data.if_stats.ts_low       = isb.timestamp_low;
1803         }
1804         pcapng_debug1("pcapng_read_interface_statistics_block: interface_id %u", wblock->data.if_stats.interface_id);
1805
1806         /* Option defaults */
1807         wblock->data.if_stats.opt_comment          = NULL;
1808         wblock->data.if_stats.isb_ifrecv           = -1;
1809         wblock->data.if_stats.isb_ifdrop           = -1;
1810         wblock->data.if_stats.isb_filteraccept     = -1;
1811         wblock->data.if_stats.isb_osdrop           = -1;
1812         wblock->data.if_stats.isb_usrdeliv         = -1;
1813
1814         /* Options */
1815         errno = WTAP_ERR_CANT_READ;
1816         to_read = bh->block_total_length -
1817                   (MIN_BLOCK_SIZE + block_read);    /* fixed and variable part, including padding */
1818
1819         /* Allocate enough memory to hold all options */
1820         opt_cont_buf_len = to_read;
1821         option_content = (char *)g_try_malloc(opt_cont_buf_len);
1822         if (opt_cont_buf_len != 0 && option_content == NULL) {
1823                 *err = ENOMEM;  /* we assume we're out of memory */
1824                 return -1;
1825         }
1826
1827         while (to_read != 0) {
1828                 /* read option */
1829                 bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, to_read, err, err_info);
1830                 if (bytes_read <= 0) {
1831                         pcapng_debug0("pcapng_read_interface_statistics_block: failed to read option");
1832                         return bytes_read;
1833                 }
1834                 block_read += bytes_read;
1835                 to_read -= bytes_read;
1836
1837                 /* handle option content */
1838                 switch (oh.option_code) {
1839                     case(0): /* opt_endofopt */
1840                         if (to_read != 0) {
1841                                 pcapng_debug1("pcapng_read_interface_statistics_block: %u bytes after opt_endofopt", to_read);
1842                         }
1843                         /* padding should be ok here, just get out of this */
1844                         to_read = 0;
1845                         break;
1846                     case(1): /* opt_comment */
1847                         if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
1848                                 wblock->data.if_stats.opt_comment = g_strndup(option_content, oh.option_length);
1849                                 pcapng_debug1("pcapng_read_interface_statistics_block: opt_comment %s", wblock->data.if_stats.opt_comment);
1850                         } else {
1851                                 pcapng_debug1("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
1852                         }
1853                         break;
1854                     case(2): /* isb_starttime */
1855                         if (oh.option_length == 8) {
1856                                 guint32 high, low;
1857
1858                                 /*  Don't cast a char[] into a guint32--the
1859                                  *  char[] may not be aligned correctly.
1860                                  */
1861                                 memcpy(&high, option_content, sizeof(guint32));
1862                                 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
1863                                 if (pn->byte_swapped) {
1864                                         high = BSWAP32(high);
1865                                         low = BSWAP32(low);
1866                                 }
1867                                 wblock->data.if_stats.isb_starttime = (guint64)high;
1868                                 wblock->data.if_stats.isb_starttime <<= 32;
1869                                 wblock->data.if_stats.isb_starttime += (guint64)low;
1870                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_starttime);
1871                         } else {
1872                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
1873                         }
1874                         break;
1875                     case(3): /* isb_endtime */
1876                         if (oh.option_length == 8) {
1877                                 guint32 high, low;
1878
1879                                 /*  Don't cast a char[] into a guint32--the
1880                                  *  char[] may not be aligned correctly.
1881                                  */
1882                                 memcpy(&high, option_content, sizeof(guint32));
1883                                 memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
1884                                 if (pn->byte_swapped) {
1885                                         high = BSWAP32(high);
1886                                         low = BSWAP32(low);
1887                                 }
1888                                 wblock->data.if_stats.isb_endtime = (guint64)high;
1889                                 wblock->data.if_stats.isb_endtime <<= 32;
1890                                 wblock->data.if_stats.isb_endtime += (guint64)low;
1891                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_endtime);
1892                         } else {
1893                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
1894                         }
1895                         break;
1896                     case(4): /* isb_ifrecv */
1897                         if (oh.option_length == 8) {
1898                                 /*  Don't cast a char[] into a guint32--the
1899                                  *  char[] may not be aligned correctly.
1900                                  */
1901                                 memcpy(&wblock->data.if_stats.isb_ifrecv, option_content, sizeof(guint64));
1902                                 if (pn->byte_swapped)
1903                                         wblock->data.if_stats.isb_ifrecv = BSWAP64(wblock->data.if_stats.isb_ifrecv);
1904                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_ifrecv);
1905                         } else {
1906                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
1907                         }
1908                         break;
1909                     case(5): /* isb_ifdrop */
1910                         if (oh.option_length == 8) {
1911                                 /*  Don't cast a char[] into a guint32--the
1912                                  *  char[] may not be aligned correctly.
1913                                  */
1914                                 memcpy(&wblock->data.if_stats.isb_ifdrop, option_content, sizeof(guint64));
1915                                 if (pn->byte_swapped)
1916                                         wblock->data.if_stats.isb_ifdrop = BSWAP64(wblock->data.if_stats.isb_ifdrop);
1917                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_ifdrop);
1918                         } else {
1919                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
1920                         }
1921                         break;
1922                     case(6): /* isb_filteraccept 6 */
1923                         if (oh.option_length == 8) {
1924                                 /*  Don't cast a char[] into a guint32--the
1925                                  *  char[] may not be aligned correctly.
1926                                  */
1927                                 memcpy(&wblock->data.if_stats.isb_filteraccept, option_content, sizeof(guint64));
1928                                 if (pn->byte_swapped)
1929                                         wblock->data.if_stats.isb_ifdrop = BSWAP64(wblock->data.if_stats.isb_filteraccept);
1930                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_filteraccept);
1931                         } else {
1932                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_filteraccept length %u not 8 as expected", oh.option_length);
1933                         }
1934                         break;
1935                     case(7): /* isb_osdrop 7 */
1936                         if (oh.option_length == 8) {
1937                                 /*  Don't cast a char[] into a guint32--the
1938                                  *  char[] may not be aligned correctly.
1939                                  */
1940                                 memcpy(&wblock->data.if_stats.isb_osdrop, option_content, sizeof(guint64));
1941                                 if (pn->byte_swapped)
1942                                         wblock->data.if_stats.isb_osdrop = BSWAP64(wblock->data.if_stats.isb_osdrop);
1943                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_osdrop);
1944                         } else {
1945                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_osdrop length %u not 8 as expected", oh.option_length);
1946                         }
1947                         break;
1948                     case(8): /* isb_usrdeliv 8  */
1949                         if (oh.option_length == 8) {
1950                                 /*  Don't cast a char[] into a guint32--the
1951                                  *  char[] may not be aligned correctly.
1952                                  */
1953                                 memcpy(&wblock->data.if_stats.isb_usrdeliv, option_content, sizeof(guint64));
1954                                 if (pn->byte_swapped)
1955                                         wblock->data.if_stats.isb_usrdeliv = BSWAP64(wblock->data.if_stats.isb_osdrop);
1956                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_usrdeliv);
1957                         } else {
1958                                 pcapng_debug1("pcapng_read_interface_statistics_block: isb_usrdeliv length %u not 8 as expected", oh.option_length);
1959                         }
1960                         break;
1961                     default:
1962                         pcapng_debug2("pcapng_read_interface_statistics_block: unknown option %u - ignoring %u bytes",
1963                                       oh.option_code, oh.option_length);
1964                 }
1965         }
1966
1967         g_free(option_content);
1968
1969         return block_read;
1970 }
1971
1972
1973 static int
1974 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)
1975 {
1976         int block_read;
1977         guint64 file_offset64;
1978         guint32 block_total_length;
1979
1980         if (bh->block_total_length < MIN_BLOCK_SIZE) {
1981                 *err = WTAP_ERR_BAD_FILE;
1982                 *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",
1983                               bh->block_total_length, MIN_BLOCK_SIZE);
1984                 return -1;
1985         }
1986
1987         /* add padding bytes to "block total length" */
1988         /* (the "block total length" of some example files don't contain any padding bytes!) */
1989         if (bh->block_total_length % 4) {
1990                 block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
1991         } else {
1992                 block_total_length = bh->block_total_length;
1993         }
1994
1995         block_read = block_total_length - MIN_BLOCK_SIZE;
1996
1997         /* jump over this unknown block */
1998         file_offset64 = file_seek(fh, block_read, SEEK_CUR, err);
1999         if (file_offset64 <= 0) {
2000                 if (*err != 0)
2001                         return -1;
2002                 return 0;
2003         }
2004
2005         return block_read;
2006 }
2007
2008
2009 static int
2010 pcapng_read_block(FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info)
2011 {
2012         int block_read;
2013         int bytes_read;
2014         pcapng_block_header_t bh;
2015         guint32 block_total_length;
2016
2017
2018         /* Try to read the (next) block header */
2019         errno = WTAP_ERR_CANT_READ;
2020         bytes_read = file_read(&bh, sizeof bh, fh);
2021         if (bytes_read != sizeof bh) {
2022                 *err = file_error(fh, err_info);
2023                 pcapng_debug3("pcapng_read_block: file_read() returned %d instead of %u, err = %d.", bytes_read, (unsigned int)sizeof bh, *err);
2024                 if (*err != 0)
2025                         return -1;
2026                 return 0;
2027         }
2028
2029         block_read = bytes_read;
2030         if (pn->byte_swapped) {
2031                 bh.block_type         = BSWAP32(bh.block_type);
2032                 bh.block_total_length = BSWAP32(bh.block_total_length);
2033         }
2034
2035         wblock->type = bh.block_type;
2036
2037         pcapng_debug1("pcapng_read_block: block_type 0x%x", bh.block_type);
2038
2039         if (first_block) {
2040                 /*
2041                  * This is being read in by pcapng_open(), so this block
2042                  * must be an SHB.  If it's not, this is not a pcap-ng
2043                  * file.
2044                  *
2045                  * XXX - check for various forms of Windows <-> UN*X
2046                  * mangling, and suggest that the file might be a
2047                  * pcap-ng file that was damaged in transit?
2048                  */
2049                 if (bh.block_type != BLOCK_TYPE_SHB)
2050                         return 0;       /* not a pcap-ng file */
2051         }
2052
2053         switch (bh.block_type) {
2054                 case(BLOCK_TYPE_SHB):
2055                         bytes_read = pcapng_read_section_header_block(fh, first_block, &bh, pn, wblock, err, err_info);
2056                         break;
2057                 case(BLOCK_TYPE_IDB):
2058                         bytes_read = pcapng_read_if_descr_block(fh, &bh, pn, wblock, err, err_info);
2059                         break;
2060                 case(BLOCK_TYPE_PB):
2061                         bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE);
2062                         break;
2063                 case(BLOCK_TYPE_SPB):
2064                         bytes_read = pcapng_read_simple_packet_block(fh, &bh, pn, wblock, err, err_info);
2065                         break;
2066                 case(BLOCK_TYPE_EPB):
2067                         bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, TRUE);
2068                         break;
2069                 case(BLOCK_TYPE_NRB):
2070                         bytes_read = pcapng_read_name_resolution_block(fh, &bh, pn, wblock, err, err_info);
2071                         break;
2072                 case(BLOCK_TYPE_ISB):
2073                         bytes_read = pcapng_read_interface_statistics_block(fh, &bh, pn, wblock, err, err_info);
2074                         break;
2075                 default:
2076                         pcapng_debug2("pcapng_read_block: Unknown block_type: 0x%x (block ignored), block total length %d", bh.block_type, bh.block_total_length);
2077                         bytes_read = pcapng_read_unknown_block(fh, &bh, pn, wblock, err, err_info);
2078         }
2079
2080         if (bytes_read <= 0) {
2081                 return bytes_read;
2082         }
2083         block_read += bytes_read;
2084
2085         /* sanity check: first and second block lengths must match */
2086         errno = WTAP_ERR_CANT_READ;
2087         bytes_read = file_read(&block_total_length, sizeof block_total_length, fh);
2088         if (bytes_read != sizeof block_total_length) {
2089                 pcapng_debug0("pcapng_read_block: couldn't read second block length");
2090                 *err = file_error(fh, err_info);
2091                 if (*err == 0)
2092                         *err = WTAP_ERR_SHORT_READ;
2093                 return -1;
2094         }
2095         block_read += bytes_read;
2096
2097         if (pn->byte_swapped)
2098                 block_total_length = BSWAP32(block_total_length);
2099
2100         if (!(block_total_length == bh.block_total_length)) {
2101                 *err = WTAP_ERR_BAD_FILE;
2102                 *err_info = g_strdup_printf("pcapng_read_block: total block lengths (first %u and second %u) don't match",
2103                               bh.block_total_length, block_total_length);
2104                 return -1;
2105         }
2106
2107         return block_read;
2108 }
2109
2110 /* Process an IDB that we've just read. */
2111 static void
2112 pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
2113 {
2114         wtapng_if_descr_t int_data;
2115         interface_data_t interface_data;
2116
2117         int_data.wtap_encap = wblock->data.if_descr.wtap_encap;
2118         int_data.time_units_per_second = wblock->data.if_descr.time_units_per_second;
2119         int_data.link_type = wblock->data.if_descr.link_type;
2120         int_data.snap_len = wblock->data.if_descr.snap_len;
2121         /* Options */
2122         int_data.opt_comment = wblock->data.if_descr.opt_comment;
2123         int_data.if_name = wblock->data.if_descr.if_name;
2124         int_data.if_description = wblock->data.if_descr.if_description;
2125         /* XXX: if_IPv4addr opt 4  Interface network address and netmask.*/
2126         /* XXX: if_IPv6addr opt 5  Interface network address and prefix length (stored in the last byte).*/
2127         /* XXX: if_MACaddr  opt 6  Interface Hardware MAC address (48 bits).*/
2128         /* XXX: if_EUIaddr  opt 7  Interface Hardware EUI address (64 bits)*/
2129         int_data.if_speed = wblock->data.if_descr.if_speed;
2130         int_data.if_tsresol = wblock->data.if_descr.if_tsresol;
2131         /* XXX: if_tzone      10  Time zone for GMT support (TODO: specify better). */
2132         int_data.if_filter_str = wblock->data.if_descr.if_filter_str;
2133         int_data.bpf_filter_len = wblock->data.if_descr.bpf_filter_len;
2134         int_data.if_filter_bpf_bytes = wblock->data.if_descr.if_filter_bpf_bytes;
2135         int_data.if_os = wblock->data.if_descr.if_os;
2136         int_data.if_fcslen = wblock->data.if_descr.if_fcslen;
2137         /* XXX if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
2138         /* Interface statistics */
2139         int_data.num_stat_entries = 0;
2140         int_data.interface_statistics = NULL;
2141
2142         g_array_append_val(wth->interface_data, int_data);
2143         wth->number_of_interfaces++;
2144
2145         interface_data.wtap_encap = wblock->data.if_descr.wtap_encap;
2146         interface_data.snap_len = wblock->data.if_descr.snap_len;
2147         interface_data.time_units_per_second = wblock->data.if_descr.time_units_per_second;
2148
2149         g_array_append_val(pcapng->interface_data, interface_data);
2150         pcapng->number_of_interfaces++;
2151 }
2152
2153 /* classic wtap: open capture file */
2154 int
2155 pcapng_open(wtap *wth, int *err, gchar **err_info)
2156 {
2157         int bytes_read;
2158         pcapng_t pn;
2159         wtapng_block_t wblock;
2160         pcapng_t *pcapng;
2161         pcapng_block_header_t bh;
2162         gint64 saved_offset;
2163
2164         pn.shb_read = FALSE;
2165         /* we don't know the byte swapping of the file yet */
2166         pn.byte_swapped = FALSE;
2167         pn.if_fcslen = -1;
2168         pn.version_major = -1;
2169         pn.version_minor = -1;
2170         pn.interface_data = g_array_new(FALSE, FALSE, sizeof(interface_data_t));
2171         pn.number_of_interfaces = 0;
2172
2173
2174         /* we don't expect any packet blocks yet */
2175         wblock.frame_buffer = NULL;
2176         wblock.packet_header = NULL;
2177         wblock.file_encap = &wth->file_encap;
2178
2179         pcapng_debug0("pcapng_open: opening file");
2180         /* read first block */
2181         bytes_read = pcapng_read_block(wth->fh, TRUE, &pn, &wblock, err, err_info);
2182         if (bytes_read <= 0) {
2183                 pcapng_debug0("pcapng_open: couldn't read first SHB");
2184                 *err = file_error(wth->fh, err_info);
2185                 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
2186                         return -1;
2187                 return 0;
2188         }
2189
2190         /* first block must be a "Section Header Block" */
2191         if (wblock.type != BLOCK_TYPE_SHB) {
2192                 /*
2193                  * XXX - check for damage from transferring a file
2194                  * between Windows and UN*X as text rather than
2195                  * binary data?
2196                  */
2197                 pcapng_debug1("pcapng_open: first block type %u not SHB", wblock.type);
2198                 return 0;
2199         }
2200         pn.shb_read = TRUE;
2201
2202         /*
2203          * At this point, we've decided this is a pcap-NG file, not
2204          * some other type of file, so we can't return 0, as that
2205          * means "this isn't a pcap-NG file, try some other file
2206          * type".
2207          */
2208         wth->shb_hdr.opt_comment = wblock.data.section.opt_comment;
2209         wth->shb_hdr.shb_hardware = wblock.data.section.shb_hardware;
2210         wth->shb_hdr.shb_os = wblock.data.section.shb_os;
2211         wth->shb_hdr.shb_user_appl = wblock.data.section.shb_user_appl;
2212
2213         wth->file_encap = WTAP_ENCAP_UNKNOWN;
2214         wth->snapshot_length = 0;
2215         wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
2216         pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t));
2217         wth->priv = (void *)pcapng;
2218         *pcapng = pn;
2219
2220         wth->subtype_read = pcapng_read;
2221         wth->subtype_seek_read = pcapng_seek_read;
2222         wth->subtype_close = pcapng_close;
2223         wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
2224
2225         /* Read IDBs */
2226         wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
2227         wth->number_of_interfaces = 0;
2228
2229         /* Loop over all IDB:s that appear before any packets */
2230         while (1) {
2231                 /* peek at next block */
2232                 /* Try to read the (next) block header */
2233                 saved_offset = file_tell(wth->fh);
2234                 errno = WTAP_ERR_CANT_READ;
2235                 bytes_read = file_read(&bh, sizeof bh, wth->fh);
2236                 if (bytes_read == 0) {
2237                         pcapng_debug0("No more IDBs available...");
2238                         break;
2239                 }
2240                 if (bytes_read != sizeof bh) {
2241                         *err = file_error(wth->fh, err_info);
2242                         pcapng_debug3("pcapng_open:  Check for more IDB:s, file_read() returned %d instead of %u, err = %d.", bytes_read, (unsigned int)sizeof bh, *err);
2243                         if (*err == 0)
2244                                 *err = WTAP_ERR_SHORT_READ;
2245                         return -1;
2246                 }
2247
2248                 /* go back to where we were */
2249                 file_seek(wth->fh, saved_offset, SEEK_SET, err);
2250
2251                 if (pn.byte_swapped) {
2252                         bh.block_type         = BSWAP32(bh.block_type);
2253                 }
2254
2255                 pcapng_debug1("pcapng_open: Check for more IDB:s block_type 0x%x", bh.block_type);
2256
2257                 if (bh.block_type != BLOCK_TYPE_IDB) {
2258                         break;  /* No more IDB:s */
2259                 }
2260                 bytes_read = pcapng_read_block(wth->fh, FALSE, &pn, &wblock, err, err_info);
2261                 if (bytes_read == 0) {
2262                         pcapng_debug0("No more IDBs available...");
2263                         break;
2264                 }
2265                 if (bytes_read <= 0) {
2266                         pcapng_debug0("pcapng_open: couldn't read IDB");
2267                         *err = file_error(wth->fh, err_info);
2268                         if (*err == 0)
2269                                 *err = WTAP_ERR_SHORT_READ;
2270                         return -1;
2271                 }
2272                 pcapng_process_idb(wth, pcapng, &wblock);
2273                 pcapng_debug2("pcapng_open: Read IDB number_of_interfaces %u, wtap_encap %i", wth->number_of_interfaces, *wblock.file_encap);
2274         }
2275         return 1;
2276 }
2277
2278
2279 /* classic wtap: read packet */
2280 static gboolean
2281 pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
2282 {
2283         pcapng_t *pcapng = (pcapng_t *)wth->priv;
2284         int bytes_read;
2285         wtapng_block_t wblock;
2286         wtapng_if_descr_t *wtapng_if_descr;
2287         wtapng_if_stats_t if_stats;
2288
2289         *data_offset = file_tell(wth->fh);
2290         pcapng_debug1("pcapng_read: data_offset is initially %" G_GINT64_MODIFIER "d", *data_offset);
2291
2292         wblock.frame_buffer  = wth->frame_buffer;
2293         wblock.packet_header = &wth->phdr;
2294         wblock.file_encap    = &wth->file_encap;
2295
2296         pcapng->add_new_ipv4 = wth->add_new_ipv4;
2297         pcapng->add_new_ipv6 = wth->add_new_ipv6;
2298
2299         /* read next block */
2300         while (1) {
2301                 bytes_read = pcapng_read_block(wth->fh, FALSE, pcapng, &wblock, err, err_info);
2302                 if (bytes_read <= 0) {
2303                         pcapng_debug1("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
2304                         pcapng_debug0("pcapng_read: couldn't read packet block");
2305                         return FALSE;
2306                 }
2307
2308                 switch (wblock.type) {
2309
2310                 case(BLOCK_TYPE_SHB):
2311                         /* We don't currently support multi-section files. */
2312                         wth->phdr.pkt_encap = WTAP_ENCAP_UNKNOWN;
2313                         *err = WTAP_ERR_UNSUPPORTED;
2314                         *err_info = g_strdup_printf("pcapng: multi-section files not currently supported.");
2315                         return FALSE;
2316
2317                 case(BLOCK_TYPE_PB):
2318                 case(BLOCK_TYPE_SPB):
2319                 case(BLOCK_TYPE_EPB):
2320                         /* packet block - we've found a packet */
2321                         goto got_packet;
2322
2323                 case(BLOCK_TYPE_IDB):
2324                         /* A new interface */
2325                         pcapng_debug0("pcapng_read: block type BLOCK_TYPE_IDB");
2326                         *data_offset += bytes_read;
2327                         pcapng_process_idb(wth, pcapng, &wblock);
2328                         break;
2329
2330                 case(BLOCK_TYPE_NRB):
2331                         /* More name resolution entries */
2332                         pcapng_debug0("pcapng_read: block type BLOCK_TYPE_NRB");
2333                         *data_offset += bytes_read;
2334                         break;
2335
2336                 case(BLOCK_TYPE_ISB):
2337                         /* Another interface statistics report */
2338                         pcapng_debug0("pcapng_read: block type BLOCK_TYPE_ISB");
2339                         *data_offset += bytes_read;
2340                         pcapng_debug1("pcapng_read: *data_offset is updated to %" G_GINT64_MODIFIER "d", *data_offset);
2341                         if (wth->number_of_interfaces < wblock.data.if_stats.interface_id) {
2342                                 pcapng_debug1("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u > number_of_interfaces", wblock.data.if_stats.interface_id);
2343                         } else {
2344                                 /* Get the interface description */
2345                                 wtapng_if_descr = &g_array_index(wth->interface_data, wtapng_if_descr_t, wblock.data.if_stats.interface_id);
2346                                 if (wtapng_if_descr->num_stat_entries == 0) {
2347                                     /* First ISB found, no previous entry */
2348                                     pcapng_debug0("pcapng_read: block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
2349                                     wtapng_if_descr->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtapng_if_stats_t));
2350                                 }
2351
2352                                 if_stats.interface_id       = wblock.data.if_stats.interface_id;
2353                                 if_stats.ts_high            = wblock.data.if_stats.ts_high;
2354                                 if_stats.ts_low             = wblock.data.if_stats.ts_low;
2355                                 /* options */
2356                                 if_stats.opt_comment        = wblock.data.if_stats.opt_comment; /* NULL if not available */
2357                                 if_stats.isb_starttime      = wblock.data.if_stats.isb_starttime;
2358                                 if_stats.isb_endtime        = wblock.data.if_stats.isb_endtime;
2359                                 if_stats.isb_ifrecv         = wblock.data.if_stats.isb_ifrecv;
2360                                 if_stats.isb_ifdrop         = wblock.data.if_stats.isb_ifdrop;
2361                                 if_stats.isb_filteraccept   = wblock.data.if_stats.isb_filteraccept;
2362                                 if_stats.isb_osdrop         = wblock.data.if_stats.isb_osdrop;
2363                                 if_stats.isb_usrdeliv       = wblock.data.if_stats.isb_usrdeliv;
2364
2365                                 g_array_append_val(wtapng_if_descr->interface_statistics, if_stats);
2366                                 wtapng_if_descr->num_stat_entries++;
2367                         }
2368                         break;
2369
2370                 default:
2371                         /* XXX - improve handling of "unknown" blocks */
2372                         pcapng_debug1("pcapng_read: Unknown block type 0x%08x", wblock.type);
2373                         *data_offset += bytes_read;
2374                         pcapng_debug1("pcapng_read: *data_offset is updated to %" G_GINT64_MODIFIER "d", *data_offset);
2375                         break;
2376                 }
2377         }
2378
2379 got_packet:
2380
2381         /*pcapng_debug2("Read length: %u Packet length: %u", bytes_read, wth->phdr.caplen);*/
2382         pcapng_debug1("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset + bytes_read);
2383
2384         return TRUE;
2385 }
2386
2387
2388 /* classic wtap: seek to file position and read packet */
2389 static gboolean
2390 pcapng_seek_read(wtap *wth, gint64 seek_off,
2391     struct wtap_pkthdr *phdr, Buffer *buf, int length _U_,
2392     int *err, gchar **err_info)
2393 {
2394         pcapng_t *pcapng = (pcapng_t *)wth->priv;
2395         guint64 bytes_read64;
2396         int bytes_read;
2397         wtapng_block_t wblock;
2398
2399
2400         /* seek to the right file position */
2401         bytes_read64 = file_seek(wth->random_fh, seek_off, SEEK_SET, err);
2402         if (bytes_read64 <= 0) {
2403                 return FALSE;   /* Seek error */
2404         }
2405         pcapng_debug1("pcapng_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
2406
2407         wblock.frame_buffer = buf;
2408         wblock.packet_header = phdr;
2409         wblock.file_encap = &wth->file_encap;
2410
2411         /* read the block */
2412         bytes_read = pcapng_read_block(wth->random_fh, FALSE, pcapng, &wblock, err, err_info);
2413         if (bytes_read <= 0) {
2414                 pcapng_debug3("pcapng_seek_read: couldn't read packet block (err=%d, errno=%d, bytes_read=%d).",
2415                               *err, errno, bytes_read);
2416                 return FALSE;
2417         }
2418
2419         /* block must be a "Packet Block", an "Enhanced Packet Block",
2420            or a "Simple Packet Block" */
2421         if (wblock.type != BLOCK_TYPE_PB && wblock.type != BLOCK_TYPE_EPB &&
2422             wblock.type != BLOCK_TYPE_SPB) {
2423                 pcapng_debug1("pcapng_seek_read: block type %u not PB/EPB/SPB", wblock.type);
2424                 return FALSE;
2425         }
2426
2427         return TRUE;
2428 }
2429
2430
2431 /* classic wtap: close capture file */
2432 static void
2433 pcapng_close(wtap *wth)
2434 {
2435         pcapng_t *pcapng = (pcapng_t *)wth->priv;
2436
2437         pcapng_debug0("pcapng_close: closing file");
2438         if (pcapng->interface_data != NULL) {
2439                 g_array_free(pcapng->interface_data, TRUE);
2440         }
2441 }
2442
2443
2444
2445 typedef struct {
2446         GArray *interface_data;
2447         guint number_of_interfaces;
2448 } pcapng_dump_t;
2449
2450 static gboolean
2451 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
2452 {
2453         pcapng_block_header_t bh;
2454         pcapng_section_header_block_t shb;
2455         const guint32 zero_pad = 0;
2456         gboolean have_options = FALSE;
2457         struct option option_hdr;                   /* guint16 type, guint16 value_length; */
2458         guint32 options_total_length = 0;
2459         guint32 comment_len = 0, shb_hardware_len = 0, shb_os_len = 0, shb_user_appl_len = 0;
2460         guint32 comment_pad_len = 0, shb_hardware_pad_len = 0, shb_os_pad_len = 0, shb_user_appl_pad_len = 0;
2461
2462         if (wdh->shb_hdr) {
2463                 pcapng_debug0("pcapng_write_section_header_block: Have shb_hdr");
2464                 /* Check if we should write comment option */
2465                 if (wdh->shb_hdr->opt_comment) {
2466                         have_options = TRUE;
2467                         comment_len = (guint32)strlen(wdh->shb_hdr->opt_comment) & 0xffff;
2468                         if ((comment_len % 4)) {
2469                                 comment_pad_len = 4 - (comment_len % 4);
2470                         } else {
2471                                 comment_pad_len = 0;
2472                         }
2473                         options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
2474                 }
2475
2476                 /* Check if we should write shb_hardware option */
2477                 if (wdh->shb_hdr->shb_hardware) {
2478                         have_options = TRUE;
2479                         shb_hardware_len = (guint32)strlen(wdh->shb_hdr->shb_hardware) & 0xffff;
2480                         if ((shb_hardware_len % 4)) {
2481                                 shb_hardware_pad_len = 4 - (shb_hardware_len % 4);
2482                         } else {
2483                                 shb_hardware_pad_len = 0;
2484                         }
2485                         options_total_length = options_total_length + shb_hardware_len + shb_hardware_pad_len + 4 /* options tag */ ;
2486                 }
2487
2488                 /* Check if we should write shb_os option */
2489                 if (wdh->shb_hdr->shb_os) {
2490                         have_options = TRUE;
2491                         shb_os_len = (guint32)strlen(wdh->shb_hdr->shb_os) & 0xffff;
2492                         if ((shb_os_len % 4)) {
2493                                 shb_os_pad_len = 4 - (shb_os_len % 4);
2494                         } else {
2495                                 shb_os_pad_len = 0;
2496                         }
2497                         options_total_length = options_total_length + shb_os_len + shb_os_pad_len + 4 /* options tag */ ;
2498                 }
2499
2500                 /* Check if we should write shb_user_appl option */
2501                 if (wdh->shb_hdr->shb_user_appl) {
2502                         have_options = TRUE;
2503                         shb_user_appl_len = (guint32)strlen(wdh->shb_hdr->shb_user_appl) & 0xffff;
2504                         if ((shb_user_appl_len % 4)) {
2505                                 shb_user_appl_pad_len = 4 - (shb_user_appl_len % 4);
2506                         } else {
2507                                 shb_user_appl_pad_len = 0;
2508                         }
2509                         options_total_length = options_total_length + shb_user_appl_len + shb_user_appl_pad_len + 4 /* options tag */ ;
2510                 }
2511                 if (have_options) {
2512                         /* End-of-options tag */
2513                         options_total_length += 4;
2514                 }
2515         }
2516
2517         /* write block header */
2518         bh.block_type = BLOCK_TYPE_SHB;
2519         bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + options_total_length + 4);
2520         pcapng_debug2("pcapng_write_section_header_block: Total len %u, Options total len %u",bh.block_total_length, options_total_length);
2521
2522         if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
2523                 return FALSE;
2524         wdh->bytes_dumped += sizeof bh;
2525
2526         /* write block fixed content */
2527         /* XXX - get these values from wblock? */
2528         shb.magic = 0x1A2B3C4D;
2529         shb.version_major = 1;
2530         shb.version_minor = 0;
2531         shb.section_length = -1;
2532
2533         if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
2534                 return FALSE;
2535         wdh->bytes_dumped += sizeof shb;
2536
2537         /* XXX - write (optional) block options
2538          * opt_comment  1
2539          * shb_hardware 2
2540          * shb_os       3
2541          * shb_user_appl 4
2542          */
2543
2544         if (comment_len) {
2545                 option_hdr.type          = OPT_COMMENT;
2546                 option_hdr.value_length = comment_len;
2547                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2548                         return FALSE;
2549                 wdh->bytes_dumped += 4;
2550
2551                 /* Write the comments string */
2552                 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);
2553                 if (!wtap_dump_file_write(wdh, wdh->shb_hdr->opt_comment, comment_len, err))
2554                         return FALSE;
2555                 wdh->bytes_dumped += comment_len;
2556
2557                 /* write padding (if any) */
2558                 if (comment_pad_len != 0) {
2559                         if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
2560                                 return FALSE;
2561                         wdh->bytes_dumped += comment_pad_len;
2562                 }
2563         }
2564
2565         if (shb_hardware_len) {
2566                 option_hdr.type          = OPT_SHB_HARDWARE;
2567                 option_hdr.value_length = shb_hardware_len;
2568                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2569                         return FALSE;
2570                 wdh->bytes_dumped += 4;
2571
2572                 /* Write the string */
2573                 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);
2574                 if (!wtap_dump_file_write(wdh, wdh->shb_hdr->shb_hardware, shb_hardware_len, err))
2575                         return FALSE;
2576                 wdh->bytes_dumped += shb_hardware_len;
2577
2578                 /* write padding (if any) */
2579                 if (shb_hardware_pad_len != 0) {
2580                         if (!wtap_dump_file_write(wdh, &zero_pad, shb_hardware_pad_len, err))
2581                                 return FALSE;
2582                         wdh->bytes_dumped += shb_hardware_pad_len;
2583                 }
2584         }
2585
2586         if (shb_os_len) {
2587                 option_hdr.type          = OPT_SHB_OS;
2588                 option_hdr.value_length = shb_os_len;
2589                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2590                         return FALSE;
2591                 wdh->bytes_dumped += 4;
2592
2593                 /* Write the string */
2594                 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);
2595                 if (!wtap_dump_file_write(wdh, wdh->shb_hdr->shb_os, shb_os_len, err))
2596                         return FALSE;
2597                 wdh->bytes_dumped += shb_os_len;
2598
2599                 /* write padding (if any) */
2600                 if (shb_os_pad_len != 0) {
2601                         if (!wtap_dump_file_write(wdh, &zero_pad, shb_os_pad_len, err))
2602                                 return FALSE;
2603                         wdh->bytes_dumped += shb_os_pad_len;
2604                 }
2605         }
2606
2607         if (shb_user_appl_len) {
2608                 option_hdr.type          = OPT_SHB_USERAPPL;
2609                 option_hdr.value_length = shb_user_appl_len;
2610                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2611                         return FALSE;
2612                 wdh->bytes_dumped += 4;
2613
2614                 /* Write the comments string */
2615                 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);
2616                 if (!wtap_dump_file_write(wdh, wdh->shb_hdr->shb_user_appl, shb_user_appl_len, err))
2617                         return FALSE;
2618                 wdh->bytes_dumped += shb_user_appl_len;
2619
2620                 /* write padding (if any) */
2621                 if (shb_user_appl_pad_len != 0) {
2622                         if (!wtap_dump_file_write(wdh, &zero_pad, shb_user_appl_pad_len, err))
2623                                 return FALSE;
2624                         wdh->bytes_dumped += shb_user_appl_pad_len;
2625                 }
2626         }
2627
2628         /* Write end of options if we have otions */
2629         if (have_options) {
2630                 option_hdr.type = OPT_EOFOPT;
2631                 option_hdr.value_length = 0;
2632                 if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
2633                         return FALSE;
2634                 wdh->bytes_dumped += 4;
2635         }
2636
2637         /* write block footer */
2638         if (!wtap_dump_file_write(wdh, &bh.block_total_length,
2639             sizeof bh.block_total_length, err))
2640                 return FALSE;
2641         wdh->bytes_dumped += sizeof bh.block_total_length;
2642
2643         return TRUE;
2644 }
2645
2646 #define IDB_OPT_IF_NAME         2
2647 #define IDB_OPT_IF_DESCR        3
2648 #define IDB_OPT_IF_SPEED        8
2649 #define IDB_OPT_IF_TSRESOL      9
2650 #define IDB_OPT_IF_FILTER       11
2651 #define IDB_OPT_IF_OS           12
2652
2653 static gboolean
2654 pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *err)
2655 {
2656         pcapng_block_header_t bh;
2657         pcapng_interface_description_block_t idb;
2658         const guint32 zero_pad = 0;
2659         gboolean have_options = FALSE;
2660         struct option option_hdr;                   /* guint16 type, guint16 value_length; */
2661         guint32 options_total_length = 0;
2662         guint32 comment_len = 0, if_name_len = 0, if_description_len = 0 , if_os_len = 0, if_filter_str_len = 0;
2663         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;
2664
2665
2666         pcapng_debug3("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
2667                       int_data->link_type,
2668                       wtap_encap_string(wtap_pcap_encap_to_wtap_encap(int_data->link_type)),
2669                       int_data->snap_len);
2670
2671         if (int_data->link_type == (guint16)-1) {
2672                 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
2673                 return FALSE;
2674         }
2675
2676         /* Calculate options length */
2677         if (int_data->opt_comment) {
2678                 have_options = TRUE;
2679                 comment_len = (guint32)strlen(int_data->opt_comment) & 0xffff;
2680                 if ((comment_len % 4)) {
2681                         comment_pad_len = 4 - (comment_len % 4);
2682                 } else {
2683                         comment_pad_len = 0;
2684                 }
2685                 options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
2686         }
2687
2688         /*
2689          * if_name        2  A UTF-8 string containing the name of the device used to capture data.
2690          */
2691         if (int_data->if_name) {
2692                 have_options = TRUE;
2693                 if_name_len = (guint32)strlen(int_data->if_name) & 0xffff;
2694                 if ((if_name_len % 4)) {
2695                         if_name_pad_len = 4 - (if_name_len % 4);
2696                 } else {
2697                         if_name_pad_len = 0;
2698                 }
2699                 options_total_length = options_total_length + if_name_len + if_name_pad_len + 4 /* comment options tag */ ;
2700         }
2701
2702         /*
2703          * if_description 3  A UTF-8 string containing the description of the device used to capture data.
2704          */
2705         if (int_data->if_description) {
2706                 have_options = TRUE;
2707                 if_description_len = (guint32)strlen(int_data->if_description) & 0xffff;
2708                 if ((if_description_len % 4)) {
2709                         if_description_pad_len = 4 - (if_description_len % 4);
2710                 } else {
2711                         if_description_pad_len = 0;
2712                 }
2713                 options_total_length = options_total_length + if_description_len + if_description_pad_len + 4 /* comment options tag */ ;
2714         }
2715         /* Currently not handled
2716          * if_IPv4addr    4  Interface network address and netmask.
2717          * if_IPv6addr    5  Interface network address and prefix length (stored in the last byte).
2718          * if_MACaddr     6  Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
2719          * if_EUIaddr     7  Interface Hardware EUI address (64 bits), if available. TODO: give a good example
2720          */
2721         /*
2722          * if_speed       8  Interface speed (in bps). 100000000 for 100Mbps
2723          */
2724         if (int_data->if_speed != 0) {
2725                 have_options = TRUE;
2726                 options_total_length = options_total_length + 8 + 4;
2727         }
2728         /*
2729          * if_tsresol     9  Resolution of timestamps.
2730          */
2731         if (int_data->if_tsresol != 0) {
2732                 have_options = TRUE;
2733                 options_total_length = options_total_length + 4 + 4;
2734         }
2735         /* Not used
2736          * if_tzone      10  Time zone for GMT support (TODO: specify better). TODO: give a good example
2737          */
2738         /*
2739          * if_filter     11  The filter (e.g. "capture only TCP traffic") used to capture traffic.
2740          * 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).
2741          */
2742         if (int_data->if_filter_str) {
2743                 have_options = TRUE;
2744                 if_filter_str_len = (guint32)(strlen(int_data->if_filter_str) + 1) & 0xffff;
2745                 if ((if_filter_str_len % 4)) {
2746                         if_filter_str_pad_len = 4 - (if_filter_str_len % 4);
2747                 } else {
2748                         if_filter_str_pad_len = 0;
2749                 }
2750                 options_total_length = options_total_length + if_filter_str_len + if_filter_str_pad_len + 4 /* comment options tag */ ;
2751         }
2752         /*
2753          * if_os         12  A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
2754          */
2755         if (int_data->if_os) {
2756                 have_options = TRUE;
2757                 if_os_len = (guint32)strlen(int_data->if_os) & 0xffff;
2758                 if ((if_os_len % 4)) {
2759                         if_os_pad_len = 4 - (if_os_len % 4);
2760                 } else {
2761                         if_os_pad_len = 0;
2762                 }
2763                 options_total_length = options_total_length + if_os_len + if_os_pad_len + 4 /* comment options tag */ ;
2764         }
2765         /*
2766          * if_fcslen     13  An integer value that specified the length of the Frame Check Sequence (in bits) for this interface.
2767          * -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.
2768          */
2769         if (int_data->if_fcslen != 0) {
2770         }
2771         /* Not used
2772          * if_tsoffset   14  A 64 bits integer value that specifies an offset (in seconds) that must be added to the timestamp of each packet
2773          * to obtain the absolute timestamp of a packet. If the option is missing, the timestamps stored in the packet must be considered absolute timestamps.
2774          */
2775
2776         if (have_options) {
2777                 /* End-of-options tag */
2778                 options_total_length += 4;
2779         }
2780
2781         /* write block header */
2782         bh.block_type = BLOCK_TYPE_IDB;
2783         bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + options_total_length + 4);
2784
2785         if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
2786                 return FALSE;
2787         wdh->bytes_dumped += sizeof bh;
2788
2789         /* write block fixed content */
2790         idb.linktype    = int_data->link_type;
2791         idb.reserved    = 0;
2792         idb.snaplen     = int_data->snap_len;
2793
2794         if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
2795                 return FALSE;
2796         wdh->bytes_dumped += sizeof idb;
2797
2798         /* XXX - write (optional) block options */
2799         if (comment_len != 0) {
2800                 option_hdr.type         = OPT_COMMENT;
2801                 option_hdr.value_length = comment_len;
2802                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2803                         return FALSE;
2804                 wdh->bytes_dumped += 4;
2805
2806                 /* Write the comments string */
2807                 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);
2808                 if (!wtap_dump_file_write(wdh, int_data->opt_comment, comment_len, err))
2809                         return FALSE;
2810                 wdh->bytes_dumped += comment_len;
2811
2812                 /* write padding (if any) */
2813                 if (comment_pad_len != 0) {
2814                         if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
2815                                 return FALSE;
2816                         wdh->bytes_dumped += comment_pad_len;
2817                 }
2818         }
2819         /*
2820          * if_name        2  A UTF-8 string containing the name of the device used to capture data.
2821          */
2822         if (if_name_len !=0) {
2823                 option_hdr.type = IDB_OPT_IF_NAME;
2824                 option_hdr.value_length = if_name_len;
2825                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2826                         return FALSE;
2827                 wdh->bytes_dumped += 4;
2828
2829                 /* Write the comments string */
2830                 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);
2831                 if (!wtap_dump_file_write(wdh, int_data->if_name, if_name_len, err))
2832                         return FALSE;
2833                 wdh->bytes_dumped += if_name_len;
2834
2835                 /* write padding (if any) */
2836                 if (if_name_pad_len != 0) {
2837                         if (!wtap_dump_file_write(wdh, &zero_pad, if_name_pad_len, err))
2838                                 return FALSE;
2839                         wdh->bytes_dumped += if_name_pad_len;
2840                 }
2841         }
2842         /*
2843          * if_description 3  A UTF-8 string containing the description of the device used to capture data.
2844          */
2845         if (if_description_len != 0) {
2846                 option_hdr.type          = IDB_OPT_IF_NAME;
2847                 option_hdr.value_length = if_description_len;
2848                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2849                         return FALSE;
2850                 wdh->bytes_dumped += 4;
2851
2852                 /* Write the comments string */
2853                 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);
2854                 if (!wtap_dump_file_write(wdh, int_data->if_description, if_description_len, err))
2855                         return FALSE;
2856                 wdh->bytes_dumped += if_description_len;
2857
2858                 /* write padding (if any) */
2859                 if (if_description_pad_len != 0) {
2860                         if (!wtap_dump_file_write(wdh, &zero_pad, if_description_pad_len, err))
2861                                 return FALSE;
2862                         wdh->bytes_dumped += if_description_pad_len;
2863                 }
2864         }
2865         /* Currently not handled
2866          * if_IPv4addr    4  Interface network address and netmask.
2867          * if_IPv6addr    5  Interface network address and prefix length (stored in the last byte).
2868          * if_MACaddr     6  Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
2869          * if_EUIaddr     7  Interface Hardware EUI address (64 bits), if available. TODO: give a good example
2870          */
2871         /*
2872          * if_speed       8  Interface speed (in bps). 100000000 for 100Mbps
2873          */
2874         if (int_data->if_speed != 0) {
2875                 option_hdr.type          = IDB_OPT_IF_SPEED;
2876                 option_hdr.value_length = 8;
2877                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2878                         return FALSE;
2879                 wdh->bytes_dumped += 4;
2880
2881                 /* Write the comments string */
2882                 pcapng_debug1("pcapng_write_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", int_data->if_speed);
2883                 if (!wtap_dump_file_write(wdh, &int_data->if_speed, sizeof(guint64), err))
2884                         return FALSE;
2885                 wdh->bytes_dumped += 8;
2886         }
2887         /*
2888          * if_tsresol     9  Resolution of timestamps.
2889          * default is 6 for microsecond resolution, opt 9  Resolution of timestamps.
2890          * If the Most Significant Bit is equal to zero, the remaining bits indicates
2891          * the resolution of the timestamp as as a negative power of 10
2892          */
2893         if (int_data->if_tsresol != 0) {
2894                 option_hdr.type          = IDB_OPT_IF_TSRESOL;
2895                 option_hdr.value_length = 1;
2896                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
2897                         return FALSE;
2898                 wdh->bytes_dumped += 4;
2899
2900                 /* Write the time stamp resolution */
2901                 pcapng_debug1("pcapng_write_if_descr_block: if_tsresol %u", int_data->if_tsresol);
2902                 if (!wtap_dump_file_write(wdh, &int_data->if_tsresol, 1, err))
2903                         return FALSE;
2904                 wdh->bytes_dumped += 1;
2905                 if (!wtap_dump_file_write(wdh, &zero_pad, 3, err))
2906                         return FALSE;
2907                 wdh->bytes_dumped += 3;
2908         }
2909         /* not used
2910          * if_tzone      10  Time zone for GMT support (TODO: specify better). TODO: give a good example
2911          */
2912         /*
2913          * if_filter     11  The filter (e.g. "capture only TCP traffic") used to capture traffic.
2914          */
2915         /* Libpcap string variant */
2916         if (if_filter_str_len !=0) {
2917                 option_hdr.type          = IDB_OPT_IF_FILTER;
2918                 option_hdr.value_length = if_filter_str_len;
2919                 /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
2920                 if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))