2 * Copyright 2006-2007 The MITRE Corporation.
4 * Approved for Public Release; Distribution Unlimited.
5 * Tracking Number 07-0090.
7 * The US Government will not be charged any license fee and/or royalties
8 * related to this software. Neither name of The MITRE Corporation; nor the
9 * names of its contributors may be used to endorse or promote products
10 * derived from this software without specific prior written permission.
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * SPDX-License-Identifier: GPL-2.0-or-later
18 * Specification reference:
20 * http://tools.ietf.org/html/rfc5050
24 * Modifications were made to this file under designation MFS-33289-1 and
25 * are Copyright 2015 United States Government as represented by NASA
26 * Marshall Space Flight Center. All Rights Reserved.
28 * Released under the GNU GPL with NASA legal approval granted 2016-06-10.
30 * The subject software is provided "AS IS" WITHOUT ANY WARRANTY of any kind,
31 * either expressed, implied or statutory and this agreement does not,
32 * in any manner, constitute an endorsement by government agency of any
33 * results, designs or products resulting from use of the subject software.
34 * See the Agreement for the specific language governing permissions and
41 #include <epan/packet.h>
42 #include <epan/reassemble.h>
43 #include <epan/expert.h>
44 #include "packet-dtn.h"
45 #include "packet-tcp.h"
47 static int dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, packet_info *pinfo,
48 int offset, int payload_length, gboolean* success);
50 /* For Reassembling TCP Convergence Layer segments */
51 static reassembly_table msg_reassembly_table;
53 static const char magic[] = {'d', 't', 'n', '!'};
55 static int proto_bundle = -1;
56 static int proto_tcp_conv = -1;
57 static int hf_bundle_pdu_version = -1;
59 /* TCP Convergence Header Variables */
60 static int hf_tcp_convergence_pkt_type = -1;
62 static int hf_contact_hdr_version = -1;
63 static int hf_contact_hdr_flags = -1;
64 static int hf_contact_hdr_keep_alive = -1;
65 static int hf_contact_hdr_flags_ack_req = -1;
66 static int hf_contact_hdr_flags_frag_enable = -1;
67 static int hf_contact_hdr_flags_nak = -1;
68 static int hf_contact_hdr_magic = -1;
69 static int hf_contact_hdr_local_eid_length = -1;
70 static int hf_contact_hdr_local_eid = -1;
72 /* TCP Convergence Data Header Variables */
73 static int hf_tcp_convergence_data_procflags = -1;
74 static int hf_tcp_convergence_data_procflags_start = -1;
75 static int hf_tcp_convergence_data_procflags_end = -1;
76 static int hf_tcp_convergence_data_segment_length = -1;
78 /* TCP Convergence Ack Variables */
79 static int hf_tcp_convergence_ack_length = -1;
81 /* TCP Convergence Shutdown Header Variables */
82 static int hf_tcp_convergence_shutdown_flags = -1;
83 static int hf_tcp_convergence_shutdown_flags_reason = -1;
84 static int hf_tcp_convergence_shutdown_flags_delay = -1;
85 static int hf_tcp_convergence_shutdown_reason = -1;
86 static int hf_tcp_convergence_shutdown_delay = -1;
88 /*TCP Convergence Layer Reassembly boilerplate*/
89 static int hf_msg_fragments = -1;
90 static int hf_msg_fragment = -1;
91 static int hf_msg_fragment_overlap = -1;
92 static int hf_msg_fragment_overlap_conflicts = -1;
93 static int hf_msg_fragment_multiple_tails = -1;
94 static int hf_msg_fragment_too_long_fragment = -1;
95 static int hf_msg_fragment_error = -1;
96 static int hf_msg_fragment_count = -1;
97 static int hf_msg_reassembled_in = -1;
98 static int hf_msg_reassembled_length = -1;
100 /* Primary Header Processing Flag Variables */
101 static int hf_bundle_procflags = -1;
102 static int hf_bundle_procflags_fragment = -1;
103 static int hf_bundle_procflags_admin = -1;
104 static int hf_bundle_procflags_dont_fragment = -1;
105 static int hf_bundle_procflags_cust_xfer_req = -1;
106 static int hf_bundle_procflags_dest_singleton = -1;
107 static int hf_bundle_procflags_application_ack = -1;
109 /* Additions for Version 5 */
110 static int hf_bundle_control_flags = -1;
111 static int hf_bundle_procflags_general = -1;
112 static int hf_bundle_procflags_cos = -1;
113 static int hf_bundle_procflags_status = -1;
115 /* Primary Header COS Flag Variables */
116 static int hf_bundle_cosflags = -1;
117 static int hf_bundle_cosflags_priority = -1;
119 /* Primary Header Status Report Request Flag Variables */
120 static int hf_bundle_srrflags = -1;
121 static int hf_bundle_srrflags_report_receipt = -1;
122 static int hf_bundle_srrflags_report_cust_accept = -1;
123 static int hf_bundle_srrflags_report_forward = -1;
124 static int hf_bundle_srrflags_report_delivery = -1;
125 static int hf_bundle_srrflags_report_deletion = -1;
126 static int hf_bundle_srrflags_report_ack = -1;
128 /* Primary Header Fields*/
129 static int hf_bundle_primary_header_len = -1;
130 static int hf_bundle_primary_dictionary_len = -1;
131 static int hf_bundle_primary_timestamp = -1;
132 static int hf_bundle_primary_fragment_offset = -1;
133 static int hf_bundle_primary_total_adu_len = -1;
134 static int hf_bundle_primary_timestamp_seq_num64 = -1;
135 static int hf_bundle_primary_timestamp_seq_num32 = -1;
137 static int hf_bundle_dest_scheme_offset_u16 = -1;
138 static int hf_bundle_dest_scheme_offset_i32 = -1;
139 static int hf_bundle_dest_ssp_offset_u16 = -1;
140 static int hf_bundle_dest_ssp_offset_i32 = -1;
141 static int hf_bundle_source_scheme_offset_u16 = -1;
142 static int hf_bundle_source_scheme_offset_i32 = -1;
143 static int hf_bundle_source_ssp_offset_u16 = -1;
144 static int hf_bundle_source_ssp_offset_i32 = -1;
145 static int hf_bundle_report_scheme_offset_u16 = -1;
146 static int hf_bundle_report_scheme_offset_i32 = -1;
147 static int hf_bundle_report_ssp_offset_u16 = -1;
148 static int hf_bundle_report_ssp_offset_i32 = -1;
149 static int hf_bundle_cust_scheme_offset_u16 = -1;
150 static int hf_bundle_cust_scheme_offset_i32 = -1;
151 static int hf_bundle_cust_ssp_offset_u16 = -1;
152 static int hf_bundle_cust_ssp_offset_i32 = -1;
154 /* Dictionary EIDs */
155 static int hf_bundle_dest_scheme = -1;
156 static int hf_bundle_dest_ssp = -1;
157 static int hf_bundle_source_scheme = -1;
158 static int hf_bundle_source_ssp = -1;
159 static int hf_bundle_report_scheme = -1;
160 static int hf_bundle_report_ssp = -1;
161 static int hf_bundle_custodian_scheme = -1;
162 static int hf_bundle_custodian_ssp = -1;
164 /* Remaining Primary Header Fields */
165 static int hf_bundle_creation_timestamp = -1;
166 static int hf_bundle_lifetime = -1;
167 static int hf_bundle_lifetime_sdnv = -1;
169 /* Secondary Header Processing Flag Variables */
170 static int hf_bundle_payload_length = -1;
171 static int hf_bundle_payload_header_type = -1;
172 static int hf_bundle_payload_data = -1;
173 static int hf_bundle_payload_flags = -1;
174 static int hf_bundle_payload_flags_replicate_hdr = -1;
175 static int hf_bundle_payload_flags_xmit_report = -1;
176 static int hf_bundle_payload_flags_discard_on_fail = -1;
177 static int hf_bundle_payload_flags_last_header = -1;
179 /* Block Processing Control Flag Variables (Version 5) */
180 static int hf_block_control_flags = -1;
181 static int hf_block_control_flags_sdnv = -1;
182 static int hf_block_control_replicate = -1;
183 static int hf_block_control_transmit_status = -1;
184 static int hf_block_control_delete_bundle = -1;
185 static int hf_block_control_last_block = -1;
186 static int hf_block_control_discard_block = -1;
187 static int hf_block_control_not_processed = -1;
188 static int hf_block_control_eid_reference = -1;
189 static int hf_block_control_block_length = -1;
190 static int hf_block_control_block_cteb_custody_id = -1;
191 static int hf_block_control_block_cteb_creator_custodian_eid = -1;
193 /* Non-Primary Block Type Code Variable */
194 static int hf_bundle_block_type_code = -1;
195 static int hf_bundle_unprocessed_block_data = -1;
197 /* ECOS Flag Variables */
198 static int hf_ecos_flags = -1;
199 static int hf_ecos_flags_critical = -1;
200 static int hf_ecos_flags_streaming = -1;
201 static int hf_ecos_flags_flowlabel = -1;
202 static int hf_ecos_flags_reliable = -1;
203 static int hf_ecos_flow_label = -1;
205 static int hf_ecos_ordinal = -1;
207 /* Administrative Record Variables */
208 static int hf_bundle_admin_record_type = -1;
209 static int hf_bundle_admin_record_fragment = -1;
210 static int hf_bundle_admin_statflags = -1;
211 static int hf_bundle_admin_rcvd = -1;
212 static int hf_bundle_admin_accepted = -1;
213 static int hf_bundle_admin_forwarded = -1;
214 static int hf_bundle_admin_delivered = -1;
215 static int hf_bundle_admin_deleted = -1;
216 static int hf_bundle_admin_acked = -1;
217 static int hf_bundle_admin_fragment_offset = -1;
218 static int hf_bundle_admin_fragment_length = -1;
219 static int hf_bundle_admin_timestamp_seq_num64 = -1;
220 static int hf_bundle_admin_timestamp_seq_num32 = -1;
221 static int hf_bundle_admin_endpoint_length = -1;
222 static int hf_bundle_admin_endpoint_id = -1;
224 static int hf_bundle_admin_receipt_time = -1;
225 static int hf_bundle_admin_accept_time = -1;
226 static int hf_bundle_admin_forward_time = -1;
227 static int hf_bundle_admin_delivery_time = -1;
228 static int hf_bundle_admin_delete_time = -1;
229 static int hf_bundle_admin_ack_time = -1;
230 static int hf_bundle_admin_timestamp_copy = -1;
231 static int hf_bundle_admin_signal_time = -1;
232 static int hf_bundle_status_report_reason_code = -1;
233 static int hf_bundle_custody_trf_succ_flg = -1;
234 static int hf_bundle_custody_signal_reason = -1;
235 static int hf_bundle_custody_id_range_start = -1;
236 static int hf_bundle_custody_id_range_end = -1;
238 static int hf_bundle_age_extension_block_code = -1;
239 static int hf_bundle_block_previous_hop_scheme = -1;
240 static int hf_bundle_block_previous_hop_eid = -1;
242 /* Security Block Variables */
243 static int hf_bundle_target_block_type = -1;
244 static int hf_bundle_target_block_occurance = -1;
245 static int hf_bundle_ciphersuite_type = -1;
246 static int hf_bundle_ciphersuite_flags = -1;
247 static int hf_block_ciphersuite_params = -1;
248 static int hf_block_ciphersuite_params_length = -1;
249 static int hf_block_ciphersuite_params_item_length = -1;
250 static int hf_block_ciphersuite_param_type = -1;
251 static int hf_block_ciphersuite_param_data = -1;
252 static int hf_block_ciphersuite_result_length = -1;
253 static int hf_block_ciphersuite_result_item_length = -1;
254 static int hf_block_ciphersuite_result_type = -1;
255 static int hf_block_ciphersuite_result_data = -1;
256 static int hf_block_ciphersuite_range_offset = -1;
257 static int hf_block_ciphersuite_range_length = -1;
259 /* Tree Node Variables */
260 static gint ett_bundle = -1;
261 static gint ett_conv_flags = -1;
262 static gint ett_shutdown_flags = -1;
263 static gint ett_bundle_hdr = -1;
264 static gint ett_primary_hdr = -1;
265 static gint ett_proc_flags = -1;
266 static gint ett_gen_flags = -1;
267 static gint ett_cos_flags = -1;
268 static gint ett_srr_flags = -1;
269 static gint ett_dictionary = -1;
270 static gint ett_payload_hdr = -1;
271 static gint ett_payload_flags = -1;
272 static gint ett_block_flags = -1;
273 static gint ett_contact_hdr_flags = -1;
274 static gint ett_admin_record = -1;
275 static gint ett_admin_rec_status = -1;
276 static gint ett_metadata_hdr = -1;
277 static gint ett_sec_block_param_data = -1;
279 static gint ett_tcp_conv = -1;
280 static gint ett_tcp_conv_hdr = -1;
281 static gint ett_msg_fragment = -1;
282 static gint ett_msg_fragments = -1;
284 static expert_field ei_bundle_payload_length = EI_INIT;
285 static expert_field ei_bundle_control_flags_length = EI_INIT;
286 static expert_field ei_bundle_block_control_flags = EI_INIT;
287 static expert_field ei_bundle_sdnv_length = EI_INIT;
288 static expert_field ei_bundle_timestamp_seq_num = EI_INIT;
289 static expert_field ei_bundle_offset_error = EI_INIT;
290 static expert_field ei_block_control_block_cteb_invalid = EI_INIT;
291 static expert_field ei_block_control_block_cteb_valid = EI_INIT;
293 static expert_field ei_tcp_convergence_data_flags = EI_INIT;
294 static expert_field ei_tcp_convergence_segment_length = EI_INIT;
295 static expert_field ei_tcp_convergence_ack_length = EI_INIT;
298 static dissector_handle_t bundle_handle;
300 #define BUNDLE_PORT 4556
302 typedef struct dictionary_data {
303 int bundle_header_dict_length;
305 int dest_scheme_offset;
308 int source_scheme_offset;
311 int report_scheme_offset;
314 int cust_scheme_offset;
319 int source_ssp_offset;
321 int report_ssp_offset;
329 static const value_string packet_type_vals[] = {
330 {((TCP_CONVERGENCE_DATA_SEGMENT>>4) & 0x0F), "Data"},
331 {((TCP_CONVERGENCE_ACK_SEGMENT>>4) & 0x0F), "Ack"},
332 {((TCP_CONVERGENCE_REFUSE_BUNDLE>>4) & 0x0F), "Refuse Bundle"},
333 {((TCP_CONVERGENCE_KEEP_ALIVE>>4) & 0x0F), "Keep Alive"},
334 {((TCP_CONVERGENCE_SHUTDOWN>>4) & 0x0F), "Shutdown"},
338 static const value_string admin_record_type_vals[] = {
339 {ADMIN_REC_TYPE_STATUS_REPORT, "Bundle Status Report"},
340 {ADMIN_REC_TYPE_CUSTODY_SIGNAL, "Custody Signal"},
341 {ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL, "Aggregate Custody Signal"},
342 {ADMIN_REC_TYPE_ANNOUNCE_BUNDLE, "Announce Record (Contact)"},
346 static const value_string custody_signal_reason_codes[] = {
347 {0x0, "No Additional Information"},
348 {0x3, "Redundant Reception"},
349 {0x4, "Depleted Storage"},
350 {0x5, "Destination Endpoint ID Unintelligible"},
351 {0x6, "No Known Route to Destination"},
352 {0x7, "No Timely Contact with Next Node on Route"},
353 {0x8, "Header Unintelligible"},
357 static const value_string status_report_reason_codes[] = {
358 {0x0, "No Additional Information"},
359 {0x1, "Lifetime Expired"},
360 {0x2, "Forwarded over Unidirectional Link"},
361 {0x3, "Transmission Cancelled"},
362 {0x4, "Depleted Storage"},
363 {0x5, "Destination Endpoint ID Unintelligible"},
364 {0x6, "No Known Route to Destination"},
365 {0x7, "No Timely Contact with Next Node on Route"},
366 {0x8, "Header Unintelligible"},
370 static const value_string bundle_block_type_codes[] = {
371 {0x01, "Bundle Payload Block"},
372 {0x02, "Bundle Authentication Block"},
373 {0x03, "Block Integrity Block"},
374 {0x04, "Block Confidentiality Block"},
375 {0x05, "Previous-Hop Insertion Block"},
376 {0x08, "Metadata Extension Block"},
377 {0x09, "Extension Security Block"},
378 {0x0a, "Custody Transfer Enhancement Block"},
379 {0x13, "Extended Class of Service Block"},
380 {0x14, "Bundle Age Extension Block"},
384 static const value_string cosflags_priority_vals[] = {
388 {0x03, "Invalid (Reserved)"},
392 static const value_string ciphersuite_types[] = {
394 {0x05, "HMAC_SHA256"},
395 {0x06, "ARC4_AES128"},
396 {0xD1, "HMAC_SHA384"},
397 {0xD2, "ECDSA_SHA256"},
398 {0xD3, "ECDSA_SHA384"},
399 {0xD4, "SHA256_AES128"},
400 {0xD5, "SHA384_AES256"},
404 static const value_string res_params_types[] = {
405 {0x01, "Initialization Vector"},
406 {0x03, "Key Information"},
407 {0x04, "Content Range"},
408 {0x05, "Integrity Signature"},
410 {0x08, "BCB Integrity Check Value"},
415 * SDNV has a zero in high-order bit position of last byte. The high-order
416 * bit of all preceding bytes is set to one. This returns the numeric value
417 * in an integer and sets the value of the second argument to the number of
418 * bytes used to code the SDNV. A -1 is returned if the evaluation fails
419 * (value exceeds maximum for signed integer). 0 is an acceptable value.
422 #define SDNV_MASK 0x7f
424 static const fragment_items msg_frag_items = {
425 /*Fragment subtrees*/
431 &hf_msg_fragment_overlap,
432 &hf_msg_fragment_overlap_conflicts,
433 &hf_msg_fragment_multiple_tails,
434 &hf_msg_fragment_too_long_fragment,
435 &hf_msg_fragment_error,
436 &hf_msg_fragment_count,
437 /*Reassembled in field*/
438 &hf_msg_reassembled_in,
439 /*Reassembled length field*/
440 &hf_msg_reassembled_length,
441 /* Reassembled data field */
448 * Adds the result of 2 SDNVs to tree: First SDNV is seconds, next is nanoseconds.
449 * Returns bytes in both SDNVs or 0 if something goes wrong.
452 add_dtn_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_dtn_time)
455 int sdnv_length, sdnv2_length;
459 orig_offset = offset;
461 sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
462 if (sdnv_value < 0) {
466 dtn_time.secs = (time_t)(sdnv_value + 946684800);
467 offset += sdnv_length;
469 dtn_time.nsecs = evaluate_sdnv(tvb, offset, &sdnv2_length);
470 if (dtn_time.nsecs < 0) {
474 proto_tree_add_time(tree, hf_dtn_time, tvb, orig_offset, sdnv_length + sdnv2_length, &dtn_time);
476 return (sdnv_length + sdnv2_length);
480 * Adds the result of SDNV which is a time since 2000 to tree.
481 * Returns bytes in SDNV or 0 if something goes wrong.
484 add_sdnv_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_sdnv_time)
490 sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
491 if (sdnv_value < 0) {
495 dtn_time.secs = (time_t)(sdnv_value + 946684800);
497 proto_tree_add_time(tree, hf_sdnv_time, tvb, offset, sdnv_length, &dtn_time);
503 add_sdnv_to_tree(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, int offset, int hf_sdnv)
509 sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
510 ti = proto_tree_add_int(tree, hf_sdnv, tvb, offset, sdnv_length, sdnv_value);
511 if (sdnv_value < 0) {
512 expert_add_info(pinfo, ti, &ei_bundle_sdnv_length);
519 * Pull out stuff from the dictionary
522 dissect_dictionary(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, dictionary_data_t* dict_data,
523 guint8 pri_hdr_procflags, gchar **bundle_custodian, int creation_timestamp, int timestamp_sequence)
525 proto_tree *dict_tree;
526 const gchar* col_text;
528 col_text = col_get_text(pinfo->cinfo, COL_INFO);
530 dict_tree = proto_tree_add_subtree(tree, tvb, offset, dict_data->bundle_header_dict_length, ett_dictionary, NULL, "Dictionary");
533 * If the dictionary length is 0, then the CBHE block compression method is applied. (RFC6260)
534 * So the scheme offset is the node number and the ssp offset is the service number.
535 * If destination scheme offset is 2 and destination ssp offset is 1, then the EID is
538 if (dict_data->bundle_header_dict_length == 0)
540 const gchar *src_node, *dst_node;
545 if (dict_data->dest_scheme_offset == 0 && dict_data->dest_ssp_offset == 0)
547 proto_tree_add_string(dict_tree, hf_bundle_dest_scheme, tvb, 0, 0, DTN_SCHEME_STR);
548 proto_tree_add_string(dict_tree, hf_bundle_dest_ssp, tvb, dict_data->dst_scheme_pos,
549 dict_data->dst_scheme_len + dict_data->dst_ssp_len, "none");
551 dst_node = "dtn:none";
555 proto_tree_add_string(dict_tree, hf_bundle_dest_scheme, tvb, 0, 0, IPN_SCHEME_STR);
556 proto_tree_add_string(dict_tree, hf_bundle_dest_ssp, tvb, dict_data->dst_scheme_pos,
557 dict_data->dst_scheme_len + dict_data->dst_ssp_len,
558 wmem_strdup_printf(wmem_packet_scope(), "%d.%d",dict_data->dest_scheme_offset,dict_data->dest_ssp_offset));
560 dst_node = wmem_strdup_printf(wmem_packet_scope(), "%s:%d.%d", IPN_SCHEME_STR,
561 dict_data->dest_scheme_offset, dict_data->dest_ssp_offset);
567 if (dict_data->source_scheme_offset == 0 && dict_data->source_ssp_offset == 0)
569 proto_tree_add_string(dict_tree, hf_bundle_source_scheme, tvb, 0, 0, DTN_SCHEME_STR);
570 proto_tree_add_string(dict_tree, hf_bundle_source_ssp, tvb, dict_data->src_scheme_pos,
571 dict_data->src_scheme_len + dict_data->src_ssp_len, "none");
573 src_node = "dtn:none";
577 proto_tree_add_string(dict_tree, hf_bundle_source_scheme, tvb, 0, 0, IPN_SCHEME_STR);
578 proto_tree_add_string(dict_tree, hf_bundle_source_ssp, tvb, dict_data->src_scheme_pos,
579 dict_data->src_scheme_len + dict_data->src_ssp_len,
580 wmem_strdup_printf(wmem_packet_scope(), "%d.%d", dict_data->source_scheme_offset, dict_data->source_ssp_offset));
582 src_node = wmem_strdup_printf(wmem_packet_scope(), "%s:%d.%d", IPN_SCHEME_STR,
583 dict_data->source_scheme_offset, dict_data->source_ssp_offset);
589 if (dict_data->report_scheme_offset == 0 && dict_data->report_ssp_offset == 0)
591 proto_tree_add_string(dict_tree, hf_bundle_report_scheme, tvb, 0, 0, DTN_SCHEME_STR);
592 proto_tree_add_string(dict_tree, hf_bundle_report_ssp, tvb, dict_data->rpt_scheme_pos,
593 dict_data->rpt_scheme_len + dict_data->rpt_ssp_len, "none");
597 proto_tree_add_string(dict_tree, hf_bundle_report_scheme, tvb, 0, 0, IPN_SCHEME_STR);
598 proto_tree_add_string(dict_tree, hf_bundle_report_ssp, tvb, dict_data->rpt_scheme_pos,
599 dict_data->rpt_scheme_len + dict_data->rpt_ssp_len,
600 wmem_strdup_printf(wmem_packet_scope(), "%d.%d", dict_data->report_scheme_offset, dict_data->report_ssp_offset));
606 if (dict_data->cust_scheme_offset == 0 && dict_data->cust_ssp_offset == 0)
608 proto_tree_add_string(dict_tree, hf_bundle_custodian_scheme, tvb, 0, 0, DTN_SCHEME_STR);
609 proto_tree_add_string(dict_tree, hf_bundle_custodian_ssp, tvb, dict_data->cust_scheme_pos,
610 dict_data->cust_scheme_len + dict_data->cust_ssp_len, "none");
614 proto_tree_add_string(dict_tree, hf_bundle_custodian_scheme, tvb, 0, 0, IPN_SCHEME_STR);
615 proto_tree_add_string(dict_tree, hf_bundle_custodian_ssp, tvb, dict_data->cust_scheme_pos,
616 dict_data->cust_scheme_len + dict_data->cust_ssp_len,
617 wmem_strdup_printf(wmem_packet_scope(), "%d.%d", dict_data->cust_scheme_offset, dict_data->cust_ssp_offset));
620 /* remember custodian, for use in checking cteb validity */
621 col_set_writable(pinfo->cinfo, COL_INFO, TRUE);
622 col_clear_fence(pinfo->cinfo, COL_INFO);
623 if (col_text && strstr(col_text, " > ")) {
624 if (! strstr(col_text, "[multiple]")) {
625 col_append_str(pinfo->cinfo, COL_INFO, ", [multiple]");
628 col_clear(pinfo->cinfo, COL_INFO);
629 col_add_fstr(pinfo->cinfo, COL_INFO, "%s > %s %d.%d", src_node, dst_node, creation_timestamp, timestamp_sequence);
631 col_set_fence(pinfo->cinfo, COL_INFO);
633 *bundle_custodian = wmem_strdup_printf(wmem_packet_scope(), "%s:%d.%d", IPN_SCHEME_STR,
634 dict_data->cust_scheme_offset, dict_data->cust_ssp_offset);
638 * This pointer can be made to address outside the packet boundaries so we
639 * need to check for improperly formatted strings (no null termination).
648 proto_tree_add_item(dict_tree, hf_bundle_dest_scheme,
649 tvb, offset + dict_data->dest_scheme_offset, -1, ENC_ASCII|ENC_NA);
650 proto_tree_add_item(dict_tree, hf_bundle_dest_ssp,
651 tvb, offset + dict_data->dest_ssp_offset, -1, ENC_ASCII|ENC_NA);
657 proto_tree_add_item(dict_tree, hf_bundle_source_scheme,
658 tvb, offset + dict_data->source_scheme_offset, -1, ENC_ASCII|ENC_NA);
659 proto_tree_add_item(dict_tree, hf_bundle_source_ssp,
660 tvb, offset + dict_data->source_ssp_offset, -1, ENC_ASCII|ENC_NA);
666 proto_tree_add_item(dict_tree, hf_bundle_report_scheme,
667 tvb, offset + dict_data->report_scheme_offset, -1, ENC_ASCII|ENC_NA);
668 proto_tree_add_item(dict_tree, hf_bundle_report_ssp,
669 tvb, offset + dict_data->report_ssp_offset, -1, ENC_ASCII|ENC_NA);
675 proto_tree_add_item(dict_tree, hf_bundle_custodian_scheme, tvb, offset + dict_data->cust_scheme_offset, -1, ENC_ASCII|ENC_NA);
676 proto_tree_add_item(dict_tree, hf_bundle_custodian_ssp, tvb, offset + dict_data->cust_ssp_offset, -1, ENC_ASCII|ENC_NA);
679 * Add Source/Destination to INFO Field
682 col_set_writable(pinfo->cinfo, COL_INFO, TRUE);
683 col_clear_fence(pinfo->cinfo, COL_INFO);
684 if (col_text && strstr(col_text, " > "))
685 col_append_str(pinfo->cinfo, COL_INFO, ", [multiple]");
687 col_clear(pinfo->cinfo, COL_INFO);
688 col_add_fstr(pinfo->cinfo, COL_INFO, "%s:%s > %s:%s %d.%d",
689 tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset + dict_data->source_scheme_offset, NULL, ENC_ASCII),
690 tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset + dict_data->source_ssp_offset, NULL, ENC_ASCII),
691 tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset + dict_data->dest_scheme_offset, NULL, ENC_ASCII),
692 tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset + dict_data->dest_ssp_offset, NULL, ENC_ASCII),
693 creation_timestamp, timestamp_sequence);
695 col_set_fence(pinfo->cinfo, COL_INFO);
698 /* remember custodian, for use in checking cteb validity */
699 *bundle_custodian = wmem_strdup_printf(wmem_packet_scope(),
701 tvb_get_stringz_enc(wmem_packet_scope(),
702 tvb, offset + dict_data->cust_scheme_offset,
704 tvb_get_stringz_enc(wmem_packet_scope(),
705 tvb, offset + dict_data->cust_ssp_offset,
708 offset += dict_data->bundle_header_dict_length; /*Skip over dictionary*/
711 * Do this only if Fragment Flag is set
714 if (pri_hdr_procflags & BUNDLE_PROCFLAGS_FRAG_MASK) {
716 sdnv_length = add_sdnv_to_tree(tree, tvb, pinfo, offset, hf_bundle_primary_fragment_offset);
717 if (sdnv_length < 0) {
720 offset += sdnv_length;
722 sdnv_length = add_sdnv_to_tree(tree, tvb, pinfo, offset, hf_bundle_primary_total_adu_len);
723 if (sdnv_length < 0) {
726 offset += sdnv_length;
733 * This routine returns 0 if header decoding fails, otherwise the length of the primary
734 * header, starting right after version number.
737 dissect_version_4_primary_header(packet_info *pinfo, proto_tree *primary_tree, tvbuff_t *tvb,
738 guint8* pri_hdr_procflags, gchar **bundle_custodian)
740 int bundle_header_length;
741 int offset = 1; /* Version Number already displayed */
743 dictionary_data_t dict_data;
746 proto_tree *srr_flag_tree, *proc_flag_tree, *cos_flag_tree;
748 /* Primary Header Processing Flags */
749 *pri_hdr_procflags = tvb_get_guint8(tvb, offset);
750 ti = proto_tree_add_item(primary_tree, hf_bundle_procflags, tvb,
751 offset, 1, ENC_BIG_ENDIAN);
752 proc_flag_tree = proto_item_add_subtree(ti, ett_proc_flags);
753 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_fragment,
754 tvb, offset, 1, ENC_BIG_ENDIAN);
755 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_admin,
756 tvb, offset, 1, ENC_BIG_ENDIAN);
757 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_dont_fragment,
758 tvb, offset, 1, ENC_BIG_ENDIAN);
759 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_cust_xfer_req,
760 tvb, offset, 1, ENC_BIG_ENDIAN);
761 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_dest_singleton,
762 tvb, offset, 1, ENC_BIG_ENDIAN);
764 /* Primary Header COS Flags */
766 ti = proto_tree_add_item(primary_tree, hf_bundle_cosflags, tvb,
767 offset, 1, ENC_BIG_ENDIAN);
768 cos_flag_tree = proto_item_add_subtree(ti, ett_cos_flags);
769 proto_tree_add_item(cos_flag_tree, hf_bundle_cosflags_priority,
770 tvb, offset, 1, ENC_BIG_ENDIAN);
771 /* Status Report Request Flags */
773 ti = proto_tree_add_item(primary_tree, hf_bundle_srrflags, tvb,
774 offset, 1, ENC_BIG_ENDIAN);
775 srr_flag_tree = proto_item_add_subtree(ti, ett_srr_flags);
777 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_receipt,
778 tvb, offset, 1, ENC_BIG_ENDIAN);
779 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_cust_accept,
780 tvb, offset, 1, ENC_BIG_ENDIAN);
781 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_forward,
782 tvb, offset, 1, ENC_BIG_ENDIAN);
783 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_delivery,
784 tvb, offset, 1, ENC_BIG_ENDIAN);
785 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_deletion,
786 tvb, offset, 1, ENC_BIG_ENDIAN);
787 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_ack,
788 tvb, offset, 1, ENC_BIG_ENDIAN);
791 bundle_header_length = evaluate_sdnv(tvb, offset, &sdnv_length);
792 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_header_len, tvb, offset, sdnv_length,
793 bundle_header_length);
794 if (bundle_header_length < 0) {
795 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Bundle Header Length Error");
799 offset += sdnv_length;
801 /* Ensure all fields have been initialized */
802 memset(&dict_data, 0, sizeof(dict_data));
805 * Pick up offsets into dictionary (8 of them)
808 dict_data.dest_scheme_offset = tvb_get_ntohs(tvb, offset);
809 dict_data.dst_scheme_pos = offset;
810 dict_data.dst_scheme_len = 2;
811 proto_tree_add_item(primary_tree, hf_bundle_dest_scheme_offset_u16,
812 tvb, offset, 2, ENC_BIG_ENDIAN);
815 dict_data.dest_ssp_offset = tvb_get_ntohs(tvb, offset);
816 dict_data.dst_ssp_len = 2;
817 proto_tree_add_item(primary_tree, hf_bundle_dest_ssp_offset_u16,
818 tvb, offset, 2, ENC_BIG_ENDIAN);
821 dict_data.source_scheme_offset = tvb_get_ntohs(tvb, offset);
822 dict_data.src_scheme_pos = offset;
823 dict_data.src_scheme_len = 2;
824 proto_tree_add_item(primary_tree, hf_bundle_source_scheme_offset_u16,
825 tvb, offset, 2, ENC_BIG_ENDIAN);
828 dict_data.source_ssp_offset = tvb_get_ntohs(tvb, offset);
829 dict_data.src_ssp_len = 2;
830 proto_tree_add_item(primary_tree, hf_bundle_source_ssp_offset_u16,
831 tvb, offset, 2, ENC_BIG_ENDIAN);
834 dict_data.report_scheme_offset = tvb_get_ntohs(tvb, offset);
835 dict_data.rpt_scheme_pos = offset;
836 dict_data.rpt_scheme_len = 2;
837 proto_tree_add_item(primary_tree, hf_bundle_report_scheme_offset_u16,
838 tvb, offset, 2, ENC_BIG_ENDIAN);
841 dict_data.report_ssp_offset = tvb_get_ntohs(tvb, offset);
842 dict_data.rpt_ssp_len = 2;
843 proto_tree_add_item(primary_tree, hf_bundle_report_ssp_offset_u16,
844 tvb, offset, 2, ENC_BIG_ENDIAN);
847 dict_data.cust_scheme_offset = tvb_get_ntohs(tvb, offset);
848 dict_data.cust_scheme_pos = offset;
849 dict_data.cust_scheme_len = 2;
850 proto_tree_add_item(primary_tree, hf_bundle_cust_scheme_offset_u16,
851 tvb, offset, 2, ENC_BIG_ENDIAN);
854 dict_data.cust_ssp_offset = tvb_get_ntohs(tvb, offset);
855 dict_data.cust_ssp_len = 2;
856 proto_tree_add_item(primary_tree, hf_bundle_cust_ssp_offset_u16,
857 tvb, offset, 2, ENC_BIG_ENDIAN);
860 proto_tree_add_item(primary_tree, hf_bundle_creation_timestamp,
861 tvb, offset, 8, ENC_BIG_ENDIAN);
864 proto_tree_add_item(primary_tree, hf_bundle_lifetime, tvb, offset, 4, ENC_BIG_ENDIAN);
867 dict_data.bundle_header_dict_length = evaluate_sdnv(tvb, offset, &sdnv_length);
868 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_dictionary_len, tvb, offset, sdnv_length,
869 dict_data.bundle_header_dict_length);
870 if (dict_data.bundle_header_dict_length < 0) {
871 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Dictionary Header Length Error");
874 offset += sdnv_length;
876 offset = dissect_dictionary(pinfo, primary_tree, tvb, offset, &dict_data, *pri_hdr_procflags, bundle_custodian, 0, 0);
882 * This routine returns 0 if header decoding fails, otherwise the length of the primary
883 * header, starting right after version number.
887 dissect_version_5_and_6_primary_header(packet_info *pinfo,
888 proto_tree *primary_tree, tvbuff_t *tvb,
889 guint8* pri_hdr_procflags, gchar **bundle_custodian)
891 guint64 bundle_processing_control_flags;
893 int bundle_header_length;
894 int offset = 1; /* Version Number already displayed */
896 dictionary_data_t dict_data;
897 int timestamp_sequence;
898 int creation_timestamp;
901 proto_item *ti_dst_scheme_offset, *ti_dst_ssp_offset;
902 proto_item *ti_src_scheme_offset, *ti_src_ssp_offset;
903 proto_item *ti_cust_scheme_offset, *ti_cust_ssp_offset;
904 proto_item *ti_rprt_scheme_offset, *ti_rprt_ssp_offset;
905 proto_tree *gen_flag_tree, *srr_flag_tree, *proc_flag_tree, *cos_flag_tree;
906 static const int * pri_flags[] = {
907 &hf_bundle_procflags_fragment,
908 &hf_bundle_procflags_admin,
909 &hf_bundle_procflags_dont_fragment,
910 &hf_bundle_procflags_cust_xfer_req,
911 &hf_bundle_procflags_dest_singleton,
912 &hf_bundle_procflags_application_ack,
916 static const int * srr_flags[] = {
917 &hf_bundle_srrflags_report_receipt,
918 &hf_bundle_srrflags_report_cust_accept,
919 &hf_bundle_srrflags_report_forward,
920 &hf_bundle_srrflags_report_delivery,
921 &hf_bundle_srrflags_report_deletion,
925 bundle_processing_control_flags = evaluate_sdnv_64(tvb, offset, &sdnv_length);
927 /* Primary Header Processing Flags */
928 *pri_hdr_procflags = (guint8) (bundle_processing_control_flags & 0x7f);
930 if (sdnv_length < 1 || sdnv_length > 8) {
931 expert_add_info_format(pinfo, primary_tree, &ei_bundle_control_flags_length,
932 "Wrong bundle control flag length: %d", sdnv_length);
935 ti = proto_tree_add_item(primary_tree, hf_bundle_control_flags, tvb,
936 offset, sdnv_length, ENC_BIG_ENDIAN);
937 proc_flag_tree = proto_item_add_subtree(ti, ett_proc_flags);
939 ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_general, tvb, offset,
940 sdnv_length, *pri_hdr_procflags);
941 gen_flag_tree = proto_item_add_subtree(ti, ett_gen_flags);
943 /* With the variability of sdnv_length, proto_tree_add_bitmask_value
946 proto_tree_add_bitmask_list_value(gen_flag_tree, tvb, offset, sdnv_length, pri_flags, *pri_hdr_procflags);
948 /* Primary Header COS Flags */
949 cosflags = (guint8) ((bundle_processing_control_flags >> 7) & 0x7f);
950 ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_cos, tvb, offset,
951 sdnv_length, cosflags);
952 cos_flag_tree = proto_item_add_subtree(ti, ett_cos_flags);
953 proto_tree_add_uint(cos_flag_tree, hf_bundle_cosflags_priority, tvb, offset,
954 sdnv_length, cosflags);
956 /* Status Report Request Flags */
957 srrflags = (guint8) ((bundle_processing_control_flags >> 14) & 0x7f);
958 ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_status, tvb, offset,
959 sdnv_length, srrflags);
960 srr_flag_tree = proto_item_add_subtree(ti, ett_srr_flags);
962 proto_tree_add_bitmask_list_value(srr_flag_tree, tvb, offset, sdnv_length, srr_flags, srrflags);
963 offset += sdnv_length;
965 /* -- hdr_length -- */
966 bundle_header_length = evaluate_sdnv(tvb, offset, &sdnv_length);
967 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_header_len, tvb, offset, sdnv_length,
968 bundle_header_length);
969 if (bundle_header_length < 0) {
970 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Bundle Header Length Error");
974 offset += sdnv_length;
977 * Pick up offsets into dictionary (8 of them). Do rough sanity check that SDNV
978 * hasn't told us to access way past the Primary Header.
981 /* Ensure all fields have been initialized */
982 memset(&dict_data, 0, sizeof(dict_data));
984 /* -- dest_scheme -- */
985 dict_data.dest_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
986 dict_data.dst_scheme_pos = offset;
987 dict_data.dst_scheme_len = sdnv_length;
989 ti_dst_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_dest_scheme_offset_i32, tvb, offset, sdnv_length,
990 dict_data.dest_scheme_offset);
991 offset += sdnv_length;
994 dict_data.dest_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
995 dict_data.dst_ssp_len = sdnv_length;
997 ti_dst_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_dest_ssp_offset_i32, tvb, offset, sdnv_length,
998 dict_data.dest_ssp_offset);
999 offset += sdnv_length;
1001 /* -- source_scheme -- */
1002 dict_data.source_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1003 dict_data.src_scheme_pos = offset;
1004 dict_data.src_scheme_len = sdnv_length;
1006 ti_src_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_source_scheme_offset_i32, tvb, offset, sdnv_length,
1007 dict_data.source_scheme_offset);
1008 offset += sdnv_length;
1010 /* -- source_ssp -- */
1011 dict_data.source_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1012 dict_data.src_ssp_len = sdnv_length;
1014 ti_src_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_source_ssp_offset_i32, tvb, offset, sdnv_length,
1015 dict_data.source_ssp_offset);
1016 offset += sdnv_length;
1018 /* -- report_scheme -- */
1019 dict_data.report_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1020 dict_data.rpt_scheme_pos = offset;
1021 dict_data.rpt_scheme_len = sdnv_length;
1023 ti_rprt_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_report_scheme_offset_i32, tvb, offset,
1024 sdnv_length, dict_data.report_scheme_offset);
1025 offset += sdnv_length;
1027 /* -- report_ssp -- */
1028 dict_data.report_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1029 dict_data.rpt_ssp_len = sdnv_length;
1031 ti_rprt_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_report_ssp_offset_i32, tvb, offset, sdnv_length,
1032 dict_data.report_ssp_offset);
1033 offset += sdnv_length;
1036 /* -- cust_scheme -- */
1037 dict_data.cust_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1038 dict_data.cust_scheme_pos = offset;
1039 dict_data.cust_scheme_len = sdnv_length;
1041 ti_cust_scheme_offset = proto_tree_add_int(primary_tree, hf_bundle_cust_scheme_offset_i32, tvb, offset, sdnv_length,
1042 dict_data.cust_scheme_offset);
1043 offset += sdnv_length;
1045 /* -- cust_ssp -- */
1046 dict_data.cust_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1047 dict_data.cust_ssp_len = sdnv_length;
1049 ti_cust_ssp_offset = proto_tree_add_int(primary_tree, hf_bundle_cust_ssp_offset_i32, tvb, offset, sdnv_length,
1050 dict_data.cust_ssp_offset);
1051 offset += sdnv_length;
1054 creation_timestamp = evaluate_sdnv(tvb, offset, &sdnv_length);
1055 sdnv_length = add_sdnv_time_to_tree(primary_tree, tvb, offset, hf_bundle_primary_timestamp);
1056 if (sdnv_length == 0)
1059 offset += sdnv_length;
1061 /* -- timestamp_sequence -- */
1062 timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1063 if (timestamp_sequence < 0) {
1064 gint64 ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1066 ti = proto_tree_add_int64(primary_tree, hf_bundle_primary_timestamp_seq_num64,
1067 tvb, offset, sdnv_length, ts_seq);
1069 expert_add_info(pinfo, ti, &ei_bundle_timestamp_seq_num);
1073 proto_tree_add_int(primary_tree, hf_bundle_primary_timestamp_seq_num32,
1074 tvb, offset, sdnv_length, timestamp_sequence);
1076 offset += sdnv_length;
1078 /* -- lifetime -- */
1079 sdnv_length = add_sdnv_to_tree(primary_tree, tvb, pinfo, offset, hf_bundle_lifetime_sdnv);
1080 offset += sdnv_length;
1082 /* -- dict_length -- */
1083 dict_data.bundle_header_dict_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1084 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_dictionary_len, tvb, offset, sdnv_length,
1085 dict_data.bundle_header_dict_length);
1086 if (dict_data.bundle_header_dict_length < 0) {
1087 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Dictionary Header Length Error");
1090 offset += sdnv_length;
1092 if ((dict_data.dest_scheme_offset < 0) ||
1093 (dict_data.bundle_header_dict_length > 0 && (dict_data.dest_scheme_offset > bundle_header_length))) {
1094 expert_add_info_format(pinfo, ti_dst_scheme_offset, &ei_bundle_offset_error, "Destination Scheme Offset Error");
1096 if ((dict_data.dest_ssp_offset < 0) ||
1097 (dict_data.bundle_header_dict_length > 0 && (dict_data.dest_ssp_offset > bundle_header_length))) {
1098 expert_add_info_format(pinfo, ti_dst_ssp_offset, &ei_bundle_offset_error, "Destination SSP Offset Error");
1100 if ((dict_data.source_scheme_offset < 0) ||
1101 (dict_data.bundle_header_dict_length > 0 && (dict_data.source_scheme_offset > bundle_header_length))) {
1102 expert_add_info_format(pinfo, ti_src_scheme_offset, &ei_bundle_offset_error, "Source Scheme Offset Error");
1104 if ((dict_data.source_ssp_offset < 0) ||
1105 (dict_data.bundle_header_dict_length > 0 && (dict_data.source_ssp_offset > bundle_header_length))) {
1106 expert_add_info_format(pinfo, ti_src_ssp_offset, &ei_bundle_offset_error, "Source SSP Offset Error");
1108 if ((dict_data.report_scheme_offset < 0) ||
1109 (dict_data.bundle_header_dict_length > 0 && (dict_data.report_scheme_offset > bundle_header_length))) {
1110 expert_add_info_format(pinfo, ti_rprt_scheme_offset, &ei_bundle_offset_error, "Report Scheme Offset Error");
1112 if ((dict_data.report_ssp_offset < 0) ||
1113 (dict_data.bundle_header_dict_length > 0 && (dict_data.report_ssp_offset > bundle_header_length))) {
1114 expert_add_info_format(pinfo, ti_rprt_ssp_offset, &ei_bundle_offset_error, "Report SSP Offset Error");
1116 if ((dict_data.cust_scheme_offset < 0) ||
1117 (dict_data.bundle_header_dict_length > 0 && (dict_data.cust_scheme_offset > bundle_header_length))) {
1118 expert_add_info_format(pinfo, ti_cust_scheme_offset, &ei_bundle_offset_error, "Custodian Scheme Offset Error");
1120 if ((dict_data.cust_ssp_offset < 0) ||
1121 (dict_data.bundle_header_dict_length > 0 && (dict_data.cust_ssp_offset > bundle_header_length))) {
1122 expert_add_info_format(pinfo, ti_cust_ssp_offset, &ei_bundle_offset_error, "Custodian SSP Offset Error");
1125 offset = dissect_dictionary(pinfo, primary_tree, tvb, offset, &dict_data, *pri_hdr_procflags, bundle_custodian,
1126 creation_timestamp, timestamp_sequence);
1131 * offset is where the header starts.
1132 * Return new offset, and set lastheader if failure.
1135 dissect_payload_header(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, guint8 version,
1136 guint8 pri_hdr_procflags, gboolean *lastheader)
1138 proto_item *payload_block, *payload_item, *ti;
1139 proto_tree *payload_block_tree, *payload_tree;
1140 int sdnv_length, payload_length;
1142 payload_block_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_payload_hdr, &payload_block, "Payload Block");
1144 payload_tree = proto_tree_add_subtree(payload_block_tree, tvb, offset, -1, ett_payload_hdr, &payload_item, "Payload Header");
1146 proto_tree_add_uint(payload_tree, hf_bundle_payload_header_type, tvb, offset, 1, 1);
1149 /* Add tree for processing flags */
1150 /* This is really a SDNV but there are only 7 bits defined so leave it this way*/
1153 static const gint *flags[] = {
1154 &hf_bundle_payload_flags_replicate_hdr,
1155 &hf_bundle_payload_flags_xmit_report,
1156 &hf_bundle_payload_flags_discard_on_fail,
1157 &hf_bundle_payload_flags_last_header,
1162 procflags = tvb_get_guint8(tvb, offset);
1163 if (procflags & HEADER_PROCFLAGS_LAST_HEADER) {
1167 *lastheader = FALSE;
1169 proto_tree_add_bitmask(payload_tree, tvb, offset, hf_bundle_payload_flags,
1170 ett_payload_flags, flags, ENC_BIG_ENDIAN);
1173 else { /*Bundle Protocol Version 5*/
1175 proto_item *block_flag_item;
1176 proto_tree *block_flag_tree;
1178 control_flags = evaluate_sdnv(tvb, offset, &sdnv_length);
1179 if (control_flags & BLOCK_CONTROL_LAST_BLOCK) {
1183 *lastheader = FALSE;
1185 block_flag_item = proto_tree_add_item(payload_tree, hf_block_control_flags, tvb,
1186 offset, sdnv_length, ENC_BIG_ENDIAN);
1187 block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1189 proto_tree_add_item(block_flag_tree, hf_block_control_replicate,
1190 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1191 proto_tree_add_item(block_flag_tree, hf_block_control_transmit_status,
1192 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1193 proto_tree_add_item(block_flag_tree, hf_block_control_delete_bundle,
1194 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1195 proto_tree_add_item(block_flag_tree, hf_block_control_last_block,
1196 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1197 proto_tree_add_item(block_flag_tree, hf_block_control_discard_block,
1198 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1199 proto_tree_add_item(block_flag_tree, hf_block_control_not_processed,
1200 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1201 proto_tree_add_item(block_flag_tree, hf_block_control_eid_reference,
1202 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1203 offset += sdnv_length;
1206 payload_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1207 ti = proto_tree_add_int(payload_tree, hf_bundle_payload_length, tvb, offset, sdnv_length, payload_length);
1208 if (payload_length < 0) {
1209 expert_add_info(pinfo, ti, &ei_bundle_payload_length);
1215 proto_item_set_len(payload_item, 2 + sdnv_length);
1216 proto_item_set_len(payload_block, 2 + sdnv_length + payload_length);
1218 offset += sdnv_length;
1219 if (pri_hdr_procflags & BUNDLE_PROCFLAGS_ADMIN_MASK) {
1220 gboolean success = FALSE;
1223 * XXXX - Have not allowed for admin record spanning multiple segments!
1226 offset = dissect_admin_record(payload_block_tree, tvb, pinfo, offset, payload_length, &success);
1233 proto_tree_add_item(payload_block_tree, hf_bundle_payload_data, tvb, offset, payload_length, ENC_ASCII);
1234 offset += payload_length;
1241 * Return the offset after the Administrative Record or set success = FALSE if analysis fails.
1244 dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, packet_info *pinfo,
1245 int offset, int payload_length, gboolean* success)
1247 proto_item *admin_record_item;
1248 proto_tree *admin_record_tree;
1249 proto_item *timestamp_sequence_item;
1252 int start_offset = offset;
1254 int timestamp_sequence;
1255 int endpoint_length;
1258 admin_record_tree = proto_tree_add_subtree(primary_tree, tvb, offset, -1,
1259 ett_admin_record, &admin_record_item, "Administrative Record");
1260 record_type = tvb_get_guint8(tvb, offset);
1262 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1264 switch ((record_type >> 4) & 0xf)
1266 case ADMIN_REC_TYPE_STATUS_REPORT:
1268 proto_item *status_flag_item;
1269 proto_tree *status_flag_tree;
1271 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1274 /* Decode Bundle Status Report Flags */
1275 status = tvb_get_guint8(tvb, offset);
1276 status_flag_item = proto_tree_add_item(admin_record_tree,
1277 hf_bundle_admin_statflags, tvb, offset, 1, ENC_BIG_ENDIAN);
1278 status_flag_tree = proto_item_add_subtree(status_flag_item,
1279 ett_admin_rec_status);
1280 proto_tree_add_item(status_flag_tree, hf_bundle_admin_rcvd,
1281 tvb, offset, 1, ENC_BIG_ENDIAN);
1282 proto_tree_add_item(status_flag_tree, hf_bundle_admin_accepted,
1283 tvb, offset, 1, ENC_BIG_ENDIAN);
1284 proto_tree_add_item(status_flag_tree, hf_bundle_admin_forwarded,
1285 tvb, offset, 1, ENC_BIG_ENDIAN);
1286 proto_tree_add_item(status_flag_tree, hf_bundle_admin_delivered,
1287 tvb, offset, 1, ENC_BIG_ENDIAN);
1288 proto_tree_add_item(status_flag_tree, hf_bundle_admin_deleted,
1289 tvb, offset, 1, ENC_BIG_ENDIAN);
1290 proto_tree_add_item(status_flag_tree, hf_bundle_admin_acked,
1291 tvb, offset, 1, ENC_BIG_ENDIAN);
1294 proto_tree_add_item(admin_record_tree, hf_bundle_status_report_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1297 if (record_type & ADMIN_REC_FLAGS_FRAGMENT) {
1298 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_offset);
1299 if (sdnv_length <= 0) {
1302 offset += sdnv_length;
1303 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_length);
1304 if (sdnv_length <= 0) {
1307 offset += sdnv_length;
1309 if (status & ADMIN_STATUS_FLAGS_RECEIVED) {
1310 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_receipt_time);
1311 if (sdnv_length <= 0) {
1314 offset += sdnv_length;
1316 if (status & ADMIN_STATUS_FLAGS_ACCEPTED) {
1317 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_accept_time);
1318 if (sdnv_length <= 0) {
1321 offset += sdnv_length;
1323 if (status & ADMIN_STATUS_FLAGS_FORWARDED) {
1324 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_forward_time);
1325 if (sdnv_length <= 0) {
1328 offset += sdnv_length;
1330 if (status & ADMIN_STATUS_FLAGS_DELIVERED) {
1331 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_delivery_time);
1332 if (sdnv_length <= 0) {
1335 offset += sdnv_length;
1337 if (status & ADMIN_STATUS_FLAGS_DELETED) {
1338 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_delete_time);
1339 if (sdnv_length <= 0) {
1342 offset += sdnv_length;
1344 if (status & ADMIN_STATUS_FLAGS_ACKNOWLEDGED) {
1345 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_ack_time);
1346 if (sdnv_length <= 0) {
1349 offset += sdnv_length;
1352 /* Get 2 SDNVs for Creation Timestamp */
1353 sdnv_length = add_sdnv_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_timestamp_copy);
1354 if (sdnv_length <= 0) {
1357 offset += sdnv_length;
1359 timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1360 if (timestamp_sequence < 0) {
1361 gint64 ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1363 timestamp_sequence_item = proto_tree_add_int64(admin_record_tree, hf_bundle_admin_timestamp_seq_num64,
1364 tvb, offset, sdnv_length, ts_seq);
1366 expert_add_info(pinfo, timestamp_sequence_item, &ei_bundle_timestamp_seq_num);
1371 proto_tree_add_int(admin_record_tree, hf_bundle_admin_timestamp_seq_num32,
1372 tvb, offset, sdnv_length, timestamp_sequence);
1374 offset += sdnv_length;
1376 endpoint_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1377 if (endpoint_length < 0) {
1380 proto_tree_add_int(admin_record_tree, hf_bundle_admin_endpoint_length, tvb, offset, sdnv_length, endpoint_length);
1381 offset += sdnv_length;
1384 * Endpoint name may not be null terminated. This routine is supposed
1385 * to add the null at the end of the string buffer.
1387 proto_tree_add_item(admin_record_tree, hf_bundle_admin_endpoint_id, tvb, offset, endpoint_length, ENC_NA|ENC_ASCII);
1388 offset += endpoint_length;
1391 } /* case ADMIN_REC_TYPE_STATUS_REPORT */
1392 case ADMIN_REC_TYPE_CUSTODY_SIGNAL:
1394 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1397 proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
1398 proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
1401 if (record_type & ADMIN_REC_FLAGS_FRAGMENT) {
1402 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_offset);
1403 if (sdnv_length <= 0) {
1406 offset += sdnv_length;
1407 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_length);
1408 if (sdnv_length <= 0) {
1411 offset += sdnv_length;
1415 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_signal_time);
1416 if (sdnv_length <= 0) {
1419 offset += sdnv_length;
1421 /* Timestamp copy */
1422 sdnv_length = add_sdnv_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_timestamp_copy);
1423 if (sdnv_length <= 0) {
1426 offset += sdnv_length;
1428 timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1429 if (timestamp_sequence < 0) {
1430 gint64 ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1432 timestamp_sequence_item = proto_tree_add_int64(admin_record_tree, hf_bundle_admin_timestamp_seq_num64,
1433 tvb, offset, sdnv_length, ts_seq);
1435 expert_add_info(pinfo, timestamp_sequence_item, &ei_bundle_timestamp_seq_num);
1440 proto_tree_add_int(admin_record_tree, hf_bundle_admin_timestamp_seq_num32,
1441 tvb, offset, sdnv_length, timestamp_sequence);
1443 offset += sdnv_length;
1445 endpoint_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1446 if (endpoint_length < 0) {
1449 proto_tree_add_int(admin_record_tree, hf_bundle_admin_endpoint_length, tvb, offset, sdnv_length, endpoint_length);
1450 offset += sdnv_length;
1451 proto_tree_add_item(admin_record_tree, hf_bundle_admin_endpoint_id, tvb, offset, endpoint_length, ENC_NA|ENC_ASCII);
1452 offset += endpoint_length;
1454 } /* case ADMIN_REC_TYPE_CUSTODY_SIGNAL */
1455 case ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL:
1458 int payload_bytes_processed = 0;
1459 int right_edge = -1;
1461 int fill_length = -1;
1462 int sdnv_length_start = -1;
1463 int sdnv_length_gap = -1;
1464 int sdnv_length_length = -1;
1466 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1468 ++payload_bytes_processed;
1470 proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
1471 proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
1473 ++payload_bytes_processed;
1475 /* process the first fill */
1476 fill_start = evaluate_sdnv(tvb, offset, &sdnv_length_start);
1477 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_start, tvb, offset, sdnv_length_start, fill_start);
1478 if (fill_start < 0 || sdnv_length_start < 0) {
1479 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range start SDNV");
1482 fill_length = evaluate_sdnv(tvb, offset + sdnv_length_start, &sdnv_length_length);
1483 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_end, tvb, offset,
1484 sdnv_length_start + sdnv_length_length, fill_start + fill_length - 1);
1485 if (fill_length < 0 || sdnv_length_length < 0) {
1486 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range length SDNV");
1490 right_edge = fill_start + fill_length;
1491 offset += sdnv_length_start + sdnv_length_length;
1492 payload_bytes_processed += sdnv_length_start + sdnv_length_length;
1494 /* now attempt to consume all the rest of the data in the
1495 * payload as additional fills */
1496 while (payload_bytes_processed < payload_length) {
1498 fill_gap = evaluate_sdnv(tvb, offset, &sdnv_length_gap);
1499 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_start, tvb, offset, sdnv_length_gap, fill_gap);
1500 if (fill_gap < 0 || sdnv_length_gap < 0) {
1501 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range gap SDNV");
1504 fill_length = evaluate_sdnv(tvb, offset + sdnv_length_gap, &sdnv_length_length);
1505 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_end, tvb, offset,
1506 sdnv_length_gap + sdnv_length_length, right_edge + fill_gap + fill_length - 1);
1507 if (fill_length < 0 || sdnv_length_length < 0) {
1508 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range length SDNV");
1512 right_edge += fill_gap + fill_length;
1513 offset += sdnv_length_gap + sdnv_length_length;
1514 payload_bytes_processed += sdnv_length_gap + sdnv_length_length;
1517 if (payload_bytes_processed > payload_length) {
1518 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "ACS: CTEB Custody ID Range data extends past payload length");
1523 } /* case ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL */
1524 case ADMIN_REC_TYPE_ANNOUNCE_BUNDLE:
1530 proto_item_set_len(admin_record_item, offset - start_offset);
1536 display_extension_block(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, gchar *bundle_custodian, gboolean *lastheader)
1538 proto_item *block_item, *ti, *block_flag_replicate_item, *block_flag_eid_reference_item;
1539 proto_tree *block_tree;
1545 unsigned int control_flags;
1546 proto_tree *block_flag_tree;
1547 proto_item *block_flag_item;
1549 type = tvb_get_guint8(tvb, offset);
1550 block_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_metadata_hdr, &block_item, "Extension Block");
1552 proto_tree_add_item(block_tree, hf_bundle_block_type_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1556 control_flags = (unsigned int)evaluate_sdnv(tvb, offset, &sdnv_length);
1557 if (control_flags & BLOCK_CONTROL_LAST_BLOCK) {
1560 *lastheader = FALSE;
1562 block_flag_item = proto_tree_add_uint(block_tree, hf_block_control_flags_sdnv, tvb,
1563 offset, sdnv_length, control_flags);
1564 block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1565 block_flag_replicate_item = proto_tree_add_boolean(block_flag_tree, hf_block_control_replicate,
1566 tvb, offset, sdnv_length, control_flags);
1567 proto_tree_add_boolean(block_flag_tree, hf_block_control_transmit_status,
1568 tvb, offset, sdnv_length, control_flags);
1569 proto_tree_add_boolean(block_flag_tree, hf_block_control_delete_bundle,
1570 tvb, offset, sdnv_length, control_flags);
1571 proto_tree_add_boolean(block_flag_tree, hf_block_control_last_block,
1572 tvb, offset, sdnv_length, control_flags);
1573 proto_tree_add_boolean(block_flag_tree, hf_block_control_discard_block,
1574 tvb, offset, sdnv_length, control_flags);
1575 proto_tree_add_boolean(block_flag_tree, hf_block_control_not_processed,
1576 tvb, offset, sdnv_length, control_flags);
1577 block_flag_eid_reference_item = proto_tree_add_boolean(block_flag_tree, hf_block_control_eid_reference,
1578 tvb, offset, sdnv_length, control_flags);
1579 offset += sdnv_length;
1580 block_overhead += sdnv_length;
1582 /* TODO: if this block has EID references, add them to display tree */
1583 if (control_flags & BLOCK_CONTROL_EID_REFERENCE) {
1587 num_eid_ref = evaluate_sdnv(tvb, offset, &sdnv_length);
1588 offset += sdnv_length;
1589 block_overhead += sdnv_length;
1591 for (i = 0; i < num_eid_ref; i++)
1593 if (evaluate_sdnv(tvb, offset, &sdnv_length) < 0)
1595 offset += sdnv_length;
1596 block_overhead += sdnv_length;
1598 if (evaluate_sdnv(tvb, offset, &sdnv_length) < 0)
1600 offset += sdnv_length;
1601 block_overhead += sdnv_length;
1605 block_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1606 ti = proto_tree_add_int(block_tree, hf_block_control_block_length, tvb, offset, sdnv_length, block_length);
1607 if (block_length < 0) {
1608 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Metadata Block Length Error");
1609 /* Force quitting */
1613 offset += sdnv_length;
1614 block_overhead += sdnv_length;
1616 /* now we have enough info to know total length of metadata block */
1617 proto_item_set_len(block_item, block_overhead + block_length);
1621 case BUNDLE_BLOCK_TYPE_AUTHENTICATION:
1622 case BUNDLE_BLOCK_TYPE_METADATA_EXTENSION:
1623 case BUNDLE_BLOCK_TYPE_EXTENSION_SECURITY:
1625 proto_tree_add_string(block_tree, hf_bundle_unprocessed_block_data, tvb, offset, block_length, "Block data");
1626 /* not yet dissected, skip past data */
1627 offset += block_length;
1630 case BUNDLE_BLOCK_TYPE_BUNDLE_AGE:
1632 bundle_age = evaluate_sdnv(tvb, offset, &sdnv_length);
1633 proto_tree_add_int(block_tree, hf_bundle_age_extension_block_code, tvb, offset, sdnv_length, bundle_age/1000000);
1634 offset += block_length;
1637 case BUNDLE_BLOCK_TYPE_PREVIOUS_HOP_INSERT:
1641 proto_tree_add_item_ret_length(block_tree, hf_bundle_block_previous_hop_scheme, tvb, offset, 4, ENC_ASCII, &scheme_length);
1642 offset += scheme_length;
1643 proto_tree_add_item(block_tree, hf_bundle_block_previous_hop_eid, tvb, offset, block_length-scheme_length, ENC_ASCII|ENC_NA);
1644 offset += block_length - scheme_length;
1648 case BUNDLE_BLOCK_TYPE_INTEGRITY:
1649 case BUNDLE_BLOCK_TYPE_CONFIDENTIALITY:
1651 int target_block_type;
1652 int target_block_occurance;
1653 int ciphersuite_type;
1654 unsigned int ciphersuite_flags;
1656 target_block_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1657 proto_tree_add_int(block_tree, hf_bundle_target_block_type, tvb, offset, sdnv_length, target_block_type);
1658 offset += sdnv_length;
1660 target_block_occurance = evaluate_sdnv(tvb, offset, &sdnv_length);
1661 proto_tree_add_int(block_tree, hf_bundle_target_block_occurance, tvb, offset, sdnv_length, target_block_occurance);
1662 offset += sdnv_length;
1664 ciphersuite_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1665 proto_tree_add_int(block_tree, hf_bundle_ciphersuite_type, tvb, offset, sdnv_length, ciphersuite_type);
1666 offset += sdnv_length;
1668 ciphersuite_flags = (unsigned int)evaluate_sdnv(tvb, offset, &sdnv_length);
1669 block_flag_item = proto_tree_add_uint(block_tree, hf_bundle_ciphersuite_flags, tvb, offset, sdnv_length, ciphersuite_flags);
1670 block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1671 proto_tree_add_boolean(block_flag_tree, hf_block_ciphersuite_params, tvb, offset, sdnv_length, ciphersuite_flags);
1672 offset += sdnv_length;
1676 if (ciphersuite_flags & BLOCK_CIPHERSUITE_PARAMS) {
1677 /* Decode cipher suite parameters */
1681 proto_tree *param_tree;
1683 params_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1684 param_tree = proto_tree_add_subtree(block_tree, tvb, offset, params_length+1, ett_sec_block_param_data, NULL, "Ciphersuite Parameters Data");
1685 proto_tree_add_int(param_tree, hf_block_ciphersuite_params_length, tvb, offset, sdnv_length, params_length);
1686 offset += sdnv_length;
1688 for(int i = 0; i < params_length; i+=item_length+2)
1690 param_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1691 proto_tree_add_int(param_tree, hf_block_ciphersuite_param_type, tvb, offset, sdnv_length, param_type);
1692 offset += sdnv_length;
1694 item_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1695 proto_tree_add_int(param_tree, hf_block_ciphersuite_params_item_length, tvb, offset, sdnv_length, item_length);
1696 offset += sdnv_length;
1706 proto_tree_add_item(param_tree, hf_block_ciphersuite_param_data, tvb, offset, item_length, ENC_NA);
1707 offset += item_length;
1710 //pair of sdnvs offset and length
1711 range_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1712 proto_tree_add_int(param_tree, hf_block_ciphersuite_range_offset, tvb, offset, sdnv_length, range_offset);
1713 offset += sdnv_length;
1715 range_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1716 proto_tree_add_int(param_tree, hf_block_ciphersuite_range_length, tvb, offset, sdnv_length, range_length);
1717 offset += sdnv_length;
1724 /* Decode cipher suite results */
1727 int result_item_length;
1728 proto_tree *result_tree;
1730 result_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1731 result_tree = proto_tree_add_subtree(block_tree, tvb, offset, result_length+1, ett_sec_block_param_data, NULL, "Security Results Data");
1732 proto_tree_add_int(result_tree, hf_block_ciphersuite_result_length, tvb, offset, sdnv_length, result_length);
1733 offset += sdnv_length;
1735 for(int i = 0; i < result_length; i+=result_item_length+2)
1737 result_type = evaluate_sdnv(tvb, offset, &sdnv_length);
1738 proto_tree_add_int(result_tree, hf_block_ciphersuite_result_type, tvb, offset, sdnv_length, result_type);
1739 offset += sdnv_length;
1741 result_item_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1742 proto_tree_add_int(result_tree, hf_block_ciphersuite_result_item_length, tvb, offset, sdnv_length, result_item_length);
1743 offset += sdnv_length;
1746 switch (result_type)
1753 proto_tree_add_item(result_tree, hf_block_ciphersuite_result_data, tvb, offset, result_item_length, ENC_NA);
1754 offset += result_item_length;
1757 //pair of sdnvs offset and length
1758 range_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
1759 proto_tree_add_int(result_tree, hf_block_ciphersuite_range_offset, tvb, offset, sdnv_length, range_offset);
1760 offset += sdnv_length;
1762 range_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1763 proto_tree_add_int(result_tree, hf_block_ciphersuite_range_length, tvb, offset, sdnv_length, range_length);
1764 offset += sdnv_length;
1774 case BUNDLE_BLOCK_TYPE_CUSTODY_TRANSFER:
1777 const guint8 *cteb_creator_custodian_eid;
1778 int cteb_creator_custodian_eid_length;
1780 /* check requirements for Block Processing Control Flags */
1781 if ((control_flags & BLOCK_CONTROL_REPLICATE) != 0) {
1782 expert_add_info_format(pinfo, block_flag_replicate_item, &ei_bundle_block_control_flags, "ERROR: Replicate must be clear for CTEB");
1784 if ((control_flags & BLOCK_CONTROL_EID_REFERENCE) != 0) {
1785 expert_add_info_format(pinfo, block_flag_eid_reference_item, &ei_bundle_block_control_flags, "ERROR: EID-Reference must be clear for CTEB");
1788 /* there are two elements in a CTEB, first is the custody ID */
1789 custody_id = evaluate_sdnv(tvb, offset, &sdnv_length);
1790 proto_tree_add_int(block_tree, hf_block_control_block_cteb_custody_id, tvb, offset, sdnv_length, custody_id);
1791 offset += sdnv_length;
1793 /* and second is the creator custodian EID */
1794 cteb_creator_custodian_eid_length = block_length - sdnv_length;
1795 ti = proto_tree_add_item_ret_string(block_tree, hf_block_control_block_cteb_creator_custodian_eid, tvb, offset,
1796 cteb_creator_custodian_eid_length, ENC_ASCII, wmem_packet_scope(), &cteb_creator_custodian_eid);
1798 /* also check if CTEB is valid, i.e. custodians match */
1799 if (bundle_custodian == NULL) {
1800 expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1801 "CTEB Is NOT Valid (Bundle Custodian NULL)");
1803 else if (strlen(cteb_creator_custodian_eid) != strlen(bundle_custodian)) {
1804 expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1805 "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
1806 bundle_custodian, cteb_creator_custodian_eid);
1808 else if (memcmp(cteb_creator_custodian_eid, bundle_custodian, strlen(bundle_custodian)) != 0) {
1809 expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1810 "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
1811 bundle_custodian, cteb_creator_custodian_eid);
1814 expert_add_info(pinfo, ti, &ei_block_control_block_cteb_valid);
1816 offset += cteb_creator_custodian_eid_length;
1820 case BUNDLE_BLOCK_TYPE_EXTENDED_COS:
1823 static const int * ecos_flags_fields[] = {
1824 &hf_ecos_flags_critical,
1825 &hf_ecos_flags_streaming,
1826 &hf_ecos_flags_flowlabel,
1827 &hf_ecos_flags_reliable,
1831 /* check requirements for Block Processing Control Flags */
1832 if ((control_flags & BLOCK_CONTROL_REPLICATE) == 0) {
1833 expert_add_info_format(pinfo, block_flag_replicate_item, &ei_bundle_block_control_flags, "ERROR: Replicate must be set for ECOS");
1835 if ((control_flags & BLOCK_CONTROL_EID_REFERENCE) != 0) {
1836 expert_add_info_format(pinfo, block_flag_eid_reference_item, &ei_bundle_block_control_flags, "ERROR: EID-Reference must be clear for ECOS");
1840 flags = (int)tvb_get_guint8(tvb, offset);
1841 proto_tree_add_bitmask(block_tree, tvb, offset, hf_ecos_flags, ett_block_flags, ecos_flags_fields, ENC_BIG_ENDIAN);
1845 proto_tree_add_item(block_tree, hf_ecos_ordinal, tvb, offset, 1, ENC_BIG_ENDIAN);
1848 /* optional flow label sdnv */
1849 if ((flags & ECOS_FLAGS_FLOWLABEL) != 0) {
1851 flow_label = evaluate_sdnv(tvb, offset, &sdnv_length);
1852 ti = proto_tree_add_int(block_tree, hf_ecos_flow_label, tvb, offset, sdnv_length, flow_label);
1853 if (flow_label < 0) {
1854 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ECOS Flow Label Error");
1855 /* Force quitting */
1859 offset += sdnv_length;
1866 proto_tree_add_string(block_tree, hf_bundle_unprocessed_block_data, tvb, offset, block_length, "Block data");
1867 /* unknown bundle type, skip past data */
1868 offset += block_length;
1876 /*3rd arg is number of bytes in field (returned)*/
1878 evaluate_sdnv(tvbuff_t *tvb, int offset, int *bytecount)
1885 if (!tvb_bytes_exist(tvb, offset, 1)) {
1890 * Get 1st byte and continue to get them while high-order bit is 1
1893 while ((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK) {
1894 if (*bytecount >= (int) sizeof(int)) {
1899 value |= (curbyte & SDNV_MASK);
1903 if (!tvb_bytes_exist(tvb, offset, 1)) {
1909 * Add in the byte whose high-order bit is 0 (last one)
1913 value |= (curbyte & SDNV_MASK);
1918 /* Special Function to evaluate 64 bit SDNVs */
1919 /*3rd arg is number of bytes in field (returned)*/
1921 evaluate_sdnv_64(tvbuff_t *tvb, int offset, int *bytecount)
1928 if (!tvb_bytes_exist(tvb, offset, 1)) {
1933 * Get 1st byte and continue to get them while high-order bit is 1
1936 while ((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK) {
1937 if (*bytecount >= (int) sizeof(gint64)) {
1942 value |= (curbyte & SDNV_MASK);
1946 if (!tvb_bytes_exist(tvb, offset, 1)) {
1952 * Add in the byte whose high-order bit is 0 (last one)
1956 value |= (curbyte & SDNV_MASK);
1961 /* Special Function to evaluate 32 bit unsigned SDNVs with error indication
1962 * bytecount returns the number bytes consumed
1963 * value returns the actual value
1965 * result is TRUE (1) on success else FALSE (0)
1968 evaluate_sdnv32(tvbuff_t *tvb, int offset, int *bytecount, guint32 *value)
1971 int num_bits_in_value;
1979 num_bits_in_value = 0;
1981 if (tvb_bytes_exist(tvb, offset, 1)) {
1983 * Get 1st byte and continue to get them while high-order bit is 1
1987 /* Determine number of non-zero bits in first SDNV byte */
1988 /* technically 0x80 0x80 ... 0x81 is a valid inefficient representation of "1" */
1989 while ((0 == num_bits_in_value) && ((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK)) {
1990 if (!tvb_bytes_exist(tvb, offset, 1)) {
1994 num_bits_in_value = 7;
1996 while ((num_bits_in_value > 0) && (!(curbyte & high_bit))) {
1997 --num_bits_in_value;
1998 high_bit = high_bit >> 1;
2001 *value |= (curbyte & SDNV_MASK);
2008 /* Process additional bytes that have the high order bit set */
2009 while (result && ((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK)) {
2010 /* Since the high order bit is set there must be 7 low order bits after this byte */
2011 if (!tvb_bytes_exist(tvb, offset, 1) || ((num_bits_in_value + 7) > (32 - 7))) {
2014 *value = *value << 7;
2015 *value |= (curbyte & SDNV_MASK);
2023 * Add in the byte whose high-order bit is 0 (last one)
2025 *value = *value << 7;
2026 *value |= (curbyte & SDNV_MASK);
2037 /* Special Function to evaluate 64 bit unsigned SDNVs with error indication
2038 * bytecount returns the number bytes consumed or zero on error
2039 * value returns the actual value
2041 * result is TRUE (1) on success else FALSE (0)
2044 evaluate_sdnv64(tvbuff_t *tvb, int offset, int *bytecount, guint64 *value)
2047 int num_bits_in_value;
2055 num_bits_in_value = 0;
2057 if (tvb_bytes_exist(tvb, offset, 1)) {
2059 * Get 1st byte and continue to get them while high-order bit is 1
2063 /* Determine number of non-zero bits in first SDNV byte */
2064 /* technically 0x80 0x80 ... 0x81 is a valid inefficient representation of "1" */
2065 while ((0 == num_bits_in_value) && ((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK)) {
2066 if (!tvb_bytes_exist(tvb, offset, 1)) {
2070 num_bits_in_value = 7;
2072 while ((num_bits_in_value > 0) && (!(curbyte & high_bit))) {
2073 --num_bits_in_value;
2074 high_bit = high_bit >> 1;
2077 *value |= (curbyte & SDNV_MASK);
2084 /* Process additional bytes that have the high order bit set */
2085 while (result && ((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK)) {
2086 /* Since the high order bit is set there must be 7 low order bits after this byte */
2087 if (!tvb_bytes_exist(tvb, offset, 1) || ((num_bits_in_value + 7) > (64 - 7))) {
2090 *value = *value << 7;
2091 *value |= (curbyte & SDNV_MASK);
2099 * Add in the byte whose high-order bit is 0 (last one)
2101 *value = *value << 7;
2102 *value |= (curbyte & SDNV_MASK);
2114 get_dtn_contact_header_len(packet_info *pinfo _U_, tvbuff_t *tvb,
2115 int offset, void *data _U_)
2119 /* get length from sdnv */
2120 len = evaluate_sdnv(tvb, offset+8, &bytecount);
2124 return len+bytecount+8;
2128 dissect_dtn_contact_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2131 proto_tree *conv_proto_tree, *conv_tree, *conv_flag_tree;
2132 int eid_length, sdnv_length;
2135 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCL");
2136 col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
2137 col_add_str(pinfo->cinfo, COL_INFO, "Contact Header");
2139 ti = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
2140 conv_proto_tree = proto_item_add_subtree(ti, ett_tcp_conv);
2142 conv_tree = proto_tree_add_subtree(conv_proto_tree, tvb, offset, -1, ett_tcp_conv, NULL, "Contact Header");
2144 proto_tree_add_item(conv_tree, hf_contact_hdr_magic, tvb, offset, 4, ENC_NA|ENC_ASCII);
2146 proto_tree_add_item(conv_tree, hf_contact_hdr_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2149 /* Subtree to expand the bits in the Contact Header Flags */
2150 ti = proto_tree_add_item(conv_tree, hf_contact_hdr_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
2151 conv_flag_tree = proto_item_add_subtree(ti, ett_contact_hdr_flags);
2152 proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
2153 proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_frag_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
2154 proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_nak, tvb, offset, 1, ENC_BIG_ENDIAN);
2157 proto_tree_add_item(conv_tree, hf_contact_hdr_keep_alive, tvb, offset, 2, ENC_BIG_ENDIAN);
2161 * New format Contact header has length field followed by Bundle Header.
2163 eid_length = evaluate_sdnv(tvb, offset, &sdnv_length);
2164 ti = proto_tree_add_int(tree, hf_contact_hdr_local_eid_length, tvb, offset, sdnv_length, eid_length);
2165 if (eid_length < 0) {
2166 expert_add_info(pinfo, ti, &ei_bundle_sdnv_length);
2170 proto_tree_add_item(conv_tree, hf_contact_hdr_local_eid, tvb, sdnv_length + offset, eid_length, ENC_NA|ENC_ASCII);
2171 return tvb_captured_length(tvb);
2175 get_tcpcl_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2178 guint8 conv_hdr = tvb_get_guint8(tvb, offset);
2180 switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
2182 case TCP_CONVERGENCE_DATA_SEGMENT:
2183 /* get length from sdnv */
2184 len = evaluate_sdnv(tvb, offset+1, &bytecount);
2188 return len+bytecount+1;
2190 case TCP_CONVERGENCE_ACK_SEGMENT:
2191 /* get length from sdnv */
2192 len = evaluate_sdnv(tvb, offset+1, &bytecount);
2198 case TCP_CONVERGENCE_KEEP_ALIVE:
2199 case TCP_CONVERGENCE_REFUSE_BUNDLE:
2202 case TCP_CONVERGENCE_SHUTDOWN:
2205 if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
2208 if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
2215 /* This probably isn't a TCPCL/Bundle packet, so just stop dissection */
2220 dissect_tcpcl_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2224 int sdnv_length, segment_length, convergence_hdr_size;
2225 proto_item *ci, *sub_item;
2226 proto_tree *conv_proto_tree, *conv_tree, *sub_tree;
2227 fragment_head *frag_msg;
2229 gboolean more_frags;
2230 int processed_length = 0;
2231 const gchar* col_text;
2232 gboolean bundle_in_col_info;
2234 static guint32 frag_id = 0;
2235 static guint32 last_frame = 0;
2236 static int last_raw_offset = 0;
2238 if (last_frame != pinfo->fd->num || tvb_raw_offset(tvb) < last_raw_offset)
2240 last_frame = pinfo->fd->num;
2241 last_raw_offset = tvb_raw_offset(tvb);
2243 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCL");
2244 col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
2246 col_text = col_get_text(pinfo->cinfo, COL_INFO);
2247 bundle_in_col_info = (col_text && strstr(col_text, " > "));
2249 ci = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
2250 conv_proto_tree = proto_item_add_subtree(ci, ett_tcp_conv);
2252 conv_tree = proto_tree_add_subtree(conv_proto_tree, tvb, 0, -1, ett_tcp_conv_hdr, NULL, "TCP Convergence Header");
2254 conv_hdr = tvb_get_guint8(tvb, offset);
2255 proto_tree_add_item(conv_tree, hf_tcp_convergence_pkt_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2256 col_add_str(pinfo->cinfo, COL_INFO, val_to_str_const((conv_hdr>>4)&0xF, packet_type_vals, "Unknown"));
2258 switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
2260 case TCP_CONVERGENCE_DATA_SEGMENT:
2261 sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_data_procflags, tvb,
2262 offset, 1, ENC_BIG_ENDIAN);
2263 sub_tree = proto_item_add_subtree(sub_item, ett_conv_flags);
2264 proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_start,
2265 tvb, offset, 1, ENC_BIG_ENDIAN);
2266 proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_end,
2267 tvb, offset, 1, ENC_BIG_ENDIAN);
2269 /* Only Start and End flags (bits 0 & 1) are valid in Data Segment */
2270 if ((conv_hdr & ~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_DATA_FLAGS)) != 0) {
2271 expert_add_info(pinfo, sub_item, &ei_tcp_convergence_data_flags);
2274 segment_length = evaluate_sdnv(tvb, 1, &sdnv_length);
2275 sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_data_segment_length, tvb, 1, sdnv_length, segment_length);
2276 if (segment_length < 0) {
2277 expert_add_info(pinfo, sub_item, &ei_tcp_convergence_segment_length);
2281 convergence_hdr_size = sdnv_length + 1;
2284 * 1/11/2006 - If I got here, I should have a complete convergence layer
2285 * "segment" beginning at frame_offset. However that might not be a
2286 * complete bundle. Or there might be a complete bundle plus one or more
2287 * additional convergence layer headers.
2292 if ((conv_hdr & TCP_CONVERGENCE_DATA_END_FLAG) == TCP_CONVERGENCE_DATA_END_FLAG) {
2299 frag_msg = fragment_add_seq_next(&msg_reassembly_table,
2300 tvb, offset + convergence_hdr_size,
2301 pinfo, frag_id, data,
2302 segment_length, more_frags);
2304 if (!more_frags) ++frag_id;
2306 processed_length = convergence_hdr_size + segment_length;
2308 if (frag_msg && !more_frags) {
2310 int save_fd_head_layer = frag_msg->reas_in_layer_num;
2311 frag_msg->reas_in_layer_num = pinfo->curr_layer_num;
2313 sub_item = proto_tree_add_item(tree, proto_bundle, tvb, offset, -1, ENC_NA);
2314 sub_tree = proto_item_add_subtree(sub_item, ett_bundle);
2316 new_tvb = process_reassembled_data(tvb, offset + convergence_hdr_size,
2317 pinfo, "Reassembled DTN", frag_msg,
2318 &msg_frag_items, NULL, sub_tree);
2320 frag_msg->reas_in_layer_num = save_fd_head_layer;
2324 if (0 == call_dissector_with_data(bundle_handle, new_tvb, pinfo, sub_tree, data)) {
2325 /*Couldn't parse bundle, treat as raw data */
2326 call_data_dissector(new_tvb, pinfo, sub_tree);
2327 return tvb_captured_length(tvb);
2333 * If there are 2 segments, the second of which is very short, this
2334 * gets displayed instead of the usual Source EID/Destination EID in
2335 * the Bundle Dissection frame. If these statements are left out entirely,
2336 * nothing is displayed, i.e., there seems to be no way to get the
2337 * Source/Destination in the 2-segment case. I'll leave it in because I
2338 * think it is informative in the multi-segment case although confusing in the
2341 col_add_str(pinfo->cinfo, COL_INFO, "[Bundle TCPCL Segment]");
2344 case TCP_CONVERGENCE_ACK_SEGMENT:
2345 if (bundle_in_col_info) {
2346 if (!strstr(col_text, ", TCPL ACK")) {
2347 col_add_str(pinfo->cinfo, COL_INFO, ", TCPL ACK Segment(s)");
2350 col_set_str(pinfo->cinfo, COL_INFO, "TCPL ACK Segment(s)");
2352 segment_length = evaluate_sdnv(tvb, offset+1, &sdnv_length);
2353 sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_ack_length, tvb, offset+1, sdnv_length, segment_length);
2354 if (segment_length < 0) {
2355 expert_add_info(pinfo, sub_item, &ei_tcp_convergence_ack_length);
2356 processed_length = tvb_captured_length(tvb);
2358 processed_length = sdnv_length + 1;
2361 case TCP_CONVERGENCE_KEEP_ALIVE:
2362 if (bundle_in_col_info) {
2363 if (!strstr(col_text, ", TCPL KEEPALIVE")) {
2364 col_add_str(pinfo->cinfo, COL_INFO, ", TCPL KEEPALIVE Segment");
2367 col_set_str(pinfo->cinfo, COL_INFO, "TCPL KEEPALIVE Segment");
2369 /*No valid flags in Keep Alive*/
2370 processed_length = 1;
2373 case TCP_CONVERGENCE_SHUTDOWN:
2374 if (bundle_in_col_info) {
2375 if (!strstr(col_text, ", TCPL SHUTDOWN")) {
2376 col_add_str(pinfo->cinfo, COL_INFO, ", TCPL SHUTDOWN Segment");
2379 col_set_str(pinfo->cinfo, COL_INFO, "TCPL SHUTDOWN Segment");
2381 /* Add tree for Shutdown Flags */
2382 sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_shutdown_flags, tvb,
2383 offset, 1, ENC_BIG_ENDIAN);
2384 sub_tree = proto_item_add_subtree(sub_item, ett_shutdown_flags);
2386 proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_reason,
2387 tvb, offset, 1, ENC_BIG_ENDIAN);
2388 proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_delay,
2389 tvb, offset, 1, ENC_BIG_ENDIAN);
2392 if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
2393 proto_tree_add_item(conv_tree,
2394 hf_tcp_convergence_shutdown_reason, tvb,
2395 offset, 1, ENC_BIG_ENDIAN);
2398 if (conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
2399 proto_tree_add_item(conv_tree,
2400 hf_tcp_convergence_shutdown_delay, tvb,
2401 offset, 2, ENC_BIG_ENDIAN);
2404 case TCP_CONVERGENCE_REFUSE_BUNDLE:
2405 if (bundle_in_col_info) {
2406 if (!strstr(col_text, ", TCPL REFUSE")) {
2407 col_add_str(pinfo->cinfo, COL_INFO, ", TCPL REFUSE_BUNDLE Segment");
2410 col_set_str(pinfo->cinfo, COL_INFO, "TCPL REFUSE_BUNDLE Segment");
2413 processed_length = tvb_captured_length(tvb);
2417 return processed_length;
2421 dissect_tcpcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2424 int offset, bytecount;
2425 int processed_length;
2427 /* Make sure we have a convergence header byte */
2428 if (!tvb_bytes_exist(tvb, 0, 1))
2431 conv_hdr = tvb_get_guint8(tvb, 0);
2432 switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
2434 case TCP_CONVERGENCE_DATA_SEGMENT:
2435 case TCP_CONVERGENCE_ACK_SEGMENT:
2440 if (!tvb_bytes_exist(tvb, offset, 1)) {
2441 pinfo->desegment_offset = 0;
2442 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2446 while (tvb_get_guint8(tvb, offset) & ~SDNV_MASK) {
2447 if (bytecount > (int)sizeof(int)) {
2448 /* invalid length field */
2455 if (!tvb_bytes_exist(tvb, offset, 1)) {
2456 pinfo->desegment_offset = 0;
2457 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2462 case TCP_CONVERGENCE_KEEP_ALIVE:
2463 case TCP_CONVERGENCE_REFUSE_BUNDLE:
2466 case TCP_CONVERGENCE_SHUTDOWN:
2468 ~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_SHUTDOWN_FLAGS)) != 0) {
2474 if (conv_hdr == (guint8)magic[0]) {
2475 if (!tvb_bytes_exist(tvb, 0, 4) || tvb_memeql(tvb, 0, magic, 4)) {
2480 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 8, get_dtn_contact_header_len, dissect_dtn_contact_header, data);
2481 return tvb_captured_length(tvb);
2488 processed_length = get_tcpcl_pdu_len(pinfo, tvb, 0, data);
2490 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 1, get_tcpcl_pdu_len, dissect_tcpcl_pdu, data);
2492 return processed_length;
2496 dissect_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2498 proto_item *ti, *ti_bundle_protocol;
2499 proto_tree *bundle_tree, *primary_tree;
2500 int primary_header_size;
2501 gboolean lastheader = FALSE;
2503 guint8 version, pri_hdr_procflags;
2504 /* Custodian from Primary Block, used to validate CTEB */
2505 gchar *bundle_custodian = NULL;
2508 version = tvb_get_guint8(tvb, offset); /* Primary Header Version */
2509 if ((version != 4) && (version != 5) && (version != 6)) {
2513 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Bundle");
2514 /* Clear out stuff in the info column */
2515 col_clear(pinfo->cinfo,COL_INFO);
2517 ti_bundle_protocol = proto_tree_add_item(tree, proto_bundle, tvb, offset, -1, ENC_NA);
2519 bundle_tree = proto_item_add_subtree(ti_bundle_protocol, ett_bundle);
2521 primary_tree = proto_tree_add_subtree(bundle_tree, tvb, offset, -1, ett_primary_hdr, &ti, "Primary Bundle Header");
2523 proto_tree_add_item(primary_tree, hf_bundle_pdu_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2525 primary_header_size = dissect_version_4_primary_header(pinfo, primary_tree, tvb,
2526 &pri_hdr_procflags, &bundle_custodian);
2529 primary_header_size = dissect_version_5_and_6_primary_header(pinfo, primary_tree, tvb,
2530 &pri_hdr_procflags, &bundle_custodian);
2533 if (primary_header_size == 0) { /*Couldn't parse primary header*/
2534 col_add_str(pinfo->cinfo, COL_INFO, "Protocol Error");
2535 return(0); /*Give up*/
2538 proto_item_set_len(ti, primary_header_size);
2539 offset = primary_header_size;
2542 * Done with primary header; decode the remaining headers
2545 while (lastheader == FALSE) {
2546 guint8 next_header_type;
2548 next_header_type = tvb_get_guint8(tvb, offset);
2549 if (next_header_type == BUNDLE_BLOCK_TYPE_PAYLOAD) {
2552 * Returns payload size or 0 if can't parse payload
2554 offset = dissect_payload_header(bundle_tree, tvb, pinfo, offset, version, pri_hdr_procflags, &lastheader);
2556 else { /*Assume anything else is a Metadata Block*/
2557 offset = display_extension_block(bundle_tree, tvb, pinfo, offset, bundle_custodian, &lastheader);
2561 proto_item_set_len(ti_bundle_protocol, offset);
2567 void proto_reg_handoff_bundle(void);
2568 void proto_register_bundle(void);
2571 proto_register_bundle(void)
2574 static hf_register_info hf[] = {
2575 {&hf_bundle_pdu_version,
2576 {"Bundle Version", "bundle.version",
2577 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2580 {"Message Fragments", "bundle.msg.fragments",
2581 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
2584 {"Message Fragment", "bundle.msg.fragment",
2585 FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
2587 {&hf_msg_fragment_overlap,
2588 {"Message fragment overlap", "bundle.msg.fragment.overlap",
2589 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2591 {&hf_msg_fragment_overlap_conflicts,
2592 {"Message fragment overlapping with conflicting data",
2593 "bundle.msg.fragment.overlap.conflicts",
2594 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2596 {&hf_msg_fragment_multiple_tails,
2597 {"Message has multiple tails", "bundle.msg.fragment.multiple_tails",
2598 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2600 {&hf_msg_fragment_too_long_fragment,
2601 {"Message fragment too long", "bundle.msg.fragment.too_long_fragment",
2602 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2604 {&hf_msg_fragment_error,
2605 {"Message defragmentation error", "bundle.msg.fragment.error",
2606 FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
2608 {&hf_msg_fragment_count,
2609 {"Message fragment count", "bundle.msg.fragment.count",
2610 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2612 {&hf_msg_reassembled_in,
2613 {"Reassembled in", "bundle.msg.reassembled.in",
2614 FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
2616 {&hf_msg_reassembled_length,
2617 {"Reassembled DTN length", "bundle.msg.reassembled.length",
2618 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2620 {&hf_bundle_procflags,
2621 {"Primary Header Processing Flags", "bundle.primary.proc.flag",
2622 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2624 {&hf_bundle_procflags_fragment,
2625 {"Bundle is a Fragment", "bundle.primary.proc.frag",
2626 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_FRAG_MASK, NULL, HFILL}
2628 {&hf_bundle_procflags_admin,
2629 {"Administrative Record", "bundle.primary.proc.admin",
2630 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_ADMIN_MASK, NULL, HFILL}
2632 {&hf_bundle_procflags_dont_fragment,
2633 {"Do Not Fragment Bundle", "bundle.primary.proc.dontfrag",
2634 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_DONTFRAG_MASK, NULL, HFILL}
2636 {&hf_bundle_procflags_cust_xfer_req,
2637 {"Request Custody Transfer", "bundle.primary.proc.xferreq",
2638 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_XFERREQ_MASK, NULL, HFILL}
2640 {&hf_bundle_procflags_dest_singleton,
2641 {"Destination is Singleton", "bundle.primary.proc.single",
2642 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_SINGLETON_MASK, NULL, HFILL}
2644 {&hf_bundle_procflags_application_ack,
2645 {"Request Acknowledgement by Application", "bundle.primary.proc.ack",
2646 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_APP_ACK_MASK, NULL, HFILL}
2648 {&hf_bundle_control_flags,
2649 {"Bundle Processing Control Flags", "bundle.primary.proc.flag",
2650 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}
2652 {&hf_bundle_procflags_general,
2653 {"General Flags", "bundle.primary.proc.gen",
2654 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2656 {&hf_bundle_procflags_cos,
2657 {"Class of Service Flags", "bundle.primary.proc.cos",
2658 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2660 {&hf_bundle_procflags_status,
2661 {"Status Report Flags", "bundle.primary.proc.status",
2662 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2664 {&hf_bundle_cosflags,
2665 {"Primary Header COS Flags", "bundle.primary.cos.flags",
2666 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2668 {&hf_bundle_cosflags_priority,
2669 {"Priority", "bundle.primary.cos.priority",
2670 FT_UINT8, BASE_DEC, VALS(cosflags_priority_vals), BUNDLE_COSFLAGS_PRIORITY_MASK, NULL, HFILL}
2672 {&hf_bundle_srrflags,
2673 {"Primary Header Report Request Flags", "bundle.primary.srr.flag",
2674 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2676 {&hf_bundle_srrflags_report_receipt,
2677 {"Request Reception Report", "bundle.primary.srr.report",
2678 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_REPORT_MASK, NULL, HFILL}
2680 {&hf_bundle_srrflags_report_cust_accept,
2681 {"Request Report of Custody Acceptance", "bundle.primary.srr.custaccept",
2682 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_CUSTODY_MASK, NULL, HFILL}
2684 {&hf_bundle_srrflags_report_forward,
2685 {"Request Report of Bundle Forwarding", "bundle.primary.srr.forward",
2686 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_FORWARD_MASK, NULL, HFILL}
2688 {&hf_bundle_srrflags_report_delivery,
2689 {"Request Report of Bundle Delivery", "bundle.primary.srr.delivery",
2690 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_DELIVERY_MASK, NULL, HFILL}
2692 {&hf_bundle_srrflags_report_deletion,
2693 {"Request Report of Bundle Deletion", "bundle.primary.srr.delete",
2694 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_DELETION_MASK, NULL, HFILL}
2696 {&hf_bundle_srrflags_report_ack,
2697 {"Request Report of Application Ack", "bundle.primary.srr.ack",
2698 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_ACK_MASK, NULL, HFILL}
2700 {&hf_bundle_primary_header_len,
2701 {"Bundle Header Length", "bundle.primary.len",
2702 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2704 {&hf_bundle_primary_dictionary_len,
2705 {"Dictionary Length", "bundle.primary.dictionary_len",
2706 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2708 {&hf_bundle_primary_fragment_offset,
2709 {"Fragment Offset", "bundle.primary.fragment_offset",
2710 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2712 {&hf_bundle_primary_total_adu_len,
2713 {"Total Application Data Unit Length", "bundle.primary.total_adu_len",
2714 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2716 {&hf_bundle_primary_timestamp_seq_num64,
2717 {"Timestamp Sequence Number", "bundle.primary.timestamp_seq_num",
2718 FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
2720 {&hf_bundle_primary_timestamp_seq_num32,
2721 {"Timestamp Sequence Number", "bundle.primary.timestamp_seq_num",
2722 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2724 {&hf_bundle_primary_timestamp,
2725 {"Timestamp", "bundle.primary.timestamp",
2726 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2728 {&hf_bundle_dest_scheme_offset_u16,
2729 {"Destination Scheme Offset", "bundle.primary.destschemeoff",
2730 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2732 {&hf_bundle_dest_scheme_offset_i32,
2733 {"Destination Scheme Offset", "bundle.primary.destschemeoff",
2734 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2736 {&hf_bundle_dest_ssp_offset_u16,
2737 {"Destination SSP Offset", "bundle.primary.destssspoff",
2738 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2740 {&hf_bundle_dest_ssp_offset_i32,
2741 {"Destination SSP Offset", "bundle.primary.destssspoff",
2742 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2744 {&hf_bundle_source_scheme_offset_u16,
2745 {"Source Scheme Offset", "bundle.primary.srcschemeoff",
2746 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2748 {&hf_bundle_source_scheme_offset_i32,
2749 {"Source Scheme Offset", "bundle.primary.srcschemeoff",
2750 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2752 {&hf_bundle_source_ssp_offset_u16,
2753 {"Source SSP Offset", "bundle.primary.srcsspoff",
2754 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2756 {&hf_bundle_source_ssp_offset_i32,
2757 {"Source SSP Offset", "bundle.primary.srcsspoff",
2758 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2760 {&hf_bundle_report_scheme_offset_u16,
2761 {"Report Scheme Offset", "bundle.primary.rptschemeoff",
2762 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2764 {&hf_bundle_report_scheme_offset_i32,
2765 {"Report Scheme Offset", "bundle.primary.rptschemeoff",
2766 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2768 {&hf_bundle_report_ssp_offset_u16,
2769 {"Report SSP Offset", "bundle.primary.rptsspoff",
2770 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2772 {&hf_bundle_report_ssp_offset_i32,
2773 {"Report SSP Offset", "bundle.primary.rptsspoff",
2774 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2776 {&hf_bundle_cust_scheme_offset_u16,
2777 {"Custodian Scheme Offset", "bundle.primary.custschemeoff",
2778 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2780 {&hf_bundle_cust_scheme_offset_i32,
2781 {"Custodian Scheme Offset", "bundle.primary.custschemeoff",
2782 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2784 {&hf_bundle_cust_ssp_offset_u16,
2785 {"Custodian SSP Offset", "bundle.primary.custsspoff",
2786 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2788 {&hf_bundle_cust_ssp_offset_i32,
2789 {"Custodian SSP Offset", "bundle.primary.custsspoff",
2790 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2792 {&hf_bundle_dest_scheme,
2793 {"Destination Scheme", "bundle.primary.destination_scheme",
2794 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2796 {&hf_bundle_dest_ssp,
2797 {"Destination", "bundle.primary.destination",
2798 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2800 {&hf_bundle_source_scheme,
2801 {"Source Scheme", "bundle.primary.source_scheme",
2802 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2804 {&hf_bundle_source_ssp,
2805 {"Source", "bundle.primary.source",
2806 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2808 {&hf_bundle_report_scheme,
2809 {"Report Scheme", "bundle.primary.report_scheme",
2810 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2812 {&hf_bundle_report_ssp,
2813 {"Report", "bundle.primary.report",
2814 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2816 {&hf_bundle_custodian_scheme,
2817 {"Custodian Scheme", "bundle.primary.custodian_scheme",
2818 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2820 {&hf_bundle_custodian_ssp,
2821 {"Custodian", "bundle.primary.custodian",
2822 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2824 {&hf_bundle_creation_timestamp,
2825 {"Creation Timestamp", "bundle.primary.creation_timestamp",
2826 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}
2828 {&hf_bundle_lifetime,
2829 {"Lifetime", "bundle.primary.lifetime",
2830 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2832 {&hf_bundle_lifetime_sdnv,
2833 {"Lifetime", "bundle.primary.lifetime",
2834 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2836 {&hf_bundle_payload_length,
2837 {"Payload Length", "bundle.payload.length",
2838 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2840 {&hf_bundle_payload_flags,
2841 {"Payload Header Processing Flags", "bundle.payload.proc.flag",
2842 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2844 {&hf_bundle_payload_header_type,
2845 {"Header Type", "bundle.payload.proc.header_type",
2846 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2848 {&hf_bundle_payload_data,
2849 {"Payload Data", "bundle.payload.data",
2850 FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL}
2852 {&hf_bundle_payload_flags_replicate_hdr,
2853 {"Replicate Header in Every Fragment", "bundle.payload.proc.replicate",
2854 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_REPLICATE_MASK, NULL, HFILL}
2856 {&hf_bundle_payload_flags_xmit_report,
2857 {"Report if Can't Process Header", "bundle.payload.proc.report",
2858 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_XMIT_STATUS, NULL, HFILL}
2860 {&hf_bundle_payload_flags_discard_on_fail,
2861 {"Discard if Can't Process Header", "bundle.payload.proc.discard",
2862 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_DISCARD_FAILURE, NULL, HFILL}
2864 {&hf_bundle_payload_flags_last_header,
2865 {"Last Header", "bundle.payload.proc.lastheader",
2866 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_LAST_HEADER, NULL, HFILL}
2868 {&hf_bundle_admin_record_type,
2869 {"Administrative Record Type", "bundle.admin.record_type",
2870 FT_UINT8, BASE_DEC, VALS(admin_record_type_vals), 0xF0, NULL, HFILL}
2872 {&hf_bundle_admin_record_fragment,
2873 {"Administrative Record for Fragment", "bundle.admin.record_fragment",
2874 FT_BOOLEAN, 8, TFS(&tfs_yes_no), ADMIN_REC_FLAGS_FRAGMENT, NULL, HFILL}
2876 {&hf_bundle_admin_statflags,
2877 {"Administrative Record Status Flags", "bundle.admin.status.flag",
2878 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2880 {&hf_bundle_admin_rcvd,
2881 {"Reporting Node Received Bundle", "bundle.admin.status.rcvd",
2882 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_RECEIVED, NULL, HFILL}
2884 {&hf_bundle_admin_accepted,
2885 {"Reporting Node Accepted Custody", "bundle.admin.status.accept",
2886 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_ACCEPTED, NULL, HFILL}
2888 {&hf_bundle_admin_forwarded,
2889 {"Reporting Node Forwarded Bundle", "bundle.admin.status.forward",
2890 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_FORWARDED, NULL, HFILL}
2892 {&hf_bundle_admin_delivered,
2893 {"Reporting Node Delivered Bundle", "bundle.admin.status.delivered",
2894 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_DELIVERED, NULL, HFILL}
2896 {&hf_bundle_admin_deleted,
2897 {"Reporting Node Deleted Bundle", "bundle.admin.status.delete",
2898 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_DELETED, NULL, HFILL}
2900 {&hf_bundle_admin_acked,
2901 {"Acknowledged by Application", "bundle.admin.status.ack",
2902 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_ACKNOWLEDGED, NULL, HFILL}
2904 {&hf_bundle_admin_fragment_offset,
2905 {"Fragment Offset", "bundle.admin.fragment_offset",
2906 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2908 {&hf_bundle_admin_fragment_length,
2909 {"Fragment Length", "bundle.admin.fragment_length",
2910 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2912 {&hf_bundle_admin_timestamp_seq_num64,
2913 {"Timestamp Sequence Number", "bundle.admin.timestamp_seq_num",
2914 FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
2916 {&hf_bundle_admin_timestamp_seq_num32,
2917 {"Timestamp Sequence Number", "bundle.admin.timestamp_seq_num",
2918 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2920 {&hf_bundle_admin_endpoint_length,
2921 {"Endpoint Length", "bundle.admin.endpoint_length",
2922 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2924 {&hf_bundle_admin_endpoint_id,
2925 {"Bundle Endpoint ID", "bundle.admin.endpoint_id",
2926 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2928 {&hf_bundle_admin_receipt_time,
2929 {"Bundle Received Time", "bundle.admin.status.receipttime",
2930 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2932 {&hf_bundle_admin_accept_time,
2933 {"Bundle Accepted Time", "bundle.admin.status.accepttime",
2934 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2936 {&hf_bundle_admin_forward_time,
2937 {"Bundle Forwarded Time", "bundle.admin.status.forwardtime",
2938 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2940 {&hf_bundle_admin_delivery_time,
2941 {"Bundle Delivered Time", "bundle.admin.status.deliverytime",
2942 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2944 {&hf_bundle_admin_delete_time,
2945 {"Bundle Deleted Time", "bundle.admin.status.deletetime",
2946 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2948 {&hf_bundle_admin_ack_time,
2949 {"Bundle Acknowledged Time", "bundle.admin.status.acktime",
2950 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2952 {&hf_bundle_admin_timestamp_copy,
2953 {"Bundle Creation Timestamp", "bundle.admin.status.timecopy",
2954 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2956 {&hf_bundle_admin_signal_time,
2957 {"Bundle Signal Time", "bundle.admin.signal.time",
2958 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2960 {&hf_block_control_flags,
2961 {"Block Processing Control Flags", "bundle.block.control.flags",
2962 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2964 {&hf_block_control_flags_sdnv,
2965 {"Block Processing Control Flags", "bundle.block.control.flags",
2966 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
2968 {&hf_block_control_block_length,
2969 {"Block Length", "bundle.block.length",
2970 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2972 {&hf_block_control_block_cteb_custody_id,
2973 {"CTEB Custody ID", "bundle.block.cteb_custody_id",
2974 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2976 {&hf_block_control_block_cteb_creator_custodian_eid,
2977 {"CTEB Creator Custodian EID", "bundle.block.cteb_creator_custodian_eid",
2978 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2980 {&hf_block_control_replicate,
2981 {"Replicate Block in Every Fragment", "bundle.block.control.replicate",
2982 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_REPLICATE, NULL, HFILL}
2984 {&hf_block_control_transmit_status,
2985 {"Transmit Status if Block Can't be Processeed", "bundle.block.control.status",
2986 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_TRANSMIT_STATUS, NULL, HFILL}
2988 {&hf_block_control_delete_bundle,
2989 {"Delete Bundle if Block Can't be Processeed", "bundle.block.control.delete",
2990 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_DELETE_BUNDLE, NULL, HFILL}
2992 {&hf_block_control_last_block,
2993 {"Last Block", "bundle.block.control.last",
2994 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_LAST_BLOCK, NULL, HFILL}
2996 {&hf_block_control_discard_block,
2997 {"Discard Block If Can't Process", "bundle.block.control.discard",
2998 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_DISCARD_BLOCK, NULL, HFILL}
3000 {&hf_block_control_not_processed,
3001 {"Block Was Forwarded Without Processing", "bundle.block.control.process",
3002 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_NOT_PROCESSED, NULL, HFILL}
3004 {&hf_block_control_eid_reference,
3005 {"Block Contains an EID-reference Field", "bundle.block.control.eid",
3006 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_EID_REFERENCE, NULL, HFILL}
3008 {&hf_bundle_status_report_reason_code,
3009 {"Status Report Reason Code", "bundle.status_report_reason_code",
3010 FT_UINT8, BASE_DEC, VALS(status_report_reason_codes), 0x0, NULL, HFILL}
3012 {&hf_bundle_custody_trf_succ_flg,
3013 {"Custody Transfer Succeeded Flag", "bundle.custody_trf_succ_flg",
3014 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}
3016 {&hf_bundle_custody_signal_reason,
3017 {"Custody Signal Reason Code", "bundle.custody_signal_reason_code",
3018 FT_UINT8, BASE_DEC, VALS(custody_signal_reason_codes), ADMIN_REC_CUSTODY_REASON_MASK, NULL, HFILL}
3020 {&hf_bundle_custody_id_range_start,
3021 {"CTEB Custody ID Range Start", "bundle.custody_id_range_start",
3022 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3024 {&hf_bundle_custody_id_range_end,
3025 {"CTEB Custody ID Range End", "bundle.custody_id_range_end",
3026 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3028 {&hf_bundle_block_type_code,
3029 {"Block Type Code", "bundle.block_type_code",
3030 FT_UINT8, BASE_DEC, VALS(bundle_block_type_codes), 0x0, NULL, HFILL}
3032 {&hf_bundle_unprocessed_block_data,
3033 {"Block Data", "bundle.block_data",
3034 FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL}
3037 {"ECOS Flags", "bundle.block.ecos.flags",
3038 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
3040 {&hf_ecos_flags_critical,
3041 {"Critical", "bundle.block.ecos.flags.critical",
3042 FT_BOOLEAN, 8, NULL, ECOS_FLAGS_CRITICAL, NULL, HFILL}
3044 {&hf_ecos_flags_streaming,
3045 {"Streaming", "bundle.block.ecos.flags.streaming",
3046 FT_BOOLEAN, 8, NULL, ECOS_FLAGS_STREAMING, NULL, HFILL}
3048 {&hf_ecos_flags_flowlabel,
3049 {"Flow Label", "bundle.block.ecos.flags.flowlabel",
3050 FT_BOOLEAN, 8, NULL, ECOS_FLAGS_FLOWLABEL, NULL, HFILL}
3052 {&hf_ecos_flags_reliable,
3053 {"Reliable", "bundle.block.ecos.flags.reliable",
3054 FT_BOOLEAN, 8, NULL, ECOS_FLAGS_RELIABLE, NULL, HFILL}
3056 {&hf_ecos_flow_label,
3057 {"ECOS Flow Label", "bundle.block.ecos.flow_label",
3058 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3061 {"ECOS Ordinal", "bundle.block.ecos.ordinal",
3062 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3064 {&hf_bundle_age_extension_block_code,
3065 {"Bundle Age in seconds", "bundle.age_extension_block_code",
3066 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3068 {&hf_bundle_block_previous_hop_scheme,
3069 {"Previous Hop Secheme", "bundle.block.previous_hop_scheme",
3070 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
3072 {&hf_bundle_block_previous_hop_eid,
3073 {"Previous Hop EID", "bundle.block.previous_hop_eid",
3074 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
3076 {&hf_bundle_target_block_type,
3077 {"Target Block Type", "bundle.target_block_type",
3078 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3080 {&hf_bundle_target_block_occurance,
3081 {"Target Block Occurance", "bundle.target_block_occurance",
3082 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3084 {&hf_bundle_ciphersuite_type,
3085 {"Ciphersuite Type", "bundle.ciphersuite_type",
3086 FT_INT32, BASE_DEC, VALS(ciphersuite_types), 0x0, NULL, HFILL}
3088 {&hf_bundle_ciphersuite_flags,
3089 {"Ciphersuite Flags", "bundle.ciphersuite_flags",
3090 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
3092 {&hf_block_ciphersuite_params,
3093 {"Block Contains Ciphersuite Parameters", "bundle.block.ciphersuite_params",
3094 FT_BOOLEAN, 8, NULL, BLOCK_CIPHERSUITE_PARAMS, NULL, HFILL}
3096 {&hf_block_ciphersuite_params_length,
3097 {"Ciphersuite Parameters Length", "bundle.block.ciphersuite_params_length",
3098 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3100 {&hf_block_ciphersuite_params_item_length,
3101 {"Parameter Length", "bundle.block.ciphersuite_params_item_length",
3102 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3104 {&hf_block_ciphersuite_param_type,
3105 {"Ciphersuite Parameter Type", "bundle.block.ciphersuite_param_type",
3106 FT_INT8, BASE_DEC, VALS(res_params_types), 0x0, NULL, HFILL}
3108 {&hf_block_ciphersuite_param_data,
3109 {"Ciphersuite Parameter Data", "bundle.block.ciphersuite_param_data",
3110 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
3112 {&hf_block_ciphersuite_result_length,
3113 {"Security Results Length", "bundle.block.ciphersuite_result_length",
3114 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3116 {&hf_block_ciphersuite_result_item_length,
3117 {"Security Result Item Length", "bundle.block.ciphersuite_result_item_length",
3118 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3120 {&hf_block_ciphersuite_result_type,
3121 {"Security Result Item Type", "bundle.block.ciphersuite_result_type",
3122 FT_INT8, BASE_DEC, VALS(res_params_types), 0x0, NULL, HFILL}
3124 {&hf_block_ciphersuite_result_data,
3125 {"Security Result Item Data", "bundle.block.ciphersuite_result_data",
3126 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
3128 {&hf_block_ciphersuite_range_offset,
3129 {"Content Range Offset", "bundle.block.ciphersuite_range_offset",
3130 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3132 {&hf_block_ciphersuite_range_length,
3133 {"Content Range Length", "bundle.block.ciphersuite_range_length",
3134 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3138 static hf_register_info hf_tcpcl[] = {
3139 {&hf_tcp_convergence_pkt_type,
3140 {"Pkt Type", "tcpcl.pkt_type",
3141 FT_UINT8, BASE_DEC, VALS(packet_type_vals), 0xF0, NULL, HFILL}
3143 {&hf_tcp_convergence_data_procflags,
3144 {"TCP Convergence Data Flags", "tcpcl.data.proc.flag",
3145 FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_DATA_FLAGS, NULL, HFILL}
3147 {&hf_tcp_convergence_data_procflags_start,
3148 {"Segment contains start of bundle", "tcpcl.data.proc.start",
3149 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_START_FLAG, NULL, HFILL}
3151 {&hf_tcp_convergence_data_procflags_end,
3152 {"Segment contains end of Bundle", "tcpcl.data.proc.end",
3153 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_END_FLAG, NULL, HFILL}
3155 {&hf_tcp_convergence_data_segment_length,
3156 {"Segment Length", "tcpcl.data.length",
3157 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3159 {&hf_tcp_convergence_shutdown_flags,
3160 {"TCP Convergence Shutdown Flags", "tcpcl.shutdown.flags",
3161 FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_SHUTDOWN_FLAGS, NULL, HFILL}
3163 {&hf_tcp_convergence_shutdown_flags_reason,
3164 {"Shutdown includes Reason Code", "tcpcl.shutdown.reason.flag",
3165 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_REASON, NULL, HFILL}
3167 {&hf_tcp_convergence_shutdown_flags_delay,
3168 {"Shutdown includes Reconnection Delay", "tcpcl.shutdown.delay.flag",
3169 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_DELAY, NULL, HFILL}
3171 {&hf_tcp_convergence_shutdown_reason,
3172 {"Shutdown Reason Code", "tcpcl.shutdown.reason",
3173 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3175 {&hf_tcp_convergence_shutdown_delay,
3176 {"Shutdown Reconnection Delay", "tcpcl.shutdown.delay",
3177 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
3179 {&hf_tcp_convergence_ack_length,
3180 {"Ack Length", "tcpcl.ack.length",
3181 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3183 {&hf_contact_hdr_version,
3184 {"Version", "tcpcl.contact_hdr.version",
3185 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
3187 {&hf_contact_hdr_flags,
3188 {"Flags", "tcpcl.contact_hdr.flags",
3189 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
3191 {&hf_contact_hdr_flags_ack_req,
3192 {"Bundle Acks Requested", "tcpcl.contact_hdr.flags.ackreq",
3193 FT_BOOLEAN, 8, NULL, TCP_CONV_BUNDLE_ACK_FLAG, NULL, HFILL}
3195 {&hf_contact_hdr_flags_frag_enable,
3196 {"Reactive Fragmentation Enabled", "tcpcl.contact_hdr.flags.fragen",
3197 FT_BOOLEAN, 8, NULL, TCP_CONV_REACTIVE_FRAG_FLAG, NULL, HFILL}
3199 {&hf_contact_hdr_flags_nak,
3200 {"Support Negative Acknowledgements", "tcpcl.contact_hdr.flags.nak",
3201 FT_BOOLEAN, 8, NULL, TCP_CONV_CONNECTOR_RCVR_FLAG, NULL, HFILL}
3203 {&hf_contact_hdr_keep_alive,
3204 {"Keep Alive", "tcpcl.contact_hdr.keep_alive",
3205 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
3207 {&hf_contact_hdr_magic,
3208 {"Magic", "tcpcl.contact_hdr.magic",
3209 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
3211 {&hf_contact_hdr_local_eid,
3212 {"Local EID", "tcpcl.contact_hdr.local_eid",
3213 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
3215 {&hf_contact_hdr_local_eid_length,
3216 {"Local EID Length", "tcpcl.contact_hdr.local_eid_length",
3217 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
3221 static gint *ett[] = {
3233 &ett_contact_hdr_flags,
3235 &ett_shutdown_flags,
3237 &ett_admin_rec_status,
3239 &ett_sec_block_param_data
3242 static gint *ett_tcpcl[] = {
3249 static ei_register_info ei[] = {
3250 { &ei_bundle_control_flags_length,
3251 { "bundle.block.control.flags.length", PI_UNDECODED, PI_WARN, "Wrong bundle control flag length", EXPFILL }
3253 { &ei_bundle_payload_length,
3254 { "bundle.payload.length.invalid", PI_PROTOCOL, PI_ERROR, "Payload length error", EXPFILL }
3256 { &ei_bundle_sdnv_length,
3257 { "bundle.sdnv_length_invalid", PI_PROTOCOL, PI_ERROR, "SDNV length error", EXPFILL }
3259 { &ei_bundle_timestamp_seq_num,
3260 { "bundle.timestamp_seq_num_invalid", PI_PROTOCOL, PI_ERROR, "Timestamp Sequence Number error", EXPFILL }
3262 { &ei_bundle_offset_error,
3263 { "bundle.offset_error", PI_PROTOCOL, PI_WARN, "Offset field error", EXPFILL }
3265 { &ei_bundle_block_control_flags,
3266 { "bundle.block.control.flags.error", PI_PROTOCOL, PI_WARN, "Control flag error", EXPFILL }
3268 { &ei_block_control_block_cteb_invalid,
3269 { "bundle.block.control.cteb_invalid", PI_PROTOCOL, PI_WARN, "CTEB Is Invalid", EXPFILL }
3271 { &ei_block_control_block_cteb_valid,
3272 { "bundle.block.control.cteb_valid", PI_PROTOCOL, PI_NOTE, "CTEB Is Valid", EXPFILL }
3276 static ei_register_info ei_tcpcl[] = {
3277 { &ei_tcp_convergence_data_flags,
3278 { "tcpcl.data.flags.invalid", PI_PROTOCOL, PI_WARN, "Invalid TCP CL Data Segment Flags", EXPFILL }
3280 { &ei_tcp_convergence_segment_length,
3281 { "tcpcl.data.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Data Length", EXPFILL }
3283 { &ei_tcp_convergence_ack_length,
3284 { "tcpcl.ack.length.error", PI_PROTOCOL, PI_WARN, "Ack Length: Error", EXPFILL }
3288 expert_module_t *expert_bundle, *expert_tcpcl;
3290 proto_bundle = proto_register_protocol("Bundle Protocol", "Bundle", "bundle");
3291 bundle_handle = register_dissector("bundle", dissect_bundle, proto_bundle);
3293 proto_tcp_conv = proto_register_protocol ("DTN TCP Convergence Layer Protocol", "TCPCL", "tcpcl");
3295 proto_register_field_array(proto_bundle, hf, array_length(hf));
3296 proto_register_subtree_array(ett, array_length(ett));
3297 expert_bundle = expert_register_protocol(proto_bundle);
3298 expert_register_field_array(expert_bundle, ei, array_length(ei));
3300 proto_register_field_array(proto_tcp_conv, hf_tcpcl, array_length(hf_tcpcl));
3301 proto_register_subtree_array(ett_tcpcl, array_length(ett_tcpcl));
3302 expert_tcpcl = expert_register_protocol(proto_tcp_conv);
3303 expert_register_field_array(expert_tcpcl, ei_tcpcl, array_length(ei_tcpcl));
3305 reassembly_table_register(&msg_reassembly_table,
3306 &addresses_reassembly_table_functions);
3311 proto_reg_handoff_bundle(void)
3313 dissector_handle_t tcpcl_handle;
3315 tcpcl_handle = create_dissector_handle(dissect_tcpcl, proto_bundle);
3316 dissector_add_uint_with_preference("tcp.port", BUNDLE_PORT, tcpcl_handle);
3317 dissector_add_uint_with_preference("udp.port", BUNDLE_PORT, bundle_handle);
3321 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3326 * indent-tabs-mode: nil
3329 * vi: set shiftwidth=4 tabstop=8 expandtab:
3330 * :indentSize=4:tabSize=8:noTabs=true: