2 * Definitions for Bundle Protocol Version 7 dissection.
4 * RFC 9171: https://www.rfc-editor.org/rfc/rfc9171.html
6 * Copyright 2019-2021, Brian Sipos <brian.sipos@gmail.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: LGPL-2.1-or-later
17 #include <ws_symbol_export.h>
18 #include <epan/tvbuff.h>
19 #include <epan/proto.h>
20 #include <epan/expert.h>
26 /* This dissector defines two layers of protocol:
27 * - The BPv7 bundle format, its endpoint naming and its block types.
28 * - The BPv7 Administrative Record which is a bundle payload as indicated by
29 * a primary block flag.
31 * BPv7 endpoint identifier (EID) dissectors for the scheme-specific
32 * part (SSP) are registered with the dissector table "bpv7.eid".
33 * This table uses a `uint` key for the scheme number and uses bp_eid_t* as
34 * dissector user data to be populated by the SSP data.
35 * Specifically the bp_eid_t::uri should be populated by the text form
36 * of the EID (as an AT_STRINGZ value).
38 * BPv7 block-type-specific data (BTSD) dissectors are registered with the
39 * dissector table "bpv7.block_type" and Administrative Record dissectors
40 * with the table "bpv7.admin_record_type". Both use uint64_t* table keys.
41 * Both use bp_dissector_data_t* as dissector user data.
43 * There is a BTSD heuristic dissector table "bpv7.btsd" which uses
44 * bp_dissector_data_t* as dissector user data.
46 * Payload block (block type 1) dissection is additionally handled based on
47 * bundle flags and destination EID as:
48 * - If the bundle flags mark it as administrative, it is dissected as such.
49 * - If the destination is a well-known SSP, the dissector table
50 * "bpv7.payload.dtn_wkssp" is used with the scheme-specific part.
51 * - If the destination is "dtn" scheme, the dissector table
52 * "bpv7.payload.dtn_serv" is used with the service demux (text string).
53 * There is also Decode As behavior for dtn service demux.
54 * - If the destination is "ipn" scheme, the dissector table
55 * "bpv7.payload.ipn_serv" is used with the service number (uint value).
56 * There is also Decode As behavior for ipn service number.
57 * - Finally, fall through to BTSD heuristic dissection.
58 * All payload dissection uses bp_dissector_data_t* as dissector user data.
62 * RFC 9171 Section 4.2.1.
65 /// no CRC is present.
67 /// a standard X-25 CRC-16 is present.
69 /// a standard CRC32C (Castagnoli) CRC-32 is present.
73 /** Bundle processing control flags.
74 * RFC 9171 Section 4.2.3.
77 /// bundle deletion status reports are requested.
78 BP_BUNDLE_REQ_DELETION_REPORT
= 0x040000,
79 /// bundle delivery status reports are requested.
80 BP_BUNDLE_REQ_DELIVERY_REPORT
= 0x020000,
81 /// bundle forwarding status reports are requested.
82 BP_BUNDLE_REQ_FORWARDING_REPORT
= 0x010000,
83 /// bundle reception status reports are requested.
84 BP_BUNDLE_REQ_RECEPTION_REPORT
= 0x004000,
85 /// status time is requested in all status reports.
86 BP_BUNDLE_REQ_STATUS_TIME
= 0x000040,
87 /// user application acknowledgement is requested.
88 BP_BUNDLE_USER_APP_ACK
= 0x000020,
89 /// bundle must not be fragmented.
90 BP_BUNDLE_NO_FRAGMENT
= 0x000004,
91 /// payload is an administrative record.
92 BP_BUNDLE_PAYLOAD_ADMIN
= 0x000002,
93 /// bundle is a fragment.
94 BP_BUNDLE_IS_FRAGMENT
= 0x000001,
95 } BundleProcessingFlag
;
97 /** Block processing control flags.
98 * RFC 9171 Section 4.2.4.
101 /// block must be removed from bundle if it can't be processed.
102 BP_BLOCK_REMOVE_IF_NO_PROCESS
= 0x10,
103 /// bundle must be deleted if block can't be processed.
104 BP_BLOCK_DELETE_IF_NO_PROCESS
= 0x04,
105 /// transmission of a status report is requested if block can't be processed.
106 BP_BLOCK_STATUS_IF_NO_PROCESS
= 0x02,
107 /// block must be replicated in every fragment.
108 BP_BLOCK_REPLICATE_IN_FRAGMENT
= 0x01,
109 } BlockProcessingFlag
;
111 /** Standard block type codes.
112 * RFC 9171 Section 4.3.2 and Section 4.4.
115 BP_BLOCKTYPE_INVALID
= 0,
117 BP_BLOCKTYPE_PAYLOAD
= 1,
119 BP_BLOCKTYPE_PREV_NODE
= 6,
121 BP_BLOCKTYPE_BUNDLE_AGE
= 7,
123 BP_BLOCKTYPE_HOP_COUNT
= 10,
124 /// Block Integrity Block
125 BP_BLOCKTYPE_BIB
= 11,
126 /// Block Confidentiality Block
127 BP_BLOCKTYPE_BCB
= 12,
130 /** Administrative record type codes.
131 * RFC 9171 Section 6.1.
134 /// Bundle status report
135 BP_ADMINTYPE_BUNDLE_STATUS
= 1,
136 } AdminRecordTypeCode
;
138 /// DTN time with derived UTC time
146 /// Creation Timestamp used to correlate bundles
149 bp_dtn_time_t abstime
;
154 /** Function to match the GCompareDataFunc signature.
157 int bp_creation_ts_compare(const void *a
, const void *b
, void *user_data
);
159 /** Endpoint ID scheme encodings.
166 /// Metadata from a Endpoint ID
168 /// Allocator for #uri text and optional members
169 wmem_allocator_t
*alloc
;
172 /// Derived URI text as address
175 /// Optional DTN-scheme well-known SSP
176 const char *dtn_wkssp
;
177 /// Optional DTN-scheme service name
178 const char *dtn_serv
;
179 /// Optional IPN-scheme service name
183 /** Construct a new timestamp.
186 bp_eid_t
* bp_eid_new(wmem_allocator_t
*alloc
);
188 /** Function to match the GDestroyNotify signature.
191 void bp_eid_free(bp_eid_t
*obj
);
193 /** Function to match the GCompareFunc signature.
196 bool bp_eid_equal(const void *a
, const void *b
);
198 /// Security marking metadata
200 /// Block numbers marking the data as security integrity protected
202 /// Block numbers marking the data as security-modified and not decodable
206 /// Metadata extracted from the primary block
208 /// Display item for the whole block
209 proto_item
*item_block
;
211 /// Bundle flags (assumed zero).
212 /// Values are BundleProcessingFlag.
217 bp_eid_t
*src_nodeid
;
219 bp_eid_t
*rep_nodeid
;
220 /// Creation Timestamp
222 /// Optional fragment start offset
223 uint64_t *frag_offset
;
224 /// Optional bundle total length
226 /// CRC type code (assumed zero)
228 /// Raw bytes of CRC field
232 } bp_block_primary_t
;
234 /** Construct a new object on the file allocator.
237 bp_block_primary_t
* bp_block_primary_new(wmem_allocator_t
*alloc
);
239 /** Function to match the GDestroyNotify signature.
242 void bp_block_primary_free(wmem_allocator_t
*alloc
, bp_block_primary_t
*obj
);
245 /// The index of the block within the bundle.
246 /// This is for internal bookkeeping, *not* the block number.
248 /// Display item for the whole block
249 proto_item
*item_block
;
251 /// Type of this block
253 /// Unique identifier for this block
254 uint64_t *block_number
;
255 /// All flags on this block
257 /// CRC type code (assumed zero)
259 /// Raw bytes of CRC field
262 /// Type-specific data, unencoded
264 /// Type-specific data tree
265 proto_tree
*tree_data
;
268 } bp_block_canonical_t
;
270 /** Construct a new object on the file allocator.
271 * @param blk_ix The index of the block within the bundle.
272 * The canonical index is always greater than zero.
275 bp_block_canonical_t
* bp_block_canonical_new(wmem_allocator_t
*alloc
, uint64_t blk_ix
);
278 void bp_block_canonical_delete(wmem_allocator_t
*alloc
, bp_block_canonical_t
*obj
);
280 /// Identification of an individual bundle
282 /// Normalized EID URI for the Source Node ID
284 /// Creation Timestamp
286 /// Pointer to external optional fragment start offset
287 const uint64_t *frag_offset
;
288 /// Pointer to external optional bundle total length
289 const uint64_t *total_len
;
292 /** Construct a new object on the file allocator.
293 * @param alloc The allocator to use.
294 * @param src The non-null pointer to source EID.
295 * @param ts The non-null pointer to Timestamp.
296 * @param off Optional fragment offset value.
297 * @param len Optional fragment length value.
300 bp_bundle_ident_t
* bp_bundle_ident_new(wmem_allocator_t
*alloc
, const bp_eid_t
*src
, const bp_creation_ts_t
*ts
, const uint64_t *off
, const uint64_t *len
);
303 void bp_bundle_ident_free(wmem_allocator_t
*alloc
, bp_bundle_ident_t
*obj
);
305 /** Function to match the GEqualFunc signature.
308 gboolean
bp_bundle_ident_equal(const void *a
, const void *b
);
310 /** Function to match the GHashFunc signature.
313 unsigned bp_bundle_ident_hash(const void *key
);
315 /// Metadata extracted per-bundle
317 /// Index of the frame
319 /// Layer within the frame
321 /// Timestamp on the frame (end time if reassembled)
323 /// Bundle identity derived from #primary data
324 bp_bundle_ident_t
*ident
;
325 /// Required primary block
326 bp_block_primary_t
*primary
;
327 /// Additional blocks in order (type bp_block_canonical_t)
329 /// Map from block number (uint64_t) to pointer to block of that number
330 /// (bp_block_canonical_t owned by #blocks)
331 wmem_map_t
*block_nums
;
332 /// Map from block type code (uint64_t) to sequence (wmem_list_t) of
333 /// pointers to block of that type (bp_block_canonical_t owned by #blocks)
334 wmem_map_t
*block_types
;
336 /// Payload BTSD start offset in bundle TVB
337 unsigned *pyld_start
;
338 /// Payload BTSD length
342 /** Construct a new object on the file allocator.
345 bp_bundle_t
* bp_bundle_new(wmem_allocator_t
*alloc
);
347 /** Function to match the GDestroyNotify signature.
350 void bp_bundle_free(wmem_allocator_t
*alloc
, bp_bundle_t
*obj
);
352 /** Extract an Endpoint ID.
353 * All EID fields are allocated with wmem_file_scope().
355 * @param tree The tree to write items under.
356 * @param hfindex The root item field.
357 * @param hfindex_uri The reassembled URI item field.
358 * @param pinfo Packet info to update.
359 * @param tvb Buffer to read from.
360 * @param[in,out] offset Starting offset within @c tvb.
361 * @param[out] eid If non-null, the EID to write to.
362 * @return The new tree item.
365 proto_item
* proto_tree_add_cbor_eid(proto_tree
*tree
, int hfindex
, int hfindex_uri
, packet_info
*pinfo
, tvbuff_t
*tvb
, int *offset
, bp_eid_t
*eid
);
367 /// Metadata for an entire file
369 /// Map from a bundle ID (bp_bundle_ident_t) to wmem_list_t of bundle (bp_bundle_t)
371 /// Map from subject bundle ID (bp_bundle_ident_t) to
372 /// map from references (bp_bundle_ident_t) of status bundles to NULL
374 wmem_map_t
*admin_status
;
377 /** Data supplied to each block sub-dissector.
380 /// The overall bundle being decoded (so far)
382 /// This block being decoded
383 bp_block_canonical_t
*block
;
384 } bp_dissector_data_t
;
390 #endif /* PACKET_BPV7_H */