aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGraeme Lunt <graeme.lunt@smhs.co.uk>2007-06-24 05:28:27 +0000
committerGraeme Lunt <graeme.lunt@smhs.co.uk>2007-06-24 05:28:27 +0000
commit21209f9b5b09ad035e59cfae9105948299a977d9 (patch)
treed87e24b882f7314ea4c943717d924e0a9758d4c5
parent124ef666854fdbe1257088dcb175383a087909d9 (diff)
This patch adds RTSE reassembly. The reassembly is done when
receiving a SES MAJOR SYNC POINT, as this indicates the end of the COTP DT Data stream. Previous the RTSE dissector was called when receiving a COTP DT Data fragment with the "last data unit" bit set, but this does not work with messages fragmented in RTSE. Reassembly can be turned off in the preferences. svn path=/trunk/; revision=22176
-rw-r--r--AUTHORS7
-rw-r--r--asn1/pres/packet-pres-template.c21
-rw-r--r--asn1/rtse/packet-rtse-template.c163
-rw-r--r--epan/dissectors/packet-pres.c27
-rw-r--r--epan/dissectors/packet-rtse.c175
-rw-r--r--epan/dissectors/packet-ses.c28
-rw-r--r--epan/dissectors/packet-ses.h1
7 files changed, 380 insertions, 42 deletions
diff --git a/AUTHORS b/AUTHORS
index 05a7a9846d..2f07c8824a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2453,9 +2453,10 @@ Menno Andriesse <s5066 [AT] nc3a.nato.int> {
}
Stig Bjørlykke <stig [AT] bjorlykke.org> {
- P_Mul (ACP142) packet disassembly
- CDT (CompressedDataType) support
- DMP (STANAG 4406 Direct Message Profile) support
+ P_Mul (ACP142) packet disassembly
+ CDT (CompressedDataType) support
+ DMP (STANAG 4406 Direct Message Profile) support
+ COTP and RTSE reassembly improvements
}
Kyle J. Harms <kyle.j.harms [AT] boeing.com> {
diff --git a/asn1/pres/packet-pres-template.c b/asn1/pres/packet-pres-template.c
index aede2abbba..ec5fd270ec 100644
--- a/asn1/pres/packet-pres-template.c
+++ b/asn1/pres/packet-pres-template.c
@@ -232,9 +232,12 @@ dissect_pres(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
/* first, try to check length */
/* do we have at least 4 bytes */
if (!tvb_bytes_exist(tvb, 0, 4)){
- proto_tree_add_text(parent_tree, tvb, offset,
- tvb_reported_length_remaining(tvb,offset),"User data");
- return; /* no, it isn't a presentation PDU */
+ session = ((struct SESSION_DATA_STRUCTURE*)(pinfo->private_data));
+ if (session && session->spdu_type != SES_MAJOR_SYNC_POINT) {
+ proto_tree_add_text(parent_tree, tvb, offset,
+ tvb_reported_length_remaining(tvb,offset),"User data");
+ return; /* no, it isn't a presentation PDU */
+ }
}
/* we can't make any additional checking here */
@@ -248,6 +251,18 @@ dissect_pres(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
global_tree = parent_tree;
global_pinfo = pinfo;
+ if (session && session->spdu_type == SES_MAJOR_SYNC_POINT) {
+ /* This is a reassembly initiated in packet-ses */
+ char *oid = find_oid_by_pres_ctx_id (pinfo, session->pres_ctx_id);
+ if (oid) {
+ call_ber_oid_callback (oid, tvb, offset, pinfo, parent_tree);
+ } else {
+ proto_tree_add_text(parent_tree, tvb, offset,
+ tvb_reported_length_remaining(tvb,offset),"User data");
+ }
+ return;
+ }
+
while (tvb_reported_length_remaining(tvb, offset) > 0){
old_offset = offset;
offset = dissect_ppdu(tvb, offset, pinfo, parent_tree);
diff --git a/asn1/rtse/packet-rtse-template.c b/asn1/rtse/packet-rtse-template.c
index 202fd082e3..b40ce44605 100644
--- a/asn1/rtse/packet-rtse-template.c
+++ b/asn1/rtse/packet-rtse-template.c
@@ -30,6 +30,8 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/conversation.h>
+#include <epan/prefs.h>
+#include <epan/reassemble.h>
#include <epan/asn1.h>
#include <stdio.h>
@@ -62,6 +64,9 @@ static proto_tree *top_tree=NULL;
static dissector_handle_t rtse_handle = NULL;
static dissector_handle_t ros_handle = NULL;
+/* Preferences */
+static gboolean rtse_reassemble = TRUE;
+
#include "packet-rtse-hf.c"
/* Initialize the subtree pointers */
@@ -73,6 +78,39 @@ static dissector_table_t rtse_oid_dissector_table=NULL;
static GHashTable *oid_table=NULL;
static gint ett_rtse_unknown = -1;
+static GHashTable *rtse_segment_table = NULL;
+static GHashTable *rtse_reassembled_table = NULL;
+
+static int hf_rtse_fragments = -1;
+static int hf_rtse_fragment = -1;
+static int hf_rtse_fragment_overlap = -1;
+static int hf_rtse_fragment_overlap_conflicts = -1;
+static int hf_rtse_fragment_multiple_tails = -1;
+static int hf_rtse_fragment_too_long_fragment = -1;
+static int hf_rtse_fragment_error = -1;
+static int hf_rtse_reassembled_in = -1;
+
+static gint ett_rtse_fragment = -1;
+static gint ett_rtse_fragments = -1;
+
+static const fragment_items rtse_frag_items = {
+ /* Fragment subtrees */
+ &ett_rtse_fragment,
+ &ett_rtse_fragments,
+ /* Fragment fields */
+ &hf_rtse_fragments,
+ &hf_rtse_fragment,
+ &hf_rtse_fragment_overlap,
+ &hf_rtse_fragment_overlap_conflicts,
+ &hf_rtse_fragment_multiple_tails,
+ &hf_rtse_fragment_too_long_fragment,
+ &hf_rtse_fragment_error,
+ /* Reassembled in field */
+ &hf_rtse_reassembled_in,
+ /* Tag */
+ "RTSE fragments"
+};
+
void
register_rtse_oid_dissector_handle(const char *oid, dissector_handle_t dissector, int proto _U_, const char *name, gboolean uses_ros)
{
@@ -134,6 +172,12 @@ dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
int old_offset;
proto_item *item=NULL;
proto_tree *tree=NULL;
+ tvbuff_t *next_tvb = NULL;
+ tvbuff_t *data_tvb = NULL;
+ fragment_data *frag_msg = NULL;
+ guint32 fragment_length;
+ guint32 rtse_id = 0;
+ conversation_t *conversation = NULL;
asn1_ctx_t asn1_ctx;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
@@ -152,28 +196,83 @@ dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
- if(parent_tree){
- item = proto_tree_add_item(parent_tree, proto_rtse, tvb, 0, -1, FALSE);
- tree = proto_item_add_subtree(item, ett_rtse);
- }
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSE");
if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
- while (tvb_reported_length_remaining(tvb, offset) > 0){
- old_offset=offset;
- offset=dissect_rtse_RTSE_apdus(FALSE, tvb, offset, &asn1_ctx , tree, -1);
- if(offset == old_offset){
- proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte RTSE PDU");
- offset = tvb_length(tvb);
- break;
+ if (rtse_reassemble &&
+ ((session->spdu_type == SES_DATA_TRANSFER) ||
+ (session->spdu_type == SES_MAJOR_SYNC_POINT))) {
+ /* Use conversation index as fragment id */
+ conversation = find_conversation (pinfo->fd->num,
+ &pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0);
+ if (conversation != NULL) {
+ rtse_id = conversation->index;
+ }
+ session->rtse_reassemble = TRUE;
+ }
+ if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
+ frag_msg = fragment_end_seq_next (pinfo, rtse_id, rtse_segment_table,
+ rtse_reassembled_table);
+ next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE",
+ frag_msg, &rtse_frag_items, NULL, parent_tree);
+ }
+ if(parent_tree){
+ item = proto_tree_add_item(parent_tree, proto_rtse, tvb, 0, -1, FALSE);
+ tree = proto_item_add_subtree(item, ett_rtse);
+ }
+ if (rtse_reassemble && session->spdu_type == SES_DATA_TRANSFER) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "[RTSE Fragment]");
+
+ /* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */
+ offset = dissect_ber_octet_string(FALSE, &asn1_ctx, NULL, tvb, offset, 0, &data_tvb);
+
+
+ fragment_length = tvb_length_remaining (data_tvb, 0);
+ proto_tree_add_text(tree, data_tvb, 0, (fragment_length) ? -1 : 0,
+ "RTSE segment data (%u byte%s)", fragment_length,
+ plurality(fragment_length, "", "s"));
+ frag_msg = fragment_add_seq_next (data_tvb, 0, pinfo,
+ rtse_id, rtse_segment_table,
+ rtse_reassembled_table, fragment_length, TRUE);
+ if (frag_msg && pinfo->fd->num != frag_msg->reassembled_in) {
+ /* Add a "Reassembled in" link if not reassembled in this frame */
+ proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in),
+ data_tvb, 0, 0, frag_msg->reassembled_in);
+ }
+ pinfo->fragmented = TRUE;
+ } else if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
+ if (next_tvb) {
+ /* ROS won't do this for us */
+ session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT);
+ offset=dissect_rtse_EXTERNALt(FALSE, next_tvb, 0, &asn1_ctx, tree, -1);
+ } else {
+ offset = tvb_length (tvb);
+ }
+ pinfo->fragmented = FALSE;
+ } else {
+ while (tvb_reported_length_remaining(tvb, offset) > 0){
+ old_offset=offset;
+ offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1);
+ if(offset == old_offset){
+ proto_tree_add_text(tree, tvb, offset, -1, "Internal error, zero-byte RTSE PDU");
+ offset = tvb_length(tvb);
+ break;
+ }
}
}
top_tree = NULL;
}
+static void rtse_reassemble_init (void)
+{
+ fragment_table_init (&rtse_segment_table);
+ reassembled_table_init (&rtse_reassembled_table);
+}
/*--- proto_register_rtse -------------------------------------------*/
void proto_register_rtse(void) {
@@ -181,6 +280,35 @@ void proto_register_rtse(void) {
/* List of fields */
static hf_register_info hf[] =
{
+ /* Fragment entries */
+ { &hf_rtse_fragments,
+ { "RTSE fragments", "rtse.fragments", FT_NONE, BASE_NONE,
+ NULL, 0x00, "Message fragments", HFILL } },
+ { &hf_rtse_fragment,
+ { "RTSE fragment", "rtse.fragment", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x00, "Message fragment", HFILL } },
+ { &hf_rtse_fragment_overlap,
+ { "RTSE fragment overlap", "rtse.fragment.overlap", FT_BOOLEAN,
+ BASE_NONE, NULL, 0x00, "Message fragment overlap", HFILL } },
+ { &hf_rtse_fragment_overlap_conflicts,
+ { "RTSE fragment overlapping with conflicting data",
+ "rtse.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, NULL,
+ 0x00, "Message fragment overlapping with conflicting data", HFILL } },
+ { &hf_rtse_fragment_multiple_tails,
+ { "RTSE has multiple tail fragments",
+ "rtse.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x00, "Message has multiple tail fragments", HFILL } },
+ { &hf_rtse_fragment_too_long_fragment,
+ { "RTSE fragment too long", "rtse.fragment.too_long_fragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, "Message fragment too long",
+ HFILL } },
+ { &hf_rtse_fragment_error,
+ { "RTSE defragmentation error", "rtse.fragment.error", FT_FRAMENUM,
+ BASE_NONE, NULL, 0x00, "Message defragmentation error", HFILL } },
+ { &hf_rtse_reassembled_in,
+ { "Reassembled RTSE in frame", "rtse.reassembled.in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x00, "This RTSE packet is reassembled in this frame", HFILL } },
+
#include "packet-rtse-hfarr.c"
};
@@ -188,15 +316,28 @@ void proto_register_rtse(void) {
static gint *ett[] = {
&ett_rtse,
&ett_rtse_unknown,
+ &ett_rtse_fragment,
+ &ett_rtse_fragments,
#include "packet-rtse-ettarr.c"
};
+ module_t *rtse_module;
+
/* Register protocol */
proto_rtse = proto_register_protocol(PNAME, PSNAME, PFNAME);
register_dissector("rtse", dissect_rtse, proto_rtse);
/* Register fields and subtrees */
proto_register_field_array(proto_rtse, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ register_init_routine (&rtse_reassemble_init);
+ rtse_module = prefs_register_protocol_subtree("OSI", proto_rtse, NULL);
+
+ prefs_register_bool_preference(rtse_module, "reassemble",
+ "Reassemble segmented RTSE datagrams",
+ "Whether segmented RTSE datagrams should be reassembled."
+ " To use this option, you must also enable"
+ " \"Allow subdissectors to reassemble TCP streams\""
+ " in the TCP protocol settings.", &rtse_reassemble);
rtse_oid_dissector_table = register_dissector_table("rtse.oid", "RTSE OID Dissectors", FT_STRING, BASE_NONE);
oid_table=g_hash_table_new(g_str_hash, g_str_equal);
diff --git a/epan/dissectors/packet-pres.c b/epan/dissectors/packet-pres.c
index a0f8fc2fb7..5eafbaff27 100644
--- a/epan/dissectors/packet-pres.c
+++ b/epan/dissectors/packet-pres.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* .\packet-pres.c */
+/* ./packet-pres.c */
/* ../../tools/asn2wrs.py -b -e -p pres -c pres.cnf -s packet-pres-template ISO8823-PRESENTATION.asn */
/* Input file: packet-pres-template.c */
@@ -1503,9 +1503,12 @@ dissect_pres(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
/* first, try to check length */
/* do we have at least 4 bytes */
if (!tvb_bytes_exist(tvb, 0, 4)){
- proto_tree_add_text(parent_tree, tvb, offset,
- tvb_reported_length_remaining(tvb,offset),"User data");
- return; /* no, it isn't a presentation PDU */
+ session = ((struct SESSION_DATA_STRUCTURE*)(pinfo->private_data));
+ if (session && session->spdu_type != SES_MAJOR_SYNC_POINT) {
+ proto_tree_add_text(parent_tree, tvb, offset,
+ tvb_reported_length_remaining(tvb,offset),"User data");
+ return; /* no, it isn't a presentation PDU */
+ }
}
/* we can't make any additional checking here */
@@ -1519,6 +1522,18 @@ dissect_pres(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
global_tree = parent_tree;
global_pinfo = pinfo;
+ if (session && session->spdu_type == SES_MAJOR_SYNC_POINT) {
+ /* This is a reassembly initiated in packet-ses */
+ char *oid = find_oid_by_pres_ctx_id (pinfo, session->pres_ctx_id);
+ if (oid) {
+ call_ber_oid_callback (oid, tvb, offset, pinfo, parent_tree);
+ } else {
+ proto_tree_add_text(parent_tree, tvb, offset,
+ tvb_reported_length_remaining(tvb,offset),"User data");
+ }
+ return;
+ }
+
while (tvb_reported_length_remaining(tvb, offset) > 0){
old_offset = offset;
offset = dissect_ppdu(tvb, offset, pinfo, parent_tree);
@@ -1866,7 +1881,7 @@ void proto_register_pres(void) {
"", HFILL }},
/*--- End of included file: packet-pres-hfarr.c ---*/
-#line 290 "packet-pres-template.c"
+#line 305 "packet-pres-template.c"
};
/* List of subtrees */
@@ -1912,7 +1927,7 @@ void proto_register_pres(void) {
&ett_pres_User_session_requirements,
/*--- End of included file: packet-pres-ettarr.c ---*/
-#line 296 "packet-pres-template.c"
+#line 311 "packet-pres-template.c"
};
/* Register protocol */
diff --git a/epan/dissectors/packet-rtse.c b/epan/dissectors/packet-rtse.c
index e25fd9435a..d29b9ca785 100644
--- a/epan/dissectors/packet-rtse.c
+++ b/epan/dissectors/packet-rtse.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* .\packet-rtse.c */
+/* ./packet-rtse.c */
/* ../../tools/asn2wrs.py -b -e -p rtse -c rtse.cnf -s packet-rtse-template rtse.asn */
/* Input file: packet-rtse-template.c */
@@ -38,6 +38,8 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/conversation.h>
+#include <epan/prefs.h>
+#include <epan/reassemble.h>
#include <epan/asn1.h>
#include <stdio.h>
@@ -70,6 +72,9 @@ static proto_tree *top_tree=NULL;
static dissector_handle_t rtse_handle = NULL;
static dissector_handle_t ros_handle = NULL;
+/* Preferences */
+static gboolean rtse_reassemble = TRUE;
+
/*--- Included file: packet-rtse-hf.c ---*/
#line 1 "packet-rtse-hf.c"
@@ -106,7 +111,7 @@ static int hf_rtse_octet_aligned = -1; /* OCTET_STRING */
static int hf_rtse_arbitrary = -1; /* BIT_STRING */
/*--- End of included file: packet-rtse-hf.c ---*/
-#line 66 "packet-rtse-template.c"
+#line 71 "packet-rtse-template.c"
/* Initialize the subtree pointers */
static gint ett_rtse = -1;
@@ -125,13 +130,46 @@ static gint ett_rtse_EXTERNALt = -1;
static gint ett_rtse_T_encoding = -1;
/*--- End of included file: packet-rtse-ett.c ---*/
-#line 70 "packet-rtse-template.c"
+#line 75 "packet-rtse-template.c"
static dissector_table_t rtse_oid_dissector_table=NULL;
static GHashTable *oid_table=NULL;
static gint ett_rtse_unknown = -1;
+static GHashTable *rtse_segment_table = NULL;
+static GHashTable *rtse_reassembled_table = NULL;
+
+static int hf_rtse_fragments = -1;
+static int hf_rtse_fragment = -1;
+static int hf_rtse_fragment_overlap = -1;
+static int hf_rtse_fragment_overlap_conflicts = -1;
+static int hf_rtse_fragment_multiple_tails = -1;
+static int hf_rtse_fragment_too_long_fragment = -1;
+static int hf_rtse_fragment_error = -1;
+static int hf_rtse_reassembled_in = -1;
+
+static gint ett_rtse_fragment = -1;
+static gint ett_rtse_fragments = -1;
+
+static const fragment_items rtse_frag_items = {
+ /* Fragment subtrees */
+ &ett_rtse_fragment,
+ &ett_rtse_fragments,
+ /* Fragment fields */
+ &hf_rtse_fragments,
+ &hf_rtse_fragment,
+ &hf_rtse_fragment_overlap,
+ &hf_rtse_fragment_overlap_conflicts,
+ &hf_rtse_fragment_multiple_tails,
+ &hf_rtse_fragment_too_long_fragment,
+ &hf_rtse_fragment_error,
+ /* Reassembled in field */
+ &hf_rtse_reassembled_in,
+ /* Tag */
+ "RTSE fragments"
+};
+
void
register_rtse_oid_dissector_handle(const char *oid, dissector_handle_t dissector, int proto _U_, const char *name, gboolean uses_ros)
{
@@ -862,7 +900,7 @@ dissect_rtse_EXTERNALt(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset
/*--- End of included file: packet-rtse-fn.c ---*/
-#line 126 "packet-rtse-template.c"
+#line 164 "packet-rtse-template.c"
/*
* Dissect RTSE PDUs inside a PPDU.
@@ -874,6 +912,12 @@ dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
int old_offset;
proto_item *item=NULL;
proto_tree *tree=NULL;
+ tvbuff_t *next_tvb = NULL;
+ tvbuff_t *data_tvb = NULL;
+ fragment_data *frag_msg = NULL;
+ guint32 fragment_length;
+ guint32 rtse_id = 0;
+ conversation_t *conversation = NULL;
asn1_ctx_t asn1_ctx;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
@@ -892,28 +936,83 @@ dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
- if(parent_tree){
- item = proto_tree_add_item(parent_tree, proto_rtse, tvb, 0, -1, FALSE);
- tree = proto_item_add_subtree(item, ett_rtse);
- }
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSE");
if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
- while (tvb_reported_length_remaining(tvb, offset) > 0){
- old_offset=offset;
- offset=dissect_rtse_RTSE_apdus(FALSE, tvb, offset, &asn1_ctx , tree, -1);
- if(offset == old_offset){
- proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte RTSE PDU");
- offset = tvb_length(tvb);
- break;
+ if (rtse_reassemble &&
+ ((session->spdu_type == SES_DATA_TRANSFER) ||
+ (session->spdu_type == SES_MAJOR_SYNC_POINT))) {
+ /* Use conversation index as fragment id */
+ conversation = find_conversation (pinfo->fd->num,
+ &pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0);
+ if (conversation != NULL) {
+ rtse_id = conversation->index;
+ }
+ session->rtse_reassemble = TRUE;
+ }
+ if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
+ frag_msg = fragment_end_seq_next (pinfo, rtse_id, rtse_segment_table,
+ rtse_reassembled_table);
+ next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE",
+ frag_msg, &rtse_frag_items, NULL, parent_tree);
+ }
+ if(parent_tree){
+ item = proto_tree_add_item(parent_tree, proto_rtse, tvb, 0, -1, FALSE);
+ tree = proto_item_add_subtree(item, ett_rtse);
+ }
+ if (rtse_reassemble && session->spdu_type == SES_DATA_TRANSFER) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "[RTSE Fragment]");
+
+ /* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */
+ offset = dissect_ber_octet_string(FALSE, &asn1_ctx, NULL, tvb, offset, 0, &data_tvb);
+
+
+ fragment_length = tvb_length_remaining (data_tvb, 0);
+ proto_tree_add_text(tree, data_tvb, 0, (fragment_length) ? -1 : 0,
+ "RTSE segment data (%u byte%s)", fragment_length,
+ plurality(fragment_length, "", "s"));
+ frag_msg = fragment_add_seq_next (data_tvb, 0, pinfo,
+ rtse_id, rtse_segment_table,
+ rtse_reassembled_table, fragment_length, TRUE);
+ if (frag_msg && pinfo->fd->num != frag_msg->reassembled_in) {
+ /* Add a "Reassembled in" link if not reassembled in this frame */
+ proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in),
+ data_tvb, 0, 0, frag_msg->reassembled_in);
+ }
+ pinfo->fragmented = TRUE;
+ } else if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
+ if (next_tvb) {
+ /* ROS won't do this for us */
+ session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT);
+ offset=dissect_rtse_EXTERNALt(FALSE, next_tvb, 0, &asn1_ctx, tree, -1);
+ } else {
+ offset = tvb_length (tvb);
+ }
+ pinfo->fragmented = FALSE;
+ } else {
+ while (tvb_reported_length_remaining(tvb, offset) > 0){
+ old_offset=offset;
+ offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1);
+ if(offset == old_offset){
+ proto_tree_add_text(tree, tvb, offset, -1, "Internal error, zero-byte RTSE PDU");
+ offset = tvb_length(tvb);
+ break;
+ }
}
}
top_tree = NULL;
}
+static void rtse_reassemble_init (void)
+{
+ fragment_table_init (&rtse_segment_table);
+ reassembled_table_init (&rtse_reassembled_table);
+}
/*--- proto_register_rtse -------------------------------------------*/
void proto_register_rtse(void) {
@@ -921,6 +1020,35 @@ void proto_register_rtse(void) {
/* List of fields */
static hf_register_info hf[] =
{
+ /* Fragment entries */
+ { &hf_rtse_fragments,
+ { "RTSE fragments", "rtse.fragments", FT_NONE, BASE_NONE,
+ NULL, 0x00, "Message fragments", HFILL } },
+ { &hf_rtse_fragment,
+ { "RTSE fragment", "rtse.fragment", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x00, "Message fragment", HFILL } },
+ { &hf_rtse_fragment_overlap,
+ { "RTSE fragment overlap", "rtse.fragment.overlap", FT_BOOLEAN,
+ BASE_NONE, NULL, 0x00, "Message fragment overlap", HFILL } },
+ { &hf_rtse_fragment_overlap_conflicts,
+ { "RTSE fragment overlapping with conflicting data",
+ "rtse.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, NULL,
+ 0x00, "Message fragment overlapping with conflicting data", HFILL } },
+ { &hf_rtse_fragment_multiple_tails,
+ { "RTSE has multiple tail fragments",
+ "rtse.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x00, "Message has multiple tail fragments", HFILL } },
+ { &hf_rtse_fragment_too_long_fragment,
+ { "RTSE fragment too long", "rtse.fragment.too_long_fragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, "Message fragment too long",
+ HFILL } },
+ { &hf_rtse_fragment_error,
+ { "RTSE defragmentation error", "rtse.fragment.error", FT_FRAMENUM,
+ BASE_NONE, NULL, 0x00, "Message defragmentation error", HFILL } },
+ { &hf_rtse_reassembled_in,
+ { "Reassembled RTSE in frame", "rtse.reassembled.in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x00, "This RTSE packet is reassembled in this frame", HFILL } },
+
/*--- Included file: packet-rtse-hfarr.c ---*/
#line 1 "packet-rtse-hfarr.c"
@@ -1050,13 +1178,15 @@ void proto_register_rtse(void) {
"rtse.BIT_STRING", HFILL }},
/*--- End of included file: packet-rtse-hfarr.c ---*/
-#line 185 "packet-rtse-template.c"
+#line 313 "packet-rtse-template.c"
};
/* List of subtrees */
static gint *ett[] = {
&ett_rtse,
&ett_rtse_unknown,
+ &ett_rtse_fragment,
+ &ett_rtse_fragments,
/*--- Included file: packet-rtse-ettarr.c ---*/
#line 1 "packet-rtse-ettarr.c"
@@ -1072,15 +1202,26 @@ void proto_register_rtse(void) {
&ett_rtse_T_encoding,
/*--- End of included file: packet-rtse-ettarr.c ---*/
-#line 192 "packet-rtse-template.c"
+#line 322 "packet-rtse-template.c"
};
+ module_t *rtse_module;
+
/* Register protocol */
proto_rtse = proto_register_protocol(PNAME, PSNAME, PFNAME);
register_dissector("rtse", dissect_rtse, proto_rtse);
/* Register fields and subtrees */
proto_register_field_array(proto_rtse, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ register_init_routine (&rtse_reassemble_init);
+ rtse_module = prefs_register_protocol_subtree("OSI", proto_rtse, NULL);
+
+ prefs_register_bool_preference(rtse_module, "reassemble",
+ "Reassemble segmented RTSE datagrams",
+ "Whether segmented RTSE datagrams should be reassembled."
+ " To use this option, you must also enable"
+ " \"Allow subdissectors to reassemble TCP streams\""
+ " in the TCP protocol settings.", &rtse_reassemble);
rtse_oid_dissector_table = register_dissector_table("rtse.oid", "RTSE OID Dissectors", FT_STRING, BASE_NONE);
oid_table=g_hash_table_new(g_str_hash, g_str_equal);
diff --git a/epan/dissectors/packet-ses.c b/epan/dissectors/packet-ses.c
index d172497e6b..c10cc0beac 100644
--- a/epan/dissectors/packet-ses.c
+++ b/epan/dissectors/packet-ses.c
@@ -41,7 +41,7 @@
#include "packet-frame.h"
#include <epan/prefs.h>
-
+#include <epan/emem.h>
#include <epan/strutil.h>
/* ses header fields */
@@ -268,6 +268,9 @@ static const value_string reason_vals[] =
/* desegmentation of OSI over ses */
/*static gboolean ses_desegment = TRUE;*/
+/* RTSE reassembly data */
+static guint ses_pres_ctx_id = 0;
+static gboolean ses_rtse_reassemble = FALSE;
/* find the dissector for data */
static dissector_handle_t data_handle;
@@ -971,6 +974,7 @@ dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
guint16 parameters_len;
tvbuff_t *next_tvb;
void *save_private_data;
+ guint32 *pres_ctx_id = NULL;
struct SESSION_DATA_STRUCTURE session;
/*
@@ -980,6 +984,7 @@ dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
session.spdu_type = type;
session.abort_type = SESSION_NO_ABORT;
session.ros_op = 0;
+ session.rtse_reassemble = FALSE;
if (tokens) {
if (check_col(pinfo->cinfo, COL_INFO))
@@ -1014,6 +1019,21 @@ dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
case SES_TYPED_DATA:
has_user_information = TRUE;
break;
+ case SES_MAJOR_SYNC_POINT:
+ pres_ctx_id = p_get_proto_data (pinfo->fd, proto_ses);
+ if (ses_rtse_reassemble != 0 && !pres_ctx_id) {
+ /* First time visited - save pres_ctx_id */
+ pres_ctx_id = se_alloc (sizeof (guint32));
+ *pres_ctx_id = ses_pres_ctx_id;
+ p_add_proto_data (pinfo->fd, proto_ses, pres_ctx_id);
+ }
+ if (pres_ctx_id) {
+ session.pres_ctx_id = *pres_ctx_id;
+ session.rtse_reassemble = TRUE;
+ has_user_information = TRUE;
+ }
+ ses_rtse_reassemble = FALSE;
+ break;
}
}
offset++;
@@ -1035,7 +1055,7 @@ dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
/* Dissect user information, if present */
if (has_user_information) {
- if (tvb_reported_length_remaining(tvb, offset) > 0) {
+ if (tvb_reported_length_remaining(tvb, offset) > 0 || type == SES_MAJOR_SYNC_POINT) {
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
/* do we have OSI presentation packet dissector ? */
@@ -1059,6 +1079,10 @@ dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
* end of the tvbuff.
*/
offset = tvb_length(tvb);
+ if (session.rtse_reassemble && type == SES_DATA_TRANSFER) {
+ ses_pres_ctx_id = session.pres_ctx_id;
+ ses_rtse_reassemble = TRUE;
+ }
}
}
return offset;
diff --git a/epan/dissectors/packet-ses.h b/epan/dissectors/packet-ses.h
index 200f61202a..72e2417382 100644
--- a/epan/dissectors/packet-ses.h
+++ b/epan/dissectors/packet-ses.h
@@ -197,6 +197,7 @@ struct SESSION_DATA_STRUCTURE
guint8 abort_type;
guint8 pres_ctx_id;
guint32 ros_op;
+ gboolean rtse_reassemble;
};
#define implementation_restriction 0x10