Coverage Report

Created: 2026-01-02 06:13

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