Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-bpv6.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-bpv6.c
2
 * References:
3
 *     RFC 5050: https://tools.ietf.org/html/rfc5050
4
 *
5
 * Copyright 2006-2007 The MITRE Corporation.
6
 * All Rights Reserved.
7
 * Approved for Public Release; Distribution Unlimited.
8
 * Tracking Number 07-0090.
9
 *
10
 * The US Government will not be charged any license fee and/or royalties
11
 * related to this software. Neither name of The MITRE Corporation; nor the
12
 * names of its contributors may be used to endorse or promote products
13
 * derived from this software without specific prior written permission.
14
 *
15
 * Wireshark - Network traffic analyzer
16
 * By Gerald Combs <gerald@wireshark.org>
17
 * Copyright 1998 Gerald Combs
18
 *
19
 * SPDX-License-Identifier: GPL-2.0-or-later
20
 *
21
 * Specification reference:
22
 * RFC 5050
23
 * https://tools.ietf.org/html/rfc5050
24
 */
25
26
/*
27
 *    Modifications were made to this file under designation MFS-33289-1 and
28
 *    are Copyright 2015 United States Government as represented by NASA
29
 *       Marshall Space Flight Center. All Rights Reserved.
30
 *
31
 *    Released under the GNU GPL with NASA legal approval granted 2016-06-10.
32
 *
33
 *    The subject software is provided "AS IS" WITHOUT ANY WARRANTY of any kind,
34
 *    either expressed, implied or statutory and this agreement does not,
35
 *    in any manner, constitute an endorsement by government agency of any
36
 *    results, designs or products resulting from use of the subject software.
37
 *    See the Agreement for the specific language governing permissions and
38
 *    limitations.
39
 */
40
41
#include "config.h"
42
43
#include <epan/packet.h>
44
#include <epan/expert.h>
45
#include <epan/tfs.h>
46
#include <epan/wscbor.h>
47
#include "packet-bpv6.h"
48
#include "packet-cfdp.h"
49
50
void proto_register_bpv6(void);
51
void proto_reg_handoff_bpv6(void);
52
53
static int dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, packet_info *pinfo,
54
                                int offset, int payload_length, bool* success);
55
56
extern void
57
dissect_amp_as_subtree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
58
59
60
static int evaluate_sdnv(tvbuff_t *tvb, int offset, int *bytecount);
61
62
/// Return an error_info index if not valid
63
static int evaluate_sdnv_ei(tvbuff_t *tvb, int offset, int *bytecount, expert_field **error);
64
65
static int add_sdnv_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_sdnv_time);
66
67
static int64_t
68
evaluate_sdnv_64(tvbuff_t *tvb, int offset, int *bytecount);
69
70
static int proto_bundle;
71
static dissector_handle_t bundle_handle;
72
static dissector_handle_t bpv6_handle;
73
static dissector_handle_t bpv7_handle;
74
75
static int hf_bundle_pdu_version;
76
77
/* Primary Header Processing Flag Variables */
78
static int hf_bundle_procflags;
79
static int hf_bundle_procflags_fragment;
80
static int hf_bundle_procflags_admin;
81
static int hf_bundle_procflags_dont_fragment;
82
static int hf_bundle_procflags_cust_xfer_req;
83
static int hf_bundle_procflags_dest_singleton;
84
static int hf_bundle_procflags_application_ack;
85
86
/* Additions for Version 5 */
87
static int hf_bundle_control_flags;
88
static int hf_bundle_procflags_general;
89
static int hf_bundle_procflags_cos;
90
static int hf_bundle_procflags_status;
91
92
/* Primary Header COS Flag Variables */
93
static int hf_bundle_cosflags;
94
static int hf_bundle_cosflags_priority;
95
96
/* Primary Header Status Report Request Flag Variables */
97
static int hf_bundle_srrflags;
98
static int hf_bundle_srrflags_report_receipt;
99
static int hf_bundle_srrflags_report_cust_accept;
100
static int hf_bundle_srrflags_report_forward;
101
static int hf_bundle_srrflags_report_delivery;
102
static int hf_bundle_srrflags_report_deletion;
103
static int hf_bundle_srrflags_report_ack;
104
105
/* Primary Header Fields*/
106
static int hf_bundle_primary_header_len;
107
static int hf_bundle_primary_dictionary_len;
108
static int hf_bundle_primary_timestamp;
109
static int hf_bundle_primary_fragment_offset;
110
static int hf_bundle_primary_total_adu_len;
111
static int hf_bundle_primary_timestamp_seq_num64;
112
static int hf_bundle_primary_timestamp_seq_num32;
113
114
static int hf_bundle_dest_scheme_offset_u16;
115
static int hf_bundle_dest_scheme_offset_i32;
116
static int hf_bundle_dest_ssp_offset_u16;
117
static int hf_bundle_dest_ssp_offset_i32;
118
static int hf_bundle_source_scheme_offset_u16;
119
static int hf_bundle_source_scheme_offset_i32;
120
static int hf_bundle_source_ssp_offset_u16;
121
static int hf_bundle_source_ssp_offset_i32;
122
static int hf_bundle_report_scheme_offset_u16;
123
static int hf_bundle_report_scheme_offset_i32;
124
static int hf_bundle_report_ssp_offset_u16;
125
static int hf_bundle_report_ssp_offset_i32;
126
static int hf_bundle_cust_scheme_offset_u16;
127
static int hf_bundle_cust_scheme_offset_i32;
128
static int hf_bundle_cust_ssp_offset_u16;
129
static int hf_bundle_cust_ssp_offset_i32;
130
131
/* Dictionary EIDs */
132
static int hf_bundle_dest_scheme;
133
static int hf_bundle_dest_ssp;
134
static int hf_bundle_source_scheme;
135
static int hf_bundle_source_ssp;
136
static int hf_bundle_report_scheme;
137
static int hf_bundle_report_ssp;
138
static int hf_bundle_custodian_scheme;
139
static int hf_bundle_custodian_ssp;
140
141
/* Remaining Primary Header Fields */
142
static int hf_bundle_creation_timestamp;
143
static int hf_bundle_lifetime;
144
static int hf_bundle_lifetime_sdnv;
145
146
/* Secondary Header Processing Flag Variables */
147
static int hf_bundle_payload_length;
148
static int hf_bundle_payload_header_type;
149
static int hf_bundle_payload_data;
150
static int hf_bundle_payload_flags;
151
static int hf_bundle_payload_flags_replicate_hdr;
152
static int hf_bundle_payload_flags_xmit_report;
153
static int hf_bundle_payload_flags_discard_on_fail;
154
static int hf_bundle_payload_flags_last_header;
155
156
/* Block Processing Control Flag Variables (Version 5) */
157
static int hf_block_control_flags;
158
static int hf_block_control_flags_sdnv;
159
static int hf_block_control_replicate;
160
static int hf_block_control_transmit_status;
161
static int hf_block_control_delete_bundle;
162
static int hf_block_control_last_block;
163
static int hf_block_control_discard_block;
164
static int hf_block_control_not_processed;
165
static int hf_block_control_eid_reference;
166
static int hf_block_control_block_length;
167
static int hf_block_control_block_cteb_custody_id;
168
static int hf_block_control_block_cteb_creator_custodian_eid;
169
170
/* Non-Primary Block Type Code Variable */
171
static int hf_bundle_block_type_code;
172
static int hf_bundle_unprocessed_block_data;
173
174
/* ECOS Flag Variables */
175
static int hf_ecos_flags;
176
static int hf_ecos_flags_critical;
177
static int hf_ecos_flags_streaming;
178
static int hf_ecos_flags_flowlabel;
179
static int hf_ecos_flags_reliable;
180
static int hf_ecos_flow_label;
181
182
static int hf_ecos_ordinal;
183
184
/* Administrative Record Variables */
185
static int hf_bundle_admin_record_type;
186
static int hf_bundle_admin_record_fragment;
187
static int hf_bundle_admin_statflags;
188
static int hf_bundle_admin_rcvd;
189
static int hf_bundle_admin_accepted;
190
static int hf_bundle_admin_forwarded;
191
static int hf_bundle_admin_delivered;
192
static int hf_bundle_admin_deleted;
193
static int hf_bundle_admin_acked;
194
static int hf_bundle_admin_fragment_offset;
195
static int hf_bundle_admin_fragment_length;
196
static int hf_bundle_admin_timestamp_seq_num64;
197
static int hf_bundle_admin_timestamp_seq_num32;
198
static int hf_bundle_admin_endpoint_length;
199
static int hf_bundle_admin_endpoint_id;
200
201
static int hf_bundle_admin_receipt_time;
202
static int hf_bundle_admin_accept_time;
203
static int hf_bundle_admin_forward_time;
204
static int hf_bundle_admin_delivery_time;
205
static int hf_bundle_admin_delete_time;
206
static int hf_bundle_admin_ack_time;
207
static int hf_bundle_admin_timestamp_copy;
208
static int hf_bundle_admin_signal_time;
209
static int hf_bundle_status_report_reason_code;
210
static int hf_bundle_custody_trf_succ_flg;
211
static int hf_bundle_custody_signal_reason;
212
static int hf_bundle_custody_id_range_start;
213
static int hf_bundle_custody_id_range_end;
214
215
static int hf_bundle_age_extension_block_code;
216
static int hf_bundle_block_previous_hop_scheme;
217
static int hf_bundle_block_previous_hop_eid;
218
219
/* Security Block Variables */
220
static int hf_bundle_target_block_type;
221
static int hf_bundle_target_block_occurrence;
222
static int hf_bundle_ciphersuite_type;
223
static int hf_bundle_ciphersuite_flags;
224
static int hf_block_ciphersuite_params;
225
static int hf_block_ciphersuite_params_length;
226
static int hf_block_ciphersuite_params_item_length;
227
static int hf_block_ciphersuite_param_type;
228
static int hf_block_ciphersuite_param_data;
229
static int hf_block_ciphersuite_result_length;
230
static int hf_block_ciphersuite_result_item_length;
231
static int hf_block_ciphersuite_result_type;
232
static int hf_block_ciphersuite_result_data;
233
static int hf_block_ciphersuite_range_offset;
234
static int hf_block_ciphersuite_range_length;
235
236
/* Tree Node Variables */
237
static int ett_bundle;
238
static int ett_bundle_hdr;
239
static int ett_primary_hdr;
240
static int ett_proc_flags;
241
static int ett_gen_flags;
242
static int ett_cos_flags;
243
static int ett_srr_flags;
244
static int ett_dictionary;
245
static int ett_payload_hdr;
246
static int ett_payload_flags;
247
static int ett_block_flags;
248
static int ett_admin_record;
249
static int ett_admin_rec_status;
250
static int ett_metadata_hdr;
251
static int ett_sec_block_param_data;
252
253
static expert_field ei_bundle_payload_length;
254
static expert_field ei_bundle_control_flags_length;
255
static expert_field ei_bundle_block_control_flags;
256
static expert_field ei_bundle_sdnv_length;
257
static expert_field ei_bundle_timestamp_seq_num;
258
static expert_field ei_bundle_offset_error;
259
static expert_field ei_block_control_block_cteb_invalid;
260
static expert_field ei_block_control_block_cteb_valid;
261
262
263
typedef struct dictionary_data {
264
    int bundle_header_dict_length;
265
266
    int dest_scheme_offset;
267
    int dst_scheme_pos;
268
    int dst_scheme_len;
269
    int source_scheme_offset;
270
    int src_scheme_pos;
271
    int src_scheme_len;
272
    int report_scheme_offset;
273
    int rpt_scheme_pos;
274
    int rpt_scheme_len;
275
    int cust_scheme_offset;
276
    int cust_scheme_pos;
277
    int cust_scheme_len;
278
    int dest_ssp_offset;
279
    int dst_ssp_len;
280
    int source_ssp_offset;
281
    int src_ssp_len;
282
    int report_ssp_offset;
283
    int rpt_ssp_len;
284
    int cust_ssp_offset;
285
    int cust_ssp_len;
286
287
} dictionary_data_t;
288
289
290
static const value_string admin_record_type_vals[] = {
291
    {ADMIN_REC_TYPE_STATUS_REPORT, "Bundle Status Report"},
292
    {ADMIN_REC_TYPE_CUSTODY_SIGNAL, "Custody Signal"},
293
    {ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL, "Aggregate Custody Signal"},
294
    {ADMIN_REC_TYPE_ANNOUNCE_BUNDLE, "Announce Record (Contact)"},
295
    {0, NULL}
296
};
297
298
static const value_string custody_signal_reason_codes[] = {
299
    {0x0, "No Additional Information"},
300
    {0x3, "Redundant Reception"},
301
    {0x4, "Depleted Storage"},
302
    {0x5, "Destination Endpoint ID Unintelligible"},
303
    {0x6, "No Known Route to Destination"},
304
    {0x7, "No Timely Contact with Next Node on Route"},
305
    {0x8, "Header Unintelligible"},
306
    {0, NULL}
307
};
308
309
static const value_string status_report_reason_codes[] = {
310
    {0x0, "No Additional Information"},
311
    {0x1, "Lifetime Expired"},
312
    {0x2, "Forwarded over Unidirectional Link"},
313
    {0x3, "Transmission Cancelled"},
314
    {0x4, "Depleted Storage"},
315
    {0x5, "Destination Endpoint ID Unintelligible"},
316
    {0x6, "No Known Route to Destination"},
317
    {0x7, "No Timely Contact with Next Node on Route"},
318
    {0x8, "Header Unintelligible"},
319
    {0, NULL}
320
};
321
322
static const value_string bundle_block_type_codes[] = {
323
    {0x01, "Bundle Payload Block"},
324
    {0x02, "Bundle Authentication Block"},
325
    {0x03, "Block Integrity Block"},
326
    {0x04, "Block Confidentiality Block"},
327
    {0x05, "Previous-Hop Insertion Block"},
328
    {0x08, "Metadata Extension Block"},
329
    {0x09, "Extension Security Block"},
330
    {0x0a, "Custody Transfer Enhancement Block"},
331
    {0x13, "Extended Class of Service Block"},
332
    {0x14, "Bundle Age Extension Block"},
333
    {0, NULL}
334
};
335
336
static const value_string cosflags_priority_vals[] = {
337
    {0x00, "Bulk"},
338
    {0x01, "Normal"},
339
    {0x02, "Expedited"},
340
    {0x03, "Invalid (Reserved)"},
341
    {0, NULL}
342
};
343
344
static const value_string ciphersuite_types[] = {
345
    {0x01, "HMAC_SHA1"},
346
    {0x05, "HMAC_SHA256"},
347
    {0x06, "ARC4_AES128"},
348
    {0xD1, "HMAC_SHA384"},
349
    {0xD2, "ECDSA_SHA256"},
350
    {0xD3, "ECDSA_SHA384"},
351
    {0xD4, "SHA256_AES128"},
352
    {0xD5, "SHA384_AES256"},
353
    {0, NULL}
354
};
355
356
static const value_string res_params_types[] = {
357
    {0x01, "Initialization Vector"},
358
    {0x03, "Key Information"},
359
    {0x04, "Content Range"},
360
    {0x05, "Integrity Signature"},
361
    {0x07, "Salt"},
362
    {0x08, "BCB Integrity Check Value"},
363
    {0, NULL}
364
};
365
366
/*
367
 * Adds the result of 2 SDNVs to tree: First SDNV is seconds, next is nanoseconds.
368
 * Returns bytes in both SDNVs or 0 if something goes wrong.
369
 */
