diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:33 +0000 |
commit | 9f153fbfec0fb9c9ce38e749a7c6f4a5e115d4e9 (patch) | |
tree | 2784370cda9bbf2da9114d70f05399c0b229d28c /epan/dissectors/packet-rdp_drdynvc.c | |
parent | Adding debian version 4.2.6-1. (diff) | |
download | wireshark-9f153fbfec0fb9c9ce38e749a7c6f4a5e115d4e9.tar.xz wireshark-9f153fbfec0fb9c9ce38e749a7c6f4a5e115d4e9.zip |
Merging upstream version 4.4.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-rdp_drdynvc.c')
-rw-r--r-- | epan/dissectors/packet-rdp_drdynvc.c | 368 |
1 files changed, 216 insertions, 152 deletions
diff --git a/epan/dissectors/packet-rdp_drdynvc.c b/epan/dissectors/packet-rdp_drdynvc.c index ddd3ec4b..7e9ed0b8 100644 --- a/epan/dissectors/packet-rdp_drdynvc.c +++ b/epan/dissectors/packet-rdp_drdynvc.c @@ -22,44 +22,45 @@ void proto_register_rdp_drdynvc(void); void proto_reg_handoff_drdynvc(void); -static int proto_rdp_drdynvc = -1; - -static int hf_rdp_drdynvc_cbId = -1; -static int hf_rdp_drdynvc_sp = -1; -static int hf_rdp_drdynvc_pri = -1; -static int hf_rdp_drdynvc_cmd = -1; -static int hf_rdp_drdynvc_capa_version = -1; -static int hf_rdp_drdynvc_capa_prio0 = -1; -static int hf_rdp_drdynvc_capa_prio1 = -1; -static int hf_rdp_drdynvc_capa_prio2 = -1; -static int hf_rdp_drdynvc_capa_prio3 = -1; -static int hf_rdp_drdynvc_channelId = -1; -static int hf_rdp_drdynvc_pad = -1; -static int hf_rdp_drdynvc_channelName = -1; -static int hf_rdp_drdynvc_creationStatus = -1; -static int hf_rdp_drdynvc_createresp_channelname = -1; -static int hf_rdp_drdynvc_length = -1; -static int hf_rdp_drdynvc_softsync_req_length = -1; -static int hf_rdp_drdynvc_softsync_req_flags = -1; -static int hf_rdp_drdynvc_softsync_req_ntunnels = -1; -static int hf_rdp_drdynvc_softsync_req_channel_tunnelType = -1; -static int hf_rdp_drdynvc_softsync_req_channel_ndvc = -1; -static int hf_rdp_drdynvc_softsync_req_channel_dvcid = -1; -static int hf_rdp_drdynvc_softsync_resp_ntunnels = -1; -static int hf_rdp_drdynvc_softsync_resp_tunnel = -1; -static int hf_rdp_drdynvc_data = -1; -static int hf_rdp_drdynvc_data_progress = -1; - - -static int ett_rdp_drdynvc = -1; -static int ett_rdp_drdynvc_softsync_channels = -1; -static int ett_rdp_drdynvc_softsync_channel = -1; -static int ett_rdp_drdynvc_softsync_dvc = -1; +static int proto_rdp_drdynvc; + +static int hf_rdp_drdynvc_cbId; +static int hf_rdp_drdynvc_sp; +static int hf_rdp_drdynvc_pri; +static int hf_rdp_drdynvc_cmd; +static int hf_rdp_drdynvc_capa_version; +static int hf_rdp_drdynvc_capa_prio0; +static int hf_rdp_drdynvc_capa_prio1; +static int hf_rdp_drdynvc_capa_prio2; +static int hf_rdp_drdynvc_capa_prio3; +static int hf_rdp_drdynvc_channelId; +static int hf_rdp_drdynvc_pad; +static int hf_rdp_drdynvc_channelName; +static int hf_rdp_drdynvc_creationStatus; +static int hf_rdp_drdynvc_createresp_channelname; +static int hf_rdp_drdynvc_length; +static int hf_rdp_drdynvc_softsync_req_length; +static int hf_rdp_drdynvc_softsync_req_flags; +static int hf_rdp_drdynvc_softsync_req_ntunnels; +static int hf_rdp_drdynvc_softsync_req_channel_tunnelType; +static int hf_rdp_drdynvc_softsync_req_channel_ndvc; +static int hf_rdp_drdynvc_softsync_req_channel_dvcid; +static int hf_rdp_drdynvc_softsync_resp_ntunnels; +static int hf_rdp_drdynvc_softsync_resp_tunnel; +static int hf_rdp_drdynvc_data; +static int hf_rdp_drdynvc_data_progress; + + +static int ett_rdp_drdynvc; +static int ett_rdp_drdynvc_softsync_channels; +static int ett_rdp_drdynvc_softsync_channel; +static int ett_rdp_drdynvc_softsync_dvc; dissector_handle_t egfx_handle; dissector_handle_t rail_handle; dissector_handle_t cliprdr_handle; dissector_handle_t snd_handle; +dissector_handle_t ear_handle; #define PNAME "RDP Dynamic Channel Protocol" #define PSNAME "DRDYNVC" @@ -93,22 +94,22 @@ typedef enum { DRDYNVC_CHANNEL_RAIL, /* MS-RDPERP */ DRDYNVC_CHANNEL_CLIPRDR, /* MS-RDPECLIP */ + DRDYNVC_CHANNEL_DR, /* MS-RDPDR */ } drdynvc_known_channel_t; enum { DRDYNVC_CHANNEL_PDUS_KEY = 1, }; -typedef struct { - guint32 length; - guint8* data; -} drdynvc_pdu_t; typedef struct { - drdynvc_pdu_t key; - gboolean fragmented; - guint32 packetLen; - guint32 progress; + bool reassembled; + bool decodePayload; + uint32_t progressStart; + uint32_t progressEnd; + uint32_t packetLen; + uint32_t startReassemblyFrame; + uint32_t endReassemblyFrame; tvbuff_t* tvb; } drdynvc_pdu_info_t; @@ -117,16 +118,19 @@ typedef struct { } drdynvc_pinfo_t; typedef struct { - wmem_array_t *packet; - guint32 packetLen; - guint32 pendingLen; - guint32 startFrame; + wmem_array_t *currentPacket; + uint32_t packetLen; + uint32_t pendingLen; + uint32_t startFrame; + uint32_t endReassemblyFrame; + wmem_array_t *chunks; } drdynvc_pending_packet_t; +/** @brief context associated with a dynamic channel */ typedef struct { drdynvc_known_channel_t type; char *name; - guint32 channelId; + uint32_t channelId; drdynvc_pending_packet_t pending_cs; drdynvc_pending_packet_t pending_sc; @@ -160,6 +164,7 @@ static drdynvc_know_channel_def knownChannels[] = { /* static channels that can be reopened on the dynamic channel */ {"rail", "rail", DRDYNVC_CHANNEL_RAIL}, {"cliprdr", "cliprdr", DRDYNVC_CHANNEL_CLIPRDR}, + {"rdpdr", "rdpdr", DRDYNVC_CHANNEL_DR}, }; static const value_string drdynvc_tunneltype_vals[] = { @@ -196,10 +201,21 @@ static const value_string rdp_drdynvc_cmd_vals[] = { { 0x0, NULL}, }; +static void +drdynvc_pending_packet_init(drdynvc_pending_packet_t *pending, uint32_t startFrame) +{ + pending->packetLen = 0; + pending->pendingLen = 0; + pending->startFrame = startFrame; + pending->endReassemblyFrame = 0; + pending->currentPacket = NULL; + pending->chunks = NULL; +} + static drdynvc_known_channel_t drdynvc_find_channel_type(const char *name) { - guint i; + unsigned i; for (i = 0; i < array_length(knownChannels); i++) { @@ -235,22 +251,22 @@ drdynvc_get_conversation_data(packet_info *pinfo) static int -dissect_rdp_vlength(tvbuff_t *tvb, int hf_index, int offset, guint8 vlen, proto_tree *tree, guint32 *ret) +dissect_rdp_vlength(tvbuff_t *tvb, int hf_index, int offset, uint8_t vlen, proto_tree *tree, uint32_t *ret) { int len; - guint32 value; + uint32_t value; switch (vlen) { case 0: - value = tvb_get_guint8(tvb, offset); + value = tvb_get_uint8(tvb, offset); len = 1; break; case 1: - value = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN); + value = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN); len = 2; break; case 2: - value = tvb_get_guint32(tvb, offset, ENC_LITTLE_ENDIAN); + value = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN); len = 4; break; default: @@ -266,7 +282,7 @@ dissect_rdp_vlength(tvbuff_t *tvb, int hf_index, int offset, guint8 vlen, proto_ } static const char * -find_channel_name_by_id(packet_info *pinfo, drdynvc_conv_info_t *dyninfo, guint32 dvcId) { +find_channel_name_by_id(packet_info *pinfo, drdynvc_conv_info_t *dyninfo, uint32_t dvcId) { drdynvc_channel_def_t *dynChannel = wmem_multimap_lookup32_le(dyninfo->channels, GUINT_TO_POINTER(dvcId), pinfo->num); if (dynChannel) return dynChannel->name; @@ -292,14 +308,15 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, { proto_item *item; proto_tree *tree; - gint offset = 0; - guint8 cbIdSpCmd, cmdId; - guint8 cbId, Len; - gboolean haveChannelId, havePri, haveLen; - gboolean isServerTarget = rdp_isServerAddressTarget(pinfo); - guint32 channelId = 0; - guint32 pduLen = 0; + int offset = 0; + uint8_t cbIdSpCmd, cmdId; + uint8_t cbId, Len; + bool haveChannelId, havePri, haveLen; + bool isServerTarget = rdp_isServerAddressTarget(pinfo); + uint32_t channelId = 0; + uint32_t fullPduLen = 0; drdynvc_conv_info_t *info; + drdynvc_channel_def_t *channel = NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRDYNVC"); col_clear(pinfo->cinfo, COL_INFO); @@ -308,7 +325,7 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, item = proto_tree_add_item(parent_tree, proto_rdp_drdynvc, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_rdp_drdynvc); - cbIdSpCmd = tvb_get_guint8(tvb, offset); + cbIdSpCmd = tvb_get_uint8(tvb, offset); cmdId = (cbIdSpCmd >> 4) & 0xf; cbId = (cbIdSpCmd & 0x3); @@ -342,48 +359,45 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree_add_item(tree, hf_rdp_drdynvc_cmd, tvb, offset, 1, ENC_NA); offset++; - if (haveChannelId) + + info = drdynvc_get_conversation_data(pinfo); + if (haveChannelId) { offset += dissect_rdp_vlength(tvb, hf_rdp_drdynvc_channelId, offset, cbId, tree, &channelId); + channel = wmem_multimap_lookup32_le(info->channels, GUINT_TO_POINTER(channelId), pinfo->num); + } + if (haveLen) { Len = (cbIdSpCmd >> 2) & 0x3; - offset += dissect_rdp_vlength(tvb, hf_rdp_drdynvc_length, offset, Len, tree, &pduLen); + offset += dissect_rdp_vlength(tvb, hf_rdp_drdynvc_length, offset, Len, tree, &fullPduLen); } - info = drdynvc_get_conversation_data(pinfo); switch (cmdId) { case DRDYNVC_CREATE_REQUEST_PDU: if (!isServerTarget) { - guint nameLen = tvb_strsize(tvb, offset); + unsigned nameLen = tvb_strsize(tvb, offset); col_set_str(pinfo->cinfo, COL_INFO, "CreateChannel Request"); proto_tree_add_item(tree, hf_rdp_drdynvc_channelName, tvb, offset, -1, ENC_ASCII); - drdynvc_channel_def_t *channel; if (!PINFO_FD_VISITED(pinfo)) { channel = wmem_alloc(wmem_file_scope(), sizeof(*channel)); channel->channelId = channelId; channel->name = tvb_get_string_enc(wmem_file_scope(), tvb, offset, nameLen, ENC_ASCII); channel->type = drdynvc_find_channel_type(channel->name); - channel->pending_cs.pendingLen = 0; - channel->pending_cs.packet = NULL; - channel->pending_cs.startFrame = pinfo->num; - channel->pending_sc.pendingLen = 0; - channel->pending_sc.packet = NULL; - channel->pending_sc.startFrame = pinfo->num; - //printf("dynamic %s -> 0x%x\n", channel->name, channel->channelId); + drdynvc_pending_packet_init(&channel->pending_cs, pinfo->num); + drdynvc_pending_packet_init(&channel->pending_sc, pinfo->num); wmem_multimap_insert32(info->channels, GUINT_TO_POINTER(channelId), pinfo->num, channel); } } else { - drdynvc_channel_def_t *channel = wmem_multimap_lookup32_le(info->channels, GUINT_TO_POINTER(channelId), pinfo->num); - col_set_str(pinfo->cinfo, COL_INFO, "CreateChannel Response"); if (channel) { - proto_item *channelName = proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_createresp_channelname, tvb, offset, 0, NULL, "%s", channel->name); - proto_item_set_generated(channelName); + proto_item_set_generated( + proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_createresp_channelname, tvb, offset, 0, NULL, "%s", channel->name) + ); } proto_tree_add_item(tree, hf_rdp_drdynvc_creationStatus, tvb, offset, 4, ENC_NA); @@ -394,7 +408,7 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree_add_item(tree, hf_rdp_drdynvc_pad, tvb, offset, 1, ENC_NA); offset++; - guint32 version; + uint32_t version; proto_tree_add_item_ret_uint(tree, hf_rdp_drdynvc_capa_version, tvb, offset, 2, ENC_LITTLE_ENDIAN, &version); offset += 2; @@ -419,22 +433,55 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, case DRDYNVC_DATA_FIRST_PDU: { col_set_str(pinfo->cinfo, COL_INFO, "Data first"); - drdynvc_channel_def_t *channel = wmem_multimap_lookup32_le(info->channels, GUINT_TO_POINTER(channelId), pinfo->num); if (channel) { + drdynvc_pdu_info_t *pduInfo = NULL; drdynvc_pending_packet_t *pendingPacket = isServerTarget ? &channel->pending_cs : &channel->pending_sc; - gint payloadLen = tvb_reported_length_remaining(tvb, offset); - proto_item *channelName = proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_createresp_channelname, tvb, offset, 0, NULL, "%s", channel->name); - proto_item_set_generated(channelName); + int payloadLen = tvb_reported_length_remaining(tvb, offset); + bool isSinglePacket = (fullPduLen == (uint32_t)payloadLen); + drdynvc_pinfo_t *drdynvcPinfo = getDrDynPacketInfo(pinfo); + uint32_t key = crc32_ccitt_tvb_offset(tvb, offset, payloadLen); + + proto_item_set_generated( + proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_createresp_channelname, tvb, offset, 0, NULL, "%s", channel->name) + ); proto_item_set_generated( - proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_data_progress, tvb, offset, 0, NULL, "0-%d/%d", payloadLen, pduLen) + proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_data_progress, tvb, offset, 0, NULL, "0-%d/%d", payloadLen, fullPduLen) ); - pendingPacket->packetLen = pduLen; - pendingPacket->pendingLen = pduLen - payloadLen; - pendingPacket->startFrame = pinfo->num; + if (!PINFO_FD_VISITED(pinfo)) { + if (!isSinglePacket) { + if (pendingPacket->chunks) + wmem_destroy_array(pendingPacket->chunks); + pendingPacket->chunks = wmem_array_new(wmem_file_scope(), sizeof(drdynvc_pdu_info_t*)); + + pduInfo = wmem_alloc(wmem_file_scope(), sizeof(*pduInfo)); + pduInfo->reassembled = true; + pduInfo->startReassemblyFrame = pinfo->num; + pduInfo->progressStart = 0; + pduInfo->progressEnd = fullPduLen; + pduInfo->tvb = NULL; + + wmem_tree_insert32(drdynvcPinfo->pdus, key, pduInfo); + wmem_array_append(pendingPacket->chunks, &pduInfo, 1); + + pendingPacket->packetLen = fullPduLen; + pendingPacket->pendingLen = fullPduLen - payloadLen; + pendingPacket->startFrame = pinfo->num; + pendingPacket->currentPacket = wmem_array_sized_new(wmem_file_scope(), 1, fullPduLen); + wmem_array_append(pendingPacket->currentPacket, tvb_get_ptr(tvb, offset, payloadLen), payloadLen); + } else { + if (pendingPacket->pendingLen || pendingPacket->chunks) + printf("(%d) looks like we have a non completed packet...\n", pinfo->num); + if (pendingPacket->chunks) + wmem_destroy_array(pendingPacket->chunks); + memset(pendingPacket, 0, sizeof(*pendingPacket)); + } + } else { + pduInfo = (drdynvc_pdu_info_t*)wmem_tree_lookup32(drdynvcPinfo->pdus, key); + } - if (!pendingPacket->pendingLen) { + if (isSinglePacket) { switch (channel->type) { case DRDYNVC_CHANNEL_EGFX: call_dissector(egfx_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); @@ -448,6 +495,9 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, case DRDYNVC_CHANNEL_AUDIOUT: call_dissector(snd_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); break; + case DRDYNVC_CHANNEL_AUTH_REDIR: + call_dissector(ear_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); + break; default: proto_tree_add_item(tree, hf_rdp_drdynvc_data, tvb, offset, -1, ENC_NA); break; @@ -455,10 +505,8 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, offset += payloadLen; return offset; - } else { - pendingPacket->packet = wmem_array_sized_new(wmem_file_scope(), 1, pduLen); - wmem_array_append(pendingPacket->packet, tvb_get_ptr(tvb, offset, -1), payloadLen); } + } proto_tree_add_item(tree, hf_rdp_drdynvc_data, tvb, offset, -1, ENC_NA); @@ -467,54 +515,67 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, case DRDYNVC_DATA_PDU: { col_set_str(pinfo->cinfo, COL_INFO, "Data"); - drdynvc_channel_def_t *channel = wmem_multimap_lookup32_le(info->channels, GUINT_TO_POINTER(channelId), pinfo->num); if (channel) { tvbuff_t *targetTvb = NULL; - gboolean fragmented = FALSE; - proto_item *channelName = proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_createresp_channelname, tvb, offset, 0, NULL, "%s", channel->name); - proto_item_set_generated(channelName); + proto_item_set_generated( + proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_createresp_channelname, tvb, offset, 0, NULL, "%s", channel->name) + ); drdynvc_pinfo_t *drdynvcPinfo = getDrDynPacketInfo(pinfo); - drdynvc_pdu_info_t *pduInfo; - gint payloadLen = tvb_reported_length_remaining(tvb, offset); - guint32 key = crc32_ccitt_tvb_offset(tvb, offset, payloadLen); + drdynvc_pdu_info_t *pduInfo = NULL; + int payloadLen = tvb_reported_length_remaining(tvb, offset); + uint32_t key = crc32_ccitt_tvb_offset(tvb, offset, payloadLen); if (!PINFO_FD_VISITED(pinfo)) { drdynvc_pending_packet_t *pendingPacket = isServerTarget ? &channel->pending_cs : &channel->pending_sc; - /*printf("num=%d payloadLen=%d pendingLen=%d/%d\n", pinfo->num, payloadLen, - pendingPacket->pendingLen, pendingPacket->packetLen);*/ + pduInfo = wmem_alloc(wmem_file_scope(), sizeof(*pduInfo)); + wmem_tree_insert32(drdynvcPinfo->pdus, key, pduInfo); + if (pendingPacket->pendingLen) { - if ((guint32)payloadLen > pendingPacket->pendingLen) { + /* we have a fragmented packet in progress */ + if ((uint32_t)payloadLen > pendingPacket->pendingLen) { // TODO: error - /*printf("num=%d error\n", pinfo->num);*/ + printf("num=%d error payload too big\n", pinfo->num); return offset; } - pendingPacket->pendingLen -= payloadLen; - wmem_array_append(pendingPacket->packet, tvb_get_ptr(tvb, offset, -1), payloadLen); - fragmented = TRUE; - } + pduInfo->reassembled = true; + pduInfo->decodePayload = false; + pduInfo->progressStart = pendingPacket->packetLen - pendingPacket->pendingLen; + pduInfo->progressEnd = pduInfo->progressStart + payloadLen; + pduInfo->packetLen = pendingPacket->packetLen; - if (!pendingPacket->pendingLen) { - pendingPacket->packetLen = 0; + wmem_array_append(pendingPacket->chunks, &pduInfo, 1); - if (!fragmented) { - targetTvb = tvb_new_subset_remaining(tvb, offset); - } else { - gint reassembled_len = wmem_array_get_count(pendingPacket->packet); - targetTvb = tvb_new_real_data(wmem_array_get_raw(pendingPacket->packet), reassembled_len, reassembled_len); + pendingPacket->pendingLen -= payloadLen; + wmem_array_append(pendingPacket->currentPacket, tvb_get_ptr(tvb, offset, payloadLen), payloadLen); + + if (!pendingPacket->pendingLen) { + /* last packet of the reassembly */ + int reassembled_len = wmem_array_get_count(pendingPacket->currentPacket); + pduInfo->tvb = tvb_new_real_data(wmem_array_get_raw(pendingPacket->currentPacket), reassembled_len, reassembled_len); + pduInfo->decodePayload = true; + pendingPacket->currentPacket = NULL; + + for (unsigned i = 0; i < wmem_array_get_count(pendingPacket->chunks); i++) { + drdynvc_pdu_info_t *chunk = *(drdynvc_pdu_info_t **)wmem_array_index(pendingPacket->chunks, i); + chunk->endReassemblyFrame = pinfo->num; + } + wmem_destroy_array(pendingPacket->chunks); + pendingPacket->chunks = NULL; } + } else { + /* single data packet */ + pduInfo->reassembled = false; + pduInfo->decodePayload = true; + pduInfo->progressStart = 0; + pduInfo->progressEnd = payloadLen; + pduInfo->packetLen = payloadLen; + pduInfo->tvb = NULL; + pduInfo->startReassemblyFrame = pduInfo->endReassemblyFrame = pinfo->num; } - - pduInfo = wmem_alloc(wmem_file_scope(), sizeof(*pduInfo)); - pduInfo->fragmented = fragmented; - pduInfo->packetLen = pendingPacket->packetLen ? pendingPacket->packetLen : (guint32)payloadLen; - pduInfo->progress = pendingPacket->packetLen - pendingPacket->pendingLen; - pduInfo->tvb = fragmented ? targetTvb : NULL; - - wmem_tree_insert32(drdynvcPinfo->pdus, key, pduInfo); } else { pduInfo = (drdynvc_pdu_info_t*)wmem_tree_lookup32(drdynvcPinfo->pdus, key); } @@ -522,19 +583,22 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, if (pduInfo) { proto_item_set_generated( proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_data_progress, tvb, offset, 0, NULL, "%d-%d/%d", - pduInfo->progress, pduInfo->progress + payloadLen, pduInfo->packetLen) + pduInfo->progressStart, pduInfo->progressEnd, pduInfo->packetLen) ); - } - - if (!pduInfo->fragmented) - targetTvb = tvb_new_subset_remaining(tvb, offset); - else - targetTvb = pduInfo->tvb; - if(targetTvb) { - if (pduInfo->fragmented) + if (pduInfo->tvb) { + targetTvb = pduInfo->tvb; add_new_data_source(pinfo, targetTvb, "Reassembled DRDYNVC"); + } else { + targetTvb = tvb_new_subset_remaining(tvb, offset); + } + + if (pduInfo->endReassemblyFrame && (pduInfo->endReassemblyFrame != pinfo->num)) { + // TODO: show a link to the end frame ? + } + } + if (pduInfo && pduInfo->decodePayload) { switch (channel->type) { case DRDYNVC_CHANNEL_EGFX: call_dissector(egfx_handle, targetTvb, pinfo, tree); @@ -548,8 +612,11 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, case DRDYNVC_CHANNEL_AUDIOUT: call_dissector(snd_handle, targetTvb, pinfo, tree); break; + case DRDYNVC_CHANNEL_AUTH_REDIR: + call_dissector(ear_handle, targetTvb, pinfo, tree); + break; default: - proto_tree_add_item(tree, hf_rdp_drdynvc_data, targetTvb, offset, -1, ENC_NA); + proto_tree_add_item(tree, hf_rdp_drdynvc_data, targetTvb, 0, -1, ENC_NA); break; } return tvb_reported_length(tvb); @@ -566,8 +633,8 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, col_set_str(pinfo->cinfo, COL_INFO, "Data compressed"); break; case DRDYNVC_SOFT_SYNC_REQUEST_PDU: { - guint32 ntunnels; - guint32 flags; + uint32_t ntunnels; + uint32_t flags; col_set_str(pinfo->cinfo, COL_INFO, "SoftSync Request"); @@ -586,14 +653,14 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, offset += 2; if (flags & 0x02) { /* SOFT_SYNC_CHANNEL_LIST_PRESENT */ - guint16 i; + uint16_t i; proto_tree *tunnels_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_rdp_drdynvc_softsync_channels, NULL, "Channels"); for (i = 0; i < ntunnels; i++) { - guint16 j; - guint32 tunnelType = tvb_get_guint32(tvb, offset, ENC_LITTLE_ENDIAN); - guint16 ndvcs = tvb_get_guint16(tvb, offset + 4, ENC_LITTLE_ENDIAN); - gint channelSz = 4 + 2 + (ndvcs * 4); + uint16_t j; + uint32_t tunnelType = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN); + uint16_t ndvcs = tvb_get_uint16(tvb, offset + 4, ENC_LITTLE_ENDIAN); + int channelSz = 4 + 2 + (ndvcs * 4); proto_tree *channel_tree; const char *label = (tunnelType == 0x1) ? "Reliable channels" : "Lossy channels"; @@ -607,10 +674,10 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, for (j = 0; j < ndvcs; j++, offset += 4) { proto_tree *dvc_tree; - guint32 dvcId; + uint32_t dvcId; const char *showLabel; - dvcId = tvb_get_guint32(tvb, offset, ENC_LITTLE_ENDIAN); + dvcId = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN); showLabel = label = find_channel_name_by_id(pinfo, info, dvcId); if (!label) showLabel = "DVC"; @@ -627,7 +694,7 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, break; } case DRDYNVC_SOFT_SYNC_RESPONSE_PDU: { - guint32 ntunnels, i; + uint32_t ntunnels, i; col_set_str(pinfo->cinfo, COL_INFO, "SoftSync Response"); @@ -647,12 +714,11 @@ dissect_rdp_drdynvc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, break; } case DRDYNVC_CLOSE_REQUEST_PDU: { - drdynvc_channel_def_t *channel = wmem_multimap_lookup32_le(info->channels, GUINT_TO_POINTER(channelId), pinfo->num); - col_set_str(pinfo->cinfo, COL_INFO, "Close request"); if (channel) { - proto_item *channelName = proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_channelName, tvb, offset, 0, NULL, "%s", channel->name); - proto_item_set_generated(channelName); + proto_item_set_generated( + proto_tree_add_string_format_value(tree, hf_rdp_drdynvc_channelName, tvb, offset, 0, NULL, "%s", channel->name) + ); } break; } @@ -769,21 +835,18 @@ void proto_register_rdp_drdynvc(void) { }; /* List of subtrees */ - static gint *ett[] = { - &ett_rdp_drdynvc, - &ett_rdp_drdynvc_softsync_channels, - &ett_rdp_drdynvc_softsync_channel, - &ett_rdp_drdynvc_softsync_dvc + static int *ett[] = { + &ett_rdp_drdynvc, + &ett_rdp_drdynvc_softsync_channels, + &ett_rdp_drdynvc_softsync_channel, + &ett_rdp_drdynvc_softsync_dvc }; - //module_t *drdynvc_module; proto_rdp_drdynvc = proto_register_protocol(PNAME, PSNAME, PFNAME); /* Register fields and subtrees */ proto_register_field_array(proto_rdp_drdynvc, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); - /*drdynvc_module = prefs_register_protocol(proto_rdp_drdynvc, NULL);*/ - register_dissector("rdp_drdynvc", dissect_rdp_drdynvc, proto_rdp_drdynvc); } @@ -792,6 +855,7 @@ void proto_reg_handoff_drdynvc(void) { rail_handle = find_dissector("rdp_rail"); cliprdr_handle = find_dissector("rdp_cliprdr"); snd_handle = find_dissector("rdp_snd"); + ear_handle = find_dissector("rdp_ear"); } /* |