diff options
Diffstat (limited to 'epan/dissectors/packet-mc-nmf.c')
-rw-r--r-- | epan/dissectors/packet-mc-nmf.c | 83 |
1 files changed, 47 insertions, 36 deletions
diff --git a/epan/dissectors/packet-mc-nmf.c b/epan/dissectors/packet-mc-nmf.c index a5279f8b93..a4cfdbf74f 100644 --- a/epan/dissectors/packet-mc-nmf.c +++ b/epan/dissectors/packet-mc-nmf.c @@ -31,6 +31,8 @@ void proto_register_mc_nmf(void); static dissector_handle_t ms_nns_handle; static dissector_handle_t tls_handle; +static dissector_handle_t mc_nmf_handle; + /* Initialize the protocol and registered fields */ #define MC_NMF_REC_VERSION 0 @@ -92,40 +94,43 @@ struct mc_nmf_session_state { guint32 upgrade_rsp; }; -static int proto_mc_nmf = -1; -static int hf_mc_nmf_record_type = -1; -static int hf_mc_nmf_major_version = -1; -static int hf_mc_nmf_minor_version = -1; -static int hf_mc_nmf_mode = -1; -static int hf_mc_nmf_known_encoding = -1; -static int hf_mc_nmf_via_length = -1; -static int hf_mc_nmf_via = -1; -static int hf_mc_nmf_encoding_length = -1; -static int hf_mc_nmf_encoding_type = -1; -static int hf_mc_nmf_fault_length = -1; -static int hf_mc_nmf_fault = -1; -static int hf_mc_nmf_upgrade_length = -1; -static int hf_mc_nmf_upgrade = -1; -static int hf_mc_nmf_chunk_length = -1; -static int hf_mc_nmf_chunk = -1; -static int hf_mc_nmf_terminator = -1; -static int hf_mc_nmf_payload_length = -1; -static int hf_mc_nmf_payload = -1; -static int hf_mc_nmf_upgrade_proto_data = -1; - -static expert_field ei_mc_nmf_size_too_big = EI_INIT; - -#define MC_NMF_TCP_PORT 0 +static int proto_mc_nmf; +static int hf_mc_nmf_record_type; +static int hf_mc_nmf_major_version; +static int hf_mc_nmf_minor_version; +static int hf_mc_nmf_mode; +static int hf_mc_nmf_known_encoding; +static int hf_mc_nmf_via_length; +static int hf_mc_nmf_via; +static int hf_mc_nmf_encoding_length; +static int hf_mc_nmf_encoding_type; +static int hf_mc_nmf_fault_length; +static int hf_mc_nmf_fault; +static int hf_mc_nmf_upgrade_length; +static int hf_mc_nmf_upgrade; +static int hf_mc_nmf_chunk_length; +static int hf_mc_nmf_chunk; +static int hf_mc_nmf_terminator; +static int hf_mc_nmf_payload_length; +static int hf_mc_nmf_payload; +static int hf_mc_nmf_upgrade_proto_data; + +static expert_field ei_mc_nmf_size_too_big; + +// [MC-NMF] does not have a defined port https://learn.microsoft.com/en-us/openspecs/windows_protocols/mc-nmf/51b5eb53-f488-4b74-b21d-8a498f016b61 +// but 9389 is ADWS port https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adcap/cfff3d7f-e7cd-4529-86a0-4de89efe3855 +// which relies on [MC-NMF], so by doing this, all ADWS traffic on port 9389 is properly dissected by default +#define MC_NMF_TCP_PORT 9389 /* Initialize the subtree pointers */ -static gint ett_mc_nmf = -1; -static gint ett_mc_nmf_rec = -1; +static gint ett_mc_nmf; +static gint ett_mc_nmf_rec; #define MC_NMF_MIN_LENGTH 1 static gboolean get_size_length(tvbuff_t *tvb, int *offset, guint *len_length, packet_info *pinfo, guint32 *out_size) { guint8 lbyte; - gint64 size = 0; + guint64 size = 0; guint shiftcount = 0; lbyte = tvb_get_guint8(tvb, *offset); @@ -135,13 +140,20 @@ static gboolean get_size_length(tvbuff_t *tvb, int *offset, guint *len_length, p while ( lbyte & 0x80 ) { lbyte = tvb_get_guint8(tvb, *offset); *offset += 1; + /* Guard against the pathological case of a sequence of 0x80 + * bytes (which add nothing to size). + */ + if (*len_length >= 5) { + expert_add_info(pinfo, NULL, &ei_mc_nmf_size_too_big); + return FALSE; + } shiftcount = 7 * *len_length; - size = ((lbyte & 0x7F) << shiftcount) | (size); + size = ((lbyte & UINT64_C(0x7F)) << shiftcount) | (size); *len_length += 1; /* * Check if size if is too big to prevent against overflow. * According to spec an implementation SHOULD support record sizes as - * large as 0xffffffff octets. + * large as 0xffffffff octets (encoded size requires five octets). */ if (size > 0xffffffff) { expert_add_info(pinfo, NULL, &ei_mc_nmf_size_too_big); @@ -235,7 +247,7 @@ dissect_mc_nmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _ if (!get_size_length(tvb, &offset, &len_length, pinfo, &size)) return tvb_reported_length(tvb); proto_tree_add_uint(rec_tree, hf_mc_nmf_via_length, tvb, offset - len_length, len_length, size); - proto_tree_add_item(rec_tree, hf_mc_nmf_via, tvb, offset, size, ENC_UTF_8|ENC_NA); + proto_tree_add_item(rec_tree, hf_mc_nmf_via, tvb, offset, size, ENC_UTF_8); offset += size; break; case MC_NMF_REC_KNOWN_ENC: @@ -250,7 +262,7 @@ dissect_mc_nmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _ if (!get_size_length(tvb, &offset, &len_length, pinfo, &size)) return tvb_reported_length(tvb); proto_tree_add_uint(rec_tree, hf_mc_nmf_encoding_length, tvb, offset - len_length, len_length, size); - proto_tree_add_item(rec_tree, hf_mc_nmf_encoding_type, tvb, offset, size, ENC_UTF_8|ENC_NA); + proto_tree_add_item(rec_tree, hf_mc_nmf_encoding_type, tvb, offset, size, ENC_UTF_8); offset += size; break; case MC_NMF_REC_UNSIZED_ENV: @@ -286,7 +298,7 @@ dissect_mc_nmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _ if (!get_size_length(tvb, &offset, &len_length, pinfo, &size)) return tvb_reported_length(tvb); proto_tree_add_uint(rec_tree, hf_mc_nmf_fault_length, tvb, offset - len_length, len_length, size); - proto_tree_add_item(rec_tree, hf_mc_nmf_fault, tvb, offset, size, ENC_UTF_8|ENC_NA); + proto_tree_add_item(rec_tree, hf_mc_nmf_fault, tvb, offset, size, ENC_UTF_8); offset += size; break; case MC_NMF_REC_UPGRADE_REQ: @@ -296,7 +308,7 @@ dissect_mc_nmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _ if (!get_size_length(tvb, &offset, &len_length, pinfo, &size)) return tvb_reported_length(tvb); proto_tree_add_uint(rec_tree, hf_mc_nmf_upgrade_length, tvb, offset - len_length, len_length, size); - proto_tree_add_item(rec_tree, hf_mc_nmf_upgrade, tvb, offset, size, ENC_UTF_8|ENC_NA); + proto_tree_add_item(rec_tree, hf_mc_nmf_upgrade, tvb, offset, size, ENC_UTF_8); upgrade_protocol = tvb_get_string_enc(pinfo->pool, tvb, offset, size, ENC_UTF_8|ENC_NA); offset += size; if (strcmp((char*)upgrade_protocol, "application/negotiate") == 0) { @@ -438,13 +450,12 @@ void proto_register_mc_nmf(void) proto_register_subtree_array(ett, array_length(ett)); expert_mc_nmf = expert_register_protocol(proto_mc_nmf); expert_register_field_array(expert_mc_nmf, ei, array_length(ei)); + + mc_nmf_handle = register_dissector("mc-nmf", dissect_mc_nmf, proto_mc_nmf); } void proto_reg_handoff_mc_nmf(void) { - dissector_handle_t mc_nmf_handle; - - mc_nmf_handle = create_dissector_handle(dissect_mc_nmf, proto_mc_nmf); dissector_add_uint_with_preference("tcp.port", MC_NMF_TCP_PORT, mc_nmf_handle); ms_nns_handle = find_dissector_add_dependency("ms-nns", proto_mc_nmf); tls_handle = find_dissector("tls"); |