370
static int
371
add_dtn_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_dtn_time)
372
220
{
373
220
    nstime_t dtn_time;
374
220
    int      sdnv_length, sdnv2_length;
375
220
    int      sdnv_value;
376
220
    int      orig_offset;
377
378
220
    orig_offset = offset;
379
380
220
    sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
381
220
    if (sdnv_value < 0) {
382
2
        return 0;
383
2
    }
384
385
218
    dtn_time.secs = (time_t)(sdnv_value + 946684800);
386
218
    offset += sdnv_length;
387
388
218
    dtn_time.nsecs = evaluate_sdnv(tvb, offset, &sdnv2_length);
389
218
    if (dtn_time.nsecs < 0) {
390
2
        return 0;
391
2
    }
392
393
216
    proto_tree_add_time(tree, hf_dtn_time, tvb, orig_offset, sdnv_length + sdnv2_length, &dtn_time);
394
395
216
    return (sdnv_length + sdnv2_length);
396
218
}
397
398
/*
399
 * Adds the result of SDNV which is a time since 2000 to tree.
400
 * Returns bytes in SDNV or 0 if something goes wrong.
401
 */
402
int
403
add_sdnv_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_sdnv_time)
404
712
{
405
712
    nstime_t dtn_time;
406
712
    int      sdnv_length;
407
712
    int      sdnv_value;
408
409
712
    sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
410
712
    if (sdnv_value < 0) {
411
10
        return 0;
412
10
    }
413
414
702
    dtn_time.secs = (time_t)(sdnv_value + 946684800);
415
702
    dtn_time.nsecs = 0;
416
702
    proto_tree_add_time(tree, hf_sdnv_time, tvb, offset, sdnv_length, &dtn_time);
417
418
702
    return sdnv_length;
419
712
}
420
421
static int
422
add_sdnv_to_tree(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, int offset, int hf_sdnv)
423
1.14k
{
424
1.14k
    proto_item *ti;
425
1.14k
    int         sdnv_length;
426
1.14k
    int         sdnv_value;
427
428
1.14k
    sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
429
1.14k
    ti = proto_tree_add_int(tree, hf_sdnv, tvb, offset, sdnv_length, sdnv_value);
430
1.14k
    if (sdnv_value < 0) {
431
16
        expert_add_info(pinfo, ti, &ei_bundle_sdnv_length);
432
16
        return 0;
433
16
    }
434
1.12k
    return sdnv_length;
435
1.14k
}
436
437
/*
438
 * Pull out stuff from the dictionary
439
 */
440
static int
441
dissect_dictionary(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, dictionary_data_t* dict_data,
442
                    uint8_t pri_hdr_procflags, char **bundle_custodian, int creation_timestamp, int timestamp_sequence)
443
595
{
444
595
    proto_tree  *dict_tree;
445
595
    const char* col_text;
446
447
595
    col_text = col_get_text(pinfo->cinfo, COL_INFO);
448
449
595
    dict_tree = proto_tree_add_subtree(tree, tvb, offset, dict_data->bundle_header_dict_length, ett_dictionary, NULL, "Dictionary");
450
451
    /*
452
     * If the dictionary length is 0, then the CBHE block compression method is applied. (RFC6260)
453
     * So the scheme offset is the node number and the ssp offset is the service number.
454
     * If destination scheme offset is 2 and destination ssp offset is 1, then the EID is
455
     * ipn:2.1
456
     */
457
595
    if (dict_data->bundle_header_dict_length == 0)
458
401
    {
459
401
        const char *src_node, *dst_node;
460
461
        /*
462
         * Destination info
463
         */
464
401
        if (dict_data->dest_scheme_offset == 0 && dict_data->dest_ssp_offset == 0)
465
73
        {
466
73
            proto_tree_add_string(dict_tree, hf_bundle_dest_scheme, tvb, 0, 0, DTN_SCHEME_STR);
467
73
            proto_tree_add_string(dict_tree, hf_bundle_dest_ssp, tvb, dict_data->dst_scheme_pos,
468
73
                            dict_data->dst_scheme_len + dict_data->dst_ssp_len, "none");
469
470
73
            dst_node = "dtn:none";
471
73
        }
472
328
        else
473
328
        {
474
328
            proto_tree_add_string(dict_tree, hf_bundle_dest_scheme, tvb, 0, 0, IPN_SCHEME_STR);
475
328
            proto_tree_add_string(dict_tree, hf_bundle_dest_ssp, tvb, dict_data->dst_scheme_pos,
476
328
                            dict_data->dst_scheme_len + dict_data->dst_ssp_len,
477
328
                            wmem_strdup_printf(pinfo->pool, "%d.%d",dict_data->dest_scheme_offset,dict_data->dest_ssp_offset));
478
479
328
            dst_node = wmem_strdup_printf(pinfo->pool, "%s:%d.%d", IPN_SCHEME_STR,
480
328
                                          dict_data->dest_scheme_offset, dict_data->dest_ssp_offset);
481
328
        }
482
483
        /*
484
         * Source info
485
         */
486
401
        if (dict_data->source_scheme_offset == 0 && dict_data->source_ssp_offset == 0)
487
135
        {
488
135
            proto_tree_add_string(dict_tree, hf_bundle_source_scheme, tvb, 0, 0, DTN_SCHEME_STR);
489
135
            proto_tree_add_string(dict_tree, hf_bundle_source_ssp, tvb, dict_data->src_scheme_pos,
490
135
                            dict_data->src_scheme_len + dict_data->src_ssp_len, "none");
491
492
135
            src_node = "dtn:none";
493
135
        }
494
266
        else
495
266
        {
496
266
            proto_tree_add_string(dict_tree, hf_bundle_source_scheme, tvb, 0, 0, IPN_SCHEME_STR);
497
266
            proto_tree_add_string(dict_tree, hf_bundle_source_ssp, tvb, dict_data->src_scheme_pos,
498
266
                            dict_data->src_scheme_len + dict_data->src_ssp_len,
499
266
                            wmem_strdup_printf(pinfo->pool, "%d.%d", dict_data->source_scheme_offset, dict_data->source_ssp_offset));
500
501
266
            src_node = wmem_strdup_printf(pinfo->pool, "%s:%d.%d", IPN_SCHEME_STR,
502
266
                                          dict_data->source_scheme_offset, dict_data->source_ssp_offset);
503
266
        }
504
505
        /*
506
         * Report to info
507
         */
508
401
        if (dict_data->report_scheme_offset == 0 && dict_data->report_ssp_offset == 0)
509
78
        {
510
78
            proto_tree_add_string(dict_tree, hf_bundle_report_scheme, tvb, 0, 0, DTN_SCHEME_STR);
511
78
            proto_tree_add_string(dict_tree, hf_bundle_report_ssp, tvb, dict_data->rpt_scheme_pos,
512
78
                            dict_data->rpt_scheme_len + dict_data->rpt_ssp_len, "none");
513
78
        }
514
323
        else
515
323
        {
516
323
            proto_tree_add_string(dict_tree, hf_bundle_report_scheme, tvb, 0, 0, IPN_SCHEME_STR);
517
323
            proto_tree_add_string(dict_tree, hf_bundle_report_ssp, tvb, dict_data->rpt_scheme_pos,
518
323
                            dict_data->rpt_scheme_len + dict_data->rpt_ssp_len,
519
323
                            wmem_strdup_printf(pinfo->pool, "%d.%d", dict_data->report_scheme_offset, dict_data->report_ssp_offset));
520
323
        }
521
522
        /*
523
         * Custodian info
524
         */
525
401
        if (dict_data->cust_scheme_offset == 0 && dict_data->cust_ssp_offset == 0)
526
81
        {
527
81
            proto_tree_add_string(dict_tree, hf_bundle_custodian_scheme, tvb, 0, 0, DTN_SCHEME_STR);
528
81
            proto_tree_add_string(dict_tree, hf_bundle_custodian_ssp, tvb, dict_data->cust_scheme_pos,
529
81
                            dict_data->cust_scheme_len + dict_data->cust_ssp_len, "none");
530
81
        }
531
320
        else
532
320
        {
533
320
            proto_tree_add_string(dict_tree, hf_bundle_custodian_scheme, tvb, 0, 0, IPN_SCHEME_STR);
534
320
            proto_tree_add_string(dict_tree, hf_bundle_custodian_ssp, tvb, dict_data->cust_scheme_pos,
535
320
                            dict_data->cust_scheme_len + dict_data->cust_ssp_len,
536
320
                            wmem_strdup_printf(pinfo->pool, "%d.%d", dict_data->cust_scheme_offset, dict_data->cust_ssp_offset));
537
320
        }
538
539
        /* remember custodian, for use in checking cteb validity */
540
401
        col_set_writable(pinfo->cinfo, COL_INFO, true);
541
401
        col_clear_fence(pinfo->cinfo, COL_INFO);
542
401
        if (col_text && strstr(col_text, " > ")) {
543
0
            if (! strstr(col_text, "[multiple]")) {
544
0
                col_append_str(pinfo->cinfo, COL_INFO, ", [multiple]");
545
0
            }
546
401
        } else {
547
401
            col_clear(pinfo->cinfo, COL_INFO);
548
401
            col_add_fstr(pinfo->cinfo, COL_INFO, "%s > %s %d.%d", src_node, dst_node, creation_timestamp, timestamp_sequence);
549
401
        }
550
401
        col_set_fence(pinfo->cinfo, COL_INFO);
551
552
401
        *bundle_custodian = wmem_strdup_printf(pinfo->pool, "%s:%d.%d", IPN_SCHEME_STR,
553
401
                                               dict_data->cust_scheme_offset, dict_data->cust_ssp_offset);
554
401
    }
555
556
    /*
557
     * This pointer can be made to address outside the packet boundaries so we
558
     * need to check for improperly formatted strings (no null termination).
559
     */
560
561
194
    else
562
194
    {
563
        /*
564
         * Destination info
565
         */
566
567
194
        proto_tree_add_item(dict_tree, hf_bundle_dest_scheme,
568
194
                            tvb, offset + dict_data->dest_scheme_offset, -1, ENC_ASCII);
569
194
        proto_tree_add_item(dict_tree, hf_bundle_dest_ssp,
570
194
                            tvb, offset + dict_data->dest_ssp_offset, -1, ENC_ASCII);
571
572
        /*
573
         * Source info
574
         */
575
576
194
        proto_tree_add_item(dict_tree, hf_bundle_source_scheme,
577
194
                            tvb, offset + dict_data->source_scheme_offset, -1, ENC_ASCII);
578
194
        proto_tree_add_item(dict_tree, hf_bundle_source_ssp,
579
194
                            tvb, offset + dict_data->source_ssp_offset, -1, ENC_ASCII);
580
581
        /*
582
         * Report to info
583
         */
584
585
194
        proto_tree_add_item(dict_tree, hf_bundle_report_scheme,
586
194
                            tvb, offset + dict_data->report_scheme_offset, -1, ENC_ASCII);
587
194
        proto_tree_add_item(dict_tree, hf_bundle_report_ssp,
588
194
                            tvb, offset + dict_data->report_ssp_offset, -1, ENC_ASCII);
589
590
        /*
591
         * Custodian info
592
         */
593
594
194
        proto_tree_add_item(dict_tree, hf_bundle_custodian_scheme, tvb, offset + dict_data->cust_scheme_offset, -1, ENC_ASCII);
595
194
        proto_tree_add_item(dict_tree, hf_bundle_custodian_ssp, tvb, offset + dict_data->cust_ssp_offset, -1, ENC_ASCII);
596
597
        /*
598
         * Add Source/Destination to INFO Field
599
         */
600
601
194
        col_set_writable(pinfo->cinfo, COL_INFO, true);
602
194
        col_clear_fence(pinfo->cinfo, COL_INFO);
603
194
        if (col_text && strstr(col_text, " > "))
604
0
            col_append_str(pinfo->cinfo, COL_INFO, ", [multiple]");
605
194
        else {
606
194
            col_clear(pinfo->cinfo, COL_INFO);
607
194
            col_add_fstr(pinfo->cinfo, COL_INFO, "%s:%s > %s:%s %d.%d",
608
194
                         tvb_get_stringz_enc(pinfo->pool, tvb, offset + dict_data->source_scheme_offset, NULL, ENC_ASCII),
609
194
                         tvb_get_stringz_enc(pinfo->pool, tvb, offset + dict_data->source_ssp_offset, NULL, ENC_ASCII),
610
194
                         tvb_get_stringz_enc(pinfo->pool, tvb, offset + dict_data->dest_scheme_offset, NULL, ENC_ASCII),
611
194
                         tvb_get_stringz_enc(pinfo->pool, tvb, offset + dict_data->dest_ssp_offset, NULL, ENC_ASCII),
612
194
                         creation_timestamp, timestamp_sequence);
613
194
        }
614
194
        col_set_fence(pinfo->cinfo, COL_INFO);
615
616
617
        /* remember custodian, for use in checking cteb validity */
618
194
        *bundle_custodian = wmem_strdup_printf(pinfo->pool,
619
194
                                               "%s:%s",
620
194
                                               tvb_get_stringz_enc(pinfo->pool,
621
194
                                                               tvb, offset + dict_data->cust_scheme_offset,
622
194
                                                               NULL, ENC_ASCII),
623
194
                                               tvb_get_stringz_enc(pinfo->pool,
624
194
                                                               tvb, offset + dict_data->cust_ssp_offset,
625
194
                                                               NULL, ENC_ASCII));
626
194
    }
627
595
    offset += dict_data->bundle_header_dict_length;        /*Skip over dictionary*/
628
629
    /*
630
     * Do this only if Fragment Flag is set
631
     */
632
633
595
    if (pri_hdr_procflags & BUNDLE_PROCFLAGS_FRAG_MASK) {
634
189
        int sdnv_length;
635
189
        sdnv_length = add_sdnv_to_tree(tree, tvb, pinfo, offset, hf_bundle_primary_fragment_offset);
636
189
        if (sdnv_length < 0) {
637
0
            return 0;
638
0
        }
639
189
        offset += sdnv_length;
640
641
189
        sdnv_length = add_sdnv_to_tree(tree, tvb, pinfo, offset, hf_bundle_primary_total_adu_len);
642
189
        if (sdnv_length < 0) {
643
0
            return 0;
644
0
        }
645
189
        offset += sdnv_length;
646
189
    }
647
648
595
    return offset;
649
595
}
650
651
/*
652
 * This routine returns 0 if header decoding fails, otherwise the length of the primary
653
 * header, starting right after version number.
654
 */
655
static int
656
dissect_version_4_primary_header(packet_info *pinfo, proto_tree *primary_tree, tvbuff_t *tvb,
657
                                 uint8_t* pri_hdr_procflags, char **bundle_custodian)
