Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / file-pcapng.c
blob7003ccfaeb37115413f0e57f2680a1605222de8c
1 /* file-pcapng.c
2 * Routines for PCAPNG File Format
3 * https://github.com/pcapng/pcapng
5 * Copyright 2015, Michal Labedzki for Tieto Corporation
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/prefs.h>
18 #include <epan/expert.h>
19 #include <epan/exceptions.h>
20 #include <epan/show_exception.h>
21 #include <epan/addr_resolv.h>
22 #include <epan/tfs.h>
23 #include <wiretap/pcapng_module.h>
24 #include <wiretap/secrets-types.h>
25 #include <wsutil/array.h>
27 #include "file-pcapng.h"
28 #include "packet-pcap_pktdata.h"
30 static int proto_pcapng;
32 static dissector_handle_t pcap_pktdata_handle;
34 static int hf_pcapng_block;
36 static int hf_pcapng_block_type;
37 static int hf_pcapng_block_type_vendor;
38 static int hf_pcapng_block_type_value;
39 static int hf_pcapng_block_length;
40 static int hf_pcapng_block_length_trailer;
41 static int hf_pcapng_block_data;
43 static int hf_pcapng_section_header_byte_order_magic;
44 static int hf_pcapng_section_header_major_version;
45 static int hf_pcapng_section_header_minor_version;
46 static int hf_pcapng_section_header_section_length;
47 static int hf_pcapng_options;
48 static int hf_pcapng_option;
49 static int hf_pcapng_option_code;
50 static int hf_pcapng_option_code_section_header;
51 static int hf_pcapng_option_code_interface_description;
52 static int hf_pcapng_option_code_enhanced_packet;
53 static int hf_pcapng_option_code_packet;
54 static int hf_pcapng_option_code_interface_statistics;
55 static int hf_pcapng_option_code_name_resolution;
56 static int hf_pcapng_option_length;
57 static int hf_pcapng_option_data;
58 static int hf_pcapng_option_data_comment;
59 static int hf_pcapng_option_data_section_header_hardware;
60 static int hf_pcapng_option_data_section_header_os;
61 static int hf_pcapng_option_data_section_header_user_application;
62 static int hf_pcapng_option_data_interface_description_name;
63 static int hf_pcapng_option_data_interface_description_description;
64 static int hf_pcapng_option_data_ipv4;
65 static int hf_pcapng_option_data_ipv4_mask;
66 static int hf_pcapng_option_data_ipv6;
67 static int hf_pcapng_option_data_ipv6_mask;
68 static int hf_pcapng_option_data_mac_address;
69 static int hf_pcapng_option_data_eui_address;
70 static int hf_pcapng_option_data_interface_speed;
71 static int hf_pcapng_option_data_interface_timestamp_resolution;
72 static int hf_pcapng_option_data_interface_timestamp_resolution_base;
73 static int hf_pcapng_option_data_interface_timestamp_resolution_value;
74 static int hf_pcapng_option_data_interface_timezone;
75 static int hf_pcapng_option_data_interface_filter_type;
76 static int hf_pcapng_option_data_interface_filter_string;
77 static int hf_pcapng_option_data_interface_filter_bpf_program;
78 static int hf_pcapng_option_data_interface_filter_unknown;
79 static int hf_pcapng_option_data_interface_os;
80 static int hf_pcapng_option_data_interface_hardware;
81 static int hf_pcapng_option_data_interface_fcs_length;
82 static int hf_pcapng_option_data_interface_timestamp_offset;
83 static int hf_pcapng_option_data_packet_verdict_type;
84 static int hf_pcapng_option_data_packet_verdict_data;
85 static int hf_pcapng_option_data_packet_queue;
86 static int hf_pcapng_option_data_packet_id;
87 static int hf_pcapng_option_data_packet_drop_count;
88 static int hf_pcapng_option_data_packet_hash_algorithm;
89 static int hf_pcapng_option_data_packet_hash_data;
90 static int hf_pcapng_option_data_packet_flags;
91 static int hf_pcapng_option_data_packet_flags_link_layer_errors;
92 static int hf_pcapng_option_data_packet_flags_link_layer_errors_symbol;
93 static int hf_pcapng_option_data_packet_flags_link_layer_errors_preamble;
94 static int hf_pcapng_option_data_packet_flags_link_layer_errors_start_frame_delimiter;
95 static int hf_pcapng_option_data_packet_flags_link_layer_errors_unaligned_frame;
96 static int hf_pcapng_option_data_packet_flags_link_layer_errors_wrong_inter_frame_gap;
97 static int hf_pcapng_option_data_packet_flags_link_layer_errors_packet_too_short;
98 static int hf_pcapng_option_data_packet_flags_link_layer_errors_packet_too_long;
99 static int hf_pcapng_option_data_packet_flags_link_layer_errors_crc_error;
100 static int hf_pcapng_option_data_packet_flags_link_layer_errors_reserved;
101 static int hf_pcapng_option_data_packet_flags_reserved;
102 static int hf_pcapng_option_data_packet_flags_fcs_length;
103 static int hf_pcapng_option_data_packet_flags_reception_type;
104 static int hf_pcapng_option_data_packet_flags_direction;
105 static int hf_pcapng_option_data_dns_name;
106 static int hf_pcapng_option_data_start_time;
107 static int hf_pcapng_option_data_end_time;
108 static int hf_pcapng_option_data_interface_received;
109 static int hf_pcapng_option_data_interface_dropped;
110 static int hf_pcapng_option_data_interface_accepted_by_filter;
111 static int hf_pcapng_option_data_interface_dropped_by_os;
112 static int hf_pcapng_option_data_interface_delivered_to_user;
113 static int hf_pcapng_option_padding;
114 static int hf_pcapng_interface_description_link_type;
115 static int hf_pcapng_interface_description_reserved;
116 static int hf_pcapng_interface_description_snap_length;
117 static int hf_pcapng_packet_block_interface_id;
118 static int hf_pcapng_packet_block_drops_count;
119 static int hf_pcapng_captured_length;
120 static int hf_pcapng_original_length;
121 static int hf_pcapng_packet_data;
122 static int hf_pcapng_packet_padding;
123 static int hf_pcapng_interface_id;
124 static int hf_pcapng_timestamp_high;
125 static int hf_pcapng_timestamp_low;
126 static int hf_pcapng_timestamp;
127 static int hf_pcapng_records;
128 static int hf_pcapng_record;
129 static int hf_pcapng_record_code;
130 static int hf_pcapng_record_length;
131 static int hf_pcapng_record_data;
132 static int hf_pcapng_record_ipv4;
133 static int hf_pcapng_record_ipv6;
134 static int hf_pcapng_record_name;
135 static int hf_pcapng_record_padding;
137 static int hf_pcapng_dsb_secrets_type;
138 static int hf_pcapng_dsb_secrets_length;
139 static int hf_pcapng_dsb_secrets_data;
141 static int hf_pcapng_cb_pen;
142 static int hf_pcapng_cb_data;
143 static int hf_pcapng_cb_option_string;
144 static int hf_pcapng_cb_option_data;
146 static int hf_pcapng_option_data_packet_darwin_dpeb_id;
147 static int hf_pcapng_option_data_packet_darwin_svc_class;
148 static int hf_pcapng_option_data_packet_darwin_edpeb_id;
149 static int hf_pcapng_option_data_packet_darwin_flags;
150 static int hf_pcapng_option_data_packet_darwin_flags_reserved;
151 static int hf_pcapng_option_data_packet_darwin_flags_wk;
152 static int hf_pcapng_option_data_packet_darwin_flags_ch;
153 static int hf_pcapng_option_data_packet_darwin_flags_so;
154 static int hf_pcapng_option_data_packet_darwin_flags_re;
155 static int hf_pcapng_option_data_packet_darwin_flags_ka;
156 static int hf_pcapng_option_data_packet_darwin_flags_nf;
157 static int hf_pcapng_option_data_packet_darwin_flow_id;
159 static expert_field ei_invalid_byte_order_magic;
160 static expert_field ei_block_length_below_block_minimum;
161 static expert_field ei_block_length_below_block_content_length;
162 static expert_field ei_block_length_not_multiple_of_4;
163 static expert_field ei_block_lengths_dont_match;
164 static expert_field ei_invalid_option_length;
165 static expert_field ei_invalid_record_length;
166 static expert_field ei_missing_idb;
168 static int ett_pcapng;
169 static int ett_pcapng_section_header_block;
170 static int ett_pcapng_block_data;
171 static int ett_pcapng_block_type;
172 static int ett_pcapng_options;
173 static int ett_pcapng_option;
174 static int ett_pcapng_records;
175 static int ett_pcapng_record;
176 static int ett_pcapng_packet_data;
178 static int * const hfx_pcapng_option_data_interface_timestamp_resolution[] = {
179 &hf_pcapng_option_data_interface_timestamp_resolution_base,
180 &hf_pcapng_option_data_interface_timestamp_resolution_value,
181 NULL
184 static int * const hfx_pcapng_option_data_packet_flags_link_layer_errors[] = {
185 &hf_pcapng_option_data_packet_flags_link_layer_errors_symbol,
186 &hf_pcapng_option_data_packet_flags_link_layer_errors_preamble,
187 &hf_pcapng_option_data_packet_flags_link_layer_errors_start_frame_delimiter,
188 &hf_pcapng_option_data_packet_flags_link_layer_errors_unaligned_frame,
189 &hf_pcapng_option_data_packet_flags_link_layer_errors_wrong_inter_frame_gap,
190 &hf_pcapng_option_data_packet_flags_link_layer_errors_packet_too_short,
191 &hf_pcapng_option_data_packet_flags_link_layer_errors_packet_too_long,
192 &hf_pcapng_option_data_packet_flags_link_layer_errors_crc_error,
193 &hf_pcapng_option_data_packet_flags_link_layer_errors_reserved,
194 NULL
197 static int * const hfx_pcapng_option_data_packet_flags[] = {
198 &hf_pcapng_option_data_packet_flags_reserved,
199 &hf_pcapng_option_data_packet_flags_fcs_length,
200 &hf_pcapng_option_data_packet_flags_reception_type,
201 &hf_pcapng_option_data_packet_flags_direction,
202 NULL
205 static int * const hfx_pcapng_option_data_packet_darwin_flags[] = {
206 &hf_pcapng_option_data_packet_darwin_flags_reserved,
207 &hf_pcapng_option_data_packet_darwin_flags_wk,
208 &hf_pcapng_option_data_packet_darwin_flags_ch,
209 &hf_pcapng_option_data_packet_darwin_flags_so,
210 &hf_pcapng_option_data_packet_darwin_flags_re,
211 &hf_pcapng_option_data_packet_darwin_flags_ka,
212 &hf_pcapng_option_data_packet_darwin_flags_nf,
213 NULL
216 static bool pref_dissect_next_layer;
218 static const value_string block_type_vals[] = {
219 { BLOCK_TYPE_IDB, "Interface Description Block" },
220 { BLOCK_TYPE_PB, "Packet Block" },
221 { BLOCK_TYPE_SPB, "Simple Packet Block" },
222 { BLOCK_TYPE_NRB, "Name Resolution Block" },
223 { BLOCK_TYPE_ISB, "Interface Statistics Block" },
224 { BLOCK_TYPE_EPB, "Enhanced Packet Block" },
225 { BLOCK_TYPE_IRIG_TS, "IRIG Timestamp Block" },
226 { BLOCK_TYPE_ARINC_429, "Arinc 429 in AFDX Encapsulation Information Block" },
227 { BLOCK_TYPE_SYSTEMD_JOURNAL_EXPORT, "systemd Journal Export Block" },
228 { BLOCK_TYPE_DSB, "Decryption Secrets Block" },
229 { BLOCK_TYPE_SYSDIG_MI, "Sysdig Machine Info Block" },
230 { BLOCK_TYPE_SYSDIG_PL_V1, "Sysdig Process List Block" },
231 { BLOCK_TYPE_SYSDIG_FDL_V1, "Sysdig File Descriptor List Block" },
232 { BLOCK_TYPE_SYSDIG_EVENT, "Sysdig Event Block" },
233 { BLOCK_TYPE_SYSDIG_IL_V1, "Sysdig Interface List Block" },
234 { BLOCK_TYPE_SYSDIG_UL_V1, "Sysdig User List Block" },
235 { BLOCK_TYPE_SYSDIG_PL_V2, "Sysdig Process List Block version 2" },
236 { BLOCK_TYPE_SYSDIG_EVF, "Sysdig Event Block with flags" },
237 { BLOCK_TYPE_SYSDIG_PL_V3, "Sysdig Process List Block version 3" },
238 { BLOCK_TYPE_SYSDIG_PL_V4, "Sysdig Process List Block version 4" },
239 { BLOCK_TYPE_SYSDIG_PL_V5, "Sysdig Process List Block version 5" },
240 { BLOCK_TYPE_SYSDIG_PL_V6, "Sysdig Process List Block version 6" },
241 { BLOCK_TYPE_SYSDIG_PL_V7, "Sysdig Process List Block version 7" },
242 { BLOCK_TYPE_SYSDIG_PL_V8, "Sysdig Process List Block version 8" },
243 { BLOCK_TYPE_SYSDIG_PL_V9, "Sysdig Process List Block version 9" },
244 { BLOCK_TYPE_SYSDIG_EVENT_V2, "Sysdig Event Block v2" },
245 { BLOCK_TYPE_SYSDIG_EVF_V2, "Sysdig Event Block with flags v2" },
246 { BLOCK_TYPE_SYSDIG_FDL_V2, "Sysdig File Descriptor List Block" },
247 { BLOCK_TYPE_SYSDIG_IL_V2, "Sysdig Interface List Block version 2" },
248 { BLOCK_TYPE_SYSDIG_UL_V2, "Sysdig User List Block version 2" },
249 { BLOCK_TYPE_SYSDIG_EVENT_V2_LARGE, "Sysdig Event Block v2 large payload" },
250 { BLOCK_TYPE_SYSDIG_EVF_V2_LARGE, "Sysdig Event Block with flags v2 large payload" },
251 { BLOCK_TYPE_CB_COPY, "Custom Block which can be copied"},
252 { BLOCK_TYPE_CB_NO_COPY, "Custom Block which should not be copied"},
253 { BLOCK_TYPE_SHB, "Section Header Block" },
254 { 0, NULL }
258 /* blockId-> local_block_callback_info_t* */
259 static GHashTable *s_local_block_callback_table;
261 #define OPTION_CODE_CUSTOM_OPTIONS \
262 { 2988, "Custom Option UTF-8 string which can be copied" }, \
263 { 2989, "Custom Option which can be copied" }, \
264 { 19372, "Custom Option UTF-8 string which should not be copied" }, \
265 { 19373, "Custom Option which should not be copied" }
267 static const value_string option_code_section_header_vals[] = {
268 { 0, "End of Options" },
269 { 1, "Comment" },
271 { 2, "Hardware Description" },
272 { 3, "OS Description" },
273 { 4, "User Application" },
274 OPTION_CODE_CUSTOM_OPTIONS,
275 { 0, NULL }
278 static const value_string option_code_interface_description_vals[] = {
279 { 0, "End of Options" },
280 { 1, "Comment" },
282 { 2, "Interface Name" },
283 { 3, "Interface Description" },
284 { 4, "IPv4 Address" },
285 { 5, "IPv6 Address" },
286 { 6, "MAC Address" },
287 { 7, "EUI Address" },
288 { 8, "Speed" },
289 { 9, "Timestamp Resolution" },
290 { 10, "Timezone" },
291 { 11, "Filter" },
292 { 12, "OS" },
293 { 13, "FCS Length" },
294 { 14, "Timestamp Offset" },
295 { 15, "Hardware" },
296 OPTION_CODE_CUSTOM_OPTIONS,
297 { 0, NULL }
302 * Enhanced Packet Block (EPB) options for supporting Darwin process information
304 * Enhanced Packet Blocks may be augmented with an Apple defined Darwin
305 * process event block id option (dpeb_id) and / or an effective Darwin
306 * process event block id option (edpeb_id) that refer to particular
307 * Darwin processes via the supplied DPEB ID option payload value. There
308 * must be a Darwin Process Event Block for each Darwin process to which an
309 * augmented EPB references. If the file does not contain any EPBs that
310 * contain any Darwin dpeb_id or edpeb_id options then the file does not need
311 * to have any DPEBs.
313 * A Darwin Process Event Block is valid only inside the section to which
314 * it belongs. The structure of a Darwin Process Event Block is shown in
315 * Figure XXX.1 below.
317 * An Enhanced Packet Block (EPB) may be augmented with any or all of the
318 * following block options for Darwin process information:
320 * +------------------+-------+--------+-------------------+
321 * | Name | Code | Length | Multiple allowed? |
322 * +------------------+-------+--------+-------------------+
323 * | darwin_dpeb_id | 32769 | 4 | no? |
324 * | darwin_svc_class | 32770 | 4 | no? |
325 * | darwin_edpeb_id | 32771 | 4 | no? |
326 * | darwin_flags | 32772 | 4 | no? |
327 * | darwin_flow_id | 32773 | 4 | no? |
328 * +------------------+------+---------+-------------------+
330 * Table XXX.2: Darwin options for Enhanced Packet Blocks
332 * darwin_dpeb_id:
333 * The darwin_dpeb_id option specifies the Darwin Process Event
334 * Block ID for the process (proc) this packet is associated with;
335 * the correct DPEB will be the one whose DPEB ID (within the
336 * current Section of the file) is identified by the same number
337 * (see Section XXX.X) of this field. The DPEB ID MUST be valid,
338 * which means that a matching Darwin Process Event Block MUST
339 * exist.
341 * darwin_srv_class:
342 * The darwin_svc_class option is a number that maps to a
343 * specific Darwin Service Class mnemonic that the packet is
344 * associated with.
346 * The following Darwin Service Class values are defined:
348 * +---------------------+------------------------+
349 * | Service Class Value | Service Class Mnemonic |
350 * +---------------------+------------------------+
351 * | 0 | BE |
352 * | 100 | BK_SYS |
353 * | 200 | BK |
354 * | 300 | RD |
355 * | 400 | OAM |
356 * | 500 | AV |
357 * | 600 | RV |
358 * | 700 | VI |
359 * | 800 | VO |
360 * | 900 | CTL |
361 * +---------------------+------------------------+
363 * Table XXX.3: Darwin Service Class Option Values
365 * darwin_edpeb_id:
366 * The darwin_edpeb_id option specifies the Darwin Process Event
367 * Block ID for the effective process (eproc) this packet is
368 * associated with; the correct DPEB will be the one whose DPEB
369 * ID (within the current Section of the file) is identified by
370 * the same number (see Section XXX.X) of this field. The DPEB
371 * ID MUST be valid, which means that a matching Darwin Process
372 * Event Block MUST exist.
374 * darwin_flags:
375 * The darwin_flags option is a 32 bit field for indicating
376 * various Darwin specific flags.
378 * The following Darwin Flags are defined:
380 * +-------------------------+
381 * | FLAG_MASK | Flag |
382 * +-------------------------+
383 * | 0x00000020 | wk |
384 * | 0x00000010 | ch |
385 * | 0x00000008 | so |
386 * | 0x00000004 | re |
387 * | 0x00000002 | ka |
388 * | 0x00000001 | nf |
389 * +-------------------------+
391 * Table XXX.4: Darwin Flags
393 * wk = Wake Packet
394 * ch = Nexus Channel
395 * so = Socket
396 * re = ReXmit
397 * ka = Keep Alive
398 * nf = New Flow
400 * darwin_flow_id:
401 * The darwin_flow_id option is a 32 bit value that
402 * identifies a specific flow this packet is a part of.
406 static const value_string option_code_enhanced_packet_vals[] = {
407 { 0, "End of Options" },
408 { 1, "Comment" },
410 { 2, "Flags" },
411 { 3, "Hash" },
412 { 4, "Drop Count" },
413 { 5, "Packet ID" },
414 { 6, "Queue" },
415 { 7, "Verdict" },
416 OPTION_CODE_CUSTOM_OPTIONS,
417 { 32769, "Darwin DPEB ID" },
418 { 32770, "Darwin Service Class" },
419 { 32771, "Darwin Effective DPEB ID" },
420 { 32772, "Darwin Flags" },
421 { 32773, "Darwin Flow ID" },
422 { 0, NULL }
425 static const value_string option_code_packet_vals[] = {
426 { 0, "End of Options" },
427 { 1, "Comment" },
429 { 2, "Flags" },
430 { 3, "Hash" },
431 OPTION_CODE_CUSTOM_OPTIONS,
432 { 0, NULL }
435 static const value_string option_code_name_resolution_vals[] = {
436 { 0, "End of Options" },
437 { 1, "Comment" },
439 { 2, "DNS Name" },
440 { 3, "DNS IPv4 Address" },
441 { 4, "DNS IPv6 Address" },
442 OPTION_CODE_CUSTOM_OPTIONS,
443 { 0, NULL }
446 static const value_string option_code_interface_statistics_vals[] = {
447 { 0, "End of Options" },
448 { 1, "Comment" },
450 { 2, "Start Time" },
451 { 3, "End Time" },
452 { 4, "Number of Received Packets" },
453 { 5, "Number of Dropped Packets" },
454 { 6, "Number of Accepted Packets" },
455 { 7, "Number of Packets Dropped by OS" },
456 { 8, "Number of Packets Delivered to the User" },
457 OPTION_CODE_CUSTOM_OPTIONS,
458 { 0, NULL }
461 static const value_string option_code_darwin_svc_class_vals[] = {
462 { 0x0000, "BE" },
463 { 0x0064, "BK_SYS" },
464 { 0x00C8, "BK" },
465 { 0x012C, "RD" },
466 { 0x0190, "OAM" },
467 { 0x01F4, "AV" },
468 { 0x0258, "RV" },
469 { 0x02BC, "VI" },
470 { 0x0320, "VO" },
471 { 0x0384, "CTL" },
472 { 0, NULL }
475 static const value_string record_code_vals[] = {
476 { 0x0000, "End of Records" },
477 { 0x0001, "IPv4 Record" },
478 { 0x0002, "IPv6 Record" },
479 { 0, NULL }
482 static const value_string timestamp_resolution_base_vals[] = {
483 { 0x0000, "Power of 10" },
484 { 0x0001, "Power of 2" },
485 { 0, NULL }
488 static const value_string interface_filter_type_vals[] = {
489 { 0, "Libpcap string" },
490 { 1, "BPF program" },
491 { 0, NULL }
494 static const value_string packet_verdict_type_vals[] = {
495 { 0, "Hardware" },
496 { 1, "Linux eBPF TC" },
497 { 2, "Linux eBPF XDP" },
498 { 0, NULL }
501 static const value_string packet_hash_algorithm_vals[] = {
502 { 0, "2's complement" },
503 { 1, "XOR" },
504 { 2, "CRC32" },
505 { 3, "MD5" },
506 { 4, "SHA1" },
507 { 0, NULL }
510 static const value_string packet_flags_direction_vals[] = {
511 { 0x00, "Information Not Available" },
512 { 0x01, "Inbound" },
513 { 0x02, "Outbound" },
514 { 0, NULL }
517 static const value_string flags_reception_type_vals[] = {
518 { 0x00, "Not Specified" },
519 { 0x01, "Unicast" },
520 { 0x02, "Multicast" },
521 { 0x03, "Broadcast" },
522 { 0x04, "Promiscuous" },
523 { 0, NULL }
526 static const value_string dsb_secrets_types_vals[] = {
527 { SECRETS_TYPE_TLS, "TLS Key Log" },
528 { SECRETS_TYPE_SSH, "SSH Key Log" },
529 { SECRETS_TYPE_WIREGUARD, "WireGuard Key Log" },
530 { SECRETS_TYPE_ZIGBEE_NWK_KEY, "Zigbee NWK Key" },
531 { SECRETS_TYPE_ZIGBEE_APS_KEY, "Zigbee APS Key" },
532 { SECRETS_TYPE_OPCUA, "OPC UA Key Log" },
533 { 0, NULL }
536 void proto_register_pcapng(void);
537 void proto_reg_handoff_pcapng(void);
539 #define BYTE_ORDER_MAGIC_SIZE 4
541 static const uint8_t pcapng_big_endian_magic[BYTE_ORDER_MAGIC_SIZE] = {
542 0x1A, 0x2B, 0x3C, 0x4D
544 static const uint8_t pcapng_little_endian_magic[BYTE_ORDER_MAGIC_SIZE] = {
545 0x4D, 0x3C, 0x2B, 0x1A
548 static
549 void dissect_custom_options(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset,
550 uint32_t option_code, uint32_t option_length, unsigned encoding)
552 proto_tree_add_item(tree, hf_pcapng_cb_pen, tvb, offset, 4, encoding);
553 offset += 4;
555 /* Todo: Add known PEN custom options dissection. */
556 switch (option_code) {
557 case 2988:
558 case 19372:
559 proto_tree_add_item(tree, hf_pcapng_cb_option_string, tvb, offset, option_length - 4, ENC_UTF_8);
560 break;
561 case 2989:
562 case 19373:
563 proto_tree_add_item(tree, hf_pcapng_cb_option_data, tvb, offset, option_length - 4, encoding);
564 break;
568 int dissect_options(proto_tree *tree, packet_info *pinfo,
569 uint32_t block_type, tvbuff_t *tvb, int offset, unsigned encoding,
570 void *user_data)
572 proto_tree *options_tree;
573 proto_item *options_item;
574 proto_tree *option_tree;
575 proto_item *option_item;
576 proto_item *option_length_item;
577 proto_item *p_item;
578 uint32_t option_code;
579 uint32_t option_length;
580 int hfj_pcapng_option_code;
581 char *str;
582 const char *const_str;
583 wmem_strbuf_t *strbuf;
584 address addr;
585 address addr_mask;
586 uint32_t if_filter_type;
587 const value_string *vals = NULL;
588 uint8_t value_u8;
589 uint32_t value_u32;
590 uint64_t value_u64;
592 if (tvb_reported_length_remaining(tvb, offset) <= 0)
593 return 0;
595 /* Lookup handlers for known local block type */
596 local_block_callback_info_t *p_local_block_callback = NULL;
597 if (block_type >= 0x80000000) {
598 p_local_block_callback = (local_block_callback_info_t*)g_hash_table_lookup(s_local_block_callback_table, GUINT_TO_POINTER(block_type));
599 DISSECTOR_ASSERT((p_local_block_callback->option_root_hf > 0) &&
600 p_local_block_callback->option_dissector &&
601 p_local_block_callback->option_vals);
604 options_item = proto_tree_add_item(tree, hf_pcapng_options, tvb, offset, -1, ENC_NA);
605 options_tree = proto_item_add_subtree(options_item, ett_pcapng_options);
607 while (tvb_reported_length_remaining(tvb, offset) > 0) {
608 str = NULL;
609 option_item = proto_tree_add_item(options_tree, hf_pcapng_option, tvb, offset, -1, ENC_NA);
610 option_tree = proto_item_add_subtree(option_item, ett_pcapng_option);
612 /* TODO: could have done this once outside of loop? */
613 switch (block_type) {
614 case BLOCK_TYPE_SHB:
615 hfj_pcapng_option_code = hf_pcapng_option_code_section_header;
616 vals = option_code_section_header_vals;
617 break;
618 case BLOCK_TYPE_IDB:
619 hfj_pcapng_option_code = hf_pcapng_option_code_interface_description;
620 vals = option_code_interface_description_vals;
621 break;
622 case BLOCK_TYPE_EPB:
623 hfj_pcapng_option_code = hf_pcapng_option_code_enhanced_packet;
624 vals = option_code_enhanced_packet_vals;
625 break;
626 case BLOCK_TYPE_PB:
627 hfj_pcapng_option_code = hf_pcapng_option_code_packet;
628 vals = option_code_packet_vals;
629 break;
630 case BLOCK_TYPE_NRB:
631 hfj_pcapng_option_code = hf_pcapng_option_code_name_resolution;
632 vals = option_code_name_resolution_vals;
633 break;
634 case BLOCK_TYPE_ISB:
635 hfj_pcapng_option_code = hf_pcapng_option_code_interface_statistics;
636 vals = option_code_interface_statistics_vals;
637 break;
639 default:
640 /* Use and handling we have for a local lock type */
641 if (p_local_block_callback) {
642 hfj_pcapng_option_code = p_local_block_callback->option_root_hf;
643 vals = p_local_block_callback->option_vals;
645 else {
646 hfj_pcapng_option_code = hf_pcapng_option_code;
650 proto_tree_add_item_ret_uint(option_tree, hfj_pcapng_option_code, tvb, offset, 2, encoding, &option_code);
651 if (vals)
652 proto_item_append_text(option_item, ": %s", val_to_str_const(option_code, vals, "Unknown"));
653 offset += 2;
655 option_length_item = proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_length, tvb, offset, 2, encoding, &option_length);
656 offset += 2;
658 if (option_code == 0) {
659 if (option_length != 0)
660 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
661 proto_item_set_len(option_item, option_length + 2 * 2);
662 break;
663 } else if (option_code == 1) {
664 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_comment, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
665 proto_item_append_text(option_item, " = %s", str);
666 offset += option_length;
667 } else if (option_code == 2988 || option_code == 2989 || option_code == 19372 || option_code == 19373) {
668 dissect_custom_options(option_tree, pinfo, tvb, offset, option_code, option_length, encoding);
669 offset += option_length;
670 } else switch (block_type) {
671 case BLOCK_TYPE_SHB:
672 switch (option_code) {
673 case 2:
674 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_section_header_hardware, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
675 proto_item_append_text(option_item, " = %s", str);
676 offset += option_length;
677 break;
678 case 3:
679 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_section_header_os, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
680 proto_item_append_text(option_item, " = %s", str);
681 offset += option_length;
682 break;
683 case 4:
684 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_section_header_user_application, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
685 proto_item_append_text(option_item, " = %s", str);
686 offset += option_length;
687 break;
688 default:
689 proto_tree_add_item(option_tree, hf_pcapng_option_data, tvb, offset, option_length, ENC_NA);
690 offset += option_length;
692 break;
693 case BLOCK_TYPE_IDB: {
694 struct interface_description *interface_description = (struct interface_description *) user_data;
696 switch (option_code) {
697 case 2:
698 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_interface_description_name, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
699 proto_item_append_text(option_item, " = %s", str);
700 offset += option_length;
701 break;
702 case 3:
703 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_interface_description_description, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
704 proto_item_append_text(option_item, " = %s", str);
705 offset += option_length;
706 break;
707 case 4:
708 if (option_length != 8) {
709 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
710 offset += option_length;
711 break;
713 proto_tree_add_item(option_tree, hf_pcapng_option_data_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
714 set_address_tvb(&addr, AT_IPv4, 4, tvb, offset);
715 offset += 4;
717 proto_tree_add_item(option_tree, hf_pcapng_option_data_ipv4_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
718 set_address_tvb(&addr_mask, AT_IPv4, 4, tvb, offset);
719 offset += 4;
721 proto_item_append_text(option_item, " = %s/%s",
722 address_to_display(pinfo->pool, &addr),
723 address_to_display(pinfo->pool, &addr_mask));
724 break;
725 case 5:
726 if (option_length != 17) {
727 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
728 offset += option_length;
729 break;
732 proto_tree_add_item(option_tree, hf_pcapng_option_data_ipv6, tvb, offset, 16, ENC_NA);
733 set_address_tvb(&addr, AT_IPv6, 16, tvb, offset);
734 offset += 16;
736 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_ipv6_mask, tvb, offset, 1, ENC_NA, &value_u32);
737 offset += 1;
739 proto_item_append_text(option_item, " = %s/%u",
740 address_to_display(pinfo->pool, &addr), value_u32);
742 break;
743 case 6:
744 if (option_length != 6) {
745 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
746 offset += option_length;
747 break;
750 proto_tree_add_item(option_tree, hf_pcapng_option_data_mac_address, tvb, offset, 6, encoding);
751 proto_item_append_text(option_item, " = %s",
752 tvb_get_ether_name(tvb, offset));
753 offset += 6;
755 break;
756 case 7:
757 if (option_length != 8) {
758 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
759 offset += option_length;
760 break;
763 proto_tree_add_item(option_tree, hf_pcapng_option_data_eui_address, tvb, offset, 8, encoding);
764 set_address_tvb(&addr, AT_EUI64, 8, tvb, offset);
765 offset += 8;
767 proto_item_append_text(option_item, " = %s",
768 address_to_display(pinfo->pool, &addr));
770 break;
771 case 8:
772 if (option_length != 8) {
773 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
774 offset += option_length;
775 break;
778 p_item = proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_interface_speed, tvb, offset, 8, encoding, &value_u64);
779 /* XXX - is there a general routine to do this mapping? */
780 if (value_u64 == 10000000) {
781 const_str = "10 Mbps";
782 } else if (value_u64 == 100000000) {
783 const_str = "100 Mbps";
784 } else if (value_u64 == 1000000000) {
785 const_str = "1 Gbps";
786 } else {
787 const_str = wmem_strdup_printf(pinfo->pool, "%"PRIu64, value_u64);
789 proto_item_append_text(p_item, "%s", const_str);
790 proto_item_append_text(option_item, " = %s", const_str);
791 offset += 8;
793 break;
794 case 9:
796 uint32_t base;
797 uint32_t exponent;
798 uint32_t i;
799 uint64_t resolution;
801 if (option_length != 1) {
802 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
803 offset += option_length;
804 break;
807 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_interface_timestamp_resolution, ett_pcapng_option, hfx_pcapng_option_data_interface_timestamp_resolution, ENC_NA);
808 value_u8 = tvb_get_uint8(tvb, offset);
809 offset += 1;
811 if (value_u8 & 0x80) {
812 base = 2;
813 } else {
814 base = 10;
816 exponent = value_u8 & 0x7F;
818 strbuf = wmem_strbuf_new(pinfo->pool, "");
819 wmem_strbuf_append_printf(strbuf, "%u^-%u", base, exponent);
820 resolution = 1;
821 for (i = 0; i < exponent; i += 1)
822 resolution *= base;
823 if (interface_description) {
824 interface_description->timestamp_resolution = resolution;
826 switch (resolution) {
828 case 0:
829 /* Overflow */
830 wmem_strbuf_append(strbuf, " (overflow)");
831 break;
833 case 1:
834 wmem_strbuf_append(strbuf, " (seconds)");
835 break;
837 case 10:
838 wmem_strbuf_append(strbuf, " (.1 seconds)");
839 break;
841 case 100:
842 wmem_strbuf_append(strbuf, " (.01 seconds)");
843 break;
845 case 1000:
846 wmem_strbuf_append(strbuf, " (milliseconds)");
847 break;
849 case 10000:
850 wmem_strbuf_append(strbuf, " (.1 milliseconds)");
851 break;
853 case 100000:
854 wmem_strbuf_append(strbuf, " (.01 milliseconds)");
855 break;
857 case 1000000:
858 wmem_strbuf_append(strbuf, " (microseconds)");
859 break;
861 case 10000000:
862 wmem_strbuf_append(strbuf, " (.1 microseconds)");
863 break;
865 case 100000000:
866 wmem_strbuf_append(strbuf, " (.01 microseconds)");
867 break;
869 case 1000000000:
870 wmem_strbuf_append(strbuf, " (nanoseconds)");
871 break;
873 case 10000000000:
874 wmem_strbuf_append(strbuf, " (.1 nanoseconds)");
875 break;
877 case 100000000000:
878 wmem_strbuf_append(strbuf, " (.01 nanoseconds)");
879 break;
881 case 1000000000000:
882 wmem_strbuf_append(strbuf, " (picoseconds)");
883 break;
885 case 10000000000000:
886 wmem_strbuf_append(strbuf, " (.1 picoseconds)");
887 break;
889 case 100000000000000:
890 wmem_strbuf_append(strbuf, " (.01 picoseconds)");
891 break;
893 proto_item_append_text(option_item, " = %s",
894 wmem_strbuf_finalize(strbuf));
895 break;
897 case 10:
898 if (option_length != 4) {
899 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
900 offset += option_length;
901 break;
904 /* TODO: Better timezone decoding */
905 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_interface_timezone, tvb, offset, 4, encoding, &value_u32);
906 offset += 4;
908 proto_item_append_text(option_item, " = %u", value_u32);
910 break;
911 case 11:
912 if (option_length == 0) {
913 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
914 break;
918 /* Get filter type (0 is libpcap, 1 is BPF program, others are unspecified.) */
919 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_interface_filter_type, tvb, offset, 1, ENC_NA, &if_filter_type);
920 offset++;
921 switch (if_filter_type) {
923 case 0:
924 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_interface_filter_string, tvb, offset, option_length - 1, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
925 proto_item_append_text(option_item, " = %s", str);
926 break;
928 case 1:
929 proto_tree_add_item(option_tree, hf_pcapng_option_data_interface_filter_bpf_program, tvb, offset, option_length - 1, ENC_NA);
930 proto_item_append_text(option_item, " = {BPF program}");
931 break;
933 default:
934 proto_tree_add_item(option_tree, hf_pcapng_option_data_interface_filter_unknown, tvb, offset, option_length - 1, ENC_NA);
935 proto_item_append_text(option_item, " = unknown (type %u)", if_filter_type);
936 break;
938 offset += option_length - 1;
940 break;
941 case 12:
942 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_interface_os, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
943 proto_item_append_text(option_item, " = %s", str);
944 offset += option_length;
946 break;
947 case 13:
948 if (option_length != 1) {
949 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
950 offset += option_length;
951 break;
954 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_interface_fcs_length, tvb, offset, 1, ENC_NA, &value_u32);
955 offset += 1;
956 proto_item_append_text(option_item, " = %u", value_u32);
958 break;
959 case 14:
960 if (option_length != 8) {
961 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
962 offset += option_length;
963 break;
966 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_interface_timestamp_offset, tvb, offset, 8, encoding, &value_u64);
967 offset += 8;
968 proto_item_append_text(option_item, " = %"PRIu64, value_u64);
970 if (interface_description) {
971 interface_description->timestamp_offset = value_u64;
974 break;
975 case 15:
976 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_interface_hardware, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
977 proto_item_append_text(option_item, " = %s", str);
978 offset += option_length;
980 break;
981 default:
982 proto_tree_add_item(option_tree, hf_pcapng_option_data, tvb, offset, option_length, ENC_NA);
983 offset += option_length;
986 break;
987 case BLOCK_TYPE_PB:
988 switch (option_code) {
989 case 2:
990 if (option_length != 4) {
991 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
992 offset += option_length;
993 break;
996 if (encoding == ENC_LITTLE_ENDIAN) {
997 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags, ett_pcapng_option, hfx_pcapng_option_data_packet_flags, encoding);
998 offset += 2;
1000 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags_link_layer_errors, ett_pcapng_option, hfx_pcapng_option_data_packet_flags_link_layer_errors, encoding);
1001 offset += 2;
1002 } else {
1003 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags_link_layer_errors, ett_pcapng_option, hfx_pcapng_option_data_packet_flags_link_layer_errors, encoding);
1004 offset += 2;
1006 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags, ett_pcapng_option, hfx_pcapng_option_data_packet_flags, encoding);
1007 offset += 2;
1010 break;
1011 case 3:
1012 proto_tree_add_item(option_tree, hf_pcapng_option_data_packet_hash_algorithm, tvb, offset, 1, ENC_NA);
1013 offset += 1;
1015 proto_tree_add_item(option_tree, hf_pcapng_option_data_packet_hash_data, tvb, offset, option_length - 1, ENC_NA);
1016 offset += option_length - 1;
1018 break;
1019 default:
1020 proto_tree_add_item(option_tree, hf_pcapng_option_data, tvb, offset, option_length, ENC_NA);
1021 offset += option_length;
1024 break;
1025 case BLOCK_TYPE_NRB:
1026 switch (option_code) {
1027 case 2:
1028 proto_tree_add_item_ret_display_string(option_tree, hf_pcapng_option_data_dns_name, tvb, offset, option_length, ENC_NA | ENC_UTF_8, pinfo->pool, &str);
1029 proto_item_append_text(option_item, " = %s", str);
1030 offset += option_length;
1032 break;
1033 case 3:
1034 if (option_length != 4) {
1035 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1036 offset += option_length;
1037 break;
1040 proto_tree_add_item(option_tree, hf_pcapng_option_data_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
1041 set_address_tvb(&addr, AT_IPv4, 4, tvb, offset);
1042 offset += 4;
1044 proto_item_append_text(option_item, " = %s",
1045 address_to_display(pinfo->pool, &addr));
1047 break;
1048 case 4:
1049 if (option_length != 16) {
1050 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1051 offset += option_length;
1052 break;
1055 proto_tree_add_item(option_tree, hf_pcapng_option_data_ipv6, tvb, offset, 16, ENC_NA);
1056 set_address_tvb(&addr, AT_IPv6, 16, tvb, offset);
1057 offset += 16;
1059 proto_item_append_text(option_item, " = %s",
1060 address_to_display(pinfo->pool, &addr));
1062 break;
1063 default:
1064 proto_tree_add_item(option_tree, hf_pcapng_option_data, tvb, offset, option_length, ENC_NA);
1065 offset += option_length;
1068 break;
1069 case BLOCK_TYPE_ISB:
1070 switch (option_code) {
1071 case 2:
1072 if (option_length != 8) {
1073 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1074 offset += option_length;
1075 break;
1078 proto_tree_add_item(option_tree, hf_pcapng_option_data_start_time, tvb, offset, 8, encoding);
1079 offset += 8;
1081 break;
1082 case 3:
1083 if (option_length != 8) {
1084 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1085 offset += option_length;
1086 break;
1089 proto_tree_add_item(option_tree, hf_pcapng_option_data_end_time, tvb, offset, 8, encoding);
1090 offset += 8;
1092 break;
1093 case 4:
1094 if (option_length != 8) {
1095 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1096 offset += option_length;
1097 break;
1100 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_interface_received, tvb, offset, 8, encoding, &value_u64);
1101 proto_item_append_text(option_item, " = %"PRIu64, value_u64);
1102 offset += 8;
1104 break;
1105 case 5:
1106 if (option_length != 8) {
1107 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1108 offset += option_length;
1109 break;
1112 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_interface_dropped, tvb, offset, 8, encoding, &value_u64);
1113 proto_item_append_text(option_item, " = %"PRIu64, value_u64);
1114 offset += 8;
1116 break;
1117 case 6:
1118 if (option_length != 8) {
1119 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1120 offset += option_length;
1121 break;
1124 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_interface_accepted_by_filter, tvb, offset, 8, encoding, &value_u64);
1125 proto_item_append_text(option_item, " = %"PRIu64, value_u64);
1126 offset += 8;
1128 break;
1129 case 7:
1130 if (option_length != 8) {
1131 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1132 offset += option_length;
1133 break;
1136 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_interface_dropped_by_os, tvb, offset, 8, encoding, &value_u64);
1137 proto_item_append_text(option_item, " = %"PRIu64, value_u64);
1138 offset += 8;
1140 break;
1141 case 8:
1142 if (option_length != 8) {
1143 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1144 offset += option_length;
1145 break;
1148 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_interface_delivered_to_user, tvb, offset, 8, encoding, &value_u64);
1149 proto_item_append_text(option_item, " = %"PRIu64, value_u64);
1150 offset += 8;
1152 break;
1153 default:
1154 proto_tree_add_item(option_tree, hf_pcapng_option_data, tvb, offset, option_length, ENC_NA);
1155 offset += option_length;
1158 break;
1159 case BLOCK_TYPE_EPB:
1160 switch (option_code) {
1161 case 2:
1162 if (option_length != 4) {
1163 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1164 offset += option_length;
1165 break;
1168 if (encoding == ENC_LITTLE_ENDIAN) {
1169 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags, ett_pcapng_option, hfx_pcapng_option_data_packet_flags, encoding);
1170 offset += 2;
1172 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags_link_layer_errors, ett_pcapng_option, hfx_pcapng_option_data_packet_flags_link_layer_errors, encoding);
1173 offset += 2;
1174 } else {
1175 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags_link_layer_errors, ett_pcapng_option, hfx_pcapng_option_data_packet_flags_link_layer_errors, encoding);
1176 offset += 2;
1178 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_flags, ett_pcapng_option, hfx_pcapng_option_data_packet_flags, encoding);
1179 offset += 2;
1182 break;
1183 case 3:
1184 proto_tree_add_item(option_tree, hf_pcapng_option_data_packet_hash_algorithm, tvb, offset, 1, ENC_NA);
1185 offset += 1;
1187 proto_tree_add_item(option_tree, hf_pcapng_option_data_packet_hash_data, tvb, offset, option_length - 1, ENC_NA);
1188 offset += option_length - 1;
1190 break;
1191 case 4:
1192 if (option_length != 8) {
1193 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1194 offset += option_length;
1195 break;
1198 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_packet_drop_count, tvb, offset, 8, encoding, &value_u64);
1199 proto_item_append_text(option_item, " = %"PRIu64, value_u64);
1200 offset += 8;
1202 break;
1203 case 5:
1204 if (option_length != 8) {
1205 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1206 offset += option_length;
1207 break;
1210 proto_tree_add_item_ret_uint64(option_tree, hf_pcapng_option_data_packet_id, tvb, offset, 8, encoding, &value_u64);
1211 proto_item_append_text(option_item, " = 0x%016"PRIx64, value_u64);
1212 offset += 8;
1214 break;
1215 case 6:
1216 if (option_length != 4) {
1217 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1218 offset += option_length;
1219 break;
1222 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_packet_queue, tvb, offset, 4, encoding, &value_u32);
1223 proto_item_append_text(option_item, " = %u", value_u32);
1224 offset += 4;
1226 break;
1227 case 7:
1228 if (option_length < 1) {
1229 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1230 break;
1233 switch (tvb_get_uint8(tvb, offset)) {
1234 case 1:
1235 case 2:
1236 if (option_length != 9) {
1237 expert_add_info(pinfo, option_length_item, &ei_invalid_option_length);
1239 break;
1240 default:
1241 break;
1244 proto_tree_add_item(option_tree, hf_pcapng_option_data_packet_verdict_type, tvb, offset, 1, ENC_NA);
1245 if (option_length > 1)
1246 proto_tree_add_item(option_tree, hf_pcapng_option_data_packet_verdict_data, tvb, offset + 1, option_length - 1, ENC_NA);
1247 offset += option_length;
1249 break;
1250 case 32769: /* Darwin DPEB ID */
1251 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_packet_darwin_dpeb_id, tvb, offset, option_length, encoding, &value_u32);
1252 offset += option_length;
1254 proto_item_append_text(option_item, " = %u", value_u32);
1256 break;
1257 case 32770: /* Darwin Service Type */
1258 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_packet_darwin_svc_class, tvb, offset, option_length, encoding, &value_u32);
1259 offset += option_length;
1261 proto_item_append_text(option_item, " = %s", val_to_str_const(value_u32, option_code_darwin_svc_class_vals, "Unknown"));
1263 break;
1264 case 32771: /* Darwin Effective DPEB ID */
1265 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_packet_darwin_edpeb_id, tvb, offset, option_length, encoding, &value_u32);
1266 offset += option_length;
1268 proto_item_append_text(option_item, " = %u", value_u32);
1270 break;
1271 case 32772: /* Darwin Flags */
1272 proto_tree_add_bitmask(option_tree, tvb, offset, hf_pcapng_option_data_packet_darwin_flags, ett_pcapng_option, hfx_pcapng_option_data_packet_darwin_flags, encoding);
1273 offset += option_length;
1275 break;
1276 case 32773: /* Darwin Flow ID */
1277 proto_tree_add_item_ret_uint(option_tree, hf_pcapng_option_data_packet_darwin_flow_id, tvb, offset, option_length, encoding, &value_u32);
1278 offset += option_length;
1280 proto_item_append_text(option_item, " = %u", value_u32);
1282 break;
1283 default:
1284 proto_tree_add_item(option_tree, hf_pcapng_option_data, tvb, offset, option_length, ENC_NA);
1285 offset += option_length;
1288 break;
1290 default:
1291 /* Use local block handling if available */
1292 if (p_local_block_callback) {
1293 p_local_block_callback->option_dissector(option_tree, option_item, pinfo, tvb, offset,
1294 hf_pcapng_option_data, option_code, option_length, encoding);
1296 else {
1297 proto_tree_add_item(option_tree, hf_pcapng_option_data, tvb, offset, option_length, ENC_NA);
1299 offset += option_length;
1302 /* Pad this option out to next 4 bytes */
1303 if ((option_length % 4) != 0) {
1304 proto_item_set_len(option_item, option_length + 2 * 2 + (4 - option_length % 4));
1305 option_length = 4 - option_length % 4;
1306 proto_tree_add_item(option_tree, hf_pcapng_option_padding, tvb, offset, option_length, ENC_NA);
1307 offset += option_length;
1308 } else
1309 proto_item_set_len(option_item, option_length + 2 * 2);
1311 proto_item_set_end(options_item, tvb, offset);
1313 return offset;
1316 static void
1317 pcapng_add_timestamp(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1318 int offset, unsigned encoding,
1319 struct interface_description *interface_description)
1321 proto_tree_add_item(tree, hf_pcapng_timestamp_high, tvb, offset, 4, encoding);
1322 proto_tree_add_item(tree, hf_pcapng_timestamp_low, tvb, offset + 4, 4, encoding);
1324 if (interface_description != NULL) {
1325 nstime_t timestamp;
1326 uint64_t ts;
1327 proto_item *ti;
1329 ts = ((uint64_t)(tvb_get_uint32(tvb, offset, encoding))) << 32 |
1330 tvb_get_uint32(tvb, offset + 4, encoding);
1332 ts += interface_description->timestamp_offset;
1334 if (interface_description->timestamp_resolution == 0) {
1335 /* This overflowed, so we can't calculate the time stamp */
1336 pinfo->presence_flags &= ~PINFO_HAS_TS;
1337 } else {
1338 timestamp.secs = (time_t)(ts / interface_description->timestamp_resolution);
1339 timestamp.nsecs = (int)(((ts % interface_description->timestamp_resolution) * 1000000000) / interface_description->timestamp_resolution);
1341 ti = proto_tree_add_time(tree, hf_pcapng_timestamp, tvb, offset, 8, &timestamp);
1342 proto_item_set_generated(ti);
1344 pinfo->abs_ts = timestamp;
1349 static struct interface_description *
1350 get_interface_description(struct info *info, unsigned interface_id,
1351 packet_info *pinfo, proto_tree *tree)
1353 if (interface_id >= wmem_array_get_count(info->interfaces)) {
1354 expert_add_info(pinfo, tree, &ei_missing_idb);
1355 return NULL;
1357 return (struct interface_description *) wmem_array_index(info->interfaces, interface_id);
1361 * This is tricky - for most blocks, we can dissect this first, but, for
1362 * a Section Header Block, we must dissect it *after* determining the
1363 * byte order.
1365 * So we extract it into a routine and call it at the appropriate time.
1367 static tvbuff_t *
1368 process_block_length(proto_tree *block_tree, packet_info *pinfo,
1369 tvbuff_t *tvb, int offset, proto_tree **block_data_tree_p,
1370 proto_item **block_length_item_p, uint32_t *block_length_p,
1371 unsigned encoding)
1373 proto_item *block_data_item;
1374 uint32_t block_data_length;
1376 *block_length_item_p = proto_tree_add_item_ret_uint(block_tree, hf_pcapng_block_length, tvb, offset, 4, encoding, block_length_p);
1377 if (*block_length_p < 3*4) {
1378 expert_add_info(pinfo, *block_length_item_p, &ei_block_length_below_block_minimum);
1379 return NULL;
1382 * To quote the current pcapng spec, "Block Total Length (32 bits) ...
1383 * This value MUST be a multiple of 4."
1385 if ((*block_length_p % 4) != 0) {
1386 expert_add_info(pinfo, *block_length_item_p, &ei_block_length_not_multiple_of_4);
1387 return NULL;
1391 * Subtract the per-block overhead (block type, block length, trailing
1392 * block length) to give the length of the block data.
1393 * block.
1395 block_data_length = *block_length_p - 3*4;
1398 * Now that we know the block data length, create an item for its
1399 * tree, and provide the tree to our caller.
1401 offset += 4;
1402 block_data_item = proto_tree_add_item(block_tree, hf_pcapng_block_data, tvb, offset, block_data_length, ENC_NA);
1403 *block_data_tree_p = proto_item_add_subtree(block_data_item, ett_pcapng_block_data);
1406 * Create a tvbuff for the block data, and provide it to our caller.
1408 return tvb_new_subset_length(tvb, offset, block_data_length);
1413 static bool
1414 dissect_shb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1415 bool byte_order_magic_bad, block_data_arg *argp)
1417 int offset = 0;
1418 proto_item *byte_order_magic_item;
1420 byte_order_magic_item = proto_tree_add_item(tree, hf_pcapng_section_header_byte_order_magic, tvb, offset, 4, ENC_NA);
1421 if (byte_order_magic_bad) {
1422 expert_add_info(pinfo, byte_order_magic_item, &ei_invalid_byte_order_magic);
1423 return false;
1425 if (argp->info->encoding == ENC_BIG_ENDIAN)
1426 proto_item_append_text(byte_order_magic_item, " (Big-endian)");
1427 else
1428 proto_item_append_text(byte_order_magic_item, " (Little-endian)");
1429 offset += 4;
1431 proto_tree_add_item(tree, hf_pcapng_section_header_major_version, tvb, offset, 2, argp->info->encoding);
1432 offset += 2;
1434 proto_tree_add_item(tree, hf_pcapng_section_header_minor_version, tvb, offset, 2, argp->info->encoding);
1435 offset += 2;
1437 proto_tree_add_item(tree, hf_pcapng_section_header_section_length, tvb, offset, 8, argp->info->encoding);
1438 offset += 8;
1440 dissect_options(tree, pinfo, BLOCK_TYPE_SHB, tvb, offset, argp->info->encoding, NULL);
1442 return true;
1445 static void
1446 dissect_idb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1447 block_data_arg *argp)
1449 int offset = 0;
1450 struct interface_description interface_description;
1452 memset(&interface_description, 0, sizeof(struct interface_description));
1453 interface_description.timestamp_resolution = 1000000; /* 1 microsecond resolution is the default */
1455 proto_item_append_text(argp->block_item, " %u", argp->info->interface_number);
1456 argp->info->interface_number += 1;
1458 proto_tree_add_item(tree, hf_pcapng_interface_description_link_type, tvb, offset, 2, argp->info->encoding);
1459 interface_description.link_type = tvb_get_uint16(tvb, offset, argp->info->encoding);
1460 offset += 2;
1462 proto_tree_add_item(tree, hf_pcapng_interface_description_reserved, tvb, offset, 2, argp->info->encoding);
1463 offset += 2;
1465 proto_tree_add_item(tree, hf_pcapng_interface_description_snap_length, tvb, offset, 4, argp->info->encoding);
1466 interface_description.snap_len = tvb_get_uint32(tvb, offset, argp->info->encoding);
1467 offset += 4;
1469 dissect_options(tree, pinfo, BLOCK_TYPE_IDB, tvb, offset, argp->info->encoding, &interface_description);
1471 wmem_array_append_one(argp->info->interfaces, interface_description);
1474 static void
1475 dissect_pb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1476 block_data_arg *argp)
1478 volatile int offset = 0;
1479 uint32_t interface_id;
1480 struct interface_description *interface_description;
1481 uint32_t captured_length;
1482 uint32_t original_length;
1483 proto_item *packet_data_item;
1485 proto_item_append_text(argp->block_item, " %u", argp->info->frame_number);
1487 proto_tree_add_item(tree, hf_pcapng_packet_block_interface_id, tvb, offset, 2, argp->info->encoding);
1488 interface_id = tvb_get_uint16(tvb, offset, argp->info->encoding);
1489 offset += 2;
1490 interface_description = get_interface_description(argp->info, interface_id,
1491 pinfo, argp->block_tree);
1493 proto_tree_add_item(tree, hf_pcapng_packet_block_drops_count, tvb, offset, 2, argp->info->encoding);
1494 offset += 2;
1496 pcapng_add_timestamp(tree, pinfo, tvb, offset, argp->info->encoding, interface_description);
1497 offset += 8;
1499 proto_tree_add_item_ret_uint(tree, hf_pcapng_captured_length, tvb, offset, 4, argp->info->encoding, &captured_length);
1500 offset += 4;
1502 proto_tree_add_item_ret_uint(tree, hf_pcapng_original_length, tvb, offset, 4, argp->info->encoding, &original_length);
1503 offset += 4;
1505 packet_data_item = proto_tree_add_item(tree, hf_pcapng_packet_data, tvb, offset, captured_length, argp->info->encoding);
1507 if (pref_dissect_next_layer && interface_description != NULL) {
1508 proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
1510 pinfo->num = argp->info->frame_number;
1512 TRY {
1513 call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length_caplen(tvb, offset, captured_length, original_length),
1514 pinfo, packet_data_tree, &interface_description->link_type);
1516 CATCH_BOUNDS_ERRORS {
1517 show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
1519 ENDTRY;
1521 argp->info->frame_number += 1;
1522 offset += captured_length;
1524 if (captured_length % 4) {
1525 proto_tree_add_item(tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4) ? (4 - (captured_length % 4)) : 0), ENC_NA);
1526 offset += ((captured_length % 4) ?(4 - (captured_length % 4)):0);
1529 dissect_options(tree, pinfo, BLOCK_TYPE_PB, tvb, offset, argp->info->encoding, NULL);
1532 static void
1533 dissect_spb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1534 block_data_arg *argp)
1536 volatile int offset = 0;
1537 struct interface_description *interface_description;
1538 proto_item *ti;
1539 volatile uint32_t captured_length;
1540 uint32_t original_length;
1541 proto_item *packet_data_item;
1543 interface_description = get_interface_description(argp->info, 0,
1544 pinfo, argp->block_tree);
1546 proto_item_append_text(argp->block_item, " %u", argp->info->frame_number);
1548 proto_tree_add_item_ret_uint(tree, hf_pcapng_original_length, tvb, offset, 4, argp->info->encoding, &original_length);
1549 offset += 4;
1551 captured_length = original_length;
1552 if (interface_description && interface_description->snap_len != 0) {
1553 captured_length = MIN(original_length, interface_description->snap_len);
1555 ti = proto_tree_add_uint(tree, hf_pcapng_captured_length, tvb, 0, 0, captured_length);
1556 proto_item_set_generated(ti);
1558 packet_data_item = proto_tree_add_item(tree, hf_pcapng_packet_data, tvb, offset, captured_length, argp->info->encoding);
1560 if (pref_dissect_next_layer && interface_description != NULL) {
1561 proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
1563 pinfo->num = argp->info->frame_number;
1565 TRY {
1566 call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length(tvb, offset, captured_length),
1567 pinfo, packet_data_tree, &interface_description->link_type);
1569 CATCH_BOUNDS_ERRORS {
1570 show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
1572 ENDTRY;
1574 argp->info->frame_number += 1;
1575 offset += captured_length;
1577 if (captured_length % 4) {
1578 proto_tree_add_item(tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4)?(4 - (captured_length % 4)):0), ENC_NA);
1579 offset += ((captured_length % 4) ? (4 - (captured_length % 4)):0);
1583 static void
1584 dissect_nrb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1585 block_data_arg *argp)
1587 int offset = 0;
1588 proto_tree *records_tree;
1589 proto_item *records_item;
1590 proto_tree *record_tree;
1591 proto_item *record_item;
1592 proto_item *record_length_item;
1593 int offset_string_start;
1594 uint32_t record_code;
1595 uint32_t record_length;
1596 int string_length;
1597 char *str = NULL;
1598 address addr;
1600 records_item = proto_tree_add_item(tree, hf_pcapng_records, tvb, offset, -1, ENC_NA);
1601 records_tree = proto_item_add_subtree(records_item, ett_pcapng_records);
1603 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1604 record_item = proto_tree_add_item(records_tree, hf_pcapng_record, tvb, offset, -1, ENC_NA);
1605 record_tree = proto_item_add_subtree(record_item, ett_pcapng_record);
1607 proto_tree_add_item_ret_uint(record_tree, hf_pcapng_record_code, tvb, offset, 2, argp->info->encoding, &record_code);
1608 proto_item_append_text(record_item, ": %s", val_to_str_const(record_code, record_code_vals, "Unknown"));
1609 offset += 2;
1611 record_length_item = proto_tree_add_item_ret_uint(record_tree, hf_pcapng_record_length, tvb, offset, 2, argp->info->encoding, &record_length);
1612 offset += 2;
1614 if (record_code == 0) {
1615 if (record_length != 0)
1616 expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
1617 proto_item_set_len(record_item, record_length + 2 * 2);
1618 break;
1619 } else switch (record_code) {
1620 case 0x0001: /* IPv4 Record */
1621 if (record_length < 5) {
1622 expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
1623 offset += record_length;
1624 break;
1627 proto_tree_add_item(record_tree, hf_pcapng_record_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
1628 set_address_tvb(&addr, AT_IPv4, 4, tvb, offset);
1629 offset += 4;
1631 offset_string_start = offset;
1632 while ((unsigned)(offset - offset_string_start) < record_length - 4) {
1633 string_length = tvb_strnlen(tvb, offset, (offset - offset_string_start) + record_length - 4);
1634 if (string_length >= 0) {
1635 proto_tree_add_item(record_tree, hf_pcapng_record_name, tvb, offset, string_length + 1, argp->info->encoding);
1636 offset += string_length + 1;
1637 } else {
1639 * XXX - flag with an error, as this means we didn't
1640 * see a terminating NUL, but the spec says "zero
1641 * or more zero-terminated UTF-8 strings containing
1642 * the DNS entries for that address".
1644 proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, (record_length - 4) - (offset - offset_string_start), argp->info->encoding);
1645 offset += (record_length - 4) - (offset - offset_string_start);
1649 str = address_to_display(pinfo->pool, &addr);
1650 break;
1651 case 0x0002: /* IPv6 Record */
1652 if (record_length < 17) {
1653 expert_add_info(pinfo, record_length_item, &ei_invalid_record_length);
1654 offset += record_length;
1655 break;
1658 proto_tree_add_item(record_tree, hf_pcapng_record_ipv6, tvb, offset, 16, ENC_NA);
1659 set_address_tvb(&addr, AT_IPv6, 16, tvb, offset);
1660 offset += 16;
1662 offset_string_start = offset;
1663 while ((unsigned)(offset - offset_string_start) < record_length - 16) {
1664 string_length = tvb_strnlen(tvb, offset, (offset - offset_string_start) + record_length - 16);
1665 if (string_length >= 0) {
1666 proto_tree_add_item(record_tree, hf_pcapng_record_name, tvb, offset, string_length + 1, argp->info->encoding);
1667 offset += string_length + 1;
1668 } else {
1670 * XXX - flag with an error, as this means we didn't
1671 * see a terminating NUL, but the spec says "zero
1672 * or more zero-terminated UTF-8 strings containing
1673 * the DNS entries for that address".
1675 proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, (record_length - 16) - (offset - offset_string_start), argp->info->encoding);
1676 offset += (record_length - 16) - (offset - offset_string_start);
1680 str = address_to_display(pinfo->pool, &addr);
1682 break;
1683 default:
1684 proto_tree_add_item(record_tree, hf_pcapng_record_data, tvb, offset, record_length, ENC_NA);
1685 offset += record_length;
1688 if (record_code != 0 && record_length % 4) {
1689 proto_item_set_len(record_item, record_length + 2 * 2 + (4 - record_length % 4));
1690 record_length = 4 - record_length % 4;
1691 proto_tree_add_item(record_tree, hf_pcapng_record_padding, tvb, offset, record_length, ENC_NA);
1692 offset += record_length;
1693 } else
1694 proto_item_set_len(record_item, record_length + 2 * 2);
1696 if (str)
1697 proto_item_append_text(record_item, " = %s", str);
1699 proto_item_set_end(records_item, tvb, offset);
1701 dissect_options(tree, pinfo, BLOCK_TYPE_NRB, tvb, offset, argp->info->encoding, NULL);
1704 static void
1705 dissect_isb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1706 block_data_arg *argp)
1708 int offset = 0;
1709 uint32_t interface_id;
1710 struct interface_description *interface_description;
1712 proto_tree_add_item(tree, hf_pcapng_interface_id, tvb, offset, 4, argp->info->encoding);
1713 interface_id = tvb_get_uint32(tvb, offset, argp->info->encoding);
1714 offset += 4;
1715 interface_description = get_interface_description(argp->info, interface_id,
1716 pinfo, argp->block_tree);
1718 pcapng_add_timestamp(tree, pinfo, tvb, offset, argp->info->encoding, interface_description);
1719 offset += 8;
1721 dissect_options(tree, pinfo, BLOCK_TYPE_ISB, tvb, offset, argp->info->encoding, NULL);
1724 static void
1725 dissect_epb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1726 block_data_arg *argp)
1728 volatile int offset = 0;
1729 uint32_t interface_id;
1730 struct interface_description *interface_description;
1731 uint32_t captured_length;
1732 uint32_t original_length;
1733 proto_item *packet_data_item;
1735 proto_item_append_text(argp->block_item, " %u", argp->info->frame_number);
1737 proto_tree_add_item(tree, hf_pcapng_interface_id, tvb, offset, 4, argp->info->encoding);
1738 interface_id = tvb_get_uint32(tvb, offset, argp->info->encoding);
1739 offset += 4;
1740 interface_description = get_interface_description(argp->info, interface_id,
1741 pinfo, argp->block_tree);
1743 pcapng_add_timestamp(tree, pinfo, tvb, offset, argp->info->encoding, interface_description);
1744 offset += 8;
1746 proto_tree_add_item_ret_uint(tree, hf_pcapng_captured_length, tvb, offset, 4, argp->info->encoding, &captured_length);
1747 offset += 4;
1749 proto_tree_add_item_ret_uint(tree, hf_pcapng_original_length, tvb, offset, 4, argp->info->encoding, &original_length);
1750 offset += 4;
1752 packet_data_item = proto_tree_add_item(tree, hf_pcapng_packet_data, tvb, offset, captured_length, argp->info->encoding);
1754 if (pref_dissect_next_layer && interface_description != NULL) {
1755 proto_tree *packet_data_tree = proto_item_add_subtree(packet_data_item, ett_pcapng_packet_data);
1757 pinfo->num = argp->info->frame_number;
1759 TRY {
1760 call_dissector_with_data(pcap_pktdata_handle, tvb_new_subset_length_caplen(tvb, offset, captured_length, original_length),
1761 pinfo, packet_data_tree, &interface_description->link_type);
1763 CATCH_BOUNDS_ERRORS {
1764 show_exception(tvb, pinfo, packet_data_tree, EXCEPT_CODE, GET_MESSAGE);
1766 ENDTRY;
1768 argp->info->frame_number += 1;
1769 offset += captured_length;
1771 if (captured_length % 4) {
1772 proto_tree_add_item(tree, hf_pcapng_packet_padding, tvb, offset, ((captured_length % 4)? (4 - (captured_length % 4)):0), ENC_NA);
1773 offset += ((captured_length % 4) ?(4 - (captured_length % 4)):0);
1776 dissect_options(tree, pinfo, BLOCK_TYPE_EPB, tvb, offset, argp->info->encoding, NULL);
1779 static void
1780 dissect_dsb_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1781 block_data_arg *argp)
1783 int offset = 0;
1784 uint32_t secrets_length;
1786 proto_tree_add_item(tree, hf_pcapng_dsb_secrets_type, tvb, offset, 4, argp->info->encoding);
1787 offset += 4;
1788 proto_tree_add_item_ret_uint(tree, hf_pcapng_dsb_secrets_length, tvb, offset, 4, argp->info->encoding, &secrets_length);
1789 offset += 4;
1790 proto_tree_add_item(tree, hf_pcapng_dsb_secrets_data, tvb, offset, secrets_length, argp->info->encoding);
1791 offset += secrets_length;
1793 uint32_t padlen = (4 - (secrets_length & 3)) & 3;
1794 if (padlen) {
1795 proto_tree_add_item(tree, hf_pcapng_record_padding, tvb, offset, padlen, ENC_NA);
1796 offset += padlen;
1799 dissect_options(tree, pinfo, BLOCK_TYPE_DSB, tvb, offset, argp->info->encoding, NULL);
1802 static void
1803 dissect_cb_data(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb,
1804 block_data_arg *argp)
1806 int offset = 0;
1808 proto_tree_add_item(tree, hf_pcapng_cb_pen, tvb, offset, 4, argp->info->encoding);
1809 offset += 4;
1811 /* Todo: Add known PEN custom data dissection. */
1812 proto_tree_add_item(tree, hf_pcapng_cb_data, tvb, offset, tvb_reported_length(tvb) - offset, argp->info->encoding);
1815 * The pcapng spec does not tell the size of the custom data without knowing the data content,
1816 * so it's not possible to dissect options.
1818 * dissect_options(tree, pinfo, BLOCK_CB_COPY, tvb, offset, argp->info->encoding, NULL);
1822 #define BLOCK_BAD_SHB_SIZE 12
1824 int dissect_block(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, struct info *info)
1826 proto_tree *block_tree, *block_type_tree;
1827 proto_item *block_item, *block_type_item;
1828 proto_tree *block_data_tree;
1829 proto_item *block_length_item;
1830 proto_item *block_length_trailer_item;
1831 int offset = 0;
1832 uint32_t block_type;
1833 uint32_t block_length, block_length_trailer;
1834 uint32_t length;
1835 tvbuff_t *volatile next_tvb = NULL;
1836 block_data_arg arg;
1837 volatile bool stop_dissecting = false;
1838 volatile bool byte_order_magic_bad = false;
1840 block_type = tvb_get_uint32(tvb, offset + 0, info->encoding);
1841 length = tvb_get_uint32(tvb, offset + 4, info->encoding);
1843 /* Lookup handlers for known local block type */
1844 local_block_callback_info_t *volatile p_local_block_callback = NULL;
1845 if (block_type >= 0x80000000) {
1846 p_local_block_callback = (local_block_callback_info_t*)g_hash_table_lookup(s_local_block_callback_table, GUINT_TO_POINTER(block_type));
1849 /* Create block tree */
1850 block_item = proto_tree_add_item(tree, hf_pcapng_block, tvb, offset, length, ENC_NA);
1851 block_tree = proto_item_add_subtree(block_item, ett_pcapng_section_header_block);
1853 /* Block type */
1854 block_type_item = proto_tree_add_item(block_tree, hf_pcapng_block_type, tvb, offset, 4, info->encoding);
1855 block_type_tree = proto_item_add_subtree(block_type_item, ett_pcapng_block_type);
1857 proto_tree_add_item(block_type_tree, hf_pcapng_block_type_vendor, tvb, offset, 4, info->encoding);
1858 proto_item *block_type_value_item = proto_tree_add_item(block_type_tree, hf_pcapng_block_type_value, tvb, offset, 4, info->encoding);
1859 offset += 4;
1861 /* Name is either from local 'name', or from fixed block_type_vals */
1862 if (p_local_block_callback) {
1863 proto_item_append_text(block_item, " %u: %s", info->block_number, p_local_block_callback->name);
1864 proto_item_append_text(block_type_item, ": (%s)", p_local_block_callback->name);
1865 proto_item_append_text(block_type_value_item, ": (%s)", p_local_block_callback->name);
1867 else {
1868 proto_item_append_text(block_item, " %u: %s", info->block_number, val_to_str_const(block_type, block_type_vals, "Unknown"));
1869 proto_item_append_text(block_type_item, ": (%s)", val_to_str_const(block_type, block_type_vals, "Unknown"));
1870 proto_item_append_text(block_type_value_item, ": (%s)", val_to_str_const(block_type, block_type_vals, "Unknown"));
1872 info->block_number += 1;
1874 arg.block_item = block_item;
1875 arg.block_tree = block_tree;
1876 arg.info = info;
1878 if (block_type == BLOCK_TYPE_SHB && tvb_captured_length(tvb) == BLOCK_BAD_SHB_SIZE) {
1880 * dissect_pcapng() gave us a short SHB because its byte-order magic is bad.
1881 * process_block_length() would fail, so generate an abbreviated TVB
1882 * to pass to dissect_shb_data() which will flag up the bad magic.
1884 byte_order_magic_bad = true;
1885 next_tvb = tvb_new_subset_length(tvb, 8, 4);
1886 block_data_tree = block_tree;
1887 block_length_item = NULL;
1889 else {
1890 next_tvb = process_block_length(block_tree, pinfo, tvb, offset, &block_data_tree, &block_length_item, &block_length, info->encoding);
1891 if (next_tvb == NULL) {
1892 /* The length was invalid, so we can't dissect any further */
1893 return -1;
1896 offset += 4;
1899 * Dissect the block data.
1900 * Catch exceptions; ReportedBoundsError means that the body
1901 * doesn't fit in the block.
1903 TRY {
1904 switch (block_type) {
1905 case BLOCK_TYPE_SHB:
1906 proto_item_append_text(block_item, " %u", info->section_number);
1907 if (!dissect_shb_data(block_data_tree, pinfo, next_tvb, byte_order_magic_bad, &arg)) {
1908 stop_dissecting = true;
1910 break;
1911 case BLOCK_TYPE_IDB:
1912 dissect_idb_data(block_data_tree, pinfo, next_tvb, &arg);
1913 break;
1914 case BLOCK_TYPE_PB:
1915 dissect_pb_data(block_data_tree, pinfo, next_tvb, &arg);
1916 break;
1917 case BLOCK_TYPE_SPB:
1918 dissect_spb_data(block_data_tree, pinfo, next_tvb, &arg);
1919 break;
1920 case BLOCK_TYPE_NRB:
1921 dissect_nrb_data(block_data_tree, pinfo, next_tvb, &arg);
1922 break;
1923 case BLOCK_TYPE_ISB:
1924 dissect_isb_data(block_data_tree, pinfo, next_tvb, &arg);
1925 break;
1926 case BLOCK_TYPE_EPB:
1927 dissect_epb_data(block_data_tree, pinfo, next_tvb, &arg);
1928 break;
1929 case BLOCK_TYPE_DSB:
1930 dissect_dsb_data(block_data_tree, pinfo, next_tvb, &arg);
1931 break;
1932 case BLOCK_TYPE_CB_COPY:
1933 case BLOCK_TYPE_CB_NO_COPY:
1934 dissect_cb_data(block_data_tree, pinfo, next_tvb, &arg);
1935 break;
1936 case BLOCK_TYPE_IRIG_TS:
1937 case BLOCK_TYPE_ARINC_429:
1938 break;
1940 default:
1941 /* Use local block type handling if available */
1942 if (p_local_block_callback) {
1943 p_local_block_callback->dissector(block_data_tree, pinfo, next_tvb, &arg);
1945 break;
1948 CATCH(ReportedBoundsError) {
1950 * The body didn't fit in the block.
1951 * Mark the length as being too small.
1953 expert_add_info(pinfo, block_length_item, &ei_block_length_below_block_content_length);
1955 CATCH_ALL {
1957 * Just rethrow other exceptions to the ultimate handler.
1959 RETHROW;
1961 ENDTRY;
1963 if (stop_dissecting) {
1964 /* We found a fatal problem with the file. */
1965 return -1;
1969 * Skip past the block data.
1971 offset += tvb_reported_length(next_tvb);
1973 block_length_trailer_item = proto_tree_add_item_ret_uint(block_tree, hf_pcapng_block_length_trailer, tvb, offset, 4, info->encoding, &block_length_trailer);
1974 if (block_length != block_length_trailer)
1975 expert_add_info(pinfo, block_length_trailer_item, &ei_block_lengths_dont_match);
1976 offset += 4;
1978 return offset;
1981 #define BLOCK_TYPE_SIZE 4
1983 static int
1984 dissect_pcapng(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1986 static const uint8_t pcapng_premagic[BLOCK_TYPE_SIZE] = {
1987 0x0A, 0x0D, 0x0D, 0x0A
1989 int offset = 0;
1990 uint32_t length;
1991 uint32_t block_type;
1992 proto_tree *main_tree;
1993 proto_item *main_item;
1994 struct info info;
1995 volatile bool byte_order_magic_bad = false;
1997 if (tvb_memeql(tvb, 0, pcapng_premagic, BLOCK_TYPE_SIZE) != 0)
1998 return 0;
2000 info.encoding = ENC_BIG_ENDIAN;
2001 info.block_number = 1;
2002 info.section_number = 0;
2003 info.interface_number = 0;
2004 info.darwin_process_event_number = 0;
2005 info.frame_number = 1;
2006 info.interfaces = NULL;
2007 info.darwin_process_events = wmem_array_new(pinfo->pool, sizeof(struct darwin_process_event_description));
2009 main_item = proto_tree_add_item(tree, proto_pcapng, tvb, offset, -1, ENC_NA);
2010 main_tree = proto_item_add_subtree(main_item, ett_pcapng);
2012 while (tvb_captured_length_remaining(tvb, offset) > 8) {
2013 tvbuff_t *next_tvb;
2014 int block_length;
2016 block_type = tvb_get_uint32(tvb, offset, info.encoding);
2017 if (block_type == BLOCK_TYPE_SHB) {
2018 info.section_number += 1;
2019 info.interface_number = 0;
2020 info.darwin_process_event_number = 0;
2021 info.frame_number = 1;
2022 if (info.interfaces != NULL) {
2023 wmem_free(pinfo->pool, info.interfaces);
2025 info.interfaces = wmem_array_new(pinfo->pool, sizeof(struct interface_description));
2027 /* Byte order may change from that of previous SHB [#19371] */
2028 if (tvb_memeql(tvb, offset + 8, pcapng_big_endian_magic, BYTE_ORDER_MAGIC_SIZE) == 0) {
2029 info.encoding = ENC_BIG_ENDIAN;
2030 } else if (tvb_memeql(tvb, offset + 8, pcapng_little_endian_magic, BYTE_ORDER_MAGIC_SIZE) == 0) {
2031 info.encoding = ENC_LITTLE_ENDIAN;
2032 } else {
2033 byte_order_magic_bad = true;
2034 if (offset == 0) {
2035 return 0;
2040 if (G_UNLIKELY(byte_order_magic_bad)) {
2041 /* Pass a shortened TVB that's just big enough to let
2042 * dissect_block() mark the SHB's byte order magic as bad.
2044 length = BLOCK_BAD_SHB_SIZE;
2046 else {
2047 length = tvb_get_uint32(tvb, offset + 4, info.encoding);
2049 next_tvb = tvb_new_subset_length(tvb, offset, length);
2051 block_length = dissect_block(main_tree, pinfo, next_tvb, &info);
2052 if (block_length == -1) {
2053 /* Fatal error. */
2054 break;
2056 offset += block_length;
2059 return offset;
2062 static void pcapng_shutdown_protocol(void)
2064 /* Create table for local block dissectors */
2065 g_hash_table_destroy(s_local_block_callback_table);
2066 s_local_block_callback_table = NULL;
2069 static bool
2070 dissect_pcapng_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2072 return dissect_pcapng(tvb, pinfo, tree, data) > 0;
2075 /* Expected to be called by an external dissector. For an in-tree example, please see file-pcap-darwin.c */
2076 void register_pcapng_local_block_dissector(uint32_t block_number, local_block_callback_info_t *block_callback_info)
2078 /* Add this entry into table. */
2079 g_hash_table_insert(s_local_block_callback_table, GUINT_TO_POINTER(block_number), block_callback_info);
2082 void
2083 proto_register_pcapng(void)
2085 module_t *module;
2086 expert_module_t *expert_module;
2088 static hf_register_info hf[] = {
2089 { &hf_pcapng_block,
2090 { "Block", "pcapng.block",
2091 FT_NONE, BASE_NONE, NULL, 0x00,
2092 NULL, HFILL }
2094 { &hf_pcapng_block_type,
2095 { "Block Type", "pcapng.block.type",
2096 FT_UINT32, BASE_HEX, NULL, 0x00,
2097 NULL, HFILL }
2099 { &hf_pcapng_block_type_vendor,
2100 { "Block Type Vendor", "pcapng.block.type.vendor",
2101 FT_BOOLEAN, 32, NULL, 0x80000000,
2102 NULL, HFILL }
2104 { &hf_pcapng_block_type_value,
2105 { "Block Type Value", "pcapng.block.type.value",
2106 FT_UINT32, BASE_HEX, NULL, 0x7FFFFFFF,
2107 NULL, HFILL }
2109 { &hf_pcapng_block_length,
2110 { "Block Length", "pcapng.block.length",
2111 FT_UINT32, BASE_DEC, NULL, 0x00,
2112 NULL, HFILL }
2114 { &hf_pcapng_block_length_trailer,
2115 { "Block Length (trailer)", "pcapng.block.length_trailer",
2116 FT_UINT32, BASE_DEC, NULL, 0x00,
2117 NULL, HFILL }
2119 { &hf_pcapng_block_data,
2120 { "Block Data", "pcapng.block.data",
2121 FT_NONE, BASE_NONE, NULL, 0x00,
2122 NULL, HFILL }
2124 { &hf_pcapng_options,
2125 { "Options", "pcapng.options",
2126 FT_NONE, BASE_NONE, NULL, 0x00,
2127 NULL, HFILL }
2129 { &hf_pcapng_option,
2130 { "Option", "pcapng.options.option",
2131 FT_NONE, BASE_NONE, NULL, 0x00,
2132 NULL, HFILL }
2134 { &hf_pcapng_option_code_interface_description,
2135 { "Code", "pcapng.options.option.code",
2136 FT_UINT16, BASE_DEC, VALS(option_code_interface_description_vals), 0x00,
2137 NULL, HFILL }
2139 { &hf_pcapng_option_code_enhanced_packet,
2140 { "Code", "pcapng.options.option.code",
2141 FT_UINT16, BASE_DEC, VALS(option_code_enhanced_packet_vals), 0x00,
2142 NULL, HFILL }
2144 { &hf_pcapng_option_code_packet,
2145 { "Code", "pcapng.options.option.code",
2146 FT_UINT16, BASE_DEC, VALS(option_code_packet_vals), 0x00,
2147 NULL, HFILL }
2149 { &hf_pcapng_option_code_name_resolution,
2150 { "Code", "pcapng.options.option.code",
2151 FT_UINT16, BASE_DEC, VALS(option_code_name_resolution_vals), 0x00,
2152 NULL, HFILL }
2154 { &hf_pcapng_option_code_interface_statistics,
2155 { "Code", "pcapng.options.option.code",
2156 FT_UINT16, BASE_DEC, VALS(option_code_interface_statistics_vals), 0x00,
2157 NULL, HFILL }
2159 { &hf_pcapng_option_code,
2160 { "Code", "pcapng.options.option.code",
2161 FT_UINT16, BASE_DEC, NULL, 0x00,
2162 NULL, HFILL }
2164 { &hf_pcapng_option_length,
2165 { "Length", "pcapng.options.option.length",
2166 FT_UINT16, BASE_DEC, NULL, 0x00,
2167 NULL, HFILL }
2169 { &hf_pcapng_option_data,
2170 { "Option Data", "pcapng.options.option.data",
2171 FT_NONE, BASE_NONE, NULL, 0x00,
2172 NULL, HFILL }
2174 { &hf_pcapng_option_padding,
2175 { "Option Padding", "pcapng.options.option.padding",
2176 FT_NONE, BASE_NONE, NULL, 0x00,
2177 NULL, HFILL }
2179 { &hf_pcapng_option_data_comment,
2180 { "Comment", "pcapng.options.option.data.comment",
2181 FT_STRING, BASE_NONE, NULL, 0x00,
2182 NULL, HFILL }
2184 { &hf_pcapng_section_header_byte_order_magic,
2185 { "Byte Order Magic", "pcapng.section_header.byte_order_magic",
2186 FT_BYTES, BASE_NONE, NULL, 0x00,
2187 NULL, HFILL }
2189 { &hf_pcapng_section_header_major_version,
2190 { "Major Version", "pcapng.section_header.version.major",
2191 FT_UINT16, BASE_DEC, NULL, 0x00,
2192 NULL, HFILL }
2194 { &hf_pcapng_section_header_minor_version,
2195 { "Minor Version", "pcapng.section_header.version.minor",
2196 FT_UINT16, BASE_DEC, NULL, 0x00,
2197 NULL, HFILL }
2199 { &hf_pcapng_section_header_section_length,
2200 { "Section Length", "pcapng.section_header.section_length",
2201 FT_INT64, BASE_DEC, NULL, 0x00,
2202 NULL, HFILL }
2204 { &hf_pcapng_option_code_section_header,
2205 { "Code", "pcapng.options.option.code",
2206 FT_UINT16, BASE_DEC, VALS(option_code_section_header_vals), 0x00,
2207 NULL, HFILL }
2209 { &hf_pcapng_option_data_section_header_hardware,
2210 { "Hardware", "pcapng.options.option.data.hardware",
2211 FT_STRING, BASE_NONE, NULL, 0x00,
2212 NULL, HFILL }
2214 { &hf_pcapng_option_data_section_header_os,
2215 { "OS", "pcapng.options.option.data.os",
2216 FT_STRING, BASE_NONE, NULL, 0x00,
2217 NULL, HFILL }
2219 { &hf_pcapng_option_data_section_header_user_application,
2220 { "User Application", "pcapng.options.option.data.user_application",
2221 FT_STRING, BASE_NONE, NULL, 0x00,
2222 NULL, HFILL }
2224 { &hf_pcapng_option_data_interface_description_name,
2225 { "Name", "pcapng.options.option.data.interface.name",
2226 FT_STRING, BASE_NONE, NULL, 0x00,
2227 NULL, HFILL }
2229 { &hf_pcapng_option_data_interface_description_description,
2230 { "Description", "pcapng.options.option.data.interface.description",
2231 FT_STRING, BASE_NONE, NULL, 0x00,
2232 NULL, HFILL }
2234 { &hf_pcapng_option_data_ipv4,
2235 { "IPv4", "pcapng.options.option.data.ipv4",
2236 FT_IPv4, BASE_NONE, NULL, 0x00,
2237 NULL, HFILL }
2239 { &hf_pcapng_option_data_ipv4_mask,
2240 { "IPv4 Mask", "pcapng.options.option.data.ipv4_mask",
2241 FT_IPv4, BASE_NONE, NULL, 0x00,
2242 NULL, HFILL }
2244 { &hf_pcapng_option_data_ipv6,
2245 { "IPv6", "pcapng.options.option.data.ipv6",
2246 FT_IPv6, BASE_NONE, NULL, 0x00,
2247 NULL, HFILL }
2249 { &hf_pcapng_option_data_ipv6_mask,
2250 { "IPv6 Mask", "pcapng.options.option.data.ipv6_mask",
2251 FT_UINT8, BASE_DEC, NULL, 0x00,
2252 NULL, HFILL }
2254 { &hf_pcapng_option_data_mac_address,
2255 { "MAC Address", "pcapng.options.option.data.mac",
2256 FT_ETHER, BASE_NONE, NULL, 0x00,
2257 NULL, HFILL }
2259 { &hf_pcapng_option_data_eui_address,
2260 { "EUI Address", "pcapng.options.option.data.eui",
2261 FT_EUI64, BASE_NONE, NULL, 0x00,
2262 NULL, HFILL }
2264 { &hf_pcapng_option_data_interface_speed,
2265 { "Speed", "pcapng.options.option.data.interface.speed",
2266 FT_UINT64, BASE_DEC, NULL, 0x00,
2267 NULL, HFILL }
2269 { &hf_pcapng_option_data_interface_timestamp_resolution,
2270 { "Timestamp Resolution", "pcapng.options.option.data.interface.timestamp_resolution",
2271 FT_UINT8, BASE_HEX, NULL, 0x00,
2272 NULL, HFILL }
2274 { &hf_pcapng_option_data_interface_timestamp_resolution_base,
2275 { "Base", "pcapng.options.option.data.interface.timestamp_resolution.base",
2276 FT_UINT8, BASE_HEX, VALS(timestamp_resolution_base_vals), 0x80,
2277 NULL, HFILL }
2279 { &hf_pcapng_option_data_interface_timestamp_resolution_value,
2280 { "Value", "pcapng.options.option.data.interface.timestamp_resolution.value",
2281 FT_UINT8, BASE_DEC, NULL, 0x7F,
2282 NULL, HFILL }
2284 { &hf_pcapng_option_data_interface_timezone,
2285 { "Timezone", "pcapng.options.option.data.interface.timezone",
2286 FT_UINT32, BASE_DEC, NULL, 0x00,
2287 NULL, HFILL }
2289 { &hf_pcapng_option_data_interface_filter_type,
2290 { "Filter type", "pcapng.options.option.data.interface.filter.type",
2291 FT_UINT8, BASE_DEC, VALS(interface_filter_type_vals), 0x00,
2292 NULL, HFILL }
2294 { &hf_pcapng_option_data_interface_filter_string,
2295 { "Filter string", "pcapng.options.option.data.interface.filter.string",
2296 FT_STRING, BASE_NONE, NULL, 0x00,
2297 NULL, HFILL }
2299 { &hf_pcapng_option_data_interface_filter_bpf_program,
2300 { "Filter BPF program", "pcapng.options.option.data.interface.filter.bpf_program",
2301 FT_NONE, BASE_NONE, NULL, 0x00,
2302 NULL, HFILL }
2304 { &hf_pcapng_option_data_interface_filter_unknown,
2305 { "Filter data", "pcapng.options.option.data.interface.filter.unknown",
2306 FT_NONE, BASE_NONE, NULL, 0x00,
2307 NULL, HFILL }
2309 { &hf_pcapng_option_data_interface_os,
2310 { "OS", "pcapng.options.option.data.interface.os",
2311 FT_STRING, BASE_NONE, NULL, 0x00,
2312 NULL, HFILL }
2314 { &hf_pcapng_option_data_interface_hardware,
2315 { "Hardware", "pcapng.options.option.data.interface.hardware",
2316 FT_STRING, BASE_NONE, NULL, 0x00,
2317 NULL, HFILL }
2319 { &hf_pcapng_option_data_interface_fcs_length,
2320 { "FCS Length", "pcapng.options.option.data.interface.fcs_length",
2321 FT_UINT8, BASE_DEC, NULL, 0x00,
2322 NULL, HFILL }
2324 { &hf_pcapng_option_data_interface_timestamp_offset,
2325 { "Timestamp Offset", "pcapng.options.option.data.interface.timestamp_offset",
2326 FT_UINT64, BASE_DEC, NULL, 0x00,
2327 NULL, HFILL }
2329 { &hf_pcapng_option_data_packet_verdict_type,
2330 { "Verdict type", "pcapng.options.option.data.packet.verdict.type",
2331 FT_UINT8, BASE_DEC, VALS(packet_verdict_type_vals), 0x00,
2332 NULL, HFILL }
2334 { &hf_pcapng_option_data_packet_verdict_data,
2335 { "Verdict data", "pcapng.options.option.data.packet.verdict.data",
2336 FT_BYTES, BASE_NONE, NULL, 0x00,
2337 NULL, HFILL }
2339 { &hf_pcapng_option_data_packet_queue,
2340 { "Queue", "pcapng.options.option.data.packet.queue",
2341 FT_UINT32, BASE_DEC, NULL, 0x00,
2342 NULL, HFILL }
2344 { &hf_pcapng_option_data_packet_id,
2345 { "Packet ID", "pcapng.options.option.data.packet.id",
2346 FT_UINT64, BASE_HEX, NULL, 0x00,
2347 NULL, HFILL }
2349 { &hf_pcapng_option_data_packet_drop_count,
2350 { "Drop Count", "pcapng.options.option.data.packet.drop_count",
2351 FT_UINT64, BASE_DEC, NULL, 0x00,
2352 NULL, HFILL }
2354 { &hf_pcapng_option_data_packet_hash_algorithm,
2355 { "Hash Algorithm", "pcapng.options.option.data.packet.hash.algorithm",
2356 FT_UINT8, BASE_DEC, VALS(packet_hash_algorithm_vals), 0x00,
2357 NULL, HFILL }
2359 { &hf_pcapng_option_data_packet_hash_data,
2360 { "Hash Data", "pcapng.options.option.data.packet.hash.data",
2361 FT_BYTES, BASE_NONE, NULL, 0x00,
2362 NULL, HFILL }
2364 { &hf_pcapng_option_data_packet_flags_link_layer_errors,
2365 { "Link Layer Errors", "pcapng.options.option.data.packet.flags.link_layer_errors",
2366 FT_UINT16, BASE_HEX, NULL, 0x00,
2367 NULL, HFILL }
2369 { &hf_pcapng_option_data_packet_flags_link_layer_errors_symbol,
2370 { "Symbol Error", "pcapng.options.option.data.packet.flags.link_layer_errors.symbol",
2371 FT_BOOLEAN, 16, NULL, 0x8000,
2372 NULL, HFILL }
2374 { &hf_pcapng_option_data_packet_flags_link_layer_errors_preamble,
2375 { "Preamble Error", "pcapng.options.option.data.packet.flags.link_layer_errors.preamble",
2376 FT_BOOLEAN, 16, NULL, 0x4000,
2377 NULL, HFILL }
2379 { &hf_pcapng_option_data_packet_flags_link_layer_errors_start_frame_delimiter,
2380 { "Start Frame Delimiter Error", "pcapng.options.option.data.packet.flags.link_layer_errors.start_frame_delimiter",
2381 FT_BOOLEAN, 16, NULL, 0x2000,
2382 NULL, HFILL }
2384 { &hf_pcapng_option_data_packet_flags_link_layer_errors_unaligned_frame,
2385 { "Unaligned Frame Error", "pcapng.options.option.data.packet.flags.link_layer_errors.unaligned_frame",
2386 FT_BOOLEAN, 16, NULL, 0x1000,
2387 NULL, HFILL }
2389 { &hf_pcapng_option_data_packet_flags_link_layer_errors_wrong_inter_frame_gap,
2390 { "Wrong Inter Frame Gap", "pcapng.options.option.data.packet.flags.link_layer_errors.wrong_inter_frame_gap",
2391 FT_BOOLEAN, 16, NULL, 0x0800,
2392 NULL, HFILL }
2394 { &hf_pcapng_option_data_packet_flags_link_layer_errors_packet_too_short,
2395 { "Packet Too Short", "pcapng.options.option.data.packet.flags.link_layer_errors.packet_too_short",
2396 FT_BOOLEAN, 16, NULL, 0x0400,
2397 NULL, HFILL }
2399 { &hf_pcapng_option_data_packet_flags_link_layer_errors_packet_too_long,
2400 { "Packet Too Long", "pcapng.options.option.data.packet.flags.link_layer_errors.packet_too_long",
2401 FT_BOOLEAN, 16, NULL, 0x0200,
2402 NULL, HFILL }
2404 { &hf_pcapng_option_data_packet_flags_link_layer_errors_crc_error,
2405 { "CRC Error", "pcapng.options.option.data.packet.flags.link_layer_errors.crc",
2406 FT_BOOLEAN, 16, NULL, 0x0100,
2407 NULL, HFILL }
2409 { &hf_pcapng_option_data_packet_flags_link_layer_errors_reserved,
2410 { "Reserved", "pcapng.options.option.data.packet.flags.link_layer_errors.reserved",
2411 FT_UINT16, BASE_HEX, NULL, 0x00FF,
2412 NULL, HFILL }
2414 { &hf_pcapng_option_data_packet_flags,
2415 { "Flags", "pcapng.options.option.data.packet.flags",
2416 FT_UINT16, BASE_HEX, NULL, 0x00,
2417 NULL, HFILL }
2419 { &hf_pcapng_option_data_packet_flags_reserved,
2420 { "Reserved", "pcapng.options.option.data.packet.flags.reserved",
2421 FT_UINT16, BASE_HEX, NULL, 0xFE00,
2422 NULL, HFILL }
2424 { &hf_pcapng_option_data_packet_flags_fcs_length,
2425 { "FCS Length", "pcapng.options.option.data.packet.flags.fcs_length",
2426 FT_UINT16, BASE_DEC, NULL, 0x01E0,
2427 NULL, HFILL }
2429 { &hf_pcapng_option_data_packet_flags_reception_type,
2430 { "Reception Type", "pcapng.options.option.data.packet.flags.reception_type",
2431 FT_UINT16, BASE_HEX, VALS(flags_reception_type_vals), 0x001C,
2432 NULL, HFILL }
2434 { &hf_pcapng_option_data_packet_flags_direction,
2435 { "Direction", "pcapng.options.option.data.packet.flags.direction",
2436 FT_UINT16, BASE_HEX, VALS(packet_flags_direction_vals), 0x0003,
2437 NULL, HFILL }
2439 { &hf_pcapng_option_data_packet_darwin_dpeb_id,
2440 { "DPEB ID", "pcapng.options.option.data.packet.darwin.dpeb_id",
2441 FT_UINT32, BASE_DEC, NULL, 0x00,
2442 NULL, HFILL }
2444 { &hf_pcapng_option_data_packet_darwin_svc_class,
2445 { "Darwin svc", "pcapng.options.option.data.packet.darwin.svc_class",
2446 FT_UINT32, BASE_DEC, VALS(option_code_darwin_svc_class_vals), 0x00,
2447 NULL, HFILL }
2449 { &hf_pcapng_option_data_packet_darwin_edpeb_id,
2450 { "Effective DPED ID", "pcapng.options.option.data.packet.darwin.edpeb_id",
2451 FT_UINT32, BASE_DEC, NULL, 0x00,
2452 NULL, HFILL }
2454 { &hf_pcapng_option_data_packet_darwin_flags,
2455 { "Darwin Flags", "pcapng.options.option.data.packet.darwin.flags",
2456 FT_UINT32, BASE_HEX, NULL, 0x00,
2457 NULL, HFILL }
2459 { &hf_pcapng_option_data_packet_darwin_flags_reserved,
2460 { "Reserved", "pcapng.options.option.data.packet.darwin.flags.reserved",
2461 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0xFFFFFFC0,
2462 NULL, HFILL }
2464 { &hf_pcapng_option_data_packet_darwin_flags_wk,
2465 { "Wake Packet(wk)", "pcapng.options.option.data.packet.darwin.flags.wk",
2466 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000020,
2467 NULL, HFILL }
2469 { &hf_pcapng_option_data_packet_darwin_flags_ch,
2470 { "Nexus Channel(ch)", "pcapng.options.option.data.packet.darwin.flags.ch",
2471 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000010,
2472 NULL, HFILL }
2474 { &hf_pcapng_option_data_packet_darwin_flags_so,
2475 { "Socket(so)", "pcapng.options.option.data.packet.darwin.flags.so",
2476 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000008,
2477 NULL, HFILL }
2479 { &hf_pcapng_option_data_packet_darwin_flags_re,
2480 { "ReXmit(re)", "pcapng.options.option.data.packet.darwin.flags.re",
2481 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000004,
2482 NULL, HFILL }
2484 { &hf_pcapng_option_data_packet_darwin_flags_ka,
2485 { "Keep Alive(ka)", "pcapng.options.option.data.packet.darwin.flags.ka",
2486 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000002,
2487 NULL, HFILL }
2489 { &hf_pcapng_option_data_packet_darwin_flags_nf,
2490 { "New Flow(nf)", "pcapng.options.option.data.packet.darwin.flags.nf",
2491 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000001,
2492 NULL, HFILL }
2494 { &hf_pcapng_option_data_packet_darwin_flow_id,
2495 { "Flow ID", "pcapng.options.option.data.packet.darwin.flow_id",
2496 FT_UINT32, BASE_DEC, NULL, 0x00,
2497 NULL, HFILL }
2499 { &hf_pcapng_option_data_dns_name,
2500 { "DNS Name", "pcapng.options.option.data.dns_name",
2501 FT_STRING, BASE_NONE, NULL, 0x00,
2502 NULL, HFILL }
2504 { &hf_pcapng_option_data_start_time,
2505 { "Start Time", "pcapng.options.option.data.start_time",
2506 FT_NONE, BASE_NONE, NULL, 0x00,
2507 NULL, HFILL }
2509 { &hf_pcapng_option_data_end_time,
2510 { "End Time", "pcapng.options.option.data.end_time",
2511 FT_NONE, BASE_NONE, NULL, 0x00,
2512 NULL, HFILL }
2514 { &hf_pcapng_option_data_interface_received,
2515 { "Number of Received Packets", "pcapng.options.option.data.interface.received",
2516 FT_UINT64, BASE_DEC, NULL, 0x00,
2517 NULL, HFILL }
2519 { &hf_pcapng_option_data_interface_dropped,
2520 { "Number of Dropped Packets", "pcapng.options.option.data.interface.dropped",
2521 FT_UINT64, BASE_DEC, NULL, 0x00,
2522 NULL, HFILL }
2524 { &hf_pcapng_option_data_interface_accepted_by_filter,
2525 { "Number of Accepted by Filter Packets", "pcapng.options.option.data.interface.accepted_by_filter",
2526 FT_UINT64, BASE_DEC, NULL, 0x00,
2527 NULL, HFILL }
2529 { &hf_pcapng_option_data_interface_dropped_by_os,
2530 { "Number of Dropped Packets by OS", "pcapng.options.option.data.interface.dropped_by_os",
2531 FT_UINT64, BASE_DEC, NULL, 0x00,
2532 NULL, HFILL }
2534 { &hf_pcapng_option_data_interface_delivered_to_user,
2535 { "Number of Delivered to the User Packets", "pcapng.options.option.data.interface.delivered_to_user",
2536 FT_UINT64, BASE_DEC, NULL, 0x00,
2537 NULL, HFILL }
2539 { &hf_pcapng_interface_description_link_type,
2540 { "Link Type", "pcapng.interface_description.link_type",
2541 FT_UINT16, BASE_DEC_HEX, VALS(link_type_vals), 0x00,
2542 NULL, HFILL }
2544 { &hf_pcapng_interface_description_reserved,
2545 { "Reserved", "pcapng.interface_description.reserved",
2546 FT_UINT16, BASE_HEX, NULL, 0x00,
2547 NULL, HFILL }
2549 { &hf_pcapng_interface_description_snap_length,
2550 { "Snap Length", "pcapng.interface_description.snap_length",
2551 FT_UINT32, BASE_DEC, NULL, 0x00,
2552 NULL, HFILL }
2554 { &hf_pcapng_packet_block_interface_id,
2555 { "Interface", "pcapng.packet.interface_id",
2556 FT_UINT16, BASE_DEC, NULL, 0x00,
2557 NULL, HFILL }
2559 { &hf_pcapng_packet_block_drops_count,
2560 { "Drops Count", "pcapng.packet.drops_count",
2561 FT_UINT16, BASE_DEC, NULL, 0x00,
2562 NULL, HFILL }
2564 { &hf_pcapng_captured_length,
2565 { "Captured Packet Length", "pcapng.packet.captured_length",
2566 FT_UINT32, BASE_DEC, NULL, 0x00,
2567 NULL, HFILL }
2569 { &hf_pcapng_original_length,
2570 { "Original Packet Length", "pcapng.packet.original_length",
2571 FT_UINT32, BASE_DEC, NULL, 0x00,
2572 NULL, HFILL }
2574 { &hf_pcapng_packet_data,
2575 { "Packet Data", "pcapng.packet.packet_data",
2576 FT_NONE, BASE_NONE, NULL, 0x00,
2577 NULL, HFILL }
2579 { &hf_pcapng_packet_padding,
2580 { "Packet Padding", "pcapng.packet.padding",
2581 FT_NONE, BASE_NONE, NULL, 0x00,
2582 NULL, HFILL }
2584 { &hf_pcapng_interface_id,
2585 { "Interface", "pcapng.interface_id",
2586 FT_UINT32, BASE_DEC, NULL, 0x00,
2587 NULL, HFILL }
2589 { &hf_pcapng_timestamp_high,
2590 { "Timestamp (High)", "pcapng.timestamp_high",
2591 FT_UINT32, BASE_DEC, NULL, 0x00,
2592 NULL, HFILL }
2594 { &hf_pcapng_timestamp_low,
2595 { "Timestamp (Low)", "pcapng.timestamp_low",
2596 FT_UINT32, BASE_DEC, NULL, 0x00,
2597 NULL, HFILL }
2599 { &hf_pcapng_timestamp,
2600 { "Timestamp", "pcapng.timestamp",
2601 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
2602 NULL, HFILL }
2604 { &hf_pcapng_records,
2605 { "Records", "pcapng.records",
2606 FT_NONE, BASE_NONE, NULL, 0x00,
2607 NULL, HFILL }
2609 { &hf_pcapng_record,
2610 { "Record", "pcapng.records.record",
2611 FT_NONE, BASE_NONE, NULL, 0x00,
2612 NULL, HFILL }
2614 { &hf_pcapng_record_code,
2615 { "Code", "pcapng.records.record.code",
2616 FT_UINT16, BASE_DEC, VALS(record_code_vals), 0x00,
2617 NULL, HFILL }
2619 { &hf_pcapng_record_length,
2620 { "Length", "pcapng.records.record.length",
2621 FT_UINT16, BASE_DEC, NULL, 0x00,
2622 NULL, HFILL }
2624 { &hf_pcapng_record_data,
2625 { "Record Data", "pcapng.records.record.data",
2626 FT_NONE, BASE_NONE, NULL, 0x00,
2627 NULL, HFILL }
2629 { &hf_pcapng_record_padding,
2630 { "Record Padding", "pcapng.records.record.padding",
2631 FT_NONE, BASE_NONE, NULL, 0x00,
2632 NULL, HFILL }
2634 { &hf_pcapng_record_ipv4,
2635 { "IPv4", "pcapng.records.record.data.ipv4",
2636 FT_IPv4, BASE_NONE, NULL, 0x00,
2637 NULL, HFILL }
2639 { &hf_pcapng_record_ipv6,
2640 { "IPv6", "pcapng.records.record.data.ipv6",
2641 FT_IPv6, BASE_NONE, NULL, 0x00,
2642 NULL, HFILL }
2644 { &hf_pcapng_record_name,
2645 { "Name", "pcapng.records.record.data.name",
2646 FT_STRINGZ, BASE_NONE, NULL, 0x00,
2647 NULL, HFILL }
2649 { &hf_pcapng_dsb_secrets_type,
2650 { "Secrets Type", "pcapng.dsb.secrets_type",
2651 FT_UINT32, BASE_HEX, VALS(dsb_secrets_types_vals), 0x00,
2652 NULL, HFILL }
2654 { &hf_pcapng_dsb_secrets_length,
2655 { "Secrets Length", "pcapng.dsb.secrets_length",
2656 FT_UINT32, BASE_DEC, NULL, 0x00,
2657 NULL, HFILL }
2659 { &hf_pcapng_dsb_secrets_data,
2660 { "Secrets Data", "pcapng.dsb.secrets_data",
2661 FT_BYTES, BASE_NONE, NULL, 0x00,
2662 NULL, HFILL }
2664 { &hf_pcapng_cb_pen,
2665 { "Private Enterprise Number (PEN)", "pcapng.cb.pen",
2666 FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0x00,
2667 NULL, HFILL }
2669 { &hf_pcapng_cb_data,
2670 { "Custom Data", "pcapng.cb.custom_data",
2671 FT_BYTES, BASE_NONE, NULL, 0x00,
2672 NULL, HFILL }
2674 { &hf_pcapng_cb_option_string,
2675 { "Custom Option String", "pcapng.cb.custom_option.string",
2676 FT_STRING, BASE_NONE, NULL, 0x00,
2677 NULL, HFILL }
2679 { &hf_pcapng_cb_option_data,
2680 { "Custom Option Binary", "pcapng.cb.custom_option.data",
2681 FT_BYTES, BASE_NONE, NULL, 0x00,
2682 NULL, HFILL }
2686 static ei_register_info ei[] = {
2687 { &ei_invalid_byte_order_magic, { "pcapng.invalid_byte_order_magic", PI_PROTOCOL, PI_ERROR, "The byte-order magic number is not valid", EXPFILL }},
2688 { &ei_block_length_below_block_minimum, { "pcapng.block_length_below_block_minimum", PI_PROTOCOL, PI_ERROR, "Block length is < 12 bytes", EXPFILL }},
2689 { &ei_block_length_below_block_content_length, { "pcapng.block_length_below_block_content_length", PI_PROTOCOL, PI_ERROR, "Block length is < the length of the contents of the block", EXPFILL }},
2690 { &ei_block_length_not_multiple_of_4, { "pcapng.block_length_not_multiple_of4", PI_PROTOCOL, PI_ERROR, "Block length is not a multiple of 4", EXPFILL }},
2691 { &ei_block_lengths_dont_match, { "pcapng.block_lengths_dont_match", PI_PROTOCOL, PI_ERROR, "Block length in trailer differs from block length in header", EXPFILL }},
2692 { &ei_invalid_option_length, { "pcapng.invalid_option_length", PI_PROTOCOL, PI_ERROR, "Invalid Option Length", EXPFILL }},
2693 { &ei_invalid_record_length, { "pcapng.invalid_record_length", PI_PROTOCOL, PI_ERROR, "Invalid Record Length", EXPFILL }},
2694 { &ei_missing_idb, { "pcapng.no_interfaces", PI_PROTOCOL, PI_ERROR, "No Interface Description before block that requires it", EXPFILL }},
2697 static int *ett[] = {
2698 &ett_pcapng,
2699 &ett_pcapng_section_header_block,
2700 &ett_pcapng_block_data,
2701 &ett_pcapng_block_type,
2702 &ett_pcapng_options,
2703 &ett_pcapng_option,
2704 &ett_pcapng_records,
2705 &ett_pcapng_record,
2706 &ett_pcapng_packet_data
2709 proto_pcapng = proto_register_protocol("PCAPNG File Format", "File-PCAPNG", "file-pcapng");
2710 proto_register_field_array(proto_pcapng, hf, array_length(hf));
2711 proto_register_subtree_array(ett, array_length(ett));
2713 register_dissector("file-pcapng", dissect_pcapng, proto_pcapng);
2715 module = prefs_register_protocol(proto_pcapng, NULL);
2716 prefs_register_static_text_preference(module, "version",
2717 "PCAPNG version: 1.0",
2718 "Version of file-format supported by this dissector.");
2720 prefs_register_bool_preference(module, "dissect_next_layer",
2721 "Dissect next layer",
2722 "Dissect next layer",
2723 &pref_dissect_next_layer);
2725 expert_module = expert_register_protocol(proto_pcapng);
2726 expert_register_field_array(expert_module, ei, array_length(ei));
2728 /* Create table for local block dissectors */
2729 s_local_block_callback_table = g_hash_table_new(g_direct_hash, g_direct_equal);
2731 /* Ensure this table will be deleted */
2732 register_shutdown_routine(&pcapng_shutdown_protocol);
2735 void
2736 proto_reg_handoff_pcapng(void)
2738 heur_dissector_add("wtap_file", dissect_pcapng_heur, "PCAPNG File", "pcapng_wtap", proto_pcapng, HEURISTIC_ENABLE);
2739 pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_pcapng);
2743 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2745 * Local variables:
2746 * c-basic-offset: 4
2747 * tab-width: 8
2748 * indent-tabs-mode: nil
2749 * End:
2751 * vi: set shiftwidth=4 tabstop=8 expandtab:
2752 * :indentSize=4:tabSize=8:noTabs=true: