wireshark/epan/dissectors/packet-rdp.c

2979 lines
108 KiB
C

/* Packet-rdp.c
* Routines for Remote Desktop Protocol (RDP) packet dissection
* Copyright 2010, Graeme Lunt
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* See: "[MS -RDPBCGR] Remote Desktop Protocol: Basic Connectivity and Graphics Remoting"
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/conversation.h>
#include <epan/asn1.h>
#include "packet-ssl.h"
#include "packet-t124.h"
#define PNAME "Remote Desktop Protocol"
#define PSNAME "RDP"
#define PFNAME "rdp"
static guint global_rdp_tcp_port = 3389;
static dissector_handle_t tpkt_handle;
void proto_register_rdp(void);
void proto_reg_handoff_rdp(void);
static void prefs_register_rdp(void);
static int proto_rdp = -1;
static int ett_rdp = -1;
static int ett_rdp_SendData = -1;
static int ett_rdp_ClientData = -1;
static int ett_rdp_clientCoreData = -1;
static int ett_rdp_clientSecurityData = -1;
static int ett_rdp_clientNetworkData = -1;
static int ett_rdp_clientClusterData = -1;
static int ett_rdp_clientMonitorData = -1;
static int ett_rdp_clientMsgChannelData = -1;
static int ett_rdp_clientMonitorExData = -1;
static int ett_rdp_clientMultiTransportData = -1;
static int ett_rdp_clientUnknownData = -1;
static int ett_rdp_ServerData = -1;
static int ett_rdp_serverCoreData = -1;
static int ett_rdp_serverSecurityData = -1;
static int ett_rdp_serverNetworkData = -1;
static int ett_rdp_serverMsgChannelData = -1;
static int ett_rdp_serverMultiTransportData = -1;
static int ett_rdp_serverUnknownData = -1;
static int ett_rdp_channelIdArray = -1;
static int ett_rdp_securityExchangePDU = -1;
static int ett_rdp_clientInfoPDU = -1;
static int ett_rdp_validClientLicenseData = -1;
static int ett_rdp_shareControlHeader = -1;
static int ett_rdp_pduType = -1;
static int ett_rdp_flags = -1;
static int ett_rdp_compressedType = -1;
static int ett_rdp_mapFlags = -1;
static int ett_rdp_options = -1;
static int ett_rdp_channelDefArray = -1;
static int ett_rdp_channelDef = -1;
static int ett_rdp_channelPDUHeader = -1;
static int ett_rdp_channelFlags = -1;
static int ett_rdp_capabilitySet = -1;
static int ett_rdp_StandardDate = -1;
static int ett_rdp_DaylightDate = -1;
static int ett_rdp_clientTimeZone = -1;
static int hf_rdp_ClientData = -1;
static int hf_rdp_SendData = -1;
static int hf_rdp_clientCoreData = -1;
static int hf_rdp_clientSecurityData = -1;
static int hf_rdp_clientNetworkData = -1;
static int hf_rdp_clientClusterData = -1;
static int hf_rdp_clientMonitorData = -1;
static int hf_rdp_clientMsgChannelData = -1;
static int hf_rdp_clientMonitorExData = -1;
static int hf_rdp_clientMultiTransportData = -1;
static int hf_rdp_clientUnknownData = -1;
static int hf_rdp_ServerData = -1;
static int hf_rdp_serverCoreData = -1;
static int hf_rdp_serverSecurityData = -1;
static int hf_rdp_serverNetworkData = -1;
static int hf_rdp_serverMsgChannelData = -1;
static int hf_rdp_serverMultiTransportData = -1;
static int hf_rdp_serverUnknownData = -1;
static int hf_rdp_securityExchangePDU = -1;
static int hf_rdp_clientInfoPDU = -1;
static int hf_rdp_validClientLicenseData = -1;
static int hf_rdp_headerType = -1;
static int hf_rdp_headerLength = -1;
static int hf_rdp_versionMajor = -1;
static int hf_rdp_versionMinor = -1;
static int hf_rdp_desktopWidth = -1;
static int hf_rdp_desktopHeight = -1;
static int hf_rdp_colorDepth = -1;
static int hf_rdp_SASSequence = -1;
static int hf_rdp_keyboardLayout = -1;
static int hf_rdp_clientBuild = -1;
static int hf_rdp_clientName = -1;
static int hf_rdp_keyboardType = -1;
static int hf_rdp_keyboardSubType = -1;
static int hf_rdp_keyboardFunctionKey = -1;
static int hf_rdp_imeFileName = -1;
static int hf_rdp_postBeta2ColorDepth = -1;
static int hf_rdp_clientProductId = -1;
static int hf_rdp_serialNumber = -1;
static int hf_rdp_highColorDepth = -1;
static int hf_rdp_supportedColorDepths = -1;
static int hf_rdp_earlyCapabilityFlags = -1;
static int hf_rdp_clientDigProductId = -1;
static int hf_rdp_connectionType = -1;
static int hf_rdp_pad1octet = -1;
static int hf_rdp_serverSelectedProtocol = -1;
static int hf_rdp_encryptionMethods = -1;
static int hf_rdp_extEncryptionMethods = -1;
static int hf_rdp_cluster_flags = -1;
static int hf_rdp_redirectedSessionId = -1;
static int hf_rdp_msgChannelFlags = -1;
static int hf_rdp_msgChannelId = -1;
static int hf_rdp_monitorExFlags = -1;
static int hf_rdp_monitorAttributeSize = -1;
static int hf_rdp_monitorCount = -1;
static int hf_rdp_multiTransportFlags = -1;
static int hf_rdp_encryptionMethod = -1;
static int hf_rdp_encryptionLevel = -1;
static int hf_rdp_serverRandomLen = -1;
static int hf_rdp_serverCertLen = -1;
static int hf_rdp_serverRandom = -1;
static int hf_rdp_serverCertificate = -1;
static int hf_rdp_clientRequestedProtocols = -1;
static int hf_rdp_MCSChannelId = -1;
static int hf_rdp_channelCount = -1;
static int hf_rdp_channelIdArray = -1;
static int hf_rdp_Pad = -1;
static int hf_rdp_length = -1;
static int hf_rdp_encryptedClientRandom = -1;
static int hf_rdp_dataSignature = -1;
static int hf_rdp_fipsLength = -1;
static int hf_rdp_fipsVersion = -1;
static int hf_rdp_padlen = -1;
static int hf_rdp_flags = -1;
static int hf_rdp_flagsPkt = -1;
static int hf_rdp_flagsEncrypt = -1;
static int hf_rdp_flagsResetSeqno = -1;
static int hf_rdp_flagsIgnoreSeqno = -1;
static int hf_rdp_flagsLicenseEncrypt = -1;
static int hf_rdp_flagsSecureChecksum = -1;
static int hf_rdp_flagsFlagsHiValid = -1;
static int hf_rdp_flagsHi = -1;
static int hf_rdp_codePage = -1;
static int hf_rdp_optionFlags = -1;
static int hf_rdp_cbDomain = -1;
static int hf_rdp_cbUserName = -1;
static int hf_rdp_cbPassword = -1;
static int hf_rdp_cbAlternateShell = -1;
static int hf_rdp_cbWorkingDir = -1;
static int hf_rdp_cbClientAddress = -1;
static int hf_rdp_cbClientDir = -1;
static int hf_rdp_cbAutoReconnectLen = -1;
static int hf_rdp_domain = -1;
static int hf_rdp_userName = -1;
static int hf_rdp_password = -1;
static int hf_rdp_alternateShell = -1;
static int hf_rdp_workingDir = -1;
static int hf_rdp_clientAddressFamily = -1;
static int hf_rdp_clientAddress = -1;
static int hf_rdp_clientDir = -1;
static int hf_rdp_clientTimeZone = -1;
static int hf_rdp_clientSessionId = -1;
static int hf_rdp_performanceFlags = -1;
static int hf_rdp_autoReconnectCookie = -1;
static int hf_rdp_reserved1 = -1;
static int hf_rdp_reserved2 = -1;
static int hf_rdp_bMsgType = -1;
static int hf_rdp_bVersion = -1;
static int hf_rdp_wMsgSize = -1;
static int hf_rdp_wBlobType = -1;
static int hf_rdp_wBlobLen = -1;
static int hf_rdp_blobData = -1;
static int hf_rdp_shareControlHeader = -1;
static int hf_rdp_totalLength = -1;
static int hf_rdp_pduType = -1;
static int hf_rdp_pduTypeType = -1;
static int hf_rdp_pduTypeVersionLow = -1;
static int hf_rdp_pduTypeVersionHigh = -1;
static int hf_rdp_pduSource = -1;
static int hf_rdp_shareId = -1;
static int hf_rdp_pad1 = -1;
static int hf_rdp_streamId = -1;
static int hf_rdp_uncompressedLength = -1;
static int hf_rdp_pduType2 = -1;
static int hf_rdp_compressedType = -1;
static int hf_rdp_compressedTypeType = -1;
static int hf_rdp_compressedTypeCompressed = -1;
static int hf_rdp_compressedTypeAtFront = -1;
static int hf_rdp_compressedTypeFlushed = -1;
static int hf_rdp_compressedLength = -1;
static int hf_rdp_wErrorCode = -1;
static int hf_rdp_wStateTransition = -1;
static int hf_rdp_numberEntries = -1;
static int hf_rdp_totalNumberEntries = -1;
static int hf_rdp_mapFlags = -1;
static int hf_rdp_fontMapFirst = -1;
static int hf_rdp_fontMapLast = -1;
/* Control */
static int hf_rdp_action = -1;
static int hf_rdp_grantId = -1;
static int hf_rdp_controlId = -1;
/* Synchronize */
static int hf_rdp_messageType = -1;
static int hf_rdp_targetUser = -1;
/* BitmapCache Persistent List */
static int hf_rdp_numEntriesCache0 = -1;
static int hf_rdp_numEntriesCache1 = -1;
static int hf_rdp_numEntriesCache2 = -1;
static int hf_rdp_numEntriesCache3 = -1;
static int hf_rdp_numEntriesCache4 = -1;
static int hf_rdp_totalEntriesCache0 = -1;
static int hf_rdp_totalEntriesCache1 = -1;
static int hf_rdp_totalEntriesCache2 = -1;
static int hf_rdp_totalEntriesCache3 = -1;
static int hf_rdp_totalEntriesCache4 = -1;
static int hf_rdp_bBitMask = -1;
static int hf_rdp_Pad2 = -1;
static int hf_rdp_Pad3 = -1;
/* BitmapCache Persistent List Entry */
/* static int hf_rdp_Key1 = -1; */
/* static int hf_rdp_Key2 = -1; */
/* FontList */
#if 0
static int hf_rdp_numberFonts = -1;
static int hf_rdp_totalNumFonts = -1;
static int hf_rdp_listFlags = -1;
#endif
static int hf_rdp_entrySize = -1;
/* Confirm Active PDU */
static int hf_rdp_originatorId = -1;
static int hf_rdp_lengthSourceDescriptor = -1;
static int hf_rdp_lengthCombinedCapabilities = -1;
static int hf_rdp_sourceDescriptor = -1;
static int hf_rdp_numberCapabilities = -1;
static int hf_rdp_pad2Octets = -1;
static int hf_rdp_capabilitySet = -1;
static int hf_rdp_capabilitySetType = -1;
static int hf_rdp_lengthCapability = -1;
static int hf_rdp_capabilityData = -1;
static int hf_rdp_sessionId = -1;
/* static int hf_rdp_unknownData = -1; */
static int hf_rdp_notYetImplemented = -1;
static int hf_rdp_encrypted = -1;
/* static int hf_rdp_compressed = -1; */
static int hf_rdp_channelDefArray = -1;
static int hf_rdp_channelDef = -1;
static int hf_rdp_name = -1;
static int hf_rdp_options = -1;
static int hf_rdp_optionsInitialized = -1;
static int hf_rdp_optionsEncryptRDP = -1;
static int hf_rdp_optionsEncryptSC = -1;
static int hf_rdp_optionsEncryptCS = -1;
static int hf_rdp_optionsPriHigh = -1;
static int hf_rdp_optionsPriMed = -1;
static int hf_rdp_optionsPriLow = -1;
static int hf_rdp_optionsCompressRDP = -1;
static int hf_rdp_optionsCompress = -1;
static int hf_rdp_optionsShowProtocol= -1;
static int hf_rdp_optionsRemoteControlPersistent = -1;
static int hf_rdp_channelPDUHeader = -1;
static int hf_rdp_channelFlags = -1;
static int hf_rdp_channelFlagFirst = -1;
static int hf_rdp_channelFlagLast = -1;
static int hf_rdp_channelFlagShowProtocol = -1;
static int hf_rdp_channelFlagSuspend = -1;
static int hf_rdp_channelFlagResume = -1;
static int hf_rdp_channelPacketCompressed = -1;
static int hf_rdp_channelPacketAtFront = -1;
static int hf_rdp_channelPacketFlushed = -1;
static int hf_rdp_channelPacketCompressionType = -1;
static int hf_rdp_virtualChannelData = -1;
static int hf_rdp_wYear = -1;
static int hf_rdp_wMonth = -1;
static int hf_rdp_wDayOfWeek = -1;
static int hf_rdp_wDay = -1;
static int hf_rdp_wHour = -1;
static int hf_rdp_wMinute = -1;
static int hf_rdp_wSecond = -1;
static int hf_rdp_wMilliseconds = -1;
static int hf_rdp_Bias = -1;
static int hf_rdp_StandardName = -1;
static int hf_rdp_StandardDate = -1;
static int hf_rdp_StandardBias = -1;
static int hf_rdp_DaylightName = -1;
static int hf_rdp_DaylightDate = -1;
static int hf_rdp_DaylightBias = -1;
static int hf_rdp_unused = -1;
#define CS_CORE 0xC001
#define CS_SECURITY 0xC002
#define CS_NET 0xC003
#define CS_CLUSTER 0xC004
#define CS_MONITOR 0xC005
#define CS_MCS_MSGCHANNEL 0xC006
#define CS_MONITOR_EX 0xC008
#define CS_MULTITRANSPORT 0xC00A
#define SC_CORE 0x0C01
#define SC_SECURITY 0x0C02
#define SC_NET 0x0C03
#define SC_MCS_MSGCHANNEL 0x0C04
#define SC_MULTITRANSPORT 0x0C08
#define SEC_EXCHANGE_PKT 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_RESET_SEQNO 0x0010
#define SEC_IGNORE_SEQNO 0x0020
#define SEC_INFO_PKT 0x0040
#define SEC_LICENSE_PKT 0x0080
#define SEC_LICENSE_ENCRYPT_CS 0x0200
#define SEC_LICENSE_ENCRYPT_SC 0x0200
#define SEC_REDIRECTION_PKT 0x0400
#define SEC_SECURE_CHECKSUM 0x0800
#define SEC_FLAGSHI_VALID 0x8000
#define SEC_PKT_MASK 0x04c1
#define ENCRYPTION_METHOD_NONE 0x00000000
#define ENCRYPTION_METHOD_40BIT 0x00000001
#define ENCRYPTION_METHOD_128BIT 0x00000002
#define ENCRYPTION_METHOD_56BIT 0x00000008
#define ENCRYPTION_METHOD_FIPS 0x00000010
#define ENCRYPTION_LEVEL_NONE 0x00000000
#define ENCRYPTION_LEVEL_LOW 0x00000001
#define ENCRYPTION_LEVEL_CLIENT_COMPATIBLE 0x00000002
#define ENCRYPTION_LEVEL_HIGH 0x00000003
#define ENCRYPTION_LEVEL_FIPS 0x00000004
/* sent by server */
#define LICENSE_REQUEST 0x01
#define PLATFORM_CHALLENGE 0x02
#define NEW_LICENSE 0x03
#define UPGRADE_LICENSE 0x04
/* sent by client */
#define LICENSE_INFO 0x12
#define NEW_LICENSE_REQUEST 0x13
#define PLATFORM_CHALLENGE_RESPONSE 0x15
/* sent by either */
#define ERROR_ALERT 0xff
#define ERR_INVALID_SERVER_CERTIFICIATE 0x00000001
#define ERR_NO_LICENSE 0x00000002
#define ERR_INVALID_MAC 0x00000003
#define ERR_INVALID_SCOPE 0x00000004
#define ERR_NO_LICENSE_SERVER 0x00000006
#define STATUS_VALID_CLIENT 0x00000007
#define ERR_INVALID_CLIENT 0x00000008
#define ERR_INVALID_PRODUCTID 0x0000000B
#define ERR_INVALID_MESSAGE_LEN 0x0000000C
#define ST_TOTAL_ABORT 0x00000001
#define ST_NO_TRANSITION 0x00000002
#define ST_RESET_PHASE_TO_START 0x00000003
#define ST_RESEND_LAST_MESSAGE 0x00000004
#define BB_DATA_BLOB 0x0001
#define BB_RANDOM_BLOB 0x0002
#define BB_CERTIFICATE_BLOB 0x0003
#define BB_ERROR_BLOB 0x0004
#define BB_ENCRYPTED_DATA_BLOB 0x0009
#define BB_KEY_EXCHG_ALG_BLOB 0x000D
#define BB_SCOPE_BLOB 0x000E
#define BB_CLIENT_USER_NAME_BLOB 0x000F
#define BB_CLIENT_MACHINE_NAME_BLOB 0x0010
#define PDUTYPE_TYPE_MASK 0x000F
#define PDUTYPE_VERSIONLOW_MASK 0x00F0
#define PDUTYPE_VERSIONHIGH_MASK 0xFF00
#define PDUTYPE_DEMANDACTIVEPDU 0x1
#define PDUTYPE_CONFIRMACTIVEPDU 0x3
#define PDUTYPE_DEACTIVATEALLPDU 0x6
#define PDUTYPE_DATAPDU 0x7
#define PDUTYPE_SERVER_REDIR_PKT 0xA
#define TS_PROTOCOL_VERSION 0x1
#define PDUTYPE2_UPDATE 0x02
#define PDUTYPE2_CONTROL 0x14
#define PDUTYPE2_POINTER 0x1B
#define PDUTYPE2_INPUT 0x1C
#define PDUTYPE2_SYNCHRONIZE 0x1F
#define PDUTYPE2_REFRESH_RECT 0x21
#define PDUTYPE2_PLAY_SOUND 0x22
#define PDUTYPE2_SUPPRESS_OUTPUT 0x23
#define PDUTYPE2_SHUTDOWN_REQUEST 0x24
#define PDUTYPE2_SHUTDOWN_DENIED 0x25
#define PDUTYPE2_SAVE_SESSION_INFO 0x26
#define PDUTYPE2_FONTLIST 0x27
#define PDUTYPE2_FONTMAP 0x28
#define PDUTYPE2_SET_KEYBOARD_INDICATORS 0x29
#define PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST 0x2B
#define PDUTYPE2_BITMAPCACHE_ERROR_PDU 0x2C
#define PDUTYPE2_SET_KEYBOARD_IME_STATUS 0x2D
#define PDUTYPE2_OFFSCRCACHE_ERROR_PDU 0x2E
#define PDUTYPE2_SET_ERROR_INFO_PDU 0x2F
#define PDUTYPE2_DRAWNINEGRID_ERROR_PDU 0x30
#define PDUTYPE2_DRAWGDIPLUS_ERROR_PDU 0x31
#define PDUTYPE2_ARC_STATUS_PDU 0x32
#define PDUTYPE2_STATUS_INFO_PDU 0x36
#define PDUTYPE2_MONITOR_LAYOUT_PDU 0x37
#define PACKET_COMPRESSED 0x20
#define PACKET_AT_FRONT 0x40
#define PACKET_FLUSHED 0x80
#define PacketCompressionTypeMask 0x0f
#define PACKET_COMPR_TYPE_8K 0x0
#define PACKET_COMPR_TYPE_64K 0x1
#define PACKET_COMPR_TYPE_RDP6 0x2
#define PACKET_COMPR_TYPE_RDP61 0x3
#define CHANNEL_FLAG_FIRST 0x00000001
#define CHANNEL_FLAG_LAST 0x00000002
#define CHANNEL_FLAG_SHOW_PROTOCOL 0x00000010
#define CHANNEL_FLAG_SUSPEND 0x00000020
#define CHANNEL_FLAG_RESUME 0x00000040
#define CHANNEL_PACKET_COMPRESSED 0x00200000
#define CHANNEL_PACKET_AT_FRONT 0x00400000
#define CHANNEL_PACKET_FLUSHED 0x00800000
#define ChannelCompressionTypeMask 0x000f0000
#define CHANNEL_COMPR_TYPE_8K 0x00000000
#define CHANNEL_COMPR_TYPE_64K 0x00010000
#define CHANNEL_COMPR_TYPE_RDP6 0x00020000
#define CHANNEL_COMPR_TYPE_RDP61 0x00030000
#define MapFlagsMask 0xffff
#define FONTMAP_FIRST 0x0001
#define FONTMAP_LAST 0x0002
/* There may well be others */
#define CTRLACTION_REQUEST_CONTROL 0x0001
#define CTRLACTION_GRANTED_CONTROL 0x0002
#define CTRLACTION_DETACH 0x0003
#define CTRLACTION_COOPERATE 0x0004
#define CAPSTYPE_GENERAL 0x0001
#define CAPSTYPE_BITMAP 0x0002
#define CAPSTYPE_ORDER 0x0003
#define CAPSTYPE_BITMAPCACHE 0x0004
#define CAPSTYPE_CONTROL 0x0005
#define CAPSTYPE_ACTIVATION 0x0007
#define CAPSTYPE_POINTER 0x0008
#define CAPSTYPE_SHARE 0x0009
#define CAPSTYPE_COLORCACHE 0x000A
#define CAPSTYPE_SOUND 0x000C
#define CAPSTYPE_INPUT 0x000D
#define CAPSTYPE_FONT 0x000E
#define CAPSTYPE_BRUSH 0x000F
#define CAPSTYPE_GLYPHCACHE 0x0010
#define CAPSTYPE_OFFSCREENCACHE 0x0011
#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT 0x0012
#define CAPSTYPE_BITMAPCACHE_REV2 0x0013
#define CAPSTYPE_BITMAPCACHE_VIRTUALCHANNEL 0x0014
#define CAPSTYPE_DRAWNINEGRIDCACHE 0x0015
#define CAPSTYPE_DRAWGDIPLUS 0x0016
#define CAPSTYPE_RAIL 0x0017
#define CAPSTYPE_WINDOW 0x0018
#define CAPSTYPE_COMPDESK 0x0019
#define CAPSTYPE_MULTIFRAGMENTUPDATE 0x001A
#define CAPSTYPE_LARGE_POINTER 0x001B
#define CAPSTYPE_SURFACE_COMMANDS 0x001C
#define CAPSTYPE_BITMAP_CODECS 0x001D
#define CHANNEL_OPTION_INITIALIZED 0x80000000
#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
#define CHANNEL_OPTION_ENCRYPT_SC 0x20000000
#define CHANNEL_OPTION_ENCRYPT_CS 0x10000000
#define CHANNEL_OPTION_PRI_HIGH 0x08000000
#define CHANNEL_OPTION_PRI_MED 0x04000000
#define CHANNEL_OPTION_PRI_LOW 0x02000000
#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
#define CHANNEL_OPTION_COMPRESS 0x00400000
#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
#define CHANNEL_OPTION_REMOTE_CONTROL_PERSISTENT 0x00100000
#define MAX_CHANNELS 31
typedef struct rdp_conv_info_t {
guint32 staticChannelId;
guint32 encryptionMethod;
guint32 encryptionLevel;
guint32 licenseAgreed;
guint8 maxChannels;
value_string channels[MAX_CHANNELS+1]; /* we may need to hold more information later */
} rdp_conv_info_t;
#define RDP_FI_NONE 0x00
#define RDP_FI_OPTIONAL 0x01
#define RDP_FI_STRING 0x02
#define RDP_FI_UNICODE 0x04 /* field is always Unicode (UTF-16) */
#define RDP_FI_ANSI 0x08 /* field is always ANSI (code page) */
#define RDP_FI_NOINCOFFSET 0x10 /* do not increase the offset */
#define RDP_FI_SUBTREE 0x20
#define RDP_FI_INFO_FLAGS 0x40
typedef struct rdp_field_info_t {
const int *pfield;
gint32 fixedLength;
guint32 *variableLength;
int offsetOrTree;
guint32 flags;
const struct rdp_field_info_t *subfields;
} rdp_field_info_t;
#define FI_FIXEDLEN(_hf_, _len_) { _hf_, _len_, NULL, 0, 0, NULL }
#define FI_FIXEDLEN_ANSI_STRING(_hf_, _len_) { _hf_, _len_, NULL, 0, RDP_FI_STRING|RDP_FI_ANSI, NULL }
#define FI_VALUE(_hf_, _len_, _value_) { _hf_, _len_, &_value_, 0, 0, NULL }
#define FI_VARLEN(_hf, _length_) { _hf_, 0, &_length_, 0, 0, NULL }
#define FI_SUBTREE(_hf_, _len_, _ett_, _sf_) { _hf_, _len_, NULL, _ett_, RDP_FI_SUBTREE, _sf_ }
#define FI_TERMINATOR {NULL, 0, NULL, 0, 0, NULL}
static const value_string rdp_headerType_vals[] = {
{ CS_CORE, "clientCoreData" },
{ CS_SECURITY, "clientSecurityData" },
{ CS_NET, "clientNetworkData" },
{ CS_CLUSTER, "clientClusterData" },
{ CS_MONITOR, "clientMonitorData" },
{ CS_MCS_MSGCHANNEL, "clientMsgChannelData" },
{ CS_MONITOR_EX, "clientMonitorExData" },
{ CS_MULTITRANSPORT, "clientMultiTransportData" },
{ SC_CORE, "serverCoreData" },
{ SC_SECURITY, "serverSecurityData" },
{ SC_NET, "serverNetworkData" },
{ SC_MCS_MSGCHANNEL, "serverMsgChannelData" },
{ SC_MULTITRANSPORT, "serverMultiTransportData" },
{ 0, NULL }
};
static const value_string rdp_colorDepth_vals[] = {
{ 0xCA00, "4 bits-per-pixel (bpp)"},
{ 0xCA01, "8 bits-per-pixel (bpp)"},
{ 0xCA02, "15-bit 555 RGB mask"},
{ 0xCA03, "16-bit 565 RGB mask"},
{ 0xCA04, "24-bit RGB mask"},
{ 0, NULL }
};
static const value_string rdp_highColorDepth_vals[] = {
{ 0x0004, "4 bits-per-pixel (bpp)"},
{ 0x0008, "8 bits-per-pixel (bpp)"},
{ 0x000F, "15-bit 555 RGB mask"},
{ 0x0010, "16-bit 565 RGB mask"},
{ 0x0018, "24-bit RGB mask"},
{ 0, NULL }
};
static const value_string rdp_keyboardType_vals[] = {
{ 1, "IBM PC/XT or compatible (83-key) keyboard" },
{ 2, "Olivetti \"ICO\" (102-key) keyboard" },
{ 3, "IBM PC/AT (84-key) and similar keyboards" },
{ 4, "IBM enhanced (101-key or 102-key) keyboard" },
{ 5, "Noki 1050 and similar keyboards" },
{ 6, "Nokia 9140 and similar keyboards" },
{ 7, "Japanese keyboard" },
{ 0, NULL }
};
static const value_string rdp_connectionType_vals[] = {
{ 1, "Modem (56 Kbps)" },
{ 2, "Low-speed broadband (256 Kbps - 2Mbps)" },
{ 3, "Satellite (2 Mbps - 16Mbps with high latency)" },
{ 4, "High-speed broadband (2 Mbps - 10Mbps)" },
{ 5, "WAN (10 Mbps or higher with high latency)" },
{ 6, "LAN (10 Mbps or higher)" },
{ 7, "Auto Detect" },
{ 0, NULL},
};
static const value_string rdp_requestedProtocols_vals[] = {
{ 0, "Standard RDP Security" },
{ 1, "TLS 1.0" },
{ 2, "Credential Security Support Provider protocol (CredSSP)" },
{ 3, "Credential Security Support Provider protocol (CredSSP)" },
{ 0, NULL},
};
static const value_string rdp_flagsPkt_vals[] = {
{0, "(None)" },
{SEC_EXCHANGE_PKT, "Security Exchange PDU" },
{SEC_INFO_PKT, "Client Info PDU" },
{SEC_LICENSE_PKT, "Licensing PDU" },
{SEC_REDIRECTION_PKT, "Standard Security Server Redirection PDU"},
{0, NULL},
};
static const value_string rdp_encryptionMethod_vals[] = {
{ ENCRYPTION_METHOD_NONE, "None" },
{ ENCRYPTION_METHOD_40BIT, "40-bit RC4" },
{ ENCRYPTION_METHOD_128BIT, "128-bit RC4" },
{ ENCRYPTION_METHOD_56BIT, "56-bit RC4" },
{ ENCRYPTION_METHOD_FIPS, "FIPS140-1 3DES" },
{ 0, NULL},
};
static const value_string rdp_encryptionLevel_vals[] = {
{ ENCRYPTION_LEVEL_NONE, "None" },
{ ENCRYPTION_LEVEL_LOW, "Low" },
{ ENCRYPTION_LEVEL_CLIENT_COMPATIBLE, "Client Compatible" },
{ ENCRYPTION_LEVEL_HIGH, "High" },
{ ENCRYPTION_LEVEL_FIPS, "FIPS140-1" },
{ 0, NULL},
};
static const value_string rdp_bMsgType_vals[] = {
{ LICENSE_REQUEST, "License Request" },
{ PLATFORM_CHALLENGE, "Platform Challenge" },
{ NEW_LICENSE, "New License" },
{ UPGRADE_LICENSE, "Upgrade License" },
{ LICENSE_INFO, "License Info" },
{ NEW_LICENSE_REQUEST, "New License Request" },
{ PLATFORM_CHALLENGE_RESPONSE, "Platform Challenge Response" },
{ ERROR_ALERT, "Error Alert" },
{ 0, NULL},
};
static const value_string rdp_wErrorCode_vals[] = {
{ ERR_INVALID_SERVER_CERTIFICIATE, "Invalid Server Certificate" },
{ ERR_NO_LICENSE, "No License" },
{ ERR_INVALID_MAC, "Invalid MAC" },
{ ERR_INVALID_SCOPE, "Invalid Scope" },
{ ERR_NO_LICENSE_SERVER, "No License Server" },
{ STATUS_VALID_CLIENT, "Valid Client" },
{ ERR_INVALID_CLIENT, "Invalid Client" },
{ ERR_INVALID_PRODUCTID, "Invalid Product Id" },
{ ERR_INVALID_MESSAGE_LEN, "Invalid Message Length" },
{ 0, NULL},
};
static const value_string rdp_wStateTransition_vals[] = {
{ ST_TOTAL_ABORT, "Total Abort" },
{ ST_NO_TRANSITION, "No Transition" },
{ ST_RESET_PHASE_TO_START, "Reset Phase to Start" },
{ ST_RESEND_LAST_MESSAGE, "Resend Last Message" },
{ 0, NULL},
};
static const value_string rdp_wBlobType_vals[] = {
{ BB_DATA_BLOB, "Data" },
{ BB_RANDOM_BLOB, "Random" },
{ BB_CERTIFICATE_BLOB, "Certificate" },
{ BB_ERROR_BLOB, "Error" },
{ BB_ENCRYPTED_DATA_BLOB, "Encrypted Data" },
{ BB_KEY_EXCHG_ALG_BLOB, "Key Exchange Algorithm" },
{ BB_SCOPE_BLOB, "Scope" },
{ BB_CLIENT_USER_NAME_BLOB, "Client User Name" },
{ BB_CLIENT_MACHINE_NAME_BLOB, "Client Machine Name" },
{ 0, NULL},
};
static const value_string rdp_pduTypeType_vals[] = {
{ PDUTYPE_DEMANDACTIVEPDU, "Demand Active PDU" },
{ PDUTYPE_CONFIRMACTIVEPDU, "Confirm Active PDU" },
{ PDUTYPE_DEACTIVATEALLPDU, "Deactivate All PDU" },
{ PDUTYPE_DATAPDU, "Data PDU" },
{ PDUTYPE_SERVER_REDIR_PKT, "Server Redirection PDU" },
{ 0, NULL},
};
static const value_string rdp_pduType2_vals[] = {
{ PDUTYPE2_UPDATE, "Update"},
{ PDUTYPE2_CONTROL, "Control"},
{ PDUTYPE2_POINTER, "Pointer"},
{ PDUTYPE2_INPUT, "Input"},
{ PDUTYPE2_SYNCHRONIZE, "Synchronize"},
{ PDUTYPE2_REFRESH_RECT, "Refresh Rect"},
{ PDUTYPE2_PLAY_SOUND, "Play Sound"},
{ PDUTYPE2_SUPPRESS_OUTPUT, "Suppress Output"},
{ PDUTYPE2_SHUTDOWN_REQUEST, "Shutdown Request" },
{ PDUTYPE2_SHUTDOWN_DENIED, "Shutdown Denied" },
{ PDUTYPE2_SAVE_SESSION_INFO, "Save Session Info" },
{ PDUTYPE2_FONTLIST, "FontList" },
{ PDUTYPE2_FONTMAP, "FontMap" },
{ PDUTYPE2_SET_KEYBOARD_INDICATORS, "Set Keyboard Indicators" },
{ PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST, "BitmapCache Persistent List" },
{ PDUTYPE2_BITMAPCACHE_ERROR_PDU, "BitmapCache Error" },
{ PDUTYPE2_SET_KEYBOARD_IME_STATUS, "Set Keyboard IME Status" },
{ PDUTYPE2_OFFSCRCACHE_ERROR_PDU, "OffScrCache Error" },
{ PDUTYPE2_SET_ERROR_INFO_PDU, "Set Error Info" },
{ PDUTYPE2_DRAWNINEGRID_ERROR_PDU, "DrawNineGrid Error" },
{ PDUTYPE2_DRAWGDIPLUS_ERROR_PDU, "DrawGDIPlus Error" },
{ PDUTYPE2_ARC_STATUS_PDU, "Arc Status" },
{ PDUTYPE2_STATUS_INFO_PDU, "Status Info" },
{ PDUTYPE2_MONITOR_LAYOUT_PDU, "Monitor Layout" },
{ 0, NULL},
};
static const value_string rdp_compressionType_vals[] = {
{ PACKET_COMPR_TYPE_8K, "RDP 4.0 bulk compression" },
{ PACKET_COMPR_TYPE_64K, "RDP 5.0 bulk compression" },
{ PACKET_COMPR_TYPE_RDP6, "RDP 6.0 bulk compression" },
{ PACKET_COMPR_TYPE_RDP61, "RDP 6.1 bulk compression" },
{ 0, NULL},
};
static const value_string rdp_channelCompressionType_vals[] = {
{ CHANNEL_COMPR_TYPE_8K, "RDP 4.0 bulk compression" },
{ CHANNEL_COMPR_TYPE_64K, "RDP 5.0 bulk compression" },
{ CHANNEL_COMPR_TYPE_RDP6, "RDP 6.0 bulk compression" },
{ CHANNEL_COMPR_TYPE_RDP61, "RDP 6.1 bulk compression" },
{ 0, NULL},
};
static const value_string rdp_action_vals[] = {
{ CTRLACTION_REQUEST_CONTROL, "Request control" },
{ CTRLACTION_GRANTED_CONTROL, "Granted control" },
{ CTRLACTION_DETACH, "Detach" },
{ CTRLACTION_COOPERATE, "Cooperate" },
{0, NULL },
};
static const value_string rdp_capabilityType_vals[] = {
{ CAPSTYPE_GENERAL, "General" },
{ CAPSTYPE_BITMAP, "Bitmap" },
{ CAPSTYPE_ORDER, "Order" },
{ CAPSTYPE_BITMAPCACHE, "Bitmap Cache" },
{ CAPSTYPE_CONTROL, "Control" },
{ CAPSTYPE_ACTIVATION, "Activation" },
{ CAPSTYPE_POINTER, "Pointer" },
{ CAPSTYPE_SHARE, "Share" },
{ CAPSTYPE_COLORCACHE, "Color Cache" },
{ CAPSTYPE_SOUND, "Sound" },
{ CAPSTYPE_INPUT, "Input" },
{ CAPSTYPE_FONT, "Font" },
{ CAPSTYPE_BRUSH, "Brush" },
{ CAPSTYPE_GLYPHCACHE, "Glyph Cache" },
{ CAPSTYPE_OFFSCREENCACHE, "Off-screen Cache" },
{ CAPSTYPE_BITMAPCACHE_HOSTSUPPORT, "Bitmap Cache Host Support" },
{ CAPSTYPE_BITMAPCACHE_REV2, "Bitmap Cache Rev 2" },
{ CAPSTYPE_BITMAPCACHE_VIRTUALCHANNEL, "Virtual Channel"},
{ CAPSTYPE_DRAWNINEGRIDCACHE, "Draw Nine Grid Cache" },
{ CAPSTYPE_DRAWGDIPLUS, "Draw GDI Plus" },
{ CAPSTYPE_RAIL, "Rail" },
{ CAPSTYPE_WINDOW, "Window" },
{ CAPSTYPE_COMPDESK, "Comp Desk" },
{ CAPSTYPE_MULTIFRAGMENTUPDATE, "Multi-Fragment Update" },
{ CAPSTYPE_LARGE_POINTER, "Large Pointer" },
{ CAPSTYPE_SURFACE_COMMANDS, "Surface Commands" },
{ CAPSTYPE_BITMAP_CODECS, "Bitmap Codecs" },
{0, NULL },
};
static const value_string rdp_wDayOfWeek_vals[] = {
{ 0, "Sunday" },
{ 1, "Monday" },
{ 2, "Tuesday" },
{ 3, "Wednesday" },
{ 4, "Thursday" },
{ 5, "Friday" },
{ 6, "Saturday" },
{0, NULL },
};
static const value_string rdp_wDay_vals[] = {
{ 1, "First occurrence" },
{ 2, "Second occurrence" },
{ 3, "Third occurrence" },
{ 4, "Fourth occurrence" },
{ 5, "Last occurrence" },
{0, NULL },
};
static const value_string rdp_wMonth_vals[] = {
{ 1, "January" },
{ 2, "February" },
{ 3, "March" },
{ 4, "April" },
{ 5, "May" },
{ 6, "June" },
{ 7, "July" },
{ 8, "August" },
{ 9, "September" },
{ 10, "October" },
{ 11, "November" },
{ 12, "December" },
{0, NULL },
};
/*
* Flags in the flags field of a TS_INFO_PACKET.
* XXX - define more, and show them underneath that field.
*/
#define INFO_UNICODE 0x00000010
static rdp_conv_info_t *
rdp_get_conversation_data(packet_info *pinfo)
{
conversation_t *conversation;
rdp_conv_info_t *rdp_info;
conversation = find_or_create_conversation(pinfo);
rdp_info = (rdp_conv_info_t *)conversation_get_proto_data(conversation, proto_rdp);
if (rdp_info == NULL) {
rdp_info = wmem_new0(wmem_file_scope(), rdp_conv_info_t);
rdp_info->staticChannelId = -1;
rdp_info->encryptionMethod = 0;
rdp_info->encryptionLevel = 0;
rdp_info->licenseAgreed = 0;
rdp_info->maxChannels = 0;
conversation_add_proto_data(conversation, proto_rdp, rdp_info);
}
return rdp_info;
}
static int
dissect_rdp_fields(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const rdp_field_info_t *fields, int totlen)
{
const rdp_field_info_t *c;
gint len;
int base_offset = offset;
guint32 info_flags = 0;
guint encoding;
while (((c = fields++)->pfield) != NULL) {
if ((c->fixedLength == 0) && (c->variableLength)) {
len = *(c->variableLength);
} else {
len = c->fixedLength;
if ((c->variableLength) && (c->fixedLength <= 4)) {
switch (c->fixedLength) {
case 1:
*(c->variableLength) = tvb_get_guint8(tvb, offset);
break;
case 2:
*(c->variableLength) = tvb_get_letohs(tvb, offset);
break;
case 4:
*(c->variableLength) = tvb_get_letohl(tvb, offset);
break;
default:
REPORT_DISSECTOR_BUG("Invalid length");
}
*(c->variableLength) += c->offsetOrTree; /* XXX: ??? */
}
}
if (len) {
proto_item *pi;
if (c->flags & RDP_FI_STRING) {
/* If this is always Unicode, or if the INFO_UNICODE flag is set,
treat this as UTF-16; otherwise, treat it as "ANSI". */
if (c->flags & RDP_FI_UNICODE)
encoding = ENC_UTF_16|ENC_LITTLE_ENDIAN;
else if (c->flags & RDP_FI_ANSI)
encoding = ENC_ASCII|ENC_NA; /* XXX - code page */
else {
/* Could be Unicode, could be ANSI, based on INFO_UNICODE flag */
encoding = (info_flags & INFO_UNICODE) ? ENC_UTF_16|ENC_LITTLE_ENDIAN : ENC_ASCII|ENC_NA; /* XXX - code page */
}
} else
encoding = ENC_LITTLE_ENDIAN;
pi = proto_tree_add_item(tree, *c->pfield, tvb, offset, len, encoding);
if (c->flags & RDP_FI_INFO_FLAGS) {
/* TS_INFO_PACKET flags field; save it for later use */
DISSECTOR_ASSERT(len == 4);
info_flags = tvb_get_letohl(tvb, offset);
}
if (c->flags & RDP_FI_SUBTREE) {
proto_tree *next_tree;
if (c->offsetOrTree != -1)
next_tree = proto_item_add_subtree(pi, c->offsetOrTree);
else
REPORT_DISSECTOR_BUG("Tree Error!!");
if (c->subfields)
dissect_rdp_fields(tvb, offset, pinfo, next_tree, c->subfields, 0);
}
if (!(c->flags & RDP_FI_NOINCOFFSET))
offset += len;
}
if ((totlen > 0) && ((offset-base_offset) >= totlen))
break; /* we're done: skip optional fields */
/* XXX: err if > totlen ?? */
}
return offset;
}
static int
dissect_rdp_nyi(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char *info)
{
rdp_field_info_t nyi_fields[] = {
{&hf_rdp_notYetImplemented, -1, NULL, 0, 0, NULL },
FI_TERMINATOR
};
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, nyi_fields, 0);
if ((tree != NULL) && (info != NULL))
proto_item_append_text(tree->last_child, " (%s)", info);
return offset;
}
static int
dissect_rdp_encrypted(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char *info)
{
rdp_field_info_t enc_fields[] = {
{&hf_rdp_encrypted, -1, NULL, 0, 0, NULL },
FI_TERMINATOR
};
offset = dissect_rdp_fields(tvb, offset,pinfo, tree, enc_fields, 0);
if ((tree != NULL) && (info != NULL))
proto_item_append_text(tree->last_child, " (%s)", info);
col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "[Encrypted]");
return offset;
}
static int
dissect_rdp_clientNetworkData(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint length, rdp_conv_info_t *rdp_info)
{
proto_tree *next_tree;
proto_item *pi;
guint32 channelCount = 0;
rdp_field_info_t net_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
FI_VALUE(&hf_rdp_channelCount, 4, channelCount),
FI_TERMINATOR
};
rdp_field_info_t option_fields[] = {
{&hf_rdp_optionsInitialized, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsEncryptRDP, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsEncryptSC, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsEncryptCS, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsPriHigh, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsPriMed, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsPriLow, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsCompressRDP, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsCompress, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsShowProtocol, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_optionsRemoteControlPersistent, 4, NULL, 0, 0, NULL },
FI_TERMINATOR,
};
rdp_field_info_t channel_fields[] = {
FI_FIXEDLEN_ANSI_STRING(&hf_rdp_name, 8),
FI_SUBTREE(&hf_rdp_options, 4, ett_rdp_options, option_fields),
FI_TERMINATOR
};
rdp_field_info_t def_fields[] = {
FI_SUBTREE(&hf_rdp_channelDef, 12, ett_rdp_channelDef, channel_fields),
FI_TERMINATOR
};
pi = proto_tree_add_item(tree, hf_rdp_clientNetworkData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientNetworkData);
offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, net_fields, 0);
if (channelCount > 0) {
guint i;
pi = proto_tree_add_item(next_tree, hf_rdp_channelDefArray, tvb, offset, channelCount * 12, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_channelDefArray);
if (rdp_info)
rdp_info->maxChannels = MIN(channelCount, MAX_CHANNELS);
for (i = 0; i < MIN(channelCount, MAX_CHANNELS); i++) {
if (rdp_info) {
rdp_info->channels[i].value = -1; /* unset */
rdp_info->channels[i].strptr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 8, ENC_ASCII);
}
offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, def_fields, 0);
}
if (rdp_info) {
/* value_strings are normally terminated with a {0, NULL} entry */
rdp_info->channels[i].value = 0;
rdp_info->channels[i].strptr = NULL;
}
}
return offset;
}
static int
dissect_rdp_basicSecurityHeader(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 *flags_ptr) {
guint32 flags = 0;
rdp_field_info_t secFlags_fields[] = {
{&hf_rdp_flagsPkt, 2, &flags, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsEncrypt, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsResetSeqno, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsIgnoreSeqno, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsLicenseEncrypt,2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsSecureChecksum,2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsFlagsHiValid, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
FI_TERMINATOR
};
rdp_field_info_t flags_fields[] = {
FI_SUBTREE(&hf_rdp_flags, 2, ett_rdp_flags, secFlags_fields),
FI_FIXEDLEN(&hf_rdp_flagsHi, 2),
FI_TERMINATOR
};
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, flags_fields, 0);
if (flags_ptr)
*flags_ptr = flags;
return offset;
}
static int
dissect_rdp_securityHeader(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rdp_conv_info_t *rdp_info, gboolean alwaysBasic, guint32 *flags_ptr) {
rdp_field_info_t fips_fields[] = {
{&hf_rdp_fipsLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_fipsVersion, 1, NULL, 0, 0, NULL },
{&hf_rdp_padlen, 1, NULL, 0, 0, NULL },
{&hf_rdp_dataSignature, 8, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t enc_fields[] = {
{&hf_rdp_dataSignature, 8, NULL, 0, 0, NULL },
FI_TERMINATOR
};
const rdp_field_info_t *fields = NULL;
if (rdp_info) {
if (alwaysBasic || (rdp_info->encryptionLevel != ENCRYPTION_LEVEL_NONE))
offset = dissect_rdp_basicSecurityHeader(tvb, offset, pinfo, tree, flags_ptr);
if (rdp_info->encryptionMethod &
(ENCRYPTION_METHOD_40BIT |
ENCRYPTION_METHOD_128BIT |
ENCRYPTION_METHOD_56BIT)) {
fields = enc_fields;
} else if (rdp_info->encryptionMethod == ENCRYPTION_METHOD_FIPS) {
fields = fips_fields;
}
if (fields)
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
}
return offset;
}
static int
dissect_rdp_channelPDU(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
guint32 length = 0;
rdp_field_info_t flag_fields[] = {
{&hf_rdp_channelFlagFirst, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelFlagLast, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelFlagShowProtocol, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelFlagSuspend, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelFlagResume, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelPacketCompressed, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelPacketAtFront, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelPacketFlushed, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_channelPacketCompressionType, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t channel_fields[] = {
FI_VALUE(&hf_rdp_length, 4, length),
FI_SUBTREE(&hf_rdp_channelFlags, 4, ett_rdp_channelFlags, flag_fields),
FI_TERMINATOR
};
rdp_field_info_t channelPDU_fields[] = {
FI_SUBTREE(&hf_rdp_channelPDUHeader, 8, ett_rdp_channelPDUHeader, channel_fields),
FI_FIXEDLEN(&hf_rdp_virtualChannelData, -1),
FI_TERMINATOR
};
/* length is the uncompressed length, and the PDU may be compressed */
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, channelPDU_fields, 0);
return offset;
}
static int
dissect_rdp_shareDataHeader(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
guint32 pduType2 = 0;
guint32 compressedType;
guint32 action = 0;
rdp_field_info_t compressed_fields[] = {
{&hf_rdp_compressedTypeType, 1, &compressedType, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_compressedTypeCompressed, 1, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_compressedTypeAtFront, 1, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_compressedTypeFlushed, 1, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t share_fields[] = {
{&hf_rdp_shareId, 4, NULL, 0, 0, NULL },
{&hf_rdp_pad1, 1, NULL, 0, 0, NULL },
{&hf_rdp_streamId, 1, NULL, 0, 0, NULL },
{&hf_rdp_uncompressedLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_pduType2, 1, &pduType2, 0, 0, NULL },
FI_SUBTREE(&hf_rdp_compressedType, 1, ett_rdp_compressedType, compressed_fields),
{&hf_rdp_compressedLength, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t control_fields[] = {
{&hf_rdp_action, 2, &action, 0, 0, NULL },
{&hf_rdp_grantId, 2, NULL, 0, 0, NULL },
{&hf_rdp_controlId, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t sync_fields[] = {
{&hf_rdp_messageType, 2, NULL, 0, 0, NULL },
{&hf_rdp_targetUser, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t mapflags_fields[] = {
{&hf_rdp_fontMapFirst, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_fontMapLast, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
FI_TERMINATOR
};
rdp_field_info_t fontmap_fields[] = {
{&hf_rdp_numberEntries, 2, NULL, 0, 0, NULL },
{&hf_rdp_totalNumberEntries, 2, NULL, 0, 0, NULL },
FI_SUBTREE(&hf_rdp_mapFlags, 2, ett_rdp_mapFlags, mapflags_fields),
{&hf_rdp_entrySize, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t persistent_fields[] = {
{&hf_rdp_numEntriesCache0, 2, NULL, 0, 0, NULL },
{&hf_rdp_numEntriesCache1, 2, NULL, 0, 0, NULL },
{&hf_rdp_numEntriesCache2, 2, NULL, 0, 0, NULL },
{&hf_rdp_numEntriesCache3, 2, NULL, 0, 0, NULL },
{&hf_rdp_numEntriesCache4, 2, NULL, 0, 0, NULL },
{&hf_rdp_totalEntriesCache0, 2, NULL, 0, 0, NULL },
{&hf_rdp_totalEntriesCache1, 2, NULL, 0, 0, NULL },
{&hf_rdp_totalEntriesCache2, 2, NULL, 0, 0, NULL },
{&hf_rdp_totalEntriesCache3, 2, NULL, 0, 0, NULL },
{&hf_rdp_totalEntriesCache4, 2, NULL, 0, 0, NULL },
{&hf_rdp_bBitMask, 1, NULL, 0, 0, NULL },
{&hf_rdp_Pad2, 1, NULL, 0, 0, NULL },
{&hf_rdp_Pad3, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
const rdp_field_info_t *fields;
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, share_fields, 0);
if (pduType2 != PDUTYPE2_CONTROL)
col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str_const(pduType2, rdp_pduType2_vals, "Unknown"));
fields = NULL;
switch(pduType2) {
case PDUTYPE2_UPDATE:
break;
case PDUTYPE2_CONTROL:
fields = control_fields;
break;
case PDUTYPE2_POINTER:
break;
case PDUTYPE2_INPUT:
break;
case PDUTYPE2_SYNCHRONIZE:
fields = sync_fields;
break;
case PDUTYPE2_REFRESH_RECT:
break;
case PDUTYPE2_PLAY_SOUND:
break;
case PDUTYPE2_SUPPRESS_OUTPUT:
break;
case PDUTYPE2_SHUTDOWN_REQUEST:
break;
case PDUTYPE2_SHUTDOWN_DENIED:
break;
case PDUTYPE2_SAVE_SESSION_INFO:
break;
case PDUTYPE2_FONTLIST:
break;
case PDUTYPE2_FONTMAP:
fields = fontmap_fields;
break;
case PDUTYPE2_SET_KEYBOARD_INDICATORS:
break;
case PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST:
fields = persistent_fields;
break;
case PDUTYPE2_BITMAPCACHE_ERROR_PDU:
break;
case PDUTYPE2_SET_KEYBOARD_IME_STATUS:
break;
case PDUTYPE2_OFFSCRCACHE_ERROR_PDU:
break;
case PDUTYPE2_SET_ERROR_INFO_PDU:
break;
case PDUTYPE2_DRAWNINEGRID_ERROR_PDU:
break;
case PDUTYPE2_DRAWGDIPLUS_ERROR_PDU:
break;
case PDUTYPE2_ARC_STATUS_PDU:
break;
case PDUTYPE2_STATUS_INFO_PDU:
break;
case PDUTYPE2_MONITOR_LAYOUT_PDU:
break;
default:
break;
}
if (fields) {
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
}
if (pduType2 == PDUTYPE2_CONTROL)
col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str_const(action, rdp_action_vals, "Unknown"));
return offset;
}
static int
dissect_rdp_capabilitySets(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 numberCapabilities) {
guint i;
guint32 lengthCapability;
rdp_field_info_t cs_fields[] = {
{&hf_rdp_capabilitySetType, 2, NULL, 0, 0, NULL },
{&hf_rdp_lengthCapability, 2, &lengthCapability, -4, 0, NULL },
{&hf_rdp_capabilityData, 0, &lengthCapability, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t set_fields[] = {
FI_SUBTREE(&hf_rdp_capabilitySet, 0, ett_rdp_capabilitySet, cs_fields),
FI_TERMINATOR
};
for (i = 0; i < numberCapabilities; i++) {
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, set_fields, 0);
}
return offset;
}
static int
dissect_rdp_demandActivePDU(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
guint32 lengthSourceDescriptor;
guint32 numberCapabilities = 0;
rdp_field_info_t fields[] = {
{&hf_rdp_shareId, 4, NULL, 0, 0, NULL },
{&hf_rdp_lengthSourceDescriptor, 2, &lengthSourceDescriptor, 0, 0, NULL },
{&hf_rdp_lengthCombinedCapabilities, 2, NULL, 0, 0, NULL },
{&hf_rdp_sourceDescriptor, 0, &lengthSourceDescriptor, 0, RDP_FI_STRING|RDP_FI_ANSI, NULL }, /* XXX - T.128 says this is T.50, which is ISO 646, which is only ASCII in its US form */
{&hf_rdp_numberCapabilities, 2, &numberCapabilities, 0, 0, NULL },
{&hf_rdp_pad2Octets, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t final_fields[] = {
{&hf_rdp_sessionId, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
offset = dissect_rdp_capabilitySets(tvb, offset, pinfo, tree, numberCapabilities);
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, final_fields, 0);
return offset;
}
static int
dissect_rdp_confirmActivePDU(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
guint32 lengthSourceDescriptor;
guint32 numberCapabilities = 0;
rdp_field_info_t fields[] = {
{&hf_rdp_shareId, 4, NULL, 0, 0, NULL },
{&hf_rdp_originatorId, 2, NULL, 0, 0, NULL },
{&hf_rdp_lengthSourceDescriptor, 2, &lengthSourceDescriptor, 0, 0, NULL },
{&hf_rdp_lengthCombinedCapabilities, 2, NULL, 0, 0, NULL },
{&hf_rdp_sourceDescriptor, 0, &lengthSourceDescriptor, 0, 0, NULL },
{&hf_rdp_numberCapabilities, 2, &numberCapabilities, 0, 0, NULL },
{&hf_rdp_pad2Octets, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
offset = dissect_rdp_capabilitySets(tvb, offset, pinfo, tree, numberCapabilities);
return offset;
}
static proto_tree *
dissect_rdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
proto_item *item;
proto_tree *tree;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDP");
col_clear(pinfo->cinfo, COL_INFO);
item = proto_tree_add_item(parent_tree, proto_rdp, tvb, 0, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_rdp);
return tree;
}
static int
dissect_rdp_SendData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
proto_item *pi;
int offset = 0;
guint32 flags = 0;
guint32 cbDomain, cbUserName, cbPassword, cbAlternateShell, cbWorkingDir,
cbClientAddress, cbClientDir, cbAutoReconnectLen, wBlobLen, pduType = 0;
guint32 bMsgType = 0xffffffff;
guint32 encryptedLen = 0;
conversation_t *conversation;
rdp_conv_info_t *rdp_info;
rdp_field_info_t secFlags_fields[] = {
{&hf_rdp_flagsPkt, 2, &flags, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsEncrypt, 2, NULL , 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsResetSeqno, 2, NULL , 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsIgnoreSeqno, 2, NULL , 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsLicenseEncrypt,2, NULL , 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsSecureChecksum,2, NULL , 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_flagsFlagsHiValid, 2, NULL , 0, RDP_FI_NOINCOFFSET, NULL },
FI_TERMINATOR
};
rdp_field_info_t se_fields[] = {
FI_SUBTREE(&hf_rdp_flags, 2, ett_rdp_flags, secFlags_fields),
FI_FIXEDLEN(&hf_rdp_flagsHi, 2),
{&hf_rdp_length, 4, &encryptedLen, 0, 0, NULL },
{&hf_rdp_encryptedClientRandom, 0, &encryptedLen, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t systime_fields [] = {
FI_FIXEDLEN(&hf_rdp_wYear , 2),
FI_FIXEDLEN(&hf_rdp_wMonth , 2),
FI_FIXEDLEN(&hf_rdp_wDayOfWeek , 2),
FI_FIXEDLEN(&hf_rdp_wDay , 2),
FI_FIXEDLEN(&hf_rdp_wHour , 2),
FI_FIXEDLEN(&hf_rdp_wMinute , 2),
FI_FIXEDLEN(&hf_rdp_wSecond , 2),
FI_FIXEDLEN(&hf_rdp_wMilliseconds, 2),
FI_TERMINATOR,
};
rdp_field_info_t tz_info_fields [] = {
FI_FIXEDLEN(&hf_rdp_Bias, 4),
{&hf_rdp_StandardName, 64, NULL, 0, RDP_FI_STRING|RDP_FI_UNICODE, NULL },
FI_SUBTREE(&hf_rdp_StandardDate, 16, ett_rdp_StandardDate, systime_fields),
FI_FIXEDLEN(&hf_rdp_StandardBias, 4),
{&hf_rdp_DaylightName, 64, NULL, 0, RDP_FI_STRING|RDP_FI_UNICODE, NULL },
FI_SUBTREE(&hf_rdp_DaylightDate, 16, ett_rdp_DaylightDate, systime_fields),
FI_FIXEDLEN(&hf_rdp_DaylightBias, 4),
FI_TERMINATOR,
};
rdp_field_info_t ue_fields[] = {
{&hf_rdp_codePage, 4, NULL, 0, 0, NULL },
{&hf_rdp_optionFlags, 4, NULL, 0, RDP_FI_INFO_FLAGS, NULL },
{&hf_rdp_cbDomain, 2, &cbDomain, 2, 0, NULL },
{&hf_rdp_cbUserName, 2, &cbUserName, 2, 0, NULL },
{&hf_rdp_cbPassword, 2, &cbPassword, 2, 0, NULL },
{&hf_rdp_cbAlternateShell, 2, &cbAlternateShell, 2, 0, NULL },
{&hf_rdp_cbWorkingDir, 2, &cbWorkingDir, 2, 0, NULL },
{&hf_rdp_domain, 0, &cbDomain, 0, RDP_FI_STRING, NULL },
{&hf_rdp_userName, 0, &cbUserName, 0, RDP_FI_STRING, NULL },
{&hf_rdp_password, 0, &cbPassword, 0, RDP_FI_STRING, NULL },
{&hf_rdp_alternateShell, 0, &cbAlternateShell, 0, RDP_FI_STRING, NULL },
{&hf_rdp_workingDir, 0, &cbWorkingDir, 0, RDP_FI_STRING, NULL },
{&hf_rdp_clientAddressFamily,2, NULL, 0, 0, NULL },
{&hf_rdp_cbClientAddress, 2, &cbClientAddress, 0, 0, NULL },
{&hf_rdp_clientAddress, 0, &cbClientAddress, 0, RDP_FI_STRING, NULL },
{&hf_rdp_cbClientDir, 2, &cbClientDir, 0, 0, NULL },
{&hf_rdp_clientDir, 0, &cbClientDir, 0, RDP_FI_STRING, NULL },
FI_SUBTREE(&hf_rdp_clientTimeZone, 172, ett_rdp_clientTimeZone, tz_info_fields),
{&hf_rdp_clientSessionId, 4, NULL, 0, 0, NULL },
{&hf_rdp_performanceFlags, 4, NULL, 0, 0, NULL },
{&hf_rdp_cbAutoReconnectLen, 2, &cbAutoReconnectLen, 0, 0, NULL },
{&hf_rdp_autoReconnectCookie,0, &cbAutoReconnectLen, 0, 0, NULL },
{&hf_rdp_reserved1, 2, NULL, 0, 0, NULL },
{&hf_rdp_reserved2, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t msg_fields[] = {
{&hf_rdp_bMsgType, 1, &bMsgType, 0, 0, NULL },
{&hf_rdp_bVersion, 1, NULL, 0, 0, NULL },
{&hf_rdp_wMsgSize, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t error_fields[] = {
{&hf_rdp_wErrorCode, 4, NULL, 0, 0, NULL },
{&hf_rdp_wStateTransition, 4, NULL, 0, 0, NULL },
{&hf_rdp_wBlobType, 2, NULL, 0, 0, NULL },
{&hf_rdp_wBlobLen, 2, &wBlobLen, 0, 0, NULL },
{&hf_rdp_blobData, 0, &wBlobLen, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t pdu_fields[] = {
{&hf_rdp_pduTypeType, 2, &pduType, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_pduTypeVersionLow, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
{&hf_rdp_pduTypeVersionHigh, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t ctrl_fields[] = {
{&hf_rdp_totalLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_pduType, 2, NULL, ett_rdp_pduType, RDP_FI_SUBTREE,
pdu_fields },
{&hf_rdp_pduSource, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
tree = dissect_rdp(tvb, pinfo, tree);
pi = proto_tree_add_item(tree, hf_rdp_SendData, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(pi, ett_rdp_SendData);
conversation = find_or_create_conversation(pinfo);
rdp_info = (rdp_conv_info_t *)conversation_get_proto_data(conversation, proto_rdp);
if (rdp_info &&
((rdp_info->licenseAgreed == 0) ||
(pinfo->fd->num <= rdp_info->licenseAgreed))) {
/* licensing stage hasn't been completed */
proto_tree *next_tree;
flags = tvb_get_letohs(tvb, offset);
switch(flags & SEC_PKT_MASK) {
case SEC_EXCHANGE_PKT:
pi = proto_tree_add_item(tree, hf_rdp_securityExchangePDU, tvb, offset, -1, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_securityExchangePDU);
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "SecurityExchange");
/*offset=*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, se_fields, 0);
break;
case SEC_INFO_PKT:
pi = proto_tree_add_item(tree, hf_rdp_clientInfoPDU, tvb, offset, -1, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientInfoPDU);
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ClientInfo");
offset = dissect_rdp_securityHeader(tvb, offset, pinfo, next_tree, rdp_info, TRUE, NULL);
if (!(flags & SEC_ENCRYPT)) {
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, ue_fields, 0);
} else {
/*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, next_tree, NULL);
}
break;
case SEC_LICENSE_PKT:
pi = proto_tree_add_item(tree, hf_rdp_validClientLicenseData, tvb, offset, -1, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_validClientLicenseData);
offset = dissect_rdp_securityHeader(tvb, offset, pinfo, next_tree, rdp_info, TRUE, NULL);
if (!(flags & SEC_ENCRYPT)) {
offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, msg_fields, 0);
col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str_const(bMsgType, rdp_bMsgType_vals, "Unknown"));
switch(bMsgType) {
case LICENSE_REQUEST:
case PLATFORM_CHALLENGE:
case NEW_LICENSE:
case UPGRADE_LICENSE:
case LICENSE_INFO:
case NEW_LICENSE_REQUEST:
case PLATFORM_CHALLENGE_RESPONSE:
/* RDPELE Not supported */
/*offset =*/ dissect_rdp_nyi(tvb, offset, pinfo, next_tree, "RDPELE not implemented");
break;
case ERROR_ALERT:
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, error_fields, 0);
rdp_info->licenseAgreed = pinfo->fd->num;
break;
default:
/* Unknown msgType */
break;
}
} else {
/*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, next_tree, NULL);
/* XXX: we assume the license is agreed in this exchange */
rdp_info->licenseAgreed = pinfo->fd->num;
}
break;
case SEC_REDIRECTION_PKT:
/* NotYetImplemented */
break;
default:
break;
}
return tvb_captured_length(tvb);
} /* licensing stage */
if (rdp_info && (t124_get_last_channelId() == rdp_info->staticChannelId)) {
offset = dissect_rdp_securityHeader(tvb, offset, pinfo, tree, rdp_info, FALSE, &flags);
if (!(flags & SEC_ENCRYPT)) {
proto_tree *next_tree;
pi = proto_tree_add_item(tree, hf_rdp_shareControlHeader, tvb, offset, -1, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_shareControlHeader);
offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, ctrl_fields, 0);
pduType &= PDUTYPE_TYPE_MASK; /* mask out just the type */
if (pduType != PDUTYPE_DATAPDU)
col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str_const(pduType, rdp_pduTypeType_vals, "Unknown"));
switch(pduType) {
case PDUTYPE_DEMANDACTIVEPDU:
/*offset =*/ dissect_rdp_demandActivePDU(tvb, offset, pinfo, next_tree);
break;
case PDUTYPE_CONFIRMACTIVEPDU:
/*offset =*/ dissect_rdp_confirmActivePDU(tvb, offset, pinfo, next_tree);
break;
case PDUTYPE_DEACTIVATEALLPDU:
break;
case PDUTYPE_DATAPDU:
/*offset =*/ dissect_rdp_shareDataHeader(tvb, offset, pinfo, next_tree);
break;
case PDUTYPE_SERVER_REDIR_PKT:
break;
default:
break;
}
} else {
/*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, tree, NULL);
}
/* we may get multiple control headers in a single frame */
col_set_fence(pinfo->cinfo, COL_INFO);
return tvb_captured_length(tvb);
} /* (rdp_info && (t124_get_last_channelId() == rdp_info->staticChannelId)) */
/* Virtual Channel */
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Virtual Channel PDU");
offset = dissect_rdp_securityHeader(tvb, offset, pinfo, tree, rdp_info, FALSE, &flags);
if (!(flags & SEC_ENCRYPT))
/*offset =*/ dissect_rdp_channelPDU(tvb, offset, pinfo, tree);
else
/*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, tree, "Channel PDU");
return tvb_captured_length(tvb);
}
static int
dissect_rdp_ClientData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
int offset = 0;
proto_item *pi;
proto_tree *next_tree;
guint16 type;
guint length;
rdp_conv_info_t *rdp_info;
rdp_field_info_t header_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t core_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_versionMajor, 2, NULL, 0, 0, NULL },
{&hf_rdp_versionMinor, 2, NULL, 0, 0, NULL },
{&hf_rdp_desktopWidth, 2, NULL, 0, 0, NULL },
{&hf_rdp_desktopHeight, 2, NULL, 0, 0, NULL },
{&hf_rdp_colorDepth, 2, NULL, 0, 0, NULL },
{&hf_rdp_SASSequence, 2, NULL, 0, 0, NULL },
{&hf_rdp_keyboardLayout, 4, NULL, 0, 0, NULL },
{&hf_rdp_clientBuild, 4, NULL, 0, 0, NULL },
{&hf_rdp_clientName, 32, NULL, 0, RDP_FI_STRING|RDP_FI_UNICODE, NULL },
{&hf_rdp_keyboardType, 4, NULL, 0, 0, NULL },
{&hf_rdp_keyboardSubType, 4, NULL, 0, 0, NULL },
{&hf_rdp_keyboardFunctionKey, 4, NULL, 0, 0, NULL },
{&hf_rdp_imeFileName, 64, NULL, 0, 0, NULL },
/* The following fields are *optional*. */
/* I.E., a sequence of one or more of the trailing */
/* fields at the end of the Data Block need not be */
/* present. The length from the header field determines */
/* the actual number of fields which are present. */
{&hf_rdp_postBeta2ColorDepth, 2, NULL, 0, 0, NULL },
{&hf_rdp_clientProductId, 2, NULL, 0, 0, NULL },
{&hf_rdp_serialNumber, 4, NULL, 0, 0, NULL },
{&hf_rdp_highColorDepth, 2, NULL, 0, 0, NULL },
{&hf_rdp_supportedColorDepths, 2, NULL, 0, 0, NULL },
{&hf_rdp_earlyCapabilityFlags, 2, NULL, 0, 0, NULL },
{&hf_rdp_clientDigProductId, 64, NULL, 0, RDP_FI_STRING|RDP_FI_UNICODE, NULL }, /* XXX - is this always a string? MS-RDPBCGR doesn't say so */
{&hf_rdp_connectionType, 1, NULL, 0, 0, NULL },
{&hf_rdp_pad1octet, 1, NULL, 0, 0, NULL },
{&hf_rdp_serverSelectedProtocol, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t security_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_encryptionMethods, 4, NULL, 0, 0, NULL },
{&hf_rdp_extEncryptionMethods, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t cluster_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_cluster_flags, 4, NULL, 0, 0, NULL },
{&hf_rdp_redirectedSessionId, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t msgchannel_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_msgChannelFlags, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t monitor_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_monitorCount, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t monitorex_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_monitorExFlags, 4, NULL, 0, 0, NULL },
{&hf_rdp_monitorAttributeSize, 4, NULL, 0, 0, NULL },
{&hf_rdp_monitorCount, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t multitransport_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_multiTransportFlags, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
tree = dissect_rdp(tvb, pinfo, tree);
rdp_info = rdp_get_conversation_data(pinfo);
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ClientData");
pi = proto_tree_add_item(tree, hf_rdp_ClientData, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(pi, ett_rdp_ClientData);
/* Advance through the data blocks using the length from the header for each block.
* ToDo: Expert if actual amount dissected (based upon field array) is not equal to length ??
* Note: If length is less than the header size (4 bytes) offset is advanced by 4 bytes
* to ensure that dissection eventually terminates.
*/
while (tvb_reported_length_remaining(tvb, offset) > 0) {
type = tvb_get_letohs(tvb, offset);
length = tvb_get_letohs(tvb, offset+2);
#if 0
printf("offset=%d, type=%x, length=%d, remaining=%d\n",
offset, type, length, tvb_captured_length_remaining(tvb, offset));
#endif
switch(type) {
case CS_CORE:
pi = proto_tree_add_item(tree, hf_rdp_clientCoreData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientCoreData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, core_fields, length);
break;
case CS_SECURITY:
pi = proto_tree_add_item(tree, hf_rdp_clientSecurityData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientSecurityData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, security_fields, 0);
break;
case CS_NET:
/*offset =*/ dissect_rdp_clientNetworkData(tvb, offset, pinfo, tree, length, rdp_info);
break;
case CS_CLUSTER:
pi = proto_tree_add_item(tree, hf_rdp_clientClusterData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientClusterData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, cluster_fields, 0);
break;
case CS_MONITOR:
pi = proto_tree_add_item(tree, hf_rdp_clientMonitorData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientMonitorData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, monitor_fields, 0);
break;
case CS_MONITOR_EX:
pi = proto_tree_add_item(tree, hf_rdp_clientMonitorExData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientMonitorExData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, monitorex_fields, 0);
break;
case CS_MCS_MSGCHANNEL:
pi = proto_tree_add_item(tree, hf_rdp_clientMsgChannelData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientMsgChannelData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, msgchannel_fields, 0);
break;
case CS_MULTITRANSPORT:
pi = proto_tree_add_item(tree, hf_rdp_clientMultiTransportData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientMultiTransportData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, multitransport_fields, 0);
break;
default: /* unknown */
pi = proto_tree_add_item(tree, hf_rdp_clientUnknownData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_clientUnknownData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, header_fields, 0);
break;
}
offset += MAX(4, length); /* Use length from header, but advance at least 4 bytes */
}
return tvb_captured_length(tvb);
}
static int
dissect_rdp_ServerData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
int offset = 0;
proto_item *pi;
proto_tree *next_tree;
guint16 type;
guint length;
guint32 serverRandomLen = 0;
guint32 serverCertLen = 0;
guint32 encryptionMethod = 0;
guint32 encryptionLevel = 0;
guint32 channelCount = 0;
guint32 channelId = 0;
guint i;
rdp_conv_info_t *rdp_info;
rdp_field_info_t header_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t sc_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_versionMajor, 2, NULL, 0, 0, NULL },
{&hf_rdp_versionMinor, 2, NULL, 0, 0, NULL },
/* The following fields are *optional*. */
/* I.E., a sequence of one or more of the trailing */
/* fields at the end of the Data Block need not be */
/* present. The length from the header field determines */
/* the actual number of fields which are present. */
{&hf_rdp_clientRequestedProtocols, 4, NULL, 0, 0, NULL },
{&hf_rdp_earlyCapabilityFlags, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t ss_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_encryptionMethod, 4, &encryptionMethod, 0, 0, NULL },
{&hf_rdp_encryptionLevel, 4, &encryptionLevel, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t encryption_fields[] = {
{&hf_rdp_serverRandomLen, 4, &serverRandomLen, 0, 0, NULL },
{&hf_rdp_serverCertLen, 4, &serverCertLen, 0, 0, NULL },
{&hf_rdp_serverRandom, 0, &serverRandomLen, 0, 0, NULL },
{&hf_rdp_serverCertificate, 0, &serverCertLen, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t sn_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_MCSChannelId, 2, &channelId, 0, 0, NULL },
{&hf_rdp_channelCount, 2, &channelCount, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t array_fields[] = {
{&hf_rdp_channelIdArray, 0 /*(channelCount * 2)*/, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t channel_fields[] = {
{&hf_rdp_MCSChannelId, 2, &channelId, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t pad_fields[] = {
{&hf_rdp_Pad, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t msgchannel_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_msgChannelId, 2, NULL, 0, 0, NULL },
FI_TERMINATOR
};
rdp_field_info_t multitransport_fields[] = {
{&hf_rdp_headerType, 2, NULL, 0, 0, NULL },
{&hf_rdp_headerLength, 2, NULL, 0, 0, NULL },
{&hf_rdp_multiTransportFlags, 4, NULL, 0, 0, NULL },
FI_TERMINATOR
};
tree = dissect_rdp(tvb, pinfo, tree);
rdp_info = rdp_get_conversation_data(pinfo);
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ServerData");
pi = proto_tree_add_item(tree, hf_rdp_ServerData, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(pi, ett_rdp_ServerData);
/* Advance through the data blocks using the length from the header for each block.
* ToDo: Expert if actual amount dissected (based upon field array) is not equal to length ??
* Note: If length is less than the header size (4 bytes) offset is advanced by 4 bytes
* to ensure that dissection eventually terminates.
*/
while (tvb_reported_length_remaining(tvb, offset) > 0) {
type = tvb_get_letohs(tvb, offset);
length = tvb_get_letohs(tvb, offset+2);
/* printf("offset=%d, type=%x, length=%d, remaining=%d\n",
offset, type, length, tvb_captured_length_remaining(tvb, offset)); */
switch(type) {
case SC_CORE:
pi = proto_tree_add_item(tree, hf_rdp_serverCoreData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_serverCoreData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, sc_fields, length);
break;
case SC_SECURITY: {
gint lcl_offset;
pi = proto_tree_add_item(tree, hf_rdp_serverSecurityData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_serverSecurityData);
lcl_offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, ss_fields, 0);
col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "Encryption: %s (%s)",
val_to_str_const(encryptionMethod, rdp_encryptionMethod_vals, "Unknown"),
val_to_str_const(encryptionLevel, rdp_encryptionLevel_vals, "Unknown"));
if ((encryptionLevel != 0) || (encryptionMethod != 0)) {
/*lcl_offset =*/ dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, encryption_fields, 0);
}
rdp_info->encryptionMethod = encryptionMethod;
rdp_info->encryptionLevel = encryptionLevel;
break;
}
case SC_NET: {
gint lcl_offset;
pi = proto_tree_add_item(tree, hf_rdp_serverNetworkData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_serverNetworkData);
lcl_offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, sn_fields, 0);
rdp_info->staticChannelId = channelId;
register_t124_sd_dissector(pinfo, channelId, dissect_rdp_SendData, proto_rdp);
if (channelCount > 0) {
array_fields[0].fixedLength = channelCount * 2;
dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, array_fields, 0);
if (next_tree)
next_tree = proto_item_add_subtree(next_tree->last_child, ett_rdp_channelIdArray);
for (i = 0; i < channelCount; i++) {
lcl_offset = dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, channel_fields, 0);
if (i < MAX_CHANNELS)
rdp_info->channels[i].value = channelId;
/* register SendData on this for now */
register_t124_sd_dissector(pinfo, channelId, dissect_rdp_SendData, proto_rdp);
}
if (channelCount % 2)
/*lcl_offset =*/ dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, pad_fields, 0);
}
break;
}
case SC_MCS_MSGCHANNEL:
pi = proto_tree_add_item(tree, hf_rdp_serverMsgChannelData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_serverMsgChannelData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, msgchannel_fields, length);
break;
case SC_MULTITRANSPORT:
pi = proto_tree_add_item(tree, hf_rdp_serverMultiTransportData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_serverMultiTransportData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, multitransport_fields, length);
break;
default: /* unknown */
pi = proto_tree_add_item(tree, hf_rdp_serverUnknownData, tvb, offset, length, ENC_NA);
next_tree = proto_item_add_subtree(pi, ett_rdp_serverUnknownData);
/*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, header_fields, 0);
break;
}
offset += MAX(4, length); /* Use length from header, but advance at least 4 bytes */
}
return tvb_captured_length(tvb);
}
/*--- proto_register_rdp -------------------------------------------*/
void
proto_register_rdp(void) {
/* List of fields */
static hf_register_info hf[] = {
{ &hf_rdp_ClientData,
{ "ClientData", "rdp.clientData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_SendData,
{ "SendData", "rdp.sendData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientCoreData,
{ "clientCoreData", "rdp.client.coreData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientSecurityData,
{ "clientSecurityData", "rdp.client.securityData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientNetworkData,
{ "clientNetworkData", "rdp.client.networkData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientClusterData,
{ "clientClusterData", "rdp.client.clusterData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientMonitorData,
{ "clientMonitorData", "rdp.client.monitorData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientMsgChannelData,
{ "clientMsgChannelData", "rdp.client.msgChannelData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientMonitorExData,
{ "clientMonitorExData", "rdp.client.monitorExData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientMultiTransportData,
{ "clientMultiTransportData", "rdp.client.multiTransportData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientUnknownData,
{ "clientUnknownData", "rdp.unknownData.client",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_ServerData,
{ "ServerData", "rdp.serverData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverCoreData,
{ "serverCoreData", "rdp.server.coreData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverSecurityData,
{ "serverSecurityData", "rdp.server.securityData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverNetworkData,
{ "serverNetworkData", "rdp.server.networkData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverMsgChannelData,
{ "serverMsgChannelData", "rdp.server.msgChannelData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverMultiTransportData,
{ "serverMultiTransportData", "rdp.server.multiTransportData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverUnknownData,
{ "serverUnknownData", "rdp.unknownData.server",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_securityExchangePDU,
{ "securityExchangePDU", "rdp.securityExchangePDU",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientInfoPDU,
{ "clientInfoPDU", "rdp.clientInfoPDU",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_validClientLicenseData,
{ "validClientLicenseData", "rdp.validClientLicenseData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_headerType,
{ "headerType", "rdp.header.type",
FT_UINT16, BASE_HEX, VALS(rdp_headerType_vals), 0,
NULL, HFILL }},
{ &hf_rdp_headerLength,
{ "headerLength", "rdp.header.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_versionMajor,
{ "versionMajor", "rdp.version.major",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_versionMinor,
{ "versionMinor", "rdp.version.minor",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_desktopWidth,
{ "desktopWidth", "rdp.desktop.width",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_desktopHeight,
{ "desktopHeight", "rdp.desktop.height",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_colorDepth,
{ "colorDepth", "rdp.colorDepth",
FT_UINT16, BASE_HEX, VALS(rdp_colorDepth_vals), 0,
NULL, HFILL }},
{ &hf_rdp_SASSequence,
{ "SASSequence", "rdp.SASSequence",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_keyboardLayout,
{ "keyboardLayout", "rdp.keyboardLayout",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientBuild,
{ "clientBuild", "rdp.client.build",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientName,
{ "clientName", "rdp.client.name",
FT_STRINGZ, BASE_NONE, NULL, 0, /* supposed to be null-terminated */
NULL, HFILL }},
{ &hf_rdp_keyboardType,
{ "keyboardType", "rdp.keyboard.type",
FT_UINT32, BASE_DEC, VALS(rdp_keyboardType_vals), 0,
NULL, HFILL }},
{ &hf_rdp_keyboardSubType,
{ "keyboardSubType", "rdp.keyboard.subtype",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_keyboardFunctionKey,
{ "keyboardFunctionKey", "rdp.keyboard.functionkey",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_imeFileName,
{ "imeFileName", "rdp.imeFileName",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_postBeta2ColorDepth,
{ "postBeta2ColorDepth", "rdp.postBeta2ColorDepth",
FT_UINT16, BASE_HEX, VALS(rdp_colorDepth_vals), 0,
NULL, HFILL }},
{ &hf_rdp_clientProductId,
{ "clientProductId", "rdp.client.productId",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serialNumber,
{ "serialNumber", "rdp.serialNumber",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_highColorDepth,
{ "highColorDepth", "rdp.highColorDepth",
FT_UINT16, BASE_HEX, VALS(rdp_highColorDepth_vals), 0,
NULL, HFILL }},
{ &hf_rdp_supportedColorDepths,
{ "supportedColorDepths", "rdp.supportedColorDepths",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_earlyCapabilityFlags,
{ "earlyCapabilityFlags", "rdp.earlyCapabilityFlags",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientDigProductId,
{ "clientDigProductId", "rdp.client.digProductId",
FT_STRINGZ, BASE_NONE, NULL, 0, /* XXX - is this always a string? MS-RDPBCGR doesn't say so */
NULL, HFILL }},
{ &hf_rdp_connectionType,
{ "connectionType", "rdp.connectionType",
FT_UINT8, BASE_DEC, VALS(rdp_connectionType_vals), 0,
NULL, HFILL }},
{ &hf_rdp_pad1octet,
{ "pad1octet", "rdp.pad1octet",
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverSelectedProtocol,
{ "serverSelectedProtocol", "rdp.serverSelectedProtocol",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_encryptionMethods,
{ "encryptionMethods", "rdp.encryptionMethods",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_extEncryptionMethods,
{ "extEncryptionMethods", "rdp.extEncryptionMethods",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cluster_flags, /* ToDo: Display flags in detail */
{ "clusterFlags", "rdp.clusterFlags",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_redirectedSessionId,
{ "redirectedSessionId", "rdp.redirectedSessionId",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_msgChannelFlags,
{ "msgChannelFlags", "rdp.msgChannelFlags",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_msgChannelId,
{ "msgChannelId", "rdp.msgChannelId",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_monitorExFlags,
{ "monitorExFlags", "rdp.monitorExFlags",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_monitorAttributeSize,
{ "monitorAttributeSize", "rdp.monitorAttributeSize",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_monitorCount,
{ "monitorCount", "rdp.monitorCount",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_multiTransportFlags,
{ "multiTransportFlags", "rdp.multiTransportFlags",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_encryptionMethod,
{ "encryptionMethod", "rdp.encryptionMethod",
FT_UINT32, BASE_HEX, VALS(rdp_encryptionMethod_vals), 0,
NULL, HFILL }},
{ &hf_rdp_encryptionLevel,
{ "encryptionLevel", "rdp.encryptionLevel",
FT_UINT32, BASE_HEX, VALS(rdp_encryptionLevel_vals), 0,
NULL, HFILL }},
{ &hf_rdp_serverRandomLen,
{ "serverRandomLen", "rdp.serverRandomLen",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverCertLen,
{ "serverCertLen", "rdp.serverCertLen",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverRandom,
{ "serverRandom", "rdp.serverRandom",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_serverCertificate,
{ "serverCertificate", "rdp.serverCertificate",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientRequestedProtocols,
{ "clientRequestedProtocols", "rdp.client.requestedProtocols",
FT_UINT32, BASE_HEX, VALS(rdp_requestedProtocols_vals), 0,
NULL, HFILL }},
{ &hf_rdp_MCSChannelId,
{ "MCSChannelId", "rdp.MCSChannelId",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_channelCount,
{ "channelCount", "rdp.channelCount",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_channelIdArray,
{ "channelIdArray", "rdp.channelIdArray",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_Pad,
{ "Pad", "rdp.Pad",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_flags,
{ "flags", "rdp.flags",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_channelFlags,
{ "channelFlags", "rdp.channelFlags",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_flagsPkt,
{ "flagsPkt", "rdp.flags.pkt",
FT_UINT16, BASE_HEX, VALS(rdp_flagsPkt_vals), SEC_PKT_MASK,
NULL, HFILL }},
{ &hf_rdp_flagsEncrypt,
{ "flagsEncrypt", "rdp.flags.encrypt",
FT_UINT16, BASE_HEX, NULL, SEC_ENCRYPT,
NULL, HFILL }},
{ &hf_rdp_flagsResetSeqno,
{ "flagsResetSeqno", "rdp.flags.resetseqno",
FT_UINT16, BASE_HEX, NULL, SEC_RESET_SEQNO,
NULL, HFILL }},
{ &hf_rdp_flagsIgnoreSeqno,
{ "flagsIgnoreSeqno", "rdp.flags.ignoreseqno",
FT_UINT16, BASE_HEX, NULL, SEC_IGNORE_SEQNO,
NULL, HFILL }},
{ &hf_rdp_flagsLicenseEncrypt,
{ "flagsLicenseEncrypt", "rdp.flags.licenseencrypt",
FT_UINT16, BASE_HEX, NULL, SEC_LICENSE_ENCRYPT_CS,
NULL, HFILL }},
{ &hf_rdp_flagsSecureChecksum,
{ "flagsSecureChecksum", "rdp.flags.securechecksum",
FT_UINT16, BASE_HEX, NULL, SEC_SECURE_CHECKSUM,
NULL, HFILL }},
{ &hf_rdp_flagsFlagsHiValid,
{ "flagsHiValid", "rdp.flags.flagshivalid",
FT_UINT16, BASE_HEX, NULL, SEC_FLAGSHI_VALID,
NULL, HFILL }},
{ &hf_rdp_flagsHi,
{ "flagsHi", "rdp.flagsHi",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_length,
{ "length", "rdp.length",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_encryptedClientRandom,
{ "encryptedClientRandom", "rdp.encryptedClientRandom",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_dataSignature,
{ "dataSignature", "rdp.dataSignature",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_fipsLength,
{ "fipsLength", "rdp.fipsLength",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_fipsVersion,
{ "fipsVersion", "rdp.fipsVersion",
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_padlen,
{ "padlen", "rdp.padlen",
FT_UINT8, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_codePage,
{ "codePage", "rdp.codePage",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_optionFlags,
{ "optionFlags", "rdp.optionFlags",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbDomain,
{ "cbDomain", "rdp.domain.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbUserName,
{ "cbUserName", "rdp.userName.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbPassword,
{ "cbPassword", "rdp.password.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbAlternateShell,
{ "cbAlternateShell", "rdp.alternateShell.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbWorkingDir,
{ "cbWorkingDir", "rdp.workingDir.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbClientAddress,
{ "cbClientAddress", "rdp.client.address.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbClientDir,
{ "cbClientDir", "rdp.client.dir.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_cbAutoReconnectLen,
{ "cbAutoReconnectLen", "rdp.autoReconnectCookie.length",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_domain,
{ "domain", "rdp.domain",
FT_STRINGZ, BASE_NONE, NULL, 0, /* null-terminated, count includes terminator */
NULL, HFILL }},
{ &hf_rdp_userName,
{ "userName", "rdp.userName",
FT_STRINGZ, BASE_NONE, NULL, 0, /* null-terminated, count includes terminator */
NULL, HFILL }},
{ &hf_rdp_password,
{ "password", "rdp.password",
FT_STRINGZ, BASE_NONE, NULL, 0, /* null-terminated, count includes terminator */
NULL, HFILL }},
{ &hf_rdp_alternateShell,
{ "alternateShell", "rdp.alternateShell",
FT_STRINGZ, BASE_NONE, NULL, 0, /* null-terminated, count includes terminator */
NULL, HFILL }},
{ &hf_rdp_workingDir,
{ "workingDir", "rdp.workingDir",
FT_STRINGZ, BASE_NONE, NULL, 0, /* null-terminated, count includes terminator */
NULL, HFILL }},
{ &hf_rdp_clientAddressFamily,
{ "clientAddressFamily", "rdp.client.addressFamily",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientAddress,
{ "clientAddress", "rdp.client.address",
FT_STRINGZ, BASE_NONE, NULL, 0, /* null-terminated, count includes terminator */
NULL, HFILL }},
{ &hf_rdp_clientDir,
{ "clientDir", "rdp.client.dir",
FT_STRINGZ, BASE_NONE, NULL, 0, /* null-terminated, count includes terminator */
NULL, HFILL }},
{ &hf_rdp_clientTimeZone,
{ "clientTimeZone", "rdp.client.timeZone",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_clientSessionId,
{ "clientSessionId", "rdp.client.sessionId",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_performanceFlags,
{ "performanceFlags", "rdp.performanceFlags",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_autoReconnectCookie,
{ "autoReconnectCookie", "rdp.autoReconnectCookie",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_reserved1,
{ "reserved1", "rdp.reserved1",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_reserved2,
{ "reserved2", "rdp.reserved2",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_bMsgType,
{ "bMsgType", "rdp.bMsgType",
FT_UINT8, BASE_HEX, VALS(rdp_bMsgType_vals), 0,
NULL, HFILL }},
{ &hf_rdp_bVersion,
{ "bVersion", "rdp.bVersion",
FT_UINT8, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_wMsgSize,
{ "wMsgSize", "rdp.wMsgSize",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_wBlobType,
{ "wBlobType", "rdp.wBlobType",
FT_UINT16, BASE_DEC, VALS(rdp_wBlobType_vals), 0,
NULL, HFILL }},
{ &hf_rdp_wBlobLen,
{ "wBlobLen", "rdp.wBlobLen",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_blobData,
{ "blobData", "rdp.blobData",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_shareControlHeader,
{ "shareControlHeader", "rdp.shareControlHeader",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_channelPDUHeader,
{ "channelPDUHeader", "rdp.channelPDUHeader",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_virtualChannelData,
{ "virtualChannelData", "rdp.virtualChannelData",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_totalLength,
{ "totalLength", "rdp.totalLength",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_pduType,
{ "pduType", "rdp.pduType",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_pduTypeType,
{ "pduTypeType", "rdp.pduType.type",
FT_UINT16, BASE_HEX, VALS(rdp_pduTypeType_vals), PDUTYPE_TYPE_MASK,
NULL, HFILL }},
{ &hf_rdp_pduTypeVersionLow,
{ "pduTypeVersionLow", "rdp.pduType.versionLow",
FT_UINT16, BASE_DEC, NULL, PDUTYPE_VERSIONLOW_MASK,
NULL, HFILL }},
{ &hf_rdp_pduTypeVersionHigh,
{ "pduTypeVersionHigh", "rdp.pduType.versionHigh",
FT_UINT16, BASE_DEC, NULL, PDUTYPE_VERSIONHIGH_MASK,
NULL, HFILL }},
{ &hf_rdp_pduSource,
{ "pduSource", "rdp.pduSource",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_shareId,
{ "shareId", "rdp.shareId",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_pad1,
{ "pad1", "rdp.pad1",
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_streamId,
{ "streamId", "rdp.streamId",
FT_UINT8, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_uncompressedLength,
{ "uncompressedLength", "rdp.uncompressedLength",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_pduType2,
{ "pduType2", "rdp.pduType2",
FT_UINT8, BASE_DEC, VALS(rdp_pduType2_vals), 0,
NULL, HFILL }},
{ &hf_rdp_compressedType,
{ "compressedType", "rdp.compressedType",
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_compressedTypeType,
{ "compressedTypeType", "rdp.compressedType.type",
FT_UINT8, BASE_HEX, VALS(rdp_compressionType_vals),
PacketCompressionTypeMask,
NULL, HFILL }},
{ &hf_rdp_compressedTypeCompressed,
{ "compressedTypeCompressed", "rdp.compressedType.compressed",
FT_UINT8, BASE_HEX, NULL, PACKET_COMPRESSED,
NULL, HFILL }},
{ &hf_rdp_compressedTypeAtFront,
{ "compressedTypeAtFront", "rdp.compressedType.atFront",
FT_UINT8, BASE_HEX, NULL, PACKET_AT_FRONT,
NULL, HFILL }},
{ &hf_rdp_compressedTypeFlushed,
{ "compressedTypeFlushed", "rdp.compressedType.flushed",
FT_UINT8, BASE_HEX, NULL, PACKET_FLUSHED,
NULL, HFILL }},
{ &hf_rdp_compressedLength,
{ "compressedLength", "rdp.compressedLength",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_wErrorCode,
{ "errorCode", "rdp.errorCode",
FT_UINT32, BASE_DEC, VALS(rdp_wErrorCode_vals), 0,
NULL, HFILL }},
{ &hf_rdp_wStateTransition,
{ "stateTransition", "rdp.stateTransition",
FT_UINT32, BASE_DEC, VALS(rdp_wStateTransition_vals), 0,
NULL, HFILL }},
{ &hf_rdp_numberEntries,
{ "numberEntries", "rdp.numberEntries",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_totalNumberEntries,
{ "totalNumberEntries", "rdp.totalNumberEntries",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_mapFlags,
{ "mapFlags", "rdp.mapFlags",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_fontMapFirst,
{ "fontMapFirst", "rdp.mapFlags.fontMapFirst",
FT_UINT16, BASE_HEX, NULL, FONTMAP_FIRST,
NULL, HFILL }},
{ &hf_rdp_fontMapLast,
{ "fontMapLast", "rdp.mapFlags.fontMapLast",
FT_UINT16, BASE_HEX, NULL, FONTMAP_LAST,
NULL, HFILL }},
{ &hf_rdp_entrySize,
{ "entrySize", "rdp.entrySize",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_action,
{ "action", "rdp.action",
FT_UINT16, BASE_HEX, VALS(rdp_action_vals),
0,
NULL, HFILL }},
{ &hf_rdp_grantId,
{ "grantId", "rdp.grantId",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_controlId,
{ "controlId", "rdp.controlId",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_messageType,
{ "messageType", "rdp.messageType",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_targetUser,
{ "targetUser", "rdp.targetUser",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_numEntriesCache0,
{ "numEntriesCache0", "rdp.numEntriesCache0",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_numEntriesCache1,
{ "numEntriesCache1", "rdp.numEntriesCache1",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_numEntriesCache2,
{ "numEntriesCache2", "rdp.numEntriesCache2",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_numEntriesCache3,
{ "numEntriesCache3", "rdp.numEntriesCache3",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_numEntriesCache4,
{ "numEntriesCache4", "rdp.numEntriesCache4",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_totalEntriesCache0,
{ "totalEntriesCache0", "rdp.totalEntriesCache0",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_totalEntriesCache1,
{ "totalEntriesCache1", "rdp.totalEntriesCache1",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_totalEntriesCache2,
{ "totalEntriesCache2", "rdp.totalEntriesCache2",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_totalEntriesCache3,
{ "totalEntriesCache3", "rdp.totalEntriesCache3",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_totalEntriesCache4,
{ "totalEntriesCache4", "rdp.totalEntriesCache4",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_bBitMask,
{ "bBitMask", "rdp.bBitMask",
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_Pad2,
{ "Pad2", "rdp.Pad2",
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_Pad3,
{ "Pad3", "rdp.Pad3",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
#if 0
{ &hf_rdp_Key1,
{ "Key1", "rdp.Key1",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
#endif
#if 0
{ &hf_rdp_Key2,
{ "Key2", "rdp.Key2",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
#endif
{ &hf_rdp_originatorId,
{ "originatorId", "rdp.OriginatorId",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_lengthSourceDescriptor,
{ "lengthSourceDescriptor", "rdp.lengthSourceDescriptor",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_lengthCombinedCapabilities,
{ "lengthCombinedCapabilities", "rdp.lengthCombinedCapabilities",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_sourceDescriptor,
{ "sourceDescriptor", "rdp.sourceDescriptor",
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_numberCapabilities,
{ "numberCapabilities", "rdp.numberCapabilities",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_pad2Octets,
{ "pad2Octets", "rdp.pad2Octets",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_capabilitySetType,
{ "capabilitySetType", "rdp.capabilitySetType",
FT_UINT16, BASE_HEX, VALS(rdp_capabilityType_vals), 0,
NULL, HFILL }},
{ &hf_rdp_capabilitySet,
{ "capabilitySet", "rdp.capabilitySet",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_lengthCapability,
{ "lengthCapability", "rdp.lengthCapability",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_capabilityData,
{ "capabilityData", "rdp.capabilityData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
#if 0
{ &hf_rdp_unknownData,
{ "unknownData", "rdp.unknownData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
#endif
{ &hf_rdp_notYetImplemented,
{ "notYetImplemented", "rdp.notYetImplemented",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_encrypted,
{ "encryptedData", "rdp.encryptedData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
#if 0
{ &hf_rdp_compressed,
{ "compressedData", "rdp.compressedData",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
#endif
{ &hf_rdp_sessionId,
{ "sessionId", "rdp.sessionId",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_channelDefArray,
{ "channelDefArray", "rdp.channelDefArray",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_channelDef,
{ "channelDef", "rdp.channelDef",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_name,
{ "name", "rdp.name",
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_options,
{ "options", "rdp.options",
FT_UINT32, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_optionsInitialized,
{ "optionsInitialized", "rdp.options.initialized",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_INITIALIZED,
NULL, HFILL }},
{ &hf_rdp_optionsEncryptRDP,
{ "encryptRDP", "rdp.options.encrypt.rdp",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_ENCRYPT_RDP,
NULL, HFILL }},
{ &hf_rdp_optionsEncryptSC,
{ "encryptSC", "rdp.options.encrypt.sc",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_ENCRYPT_SC,
NULL, HFILL }},
{ &hf_rdp_optionsEncryptCS,
{ "encryptCS", "rdp.options.encrypt.cs",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_ENCRYPT_CS,
NULL, HFILL }},
{ &hf_rdp_optionsPriHigh,
{ "priorityHigh", "rdp.options.priority.high",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_PRI_HIGH,
NULL, HFILL }},
{ &hf_rdp_optionsPriMed,
{ "priorityMed", "rdp.options.priority.med",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_PRI_MED,
NULL, HFILL }},
{ &hf_rdp_optionsPriLow,
{ "priorityLow", "rdp.options.priority.low",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_PRI_LOW,
NULL, HFILL }},
{ &hf_rdp_optionsCompressRDP,
{ "compressRDP", "rdp.options.compress.rdp",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_COMPRESS_RDP,
NULL, HFILL }},
{ &hf_rdp_optionsCompress,
{ "compress", "rdp.options.compress",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_COMPRESS,
NULL, HFILL }},
{ &hf_rdp_optionsShowProtocol,
{ "showProtocol", "rdp.options.showprotocol",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_SHOW_PROTOCOL,
NULL, HFILL }},
{ &hf_rdp_optionsRemoteControlPersistent,
{ "remoteControlPersistent", "rdp.options.remotecontrolpersistent",
FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_REMOTE_CONTROL_PERSISTENT,
NULL, HFILL }},
{ &hf_rdp_channelFlagFirst,
{ "channelFlagFirst", "rdp.channelFlag.first",
FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_FIRST,
NULL, HFILL }},
{ &hf_rdp_channelFlagLast,
{ "channelFlagLast", "rdp.channelFlag.last",
FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_LAST,
NULL, HFILL }},
{ &hf_rdp_channelFlagShowProtocol,
{ "channelFlagShowProtocol", "rdp.channelFlag.showProtocol",
FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_SHOW_PROTOCOL,
NULL, HFILL }},
{ &hf_rdp_channelFlagSuspend,
{ "channelFlagSuspend", "rdp.channelFlag.suspend",
FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_SUSPEND,
NULL, HFILL }},
{ &hf_rdp_channelFlagResume,
{ "channelFlagResume", "rdp.channelFlag.resume",
FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_RESUME,
NULL, HFILL }},
{ &hf_rdp_channelPacketCompressed,
{ "channelPacketCompressed", "rdp.channelPacket.compressed",
FT_UINT32, BASE_HEX, NULL, CHANNEL_PACKET_COMPRESSED,
NULL, HFILL }},
{ &hf_rdp_channelPacketAtFront,
{ "channelPacketAtFront", "rdp.channelPacket.atFront",
FT_UINT32, BASE_HEX, NULL, CHANNEL_PACKET_AT_FRONT,
NULL, HFILL }},
{ &hf_rdp_channelPacketFlushed,
{ "channelPacketFlushed", "rdp.channelPacket.flushed",
FT_UINT32, BASE_HEX, NULL, CHANNEL_PACKET_FLUSHED,
NULL, HFILL }},
{ &hf_rdp_channelPacketCompressionType,
{ "channelPacketCompresssionType", "rdp.channelPacket.compressionType",
FT_UINT32, BASE_HEX, VALS(rdp_channelCompressionType_vals), ChannelCompressionTypeMask,
NULL, HFILL }},
{ &hf_rdp_wYear,
{ "wYear", "rdp.wYear",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_wMonth,
{ "wMonth", "rdp.wMonth",
FT_UINT16, BASE_DEC, VALS(rdp_wMonth_vals), 0,
NULL, HFILL }},
{ &hf_rdp_wDayOfWeek,
{ "wDayOfWeek", "rdp.wDayOfWeek",
FT_UINT16, BASE_DEC, VALS(rdp_wDayOfWeek_vals), 0,
NULL, HFILL }},
{ &hf_rdp_wDay,
{ "wDay", "rdp.wDay",
FT_UINT16, BASE_DEC, VALS(rdp_wDay_vals), 0,
NULL, HFILL }},
{ &hf_rdp_wHour,
{ "wHour", "rdp.wHour",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_wMinute,
{ "wMinute", "rdp.wMinute",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_wSecond,
{ "wSecond", "rdp.wSecond",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_wMilliseconds,
{ "wMilliseconds", "rdp.wMilliseconds",
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_Bias,
{ "Bias", "rdp.Bias",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_StandardBias,
{ "StandardBias", "rdp.Bias.standard",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_DaylightBias,
{ "DaylightBias", "rdp.Bias.daylight",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_StandardName,
{ "StandardName", "rdp.Name.Standard",
FT_STRINGZ, BASE_NONE, NULL, 0, /* zero-padded, not null-terminated */
NULL, HFILL }},
{ &hf_rdp_StandardDate,
{ "StandardDate", "rdp.Date.Standard",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_DaylightName,
{ "DaylightName", "rdp.Name.Daylight",
FT_STRINGZ, BASE_NONE, NULL, 0, /* zero-padded, not null-terminated */
NULL, HFILL }},
{ &hf_rdp_DaylightDate,
{ "DaylightDate", "rdp.Date.Daylight",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_rdp_unused,
{ "Unused", "rdp.unused",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
};
/* List of subtrees */
static gint *ett[] = {
&ett_rdp,
&ett_rdp_ClientData,
&ett_rdp_ServerData,
&ett_rdp_SendData,
&ett_rdp_capabilitySet,
&ett_rdp_channelDef,
&ett_rdp_channelDefArray,
&ett_rdp_channelFlags,
&ett_rdp_channelIdArray,
&ett_rdp_channelPDUHeader,
&ett_rdp_clientClusterData,
&ett_rdp_clientCoreData,
&ett_rdp_clientInfoPDU,
&ett_rdp_clientMonitorData,
&ett_rdp_clientMonitorExData,
&ett_rdp_clientMsgChannelData,
&ett_rdp_clientMultiTransportData,
&ett_rdp_clientNetworkData,
&ett_rdp_clientSecurityData,
&ett_rdp_clientUnknownData,
&ett_rdp_compressedType,
&ett_rdp_flags,
&ett_rdp_mapFlags,
&ett_rdp_options,
&ett_rdp_pduType,
&ett_rdp_securityExchangePDU,
&ett_rdp_serverCoreData,
&ett_rdp_serverMsgChannelData,
&ett_rdp_serverMultiTransportData,
&ett_rdp_serverNetworkData,
&ett_rdp_serverSecurityData,
&ett_rdp_serverUnknownData,
&ett_rdp_shareControlHeader,
&ett_rdp_validClientLicenseData,
&ett_rdp_StandardDate,
&ett_rdp_DaylightDate,
&ett_rdp_clientTimeZone,
};
module_t *rdp_module;
/* Register protocol */
proto_rdp = proto_register_protocol(PNAME, PSNAME, PFNAME);
/* Register fields and subtrees */
proto_register_field_array(proto_rdp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/* new_register_dissector("rdp", dissect_rdp, proto_rdp); */
/* Register our configuration options for RDP, particularly our port */
rdp_module = prefs_register_protocol(proto_rdp, prefs_register_rdp);
prefs_register_uint_preference(rdp_module, "tcp.port", "RDP TCP Port",
"Set the port for RDP operations (if other"
" than the default of 3389)",
10, &global_rdp_tcp_port);
}
void
proto_reg_handoff_rdp(void)
{
/* remember the tpkt handler for change in preferences */
tpkt_handle = find_dissector("tpkt");
prefs_register_rdp();
register_t124_ns_dissector("Duca", dissect_rdp_ClientData, proto_rdp);
register_t124_ns_dissector("McDn", dissect_rdp_ServerData, proto_rdp);
}
static void
prefs_register_rdp(void) {
static guint tcp_port = 0;
/* de-register the old port */
/* port 102 is registered by TPKT - don't undo this! */
if ((tcp_port > 0) && (tcp_port != 102) && tpkt_handle)
dissector_delete_uint("tcp.port", tcp_port, tpkt_handle);
/* Set our port number for future use */
tcp_port = global_rdp_tcp_port;
if ((tcp_port > 0) && (tcp_port != 102) && tpkt_handle)
dissector_add_uint("tcp.port", tcp_port, tpkt_handle);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/