658
28
{
659
28
    int bundle_header_length;
660
28
    int offset = 1;             /* Version Number already displayed */
661
28
    int sdnv_length;
662
28
    dictionary_data_t dict_data;
663
664
28
    proto_item *ti;
665
28
    proto_tree *srr_flag_tree, *proc_flag_tree, *cos_flag_tree;
666
667
    /* Primary Header Processing Flags */
668
28
    *pri_hdr_procflags = tvb_get_uint8(tvb, offset);
669
28
    ti = proto_tree_add_item(primary_tree, hf_bundle_procflags, tvb,
670
28
                                                offset, 1, ENC_BIG_ENDIAN);
671
28
    proc_flag_tree = proto_item_add_subtree(ti, ett_proc_flags);
672
28
    proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_fragment,
673
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
674
28
    proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_admin,
675
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
676
28
    proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_dont_fragment,
677
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
678
28
    proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_cust_xfer_req,
679
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
680
28
    proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_dest_singleton,
681
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
682
683
    /* Primary Header COS Flags */
684
28
    ++offset;
685
28
    ti = proto_tree_add_item(primary_tree, hf_bundle_cosflags, tvb,
686
28
                                                offset, 1, ENC_BIG_ENDIAN);
687
28
    cos_flag_tree = proto_item_add_subtree(ti, ett_cos_flags);
688
28
    proto_tree_add_item(cos_flag_tree, hf_bundle_cosflags_priority,
689
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
690
    /* Status Report Request Flags */
691
28
    ++offset;
692
28
    ti = proto_tree_add_item(primary_tree, hf_bundle_srrflags, tvb,
693
28
                                                offset, 1, ENC_BIG_ENDIAN);
694
28
    srr_flag_tree = proto_item_add_subtree(ti, ett_srr_flags);
695
696
28
    proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_receipt,
697
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
698
28
    proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_cust_accept,
699
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
700
28
    proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_forward,
701
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
702
28
    proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_delivery,
703
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
704
28
    proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_deletion,
705
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
706
28
    proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_ack,
707
28
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
708
28
    ++offset;
709
710
28
    bundle_header_length = evaluate_sdnv(tvb, offset, &sdnv_length);
711
28
    ti = proto_tree_add_int(primary_tree, hf_bundle_primary_header_len, tvb, offset, sdnv_length,
712
28
                            bundle_header_length);
713
28
    if (bundle_header_length < 0) {
714
1
        expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Bundle Header Length Error");
715
1
        return tvb_reported_length_remaining(tvb, offset);
716
1
    }
717
718
27
    offset += sdnv_length;
719
720
    /* Ensure all fields have been initialized */
721
27
    memset(&dict_data, 0, sizeof(dict_data));
722
723
    /*
724
     * Pick up offsets into dictionary (8 of them)
725
     */
726
727
27
    dict_data.dest_scheme_offset = tvb_get_ntohs(tvb, offset);
728
27
    dict_data.dst_scheme_pos = offset;
729
27
    dict_data.dst_scheme_len = 2;
730
27
    proto_tree_add_item(primary_tree, hf_bundle_dest_scheme_offset_u16,
731
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
732
27
    offset += 2;
733
734
27
    dict_data.dest_ssp_offset = tvb_get_ntohs(tvb, offset);
735
27
    dict_data.dst_ssp_len = 2;
736
27
    proto_tree_add_item(primary_tree, hf_bundle_dest_ssp_offset_u16,
737
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
738
27
    offset += 2;
739
740
27
    dict_data.source_scheme_offset = tvb_get_ntohs(tvb, offset);
741
27
    dict_data.src_scheme_pos = offset;
742
27
    dict_data.src_scheme_len = 2;
743
27
    proto_tree_add_item(primary_tree, hf_bundle_source_scheme_offset_u16,
744
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
745
27
    offset += 2;
746
747
27
    dict_data.source_ssp_offset = tvb_get_ntohs(tvb, offset);
748
27
    dict_data.src_ssp_len = 2;
749
27
    proto_tree_add_item(primary_tree, hf_bundle_source_ssp_offset_u16,
750
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
751
27
    offset += 2;
752
753
27
    dict_data.report_scheme_offset = tvb_get_ntohs(tvb, offset);
754
27
    dict_data.rpt_scheme_pos = offset;
755
27
    dict_data.rpt_scheme_len = 2;
756
27
    proto_tree_add_item(primary_tree, hf_bundle_report_scheme_offset_u16,
757
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
758
27
    offset += 2;
759
760
27
    dict_data.report_ssp_offset = tvb_get_ntohs(tvb, offset);
761
27
    dict_data.rpt_ssp_len = 2;
762
27
    proto_tree_add_item(primary_tree, hf_bundle_report_ssp_offset_u16,
763
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
764
27
    offset += 2;
765
766
27
    dict_data.cust_scheme_offset = tvb_get_ntohs(tvb, offset);
767
27
    dict_data.cust_scheme_pos = offset;
768
27
    dict_data.cust_scheme_len = 2;
769
27
    proto_tree_add_item(primary_tree, hf_bundle_cust_scheme_offset_u16,
770
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
771
27
    offset += 2;
772
773
27
    dict_data.cust_ssp_offset = tvb_get_ntohs(tvb, offset);
774
27
    dict_data.cust_ssp_len = 2;
775
27
    proto_tree_add_item(primary_tree, hf_bundle_cust_ssp_offset_u16,
776
27
                                                        tvb, offset, 2, ENC_BIG_ENDIAN);
777
27
    offset += 2;
778
779
27
    proto_tree_add_item(primary_tree, hf_bundle_creation_timestamp,
780
27
                                                        tvb, offset, 8, ENC_BIG_ENDIAN);
781
27
    offset += 8;
782
783
27
    proto_tree_add_item(primary_tree, hf_bundle_lifetime, tvb, offset, 4, ENC_BIG_ENDIAN);
784
27
    offset += 4;
785
786
27
    dict_data.bundle_header_dict_length = evaluate_sdnv(tvb, offset, &sdnv_length);
787
27
    ti = proto_tree_add_int(primary_tree, hf_bundle_primary_dictionary_len, tvb, offset, sdnv_length,
788
27
                            dict_data.bundle_header_dict_length);
789
27
    if (dict_data.bundle_header_dict_length < 0) {
790
5
        expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Dictionary Header Length Error");
791
5
        return tvb_reported_length_remaining(tvb, offset);
792
5
    }
793
22
    offset += sdnv_length;
794
795
22
    offset = dissect_dictionary(pinfo, primary_tree, tvb, offset, &dict_data, *pri_hdr_procflags, bundle_custodian, 0, 0);
796
22
    return offset;
797
27
}
798
799
800
/*
801
 * This routine returns 0 if header decoding fails, otherwise the length of the primary
802
 * header, starting right after version number.
803
 */
804
805
static int src_ssp;
806
static int dst_ssp;
807
808
static int
809
dissect_version_5_and_6_primary_header(packet_info *pinfo,
810
                                       proto_tree *primary_tree, tvbuff_t *tvb,
811
                                       uint8_t* pri_hdr_procflags, char **bundle_custodian)
812
660
{
813
660
    uint64_t           bundle_processing_control_flags;
814
660
    uint8_t            cosflags;
815
660
    int                bundle_header_length;
816
660
    int                offset = 1; /* Version Number already displayed */
817
660
    int                sdnv_length;
818
660
    dictionary_data_t  dict_data;
819
660
    int                timestamp_sequence;
820
660
    int                creation_timestamp;
821
660
    uint8_t            srrflags;
822
660
    proto_item        *ti;
823
660
    proto_item        *ti_dst_scheme_offset, *ti_dst_ssp_offset;
824
660
    proto_item        *ti_src_scheme_offset, *ti_src_ssp_offset;
825
660
    proto_item        *ti_cust_scheme_offset, *ti_cust_ssp_offset;
826
660
    proto_item        *ti_rprt_scheme_offset, *ti_rprt_ssp_offset;
827
660
    proto_tree        *gen_flag_tree, *srr_flag_tree, *proc_flag_tree, *cos_flag_tree;
828
660
    static int * const pri_flags[] = {
829
660
        &hf_bundle_procflags_fragment,
830
660
        &hf_bundle_procflags_admin,
831
660
        &hf_bundle_procflags_dont_fragment,
832
660
        &hf_bundle_procflags_cust_xfer_req,
833
660
        &hf_bundle_procflags_dest_singleton,
834
660
        &hf_bundle_procflags_application_ack,
835
660
        NULL
836
660
    };
837
838
660
    static int * const srr_flags[] = {
839
660
        &hf_bundle_srrflags_report_receipt,
840
660
        &hf_bundle_srrflags_report_cust_accept,
841
660
        &hf_bundle_srrflags_report_forward,
842
660
        &hf_bundle_srrflags_report_delivery,
843
660
        &hf_bundle_srrflags_report_deletion,
844
660
        NULL
845
660
    };
846
847
660
    bundle_processing_control_flags = evaluate_sdnv_64(tvb, offset, &sdnv_length);
848
849
    /* Primary Header Processing Flags */
850
660
    *pri_hdr_procflags = (uint8_t) (bundle_processing_control_flags & 0x7f);
851
852
660
    if (sdnv_length < 1 || sdnv_length > 8) {
853
3
        expert_add_info_format(pinfo, primary_tree, &ei_bundle_control_flags_length,
854
3
                               "Wrong bundle control flag length: %d", sdnv_length);
855
3
        return 0;
856
3
    }
857
657
    ti = proto_tree_add_item(primary_tree, hf_bundle_control_flags, tvb,
858
657
                                                offset, sdnv_length, ENC_BIG_ENDIAN);
859
657
    proc_flag_tree = proto_item_add_subtree(ti, ett_proc_flags);
860
861
657
    ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_general, tvb, offset,
862
657
                                        sdnv_length, *pri_hdr_procflags);
863
657
    gen_flag_tree = proto_item_add_subtree(ti, ett_gen_flags);
864
865
    /* With the variability of sdnv_length, proto_tree_add_bitmask_value
866
       can't be used */
867
868
657
    proto_tree_add_bitmask_list_value(gen_flag_tree, tvb, offset, sdnv_length, pri_flags, *pri_hdr_procflags);
869
870
    /* Primary Header COS Flags */
871
657
    cosflags = (uint8_t) ((bundle_processing_control_flags >> 7) & 0x7f);
872
657
    ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_cos, tvb, offset,
873
657
                                        sdnv_length, cosflags);
874
657
    cos_flag_tree = proto_item_add_subtree(ti, ett_cos_flags);
875
657
    proto_tree_add_uint(cos_flag_tree, hf_bundle_cosflags_priority, tvb, offset,
876
657
                                    sdnv_length, cosflags);
877
878
    /* Status Report Request Flags */
879
657
    srrflags = (uint8_t) ((bundle_processing_control_flags >> 14) & 0x7f);
880
657
    ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_status, tvb, offset,
881
657
                                        sdnv_length, srrflags);
882
657
    srr_flag_tree = proto_item_add_subtree(ti, ett_srr_flags);
883
884
657
    proto_tree_add_bitmask_list_value(srr_flag_tree, tvb, offset, sdnv_length, srr_flags, srrflags);
885
657
    offset += sdnv_length;
886
887
    /* -- hdr_length -- */
888
657
    bundle_header_length = evaluate_sdnv(tvb, offset, &sdnv_length);
889
657
    ti = proto_tree_add_int(primary_tree, hf_bundle_primary_header_len, tvb, offset, sdnv_length,
890
657
                            bundle_header_length);
891
657
    if (bundle_header_length < 0) {
892
3
        expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Bundle Header Length Error");
893
3
        return tvb_reported_length_remaining(tvb, offset);
894
3
    }
895
896
654
    offset += sdnv_length;
897
898
    /*
899
     * Pick up offsets into dictionary (8 of them). Do rough sanity check that SDNV
900
     * hasn't told us to access way past the Primary Header.
901
     */
902
903
    /* Ensure all fields have been initialized */
904
654
    memset(&dict_data, 0, sizeof(dict_data));
905
906
    /* -- dest_scheme -- */
907
654
    dict_data.dest_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
908
654
    dict_data.dst_scheme_pos = offset;
909
654
    dict_data.dst_scheme_len = sdnv_length;
910
911
654
    ti_dst_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_dest_scheme_offset_i32, tvb, offset, sdnv_length,
912
654
                            dict_data.dest_scheme_offset);
913
654
    offset += sdnv_length;
914
915
    /* -- dest_ssp -- */
916
654
    dict_data.dest_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
917
654
    dict_data.dst_ssp_len = sdnv_length;
918
654
    dst_ssp = dict_data.dest_ssp_offset;
919
920
654
    ti_dst_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_dest_ssp_offset_i32, tvb, offset, sdnv_length,
921
654
                            dict_data.dest_ssp_offset);
922
654
    offset += sdnv_length;
923
924
    /* -- source_scheme -- */
925
654
    dict_data.source_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
926
654
    dict_data.src_scheme_pos = offset;
927
654
    dict_data.src_scheme_len = sdnv_length;
928
929
654
    ti_src_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_source_scheme_offset_i32, tvb, offset, sdnv_length,
930
654
                            dict_data.source_scheme_offset);
931
654
    offset += sdnv_length;
932
933
    /* -- source_ssp -- */
934
654
    dict_data.source_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
935
654
    dict_data.src_ssp_len = sdnv_length;
936
654
    src_ssp = dict_data.source_ssp_offset;
937
938
654
    ti_src_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_source_ssp_offset_i32, tvb, offset, sdnv_length,
939
654
                            dict_data.source_ssp_offset);
940
654
    offset += sdnv_length;
941
942
    /* -- report_scheme -- */
943
654
    dict_data.report_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
944
654
    dict_data.rpt_scheme_pos = offset;
945
654
    dict_data.rpt_scheme_len = sdnv_length;
946
947
654
    ti_rprt_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_report_scheme_offset_i32, tvb, offset,
948
654
                            sdnv_length, dict_data.report_scheme_offset);
949
654
    offset += sdnv_length;
950
951
    /* -- report_ssp -- */
952
654
    dict_data.report_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
953
654
    dict_data.rpt_ssp_len = sdnv_length;
954
955
654
    ti_rprt_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_report_ssp_offset_i32, tvb, offset, sdnv_length,
956
654
                            dict_data.report_ssp_offset);
957
654
    offset += sdnv_length;
958
959
960
    /* -- cust_scheme -- */
961
654
    dict_data.cust_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
962
654
    dict_data.cust_scheme_pos = offset;
963
654
    dict_data.cust_scheme_len = sdnv_length;
964
965
654
    ti_cust_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_cust_scheme_offset_i32, tvb, offset, sdnv_length,
966
654
                            dict_data.cust_scheme_offset);
967
654
    offset += sdnv_length;
968
969
    /* -- cust_ssp -- */
970
654
    dict_data.cust_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
971
654
    dict_data.cust_ssp_len = sdnv_length;
972
973
654
    ti_cust_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_cust_ssp_offset_i32, tvb, offset, sdnv_length,
974
654
                            dict_data.cust_ssp_offset);
975
654
    offset += sdnv_length;
976
977
978
654
    creation_timestamp = evaluate_sdnv(tvb, offset, &sdnv_length);
979
654
    sdnv_length = add_sdnv_time_to_tree(primary_tree, tvb, offset, hf_bundle_primary_timestamp);
980
654
    if (sdnv_length == 0)
981
8
        return 0;
982
983
646
    offset += sdnv_length;
984
985
    /* -- timestamp_sequence -- */
986
646
    timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
987
646
    if (timestamp_sequence < 0) {
988
5
        int64_t ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
989
990
5
        ti = proto_tree_add_int64(primary_tree, hf_bundle_primary_timestamp_seq_num64,
991
5
                                                        tvb, offset, sdnv_length, ts_seq);
992
5
        if (ts_seq < 0) {
993
5
            expert_add_info(pinfo, ti, &ei_bundle_timestamp_seq_num);
994
5
        }
995
5
    }
996
641
    else {
997
641
        proto_tree_add_int(primary_tree, hf_bundle_primary_timestamp_seq_num32,
998
641
                                                        tvb, offset, sdnv_length, timestamp_sequence);
999
641
    }
1000
646
    offset += sdnv_length;
1001
1002
    /* -- lifetime -- */
1003
646
    sdnv_length = add_sdnv_to_tree(primary_tree, tvb, pinfo, offset, hf_bundle_lifetime_sdnv);
1004
646
    offset += sdnv_length;
1005
1006
    /* -- dict_length -- */
1007
646
    dict_data.bundle_header_dict_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1008
646
    ti = proto_tree_add_int(primary_tree, hf_bundle_primary_dictionary_len, tvb, offset, sdnv_length,
1009
646
                            dict_data.bundle_header_dict_length);
1010
646
    if (dict_data.bundle_header_dict_length < 0) {
1011
11
        expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Dictionary Header Length Error");
1012
11
        return tvb_reported_length_remaining(tvb, offset);
1013
11
    }
