aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ositp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-02-01 15:19:10 -0800
committerGuy Harris <guy@alum.mit.edu>2016-02-01 23:20:12 +0000
commitb9fb2ceb88b0904e95b2931fbf2efd6222f56285 (patch)
treecc9ed34dea4bb981ce7c997c3e19cfc9de6c8d01 /epan/dissectors/packet-ositp.c
parenta53ab9dfcc87ec817467a2a9c2259b0a70a1dd78 (diff)
Add heuristic dissectors for the variable part of COTP CR and CC PDUs.
Add tables for heuristic dissectors, and add dissectors for the stuff Microsoft puts there for RDP; they're violating the COTP spec, but I guess they're stuck because they're using TP0, which doesn't support user data. While we're at it, add variants of proto_tree_add_bitmask() and proto_tree_add_bitmask_flags() that return the bitmask, for use by callers. A side-effect of the change is that the proto_tree_add_bitmask routines no longer treat the encoding as a Boolean, so we have to pass ENC_LITTLE_ENDIAN or ENC_BIG_ENDIAN, not just some non-zero or zero value. Do so. Rename ositp_decode_CC() to ositp_decode_CR_CC(), to note that it decodes both CR and CC PDUs. Bug: 2626 Change-Id: If5fa2a6dfecd9eb99c1cb8104f2ebceccf1e57c2 Reviewed-on: https://code.wireshark.org/review/13648 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dissectors/packet-ositp.c')
-rw-r--r--epan/dissectors/packet-ositp.c77
1 files changed, 42 insertions, 35 deletions
diff --git a/epan/dissectors/packet-ositp.c b/epan/dissectors/packet-ositp.c
index 47f3851883..72f05db85f 100644
--- a/epan/dissectors/packet-ositp.c
+++ b/epan/dissectors/packet-ositp.c
@@ -146,6 +146,8 @@ static const fragment_items cotp_frag_items = {
"segments"
};
+static dissector_handle_t rdp_cr_handle;
+static dissector_handle_t rdp_cc_handle;
static dissector_handle_t data_handle;
/*
@@ -325,6 +327,10 @@ static int hf_cotp_vp_dst_tsap_bytes = -1;
/* global variables */
+/* List of dissectors to call for the variable part of CR PDUs. */
+static heur_dissector_list_t cotp_cr_heur_subdissector_list;
+/* List of dissectors to call for the variable part of CC PDUs. */
+static heur_dissector_list_t cotp_cc_heur_subdissector_list;
/* List of dissectors to call for COTP packets put atop the Inactive
Subset of CLNP. */
static heur_dissector_list_t cotp_is_heur_subdissector_list;
@@ -1496,10 +1502,10 @@ static int ositp_decode_RJ(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
} /* ositp_decode_RJ */
-static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
- packet_info *pinfo, proto_tree *tree,
- gboolean uses_inactive_subset,
- gboolean *subdissector_found)
+static int ositp_decode_CR_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
+ packet_info *pinfo, proto_tree *tree,
+ gboolean uses_inactive_subset,
+ gboolean *subdissector_found)
{
/* note: in the ATN the user is up to chose between 3 different checksums:
* standard OSI, 2 or 4 octet extended checksum.
@@ -1567,37 +1573,33 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
offset += 1;
li -= 1;
- /* Microsoft runs their Remote Desktop Protocol atop ISO COTP
- atop TPKT, and does some weird stuff in the CR packet:
-
- http://msdn.microsoft.com/en-us/library/cc240470
-
- where they might stuff a string that begins with "Cookie: ",
- possibly followed by an RDP Negotiation Request, into the
- variable part of the CR packet. (See also
-
- http://download.microsoft.com/download/5/B/C/5BC37A4E-6304-45AB-8C2D-AE712526E7F7/TS_Session_Directory.pdf
-
- a/k/a "[MSFT-SDLBTS]", as linked to, under the name "Session
- Directory and Load Balancing Using Terminal Server", on
-
- http://msdn.microsoft.com/en-us/library/E4BD6494-06AD-4aed-9823-445E921C9624
-
- which indicates that the routingToken is a string of the form
- "Cookie: msts=...".)
+ if (li > 0) {
+ /* There's more data left, so we have the variable part.
- They also may stuff an RDP Negotiation Response into the CC
- packet.
+ Microsoft's RDP hijacks the variable part of CR and CC PDUs
+ for their own user data (RDP runs atop Class 0, which doesn't
+ support user data).
- XXX - have TPKT know that a given session is an RDP session,
- and let us know, so we know whether to check for this stuff. */
- ositp_decode_var_part(tvb, offset, li, class_option, tpdu_len , pinfo,
- cotp_tree);
- offset += li;
+ Try what heuristic dissectors we have. */
+ next_tvb = tvb_new_subset_length(tvb, offset, li);
+ if (dissector_try_heuristic((tpdu == CR_TPDU) ?
+ cotp_cr_heur_subdissector_list :
+ cotp_cc_heur_subdissector_list,
+ next_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
+ /* A subdissector claimed this, so it really belongs to them. */
+ *subdissector_found = TRUE;
+ } else {
+ /* No heuristic dissector claimed it, so dissect it as a regular
+ variable part. */
+ ositp_decode_var_part(tvb, offset, li, class_option, tpdu_len, pinfo,
+ cotp_tree);
+ }
+ offset += li;
+ }
/*
- * XXX - tell the subdissector that this is user data in a CC or
- * CR packet rather than a DT packet?
+ * XXX - tell the subdissector that this is user data in a CR or
+ * CC packet rather than a DT packet?
*/
next_tvb = tvb_new_subset_remaining(tvb, offset);
if (!uses_inactive_subset){
@@ -1615,7 +1617,7 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
return offset;
-} /* ositp_decode_CC */
+} /* ositp_decode_CR_CC */
static int ositp_decode_DC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
packet_info *pinfo, proto_tree *tree)
@@ -2138,8 +2140,8 @@ static gint dissect_ositp_internal(tvbuff_t *tvb, packet_info *pinfo,
switch (tpdu) {
case CC_TPDU :
case CR_TPDU :
- new_offset = ositp_decode_CC(tvb, offset, li, tpdu, pinfo, tree,
- uses_inactive_subset, &subdissector_found);
+ new_offset = ositp_decode_CR_CC(tvb, offset, li, tpdu, pinfo, tree,
+ uses_inactive_subset, &subdissector_found);
break;
case DR_TPDU :
new_offset = ositp_decode_DR(tvb, offset, li, tpdu, pinfo, tree);
@@ -2420,6 +2422,10 @@ void proto_register_cotp(void)
"transport PDUs\" in the CLNP protocol "
"settings.", &cotp_decode_atn);
+ /* For handling protocols hijacking the variable part of CR or CC PDUs */
+ cotp_cr_heur_subdissector_list = register_heur_dissector_list("cotp_cr");
+ cotp_cc_heur_subdissector_list = register_heur_dissector_list("cotp_cc");
+
/* subdissector code in inactive subset */
cotp_is_heur_subdissector_list = register_heur_dissector_list("cotp_is");
@@ -2464,6 +2470,8 @@ proto_reg_handoff_cotp(void)
dissector_add_uint("ip.proto", IP_PROTO_TP, ositp_handle);
data_handle = find_dissector("data");
+ rdp_cr_handle = find_dissector("rdp_cr");
+ rdp_cc_handle = find_dissector("rdp_cc");
proto_clnp = proto_get_id_by_filter_name("clnp");
}
@@ -2480,4 +2488,3 @@ proto_reg_handoff_cotp(void)
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/
-