Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-bpsec.c
Line
Count
Source
1
/* packet-bpsec.c
2
 * Routines for Bundle Protocol Version 7 Security (BPSec) dissection
3
 * References:
4
 *     RFC 9172: https://www.rfc-editor.org/rfc/rfc9172.html
5
 *
6
 * Copyright 2019-2024, Brian Sipos <brian.sipos@gmail.com>
7
 *
8
 * Wireshark - Network traffic analyzer
9
 * By Gerald Combs <gerald@wireshark.org>
10
 * Copyright 1998 Gerald Combs
11
 *
12
 * SPDX-License-Identifier: LGPL-2.1-or-later
13
 */
14
#include "config.h"
15
#include <stdint.h>
16
17
#include "packet-bpsec.h"
18
#include <epan/packet.h>
19
#include <epan/prefs.h>
20
#include <epan/proto.h>
21
#include <epan/expert.h>
22
#include <epan/tfs.h>
23
#include <epan/wscbor.h>
24
25
void proto_register_bpsec(void);
26
void proto_reg_handoff_bpsec(void);
27
28
/// Protocol handles
29
static int proto_bpsec;
30
31
/// Dissect opaque CBOR data
32
static dissector_handle_t handle_cbor;
33
/// Context ID sub-dissectors
34
static dissector_table_t secctx_dissectors;
35
/// Parameter value sub-dissectors
36
static dissector_table_t param_dissectors;
37
/// Result value sub-dissectors
38
static dissector_table_t result_dissectors;
39
40
// Field definitions
41
static int hf_bib;
42
static int hf_bcb;
43
static int hf_asb_target_list;
44
static int hf_asb_target;
45
static int hf_asb_ctxid;
46
static int hf_asb_flags;
47
static int hf_asb_flags_has_params;
48
static int hf_asb_secsrc_nodeid;
49
static int hf_asb_secsrc_uri;
50
static int hf_asb_param_list;
51
static int hf_asb_param_pair;
52
static int hf_asb_param_id;
53
static int hf_asb_result_all_list;
54
static int hf_asb_result_tgt_list;
55
static int hf_asb_result_tgt_ref;
56
static int hf_asb_result_pair;
57
static int hf_asb_result_id;
58
59
static int *const asb_flags[] = {
60
    &hf_asb_flags_has_params,
61
    NULL
62
};
63
64
// Tree structures
65
static int ett_asb;
66
static int ett_asb_flags;
67
static int ett_tgt_list;
68
static int ett_param_list;
69
static int ett_param_pair;
70
static int ett_result_all_list;
71
static int ett_result_tgt_list;
72
static int ett_result_pair;
73
74
static expert_field ei_secsrc_diff;
75
static expert_field ei_ctxid_zero;
76
static expert_field ei_ctxid_priv;
77
static expert_field ei_target_invalid;
78
static expert_field ei_value_partial_decode;
79
80
144
bpsec_id_t * bpsec_id_new(wmem_allocator_t *alloc, int64_t context_id, int64_t type_id) {
81
144
    bpsec_id_t *obj;
82
144
    if (alloc) {
83
0
        obj = wmem_new(alloc, bpsec_id_t);
84
0
    }
85
144
    else {
86
144
        obj = g_new(bpsec_id_t, 1);
87
144
    }
88
144
    obj->context_id = context_id;
89
144
    obj->type_id = type_id;
90
144
    return obj;
91
144
}
92
93
192
static gboolean bpsec_id_equal(const void *a, const void *b) {
94
192
    const bpsec_id_t *aobj = a;
95
192
    const bpsec_id_t *bobj = b;
96
192
    return (
97
192
        aobj && bobj
98
192
        && (aobj->context_id == bobj->context_id)
99
32
        && (aobj->type_id == bobj->type_id)
100
192
    );
101
192
}
102
103
288
static unsigned bpsec_id_hash(const void *key) {
104
288
    const bpsec_id_t *obj = key;
105
288
    return (
106
288
        g_int64_hash(&(obj->context_id))
107
288
        ^ g_int64_hash(&(obj->type_id))
108
288
    );
109
288
}
110
111
/** Dissect an ID-value pair within a context.
112
 *
113
 */