1014
635
    offset += sdnv_length;
1015
1016
635
    if ((dict_data.dest_scheme_offset < 0) ||
1017
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.dest_scheme_offset > bundle_header_length))) {
1018
61
        expert_add_info_format(pinfo, ti_dst_scheme_offset, &ei_bundle_offset_error, "Destination Scheme Offset Error");
1019
61
    }
1020
635
    if ((dict_data.dest_ssp_offset < 0) ||
1021
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.dest_ssp_offset > bundle_header_length))) {
1022
56
        expert_add_info_format(pinfo, ti_dst_ssp_offset, &ei_bundle_offset_error, "Destination SSP Offset Error");
1023
56
    }
1024
635
    if ((dict_data.source_scheme_offset < 0) ||
1025
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.source_scheme_offset > bundle_header_length))) {
1026
53
        expert_add_info_format(pinfo, ti_src_scheme_offset, &ei_bundle_offset_error, "Source Scheme Offset Error");
1027
53
    }
1028
635
    if ((dict_data.source_ssp_offset < 0) ||
1029
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.source_ssp_offset > bundle_header_length))) {
1030
48
        expert_add_info_format(pinfo, ti_src_ssp_offset, &ei_bundle_offset_error, "Source SSP Offset Error");
1031
48
    }
1032
635
    if ((dict_data.report_scheme_offset < 0) ||
1033
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.report_scheme_offset > bundle_header_length))) {
1034
66
        expert_add_info_format(pinfo, ti_rprt_scheme_offset, &ei_bundle_offset_error, "Report Scheme Offset Error");
1035
66
    }
1036
635
    if ((dict_data.report_ssp_offset < 0) ||
1037
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.report_ssp_offset > bundle_header_length))) {
1038
65
        expert_add_info_format(pinfo, ti_rprt_ssp_offset, &ei_bundle_offset_error, "Report SSP Offset Error");
1039
65
    }
1040
635
    if ((dict_data.cust_scheme_offset < 0) ||
1041
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.cust_scheme_offset > bundle_header_length))) {
1042
61
        expert_add_info_format(pinfo, ti_cust_scheme_offset, &ei_bundle_offset_error, "Custodian Scheme Offset Error");
1043
61
    }
1044
635
    if ((dict_data.cust_ssp_offset < 0) ||
1045
635
        (dict_data.bundle_header_dict_length > 0 && (dict_data.cust_ssp_offset > bundle_header_length))) {
1046
67
        expert_add_info_format(pinfo, ti_cust_ssp_offset, &ei_bundle_offset_error, "Custodian SSP Offset Error");
1047
67
    }
1048
1049
635
    offset = dissect_dictionary(pinfo, primary_tree, tvb, offset, &dict_data, *pri_hdr_procflags, bundle_custodian,
1050
635
                                creation_timestamp, timestamp_sequence);
1051
635
    return offset;
1052
646
}
1053
1054
/*
1055
 * offset is where the header starts.
1056
 * Return new offset, and set lastheader if failure.
1057
 */
1058
static int
1059
dissect_payload_header(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, uint8_t version,
1060
                       uint8_t pri_hdr_procflags, bool *lastheader)
1061
808
{
1062
808
    proto_item *payload_block, *payload_item, *ti;
1063
808
    proto_tree *payload_block_tree, *payload_tree;
1064
808
    int         sdnv_length, payload_length;
1065
1066
808
    payload_block_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_payload_hdr, &payload_block, "Payload Block");
1067
1068
808
    payload_tree = proto_tree_add_subtree(payload_block_tree, tvb, offset, -1, ett_payload_hdr, &payload_item, "Payload Header");
1069
1070
808
    proto_tree_add_uint(payload_tree, hf_bundle_payload_header_type, tvb, offset, 1, 1);
1071
808
    ++offset;
1072
1073
    /* Add tree for processing flags */
1074
    /* This is really a SDNV but there are only 7 bits defined so leave it this way*/
1075
1076
808
    if (version == 4) {
1077
12
        static int * const flags[] = {
1078
12
            &hf_bundle_payload_flags_replicate_hdr,
1079
12
            &hf_bundle_payload_flags_xmit_report,
1080
12
            &hf_bundle_payload_flags_discard_on_fail,
1081
12
            &hf_bundle_payload_flags_last_header,
1082
12
            NULL
1083
12
        };
1084
12
        uint8_t     procflags;
1085
1086
12
        procflags = tvb_get_uint8(tvb, offset);
1087
12
        if (procflags & HEADER_PROCFLAGS_LAST_HEADER) {
1088
2
            *lastheader = true;
1089
2
        }
1090
10
        else {
1091
10
            *lastheader = false;
1092
10
        }
1093
12
        proto_tree_add_bitmask(payload_tree, tvb, offset, hf_bundle_payload_flags,
1094
12
                               ett_payload_flags, flags, ENC_BIG_ENDIAN);
1095
12
        ++offset;
1096
12
    }
1097
796
    else {      /*Bundle Protocol Version 5*/
1098
796
        int control_flags;
1099
796
        proto_item *block_flag_item;
1100
796
        proto_tree *block_flag_tree;
1101
1102
796
        control_flags = evaluate_sdnv(tvb, offset, &sdnv_length);
1103
796
        if (control_flags & BLOCK_CONTROL_LAST_BLOCK) {
1104
23
            *lastheader = true;
1105
23
        }
1106
773
        else {
1107
773
            *lastheader = false;
1108
773
        }
1109
796
        block_flag_item = proto_tree_add_item(payload_tree, hf_block_control_flags, tvb,
1110
796
                                                offset, sdnv_length, ENC_BIG_ENDIAN);
1111
796
        block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1112
1113
796
        proto_tree_add_item(block_flag_tree, hf_block_control_replicate,
1114
796
                                        tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1115
796
        proto_tree_add_item(block_flag_tree, hf_block_control_transmit_status,
1116
796
                                        tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1117
796
        proto_tree_add_item(block_flag_tree, hf_block_control_delete_bundle,
1118
796
                                        tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1119
796
        proto_tree_add_item(block_flag_tree, hf_block_control_last_block,
1120
796
                                        tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1121
796
        proto_tree_add_item(block_flag_tree, hf_block_control_discard_block,
1122
796
                                        tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1123
796
        proto_tree_add_item(block_flag_tree, hf_block_control_not_processed,
1124
796
                                        tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1125
796
        proto_tree_add_item(block_flag_tree, hf_block_control_eid_reference,
1126
796
                                        tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1127
796
        offset += sdnv_length;
1128
796
    }
1129
1130
808
    payload_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1131
808
    ti = proto_tree_add_int(payload_tree, hf_bundle_payload_length, tvb, offset, sdnv_length, payload_length);
1132
808
    if (payload_length < 0) {
1133
2
        expert_add_info(pinfo, ti, &ei_bundle_payload_length);
1134
        /* Force quitting */
1135
2
        *lastheader = true;
1136
2
        return offset;
1137
2
    }
1138
1139
806
    proto_item_set_len(payload_item, 2 + sdnv_length);
1140
806
    proto_item_set_len(payload_block, 2 + sdnv_length + payload_length);
1141
1142
806
    offset += sdnv_length;
1143
806
    if (pri_hdr_procflags & BUNDLE_PROCFLAGS_ADMIN_MASK) {
1144
572
        bool success = false;
1145
1146
        /*
1147
         * XXXX - Have not allowed for admin record spanning multiple segments!
1148
         */
1149
1150
572
        offset = dissect_admin_record(payload_block_tree, tvb, pinfo, offset, payload_length, &success);
1151
572
        if (!success) {
1152
            /* Force quitting */
1153
26
            *lastheader = true;
1154
26
            return offset;
1155
26
        }
1156
572
    } else {
1157
        /* If Source SSP Offset is 64 and Destination SSP offset is 65, then
1158
           interpret the payload-data part as CFDP. */
1159
234
        if (src_ssp == 0x40 &&
1160
234
            dst_ssp == 0x41)
1161
0
          {
1162
0
            dissect_cfdp_as_subtree (tvb, pinfo, payload_block_tree, offset);
1163
0
          }
1164
        /* If Source SSP Offset is 5 and Destination SSP offset is 6, then
1165
           interpret the payload-data part as AMP. */
1166
234
        else if ((src_ssp == 0x5 && dst_ssp == 0x6) ||
1167
234
                 (dst_ssp == 0x5 && src_ssp == 0x6))
1168
95
          {
1169
95
            dissect_amp_as_subtree (tvb, pinfo, payload_block_tree, offset);
1170
95
          }
1171
139
        else
1172
139
          {
1173
139
            proto_tree_add_string(payload_block_tree, hf_bundle_payload_data, tvb, offset, payload_length,
1174
139
                                  wmem_strdup_printf(pinfo->pool, "<%d bytes>",payload_length));
1175
139
          }
1176
1177
234
        offset += payload_length;
1178
234
    }
1179
1180
780
    return offset;
1181
806
}
1182
1183
/*
1184
 * Return the offset after the Administrative Record or set success = false if analysis fails.
1185
 */
1186
static int
1187
dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, packet_info *pinfo,
1188
                     int offset, int payload_length, bool* success)
1189
572
{
1190
572
    proto_item *admin_record_item;
1191
572
    proto_tree *admin_record_tree;
1192
572
    proto_item *timestamp_sequence_item;
1193
572
    uint8_t     record_type;
1194
572
    uint8_t     status;
1195
572
    int         start_offset = offset;
1196
572
    int         sdnv_length;
1197
572
    int         timestamp_sequence;
1198
572
    int         endpoint_length;
1199
1200
572
    *success = false;
1201
572
    admin_record_tree = proto_tree_add_subtree(primary_tree, tvb, offset, -1,
1202
572
                        ett_admin_record, &admin_record_item, "Administrative Record");
1203
572
    record_type = tvb_get_uint8(tvb, offset);
1204
1205
572
    proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1206
1207
572
    switch ((record_type >> 4) & 0xf)
1208
572
    {
1209
73
    case ADMIN_REC_TYPE_STATUS_REPORT:
1210
73
    {
1211
73
        proto_item *status_flag_item;
1212
73
        proto_tree *status_flag_tree;
1213
1214
73
        proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1215
73
        ++offset;
1216
1217
        /* Decode Bundle Status Report Flags */
1218
73
        status = tvb_get_uint8(tvb, offset);
1219
73
        status_flag_item = proto_tree_add_item(admin_record_tree,
1220
73
                                hf_bundle_admin_statflags, tvb, offset, 1, ENC_BIG_ENDIAN);
1221
73
        status_flag_tree = proto_item_add_subtree(status_flag_item,
1222
73
                                                        ett_admin_rec_status);
1223
73
        proto_tree_add_item(status_flag_tree, hf_bundle_admin_rcvd,
1224
73
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
1225
73
        proto_tree_add_item(status_flag_tree, hf_bundle_admin_accepted,
1226
73
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
1227
73
        proto_tree_add_item(status_flag_tree, hf_bundle_admin_forwarded,
1228
73
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
1229
73
        proto_tree_add_item(status_flag_tree, hf_bundle_admin_delivered,
1230
73
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
1231
73
        proto_tree_add_item(status_flag_tree, hf_bundle_admin_deleted,
1232
73
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
1233
73
        proto_tree_add_item(status_flag_tree, hf_bundle_admin_acked,
1234
73
                                                tvb, offset, 1, ENC_BIG_ENDIAN);
1235
73
        ++offset;
1236
1237
73
        proto_tree_add_item(admin_record_tree, hf_bundle_status_report_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1238
73
        ++offset;
1239
1240
73
        if (record_type & ADMIN_REC_FLAGS_FRAGMENT) {
1241
64
            sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_offset);
1242
64
            if (sdnv_length <= 0) {
1243
0
                return offset;
1244
0
            }
1245
64
            offset += sdnv_length;
1246
64
            sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_length);
1247
64
            if (sdnv_length <= 0) {
1248
1
                return offset;
1249
1
            }
1250
63
            offset += sdnv_length;
1251
63
        }
1252
72
        if (status & ADMIN_STATUS_FLAGS_RECEIVED) {
1253
59
            sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_receipt_time);
1254
59
            if (sdnv_length <= 0) {
1255
1
                return offset;
1256
1
            }
1257
58
            offset += sdnv_length;
1258
58
        }
1259
71
        if (status & ADMIN_STATUS_FLAGS_ACCEPTED) {
1260
49
            sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_accept_time);
1261
49
            if (sdnv_length <= 0) {
1262
0
                return offset;
1263
0
            }
1264
49
            offset += sdnv_length;
1265
49
        }
1266
71
        if (status & ADMIN_STATUS_FLAGS_FORWARDED) {
1267
13
            sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_forward_time);
1268
13
            if (sdnv_length <= 0) {
1269
1
                return offset;
1270
1
            }
1271
12
            offset += sdnv_length;
1272
12
        }
1273
70
        if (status & ADMIN_STATUS_FLAGS_DELIVERED) {
1274
15
            sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_delivery_time);
1275
15
            if (sdnv_length <= 0) {
1276
1
                return offset;
1277
1
            }
1278
14
            offset += sdnv_length;
1279
14
        }
1280
69
        if (status & ADMIN_STATUS_FLAGS_DELETED) {
1281
53
            sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_delete_time);
1282
53
            if (sdnv_length <= 0) {
1283
1
                return offset;
1284
1
            }
1285
52
            offset += sdnv_length;
1286
52
        }
1287
68
        if (status & ADMIN_STATUS_FLAGS_ACKNOWLEDGED) {
1288
5
            sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_ack_time);
1289
5
            if (sdnv_length <= 0) {
1290
0
                return offset;
1291
0
            }
1292
5
            offset += sdnv_length;
1293
5
        }
1294
1295
        /* Get 2 SDNVs for Creation Timestamp */
1296
68
        sdnv_length = add_sdnv_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_timestamp_copy);
1297
68
        if (sdnv_length <= 0) {
1298
1
            return offset;
1299
1
        }
1300
67
        offset += sdnv_length;
1301
1302
67
        timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1303
67
        if (timestamp_sequence < 0) {
1304
1
            int64_t ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1305
1306
1
            timestamp_sequence_item = proto_tree_add_int64(admin_record_tree, hf_bundle_admin_timestamp_seq_num64,
1307
1
                                                            tvb, offset, sdnv_length, ts_seq);
1308
1
            if (ts_seq < 0) {
1309
1
                expert_add_info(pinfo, timestamp_sequence_item, &ei_bundle_timestamp_seq_num);
1310
1
               return offset;
1311
1
            }
1312
1
        }
1313
66
        else {
1314
66
            proto_tree_add_int(admin_record_tree, hf_bundle_admin_timestamp_seq_num32,
1315
66
                                                            tvb, offset, sdnv_length, timestamp_sequence);
1316
66
        }
1317
66
        offset += sdnv_length;
1318
1319
66
        endpoint_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1320
66
        if (endpoint_length < 0) {
1321
1
            return tvb_reported_length_remaining(tvb, offset);
1322
1
        }
1323
65
        proto_tree_add_int(admin_record_tree, hf_bundle_admin_endpoint_length, tvb, offset, sdnv_length, endpoint_length);
1324
65
        offset += sdnv_length;
1325
1326
        /*
1327
         * Endpoint name may not be null terminated. This routine is supposed
1328
         * to add the null at the end of the string buffer.
1329
         */
1330
65
        proto_tree_add_item(admin_record_tree, hf_bundle_admin_endpoint_id, tvb, offset, endpoint_length, ENC_ASCII);
1331
65
        offset += endpoint_length;
1332
1333
65
        break;
1334
66
    } /* case ADMIN_REC_TYPE_STATUS_REPORT */
1335
27
    case ADMIN_REC_TYPE_CUSTODY_SIGNAL:
1336
27
    {
1337
27
        proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1338
27
        ++offset;
1339
1340
27
        proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
1341
27
        proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
1342
27
        ++offset;
1343
1344
27
        if (record_type & ADMIN_REC_FLAGS_FRAGMENT) {
1345
14
            sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_offset);
1346
14
            if (sdnv_length <= 0) {
1347
0
                return offset;
1348
0
            }
1349
14
            offset += sdnv_length;
1350
14
            sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_length);
1351
14
            if (sdnv_length <= 0) {
1352
1
                return offset;
1353
1
            }
1354
13
            offset += sdnv_length;
1355
13
        }
1356
1357
        /* Signal Time */
1358
26
        sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_signal_time);
1359
26
        if (sdnv_length <= 0) {
1360
0
            return offset;
1361
0
        }
1362
26
        offset += sdnv_length;
1363
1364
        /* Timestamp copy */
1365
26
        sdnv_length = add_sdnv_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_timestamp_copy);
1366
26
        if (sdnv_length <= 0) {
1367
1
            return offset;
1368
1
        }
1369
25
        offset += sdnv_length;
1370
1371
25
        timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1372
25
        if (timestamp_sequence < 0) {
1373
1
            int64_t ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1374
1375
1
            timestamp_sequence_item = proto_tree_add_int64(admin_record_tree, hf_bundle_admin_timestamp_seq_num64,
1376
1
                                                            tvb, offset, sdnv_length, ts_seq);
1377
1
            if (ts_seq < 0) {
1378
1
                expert_add_info(pinfo, timestamp_sequence_item, &ei_bundle_timestamp_seq_num);
1379
1
               return offset;
1380
1
            }
1381
1
        }
1382
24
        else {
1383
24
            proto_tree_add_int(admin_record_tree, hf_bundle_admin_timestamp_seq_num32,
1384
24
                                                            tvb, offset, sdnv_length, timestamp_sequence);
1385
24
        }
1386
24
        offset += sdnv_length;
1387
1388
24
        endpoint_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1389
24
        if (endpoint_length < 0) {
1390
1
            return tvb_reported_length_remaining(tvb, offset);
1391
1
        }
1392
23
        proto_tree_add_int(admin_record_tree, hf_bundle_admin_endpoint_length, tvb, offset, sdnv_length, endpoint_length);
1393
23
        offset += sdnv_length;
1394
23
        proto_tree_add_item(admin_record_tree, hf_bundle_admin_endpoint_id, tvb, offset, endpoint_length, ENC_ASCII);
1395
23
        offset += endpoint_length;
1396
23
        break;
1397
24
    } /* case ADMIN_REC_TYPE_CUSTODY_SIGNAL */
1398
23
    case ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL:
1399
23
    {
1400
23
        proto_item *ti;
1401
23
        int payload_bytes_processed = 0;
1402
23
        int right_edge = -1;
1403
23
        int fill_start;
1404
23
        int fill_length = -1;
1405
23
        int sdnv_length_start = -1;
1406
23
        int sdnv_length_gap = -1;
1407
23
        int sdnv_length_length = -1;
1408
1409
23
        proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1410
23
        ++offset;
1411
23
        ++payload_bytes_processed;
1412
1413
23
        proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
1414
23
        proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
1415
23
        ++offset;
1416
23
        ++payload_bytes_processed;
1417
1418
        /* process the first fill */
1419
23
        fill_start = evaluate_sdnv(tvb, offset, &sdnv_length_start);
1420
23
        ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_start, tvb, offset, sdnv_length_start, fill_start);
1421
23
        if (fill_start < 0 || sdnv_length_start < 0) {
1422
1
            expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range start SDNV");
1423
1
            return offset;
1424
1
        }
1425
22
        fill_length = evaluate_sdnv(tvb, offset + sdnv_length_start, &sdnv_length_length);
1426
22
        ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_end, tvb, offset,
1427
22
                                sdnv_length_start + sdnv_length_length, fill_start + fill_length - 1);
1428
22
        if (fill_length < 0 || sdnv_length_length < 0) {
1429
0
            expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range length SDNV");
1430
0
            return tvb_reported_length_remaining(tvb, offset);
1431
0
        }
1432
1433
22
        right_edge = fill_start + fill_length;
1434
22
        offset += sdnv_length_start + sdnv_length_length;
1435
22
        payload_bytes_processed += sdnv_length_start + sdnv_length_length;
1436
1437
        /* now attempt to consume all the rest of the data in the
1438
         * payload as additional fills */
1439
615
        while (payload_bytes_processed < payload_length) {
1440
604
            int fill_gap;
1441
604
            fill_gap = evaluate_sdnv(tvb, offset, &sdnv_length_gap);
1442
604
            ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_start, tvb, offset, sdnv_length_gap, fill_gap);
1443
604
            if (fill_gap < 0 || sdnv_length_gap < 0) {
1444
5
                expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range gap SDNV");
1445
5
                return offset;
1446
5
            }
1447
599
            fill_length = evaluate_sdnv(tvb, offset + sdnv_length_gap, &sdnv_length_length);
1448
599
            ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_end, tvb, offset,
1449
599
                                    sdnv_length_gap + sdnv_length_length, right_edge + fill_gap + fill_length - 1);
1450
599
            if (fill_length < 0 || sdnv_length_length < 0) {
1451
6
                expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range length SDNV");
1452
6
                return tvb_reported_length_remaining(tvb, offset);
1453
6
            }
1454
1455
593
            right_edge += fill_gap + fill_length;
1456
593
            offset += sdnv_length_gap + sdnv_length_length;
1457
593
            payload_bytes_processed += sdnv_length_gap + sdnv_length_length;
1458
593
        }
1459
1460
11
        if (payload_bytes_processed > payload_length) {
1461
2
            expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "ACS: CTEB Custody ID Range data extends past payload length");
1462
2
            return offset;
1463
2
        }
1464
1465
9
        break;
1466
11
    } /* case ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL */
1467
9
    case ADMIN_REC_TYPE_ANNOUNCE_BUNDLE:
1468
449
    default:
1469
449
        offset++;
1470
449
        break;
1471
572
    }   /* End Switch */
1472
1473
524
    proto_item_set_len(admin_record_item, offset - start_offset);
1474
524
    *success = true;
1475
524
    return offset;
1476
572
}
1477
1478
static int
1479
display_extension_block(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, char *bundle_custodian, bool *lastheader)
1480
2.25k
{
1481
2.25k
    proto_item   *block_item, *ti, *block_flag_replicate_item, *block_flag_eid_reference_item;
1482
2.25k
    proto_tree   *block_tree;
1483
2.25k
    int           sdnv_length;
1484
2.25k
    int           block_length;
1485
2.25k
    int           block_overhead;
1486
2.25k
    int           bundle_age;
1487
2.25k
    uint8_t       type;
1488
2.25k
    unsigned int  control_flags;
1489
2.25k
    proto_tree   *block_flag_tree;
1490
2.25k
    proto_item   *block_flag_item;
1491
1492
2.25k
    type = tvb_get_uint8(tvb, offset);
1493
2.25k
    block_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_metadata_hdr, &block_item, "Extension Block");
1494
1495
2.25k
    proto_tree_add_item(block_tree, hf_bundle_block_type_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1496
2.25k
    ++offset;
1497
2.25k
    block_overhead = 1;
1498
1499
2.25k
    control_flags = (unsigned int)evaluate_sdnv(tvb, offset, &sdnv_length);
1500
2.25k
    if (control_flags & BLOCK_CONTROL_LAST_BLOCK) {
1501
150
        *lastheader = true;
1502
2.10k
    } else {
1503
2.10k
        *lastheader = false;
1504
2.10k
    }
1505
2.25k
    block_flag_item = proto_tree_add_uint(block_tree, hf_block_control_flags_sdnv, tvb,
1506
2.25k
                                            offset, sdnv_length, control_flags);
1507
2.25k
    block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1508
2.25k
    block_flag_replicate_item = proto_tree_add_boolean(block_flag_tree, hf_block_control_replicate,
1509
2.25k
                           tvb, offset, sdnv_length, control_flags);
1510
2.25k
    proto_tree_add_boolean(block_flag_tree, hf_block_control_transmit_status,
1511
2.25k
                           tvb, offset, sdnv_length, control_flags);
1512
2.25k
    proto_tree_add_boolean(block_flag_tree, hf_block_control_delete_bundle,
1513
2.25k
                           tvb, offset, sdnv_length, control_flags);
1514
2.25k
    proto_tree_add_boolean(block_flag_tree, hf_block_control_last_block,
1515
2.25k
                           tvb, offset, sdnv_length, control_flags);
1516
2.25k
    proto_tree_add_boolean(block_flag_tree, hf_block_control_discard_block,
1517
2.25k
                           tvb, offset, sdnv_length, control_flags);
1518
2.25k
    proto_tree_add_boolean(block_flag_tree, hf_block_control_not_processed,
1519
2.25k
                           tvb, offset, sdnv_length, control_flags);
1520
2.25k
    block_flag_eid_reference_item = proto_tree_add_boolean(block_flag_tree, hf_block_control_eid_reference,
1521
2.25k
                           tvb, offset, sdnv_length, control_flags);
1522
2.25k
    offset += sdnv_length;
1523
2.25k
    block_overhead += sdnv_length;
1524
1525
    /* TODO: if this block has EID references, add them to display tree */
1526
2.25k
    if (control_flags & BLOCK_CONTROL_EID_REFERENCE) {
1527
209
        int i;
1528
209
        int num_eid_ref;
1529
1530
209
        num_eid_ref = evaluate_sdnv(tvb, offset, &sdnv_length);
1531
209
        offset += sdnv_length;
1532
209
        block_overhead += sdnv_length;
1533
1534
3.11k
        for (i = 0; i < num_eid_ref; i++)
1535
2.92k
        {
1536
2.92k
            if (evaluate_sdnv(tvb, offset, &sdnv_length) < 0)
1537
11
                break;
1538
2.91k
            offset += sdnv_length;
1539
2.91k
            block_overhead += sdnv_length;
1540
1541
2.91k
            if (evaluate_sdnv(tvb, offset, &sdnv_length) < 0)
1542
9
                break;
1543
2.90k
            offset += sdnv_length;
1544
2.90k
            block_overhead += sdnv_length;
1545
2.90k
        }
1546
209
    }
1547
1548
2.25k
    block_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1549
2.25k
    ti = proto_tree_add_int(block_tree, hf_block_control_block_length, tvb, offset, sdnv_length, block_length);
1550
2.25k
    if (block_length < 0) {
1551
40
        expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Metadata Block Length Error");
1552
        /* Force quitting */
1553
40
        *lastheader = true;
1554
40
        return offset;
1555
40
    }
1556
2.21k
    offset += sdnv_length;
1557
2.21k
    block_overhead += sdnv_length;
1558
1559
    /* now we have enough info to know total length of metadata block */
1560
2.21k
    proto_item_set_len(block_item, block_overhead + block_length);
1561
1562
2.21k
    switch (type)
1563
2.21k
    {
1564
90
    case BUNDLE_BLOCK_TYPE_AUTHENTICATION:
1565
101
    case BUNDLE_BLOCK_TYPE_METADATA_EXTENSION:
1566
117
    case BUNDLE_BLOCK_TYPE_EXTENSION_SECURITY:
1567
117
    {
1568
117
        proto_tree_add_string(block_tree, hf_bundle_unprocessed_block_data, tvb, offset, block_length, "Block data");
1569
        /* not yet dissected, skip past data */
1570
117
        offset += block_length;
1571
117
        break;
1572
101
    }
1573
7
    case BUNDLE_BLOCK_TYPE_BUNDLE_AGE:
1574
7
    {
1575
7
        bundle_age = evaluate_sdnv(tvb, offset, &sdnv_length);
1576
7
        proto_tree_add_int(block_tree, hf_bundle_age_extension_block_code, tvb, offset, sdnv_length, bundle_age/1000000);
1577
7
        offset += block_length;
1578
7
        break;
1579
101
    }
1580
21
    case BUNDLE_BLOCK_TYPE_PREVIOUS_HOP_INSERT:
1581
21
    {
1582
21
        int scheme_length;
1583
1584
21
        proto_tree_add_item_ret_length(block_tree, hf_bundle_block_previous_hop_scheme, tvb, offset, 4, ENC_ASCII, &scheme_length);
1585
21
        offset += scheme_length;
1586
21
        proto_tree_add_item(block_tree, hf_bundle_block_previous_hop_eid, tvb, offset, block_length-scheme_length, ENC_ASCII);
1587
21
        if (block_length - scheme_length < 1) {
1588
2
            expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Metadata Block Length Error");
1589
2
            *lastheader = true;
1590
2
            return offset;
1591
2
        }
1592
19
        offset += block_length - scheme_length;
1593
1594
19
        break;
1595
21
    }
1596
97
    case BUNDLE_BLOCK_TYPE_INTEGRITY:
1597
350
    case BUNDLE_BLOCK_TYPE_CONFIDENTIALITY:
1598
350
    {
1599
350
        int target_block_type;
1600
350
        int target_block_occurrence;
1601
350
        int ciphersuite_type;
1602
350
        unsigned int ciphersuite_flags;
1603
1604
350
        target_block_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1605
350
        proto_tree_add_int(block_tree, hf_bundle_target_block_type, tvb, offset, sdnv_length, target_block_type);
1606
350
        offset += sdnv_length;
1607
1608
350
        target_block_occurrence = evaluate_sdnv(tvb, offset, &sdnv_length);
1609
350
        proto_tree_add_int(block_tree, hf_bundle_target_block_occurrence, tvb, offset, sdnv_length, target_block_occurrence);
1610
350
        offset += sdnv_length;
1611
1612
350
        ciphersuite_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1613
350
        proto_tree_add_int(block_tree, hf_bundle_ciphersuite_type, tvb, offset, sdnv_length, ciphersuite_type);
1614
350
        offset += sdnv_length;
1615
1616
350
        ciphersuite_flags = (unsigned int)evaluate_sdnv(tvb, offset, &sdnv_length);
1617
350
        block_flag_item = proto_tree_add_uint(block_tree, hf_bundle_ciphersuite_flags, tvb, offset, sdnv_length, ciphersuite_flags);
1618
350
        block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1619
350
        proto_tree_add_boolean(block_flag_tree, hf_block_ciphersuite_params, tvb, offset, sdnv_length, ciphersuite_flags);
1620
350
        offset += sdnv_length;
1621
1622
350
        int range_offset;
1623
350
        int range_length;
1624
350
        if (ciphersuite_flags & BLOCK_CIPHERSUITE_PARAMS) {
1625
            /* Decode cipher suite parameters */
1626
130
            int params_length;
1627
130
            int param_type;
1628
130
            int item_length;
1629
130
            proto_tree   *param_tree;
1630
130
            expert_field *ei = NULL;
1631
1632
130
            params_length = evaluate_sdnv_ei(tvb, offset, &sdnv_length, &ei);
1633
130
            if (ei) {
1634
4
                proto_tree_add_expert(block_tree, pinfo, ei, tvb, offset, -1);
1635
4
                *lastheader = true;
1636
4
                return offset;
1637
4
            }
1638
126
            param_tree = proto_tree_add_subtree(block_tree, tvb, offset, params_length+1, ett_sec_block_param_data, NULL, "Ciphersuite Parameters Data");
1639
126
            proto_tree_add_int(param_tree, hf_block_ciphersuite_params_length, tvb, offset, sdnv_length, params_length);
1640
126
            offset += sdnv_length;
1641
1642
1.18k
            for(int i = 0; i < params_length; i+=item_length+2)
1643
1.08k
            {
1644
1.08k
                param_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1645
1.08k
                proto_tree_add_int(param_tree, hf_block_ciphersuite_param_type, tvb, offset, sdnv_length, param_type);
1646
1.08k
                offset += sdnv_length;
1647
1648
1.08k
                ei = NULL;
1649
1.08k
                item_length = evaluate_sdnv_ei(tvb, offset, &sdnv_length, &ei);
1650
1.08k
                proto_tree_add_int(param_tree, hf_block_ciphersuite_params_item_length, tvb, offset, sdnv_length, item_length);
1651
1.08k
                if (ei) {
1652
8
                    proto_tree_add_expert(param_tree, pinfo, ei, tvb, offset, -1);
1653
8
                    *lastheader = true;
1654
8
                    return offset;
1655
8
                }
1656
1657
1.08k
                offset += sdnv_length;
1658
1659
                //display item data
1660
1.08k
                switch (param_type)
1661
1.08k
                {
1662
70
                case 1:
1663
146
                case 3:
1664
158
                case 5:
1665
174
                case 7:
1666
179
                case 8:
1667
179
                    proto_tree_add_item(param_tree, hf_block_ciphersuite_param_data, tvb, offset, item_length, ENC_NA);
1668
179
                    offset += item_length;
1669
179
                    break;
1670
76
                case 4:
1671
                    //pair of sdnvs offset and length
1672
76
                    range_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1673
76
                    proto_tree_add_int(param_tree, hf_block_ciphersuite_range_offset, tvb, offset, sdnv_length, range_offset);
1674
76
                    offset += sdnv_length;
1675
1676
76
                    range_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1677
76
                    proto_tree_add_int(param_tree, hf_block_ciphersuite_range_length, tvb, offset, sdnv_length, range_length);
1678
76
                    offset += sdnv_length;
1679
76
                    break;
1680
807
                default:
1681
807
                    break;
1682
1.08k
                }
1683
1.08k
            }
1684
126
        }
1685
        /* Decode cipher suite results */
1686
312
        int result_length;
1687
312
        int result_type;
1688
312
        int result_item_length;
1689
312
        proto_tree   *result_tree;
1690
1691
312
        result_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1692
312
        result_tree = proto_tree_add_subtree(block_tree, tvb, offset, result_length+1, ett_sec_block_param_data, NULL, "Security Results Data");
1693
312
        proto_tree_add_int(result_tree, hf_block_ciphersuite_result_length, tvb, offset, sdnv_length, result_length);
1694
312
        offset += sdnv_length;
1695
1696
2.94k
        for(int i = 0; i < result_length; i+=result_item_length+2)
1697
2.68k
        {
1698
2.68k
            result_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1699
2.68k
            proto_tree_add_int(result_tree, hf_block_ciphersuite_result_type, tvb, offset, sdnv_length, result_type);
1700
2.68k
            offset += sdnv_length;
1701
1702
2.68k
            expert_field *ei = NULL;
1703
2.68k
            result_item_length = evaluate_sdnv_ei(tvb, offset, &sdnv_length, &ei);
1704
2.68k
            proto_tree_add_int(result_tree, hf_block_ciphersuite_result_item_length, tvb, offset, sdnv_length, result_item_length);
1705
2.68k
            if (ei) {
1706
5
                proto_tree_add_expert(result_tree, pinfo, ei, tvb, offset, -1);
1707
5
                *lastheader = true;
1708
5
                return offset;
1709
5
            }
1710
2.68k
            offset += sdnv_length;
1711
1712
            //display item data
1713
2.68k
            switch (result_type)
1714
2.68k
            {
1715
218
            case 1:
1716
313
            case 3:
1717
355
            case 5:
1718
417
            case 7:
1719
428
            case 8:
1720
428
                proto_tree_add_item(result_tree, hf_block_ciphersuite_result_data, tvb, offset, result_item_length, ENC_NA);
1721
428
                offset += result_item_length;
1722
428
                break;
1723
202
            case 4:
1724
                //pair of sdnvs offset and length
1725
202
                range_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1726
202
                proto_tree_add_int(result_tree, hf_block_ciphersuite_range_offset, tvb, offset, sdnv_length, range_offset);
1727
202
                offset += sdnv_length;
1728
1729
202
                range_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1730
202
                proto_tree_add_int(result_tree, hf_block_ciphersuite_range_length, tvb, offset, sdnv_length, range_length);
1731
202
                offset += sdnv_length;
1732
202
                break;
1733
2.02k
            default:
1734
2.02k
                break;
1735
2.68k
            }
1736
1737
2.68k
        }
1738
258
        break;
1739
1740
312
    }
1741
258
    case BUNDLE_BLOCK_TYPE_CUSTODY_TRANSFER:
1742
11
    {
1743
11
        int custody_id;
1744
11
        const uint8_t *cteb_creator_custodian_eid;
1745
11
        int cteb_creator_custodian_eid_length;
1746
1747
        /* check requirements for Block Processing Control Flags */
1748
11
        if ((control_flags & BLOCK_CONTROL_REPLICATE) != 0) {
1749
2
            expert_add_info_format(pinfo, block_flag_replicate_item, &ei_bundle_block_control_flags, "ERROR: Replicate must be clear for CTEB");
1750
2
        }
1751
11
        if ((control_flags & BLOCK_CONTROL_EID_REFERENCE) != 0) {
1752
1
            expert_add_info_format(pinfo, block_flag_eid_reference_item, &ei_bundle_block_control_flags, "ERROR: EID-Reference must be clear for CTEB");
1753
1
        }
1754
1755
        /* there are two elements in a CTEB, first is the custody ID */
1756
11
        custody_id = evaluate_sdnv(tvb, offset, &sdnv_length);
1757
11
        proto_tree_add_int(block_tree, hf_block_control_block_cteb_custody_id, tvb, offset, sdnv_length, custody_id);
1758
11
        offset += sdnv_length;
1759
1760
        /* and second is the creator custodian EID */
1761
11
        if (block_length - sdnv_length < 1) {
1762
2
            expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Metadata Block Length Error");
1763
2
            *lastheader = true;
1764
2
            return offset;
1765
2
        }
1766
9
        cteb_creator_custodian_eid_length = block_length - sdnv_length;
1767
9
        ti = proto_tree_add_item_ret_string(block_tree, hf_block_control_block_cteb_creator_custodian_eid, tvb, offset,
1768
9
                                cteb_creator_custodian_eid_length, ENC_ASCII, pinfo->pool, &cteb_creator_custodian_eid);
1769
1770
        /* also check if CTEB is valid, i.e. custodians match */
1771
9
        if (bundle_custodian == NULL) {
1772
1
            expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1773
1
                                "CTEB Is NOT Valid (Bundle Custodian NULL)");
1774
1
        }
1775
8
        else if (strlen(cteb_creator_custodian_eid) != strlen(bundle_custodian)) {
1776
3
            expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1777
3
                                "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
1778
3
                                bundle_custodian, cteb_creator_custodian_eid);
1779
3
        }
1780
5
        else if (memcmp(cteb_creator_custodian_eid, bundle_custodian, strlen(bundle_custodian)) != 0) {
1781
4
            expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1782
4
                                "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
1783
4
                                bundle_custodian, cteb_creator_custodian_eid);
1784
4
        }
