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