HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-dtn.c
blobce5c6371649bdfd79e8d2ecc79693743b2da10e1
1 /*
2 * Copyright 2006-2007 The MITRE Corporation.
3 * All Rights Reserved.
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 * $Id$
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 * Specification reference:
33 * RFC 5050
34 * http://tools.ietf.org/html/rfc5050
37 #include "config.h"
39 #include <glib.h>
41 #include <epan/packet.h>
42 #include <epan/prefs.h>
43 #include <epan/reassemble.h>
44 #include <epan/expert.h>
45 #include <epan/wmem/wmem.h>
46 #include "packet-dtn.h"
47 #include "packet-tcp.h"
49 static int dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, packet_info *pinfo,
50 int offset, int payload_length, gboolean* success);
52 /* For Reassembling TCP Convergence Layer segments */
53 static reassembly_table msg_reassembly_table;
55 static char magic[] = {'d', 't', 'n', '!'};
57 static int proto_bundle = -1;
58 static int proto_tcp_conv = -1;
59 static int hf_bundle_pdu_version = -1;
61 /* TCP Convergence Header Variables */
62 static int hf_tcp_convergence_pkt_type = -1;
64 static int hf_contact_hdr_version = -1;
65 static int hf_contact_hdr_flags = -1;
66 static int hf_contact_hdr_keep_alive = -1;
67 static int hf_contact_hdr_flags_ack_req = -1;
68 static int hf_contact_hdr_flags_frag_enable = -1;
69 static int hf_contact_hdr_flags_nak = -1;
70 static int hf_contact_hdr_magic = -1;
71 static int hf_contact_hdr_local_eid_length = -1;
72 static int hf_contact_hdr_local_eid = -1;
74 /* TCP Convergence Data Header Variables */
75 static int hf_tcp_convergence_data_procflags = -1;
76 static int hf_tcp_convergence_data_procflags_start = -1;
77 static int hf_tcp_convergence_data_procflags_end = -1;
78 static int hf_tcp_convergence_data_segment_length = -1;
80 /* TCP Convergence Ack Variables */
81 static int hf_tcp_convergence_ack_length = -1;
83 /* TCP Convergence Shutdown Header Variables */
84 static int hf_tcp_convergence_shutdown_flags = -1;
85 static int hf_tcp_convergence_shutdown_flags_reason = -1;
86 static int hf_tcp_convergence_shutdown_flags_delay = -1;
87 static int hf_tcp_convergence_shutdown_reason = -1;
88 static int hf_tcp_convergence_shutdown_delay = -1;
90 /*TCP Convergence Layer Reassembly boilerplate*/
91 static int hf_msg_fragments = -1;
92 static int hf_msg_fragment = -1;
93 static int hf_msg_fragment_overlap = -1;
94 static int hf_msg_fragment_overlap_conflicts = -1;
95 static int hf_msg_fragment_multiple_tails = -1;
96 static int hf_msg_fragment_too_long_fragment = -1;
97 static int hf_msg_fragment_error = -1;
98 static int hf_msg_fragment_count = -1;
99 static int hf_msg_reassembled_in = -1;
100 static int hf_msg_reassembled_length = -1;
102 /* Primary Header Processing Flag Variables */
103 static int hf_bundle_procflags = -1;
104 static int hf_bundle_procflags_fragment = -1;
105 static int hf_bundle_procflags_admin = -1;
106 static int hf_bundle_procflags_dont_fragment = -1;
107 static int hf_bundle_procflags_cust_xfer_req = -1;
108 static int hf_bundle_procflags_dest_singleton = -1;
109 static int hf_bundle_procflags_application_ack = -1;
111 /* Additions for Version 5 */
112 static int hf_bundle_control_flags = -1;
113 static int hf_bundle_procflags_general = -1;
114 static int hf_bundle_procflags_cos = -1;
115 static int hf_bundle_procflags_status = -1;
117 /* Primary Header COS Flag Variables */
118 static int hf_bundle_cosflags = -1;
119 static int hf_bundle_cosflags_priority = -1;
121 /* Primary Header Status Report Request Flag Variables */
122 static int hf_bundle_srrflags = -1;
123 static int hf_bundle_srrflags_report_receipt = -1;
124 static int hf_bundle_srrflags_report_cust_accept = -1;
125 static int hf_bundle_srrflags_report_forward = -1;
126 static int hf_bundle_srrflags_report_delivery = -1;
127 static int hf_bundle_srrflags_report_deletion = -1;
128 static int hf_bundle_srrflags_report_ack = -1;
130 /* Primary Header Fields*/
131 static int hf_bundle_primary_header_len = -1;
132 static int hf_bundle_primary_dictionary_len = -1;
133 static int hf_bundle_primary_timestamp = -1;
134 static int hf_bundle_primary_fragment_offset = -1;
135 static int hf_bundle_primary_total_adu_len = -1;
136 static int hf_bundle_primary_timestamp_seq_num64 = -1;
137 static int hf_bundle_primary_timestamp_seq_num32 = -1;
139 static int hf_bundle_dest_scheme_offset_u16 = -1;
140 static int hf_bundle_dest_scheme_offset_i32 = -1;
141 static int hf_bundle_dest_ssp_offset_u16 = -1;
142 static int hf_bundle_dest_ssp_offset_i32 = -1;
143 static int hf_bundle_source_scheme_offset_u16 = -1;
144 static int hf_bundle_source_scheme_offset_i32 = -1;
145 static int hf_bundle_source_ssp_offset_u16 = -1;
146 static int hf_bundle_source_ssp_offset_i32 = -1;
147 static int hf_bundle_report_scheme_offset_u16 = -1;
148 static int hf_bundle_report_scheme_offset_i32 = -1;
149 static int hf_bundle_report_ssp_offset_u16 = -1;
150 static int hf_bundle_report_ssp_offset_i32 = -1;
151 static int hf_bundle_cust_scheme_offset_u16 = -1;
152 static int hf_bundle_cust_scheme_offset_i32 = -1;
153 static int hf_bundle_cust_ssp_offset_u16 = -1;
154 static int hf_bundle_cust_ssp_offset_i32 = -1;
156 /* Dictionary EIDs */
157 static int hf_bundle_dest_scheme = -1;
158 static int hf_bundle_dest_ssp = -1;
159 static int hf_bundle_source_scheme = -1;
160 static int hf_bundle_source_ssp = -1;
161 static int hf_bundle_report_scheme = -1;
162 static int hf_bundle_report_ssp = -1;
163 static int hf_bundle_custodian_scheme = -1;
164 static int hf_bundle_custodian_ssp = -1;
166 /* Remaining Primary Header Fields */
167 static int hf_bundle_creation_timestamp = -1;
168 static int hf_bundle_lifetime = -1;
169 static int hf_bundle_lifetime_sdnv = -1;
171 /* Secondary Header Processing Flag Variables */
172 static int hf_bundle_payload_length = -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;
196 /* ECOS Flag Variables */
197 static int hf_ecos_flags = -1;
198 static int hf_ecos_flags_critical = -1;
199 static int hf_ecos_flags_streaming = -1;
200 static int hf_ecos_flags_ordinal = -1;
201 static int hf_ecos_flow_label = -1;
203 static int hf_ecos_ordinal = -1;
205 /* Administrative Record Variables */
206 static int hf_bundle_admin_record_type = -1;
207 static int hf_bundle_admin_record_fragment = -1;
208 static int hf_bundle_admin_statflags = -1;
209 static int hf_bundle_admin_rcvd = -1;
210 static int hf_bundle_admin_accepted = -1;
211 static int hf_bundle_admin_forwarded = -1;
212 static int hf_bundle_admin_delivered = -1;
213 static int hf_bundle_admin_deleted = -1;
214 static int hf_bundle_admin_acked = -1;
215 static int hf_bundle_admin_fragment_offset = -1;
216 static int hf_bundle_admin_fragment_length = -1;
217 static int hf_bundle_admin_timestamp_seq_num64 = -1;
218 static int hf_bundle_admin_timestamp_seq_num32 = -1;
219 static int hf_bundle_admin_endpoint_length = -1;
220 static int hf_bundle_admin_endpoint_id = -1;
222 static int hf_bundle_admin_receipt_time = -1;
223 static int hf_bundle_admin_accept_time = -1;
224 static int hf_bundle_admin_forward_time = -1;
225 static int hf_bundle_admin_delivery_time = -1;
226 static int hf_bundle_admin_delete_time = -1;
227 static int hf_bundle_admin_ack_time = -1;
228 static int hf_bundle_admin_timestamp_copy = -1;
229 static int hf_bundle_admin_signal_time = -1;
230 static int hf_bundle_status_report_reason_code = -1;
231 static int hf_bundle_custody_trf_succ_flg = -1;
232 static int hf_bundle_custody_signal_reason = -1;
233 static int hf_bundle_custody_id_range_start = -1;
234 static int hf_bundle_custody_id_range_end = -1;
236 /* Tree Node Variables */
237 static gint ett_bundle = -1;
238 static gint ett_conv_flags = -1;
239 static gint ett_shutdown_flags = -1;
240 static gint ett_bundle_hdr = -1;
241 static gint ett_primary_hdr = -1;
242 static gint ett_proc_flags = -1;
243 static gint ett_gen_flags = -1;
244 static gint ett_cos_flags = -1;
245 static gint ett_srr_flags = -1;
246 static gint ett_dictionary = -1;
247 static gint ett_payload_hdr = -1;
248 static gint ett_payload_flags = -1;
249 static gint ett_block_flags = -1;
250 static gint ett_contact_hdr_flags = -1;
251 static gint ett_admin_record = -1;
252 static gint ett_admin_rec_status = -1;
253 static gint ett_metadata_hdr = -1;
255 static gint ett_tcp_conv = -1;
256 static gint ett_tcp_conv_hdr = -1;
257 static gint ett_msg_fragment = -1;
258 static gint ett_msg_fragments = -1;
261 static expert_field ei_bundle_payload_length = EI_INIT;
262 static expert_field ei_bundle_control_flags_length = EI_INIT;
263 static expert_field ei_bundle_block_control_flags = EI_INIT;
264 static expert_field ei_bundle_sdnv_length = EI_INIT;
265 static expert_field ei_bundle_timestamp_seq_num = EI_INIT;
266 static expert_field ei_bundle_offset_error = EI_INIT;
267 static expert_field ei_block_control_block_cteb_invalid = EI_INIT;
268 static expert_field ei_block_control_block_cteb_valid = EI_INIT;
270 static expert_field ei_tcp_convergence_data_flags = EI_INIT;
271 static expert_field ei_tcp_convergence_segment_length = EI_INIT;
272 static expert_field ei_tcp_convergence_ack_length = EI_INIT;
275 static dissector_handle_t bundle_handle;
276 static dissector_handle_t data_handle;
278 static guint bundle_tcp_port = 4556;
279 static guint bundle_udp_port = 4556;
281 typedef struct dictionary_data {
282 int bundle_header_dict_length;
284 int dest_scheme_offset;
285 int dst_scheme_pos;
286 int dst_scheme_len;
287 int source_scheme_offset;
288 int src_scheme_pos;
289 int src_scheme_len;
290 int report_scheme_offset;
291 int rpt_scheme_pos;
292 int rpt_scheme_len;
293 int cust_scheme_offset;
294 int cust_scheme_pos;
295 int cust_scheme_len;
296 int dest_ssp_offset;
297 int dst_ssp_len;
298 int source_ssp_offset;
299 int src_ssp_len;
300 int report_ssp_offset;
301 int rpt_ssp_len;
302 int cust_ssp_offset;
303 int cust_ssp_len;
305 } dictionary_data_t;
308 static const value_string packet_type_vals[] = {
309 {((TCP_CONVERGENCE_DATA_SEGMENT>>4) & 0x0F), "Data"},
310 {((TCP_CONVERGENCE_ACK_SEGMENT>>4) & 0x0F), "Ack"},
311 {((TCP_CONVERGENCE_REFUSE_BUNDLE>>4) & 0x0F), "Refuse Bundle"},
312 {((TCP_CONVERGENCE_KEEP_ALIVE>>4) & 0x0F), "Keep Alive"},
313 {((TCP_CONVERGENCE_SHUTDOWN>>4) & 0x0F), "Shutdown"},
314 {0, NULL}
317 static const value_string admin_record_type_vals[] = {
318 {ADMIN_REC_TYPE_STATUS_REPORT, "Bundle Status Report"},
319 {ADMIN_REC_TYPE_CUSTODY_SIGNAL, "Custody Signal"},
320 {ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL, "Aggregate Custody Signal"},
321 {ADMIN_REC_TYPE_ANNOUNCE_BUNDLE, "Announce Record (Contact)"},
322 {0, NULL}
325 static const value_string custody_signal_reason_codes[] = {
326 {0x0, "No Additional Information"},
327 {0x3, "Redundant Reception"},
328 {0x4, "Depleted Storage"},
329 {0x5, "Destination Endpoint ID Unintelligible"},
330 {0x6, "No Known Route to Destination"},
331 {0x7, "No Timely Contact with Next Node on Route"},
332 {0x8, "Header Unintelligible"},
333 {0, NULL}
336 static const value_string status_report_reason_codes[] = {
337 {0x0, "No Additional Information"},
338 {0x1, "Lifetime Expired"},
339 {0x2, "Forwarded over Unidirectional Link"},
340 {0x3, "Transmission Cancelled"},
341 {0x4, "Depleted Storage"},
342 {0x5, "Destination Endpoint ID Unintelligible"},
343 {0x6, "No Known Route to Destination"},
344 {0x7, "No Timely Contact with Next Node on Route"},
345 {0x8, "Header Unintelligible"},
346 {0, NULL}
349 static const value_string bundle_block_type_codes[] = {
350 {0x01, "Bundle Payload Block"},
351 {0x02, "Bundle Authentication Block"},
352 {0x03, "Payload Integrity Block"},
353 {0x04, "Payload Confidentiality Block"},
354 {0x05, "Previous-Hop Insertion Block"},
355 {0x08, "Metadata Extension Block"},
356 {0x09, "Extension Security Block"},
357 {0x0a, "Custody Transfer Enhancement Block"},
358 {0x13, "Extended Class of Service Block"},
359 {0, NULL}
362 static const value_string cosflags_priority_vals[] = {
363 {0x00, "Bulk"},
364 {0x01, "Normal"},
365 {0x02, "Expedited"},
366 {0x03, "Invalid (Reserved)"},
367 {0, NULL}
370 static const value_string ecos_flags[] = {
371 {0x00, "None"},
372 {0x01, "ECOS Critical"},
373 {0x02, "ECOS Streaming"},
374 {0x03, "ECOS Critical+Streaming"},
375 {0x04, "ECOS Ordinal"},
376 {0x05, "ECOS Critical+Ordinal"},
377 {0x06, "ECOS Streaming+Ordinal"},
378 {0x07, "ECOS Critical+Streaming+Ordinal"},
379 {0, NULL}
383 * SDNV has a zero in high-order bit position of last byte. The high-order
384 * bit of all preceding bytes is set to one. This returns the numeric value
385 * in an integer and sets the value of the second argument to the number of
386 * bytes used to code the SDNV. A -1 is returned if the evaluation fails
387 * (value exceeds maximum for signed integer). 0 is an acceptable value.
390 #define SDNV_MASK 0x7f
392 static const fragment_items msg_frag_items = {
393 /*Fragment subtrees*/
394 &ett_msg_fragment,
395 &ett_msg_fragments,
396 /*Fragment Fields*/
397 &hf_msg_fragments,
398 &hf_msg_fragment,
399 &hf_msg_fragment_overlap,
400 &hf_msg_fragment_overlap_conflicts,
401 &hf_msg_fragment_multiple_tails,
402 &hf_msg_fragment_too_long_fragment,
403 &hf_msg_fragment_error,
404 &hf_msg_fragment_count,
405 /*Reassembled in field*/
406 &hf_msg_reassembled_in,
407 /*Reassembled length field*/
408 &hf_msg_reassembled_length,
409 /* Reassembled data field */
410 NULL,
411 /*Tag*/
412 "Message fragments"
416 * Adds the result of 2 SDNVs to tree: First SDNV is seconds, next is nanoseconds.
417 * Returns bytes in both SDNVs or 0 if something goes wrong.
419 static int
420 add_dtn_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_dtn_time)
422 nstime_t dtn_time;
423 int sdnv_length, sdnv2_length;
424 int sdnv_value;
426 sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
427 if(sdnv_value < 0) {
428 return 0;
431 dtn_time.secs = (time_t)(sdnv_value + 946684800);
432 offset += sdnv_length;
434 dtn_time.nsecs = evaluate_sdnv(tvb, offset, &sdnv2_length);
435 if(dtn_time.nsecs < 0) {
436 return 0;
439 proto_tree_add_time(tree, hf_dtn_time, tvb, offset, sdnv_length + sdnv2_length, &dtn_time);
441 return (sdnv_length + sdnv2_length);
445 * Adds the result of SDNV which is a time since 2000 to tree.
446 * Returns bytes in SDNV or 0 if something goes wrong.
448 static int
449 add_sdnv_time_to_tree(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_sdnv_time)
451 nstime_t dtn_time;
452 int sdnv_length;
453 int sdnv_value;
455 sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
456 if(sdnv_value < 0) {
457 return 0;
460 dtn_time.secs = (time_t)(sdnv_value + 946684800);
461 dtn_time.nsecs = 0;
462 proto_tree_add_time(tree, hf_sdnv_time, tvb, offset, sdnv_length, &dtn_time);
464 return sdnv_length;
467 static int
468 add_sdnv_to_tree(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, int offset, int hf_sdnv)
470 proto_item* ti;
471 int sdnv_length;
472 int sdnv_value;
474 sdnv_value = evaluate_sdnv(tvb, offset, &sdnv_length);
475 ti = proto_tree_add_int(tree, hf_sdnv, tvb, offset, sdnv_length, sdnv_value);
476 if(sdnv_value < 0) {
477 expert_add_info(pinfo, ti, &ei_bundle_sdnv_length);
478 return 0;
480 return sdnv_length;
484 * Pull out stuff from the dictionary
486 static int
487 dissect_dictionary(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, dictionary_data_t* dict_data,
488 guint8 pri_hdr_procflags, gchar **bundle_custodian)
490 proto_item *ti;
491 proto_tree *dict_tree;
492 int sdnv_length;
493 const gchar *src_node, *dst_node;
495 ti = proto_tree_add_text(tree, tvb, offset, dict_data->bundle_header_dict_length, "Dictionary");
496 dict_tree = proto_item_add_subtree(ti, ett_dictionary);
499 * If the dictionary length is 0, then the CBHE block compression method is applied. (RFC6260)
500 * So the scheme offset is the node number and the ssp offset is the service number.
501 * If destination scheme offset is 2 and destination ssp offset is 1, then the EID is
502 * ipn:2.1
504 if(dict_data->bundle_header_dict_length == 0)
507 * Destination info
509 proto_tree_add_text(dict_tree, tvb, 0,
510 0, "Destination Scheme: %s",IPN_SCHEME_STR);
511 if(dict_data->dest_scheme_offset == 0 && dict_data->dest_ssp_offset == 0)
513 proto_tree_add_text(dict_tree, tvb, dict_data->dst_scheme_pos,
514 dict_data->dst_scheme_len + dict_data->dst_ssp_len, "Destination: Null");
516 else
518 proto_tree_add_text(dict_tree, tvb, dict_data->dst_scheme_pos,
519 dict_data->dst_scheme_len + dict_data->dst_ssp_len,
520 "Destination: %d.%d",dict_data->dest_scheme_offset,dict_data->dest_ssp_offset);
524 * Source info
526 proto_tree_add_text(dict_tree, tvb, 0, 0, "Source Scheme: %s",IPN_SCHEME_STR);
527 if(dict_data->source_scheme_offset == 0 && dict_data->source_ssp_offset == 0)
529 proto_tree_add_text(dict_tree, tvb, dict_data->src_scheme_pos,
530 dict_data->src_scheme_len + dict_data->src_ssp_len, "Source: Null");
532 else
534 proto_tree_add_text(dict_tree, tvb, dict_data->src_scheme_pos,
535 dict_data->src_scheme_len + dict_data->src_ssp_len,
536 "Source: %d.%d", dict_data->source_scheme_offset, dict_data->source_ssp_offset);
540 * Report to info
542 proto_tree_add_text(dict_tree, tvb, 0, 0, "Report Scheme: %s",IPN_SCHEME_STR);
543 if (dict_data->report_scheme_offset == 0 && dict_data->report_ssp_offset == 0)
545 proto_tree_add_text(dict_tree, tvb, dict_data->rpt_scheme_pos,
546 dict_data->rpt_scheme_len + dict_data->rpt_ssp_len, "Report: Null");
548 else
550 proto_tree_add_text(dict_tree, tvb, dict_data->rpt_scheme_pos,
551 dict_data->rpt_scheme_len + dict_data->rpt_ssp_len,
552 "Report: %d.%d", dict_data->report_scheme_offset, dict_data->report_ssp_offset);
556 * Custodian info
558 proto_tree_add_text(dict_tree, tvb, 0, 0, "Custodian Scheme: %s",IPN_SCHEME_STR);
559 if (dict_data->cust_scheme_offset == 0 && dict_data->cust_ssp_offset == 0)
561 proto_tree_add_text(dict_tree, tvb, dict_data->cust_scheme_pos,
562 dict_data->cust_scheme_len + dict_data->cust_ssp_len, "Custodian: Null");
564 else
566 proto_tree_add_text(dict_tree, tvb, dict_data->cust_scheme_pos,
567 dict_data->cust_scheme_len + dict_data->cust_ssp_len,
568 "Custodian: %d.%d", dict_data->cust_scheme_offset, dict_data->cust_ssp_offset);
571 if (dict_data->source_scheme_offset == 0 && dict_data->source_ssp_offset == 0)
573 src_node = "Null";
575 else
577 src_node = wmem_strdup_printf(wmem_packet_scope(), "%s:%d.%d", IPN_SCHEME_STR,
578 dict_data->source_scheme_offset, dict_data->source_ssp_offset);
580 if (dict_data->dest_scheme_offset == 0 && dict_data->dest_ssp_offset == 0)
582 dst_node = "Null";
584 else
586 dst_node = wmem_strdup_printf(wmem_packet_scope(), "%s:%d.%d", IPN_SCHEME_STR,
587 dict_data->dest_scheme_offset, dict_data->dest_ssp_offset);
590 col_add_fstr(pinfo->cinfo, COL_INFO, "%s > %s", src_node, dst_node);
591 /* remember custodian, for use in checking cteb validity */
592 *bundle_custodian = wmem_strdup_printf(wmem_packet_scope(), "%s:%d.%d", IPN_SCHEME_STR,
593 dict_data->cust_scheme_offset, dict_data->cust_ssp_offset);
597 * This pointer can be made to address outside the packet boundaries so we
598 * need to check for improperly formatted strings (no null termination).
601 else
604 * Destination info
607 proto_tree_add_item(dict_tree, hf_bundle_dest_scheme, tvb, offset + dict_data->dest_scheme_offset, -1, ENC_ASCII|ENC_NA);
608 proto_tree_add_item(dict_tree, hf_bundle_dest_ssp, tvb, offset + dict_data->dest_ssp_offset, -1, ENC_ASCII|ENC_NA);
611 * Source info
614 proto_tree_add_item(dict_tree, hf_bundle_source_scheme, tvb, offset + dict_data->source_scheme_offset, -1, ENC_ASCII|ENC_NA);
615 proto_tree_add_item(dict_tree, hf_bundle_source_ssp, tvb, offset + dict_data->source_ssp_offset, -1, ENC_ASCII|ENC_NA);
618 * Report to info
621 proto_tree_add_item(dict_tree, hf_bundle_report_scheme, tvb, offset + dict_data->report_scheme_offset, -1, ENC_ASCII|ENC_NA);
622 proto_tree_add_item(dict_tree, hf_bundle_report_ssp, tvb, offset + dict_data->report_ssp_offset, -1, ENC_ASCII|ENC_NA);
625 * Custodian info
628 proto_tree_add_item(dict_tree, hf_bundle_custodian_scheme, tvb, offset + dict_data->cust_scheme_offset, -1, ENC_ASCII|ENC_NA);
629 proto_tree_add_item(dict_tree, hf_bundle_custodian_ssp, tvb, offset + dict_data->cust_ssp_offset, -1, ENC_ASCII|ENC_NA);
632 * Add Source/Destination to INFO Field
635 col_add_fstr(pinfo->cinfo, COL_INFO, "%s:%s > %s:%s",
636 tvb_get_stringz(wmem_packet_scope(), tvb, offset + dict_data->source_scheme_offset, NULL),
637 tvb_get_stringz(wmem_packet_scope(), tvb, offset + dict_data->source_ssp_offset, NULL),
638 tvb_get_stringz(wmem_packet_scope(), tvb, offset + dict_data->dest_scheme_offset, NULL),
639 tvb_get_stringz(wmem_packet_scope(), tvb, offset + dict_data->dest_ssp_offset, NULL));
641 /* remember custodian, for use in checking cteb validity */
642 *bundle_custodian = wmem_strdup_printf(wmem_packet_scope(), "%s:%s",
643 tvb_get_stringz(wmem_packet_scope(), tvb, offset + dict_data->cust_scheme_offset, NULL),
644 tvb_get_stringz(wmem_packet_scope(), tvb, offset + dict_data->cust_ssp_offset, NULL));
646 offset += dict_data->bundle_header_dict_length; /*Skip over dictionary*/
649 * Do this only if Fragment Flag is set
652 if(pri_hdr_procflags & BUNDLE_PROCFLAGS_FRAG_MASK) {
653 sdnv_length = add_sdnv_to_tree(tree, tvb, pinfo, offset, hf_bundle_primary_fragment_offset);
654 if (sdnv_length < 0) {
655 return 0;
657 offset += sdnv_length;
659 sdnv_length = add_sdnv_to_tree(tree, tvb, pinfo, offset, hf_bundle_primary_total_adu_len);
660 if (sdnv_length < 0) {
661 return 0;
663 offset += sdnv_length;
666 return offset;
670 * This routine returns 0 if header decoding fails, otherwise the length of the primary
671 * header, starting right after version number.
673 static int
674 dissect_version_4_primary_header(packet_info *pinfo, proto_tree *primary_tree, tvbuff_t *tvb, guint8* pri_hdr_procflags, gchar **bundle_custodian)
676 int bundle_header_length;
677 int offset = 1; /* Version Number already displayed */
678 int sdnv_length;
679 dictionary_data_t dict_data;
681 proto_item *ti;
682 proto_tree *srr_flag_tree, *proc_flag_tree, *cos_flag_tree;
684 /* Primary Header Processing Flags */
685 *pri_hdr_procflags = tvb_get_guint8(tvb, offset);
686 ti = proto_tree_add_item(primary_tree, hf_bundle_procflags, tvb,
687 offset, 1, ENC_BIG_ENDIAN);
688 proc_flag_tree = proto_item_add_subtree(ti, ett_proc_flags);
689 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_fragment,
690 tvb, offset, 1, ENC_BIG_ENDIAN);
691 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_admin,
692 tvb, offset, 1, ENC_BIG_ENDIAN);
693 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_dont_fragment,
694 tvb, offset, 1, ENC_BIG_ENDIAN);
695 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_cust_xfer_req,
696 tvb, offset, 1, ENC_BIG_ENDIAN);
697 proto_tree_add_item(proc_flag_tree, hf_bundle_procflags_dest_singleton,
698 tvb, offset, 1, ENC_BIG_ENDIAN);
700 /* Primary Header COS Flags */
701 ++offset;
702 ti = proto_tree_add_item(primary_tree, hf_bundle_cosflags, tvb,
703 offset, 1, ENC_BIG_ENDIAN);
704 cos_flag_tree = proto_item_add_subtree(ti, ett_cos_flags);
705 proto_tree_add_item(cos_flag_tree, hf_bundle_cosflags_priority,
706 tvb, offset, 1, ENC_BIG_ENDIAN);
707 /* Status Report Request Flags */
708 ++offset;
709 ti = proto_tree_add_item(primary_tree, hf_bundle_srrflags, tvb,
710 offset, 1, ENC_BIG_ENDIAN);
711 srr_flag_tree = proto_item_add_subtree(ti, ett_srr_flags);
713 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_receipt,
714 tvb, offset, 1, ENC_BIG_ENDIAN);
715 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_cust_accept,
716 tvb, offset, 1, ENC_BIG_ENDIAN);
717 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_forward,
718 tvb, offset, 1, ENC_BIG_ENDIAN);
719 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_delivery,
720 tvb, offset, 1, ENC_BIG_ENDIAN);
721 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_deletion,
722 tvb, offset, 1, ENC_BIG_ENDIAN);
723 proto_tree_add_item(srr_flag_tree, hf_bundle_srrflags_report_ack,
724 tvb, offset, 1, ENC_BIG_ENDIAN);
725 ++offset;
727 bundle_header_length = evaluate_sdnv(tvb, offset, &sdnv_length);
728 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_header_len, tvb, offset, sdnv_length, bundle_header_length);
729 if(bundle_header_length < 0) {
730 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Bundle Header Length Error");
731 return 0;
734 offset += sdnv_length;
736 /* Ensure all fields have been initialized */
737 memset(&dict_data, 0, sizeof(dict_data));
740 * Pick up offsets into dictionary (8 of them)
743 dict_data.dest_scheme_offset = tvb_get_ntohs(tvb, offset);
744 dict_data.dst_scheme_pos = offset;
745 dict_data.dst_scheme_len = 2;
746 proto_tree_add_item(primary_tree, hf_bundle_dest_scheme_offset_u16,
747 tvb, offset, 2, ENC_BIG_ENDIAN);
748 offset += 2;
750 dict_data.dest_ssp_offset = tvb_get_ntohs(tvb, offset);
751 dict_data.dst_ssp_len = 2;
752 proto_tree_add_item(primary_tree, hf_bundle_dest_ssp_offset_u16,
753 tvb, offset, 2, ENC_BIG_ENDIAN);
754 offset += 2;
756 dict_data.source_scheme_offset = tvb_get_ntohs(tvb, offset);
757 dict_data.src_scheme_pos = offset;
758 dict_data.src_scheme_len = 2;
759 proto_tree_add_item(primary_tree, hf_bundle_source_scheme_offset_u16,
760 tvb, offset, 2, ENC_BIG_ENDIAN);
761 offset += 2;
763 dict_data.source_ssp_offset = tvb_get_ntohs(tvb, offset);
764 dict_data.src_ssp_len = 2;
765 proto_tree_add_item(primary_tree, hf_bundle_source_ssp_offset_u16,
766 tvb, offset, 2, ENC_BIG_ENDIAN);
767 offset += 2;
769 dict_data.report_scheme_offset = tvb_get_ntohs(tvb, offset);
770 dict_data.rpt_scheme_pos = offset;
771 dict_data.rpt_scheme_len = 2;
772 proto_tree_add_item(primary_tree, hf_bundle_report_scheme_offset_u16,
773 tvb, offset, 2, ENC_BIG_ENDIAN);
774 offset += 2;
776 dict_data.report_ssp_offset = tvb_get_ntohs(tvb, offset);
777 dict_data.rpt_ssp_len = 2;
778 proto_tree_add_item(primary_tree, hf_bundle_report_ssp_offset_u16,
779 tvb, offset, 2, ENC_BIG_ENDIAN);
780 offset += 2;
782 dict_data.cust_scheme_offset = tvb_get_ntohs(tvb, offset);
783 dict_data.cust_scheme_pos = offset;
784 dict_data.cust_scheme_len = 2;
785 proto_tree_add_item(primary_tree, hf_bundle_cust_scheme_offset_u16,
786 tvb, offset, 2, ENC_BIG_ENDIAN);
787 offset += 2;
789 dict_data.cust_ssp_offset = tvb_get_ntohs(tvb, offset);
790 dict_data.cust_ssp_len = 2;
791 proto_tree_add_item(primary_tree, hf_bundle_cust_ssp_offset_u16,
792 tvb, offset, 2, ENC_BIG_ENDIAN);
793 offset += 2;
795 proto_tree_add_item(primary_tree, hf_bundle_creation_timestamp,
796 tvb, offset, 8, ENC_BIG_ENDIAN);
797 offset += 8;
799 proto_tree_add_item(primary_tree, hf_bundle_lifetime, tvb, offset, 4, ENC_BIG_ENDIAN);
800 offset += 4;
802 dict_data.bundle_header_dict_length = evaluate_sdnv(tvb, offset, &sdnv_length);
803 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_dictionary_len, tvb, offset, sdnv_length, dict_data.bundle_header_dict_length);
804 if(dict_data.bundle_header_dict_length < 0) {
805 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Dictionary Header Length Error");
806 return 0;
808 offset += sdnv_length;
810 offset = dissect_dictionary(pinfo, primary_tree, tvb, offset, &dict_data, *pri_hdr_procflags, bundle_custodian);
811 return offset;
816 * This routine returns 0 if header decoding fails, otherwise the length of the primary
817 * header, starting right after version number.
820 static int
821 dissect_version_5_and_6_primary_header(packet_info *pinfo,
822 proto_tree *primary_tree, tvbuff_t *tvb, guint8* pri_hdr_procflags, gchar **bundle_custodian)
824 guint64 bundle_processing_control_flags;
825 guint8 cosflags;
826 int bundle_header_length;
827 int offset = 1; /* Version Number already displayed */
828 int sdnv_length;
829 dictionary_data_t dict_data;
830 int timestamp_sequence;
831 guint8 srrflags;
832 proto_item *ti;
833 proto_tree *gen_flag_tree, *srr_flag_tree, *proc_flag_tree, *cos_flag_tree;
835 bundle_processing_control_flags = evaluate_sdnv_64(tvb, offset, &sdnv_length);
837 /* Primary Header Processing Flags */
838 *pri_hdr_procflags = (guint8) (bundle_processing_control_flags & 0x7f);
840 if (sdnv_length < 1 || sdnv_length > 8) {
841 expert_add_info_format(pinfo, primary_tree, &ei_bundle_control_flags_length,
842 "Wrong bundle control flag length: %d", sdnv_length);
843 return 0;
845 ti = proto_tree_add_item(primary_tree, hf_bundle_control_flags, tvb,
846 offset, sdnv_length, ENC_BIG_ENDIAN);
847 proc_flag_tree = proto_item_add_subtree(ti, ett_proc_flags);
849 ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_general, tvb, offset,
850 sdnv_length, *pri_hdr_procflags);
851 gen_flag_tree = proto_item_add_subtree(ti, ett_gen_flags);
853 proto_tree_add_boolean(gen_flag_tree, hf_bundle_procflags_fragment,
854 tvb, offset, sdnv_length, *pri_hdr_procflags);
855 proto_tree_add_boolean(gen_flag_tree, hf_bundle_procflags_admin,
856 tvb, offset, sdnv_length, *pri_hdr_procflags);
857 proto_tree_add_boolean(gen_flag_tree, hf_bundle_procflags_dont_fragment,
858 tvb, offset, sdnv_length, *pri_hdr_procflags);
859 proto_tree_add_boolean(gen_flag_tree, hf_bundle_procflags_cust_xfer_req,
860 tvb, offset, sdnv_length, *pri_hdr_procflags);
861 proto_tree_add_boolean(gen_flag_tree, hf_bundle_procflags_dest_singleton,
862 tvb, offset, sdnv_length, *pri_hdr_procflags);
863 proto_tree_add_boolean(gen_flag_tree, hf_bundle_procflags_application_ack,
864 tvb, offset, sdnv_length, *pri_hdr_procflags);
866 /* Primary Header COS Flags */
867 cosflags = (guint8) ((bundle_processing_control_flags >> 7) & 0x7f);
868 ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_cos, tvb, offset,
869 sdnv_length, cosflags);
870 cos_flag_tree = proto_item_add_subtree(ti, ett_cos_flags);
871 proto_tree_add_uint(cos_flag_tree, hf_bundle_cosflags_priority, tvb, offset,
872 sdnv_length, cosflags);
874 /* Status Report Request Flags */
875 srrflags = (guint8) ((bundle_processing_control_flags >> 14) & 0x7f);
876 ti = proto_tree_add_uint(proc_flag_tree, hf_bundle_procflags_status, tvb, offset,
877 sdnv_length, srrflags);
878 srr_flag_tree = proto_item_add_subtree(ti, ett_srr_flags);
880 proto_tree_add_boolean(srr_flag_tree, hf_bundle_srrflags_report_receipt,
881 tvb, offset, sdnv_length, srrflags);
882 proto_tree_add_boolean(srr_flag_tree, hf_bundle_srrflags_report_cust_accept,
883 tvb, offset, sdnv_length, srrflags);
884 proto_tree_add_boolean(srr_flag_tree, hf_bundle_srrflags_report_forward,
885 tvb, offset, sdnv_length, srrflags);
886 proto_tree_add_boolean(srr_flag_tree, hf_bundle_srrflags_report_delivery,
887 tvb, offset, sdnv_length, srrflags);
888 proto_tree_add_boolean(srr_flag_tree, hf_bundle_srrflags_report_deletion,
889 tvb, offset, sdnv_length, srrflags);
890 offset += sdnv_length;
892 /* -- hdr_length -- */
893 bundle_header_length = evaluate_sdnv(tvb, offset, &sdnv_length);
894 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_header_len, tvb, offset, sdnv_length, bundle_header_length);
895 if(bundle_header_length < 0) {
896 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Bundle Header Length Error");
897 return 0;
900 offset += sdnv_length;
903 * Pick up offsets into dictionary (8 of them). Do rough sanity check that SDNV
904 * hasn't told us to access way past the Primary Header.
907 /* Ensure all fields have been initialized */
908 memset(&dict_data, 0, sizeof(dict_data));
910 /* -- dest_scheme -- */
911 dict_data.dest_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
912 dict_data.dst_scheme_pos = offset;
913 dict_data.dst_scheme_len = sdnv_length;
915 ti = proto_tree_add_int(primary_tree, hf_bundle_dest_scheme_offset_i32, tvb, offset, sdnv_length, dict_data.dest_scheme_offset);
916 if((dict_data.dest_scheme_offset < 0) || (dict_data.dest_scheme_offset > bundle_header_length)) {
917 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Destination Scheme Offset Error");
919 offset += sdnv_length;
921 /* -- dest_ssp -- */
922 dict_data.dest_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
923 dict_data.dst_ssp_len = sdnv_length;
925 ti = proto_tree_add_int(primary_tree, hf_bundle_dest_ssp_offset_i32, tvb, offset, sdnv_length, dict_data.dest_ssp_offset);
926 if((dict_data.dest_ssp_offset < 0) || (dict_data.dest_ssp_offset > bundle_header_length)) {
927 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Destination SSP Offset Error");
929 offset += sdnv_length;
931 /* -- source_scheme -- */
932 dict_data.source_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
933 dict_data.src_scheme_pos = offset;
934 dict_data.src_scheme_len = sdnv_length;
936 ti = proto_tree_add_int(primary_tree, hf_bundle_source_scheme_offset_i32, tvb, offset, sdnv_length, dict_data.source_scheme_offset);
937 if((dict_data.source_scheme_offset < 0) || (dict_data.source_scheme_offset > bundle_header_length)) {
938 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Source Scheme Offset Error");
940 offset += sdnv_length;
942 /* -- source_ssp -- */
943 dict_data.source_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
944 dict_data.src_ssp_len = sdnv_length;
946 ti = proto_tree_add_int(primary_tree, hf_bundle_source_ssp_offset_i32, tvb, offset, sdnv_length, dict_data.source_ssp_offset);
947 if((dict_data.source_ssp_offset < 0) || (dict_data.source_ssp_offset > bundle_header_length)) {
948 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Source SSP Offset Error");
950 offset += sdnv_length;
952 /* -- report_scheme -- */
953 dict_data.report_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
954 dict_data.rpt_scheme_pos = offset;
955 dict_data.rpt_scheme_len = sdnv_length;
957 ti = proto_tree_add_int(primary_tree, hf_bundle_report_scheme_offset_i32, tvb, offset, sdnv_length, dict_data.report_scheme_offset);
958 if((dict_data.report_scheme_offset < 0) || (dict_data.report_scheme_offset > bundle_header_length)) {
959 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Report Scheme Offset Error");
961 offset += sdnv_length;
963 /* -- report_ssp -- */
964 dict_data.report_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
965 dict_data.rpt_ssp_len = sdnv_length;
967 ti = proto_tree_add_int(primary_tree, hf_bundle_report_ssp_offset_i32, tvb, offset, sdnv_length, dict_data.report_ssp_offset);
968 if((dict_data.report_ssp_offset < 0) || (dict_data.report_ssp_offset > bundle_header_length)) {
969 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Report SSP Offset Error");
971 offset += sdnv_length;
974 /* -- cust_scheme -- */
975 dict_data.cust_scheme_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
976 dict_data.cust_scheme_pos = offset;
977 dict_data.cust_scheme_len = sdnv_length;
979 ti = proto_tree_add_int(primary_tree, hf_bundle_cust_scheme_offset_i32, tvb, offset, sdnv_length, dict_data.cust_scheme_offset);
980 if((dict_data.cust_scheme_offset < 0) || (dict_data.cust_scheme_offset > bundle_header_length)) {
981 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Custodian Scheme Offset Error");
983 offset += sdnv_length;
985 /* -- cust_ssp -- */
986 dict_data.cust_ssp_offset = evaluate_sdnv(tvb, offset, &sdnv_length);
987 dict_data.cust_ssp_len = sdnv_length;
989 ti = proto_tree_add_int(primary_tree, hf_bundle_cust_ssp_offset_i32, tvb, offset, sdnv_length, dict_data.cust_ssp_offset);
990 if((dict_data.cust_ssp_offset < 0) || (dict_data.cust_ssp_offset > bundle_header_length)) {
991 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Custodian SSP Offset Error");
993 offset += sdnv_length;
996 sdnv_length = add_sdnv_time_to_tree(primary_tree, tvb, offset, hf_bundle_primary_timestamp);
997 if (sdnv_length == 0)
998 return 0;
1000 offset += sdnv_length;
1002 /* -- timestamp_sequence -- */
1003 timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1004 if(timestamp_sequence < 0) {
1005 gint64 ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1007 ti = proto_tree_add_int64(primary_tree, hf_bundle_primary_timestamp_seq_num64,
1008 tvb, offset, sdnv_length, ts_seq);
1009 if(ts_seq < 0) {
1010 expert_add_info(pinfo, ti, &ei_bundle_timestamp_seq_num);
1013 else {
1014 proto_tree_add_int(primary_tree, hf_bundle_primary_timestamp_seq_num32,
1015 tvb, offset, sdnv_length, timestamp_sequence);
1017 offset += sdnv_length;
1019 /* -- lifetime -- */
1020 sdnv_length = add_sdnv_to_tree(primary_tree, tvb, pinfo, offset, hf_bundle_lifetime_sdnv);
1021 offset += sdnv_length;
1023 /* -- dict_length -- */
1024 dict_data.bundle_header_dict_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1025 ti = proto_tree_add_int(primary_tree, hf_bundle_primary_dictionary_len, tvb, offset, sdnv_length, dict_data.bundle_header_dict_length);
1026 if(dict_data.bundle_header_dict_length < 0) {
1027 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "Dictionary Header Length Error");
1028 return 0;
1030 offset += sdnv_length;
1032 offset = dissect_dictionary(pinfo, primary_tree, tvb, offset, &dict_data, *pri_hdr_procflags, bundle_custodian);
1033 return offset;
1037 * offset is where the header starts.
1038 * Return new offset, and set lastheader if failure.
1040 static int
1041 dissect_payload_header(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, guint8 version,
1042 guint8 pri_hdr_procflags, gboolean *lastheader)
1044 proto_item *payload_item, *ti;
1045 proto_tree *payload_tree;
1046 int sdnv_length, payload_length;
1048 payload_item = proto_tree_add_text(tree, tvb, offset, -1, "Payload Header");
1049 payload_tree = proto_item_add_subtree(payload_item, ett_payload_hdr);
1051 proto_tree_add_text(payload_tree, tvb, offset, 1, "Header Type: 1");
1052 ++offset;
1054 /* Add tree for processing flags */
1055 /* This is really a SDNV but there are only 7 bits defined so leave it this way*/
1057 if(version == 4) {
1058 proto_item *proc_flag_item;
1059 proto_tree *proc_flag_tree;
1060 guint8 procflags;
1062 procflags = tvb_get_guint8(tvb, offset);
1063 if(procflags & HEADER_PROCFLAGS_LAST_HEADER) {
1064 *lastheader = TRUE;
1066 else {
1067 *lastheader = FALSE;
1069 proc_flag_item = proto_tree_add_item(payload_tree, hf_bundle_payload_flags, tvb,
1070 offset, 1, ENC_BIG_ENDIAN);
1071 proc_flag_tree = proto_item_add_subtree(proc_flag_item, ett_payload_flags);
1072 proto_tree_add_item(proc_flag_tree, hf_bundle_payload_flags_replicate_hdr,
1073 tvb, offset, 1, ENC_BIG_ENDIAN);
1074 proto_tree_add_item(proc_flag_tree, hf_bundle_payload_flags_xmit_report,
1075 tvb, offset, 1, ENC_BIG_ENDIAN);
1076 proto_tree_add_item(proc_flag_tree, hf_bundle_payload_flags_discard_on_fail,
1077 tvb, offset, 1, ENC_BIG_ENDIAN);
1078 proto_tree_add_item(proc_flag_tree, hf_bundle_payload_flags_last_header,
1079 tvb, offset, 1, ENC_BIG_ENDIAN);
1080 ++offset;
1082 else { /*Bundle Protocol Version 5*/
1083 int control_flags;
1084 proto_item *block_flag_item;
1085 proto_tree *block_flag_tree;
1087 control_flags = evaluate_sdnv(tvb, offset, &sdnv_length);
1088 if(control_flags & BLOCK_CONTROL_LAST_BLOCK) {
1089 *lastheader = TRUE;
1091 else {
1092 *lastheader = FALSE;
1094 block_flag_item = proto_tree_add_item(payload_tree, hf_block_control_flags, tvb,
1095 offset, sdnv_length, ENC_BIG_ENDIAN);
1096 block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1098 proto_tree_add_item(block_flag_tree, hf_block_control_replicate,
1099 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1100 proto_tree_add_item(block_flag_tree, hf_block_control_transmit_status,
1101 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1102 proto_tree_add_item(block_flag_tree, hf_block_control_delete_bundle,
1103 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1104 proto_tree_add_item(block_flag_tree, hf_block_control_last_block,
1105 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1106 proto_tree_add_item(block_flag_tree, hf_block_control_discard_block,
1107 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1108 proto_tree_add_item(block_flag_tree, hf_block_control_not_processed,
1109 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1110 proto_tree_add_item(block_flag_tree, hf_block_control_eid_reference,
1111 tvb, offset, sdnv_length, ENC_BIG_ENDIAN);
1112 offset += sdnv_length;
1115 payload_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1116 ti = proto_tree_add_int(payload_tree, hf_bundle_payload_length, tvb, offset, sdnv_length, payload_length);
1117 if(payload_length < 0) {
1118 expert_add_info(pinfo, ti, &ei_bundle_payload_length);
1119 /* Force quiting */
1120 *lastheader = TRUE;
1121 return offset;
1124 proto_item_set_len(payload_item, 2 + sdnv_length);
1126 offset += sdnv_length;
1127 if(pri_hdr_procflags & BUNDLE_PROCFLAGS_ADMIN_MASK) {
1128 gboolean success = FALSE;
1131 * XXXX - Have not allowed for admin record spanning multiple segments!
1134 offset = dissect_admin_record(payload_tree, tvb, pinfo, offset, payload_length, &success);
1135 if (!success) {
1136 /* Force quiting */
1137 *lastheader = TRUE;
1138 return offset;
1142 return payload_length + offset;
1146 * Return the offset after the Administrative Record or set success = FALSE if analysis fails.
1148 static int
1149 dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, packet_info *pinfo,
1150 int offset, int payload_length, gboolean* success)
1152 proto_item *admin_record_item, *ti;
1153 proto_tree *admin_record_tree;
1154 proto_item *timestamp_sequence_item;
1155 guint8 record_type;
1156 guint8 status;
1157 int start_offset = offset;
1158 int sdnv_length;
1159 int timestamp_sequence;
1160 int endpoint_length;
1162 *success = FALSE;
1163 admin_record_item = proto_tree_add_text(primary_tree, tvb, offset, -1, "Administrative Record");
1164 admin_record_tree = proto_item_add_subtree(admin_record_item, ett_admin_record);
1165 record_type = tvb_get_guint8(tvb, offset);
1167 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_type, tvb, offset, 1, ENC_NA);
1169 switch((record_type >> 4) & 0xf)
1171 case ADMIN_REC_TYPE_STATUS_REPORT:
1173 proto_item *status_flag_item;
1174 proto_tree *status_flag_tree;
1176 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1177 ++offset;
1179 /* Decode Bundle Status Report Flags */
1180 status = tvb_get_guint8(tvb, offset);
1181 status_flag_item = proto_tree_add_item(admin_record_tree,
1182 hf_bundle_admin_statflags, tvb, offset, 1, ENC_BIG_ENDIAN);
1183 status_flag_tree = proto_item_add_subtree(status_flag_item,
1184 ett_admin_rec_status);
1185 proto_tree_add_item(status_flag_tree, hf_bundle_admin_rcvd,
1186 tvb, offset, 1, ENC_BIG_ENDIAN);
1187 proto_tree_add_item(status_flag_tree, hf_bundle_admin_accepted,
1188 tvb, offset, 1, ENC_BIG_ENDIAN);
1189 proto_tree_add_item(status_flag_tree, hf_bundle_admin_forwarded,
1190 tvb, offset, 1, ENC_BIG_ENDIAN);
1191 proto_tree_add_item(status_flag_tree, hf_bundle_admin_delivered,
1192 tvb, offset, 1, ENC_BIG_ENDIAN);
1193 proto_tree_add_item(status_flag_tree, hf_bundle_admin_deleted,
1194 tvb, offset, 1, ENC_BIG_ENDIAN);
1195 proto_tree_add_item(status_flag_tree, hf_bundle_admin_acked,
1196 tvb, offset, 1, ENC_BIG_ENDIAN);
1197 ++offset;
1199 proto_tree_add_item(admin_record_tree, hf_bundle_status_report_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1200 ++offset;
1202 if(record_type & ADMIN_REC_FLAGS_FRAGMENT) {
1203 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_offset);
1204 if(sdnv_length <= 0) {
1205 return offset;
1207 offset += sdnv_length;
1208 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_length);
1209 if(sdnv_length <= 0) {
1210 return offset;
1212 offset += sdnv_length;
1214 if(status & ADMIN_STATUS_FLAGS_RECEIVED) {
1215 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_receipt_time);
1216 if(sdnv_length <= 0) {
1217 return offset;
1219 offset += sdnv_length;
1221 if(status & ADMIN_STATUS_FLAGS_ACCEPTED) {
1222 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_accept_time);
1223 if(sdnv_length <= 0) {
1224 return offset;
1226 offset += sdnv_length;
1228 if(status & ADMIN_STATUS_FLAGS_FORWARDED) {
1229 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_forward_time);
1230 if(sdnv_length <= 0) {
1231 return offset;
1233 offset += sdnv_length;
1235 if(status & ADMIN_STATUS_FLAGS_DELIVERED) {
1236 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_delivery_time);
1237 if(sdnv_length <= 0) {
1238 return offset;
1240 offset += sdnv_length;
1242 if(status & ADMIN_STATUS_FLAGS_DELETED) {
1243 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_delete_time);
1244 if(sdnv_length <= 0) {
1245 return offset;
1247 offset += sdnv_length;
1249 if(status & ADMIN_STATUS_FLAGS_ACKNOWLEDGED) {
1250 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_ack_time);
1251 if(sdnv_length <= 0) {
1252 return offset;
1254 offset += sdnv_length;
1257 /* Get 2 SDNVs for Creation Timestamp */
1258 sdnv_length = add_sdnv_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_timestamp_copy);
1259 if(sdnv_length <= 0) {
1260 return offset;
1262 offset += sdnv_length;
1264 timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1265 if(timestamp_sequence < 0) {
1266 gint64 ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1268 timestamp_sequence_item = proto_tree_add_int64(admin_record_tree, hf_bundle_admin_timestamp_seq_num64,
1269 tvb, offset, sdnv_length, ts_seq);
1270 if(ts_seq < 0) {
1271 expert_add_info(pinfo, timestamp_sequence_item, &ei_bundle_timestamp_seq_num);
1272 return offset;
1275 else {
1276 proto_tree_add_int(admin_record_tree, hf_bundle_admin_timestamp_seq_num32,
1277 tvb, offset, sdnv_length, timestamp_sequence);
1279 offset += sdnv_length;
1281 endpoint_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1282 if(endpoint_length < 0) {
1283 return offset;
1285 proto_tree_add_int(admin_record_tree, hf_bundle_admin_endpoint_length, tvb, offset, sdnv_length, endpoint_length);
1286 offset += sdnv_length;
1289 * Endpoint name may not be null terminated. This routine is supposed
1290 * to add the null at the end of the string buffer.
1292 proto_tree_add_item(admin_record_tree, hf_bundle_admin_endpoint_id, tvb, offset, endpoint_length, ENC_NA|ENC_ASCII);
1293 offset += endpoint_length;
1295 break;
1296 } /* case ADMIN_REC_TYPE_STATUS_REPORT */
1297 case ADMIN_REC_TYPE_CUSTODY_SIGNAL:
1299 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1300 ++offset;
1302 proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
1303 proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
1304 ++offset;
1306 if(record_type & ADMIN_REC_FLAGS_FRAGMENT) {
1307 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_offset);
1308 if(sdnv_length <= 0) {
1309 return offset;
1311 offset += sdnv_length;
1312 sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, pinfo, offset, hf_bundle_admin_fragment_length);
1313 if(sdnv_length <= 0) {
1314 return offset;
1316 offset += sdnv_length;
1319 /* Signal Time */
1320 sdnv_length = add_dtn_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_signal_time);
1321 if(sdnv_length <= 0) {
1322 return offset;
1324 offset += sdnv_length;
1326 /* Timestamp copy */
1327 sdnv_length = add_sdnv_time_to_tree(admin_record_tree, tvb, offset, hf_bundle_admin_timestamp_copy);
1328 if(sdnv_length <= 0) {
1329 return offset;
1331 offset += sdnv_length;
1333 timestamp_sequence = evaluate_sdnv(tvb, offset, &sdnv_length);
1334 if(timestamp_sequence < 0) {
1335 gint64 ts_seq = evaluate_sdnv_64(tvb, offset, &sdnv_length);
1337 timestamp_sequence_item = proto_tree_add_int64(admin_record_tree, hf_bundle_admin_timestamp_seq_num64,
1338 tvb, offset, sdnv_length, ts_seq);
1339 if(ts_seq < 0) {
1340 expert_add_info(pinfo, timestamp_sequence_item, &ei_bundle_timestamp_seq_num);
1341 return offset;
1344 else {
1345 proto_tree_add_int(admin_record_tree, hf_bundle_admin_timestamp_seq_num32,
1346 tvb, offset, sdnv_length, timestamp_sequence);
1348 offset += sdnv_length;
1350 endpoint_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1351 if(endpoint_length < 0) {
1352 return 0;
1354 proto_tree_add_int(admin_record_tree, hf_bundle_admin_endpoint_length, tvb, offset, sdnv_length, endpoint_length);
1355 offset += sdnv_length;
1356 proto_tree_add_item(admin_record_tree, hf_bundle_admin_endpoint_id, tvb, offset, endpoint_length, ENC_NA|ENC_ASCII);
1357 offset += endpoint_length;
1358 break;
1359 } /* case ADMIN_REC_TYPE_CUSTODY_SIGNAL */
1360 case ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL:
1362 int payload_bytes_processed = 0;
1363 int right_edge = -1;
1364 int fill_start = -1;
1365 int fill_gap = -1;
1366 int fill_length = -1;
1367 int sdnv_length_start = -1;
1368 int sdnv_length_gap = -1;
1369 int sdnv_length_length = -1;
1371 proto_tree_add_item(admin_record_tree, hf_bundle_admin_record_fragment, tvb, offset, 1, ENC_NA);
1372 ++offset;
1373 ++payload_bytes_processed;
1375 proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
1376 proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
1377 ++offset;
1378 ++payload_bytes_processed;
1380 /* process the first fill */
1381 fill_start = evaluate_sdnv(tvb, offset, &sdnv_length_start);
1382 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_start, tvb, offset, sdnv_length_start, fill_start);
1383 if (fill_start < 0 || sdnv_length_start < 0) {
1384 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range start SDNV");
1385 return offset;
1387 fill_length = evaluate_sdnv(tvb, offset + sdnv_length_start, &sdnv_length_length);
1388 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_end, tvb, offset,
1389 sdnv_length_start + sdnv_length_length, fill_start + fill_length - 1);
1390 if (fill_length < 0 || sdnv_length_length < 0) {
1391 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range length SDNV");
1392 return offset;
1395 right_edge = fill_start + fill_length;
1396 offset += sdnv_length_start + sdnv_length_length;
1397 payload_bytes_processed += sdnv_length_start + sdnv_length_length;
1399 /* now attempt to consume all the rest of the data in the
1400 * payload as additional fills */
1401 while (payload_bytes_processed < payload_length) {
1402 fill_gap = evaluate_sdnv(tvb, offset, &sdnv_length_gap);
1403 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_start, tvb, offset, sdnv_length_gap, fill_gap);
1404 if (fill_gap < 0 || sdnv_length_gap < 0) {
1405 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range gap SDNV");
1406 return offset;
1408 fill_length = evaluate_sdnv(tvb, offset + sdnv_length_gap, &sdnv_length_length);
1409 ti = proto_tree_add_int(admin_record_tree, hf_bundle_custody_id_range_end, tvb, offset,
1410 sdnv_length_gap + sdnv_length_length, right_edge + fill_gap + fill_length - 1);
1411 if (fill_length < 0 || sdnv_length_length < 0) {
1412 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ACS: Unable to process CTEB Custody ID Range length SDNV");
1413 return offset;
1416 right_edge += fill_gap + fill_length;
1417 offset += sdnv_length_gap + sdnv_length_length;
1418 payload_bytes_processed += sdnv_length_gap + sdnv_length_length;
1421 if (payload_bytes_processed > payload_length) {
1422 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "ACS: CTEB Custody ID Range data extends past payload length");
1423 return offset;
1426 break;
1427 } /* case ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL */
1428 case ADMIN_REC_TYPE_ANNOUNCE_BUNDLE:
1429 default:
1430 offset++;
1431 break;
1432 } /* End Switch */
1434 proto_item_set_len(admin_record_item, offset - start_offset);
1435 *success = TRUE;
1436 return offset;
1439 static int
1440 display_metadata_block(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, gchar *bundle_custodian, gboolean *lastheader)
1442 proto_item *block_item, *ti, *block_flag_replicate_item, *block_flag_eid_reference_item;
1443 proto_tree *block_tree;
1444 int sdnv_length;
1445 int block_length;
1446 guint8 type;
1447 unsigned int control_flags;
1448 proto_tree *block_flag_tree = NULL;
1449 proto_item *block_flag_item = NULL;
1450 int num_eid_ref = 0;
1451 int i = 0;
1453 type = tvb_get_guint8(tvb, offset);
1454 block_item = proto_tree_add_text(tree, tvb, offset, -1, "Metadata Block");
1455 block_tree = proto_item_add_subtree(block_item, ett_metadata_hdr);
1457 proto_tree_add_item(block_tree, hf_bundle_block_type_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1458 ++offset;
1460 control_flags = (unsigned int)evaluate_sdnv(tvb, offset, &sdnv_length);
1461 if(control_flags & BLOCK_CONTROL_LAST_BLOCK) {
1462 *lastheader = TRUE;
1463 } else {
1464 *lastheader = FALSE;
1466 block_flag_item = proto_tree_add_uint(block_tree, hf_block_control_flags_sdnv, tvb,
1467 offset, sdnv_length, control_flags);
1468 block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
1469 block_flag_replicate_item = proto_tree_add_boolean(block_flag_tree, hf_block_control_replicate,
1470 tvb, offset, sdnv_length, control_flags);
1471 proto_tree_add_boolean(block_flag_tree, hf_block_control_transmit_status,
1472 tvb, offset, sdnv_length, control_flags);
1473 proto_tree_add_boolean(block_flag_tree, hf_block_control_delete_bundle,
1474 tvb, offset, sdnv_length, control_flags);
1475 proto_tree_add_boolean(block_flag_tree, hf_block_control_last_block,
1476 tvb, offset, sdnv_length, control_flags);
1477 proto_tree_add_boolean(block_flag_tree, hf_block_control_discard_block,
1478 tvb, offset, sdnv_length, control_flags);
1479 proto_tree_add_boolean(block_flag_tree, hf_block_control_not_processed,
1480 tvb, offset, sdnv_length, control_flags);
1481 block_flag_eid_reference_item = proto_tree_add_boolean(block_flag_tree, hf_block_control_eid_reference,
1482 tvb, offset, sdnv_length, control_flags);
1483 offset += sdnv_length;
1485 /* TODO: if this block has EID references, add them to display tree */
1486 if (control_flags & BLOCK_CONTROL_EID_REFERENCE) {
1487 num_eid_ref = evaluate_sdnv(tvb, offset, &sdnv_length);
1488 offset += sdnv_length;
1490 for (i = 0; i < num_eid_ref; i++)
1492 evaluate_sdnv(tvb, offset, &sdnv_length);
1493 offset += sdnv_length;
1495 evaluate_sdnv(tvb, offset, &sdnv_length);
1496 offset += sdnv_length;
1500 block_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1501 ti = proto_tree_add_int(block_tree, hf_block_control_block_length, tvb, offset, sdnv_length, block_length);
1502 if(block_length < 0) {
1503 expert_add_info_format(pinfo, ti, &ei_bundle_offset_error, "Metadata Block Length Error");
1504 /* Force quitting */
1505 *lastheader = TRUE;
1506 return offset;
1508 offset += sdnv_length;
1509 /* now we have enough info to know total length of metadata block */
1510 proto_item_set_len(block_item, offset + block_length);
1512 switch (type)
1514 case BUNDLE_BLOCK_TYPE_AUTHENTICATION:
1515 case BUNDLE_BLOCK_TYPE_INTEGRITY:
1516 case BUNDLE_BLOCK_TYPE_CONFIDENTIALITY:
1517 case BUNDLE_BLOCK_TYPE_PREVIOUS_HOP_INSERT:
1518 case BUNDLE_BLOCK_TYPE_METADATA_EXTENSION:
1519 case BUNDLE_BLOCK_TYPE_EXTENSION_SECURITY:
1521 /* not yet dissected, skip past data */
1522 offset += block_length;
1523 break;
1525 case BUNDLE_BLOCK_TYPE_CUSTODY_TRANSFER:
1527 int custody_id;
1528 const char *cteb_creator_custodian_eid;
1529 int cteb_creator_custodian_eid_length;
1531 /* check requirements for Block Processing Control Flags */
1532 if ((control_flags & BLOCK_CONTROL_REPLICATE) != 0) {
1533 expert_add_info_format(pinfo, block_flag_replicate_item, &ei_bundle_block_control_flags, "ERROR: Replicate must be clear for CTEB");
1535 if ((control_flags & BLOCK_CONTROL_EID_REFERENCE) != 0) {
1536 expert_add_info_format(pinfo, block_flag_eid_reference_item, &ei_bundle_block_control_flags, "ERROR: EID-Reference must be clear for CTEB");
1539 /* there are two elements in a CTEB, first is the custody ID */
1540 custody_id = evaluate_sdnv(tvb, offset, &sdnv_length);
1541 proto_tree_add_int(block_tree, hf_block_control_block_cteb_custody_id, tvb, offset, sdnv_length, custody_id);
1542 offset += sdnv_length;
1544 /* and second is the creator custodian EID */
1545 cteb_creator_custodian_eid_length = block_length - sdnv_length;
1546 cteb_creator_custodian_eid = (char *) tvb_get_string(wmem_packet_scope(), tvb, offset, cteb_creator_custodian_eid_length);
1547 ti = proto_tree_add_string(block_tree, hf_block_control_block_cteb_creator_custodian_eid, tvb, offset,
1548 cteb_creator_custodian_eid_length, cteb_creator_custodian_eid);
1550 /* also check if CTEB is valid, i.e. custodians match */
1551 if (bundle_custodian == NULL) {
1552 expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1553 "CTEB Is NOT Valid (Bundle Custodian NULL)");
1555 else if (strlen(cteb_creator_custodian_eid) != strlen(bundle_custodian)) {
1556 expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1557 "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
1558 bundle_custodian, cteb_creator_custodian_eid);
1560 else if (memcmp(cteb_creator_custodian_eid, bundle_custodian, strlen(bundle_custodian)) != 0) {
1561 expert_add_info_format(pinfo, ti, &ei_block_control_block_cteb_invalid,
1562 "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
1563 bundle_custodian, cteb_creator_custodian_eid);
1565 else {
1566 expert_add_info(pinfo, ti, &ei_block_control_block_cteb_valid);
1568 offset += cteb_creator_custodian_eid_length;
1570 break;
1572 case BUNDLE_BLOCK_TYPE_EXTENDED_COS:
1574 proto_item *ecos_flag_item;
1575 proto_tree *ecos_flag_tree;
1576 int flags, flow_label;
1578 /* check requirements for Block Processing Control Flags */
1579 if ((control_flags & BLOCK_CONTROL_REPLICATE) == 0) {
1580 expert_add_info_format(pinfo, block_flag_replicate_item, &ei_bundle_block_control_flags, "ERROR: Replicate must be set for ECOS");
1582 if ((control_flags & BLOCK_CONTROL_EID_REFERENCE) != 0) {
1583 expert_add_info_format(pinfo, block_flag_eid_reference_item, &ei_bundle_block_control_flags, "ERROR: EID-Reference must be clear for ECOS");
1586 /* flags byte */
1587 flags = (int)tvb_get_guint8(tvb, offset);
1588 ecos_flag_item = proto_tree_add_item(block_tree, hf_ecos_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1589 ecos_flag_tree = proto_item_add_subtree(ecos_flag_item, ett_block_flags);
1590 proto_tree_add_boolean(ecos_flag_tree, hf_ecos_flags_critical, tvb, offset, 1, flags);
1591 proto_tree_add_boolean(ecos_flag_tree, hf_ecos_flags_streaming, tvb, offset, 1, flags);
1592 proto_tree_add_boolean(ecos_flag_tree, hf_ecos_flags_ordinal, tvb, offset, 1, flags);
1593 offset += 1;
1595 /* ordinal byte */
1596 proto_tree_add_item(block_tree, hf_ecos_ordinal, tvb, offset, 1, ENC_BIG_ENDIAN);
1597 offset += 1;
1599 /* optional flow label sdnv */
1600 if ((flags & ECOS_FLAGS_ORDINAL) != 0) {
1601 flow_label = evaluate_sdnv(tvb, offset, &sdnv_length);
1602 ti = proto_tree_add_int(block_tree, hf_ecos_flow_label, tvb, offset, sdnv_length, flow_label);
1603 if(flow_label < 0) {
1604 expert_add_info_format(pinfo, ti, &ei_bundle_sdnv_length, "ECOS Flow Label Error");
1605 /* Force quitting */
1606 *lastheader = TRUE;
1607 return offset;
1609 offset += sdnv_length;
1612 break;
1614 default:
1616 /* unknown bundle type, skip past data */
1617 offset += block_length;
1618 break;
1622 return offset;
1625 /*3rd arg is number of bytes in field (returned)*/
1627 evaluate_sdnv(tvbuff_t *tvb, int offset, int *bytecount)
1629 int value = 0;
1630 guint8 curbyte;
1632 *bytecount = 0;
1635 * Get 1st byte and continue to get them while high-order bit is 1
1638 while((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK) {
1639 if(*bytecount >= (int) sizeof(int)) {
1640 *bytecount = 0;
1641 return -1;
1643 value = value << 7;
1644 value |= (curbyte & SDNV_MASK);
1645 ++offset;
1646 ++*bytecount;
1650 * Add in the byte whose high-order bit is 0 (last one)
1653 value = value << 7;
1654 value |= (curbyte & SDNV_MASK);
1655 ++*bytecount;
1656 return value;
1659 /* Special Function to evaluate 64 bit SDNVs */
1660 gint64
1661 evaluate_sdnv_64(tvbuff_t *tvb, int offset, int *bytecount)
1663 gint64 value = 0;
1664 guint8 curbyte;
1666 *bytecount = 0;
1669 * Get 1st byte and continue to get them while high-order bit is 1
1672 while((curbyte = tvb_get_guint8(tvb, offset)) & ~SDNV_MASK) {
1673 if(*bytecount >= (int) sizeof(gint64)) {
1674 *bytecount = 0;
1675 return -1;
1677 value = value << 7;
1678 value |= (curbyte & SDNV_MASK);
1679 ++offset;
1680 ++*bytecount;
1684 * Add in the byte whose high-order bit is 0 (last one)
1687 value = value << 7;
1688 value |= (curbyte & SDNV_MASK);
1689 ++*bytecount;
1690 return value;
1693 static guint
1694 get_dtn_contact_header_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1696 int len, bytecount;
1698 /* get length from sdnv */
1699 len = evaluate_sdnv(tvb, offset+8, &bytecount);
1700 if (len < 0)
1701 return 0;
1703 return len+bytecount+8;
1706 static int
1707 dissect_dtn_contact_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1709 proto_item *ti;
1710 proto_tree *conv_proto_tree, *conv_tree, *conv_flag_tree;
1711 int eid_length, sdnv_length;
1712 int offset = 0;
1714 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCL");
1715 col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
1717 ti = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
1718 conv_proto_tree = proto_item_add_subtree(ti, ett_tcp_conv);
1720 ti = proto_tree_add_text(conv_proto_tree, tvb, offset, -1, "Contact Header");
1721 conv_tree = proto_item_add_subtree(ti, ett_tcp_conv);
1723 proto_tree_add_item(conv_tree, hf_contact_hdr_magic, tvb, offset, 4, ENC_NA|ENC_ASCII);
1724 offset += 4;
1725 proto_tree_add_item(conv_tree, hf_contact_hdr_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1726 offset++;
1728 /* Subtree to expand the bits in the Contact Header Flags */
1729 ti = proto_tree_add_item(conv_tree, hf_contact_hdr_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1730 conv_flag_tree = proto_item_add_subtree(ti, ett_contact_hdr_flags);
1731 proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1732 proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_frag_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
1733 proto_tree_add_item(conv_flag_tree, hf_contact_hdr_flags_nak, tvb, offset, 1, ENC_BIG_ENDIAN);
1734 offset++;
1736 proto_tree_add_item(conv_tree, hf_contact_hdr_keep_alive, tvb, offset, 2, ENC_BIG_ENDIAN);
1737 offset += 2;
1740 * New format Contact header has length field followed by Bundle Header.
1742 eid_length = evaluate_sdnv(tvb, offset, &sdnv_length);
1743 ti = proto_tree_add_int(tree, hf_contact_hdr_local_eid_length, tvb, offset, sdnv_length, eid_length);
1744 if(eid_length < 0) {
1745 expert_add_info(pinfo, ti, &ei_bundle_sdnv_length);
1746 return offset;
1749 proto_tree_add_item(conv_tree, hf_contact_hdr_local_eid, tvb, sdnv_length + offset, eid_length, ENC_NA|ENC_ASCII);
1750 return tvb_length(tvb);
1753 static guint
1754 get_tcpcl_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1756 int len, bytecount;
1757 guint8 conv_hdr = tvb_get_guint8(tvb, offset);
1759 switch(conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
1761 case TCP_CONVERGENCE_DATA_SEGMENT:
1762 case TCP_CONVERGENCE_ACK_SEGMENT:
1763 /* get length from sdnv */
1764 len = evaluate_sdnv(tvb, offset+1, &bytecount);
1765 if (len < 0)
1766 return 0;
1768 return len+bytecount+1;
1770 case TCP_CONVERGENCE_KEEP_ALIVE:
1771 case TCP_CONVERGENCE_REFUSE_BUNDLE:
1772 /* always 1 byte */
1773 return 1;
1774 case TCP_CONVERGENCE_SHUTDOWN:
1775 len = 1;
1777 if(conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
1778 len += 1;
1780 if(conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
1781 len += 2;
1784 return len;
1787 return 0;
1790 static int
1791 dissect_tcpcl_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1793 guint8 conv_hdr;
1794 int offset = 0;
1795 int sdnv_length, segment_length, convergence_hdr_size;
1796 proto_item *ci, *conv_item, *sub_item;
1797 proto_tree *conv_proto_tree, *conv_tree, *sub_tree;
1798 fragment_head *frag_msg;
1799 tvbuff_t *new_tvb;
1800 gboolean more_frags;
1802 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPCL");
1803 col_clear(pinfo->cinfo,COL_INFO); /* Clear out stuff in the info column */
1805 ci = proto_tree_add_item(tree, proto_tcp_conv, tvb, offset, -1, ENC_NA);
1806 conv_proto_tree = proto_item_add_subtree(ci, ett_tcp_conv);
1808 conv_item = proto_tree_add_text(conv_proto_tree, tvb, 0, -1, "TCP Convergence Header");
1809 conv_tree = proto_item_add_subtree(conv_item, ett_tcp_conv_hdr);
1811 conv_hdr = tvb_get_guint8(tvb, offset);
1812 proto_tree_add_item(conv_tree, hf_tcp_convergence_pkt_type, tvb, offset, 1, ENC_NA);
1813 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const((conv_hdr>>4)&0xF, packet_type_vals, "Unknown"));
1815 switch (conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
1817 case TCP_CONVERGENCE_DATA_SEGMENT:
1818 sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_data_procflags, tvb,
1819 offset, 1, ENC_BIG_ENDIAN);
1820 sub_tree = proto_item_add_subtree(sub_item, ett_conv_flags);
1821 proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_start,
1822 tvb, offset, 1, ENC_BIG_ENDIAN);
1823 proto_tree_add_item(sub_tree, hf_tcp_convergence_data_procflags_end,
1824 tvb, offset, 1, ENC_BIG_ENDIAN);
1826 /* Only Start and End flags (bits 0 & 1) are valid in Data Segment */
1827 if((conv_hdr & ~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_DATA_FLAGS)) != 0) {
1828 expert_add_info(pinfo, sub_item, &ei_tcp_convergence_data_flags);
1831 segment_length = evaluate_sdnv(tvb, 1, &sdnv_length);
1832 sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_data_segment_length, tvb, 1, sdnv_length, segment_length);
1833 if(segment_length < 0) {
1834 expert_add_info(pinfo, sub_item, &ei_tcp_convergence_segment_length);
1835 return 1;
1838 convergence_hdr_size = sdnv_length + 1;
1841 * 1/11/2006 - If I got here, I should have a complete convergence layer
1842 * "segment" beginning at frame_offset. However that might not be a
1843 * complete bundle. Or there might be a complete bundle plus one or more
1844 * additional convergence layer headers.
1847 new_tvb = NULL;
1848 sub_tree = NULL;
1849 if((conv_hdr & TCP_CONVERGENCE_DATA_END_FLAG) == TCP_CONVERGENCE_DATA_END_FLAG) {
1850 more_frags = FALSE;
1852 else {
1853 more_frags = TRUE;
1857 * Note: The reassembled bundle will only include the first
1858 * Convergence layer header.
1860 frag_msg = fragment_add_seq_next(&msg_reassembly_table,
1861 tvb, offset + convergence_hdr_size,
1862 pinfo, 0, NULL,
1863 segment_length, more_frags);
1864 if(frag_msg && !more_frags) {
1866 sub_item = proto_tree_add_item(tree, proto_bundle, tvb, offset, -1, ENC_NA);
1867 sub_tree = proto_item_add_subtree(sub_item, ett_bundle);
1869 new_tvb = process_reassembled_data(tvb, offset + convergence_hdr_size,
1870 pinfo, "Reassembled DTN", frag_msg,
1871 &msg_frag_items, NULL, sub_tree);
1874 if(new_tvb) {
1875 int bundle_size = call_dissector(bundle_handle, new_tvb, pinfo, sub_tree);
1877 if(bundle_size == 0) {
1878 /*Couldn't parse bundle, treat as raw data */
1879 call_dissector(data_handle, new_tvb, pinfo, sub_tree);
1880 return tvb_length(tvb);
1883 else {
1886 * If there are 2 segments, the second of which is very short, this
1887 * gets displayed instead of the usual Source EID/Destination EID in
1888 * the Bundle Dissection frame. If these statements are left out entirely,
1889 * nothing is displayed, i.e., there seems to be no way to get the
1890 * Source/Destination in the 2-segment case. I'll leave it in because I
1891 * think it is informative in the multi-segment case although confusing in the
1892 * 2-segment case.
1894 col_set_str(pinfo->cinfo, COL_INFO, "[Reassembled Segment of a Bundle]");
1896 break;
1897 case TCP_CONVERGENCE_ACK_SEGMENT:
1898 segment_length = evaluate_sdnv(tvb, offset+1, &sdnv_length);
1899 sub_item = proto_tree_add_int(conv_tree, hf_tcp_convergence_ack_length, tvb, offset+1, sdnv_length, segment_length);
1900 if(segment_length < 0) {
1901 expert_add_info(pinfo, sub_item, &ei_tcp_convergence_ack_length);
1903 break;
1904 case TCP_CONVERGENCE_KEEP_ALIVE:
1905 /*No valid flags in Keep Alive*/
1906 break;
1908 case TCP_CONVERGENCE_SHUTDOWN:
1909 /* Add tree for Shutdown Flags */
1910 sub_item = proto_tree_add_item(conv_tree, hf_tcp_convergence_shutdown_flags, tvb,
1911 offset, 1, ENC_BIG_ENDIAN);
1912 sub_tree = proto_item_add_subtree(sub_item, ett_shutdown_flags);
1914 proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_reason,
1915 tvb, offset, 1, ENC_BIG_ENDIAN);
1916 proto_tree_add_item(sub_tree, hf_tcp_convergence_shutdown_flags_delay,
1917 tvb, offset, 1, ENC_BIG_ENDIAN);
1919 offset += 1;
1920 if(conv_hdr & TCP_CONVERGENCE_SHUTDOWN_REASON) {
1921 proto_tree_add_item(conv_tree,
1922 hf_tcp_convergence_shutdown_reason, tvb,
1923 offset, 1, ENC_BIG_ENDIAN);
1924 offset += 1;
1926 if(conv_hdr & TCP_CONVERGENCE_SHUTDOWN_DELAY) {
1927 proto_tree_add_item(conv_tree,
1928 hf_tcp_convergence_shutdown_delay, tvb,
1929 offset, 2, ENC_BIG_ENDIAN);
1931 break;
1932 case TCP_CONVERGENCE_REFUSE_BUNDLE:
1933 /*No valid flags*/
1934 break;
1937 return tvb_length(tvb);
1940 static int
1941 dissect_tcpcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1943 guint8 conv_hdr;
1944 int offset, bytecount;
1946 /* Make sure we have a convergence header byte */
1947 if (!tvb_bytes_exist(tvb, 0, 1))
1948 return 0;
1950 conv_hdr = tvb_get_guint8(tvb, 0);
1951 switch(conv_hdr & TCP_CONVERGENCE_TYPE_MASK)
1953 case TCP_CONVERGENCE_DATA_SEGMENT:
1954 case TCP_CONVERGENCE_ACK_SEGMENT:
1955 /* ensure sdnv */
1956 offset = 1;
1957 bytecount = 1;
1959 if (!tvb_bytes_exist(tvb, offset, 1))
1960 return 0;
1962 while(tvb_get_guint8(tvb, offset) & ~SDNV_MASK) {
1963 if (bytecount > (int)sizeof(int)) {
1964 /* invalid length field */
1965 return 0;
1968 if (!tvb_bytes_exist(tvb, offset, 1))
1969 return 0;
1971 bytecount++;
1972 offset++;
1974 break;
1975 case TCP_CONVERGENCE_KEEP_ALIVE:
1976 case TCP_CONVERGENCE_REFUSE_BUNDLE:
1977 /* always 1 byte */
1978 break;
1979 case TCP_CONVERGENCE_SHUTDOWN:
1980 if((conv_hdr &
1981 ~(TCP_CONVERGENCE_TYPE_MASK | TCP_CONVERGENCE_SHUTDOWN_FLAGS)) != 0) {
1982 /* Not for us */
1983 return 0;
1985 break;
1986 default:
1987 if (conv_hdr == (guint8)magic[0]) {
1988 if (!tvb_bytes_exist(tvb, 0, 4) || tvb_memeql(tvb, 0, magic, 4)) {
1989 /* Not for us */
1990 return 0;
1993 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 8, get_dtn_contact_header_len, dissect_dtn_contact_header, data);
1994 return tvb_length(tvb);
1997 /* Not for us */
1998 return 0;
2001 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 1, get_tcpcl_pdu_len, dissect_tcpcl_pdu, data);
2002 return tvb_length(tvb);
2005 static int
2006 dissect_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2008 proto_item *ti;
2009 proto_tree *bundle_tree, *primary_tree;
2010 int primary_header_size;
2011 gboolean lastheader = FALSE;
2012 int offset = 0;
2013 guint8 version, pri_hdr_procflags;
2014 /* Custodian from Primary Block, used to validate CTEB */
2015 gchar *bundle_custodian = NULL;
2017 version = tvb_get_guint8(tvb, offset); /* Primary Header Version */
2018 if((version != 4) && (version != 5) && (version != 6)) {
2019 return 0;
2022 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Bundle");
2023 /* Clear out stuff in the info column */
2024 col_clear(pinfo->cinfo,COL_INFO);
2026 ti = proto_tree_add_item(tree, proto_bundle, tvb, offset, -1, ENC_NA);
2027 bundle_tree = proto_item_add_subtree(ti, ett_bundle);
2029 ti = proto_tree_add_text(tree, tvb, offset, -1, "Primary Bundle Header");
2030 primary_tree = proto_item_add_subtree(ti, ett_primary_hdr);
2032 proto_tree_add_item(primary_tree, hf_bundle_pdu_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2033 if (version == 4) {
2034 primary_header_size = dissect_version_4_primary_header(pinfo, primary_tree, tvb,
2035 &pri_hdr_procflags, &bundle_custodian);
2037 else {
2038 primary_header_size = dissect_version_5_and_6_primary_header(pinfo, primary_tree, tvb,
2039 &pri_hdr_procflags, &bundle_custodian);
2042 if(primary_header_size == 0) { /*Couldn't parse primary header*/
2043 col_set_str(pinfo->cinfo, COL_INFO, "Protocol Error");
2044 return(0); /*Give up*/
2047 proto_item_set_len(ti, primary_header_size);
2048 offset = primary_header_size;
2051 * Done with primary header; decode the remaining headers
2054 while(lastheader == FALSE) {
2055 guint8 next_header_type;
2057 next_header_type = tvb_get_guint8(tvb, offset);
2058 if(next_header_type == BUNDLE_BLOCK_TYPE_PAYLOAD) {
2061 * Returns payload size or 0 if can't parse payload
2063 offset = dissect_payload_header(bundle_tree, tvb, pinfo, offset, version, pri_hdr_procflags, &lastheader);
2065 else { /*Assume anything else is a Metadata Block*/
2066 offset = display_metadata_block(bundle_tree, tvb, pinfo, offset, bundle_custodian, &lastheader);
2070 return(offset);
2073 static void
2074 bundle_defragment_init(void) {
2075 reassembly_table_init(&msg_reassembly_table,
2076 &addresses_reassembly_table_functions);
2080 void
2081 proto_reg_handoff_bundle(void)
2083 static dissector_handle_t tcpcl_handle;
2084 static guint tcp_port;
2085 static guint udp_port;
2087 static int Initialized = FALSE;
2089 if (!Initialized) {
2090 tcpcl_handle = new_create_dissector_handle(dissect_tcpcl, proto_bundle);
2091 data_handle = find_dissector("data");
2092 Initialized = TRUE;
2094 else {
2095 dissector_delete_uint("tcp.port", tcp_port, tcpcl_handle);
2096 dissector_delete_uint("udp.port", udp_port, bundle_handle);
2098 tcp_port = bundle_tcp_port;
2099 udp_port = bundle_udp_port;
2100 dissector_add_uint("tcp.port", tcp_port, tcpcl_handle);
2101 dissector_add_uint("udp.port", udp_port, bundle_handle);
2104 void
2105 proto_register_bundle(void)
2108 static hf_register_info hf[] = {
2109 {&hf_bundle_pdu_version,
2110 {"Bundle Version", "bundle.version",
2111 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2113 {&hf_msg_fragments,
2114 {"Message Fragments", "bundle.msg.fragments",
2115 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
2117 {&hf_msg_fragment,
2118 {"Message Fragment", "bundle.msg.fragment",
2119 FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
2121 {&hf_msg_fragment_overlap,
2122 {"Message fragment overlap", "bundle.msg.fragment.overlap",
2123 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2125 {&hf_msg_fragment_overlap_conflicts,
2126 {"Message fragment overlapping with conflicting data",
2127 "bundle.msg.fragment.overlap.conflicts",
2128 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2130 {&hf_msg_fragment_multiple_tails,
2131 {"Message has multiple tails", "bundle.msg.fragment.multiple_tails",
2132 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2134 {&hf_msg_fragment_too_long_fragment,
2135 {"Message fragment too long", "bundle.msg.fragment.too_long_fragment",
2136 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL}
2138 {&hf_msg_fragment_error,
2139 {"Message defragmentation error", "bundle.msg.fragment.error",
2140 FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
2142 {&hf_msg_fragment_count,
2143 {"Message fragment count", "bundle.msg.fragment.count",
2144 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2146 {&hf_msg_reassembled_in,
2147 {"Reassembled in", "bundle.msg.reassembled.in",
2148 FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL}
2150 {&hf_msg_reassembled_length,
2151 {"Reassembled DTN length", "bundle.msg.reassembled.length",
2152 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2154 {&hf_bundle_procflags,
2155 {"Primary Header Processing Flags", "bundle.primary.proc.flag",
2156 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2158 {&hf_bundle_procflags_fragment,
2159 {"Bundle is a Fragment", "bundle.primary.proc.frag",
2160 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_FRAG_MASK, NULL, HFILL}
2162 {&hf_bundle_procflags_admin,
2163 {"Administrative Record", "bundle.primary.proc.admin",
2164 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_ADMIN_MASK, NULL, HFILL}
2166 {&hf_bundle_procflags_dont_fragment,
2167 {"Do Not Fragment Bundle", "bundle.primary.proc.dontfrag",
2168 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_DONTFRAG_MASK, NULL, HFILL}
2170 {&hf_bundle_procflags_cust_xfer_req,
2171 {"Request Custody Transfer", "bundle.primary.proc.xferreq",
2172 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_XFERREQ_MASK, NULL, HFILL}
2174 {&hf_bundle_procflags_dest_singleton,
2175 {"Destination is Singleton", "bundle.primary.proc.single",
2176 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_SINGLETON_MASK, NULL, HFILL}
2178 {&hf_bundle_procflags_application_ack,
2179 {"Request Acknowledgement by Application", "bundle.primary.proc.ack",
2180 FT_BOOLEAN, 8, NULL, BUNDLE_PROCFLAGS_APP_ACK_MASK, NULL, HFILL}
2182 {&hf_bundle_control_flags,
2183 {"Bundle Processing Control Flags", "bundle.primary.proc.flag",
2184 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}
2186 {&hf_bundle_procflags_general,
2187 {"General Flags", "bundle.primary.proc.gen",
2188 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2190 {&hf_bundle_procflags_cos,
2191 {"Cloass of Service Flags", "bundle.primary.proc.cos",
2192 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2194 {&hf_bundle_procflags_status,
2195 {"Status Report Flags", "bundle.primary.proc.status",
2196 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2198 {&hf_bundle_cosflags,
2199 {"Primary Header COS Flags", "bundle.primary.cos.flags",
2200 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2202 {&hf_bundle_cosflags_priority,
2203 {"Priority", "bundle.primary.cos.priority",
2204 FT_UINT8, BASE_DEC, VALS(cosflags_priority_vals), BUNDLE_COSFLAGS_PRIORITY_MASK, NULL, HFILL}
2206 {&hf_bundle_srrflags,
2207 {"Primary Header Report Request Flags", "bundle.primary.srr.flag",
2208 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2210 {&hf_bundle_srrflags_report_receipt,
2211 {"Request Reception Report", "bundle.primary.srr.report",
2212 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_REPORT_MASK, NULL, HFILL}
2214 {&hf_bundle_srrflags_report_cust_accept,
2215 {"Request Report of Custody Acceptance", "bundle.primary.srr.custaccept",
2216 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_CUSTODY_MASK, NULL, HFILL}
2218 {&hf_bundle_srrflags_report_forward,
2219 {"Request Report of Bundle Forwarding", "bundle.primary.srr.forward",
2220 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_FORWARD_MASK, NULL, HFILL}
2222 {&hf_bundle_srrflags_report_delivery,
2223 {"Request Report of Bundle Delivery", "bundle.primary.srr.delivery",
2224 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_DELIVERY_MASK, NULL, HFILL}
2226 {&hf_bundle_srrflags_report_deletion,
2227 {"Request Report of Bundle Deletion", "bundle.primary.srr.delete",
2228 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_DELETION_MASK, NULL, HFILL}
2230 {&hf_bundle_srrflags_report_ack,
2231 {"Request Report of Application Ack", "bundle.primary.srr.ack",
2232 FT_BOOLEAN, 8, NULL, BUNDLE_SRRFLAGS_ACK_MASK, NULL, HFILL}
2234 {&hf_bundle_primary_header_len,
2235 {"Bundle Header Length", "bundle.primary.len",
2236 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2238 {&hf_bundle_primary_dictionary_len,
2239 {"Dictionary Length", "bundle.primary.dictionary_len",
2240 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2242 {&hf_bundle_primary_fragment_offset,
2243 {"Fragment Offset", "bundle.primary.fragment_offset",
2244 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2246 {&hf_bundle_primary_total_adu_len,
2247 {"Total Application Data Unit Length", "bundle.primary.total_adu_len",
2248 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2250 {&hf_bundle_primary_timestamp_seq_num64,
2251 {"Timestamp Sequence Number", "bundle.primary.timestamp_seq_num",
2252 FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
2254 {&hf_bundle_primary_timestamp_seq_num32,
2255 {"Timestamp Sequence Number", "bundle.primary.timestamp_seq_num",
2256 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2258 {&hf_bundle_primary_timestamp,
2259 {"Timestamp", "bundle.primary.timestamp",
2260 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2262 {&hf_bundle_dest_scheme_offset_u16,
2263 {"Destination Scheme Offset", "bundle.primary.destschemeoff",
2264 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2266 {&hf_bundle_dest_scheme_offset_i32,
2267 {"Destination Scheme Offset", "bundle.primary.destschemeoff",
2268 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2270 {&hf_bundle_dest_ssp_offset_u16,
2271 {"Destination SSP Offset", "bundle.primary.destssspoff",
2272 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2274 {&hf_bundle_dest_ssp_offset_i32,
2275 {"Destination SSP Offset", "bundle.primary.destssspoff",
2276 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2278 {&hf_bundle_source_scheme_offset_u16,
2279 {"Source Scheme Offset", "bundle.primary.srcschemeoff",
2280 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2282 {&hf_bundle_source_scheme_offset_i32,
2283 {"Source Scheme Offset", "bundle.primary.srcschemeoff",
2284 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2286 {&hf_bundle_source_ssp_offset_u16,
2287 {"Source SSP Offset", "bundle.primary.srcsspoff",
2288 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2290 {&hf_bundle_source_ssp_offset_i32,
2291 {"Source SSP Offset", "bundle.primary.srcsspoff",
2292 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2294 {&hf_bundle_report_scheme_offset_u16,
2295 {"Report Scheme Offset", "bundle.primary.rptschemeoff",
2296 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2298 {&hf_bundle_report_scheme_offset_i32,
2299 {"Report Scheme Offset", "bundle.primary.rptschemeoff",
2300 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2302 {&hf_bundle_report_ssp_offset_u16,
2303 {"Report SSP Offset", "bundle.primary.rptsspoff",
2304 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2306 {&hf_bundle_report_ssp_offset_i32,
2307 {"Report SSP Offset", "bundle.primary.rptsspoff",
2308 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2310 {&hf_bundle_cust_scheme_offset_u16,
2311 {"Custodian Scheme Offset", "bundle.primary.custschemeoff",
2312 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2314 {&hf_bundle_cust_scheme_offset_i32,
2315 {"Custodian Scheme Offset", "bundle.primary.custschemeoff",
2316 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2318 {&hf_bundle_cust_ssp_offset_u16,
2319 {"Custodian SSP Offset", "bundle.primary.custsspoff",
2320 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2322 {&hf_bundle_cust_ssp_offset_i32,
2323 {"Custodian SSP Offset", "bundle.primary.custsspoff",
2324 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2326 {&hf_bundle_dest_scheme,
2327 {"Destination Scheme", "bundle.primary.destination_scheme",
2328 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2330 {&hf_bundle_dest_ssp,
2331 {"Destination", "bundle.primary.destination",
2332 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2334 {&hf_bundle_source_scheme,
2335 {"Source Scheme", "bundle.primary.source_scheme",
2336 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2338 {&hf_bundle_source_ssp,
2339 {"Source", "bundle.primary.source",
2340 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2342 {&hf_bundle_report_scheme,
2343 {"Report Scheme", "bundle.primary.report_scheme",
2344 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2346 {&hf_bundle_report_ssp,
2347 {"Report", "bundle.primary.report",
2348 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2350 {&hf_bundle_custodian_scheme,
2351 {"Custodian Scheme", "bundle.primary.custodian_scheme",
2352 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2354 {&hf_bundle_custodian_ssp,
2355 {"Custodian", "bundle.primary.custodian",
2356 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL}
2358 {&hf_bundle_creation_timestamp,
2359 {"Creation Timestamp", "bundle.primary.timestamp",
2360 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}
2362 {&hf_bundle_lifetime,
2363 {"Lifetime", "bundle.primary.lifetime",
2364 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2366 {&hf_bundle_lifetime_sdnv,
2367 {"Lifetime", "bundle.primary.lifetime",
2368 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2370 {&hf_bundle_payload_length,
2371 {"Payload Length", "bundle.payload.length",
2372 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2374 {&hf_bundle_payload_flags,
2375 {"Payload Header Processing Flags", "bundle.payload.proc.flag",
2376 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2378 {&hf_bundle_payload_flags_replicate_hdr,
2379 {"Replicate Header in Every Fragment", "bundle.payload.proc.replicate",
2380 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_REPLICATE_MASK, NULL, HFILL}
2382 {&hf_bundle_payload_flags_xmit_report,
2383 {"Report if Can't Process Header", "bundle.payload.proc.report",
2384 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_XMIT_STATUS, NULL, HFILL}
2386 {&hf_bundle_payload_flags_discard_on_fail,
2387 {"Discard if Can't Process Header", "bundle.payload.proc.discard",
2388 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_DISCARD_FAILURE, NULL, HFILL}
2390 {&hf_bundle_payload_flags_last_header,
2391 {"Last Header", "bundle.payload.proc.lastheader",
2392 FT_BOOLEAN, 8, NULL, PAYLOAD_PROCFLAGS_LAST_HEADER, NULL, HFILL}
2394 {&hf_bundle_admin_record_type,
2395 {"Administrative Record Type", "bundle.admin.record_type",
2396 FT_UINT8, BASE_DEC, VALS(admin_record_type_vals), 0xF0, NULL, HFILL}
2398 {&hf_bundle_admin_record_fragment,
2399 {"Administrative Record Type", "bundle.admin.record_type",
2400 FT_BOOLEAN, 8, TFS(&tfs_yes_no), ADMIN_REC_FLAGS_FRAGMENT, NULL, HFILL}
2402 {&hf_bundle_admin_statflags,
2403 {"Administrative Record Status Flags", "bundle.admin.status.flag",
2404 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2406 {&hf_bundle_admin_rcvd,
2407 {"Reporting Node Received Bundle", "bundle.admin.status.rcvd",
2408 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_RECEIVED, NULL, HFILL}
2410 {&hf_bundle_admin_accepted,
2411 {"Reporting Node Accepted Custody", "bundle.admin.status.accept",
2412 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_ACCEPTED, NULL, HFILL}
2414 {&hf_bundle_admin_forwarded,
2415 {"Reporting Node Forwarded Bundle", "bundle.admin.status.forward",
2416 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_FORWARDED, NULL, HFILL}
2418 {&hf_bundle_admin_delivered,
2419 {"Reporting Node Delivered Bundle", "bundle.admin.status.delivered",
2420 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_DELIVERED, NULL, HFILL}
2422 {&hf_bundle_admin_deleted,
2423 {"Reporting Node Deleted Bundle", "bundle.admin.status.delete",
2424 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_DELETED, NULL, HFILL}
2426 {&hf_bundle_admin_acked,
2427 {"Acknowledged by Application", "bundle.admin.status.ack",
2428 FT_BOOLEAN, 8, NULL, ADMIN_STATUS_FLAGS_ACKNOWLEDGED, NULL, HFILL}
2430 {&hf_bundle_admin_fragment_offset,
2431 {"Fragment Offset", "bundle.admin.fragment_offset",
2432 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2434 {&hf_bundle_admin_fragment_length,
2435 {"Fragment Length", "bundle.admin.fragment_length",
2436 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2438 {&hf_bundle_admin_timestamp_seq_num64,
2439 {"Timestamp Sequence Number", "bundle.admin.timestamp_seq_num",
2440 FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
2442 {&hf_bundle_admin_timestamp_seq_num32,
2443 {"Timestamp Sequence Number", "bundle.admin.timestamp_seq_num",
2444 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2446 {&hf_bundle_admin_endpoint_length,
2447 {"Endpoint Length", "bundle.admin.endpoint_length",
2448 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2450 {&hf_bundle_admin_endpoint_id,
2451 {"Bundle Endpoint ID", "bundle.admin.endpoint_id",
2452 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2454 {&hf_bundle_admin_receipt_time,
2455 {"Bundle Received Time", "bundle.admin.status.receipttime",
2456 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2458 {&hf_bundle_admin_accept_time,
2459 {"Bundle Accepted Time", "bundle.admin.status.accepttime",
2460 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2462 {&hf_bundle_admin_forward_time,
2463 {"Bundle Forwarded Time", "bundle.admin.status.forwardtime",
2464 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2466 {&hf_bundle_admin_delivery_time,
2467 {"Bundle Delivered Time", "bundle.admin.status.deliverytime",
2468 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2470 {&hf_bundle_admin_delete_time,
2471 {"Bundle Deleted Time", "bundle.admin.status.deletetime",
2472 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2474 {&hf_bundle_admin_ack_time,
2475 {"Bundle Acknowledged Time", "bundle.admin.status.acktime",
2476 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2478 {&hf_bundle_admin_timestamp_copy,
2479 {"Bundle Creation Timestamp", "bundle.admin.status.timecopy",
2480 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2482 {&hf_bundle_admin_signal_time,
2483 {"Bundle Signal Time", "bundle.admin.signal.time",
2484 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}
2486 {&hf_block_control_flags,
2487 {"Block Processing Control Flags", "bundle.block.control.flags",
2488 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2490 {&hf_block_control_flags_sdnv,
2491 {"Block Processing Control Flags", "bundle.block.control.flags",
2492 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
2494 {&hf_block_control_block_length,
2495 {"Block Length", "bundle.block.length",
2496 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2498 {&hf_block_control_block_cteb_custody_id,
2499 {"CTEB Custody ID", "bundle.block.cteb_custody_id",
2500 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2502 {&hf_block_control_block_cteb_creator_custodian_eid,
2503 {"CTEB Creator Custodian EID", "bundle.block.cteb_creator_custodian_eid",
2504 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2506 {&hf_block_control_replicate,
2507 {"Replicate Block in Every Fragment", "bundle.block.control.replicate",
2508 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_REPLICATE, NULL, HFILL}
2510 {&hf_block_control_transmit_status,
2511 {"Transmit Status if Block Can't be Processeed", "bundle.block.control.status",
2512 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_TRANSMIT_STATUS, NULL, HFILL}
2514 {&hf_block_control_delete_bundle,
2515 {"Delete Bundle if Block Can't be Processeed", "bundle.block.control.delete",
2516 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_DELETE_BUNDLE, NULL, HFILL}
2518 {&hf_block_control_last_block,
2519 {"Last Block", "bundle.block.control.last",
2520 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_LAST_BLOCK, NULL, HFILL}
2522 {&hf_block_control_discard_block,
2523 {"Discard Block If Can't Process", "bundle.block.control.discard",
2524 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_DISCARD_BLOCK, NULL, HFILL}
2526 {&hf_block_control_not_processed,
2527 {"Block Was Forwarded Without Processing", "bundle.block.control.process",
2528 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_NOT_PROCESSED, NULL, HFILL}
2530 {&hf_block_control_eid_reference,
2531 {"Block Contains an EID-reference Field", "bundle.block.control.eid",
2532 FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_EID_REFERENCE, NULL, HFILL}
2534 {&hf_bundle_status_report_reason_code,
2535 {"Status Report Reason Code", "bundle.status_report_reason_code",
2536 FT_UINT8, BASE_DEC, VALS(status_report_reason_codes), 0x0, NULL, HFILL}
2538 {&hf_bundle_custody_trf_succ_flg,
2539 {"Custody Transfer Succeeded Flag", "bundle.custody_trf_succ_flg",
2540 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}
2542 {&hf_bundle_custody_signal_reason,
2543 {"Custody Signal Reason Code", "bundle.custody_signal_reason_code",
2544 FT_UINT8, BASE_DEC, VALS(custody_signal_reason_codes), ADMIN_REC_CUSTODY_REASON_MASK, NULL, HFILL}
2546 {&hf_bundle_custody_id_range_start,
2547 {"CTEB Custody ID Range Start", "bundle.custody_id_range_start",
2548 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2550 {&hf_bundle_custody_id_range_end,
2551 {"CTEB Custody ID Range End", "bundle.custody_id_range_end",
2552 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2554 {&hf_bundle_block_type_code,
2555 {"Non-Primary Bundle Block Type Code", "bundle.block_type_code",
2556 FT_UINT8, BASE_DEC, VALS(bundle_block_type_codes), 0x0, NULL, HFILL}
2558 {&hf_ecos_flags,
2559 {"ECOS Flags", "bundle.block.ecos.flags",
2560 FT_UINT8, BASE_HEX, VALS(ecos_flags), 0x0, NULL, HFILL}
2562 {&hf_ecos_flags_critical,
2563 {"ECOS Critical Flag", "bundle.block.ecos.flags.critical",
2564 FT_BOOLEAN, 8, NULL, ECOS_FLAGS_CRITICAL, NULL, HFILL}
2566 {&hf_ecos_flags_streaming,
2567 {"ECOS Streaming Flag", "bundle.block.ecos.flags.streaming",
2568 FT_BOOLEAN, 8, NULL, ECOS_FLAGS_STREAMING, NULL, HFILL}
2570 {&hf_ecos_flags_ordinal,
2571 {"ECOS Ordinal Flag", "bundle.block.ecos.flags.ordinal",
2572 FT_BOOLEAN, 8, NULL, ECOS_FLAGS_ORDINAL, NULL, HFILL}
2574 {&hf_ecos_flow_label,
2575 {"ECOS Flow Label", "bundle.block.ecos.flow_label",
2576 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2578 {&hf_ecos_ordinal,
2579 {"ECOS Ordinal", "bundle.block.ecos.ordinal",
2580 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2584 static hf_register_info hf_tcpcl[] = {
2585 {&hf_tcp_convergence_pkt_type,
2586 {"Pkt Type", "tcpcl.pkt_type",
2587 FT_UINT8, BASE_DEC, VALS(packet_type_vals), 0xF0, NULL, HFILL}
2589 {&hf_tcp_convergence_data_procflags,
2590 {"TCP Convergence Data Flags", "tcpcl.data.proc.flag",
2591 FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_DATA_FLAGS, NULL, HFILL}
2593 {&hf_tcp_convergence_data_procflags_start,
2594 {"Segment contains start of bundle", "tcpcl.data.proc.start",
2595 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_START_FLAG, NULL, HFILL}
2597 {&hf_tcp_convergence_data_procflags_end,
2598 {"Segment contains end of Bundle", "tcpcl.data.proc.end",
2599 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_DATA_END_FLAG, NULL, HFILL}
2601 {&hf_tcp_convergence_data_segment_length,
2602 {"Segment Length", "tcpcl.data.length",
2603 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2605 {&hf_tcp_convergence_shutdown_flags,
2606 {"TCP Convergence Shutdown Flags", "tcpcl.shutdown.flags",
2607 FT_UINT8, BASE_HEX, NULL, TCP_CONVERGENCE_SHUTDOWN_FLAGS, NULL, HFILL}
2609 {&hf_tcp_convergence_shutdown_flags_reason,
2610 {"Shutdown includes Reason Code", "tcpcl.shutdown.reason.flag",
2611 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_REASON, NULL, HFILL}
2613 {&hf_tcp_convergence_shutdown_flags_delay,
2614 {"Shutdown includes Reconnection Delay", "tcpcl.shutdown.delay.flag",
2615 FT_BOOLEAN, 8, NULL, TCP_CONVERGENCE_SHUTDOWN_DELAY, NULL, HFILL}
2617 {&hf_tcp_convergence_shutdown_reason,
2618 {"Shutdown Reason Code", "tcpcl.shutdown.reason",
2619 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2621 {&hf_tcp_convergence_shutdown_delay,
2622 {"Shutdown Reconnection Delay", "tcpcl.shutdown.delay",
2623 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2625 {&hf_tcp_convergence_ack_length,
2626 {"Ack Length", "tcpcl.ack.length",
2627 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2629 {&hf_contact_hdr_version,
2630 {"Version", "tcpcl.contact_hdr.version",
2631 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
2633 {&hf_contact_hdr_flags,
2634 {"Flags", "tcpcl.contact_hdr.flags",
2635 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
2637 {&hf_contact_hdr_flags_ack_req,
2638 {"Bundle Acks Requested", "tcpcl.contact_hdr.flags.ackreq",
2639 FT_BOOLEAN, 8, NULL, TCP_CONV_BUNDLE_ACK_FLAG, NULL, HFILL}
2641 {&hf_contact_hdr_flags_frag_enable,
2642 {"Reactive Fragmentation Enabled", "tcpcl.contact_hdr.flags.fragen",
2643 FT_BOOLEAN, 8, NULL, TCP_CONV_REACTIVE_FRAG_FLAG, NULL, HFILL}
2645 {&hf_contact_hdr_flags_nak,
2646 {"Support Negative Acknowledgements", "tcpcl.contact_hdr.flags.nak",
2647 FT_BOOLEAN, 8, NULL, TCP_CONV_CONNECTOR_RCVR_FLAG, NULL, HFILL}
2649 {&hf_contact_hdr_keep_alive,
2650 {"Keep Alive", "tcpcl.contact_hdr.keep_alive",
2651 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
2653 {&hf_contact_hdr_magic,
2654 {"Magic", "tcpcl.contact_hdr.magic",
2655 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2657 {&hf_contact_hdr_local_eid,
2658 {"Local EID", "tcpcl.contact_hdr.local_eid",
2659 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}
2661 {&hf_contact_hdr_local_eid_length,
2662 {"Local EID Length", "tcpcl.contact_hdr.local_eid_length",
2663 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
2667 static gint *ett[] = {
2668 &ett_bundle,
2669 &ett_bundle_hdr,
2670 &ett_primary_hdr,
2671 &ett_proc_flags,
2672 &ett_gen_flags,
2673 &ett_cos_flags,
2674 &ett_srr_flags,
2675 &ett_dictionary,
2676 &ett_payload_hdr,
2677 &ett_payload_flags,
2678 &ett_block_flags,
2679 &ett_contact_hdr_flags,
2680 &ett_conv_flags,
2681 &ett_shutdown_flags,
2682 &ett_admin_record,
2683 &ett_admin_rec_status,
2684 &ett_metadata_hdr
2687 static gint *ett_tcpcl[] = {
2688 &ett_tcp_conv,
2689 &ett_tcp_conv_hdr,
2690 &ett_msg_fragment,
2691 &ett_msg_fragments,
2694 static ei_register_info ei[] = {
2695 { &ei_bundle_control_flags_length, { "bundle.block.control.flags.length", PI_UNDECODED, PI_WARN, "Wrong bundle control flag length", EXPFILL }},
2696 { &ei_bundle_payload_length, { "bundle.payload.length.invalid", PI_PROTOCOL, PI_ERROR, "Payload length error", EXPFILL }},
2697 { &ei_bundle_sdnv_length, { "bundle.sdnv_length_invalid", PI_PROTOCOL, PI_ERROR, "SDNV length error", EXPFILL }},
2698 { &ei_bundle_timestamp_seq_num, { "bundle.timestamp_seq_num_invalid", PI_PROTOCOL, PI_ERROR, "Timestamp Sequence Number error", EXPFILL }},
2699 { &ei_bundle_offset_error, { "bundle.offset_error", PI_PROTOCOL, PI_WARN, "Offset field error", EXPFILL }},
2700 { &ei_bundle_block_control_flags, { "bundle.block.control.flags.error", PI_PROTOCOL, PI_WARN, "Control flag error", EXPFILL }},
2701 { &ei_block_control_block_cteb_invalid, { "bundle.block.control.cteb_invalid", PI_PROTOCOL, PI_WARN, "CTEB Is Invalid", EXPFILL }},
2702 { &ei_block_control_block_cteb_valid, { "bundle.block.control.cteb_valid", PI_PROTOCOL, PI_NOTE, "CTEB Is Valid", EXPFILL }},
2705 static ei_register_info ei_tcpcl[] = {
2706 { &ei_tcp_convergence_data_flags, { "tcpcl.data.flags.invalid", PI_PROTOCOL, PI_WARN, "Invalid TCP CL Data Segment Flags", EXPFILL }},
2707 { &ei_tcp_convergence_segment_length, { "tcpcl.data.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Data Length", EXPFILL }},
2708 { &ei_tcp_convergence_ack_length, { "tcpcl.ack.length.error", PI_PROTOCOL, PI_WARN, "Ack Length: Error", EXPFILL }},
2711 module_t *bundle_module;
2712 expert_module_t *expert_bundle, *expert_tcpcl;
2714 proto_bundle = proto_register_protocol("Bundle Protocol", "Bundle", "bundle");
2715 bundle_handle = new_register_dissector("bundle", dissect_bundle, proto_bundle);
2716 bundle_module = prefs_register_protocol(proto_bundle, proto_reg_handoff_bundle);
2718 proto_tcp_conv = proto_register_protocol ("DTN TCP Convergence Layer Protocol", "TCPCL", "tcpcl");
2720 prefs_register_uint_preference(bundle_module, "tcp.port",
2721 "Bundle Protocol TCP Port",
2722 "TCP Port to Accept Bundle Protocol Connections",
2724 &bundle_tcp_port);
2726 prefs_register_uint_preference(bundle_module, "udp.port",
2727 "Bundle Protocol UDP Port",
2728 "UDP Port to Accept Bundle Protocol Connections",
2730 &bundle_udp_port);
2732 proto_register_field_array(proto_bundle, hf, array_length(hf));
2733 proto_register_subtree_array(ett, array_length(ett));
2734 expert_bundle = expert_register_protocol(proto_bundle);
2735 expert_register_field_array(expert_bundle, ei, array_length(ei));
2737 proto_register_field_array(proto_tcp_conv, hf_tcpcl, array_length(hf_tcpcl));
2738 proto_register_subtree_array(ett_tcpcl, array_length(ett_tcpcl));
2739 expert_tcpcl = expert_register_protocol(proto_tcp_conv);
2740 expert_register_field_array(expert_tcpcl, ei_tcpcl, array_length(ei_tcpcl));
2742 register_init_routine(bundle_defragment_init);