aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-dtn.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-05-08 14:17:16 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-05-08 14:17:16 +0000
commit572fcbe463a088be79fb8d9539bd0d884a808a3d (patch)
tree62b9d299ebad0216933e132877f3911a968c354d /epan/dissectors/packet-dtn.c
parentbd95016694f92eeb5e0a22bf69c16271e10fed13 (diff)
From Jim Wright:
Add decoding of CTEB to packet-dtn.c https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7234 svn path=/trunk/; revision=42507
Diffstat (limited to 'epan/dissectors/packet-dtn.c')
-rw-r--r--epan/dissectors/packet-dtn.c178
1 files changed, 144 insertions, 34 deletions
diff --git a/epan/dissectors/packet-dtn.c b/epan/dissectors/packet-dtn.c
index 0b61465f41..8a9fc4068a 100644
--- a/epan/dissectors/packet-dtn.c
+++ b/epan/dissectors/packet-dtn.c
@@ -71,6 +71,9 @@ static int proto_bundle = -1;
static int proto_tcp_conv = -1;
static int hf_bundle_pdu_version = -1;
+/* Custodian from Primary Block, used to validate CTEB */
+static gchar *bundle_custodian = NULL;
+
/* TCP Convergence Header Variables */
static int hf_contact_hdr_version = -1;
static int hf_contact_hdr_flags = -1;
@@ -175,6 +178,9 @@ static int hf_block_control_discard_block = -1;
static int hf_block_control_not_processed = -1;
static int hf_block_control_eid_reference = -1;
+/* Non-Primary Block Type Code Variable */
+static int hf_bundle_block_type_code = -1;
+
/* Administrative Record Variables */
static int hf_bundle_admin_statflags = -1;
static int hf_bundle_admin_rcvd = -1;
@@ -222,7 +228,7 @@ static guint bundle_tcp_port = 4556;
static guint bundle_udp_port = 4556;
static const value_string custody_signal_reason_codes[] = {
- {0x0, "No Additional Information"},
+ {0x0, "No Additional Information"},
{0x3, "Redundant Reception"},
{0x4, "Depleted Storage"},
{0x5, "Destination Endpoint ID Unintelligible"},
@@ -233,7 +239,7 @@ static const value_string custody_signal_reason_codes[] = {
};
static const value_string status_report_reason_codes[] = {
- {0x0, "No Additional Information"},
+ {0x0, "No Additional Information"},
{0x1, "Lifetime Expired"},
{0x2, "Forwarded over Unidirectional Link"},
{0x3, "Transmission Cancelled"},
@@ -245,6 +251,19 @@ static const value_string status_report_reason_codes[] = {
{0, NULL}
};
+static const value_string bundle_block_type_codes[] = {
+ {0x01, "Bundle Payload Block"},
+ {0x02, "Bundle Authentication Block"},
+ {0x03, "Payload Integrity Block"},
+ {0x04, "Payload Confidentiality Block"},
+ {0x05, "Previous-Hop Insertion Block"},
+ {0x08, "Metadata Extension Block"},
+ {0x09, "Extension Security Block"},
+ {0x0a, "Custody Transfer Enhancement Block"},
+ {0x13, "Extended Class of Service Block"},
+ {0, NULL}
+};
+
static const fragment_items msg_frag_items = {
/*Fragment subtrees*/
&ett_msg_fragment,
@@ -546,7 +565,7 @@ dissect_udp_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gint payload_size;
next_header_type = tvb_get_guint8(tvb, hdr_offset);
- if(next_header_type == PAYLOAD_HEADER_TYPE) {
+ if(next_header_type == BUNDLE_BLOCK_TYPE_PAYLOAD) {
payload_size =
dissect_payload_header(bundle_tree, tvb, hdr_offset, &lasthdrflag);
}
@@ -633,7 +652,7 @@ dissect_complete_bundle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
int payload_size;
next_header_type = tvb_get_guint8(tvb, offset);
- if(next_header_type == PAYLOAD_HEADER_TYPE) {
+ if(next_header_type == BUNDLE_BLOCK_TYPE_PAYLOAD) {
/*
* Returns payload size or 0 if can't parse payload
@@ -855,7 +874,7 @@ dissect_version_4_primary_header(packet_info *pinfo, proto_tree *primary_tree, t
dict_tree = proto_item_add_subtree(dict_item, ett_dictionary);
/*
- * If the dictionary length is 0, then the CBHE block compression method is applied.
+ * If the dictionary length is 0, then the CBHE block compression method is applied. (RFC6260)
* So the scheme offset is the node number and the ssp offset is the service number.
* If destination scheme offset is 2 and destination ssp offset is 1, then the EID is
* ipn:2.1
@@ -948,6 +967,8 @@ dissect_version_4_primary_header(packet_info *pinfo, proto_tree *primary_tree, t
}
col_add_fstr(pinfo->cinfo, COL_INFO, "%s > %s", src_node,dst_node);
+ /* remember custodian, for use in checking cteb validity */
+ bundle_custodian = ep_strdup_printf("%s:%d.%d", IPN_SCHEME_STR, cust_scheme_offset, cust_ssp_offset);
}
/*
@@ -994,9 +1015,11 @@ dissect_version_4_primary_header(packet_info *pinfo, proto_tree *primary_tree, t
col_add_fstr(pinfo->cinfo, COL_INFO, "%s:%s > %s:%s",
dict_ptr + source_scheme_offset, dict_ptr + source_ssp_offset,
dict_ptr + dest_scheme_offset, dict_ptr + dest_ssp_offset);
-
+ /* remember custodian, for use in checking cteb validity */
+ bundle_custodian = ep_strdup_printf("%s:%s", dict_ptr + cust_scheme_offset, dict_ptr + cust_ssp_offset);
}
offset += bundle_header_dict_length; /*Skip over dictionary*/
+
/*
* Do this only if Fragment Flag is set
*/
@@ -1333,6 +1356,12 @@ dissect_version_5_and_6_primary_header(packet_info *pinfo,
"Dictionary");
dict_tree = proto_item_add_subtree(dict_item, ett_dictionary);
+ /*
+ * If the dictionary length is 0, then the CBHE block compression method is applied. (RFC6260)
+ * So the scheme offset is the node number and the ssp offset is the service number.
+ * If destination scheme offset is 2 and destination ssp offset is 1, then the EID is
+ * ipn:2.1
+ */
if(bundle_header_dict_length == 0)
{
/*
@@ -1428,6 +1457,8 @@ dissect_version_5_and_6_primary_header(packet_info *pinfo,
}
col_add_fstr(pinfo->cinfo, COL_INFO, "%s > %s", src_node, dst_node);
+ /* remember custodian, for use in checking cteb validity */
+ bundle_custodian = ep_strdup_printf("%s:%d.%d", IPN_SCHEME_STR, cust_scheme_offset, cust_ssp_offset);
}
else
{
@@ -1473,6 +1504,8 @@ dissect_version_5_and_6_primary_header(packet_info *pinfo,
col_add_fstr(pinfo->cinfo, COL_INFO, "%s:%s > %s:%s",
dict_ptr + source_scheme_offset, dict_ptr + source_ssp_offset,
dict_ptr + dest_scheme_offset, dict_ptr + dest_ssp_offset);
+ /* remember custodian, for use in checking cteb validity */
+ bundle_custodian = ep_strdup_printf("%s:%s", dict_ptr + cust_scheme_offset, dict_ptr + cust_ssp_offset);
}
offset += bundle_header_dict_length; /*Skip over dictionary*/
@@ -1669,10 +1702,10 @@ dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, int offset, int pa
tvb, offset, 1, status);
++offset;
- proto_tree_add_item(admin_record_tree, hf_bundle_status_report_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(admin_record_tree, hf_bundle_status_report_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
++offset;
- if(record_type & ADMIN_REC_FLAGS_FRAGMENT) {
+ if(record_type & ADMIN_REC_FLAGS_FRAGMENT) {
sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, offset,
"Fragment Offset");
if(sdnv_length <= 0) {
@@ -1795,11 +1828,11 @@ dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, int offset, int pa
}
++offset;
- proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
++offset;
- if(record_type & ADMIN_REC_FLAGS_FRAGMENT) {
+ if(record_type & ADMIN_REC_FLAGS_FRAGMENT) {
sdnv_length = add_sdnv_to_tree(admin_record_tree, tvb, offset,
"Fragment Offset");
if(sdnv_length <= 0) {
@@ -1887,8 +1920,8 @@ dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, int offset, int pa
++offset;
++payload_bytes_processed;
- proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(admin_record_tree, hf_bundle_custody_trf_succ_flg, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(admin_record_tree, hf_bundle_custody_signal_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
++offset;
++payload_bytes_processed;
@@ -1952,7 +1985,6 @@ dissect_admin_record(proto_tree *primary_tree, tvbuff_t *tvb, int offset, int pa
}
return offset - start_offset;
-
} /* case ADMIN_REC_TYPE_AGGREGATE_CUSTODY_SIGNAL */
case ADMIN_REC_TYPE_ANNOUNCE_BUNDLE:
{
@@ -2038,6 +2070,7 @@ display_metadata_block(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean *la
guint8 type;
int control_flags;
proto_tree *block_flag_tree = NULL;
+ proto_item *block_flag_item = NULL;
int num_eid_ref = 0;
int i = 0;
@@ -2047,7 +2080,7 @@ display_metadata_block(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean *la
block_item = proto_tree_add_text(tree, tvb, header_start + offset, -1, "Metadata Block");
block_tree = proto_item_add_subtree(block_item, ett_metadata_hdr);
- proto_tree_add_text(block_tree, tvb, header_start + offset, 1, "Block Type: %d", type);
+ proto_tree_add_item(block_tree, hf_bundle_block_type_code, tvb, header_start + offset, 1, ENC_BIG_ENDIAN);
++offset;
control_flags = evaluate_sdnv(tvb, header_start + offset, &sdnv_length);
@@ -2056,26 +2089,28 @@ display_metadata_block(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean *la
} else {
*lastheader = FALSE;
}
- proto_tree_add_text(block_tree, tvb, header_start + offset, 1, "Block Flags: 0x%x", control_flags);
- offset += sdnv_length;
-
- block_flag_tree = proto_item_add_subtree(block_item, ett_block_flags);
-
+ block_flag_item = proto_tree_add_item(block_tree, hf_block_control_flags, tvb,
+ header_start + offset, sdnv_length, ENC_BIG_ENDIAN);
+ block_flag_tree = proto_item_add_subtree(block_flag_item, ett_block_flags);
proto_tree_add_boolean(block_flag_tree, hf_block_control_replicate,
- tvb, offset, sdnv_length, control_flags);
+ tvb, header_start + offset, sdnv_length, control_flags);
proto_tree_add_boolean(block_flag_tree, hf_block_control_transmit_status,
- tvb, offset, sdnv_length, control_flags);
+ tvb, header_start + offset, sdnv_length, control_flags);
proto_tree_add_boolean(block_flag_tree, hf_block_control_delete_bundle,
- tvb, offset, sdnv_length, control_flags);
+ tvb, header_start + offset, sdnv_length, control_flags);
proto_tree_add_boolean(block_flag_tree, hf_block_control_last_block,
- tvb, offset, sdnv_length, control_flags);
+ tvb, header_start + offset, sdnv_length, control_flags);
proto_tree_add_boolean(block_flag_tree, hf_block_control_discard_block,
- tvb, offset, sdnv_length, control_flags);
+ tvb, header_start + offset, sdnv_length, control_flags);
proto_tree_add_boolean(block_flag_tree, hf_block_control_not_processed,
- tvb, offset, sdnv_length, control_flags);
+ tvb, header_start + offset, sdnv_length, control_flags);
proto_tree_add_boolean(block_flag_tree, hf_block_control_eid_reference,
- tvb, offset, sdnv_length, control_flags);
+ tvb, header_start + offset, sdnv_length, control_flags);
+ offset += sdnv_length;
+ /* TODO: if this block has EID references, add them to display tree */
+ /* TODO: for some blocks, their definition requires that no EID
+ * references exist, this should be checked */
if (control_flags & BLOCK_CONTROL_EID_REFERENCE) {
num_eid_ref = evaluate_sdnv(tvb, header_start + offset, &sdnv_length);
offset += sdnv_length;
@@ -2091,13 +2126,84 @@ display_metadata_block(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean *la
}
block_length = evaluate_sdnv(tvb, header_start + offset, &sdnv_length);
- proto_item_set_len(block_item, offset + sdnv_length + block_length);
if(block_length < 0) {
proto_tree_add_text(block_tree, tvb, header_start + offset, sdnv_length, "Metadata Block Length: Error");
return 0;
}
proto_tree_add_text(block_tree, tvb, header_start + offset, sdnv_length, "Block Length: %d", block_length);
- offset += (sdnv_length + block_length);
+ offset += sdnv_length;
+ /* now we have enough info to know total length of metadata block */
+ proto_item_set_len(block_item, offset + block_length);
+
+ switch (type)
+ {
+ case BUNDLE_BLOCK_TYPE_AUTHENTICATION:
+ case BUNDLE_BLOCK_TYPE_INTEGRITY:
+ case BUNDLE_BLOCK_TYPE_CONFIDENTIALITY:
+ case BUNDLE_BLOCK_TYPE_PREVIOUS_HOP_INSERT:
+ case BUNDLE_BLOCK_TYPE_METADATA_EXTENSION:
+ case BUNDLE_BLOCK_TYPE_EXTENSION_SECURITY:
+ case BUNDLE_BLOCK_TYPE_EXTENDED_CLASS:
+ {
+ /* not yet dissected, skip past data */
+ offset += block_length;
+ break;
+ }
+ case BUNDLE_BLOCK_TYPE_CUSTODY_TRANSFER:
+ {
+ int custody_id = -1;
+ const char *cteb_creator_custodian_eid = NULL;
+ int cteb_creator_custodian_eid_length = -1;
+
+ /* there are two elements in a CTEB, first is the custody ID */
+ custody_id = evaluate_sdnv(tvb, header_start + offset, &sdnv_length);
+ proto_tree_add_text(block_tree, tvb, header_start + offset, sdnv_length, "Custody ID: %d", custody_id);
+ offset += sdnv_length;
+
+ /* and second is the creator custodian EID */
+ cteb_creator_custodian_eid_length = block_length - sdnv_length;
+ cteb_creator_custodian_eid = (char *) tvb_get_ephemeral_string(tvb, header_start + offset, cteb_creator_custodian_eid_length);
+ proto_tree_add_text(block_tree, tvb, header_start + offset, cteb_creator_custodian_eid_length,
+ "CTEB Creator Custodian EID: %s", cteb_creator_custodian_eid);
+ /* also check if CTEB is valid, i.e. custodians match */
+ if (cteb_creator_custodian_eid == NULL) {
+ proto_tree_add_text(block_tree, tvb, header_start + offset,
+ cteb_creator_custodian_eid_length,
+ "CTEB Is NOT Valid (CTEB Custodian NULL)");
+ }
+ else if (bundle_custodian == NULL) {
+ proto_tree_add_text(block_tree, tvb, header_start + offset,
+ cteb_creator_custodian_eid_length,
+ "CTEB Is NOT Valid (Bundle Custodian NULL)");
+ }
+ else if (strlen(cteb_creator_custodian_eid) != strlen(bundle_custodian)) {
+ proto_tree_add_text(block_tree, tvb, header_start + offset,
+ cteb_creator_custodian_eid_length,
+ "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
+ bundle_custodian, cteb_creator_custodian_eid);
+ }
+ else if (memcmp(cteb_creator_custodian_eid, bundle_custodian, strlen(bundle_custodian)) != 0) {
+ proto_tree_add_text(block_tree, tvb, header_start + offset,
+ cteb_creator_custodian_eid_length,
+ "CTEB Is NOT Valid (Bundle Custodian [%s] != CTEB Custodian [%s])",
+ bundle_custodian, cteb_creator_custodian_eid);
+ }
+ else {
+ proto_tree_add_text(block_tree, tvb, header_start + offset,
+ cteb_creator_custodian_eid_length,
+ "CTEB Is Valid");
+ }
+ offset += cteb_creator_custodian_eid_length;
+
+ break;
+ }
+ default:
+ {
+ /* unknown bundle type, skip past data */
+ offset += block_length;
+ break;
+ }
+ }
return offset;
}
@@ -2629,18 +2735,22 @@ proto_register_bundle(void)
{"Block Contains an EID-reference Field", "bundle.block.control.eid",
FT_BOOLEAN, 8, NULL, BLOCK_CONTROL_EID_REFERENCE, NULL, HFILL}
},
- {&hf_bundle_status_report_reason_code,
- {"Reason Code", "bundle.status_report_reason_code",
+ {&hf_bundle_status_report_reason_code,
+ {"Status Report Reason Code", "bundle.status_report_reason_code",
FT_UINT8, BASE_DEC, VALS(status_report_reason_codes), 0x0, NULL, HFILL}
},
- {&hf_bundle_custody_trf_succ_flg,
+ {&hf_bundle_custody_trf_succ_flg,
{"Custody Transfer Succeeded Flag", "bundle.custody_trf_succ_flg",
FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}
},
- {&hf_bundle_custody_signal_reason,
- {"Reason Code", "bundle.status_report_reason_code",
+ {&hf_bundle_custody_signal_reason,
+ {"Custody Signal Reason Code", "bundle.custody_signal_reason_code",
FT_UINT8, BASE_DEC, VALS(custody_signal_reason_codes), ADMIN_REC_CUSTODY_REASON_MASK, NULL, HFILL}
},
+ {&hf_bundle_block_type_code,
+ {"Non-Primary Bundle Block Type Code", "bundle.block_type_code",
+ FT_UINT8, BASE_DEC, VALS(bundle_block_type_codes), 0x0, NULL, HFILL}
+ },
};
static gint *ett[] = {