114
0
static int dissect_value(dissector_handle_t dissector, bpsec_dissector_data_t *const data, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
115
0
    int sublen = 0;
116
0
    if (dissector) {
117
0
        sublen = call_dissector_with_data(dissector, tvb, pinfo, tree, data);
118
0
        if ((sublen < 0) || ((unsigned)sublen < tvb_captured_length(tvb))) {
119
0
            expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_value_partial_decode);
120
0
        }
121
0
    }
122
0
    if (sublen == 0) {
123
0
        sublen = call_dissector(handle_cbor, tvb, pinfo, tree);
124
0
    }
125
0
    return sublen;
126
0
}
127
128
/** Dissector for abstract security block structure.
129
 */
130
3
static int dissect_block_asb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bp_dissector_data_t *const data, int root_hfindex) {
131
3
    proto_item *item_asb = proto_tree_add_item(tree, root_hfindex, tvb, 0, -1, ENC_NA);
132
3
    proto_tree *tree_asb = proto_item_add_subtree(item_asb, ett_asb);
133
3
    int offset = 0;
134
135
3
    wmem_array_t *targets;
136
3
    targets = wmem_array_new(pinfo->pool, sizeof(uint64_t));
137
138
3
    wscbor_chunk_t *chunk_tgt_list = wscbor_chunk_read(pinfo->pool, tvb, &offset);
139
3
    wscbor_require_array(chunk_tgt_list);
140
3
    proto_item *item_tgt_list = proto_tree_add_cbor_container(tree_asb, hf_asb_target_list, pinfo, tvb, chunk_tgt_list);
141
3
    if (!wscbor_skip_if_errors(pinfo->pool, tvb, &offset, chunk_tgt_list)) {
142
0
        proto_tree *tree_tgt_list = proto_item_add_subtree(item_tgt_list, ett_tgt_list);
143
144
        // iterate all targets
145
0
        for (uint64_t param_ix = 0; param_ix < chunk_tgt_list->head_value; ++param_ix) {
146
0
            wscbor_chunk_t *chunk_tgt = wscbor_chunk_read(pinfo->pool, tvb, &offset);
147
0
            uint64_t *tgt_blknum = wscbor_require_uint64(pinfo->pool, chunk_tgt);
148
0
            proto_item *item_tgt = proto_tree_add_cbor_uint64(tree_tgt_list, hf_asb_target, pinfo, tvb, chunk_tgt, tgt_blknum);
149
0
            if (tgt_blknum) {
150
0
                wmem_array_append(targets, tgt_blknum, 1);
151
152
0
                wmem_map_t *map = NULL;
153
0
                if (*tgt_blknum == 0) {
154
0
                    map = (root_hfindex == hf_bib)
155
0
                        ? data->bundle->primary->sec.data_i
156
0
                        : data->bundle->primary->sec.data_c;
157
0
                }
158
0
                else {
159
0
                    bp_block_canonical_t *found = wmem_map_lookup(data->bundle->block_nums, tgt_blknum);
160
0
                    if (found) {
161
0
                        map = (root_hfindex == hf_bib)
162
0
                            ? found->sec.data_i
163
0
                            : found->sec.data_c;
164
0
                    }
165
0
                    else {
166
0
                        expert_add_info(pinfo, item_tgt, &ei_target_invalid);
167
0
                    }
168
0
                }
169
0
                if (map && (data->block->block_number)) {
170
0
                    wmem_map_insert(
171
0
                        map,
172
0
                        data->block->block_number,
173
0
                        NULL
174
0
                    );
175
0
                }
176
0
            }
177
0
        }
178
179
0
        proto_item_set_len(item_tgt_list, offset - chunk_tgt_list->start);
180
0
    }
181
182
3
    wscbor_chunk_t *chunk_ctxid = wscbor_chunk_read(pinfo->pool, tvb, &offset);
183
3
    int64_t *ctxid = wscbor_require_int64(pinfo->pool, chunk_ctxid);
184
3
    proto_item *item_ctxid = proto_tree_add_cbor_int64(tree_asb, hf_asb_ctxid, pinfo, tvb, chunk_ctxid, ctxid);
185
3
    if (ctxid && item_ctxid) {
186
3
        if (*ctxid == 0) {
187
2
            expert_add_info(pinfo, item_ctxid, &ei_ctxid_zero);
188
2
        }
189
1
        else if (*ctxid < 0) {
190
0
            expert_add_info(pinfo, item_ctxid, &ei_ctxid_priv);
191
0
        }
192
193
        // apply label if registered
194
3
        dissector_handle_t ctx_dis = dissector_get_custom_table_handle(secctx_dissectors, ctxid);
195
3
        const char *dis_name = dissector_handle_get_description(ctx_dis);
196
3
        if (dis_name) {
197
0
            const header_field_info *hfinfo = PITEM_HFINFO(item_ctxid);
198
0
            proto_item_set_text(item_ctxid, "%s: %s (%" PRId64 ")", hfinfo ? hfinfo->name : NULL, dis_name, *ctxid);
199
0
        }
200
3
    }
201
202
3
    wscbor_chunk_t *chunk_flags = wscbor_chunk_read(pinfo->pool, tvb, &offset);
203
3
    uint64_t *flags = wscbor_require_uint64(pinfo->pool, chunk_flags);
204
3
    proto_tree_add_cbor_bitmask(tree_asb, hf_asb_flags, ett_asb_flags, asb_flags, pinfo, tvb, chunk_flags, flags);
205
206
3
    {
207
3
        bp_eid_t *secsrc = bp_eid_new(pinfo->pool);
208
3
        proto_item *item_secsrc = proto_tree_add_cbor_eid(tree_asb, hf_asb_secsrc_nodeid, hf_asb_secsrc_uri, pinfo, tvb, &offset, secsrc);
209
3
        if (!bp_eid_equal(data->bundle->primary->src_nodeid, secsrc)) {
210
0
            expert_add_info(pinfo, item_secsrc, &ei_secsrc_diff);
211
0
        }
212
3
    }
213
214
3
    if (flags && (*flags & BPSEC_ASB_HAS_PARAMS)) {
215
0
        wscbor_chunk_t *chunk_param_list = wscbor_chunk_read(pinfo->pool, tvb, &offset);
216
0
        wscbor_require_array(chunk_param_list);
217
0
        proto_item *item_param_list = proto_tree_add_cbor_container(tree_asb, hf_asb_param_list, pinfo, tvb, chunk_param_list);
218
0
        if (!wscbor_skip_if_errors(pinfo->pool, tvb, &offset, chunk_param_list)) {
219
0
            proto_tree *tree_param_list = proto_item_add_subtree(item_param_list, ett_param_list);
220
221
            // iterate all parameters
222
0
            for (uint64_t param_ix = 0; param_ix < chunk_param_list->head_value; ++param_ix) {
223
0
                wscbor_chunk_t *chunk_param_pair = wscbor_chunk_read(pinfo->pool, tvb, &offset);
224
0
                wscbor_require_array_size(chunk_param_pair, 2, 2);
225
0
                proto_item *item_param_pair = proto_tree_add_cbor_container(tree_param_list, hf_asb_param_pair, pinfo, tvb, chunk_param_pair);
226
0
                if (!wscbor_skip_if_errors(pinfo->pool, tvb, &offset, chunk_param_pair)) {
227
0
                    proto_tree *tree_param_pair = proto_item_add_subtree(item_param_pair, ett_param_pair);
228
229
0
                    wscbor_chunk_t *chunk_paramid = wscbor_chunk_read(pinfo->pool, tvb, &offset);
230
0
                    int64_t *paramid = wscbor_require_int64(pinfo->pool, chunk_paramid);
231
0
                    proto_tree_add_cbor_int64(tree_param_pair, hf_asb_param_id, pinfo, tvb, chunk_paramid, paramid);
232
233
0
                    const int offset_value = offset;
234
0
                    if (!wscbor_skip_next_item(pinfo->pool, tvb, &offset)) {
235
0
                        return 0;
236
0
                    }
237
0
                    tvbuff_t *tvb_value = tvb_new_subset_length(tvb, offset_value, offset - offset_value);
238
239
0
                    bpsec_dissector_data_t bpsec_data = { .bp = data };
240
0
                    dissector_handle_t value_dissect = NULL;
241
0
                    if (ctxid && paramid) {
242
0
                        bpsec_data.id.context_id = *ctxid;
243
0
                        bpsec_data.id.type_id = *paramid;
244
0
                        value_dissect = dissector_get_custom_table_handle(param_dissectors, &(bpsec_data.id));
245
0
                    }
246
0
                    const char *dis_name = dissector_handle_get_description(value_dissect);
247
0
                    if (paramid) {
248
0
                        proto_item_append_text(item_param_pair, ": %s (%" PRId64 ")", dis_name, *paramid);
249
0
                    }
250
0
                    dissect_value(value_dissect, &bpsec_data, tvb_value, pinfo, tree_param_pair);
251
252
0
                    proto_item_set_len(item_param_pair, offset - chunk_param_pair->start);
253
0
                }
254
0
            }
255
256
0
            proto_item_set_len(item_param_list, offset - chunk_param_list->start);
257
0
        }
258
0
    }
259
260
    // array sizes should agree
261
3
    const unsigned tgt_size = wmem_array_get_count(targets);
262
263
3
    wscbor_chunk_t *chunk_result_all_list = wscbor_chunk_read(pinfo->pool, tvb, &offset);
264
3
    wscbor_require_array_size(chunk_result_all_list, tgt_size, tgt_size);
265
3
    proto_item *item_result_all_list = proto_tree_add_cbor_container(tree_asb, hf_asb_result_all_list, pinfo, tvb, chunk_result_all_list);
266
3
    if (!wscbor_skip_if_errors(pinfo->pool, tvb, &offset, chunk_result_all_list)) {
267
0
        proto_tree *tree_result_all_list = proto_item_add_subtree(item_result_all_list, ett_result_all_list);
268
269
        // iterate each target's results
270
0
        for (unsigned tgt_ix = 0; tgt_ix < tgt_size; ++tgt_ix) {
271
0
            wscbor_chunk_t *chunk_result_tgt_list = wscbor_chunk_read(pinfo->pool, tvb, &offset);
272
0
            wscbor_require_array(chunk_result_tgt_list);
273
0
            proto_item *item_result_tgt_list = proto_tree_add_cbor_container(tree_result_all_list, hf_asb_result_tgt_list, pinfo, tvb, chunk_result_tgt_list);
274
0
            if (!wscbor_skip_if_errors(pinfo->pool, tvb, &offset, chunk_result_tgt_list)) {
275
0
                proto_tree *tree_result_tgt_list = proto_item_add_subtree(item_result_tgt_list, ett_result_tgt_list);
276
277
                // Hint at the associated target number
278
0
                if (tgt_ix < tgt_size) {
279
0
                    const uint64_t *tgt_blknum = wmem_array_index(targets, tgt_ix);
280
0
                    proto_item *item_tgt_blknum = proto_tree_add_uint64(tree_result_tgt_list, hf_asb_result_tgt_ref, tvb, 0, 0, *tgt_blknum);
281
0
                    proto_item_set_generated(item_tgt_blknum);
282
0
                }
283
284
                // iterate all results for this target
285
0
                for (uint64_t result_ix = 0; result_ix < chunk_result_tgt_list->head_value; ++result_ix) {
286
0
                    wscbor_chunk_t *chunk_result_pair = wscbor_chunk_read(pinfo->pool, tvb, &offset);
287
0
                    wscbor_require_array_size(chunk_result_pair, 2, 2);
288
0
                    proto_item *item_result_pair = proto_tree_add_cbor_container(tree_result_tgt_list, hf_asb_result_pair, pinfo, tvb, chunk_result_pair);
289
0
                    if (!wscbor_skip_if_errors(pinfo->pool, tvb, &offset, chunk_result_pair)) {
290
0
                        proto_tree *tree_result_pair = proto_item_add_subtree(item_result_pair, ett_result_pair);
291
292
0
                        wscbor_chunk_t *chunk_resultid = wscbor_chunk_read(pinfo->pool, tvb, &offset);
293
0
                        int64_t *resultid = wscbor_require_int64(pinfo->pool, chunk_resultid);
294
0
                        proto_tree_add_cbor_int64(tree_result_pair, hf_asb_result_id, pinfo, tvb, chunk_resultid, resultid);
295
296
0
                        const int offset_value = offset;
297
0
                        if (!wscbor_skip_next_item(pinfo->pool, tvb, &offset)) {
298
0
                            return 0;
299
0
                        }
300
0
                        tvbuff_t *tvb_value = tvb_new_subset_length(tvb, offset_value, offset - offset_value);
301
302
0
                        bpsec_dissector_data_t bpsec_data = { .bp = data };
303
0
                        dissector_handle_t value_dissect = NULL;
304
0
                        if (ctxid && resultid) {
305
0
                            bpsec_data.id.context_id = *ctxid;
306
0
                            bpsec_data.id.type_id = *resultid;
307
0
                            value_dissect = dissector_get_custom_table_handle(result_dissectors, &(bpsec_data.id));
308
0
                        }
309
0
                        const char *dis_name = dissector_handle_get_description(value_dissect);
310
0
                        if (resultid) {
311
0
                            proto_item_append_text(item_result_pair, ": %s (%" PRId64 ")", dis_name, *resultid);
312
0
                        }
313
0
                        dissect_value(value_dissect, &bpsec_data, tvb_value, pinfo, tree_result_pair);
314
315
0
                        proto_item_set_len(item_result_pair, offset - chunk_result_pair->start);
316
0
                    }
317
0
                }
318
319
0
                proto_item_set_len(item_result_tgt_list, offset - chunk_result_tgt_list->start);
320
0
            }
321
0
        }
322
323
0
        proto_item_set_len(item_result_all_list, offset - chunk_result_all_list->start);
324
0
    }
325
326
3
    proto_item_set_len(item_asb, offset);
327
3
    return offset;
328
3
}
329
330
/** Dissector for Bundle Integrity block.
331
 */