1785
1
        else {
1786
1
            expert_add_info(pinfo, ti, &ei_block_control_block_cteb_valid);
1787
1
        }
1788
9
        offset += cteb_creator_custodian_eid_length;
1789
1790
9
        break;
1791
11
    }
1792
70
    case BUNDLE_BLOCK_TYPE_EXTENDED_COS:
1793
70
    {
1794
70
        int flags;
1795
70
        static int * const ecos_flags_fields[] = {
1796
70
            &hf_ecos_flags_critical,
1797
70
            &hf_ecos_flags_streaming,
1798
70
            &hf_ecos_flags_flowlabel,
1799
70
            &hf_ecos_flags_reliable,
1800
70
            NULL
1801
70
        };
1802
1803
        /* check requirements for Block Processing Control Flags */
1804
70
        if ((control_flags & BLOCK_CONTROL_REPLICATE) == 0) {
1805
9
            expert_add_info_format(pinfo, block_flag_replicate_item, &ei_bundle_block_control_flags, "ERROR: Replicate must be set for ECOS");
1806
9
        }
1807
70
        if ((control_flags & BLOCK_CONTROL_EID_REFERENCE) != 0) {
1808
7
            expert_add_info_format(pinfo, block_flag_eid_reference_item, &ei_bundle_block_control_flags, "ERROR: EID-Reference must be clear for ECOS");
1809
7
        }
1810
1811
        /* flags byte */
1812
70
        flags = (int)tvb_get_uint8(tvb, offset);
1813
70
        proto_tree_add_bitmask(block_tree, tvb, offset, hf_ecos_flags, ett_block_flags, ecos_flags_fields, ENC_BIG_ENDIAN);
1814
70
        offset += 1;
1815
1816
        /* ordinal byte */
1817
70
        proto_tree_add_item(block_tree, hf_ecos_ordinal, tvb, offset, 1, ENC_BIG_ENDIAN);
1818
70
        offset += 1;
1819
1820
        /* optional flow label sdnv */
1821
70
        if ((flags & ECOS_FLAGS_FLOWLABEL) != 0) {
1822
15
            int flow_label;
1823
15
            flow_label = evaluate_sdnv(tvb, offset, &sdnv_length);
1824
15
            ti = proto_tree_add_int(block_tree, hf_ecos_flow_label, tvb, offset, sdnv_length, flow_label);
1825
15
            if (flow_label < 0) {
1826
1
                expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ECOS Flow Label Error");
1827
                /* Force quitting */
1828
1
                *lastheader = true;
1829
1
                return offset;
1830
1
            }
1831
14
            offset += sdnv_length;
1832
14
        }
1833
1834
69
        break;
1835
70
    }
1836
1.52k
    default:
1837
1.52k
    {
1838
1.52k
        proto_tree_add_string(block_tree, hf_bundle_unprocessed_block_data, tvb, offset, block_length, "Block data");
1839
        /* unknown bundle type, skip past data */
1840
1.52k
        offset += block_length;
1841
1.52k
        break;
1842
70
    }
1843
2.21k
    }
1844
1845
1.92k
    return offset;
1846
2.21k
}
1847
1848
/*3rd arg is number of bytes in field (returned)*/
1849
static int
1850
evaluate_sdnv(tvbuff_t *tvb, int offset, int *bytecount)
1851
33.3k
{
1852
33.3k
    uint64_t value = 0;
1853
33.3k
    *bytecount = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &value, ENC_VARINT_SDNV);
1854
1855
33.3k
    if (*bytecount == 0) {
1856
258
        return -1;
1857
258
    }
1858
33.1k
    if (value > INT_MAX) {
1859
895
        ws_warning("evaluate_sdnv decoded a value too large to fit in an int, truncating");
1860
895
        return INT_MAX;
1861
895
    }
1862
32.2k
    return (int)value;
1863
33.1k
}
1864
1865
static int
1866
3.88k
evaluate_sdnv_ei(tvbuff_t *tvb, int offset, int *bytecount, expert_field **error) {
1867
3.88k
    int value = evaluate_sdnv(tvb, offset, bytecount);
1868
3.88k
    *error = (value < 0) ? &ei_bundle_sdnv_length : NULL;
1869
3.88k
    return value;
1870
3.88k
}
1871
1872
/* Special Function to evaluate 64 bit SDNVs */
1873
/*3rd arg is number of bytes in field (returned)*/
1874
static int64_t
1875
evaluate_sdnv_64(tvbuff_t *tvb, int offset, int *bytecount)
1876
667
{
1877
667
    uint64_t val = 0;
1878
667
    *bytecount = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &val, ENC_VARINT_SDNV);
1879
1880
667
    if (*bytecount == 0) {
1881
9
        return -1;
1882
9
    }
1883
658
    return val & INT64_MAX;
