1 /* pcapng.c
2  *
3  * Wiretap Library
4  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
5  *
6  * File format support for pcapng file format
7  * Copyright (c) 2007 by Ulf Lamping <ulf.lamping@web.de>
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 /* File format specification:
13  *   https://github.com/pcapng/pcapng
14  * Related Wiki page:
15  *   https://gitlab.com/wireshark/wireshark/-/wikis/Development/PcapNg
16  */
17 
18 #include "config.h"
19 
20 #define WS_LOG_DOMAIN LOG_DOMAIN_WIRETAP
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 
26 #include <wsutil/wslog.h>
27 #include <wsutil/strtoi.h>
28 #include <wsutil/glib-compat.h>
29 #include <wsutil/ws_assert.h>
30 #include <wsutil/ws_roundup.h>
31 
32 #include "wtap-int.h"
33 #include "file_wrappers.h"
34 #include "required_file_handlers.h"
35 #include "pcap-common.h"
36 #include "pcap-encap.h"
37 #include "pcapng.h"
38 #include "pcapng_module.h"
39 #include "secrets-types.h"
40 
41 #define ROUND_TO_4BYTE(len) WS_ROUNDUP_4(len)
42 
43 static gboolean
44 pcapng_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err,
45             gchar **err_info, gint64 *data_offset);
46 static gboolean
47 pcapng_seek_read(wtap *wth, gint64 seek_off,
48                  wtap_rec *rec, Buffer *buf, int *err, gchar **err_info);
49 static void
50 pcapng_close(wtap *wth);
51 
52 static gboolean
53 pcapng_encap_is_ft_specific(int encap);
54 
55 /*
56  * Minimum block size = size of block header + size of block trailer.
57  */
58 #define MIN_BLOCK_SIZE  ((guint32)(sizeof(pcapng_block_header_t) + sizeof(guint32)))
59 
60 /*
61  * Minimum SHB size = minimum block size + size of fixed length portion of SHB.
62  */
63 #define MIN_SHB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
64 
65 /* pcapng: packet block file encoding (obsolete) */
66 typedef struct pcapng_packet_block_s {
67     guint16 interface_id;
68     guint16 drops_count;
69     guint32 timestamp_high;
70     guint32 timestamp_low;
71     guint32 captured_len;
72     guint32 packet_len;
73     /* ... Packet Data ... */
74     /* ... Padding ... */
75     /* ... Options ... */
76 } pcapng_packet_block_t;
77 
78 /*
79  * Minimum PB size = minimum block size + size of fixed length portion of PB.
80  */
81 #define MIN_PB_SIZE     ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
82 
83 /* pcapng: enhanced packet block file encoding */
84 typedef struct pcapng_enhanced_packet_block_s {
85     guint32 interface_id;
86     guint32 timestamp_high;
87     guint32 timestamp_low;
88     guint32 captured_len;
89     guint32 packet_len;
90     /* ... Packet Data ... */
91     /* ... Padding ... */
92     /* ... Options ... */
93 } pcapng_enhanced_packet_block_t;
94 
95 /*
96  * Minimum EPB size = minimum block size + size of fixed length portion of EPB.
97  */
98 #define MIN_EPB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
99 
100 /* pcapng: simple packet block file encoding */
101 typedef struct pcapng_simple_packet_block_s {
102     guint32 packet_len;
103     /* ... Packet Data ... */
104     /* ... Padding ... */
105 } pcapng_simple_packet_block_t;
106 
107 /*
108  * Minimum SPB size = minimum block size + size of fixed length portion of SPB.
109  */
110 #define MIN_SPB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
111 
112 /* pcapng: name resolution block file encoding */
113 typedef struct pcapng_name_resolution_block_s {
114     guint16 record_type;
115     guint16 record_len;
116     /* ... Record ... */
117 } pcapng_name_resolution_block_t;
118 
119 /*
120  * Minimum NRB size = minimum block size + size of smallest NRB record
121  * (there must at least be an "end of records" record).
122  */
123 #define MIN_NRB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
124 
125 /* pcapng: custom block file encoding */
126 typedef struct pcapng_custom_block_s {
127     guint32 pen;
128     /* Custom data and options */
129 } pcapng_custom_block_t;
130 
131 /*
132  * Minimum CB size = minimum block size + size of fixed length portion of CB.
133  */
134 
135 #define MIN_CB_SIZE     ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_custom_block_t)))
136 
137 /*
138  * Minimum ISB size = minimum block size + size of fixed length portion of ISB.
139  */
140 #define MIN_ISB_SIZE    ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
141 
142 /*
143  * Minimum Sysdig size = minimum block size + packed size of sysdig_event_phdr.
144  * Minimum Sysdig event v2 header size = minimum block size + packed size of sysdig_event_v2_phdr (which, in addition
145  * to sysdig_event_phdr, includes the nparams 32bit value).
146  */
147 #define SYSDIG_EVENT_HEADER_SIZE ((16 + 64 + 64 + 32 + 16)/8) /* CPU ID + TS + TID + Event len + Event type */
148 #define MIN_SYSDIG_EVENT_SIZE    ((guint32)(MIN_BLOCK_SIZE + SYSDIG_EVENT_HEADER_SIZE))
149 #define SYSDIG_EVENT_V2_HEADER_SIZE ((16 + 64 + 64 + 32 + 16 + 32)/8) /* CPU ID + TS + TID + Event len + Event type + nparams */
150 #define MIN_SYSDIG_EVENT_V2_SIZE    ((guint32)(MIN_BLOCK_SIZE + SYSDIG_EVENT_V2_HEADER_SIZE))
151 
152 /*
153  * We require __REALTIME_TIMESTAMP in the Journal Export Format reader in
154  * order to set each packet timestamp. Require it here as well, although
155  * it's not strictly necessary.
156  */
157 #define SDJ__REALTIME_TIMESTAMP "__REALTIME_TIMESTAMP="
158 #define MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE    23 // "__REALTIME_TIMESTAMP=0\n"
159 #define MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE    ((guint32)(MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE + MIN_BLOCK_SIZE))
160 
161 /* pcapng: common option header file encoding for every option type */
162 typedef struct pcapng_option_header_s {
163     guint16 option_code;
164     guint16 option_length;
165     /* ... x bytes Option Body ... */
166     /* ... Padding ... */
167 } pcapng_option_header_t;
168 
169 struct pcapng_option {
170     guint16 type;
171     guint16 value_length;
172 };
173 
174 /* Option codes: 16-bit field */
175 #define OPT_EPB_FLAGS        0x0002
176 #define OPT_EPB_HASH         0x0003
177 #define OPT_EPB_DROPCOUNT    0x0004
178 #define OPT_EPB_PACKETID     0x0005
179 #define OPT_EPB_QUEUE        0x0006
180 #define OPT_EPB_VERDICT      0x0007
181 
182 #define OPT_NRB_DNSNAME      0x0002
183 #define OPT_NRB_DNSV4ADDR    0x0003
184 #define OPT_NRB_DNSV6ADDR    0x0004
185 
186 /* MSBit of option code means "local type" */
187 #define OPT_LOCAL_FLAG       0x8000
188 
189 /* OPT_EPB_VERDICT sub-types */
190 #define OPT_VERDICT_TYPE_HW  0
191 #define OPT_VERDICT_TYPE_TC  1
192 #define OPT_VERDICT_TYPE_XDP 2
193 
194 /*
195  * In order to keep from trying to allocate large chunks of memory,
196  * which could either fail or, even if it succeeds, chew up so much
197  * address space or memory+backing store as not to leave room for
198  * anything else, we impose upper limits on the size of blocks we're
199  * willing to handle.
200  *
201  * We pick a limit of an EPB with a maximum-sized D-Bus packet and 128 KiB
202  * worth of options; we use the maximum D-Bus packet size as that's larger
203  * than the maximum packet size for other link-layer types, and the maximum
204  * packet size for other link-layer types is currently small enough that
205  * the resulting block size would be less than the previous 16 MiB limit.
206  */
207 #define MAX_BLOCK_SIZE (MIN_EPB_SIZE + WTAP_MAX_PACKET_SIZE_DBUS + 131072)
208 
209 /* Note: many of the defined structures for block data are defined in wtap.h */
210 
211 /* Packet data - used for both Enhanced Packet Block and the obsolete Packet Block data */
212 typedef struct wtapng_packet_s {
213     /* mandatory */
214     guint32                         ts_high;        /* seconds since 1.1.1970 */
215     guint32                         ts_low;         /* fraction of seconds, depends on if_tsresol */
216     guint32                         cap_len;        /* data length in the file */
217     guint32                         packet_len;     /* data length on the wire */
218     guint32                         interface_id;   /* identifier of the interface. */
219     guint16                         drops_count;    /* drops count, only valid for packet block */
220     /* 0xffff if information no available */
221     /* pack_hash */
222     /* XXX - put the packet data / pseudo_header here as well? */
223 } wtapng_packet_t;
224 
225 /* Simple Packet data */
226 typedef struct wtapng_simple_packet_s {
227     /* mandatory */
228     guint32                         cap_len;        /* data length in the file */
229     guint32                         packet_len;     /* data length on the wire */
230     /* XXX - put the packet data / pseudo_header here as well? */
231 } wtapng_simple_packet_t;
232 
233 /* Interface data in private struct */
234 typedef struct interface_info_s {
235     int wtap_encap;
236     guint32 snap_len;
237     guint64 time_units_per_second;
238     int tsprecision;
239     int fcslen;
240 } interface_info_t;
241 
242 typedef struct {
243     guint current_section_number; /**< Section number of the current section being read sequentially */
244     GArray *sections;             /**< Sections found in the capture file. */
245     wtap_new_ipv4_callback_t add_new_ipv4;
246     wtap_new_ipv6_callback_t add_new_ipv6;
247 } pcapng_t;
248 
249 /*
250  * Table for plugins to handle particular block types.
251  *
252  * A handler has a "read" routine and a "write" routine.
253  *
254  * A "read" routine returns a block as a libwiretap record, filling
255  * in the wtap_rec structure with the appropriate record type and
256  * other information, and filling in the supplied Buffer with
257  * data for which there's no place in the wtap_rec structure.
258  *
259  * A "write" routine takes a libwiretap record and Buffer and writes
260  * out a block.
261  */
262 typedef struct {
263     block_reader reader;
264     block_writer writer;
265 } block_handler;
266 
267 static GHashTable *block_handlers;
268 
269 void
register_pcapng_block_type_handler(guint block_type,block_reader reader,block_writer writer)270 register_pcapng_block_type_handler(guint block_type, block_reader reader,
271                                    block_writer writer)
272 {
273     block_handler *handler;
274 
275     /*
276      * Is this a known block type?
277      */
278     switch (block_type) {
279 
280     case BLOCK_TYPE_SHB:
281     case BLOCK_TYPE_IDB:
282     case BLOCK_TYPE_PB:
283     case BLOCK_TYPE_SPB:
284     case BLOCK_TYPE_NRB:
285     case BLOCK_TYPE_ISB:
286     case BLOCK_TYPE_EPB:
287     case BLOCK_TYPE_DSB:
288     case BLOCK_TYPE_CB_COPY:
289     case BLOCK_TYPE_CB_NO_COPY:
290     case BLOCK_TYPE_SYSDIG_EVENT:
291     case BLOCK_TYPE_SYSDIG_EVENT_V2:
292     case BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE:
293     case BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT:
294         /*
295          * Yes; we already handle it, and don't allow a replacement to
296          * be registered (if there's a bug in our code, or there's
297          * something we don't handle in that block, submit a change
298          * to the main Wireshark source).
299          */
300         ws_warning("Attempt to register plugin for block type 0x%08x not allowed",
301                      block_type);
302         return;
303 
304     case BLOCK_TYPE_IRIG_TS:
305     case BLOCK_TYPE_ARINC_429:
306     case BLOCK_TYPE_SYSDIG_EVF:
307     case BLOCK_TYPE_SYSDIG_EVF_V2:
308     case BLOCK_TYPE_SYSDIG_EVF_V2_LARGE:
309         /*
310          * Yes, and we don't already handle it.  Allow a plugin to
311          * handle it.
312          *
313          * (But why not submit the plugin source to Wireshark?)
314          */
315         break;
316 
317     default:
318         /*
319          * No; is it a local block type?
320          */
321          if (!(block_type & 0x80000000)) {
322              /*
323               * No; don't allow a plugin to be registered for it, as
324               * the block type needs to be registered before it's used.
325               */
326             ws_warning("Attempt to register plugin for reserved block type 0x%08x not allowed",
327                          block_type);
328             return;
329          }
330 
331          /*
332           * Yes; allow the registration.
333           */
334          break;
335     }
336 
337     if (block_handlers == NULL) {
338         /*
339          * Create the table of block handlers.
340          *
341          * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
342          * so we use "g_direct_hash()" and "g_direct_equal()".
343          */
344         block_handlers = g_hash_table_new_full(g_direct_hash,
345                                                g_direct_equal,
346                                                NULL, g_free);
347     }
348     handler = g_new(block_handler, 1);
349     handler->reader = reader;
350     handler->writer = writer;
351     g_hash_table_insert(block_handlers, GUINT_TO_POINTER(block_type),
352                               handler);
353 }
354 
355 /*
356  * Tables for plugins to handle particular options for particular block
357  * types.
358  *
359  * An option has three handler routines:
360  *
361  *   An option parser, used when reading an option from a file:
362  *
363  *     The option parser is passed an indication of whether this section
364  *     of the file is byte-swapped, the length of the option, the data of
365  *     the option, a pointer to an error code, and a pointer to a pointer
366  *     variable for an error string.
367  *
368  *     It checks whether the length and option are valid, and, if they
369  *     aren't, returns FALSE, setting the error code to the appropriate
370  *     error (normally WTAP_ERR_BAD_FILE) and the error string to an
371  *     appropriate string indicating the problem.
372  *
373  *     Otherwise, if this section of the file is byte-swapped, it byte-swaps
374  *     multi-byte numerical values, so that it's in the host byte order.
375  *
376  *   An option sizer, used when writing an option to a file:
377  *
378  *     The option sizer is passed the option identifier for the option
379  *     and a wtap_optval_t * that points to the data for the option.
380  *
381  *     It calculates how many bytes the option's data requires, not
382  *     including any padding bytes, and returns that value.
383  *
384  *   An option writer, used when writing an option to a file:
385  *
386  *     The option writer is passed a wtap_dumper * to which the
387  *     option data should be written, the option identifier for
388  *     the option, a wtap_optval_t * that points to the data for
389  *     the option, and an int * into which an error code should
390  *     be stored if an error occurs when writing the option.
391  *
392  *     It returns a gboolean value of TRUE if the attempt to
393  *     write the option succeeds and FALSE if the attempt to
394  *     write the option gets an error.
395  */
396 
397 /*
398  * Block types indices in the table of tables of option handlers.
399  *
400  * Block types are not guaranteed to be sequential, so we map the
401  * block types we support to a sequential set.  Furthermore, all
402  * packet block types have the same set of options.
403  */
404 #define BT_INDEX_SHB        0
405 #define BT_INDEX_IDB        1
406 #define BT_INDEX_PBS        2  /* all packet blocks */
407 #define BT_INDEX_NRB        3
408 #define BT_INDEX_ISB        4
409 #define BT_INDEX_EVT        5
410 #define BT_INDEX_DSB        6
411 
412 #define NUM_BT_INDICES      7
413 
414 typedef struct {
415     option_parser parser;
416     option_sizer sizer;
417     option_writer writer;
418 } option_handler;
419 
420 static GHashTable *option_handlers[NUM_BT_INDICES];
421 
422 static gboolean
get_block_type_index(guint block_type,guint * bt_index)423 get_block_type_index(guint block_type, guint *bt_index)
424 {
425     ws_assert(bt_index);
426 
427     switch (block_type) {
428 
429         case BLOCK_TYPE_SHB:
430             *bt_index = BT_INDEX_SHB;
431             break;
432 
433         case BLOCK_TYPE_IDB:
434             *bt_index = BT_INDEX_IDB;
435             break;
436 
437         case BLOCK_TYPE_PB:
438         case BLOCK_TYPE_EPB:
439         case BLOCK_TYPE_SPB:
440             *bt_index = BT_INDEX_PBS;
441             break;
442 
443         case BLOCK_TYPE_NRB:
444             *bt_index = BT_INDEX_NRB;
445             break;
446 
447         case BLOCK_TYPE_ISB:
448             *bt_index = BT_INDEX_ISB;
449             break;
450 
451         case BLOCK_TYPE_SYSDIG_EVENT:
452         case BLOCK_TYPE_SYSDIG_EVENT_V2:
453         case BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE:
454         /* case BLOCK_TYPE_SYSDIG_EVF: */
455             *bt_index = BT_INDEX_EVT;
456             break;
457 
458         case BLOCK_TYPE_DSB:
459             *bt_index = BT_INDEX_DSB;
460             break;
461 
462         default:
463             /*
464              * This is a block type we don't process; either we ignore it,
465              * in which case the options don't get processed, or there's
466              * a plugin routine to handle it, in which case that routine
467              * will do the option processing itself.
468              *
469              * XXX - report an error?
470              */
471             return FALSE;
472     }
473 
474     return TRUE;
475 }
476 
477 void
register_pcapng_option_handler(guint block_type,guint option_code,option_parser parser,option_sizer sizer,option_writer writer)478 register_pcapng_option_handler(guint block_type, guint option_code,
479                                option_parser parser,
480                                option_sizer sizer,
481                                option_writer writer)
482 {
483     guint bt_index;
484     option_handler *handler;
485 
486     if (!get_block_type_index(block_type, &bt_index))
487         return;
488 
489     if (option_handlers[bt_index] == NULL) {
490         /*
491          * Create the table of option handlers for this block type.
492          *
493          * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
494          * so we use "g_direct_hash()" and "g_direct_equal()".
495          */
496         option_handlers[bt_index] = g_hash_table_new_full(g_direct_hash,
497                                                           g_direct_equal,
498                                                           NULL, g_free);
499     }
500     handler = g_new(option_handler, 1);
501     handler->parser = parser;
502     handler->sizer = sizer;
503     handler->writer = writer;
504     g_hash_table_insert(option_handlers[bt_index],
505                         GUINT_TO_POINTER(option_code), handler);
506 }
507 
508 void
pcapng_process_uint8_option(wtapng_block_t * wblock,guint16 option_code,guint16 option_length,const guint8 * option_content)509 pcapng_process_uint8_option(wtapng_block_t *wblock,
510                             guint16 option_code, guint16 option_length,
511                             const guint8 *option_content)
512 {
513     if (option_length == 1) {
514         /*
515          * If this option can appear only once in a block, this call
516          * will fail on the second and later occurrences of the option;
517          * we silently ignore the failure.
518          */
519         wtap_block_add_uint8_option(wblock->block, option_code, option_content[0]);
520     }
521 }
522 
523 void
pcapng_process_uint32_option(wtapng_block_t * wblock,const section_info_t * section_info,pcapng_opt_byte_order_e byte_order,guint16 option_code,guint16 option_length,const guint8 * option_content)524 pcapng_process_uint32_option(wtapng_block_t *wblock,
525                              const section_info_t *section_info,
526                              pcapng_opt_byte_order_e byte_order,
527                              guint16 option_code, guint16 option_length,
528                              const guint8 *option_content)
529 {
530     guint32 uint32;
531 
532     if (option_length == 4) {
533         /*  Don't cast a guint8 * into a guint32 *--the
534          *  guint8 * may not point to something that's
535          *  aligned correctly.
536          *
537          * XXX - options are aligned on 32-bit boundaries, so, while
538          * it may be true that 64-bit options aren't guaranteed to be
539          * aligned on 64-bit bounaries, it shouldn't be true that 32-bit
540          * options aren't guaranteed to be aligned on 32-bit boundaries.
541          */
542         memcpy(&uint32, option_content, sizeof(guint32));
543         switch (byte_order) {
544 
545         case OPT_SECTION_BYTE_ORDER:
546             if (section_info->byte_swapped) {
547                 uint32 = GUINT32_SWAP_LE_BE(uint32);
548             }
549             break;
550 
551         case OPT_BIG_ENDIAN:
552             uint32 = GUINT32_FROM_BE(uint32);
553             break;
554 
555         case OPT_LITTLE_ENDIAN:
556             uint32 = GUINT32_FROM_LE(uint32);
557             break;
558 
559         default:
560             /*
561              * This should not happen - this is called by pcapng_process_options(),
562              * which returns an error for an invalid byte_order argument, and
563              * otherwise passes the known-to-be-valid byte_order argument to
564              * us.
565              *
566              * Just ignore the option.
567              */
568             return;
569         }
570 
571         /*
572          * If this option can appear only once in a block, this call
573          * will fail on the second and later occurrences of the option;
574          * we silently ignore the failure.
575          */
576         wtap_block_add_uint32_option(wblock->block, option_code, uint32);
577     }
578 }
579 
580 void
pcapng_process_timestamp_option(wtapng_block_t * wblock,const section_info_t * section_info,pcapng_opt_byte_order_e byte_order,guint16 option_code,guint16 option_length,const guint8 * option_content)581 pcapng_process_timestamp_option(wtapng_block_t *wblock,
582                                 const section_info_t *section_info,
583                                 pcapng_opt_byte_order_e byte_order,
584                                 guint16 option_code, guint16 option_length,
585                                 const guint8 *option_content)
586 {
587     if (option_length == 8) {
588         guint32 high, low;
589         guint64 timestamp;
590 
591         /*  Don't cast a guint8 * into a guint32 *--the
592          *  guint8 * may not point to something that's
593          *  aligned correctly.
594          */
595         memcpy(&high, option_content, sizeof(guint32));
596         memcpy(&low, option_content + sizeof(guint32), sizeof(guint32));
597         switch (byte_order) {
598 
599         case OPT_SECTION_BYTE_ORDER:
600             if (section_info->byte_swapped) {
601                 high = GUINT32_SWAP_LE_BE(high);
602                 low = GUINT32_SWAP_LE_BE(low);
603             }
604             break;
605 
606         case OPT_BIG_ENDIAN:
607             high = GUINT32_FROM_BE(high);
608             low = GUINT32_FROM_BE(low);
609             break;
610 
611         case OPT_LITTLE_ENDIAN:
612             high = GUINT32_FROM_LE(high);
613             low = GUINT32_FROM_LE(low);
614             break;
615 
616         default:
617             /*
618              * This should not happen - this is called by pcapng_process_options(),
619              * which returns an error for an invalid byte_order argument, and
620              * otherwise passes the known-to-be-valid byte_order argument to
621              * us.
622              *
623              * Just ignore the option.
624              */
625             return;
626         }
627         timestamp = (guint64)high;
628         timestamp <<= 32;
629         timestamp += (guint64)low;
630         /*
631          * If this option can appear only once in a block, this call
632          * will fail on the second and later occurrences of the option;
633          * we silently ignore the failure.
634          */
635         wtap_block_add_uint64_option(wblock->block, option_code, timestamp);
636     }
637 }
638 
639 void
pcapng_process_uint64_option(wtapng_block_t * wblock,const section_info_t * section_info,pcapng_opt_byte_order_e byte_order,guint16 option_code,guint16 option_length,const guint8 * option_content)640 pcapng_process_uint64_option(wtapng_block_t *wblock,
641                              const section_info_t *section_info,
642                              pcapng_opt_byte_order_e byte_order,
643                              guint16 option_code, guint16 option_length,
644                              const guint8 *option_content)
645 {
646     guint64 uint64;
647 
648     if (option_length == 8) {
649         /*  Don't cast a guint8 * into a guint64 *--the
650          *  guint8 * may not point to something that's
651          *  aligned correctly.
652          */
653         memcpy(&uint64, option_content, sizeof(guint64));
654         switch (byte_order) {
655 
656         case OPT_SECTION_BYTE_ORDER:
657             if (section_info->byte_swapped) {
658                 uint64 = GUINT64_SWAP_LE_BE(uint64);
659             }
660             break;
661 
662         case OPT_BIG_ENDIAN:
663             uint64 = GUINT64_FROM_BE(uint64);
664             break;
665 
666         case OPT_LITTLE_ENDIAN:
667             uint64 = GUINT64_FROM_LE(uint64);
668             break;
669 
670         default:
671             /*
672              * This should not happen - this is called by pcapng_process_options(),
673              * which returns an error for an invalid byte_order argument, and
674              * otherwise passes the known-to-be-valid byte_order argument to
675              * us.
676              *
677              * Just ignore the option.
678              */
679             return;
680         }
681 
682         /*
683          * If this option can appear only once in a block, this call
684          * will fail on the second and later occurrences of the option;
685          * we silently ignore the failure.
686          */
687         wtap_block_add_uint64_option(wblock->block, option_code, uint64);
688     }
689 }
690 
691 void
pcapng_process_string_option(wtapng_block_t * wblock,guint16 option_code,guint16 option_length,const guint8 * option_content)692 pcapng_process_string_option(wtapng_block_t *wblock, guint16 option_code,
693                              guint16 option_length, const guint8 *option_content)
694 {
695     wtap_block_add_string_option(wblock->block, option_code, (const char *)option_content, option_length);
696 }
697 
698 void
pcapng_process_bytes_option(wtapng_block_t * wblock,guint16 option_code,guint16 option_length,const guint8 * option_content)699 pcapng_process_bytes_option(wtapng_block_t *wblock, guint16 option_code,
700                             guint16 option_length, const guint8 *option_content)
701 {
702     wtap_block_add_bytes_option(wblock->block, option_code, (const char *)option_content, option_length);
703 }
704 
705 static gboolean
pcapng_process_nflx_custom_option(wtapng_block_t * wblock,section_info_t * section_info,const guint8 * value,guint16 length)706 pcapng_process_nflx_custom_option(wtapng_block_t *wblock,
707                                   section_info_t *section_info,
708                                   const guint8 *value, guint16 length)
709 {
710     struct nflx_dumpinfo dumpinfo;
711     guint32 type, version;
712     gint64 dumptime, temp;
713 
714     if (length < 4) {
715         ws_debug("Length = %u too small", length);
716         return FALSE;
717     }
718     memcpy(&type, value, sizeof(guint32));
719     type = GUINT32_FROM_LE(type);
720     value += 4;
721     length -= 4;
722     ws_debug("Handling type = %u, payload of length = %u", type, length);
723     switch (type) {
724     case NFLX_OPT_TYPE_VERSION:
725         if (length == sizeof(guint32)) {
726             memcpy(&version, value, sizeof(guint32));
727             version = GUINT32_FROM_LE(version);
728             ws_debug("BBLog version: %u", version);
729             section_info->bblog_version = version;
730         } else {
731             ws_debug("BBLog version parameter has strange length: %u", length);
732         }
733         break;
734     case NFLX_OPT_TYPE_TCPINFO:
735         ws_debug("BBLog tcpinfo of length: %u", length);
736         if (wblock->type == BLOCK_TYPE_CB_COPY) {
737             ws_buffer_assure_space(wblock->frame_buffer, length);
738             wblock->rec->rec_header.custom_block_header.length = length + 4;
739             memcpy(ws_buffer_start_ptr(wblock->frame_buffer), value, length);
740             memcpy(&temp, value, sizeof(guint64));
741             temp = GUINT64_FROM_LE(temp);
742             wblock->rec->ts.secs = section_info->bblog_offset_tv_sec + temp;
743             memcpy(&temp, value + sizeof(guint64), sizeof(guint64));
744             temp = GUINT64_FROM_LE(temp);
745             wblock->rec->ts.nsecs = (guint32)(section_info->bblog_offset_tv_usec + temp) * 1000;
746             if (wblock->rec->ts.nsecs >= 1000000000) {
747                 wblock->rec->ts.secs += 1;
748                 wblock->rec->ts.nsecs -= 1000000000;
749             }
750             wblock->rec->presence_flags = WTAP_HAS_TS;
751             wblock->internal = FALSE;
752         }
753         break;
754     case NFLX_OPT_TYPE_DUMPINFO:
755         if (length == sizeof(struct nflx_dumpinfo)) {
756             memcpy(&dumpinfo, value, sizeof(struct nflx_dumpinfo));
757             section_info->bblog_offset_tv_sec = GUINT64_FROM_LE(dumpinfo.tlh_offset_tv_sec);
758             section_info->bblog_offset_tv_usec = GUINT64_FROM_LE(dumpinfo.tlh_offset_tv_usec);
759             ws_debug("BBLog dumpinfo time offset: %" G_GUINT64_FORMAT, section_info->bblog_offset_tv_sec);
760         } else {
761             ws_debug("BBLog dumpinfo parameter has strange length: %u", length);
762         }
763         break;
764     case NFLX_OPT_TYPE_DUMPTIME:
765         if (length == sizeof(gint64)) {
766             memcpy(&dumptime, value, sizeof(gint64));
767             dumptime = GINT64_FROM_LE(dumptime);
768             ws_debug("BBLog dumpinfo time offset: %" G_GUINT64_FORMAT, dumptime);
769         } else {
770             ws_debug("BBLog dumptime parameter has strange length: %u", length);
771         }
772         break;
773     case NFLX_OPT_TYPE_STACKNAME:
774         if (length >= 2) {
775             ws_debug("BBLog stack name: %.*s(%u)", length - 1, value + 1, *(guint8 *)value);
776         } else {
777             ws_debug("BBLog stack name has strange length: %u)", length);
778         }
779         break;
780     default:
781         ws_debug("Unknown type: %u, length: %u", type, length);
782         break;
783     }
784     return wtap_block_add_nflx_custom_option(wblock->block, type, value, length) == WTAP_OPTTYPE_SUCCESS;
785 }
786 
787 static gboolean
pcapng_process_custom_option(wtapng_block_t * wblock,section_info_t * section_info,guint16 option_code,guint16 option_length,const guint8 * option_content,pcapng_opt_byte_order_e byte_order,int * err,gchar ** err_info)788 pcapng_process_custom_option(wtapng_block_t *wblock,
789                              section_info_t *section_info,
790                              guint16 option_code, guint16 option_length,
791                              const guint8 *option_content,
792                              pcapng_opt_byte_order_e byte_order,
793                              int *err, gchar **err_info)
794 {
795     guint32 pen;
796     gboolean ret;
797 
798     if (option_length < 4) {
799         *err = WTAP_ERR_BAD_FILE;
800         *err_info = g_strdup_printf("pcapng: option length (%d) too small for custom option",
801                                     option_length);
802         return FALSE;
803     }
804     memcpy(&pen, option_content, sizeof(guint32));
805     switch (byte_order) {
806 
807     case OPT_SECTION_BYTE_ORDER:
808         if (section_info->byte_swapped) {
809             pen = GUINT32_SWAP_LE_BE(pen);
810         }
811         break;
812 
813     case OPT_BIG_ENDIAN:
814         pen = GUINT32_FROM_BE(pen);
815         break;
816 
817     case OPT_LITTLE_ENDIAN:
818         pen = GUINT32_FROM_LE(pen);
819         break;
820 
821     default:
822         /*
823          * This should not happen - this is called by pcapng_process_options(),
824          * which returns an error for an invalid byte_order argument, and
825          * otherwise passes the known-to-be-valid byte_order argument to
826          * us.
827          */
828         *err = WTAP_ERR_INTERNAL;
829         *err_info = g_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_custom_option()",
830                                     byte_order);
831         return FALSE;
832     }
833     switch (pen) {
834     case PEN_NFLX:
835         ret = pcapng_process_nflx_custom_option(wblock, section_info, option_content + 4, option_length - 4);
836         break;
837     default:
838         ret = wtap_block_add_custom_option(wblock->block, option_code, pen, option_content + 4, option_length - 4) == WTAP_OPTTYPE_SUCCESS;
839         ws_debug("Custom option type 0x%04x with unknown pen %u with custom data of length %u", option_code, pen, option_length - 4);
840         break;
841     }
842     ws_debug("returning %d", ret);
843     return ret;
844 }
845 
846 #ifdef HAVE_PLUGINS
847 static gboolean
pcapng_process_unhandled_option(wtapng_block_t * wblock,guint bt_index,const section_info_t * section_info,guint16 option_code,guint16 option_length,const guint8 * option_content,int * err,gchar ** err_info)848 pcapng_process_unhandled_option(wtapng_block_t *wblock,
849                                 guint bt_index,
850                                 const section_info_t *section_info,
851                                 guint16 option_code, guint16 option_length,
852                                 const guint8 *option_content,
853                                 int *err, gchar **err_info)
854 {
855     option_handler *handler;
856 
857     /*
858      * Do we have a handler for this packet block option code?
859      */
860     if (option_handlers[bt_index] != NULL &&
861         (handler = (option_handler *)g_hash_table_lookup(option_handlers[bt_index],
862                                                          GUINT_TO_POINTER((guint)option_code))) != NULL) {
863         /* Yes - call the handler. */
864         if (!handler->parser(wblock->block, section_info->byte_swapped,
865                              option_length, option_content, err, err_info))
866             /* XXX - free anything? */
867             return FALSE;
868     }
869     return TRUE;
870 }
871 #else
872 static gboolean
pcapng_process_unhandled_option(wtapng_block_t * wblock _U_,guint bt_index _U_,const section_info_t * section_info _U_,guint16 option_code _U_,guint16 option_length _U_,const guint8 * option_content _U_,int * err _U_,gchar ** err_info _U_)873 pcapng_process_unhandled_option(wtapng_block_t *wblock _U_,
874                                 guint bt_index _U_,
875                                 const section_info_t *section_info _U_,
876                                 guint16 option_code _U_, guint16 option_length _U_,
877                                 const guint8 *option_content _U_,
878                                 int *err _U_, gchar **err_info _U_)
879 {
880     return TRUE;
881 }
882 #endif
883 
884 gboolean
pcapng_process_options(FILE_T fh,wtapng_block_t * wblock,section_info_t * section_info,guint opt_cont_buf_len,gboolean (* process_option)(wtapng_block_t *,const section_info_t *,guint16,guint16,const guint8 *,int *,gchar **),pcapng_opt_byte_order_e byte_order,int * err,gchar ** err_info)885 pcapng_process_options(FILE_T fh, wtapng_block_t *wblock,
886                        section_info_t *section_info,
887                        guint opt_cont_buf_len,
888                        gboolean (*process_option)(wtapng_block_t *,
889                                                   const section_info_t *,
890                                                   guint16, guint16,
891                                                   const guint8 *,
892                                                   int *, gchar **),
893                        pcapng_opt_byte_order_e byte_order,
894                        int *err, gchar **err_info)
895 {
896     guint8 *option_content; /* Allocate as large as the options block */
897     guint opt_bytes_remaining;
898     const guint8 *option_ptr;
899     const pcapng_option_header_t *oh;
900     guint16 option_code, option_length;
901     guint rounded_option_length;
902 
903     ws_debug("Options %u bytes", opt_cont_buf_len);
904     if (opt_cont_buf_len == 0) {
905         /* No options, so nothing to do */
906         return TRUE;
907     }
908 
909     /* Allocate enough memory to hold all options */
910     option_content = (guint8 *)g_try_malloc(opt_cont_buf_len);
911     if (option_content == NULL) {
912         *err = ENOMEM;  /* we assume we're out of memory */
913         return FALSE;
914     }
915 
916     /* Read all the options into the buffer */
917     if (!wtap_read_bytes(fh, option_content, opt_cont_buf_len, err, err_info)) {
918         ws_debug("failed to read options");
919         g_free(option_content);
920         return FALSE;
921     }
922 
923     /*
924      * Now process them.
925      * option_ptr starts out aligned on at least a 4-byte boundary, as
926      * that's what g_try_malloc() gives us, and each option is padded
927      * to a length that's a multiple of 4 bytes, so it remains aligned.
928      */
929     option_ptr = &option_content[0];
930     opt_bytes_remaining = opt_cont_buf_len;
931     while (opt_bytes_remaining != 0) {
932         /* Get option header. */
933         oh = (const pcapng_option_header_t *)(const void *)option_ptr;
934         /* Sanity check: don't run past the end of the options. */
935         if (sizeof (*oh) > opt_bytes_remaining) {
936             *err = WTAP_ERR_BAD_FILE;
937             *err_info = g_strdup_printf("pcapng: Not enough data for option header");
938             g_free(option_content);
939             return FALSE;
940         }
941         option_code = oh->option_code;
942         option_length = oh->option_length;
943         switch (byte_order) {
944 
945         case OPT_SECTION_BYTE_ORDER:
946             if (section_info->byte_swapped) {
947                 option_code = GUINT16_SWAP_LE_BE(option_code);
948                 option_length = GUINT16_SWAP_LE_BE(option_length);
949             }
950             break;
951 
952         case OPT_BIG_ENDIAN:
953             option_code = GUINT16_FROM_BE(option_code);
954             option_length = GUINT16_FROM_BE(option_length);
955             break;
956 
957         case OPT_LITTLE_ENDIAN:
958             option_code = GUINT16_FROM_LE(option_code);
959             option_length = GUINT16_FROM_LE(option_length);
960             break;
961 
962         default:
963             /* Don't do that. */
964             *err = WTAP_ERR_INTERNAL;
965             *err_info = g_strdup_printf("pcapng: invalid byte order %d passed to pcapng_process_options()",
966                                         byte_order);
967             return FALSE;
968         }
969         option_ptr += sizeof (*oh); /* 4 bytes, so it remains aligned */
970         opt_bytes_remaining -= sizeof (*oh);
971 
972         /* Round up option length to a multiple of 4. */
973         rounded_option_length = ROUND_TO_4BYTE(option_length);
974 
975         /* Sanity check: don't run past the end of the options. */
976         if (rounded_option_length > opt_bytes_remaining) {
977             *err = WTAP_ERR_BAD_FILE;
978             *err_info = g_strdup_printf("pcapng: Not enough data to handle option of length %u",
979                                         option_length);
980             g_free(option_content);
981             return FALSE;
982         }
983 
984         switch (option_code) {
985             case(OPT_EOFOPT): /* opt_endofopt */
986                 if (opt_bytes_remaining != 0) {
987                     ws_debug("%u bytes after opt_endofopt", opt_bytes_remaining);
988                 }
989                 /* padding should be ok here, just get out of this */
990                 opt_bytes_remaining = rounded_option_length;
991                 break;
992             case(OPT_COMMENT):
993                 pcapng_process_string_option(wblock, option_code, option_length,
994                                              option_ptr);
995                 break;
996             case(OPT_CUSTOM_STR_COPY):
997             case(OPT_CUSTOM_BIN_COPY):
998             case(OPT_CUSTOM_STR_NO_COPY):
999             case(OPT_CUSTOM_BIN_NO_COPY):
1000                 if (!pcapng_process_custom_option(wblock, section_info,
1001                                                   option_code, option_length,
1002                                                   option_ptr,
1003                                                   byte_order,
1004                                                   err, err_info)) {
1005                     g_free(option_content);
1006                     return FALSE;
1007                 }
1008                 break;
1009 
1010             default:
1011                 if (process_option == NULL ||
1012                     !(*process_option)(wblock, (const section_info_t *)section_info, option_code,
1013                                        option_length, option_ptr,
1014                                        err, err_info)) {
1015                     g_free(option_content);
1016                     return FALSE;
1017                 }
1018         }
1019         option_ptr += rounded_option_length; /* multiple of 4 bytes, so it remains aligned */
1020         opt_bytes_remaining -= rounded_option_length;
1021     }
1022     g_free(option_content);
1023     return TRUE;
1024 }
1025 
1026 typedef enum {
1027     PCAPNG_BLOCK_OK,
1028     PCAPNG_BLOCK_NOT_SHB,
1029     PCAPNG_BLOCK_ERROR
1030 } block_return_val;
1031 
1032 static gboolean
pcapng_process_section_header_block_option(wtapng_block_t * wblock,const section_info_t * section_info,guint16 option_code,guint16 option_length,const guint8 * option_content,int * err,gchar ** err_info)1033 pcapng_process_section_header_block_option(wtapng_block_t *wblock,
1034                                            const section_info_t *section_info,
1035                                            guint16 option_code,
1036                                            guint16 option_length,
1037                                            const guint8 *option_content,
1038                                            int *err, gchar **err_info)
1039 {
1040     /*
1041      * Handle option content.
1042      *
1043      * ***DO NOT*** add any items to this table that are not
1044      * standardized option codes in either section 3.5 "Options"
1045      * of the current pcapng spec, at
1046      *
1047      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-options
1048      *
1049      * or in the list of options in section 4.1 "Section Header Block"
1050      * of the current pcapng spec, at
1051      *
1052      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-section-header-block
1053      *
1054      * All option codes in this switch statement here must be listed
1055      * in one of those places as standardized option types.
1056      */
1057     switch (option_code) {
1058         case(OPT_SHB_HARDWARE):
1059             pcapng_process_string_option(wblock, option_code, option_length,
1060                                          option_content);
1061             break;
1062         case(OPT_SHB_OS):
1063             pcapng_process_string_option(wblock, option_code, option_length,
1064                                          option_content);
1065             break;
1066         case(OPT_SHB_USERAPPL):
1067             pcapng_process_string_option(wblock, option_code, option_length,
1068                                          option_content);
1069             break;
1070         default:
1071             if (!pcapng_process_unhandled_option(wblock, BT_INDEX_SHB,
1072                                                  section_info, option_code,
1073                                                  option_length, option_content,
1074                                                  err, err_info))
1075                 return FALSE;
1076             break;
1077     }
1078     return TRUE;
1079 }
1080 
1081 static block_return_val
pcapng_read_section_header_block(FILE_T fh,pcapng_block_header_t * bh,section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)1082 pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
1083                                  section_info_t *section_info,
1084                                  wtapng_block_t *wblock,
1085                                  int *err, gchar **err_info)
1086 {
1087     gboolean byte_swapped;
1088     guint16 version_major;
1089     guint16 version_minor;
1090     guint opt_cont_buf_len;
1091     pcapng_section_header_block_t shb;
1092     wtapng_section_mandatory_t* section_data;
1093 
1094     /* read fixed-length part of the block */
1095     if (!wtap_read_bytes(fh, &shb, sizeof shb, err, err_info)) {
1096         /*
1097          * Even if this is just a short read, report it as an error.
1098          * It *is* a read error except when we're doing an open, in
1099          * which case it's a "this isn't a pcapng file" indication.
1100          * The open code will call us directly, and treat a short
1101          * read error as such an indication.
1102          */
1103         return PCAPNG_BLOCK_ERROR;
1104     }
1105 
1106     /* is the magic number one we expect? */
1107     switch (shb.magic) {
1108         case(0x1A2B3C4D):
1109             /* this seems pcapng with correct byte order */
1110             byte_swapped                = FALSE;
1111             version_major               = shb.version_major;
1112             version_minor               = shb.version_minor;
1113 
1114             ws_debug("SHB (our byte order) V%u.%u, len %u",
1115                      version_major, version_minor, bh->block_total_length);
1116             break;
1117         case(0x4D3C2B1A):
1118             /* this seems pcapng with swapped byte order */
1119             byte_swapped                = TRUE;
1120             version_major               = GUINT16_SWAP_LE_BE(shb.version_major);
1121             version_minor               = GUINT16_SWAP_LE_BE(shb.version_minor);
1122 
1123             /* tweak the block length to meet current swapping that we know now */
1124             bh->block_total_length  = GUINT32_SWAP_LE_BE(bh->block_total_length);
1125 
1126             ws_debug("SHB (byte-swapped) V%u.%u, len %u",
1127                      version_major, version_minor, bh->block_total_length);
1128             break;
1129         default:
1130             /* Not a "pcapng" magic number we know about. */
1131             *err = WTAP_ERR_BAD_FILE;
1132             *err_info = g_strdup_printf("pcapng: unknown byte-order magic number 0x%08x", shb.magic);
1133 
1134             /*
1135              * See above comment about PCAPNG_BLOCK_NOT_SHB.
1136              */
1137             return PCAPNG_BLOCK_NOT_SHB;
1138     }
1139 
1140     /*
1141      * Add padding bytes to the block total length.
1142      *
1143      * See the comment in pcapng_read_block() for a long discussion
1144      * of this.
1145      */
1146     bh->block_total_length = ROUND_TO_4BYTE(bh->block_total_length);
1147 
1148     /*
1149      * Is this block long enough to be an SHB?
1150      */
1151     if (bh->block_total_length < MIN_SHB_SIZE) {
1152         /*
1153          * No.
1154          */
1155         *err = WTAP_ERR_BAD_FILE;
1156         *err_info = g_strdup_printf("pcapng: total block length %u of an SHB is less than the minimum SHB size %u",
1157                                     bh->block_total_length, MIN_SHB_SIZE);
1158         return PCAPNG_BLOCK_ERROR;
1159     }
1160 
1161     /* OK, at this point we assume it's a pcapng file.
1162 
1163        Don't try to allocate memory for a huge number of options, as
1164        that might fail and, even if it succeeds, it might not leave
1165        any address space or memory+backing store for anything else.
1166 
1167        We do that by imposing a maximum block size of MAX_BLOCK_SIZE.
1168        We check for this *after* checking the SHB for its byte
1169        order magic number, so that non-pcapng files are less
1170        likely to be treated as bad pcapng files. */
1171     if (bh->block_total_length > MAX_BLOCK_SIZE) {
1172         *err = WTAP_ERR_BAD_FILE;
1173         *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
1174                                     bh->block_total_length, MAX_BLOCK_SIZE);
1175         return PCAPNG_BLOCK_ERROR;
1176     }
1177 
1178     /* Currently only SHB versions 1.0 and 1.2 are supported;
1179        version 1.2 is treated as being the same as version 1.0.
1180        See the current version of the pcapng specification.
1181 
1182        Version 1.2 is written by some programs that write additional
1183        block types (which can be read by any code that handles them,
1184        regarless of whether the minor version if 0 or 2, so that's
1185        not a reason to change the minor version number).
1186 
1187        XXX - the pcapng specification says that readers should
1188        just ignore sections with an unsupported version number;
1189        presumably they can also report an error if they skip
1190        all the way to the end of the file without finding
1191        any versions that they support. */
1192     if (!(version_major == 1 &&
1193           (version_minor == 0 || version_minor == 2))) {
1194         *err = WTAP_ERR_UNSUPPORTED;
1195         *err_info = g_strdup_printf("pcapng: unknown SHB version %u.%u",
1196                                     version_major, version_minor);
1197         return PCAPNG_BLOCK_ERROR;
1198     }
1199 
1200     section_info->byte_swapped  = byte_swapped;
1201     section_info->version_major = version_major;
1202     section_info->version_minor = version_minor;
1203 
1204     /*
1205      * Set wblock->block to a newly-allocated section header block.
1206      */
1207     wblock->block = wtap_block_create(WTAP_BLOCK_SECTION);
1208 
1209     /*
1210      * Set the mandatory values for the block.
1211      */
1212     section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1213     /* 64bit section_length (currently unused) */
1214     if (section_info->byte_swapped) {
1215         section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
1216     } else {
1217         section_data->section_length = shb.section_length;
1218     }
1219 
1220     /* Options */
1221     opt_cont_buf_len = bh->block_total_length - MIN_SHB_SIZE;
1222     if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1223                                 pcapng_process_section_header_block_option,
1224                                 OPT_SECTION_BYTE_ORDER, err, err_info))
1225         return PCAPNG_BLOCK_ERROR;
1226 
1227     /*
1228      * We don't return these to the caller in pcapng_read().
1229      */
1230     wblock->internal = TRUE;
1231 
1232     return PCAPNG_BLOCK_OK;
1233 }
1234 
1235 static gboolean
pcapng_process_if_descr_block_option(wtapng_block_t * wblock,const section_info_t * section_info,guint16 option_code,guint16 option_length,const guint8 * option_content,int * err,gchar ** err_info)1236 pcapng_process_if_descr_block_option(wtapng_block_t *wblock,
1237                                      const section_info_t *section_info,
1238                                      guint16 option_code,
1239                                      guint16 option_length,
1240                                      const guint8 *option_content,
1241                                      int *err, gchar **err_info)
1242 {
1243     if_filter_opt_t if_filter;
1244 
1245     /*
1246      * Handle option content.
1247      *
1248      * ***DO NOT*** add any items to this table that are not
1249      * standardized option codes in either section 3.5 "Options"
1250      * of the current pcapng spec, at
1251      *
1252      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-options
1253      *
1254      * or in the list of options in section 4.1 "Section Header Block"
1255      * of the current pcapng spec, at
1256      *
1257      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-section-header-block
1258      *
1259      * All option codes in this switch statement here must be listed
1260      * in one of those places as standardized option types.
1261      */
1262     switch (option_code) {
1263         case(OPT_IDB_NAME): /* if_name */
1264             pcapng_process_string_option(wblock, option_code, option_length,
1265                                          option_content);
1266             break;
1267         case(OPT_IDB_DESCRIPTION): /* if_description */
1268             pcapng_process_string_option(wblock, option_code, option_length,
1269                                          option_content);
1270             break;
1271         case(OPT_IDB_SPEED): /* if_speed */
1272             pcapng_process_uint64_option(wblock, section_info,
1273                                          OPT_SECTION_BYTE_ORDER,
1274                                          option_code, option_length,
1275                                          option_content);
1276             break;
1277         case(OPT_IDB_TSRESOL): /* if_tsresol */
1278             pcapng_process_uint8_option(wblock, option_code, option_length,
1279                                         option_content);
1280             break;
1281             /*
1282              * if_tzone      10  Time zone for GMT support (TODO: specify better). TODO: give a good example
1283              */
1284         case(OPT_IDB_FILTER): /* if_filter */
1285             if (option_length < 1) {
1286                 *err = WTAP_ERR_BAD_FILE;
1287                 *err_info = g_strdup_printf("pcapng: packet block verdict option length %u is < 1",
1288                                             option_length);
1289                 /* XXX - free anything? */
1290                 return FALSE;
1291             }
1292             /* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
1293              * or BPF bytecode.
1294              */
1295             if (option_content[0] == 0) {
1296                 if_filter.type = if_filter_pcap;
1297                 if_filter.data.filter_str = g_strndup((char *)option_content+1, option_length-1);
1298                 ws_debug("filter_str %s option_length %u",
1299                          if_filter.data.filter_str, option_length);
1300                 /* Fails with multiple options; we silently ignore the failure */
1301                 wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1302                 g_free(if_filter.data.filter_str);
1303             } else if (option_content[0] == 1) {
1304                 /*
1305                  * XXX - byte-swap the code and k fields
1306                  * of each instruction as needed!
1307                  *
1308                  * XXX - what if option_length-1 is not a
1309                  * multiple of the size of a BPF instruction?
1310                  */
1311                 guint num_insns;
1312                 const guint8 *insn_in;
1313 
1314                 if_filter.type = if_filter_bpf;
1315                 num_insns = (option_length-1)/8;
1316                 insn_in = option_content+1;
1317                 if_filter.data.bpf_prog.bpf_prog_len = num_insns;
1318                 if_filter.data.bpf_prog.bpf_prog = g_new(wtap_bpf_insn_t, num_insns);
1319                 for (guint i = 0; i < num_insns; i++) {
1320                     wtap_bpf_insn_t *insn = &if_filter.data.bpf_prog.bpf_prog[i];
1321 
1322                     memcpy(&insn->code, insn_in, 2);
1323                     if (section_info->byte_swapped)
1324                         insn->code = GUINT16_SWAP_LE_BE(insn->code);
1325                     insn_in += 2;
1326                     memcpy(&insn->jt, insn_in, 1);
1327                     insn_in += 1;
1328                     memcpy(&insn->jf, insn_in, 1);
1329                     insn_in += 1;
1330                     memcpy(&insn->k, insn_in, 4);
1331                     if (section_info->byte_swapped)
1332                         insn->k = GUINT32_SWAP_LE_BE(insn->k);
1333                     insn_in += 4;
1334                 }
1335                 /* Fails with multiple options; we silently ignore the failure */
1336                 wtap_block_add_if_filter_option(wblock->block, option_code, &if_filter);
1337                 g_free(if_filter.data.bpf_prog.bpf_prog);
1338             }
1339             break;
1340         case(OPT_IDB_OS): /* if_os */
1341             /*
1342              * if_os         12  A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
1343              * This can be different from the same information that can be contained by the Section Header Block (Section 3.1 (Section Header Block (mandatory)))
1344              * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
1345              */
1346             pcapng_process_string_option(wblock, option_code, option_length,
1347                                          option_content);
1348             break;
1349         case(OPT_IDB_FCSLEN): /* if_fcslen */
1350             pcapng_process_uint8_option(wblock, option_code, option_length,
1351                                         option_content);
1352             break;
1353         case(OPT_IDB_HARDWARE): /* if_hardware */
1354             pcapng_process_string_option(wblock, option_code, option_length,
1355                                          option_content);
1356             break;
1357         /* TODO: process these! */
1358         case(OPT_IDB_IP4ADDR):
1359             /*
1360              * Interface network address and netmask. This option can be
1361              * repeated multiple times within the same Interface
1362              * Description Block when multiple IPv4 addresses are assigned
1363              * to the interface. 192 168 1 1 255 255 255 0
1364              */
1365             break;
1366         case(OPT_IDB_IP6ADDR):
1367             /*
1368              * Interface network address and prefix length (stored in the
1369              * last byte). This option can be repeated multiple times
1370              * within the same Interface Description Block when multiple
1371              * IPv6 addresses are assigned to the interface.
1372              * 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in
1373              * hex) as "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44
1374              * 40"
1375              */
1376             break;
1377         case(OPT_IDB_MACADDR):
1378             /*
1379              * Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
1380              */
1381             break;
1382         case(OPT_IDB_EUIADDR):
1383             /*
1384              * Interface Hardware EUI address (64 bits), if available.
1385              * TODO: give a good example
1386              */
1387              break;
1388         case(OPT_IDB_TZONE):
1389             /*
1390              * Time zone for GMT support. TODO: specify better.
1391              * TODO: give a good example.
1392              */
1393              break;
1394         case(OPT_IDB_TSOFFSET):
1395             /*
1396              * A 64 bits integer value that specifies an offset (in
1397              * seconds) that must be added to the timestamp of each packet
1398              * to obtain the absolute timestamp of a packet. If the option
1399              * is missing, the timestamps stored in the packet must be
1400              * considered absolute timestamps. The time zone of the offset
1401              * can be specified with the option if_tzone.
1402              *
1403              * TODO: won't a if_tsoffset_low for fractional second offsets
1404              * be useful for highly synchronized capture systems? 1234
1405              */
1406              break;
1407         default:
1408             if (!pcapng_process_unhandled_option(wblock, BT_INDEX_IDB,
1409                                                  section_info, option_code,
1410                                                  option_length, option_content,
1411                                                  err, err_info))
1412                 return FALSE;
1413             break;
1414     }
1415     return TRUE;
1416 }
1417 
1418 /* "Interface Description Block" */
1419 static gboolean
pcapng_read_if_descr_block(wtap * wth,FILE_T fh,pcapng_block_header_t * bh,section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)1420 pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
1421                            section_info_t *section_info,
1422                            wtapng_block_t *wblock, int *err, gchar **err_info)
1423 {
1424     guint64 time_units_per_second = 1000000; /* default = 10^6 */
1425     guint   opt_cont_buf_len;
1426     pcapng_interface_description_block_t idb;
1427     wtapng_if_descr_mandatory_t* if_descr_mand;
1428     guint   link_type;
1429     guint8  if_tsresol;
1430 
1431     /*
1432      * Is this block long enough to be an IDB?
1433      */
1434     if (bh->block_total_length < MIN_IDB_SIZE) {
1435         /*
1436          * No.
1437          */
1438         *err = WTAP_ERR_BAD_FILE;
1439         *err_info = g_strdup_printf("pcapng: total block length %u of an IDB is less than the minimum IDB size %u",
1440                                     bh->block_total_length, MIN_IDB_SIZE);
1441         return FALSE;
1442     }
1443 
1444     /* read block content */
1445     if (!wtap_read_bytes(fh, &idb, sizeof idb, err, err_info)) {
1446         ws_debug("failed to read IDB");
1447         return FALSE;
1448     }
1449 
1450     /*
1451      * Set wblock->block to a newly-allocated interface ID and information
1452      * block.
1453      */
1454     wblock->block = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
1455 
1456     /*
1457      * Set the mandatory values for the block.
1458      */
1459     if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
1460     if (section_info->byte_swapped) {
1461         link_type = GUINT16_SWAP_LE_BE(idb.linktype);
1462         if_descr_mand->snap_len  = GUINT32_SWAP_LE_BE(idb.snaplen);
1463     } else {
1464         link_type = idb.linktype;
1465         if_descr_mand->snap_len  = idb.snaplen;
1466     }
1467 
1468     if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(link_type);
1469 
1470     ws_debug("IDB link_type %u (%s), snap %u",
1471              link_type,
1472              wtap_encap_description(if_descr_mand->wtap_encap),
1473              if_descr_mand->snap_len);
1474 
1475     if (if_descr_mand->snap_len > wtap_max_snaplen_for_encap(if_descr_mand->wtap_encap)) {
1476         /*
1477          * We do not use this value, maybe we should check the
1478          * snap_len of the packets against it. For now, only warn.
1479          */
1480         ws_debug("snapshot length %u unrealistic.",
1481                  if_descr_mand->snap_len);
1482         /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;*/
1483     }
1484 
1485     /* Options */
1486     opt_cont_buf_len = bh->block_total_length - MIN_IDB_SIZE;
1487     if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
1488                                 pcapng_process_if_descr_block_option,
1489                                 OPT_SECTION_BYTE_ORDER, err, err_info))
1490         return FALSE;
1491 
1492     /*
1493      * Did we get a time stamp precision option?
1494      */
1495     if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_TSRESOL,
1496                                           &if_tsresol) == WTAP_OPTTYPE_SUCCESS) {
1497         /*
1498          * Yes.  Set time_units_per_second appropriately.
1499          */
1500         guint64 base;
1501         guint64 result;
1502         guint8 i, exponent;
1503 
1504         if (if_tsresol & 0x80) {
1505             base = 2;
1506         } else {
1507             base = 10;
1508         }
1509         exponent = (guint8)(if_tsresol & 0x7f);
1510         if (((base == 2) && (exponent < 64)) || ((base == 10) && (exponent < 20))) {
1511             result = 1;
1512             for (i = 0; i < exponent; i++) {
1513                 result *= base;
1514             }
1515             time_units_per_second = result;
1516         } else {
1517             time_units_per_second = G_MAXUINT64;
1518         }
1519         if (time_units_per_second > (((guint64)1) << 32)) {
1520             ws_debug("time conversion might be inaccurate");
1521         }
1522     }
1523 
1524     /*
1525      * Set the time units per second for this interface.
1526      */
1527     if_descr_mand->time_units_per_second = time_units_per_second;
1528     if (time_units_per_second >= 1000000000)
1529         if_descr_mand->tsprecision = WTAP_TSPREC_NSEC;
1530     else if (time_units_per_second >= 1000000)
1531         if_descr_mand->tsprecision = WTAP_TSPREC_USEC;
1532     else if (time_units_per_second >= 1000)
1533         if_descr_mand->tsprecision = WTAP_TSPREC_MSEC;
1534     else if (time_units_per_second >= 100)
1535         if_descr_mand->tsprecision = WTAP_TSPREC_CSEC;
1536     else if (time_units_per_second >= 10)
1537         if_descr_mand->tsprecision = WTAP_TSPREC_DSEC;
1538     else
1539         if_descr_mand->tsprecision = WTAP_TSPREC_SEC;
1540 
1541     /*
1542      * If the per-file encapsulation isn't known, set it to this
1543      * interface's encapsulation.
1544      *
1545      * If it *is* known, and it isn't this interface's encapsulation,
1546      * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
1547      * have a single encapsulation for all interfaces in the file,
1548      * so it probably doesn't have a single encapsulation for all
1549      * packets in the file.
1550      */
1551     if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
1552         wth->file_encap = if_descr_mand->wtap_encap;
1553     } else {
1554         if (wth->file_encap != if_descr_mand->wtap_encap) {
1555             wth->file_encap = WTAP_ENCAP_PER_PACKET;
1556         }
1557     }
1558 
1559     /*
1560      * The same applies to the per-file time stamp resolution.
1561      */
1562     if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
1563         wth->file_tsprec = if_descr_mand->tsprecision;
1564     } else {
1565         if (wth->file_tsprec != if_descr_mand->tsprecision) {
1566             wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
1567         }
1568     }
1569 
1570     /*
1571      * We don't return these to the caller in pcapng_read().
1572      */
1573     wblock->internal = TRUE;
1574 
1575     return TRUE;
1576 }
1577 
1578 static gboolean
pcapng_read_decryption_secrets_block(FILE_T fh,pcapng_block_header_t * bh,const section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)1579 pcapng_read_decryption_secrets_block(FILE_T fh, pcapng_block_header_t *bh,
1580                                      const section_info_t *section_info,
1581                                      wtapng_block_t *wblock,
1582                                      int *err, gchar **err_info)
1583 {
1584     guint to_read;
1585     pcapng_decryption_secrets_block_t dsb;
1586     wtapng_dsb_mandatory_t *dsb_mand;
1587 
1588     /* read block content */
1589     if (!wtap_read_bytes(fh, &dsb, sizeof(dsb), err, err_info)) {
1590         ws_debug("failed to read DSB");
1591         return FALSE;
1592     }
1593 
1594     /*
1595      * Set wblock->block to a newly-allocated decryption secrets block.
1596      */
1597     wblock->block = wtap_block_create(WTAP_BLOCK_DECRYPTION_SECRETS);
1598 
1599     /*
1600      * Set the mandatory values for the block.
1601      */
1602     dsb_mand = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(wblock->block);
1603     if (section_info->byte_swapped) {
1604       dsb_mand->secrets_type = GUINT32_SWAP_LE_BE(dsb.secrets_type);
1605       dsb_mand->secrets_len = GUINT32_SWAP_LE_BE(dsb.secrets_len);
1606     } else {
1607       dsb_mand->secrets_type = dsb.secrets_type;
1608       dsb_mand->secrets_len = dsb.secrets_len;
1609     }
1610     /* Sanity check: assume the secrets are not larger than 1 GiB */
1611     if (dsb_mand->secrets_len > 1024 * 1024 * 1024) {
1612       *err = WTAP_ERR_BAD_FILE;
1613       *err_info = g_strdup_printf("pcapng: secrets block is too large: %u", dsb_mand->secrets_len);
1614       return FALSE;
1615     }
1616     dsb_mand->secrets_data = (guint8 *)g_malloc0(dsb_mand->secrets_len);
1617     if (!wtap_read_bytes(fh, dsb_mand->secrets_data, dsb_mand->secrets_len, err, err_info)) {
1618         ws_debug("failed to read DSB");
1619         return FALSE;
1620     }
1621 
1622     /* Skip past padding and discard options (not supported yet). */
1623     to_read = bh->block_total_length - MIN_DSB_SIZE - dsb_mand->secrets_len;
1624     if (!wtap_read_bytes(fh, NULL, to_read, err, err_info)) {
1625         ws_debug("failed to read DSB options");
1626         return FALSE;
1627     }
1628 
1629     /*
1630      * We don't return these to the caller in pcapng_read().
1631      */
1632     wblock->internal = TRUE;
1633 
1634     return TRUE;
1635 }
1636 
1637 static gboolean
pcapng_process_packet_block_option(wtapng_block_t * wblock,const section_info_t * section_info,guint16 option_code,guint16 option_length,const guint8 * option_content,int * err,gchar ** err_info)1638 pcapng_process_packet_block_option(wtapng_block_t *wblock,
1639                                    const section_info_t *section_info,
1640                                    guint16 option_code,
1641                                    guint16 option_length,
1642                                    const guint8 *option_content,
1643                                    int *err, gchar **err_info)
1644 {
1645     guint64 tmp64;
1646     packet_verdict_opt_t packet_verdict;
1647 
1648     /*
1649      * Handle option content.
1650      *
1651      * ***DO NOT*** add any items to this table that are not
1652      * standardized option codes in either section 3.5 "Options"
1653      * of the current pcapng spec, at
1654      *
1655      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-options
1656      *
1657      * or in the list of options in section 4.3 "Enhanced Packet Block"
1658      * of the current pcapng spec, at
1659      *
1660      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-enhanced-packet-block
1661      *
1662      * All option codes in this switch statement here must be listed
1663      * in one of those places as standardized option types.
1664      */
1665     switch (option_code) {
1666         case(OPT_EPB_FLAGS):
1667             if (option_length != 4) {
1668                 *err = WTAP_ERR_BAD_FILE;
1669                 *err_info = g_strdup_printf("pcapng: packet block flags option length %u is not 4",
1670                                             option_length);
1671                 /* XXX - free anything? */
1672                 return FALSE;
1673             }
1674             pcapng_process_uint32_option(wblock, section_info,
1675                                          OPT_SECTION_BYTE_ORDER,
1676                                          option_code, option_length,
1677                                          option_content);
1678             break;
1679         case(OPT_EPB_HASH):
1680             ws_debug("epb_hash %u currently not handled - ignoring %u bytes",
1681                      option_code, option_length);
1682             break;
1683         case(OPT_EPB_DROPCOUNT):
1684             if (option_length != 8) {
1685                 *err = WTAP_ERR_BAD_FILE;
1686                 *err_info = g_strdup_printf("pcapng: packet block drop count option length %u is not 8",
1687                                             option_length);
1688                 /* XXX - free anything? */
1689                 return FALSE;
1690             }
1691             pcapng_process_uint64_option(wblock, section_info,
1692                                          OPT_SECTION_BYTE_ORDER,
1693                                          option_code, option_length,
1694                                          option_content);
1695             break;
1696         case(OPT_EPB_PACKETID):
1697             if (option_length != 8) {
1698                 *err = WTAP_ERR_BAD_FILE;
1699                 *err_info = g_strdup_printf("pcapng: packet block packet id option length %u is not 8",
1700                                             option_length);
1701                 /* XXX - free anything? */
1702                 return FALSE;
1703             }
1704             pcapng_process_uint64_option(wblock, section_info,
1705                                          OPT_SECTION_BYTE_ORDER,
1706                                          option_code, option_length,
1707                                          option_content);
1708             break;
1709         case(OPT_EPB_QUEUE):
1710             if (option_length != 4) {
1711                 *err = WTAP_ERR_BAD_FILE;
1712                 *err_info = g_strdup_printf("pcapng: packet block queue option length %u is not 4",
1713                                             option_length);
1714                 /* XXX - free anything? */
1715                 return FALSE;
1716             }
1717             pcapng_process_uint32_option(wblock, section_info,
1718                                          OPT_SECTION_BYTE_ORDER,
1719                                          option_code, option_length,
1720                                          option_content);
1721             break;
1722         case(OPT_EPB_VERDICT):
1723             if (option_length < 1) {
1724                 *err = WTAP_ERR_BAD_FILE;
1725                 *err_info = g_strdup_printf("pcapng: packet block verdict option length %u is < 1",
1726                                             option_length);
1727                 /* XXX - free anything? */
1728                 return FALSE;
1729             }
1730             switch (option_content[0]) {
1731 
1732                 case(OPT_VERDICT_TYPE_HW):
1733                     packet_verdict.type = packet_verdict_hardware;
1734                     packet_verdict.data.verdict_bytes =
1735                         g_byte_array_new_take((guint8 *)g_memdup2(&option_content[1],
1736                                                                   option_length - 1),
1737                                               option_length - 1);
1738                     break;
1739 
1740                 case(OPT_VERDICT_TYPE_TC):
1741                     if (option_length != 9) {
1742                         *err = WTAP_ERR_BAD_FILE;
1743                         *err_info = g_strdup_printf("pcapng: packet block TC verdict option length %u is != 9",
1744                                                     option_length);
1745                         /* XXX - free anything? */
1746                         return FALSE;
1747                     }
1748                     /*  Don't cast a guint8 * into a guint64 *--the
1749                      *  guint8 * may not point to something that's
1750                      *  aligned correctly.
1751                      */
1752                     memcpy(&tmp64, &option_content[1], sizeof(guint64));
1753                     if (section_info->byte_swapped)
1754                         tmp64 = GUINT64_SWAP_LE_BE(tmp64);
1755                     packet_verdict.type = packet_verdict_linux_ebpf_tc;
1756                     packet_verdict.data.verdict_linux_ebpf_tc = tmp64;
1757                     break;
1758 
1759                 case(OPT_VERDICT_TYPE_XDP):
1760                     if (option_length != 9) {
1761                         *err = WTAP_ERR_BAD_FILE;
1762                         *err_info = g_strdup_printf("pcapng: packet block XDP verdict option length %u is != 9",
1763                                                     option_length);
1764                         /* XXX - free anything? */
1765                         return FALSE;
1766                     }
1767                     /*  Don't cast a guint8 * into a guint64 *--the
1768                      *  guint8 * may not point to something that's
1769                      *  aligned correctly.
1770                      */
1771                     memcpy(&tmp64, &option_content[1], sizeof(guint64));
1772                     if (section_info->byte_swapped)
1773                         tmp64 = GUINT64_SWAP_LE_BE(tmp64);
1774                     packet_verdict.type = packet_verdict_linux_ebpf_xdp;
1775                     packet_verdict.data.verdict_linux_ebpf_xdp = tmp64;
1776                     break;
1777 
1778                 default:
1779                     /* Silently ignore unknown verdict types */
1780                     return TRUE;
1781             }
1782             wtap_block_add_packet_verdict_option(wblock->block, option_code, &packet_verdict);
1783             wtap_packet_verdict_free(&packet_verdict);
1784             ws_debug("verdict type %u, data len %u",
1785                      option_content[0], option_length - 1);
1786             break;
1787         default:
1788             if (!pcapng_process_unhandled_option(wblock, BT_INDEX_PBS,
1789                                                  section_info, option_code,
1790                                                  option_length, option_content,
1791                                                  err, err_info))
1792                 return FALSE;
1793             break;
1794     }
1795     return TRUE;
1796 }
1797 
1798 static gboolean
pcapng_read_packet_block(FILE_T fh,pcapng_block_header_t * bh,section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info,gboolean enhanced)1799 pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh,
1800                          section_info_t *section_info,
1801                          wtapng_block_t *wblock,
1802                          int *err, gchar **err_info, gboolean enhanced)
1803 {
1804     guint block_read;
1805     guint opt_cont_buf_len;
1806     pcapng_enhanced_packet_block_t epb;
1807     pcapng_packet_block_t pb;
1808     wtapng_packet_t packet;
1809     guint32 padding;
1810     guint32 flags;
1811     guint64 tmp64;
1812     interface_info_t iface_info;
1813     guint64 ts;
1814     int pseudo_header_len;
1815     int fcslen;
1816 
1817     wblock->block = wtap_block_create(WTAP_BLOCK_PACKET);
1818 
1819     /* "(Enhanced) Packet Block" read fixed part */
1820     if (enhanced) {
1821         /*
1822          * Is this block long enough to be an EPB?
1823          */
1824         if (bh->block_total_length < MIN_EPB_SIZE) {
1825             /*
1826              * No.
1827              */
1828             *err = WTAP_ERR_BAD_FILE;
1829             *err_info = g_strdup_printf("pcapng: total block length %u of an EPB is less than the minimum EPB size %u",
1830                                         bh->block_total_length, MIN_EPB_SIZE);
1831             return FALSE;
1832         }
1833         if (!wtap_read_bytes(fh, &epb, sizeof epb, err, err_info)) {
1834             ws_debug("failed to read packet data");
1835             return FALSE;
1836         }
1837         block_read = (guint)sizeof epb;
1838 
1839         if (section_info->byte_swapped) {
1840             packet.interface_id        = GUINT32_SWAP_LE_BE(epb.interface_id);
1841             packet.drops_count         = 0xFFFF; /* invalid */
1842             packet.ts_high             = GUINT32_SWAP_LE_BE(epb.timestamp_high);
1843             packet.ts_low              = GUINT32_SWAP_LE_BE(epb.timestamp_low);
1844             packet.cap_len             = GUINT32_SWAP_LE_BE(epb.captured_len);
1845             packet.packet_len          = GUINT32_SWAP_LE_BE(epb.packet_len);
1846         } else {
1847             packet.interface_id        = epb.interface_id;
1848             packet.drops_count         = 0xFFFF; /* invalid */
1849             packet.ts_high             = epb.timestamp_high;
1850             packet.ts_low              = epb.timestamp_low;
1851             packet.cap_len             = epb.captured_len;
1852             packet.packet_len          = epb.packet_len;
1853         }
1854         ws_debug("EPB on interface_id %d, cap_len %d, packet_len %d",
1855                  packet.interface_id, packet.cap_len, packet.packet_len);
1856     } else {
1857         /*
1858          * Is this block long enough to be a PB?
1859          */
1860         if (bh->block_total_length < MIN_PB_SIZE) {
1861             /*
1862              * No.
1863              */
1864             *err = WTAP_ERR_BAD_FILE;
1865             *err_info = g_strdup_printf("pcapng: total block length %u of a PB is less than the minimum PB size %u",
1866                                         bh->block_total_length, MIN_PB_SIZE);
1867             return FALSE;
1868         }
1869         if (!wtap_read_bytes(fh, &pb, sizeof pb, err, err_info)) {
1870             ws_debug("failed to read packet data");
1871             return FALSE;
1872         }
1873         block_read = (guint)sizeof pb;
1874 
1875         if (section_info->byte_swapped) {
1876             packet.interface_id        = GUINT16_SWAP_LE_BE(pb.interface_id);
1877             packet.drops_count         = GUINT16_SWAP_LE_BE(pb.drops_count);
1878             packet.ts_high             = GUINT32_SWAP_LE_BE(pb.timestamp_high);
1879             packet.ts_low              = GUINT32_SWAP_LE_BE(pb.timestamp_low);
1880             packet.cap_len             = GUINT32_SWAP_LE_BE(pb.captured_len);
1881             packet.packet_len          = GUINT32_SWAP_LE_BE(pb.packet_len);
1882         } else {
1883             packet.interface_id        = pb.interface_id;
1884             packet.drops_count         = pb.drops_count;
1885             packet.ts_high             = pb.timestamp_high;
1886             packet.ts_low              = pb.timestamp_low;
1887             packet.cap_len             = pb.captured_len;
1888             packet.packet_len          = pb.packet_len;
1889         }
1890         ws_debug("PB on interface_id %d, cap_len %d, packet_len %d",
1891                  packet.interface_id, packet.cap_len, packet.packet_len);
1892     }
1893 
1894     /*
1895      * How much padding is there at the end of the packet data?
1896      */
1897     if ((packet.cap_len % 4) != 0)
1898         padding = 4 - (packet.cap_len % 4);
1899     else
1900         padding = 0;
1901 
1902     /*
1903      * Is this block long enough to hold the packet data?
1904      */
1905     if (enhanced) {
1906         if (bh->block_total_length <
1907             MIN_EPB_SIZE + packet.cap_len + padding) {
1908             /*
1909              * No.
1910              */
1911             *err = WTAP_ERR_BAD_FILE;
1912             *err_info = g_strdup_printf("pcapng: total block length %u of an EPB is too small for %u bytes of packet data",
1913                                         bh->block_total_length, packet.cap_len);
1914             return FALSE;
1915         }
1916     } else {
1917         if (bh->block_total_length <
1918             MIN_PB_SIZE + packet.cap_len + padding) {
1919             /*
1920              * No.
1921              */
1922             *err = WTAP_ERR_BAD_FILE;
1923             *err_info = g_strdup_printf("pcapng: total block length %u of a PB is too small for %u bytes of packet data",
1924                                         bh->block_total_length, packet.cap_len);
1925             return FALSE;
1926         }
1927     }
1928 
1929     ws_debug("packet data: packet_len %u captured_len %u interface_id %u",
1930              packet.packet_len,
1931              packet.cap_len,
1932              packet.interface_id);
1933 
1934     if (packet.interface_id >= section_info->interfaces->len) {
1935         *err = WTAP_ERR_BAD_FILE;
1936         *err_info = g_strdup_printf("pcapng: interface index %u is not less than section interface count %u",
1937                                     packet.interface_id,
1938                                     section_info->interfaces->len);
1939         return FALSE;
1940     }
1941     iface_info = g_array_index(section_info->interfaces, interface_info_t,
1942                                packet.interface_id);
1943 
1944     if (packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
1945         *err = WTAP_ERR_BAD_FILE;
1946         *err_info = g_strdup_printf("pcapng: cap_len %u is larger than %u",
1947                                     packet.cap_len,
1948                                     wtap_max_snaplen_for_encap(iface_info.wtap_encap));
1949         return FALSE;
1950     }
1951 
1952     wblock->rec->rec_type = REC_TYPE_PACKET;
1953     wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
1954 
1955     ws_debug("encapsulation = %d (%s), pseudo header size = %d.",
1956              iface_info.wtap_encap,
1957              wtap_encap_description(iface_info.wtap_encap),
1958              pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
1959     wblock->rec->rec_header.packet_header.interface_id = packet.interface_id;
1960     wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
1961     wblock->rec->tsprec = iface_info.tsprecision;
1962 
1963     memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
1964     pseudo_header_len = pcap_process_pseudo_header(fh,
1965                                                    FALSE, /* not a Nokia pcap - not a pcap at all */
1966                                                    iface_info.wtap_encap,
1967                                                    packet.cap_len,
1968                                                    wblock->rec,
1969                                                    err,
1970                                                    err_info);
1971     if (pseudo_header_len < 0) {
1972         return FALSE;
1973     }
1974     block_read += pseudo_header_len;
1975     wblock->rec->rec_header.packet_header.caplen = packet.cap_len - pseudo_header_len;
1976     wblock->rec->rec_header.packet_header.len = packet.packet_len - pseudo_header_len;
1977 
1978     /* Combine the two 32-bit pieces of the timestamp into one 64-bit value */
1979     ts = (((guint64)packet.ts_high) << 32) | ((guint64)packet.ts_low);
1980     wblock->rec->ts.secs = (time_t)(ts / iface_info.time_units_per_second);
1981     wblock->rec->ts.nsecs = (int)(((ts % iface_info.time_units_per_second) * 1000000000) / iface_info.time_units_per_second);
1982 
1983     /* "(Enhanced) Packet Block" read capture data */
1984     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
1985                                 packet.cap_len - pseudo_header_len, err, err_info))
1986         return FALSE;
1987     block_read += packet.cap_len - pseudo_header_len;
1988 
1989     /* jump over potential padding bytes at end of the packet data */
1990     if (padding != 0) {
1991         if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
1992             return FALSE;
1993         block_read += padding;
1994     }
1995 
1996     /* FCS length default */
1997     fcslen = iface_info.fcslen;
1998 
1999     /* Options */
2000     opt_cont_buf_len = bh->block_total_length -
2001         (int)sizeof(pcapng_block_header_t) -
2002         block_read -    /* fixed and variable part, including padding */
2003         (int)sizeof(bh->block_total_length);
2004     if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2005                                 pcapng_process_packet_block_option,
2006                                 OPT_SECTION_BYTE_ORDER, err, err_info))
2007         return FALSE;
2008 
2009     /*
2010      * Did we get a packet flags option?
2011      */
2012     if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(wblock->block, OPT_PKT_FLAGS, &flags)) {
2013         if (PACK_FLAGS_FCS_LENGTH(flags) != 0) {
2014             /* The FCS length is present */
2015             fcslen = PACK_FLAGS_FCS_LENGTH(flags);
2016         }
2017     }
2018     /*
2019      * How about a drop_count option? If not, set it from other sources
2020      */
2021     if (WTAP_OPTTYPE_SUCCESS != wtap_block_get_uint64_option_value(wblock->block, OPT_PKT_DROPCOUNT, &tmp64) && packet.drops_count != 0xFFFF) {
2022         wtap_block_add_uint64_option(wblock->block, OPT_PKT_DROPCOUNT, (guint64)packet.drops_count);
2023     }
2024 
2025     pcap_read_post_process(FALSE, iface_info.wtap_encap,
2026                            wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
2027                            section_info->byte_swapped, fcslen);
2028 
2029     /*
2030      * We return these to the caller in pcapng_read().
2031      */
2032     wblock->internal = FALSE;
2033 
2034     /*
2035      * We want dissectors (particularly packet_frame) to be able to
2036      * access packet comments and whatnot that are in the block. wblock->block
2037      * will be unref'd by pcapng_seek_read(), so move the block to where
2038      * dissectors can find it.
2039      */
2040     wblock->rec->block = wblock->block;
2041     wblock->block = NULL;
2042 
2043     return TRUE;
2044 }
2045 
2046 
2047 static gboolean
pcapng_read_simple_packet_block(FILE_T fh,pcapng_block_header_t * bh,const section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)2048 pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh,
2049                                 const section_info_t *section_info,
2050                                 wtapng_block_t *wblock,
2051                                 int *err, gchar **err_info)
2052 {
2053     interface_info_t iface_info;
2054     pcapng_simple_packet_block_t spb;
2055     wtapng_simple_packet_t simple_packet;
2056     guint32 padding;
2057     int pseudo_header_len;
2058 
2059     /*
2060      * Is this block long enough to be an SPB?
2061      */
2062     if (bh->block_total_length < MIN_SPB_SIZE) {
2063         /*
2064          * No.
2065          */
2066         *err = WTAP_ERR_BAD_FILE;
2067         *err_info = g_strdup_printf("pcapng: total block length %u of an SPB is less than the minimum SPB size %u",
2068                                     bh->block_total_length, MIN_SPB_SIZE);
2069         return FALSE;
2070     }
2071 
2072     /* "Simple Packet Block" read fixed part */
2073     if (!wtap_read_bytes(fh, &spb, sizeof spb, err, err_info)) {
2074         ws_debug("failed to read packet data");
2075         return FALSE;
2076     }
2077 
2078     if (0 >= section_info->interfaces->len) {
2079         *err = WTAP_ERR_BAD_FILE;
2080         *err_info = g_strdup("pcapng: SPB appeared before any IDBs in the section");
2081         return FALSE;
2082     }
2083     iface_info = g_array_index(section_info->interfaces, interface_info_t, 0);
2084 
2085     if (section_info->byte_swapped) {
2086         simple_packet.packet_len   = GUINT32_SWAP_LE_BE(spb.packet_len);
2087     } else {
2088         simple_packet.packet_len   = spb.packet_len;
2089     }
2090 
2091     /*
2092      * The captured length is not a field in the SPB; it can be
2093      * calculated as the minimum of the snapshot length from the
2094      * IDB and the packet length, as per the pcapng spec. An IDB
2095      * snapshot length of 0 means no limit.
2096      */
2097     simple_packet.cap_len = simple_packet.packet_len;
2098     if (simple_packet.cap_len > iface_info.snap_len && iface_info.snap_len != 0)
2099         simple_packet.cap_len = iface_info.snap_len;
2100 
2101     /*
2102      * How much padding is there at the end of the packet data?
2103      */
2104     if ((simple_packet.cap_len % 4) != 0)
2105         padding = 4 - (simple_packet.cap_len % 4);
2106     else
2107         padding = 0;
2108 
2109     /*
2110      * Is this block long enough to hold the packet data?
2111      */
2112     if (bh->block_total_length < MIN_SPB_SIZE + simple_packet.cap_len + padding) {
2113         /*
2114          * No.  That means that the problem is with the packet
2115          * length; the snapshot length can be bigger than the amount
2116          * of packet data in the block, as it's a *maximum* length,
2117          * not a *minimum* length.
2118          */
2119         *err = WTAP_ERR_BAD_FILE;
2120         *err_info = g_strdup_printf("pcapng: total block length %u of an SPB is too small for %u bytes of packet data",
2121                                     bh->block_total_length, simple_packet.packet_len);
2122         return FALSE;
2123     }
2124 
2125     if (simple_packet.cap_len > wtap_max_snaplen_for_encap(iface_info.wtap_encap)) {
2126         *err = WTAP_ERR_BAD_FILE;
2127         *err_info = g_strdup_printf("pcapng: cap_len %u is larger than %u",
2128                                     simple_packet.cap_len,
2129                                     wtap_max_snaplen_for_encap(iface_info.wtap_encap));
2130         return FALSE;
2131     }
2132     ws_debug("packet data: packet_len %u",
2133              simple_packet.packet_len);
2134 
2135     ws_debug("Need to read pseudo header of size %d",
2136              pcap_get_phdr_size(iface_info.wtap_encap, &wblock->rec->rec_header.packet_header.pseudo_header));
2137 
2138     /* No time stamp in a simple packet block; no options, either */
2139     wblock->rec->rec_type = REC_TYPE_PACKET;
2140     wblock->rec->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID;
2141     wblock->rec->rec_header.packet_header.interface_id = 0;
2142     wblock->rec->rec_header.packet_header.pkt_encap = iface_info.wtap_encap;
2143     wblock->rec->tsprec = iface_info.tsprecision;
2144     wblock->rec->ts.secs = 0;
2145     wblock->rec->ts.nsecs = 0;
2146     wblock->rec->rec_header.packet_header.interface_id = 0;
2147 
2148     memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2149     pseudo_header_len = pcap_process_pseudo_header(fh,
2150                                                    FALSE,
2151                                                    iface_info.wtap_encap,
2152                                                    simple_packet.cap_len,
2153                                                    wblock->rec,
2154                                                    err,
2155                                                    err_info);
2156     if (pseudo_header_len < 0) {
2157         return FALSE;
2158     }
2159     wblock->rec->rec_header.packet_header.caplen = simple_packet.cap_len - pseudo_header_len;
2160     wblock->rec->rec_header.packet_header.len = simple_packet.packet_len - pseudo_header_len;
2161 
2162     memset((void *)&wblock->rec->rec_header.packet_header.pseudo_header, 0, sizeof(union wtap_pseudo_header));
2163 
2164     /* "Simple Packet Block" read capture data */
2165     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2166                                 simple_packet.cap_len, err, err_info))
2167         return FALSE;
2168 
2169     /* jump over potential padding bytes at end of the packet data */
2170     if ((simple_packet.cap_len % 4) != 0) {
2171         if (!wtap_read_bytes(fh, NULL, 4 - (simple_packet.cap_len % 4), err, err_info))
2172             return FALSE;
2173     }
2174 
2175     pcap_read_post_process(FALSE, iface_info.wtap_encap,
2176                            wblock->rec, ws_buffer_start_ptr(wblock->frame_buffer),
2177                            section_info->byte_swapped, iface_info.fcslen);
2178 
2179     /*
2180      * We return these to the caller in pcapng_read().
2181      */
2182     wblock->internal = FALSE;
2183 
2184     return TRUE;
2185 }
2186 
2187 #define NRES_ENDOFRECORD 0
2188 #define NRES_IP4RECORD 1
2189 #define NRES_IP6RECORD 2
2190 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
2191 /* IPv6 + MAXNAMELEN */
2192 #define INITIAL_NRB_REC_SIZE (16 + 64)
2193 
2194 /*
2195  * Find the end of the NUL-terminated name the beginning of which is pointed
2196  * to by p; record_len is the number of bytes remaining in the record.
2197  *
2198  * Return the length of the name, including the terminating NUL.
2199  *
2200  * If we don't find a terminating NUL, return -1 and set *err and
2201  * *err_info appropriately.
2202  */
2203 static int
name_resolution_block_find_name_end(const char * p,guint record_len,int * err,gchar ** err_info)2204 name_resolution_block_find_name_end(const char *p, guint record_len, int *err,
2205                                     gchar **err_info)
2206 {
2207     int namelen;
2208 
2209     namelen = 0;
2210     for (;;) {
2211         if (record_len == 0) {
2212             /*
2213              * We ran out of bytes in the record without
2214              * finding a NUL.
2215              */
2216             *err = WTAP_ERR_BAD_FILE;
2217             *err_info = g_strdup("pcapng: NRB record has non-null-terminated host name");
2218             return -1;
2219         }
2220         if (*p == '\0')
2221             break;  /* that's the terminating NUL */
2222         p++;
2223         record_len--;
2224         namelen++;      /* count this byte */
2225     }
2226 
2227     /* Include the NUL in the name length. */
2228     return namelen + 1;
2229 }
2230 
2231 static gboolean
pcapng_process_name_resolution_block_option(wtapng_block_t * wblock,const section_info_t * section_info,guint16 option_code,guint16 option_length,const guint8 * option_content,int * err,gchar ** err_info)2232 pcapng_process_name_resolution_block_option(wtapng_block_t *wblock,
2233                                             const section_info_t *section_info,
2234                                             guint16 option_code,
2235                                             guint16 option_length,
2236                                             const guint8 *option_content,
2237                                             int *err, gchar **err_info)
2238 {
2239     /*
2240      * Handle option content.
2241      *
2242      * ***DO NOT*** add any items to this table that are not
2243      * standardized option codes in either section 3.5 "Options"
2244      * of the current pcapng spec, at
2245      *
2246      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-options
2247      *
2248      * or in the list of options in section 4.1 "Section Header Block"
2249      * of the current pcapng spec, at
2250      *
2251      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-section-header-block
2252      *
2253      * All option codes in this switch statement here must be listed
2254      * in one of those places as standardized option types.
2255      */
2256     switch (option_code) {
2257         /* TODO:
2258          * ns_dnsname     2
2259          * ns_dnsIP4addr  3
2260          * ns_dnsIP6addr  4
2261          */
2262         default:
2263             if (!pcapng_process_unhandled_option(wblock, BT_INDEX_NRB,
2264                                                  section_info, option_code,
2265                                                  option_length, option_content,
2266                                                  err, err_info))
2267                 return FALSE;
2268             break;
2269     }
2270     return TRUE;
2271 }
2272 
2273 static gboolean
pcapng_read_name_resolution_block(FILE_T fh,pcapng_block_header_t * bh,pcapng_t * pn,section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)2274 pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh,
2275                                   pcapng_t *pn,
2276                                   section_info_t *section_info,
2277                                   wtapng_block_t *wblock,
2278                                   int *err, gchar **err_info)
2279 {
2280     int block_read;
2281     int to_read;
2282     pcapng_name_resolution_block_t nrb;
2283     Buffer nrb_rec;
2284     guint32 v4_addr;
2285     guint record_len, opt_cont_buf_len;
2286     char *namep;
2287     int namelen;
2288 
2289     /*
2290      * Is this block long enough to be an NRB?
2291      */
2292     if (bh->block_total_length < MIN_NRB_SIZE) {
2293         /*
2294          * No.
2295          */
2296         *err = WTAP_ERR_BAD_FILE;
2297         *err_info = g_strdup_printf("pcapng: total block length %u of an NRB is less than the minimum NRB size %u",
2298                                     bh->block_total_length, MIN_NRB_SIZE);
2299         return FALSE;
2300     }
2301 
2302     to_read = bh->block_total_length - 8 - 4; /* We have read the header and should not read the final block_total_length */
2303 
2304     ws_debug("total %d bytes", bh->block_total_length);
2305 
2306     /* Ensure we have a name resolution block */
2307     if (wblock->block == NULL) {
2308         wblock->block = wtap_block_create(WTAP_BLOCK_NAME_RESOLUTION);
2309     }
2310 
2311     /*
2312      * Start out with a buffer big enough for an IPv6 address and one
2313      * 64-byte name; we'll make the buffer bigger if necessary.
2314      */
2315     ws_buffer_init(&nrb_rec, INITIAL_NRB_REC_SIZE);
2316     block_read = 0;
2317     while (block_read < to_read) {
2318         /*
2319          * There must be at least one record's worth of data
2320          * here.
2321          */
2322         if ((size_t)(to_read - block_read) < sizeof nrb) {
2323             ws_buffer_free(&nrb_rec);
2324             *err = WTAP_ERR_BAD_FILE;
2325             *err_info = g_strdup_printf("pcapng: %d bytes left in the block < NRB record header size %u",
2326                                         to_read - block_read,
2327                                         (guint)sizeof nrb);
2328             return FALSE;
2329         }
2330         if (!wtap_read_bytes(fh, &nrb, sizeof nrb, err, err_info)) {
2331             ws_buffer_free(&nrb_rec);
2332             ws_debug("failed to read record header");
2333             return FALSE;
2334         }
2335         block_read += (int)sizeof nrb;
2336 
2337         if (section_info->byte_swapped) {
2338             nrb.record_type = GUINT16_SWAP_LE_BE(nrb.record_type);
2339             nrb.record_len  = GUINT16_SWAP_LE_BE(nrb.record_len);
2340         }
2341 
2342         if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
2343             ws_buffer_free(&nrb_rec);
2344             *err = WTAP_ERR_BAD_FILE;
2345             *err_info = g_strdup_printf("pcapng: %d bytes left in the block < NRB record length + padding %u",
2346                                         to_read - block_read,
2347                                         nrb.record_len + PADDING4(nrb.record_len));
2348             return FALSE;
2349         }
2350         switch (nrb.record_type) {
2351             case NRES_ENDOFRECORD:
2352                 /* There shouldn't be any more data - but there MAY be options */
2353                 goto read_options;
2354                 break;
2355             case NRES_IP4RECORD:
2356                 /*
2357                  * The smallest possible record must have
2358                  * a 4-byte IPv4 address, hence a minimum
2359                  * of 4 bytes.
2360                  *
2361                  * (The pcapng spec really indicates
2362                  * that it must be at least 5 bytes,
2363                  * as there must be at least one name,
2364                  * and it really must be at least 6
2365                  * bytes, as the name mustn't be null,
2366                  * but there's no need to fail if there
2367                  * aren't any names at all, and we
2368                  * should report a null name as such.)
2369                  */
2370                 if (nrb.record_len < 4) {
2371                     ws_buffer_free(&nrb_rec);
2372                     *err = WTAP_ERR_BAD_FILE;
2373                     *err_info = g_strdup_printf("pcapng: NRB record length for IPv4 record %u < minimum length 4",
2374                                                 nrb.record_len);
2375                     return FALSE;
2376                 }
2377                 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2378                 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2379                                      nrb.record_len, err, err_info)) {
2380                     ws_buffer_free(&nrb_rec);
2381                     ws_debug("failed to read IPv4 record data");
2382                     return FALSE;
2383                 }
2384                 block_read += nrb.record_len;
2385 
2386                 if (pn->add_new_ipv4) {
2387                     /*
2388                      * Scan through all the names in
2389                      * the record and add them.
2390                      */
2391                     memcpy(&v4_addr,
2392                            ws_buffer_start_ptr(&nrb_rec), 4);
2393                     /* IPv4 address is in big-endian order in the file always, which is how we store
2394                        it internally as well, so don't byte-swap it */
2395                     for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 4, record_len = nrb.record_len - 4;
2396                          record_len != 0;
2397                          namep += namelen, record_len -= namelen) {
2398                         /*
2399                          * Scan forward for a null
2400                          * byte.
2401                          */
2402                         namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2403                         if (namelen == -1) {
2404                             ws_buffer_free(&nrb_rec);
2405                             return FALSE;      /* fail */
2406                         }
2407                         pn->add_new_ipv4(v4_addr, namep);
2408                     }
2409                 }
2410 
2411                 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
2412                     ws_buffer_free(&nrb_rec);
2413                     return FALSE;
2414                 }
2415                 block_read += PADDING4(nrb.record_len);
2416                 break;
2417             case NRES_IP6RECORD:
2418                 /*
2419                  * The smallest possible record must have
2420                  * a 16-byte IPv6 address, hence a minimum
2421                  * of 16 bytes.
2422                  *
2423                  * (The pcapng spec really indicates
2424                  * that it must be at least 17 bytes,
2425                  * as there must be at least one name,
2426                  * and it really must be at least 18
2427                  * bytes, as the name mustn't be null,
2428                  * but there's no need to fail if there
2429                  * aren't any names at all, and we
2430                  * should report a null name as such.)
2431                  */
2432                 if (nrb.record_len < 16) {
2433                     ws_buffer_free(&nrb_rec);
2434                     *err = WTAP_ERR_BAD_FILE;
2435                     *err_info = g_strdup_printf("pcapng: NRB record length for IPv6 record %u < minimum length 16",
2436                                                 nrb.record_len);
2437                     return FALSE;
2438                 }
2439                 if (to_read < nrb.record_len) {
2440                     ws_buffer_free(&nrb_rec);
2441                     *err = WTAP_ERR_BAD_FILE;
2442                     *err_info = g_strdup_printf("pcapng: NRB record length for IPv6 record %u > remaining data in NRB",
2443                                                 nrb.record_len);
2444                     return FALSE;
2445                 }
2446                 ws_buffer_assure_space(&nrb_rec, nrb.record_len);
2447                 if (!wtap_read_bytes(fh, ws_buffer_start_ptr(&nrb_rec),
2448                                      nrb.record_len, err, err_info)) {
2449                     ws_buffer_free(&nrb_rec);
2450                     return FALSE;
2451                 }
2452                 block_read += nrb.record_len;
2453 
2454                 if (pn->add_new_ipv6) {
2455                     for (namep = (char *)ws_buffer_start_ptr(&nrb_rec) + 16, record_len = nrb.record_len - 16;
2456                          record_len != 0;
2457                          namep += namelen, record_len -= namelen) {
2458                         /*
2459                          * Scan forward for a null
2460                          * byte.
2461                          */
2462                         namelen = name_resolution_block_find_name_end(namep, record_len, err, err_info);
2463                         if (namelen == -1) {
2464                             ws_buffer_free(&nrb_rec);
2465                             return FALSE;      /* fail */
2466                         }
2467                         pn->add_new_ipv6(ws_buffer_start_ptr(&nrb_rec),
2468                                          namep);
2469                     }
2470                 }
2471 
2472                 if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
2473                     ws_buffer_free(&nrb_rec);
2474                     return FALSE;
2475                 }
2476                 block_read += PADDING4(nrb.record_len);
2477                 break;
2478             default:
2479                 ws_debug("unknown record type 0x%x", nrb.record_type);
2480                 if (!wtap_read_bytes(fh, NULL, nrb.record_len + PADDING4(nrb.record_len), err, err_info)) {
2481                     ws_buffer_free(&nrb_rec);
2482                     return FALSE;
2483                 }
2484                 block_read += nrb.record_len + PADDING4(nrb.record_len);
2485                 break;
2486         }
2487     }
2488 
2489 read_options:
2490     to_read -= block_read;
2491 
2492     /* Options */
2493     opt_cont_buf_len = to_read;
2494     if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2495                                 pcapng_process_name_resolution_block_option,
2496                                 OPT_SECTION_BYTE_ORDER, err, err_info))
2497         return FALSE;
2498 
2499     ws_buffer_free(&nrb_rec);
2500 
2501     /*
2502      * We don't return these to the caller in pcapng_read().
2503      */
2504     wblock->internal = TRUE;
2505 
2506     return TRUE;
2507 }
2508 
2509 static gboolean
pcapng_process_interface_statistics_block_option(wtapng_block_t * wblock,const section_info_t * section_info,guint16 option_code,guint16 option_length,const guint8 * option_content,int * err,gchar ** err_info)2510 pcapng_process_interface_statistics_block_option(wtapng_block_t *wblock,
2511                                                  const section_info_t *section_info,
2512                                                  guint16 option_code,
2513                                                  guint16 option_length,
2514                                                  const guint8 *option_content,
2515                                                  int *err, gchar **err_info)
2516 {
2517     /*
2518      * Handle option content.
2519      *
2520      * ***DO NOT*** add any items to this table that are not
2521      * standardized option codes in either section 3.5 "Options"
2522      * of the current pcapng spec, at
2523      *
2524      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-options
2525      *
2526      * or in the list of options in section 4.1 "Section Header Block"
2527      * of the current pcapng spec, at
2528      *
2529      *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html#name-section-header-block
2530      *
2531      * All option codes in this switch statement here must be listed
2532      * in one of those places as standardized option types.
2533      */
2534     switch (option_code) {
2535         case(OPT_ISB_STARTTIME): /* isb_starttime */
2536             pcapng_process_timestamp_option(wblock, section_info,
2537                                             OPT_SECTION_BYTE_ORDER,
2538                                             option_code, option_length,
2539                                             option_content);
2540             break;
2541         case(OPT_ISB_ENDTIME): /* isb_endtime */
2542             pcapng_process_timestamp_option(wblock, section_info,
2543                                             OPT_SECTION_BYTE_ORDER,
2544                                             option_code, option_length,
2545                                             option_content);
2546             break;
2547         case(OPT_ISB_IFRECV): /* isb_ifrecv */
2548             pcapng_process_uint64_option(wblock, section_info,
2549                                          OPT_SECTION_BYTE_ORDER,
2550                                          option_code, option_length,
2551                                          option_content);
2552             break;
2553         case(OPT_ISB_IFDROP): /* isb_ifdrop */
2554             pcapng_process_uint64_option(wblock, section_info,
2555                                          OPT_SECTION_BYTE_ORDER,
2556                                          option_code, option_length,
2557                                          option_content);
2558             break;
2559         case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
2560             pcapng_process_uint64_option(wblock, section_info,
2561                                          OPT_SECTION_BYTE_ORDER,
2562                                          option_code, option_length,
2563                                          option_content);
2564             break;
2565         case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
2566             pcapng_process_uint64_option(wblock, section_info,
2567                                          OPT_SECTION_BYTE_ORDER,
2568                                          option_code, option_length,
2569                                          option_content);
2570             break;
2571         case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8  */
2572             pcapng_process_uint64_option(wblock, section_info,
2573                                          OPT_SECTION_BYTE_ORDER,
2574                                          option_code, option_length,
2575                                          option_content);
2576             break;
2577         default:
2578             if (!pcapng_process_unhandled_option(wblock, BT_INDEX_ISB,
2579                                                  section_info, option_code,
2580                                                  option_length, option_content,
2581                                                  err, err_info))
2582                 return FALSE;
2583             break;
2584     }
2585     return TRUE;
2586 }
2587 
2588 static gboolean
pcapng_read_interface_statistics_block(FILE_T fh,pcapng_block_header_t * bh,section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)2589 pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh,
2590                                        section_info_t *section_info,
2591                                        wtapng_block_t *wblock,
2592                                        int *err, gchar **err_info)
2593 {
2594     guint opt_cont_buf_len;
2595     pcapng_interface_statistics_block_t isb;
2596     wtapng_if_stats_mandatory_t* if_stats_mand;
2597 
2598     /*
2599      * Is this block long enough to be an ISB?
2600      */
2601     if (bh->block_total_length < MIN_ISB_SIZE) {
2602         /*
2603          * No.
2604          */
2605         *err = WTAP_ERR_BAD_FILE;
2606         *err_info = g_strdup_printf("pcapng: total block length %u of an ISB is too small (< %u)",
2607                                     bh->block_total_length, MIN_ISB_SIZE);
2608         return FALSE;
2609     }
2610 
2611     /* "Interface Statistics Block" read fixed part */
2612     if (!wtap_read_bytes(fh, &isb, sizeof isb, err, err_info)) {
2613         ws_debug("failed to read packet data");
2614         return FALSE;
2615     }
2616 
2617     /*
2618      * Set wblock->block to a newly-allocated interface statistics block.
2619      */
2620     wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
2621 
2622     /*
2623      * Set the mandatory values for the block.
2624      */
2625     if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
2626     if (section_info->byte_swapped) {
2627         if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
2628         if_stats_mand->ts_high      = GUINT32_SWAP_LE_BE(isb.timestamp_high);
2629         if_stats_mand->ts_low       = GUINT32_SWAP_LE_BE(isb.timestamp_low);
2630     } else {
2631         if_stats_mand->interface_id = isb.interface_id;
2632         if_stats_mand->ts_high      = isb.timestamp_high;
2633         if_stats_mand->ts_low       = isb.timestamp_low;
2634     }
2635     ws_debug("interface_id %u", if_stats_mand->interface_id);
2636 
2637     /* Options */
2638     opt_cont_buf_len = bh->block_total_length -
2639         (MIN_BLOCK_SIZE + (guint)sizeof isb);    /* fixed and variable part, including padding */
2640     if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2641                                 pcapng_process_interface_statistics_block_option,
2642                                 OPT_SECTION_BYTE_ORDER, err, err_info))
2643         return FALSE;
2644 
2645     /*
2646      * We don't return these to the caller in pcapng_read().
2647      */
2648     wblock->internal = TRUE;
2649 
2650     return TRUE;
2651 }
2652 
2653 #define NFLX_BLOCK_TYPE_EVENT   1
2654 #define NFLX_BLOCK_TYPE_SKIP    2
2655 
2656 typedef struct pcapng_nflx_custom_block_s {
2657     guint32 nflx_type;
2658 } pcapng_nflx_custom_block_t;
2659 
2660 #define MIN_NFLX_CB_SIZE ((guint32)(MIN_CB_SIZE + sizeof(pcapng_nflx_custom_block_t)))
2661 
2662 static gboolean
pcapng_read_nflx_custom_block(FILE_T fh,pcapng_block_header_t * bh,section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)2663 pcapng_read_nflx_custom_block(FILE_T fh, pcapng_block_header_t *bh,
2664                               section_info_t *section_info,
2665                               wtapng_block_t *wblock,
2666                               int *err, gchar **err_info)
2667 {
2668     pcapng_nflx_custom_block_t nflx_cb;
2669     guint opt_cont_buf_len;
2670     guint32 type, skipped;
2671 
2672     if (bh->block_total_length < MIN_NFLX_CB_SIZE) {
2673         *err = WTAP_ERR_BAD_FILE;
2674         *err_info = g_strdup_printf("pcapng: total block length %u of a Netflix CB is too small (< %u)",
2675                                     bh->block_total_length, MIN_NFLX_CB_SIZE);
2676         return FALSE;
2677     }
2678 
2679     wblock->rec->rec_type = REC_TYPE_CUSTOM_BLOCK;
2680     wblock->rec->rec_header.custom_block_header.pen = PEN_NFLX;
2681     /* "NFLX Custom Block" read fixed part */
2682     if (!wtap_read_bytes(fh, &nflx_cb, sizeof nflx_cb, err, err_info)) {
2683         ws_debug("Failed to read nflx type");
2684         return FALSE;
2685     }
2686     type = GUINT32_FROM_LE(nflx_cb.nflx_type);
2687     ws_debug("BBLog type: %u", type);
2688     switch (type) {
2689         case NFLX_BLOCK_TYPE_EVENT:
2690             /*
2691              * The fixed-length portion is MIN_NFLX_CB_SIZE bytes.
2692              * We already know we have that much data in the block.
2693              */
2694             wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type = BBLOG_TYPE_EVENT_BLOCK;
2695             opt_cont_buf_len = bh->block_total_length - MIN_NFLX_CB_SIZE;
2696             ws_debug("event");
2697             break;
2698         case NFLX_BLOCK_TYPE_SKIP:
2699             /*
2700              * The fixed-length portion is MIN_NFLX_CB_SIZE bytes plus a
2701              * 32-bit value.
2702              *
2703              * Make sure we have that much data in the block.
2704              */
2705             if (bh->block_total_length < MIN_NFLX_CB_SIZE + (guint32)sizeof(guint32)) {
2706                 *err = WTAP_ERR_BAD_FILE;
2707                 *err_info = g_strdup_printf("pcapng: total block length %u of a Netflix skip CB is too small (< %u)",
2708                                             bh->block_total_length,
2709                                             MIN_NFLX_CB_SIZE + (guint32)sizeof(guint32));
2710                 return FALSE;
2711             }
2712             if (!wtap_read_bytes(fh, &skipped, sizeof(guint32), err, err_info)) {
2713                 ws_debug("Failed to read skipped");
2714                 return FALSE;
2715             }
2716             wblock->rec->presence_flags = 0;
2717             wblock->rec->rec_header.custom_block_header.length = 4;
2718             wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type = BBLOG_TYPE_SKIPPED_BLOCK;
2719             wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped = GUINT32_FROM_LE(skipped);
2720             wblock->internal = FALSE;
2721             opt_cont_buf_len = bh->block_total_length - MIN_NFLX_CB_SIZE - sizeof(guint32);
2722             ws_debug("skipped: %u", wblock->rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
2723             break;
2724         default:
2725             ws_debug("Unknown type %u", type);
2726             return FALSE;
2727     }
2728 
2729     /* Options */
2730     if (!pcapng_process_options(fh, wblock, section_info, opt_cont_buf_len,
2731                                 NULL, OPT_LITTLE_ENDIAN, err, err_info))
2732         return FALSE;
2733 
2734     return TRUE;
2735 }
2736 
2737 static gboolean
pcapng_handle_generic_custom_block(FILE_T fh,pcapng_block_header_t * bh,guint32 pen,wtapng_block_t * wblock,int * err,gchar ** err_info)2738 pcapng_handle_generic_custom_block(FILE_T fh, pcapng_block_header_t *bh,
2739                                    guint32 pen, wtapng_block_t *wblock,
2740                                    int *err, gchar **err_info)
2741 {
2742     guint to_read;
2743 
2744     ws_debug("unknown pen %u", pen);
2745     if (bh->block_total_length % 4) {
2746         to_read = bh->block_total_length + 4 - (bh->block_total_length % 4);
2747     } else {
2748         to_read = bh->block_total_length;
2749     }
2750     to_read -= MIN_CB_SIZE;
2751     wblock->rec->rec_type = REC_TYPE_CUSTOM_BLOCK;
2752     wblock->rec->presence_flags = 0;
2753     wblock->rec->rec_header.custom_block_header.length = bh->block_total_length - MIN_CB_SIZE;
2754     wblock->rec->rec_header.custom_block_header.pen = pen;
2755     wblock->rec->rec_header.custom_block_header.copy_allowed = (bh->block_type == BLOCK_TYPE_CB_COPY);
2756     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer, to_read, err, err_info)) {
2757         return FALSE;
2758     }
2759     /*
2760      * We return these to the caller in pcapng_read().
2761      */
2762     wblock->internal = FALSE;
2763     return TRUE;
2764 }
2765 
2766 static gboolean
pcapng_read_custom_block(FILE_T fh,pcapng_block_header_t * bh,section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)2767 pcapng_read_custom_block(FILE_T fh, pcapng_block_header_t *bh,
2768                          section_info_t *section_info,
2769                          wtapng_block_t *wblock,
2770                          int *err, gchar **err_info)
2771 {
2772     pcapng_custom_block_t cb;
2773     guint32 pen;
2774 
2775     /* Is this block long enough to be an CB? */
2776     if (bh->block_total_length < MIN_CB_SIZE) {
2777         /*
2778          * No.
2779          */
2780         *err = WTAP_ERR_BAD_FILE;
2781         *err_info = g_strdup_printf("pcapng: total block length %u of a CB is too small (< %u)",
2782                                     bh->block_total_length, MIN_CB_SIZE);
2783         return FALSE;
2784     }
2785 
2786     wblock->block = wtap_block_create(WTAP_BLOCK_CUSTOM);
2787 
2788     /* Custom block read fixed part */
2789     if (!wtap_read_bytes(fh, &cb, sizeof cb, err, err_info)) {
2790         ws_debug("failed to read pen");
2791         return FALSE;
2792     }
2793     if (section_info->byte_swapped) {
2794         pen = GUINT32_SWAP_LE_BE(cb.pen);
2795     } else {
2796         pen = cb.pen;
2797     }
2798     ws_debug("pen %u, custom data and option length %u", pen, bh->block_total_length - MIN_CB_SIZE);
2799 
2800     switch (pen) {
2801         case PEN_NFLX:
2802             if (!pcapng_read_nflx_custom_block(fh, bh, section_info, wblock, err, err_info))
2803                 return FALSE;
2804             break;
2805         default:
2806             if (!pcapng_handle_generic_custom_block(fh, bh, pen, wblock, err, err_info)) {
2807                 return FALSE;
2808             }
2809             break;
2810     }
2811 
2812     wblock->rec->block = wblock->block;
2813     wblock->block = NULL;
2814     wblock->internal = FALSE;
2815 
2816     return TRUE;
2817 }
2818 
2819 static gboolean
pcapng_read_sysdig_event_block(FILE_T fh,pcapng_block_header_t * bh,const section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)2820 pcapng_read_sysdig_event_block(FILE_T fh, pcapng_block_header_t *bh,
2821                                const section_info_t *section_info,
2822                                wtapng_block_t *wblock,
2823                                int *err, gchar **err_info)
2824 {
2825     unsigned block_read;
2826     guint16 cpu_id;
2827     guint64 wire_ts;
2828     guint64 ts;
2829     guint64 thread_id;
2830     guint32 event_len;
2831     guint16 event_type;
2832     guint32 nparams = 0;
2833     guint min_event_size;
2834 
2835     switch (bh->block_type) {
2836         case BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE:
2837         case BLOCK_TYPE_SYSDIG_EVENT_V2:
2838             min_event_size = MIN_SYSDIG_EVENT_V2_SIZE;
2839             break;
2840         default:
2841             min_event_size = MIN_SYSDIG_EVENT_SIZE;
2842             break;
2843     }
2844 
2845     if (bh->block_total_length < min_event_size) {
2846         *err = WTAP_ERR_BAD_FILE;
2847         *err_info = g_strdup_printf("pcapng: total block length %u of a Sysdig event block is too small (< %u)",
2848                                     bh->block_total_length, min_event_size);
2849         return FALSE;
2850     }
2851 
2852     wblock->rec->rec_type = REC_TYPE_SYSCALL;
2853     wblock->rec->rec_header.syscall_header.record_type = bh->block_type;
2854     wblock->rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN /*|WTAP_HAS_INTERFACE_ID */;
2855     wblock->rec->tsprec = WTAP_TSPREC_NSEC;
2856 
2857     if (!wtap_read_bytes(fh, &cpu_id, sizeof cpu_id, err, err_info)) {
2858         ws_debug("failed to read sysdig event cpu id");
2859         return FALSE;
2860     }
2861     if (!wtap_read_bytes(fh, &wire_ts, sizeof wire_ts, err, err_info)) {
2862         ws_debug("failed to read sysdig event timestamp");
2863         return FALSE;
2864     }
2865     if (!wtap_read_bytes(fh, &thread_id, sizeof thread_id, err, err_info)) {
2866         ws_debug("failed to read sysdig event thread id");
2867         return FALSE;
2868     }
2869     if (!wtap_read_bytes(fh, &event_len, sizeof event_len, err, err_info)) {
2870         ws_debug("failed to read sysdig event length");
2871         return FALSE;
2872     }
2873     if (!wtap_read_bytes(fh, &event_type, sizeof event_type, err, err_info)) {
2874         ws_debug("failed to read sysdig event type");
2875         return FALSE;
2876     }
2877     if (bh->block_type == BLOCK_TYPE_SYSDIG_EVENT_V2 || bh->block_type == BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE) {
2878         if (!wtap_read_bytes(fh, &nparams, sizeof nparams, err, err_info)) {
2879             ws_debug("failed to read sysdig number of parameters");
2880             return FALSE;
2881         }
2882     }
2883 
2884     wblock->rec->rec_header.syscall_header.byte_order = G_BYTE_ORDER;
2885 
2886     /* XXX Use Gxxx_FROM_LE macros instead? */
2887     if (section_info->byte_swapped) {
2888         wblock->rec->rec_header.syscall_header.byte_order =
2889 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2890             G_BIG_ENDIAN;
2891 #else
2892             G_LITTLE_ENDIAN;
2893 #endif
2894         wblock->rec->rec_header.syscall_header.cpu_id = GUINT16_SWAP_LE_BE(cpu_id);
2895         ts = GUINT64_SWAP_LE_BE(wire_ts);
2896         wblock->rec->rec_header.syscall_header.thread_id = GUINT64_SWAP_LE_BE(thread_id);
2897         wblock->rec->rec_header.syscall_header.event_len = GUINT32_SWAP_LE_BE(event_len);
2898         wblock->rec->rec_header.syscall_header.event_type = GUINT16_SWAP_LE_BE(event_type);
2899         wblock->rec->rec_header.syscall_header.nparams = GUINT32_SWAP_LE_BE(nparams);
2900     } else {
2901         wblock->rec->rec_header.syscall_header.cpu_id = cpu_id;
2902         ts = wire_ts;
2903         wblock->rec->rec_header.syscall_header.thread_id = thread_id;
2904         wblock->rec->rec_header.syscall_header.event_len = event_len;
2905         wblock->rec->rec_header.syscall_header.event_type = event_type;
2906         wblock->rec->rec_header.syscall_header.nparams = nparams;
2907     }
2908 
2909     wblock->rec->ts.secs = (time_t) (ts / 1000000000);
2910     wblock->rec->ts.nsecs = (int) (ts % 1000000000);
2911 
2912     block_read = bh->block_total_length - min_event_size;
2913 
2914     wblock->rec->rec_header.syscall_header.event_filelen = block_read;
2915 
2916     /* "Sysdig Event Block" read event data */
2917     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2918                                 block_read, err, err_info))
2919         return FALSE;
2920 
2921     /* XXX Read comment? */
2922 
2923     /*
2924      * We return these to the caller in pcapng_read().
2925      */
2926     wblock->internal = FALSE;
2927 
2928     return TRUE;
2929 }
2930 
2931 static gboolean
pcapng_read_systemd_journal_export_block(wtap * wth,FILE_T fh,pcapng_block_header_t * bh,pcapng_t * pn _U_,wtapng_block_t * wblock,int * err,gchar ** err_info)2932 pcapng_read_systemd_journal_export_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_, wtapng_block_t *wblock, int *err, gchar **err_info)
2933 {
2934     guint32 entry_length;
2935     guint64 rt_ts;
2936     gboolean have_ts = FALSE;
2937 
2938     if (bh->block_total_length < MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE) {
2939         *err = WTAP_ERR_BAD_FILE;
2940         *err_info = g_strdup_printf("pcapng: total block length %u of a systemd journal export block is too small (< %u)",
2941                                     bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_BLOCK_SIZE);
2942         return FALSE;
2943     }
2944 
2945     entry_length = bh->block_total_length - MIN_BLOCK_SIZE;
2946 
2947     /* Includes padding bytes. */
2948     if (!wtap_read_packet_bytes(fh, wblock->frame_buffer,
2949                                 entry_length, err, err_info)) {
2950         return FALSE;
2951     }
2952 
2953     /*
2954      * We don't have memmem available everywhere, so we get to add space for
2955      * a trailing \0 for strstr below.
2956      */
2957     ws_buffer_assure_space(wblock->frame_buffer, entry_length+1);
2958 
2959     gchar *buf_ptr = (gchar *) ws_buffer_start_ptr(wblock->frame_buffer);
2960     while (entry_length > 0 && buf_ptr[entry_length-1] == '\0') {
2961         entry_length--;
2962     }
2963 
2964     if (entry_length < MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE) {
2965         *err = WTAP_ERR_BAD_FILE;
2966         *err_info = g_strdup_printf("pcapng: entry length %u is too small (< %u)",
2967                                     bh->block_total_length, MIN_SYSTEMD_JOURNAL_EXPORT_ENTRY_SIZE);
2968         return FALSE;
2969     }
2970 
2971     ws_debug("entry_length %u", entry_length);
2972 
2973     size_t rt_ts_len = strlen(SDJ__REALTIME_TIMESTAMP);
2974 
2975     buf_ptr[entry_length] = '\0';
2976     char *ts_pos = strstr(buf_ptr, SDJ__REALTIME_TIMESTAMP);
2977 
2978     if (!ts_pos) {
2979         ws_debug("no timestamp");
2980     } else if (ts_pos+rt_ts_len >= (char *) buf_ptr+entry_length) {
2981         ws_debug("timestamp past end of buffer");
2982     } else {
2983         const char *ts_end;
2984         have_ts = ws_strtou64(ts_pos+rt_ts_len, &ts_end, &rt_ts);
2985 
2986         if (!have_ts) {
2987             ws_debug("invalid timestamp");
2988         }
2989     }
2990 
2991     wblock->rec->rec_type = REC_TYPE_SYSTEMD_JOURNAL_EXPORT;
2992     wblock->rec->rec_header.systemd_journal_export_header.record_len = entry_length;
2993     wblock->rec->presence_flags = WTAP_HAS_CAP_LEN;
2994     if (have_ts) {
2995         wblock->rec->presence_flags |= WTAP_HAS_TS;
2996         wblock->rec->tsprec = WTAP_TSPREC_USEC;
2997         wblock->rec->ts.secs = (time_t) (rt_ts / 1000000);
2998         wblock->rec->ts.nsecs = (rt_ts % 1000000) * 1000;
2999     }
3000 
3001     /*
3002      * We return these to the caller in pcapng_read().
3003      */
3004     wblock->internal = FALSE;
3005 
3006     if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
3007         /*
3008          * Nothing (most notably an IDB) has set a file encap at this point.
3009          * Do so here.
3010          * XXX Should we set WTAP_ENCAP_SYSTEMD_JOURNAL if appropriate?
3011          */
3012         wth->file_encap = WTAP_ENCAP_PER_PACKET;
3013     }
3014 
3015     return TRUE;
3016 }
3017 
3018 static gboolean
pcapng_read_unknown_block(FILE_T fh,pcapng_block_header_t * bh,const section_info_t * section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)3019 pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
3020 #ifdef HAVE_PLUGINS
3021     const section_info_t *section_info,
3022 #else
3023     const section_info_t *section_info _U_,
3024 #endif
3025     wtapng_block_t *wblock,
3026     int *err, gchar **err_info)
3027 {
3028     guint32 block_read;
3029 #ifdef HAVE_PLUGINS
3030     block_handler *handler;
3031 #endif
3032 
3033     if (bh->block_total_length < MIN_BLOCK_SIZE) {
3034         *err = WTAP_ERR_BAD_FILE;
3035         *err_info = g_strdup_printf("pcapng: total block length %u of an unknown block type is less than the minimum block size %u",
3036                                     bh->block_total_length, MIN_BLOCK_SIZE);
3037         return FALSE;
3038     }
3039 
3040     block_read = bh->block_total_length - MIN_BLOCK_SIZE;
3041 
3042 #ifdef HAVE_PLUGINS
3043     /*
3044      * Do we have a handler for this block type?
3045      */
3046     if (block_handlers != NULL &&
3047         (handler = (block_handler *)g_hash_table_lookup(block_handlers,
3048                                                         GUINT_TO_POINTER(bh->block_type))) != NULL) {
3049         /* Yes - call it to read this block type. */
3050         if (!handler->reader(fh, block_read, section_info->byte_swapped, wblock,
3051                              err, err_info))
3052             return FALSE;
3053     } else
3054 #endif
3055     {
3056         /* No.  Skip over this unknown block. */
3057         if (!wtap_read_bytes(fh, NULL, block_read, err, err_info)) {
3058             return FALSE;
3059         }
3060 
3061         /*
3062          * We're skipping this, so we won't return these to the caller
3063          * in pcapng_read().
3064          */
3065         wblock->internal = TRUE;
3066     }
3067 
3068     return TRUE;
3069 }
3070 
3071 static gboolean
pcapng_read_and_check_block_trailer(FILE_T fh,pcapng_block_header_t * bh,section_info_t * section_info,int * err,gchar ** err_info)3072 pcapng_read_and_check_block_trailer(FILE_T fh, pcapng_block_header_t *bh,
3073                                     section_info_t *section_info,
3074                                     int *err, gchar **err_info)
3075 {
3076     guint32 block_total_length;
3077 
3078     /* sanity check: first and second block lengths must match */
3079     if (!wtap_read_bytes(fh, &block_total_length, sizeof block_total_length,
3080                          err, err_info)) {
3081         ws_debug("couldn't read second block length");
3082         return FALSE;
3083     }
3084 
3085     if (section_info->byte_swapped)
3086         block_total_length = GUINT32_SWAP_LE_BE(block_total_length);
3087 
3088     /*
3089      * According to the pcapng spec, this should equal the block total
3090      * length value at the beginning of the block, which MUST (in the
3091      * IANA sense) be a multiple of 4.
3092      *
3093      * We round the value at the beginning of the block to a multiple
3094      * of 4, so do so with this value as well.  This *does* mean that
3095      * the two values, if they're not both multiples of 4, can differ
3096      * and this code won't detect that, but we're already not detecting
3097      * non-multiple-of-4 total lengths.
3098      */
3099     block_total_length = ROUND_TO_4BYTE(block_total_length);
3100 
3101     if (block_total_length != bh->block_total_length) {
3102         *err = WTAP_ERR_BAD_FILE;
3103         *err_info = g_strdup_printf("pcapng: total block lengths (first %u and second %u) don't match",
3104                                     bh->block_total_length, block_total_length);
3105         return FALSE;
3106     }
3107     return TRUE;
3108 }
3109 
3110 static gboolean
pcapng_read_block(wtap * wth,FILE_T fh,pcapng_t * pn,section_info_t * section_info,section_info_t * new_section_info,wtapng_block_t * wblock,int * err,gchar ** err_info)3111 pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn,
3112                   section_info_t *section_info,
3113                   section_info_t *new_section_info,
3114                   wtapng_block_t *wblock,
3115                   int *err, gchar **err_info)
3116 {
3117     block_return_val ret;
3118     pcapng_block_header_t bh;
3119 
3120     wblock->block = NULL;
3121 
3122     /* Try to read the (next) block header */
3123     if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
3124         ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
3125         return FALSE;
3126     }
3127 
3128     /*
3129      * SHBs have to be treated differently from other blocks, because
3130      * the byte order of the fields in the block can only be determined
3131      * by looking at the byte-order magic number inside the block, not
3132      * by using the byte order of the section to which it belongs, as
3133      * it is the block that *defines* the byte order of the section to
3134      * which it belongs.
3135      */
3136     if (bh.block_type == BLOCK_TYPE_SHB) {
3137         /*
3138          * BLOCK_TYPE_SHB has the same value regardless of byte order,
3139          * so we don't need to byte-swap it.
3140          *
3141          * We *might* need to byte-swap the total length, but we
3142          * can't determine whether we do until we look inside the
3143          * block and find the byte-order magic number, so we rely
3144          * on pcapng_read_section_header_block() to do that and
3145          * to swap the total length (as it needs to get the total
3146          * length in the right byte order in order to read the
3147          * entire block).
3148          */
3149         wblock->type = bh.block_type;
3150 
3151         ws_debug("block_type 0x%08x", bh.block_type);
3152 
3153         /*
3154          * Fill in the section_info_t passed to us for use when
3155          * there's a new SHB; don't overwrite the existing SHB,
3156          * if there is one.
3157          */
3158         ret = pcapng_read_section_header_block(fh, &bh, new_section_info,
3159                                                wblock, err, err_info);
3160         if (ret != PCAPNG_BLOCK_OK) {
3161             return FALSE;
3162         }
3163 
3164         /*
3165          * This is the current section; use its byte order, not that
3166          * of the section pointed to by section_info (which could be
3167          * null).
3168          */
3169         section_info = new_section_info;
3170     } else {
3171         /*
3172          * Not an SHB.
3173          */
3174         if (section_info->byte_swapped) {
3175             bh.block_type         = GUINT32_SWAP_LE_BE(bh.block_type);
3176             bh.block_total_length = GUINT32_SWAP_LE_BE(bh.block_total_length);
3177         }
3178 
3179         /*
3180          * Add padding bytes to the block total length.
3181          * (The "block total length" fields of some example files
3182          * don't contain the packet data padding bytes!)
3183          *
3184          * For all block types currently defined in the pcapng
3185          * specification, the portion of the block that precedes
3186          * the options is, if necessary, padded to be a multiple
3187          * of 4 octets, the header of an option is 4 octets long,
3188          * and the value of an option is also padded to be a
3189          * multiple of 4 octets, so the total length of a block
3190          * is always a multiple of 4 octets.
3191          *
3192          * If you have defined a block where that is not true, you
3193          * have violated the pcapng specification - hwere it says
3194          * that "[The value fo the Block Total Length] MUST be a
3195          * multiple of 4.", with MUST as described in BCP 14 (RFC 2119/
3196          * RFC 8174).
3197          *
3198          * Therefore, if adjusting the block total length causes the
3199          * code to read your block type not to work, that's your
3200          * problem.  It's bad enough that some blocks were written
3201          * out with the block total length not including the padding.
3202          * (Please note that libpcap is less forgiving that we are;
3203          * it reports an error if the block total length isn't a
3204          * multiple of 4.)
3205          */
3206         bh.block_total_length = ROUND_TO_4BYTE(bh.block_total_length);
3207 
3208         wblock->type = bh.block_type;
3209 
3210         ws_debug("block_type 0x%08x", bh.block_type);
3211 
3212         /* Don't try to allocate memory for a huge number of options, as
3213            that might fail and, even if it succeeds, it might not leave
3214            any address space or memory+backing store for anything else.
3215 
3216            We do that by imposing a maximum block size of MAX_BLOCK_SIZE. */
3217         if (bh.block_total_length > MAX_BLOCK_SIZE) {
3218             *err = WTAP_ERR_BAD_FILE;
3219             *err_info = g_strdup_printf("pcapng: total block length %u is too large (> %u)",
3220                                         bh.block_total_length, MAX_BLOCK_SIZE);
3221             return FALSE;
3222         }
3223 
3224         /*
3225          * ***DO NOT*** add any items to this table that are not
3226          * standardized block types in the current pcapng spec at
3227          *
3228          *    https://pcapng.github.io/pcapng/draft-tuexen-opsawg-pcapng.html
3229          *
3230          * All block types in this switch statement here must be
3231          * listed there as standardized block types, ideally with
3232          * a description.
3233          */
3234         switch (bh.block_type) {
3235             case(BLOCK_TYPE_IDB):
3236                 if (!pcapng_read_if_descr_block(wth, fh, &bh, section_info, wblock, err, err_info))
3237                     return FALSE;
3238                 break;
3239             case(BLOCK_TYPE_PB):
3240                 if (!pcapng_read_packet_block(fh, &bh, section_info, wblock, err, err_info, FALSE))
3241                     return FALSE;
3242                 break;
3243             case(BLOCK_TYPE_SPB):
3244                 if (!pcapng_read_simple_packet_block(fh, &bh, section_info, wblock, err, err_info))
3245                     return FALSE;
3246                 break;
3247             case(BLOCK_TYPE_EPB):
3248                 if (!pcapng_read_packet_block(fh, &bh, section_info, wblock, err, err_info, TRUE))
3249                     return FALSE;
3250                 break;
3251             case(BLOCK_TYPE_NRB):
3252                 if (!pcapng_read_name_resolution_block(fh, &bh, pn, section_info, wblock, err, err_info))
3253                     return FALSE;
3254                 break;
3255             case(BLOCK_TYPE_ISB):
3256                 if (!pcapng_read_interface_statistics_block(fh, &bh, section_info, wblock, err, err_info))
3257                     return FALSE;
3258                 break;
3259             case(BLOCK_TYPE_DSB):
3260                 if (!pcapng_read_decryption_secrets_block(fh, &bh, section_info, wblock, err, err_info))
3261                     return FALSE;
3262                 break;
3263             case(BLOCK_TYPE_CB_COPY):
3264             case(BLOCK_TYPE_CB_NO_COPY):
3265                 if (!pcapng_read_custom_block(fh, &bh, section_info, wblock, err, err_info))
3266                     return FALSE;
3267                 break;
3268             case(BLOCK_TYPE_SYSDIG_EVENT):
3269             case(BLOCK_TYPE_SYSDIG_EVENT_V2):
3270             case(BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE):
3271             /* case(BLOCK_TYPE_SYSDIG_EVF): */
3272                 if (!pcapng_read_sysdig_event_block(fh, &bh, section_info, wblock, err, err_info))
3273                     return FALSE;
3274                 break;
3275             case(BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT):
3276                 if (!pcapng_read_systemd_journal_export_block(wth, fh, &bh, pn, wblock, err, err_info))
3277                     return FALSE;
3278                 break;
3279             default:
3280                 ws_debug("Unknown block_type: 0x%08x (block ignored), block total length %d",
3281                          bh.block_type, bh.block_total_length);
3282                 if (!pcapng_read_unknown_block(fh, &bh, section_info, wblock, err, err_info))
3283                     return FALSE;
3284                 break;
3285         }
3286     }
3287 
3288     /*
3289      * Read and check the block trailer.
3290      */
3291     if (!pcapng_read_and_check_block_trailer(fh, &bh, section_info, err, err_info)) {
3292         /* Not readable or not valid. */
3293         return FALSE;
3294     }
3295     return TRUE;
3296 }
3297 
3298 /* Process an IDB that we've just read. The contents of wblock are copied as needed. */
3299 static void
pcapng_process_idb(wtap * wth,section_info_t * section_info,wtapng_block_t * wblock)3300 pcapng_process_idb(wtap *wth, section_info_t *section_info,
3301                    wtapng_block_t *wblock)
3302 {
3303     wtap_block_t int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
3304     interface_info_t iface_info;
3305     wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data),
3306                                 *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
3307     guint8 if_fcslen;
3308 
3309     wtap_block_copy(int_data, wblock->block);
3310 
3311     /* XXX if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
3312     /* Interface statistics */
3313     if_descr_mand->num_stat_entries = 0;
3314     if_descr_mand->interface_statistics = NULL;
3315 
3316     wtap_add_idb(wth, int_data);
3317 
3318     iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
3319     iface_info.snap_len = wblock_if_descr_mand->snap_len;
3320     iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
3321     iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
3322 
3323     if (wtap_block_get_uint8_option_value(wblock->block, OPT_IDB_FCSLEN,
3324                                           &if_fcslen) == WTAP_OPTTYPE_SUCCESS)
3325         iface_info.fcslen = if_fcslen;
3326     else
3327         iface_info.fcslen = -1;
3328 
3329     g_array_append_val(section_info->interfaces, iface_info);
3330 }
3331 
3332 /* Process a DSB that we have just read. */
3333 static void
pcapng_process_dsb(wtap * wth,wtapng_block_t * wblock)3334 pcapng_process_dsb(wtap *wth, wtapng_block_t *wblock)
3335 {
3336     wtapng_process_dsb(wth, wblock->block);
3337 
3338     /* Store DSB such that it can be saved by the dumper. */
3339     g_array_append_val(wth->dsbs, wblock->block);
3340 }
3341 
3342 /* classic wtap: open capture file */
3343 wtap_open_return_val
pcapng_open(wtap * wth,int * err,gchar ** err_info)3344 pcapng_open(wtap *wth, int *err, gchar **err_info)
3345 {
3346     wtapng_block_t wblock;
3347     pcapng_t *pcapng;
3348     pcapng_block_header_t bh;
3349     gint64 saved_offset;
3350     section_info_t first_section, new_section, *current_section;
3351 
3352     ws_debug("opening file");
3353     /*
3354      * Read first block.
3355      *
3356      * First, try to read the block header.
3357      */
3358     if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3359         ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err);
3360         if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
3361             /*
3362              * Short read or EOF.
3363              *
3364              * We're reading this as part of an open, so
3365              * the file is too short to be a pcapng file.
3366              */
3367             *err = 0;
3368             g_free(*err_info);
3369             *err_info = NULL;
3370             return WTAP_OPEN_NOT_MINE;
3371         }
3372         return WTAP_OPEN_ERROR;
3373     }
3374 
3375     /*
3376      * If this is a pcapng file, the first block must be a
3377      * Section Header Block.
3378      */
3379     if (bh.block_type != BLOCK_TYPE_SHB) {
3380         /*
3381          * Not an SHB, so this isn't a pcapng file.
3382          *
3383          * XXX - check for damage from transferring a file
3384          * between Windows and UN*X as text rather than
3385          * binary data?
3386          */
3387         ws_debug("first block type 0x%08x not SHB", bh.block_type);
3388         return WTAP_OPEN_NOT_MINE;
3389     }
3390 
3391     ws_debug("got an SHB");
3392 
3393     /*
3394      * Now try to read the block body, filling in the section_info_t
3395      * for the first section.
3396      */
3397     wblock.type = bh.block_type;
3398     wblock.block = NULL;
3399     /* we don't expect any packet blocks yet */
3400     wblock.frame_buffer = NULL;
3401     wblock.rec = NULL;
3402 
3403     switch (pcapng_read_section_header_block(wth->fh, &bh, &first_section,
3404                                              &wblock, err, err_info)) {
3405     case PCAPNG_BLOCK_OK:
3406         /* No problem */
3407         break;
3408 
3409     case PCAPNG_BLOCK_NOT_SHB:
3410         /* This doesn't look like an SHB, so this isn't a pcapng file. */
3411         wtap_block_unref(wblock.block);
3412         *err = 0;
3413         g_free(*err_info);
3414         *err_info = NULL;
3415         return WTAP_OPEN_NOT_MINE;
3416 
3417     case PCAPNG_BLOCK_ERROR:
3418         wtap_block_unref(wblock.block);
3419         if (*err == WTAP_ERR_SHORT_READ) {
3420             /*
3421              * Short read.
3422              *
3423              * We're reading this as part of an open, so
3424              * the file is too short to be a pcapng file.
3425              */
3426             *err = 0;
3427             g_free(*err_info);
3428             *err_info = NULL;
3429             return WTAP_OPEN_NOT_MINE;
3430         }
3431         /* An I/O error. */
3432         return WTAP_OPEN_ERROR;
3433     }
3434 
3435     /*
3436      * Read and check the block trailer.
3437      */
3438     if (!pcapng_read_and_check_block_trailer(wth->fh, &bh, &first_section, err, err_info)) {
3439         /* Not readable or not valid. */
3440         wtap_block_unref(wblock.block);
3441         return WTAP_OPEN_ERROR;
3442     }
3443 
3444     /*
3445      * At this point, we've decided this is a pcapng file, not
3446      * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
3447      * past this point.
3448      *
3449      * Copy the SHB that we just read to the first entry in the table of
3450      * SHBs for this file.
3451      */
3452     wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), wblock.block);
3453     wtap_block_unref(wblock.block);
3454     wblock.block = NULL;
3455 
3456     wth->file_encap = WTAP_ENCAP_UNKNOWN;
3457     wth->snapshot_length = 0;
3458     wth->file_tsprec = WTAP_TSPREC_UNKNOWN;
3459     pcapng = g_new(pcapng_t, 1);
3460     wth->priv = (void *)pcapng;
3461     /*
3462      * We're currently processing the first section; as this is written
3463      * in C, that's section 0. :-)
3464      */
3465     pcapng->current_section_number = 0;
3466 
3467     /*
3468      * Create the array of interfaces for the first section.
3469      */
3470     first_section.interfaces = g_array_new(FALSE, FALSE, sizeof(interface_info_t));
3471 
3472     /*
3473      * The first section is at the very beginning of the file.
3474      */
3475     first_section.shb_off = 0;
3476 
3477     /*
3478      * Allocate the sections table with space reserved for the first
3479      * section, and add that section.
3480      */
3481     pcapng->sections = g_array_sized_new(FALSE, FALSE, sizeof(section_info_t), 1);
3482     g_array_append_val(pcapng->sections, first_section);
3483 
3484     /*
3485      * Set the callbacks for new addresses to null; if our caller wants
3486      * to be called, they will set them to point to the appropriate
3487      * caller.
3488      */
3489     pcapng->add_new_ipv4 = NULL;
3490     pcapng->add_new_ipv6 = NULL;
3491 
3492     wth->subtype_read = pcapng_read;
3493     wth->subtype_seek_read = pcapng_seek_read;
3494     wth->subtype_close = pcapng_close;
3495     wth->file_type_subtype = pcapng_file_type_subtype;
3496 
3497     /* Always initialize the list of Decryption Secret Blocks such that a
3498      * wtap_dumper can refer to it right after opening the capture file. */
3499     wth->dsbs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
3500 
3501     /* Loop over all IDBs that appear before any packets */
3502     while (1) {
3503         /* peek at next block */
3504         /* Try to read the (next) block header */
3505         saved_offset = file_tell(wth->fh);
3506         if (!wtap_read_bytes_or_eof(wth->fh, &bh, sizeof bh, err, err_info)) {
3507             if (*err == 0) {
3508                 /* EOF */
3509                 ws_debug("No more IDBs available...");
3510                 break;
3511             }
3512             ws_debug("Check for more IDBs, wtap_read_bytes_or_eof() failed, err = %d.",
3513                      *err);
3514             return WTAP_OPEN_ERROR;
3515         }
3516 
3517         /* go back to where we were */
3518         file_seek(wth->fh, saved_offset, SEEK_SET, err);
3519 
3520         /*
3521          * Get a pointer to the current section's section_info_t.
3522          */
3523         current_section = &g_array_index(pcapng->sections, section_info_t,
3524                                          pcapng->current_section_number);
3525 
3526         if (current_section->byte_swapped) {
3527             bh.block_type         = GUINT32_SWAP_LE_BE(bh.block_type);
3528         }
3529 
3530         ws_debug("Check for more IDBs, block_type 0x%08x",
3531                  bh.block_type);
3532 
3533         if (bh.block_type != BLOCK_TYPE_IDB) {
3534             break;  /* No more IDBs */
3535         }
3536 
3537         if (!pcapng_read_block(wth, wth->fh, pcapng, current_section,
3538                               &new_section, &wblock, err, err_info)) {
3539             wtap_block_unref(wblock.block);
3540             if (*err == 0) {
3541                 ws_debug("No more IDBs available...");
3542                 break;
3543             } else {
3544                 ws_debug("couldn't read IDB");
3545                 return WTAP_OPEN_ERROR;
3546             }
3547         }
3548         pcapng_process_idb(wth, current_section, &wblock);
3549         wtap_block_unref(wblock.block);
3550         ws_debug("Read IDB number_of_interfaces %u, wtap_encap %i",
3551                  wth->interface_data->len, wth->file_encap);
3552     }
3553     return WTAP_OPEN_MINE;
3554 }
3555 
3556 /* classic wtap: read packet */
3557 static gboolean
pcapng_read(wtap * wth,wtap_rec * rec,Buffer * buf,int * err,gchar ** err_info,gint64 * data_offset)3558 pcapng_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err,
3559             gchar **err_info, gint64 *data_offset)
3560 {
3561     pcapng_t *pcapng = (pcapng_t *)wth->priv;
3562     section_info_t *current_section, new_section;
3563     wtapng_block_t wblock;
3564     wtap_block_t wtapng_if_descr;
3565     wtap_block_t if_stats;
3566     wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
3567     wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
3568 
3569     wblock.frame_buffer  = buf;
3570     wblock.rec = rec;
3571 
3572     pcapng->add_new_ipv4 = wth->add_new_ipv4;
3573     pcapng->add_new_ipv6 = wth->add_new_ipv6;
3574 
3575     /* read next block */
3576     while (1) {
3577         *data_offset = file_tell(wth->fh);
3578         ws_debug("data_offset is %" G_GINT64_MODIFIER "d", *data_offset);
3579 
3580         /*
3581          * Get the section_info_t for the current section.
3582          */
3583         current_section = &g_array_index(pcapng->sections, section_info_t,
3584                                          pcapng->current_section_number);
3585 
3586         /*
3587          * Read the next block.
3588          */
3589         if (!pcapng_read_block(wth, wth->fh, pcapng, current_section,
3590                                &new_section, &wblock, err, err_info)) {
3591             ws_debug("data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
3592             ws_debug("couldn't read packet block");
3593             wtap_block_unref(wblock.block);
3594             return FALSE;
3595         }
3596 
3597         if (!wblock.internal) {
3598             /*
3599              * This is a block type we return to the caller to process.
3600              */
3601             ws_debug("rec_type %u", wblock.rec->rec_type);
3602             break;
3603         }
3604 
3605         /*
3606          * This is a block type we process internally, rather than
3607          * returning it for the caller to process.
3608          */
3609         switch (wblock.type) {
3610 
3611             case(BLOCK_TYPE_SHB):
3612                 ws_debug("another section header block");
3613 
3614                 /*
3615                  * Add this SHB to the table of SHBs.
3616                  */
3617                 g_array_append_val(wth->shb_hdrs, wblock.block);
3618 
3619                 /*
3620                  * Update the current section number, and add
3621                  * the updated section_info_t to the array of
3622                  * section_info_t's for this file.
3623                  */
3624                 pcapng->current_section_number++;
3625                 new_section.interfaces = g_array_new(FALSE, FALSE, sizeof(interface_info_t));
3626                 new_section.shb_off = *data_offset;
3627                 g_array_append_val(pcapng->sections, new_section);
3628                 break;
3629 
3630             case(BLOCK_TYPE_IDB):
3631                 /* A new interface */
3632                 ws_debug("block type BLOCK_TYPE_IDB");
3633                 pcapng_process_idb(wth, current_section, &wblock);
3634                 wtap_block_unref(wblock.block);
3635                 break;
3636 
3637             case(BLOCK_TYPE_DSB):
3638                 /* Decryption secrets. */
3639                 ws_debug("block type BLOCK_TYPE_DSB");
3640                 pcapng_process_dsb(wth, &wblock);
3641                 /* Do not free wblock.block, it is consumed by pcapng_process_dsb */
3642                 break;
3643 
3644             case(BLOCK_TYPE_NRB):
3645                 /* More name resolution entries */
3646                 ws_debug("block type BLOCK_TYPE_NRB");
3647                 if (wth->nrb_hdrs == NULL) {
3648                     wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
3649                 }
3650                 g_array_append_val(wth->nrb_hdrs, wblock.block);
3651                 break;
3652 
3653             case(BLOCK_TYPE_ISB):
3654                 /*
3655                  * Another interface statistics report
3656                  *
3657                  * XXX - given that they're reports, we should be
3658                  * supplying them in read calls, and displaying them
3659                  * in the "packet" list, so you can see what the
3660                  * statistics were *at the time when the report was
3661                  * made*.
3662                  *
3663                  * The statistics from the *last* ISB could be displayed
3664                  * in the summary, but if there are packets after the
3665                  * last ISB, that could be misleading.
3666                  *
3667                  * If we only display them if that ISB has an isb_endtime
3668                  * option, which *should* only appear when capturing ended
3669                  * on that interface (so there should be no more packet
3670                  * blocks or ISBs for that interface after that point,
3671                  * that would be the best way of showing "summary"
3672                  * statistics.
3673                  */
3674                 ws_debug("block type BLOCK_TYPE_ISB");
3675                 if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock.block);
3676                 if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
3677                     ws_debug("BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces",
3678                              if_stats_mand_block->interface_id);
3679                 } else {
3680                     /* Get the interface description */
3681                     wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id);
3682                     wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
3683                     if (wtapng_if_descr_mand->num_stat_entries == 0) {
3684                         /* First ISB found, no previous entry */
3685                         ws_debug("block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
3686                         wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
3687                     }
3688 
3689                     if_stats = wtap_block_create(WTAP_BLOCK_IF_STATISTICS);
3690                     if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
3691                     if_stats_mand->interface_id  = if_stats_mand_block->interface_id;
3692                     if_stats_mand->ts_high       = if_stats_mand_block->ts_high;
3693                     if_stats_mand->ts_low        = if_stats_mand_block->ts_low;
3694 
3695                     wtap_block_copy(if_stats, wblock.block);
3696                     g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
3697                     wtapng_if_descr_mand->num_stat_entries++;
3698                 }
3699                 wtap_block_unref(wblock.block);
3700                 break;
3701 
3702             default:
3703                 /* XXX - improve handling of "unknown" blocks */
3704                 ws_debug("Unknown block type 0x%08x", wblock.type);
3705                 break;
3706         }
3707     }
3708 
3709     /*ws_debug("Read length: %u Packet length: %u", bytes_read, rec->rec_header.packet_header.caplen);*/
3710     ws_debug("data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset);
3711 
3712     return TRUE;
3713 }
3714 
3715 /* classic wtap: seek to file position and read packet */
3716 static gboolean
pcapng_seek_read(wtap * wth,gint64 seek_off,wtap_rec * rec,Buffer * buf,int * err,gchar ** err_info)3717 pcapng_seek_read(wtap *wth, gint64 seek_off,
3718                  wtap_rec *rec, Buffer *buf,
3719                  int *err, gchar **err_info)
3720 {
3721     pcapng_t *pcapng = (pcapng_t *)wth->priv;
3722     section_info_t *section_info, new_section;
3723     wtapng_block_t wblock;
3724 
3725 
3726     /* seek to the right file position */
3727     if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) < 0) {
3728         return FALSE;   /* Seek error */
3729     }
3730     ws_debug("reading at offset %" G_GINT64_MODIFIER "u", seek_off);
3731 
3732     /*
3733      * Find the section_info_t for the section in which this block
3734      * appears.
3735      *
3736      * First, make sure we have at least one section; if we don't, that's
3737      * an internal error.
3738      */
3739     ws_assert(pcapng->sections->len >= 1);
3740 
3741     /*
3742      * Now scan backwards through the array to find the first section
3743      * that begins at or before the offset of the block we're reading.
3744      *
3745      * Yes, that's O(n) in the number of blocks, but we're unlikely to
3746      * have many blocks and pretty unlikely to have more than one.
3747      */
3748     guint section_number = pcapng->sections->len - 1;
3749     for (;;) {
3750         section_info = &g_array_index(pcapng->sections, section_info_t,
3751                                       section_number);
3752         if (section_info->shb_off <= seek_off)
3753             break;
3754 
3755         /*
3756          * If that's section 0, something's wrong; that section should
3757          * have an offset of 0.
3758          */
3759         ws_assert(section_number != 0);
3760         section_number--;
3761     }
3762 
3763     wblock.frame_buffer = buf;
3764     wblock.rec = rec;
3765 
3766     /* read the block */
3767     if (!pcapng_read_block(wth, wth->random_fh, pcapng, section_info,
3768                            &new_section, &wblock, err, err_info)) {
3769         ws_debug("couldn't read packet block (err=%d).", *err);
3770         wtap_block_unref(wblock.block);
3771         return FALSE;
3772     }
3773 
3774     /* block must not be one we process internally rather than supplying */
3775     if (wblock.internal) {
3776         ws_debug("block type 0x%08x is not one we return",
3777                  wblock.type);
3778         wtap_block_unref(wblock.block);
3779         return FALSE;
3780     }
3781 
3782     wtap_block_unref(wblock.block);
3783     return TRUE;
3784 }
3785 
3786 /* classic wtap: close capture file */
3787 static void
pcapng_close(wtap * wth)3788 pcapng_close(wtap *wth)
3789 {
3790     pcapng_t *pcapng = (pcapng_t *)wth->priv;
3791 
3792     ws_debug("closing file");
3793 
3794     /*
3795      * Free up the interfaces tables for all the sections.
3796      */
3797     for (guint i = 0; i < pcapng->sections->len; i++) {
3798         section_info_t *section_info = &g_array_index(pcapng->sections,
3799                                                       section_info_t, i);
3800         g_array_free(section_info->interfaces, TRUE);
3801     }
3802     g_array_free(pcapng->sections, TRUE);
3803 }
3804 
3805 typedef guint32 (*compute_option_size_func)(wtap_block_t, guint, wtap_opttype_e, wtap_optval_t*);
3806 
3807 typedef struct compute_options_size_t
3808 {
3809     guint32 size;
3810     compute_option_size_func compute_option_size;
3811 } compute_options_size_t;
3812 
pcapng_compute_string_option_size(wtap_optval_t * optval)3813 static guint32 pcapng_compute_string_option_size(wtap_optval_t *optval)
3814 {
3815     guint32 size = 0, pad;
3816 
3817     size = (guint32)strlen(optval->stringval) & 0xffff;
3818     if ((size % 4)) {
3819         pad = 4 - (size % 4);
3820     } else {
3821         pad = 0;
3822     }
3823 
3824     size += pad;
3825 
3826     return size;
3827 }
3828 
3829 #if 0
3830 static guint32 pcapng_compute_bytes_option_size(wtap_optval_t *optval)
3831 {
3832     guint32 size = 0, pad;
3833 
3834     size = (guint32)g_bytes_get_size(optval->byteval) & 0xffff;
3835     if ((size % 4)) {
3836         pad = 4 - (size % 4);
3837     } else {
3838         pad = 0;
3839     }
3840 
3841     size += pad;
3842 
3843     return size;
3844 }
3845 #endif
3846 
pcapng_compute_if_filter_option_size(wtap_optval_t * optval)3847 static guint32 pcapng_compute_if_filter_option_size(wtap_optval_t *optval)
3848 {
3849     if_filter_opt_t* filter = &optval->if_filterval;
3850     guint32 size;
3851     guint32 pad;
3852 
3853     if (filter->type == if_filter_pcap) {
3854         size = (guint32)(strlen(filter->data.filter_str) + 1) & 0xffff;
3855     } else if (filter->type == if_filter_bpf) {
3856         size = (guint32)((filter->data.bpf_prog.bpf_prog_len * 8) + 1) & 0xffff;
3857     } else {
3858         /* Unknown type; don't write it */
3859         size = 0;
3860     }
3861     if ((size % 4)) {
3862         pad = 4 - (size % 4);
3863     } else {
3864         pad = 0;
3865     }
3866     size += pad;
3867     return size;
3868 }
3869 
pcapng_compute_custom_option_size(wtap_optval_t * optval)3870 static guint32 pcapng_compute_custom_option_size(wtap_optval_t *optval)
3871 {
3872     size_t size, pad;
3873 
3874     /* PEN */
3875     size = sizeof(guint32);
3876     switch (optval->custom_opt.pen) {
3877     case PEN_NFLX:
3878         /* NFLX type */
3879         size += sizeof(guint32);
3880         size += optval->custom_opt.data.nflx_data.custom_data_len;
3881         break;
3882     default:
3883         size += optval->custom_opt.data.generic_data.custom_data_len;
3884         break;
3885     }
3886     if (size > 65535) {
3887         size = 65535;
3888     }
3889     if ((size % 4)) {
3890         pad = 4 - (size % 4);
3891     } else {
3892         pad = 0;
3893     }
3894 
3895     size += pad;
3896 
3897     return (guint32)size;
3898 }
3899 
pcapng_compute_packet_verdict_option_size(wtap_optval_t * optval)3900 static guint32 pcapng_compute_packet_verdict_option_size(wtap_optval_t *optval)
3901 {
3902     packet_verdict_opt_t* verdict = &optval->packet_verdictval;
3903     guint32 size;
3904     guint32 pad;
3905 
3906     switch (verdict->type) {
3907 
3908     case packet_verdict_hardware:
3909         size = verdict->data.verdict_bytes->len;
3910         break;
3911 
3912     case packet_verdict_linux_ebpf_tc:
3913         size = 9;
3914         break;
3915 
3916     case packet_verdict_linux_ebpf_xdp:
3917         size = 9;
3918         break;
3919 
3920     default:
3921         size = 0;
3922         break;
3923     }
3924     if ((size % 4)) {
3925         pad = 4 - (size % 4);
3926     } else {
3927         pad = 0;
3928     }
3929     size += pad;
3930     return size;
3931 }
3932 
3933 static gboolean
compute_block_option_size(wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type,wtap_optval_t * optval,void * user_data)3934 compute_block_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type, wtap_optval_t *optval, void *user_data)
3935 {
3936     compute_options_size_t* compute_options_size = (compute_options_size_t*)user_data;
3937     guint32 size = 0;
3938 
3939     /*
3940      * Process the option IDs that are the same for all block types here;
3941      * call the block-type-specific compute_size function for others.
3942      */
3943     switch(option_id)
3944     {
3945     case OPT_COMMENT:
3946         size = pcapng_compute_string_option_size(optval);
3947         break;
3948     case OPT_CUSTOM_STR_COPY:
3949     case OPT_CUSTOM_BIN_COPY:
3950         size = pcapng_compute_custom_option_size(optval);
3951         break;
3952     case OPT_CUSTOM_STR_NO_COPY:
3953     case OPT_CUSTOM_BIN_NO_COPY:
3954         /*
3955          * Do not count these, as they're not supposed to be copied to
3956          * new files.
3957          *
3958          * XXX - what if we're writing out a file that's *not* based on
3959          * another file, so that we're *not* copying it from that file?
3960          */
3961         break;
3962     default:
3963         /* Block-type dependent; call the callback. */
3964         size = (*compute_options_size->compute_option_size)(block, option_id, option_type, optval);
3965         break;
3966     }
3967 
3968     /*
3969      * Are we writing this option?
3970      */
3971     if (size != 0) {
3972         /*
3973          * Yes.  Add the size of the option header to the size of the
3974          * option data.
3975          */
3976         compute_options_size->size += 4;
3977 
3978         /* Now add the size of the option value. */
3979         compute_options_size->size += size;
3980 
3981         /* Add optional padding to 32 bits */
3982         if ((size & 0x03) != 0)
3983         {
3984             compute_options_size->size += 4 - (size & 0x03);
3985         }
3986     }
3987     return TRUE; /* we always succeed */
3988 }
3989 
3990 static guint32
compute_options_size(wtap_block_t block,compute_option_size_func compute_option_size)3991 compute_options_size(wtap_block_t block, compute_option_size_func compute_option_size)
3992 {
3993     compute_options_size_t compute_options_size;
3994 
3995     /*
3996      * Compute the total size of all the options in the block.
3997      * This always suceeds, so we don't check the return value.
3998      */
3999     compute_options_size.size = 0;
4000     compute_options_size.compute_option_size = compute_option_size;
4001     wtap_block_foreach_option(block, compute_block_option_size, &compute_options_size);
4002 
4003     /* Are we writing any options? */
4004     if (compute_options_size.size != 0) {
4005         /* Yes, add the size of the End-of-options tag. */
4006         compute_options_size.size += 4;
4007     }
4008     return compute_options_size.size;
4009 }
4010 
compute_shb_option_size(wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval)4011 static guint32 compute_shb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
4012 {
4013     guint32 size;
4014 
4015     switch(option_id)
4016     {
4017     case OPT_SHB_HARDWARE:
4018     case OPT_SHB_OS:
4019     case OPT_SHB_USERAPPL:
4020         size = pcapng_compute_string_option_size(optval);
4021         break;
4022     default:
4023         /* Unknown options - size by datatype? */
4024         size = 0;
4025         break;
4026     }
4027     return size;
4028 }
4029 
4030 typedef gboolean (*write_option_func)(wtap_dumper *, wtap_block_t, guint, wtap_opttype_e, wtap_optval_t*, int*);
4031 
4032 typedef struct write_options_t
4033 {
4034     wtap_dumper *wdh;
4035     int *err;
4036     write_option_func write_option;
4037 }
4038 write_options_t;
4039 
pcapng_write_option_eofopt(wtap_dumper * wdh,int * err)4040 static gboolean pcapng_write_option_eofopt(wtap_dumper *wdh, int *err)
4041 {
4042     struct pcapng_option_header option_hdr;
4043 
4044     /* Write end of options */
4045     option_hdr.type = OPT_EOFOPT;
4046     option_hdr.value_length = 0;
4047     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4048         return FALSE;
4049     wdh->bytes_dumped += 4;
4050     return TRUE;
4051 }
4052 
pcapng_write_uint8_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4053 static gboolean pcapng_write_uint8_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4054 {
4055     struct pcapng_option_header option_hdr;
4056     const guint32 zero_pad = 0;
4057 
4058     option_hdr.type         = (guint16)option_id;
4059     option_hdr.value_length = (guint16)1;
4060     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4061         return FALSE;
4062     wdh->bytes_dumped += 4;
4063 
4064     if (!wtap_dump_file_write(wdh, &optval->uint8val, 1, err))
4065         return FALSE;
4066     wdh->bytes_dumped += 1;
4067 
4068     if (!wtap_dump_file_write(wdh, &zero_pad, 3, err))
4069         return FALSE;
4070     wdh->bytes_dumped += 3;
4071 
4072     return TRUE;
4073 }
4074 
pcapng_write_uint32_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4075 static gboolean pcapng_write_uint32_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4076 {
4077     struct pcapng_option_header option_hdr;
4078 
4079     option_hdr.type         = (guint16)option_id;
4080     option_hdr.value_length = (guint16)4;
4081     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4082         return FALSE;
4083     wdh->bytes_dumped += 4;
4084 
4085     if (!wtap_dump_file_write(wdh, &optval->uint32val, 4, err))
4086         return FALSE;
4087     wdh->bytes_dumped += 4;
4088 
4089     return TRUE;
4090 }
4091 
pcapng_write_uint64_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4092 static gboolean pcapng_write_uint64_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4093 {
4094     struct pcapng_option_header option_hdr;
4095 
4096     option_hdr.type         = (guint16)option_id;
4097     option_hdr.value_length = (guint16)8;
4098     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4099         return FALSE;
4100     wdh->bytes_dumped += 4;
4101 
4102     if (!wtap_dump_file_write(wdh, &optval->uint64val, 8, err))
4103         return FALSE;
4104     wdh->bytes_dumped += 8;
4105 
4106     return TRUE;
4107 }
4108 
pcapng_write_timestamp_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4109 static gboolean pcapng_write_timestamp_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4110 {
4111     struct pcapng_option_header option_hdr;
4112     guint32 high, low;
4113 
4114     option_hdr.type         = (guint16)option_id;
4115     option_hdr.value_length = (guint16)8;
4116     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4117         return FALSE;
4118     wdh->bytes_dumped += 4;
4119 
4120     high = (guint32)(optval->uint64val >> 32);
4121     low = (guint32)(optval->uint64val >> 0);
4122     if (!wtap_dump_file_write(wdh, &high, 4, err))
4123         return FALSE;
4124     wdh->bytes_dumped += 4;
4125     if (!wtap_dump_file_write(wdh, &low, 4, err))
4126         return FALSE;
4127     wdh->bytes_dumped += 4;
4128 
4129     return TRUE;
4130 }
4131 
pcapng_write_string_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4132 static gboolean pcapng_write_string_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4133 {
4134     struct pcapng_option_header option_hdr;
4135     size_t size = strlen(optval->stringval);
4136     const guint32 zero_pad = 0;
4137     guint32 pad;
4138 
4139     if (size == 0)
4140         return TRUE;
4141     if (size > 65535) {
4142         /*
4143          * Too big to fit in the option.
4144          * Don't write anything.
4145          *
4146          * XXX - truncate it?  Report an error?
4147          */
4148         return TRUE;
4149     }
4150 
4151     /* String options don't consider pad bytes part of the length */
4152     option_hdr.type         = (guint16)option_id;
4153     option_hdr.value_length = (guint16)size;
4154     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4155         return FALSE;
4156     wdh->bytes_dumped += 4;
4157 
4158     if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4159         return FALSE;
4160     wdh->bytes_dumped += size;
4161 
4162     if ((size % 4)) {
4163         pad = 4 - (size % 4);
4164     } else {
4165         pad = 0;
4166     }
4167 
4168     /* write padding (if any) */
4169     if (pad != 0) {
4170         if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4171             return FALSE;
4172 
4173         wdh->bytes_dumped += pad;
4174     }
4175 
4176     return TRUE;
4177 }
4178 
4179 #if 0
4180 static gboolean pcapng_write_bytes_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4181 {
4182     struct pcapng_option_header option_hdr;
4183     size_t size = g_bytes_get_size(optval->byteval);
4184     const guint32 zero_pad = 0;
4185     guint32 pad;
4186 
4187     if (size == 0)
4188         return TRUE;
4189     if (size > 65535) {
4190         /*
4191          * Too big to fit in the option.
4192          * Don't write anything.
4193          *
4194          * XXX - truncate it?  Report an error?
4195          */
4196         return TRUE;
4197     }
4198 
4199     /* Bytes options don't consider pad bytes part of the length */
4200     option_hdr.type         = (guint16)option_id;
4201     option_hdr.value_length = (guint16)size;
4202     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4203         return FALSE;
4204     wdh->bytes_dumped += 4;
4205 
4206     if (!wtap_dump_file_write(wdh, optval->stringval, size, err))
4207         return FALSE;
4208     wdh->bytes_dumped += size;
4209 
4210     if ((size % 4)) {
4211         pad = 4 - (size % 4);
4212     } else {
4213         pad = 0;
4214     }
4215 
4216     /* write padding (if any) */
4217     if (pad != 0) {
4218         if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4219             return FALSE;
4220 
4221         wdh->bytes_dumped += pad;
4222     }
4223 
4224     return TRUE;
4225 }
4226 
4227 static gboolean pcapng_write_ipv4_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4228 {
4229     struct pcapng_option_header option_hdr;
4230 
4231     option_hdr.type         = (guint16)option_id;
4232     option_hdr.value_length = (guint16)4;
4233     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4234         return FALSE;
4235     wdh->bytes_dumped += 4;
4236 
4237     if (!wtap_dump_file_write(wdh, &optval->ipv4val, 1, err))
4238         return FALSE;
4239     wdh->bytes_dumped += 4;
4240 
4241     return TRUE;
4242 }
4243 
4244 static gboolean pcapng_write_ipv6_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4245 {
4246     struct pcapng_option_header option_hdr;
4247 
4248     option_hdr.type         = (guint16)option_id;
4249     option_hdr.value_length = (guint16)IPv6_ADDR_SIZE;
4250     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4251         return FALSE;
4252     wdh->bytes_dumped += 4;
4253 
4254     if (!wtap_dump_file_write(wdh, &optval->ipv6val.bytes, IPv6_ADDR_SIZE, err))
4255         return FALSE;
4256     wdh->bytes_dumped += IPv6_ADDR_SIZE;
4257 
4258     return TRUE;
4259 }
4260 #endif
4261 
pcapng_write_if_filter_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4262 static gboolean pcapng_write_if_filter_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4263 {
4264     if_filter_opt_t* filter = &optval->if_filterval;
4265     guint32 size, pad;
4266     guint8 filter_type;
4267     size_t filter_data_len;
4268     struct pcapng_option_header option_hdr;
4269     const guint32 zero_pad = 0;
4270 
4271     switch (filter->type) {
4272 
4273     case if_filter_pcap:
4274         filter_type = 0; /* pcap filter string */
4275         filter_data_len = strlen(filter->data.filter_str);
4276         if (filter_data_len > 65534) {
4277             /*
4278              * Too big to fit in the option.
4279              * Don't write anything.
4280              *
4281              * XXX - truncate it?  Report an error?
4282              */
4283             return TRUE;
4284         }
4285         break;
4286 
4287     case if_filter_bpf:
4288         filter_type = 1; /* BPF filter program */
4289         filter_data_len = filter->data.bpf_prog.bpf_prog_len*8;
4290         if (filter_data_len > 65528) {
4291             /*
4292              * Too big to fit in the option.  (The filter length
4293              * must be a multiple of 8, as that's the length
4294              * of a BPF instruction.)  Don't write anything.
4295              *
4296              * XXX - truncate it?  Report an error?
4297              */
4298             return TRUE;
4299         }
4300         break;
4301 
4302     default:
4303         /* Unknown filter type; don't write anything. */
4304         return TRUE;
4305     }
4306     size = (guint32)(filter_data_len + 1);
4307     if ((size % 4)) {
4308         pad = 4 - (size % 4);
4309     } else {
4310         pad = 0;
4311     }
4312 
4313     option_hdr.type         = option_id;
4314     option_hdr.value_length = size;
4315     if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4316         return FALSE;
4317     wdh->bytes_dumped += 4;
4318 
4319     /* Write the filter type */
4320     if (!wtap_dump_file_write(wdh, &filter_type, 1, err))
4321         return FALSE;
4322     wdh->bytes_dumped += 1;
4323 
4324     switch (filter->type) {
4325 
4326     case if_filter_pcap:
4327         /* Write the filter string */
4328         if (!wtap_dump_file_write(wdh, filter->data.filter_str, filter_data_len, err))
4329             return FALSE;
4330         wdh->bytes_dumped += filter_data_len;
4331         break;
4332 
4333     case if_filter_bpf:
4334         if (!wtap_dump_file_write(wdh, filter->data.bpf_prog.bpf_prog, filter_data_len, err))
4335             return FALSE;
4336         wdh->bytes_dumped += filter_data_len;
4337         break;
4338 
4339     default:
4340         ws_assert_not_reached();
4341         return TRUE;
4342     }
4343 
4344     /* write padding (if any) */
4345     if (pad != 0) {
4346         if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4347             return FALSE;
4348         wdh->bytes_dumped += pad;
4349     }
4350     return TRUE;
4351 }
4352 
pcapng_write_custom_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4353 static gboolean pcapng_write_custom_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4354 {
4355     struct pcapng_option_header option_hdr;
4356     gsize pad;
4357     gsize size;
4358     const guint32 zero_pad = 0;
4359     guint32 pen, type;
4360     gboolean use_little_endian;
4361 
4362     if ((option_id == OPT_CUSTOM_STR_NO_COPY) ||
4363         (option_id == OPT_CUSTOM_BIN_NO_COPY))
4364         return TRUE;
4365     ws_debug("PEN %d", optval->custom_opt.pen);
4366     switch (optval->custom_opt.pen) {
4367     case PEN_NFLX:
4368         size = sizeof(guint32) + sizeof(guint32) + optval->custom_opt.data.nflx_data.custom_data_len;
4369         use_little_endian = optval->custom_opt.data.nflx_data.use_little_endian;
4370         break;
4371     default:
4372         size = sizeof(guint32) + optval->custom_opt.data.generic_data.custom_data_len;
4373         use_little_endian = false;
4374         break;
4375     }
4376     ws_debug("use_little_endian %d", use_little_endian);
4377     if (size > 65535) {
4378         /*
4379          * Too big to fit in the option.
4380          * Don't write anything.
4381          *
4382          * XXX - truncate it?  Report an error?
4383          */
4384         return TRUE;
4385     }
4386 
4387     /* write option header */
4388     option_hdr.type         = (guint16)option_id;
4389     option_hdr.value_length = (guint16)size;
4390     if (use_little_endian) {
4391         option_hdr.type = GUINT16_TO_LE(option_hdr.type);
4392         option_hdr.value_length = GUINT16_TO_LE(option_hdr.value_length);
4393     }
4394     if (!wtap_dump_file_write(wdh, &option_hdr, sizeof(struct pcapng_option_header), err))
4395         return FALSE;
4396     wdh->bytes_dumped += sizeof(struct pcapng_option_header);
4397 
4398     /* write PEN */
4399     pen = optval->custom_opt.pen;
4400     if (use_little_endian) {
4401         pen = GUINT32_TO_LE(pen);
4402     }
4403     if (!wtap_dump_file_write(wdh, &pen, sizeof(guint32), err))
4404         return FALSE;
4405     wdh->bytes_dumped += sizeof(guint32);
4406 
4407     switch (optval->custom_opt.pen) {
4408     case PEN_NFLX:
4409         /* write NFLX type */
4410         type = GUINT32_TO_LE(optval->custom_opt.data.nflx_data.type);
4411         ws_debug("type=%d", type);
4412         if (!wtap_dump_file_write(wdh, &type, sizeof(guint32), err))
4413             return FALSE;
4414         wdh->bytes_dumped += sizeof(guint32);
4415         /* write custom data */
4416         if (!wtap_dump_file_write(wdh, optval->custom_opt.data.nflx_data.custom_data, optval->custom_opt.data.nflx_data.custom_data_len, err)) {
4417             return FALSE;
4418         }
4419         wdh->bytes_dumped += optval->custom_opt.data.nflx_data.custom_data_len;
4420         break;
4421     default:
4422         /* write custom data */
4423         if (!wtap_dump_file_write(wdh, optval->custom_opt.data.generic_data.custom_data, optval->custom_opt.data.generic_data.custom_data_len, err)) {
4424             return FALSE;
4425         }
4426         wdh->bytes_dumped += optval->custom_opt.data.generic_data.custom_data_len;
4427         break;
4428     }
4429 
4430     /* write padding (if any) */
4431     if (size % 4 != 0) {
4432         pad = 4 - (size % 4);
4433     } else {
4434         pad = 0;
4435     }
4436     if (pad != 0) {
4437         if (!wtap_dump_file_write(wdh, &zero_pad, pad, err)) {
4438             return FALSE;
4439         }
4440         wdh->bytes_dumped += pad;
4441     }
4442     ws_debug("Wrote custom option: type %u, length %u", option_hdr.type, option_hdr.value_length);
4443 
4444     return TRUE;
4445 }
4446 
pcapng_write_packet_verdict_option(wtap_dumper * wdh,guint option_id,wtap_optval_t * optval,int * err)4447 static gboolean pcapng_write_packet_verdict_option(wtap_dumper *wdh, guint option_id, wtap_optval_t *optval, int *err)
4448 {
4449     packet_verdict_opt_t* verdict = &optval->packet_verdictval;
4450     struct pcapng_option_header option_hdr;
4451     guint8 type;
4452     size_t size;
4453     const guint32 zero_pad = 0;
4454     guint32 pad;
4455 
4456     switch (verdict->type) {
4457 
4458     case packet_verdict_hardware:
4459         size = verdict->data.verdict_bytes->len;
4460         if (size > 65535) {
4461             /*
4462              * Too big to fit in the option.
4463              * Don't write anything.
4464              *
4465              * XXX - truncate it?  Report an error?
4466              */
4467             return TRUE;
4468         }
4469         option_hdr.type         = option_id;
4470         option_hdr.value_length = (guint16)size;
4471         if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4472             return FALSE;
4473         wdh->bytes_dumped += 4;
4474 
4475         type = packet_verdict_hardware;
4476         if (!wtap_dump_file_write(wdh, &type, sizeof(guint8), err))
4477             return FALSE;
4478         wdh->bytes_dumped += 1;
4479 
4480         if (!wtap_dump_file_write(wdh, verdict->data.verdict_bytes->data, size,
4481                                   err))
4482             return FALSE;
4483         wdh->bytes_dumped += size;
4484         break;
4485 
4486     case packet_verdict_linux_ebpf_tc:
4487         size = 9;
4488         option_hdr.type         = option_id;
4489         option_hdr.value_length = (guint16)size;
4490         if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4491             return FALSE;
4492         wdh->bytes_dumped += 4;
4493 
4494         type = packet_verdict_linux_ebpf_tc;
4495         if (!wtap_dump_file_write(wdh, &type, sizeof(guint8), err))
4496             return FALSE;
4497         wdh->bytes_dumped += 1;
4498 
4499         if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_tc,
4500                                   sizeof(guint64), err))
4501             return FALSE;
4502         wdh->bytes_dumped += 8;
4503         break;
4504 
4505     case packet_verdict_linux_ebpf_xdp:
4506         size = 9;
4507         option_hdr.type         = option_id;
4508         option_hdr.value_length = (guint16)size;
4509         if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
4510             return FALSE;
4511         wdh->bytes_dumped += 4;
4512 
4513         type = packet_verdict_linux_ebpf_xdp;
4514         if (!wtap_dump_file_write(wdh, &type, sizeof(guint8), err))
4515             return FALSE;
4516         wdh->bytes_dumped += 1;
4517 
4518         if (!wtap_dump_file_write(wdh, &verdict->data.verdict_linux_ebpf_xdp,
4519                                   sizeof(guint64), err))
4520             return FALSE;
4521         wdh->bytes_dumped += 8;
4522         break;
4523 
4524     default:
4525         /* Unknown - don't write it out. */
4526         return TRUE;
4527     }
4528 
4529     /* write padding (if any) */
4530     if ((size % 4)) {
4531         pad = 4 - (size % 4);
4532         if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
4533             return FALSE;
4534 
4535         wdh->bytes_dumped += pad;
4536     }
4537     return TRUE;
4538 }
4539 
write_block_option(wtap_block_t block,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval,void * user_data)4540 static gboolean write_block_option(wtap_block_t block, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data)
4541 {
4542     write_options_t* write_options = (write_options_t*)user_data;
4543 
4544     /*
4545      * Process the option IDs that are the same for all block types here;
4546      * call the block-type-specific compute_size function for others.
4547      */
4548     switch(option_id)
4549     {
4550     case OPT_COMMENT:
4551         if (!pcapng_write_string_option(write_options->wdh, option_id, optval, write_options->err))
4552             return FALSE;
4553         break;
4554     case OPT_CUSTOM_STR_COPY:
4555     case OPT_CUSTOM_BIN_COPY:
4556         if (!pcapng_write_custom_option(write_options->wdh, option_id, optval, write_options->err))
4557             return FALSE;
4558         break;
4559     case OPT_CUSTOM_STR_NO_COPY:
4560     case OPT_CUSTOM_BIN_NO_COPY:
4561         /*
4562          * Do not write these, as they're not supposed to be copied to
4563          * new files.
4564          *
4565          * XXX - what if we're writing out a file that's *not* based on
4566          * another file, so that we're *not* copying it from that file?
4567          */
4568         break;
4569     default:
4570         /* Block-type dependent; call the callback, if we have one. */
4571         if (write_options->write_option != NULL &&
4572             !(*write_options->write_option)(write_options->wdh, block, option_id, option_type, optval, write_options->err))
4573             return FALSE;
4574         break;
4575     }
4576     return TRUE;
4577 }
4578 
4579 static gboolean
write_options(wtap_dumper * wdh,wtap_block_t block,write_option_func write_option,int * err)4580 write_options(wtap_dumper *wdh, wtap_block_t block, write_option_func write_option, int *err)
4581 {
4582     write_options_t write_options;
4583 
4584     write_options.wdh = wdh;
4585     write_options.err = err;
4586     write_options.write_option = write_option;
4587     if (!wtap_block_foreach_option(block, write_block_option, &write_options))
4588         return FALSE;
4589 
4590     /* Write end of options */
4591     return pcapng_write_option_eofopt(wdh, err);
4592 }
4593 
write_wtap_shb_option(wtap_dumper * wdh,wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval,int * err)4594 static gboolean write_wtap_shb_option(wtap_dumper *wdh, wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
4595 {
4596     switch(option_id)
4597     {
4598     case OPT_SHB_HARDWARE:
4599     case OPT_SHB_OS:
4600     case OPT_SHB_USERAPPL:
4601         if (!pcapng_write_string_option(wdh, option_id, optval, err))
4602             return FALSE;
4603         break;
4604     default:
4605         /* Unknown options - write by datatype? */
4606         break;
4607     }
4608     return TRUE; /* success */
4609 }
4610 
4611 /* Write a section header block.
4612  * If we don't have a section block header already, create a default
4613  * one with no options.
4614  */
4615 static gboolean
pcapng_write_section_header_block(wtap_dumper * wdh,int * err)4616 pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
4617 {
4618     pcapng_block_header_t bh;
4619     pcapng_section_header_block_t shb;
4620     guint32 options_size;
4621     wtap_block_t wdh_shb = NULL;
4622 
4623     if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) {
4624         wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0);
4625     }
4626 
4627     bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + 4);
4628     options_size = 0;
4629     if (wdh_shb) {
4630         ws_debug("Have shb_hdr");
4631 
4632         /* Compute size of all the options */
4633         options_size = compute_options_size(wdh_shb, compute_shb_option_size);
4634 
4635         bh.block_total_length += options_size;
4636     }
4637 
4638     ws_debug("Total len %u", bh.block_total_length);
4639 
4640     /* write block header */
4641     bh.block_type = BLOCK_TYPE_SHB;
4642 
4643     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
4644         return FALSE;
4645     wdh->bytes_dumped += sizeof bh;
4646 
4647     /* write block fixed content */
4648     shb.magic = 0x1A2B3C4D;
4649     shb.version_major = 1;
4650     shb.version_minor = 0;
4651     if (wdh_shb) {
4652         wtapng_section_mandatory_t* section_data = (wtapng_section_mandatory_t*)wtap_block_get_mandatory_data(wdh_shb);
4653         shb.section_length = section_data->section_length;
4654     } else {
4655         shb.section_length = -1;
4656     }
4657 
4658     if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
4659         return FALSE;
4660     wdh->bytes_dumped += sizeof shb;
4661 
4662     if (wdh_shb) {
4663         /* Write options, if we have any */
4664         if (options_size != 0) {
4665             if (!write_options(wdh, wdh_shb, write_wtap_shb_option, err))
4666                 return FALSE;
4667         }
4668     }
4669 
4670     /* write block footer */
4671     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
4672                               sizeof bh.block_total_length, err))
4673         return FALSE;
4674     wdh->bytes_dumped += sizeof bh.block_total_length;
4675 
4676     return TRUE;
4677 }
4678 
4679 /* options defined in Section 2.5 (Options)
4680  * Name           Code Length     Description
4681  * opt_comment    1    variable   A UTF-8 string containing a comment that is associated to the current block.
4682  *
4683  * Enhanced Packet Block options
4684  * epb_flags      2    4          A flags word containing link-layer information. A complete specification of
4685  *                                the allowed flags can be found in Appendix A (Packet Block Flags Word).
4686  * epb_hash       3    variable   This option contains a hash of the packet. The first byte specifies the hashing algorithm,
4687  *                                while the following bytes contain the actual hash, whose size depends on the hashing algorithm,
4688  *                                                                and hence from the value in the first bit. The hashing algorithm can be: 2s complement
4689  *                                                                (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4),
4690  *                                                                MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX).
4691  *                                                                The hash covers only the packet, not the header added by the capture driver:
4692  *                                                                this gives the possibility to calculate it inside the network card.
4693  *                                                                The hash allows easier comparison/merging of different capture files, and reliable data transfer between the
4694  *                                                                data acquisition system and the capture library.
4695  * epb_dropcount   4   8          A 64bit integer value specifying the number of packets lost (by the interface and the operating system)
4696  *                                between this packet and the preceding one.
4697  * epb_packetid    5   8          The epb_packetid option is a 64-bit unsigned integer that
4698  *                                uniquely identifies the packet.  If the same packet is seen
4699  *                                by multiple interfaces and there is a way for the capture
4700  *                                application to correlate them, the same epb_packetid value
4701  *                                must be used.  An example could be a router that captures
4702  *                                packets on all its interfaces in both directions.  When a
4703  *                                packet hits interface A on ingress, an EPB entry gets
4704  *                                created, TTL gets decremented, and right before it egresses
4705  *                                on interface B another EPB entry gets created in the trace
4706  *                                file.  In this case, two packets are in the capture file,
4707  *                                which are not identical but the epb_packetid can be used to
4708  *                                correlate them.
4709  * epb_queue       6   4          The epb_queue option is a 32-bit unsigned integer that
4710  *                                identifies on which queue of the interface the specific
4711  *                                packet was received.
4712  * epb_verdict     7   variable   The epb_verdict option stores a verdict of the packet.  The
4713  *                                verdict indicates what would be done with the packet after
4714  *                                processing it.  For example, a firewall could drop the
4715  *                                packet.  This verdict can be set by various components, i.e.
4716  *                                Hardware, Linux's eBPF TC or XDP framework, etc.  etc.  The
4717  *                                first octet specifies the verdict type, while the following
4718  *                                octets contain the actual verdict data, whose size depends on
4719  *                                the verdict type, and hence from the value in the first
4720  *                                octet.  The verdict type can be: Hardware (type octet = 0,
4721  *                                size = variable), Linux_eBPF_TC (type octet = 1, size = 8
4722  *                                (64-bit unsigned integer), value = TC_ACT_* as defined in the
4723  *                                Linux pck_cls.h include), Linux_eBPF_XDP (type octet = 2,
4724  *                                size = 8 (64-bit unsigned integer), value = xdp_action as
4725  *                                defined in the Linux pbf.h include).
4726  * opt_endofopt    0   0          It delimits the end of the optional fields. This block cannot be repeated within a given list of options.
4727  */
4728 static guint32
compute_epb_option_size(wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval)4729 compute_epb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
4730 {
4731     guint32 size;
4732 
4733     switch(option_id)
4734     {
4735     case OPT_EPB_FLAGS:
4736         size = 4;
4737         break;
4738     case OPT_EPB_DROPCOUNT:
4739         size = 8;
4740         break;
4741     case OPT_EPB_PACKETID:
4742         size = 8;
4743         break;
4744     case OPT_EPB_QUEUE:
4745         size = 4;
4746         break;
4747     case OPT_EPB_VERDICT:
4748         size = pcapng_compute_packet_verdict_option_size(optval);
4749         break;
4750     default:
4751         /* Unknown options - size by datatype? */
4752         size = 0;
4753         break;
4754     }
4755     return size;
4756 }
4757 
write_wtap_epb_option(wtap_dumper * wdh,wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval,int * err)4758 static gboolean write_wtap_epb_option(wtap_dumper *wdh, wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
4759 {
4760     switch(option_id)
4761     {
4762     case OPT_PKT_FLAGS:
4763         if (!pcapng_write_uint32_option(wdh, OPT_EPB_FLAGS, optval, err))
4764             return FALSE;
4765         break;
4766     case OPT_PKT_DROPCOUNT:
4767         if (!pcapng_write_uint64_option(wdh, OPT_EPB_DROPCOUNT, optval, err))
4768             return FALSE;
4769         break;
4770     case OPT_PKT_PACKETID:
4771         if (!pcapng_write_uint64_option(wdh, OPT_EPB_PACKETID, optval, err))
4772             return FALSE;
4773         break;
4774     case OPT_PKT_QUEUE:
4775         if (!pcapng_write_uint32_option(wdh, OPT_EPB_QUEUE, optval, err))
4776             return FALSE;
4777         break;
4778     case OPT_PKT_VERDICT:
4779         if (!pcapng_write_packet_verdict_option(wdh, OPT_EPB_QUEUE, optval,
4780                                                 err))
4781         break;
4782     default:
4783         /* Unknown options - write by datatype? */
4784         break;
4785     }
4786     return TRUE; /* success */
4787 }
4788 
4789 static gboolean
pcapng_write_enhanced_packet_block(wtap_dumper * wdh,const wtap_rec * rec,const guint8 * pd,int * err,gchar ** err_info)4790 pcapng_write_enhanced_packet_block(wtap_dumper *wdh, const wtap_rec *rec,
4791                                    const guint8 *pd, int *err, gchar **err_info)
4792 {
4793     const union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
4794     pcapng_block_header_t bh;
4795     pcapng_enhanced_packet_block_t epb;
4796     guint32 options_size = 0;
4797     guint64 ts;
4798     const guint32 zero_pad = 0;
4799     guint32 pad_len;
4800     guint32 phdr_len;
4801     guint32 options_total_length = 0;
4802     wtap_block_t int_data;
4803     wtapng_if_descr_mandatory_t *int_data_mand;
4804 
4805     /* Don't write anything we're not willing to read. */
4806     if (rec->rec_header.packet_header.caplen > wtap_max_snaplen_for_encap(wdh->encap)) {
4807         *err = WTAP_ERR_PACKET_TOO_LARGE;
4808         return FALSE;
4809     }
4810 
4811     phdr_len = (guint32)pcap_get_phdr_size(rec->rec_header.packet_header.pkt_encap, pseudo_header);
4812     if ((phdr_len + rec->rec_header.packet_header.caplen) % 4) {
4813         pad_len = 4 - ((phdr_len + rec->rec_header.packet_header.caplen) % 4);
4814     } else {
4815         pad_len = 0;
4816     }
4817 
4818     if (rec->block != NULL) {
4819         /* Compute size of all the options */
4820         options_size = compute_options_size(rec->block, compute_epb_option_size);
4821     }
4822 
4823     /* write (enhanced) packet block header */
4824     bh.block_type = BLOCK_TYPE_EPB;
4825     bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + rec->rec_header.packet_header.caplen + pad_len + options_total_length + options_size + 4;
4826 
4827     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
4828         return FALSE;
4829     wdh->bytes_dumped += sizeof bh;
4830 
4831     /* write block fixed content */
4832     if (rec->presence_flags & WTAP_HAS_INTERFACE_ID)
4833         epb.interface_id        = rec->rec_header.packet_header.interface_id;
4834     else {
4835         /*
4836          * XXX - we should support writing WTAP_ENCAP_PER_PACKET
4837          * data to pcapng files even if we *don't* have interface
4838          * IDs.
4839          */
4840         epb.interface_id        = 0;
4841     }
4842     /*
4843      * Split the 64-bit timestamp into two 32-bit pieces, using
4844      * the time stamp resolution for the interface.
4845      */
4846     if (epb.interface_id >= wdh->interface_data->len) {
4847         /*
4848          * Our caller is doing something bad.
4849          */
4850         *err = WTAP_ERR_INTERNAL;
4851         *err_info = g_strdup_printf("pcapng: epb.interface_id (%u) >= wdh->interface_data->len (%u)",
4852                                     epb.interface_id, wdh->interface_data->len);
4853         return FALSE;
4854     }
4855     int_data = g_array_index(wdh->interface_data, wtap_block_t,
4856                              epb.interface_id);
4857     int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
4858     if (int_data_mand->wtap_encap != rec->rec_header.packet_header.pkt_encap) {
4859         /*
4860          * Our caller is doing something bad.
4861          */
4862         *err = WTAP_ERR_INTERNAL;
4863         *err_info = g_strdup_printf("pcapng: interface %u encap %d != packet encap %d",
4864                                     epb.interface_id,
4865                                     int_data_mand->wtap_encap,
4866                                     rec->rec_header.packet_header.pkt_encap);
4867         return FALSE;
4868     }
4869     ts = ((guint64)rec->ts.secs) * int_data_mand->time_units_per_second +
4870         (((guint64)rec->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
4871     epb.timestamp_high      = (guint32)(ts >> 32);
4872     epb.timestamp_low       = (guint32)ts;
4873     epb.captured_len        = rec->rec_header.packet_header.caplen + phdr_len;
4874     epb.packet_len          = rec->rec_header.packet_header.len + phdr_len;
4875 
4876     if (!wtap_dump_file_write(wdh, &epb, sizeof epb, err))
4877         return FALSE;
4878     wdh->bytes_dumped += sizeof epb;
4879 
4880     /* write pseudo header */
4881     if (!pcap_write_phdr(wdh, rec->rec_header.packet_header.pkt_encap, pseudo_header, err)) {
4882         return FALSE;
4883     }
4884     wdh->bytes_dumped += phdr_len;
4885 
4886     /* write packet data */
4887     if (!wtap_dump_file_write(wdh, pd, rec->rec_header.packet_header.caplen, err))
4888         return FALSE;
4889     wdh->bytes_dumped += rec->rec_header.packet_header.caplen;
4890 
4891     /* write padding (if any) */
4892     if (pad_len != 0) {
4893         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
4894             return FALSE;
4895         wdh->bytes_dumped += pad_len;
4896     }
4897 
4898     /* Write options, if we have any */
4899     if (options_size != 0) {
4900         if (!write_options(wdh, rec->block, write_wtap_epb_option, err))
4901             return FALSE;
4902     }
4903 
4904     /* write block footer */
4905     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
4906                               sizeof bh.block_total_length, err))
4907         return FALSE;
4908     wdh->bytes_dumped += sizeof bh.block_total_length;
4909 
4910     return TRUE;
4911 }
4912 
4913 static gboolean
pcapng_write_sysdig_event_block(wtap_dumper * wdh,const wtap_rec * rec,const guint8 * pd,int * err)4914 pcapng_write_sysdig_event_block(wtap_dumper *wdh, const wtap_rec *rec,
4915                                 const guint8 *pd, int *err)
4916 {
4917     pcapng_block_header_t bh;
4918     const guint32 zero_pad = 0;
4919     guint32 pad_len;
4920 #if 0
4921     gboolean have_options = FALSE;
4922     struct pcapng_option option_hdr;
4923     guint32 comment_len = 0, comment_pad_len = 0;
4924 #endif
4925     guint32 options_total_length = 0;
4926     guint16 cpu_id;
4927     guint64 hdr_ts;
4928     guint64 ts;
4929     guint64 thread_id;
4930     guint32 event_len;
4931     guint16 event_type;
4932 
4933     /* Don't write anything we're not willing to read. */
4934     if (rec->rec_header.syscall_header.event_filelen > WTAP_MAX_PACKET_SIZE_STANDARD) {
4935         *err = WTAP_ERR_PACKET_TOO_LARGE;
4936         return FALSE;
4937     }
4938 
4939     if (rec->rec_header.syscall_header.event_filelen % 4) {
4940         pad_len = 4 - (rec->rec_header.syscall_header.event_filelen % 4);
4941     } else {
4942         pad_len = 0;
4943     }
4944 
4945 #if 0
4946     /* Check if we should write comment option */
4947     if (rec->opt_comment) {
4948         have_options = TRUE;
4949         comment_len = (guint32)strlen(rec->opt_comment) & 0xffff;
4950         if ((comment_len % 4)) {
4951             comment_pad_len = 4 - (comment_len % 4);
4952         } else {
4953             comment_pad_len = 0;
4954         }
4955         options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
4956     }
4957     if (have_options) {
4958         /* End-of options tag */
4959         options_total_length += 4;
4960     }
4961 #endif
4962 
4963     /* write sysdig event block header */
4964     bh.block_type = BLOCK_TYPE_SYSDIG_EVENT;
4965     bh.block_total_length = (guint32)sizeof(bh) + SYSDIG_EVENT_HEADER_SIZE + rec->rec_header.syscall_header.event_filelen + pad_len + options_total_length + 4;
4966 
4967     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
4968         return FALSE;
4969     wdh->bytes_dumped += sizeof bh;
4970 
4971     /* Sysdig is always LE? */
4972     cpu_id = GUINT16_TO_LE(rec->rec_header.syscall_header.cpu_id);
4973     hdr_ts = (((guint64)rec->ts.secs) * 1000000000) + rec->ts.nsecs;
4974     ts = GUINT64_TO_LE(hdr_ts);
4975     thread_id = GUINT64_TO_LE(rec->rec_header.syscall_header.thread_id);
4976     event_len = GUINT32_TO_LE(rec->rec_header.syscall_header.event_len);
4977     event_type = GUINT16_TO_LE(rec->rec_header.syscall_header.event_type);
4978 
4979     if (!wtap_dump_file_write(wdh, &cpu_id, sizeof cpu_id, err))
4980         return FALSE;
4981     wdh->bytes_dumped += sizeof cpu_id;
4982 
4983     if (!wtap_dump_file_write(wdh, &ts, sizeof ts, err))
4984         return FALSE;
4985     wdh->bytes_dumped += sizeof ts;
4986 
4987     if (!wtap_dump_file_write(wdh, &thread_id, sizeof thread_id, err))
4988         return FALSE;
4989     wdh->bytes_dumped += sizeof thread_id;
4990 
4991     if (!wtap_dump_file_write(wdh, &event_len, sizeof event_len, err))
4992         return FALSE;
4993     wdh->bytes_dumped += sizeof event_len;
4994 
4995     if (!wtap_dump_file_write(wdh, &event_type, sizeof event_type, err))
4996         return FALSE;
4997     wdh->bytes_dumped += sizeof event_type;
4998 
4999     /* write event data */
5000     if (!wtap_dump_file_write(wdh, pd, rec->rec_header.syscall_header.event_filelen, err))
5001         return FALSE;
5002     wdh->bytes_dumped += rec->rec_header.syscall_header.event_filelen;
5003 
5004     /* write padding (if any) */
5005     if (pad_len != 0) {
5006         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5007             return FALSE;
5008         wdh->bytes_dumped += pad_len;
5009     }
5010 
5011     /* XXX Write comment? */
5012 
5013     /* write block footer */
5014     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5015                               sizeof bh.block_total_length, err))
5016         return FALSE;
5017 
5018     return TRUE;
5019 
5020 }
5021 
5022 static gboolean
pcapng_write_systemd_journal_export_block(wtap_dumper * wdh,const wtap_rec * rec,const guint8 * pd,int * err)5023 pcapng_write_systemd_journal_export_block(wtap_dumper *wdh, const wtap_rec *rec,
5024                                 const guint8 *pd, int *err)
5025 {
5026     pcapng_block_header_t bh;
5027     const guint32 zero_pad = 0;
5028     guint32 pad_len;
5029 
5030     /* Don't write anything we're not willing to read. */
5031     if (rec->rec_header.systemd_journal_export_header.record_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
5032         *err = WTAP_ERR_PACKET_TOO_LARGE;
5033         return FALSE;
5034     }
5035 
5036     if (rec->rec_header.systemd_journal_export_header.record_len % 4) {
5037         pad_len = 4 - (rec->rec_header.systemd_journal_export_header.record_len % 4);
5038     } else {
5039         pad_len = 0;
5040     }
5041 
5042     /* write systemd journal export block header */
5043     bh.block_type = BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT;
5044     bh.block_total_length = (guint32)sizeof(bh) + rec->rec_header.systemd_journal_export_header.record_len + pad_len + 4;
5045 
5046     ws_debug("writing %u bytes, %u padded",
5047              rec->rec_header.systemd_journal_export_header.record_len,
5048              bh.block_total_length);
5049 
5050     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5051         return FALSE;
5052     wdh->bytes_dumped += sizeof bh;
5053 
5054     /* write entry data */
5055     if (!wtap_dump_file_write(wdh, pd, rec->rec_header.systemd_journal_export_header.record_len, err))
5056         return FALSE;
5057     wdh->bytes_dumped += rec->rec_header.systemd_journal_export_header.record_len;
5058 
5059     /* write padding (if any) */
5060     if (pad_len != 0) {
5061         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5062             return FALSE;
5063         wdh->bytes_dumped += pad_len;
5064     }
5065 
5066     /* write block footer */
5067     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5068                               sizeof bh.block_total_length, err))
5069         return FALSE;
5070 
5071     return TRUE;
5072 
5073 }
5074 
5075 static gboolean
pcapng_write_custom_block(wtap_dumper * wdh,const wtap_rec * rec,const guint8 * pd,int * err)5076 pcapng_write_custom_block(wtap_dumper *wdh, const wtap_rec *rec,
5077                           const guint8 *pd, int *err)
5078 {
5079     pcapng_block_header_t bh;
5080     pcapng_custom_block_t cb;
5081     const guint32 zero_pad = 0;
5082     guint32 pad_len;
5083 
5084     /* Don't write anything we are not supposed to. */
5085     if (!rec->rec_header.custom_block_header.copy_allowed) {
5086         return TRUE;
5087     }
5088 
5089     /* Don't write anything we're not willing to read. */
5090     if (rec->rec_header.custom_block_header.length > WTAP_MAX_PACKET_SIZE_STANDARD) {
5091         *err = WTAP_ERR_PACKET_TOO_LARGE;
5092         return FALSE;
5093     }
5094 
5095     if (rec->rec_header.custom_block_header.length % 4) {
5096         pad_len = 4 - (rec->rec_header.custom_block_header.length % 4);
5097     } else {
5098         pad_len = 0;
5099     }
5100 
5101     /* write block header */
5102     bh.block_type = BLOCK_TYPE_CB_COPY;
5103     bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(cb) + rec->rec_header.custom_block_header.length + pad_len + 4;
5104     ws_debug("writing %u bytes, %u padded, PEN %u",
5105              rec->rec_header.custom_block_header.length,
5106              bh.block_total_length, rec->rec_header.custom_block_header.pen);
5107     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err)) {
5108         return FALSE;
5109     }
5110     wdh->bytes_dumped += sizeof bh;
5111 
5112     /* write custom block header */
5113     cb.pen = rec->rec_header.custom_block_header.pen;
5114     if (!wtap_dump_file_write(wdh, &cb, sizeof cb, err)) {
5115         return FALSE;
5116     }
5117     wdh->bytes_dumped += sizeof cb;
5118     ws_debug("wrote PEN = %u", cb.pen);
5119 
5120     /* write custom data */
5121     if (!wtap_dump_file_write(wdh, pd, rec->rec_header.custom_block_header.length, err)) {
5122         return FALSE;
5123     }
5124     wdh->bytes_dumped += rec->rec_header.custom_block_header.length;
5125 
5126     /* write padding (if any) */
5127     if (pad_len > 0) {
5128         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err)) {
5129             return FALSE;
5130         }
5131         wdh->bytes_dumped += pad_len;
5132     }
5133 
5134     /* write block footer */
5135     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5136                               sizeof bh.block_total_length, err)) {
5137         return FALSE;
5138     }
5139     wdh->bytes_dumped += sizeof bh.block_total_length;
5140 
5141     return TRUE;
5142 }
5143 
5144 static gboolean
pcapng_write_bblog_block(wtap_dumper * wdh,const wtap_rec * rec,const guint8 * pd _U_,int * err)5145 pcapng_write_bblog_block(wtap_dumper *wdh, const wtap_rec *rec,
5146                          const guint8 *pd _U_, int *err)
5147 {
5148     pcapng_block_header_t bh;
5149     guint32 options_size = 0;
5150     guint32 pen, skipped, type;
5151 
5152     /* Compute size of all the options */
5153     options_size = compute_options_size(rec->block, compute_epb_option_size);
5154 
5155     /* write block header */
5156     bh.block_type = BLOCK_TYPE_CB_COPY;
5157     bh.block_total_length = (guint32)(sizeof(bh) + sizeof(guint32) + sizeof(guint32) + options_size + 4);
5158     if (rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type == BBLOG_TYPE_SKIPPED_BLOCK) {
5159         bh.block_total_length += (guint32)sizeof(guint32);
5160     }
5161     ws_debug("writing %u bytes, type %u",
5162              bh.block_total_length, rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
5163     if (!wtap_dump_file_write(wdh, &bh, sizeof(bh), err)) {
5164         return FALSE;
5165     }
5166     wdh->bytes_dumped += sizeof bh;
5167 
5168     /* write PEN */
5169     pen = PEN_NFLX;
5170     if (!wtap_dump_file_write(wdh, &pen, sizeof(guint32), err)) {
5171         return FALSE;
5172     }
5173     wdh->bytes_dumped += sizeof(guint32);
5174     ws_debug("wrote PEN = %u", pen);
5175 
5176     /* write type */
5177     type = GUINT32_TO_LE(rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
5178     if (!wtap_dump_file_write(wdh, &type, sizeof(guint32), err)) {
5179         return FALSE;
5180     }
5181     wdh->bytes_dumped += sizeof(guint32);
5182     ws_debug("wrote type = %u", rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type);
5183 
5184     if (rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.type == BBLOG_TYPE_SKIPPED_BLOCK) {
5185         skipped = GUINT32_TO_LE(rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
5186         if (!wtap_dump_file_write(wdh, &skipped, sizeof(guint32), err)) {
5187             return FALSE;
5188         }
5189         wdh->bytes_dumped += sizeof(guint32);
5190         ws_debug("wrote skipped = %u", rec->rec_header.custom_block_header.custom_data_header.nflx_custom_data_header.skipped);
5191     }
5192 
5193     /* Write options, if we have any */
5194     if (options_size != 0) {
5195         /*
5196          * This block type supports only comments and custom options,
5197          * so it doesn't need a callback.
5198          */
5199         if (!write_options(wdh, rec->block, NULL, err))
5200             return FALSE;
5201     }
5202 
5203     /* write block footer */
5204     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5205                               sizeof bh.block_total_length, err)) {
5206         return FALSE;
5207     }
5208     wdh->bytes_dumped += sizeof bh.block_total_length;
5209 
5210     return TRUE;
5211 }
5212 
5213 static gboolean
pcapng_write_decryption_secrets_block(wtap_dumper * wdh,wtap_block_t sdata,int * err)5214 pcapng_write_decryption_secrets_block(wtap_dumper *wdh, wtap_block_t sdata, int *err)
5215 {
5216     pcapng_block_header_t bh;
5217     pcapng_decryption_secrets_block_t dsb;
5218     wtapng_dsb_mandatory_t *mand_data = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(sdata);
5219     guint pad_len = (4 - (mand_data->secrets_len & 3)) & 3;
5220 
5221     /* write block header */
5222     bh.block_type = BLOCK_TYPE_DSB;
5223     bh.block_total_length = MIN_DSB_SIZE + mand_data->secrets_len + pad_len;
5224     ws_debug("Total len %u", bh.block_total_length);
5225 
5226     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5227         return FALSE;
5228     wdh->bytes_dumped += sizeof bh;
5229 
5230     /* write block fixed content */
5231     dsb.secrets_type = mand_data->secrets_type;
5232     dsb.secrets_len = mand_data->secrets_len;
5233     if (!wtap_dump_file_write(wdh, &dsb, sizeof dsb, err))
5234         return FALSE;
5235     wdh->bytes_dumped += sizeof dsb;
5236 
5237     if (!wtap_dump_file_write(wdh, mand_data->secrets_data, mand_data->secrets_len, err))
5238         return FALSE;
5239     wdh->bytes_dumped += mand_data->secrets_len;
5240     if (pad_len) {
5241         const guint32 zero_pad = 0;
5242         if (!wtap_dump_file_write(wdh, &zero_pad, pad_len, err))
5243             return FALSE;
5244         wdh->bytes_dumped += pad_len;
5245     }
5246 
5247     /* write block footer */
5248     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5249                               sizeof bh.block_total_length, err))
5250         return FALSE;
5251     wdh->bytes_dumped += sizeof bh.block_total_length;
5252 
5253     return TRUE;
5254 }
5255 
5256 /*
5257  * libpcap's maximum pcapng block size is currently 16MB.
5258  *
5259  * The maximum pcapng block size in macOS's private pcapng reading code
5260  * is 1MB.  (Yes, this means that a program using the standard pcap
5261  * code to read pcapng files can handle bigger blocks than can programs
5262  * using the private code, such as Apple's tcpdump, can handle.)
5263  *
5264  * The pcapng reading code here can handle NRBs of arbitrary size (less
5265  * than 4GB, obviously), as they read each NRB record independently,
5266  * rather than reading the entire block into memory.
5267  *
5268  * So, for now, we set the maximum NRB block size we write as 1 MB.
5269  *
5270  * (Yes, for the benefit of the fussy, "MB" is really "MiB".)
5271  */
5272 
5273 #define NRES_BLOCK_MAX_SIZE (1024*1024)
5274 
5275 static guint32
compute_nrb_option_size(wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval)5276 compute_nrb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval)
5277 {
5278     guint32 size;
5279 
5280     switch(option_id)
5281     {
5282     case OPT_NS_DNSNAME:
5283         size = pcapng_compute_string_option_size(optval);
5284         break;
5285     case OPT_NS_DNSIP4ADDR:
5286         size = 4;
5287         break;
5288     case OPT_NS_DNSIP6ADDR:
5289         size = 16;
5290         break;
5291     default:
5292         /* Unknown options - size by datatype? */
5293         size = 0;
5294         break;
5295     }
5296     return size;
5297 }
5298 
5299 static gboolean
put_nrb_option(wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval,void * user_data)5300 put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data)
5301 {
5302     guint8 **opt_ptrp = (guint8 **)user_data;
5303     guint32 size = 0;
5304     struct pcapng_option_header option_hdr;
5305     guint32 pad;
5306 
5307     switch(option_id)
5308     {
5309     case OPT_COMMENT:
5310     case OPT_NS_DNSNAME:
5311         /* String options don't consider pad bytes part of the length */
5312         size = (guint32)strlen(optval->stringval) & 0xffff;
5313         option_hdr.type         = (guint16)option_id;
5314         option_hdr.value_length = (guint16)size;
5315         memcpy(*opt_ptrp, &option_hdr, 4);
5316         *opt_ptrp += 4;
5317 
5318         memcpy(*opt_ptrp, optval->stringval, size);
5319         *opt_ptrp += size;
5320 
5321         if ((size % 4)) {
5322             pad = 4 - (size % 4);
5323         } else {
5324             pad = 0;
5325         }
5326 
5327         /* put padding (if any) */
5328         if (pad != 0) {
5329             memset(*opt_ptrp, 0, pad);
5330             *opt_ptrp += pad;
5331         }
5332         break;
5333     case OPT_CUSTOM_STR_COPY:
5334     case OPT_CUSTOM_BIN_COPY:
5335         /* Custom options don't consider pad bytes part of the length */
5336         size = (guint32)(optval->custom_opt.data.generic_data.custom_data_len + sizeof(guint32)) & 0xffff;
5337         option_hdr.type         = (guint16)option_id;
5338         option_hdr.value_length = (guint16)size;
5339         memcpy(*opt_ptrp, &option_hdr, 4);
5340         *opt_ptrp += 4;
5341 
5342         memcpy(*opt_ptrp, &optval->custom_opt.pen, sizeof(guint32));
5343         *opt_ptrp += sizeof(guint32);
5344 
5345         memcpy(*opt_ptrp, optval->custom_opt.data.generic_data.custom_data, optval->custom_opt.data.generic_data.custom_data_len);
5346         *opt_ptrp += optval->custom_opt.data.generic_data.custom_data_len;
5347 
5348         if ((size % 4)) {
5349             pad = 4 - (size % 4);
5350         } else {
5351             pad = 0;
5352         }
5353 
5354         /* put padding (if any) */
5355         if (pad != 0) {
5356             memset(*opt_ptrp, 0, pad);
5357             *opt_ptrp += pad;
5358         }
5359         break;
5360     case OPT_NS_DNSIP4ADDR:
5361         option_hdr.type         = (guint16)option_id;
5362         option_hdr.value_length = 4;
5363         memcpy(*opt_ptrp, &option_hdr, 4);
5364         *opt_ptrp += 4;
5365 
5366         memcpy(*opt_ptrp, &optval->ipv4val, 4);
5367         *opt_ptrp += 4;
5368         break;
5369     case OPT_NS_DNSIP6ADDR:
5370         option_hdr.type         = (guint16)option_id;
5371         option_hdr.value_length = 16;
5372         memcpy(*opt_ptrp, &option_hdr, 4);
5373         *opt_ptrp += 4;
5374 
5375         memcpy(*opt_ptrp, &optval->ipv6val, 16);
5376         *opt_ptrp += 16;
5377         break;
5378     default:
5379         /* Unknown options - size by datatype? */
5380         break;
5381     }
5382     return TRUE; /* we always succeed */
5383 }
5384 
5385 static void
put_nrb_options(wtap_dumper * wdh,guint8 * opt_ptr)5386 put_nrb_options(wtap_dumper *wdh, guint8 *opt_ptr)
5387 {
5388     if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
5389         wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
5390         struct pcapng_option option_hdr;
5391 
5392         wtap_block_foreach_option(nrb_hdr, put_nrb_option, &opt_ptr);
5393 
5394         /* Put end of options */
5395         option_hdr.type = OPT_EOFOPT;
5396         option_hdr.value_length = 0;
5397         memcpy(opt_ptr, &option_hdr, 4);
5398     }
5399 }
5400 
5401 static gboolean
pcapng_write_name_resolution_block(wtap_dumper * wdh,int * err)5402 pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
5403 {
5404     pcapng_block_header_t bh;
5405     pcapng_name_resolution_block_t nrb;
5406     guint32 options_size;
5407     size_t max_rec_data_size;
5408     guint8 *block_data;
5409     guint32 block_off;
5410     size_t hostnamelen;
5411     guint16 namelen;
5412     guint32 tot_rec_len;
5413     hashipv4_t *ipv4_hash_list_entry;
5414     hashipv6_t *ipv6_hash_list_entry;
5415     int i;
5416 
5417     if (wtap_addrinfo_list_empty(wdh->addrinfo_lists)) {
5418         /*
5419          * No name/address pairs to write.
5420          * XXX - what if we have options?
5421          */
5422         return TRUE;
5423     }
5424 
5425     /* Calculate the space needed for options. */
5426     options_size = 0;
5427     if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) {
5428         wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0);
5429 
5430         /* Compute size of all the options */
5431         options_size = compute_options_size(nrb_hdr, compute_nrb_option_size);
5432     }
5433 
5434     /*
5435      * Make sure we can fit at least one maximum-sized record, plus
5436      * an end-of-records record, plus the options, into a maximum-sized
5437      * block.
5438      *
5439      * That requires that there be enough space for the block header
5440      * (8 bytes), a maximum-sized record (2 bytes of record type, 2
5441      * bytes of record value length, 65535 bytes of record value,
5442      * and 1 byte of padding), an end-of-records record (4 bytes),
5443      * the options (options_size bytes), and the block trailer (4
5444      * bytes).
5445      */
5446     if (8 + 2 + 2 + 65535 + 1 + 4 + options_size + 4 > NRES_BLOCK_MAX_SIZE) {
5447         /*
5448          * XXX - we can't even fit the options in the largest NRB size
5449          * we're willing to write and still have room enough for a
5450          * maximum-sized record.  Just discard the information for now.
5451          */
5452         return TRUE;
5453     }
5454 
5455     /*
5456      * Allocate a buffer for the largest block we'll write.
5457      */
5458     block_data = (guint8 *)g_malloc(NRES_BLOCK_MAX_SIZE);
5459 
5460     /*
5461      * Calculate the maximum amount of record data we'll be able to
5462      * fit into such a block, after taking into account the block header
5463      * (8 bytes), the end-of-records record (4 bytes), the options
5464      * (options_size bytes), and the block trailer (4 bytes).
5465      */
5466     max_rec_data_size = NRES_BLOCK_MAX_SIZE - (8 + 4 + options_size + 4);
5467 
5468     block_off = 8; /* block type + block total length */
5469     bh.block_type = BLOCK_TYPE_NRB;
5470     bh.block_total_length = 12; /* block header + block trailer */
5471 
5472     /*
5473      * Write out the IPv4 resolved addresses, if any.
5474      */
5475     if (wdh->addrinfo_lists->ipv4_addr_list){
5476         i = 0;
5477         ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
5478         while(ipv4_hash_list_entry != NULL){
5479 
5480             nrb.record_type = NRES_IP4RECORD;
5481             hostnamelen = strlen(ipv4_hash_list_entry->name);
5482             if (hostnamelen > (G_MAXUINT16 - 4) - 1) {
5483                 /*
5484                  * This won't fit in the largest possible NRB record;
5485                  * discard it.
5486                  */
5487                 i++;
5488                 ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
5489                 continue;
5490             }
5491             namelen = (guint16)(hostnamelen + 1);
5492             nrb.record_len = 4 + namelen;  /* 4 bytes IPv4 address length */
5493             /* 2 bytes record type, 2 bytes length field */
5494             tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
5495 
5496             if (block_off + tot_rec_len > max_rec_data_size) {
5497                 /*
5498                  * This record would overflow our maximum size for Name
5499                  * Resolution Blocks; write out all the records we created
5500                  * before it, and start a new NRB.
5501                  */
5502 
5503                 /* Append the end-of-records record */
5504                 memset(block_data + block_off, 0, 4);
5505                 block_off += 4;
5506                 bh.block_total_length += 4;
5507 
5508                 /*
5509                  * Put the options into the block.
5510                  *
5511                  * XXX - this puts the same options in all NRBs.
5512                  */
5513                 put_nrb_options(wdh, block_data + block_off);
5514                 block_off += options_size;
5515                 bh.block_total_length += options_size;
5516 
5517                 /* Copy the block header. */
5518                 memcpy(block_data, &bh, sizeof(bh));
5519 
5520                 /* Copy the block trailer. */
5521                 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5522 
5523                 ws_debug("Write bh.block_total_length bytes %d, block_off %u",
5524                          bh.block_total_length, block_off);
5525 
5526                 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5527                     g_free(block_data);
5528                     return FALSE;
5529                 }
5530                 wdh->bytes_dumped += bh.block_total_length;
5531 
5532                 /*Start a new NRB */
5533                 block_off = 8; /* block type + block total length */
5534                 bh.block_type = BLOCK_TYPE_NRB;
5535                 bh.block_total_length = 12; /* block header + block trailer */
5536             }
5537 
5538             bh.block_total_length += tot_rec_len;
5539             memcpy(block_data + block_off, &nrb, sizeof(nrb));
5540             block_off += 4;
5541             memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4);
5542             block_off += 4;
5543             memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen);
5544             block_off += namelen;
5545             memset(block_data + block_off, 0, PADDING4(namelen));
5546             block_off += PADDING4(namelen);
5547             ws_debug("added IPv4 record for %s", ipv4_hash_list_entry->name);
5548 
5549             i++;
5550             ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i);
5551         }
5552         g_list_free(wdh->addrinfo_lists->ipv4_addr_list);
5553         wdh->addrinfo_lists->ipv4_addr_list = NULL;
5554     }
5555 
5556     if (wdh->addrinfo_lists->ipv6_addr_list){
5557         i = 0;
5558         ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
5559         while(ipv6_hash_list_entry != NULL){
5560 
5561             nrb.record_type = NRES_IP6RECORD;
5562             hostnamelen = strlen(ipv6_hash_list_entry->name);
5563             if (hostnamelen > (G_MAXUINT16 - 16) - 1) {
5564                 /*
5565                  * This won't fit in the largest possible NRB record;
5566                  * discard it.
5567                  */
5568                 i++;
5569                 ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
5570                 continue;
5571             }
5572             namelen = (guint16)(hostnamelen + 1);
5573             nrb.record_len = 16 + namelen;  /* 16 bytes IPv6 address length */
5574             /* 2 bytes record type, 2 bytes length field */
5575             tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len);
5576 
5577             if (block_off + tot_rec_len > max_rec_data_size) {
5578                 /*
5579                  * This record would overflow our maximum size for Name
5580                  * Resolution Blocks; write out all the records we created
5581                  * before it, and start a new NRB.
5582                  */
5583 
5584                 /* Append the end-of-records record */
5585                 memset(block_data + block_off, 0, 4);
5586                 block_off += 4;
5587                 bh.block_total_length += 4;
5588 
5589                 /*
5590                  * Put the options into the block.
5591                  *
5592                  * XXX - this puts the same options in all NRBs.
5593                  */
5594                 put_nrb_options(wdh, block_data + block_off);
5595                 block_off += options_size;
5596                 bh.block_total_length += options_size;
5597 
5598                 /* Copy the block header. */
5599                 memcpy(block_data, &bh, sizeof(bh));
5600 
5601                 /* Copy the block trailer. */
5602                 memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5603 
5604                 ws_debug("write bh.block_total_length bytes %d, block_off %u",
5605                          bh.block_total_length, block_off);
5606 
5607                 if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5608                     g_free(block_data);
5609                     return FALSE;
5610                 }
5611                 wdh->bytes_dumped += bh.block_total_length;
5612 
5613                 /*Start a new NRB */
5614                 block_off = 8; /* block type + block total length */
5615                 bh.block_type = BLOCK_TYPE_NRB;
5616                 bh.block_total_length = 12; /* block header + block trailer */
5617             }
5618 
5619             bh.block_total_length += tot_rec_len;
5620             memcpy(block_data + block_off, &nrb, sizeof(nrb));
5621             block_off += 4;
5622             memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16);
5623             block_off += 16;
5624             memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen);
5625             block_off += namelen;
5626             memset(block_data + block_off, 0, PADDING4(namelen));
5627             block_off += PADDING4(namelen);
5628             ws_debug("added IPv6 record for %s", ipv6_hash_list_entry->name);
5629 
5630             i++;
5631             ipv6_hash_list_entry = (hashipv6_t *)g_list_nth_data(wdh->addrinfo_lists->ipv6_addr_list, i);
5632         }
5633         g_list_free(wdh->addrinfo_lists->ipv6_addr_list);
5634         wdh->addrinfo_lists->ipv6_addr_list = NULL;
5635     }
5636 
5637     /* Append the end-of-records record */
5638     memset(block_data + block_off, 0, 4);
5639     block_off += 4;
5640     bh.block_total_length += 4;
5641 
5642     /*
5643      * Put the options into the block.
5644      */
5645     put_nrb_options(wdh, block_data + block_off);
5646     block_off += options_size;
5647     bh.block_total_length += options_size;
5648 
5649     /* Copy the block header. */
5650     memcpy(block_data, &bh, sizeof(bh));
5651 
5652     /* Copy the block trailer. */
5653     memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length));
5654 
5655     ws_debug("Write bh.block_total_length bytes %d, block_off %u",
5656              bh.block_total_length, block_off);
5657 
5658     if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) {
5659         g_free(block_data);
5660         return FALSE;
5661     }
5662     wdh->bytes_dumped += bh.block_total_length;
5663 
5664     g_free(block_data);
5665 
5666     return TRUE;
5667 }
5668 
compute_isb_option_size(wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval _U_)5669 static guint32 compute_isb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval _U_)
5670 {
5671     guint32 size;
5672 
5673     switch(option_id)
5674     {
5675     case OPT_ISB_STARTTIME:
5676     case OPT_ISB_ENDTIME:
5677         size = 8;
5678         break;
5679     case OPT_ISB_IFRECV:
5680     case OPT_ISB_IFDROP:
5681     case OPT_ISB_FILTERACCEPT:
5682     case OPT_ISB_OSDROP:
5683     case OPT_ISB_USRDELIV:
5684         size = 8;
5685         break;
5686     default:
5687         /* Unknown options - size by datatype? */
5688         size = 0;
5689         break;
5690     }
5691     return size;
5692 }
5693 
write_wtap_isb_option(wtap_dumper * wdh,wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval,int * err)5694 static gboolean write_wtap_isb_option(wtap_dumper *wdh, wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
5695 {
5696     switch(option_id)
5697     {
5698     case OPT_ISB_STARTTIME:
5699     case OPT_ISB_ENDTIME:
5700         if (!pcapng_write_timestamp_option(wdh, option_id, optval, err))
5701             return FALSE;
5702         break;
5703     case OPT_ISB_IFRECV:
5704     case OPT_ISB_IFDROP:
5705     case OPT_ISB_FILTERACCEPT:
5706     case OPT_ISB_OSDROP:
5707     case OPT_ISB_USRDELIV:
5708         if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5709             return FALSE;
5710         break;
5711     default:
5712         /* Unknown options - write by datatype? */
5713         break;
5714     }
5715     return TRUE; /* success */
5716 }
5717 
5718 static gboolean
pcapng_write_interface_statistics_block(wtap_dumper * wdh,wtap_block_t if_stats,int * err)5719 pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_block_t if_stats, int *err)
5720 {
5721     pcapng_block_header_t bh;
5722     pcapng_interface_statistics_block_t isb;
5723     guint32 options_size;
5724     wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats);
5725 
5726     ws_debug("entering function");
5727 
5728     /* Compute size of all the options */
5729     options_size = compute_options_size(if_stats, compute_isb_option_size);
5730 
5731     /* write block header */
5732     bh.block_type = BLOCK_TYPE_ISB;
5733     bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + options_size + 4);
5734     ws_debug("Total len %u", bh.block_total_length);
5735 
5736     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5737         return FALSE;
5738     wdh->bytes_dumped += sizeof bh;
5739 
5740     /* write block fixed content */
5741     isb.interface_id                = mand_data->interface_id;
5742     isb.timestamp_high              = mand_data->ts_high;
5743     isb.timestamp_low               = mand_data->ts_low;
5744 
5745     if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
5746         return FALSE;
5747     wdh->bytes_dumped += sizeof isb;
5748 
5749     /* Write options */
5750     if (options_size != 0) {
5751         if (!write_options(wdh, if_stats, write_wtap_isb_option, err))
5752             return FALSE;
5753     }
5754 
5755     /* write block footer */
5756     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5757                               sizeof bh.block_total_length, err))
5758         return FALSE;
5759     wdh->bytes_dumped += sizeof bh.block_total_length;
5760     return TRUE;
5761 }
5762 
compute_idb_option_size(wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval)5763 static guint32 compute_idb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval)
5764 {
5765     guint32 size;
5766 
5767     switch(option_id)
5768     {
5769     case OPT_IDB_NAME:
5770     case OPT_IDB_DESCRIPTION:
5771     case OPT_IDB_OS:
5772     case OPT_IDB_HARDWARE:
5773         size = pcapng_compute_string_option_size(optval);
5774         break;
5775     case OPT_IDB_SPEED:
5776         size = 8;
5777         break;
5778     case OPT_IDB_TSRESOL:
5779         size = 1;
5780         break;
5781     case OPT_IDB_FILTER:
5782         size = pcapng_compute_if_filter_option_size(optval);
5783         break;
5784     case OPT_IDB_FCSLEN:
5785         size = 1;
5786         break;
5787     default:
5788         /* Unknown options - size by datatype? */
5789         size = 0;
5790         break;
5791     }
5792     return size;
5793 }
5794 
write_wtap_idb_option(wtap_dumper * wdh,wtap_block_t block _U_,guint option_id,wtap_opttype_e option_type _U_,wtap_optval_t * optval,int * err)5795 static gboolean write_wtap_idb_option(wtap_dumper *wdh, wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, int *err)
5796 {
5797     switch(option_id)
5798     {
5799     case OPT_IDB_NAME:
5800     case OPT_IDB_DESCRIPTION:
5801     case OPT_IDB_OS:
5802     case OPT_IDB_HARDWARE:
5803         if (!pcapng_write_string_option(wdh, option_id, optval, err))
5804             return FALSE;
5805         break;
5806     case OPT_IDB_SPEED:
5807         if (!pcapng_write_uint64_option(wdh, option_id, optval, err))
5808             return FALSE;
5809         break;
5810     case OPT_IDB_TSRESOL:
5811         if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5812             return FALSE;
5813         break;
5814     case OPT_IDB_FILTER:
5815         if (!pcapng_write_if_filter_option(wdh, option_id, optval, err))
5816             return FALSE;
5817         break;
5818     case OPT_IDB_FCSLEN:
5819         if (!pcapng_write_uint8_option(wdh, option_id, optval, err))
5820             return FALSE;
5821         break;
5822     default:
5823         /* Unknown options - size by datatype? */
5824         break;
5825     }
5826     return TRUE;
5827 }
5828 
5829 static gboolean
pcapng_write_if_descr_block(wtap_dumper * wdh,wtap_block_t int_data,int * err)5830 pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err)
5831 {
5832     pcapng_block_header_t bh;
5833     pcapng_interface_description_block_t idb;
5834     guint32 options_size;
5835     wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
5836     int link_type;
5837 
5838     ws_debug("encap = %d (%s), snaplen = %d",
5839              mand_data->wtap_encap,
5840              wtap_encap_description(mand_data->wtap_encap),
5841              mand_data->snap_len);
5842 
5843     link_type = wtap_wtap_encap_to_pcap_encap(mand_data->wtap_encap);
5844     if (link_type == -1) {
5845         if (!pcapng_encap_is_ft_specific(mand_data->wtap_encap)) {
5846             *err = WTAP_ERR_UNWRITABLE_ENCAP;
5847             return FALSE;
5848         }
5849     }
5850 
5851     /* Compute size of all the options */
5852     options_size = compute_options_size(int_data, compute_idb_option_size);
5853 
5854     /* write block header */
5855     bh.block_type = BLOCK_TYPE_IDB;
5856     bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + options_size + 4);
5857     ws_debug("Total len %u", bh.block_total_length);
5858 
5859     if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
5860         return FALSE;
5861     wdh->bytes_dumped += sizeof bh;
5862 
5863     /* write block fixed content */
5864     idb.linktype    = link_type;
5865     idb.reserved    = 0;
5866     idb.snaplen     = mand_data->snap_len;
5867 
5868     if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
5869         return FALSE;
5870     wdh->bytes_dumped += sizeof idb;
5871 
5872     if (options_size != 0) {
5873         /* Write options */
5874         if (!write_options(wdh, int_data, write_wtap_idb_option, err))
5875             return FALSE;
5876     }
5877 
5878     /* write block footer */
5879     if (!wtap_dump_file_write(wdh, &bh.block_total_length,
5880                               sizeof bh.block_total_length, err))
5881         return FALSE;
5882 
5883     wdh->bytes_dumped += sizeof bh.block_total_length;
5884     return TRUE;
5885 }
5886 
pcapng_add_idb(wtap_dumper * wdh,wtap_block_t idb,int * err,gchar ** err_info _U_)5887 static gboolean pcapng_add_idb(wtap_dumper *wdh, wtap_block_t idb,
5888                                int *err, gchar **err_info _U_)
5889 {
5890 	wtap_block_t idb_copy;
5891 
5892 	/*
5893 	 * Add a copy of this IDB to our array of IDBs.
5894 	 */
5895 	idb_copy = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
5896 	wtap_block_copy(idb_copy, idb);
5897 	g_array_append_val(wdh->interface_data, idb_copy);
5898 
5899 	/*
5900 	 * And write it to the output file.
5901 	 */
5902 	return pcapng_write_if_descr_block(wdh, idb_copy, err);
5903 }
5904 
pcapng_dump(wtap_dumper * wdh,const wtap_rec * rec,const guint8 * pd,int * err,gchar ** err_info)5905 static gboolean pcapng_dump(wtap_dumper *wdh,
5906                             const wtap_rec *rec,
5907                             const guint8 *pd, int *err, gchar **err_info)
5908 {
5909 #ifdef HAVE_PLUGINS
5910     block_handler *handler;
5911 #endif
5912 
5913     /* Write (optional) Decryption Secrets Blocks that were collected while
5914      * reading packet blocks. */
5915     if (wdh->dsbs_growing) {
5916         for (guint i = wdh->dsbs_growing_written; i < wdh->dsbs_growing->len; i++) {
5917             ws_debug("writing DSB %u", i);
5918             wtap_block_t dsb = g_array_index(wdh->dsbs_growing, wtap_block_t, i);
5919             if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
5920                 return FALSE;
5921             }
5922             ++wdh->dsbs_growing_written;
5923         }
5924     }
5925 
5926 
5927     ws_debug("encap = %d (%s) rec type = %u",
5928              rec->rec_header.packet_header.pkt_encap,
5929              wtap_encap_description(rec->rec_header.packet_header.pkt_encap),
5930              rec->rec_type);
5931 
5932     switch (rec->rec_type) {
5933 
5934         case REC_TYPE_PACKET:
5935             /*
5936              * XXX - write a Simple Packet Block if there's no time
5937              * stamp or other information that doesn't appear in an
5938              * SPB?
5939              */
5940             if (!pcapng_write_enhanced_packet_block(wdh, rec, pd, err,
5941                                                     err_info)) {
5942                 return FALSE;
5943             }
5944             break;
5945 
5946         case REC_TYPE_FT_SPECIFIC_EVENT:
5947         case REC_TYPE_FT_SPECIFIC_REPORT:
5948 #ifdef HAVE_PLUGINS
5949             /*
5950              * Do we have a handler for this block type?
5951              */
5952             if (block_handlers != NULL &&
5953                 (handler = (block_handler *)g_hash_table_lookup(block_handlers,
5954                                                                 GUINT_TO_POINTER(rec->rec_header.ft_specific_header.record_type))) != NULL) {
5955                 /* Yes. Call it to write out this record. */
5956                 if (!handler->writer(wdh, rec, pd, err))
5957                     return FALSE;
5958             } else
5959 #endif
5960             {
5961                 /* No. */
5962                 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
5963                 return FALSE;
5964             }
5965             break;
5966 
5967         case REC_TYPE_SYSCALL:
5968             if (!pcapng_write_sysdig_event_block(wdh, rec, pd, err)) {
5969                 return FALSE;
5970             }
5971             break;
5972 
5973         case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
5974             if (!pcapng_write_systemd_journal_export_block(wdh, rec, pd, err)) {
5975                 return FALSE;
5976             }
5977             break;
5978 
5979         case REC_TYPE_CUSTOM_BLOCK:
5980             switch (rec->rec_header.custom_block_header.pen) {
5981             case PEN_NFLX:
5982                 if (!pcapng_write_bblog_block(wdh, rec, pd, err)) {
5983                     return FALSE;
5984                 }
5985                 break;
5986             default:
5987                 if (!pcapng_write_custom_block(wdh, rec, pd, err)) {
5988                     return FALSE;
5989                 }
5990                 break;
5991             }
5992             break;
5993 
5994         default:
5995             /* We don't support writing this record type. */
5996             *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
5997             return FALSE;
5998     }
5999 
6000     return TRUE;
6001 }
6002 
6003 /* Finish writing to a dump file.
6004    Returns TRUE on success, FALSE on failure. */
pcapng_dump_finish(wtap_dumper * wdh,int * err,gchar ** err_info _U_)6005 static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err,
6006                                    gchar **err_info _U_)
6007 {
6008     guint i, j;
6009 
6010     /* Flush any hostname resolution info we may have */
6011     pcapng_write_name_resolution_block(wdh, err);
6012 
6013     for (i = 0; i < wdh->interface_data->len; i++) {
6014 
6015         /* Get the interface description */
6016         wtap_block_t int_data;
6017         wtapng_if_descr_mandatory_t *int_data_mand;
6018 
6019         int_data = g_array_index(wdh->interface_data, wtap_block_t, i);
6020         int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data);
6021 
6022         for (j = 0; j < int_data_mand->num_stat_entries; j++) {
6023             wtap_block_t if_stats;
6024 
6025             if_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j);
6026             ws_debug("write ISB for interface %u",
6027                      ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id);
6028             if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
6029                 return FALSE;
6030             }
6031         }
6032     }
6033 
6034     ws_debug("leaving function");
6035     return TRUE;
6036 }
6037 
6038 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
6039    failure */
6040 static gboolean
pcapng_dump_open(wtap_dumper * wdh,int * err,gchar ** err_info _U_)6041 pcapng_dump_open(wtap_dumper *wdh, int *err, gchar **err_info _U_)
6042 {
6043     guint i;
6044 
6045     ws_debug("entering function");
6046     /* This is a pcapng file */
6047     wdh->subtype_add_idb = pcapng_add_idb;
6048     wdh->subtype_write = pcapng_dump;
6049     wdh->subtype_finish = pcapng_dump_finish;
6050 
6051     /* write the section header block */
6052     if (!pcapng_write_section_header_block(wdh, err)) {
6053         return FALSE;
6054     }
6055     ws_debug("wrote section header block.");
6056 
6057     /* Write the Interface description blocks */
6058     ws_debug("Number of IDBs to write (number of interfaces) %u",
6059              wdh->interface_data->len);
6060 
6061     for (i = 0; i < wdh->interface_data->len; i++) {
6062 
6063         /* Get the interface description */
6064         wtap_block_t idb;
6065 
6066         idb = g_array_index(wdh->interface_data, wtap_block_t, i);
6067 
6068         if (!pcapng_write_if_descr_block(wdh, idb, err)) {
6069             return FALSE;
6070         }
6071 
6072     }
6073 
6074     /* Write (optional) fixed Decryption Secrets Blocks. */
6075     if (wdh->dsbs_initial) {
6076         for (i = 0; i < wdh->dsbs_initial->len; i++) {
6077             wtap_block_t dsb = g_array_index(wdh->dsbs_initial, wtap_block_t, i);
6078             if (!pcapng_write_decryption_secrets_block(wdh, dsb, err)) {
6079                 return FALSE;
6080             }
6081         }
6082     }
6083 
6084     return TRUE;
6085 }
6086 
6087 /* Returns 0 if we could write the specified encapsulation type,
6088    an error indication otherwise. */
pcapng_dump_can_write_encap(int wtap_encap)6089 static int pcapng_dump_can_write_encap(int wtap_encap)
6090 {
6091     ws_debug("encap = %d (%s)",
6092              wtap_encap,
6093              wtap_encap_description(wtap_encap));
6094 
6095     /* Per-packet encapsulation is supported. */
6096     if (wtap_encap == WTAP_ENCAP_PER_PACKET)
6097         return 0;
6098 
6099     /* Is it a filetype-specific encapsulation that we support? */
6100     if (pcapng_encap_is_ft_specific(wtap_encap)) {
6101         return 0;
6102     }
6103 
6104     /* Make sure we can figure out this DLT type */
6105     if (wtap_wtap_encap_to_pcap_encap(wtap_encap) == -1)
6106         return WTAP_ERR_UNWRITABLE_ENCAP;
6107 
6108     return 0;
6109 }
6110 
6111 /*
6112  * Returns TRUE if the specified encapsulation type is filetype-specific
6113  * and one that we support.
6114  */
pcapng_encap_is_ft_specific(int encap)6115 gboolean pcapng_encap_is_ft_specific(int encap)
6116 {
6117     switch (encap) {
6118     case WTAP_ENCAP_SYSTEMD_JOURNAL:
6119         return TRUE;
6120     }
6121     return FALSE;
6122 }
6123 
6124 /*
6125  * pcapng supports several block types, and supports more than one
6126  * of them.
6127  *
6128  * It also supports comments for many block types, as well as other
6129  * option types.
6130  */
6131 
6132 /* Options for section blocks. */
6133 static const struct supported_option_type section_block_options_supported[] = {
6134     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6135     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6136     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6137     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6138     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6139     { OPT_SHB_HARDWARE, ONE_OPTION_SUPPORTED },
6140     { OPT_SHB_USERAPPL, ONE_OPTION_SUPPORTED }
6141 };
6142 
6143 /* Options for interface blocks. */
6144 static const struct supported_option_type interface_block_options_supported[] = {
6145     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6146     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6147     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6148     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6149     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6150     { OPT_IDB_NAME, ONE_OPTION_SUPPORTED },
6151     { OPT_IDB_DESCRIPTION, ONE_OPTION_SUPPORTED },
6152     { OPT_IDB_IP4ADDR, MULTIPLE_OPTIONS_SUPPORTED },
6153     { OPT_IDB_IP6ADDR, MULTIPLE_OPTIONS_SUPPORTED },
6154     { OPT_IDB_MACADDR, ONE_OPTION_SUPPORTED },
6155     { OPT_IDB_EUIADDR, ONE_OPTION_SUPPORTED },
6156     { OPT_IDB_SPEED, ONE_OPTION_SUPPORTED },
6157     { OPT_IDB_TSRESOL, ONE_OPTION_SUPPORTED },
6158     { OPT_IDB_TZONE, ONE_OPTION_SUPPORTED },
6159     { OPT_IDB_FILTER, ONE_OPTION_SUPPORTED },
6160     { OPT_IDB_OS, ONE_OPTION_SUPPORTED },
6161     { OPT_IDB_FCSLEN, ONE_OPTION_SUPPORTED },
6162     { OPT_IDB_TSOFFSET, ONE_OPTION_SUPPORTED },
6163     { OPT_IDB_HARDWARE, ONE_OPTION_SUPPORTED }
6164 };
6165 
6166 /* Options for name resolution blocks. */
6167 static const struct supported_option_type name_resolution_block_options_supported[] = {
6168     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6169     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6170     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6171     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6172     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6173     { OPT_NS_DNSNAME, ONE_OPTION_SUPPORTED },
6174     { OPT_NS_DNSIP4ADDR, ONE_OPTION_SUPPORTED },
6175     { OPT_NS_DNSIP6ADDR, ONE_OPTION_SUPPORTED }
6176 };
6177 
6178 /* Options for interface statistics blocks. */
6179 static const struct supported_option_type interface_statistics_block_options_supported[] = {
6180     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6181     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6182     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6183     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6184     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6185     { OPT_ISB_STARTTIME, ONE_OPTION_SUPPORTED },
6186     { OPT_ISB_ENDTIME, ONE_OPTION_SUPPORTED },
6187     { OPT_ISB_IFRECV, ONE_OPTION_SUPPORTED },
6188     { OPT_ISB_IFDROP, ONE_OPTION_SUPPORTED },
6189     { OPT_ISB_FILTERACCEPT, ONE_OPTION_SUPPORTED },
6190     { OPT_ISB_OSDROP, ONE_OPTION_SUPPORTED },
6191     { OPT_ISB_USRDELIV, ONE_OPTION_SUPPORTED }
6192 };
6193 
6194 /* Options for decryption secrets blocks. */
6195 static const struct supported_option_type decryption_secrets_block_options_supported[] = {
6196     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6197     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6198     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6199     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6200     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6201 };
6202 
6203 /* Options for packet blocks. */
6204 static const struct supported_option_type packet_block_options_supported[] = {
6205     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6206     { OPT_PKT_FLAGS, ONE_OPTION_SUPPORTED },
6207     { OPT_PKT_DROPCOUNT, ONE_OPTION_SUPPORTED },
6208     { OPT_PKT_PACKETID, ONE_OPTION_SUPPORTED },
6209     { OPT_PKT_QUEUE, ONE_OPTION_SUPPORTED },
6210     { OPT_PKT_HASH, MULTIPLE_OPTIONS_SUPPORTED },
6211     { OPT_PKT_VERDICT, MULTIPLE_OPTIONS_SUPPORTED },
6212     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6213     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6214     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6215     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6216 };
6217 
6218 /* Options for file-type-sepcific reports. */
6219 static const struct supported_option_type ft_specific_report_block_options_supported[] = {
6220     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6221     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6222     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6223     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6224     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6225 };
6226 
6227 /* Options for file-type-sepcific event. */
6228 static const struct supported_option_type ft_specific_event_block_options_supported[] = {
6229     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6230     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6231     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6232     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6233     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6234 };
6235 
6236 /* Options for systemd journal entry. */
6237 static const struct supported_option_type systemd_journal_export_block_options_supported[] = {
6238     { OPT_COMMENT, MULTIPLE_OPTIONS_SUPPORTED },
6239     { OPT_CUSTOM_STR_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6240     { OPT_CUSTOM_BIN_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6241     { OPT_CUSTOM_STR_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED },
6242     { OPT_CUSTOM_BIN_NO_COPY, MULTIPLE_OPTIONS_SUPPORTED }
6243 };
6244 
6245 static const struct supported_block_type pcapng_blocks_supported[] = {
6246     /* Multiple sections. */
6247     { WTAP_BLOCK_SECTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(section_block_options_supported) },
6248 
6249     /* Multiple interfaces. */
6250     { WTAP_BLOCK_IF_ID_AND_INFO, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_block_options_supported) },
6251 
6252     /* Multiple blocks of name resolution information */
6253     { WTAP_BLOCK_NAME_RESOLUTION, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(name_resolution_block_options_supported) },
6254 
6255     /* Multiple blocks of interface statistics. */
6256     { WTAP_BLOCK_IF_STATISTICS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_statistics_block_options_supported) },
6257 
6258     /* Multiple blocks of decryption secrets. */
6259     { WTAP_BLOCK_DECRYPTION_SECRETS, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(decryption_secrets_block_options_supported) },
6260 
6261     /* And, obviously, multiple packets. */
6262     { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(packet_block_options_supported) },
6263 
6264     /* Multiple file-type specific reports (including local ones). */
6265     { WTAP_BLOCK_FT_SPECIFIC_REPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_report_block_options_supported) },
6266 
6267     /* Multiple file-type specific events (including local ones). */
6268     { WTAP_BLOCK_FT_SPECIFIC_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_event_block_options_supported) },
6269 
6270     /* Multiple systemd journal export records. */
6271     { WTAP_BLOCK_SYSTEMD_JOURNAL_EXPORT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(systemd_journal_export_block_options_supported) },
6272 
6273     /* Multiple custom blocks. */
6274     { WTAP_BLOCK_CUSTOM, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED },
6275 };
6276 
6277 static const struct file_type_subtype_info pcapng_info = {
6278     "Wireshark/... - pcapng", "pcapng", "pcapng", "ntar",
6279     FALSE, BLOCKS_SUPPORTED(pcapng_blocks_supported),
6280     pcapng_dump_can_write_encap, pcapng_dump_open, NULL
6281 };
6282 
register_pcapng(void)6283 void register_pcapng(void)
6284 {
6285     pcapng_file_type_subtype = wtap_register_file_type_subtype(&pcapng_info);
6286 
6287     wtap_register_backwards_compatibility_lua_name("PCAPNG",
6288                                                    pcapng_file_type_subtype);
6289 }
6290 
6291 /*
6292  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
6293  *
6294  * Local variables:
6295  * c-basic-offset: 4
6296  * tab-width: 8
6297  * indent-tabs-mode: nil
6298  * End:
6299  *
6300  * vi: set shiftwidth=4 tabstop=8 expandtab:
6301  * :indentSize=4:tabSize=8:noTabs=true:
6302  */
6303