diff options
author | Guy Harris <guy@alum.mit.edu> | 2016-02-01 15:19:10 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2016-02-01 23:20:12 +0000 |
commit | b9fb2ceb88b0904e95b2931fbf2efd6222f56285 (patch) | |
tree | cc9ed34dea4bb981ce7c997c3e19cfc9de6c8d01 /epan/dissectors/packet-ositp.c | |
parent | a53ab9dfcc87ec817467a2a9c2259b0a70a1dd78 (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.c | 77 |
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: */ - |