Coverage Report

Created: 2026-08-14 06:45

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