332
3
static int dissect_block_bib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
333
3
    return dissect_block_asb(tvb, pinfo, tree, (bp_dissector_data_t *)data, hf_bib);
334
3
}
335
336
/** Dissector for Bundle Confidentiality block.
337
 */
338
0
static int dissect_block_bcb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
339
0
    return dissect_block_asb(tvb, pinfo, tree, (bp_dissector_data_t *)data, hf_bcb);
340
0
}
341
342
/// Re-initialize after a configuration change
343
16
static void reinit_bpsec(void) {
344
16
}
345
346
/// Overall registration of the protocol
347
16
void proto_register_bpsec(void) {
348
16
    static hf_register_info fields[] = {
349
16
        {&hf_bib, {"BPSec Block Integrity Block", "bpsec.bib", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}},
350
16
        {&hf_bcb, {"BPSec Block Confidentiality Block", "bpsec.bcb", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}},
351
16
        {&hf_asb_target_list, {"Security Targets, Count", "bpsec.asb.target_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
352
16
        {&hf_asb_target, {"Target Block Number", "bpsec.asb.target", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
353
16
        {&hf_asb_ctxid, {"Context ID", "bpsec.asb.ctxid", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
354
16
        {&hf_asb_flags, {"Flags", "bpsec.asb.flags", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
355
16
        {&hf_asb_flags_has_params, {"Parameters Present", "bpsec.asb.flags.has_params", FT_BOOLEAN, 8, TFS(&tfs_set_notset), BPSEC_ASB_HAS_PARAMS, NULL, HFILL}},
356
16
        {&hf_asb_secsrc_nodeid, {"Security Source", "bpsec.asb.secsrc.nodeid", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
357
16
        {&hf_asb_secsrc_uri, {"Security Source URI", "bpsec.asb.secsrc.uri", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
358
16
        {&hf_asb_param_list, {"Security Parameters, Count", "bpsec.asb.param_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
359
16
        {&hf_asb_param_pair, {"Parameter", "bpsec.asb.param", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
360
16
        {&hf_asb_param_id, {"Type ID", "bpsec.asb.param.id", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
361
16
        {&hf_asb_result_all_list, {"Security Result Targets, Count", "bpsec.asb.result_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
362
16
        {&hf_asb_result_tgt_ref, {"Associated Target Block Number", "bpsec.asb.result_tgt_ref", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
363
16
        {&hf_asb_result_tgt_list, {"Security Results, Count", "bpsec.asb.result_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
364
16
        {&hf_asb_result_pair, {"Result", "bpsec.asb.result", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
365
16
        {&hf_asb_result_id, {"Type ID", "bpsec.asb.result.id", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
366
16
    };
367
16
    static int *ett[] = {
368
16
        &ett_asb,
369
16
        &ett_asb_flags,
370
16
        &ett_tgt_list,
371
16
        &ett_param_list,
372
16
        &ett_param_pair,
373
16
        &ett_result_all_list,
374
16
        &ett_result_tgt_list,
375
16
        &ett_result_pair,
376
16
    };
377
16
    static ei_register_info expertitems[] = {
378
16
        {&ei_secsrc_diff, {"bpsec.secsrc_diff", PI_SECURITY, PI_CHAT, "BPSec Security Source different from bundle Source", EXPFILL}},
379
16
        {&ei_ctxid_zero, {"bpsec.ctxid_zero", PI_SECURITY, PI_WARN, "BPSec Security Context ID zero is reserved", EXPFILL}},
380
16
        {&ei_ctxid_priv, {"bpsec.ctxid_priv", PI_SECURITY, PI_NOTE, "BPSec Security Context ID from private/experimental block", EXPFILL}},
381
16
        {&ei_target_invalid, {"bpsec.target_invalid", PI_PROTOCOL, PI_WARN, "Target block number not present", EXPFILL}},
382
16
        {&ei_value_partial_decode, {"bpsec.value_partial_decode", PI_UNDECODED, PI_WARN, "Value data not fully dissected", EXPFILL}},
383
16
    };
384
385
16
    proto_bpsec = proto_register_protocol("DTN Bundle Protocol Security", "BPSec", "bpsec");
386
387
16
    proto_register_field_array(proto_bpsec, fields, array_length(fields));
388
16
    proto_register_subtree_array(ett, array_length(ett));
389
16
    expert_module_t *expert = expert_register_protocol(proto_bpsec);
390
16
    expert_register_field_array(expert, expertitems, array_length(expertitems));
391
392
16
    secctx_dissectors = register_custom_dissector_table("bpsec.ctx", "BPSec Context", proto_bpsec, g_int64_hash, g_int64_equal, g_free);
393
16
    param_dissectors = register_custom_dissector_table("bpsec.param", "BPSec Parameter", proto_bpsec, bpsec_id_hash, bpsec_id_equal, g_free);
394
16
    result_dissectors = register_custom_dissector_table("bpsec.result", "BPSec Result", proto_bpsec, bpsec_id_hash, bpsec_id_equal, g_free);
395
396
16
    prefs_register_protocol(proto_bpsec, reinit_bpsec);
397
16
}
398
399
16
void proto_reg_handoff_bpsec(void) {
400
16
    handle_cbor = find_dissector("cbor");
401
402
    /* Packaged extensions */
403
16
    {
404
16
        uint64_t *key = g_new(uint64_t, 1);
405
16
        *key = BP_BLOCKTYPE_BIB;
406
16
        dissector_handle_t hdl = create_dissector_handle_with_name_and_description(dissect_block_bib, proto_bpsec, NULL, "Block Integrity Block");
407
16
        dissector_add_custom_table_handle("bpv7.block_type", key, hdl);
408
16
    }
409
16
    {
410
16
        uint64_t *key = g_new(uint64_t, 1);
411
16
        *key = BP_BLOCKTYPE_BCB;
412
16
        dissector_handle_t hdl = create_dissector_handle_with_name_and_description(dissect_block_bcb, proto_bpsec, NULL, "Block Confidentiality Block");
413
16
        dissector_add_custom_table_handle("bpv7.block_type", key, hdl);
414
16
    }
415
416
16
    reinit_bpsec();
417
16
}