1884
667
}
1885
1886
static int
1887
dissect_bpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1888
688
{
1889
688
    proto_item *ti, *ti_bundle_protocol;
1890
688
    proto_tree *bundle_tree, *primary_tree;
1891
688
    int         primary_header_size;
1892
688
    bool        lastheader = false;
1893
688
    int         offset = 0;
1894
688
    uint8_t     version, pri_hdr_procflags;
1895
    /* Custodian from Primary Block, used to validate CTEB */
1896
688
    char       *bundle_custodian = NULL;
1897
1898
1899
688
    version = tvb_get_uint8(tvb, offset);  /* Primary Header Version */
1900
688
    if ((version != 4) && (version != 5) && (version != 6)) {
1901
0
        return 0;
1902
0
    }
1903
1904
688
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Bundle");
1905
    /* Clear out stuff in the info column */
1906
688
    col_clear(pinfo->cinfo,COL_INFO);
1907
1908
688
    ti_bundle_protocol = proto_tree_add_item(tree, proto_bundle, tvb, offset, -1, ENC_NA);
1909
    // identify parent proto version
1910
688
    proto_item_append_text(ti_bundle_protocol, " Version %d", version);
1911
1912
688
    bundle_tree = proto_item_add_subtree(ti_bundle_protocol, ett_bundle);
1913
1914
688
    primary_tree = proto_tree_add_subtree(bundle_tree, tvb, offset, -1, ett_primary_hdr, &ti, "Primary Bundle Header");
1915
1916
688
    proto_tree_add_item(primary_tree, hf_bundle_pdu_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1917
688
    if (version == 4) {
1918
28
        primary_header_size = dissect_version_4_primary_header(pinfo, primary_tree, tvb,
1919
28
                                &pri_hdr_procflags, &bundle_custodian);
1920
28
    }
1921
660
    else {
1922
660
        primary_header_size = dissect_version_5_and_6_primary_header(pinfo, primary_tree, tvb,
1923
660
                                &pri_hdr_procflags, &bundle_custodian);
1924
660
    }
1925
1926
688
    if (primary_header_size == 0) {      /*Couldn't parse primary header*/
1927
11
        col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error");
1928
11
        return 0;      /*Give up*/
1929
11
    }
1930
1931
677
    proto_item_set_len(ti, primary_header_size);
1932
677
    offset = primary_header_size;
1933
1934
    /*
1935
     * Done with primary header; decode the remaining headers
1936
     */
1937
1938
3.75k
    while (lastheader == false) {
1939
3.07k
        uint8_t next_header_type;
1940
1941
3.07k
        next_header_type = tvb_get_uint8(tvb, offset);
1942
3.07k
        if (next_header_type == BUNDLE_BLOCK_TYPE_PAYLOAD) {
1943
1944
            /*
1945
             * Returns payload size or 0 if can't parse payload
1946
             */
1947
808
            offset = dissect_payload_header(bundle_tree, tvb, pinfo, offset, version, pri_hdr_procflags, &lastheader);
1948
808
        }
1949
2.26k
        else {  /*Assume anything else is a Metadata Block*/
1950
2.26k
            offset = display_extension_block(bundle_tree, tvb, pinfo, offset, bundle_custodian, &lastheader);
1951
2.26k
        }
1952
3.07k
    }
1953
1954
677
    proto_item_set_len(ti_bundle_protocol, offset);
1955
1956
677
    return offset;
1957
688
}
1958
1959
/// Introspect the data to choose a dissector version
1960
static int
1961
dissect_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1962
1.28k
{
1963
1.28k
    int offset = 0;
1964
1965
1.28k
    {
1966
        // Primary Header Version octet
1967
1.28k
        uint8_t version = tvb_get_uint8(tvb, offset);
1968
1.28k
        if ((version == 4) || (version == 5) || (version == 6)) {
1969
688
            return call_dissector(bpv6_handle, tvb, pinfo, tree);
1970
688
        }
1971
1.28k
    }
1972
1973
593
    wscbor_chunk_t *frame = wscbor_chunk_read(pinfo->pool, tvb, &offset);
1974
593
    if (frame->type_major == CBOR_TYPE_ARRAY) {
1975
329
        wscbor_chunk_t *primary = wscbor_chunk_read(pinfo->pool, tvb, &offset);
1976
329
        if (primary->type_major == CBOR_TYPE_ARRAY) {
1977
316
            wscbor_chunk_t *version = wscbor_chunk_read(pinfo->pool, tvb, &offset);
1978
316
            if (version->type_major == CBOR_TYPE_UINT) {
1979
307
                uint64_t vers_val = version->head_value;
1980
307
                if (vers_val == 7) {
1981
306
                    return call_dissector(bpv7_handle, tvb, pinfo, tree);
1982
306
                }
1983
307
            }
1984
316
        }
1985
329
    }
1986
1987
287
    return 0;
1988
593
}
1989
1990
1991
void
1992
proto_register_bpv6(void)
1993
14
{
1994
1995
14
    static hf_register_info hf[] = {
1996
14
        {&hf_bundle_pdu_version,
1997
14
         {"Bundle Version", "bundle.version",
1998
14
          FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
1999
14
        },
2000
14
        {&hf_bundle_procflags,
2001
14
         {"Primary Header Processing Flags", "bundle.primary.proc.flag",
2002
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2003
14
        },
2004
14
        {&hf_bundle_procflags_fragment,
2005
14
         {"Bundle is a Fragment", "bundle.primary.proc.frag",
2006
14
          FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_FRAG_MASK, NULL, HFILL}
2007
14
        },
2008
14
        {&hf_bundle_procflags_admin,
2009
14
         {"Administrative Record", "bundle.primary.proc.admin",
2010
14
          FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_ADMIN_MASK, NULL, HFILL}
2011
14
        },
2012
14
        {&hf_bundle_procflags_dont_fragment,
2013
14
         {"Do Not Fragment Bundle", "bundle.primary.proc.dontfrag",
2014
14
          FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_DONTFRAG_MASK, NULL, HFILL}
2015
14
        },
2016
14
        {&hf_bundle_procflags_cust_xfer_req,
2017
14
         {"Request Custody Transfer", "bundle.primary.proc.xferreq",
2018
14
          FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_XFERREQ_MASK, NULL, HFILL}
2019
14
        },
2020
14
        {&hf_bundle_procflags_dest_singleton,
2021
14
         {"Destination is Singleton", "bundle.primary.proc.single",
2022
14
          FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_SINGLETON_MASK, NULL, HFILL}
2023
14
        },
2024
14
        {&hf_bundle_procflags_application_ack,
2025
14
         {"Request Acknowledgement by Application", "bundle.primary.proc.ack",
2026
14
          FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_APP_ACK_MASK, NULL, HFILL}
2027
14
        },
2028
14
        {&hf_bundle_control_flags,
2029
14
         {"Bundle Processing Control Flags", "bundle.primary.processing.control.flag",
2030
14
          FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}
2031
14
        },
2032
14
        {&hf_bundle_procflags_general,
2033
14
         {"General Flags", "bundle.primary.proc.gen",
2034
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2035
14
        },
2036
14
        {&hf_bundle_procflags_cos,
2037
14
         {"Class of Service Flags", "bundle.primary.proc.cos",
2038
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2039
14
        },
2040
14
        {&hf_bundle_procflags_status,
2041
14
         {"Status Report Flags", "bundle.primary.proc.status",
2042
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2043
14
        },
2044
14
        {&hf_bundle_cosflags,
2045
14
         {"Primary Header COS Flags", "bundle.primary.cos.flags",
2046
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2047
14
        },
2048
14
        {&hf_bundle_cosflags_priority,
2049
14
         {"Priority", "bundle.primary.cos.priority",
2050
14
          FT_UINT8, BASE_DEC, VALS(cosflags_priority_vals), BUNDLE_COSFLAGS_PRIORITY_MASK, NULL, HFILL}
2051
14
        },
2052
14
        {&hf_bundle_srrflags,
2053
14
         {"Primary Header Report Request Flags", "bundle.primary.srr.flag",
2054
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2055
14
        },
2056
14
        {&hf_bundle_srrflags_report_receipt,
2057
14
         {"Request Reception Report", "bundle.primary.srr.report",
2058
14
          FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_REPORT_MASK, NULL, HFILL}
2059
14
        },
2060
14
        {&hf_bundle_srrflags_report_cust_accept,
2061
14
         {"Request Report of Custody Acceptance", "bundle.primary.srr.custaccept",
2062
14
          FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_CUSTODY_MASK, NULL, HFILL}
2063
14
        },
2064
14
        {&hf_bundle_srrflags_report_forward,
2065
14
         {"Request Report of Bundle Forwarding", "bundle.primary.srr.forward",
2066
14
          FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_FORWARD_MASK, NULL, HFILL}
2067
14
        },
2068
14
        {&hf_bundle_srrflags_report_delivery,
2069
14
         {"Request Report of Bundle Delivery", "bundle.primary.srr.delivery",
2070
14
          FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_DELIVERY_MASK, NULL, HFILL}
2071
14
        },
2072
14
        {&hf_bundle_srrflags_report_deletion,
2073
14
         {"Request Report of Bundle Deletion", "bundle.primary.srr.delete",
2074
14
          FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_DELETION_MASK, NULL, HFILL}
2075
14
        },
2076
14
        {&hf_bundle_srrflags_report_ack,
2077
14
         {"Request Report of Application Ack", "bundle.primary.srr.ack",
2078
14
          FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_ACK_MASK, NULL, HFILL}
2079
14
        },
2080
14
        {&hf_bundle_primary_header_len,
2081
14
         {"Bundle Header Length", "bundle.primary.len",
2082
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2083
14
        },
2084
14
        {&hf_bundle_primary_dictionary_len,
2085
14
         {"Dictionary Length", "bundle.primary.dictionary_len",
2086
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2087
14
        },
2088
14
        {&hf_bundle_primary_fragment_offset,
2089
14
         {"Fragment Offset", "bundle.primary.fragment_offset",
2090
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2091
14
        },
2092
14
        {&hf_bundle_primary_total_adu_len,
2093
14
         {"Total Application Data Unit Length", "bundle.primary.total_adu_len",
2094
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2095
14
        },
2096
14
        {&hf_bundle_primary_timestamp_seq_num64,
2097
14
         {"Timestamp Sequence Number", "bundle.primary.timestamp_seq_num64",
2098
14
          FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
2099
14
        },
2100
14
        {&hf_bundle_primary_timestamp_seq_num32,
2101
14
         {"Timestamp Sequence Number", "bundle.primary.timestamp_seq_num32",
2102
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2103
14
        },
2104
14
        {&hf_bundle_primary_timestamp,
2105
14
         {"Timestamp", "bundle.primary.timestamp",
2106
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2107
14
        },
2108
14
        {&hf_bundle_dest_scheme_offset_u16,
2109
14
         {"Destination Scheme Offset", "bundle.primary.destschemeoffu16",
2110
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2111
14
        },
2112
14
        {&hf_bundle_dest_scheme_offset_i32,
2113
14
         {"Destination Scheme Offset", "bundle.primary.destschemeoffi32",
2114
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2115
14
        },
2116
14
        {&hf_bundle_dest_ssp_offset_u16,
2117
14
         {"Destination SSP Offset", "bundle.primary.destssspoffu16",
2118
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2119
14
        },
2120
14
        {&hf_bundle_dest_ssp_offset_i32,
2121
14
         {"Destination SSP Offset", "bundle.primary.destssspoffi32",
2122
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2123
14
        },
2124
14
        {&hf_bundle_source_scheme_offset_u16,
2125
14
         {"Source Scheme Offset", "bundle.primary.srcschemeoffu16",
2126
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2127
14
        },
2128
14
        {&hf_bundle_source_scheme_offset_i32,
2129
14
         {"Source Scheme Offset", "bundle.primary.srcschemeoffi32",
2130
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2131
14
        },
2132
14
        {&hf_bundle_source_ssp_offset_u16,
2133
14
         {"Source SSP Offset", "bundle.primary.srcsspoffu16",
2134
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2135
14
        },
2136
14
        {&hf_bundle_source_ssp_offset_i32,
2137
14
         {"Source SSP Offset", "bundle.primary.srcsspoffi32",
2138
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2139
14
        },
2140
14
        {&hf_bundle_report_scheme_offset_u16,
2141
14
         {"Report Scheme Offset", "bundle.primary.rptschemeoffu16",
2142
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2143
14
        },
2144
14
        {&hf_bundle_report_scheme_offset_i32,
2145
14
         {"Report Scheme Offset", "bundle.primary.rptschemeoffi32",
2146
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2147
14
        },
2148
14
        {&hf_bundle_report_ssp_offset_u16,
2149
14
         {"Report SSP Offset", "bundle.primary.rptsspoffu16",
2150
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2151
14
        },
2152
14
        {&hf_bundle_report_ssp_offset_i32,
2153
14
         {"Report SSP Offset", "bundle.primary.rptsspoffi32",
2154
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2155
14
        },
2156
14
        {&hf_bundle_cust_scheme_offset_u16,
2157
14
         {"Custodian Scheme Offset", "bundle.primary.custschemeoffu16",
2158
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2159
14
        },
2160
14
        {&hf_bundle_cust_scheme_offset_i32,
2161
14
         {"Custodian Scheme Offset", "bundle.primary.custschemeoffi32",
2162
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2163
14
        },
2164
14
        {&hf_bundle_cust_ssp_offset_u16,
2165
14
         {"Custodian SSP Offset", "bundle.primary.custsspoffu16",
2166
14
          FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2167
14
        },
2168
14
        {&hf_bundle_cust_ssp_offset_i32,
2169
14
         {"Custodian SSP Offset", "bundle.primary.custsspoffi32",
2170
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2171
14
        },
2172
14
        {&hf_bundle_dest_scheme,
2173
14
         {"Destination Scheme", "bundle.primary.destination_scheme",
2174
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2175
14
        },
2176
14
        {&hf_bundle_dest_ssp,
2177
14
         {"Destination", "bundle.primary.destination",
2178
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2179
14
        },
2180
14
        {&hf_bundle_source_scheme,
2181
14
         {"Source Scheme", "bundle.primary.source_scheme",
2182
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2183
14
        },
2184
14
        {&hf_bundle_source_ssp,
2185
14
         {"Source", "bundle.primary.source",
2186
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2187
14
        },
2188
14
        {&hf_bundle_report_scheme,
2189
14
         {"Report Scheme", "bundle.primary.report_scheme",
2190
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2191
14
        },
2192
14
        {&hf_bundle_report_ssp,
2193
14
         {"Report", "bundle.primary.report",
2194
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2195
14
        },
2196
14
        {&hf_bundle_custodian_scheme,
2197
14
         {"Custodian Scheme", "bundle.primary.custodian_scheme",
2198
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2199
14
        },
2200
14
        {&hf_bundle_custodian_ssp,
2201
14
         {"Custodian", "bundle.primary.custodian",
2202
14
          FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2203
14
        },
2204
14
        {&hf_bundle_creation_timestamp,
2205
14
         {"Creation Timestamp", "bundle.primary.creation_timestamp",
2206
14
          FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}
2207
14
        },
2208
14
        {&hf_bundle_lifetime,
2209
14
         {"Lifetime", "bundle.primary.lifetime",
2210
14
          FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2211
14
        },
2212
14
        {&hf_bundle_lifetime_sdnv,
2213
14
         {"Lifetime", "bundle.primary.lifetime_sdnv",
2214
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2215
14
        },
2216
14
        {&hf_bundle_payload_length,
2217
14
         {"Payload Length", "bundle.payload.length",
2218
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2219
14
        },
2220
14
        {&hf_bundle_payload_flags,
2221
14
         {"Payload Header Processing Flags", "bundle.payload.proc.flag",
2222
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2223
14
        },
2224
14
        {&hf_bundle_payload_header_type,
2225
14
         {"Header Type", "bundle.payload.proc.header_type",
2226
14
          FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2227
14
        },
2228
14
        {&hf_bundle_payload_data,
2229
14
         {"Payload Data", "bundle.payload.data",
2230
14
          FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL}
2231
14
        },
2232
14
        {&hf_bundle_payload_flags_replicate_hdr,
2233
14
         {"Replicate Header in Every Fragment", "bundle.payload.proc.replicate",
2234
14
          FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_REPLICATE_MASK, NULL, HFILL}
2235
14
        },
2236
14
        {&hf_bundle_payload_flags_xmit_report,
2237
14
         {"Report if Can't Process Header", "bundle.payload.proc.report",
2238
14
          FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_XMIT_STATUS, NULL, HFILL}
2239
14
        },
2240
14
        {&hf_bundle_payload_flags_discard_on_fail,
2241
14
         {"Discard if Can't Process Header", "bundle.payload.proc.discard",
2242
14
          FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_DISCARD_FAILURE, NULL, HFILL}
2243
14
        },
2244
14
        {&hf_bundle_payload_flags_last_header,
2245
14
         {"Last Header", "bundle.payload.proc.lastheader",
2246
14
          FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_LAST_HEADER, NULL, HFILL}
2247
14
        },
2248
14
        {&hf_bundle_admin_record_type,
2249
14
         {"Administrative Record Type", "bundle.admin.record_type",
2250
14
          FT_UINT8, BASE_DEC, VALS(admin_record_type_vals), 0xF0, NULL, HFILL}
2251
14
        },
2252
14
        {&hf_bundle_admin_record_fragment,
2253
14
         {"Administrative Record for Fragment", "bundle.admin.record_fragment",
2254
14
          FT_BOOLEAN, 8, TFS(&tfs_yes_no), ADMIN_REC_FLAGS_FRAGMENT, NULL, HFILL}
2255
14
        },
2256
14
        {&hf_bundle_admin_statflags,
2257
14
         {"Administrative Record Status Flags", "bundle.admin.status.flag",
2258
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2259
14
        },
2260
14
        {&hf_bundle_admin_rcvd,
2261
14
         {"Reporting Node Received Bundle", "bundle.admin.status.rcvd",
2262
14
          FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_RECEIVED, NULL, HFILL}
2263
14
        },
2264
14
        {&hf_bundle_admin_accepted,
2265
14
         {"Reporting Node Accepted Custody", "bundle.admin.status.accept",
2266
14
          FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_ACCEPTED, NULL, HFILL}
2267
14
        },
2268
14
        {&hf_bundle_admin_forwarded,
2269
14
         {"Reporting Node Forwarded Bundle", "bundle.admin.status.forward",
2270
14
          FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_FORWARDED, NULL, HFILL}
2271
14
        },
2272
14
        {&hf_bundle_admin_delivered,
2273
14
         {"Reporting Node Delivered Bundle", "bundle.admin.status.delivered",
2274
14
          FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_DELIVERED, NULL, HFILL}
2275
14
        },
2276
14
        {&hf_bundle_admin_deleted,
2277
14
         {"Reporting Node Deleted Bundle", "bundle.admin.status.delete",
2278
14
          FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_DELETED, NULL, HFILL}
2279
14
        },
2280
14
        {&hf_bundle_admin_acked,
2281
14
         {"Acknowledged by Application", "bundle.admin.status.ack",
2282
14
          FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_ACKNOWLEDGED, NULL, HFILL}
2283
14
        },
2284
14
        {&hf_bundle_admin_fragment_offset,
2285
14
         {"Fragment Offset", "bundle.admin.fragment_offset",
2286
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2287
14
        },
2288
14
        {&hf_bundle_admin_fragment_length,
2289
14
         {"Fragment Length", "bundle.admin.fragment_length",
2290
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2291
14
        },
2292
14
        {&hf_bundle_admin_timestamp_seq_num64,
2293
14
         {"Timestamp Sequence Number", "bundle.admin.timestamp_seq_num64",
2294
14
          FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
2295
14
        },
2296
14
        {&hf_bundle_admin_timestamp_seq_num32,
2297
14
         {"Timestamp Sequence Number", "bundle.admin.timestamp_seq_num32",
2298
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2299
14
        },
2300
14
        {&hf_bundle_admin_endpoint_length,
2301
14
         {"Endpoint Length", "bundle.admin.endpoint_length",
2302
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2303
14
        },
2304
14
        {&hf_bundle_admin_endpoint_id,
2305
14
         {"Bundle Endpoint ID", "bundle.admin.endpoint_id",
2306
14
          FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2307
14
        },
2308
14
        {&hf_bundle_admin_receipt_time,
2309
14
         {"Bundle Received Time", "bundle.admin.status.receipttime",
2310
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2311
14
        },
2312
14
        {&hf_bundle_admin_accept_time,
2313
14
         {"Bundle Accepted Time", "bundle.admin.status.accepttime",
2314
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2315
14
        },
2316
14
        {&hf_bundle_admin_forward_time,
2317
14
         {"Bundle Forwarded Time", "bundle.admin.status.forwardtime",
2318
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2319
14
        },
2320
14
        {&hf_bundle_admin_delivery_time,
2321
14
         {"Bundle Delivered Time", "bundle.admin.status.deliverytime",
2322
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2323
14
        },
2324
14
        {&hf_bundle_admin_delete_time,
2325
14
         {"Bundle Deleted Time", "bundle.admin.status.deletetime",
2326
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2327
14
        },
2328
14
        {&hf_bundle_admin_ack_time,
2329
14
         {"Bundle Acknowledged Time", "bundle.admin.status.acktime",
2330
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2331
14
        },
2332
14
        {&hf_bundle_admin_timestamp_copy,
2333
14
         {"Bundle Creation Timestamp", "bundle.admin.status.timecopy",
2334
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2335
14
        },
2336
14
        {&hf_bundle_admin_signal_time,
2337
14
         {"Bundle Signal Time", "bundle.admin.signal.time",
2338
14
          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2339
14
        },
2340
14
        {&hf_block_control_flags,
2341
14
         {"Block Processing Control Flags", "bundle.block.control.flags",
2342
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2343
14
        },
2344
14
        {&hf_block_control_flags_sdnv,
2345
14
         {"Block Processing Control Flags", "bundle.block.control.flags",
2346
14
          FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
2347
14
        },
2348
14
        {&hf_block_control_block_length,
2349
14
         {"Block Length", "bundle.block.length",
2350
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2351
14
        },
2352
14
        {&hf_block_control_block_cteb_custody_id,
2353
14
         {"CTEB Custody ID", "bundle.block.cteb_custody_id",
2354
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2355
14
        },
2356
14
        {&hf_block_control_block_cteb_creator_custodian_eid,
2357
14
         {"CTEB Creator Custodian EID", "bundle.block.cteb_creator_custodian_eid",
2358
14
          FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2359
14
        },
2360
14
        {&hf_block_control_replicate,
2361
14
         {"Replicate Block in Every Fragment", "bundle.block.control.replicate",
2362
14
          FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_REPLICATE, NULL, HFILL}
2363
14
        },
2364
14
        {&hf_block_control_transmit_status,
2365
14
         {"Transmit Status if Block Can't be Processed", "bundle.block.control.status",
2366
14
          FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_TRANSMIT_STATUS, NULL, HFILL}
2367
14
        },
2368
14
        {&hf_block_control_delete_bundle,
2369
14
         {"Delete Bundle if Block Can't be Processed", "bundle.block.control.delete",
2370
14
          FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_DELETE_BUNDLE, NULL, HFILL}
2371
14
        },
2372
14
        {&hf_block_control_last_block,
2373
14
         {"Last Block", "bundle.block.control.last",
2374
14
          FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_LAST_BLOCK, NULL, HFILL}
2375
14
        },
2376
14
        {&hf_block_control_discard_block,
2377
14
         {"Discard Block If Can't Process", "bundle.block.control.discard",
2378
14
          FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_DISCARD_BLOCK, NULL, HFILL}
2379
14
        },
2380
14
        {&hf_block_control_not_processed,
2381
14
         {"Block Was Forwarded Without Processing", "bundle.block.control.process",
2382
14
          FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_NOT_PROCESSED, NULL, HFILL}
2383
14
        },
2384
14
        {&hf_block_control_eid_reference,
2385
14
         {"Block Contains an EID-reference Field", "bundle.block.control.eid",
2386
14
          FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_EID_REFERENCE, NULL, HFILL}
2387
14
        },
2388
14
        {&hf_bundle_status_report_reason_code,
2389
14
         {"Status Report Reason Code", "bundle.status_report_reason_code",
2390
14
          FT_UINT8, BASE_DEC, VALS(status_report_reason_codes), 0x0, NULL, HFILL}
2391
14
        },
2392
14
        {&hf_bundle_custody_trf_succ_flg,
2393
14
         {"Custody Transfer Succeeded Flag", "bundle.custody_trf_succ_flg",
2394
14
          FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}
2395
14
        },
2396
14
        {&hf_bundle_custody_signal_reason,
2397
14
         {"Custody Signal Reason Code", "bundle.custody_signal_reason_code",
2398
14
          FT_UINT8, BASE_DEC, VALS(custody_signal_reason_codes), ADMIN_REC_CUSTODY_REASON_MASK, NULL, HFILL}
2399
14
        },
2400
14
        {&hf_bundle_custody_id_range_start,
2401
14
         {"CTEB Custody ID Range Start", "bundle.custody_id_range_start",
2402
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2403
14
        },
2404
14
        {&hf_bundle_custody_id_range_end,
2405
14
         {"CTEB Custody ID Range End", "bundle.custody_id_range_end",
2406
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2407
14
        },
2408
14
        {&hf_bundle_block_type_code,
2409
14
         {"Block Type Code", "bundle.block_type_code",
2410
14
          FT_UINT8, BASE_DEC, VALS(bundle_block_type_codes), 0x0, NULL, HFILL}
2411
14
        },
2412
14
        {&hf_bundle_unprocessed_block_data,
2413
14
         {"Block Data", "bundle.block_data",
2414
14
          FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL}
2415
14
        },
2416
14
        {&hf_ecos_flags,
2417
14
         {"ECOS Flags", "bundle.block.ecos.flags",
2418
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2419
14
        },
2420
14
        {&hf_ecos_flags_critical,
2421
14
         {"Critical", "bundle.block.ecos.flags.critical",
2422
14
          FT_BOOLEAN, 8, NULL, ECOS_FLAGS_CRITICAL, NULL, HFILL}
2423
14
        },
2424
14
        {&hf_ecos_flags_streaming,
2425
14
         {"Streaming", "bundle.block.ecos.flags.streaming",
2426
14
          FT_BOOLEAN, 8, NULL, ECOS_FLAGS_STREAMING, NULL, HFILL}
2427
14
        },
2428
14
        {&hf_ecos_flags_flowlabel,
2429
14
         {"Flow Label", "bundle.block.ecos.flags.flowlabel",
2430
14
          FT_BOOLEAN, 8, NULL, ECOS_FLAGS_FLOWLABEL, NULL, HFILL}
2431
14
        },
2432
14
        {&hf_ecos_flags_reliable,
2433
14
         {"Reliable", "bundle.block.ecos.flags.reliable",
2434
14
          FT_BOOLEAN, 8, NULL, ECOS_FLAGS_RELIABLE, NULL, HFILL}
2435
14
        },
2436
14
        {&hf_ecos_flow_label,
2437
14
         {"ECOS Flow Label", "bundle.block.ecos.flow_label",
2438
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2439
14
        },
2440
14
        {&hf_ecos_ordinal,
2441
14
         {"ECOS Ordinal", "bundle.block.ecos.ordinal",
2442
14
          FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2443
14
        },
2444
14
        {&hf_bundle_age_extension_block_code,
2445
14
         {"Bundle Age in seconds", "bundle.age_extension_block_code",
2446
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2447
14
        },
2448
14
        {&hf_bundle_block_previous_hop_scheme,
2449
14
         {"Previous Hop Scheme", "bundle.block.previous_hop_scheme",
2450
14
          FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2451
14
        },
2452
14
        {&hf_bundle_block_previous_hop_eid,
2453
14
         {"Previous Hop EID", "bundle.block.previous_hop_eid",
2454
14
          FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2455
14
        },
2456
14
        {&hf_bundle_target_block_type,
2457
14
         {"Target Block Type", "bundle.target_block_type",
2458
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2459
14
        },
2460
14
        {&hf_bundle_target_block_occurrence,
2461
14
         {"Target Block Occurrence", "bundle.target_block_occurrence",
2462
14
          FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2463
14
        },
2464
14
        {&hf_bundle_ciphersuite_type,
2465
14
         {"Ciphersuite Type", "bundle.ciphersuite_type",
2466
14
          FT_INT32, BASE_DEC, VALS(ciphersuite_types), 0x0, NULL, HFILL}
2467
14
        },
2468
14
        {&hf_bundle_ciphersuite_flags,
2469
14
         {"Ciphersuite Flags", "bundle.ciphersuite_flags",
2470
14
          FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2471
14
        },
2472
14
        {&hf_block_ciphersuite_params,
2473
14
         {"Block Contains Ciphersuite Parameters", "bundle.block.ciphersuite_params",
2474
14
          FT_BOOLEAN, 8, NULL, BLOCK_CIPHERSUITE_PARAMS, NULL, HFILL}
2475
14
        },
2476
14
        {&hf_block_ciphersuite_params_length,
2477
14
         {"Ciphersuite Parameters Length", "bundle.block.ciphersuite_params_length",
2478
14
          FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2479
14
        },
2480
14
        {&hf_block_ciphersuite_params_item_length,
2481
14
         {"Parameter Length", "bundle.block.ciphersuite_params_item_length",
2482
14
          FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2483
14
        },
2484
14
        {&hf_block_ciphersuite_param_type,
2485
14
         {"Ciphersuite Parameter Type", "bundle.block.ciphersuite_param_type",
2486
14
          FT_INT8, BASE_DEC, VALS(res_params_types), 0x0, NULL, HFILL}
2487
14
        },
2488
14
        {&hf_block_ciphersuite_param_data,
2489
14
         {"Ciphersuite Parameter Data", "bundle.block.ciphersuite_param_data",
2490
14
          FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
2491
14
        },
2492
14
        {&hf_block_ciphersuite_result_length,
2493
14
         {"Security Results Length", "bundle.block.ciphersuite_result_length",
2494
14
          FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2495
14
        },
2496
14
        {&hf_block_ciphersuite_result_item_length,
2497
14
         {"Security Result Item Length", "bundle.block.ciphersuite_result_item_length",
2498
14
          FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2499
14
        },
2500
14
        {&hf_block_ciphersuite_result_type,
2501
14
         {"Security Result Item Type", "bundle.block.ciphersuite_result_type",
2502
14
          FT_INT8, BASE_DEC, VALS(res_params_types), 0x0, NULL, HFILL}
2503
14
        },
2504
14
        {&hf_block_ciphersuite_result_data,
2505
14
         {"Security Result Item Data", "bundle.block.ciphersuite_result_data",
2506
14
          FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
2507
14
        },
2508
14
        {&hf_block_ciphersuite_range_offset,
2509
14
         {"Content Range Offset", "bundle.block.ciphersuite_range_offset",
2510
14
          FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2511
14
        },
2512
14
        {&hf_block_ciphersuite_range_length,
2513
14
         {"Content Range Length", "bundle.block.ciphersuite_range_length",
2514
14
          FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2515
14
        },
2516
14
    };
2517
2518
14
    static int *ett[] = {
2519
14
        &ett_bundle,
2520
14
        &ett_bundle_hdr,
2521
14
        &ett_primary_hdr,
2522
14
        &ett_proc_flags,
2523
14
        &ett_gen_flags,
2524
14
        &ett_cos_flags,
2525
14
        &ett_srr_flags,
2526
14
        &ett_dictionary,
2527
14
        &ett_payload_hdr,
2528
14
        &ett_payload_flags,
2529
14
        &ett_block_flags,
2530
14
        &ett_admin_record,
2531
14
        &ett_admin_rec_status,
2532
14
        &ett_metadata_hdr,
2533
14
        &ett_sec_block_param_data
2534
14
    };
2535
2536
14
    static ei_register_info ei[] = {
2537
14
        { &ei_bundle_control_flags_length,
2538
14
          { "bundle.block.control.flags.length", PI_UNDECODED, PI_WARN, "Wrong bundle control flag length", EXPFILL }
2539
14
        },
2540
14
        { &ei_bundle_payload_length,
2541
14
          { "bundle.payload.length.invalid", PI_PROTOCOL, PI_ERROR, "Payload length error", EXPFILL }
2542
14
        },
2543
14
        { &ei_bundle_sdnv_length,
2544
14
          { "bundle.sdnv_length_invalid", PI_PROTOCOL, PI_ERROR, "SDNV length error", EXPFILL }
2545
14
        },
2546
14
        { &ei_bundle_timestamp_seq_num,
2547
14
          { "bundle.timestamp_seq_num_invalid", PI_PROTOCOL, PI_ERROR, "Timestamp Sequence Number error", EXPFILL }
2548
14
        },
2549
14
        { &ei_bundle_offset_error,
2550
14
          { "bundle.offset_error", PI_PROTOCOL, PI_WARN, "Offset field error", EXPFILL }
2551
14
        },
2552
14
        { &ei_bundle_block_control_flags,
2553
14
          { "bundle.block.control.flags.error", PI_PROTOCOL, PI_WARN, "Control flag error", EXPFILL }
2554
14
        },
2555
14
        { &ei_block_control_block_cteb_invalid,
2556
14
          { "bundle.block.control.cteb_invalid", PI_PROTOCOL, PI_WARN, "CTEB Is Invalid", EXPFILL }
2557
14
        },
2558
14
        { &ei_block_control_block_cteb_valid,
2559
14
          { "bundle.block.control.cteb_valid", PI_PROTOCOL, PI_NOTE, "CTEB Is Valid", EXPFILL }
2560
14
        },
2561
14
    };
2562
2563
14
    expert_module_t *expert_bundle;
2564
2565
14
    proto_bundle  = proto_register_protocol("Bundle Protocol", "BP", "bundle");
2566
14
    bpv6_handle = register_dissector("bpv6", dissect_bpv6, proto_bundle);
2567
14
    bundle_handle = register_dissector("bundle", dissect_bundle, proto_bundle);
2568
2569
14
    proto_register_field_array(proto_bundle, hf, array_length(hf));
2570
14
    proto_register_subtree_array(ett, array_length(ett));
2571
14
    expert_bundle = expert_register_protocol(proto_bundle);
2572
14
    expert_register_field_array(expert_bundle, ei, array_length(ei));
2573
14
}
2574
2575
void
2576
proto_reg_handoff_bpv6(void)
2577
14
{
2578
14
    bpv7_handle = find_dissector("bpv7");
2579
2580
14
    dissector_add_uint_with_preference("udp.port", BUNDLE_PORT, bundle_handle);
2581
14
}
2582
2583
/*
2584
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2585
 *
2586
 * Local variables:
2587
 * c-basic-offset: 4
2588
 * tab-width: 8
2589
 * indent-tabs-mode: nil
2590
 * End:
2591
 *
2592
 * vi: set shiftwidth=4 tabstop=8 expandtab:
2593
 * :indentSize=4:tabSize=8:noTabs=true:
2594
 */