1 /* Packet-rdp.c
2  * Routines for Remote Desktop Protocol (RDP) packet dissection
3  * Copyright 2010, Graeme Lunt
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 /*
13  * See: "[MS-RDPBCGR] Remote Desktop Protocol: Basic Connectivity and Graphics Remoting"
14  */
15 
16 #include "config.h"
17 
18 #include <epan/packet.h>
19 #include <epan/prefs.h>
20 #include <epan/conversation.h>
21 #include <epan/asn1.h>
22 #include <epan/expert.h>
23 #include <epan/strutil.h>
24 #include "packet-tls.h"
25 #include "packet-t124.h"
26 #include "packet-rdp.h"
27 
28 #define PNAME  "Remote Desktop Protocol"
29 #define PSNAME "RDP"
30 #define PFNAME "rdp"
31 
32 void proto_register_rdp(void);
33 void proto_reg_handoff_rdp(void);
34 
35 static heur_dissector_list_t rdp_heur_subdissector_list;
36 
37 int proto_rdp = -1;
38 
39 static dissector_handle_t drdynvc_handle;
40 
41 static int ett_rdp = -1;
42 
43 static int ett_negReq_flags = -1;
44 static int ett_requestedProtocols = -1;
45 
46 static int ett_negRsp_flags = -1;
47 static int ett_selectedProtocol = -1;
48 
49 static int ett_rdp_SendData = -1;
50 static int ett_rdp_MessageData = -1;
51 
52 static int ett_rdp_ClientData = -1;
53 static int ett_rdp_clientCoreData = -1;
54 static int ett_rdp_clientSecurityData = -1;
55 static int ett_rdp_clientNetworkData = -1;
56 static int ett_rdp_clientClusterData = -1;
57 static int ett_rdp_clientMonitorData = -1;
58 static int ett_rdp_clientMonitorDefData = -1;
59 static int ett_rdp_clientMsgChannelData = -1;
60 static int ett_rdp_clientMonitorExData = -1;
61 static int ett_rdp_clientMultiTransportData = -1;
62 static int ett_rdp_clientUnknownData = -1;
63 static int ett_rdp_ServerData = -1;
64 static int ett_rdp_serverCoreData = -1;
65 static int ett_rdp_serverSecurityData = -1;
66 static int ett_rdp_serverNetworkData = -1;
67 static int ett_rdp_serverMsgChannelData = -1;
68 static int ett_rdp_serverMultiTransportData = -1;
69 static int ett_rdp_serverUnknownData = -1;
70 static int ett_rdp_channelIdArray = -1;
71 static int ett_rdp_securityExchangePDU = -1;
72 static int ett_rdp_clientInfoPDU = -1;
73 static int ett_rdp_validClientLicenseData = -1;
74 static int ett_rdp_shareControlHeader = -1;
75 static int ett_rdp_pduType = -1;
76 static int ett_rdp_flags = -1;
77 static int ett_rdp_compressedType = -1;
78 static int ett_rdp_mapFlags = -1;
79 static int ett_rdp_options = -1;
80 static int ett_rdp_channelDefArray = -1;
81 static int ett_rdp_channelDef = -1;
82 static int ett_rdp_channelPDUHeader = -1;
83 static int ett_rdp_channelFlags = -1;
84 static int ett_rdp_capabilitySet = -1;
85 
86 static int ett_rdp_StandardDate = -1;
87 static int ett_rdp_DaylightDate = -1;
88 static int ett_rdp_clientTimeZone = -1;
89 static int ett_rdp_mt_req = -1;
90 static int ett_rdp_mt_rsp = -1;
91 static int ett_rdp_heartbeat = -1;
92 
93 static expert_field ei_rdp_neg_len_invalid = EI_INIT;
94 static expert_field ei_rdp_not_correlation_info = EI_INIT;
95 
96 static int hf_rdp_rt_cookie = -1;
97 static int hf_rdp_neg_type = -1;
98 static int hf_rdp_negReq_flags = -1;
99 static int hf_rdp_negReq_flag_restricted_admin_mode_req = -1;
100 static int hf_rdp_negReq_flag_correlation_info_present = -1;
101 static int hf_rdp_neg_length = -1;
102 static int hf_rdp_requestedProtocols = -1;
103 static int hf_rdp_requestedProtocols_flag_ssl = -1;
104 static int hf_rdp_requestedProtocols_flag_hybrid = -1;
105 static int hf_rdp_requestedProtocols_flag_rdstls = -1;
106 static int hf_rdp_requestedProtocols_flag_hybrid_ex = -1;
107 static int hf_rdp_correlationInfo_flags;
108 static int hf_rdp_correlationId = -1;
109 static int hf_rdp_correlationInfo_reserved = -1;
110 static int hf_rdp_negRsp_flags = -1;
111 static int hf_rdp_negRsp_flag_extended_client_data_supported = -1;
112 static int hf_rdp_negRsp_flag_dynvc_gfx_protocol_supported = -1;
113 static int hf_rdp_negRsp_flag_restricted_admin_mode_supported = -1;
114 static int hf_rdp_negRsp_flag_restricted_authentication_mode_supported = -1;
115 static int hf_rdp_selectedProtocol = -1;
116 static int hf_rdp_negFailure_failureCode = -1;
117 
118 static int hf_rdp_ClientData = -1;
119 static int hf_rdp_SendData = -1;
120 static int hf_rdp_MessageData = -1;
121 static int hf_rdp_clientCoreData = -1;
122 static int hf_rdp_clientSecurityData = -1;
123 static int hf_rdp_clientNetworkData = -1;
124 static int hf_rdp_clientClusterData = -1;
125 static int hf_rdp_clientMonitorData = -1;
126 static int hf_rdp_clientMonitorDefData = -1;
127 static int hf_rdp_clientMsgChannelData = -1;
128 static int hf_rdp_clientMonitorExData = -1;
129 static int hf_rdp_clientMultiTransportData = -1;
130 static int hf_rdp_clientUnknownData = -1;
131 static int hf_rdp_ServerData = -1;
132 static int hf_rdp_serverCoreData = -1;
133 static int hf_rdp_serverSecurityData = -1;
134 static int hf_rdp_serverNetworkData = -1;
135 static int hf_rdp_serverMsgChannelData = -1;
136 static int hf_rdp_serverMultiTransportData = -1;
137 static int hf_rdp_serverUnknownData = -1;
138 
139 static int hf_rdp_securityExchangePDU = -1;
140 static int hf_rdp_clientInfoPDU = -1;
141 static int hf_rdp_validClientLicenseData = -1;
142 
143 static int hf_rdp_headerType = -1;
144 static int hf_rdp_headerLength = -1;
145 static int hf_rdp_versionMajor = -1;
146 static int hf_rdp_versionMinor = -1;
147 static int hf_rdp_desktopWidth = -1;
148 static int hf_rdp_desktopHeight = -1;
149 static int hf_rdp_colorDepth = -1;
150 static int hf_rdp_SASSequence = -1;
151 static int hf_rdp_keyboardLayout = -1;
152 static int hf_rdp_clientBuild = -1;
153 static int hf_rdp_clientName = -1;
154 static int hf_rdp_keyboardType = -1;
155 static int hf_rdp_keyboardSubType = -1;
156 static int hf_rdp_keyboardFunctionKey = -1;
157 static int hf_rdp_imeFileName = -1;
158 static int hf_rdp_postBeta2ColorDepth = -1;
159 static int hf_rdp_clientProductId = -1;
160 static int hf_rdp_serialNumber = -1;
161 static int hf_rdp_highColorDepth = -1;
162 static int hf_rdp_supportedColorDepths = -1;
163 static int hf_rdp_earlyCapabilityFlags = -1;
164 static int hf_rdp_clientDigProductId = -1;
165 static int hf_rdp_connectionType = -1;
166 static int hf_rdp_pad1octet = -1;
167 static int hf_rdp_serverSelectedProtocol = -1;
168 
169 static int hf_rdp_encryptionMethods = -1;
170 static int hf_rdp_extEncryptionMethods = -1;
171 static int hf_rdp_cluster_flags = -1;
172 static int hf_rdp_redirectedSessionId = -1;
173 static int hf_rdp_msgChannelFlags = -1;
174 static int hf_rdp_msgChannelId = -1;
175 static int hf_rdp_monitorFlags = -1;
176 static int hf_rdp_monitorExFlags = -1;
177 static int hf_rdp_monitorAttributeSize = -1;
178 static int hf_rdp_monitorCount = -1;
179 static int hf_rdp_multiTransportFlags = -1;
180 
181 static int hf_rdp_monitorDefLeft = -1;
182 static int hf_rdp_monitorDefTop = -1;
183 static int hf_rdp_monitorDefRight = -1;
184 static int hf_rdp_monitorDefBottom = -1;
185 static int hf_rdp_monitorDefFlags = -1;
186 
187 
188 static int hf_rdp_encryptionMethod = -1;
189 static int hf_rdp_encryptionLevel  = -1;
190 static int hf_rdp_serverRandomLen  = -1;
191 static int hf_rdp_serverCertLen  = -1;
192 static int hf_rdp_serverRandom = -1;
193 static int hf_rdp_serverCertificate = -1;
194 static int hf_rdp_clientRequestedProtocols = -1;
195 static int hf_rdp_MCSChannelId = -1;
196 static int hf_rdp_channelCount = -1;
197 static int hf_rdp_channelIdArray = -1;
198 static int hf_rdp_Pad = -1;
199 static int hf_rdp_length = -1;
200 static int hf_rdp_encryptedClientRandom = -1;
201 static int hf_rdp_dataSignature = -1;
202 static int hf_rdp_fipsLength = -1;
203 static int hf_rdp_fipsVersion = -1;
204 static int hf_rdp_padlen = -1;
205 static int hf_rdp_flags = -1;
206 static int hf_rdp_flagsPkt = -1;
207 static int hf_rdp_flagsEncrypt = -1;
208 static int hf_rdp_flagsResetSeqno = -1;
209 static int hf_rdp_flagsIgnoreSeqno = -1;
210 static int hf_rdp_flagsLicenseEncrypt = -1;
211 static int hf_rdp_flagsSecureChecksum = -1;
212 static int hf_rdp_flagsFlagsHiValid = -1;
213 static int hf_rdp_flagsAutodetectReq = -1;
214 static int hf_rdp_flagsAutodetectResp = -1;
215 static int hf_rdp_flagsHeartbeat = -1;
216 static int hf_rdp_flagsTransportReq = -1;
217 static int hf_rdp_flagsTransportResp = -1;
218 static int hf_rdp_heartbeat_reserved = -1;
219 static int hf_rdp_heartbeat_period = -1;
220 static int hf_rdp_heartbeat_count1 = -1;
221 static int hf_rdp_heartbeat_count2 = -1;
222 static int hf_rdp_bandwidth_header_len = -1;
223 static int hf_rdp_bandwidth_header_type = -1;
224 static int hf_rdp_bandwidth_seqnumber = -1;
225 static int hf_rdp_bandwidth_reqtype = -1;
226 static int hf_rdp_bandwidth_resptype = -1;
227 static int hf_rdp_bandwidth_measure_payload_len = -1;
228 static int hf_rdp_bandwidth_measure_payload_data = -1;
229 static int hf_rdp_network_characteristics_basertt = -1;
230 static int hf_rdp_network_characteristics_bandwidth = -1;
231 static int hf_rdp_network_characteristics_averagertt = -1;
232 static int hf_rdp_rtt_measure_time_delta = -1;
233 static int hf_rdp_rtt_measure_time_bytecount = -1;
234 static int hf_rdp_mt_req_requestId = -1;
235 static int hf_rdp_mt_req_protocol = -1;
236 static int hf_rdp_mt_req_reserved = -1;
237 static int hf_rdp_mt_req_securityCookie = -1;
238 static int hf_rdp_mt_rsp_requestId = -1;
239 static int hf_rdp_mt_rsp_hrResponse = -1;
240 static int hf_rdp_flagsHi = -1;
241 static int hf_rdp_codePage = -1;
242 static int hf_rdp_optionFlags = -1;
243 static int hf_rdp_cbDomain = -1;
244 static int hf_rdp_cbUserName = -1;
245 static int hf_rdp_cbPassword = -1;
246 static int hf_rdp_cbAlternateShell = -1;
247 static int hf_rdp_cbWorkingDir = -1;
248 static int hf_rdp_cbClientAddress = -1;
249 static int hf_rdp_cbClientDir = -1;
250 static int hf_rdp_cbAutoReconnectLen = -1;
251 static int hf_rdp_domain = -1;
252 static int hf_rdp_userName = -1;
253 static int hf_rdp_password = -1;
254 static int hf_rdp_alternateShell = -1;
255 static int hf_rdp_workingDir = -1;
256 static int hf_rdp_clientAddressFamily = -1;
257 static int hf_rdp_clientAddress = -1;
258 static int hf_rdp_clientDir = -1;
259 static int hf_rdp_clientTimeZone = -1;
260 static int hf_rdp_clientSessionId = -1;
261 static int hf_rdp_performanceFlags = -1;
262 static int hf_rdp_autoReconnectCookie = -1;
263 static int hf_rdp_reserved1 = -1;
264 static int hf_rdp_reserved2 = -1;
265 static int hf_rdp_bMsgType = -1;
266 static int hf_rdp_bVersion = -1;
267 static int hf_rdp_wMsgSize = -1;
268 static int hf_rdp_wBlobType = -1;
269 static int hf_rdp_wBlobLen = -1;
270 static int hf_rdp_blobData = -1;
271 static int hf_rdp_shareControlHeader = -1;
272 static int hf_rdp_totalLength = -1;
273 static int hf_rdp_pduType = -1;
274 static int hf_rdp_pduTypeType = -1;
275 static int hf_rdp_pduTypeVersionLow = -1;
276 static int hf_rdp_pduTypeVersionHigh = -1;
277 static int hf_rdp_pduSource = -1;
278 
279 static int hf_rdp_shareId = -1;
280 static int hf_rdp_pad1 = -1;
281 static int hf_rdp_streamId = -1;
282 static int hf_rdp_uncompressedLength = -1;
283 static int hf_rdp_pduType2 = -1;
284 static int hf_rdp_compressedType = -1;
285 static int hf_rdp_compressedTypeType = -1;
286 static int hf_rdp_compressedTypeCompressed = -1;
287 static int hf_rdp_compressedTypeAtFront = -1;
288 static int hf_rdp_compressedTypeFlushed = -1;
289 static int hf_rdp_compressedLength = -1;
290 static int hf_rdp_wErrorCode = -1;
291 static int hf_rdp_wStateTransition = -1;
292 static int hf_rdp_numberEntries = -1;
293 static int hf_rdp_totalNumberEntries = -1;
294 static int hf_rdp_mapFlags = -1;
295 static int hf_rdp_fontMapFirst = -1;
296 static int hf_rdp_fontMapLast = -1;
297 
298 /* Control */
299 static int hf_rdp_action = -1;
300 static int hf_rdp_grantId = -1;
301 static int hf_rdp_controlId = -1;
302 
303 /* Synchronize */
304 static int hf_rdp_messageType = -1;
305 static int hf_rdp_targetUser = -1;
306 
307 /* BitmapCache Persistent List */
308 static int hf_rdp_numEntriesCache0 = -1;
309 static int hf_rdp_numEntriesCache1 = -1;
310 static int hf_rdp_numEntriesCache2 = -1;
311 static int hf_rdp_numEntriesCache3 = -1;
312 static int hf_rdp_numEntriesCache4 = -1;
313 static int hf_rdp_totalEntriesCache0 = -1;
314 static int hf_rdp_totalEntriesCache1 = -1;
315 static int hf_rdp_totalEntriesCache2 = -1;
316 static int hf_rdp_totalEntriesCache3 = -1;
317 static int hf_rdp_totalEntriesCache4 = -1;
318 static int hf_rdp_bBitMask = -1;
319 static int hf_rdp_Pad2 = -1;
320 static int hf_rdp_Pad3 = -1;
321 
322 /* BitmapCache Persistent List Entry */
323 /* static int hf_rdp_Key1 = -1; */
324 /* static int hf_rdp_Key2 = -1; */
325 
326 /* FontList */
327 #if 0
328 static int hf_rdp_numberFonts = -1;
329 static int hf_rdp_totalNumFonts = -1;
330 static int hf_rdp_listFlags = -1;
331 #endif
332 static int hf_rdp_entrySize = -1;
333 
334 /* Confirm Active PDU */
335 static int hf_rdp_originatorId = -1;
336 static int hf_rdp_lengthSourceDescriptor = -1;
337 static int hf_rdp_lengthCombinedCapabilities = -1;
338 static int hf_rdp_sourceDescriptor = -1;
339 static int hf_rdp_numberCapabilities = -1;
340 static int hf_rdp_pad2Octets = -1;
341 static int hf_rdp_capabilitySet = -1;
342 static int hf_rdp_capabilitySetType = -1;
343 static int hf_rdp_lengthCapability = -1;
344 static int hf_rdp_capabilityData = -1;
345 static int hf_rdp_sessionId = -1;
346 
347 /* static int hf_rdp_unknownData = -1; */
348 static int hf_rdp_notYetImplemented = -1;
349 static int hf_rdp_encrypted = -1;
350 /* static int hf_rdp_compressed = -1; */
351 
352 static int hf_rdp_channelDefArray = -1;
353 static int hf_rdp_channelDef = -1;
354 static int hf_rdp_name = -1;
355 static int hf_rdp_options = -1;
356 static int hf_rdp_optionsInitialized = -1;
357 static int hf_rdp_optionsEncryptRDP = -1;
358 static int hf_rdp_optionsEncryptSC = -1;
359 static int hf_rdp_optionsEncryptCS = -1;
360 static int hf_rdp_optionsPriHigh = -1;
361 static int hf_rdp_optionsPriMed = -1;
362 static int hf_rdp_optionsPriLow = -1;
363 static int hf_rdp_optionsCompressRDP = -1;
364 static int hf_rdp_optionsCompress = -1;
365 static int hf_rdp_optionsShowProtocol= -1;
366 static int hf_rdp_optionsRemoteControlPersistent = -1;
367 
368 static int hf_rdp_channelPDUHeader = -1;
369 static int hf_rdp_channelFlags = -1;
370 static int hf_rdp_channelFlagFirst = -1;
371 static int hf_rdp_channelFlagLast = -1;
372 static int hf_rdp_channelFlagShowProtocol = -1;
373 static int hf_rdp_channelFlagSuspend = -1;
374 static int hf_rdp_channelFlagResume = -1;
375 static int hf_rdp_channelPacketCompressed = -1;
376 static int hf_rdp_channelPacketAtFront = -1;
377 static int hf_rdp_channelPacketFlushed = -1;
378 static int hf_rdp_channelPacketCompressionType = -1;
379 static int hf_rdp_virtualChannelData = -1;
380 
381 static int hf_rdp_fastpathPDULength = -1;
382 
383 static int hf_rdp_wYear = -1;
384 static int hf_rdp_wMonth = -1;
385 static int hf_rdp_wDayOfWeek = -1;
386 static int hf_rdp_wDay = -1;
387 static int hf_rdp_wHour = -1;
388 static int hf_rdp_wMinute = -1;
389 static int hf_rdp_wSecond = -1;
390 static int hf_rdp_wMilliseconds = -1;
391 
392 static int hf_rdp_Bias = -1;
393 static int hf_rdp_StandardName = -1;
394 static int hf_rdp_StandardDate = -1;
395 static int hf_rdp_StandardBias = -1;
396 static int hf_rdp_DaylightName = -1;
397 static int hf_rdp_DaylightDate = -1;
398 static int hf_rdp_DaylightBias = -1;
399 
400 #define TYPE_RDP_NEG_REQ          0x01
401 #define TYPE_RDP_NEG_RSP          0x02
402 #define TYPE_RDP_NEG_FAILURE      0x03
403 #define TYPE_RDP_CORRELATION_INFO 0x06
404 
405 static const value_string neg_type_vals[] = {
406   { TYPE_RDP_NEG_REQ,          "RDP Negotiation Request" },
407   { TYPE_RDP_NEG_RSP,          "RDP Negotiation Response" },
408   { TYPE_RDP_NEG_FAILURE,      "RDP Negotiation Failure" },
409   { TYPE_RDP_CORRELATION_INFO, "RDP Correlation Info" },
410   { 0, NULL }
411 };
412 
413 #define RESTRICTED_ADMIN_MODE_REQUIRED 0x01
414 #define CORRELATION_INFO_PRESENT       0x08
415 
416 static const value_string failure_code_vals[] = {
417   { 0x00000001, "TLS required by server" },
418   { 0x00000002, "TLS not allowed by server" },
419   { 0x00000003, "TLS certificate not on server" },
420   { 0x00000004, "Inconsistent flags" },
421   { 0x00000005, "Server requires Enhanced RDP Security with CredSSP" },
422   { 0x00000006, "Server requires Enhanced RDP Security with TLS and certificate-based client authentication" },
423   { 0, NULL }
424 };
425 
426 #define CS_CORE                0xC001
427 #define CS_SECURITY            0xC002
428 #define CS_NET                 0xC003
429 #define CS_CLUSTER             0xC004
430 #define CS_MONITOR             0xC005
431 #define CS_MCS_MSGCHANNEL      0xC006
432 #define CS_MONITOR_EX          0xC008
433 #define CS_MULTITRANSPORT      0xC00A
434 
435 #define SC_CORE                0x0C01
436 #define SC_SECURITY            0x0C02
437 #define SC_NET                 0x0C03
438 #define SC_MCS_MSGCHANNEL      0x0C04
439 #define SC_MULTITRANSPORT      0x0C08
440 
441 #define SEC_EXCHANGE_PKT       0x0001
442 #define SEC_TRANSPORT_REQ  	   0x0002
443 #define SEC_TRANSPORT_RSP 	   0x0004
444 #define SEC_ENCRYPT            0x0008
445 #define SEC_RESET_SEQNO        0x0010
446 #define SEC_IGNORE_SEQNO       0x0020
447 #define SEC_INFO_PKT           0x0040
448 #define SEC_LICENSE_PKT        0x0080
449 #define SEC_LICENSE_ENCRYPT_CS 0x0200
450 #define SEC_LICENSE_ENCRYPT_SC 0x0200
451 #define SEC_REDIRECTION_PKT    0x0400
452 #define SEC_SECURE_CHECKSUM    0x0800
453 #define SEC_AUTODETECT_REQ	   0x1000
454 #define SEC_AUTODETECT_RSP 	   0x2000
455 #define SEC_HEARTBEAT 		   0x4000
456 #define SEC_FLAGSHI_VALID      0x8000
457 
458 #define SEC_PKT_MASK           0x04c1
459 
460 #define ENCRYPTION_METHOD_NONE    0x00000000
461 #define ENCRYPTION_METHOD_40BIT   0x00000001
462 #define ENCRYPTION_METHOD_128BIT  0x00000002
463 #define ENCRYPTION_METHOD_56BIT   0x00000008
464 #define ENCRYPTION_METHOD_FIPS    0x00000010
465 
466 #define ENCRYPTION_LEVEL_NONE               0x00000000
467 #define ENCRYPTION_LEVEL_LOW                0x00000001
468 #define ENCRYPTION_LEVEL_CLIENT_COMPATIBLE  0x00000002
469 #define ENCRYPTION_LEVEL_HIGH               0x00000003
470 #define ENCRYPTION_LEVEL_FIPS               0x00000004
471 
472 /* sent by server */
473 #define LICENSE_REQUEST             0x01
474 #define PLATFORM_CHALLENGE          0x02
475 #define NEW_LICENSE                 0x03
476 #define UPGRADE_LICENSE             0x04
477 /* sent by client */
478 #define LICENSE_INFO                0x12
479 #define NEW_LICENSE_REQUEST         0x13
480 #define PLATFORM_CHALLENGE_RESPONSE 0x15
481 /* sent by either */
482 #define ERROR_ALERT                 0xff
483 
484 #define ERR_INVALID_SERVER_CERTIFICIATE 0x00000001
485 #define ERR_NO_LICENSE                  0x00000002
486 #define ERR_INVALID_MAC                 0x00000003
487 #define ERR_INVALID_SCOPE               0x00000004
488 #define ERR_NO_LICENSE_SERVER           0x00000006
489 #define STATUS_VALID_CLIENT             0x00000007
490 #define ERR_INVALID_CLIENT              0x00000008
491 #define ERR_INVALID_PRODUCTID           0x0000000B
492 #define ERR_INVALID_MESSAGE_LEN         0x0000000C
493 
494 #define ST_TOTAL_ABORT                  0x00000001
495 #define ST_NO_TRANSITION                0x00000002
496 #define ST_RESET_PHASE_TO_START         0x00000003
497 #define ST_RESEND_LAST_MESSAGE          0x00000004
498 
499 #define BB_DATA_BLOB                0x0001
500 #define BB_RANDOM_BLOB              0x0002
501 #define BB_CERTIFICATE_BLOB         0x0003
502 #define BB_ERROR_BLOB               0x0004
503 #define BB_ENCRYPTED_DATA_BLOB      0x0009
504 #define BB_KEY_EXCHG_ALG_BLOB       0x000D
505 #define BB_SCOPE_BLOB               0x000E
506 #define BB_CLIENT_USER_NAME_BLOB    0x000F
507 #define BB_CLIENT_MACHINE_NAME_BLOB 0x0010
508 
509 #define PDUTYPE_TYPE_MASK           0x000F
510 #define PDUTYPE_VERSIONLOW_MASK     0x00F0
511 #define PDUTYPE_VERSIONHIGH_MASK    0xFF00
512 
513 #define PDUTYPE_DEMANDACTIVEPDU     0x1
514 #define PDUTYPE_CONFIRMACTIVEPDU    0x3
515 #define PDUTYPE_DEACTIVATEALLPDU    0x6
516 #define PDUTYPE_DATAPDU             0x7
517 #define PDUTYPE_SERVER_REDIR_PKT    0xA
518 
519 #define TS_PROTOCOL_VERSION         0x1
520 
521 #define PDUTYPE2_UPDATE                      0x02
522 #define PDUTYPE2_CONTROL                     0x14
523 #define PDUTYPE2_POINTER                     0x1B
524 #define PDUTYPE2_INPUT                       0x1C
525 #define PDUTYPE2_SYNCHRONIZE                 0x1F
526 #define PDUTYPE2_REFRESH_RECT                0x21
527 #define PDUTYPE2_PLAY_SOUND                  0x22
528 #define PDUTYPE2_SUPPRESS_OUTPUT             0x23
529 #define PDUTYPE2_SHUTDOWN_REQUEST            0x24
530 #define PDUTYPE2_SHUTDOWN_DENIED             0x25
531 #define PDUTYPE2_SAVE_SESSION_INFO           0x26
532 #define PDUTYPE2_FONTLIST                    0x27
533 #define PDUTYPE2_FONTMAP                     0x28
534 #define PDUTYPE2_SET_KEYBOARD_INDICATORS     0x29
535 #define PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST 0x2B
536 #define PDUTYPE2_BITMAPCACHE_ERROR_PDU       0x2C
537 #define PDUTYPE2_SET_KEYBOARD_IME_STATUS     0x2D
538 #define PDUTYPE2_OFFSCRCACHE_ERROR_PDU       0x2E
539 #define PDUTYPE2_SET_ERROR_INFO_PDU          0x2F
540 #define PDUTYPE2_DRAWNINEGRID_ERROR_PDU      0x30
541 #define PDUTYPE2_DRAWGDIPLUS_ERROR_PDU       0x31
542 #define PDUTYPE2_ARC_STATUS_PDU              0x32
543 #define PDUTYPE2_STATUS_INFO_PDU             0x36
544 #define PDUTYPE2_MONITOR_LAYOUT_PDU          0x37
545 
546 #define PACKET_COMPRESSED                    0x20
547 #define PACKET_AT_FRONT                      0x40
548 #define PACKET_FLUSHED                       0x80
549 
550 #define PacketCompressionTypeMask            0x0f
551 #define PACKET_COMPR_TYPE_8K                 0x0
552 #define PACKET_COMPR_TYPE_64K                0x1
553 #define PACKET_COMPR_TYPE_RDP6               0x2
554 #define PACKET_COMPR_TYPE_RDP61              0x3
555 
556 
557 #define CHANNEL_FLAG_FIRST                   0x00000001
558 #define CHANNEL_FLAG_LAST                    0x00000002
559 #define CHANNEL_FLAG_SHOW_PROTOCOL           0x00000010
560 #define CHANNEL_FLAG_SUSPEND                 0x00000020
561 #define CHANNEL_FLAG_RESUME                  0x00000040
562 #define CHANNEL_PACKET_COMPRESSED            0x00200000
563 #define CHANNEL_PACKET_AT_FRONT              0x00400000
564 #define CHANNEL_PACKET_FLUSHED               0x00800000
565 
566 #define ChannelCompressionTypeMask           0x000f0000
567 #define CHANNEL_COMPR_TYPE_8K                0x00000000
568 #define CHANNEL_COMPR_TYPE_64K               0x00010000
569 #define CHANNEL_COMPR_TYPE_RDP6              0x00020000
570 #define CHANNEL_COMPR_TYPE_RDP61             0x00030000
571 
572 #define MapFlagsMask                         0xffff
573 #define FONTMAP_FIRST                        0x0001
574 #define FONTMAP_LAST                         0x0002
575 /* There may well be others */
576 
577 #define CTRLACTION_REQUEST_CONTROL           0x0001
578 #define CTRLACTION_GRANTED_CONTROL           0x0002
579 #define CTRLACTION_DETACH                    0x0003
580 #define CTRLACTION_COOPERATE                 0x0004
581 
582 #define CAPSTYPE_GENERAL                     0x0001
583 #define CAPSTYPE_BITMAP                      0x0002
584 #define CAPSTYPE_ORDER                       0x0003
585 #define CAPSTYPE_BITMAPCACHE                 0x0004
586 #define CAPSTYPE_CONTROL                     0x0005
587 #define CAPSTYPE_ACTIVATION                  0x0007
588 #define CAPSTYPE_POINTER                     0x0008
589 #define CAPSTYPE_SHARE                       0x0009
590 #define CAPSTYPE_COLORCACHE                  0x000A
591 #define CAPSTYPE_SOUND                       0x000C
592 #define CAPSTYPE_INPUT                       0x000D
593 #define CAPSTYPE_FONT                        0x000E
594 #define CAPSTYPE_BRUSH                       0x000F
595 #define CAPSTYPE_GLYPHCACHE                  0x0010
596 #define CAPSTYPE_OFFSCREENCACHE              0x0011
597 #define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT     0x0012
598 #define CAPSTYPE_BITMAPCACHE_REV2            0x0013
599 #define CAPSTYPE_BITMAPCACHE_VIRTUALCHANNEL  0x0014
600 #define CAPSTYPE_DRAWNINEGRIDCACHE           0x0015
601 #define CAPSTYPE_DRAWGDIPLUS                 0x0016
602 #define CAPSTYPE_RAIL                        0x0017
603 #define CAPSTYPE_WINDOW                      0x0018
604 #define CAPSTYPE_COMPDESK                    0x0019
605 #define CAPSTYPE_MULTIFRAGMENTUPDATE         0x001A
606 #define CAPSTYPE_LARGE_POINTER               0x001B
607 #define CAPSTYPE_SURFACE_COMMANDS            0x001C
608 #define CAPSTYPE_BITMAP_CODECS               0x001D
609 
610 
611 #define CHANNEL_OPTION_INITIALIZED               0x80000000
612 #define CHANNEL_OPTION_ENCRYPT_RDP               0x40000000
613 #define CHANNEL_OPTION_ENCRYPT_SC                0x20000000
614 #define CHANNEL_OPTION_ENCRYPT_CS                0x10000000
615 #define CHANNEL_OPTION_PRI_HIGH                  0x08000000
616 #define CHANNEL_OPTION_PRI_MED                   0x04000000
617 #define CHANNEL_OPTION_PRI_LOW                   0x02000000
618 #define CHANNEL_OPTION_COMPRESS_RDP              0x00800000
619 #define CHANNEL_OPTION_COMPRESS                  0x00400000
620 #define CHANNEL_OPTION_SHOW_PROTOCOL             0x00200000
621 #define CHANNEL_OPTION_REMOTE_CONTROL_PERSISTENT 0x00100000
622 
623 
624 #define RDP_FI_NONE          0x00
625 #define RDP_FI_OPTIONAL      0x01
626 #define RDP_FI_STRING        0x02
627 #define RDP_FI_UNICODE       0x04 /* field is always Unicode (UTF-16) */
628 #define RDP_FI_ANSI          0x08 /* field is always ANSI (code page) */
629 #define RDP_FI_NOINCOFFSET   0x10 /* do not increase the offset */
630 #define RDP_FI_SUBTREE       0x20
631 #define RDP_FI_INFO_FLAGS    0x40
632 
633 typedef struct rdp_field_info_t {
634   const int *pfield;
635   gint32   fixedLength;
636   guint32 *variableLength;
637   int      offsetOrTree;
638   guint32  flags;
639   const struct rdp_field_info_t *subfields;
640 } rdp_field_info_t;
641 
642 #define FI_FIXEDLEN(_hf_, _len_) { _hf_, _len_, NULL, 0, 0, NULL }
643 #define FI_FIXEDLEN_ANSI_STRING(_hf_, _len_) { _hf_, _len_, NULL, 0, RDP_FI_STRING|RDP_FI_ANSI, NULL }
644 #define FI_VALUE(_hf_, _len_, _value_) { _hf_, _len_, &_value_, 0, 0, NULL }
645 #define FI_VARLEN(_hf, _length_) { _hf_, 0, &_length_, 0, 0, NULL }
646 #define FI_SUBTREE(_hf_, _len_, _ett_, _sf_) { _hf_, _len_, NULL, _ett_, RDP_FI_SUBTREE, _sf_ }
647 #define FI_TERMINATOR {NULL, 0, NULL, 0, 0, NULL}
648 
649 static const value_string rdp_headerType_vals[] = {
650   { CS_CORE,           "clientCoreData" },
651   { CS_SECURITY,       "clientSecurityData" },
652   { CS_NET,            "clientNetworkData" },
653   { CS_CLUSTER,        "clientClusterData" },
654   { CS_MONITOR,        "clientMonitorData" },
655   { CS_MCS_MSGCHANNEL, "clientMsgChannelData" },
656   { CS_MONITOR_EX,     "clientMonitorExData" },
657   { CS_MULTITRANSPORT, "clientMultiTransportData" },
658   { SC_CORE,           "serverCoreData" },
659   { SC_SECURITY,       "serverSecurityData" },
660   { SC_NET,            "serverNetworkData" },
661   { SC_MCS_MSGCHANNEL, "serverMsgChannelData" },
662   { SC_MULTITRANSPORT, "serverMultiTransportData" },
663   { 0, NULL }
664 };
665 
666 static const value_string rdp_colorDepth_vals[] = {
667   { 0xCA00, "4 bits-per-pixel (bpp)"},
668   { 0xCA01, "8 bits-per-pixel (bpp)"},
669   { 0xCA02, "15-bit 555 RGB mask"},
670   { 0xCA03, "16-bit 565 RGB mask"},
671   { 0xCA04, "24-bit RGB mask"},
672   { 0, NULL }
673 };
674 
675 static const value_string rdp_highColorDepth_vals[] = {
676   { 0x0004, "4 bits-per-pixel (bpp)"},
677   { 0x0008, "8 bits-per-pixel (bpp)"},
678   { 0x000F, "15-bit 555 RGB mask"},
679   { 0x0010, "16-bit 565 RGB mask"},
680   { 0x0018, "24-bit RGB mask"},
681   { 0, NULL }
682 };
683 
684 
685 static const value_string rdp_keyboardType_vals[] = {
686   {   1, "IBM PC/XT or compatible (83-key) keyboard" },
687   {   2, "Olivetti \"ICO\" (102-key) keyboard" },
688   {   3, "IBM PC/AT (84-key) and similar keyboards" },
689   {   4, "IBM enhanced (101-key or 102-key) keyboard" },
690   {   5, "Noki 1050 and similar keyboards" },
691   {   6, "Nokia 9140 and similar keyboards" },
692   {   7, "Japanese keyboard" },
693   {   0, NULL }
694 };
695 
696 static const value_string rdp_connectionType_vals[] = {
697   {   1, "Modem (56 Kbps)" },
698   {   2, "Low-speed broadband (256 Kbps - 2Mbps)" },
699   {   3, "Satellite (2 Mbps - 16Mbps with high latency)" },
700   {   4, "High-speed broadband (2 Mbps - 10Mbps)" },
701   {   5, "WAN (10 Mbps or higher with high latency)" },
702   {   6, "LAN (10 Mbps or higher)" },
703   {   7, "Auto Detect" },
704   {   0, NULL},
705 };
706 
707 static const value_string rdp_selectedProtocol_vals[] = {
708   {   0x0, "Standard RDP Security" },
709   {   0x1, "TLS 1.0, 1.1 or 1.2" },
710   {   0x2, "CredSSP" },
711   {   0x4, "RDSTLS protocol" },
712   {   0x8, "CredSSP with Early User Authorization Result PDU" },
713   {   0x0, NULL},
714 };
715 
716 static const value_string rdp_flagsPkt_vals[] = {
717   {0,                   "(None)" },
718   {SEC_EXCHANGE_PKT,    "Security Exchange PDU" },
719   {SEC_INFO_PKT,        "Client Info PDU" },
720   {SEC_LICENSE_PKT,     "Licensing PDU" },
721   {SEC_REDIRECTION_PKT, "Standard Security Server Redirection PDU"},
722   {0, NULL},
723 };
724 
725 static const value_string rdp_encryptionMethod_vals[] = {
726   { ENCRYPTION_METHOD_NONE,   "None" },
727   { ENCRYPTION_METHOD_40BIT,  "40-bit RC4" },
728   { ENCRYPTION_METHOD_128BIT, "128-bit RC4" },
729   { ENCRYPTION_METHOD_56BIT,  "56-bit RC4" },
730   { ENCRYPTION_METHOD_FIPS,   "FIPS140-1 3DES" },
731   { 0, NULL},
732 };
733 
734 static const value_string rdp_encryptionLevel_vals[] = {
735   { ENCRYPTION_LEVEL_NONE,              "None" },
736   { ENCRYPTION_LEVEL_LOW,               "Low" },
737   { ENCRYPTION_LEVEL_CLIENT_COMPATIBLE, "Client Compatible" },
738   { ENCRYPTION_LEVEL_HIGH,              "High" },
739   { ENCRYPTION_LEVEL_FIPS,              "FIPS140-1" },
740   { 0, NULL},
741 };
742 
743 static const value_string rdp_bMsgType_vals[] = {
744   { LICENSE_REQUEST,             "License Request" },
745   { PLATFORM_CHALLENGE,          "Platform Challenge" },
746   { NEW_LICENSE,                 "New License" },
747   { UPGRADE_LICENSE,             "Upgrade License" },
748   { LICENSE_INFO,                "License Info" },
749   { NEW_LICENSE_REQUEST,         "New License Request" },
750   { PLATFORM_CHALLENGE_RESPONSE, "Platform Challenge Response" },
751   { ERROR_ALERT,                 "Error Alert" },
752   { 0, NULL},
753 };
754 
755 static const value_string rdp_wErrorCode_vals[] = {
756   { ERR_INVALID_SERVER_CERTIFICIATE, "Invalid Server Certificate" },
757   { ERR_NO_LICENSE,                  "No License" },
758   { ERR_INVALID_MAC,                 "Invalid MAC" },
759   { ERR_INVALID_SCOPE,               "Invalid Scope" },
760   { ERR_NO_LICENSE_SERVER,           "No License Server" },
761   { STATUS_VALID_CLIENT,             "Valid Client" },
762   { ERR_INVALID_CLIENT,              "Invalid Client" },
763   { ERR_INVALID_PRODUCTID,           "Invalid Product Id" },
764   { ERR_INVALID_MESSAGE_LEN,         "Invalid Message Length" },
765   { 0, NULL},
766 };
767 
768 static const value_string rdp_wStateTransition_vals[] = {
769   { ST_TOTAL_ABORT,              "Total Abort" },
770   { ST_NO_TRANSITION,            "No Transition" },
771   { ST_RESET_PHASE_TO_START,     "Reset Phase to Start" },
772   { ST_RESEND_LAST_MESSAGE,      "Resend Last Message" },
773   { 0, NULL},
774 };
775 
776 static const value_string rdp_wBlobType_vals[] = {
777   { BB_DATA_BLOB,                "Data" },
778   { BB_RANDOM_BLOB,              "Random" },
779   { BB_CERTIFICATE_BLOB,         "Certificate" },
780   { BB_ERROR_BLOB,               "Error" },
781   { BB_ENCRYPTED_DATA_BLOB,      "Encrypted Data" },
782   { BB_KEY_EXCHG_ALG_BLOB,       "Key Exchange Algorithm" },
783   { BB_SCOPE_BLOB,               "Scope" },
784   { BB_CLIENT_USER_NAME_BLOB,    "Client User Name" },
785   { BB_CLIENT_MACHINE_NAME_BLOB, "Client Machine Name" },
786   { 0, NULL}
787 };
788 
789 enum {
790 	TYPE_ID_AUTODETECT_REQUEST = 0x00,
791 	TYPE_ID_AUTODETECT_RESPONSE = 0x01
792 };
793 
794 static const value_string bandwidth_typeid_vals[] = {
795 	{ TYPE_ID_AUTODETECT_REQUEST, "AUTODETECT_REQUEST"},
796 	{ TYPE_ID_AUTODETECT_RESPONSE, "AUTODETECT_RESPONSE"},
797 	{ 0, NULL}
798 };
799 
800 static const value_string bandwidth_request_vals[] = {
801 	{ 0x0001, "RTT Measure Request" },
802 	{ 0x1001, "RTT Measure Request (auto detection phase)" },
803 	{ 0x0014, "Bandwidth Measure Start" },
804 	{ 0x0114, "Bandwidth Measure Start (UDP lossy)" },
805 	{ 0x1014, "Bandwidth Measure Start (connect time)" },
806 	{ 0x0002, "Bandwidth Measure Payload" },
807 	{ 0x002B, "Bandwidth Measure Stop (connect time)" },
808 	{ 0x0429, "Bandwidth Measure Stop (UDP reliable or autodetect after connection)" },
809 	{ 0x0629, "Bandwidth Measure Stop (UDP lossy)" },
810 	{ 0x0840, "Network Characteristics Result (baseRTT, averageRTT)" },
811 	{ 0x0880, "Network Characteristics Result (bandwidth, averageRTT)" },
812 	{ 0x08C0, "Network Characteristics Result (baseRTT, bandwidth, averageRTT)" },
813 	{ 0, NULL}
814 };
815 
816 static const value_string bandwidth_response_vals[] = {
817 	{ 0x0000, "RTT Measure Response" },
818 	{ 0x0003, "Bandwidth Measure Results (connect time)" },
819 	{ 0x000B, "Bandwidth Measure Results (auto-detect or UDP)" },
820 	{ 0x0018, "Network Characteristics Sync" },
821 	{ 0, NULL}
822 };
823 
824 
825 enum {
826 	INITITATE_REQUEST_PROTOCOL_UDPFECR = 0x1,
827 	INITITATE_REQUEST_PROTOCOL_UDPFECL = 0x2
828 };
829 static const value_string rdp_mt_protocol_vals[] = {
830 	{ INITITATE_REQUEST_PROTOCOL_UDPFECR, "Reliable" },
831 	{ INITITATE_REQUEST_PROTOCOL_UDPFECL, "Lossy" },
832 	{ 0, NULL}
833 };
834 
835 static const value_string rdp_mt_response_vals[] = {
836 	{ 0x00000000, "S_OK" },
837 	{ 0x80004004, "E_ABORT" },
838 	{ 0, NULL}
839 };
840 
841 
842 static const value_string rdp_pduTypeType_vals[] = {
843   { PDUTYPE_DEMANDACTIVEPDU,  "Demand Active PDU" },
844   { PDUTYPE_CONFIRMACTIVEPDU, "Confirm Active PDU" },
845   { PDUTYPE_DEACTIVATEALLPDU, "Deactivate All PDU" },
846   { PDUTYPE_DATAPDU,          "Data PDU" },
847   { PDUTYPE_SERVER_REDIR_PKT, "Server Redirection PDU" },
848   { 0, NULL},
849 };
850 
851 static const value_string rdp_pduType2_vals[] = {
852   { PDUTYPE2_UPDATE,                      "Update"},
853   { PDUTYPE2_CONTROL,                     "Control"},
854   { PDUTYPE2_POINTER,                     "Pointer"},
855   { PDUTYPE2_INPUT,                       "Input"},
856   { PDUTYPE2_SYNCHRONIZE,                 "Synchronize"},
857   { PDUTYPE2_REFRESH_RECT,                "Refresh Rect"},
858   { PDUTYPE2_PLAY_SOUND,                  "Play Sound"},
859   { PDUTYPE2_SUPPRESS_OUTPUT,             "Suppress Output"},
860   { PDUTYPE2_SHUTDOWN_REQUEST,            "Shutdown Request" },
861   { PDUTYPE2_SHUTDOWN_DENIED,             "Shutdown Denied" },
862   { PDUTYPE2_SAVE_SESSION_INFO,           "Save Session Info" },
863   { PDUTYPE2_FONTLIST,                    "FontList" },
864   { PDUTYPE2_FONTMAP,                     "FontMap" },
865   { PDUTYPE2_SET_KEYBOARD_INDICATORS,     "Set Keyboard Indicators" },
866   { PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST, "BitmapCache Persistent List" },
867   { PDUTYPE2_BITMAPCACHE_ERROR_PDU,       "BitmapCache Error" },
868   { PDUTYPE2_SET_KEYBOARD_IME_STATUS,     "Set Keyboard IME Status" },
869   { PDUTYPE2_OFFSCRCACHE_ERROR_PDU,       "OffScrCache Error" },
870   { PDUTYPE2_SET_ERROR_INFO_PDU,          "Set Error Info" },
871   { PDUTYPE2_DRAWNINEGRID_ERROR_PDU,      "DrawNineGrid Error" },
872   { PDUTYPE2_DRAWGDIPLUS_ERROR_PDU,       "DrawGDIPlus Error" },
873   { PDUTYPE2_ARC_STATUS_PDU,              "Arc Status" },
874   { PDUTYPE2_STATUS_INFO_PDU,             "Status Info" },
875   { PDUTYPE2_MONITOR_LAYOUT_PDU,          "Monitor Layout" },
876   { 0, NULL},
877 };
878 
879 static const value_string rdp_compressionType_vals[] = {
880   { PACKET_COMPR_TYPE_8K,     "RDP 4.0 bulk compression" },
881   { PACKET_COMPR_TYPE_64K,    "RDP 5.0 bulk compression" },
882   { PACKET_COMPR_TYPE_RDP6,   "RDP 6.0 bulk compression" },
883   { PACKET_COMPR_TYPE_RDP61,  "RDP 6.1 bulk compression" },
884   { 0, NULL},
885 };
886 
887 static const value_string rdp_channelCompressionType_vals[] = {
888   { CHANNEL_COMPR_TYPE_8K,     		 "RDP 4.0 bulk compression" },
889   { CHANNEL_COMPR_TYPE_64K >> 16,    "RDP 5.0 bulk compression" },
890   { CHANNEL_COMPR_TYPE_RDP6 >> 16,   "RDP 6.0 bulk compression" },
891   { CHANNEL_COMPR_TYPE_RDP61 >> 16,  "RDP 6.1 bulk compression" },
892   { 0, NULL},
893 };
894 
895 static const value_string rdp_action_vals[] = {
896   { CTRLACTION_REQUEST_CONTROL, "Request control" },
897   { CTRLACTION_GRANTED_CONTROL, "Granted control" },
898   { CTRLACTION_DETACH,          "Detach" },
899   { CTRLACTION_COOPERATE,       "Cooperate" },
900   {0, NULL },
901 };
902 
903 static const value_string rdp_capabilityType_vals[] = {
904   { CAPSTYPE_GENERAL,                    "General" },
905   { CAPSTYPE_BITMAP,                     "Bitmap" },
906   { CAPSTYPE_ORDER,                      "Order" },
907   { CAPSTYPE_BITMAPCACHE,                "Bitmap Cache" },
908   { CAPSTYPE_CONTROL,                    "Control" },
909   { CAPSTYPE_ACTIVATION,                 "Activation" },
910   { CAPSTYPE_POINTER,                    "Pointer" },
911   { CAPSTYPE_SHARE,                      "Share" },
912   { CAPSTYPE_COLORCACHE,                 "Color Cache" },
913   { CAPSTYPE_SOUND,                      "Sound" },
914   { CAPSTYPE_INPUT,                      "Input" },
915   { CAPSTYPE_FONT,                       "Font" },
916   { CAPSTYPE_BRUSH,                      "Brush" },
917   { CAPSTYPE_GLYPHCACHE,                 "Glyph Cache" },
918   { CAPSTYPE_OFFSCREENCACHE,             "Off-screen Cache" },
919   { CAPSTYPE_BITMAPCACHE_HOSTSUPPORT,    "Bitmap Cache Host Support" },
920   { CAPSTYPE_BITMAPCACHE_REV2,           "Bitmap Cache Rev 2" },
921   { CAPSTYPE_BITMAPCACHE_VIRTUALCHANNEL, "Virtual Channel"},
922   { CAPSTYPE_DRAWNINEGRIDCACHE,          "Draw Nine Grid Cache" },
923   { CAPSTYPE_DRAWGDIPLUS,                "Draw GDI Plus" },
924   { CAPSTYPE_RAIL,                       "Rail" },
925   { CAPSTYPE_WINDOW,                     "Window" },
926   { CAPSTYPE_COMPDESK,                   "Comp Desk" },
927   { CAPSTYPE_MULTIFRAGMENTUPDATE,        "Multi-Fragment Update" },
928   { CAPSTYPE_LARGE_POINTER,              "Large Pointer" },
929   { CAPSTYPE_SURFACE_COMMANDS,           "Surface Commands" },
930   { CAPSTYPE_BITMAP_CODECS,              "Bitmap Codecs" },
931   {0, NULL },
932 };
933 
934 static const value_string rdp_monitorDefFlags_vals[] = {
935   { 0, "None" },
936   { 1, "Primary" },
937   {0, NULL },
938 };
939 
940 static const value_string rdp_wDayOfWeek_vals[] = {
941   { 0, "Sunday" },
942   { 1, "Monday" },
943   { 2, "Tuesday" },
944   { 3, "Wednesday" },
945   { 4, "Thursday" },
946   { 5, "Friday" },
947   { 6, "Saturday" },
948   {0, NULL },
949 };
950 
951 static const value_string rdp_wDay_vals[] = {
952   { 1, "First occurrence" },
953   { 2, "Second occurrence" },
954   { 3, "Third occurrence" },
955   { 4, "Fourth occurrence" },
956   { 5, "Last occurrence" },
957   {0, NULL },
958 };
959 
960 static const value_string rdp_wMonth_vals[] = {
961   {  1, "January" },
962   {  2, "February" },
963   {  3, "March" },
964   {  4, "April" },
965   {  5, "May" },
966   {  6, "June" },
967   {  7, "July" },
968   {  8, "August" },
969   {  9, "September" },
970   { 10, "October" },
971   { 11, "November" },
972   { 12, "December" },
973   {0, NULL },
974 };
975 
976 
977 static wmem_map_t *rdp_transport_links;
978 
979 typedef struct {
980 	address serverAddr;
981 	guint16 serverPort;
982 	gboolean reliable;
983 	guint32 requestId;
984 	guint8 securityCookie[16];
985 
986 } rdp_transports_key_t;
987 
988 typedef struct {
989 	rdp_transports_key_t key;
990 
991 	conversation_t *tcp_conversation;
992 	conversation_t *udp_conversation;
993 } rdp_transports_link_t;
994 
995 
996 static guint
rdp_udp_conversation_hash(gconstpointer k)997 rdp_udp_conversation_hash(gconstpointer k)
998 {
999 	guint h;
1000 	gint i;
1001 	const rdp_transports_key_t *key = (const rdp_transports_key_t *)k;
1002 
1003 	h = key->serverPort + key->reliable + key->requestId;
1004 	h = add_address_to_hash(h, &key->serverAddr);
1005 	for (i = 0; i < 16; i++)
1006 		h += key->securityCookie[i];
1007 
1008 	return h;
1009 }
1010 
1011 static gboolean
rdp_udp_conversation_equal_matched(gconstpointer k1,gconstpointer k2)1012 rdp_udp_conversation_equal_matched(gconstpointer k1, gconstpointer k2)
1013 {
1014 	const rdp_transports_key_t *key1 = (const rdp_transports_key_t *)k1;
1015 	const rdp_transports_key_t *key2 = (const rdp_transports_key_t *)k2;
1016 
1017 	return addresses_equal(&key1->serverAddr, &key2->serverAddr) &&
1018 			(key1->serverPort == key2->serverPort) &&
1019 			(key1->reliable == key2->reliable) &&
1020 			(key1->requestId == key2->requestId) &&
1021 			memcmp(key1->securityCookie, key2->securityCookie, 16) == 0;
1022 }
1023 
1024 /*
1025  * Flags in the flags field of a TS_INFO_PACKET.
1026  * XXX - define more, and show them underneath that field.
1027  */
1028 #define INFO_UNICODE  0x00000010
1029 
1030 static rdp_conv_info_t *
rdp_get_conversation_data(packet_info * pinfo)1031 rdp_get_conversation_data(packet_info *pinfo)
1032 {
1033   conversation_t  *conversation;
1034   rdp_conv_info_t *rdp_info;
1035 
1036   conversation = find_or_create_conversation(pinfo);
1037 
1038   rdp_info = (rdp_conv_info_t *)conversation_get_proto_data(conversation, proto_rdp);
1039 
1040   if (rdp_info == NULL) {
1041     rdp_info = wmem_new0(wmem_file_scope(), rdp_conv_info_t);
1042     rdp_info->staticChannelId  = -1;
1043     rdp_info->messageChannelId  = -1;
1044     rdp_info->encryptionMethod = 0;
1045     rdp_info->encryptionLevel  = 0;
1046     rdp_info->licenseAgreed    = 0;
1047     rdp_info->maxChannels      = 0;
1048     memset(&rdp_info->serverAddr, 0, sizeof(rdp_info->serverAddr));
1049 
1050     conversation_add_proto_data(conversation, proto_rdp, rdp_info);
1051   }
1052 
1053   return rdp_info;
1054 }
1055 
1056 static int
dissect_rdp_fields(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const rdp_field_info_t * fields,int totlen)1057 dissect_rdp_fields(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const rdp_field_info_t *fields, int totlen)
1058 {
1059   const rdp_field_info_t *c;
1060   gint              len;
1061   int               base_offset = offset;
1062   guint32           info_flags = 0;
1063   guint             encoding;
1064 
1065   while (((c = fields++)->pfield) != NULL) {
1066     if ((c->fixedLength == 0) && (c->variableLength)) {
1067       len = *(c->variableLength);
1068     } else {
1069       len = c->fixedLength;
1070 
1071       if ((c->variableLength) && (c->fixedLength <= 4)) {
1072         switch (c->fixedLength) {
1073         case 1:
1074           *(c->variableLength) = tvb_get_guint8(tvb, offset);
1075           break;
1076         case 2:
1077           *(c->variableLength) = tvb_get_letohs(tvb, offset);
1078           break;
1079         case 4:
1080           *(c->variableLength) = tvb_get_letohl(tvb, offset);
1081           break;
1082         default:
1083           REPORT_DISSECTOR_BUG("Invalid length");
1084         }
1085 
1086         *(c->variableLength) += c->offsetOrTree; /* XXX: ??? */
1087       }
1088     }
1089 
1090     if (len) {
1091       proto_item *pi;
1092       if (c->flags & RDP_FI_STRING) {
1093         /* If this is always Unicode, or if the INFO_UNICODE flag is set,
1094            treat this as UTF-16; otherwise, treat it as "ANSI". */
1095         if (c->flags & RDP_FI_UNICODE)
1096           encoding = ENC_UTF_16|ENC_LITTLE_ENDIAN;
1097         else if (c->flags & RDP_FI_ANSI)
1098           encoding = ENC_ASCII|ENC_NA;  /* XXX - code page */
1099         else {
1100           /* Could be Unicode, could be ANSI, based on INFO_UNICODE flag */
1101           encoding = (info_flags & INFO_UNICODE) ? ENC_UTF_16|ENC_LITTLE_ENDIAN : ENC_ASCII|ENC_NA;  /* XXX - code page */
1102         }
1103       } else
1104         encoding = ENC_LITTLE_ENDIAN;
1105 
1106       pi = proto_tree_add_item(tree, *c->pfield, tvb, offset, len, encoding);
1107 
1108       if (c->flags & RDP_FI_INFO_FLAGS) {
1109         /* TS_INFO_PACKET flags field; save it for later use */
1110         DISSECTOR_ASSERT(len == 4);
1111         info_flags = tvb_get_letohl(tvb, offset);
1112       }
1113 
1114       if (c->flags & RDP_FI_SUBTREE) {
1115         proto_tree *next_tree;
1116         if (c->offsetOrTree != -1)
1117           next_tree = proto_item_add_subtree(pi, c->offsetOrTree);
1118         else
1119           REPORT_DISSECTOR_BUG("Tree Error!!");
1120 
1121         if (c->subfields)
1122           dissect_rdp_fields(tvb, offset, pinfo, next_tree, c->subfields, 0);
1123       }
1124 
1125       if (!(c->flags & RDP_FI_NOINCOFFSET))
1126         offset += len;
1127     }
1128 
1129     if ((totlen > 0) && ((offset-base_offset) >= totlen))
1130       break;  /* we're done: skip optional fields */
1131               /* XXX: err if > totlen ??          */
1132   }
1133 
1134   return offset;
1135 }
1136 
1137 static int
dissect_rdp_nyi(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * info)1138 dissect_rdp_nyi(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char *info)
1139 {
1140   rdp_field_info_t nyi_fields[] = {
1141     {&hf_rdp_notYetImplemented,      -1, NULL, 0, 0, NULL },
1142     FI_TERMINATOR
1143   };
1144 
1145   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, nyi_fields, 0);
1146 
1147   if ((tree != NULL) && (info != NULL))
1148     proto_item_append_text(tree->last_child, " (%s)", info);
1149 
1150   return offset;
1151 }
1152 
1153 static int
dissect_rdp_encrypted(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * info)1154 dissect_rdp_encrypted(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char *info)
1155 {
1156   rdp_field_info_t enc_fields[] = {
1157     {&hf_rdp_encrypted,      -1, NULL, 0, 0, NULL },
1158     FI_TERMINATOR
1159   };
1160 
1161   offset = dissect_rdp_fields(tvb, offset,pinfo, tree, enc_fields, 0);
1162 
1163   if ((tree != NULL) && (info != NULL))
1164     proto_item_append_text(tree->last_child, " (%s)", info);
1165 
1166   col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "[Encrypted]");
1167 
1168   return offset;
1169 }
1170 
1171 static rdp_known_channel_t
find_known_channel_by_name(const char * name)1172 find_known_channel_by_name(const char *name) {
1173 	if (g_ascii_strcasecmp(name, "drdynvc") == 0)
1174 		return RDP_CHANNEL_DRDYNVC;
1175 	if (g_ascii_strcasecmp(name, "rdpdr") == 0)
1176 		return RDP_CHANNEL_DISK;
1177 	if (g_ascii_strcasecmp(name, "rdpsnd") == 0)
1178 		return RDP_CHANNEL_SOUND;
1179 	if (g_ascii_strcasecmp(name, "cliprdr") == 0)
1180 		return RDP_CHANNEL_CLIPBOARD;
1181 	return RDP_CHANNEL_UNKNOWN;
1182 }
1183 
1184 static int
dissect_rdp_clientNetworkData(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint length,rdp_conv_info_t * rdp_info)1185 dissect_rdp_clientNetworkData(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint length, rdp_conv_info_t *rdp_info)
1186 {
1187   proto_tree *next_tree;
1188   proto_item *pi;
1189   guint32     channelCount = 0;
1190 
1191   rdp_field_info_t net_fields[] = {
1192     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
1193     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
1194     FI_VALUE(&hf_rdp_channelCount, 4, channelCount),
1195     FI_TERMINATOR
1196   };
1197   rdp_field_info_t option_fields[] = {
1198     {&hf_rdp_optionsInitialized,  4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1199     {&hf_rdp_optionsEncryptRDP,   4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1200     {&hf_rdp_optionsEncryptSC,    4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1201     {&hf_rdp_optionsEncryptCS,    4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1202     {&hf_rdp_optionsPriHigh,      4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1203     {&hf_rdp_optionsPriMed,       4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1204     {&hf_rdp_optionsPriLow,       4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1205     {&hf_rdp_optionsCompressRDP,  4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1206     {&hf_rdp_optionsCompress,     4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1207     {&hf_rdp_optionsShowProtocol, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1208     {&hf_rdp_optionsRemoteControlPersistent, 4, NULL, 0, 0, NULL },
1209     FI_TERMINATOR,
1210   };
1211   rdp_field_info_t channel_fields[] = {
1212     FI_FIXEDLEN_ANSI_STRING(&hf_rdp_name, 8),
1213     FI_SUBTREE(&hf_rdp_options, 4, ett_rdp_options, option_fields),
1214     FI_TERMINATOR
1215   };
1216   rdp_field_info_t def_fields[] = {
1217     FI_SUBTREE(&hf_rdp_channelDef, 12, ett_rdp_channelDef, channel_fields),
1218     FI_TERMINATOR
1219   };
1220 
1221   pi        = proto_tree_add_item(tree, hf_rdp_clientNetworkData, tvb, offset, length, ENC_NA);
1222   next_tree = proto_item_add_subtree(pi, ett_rdp_clientNetworkData);
1223 
1224   offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, net_fields, 0);
1225 
1226   if (channelCount > 0) {
1227     guint i;
1228     pi        = proto_tree_add_item(next_tree, hf_rdp_channelDefArray, tvb, offset, channelCount * 12, ENC_NA);
1229     next_tree = proto_item_add_subtree(pi, ett_rdp_channelDefArray);
1230 
1231     if (rdp_info)
1232       rdp_info->maxChannels = MIN(channelCount, RDP_MAX_CHANNELS);
1233 
1234 	for (i = 0; i < MIN(channelCount, RDP_MAX_CHANNELS); i++) {
1235 		if (rdp_info) {
1236 			rdp_channel_def_t *channel = &rdp_info->staticChannels[i];
1237 			channel->value = -1; /* unset */
1238 			channel->strptr = tvb_get_string_enc(pinfo->pool, tvb,
1239 					offset, 8, ENC_ASCII);
1240 			channel->channelType = find_known_channel_by_name(
1241 					channel->strptr);
1242 		}
1243 		offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree,
1244 				def_fields, 0);
1245 	}
1246 
1247     if (rdp_info) {
1248       /* value_strings are normally terminated with a {0, NULL} entry */
1249       rdp_info->staticChannels[i].value  = 0;
1250       rdp_info->staticChannels[i].strptr = NULL;
1251     }
1252   }
1253 
1254   return offset;
1255 }
1256 
1257 static int
dissect_rdp_basicSecurityHeader(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint32 * flags_ptr)1258 dissect_rdp_basicSecurityHeader(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 *flags_ptr) {
1259 
1260   guint32 flags = 0;
1261 
1262   rdp_field_info_t secFlags_fields[] = {
1263     {&hf_rdp_flagsPkt,           2, &flags, 0, RDP_FI_NOINCOFFSET, NULL },
1264     {&hf_rdp_flagsEncrypt,       2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1265     {&hf_rdp_flagsResetSeqno,    2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1266     {&hf_rdp_flagsIgnoreSeqno,   2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1267     {&hf_rdp_flagsLicenseEncrypt,2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1268     {&hf_rdp_flagsSecureChecksum,2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1269     {&hf_rdp_flagsFlagsHiValid,  2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1270     FI_TERMINATOR
1271   };
1272 
1273   rdp_field_info_t flags_fields[] = {
1274     FI_SUBTREE(&hf_rdp_flags, 2, ett_rdp_flags, secFlags_fields),
1275     FI_FIXEDLEN(&hf_rdp_flagsHi, 2),
1276     FI_TERMINATOR
1277   };
1278 
1279   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, flags_fields, 0);
1280 
1281   if (flags_ptr)
1282     *flags_ptr = flags;
1283 
1284   return offset;
1285 }
1286 
1287 
1288 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)1289 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) {
1290 
1291   rdp_field_info_t fips_fields[] = {
1292     {&hf_rdp_fipsLength,        2, NULL, 0, 0, NULL },
1293     {&hf_rdp_fipsVersion,       1, NULL, 0, 0, NULL },
1294     {&hf_rdp_padlen,            1, NULL, 0, 0, NULL },
1295     {&hf_rdp_dataSignature,     8, NULL, 0, 0, NULL },
1296     FI_TERMINATOR
1297   };
1298   rdp_field_info_t enc_fields[] = {
1299     {&hf_rdp_dataSignature,     8, NULL, 0, 0, NULL },
1300     FI_TERMINATOR
1301   };
1302   const rdp_field_info_t *fields = NULL;
1303 
1304   if (rdp_info) {
1305 
1306     if (alwaysBasic || (rdp_info->encryptionLevel != ENCRYPTION_LEVEL_NONE))
1307       offset = dissect_rdp_basicSecurityHeader(tvb, offset, pinfo, tree, flags_ptr);
1308 
1309     if (rdp_info->encryptionMethod &
1310        (ENCRYPTION_METHOD_40BIT  |
1311         ENCRYPTION_METHOD_128BIT |
1312         ENCRYPTION_METHOD_56BIT)) {
1313       fields = enc_fields;
1314     } else if (rdp_info->encryptionMethod == ENCRYPTION_METHOD_FIPS) {
1315       fields = fips_fields;
1316     }
1317 
1318     if (fields)
1319       offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
1320   }
1321   return offset;
1322 }
1323 
1324 static rdp_known_channel_t
find_channel_type(packet_info * pinfo,guint16 channelId)1325 find_channel_type(packet_info *pinfo, guint16 channelId) {
1326 	conversation_t *conversation;
1327 	rdp_conv_info_t *rdp_info;
1328 	guint8 i;
1329 
1330 	conversation = find_or_create_conversation(pinfo);
1331 	if (!conversation)
1332 		return RDP_CHANNEL_UNKNOWN;
1333 
1334 	rdp_info = (rdp_conv_info_t *)conversation_get_proto_data(conversation, proto_rdp);
1335 	if (!rdp_info)
1336 		return RDP_CHANNEL_UNKNOWN;
1337 
1338 	for (i = 0; i < rdp_info->maxChannels; i++) {
1339 		if (rdp_info->staticChannels[i].value == channelId)
1340 			return rdp_info->staticChannels[i].channelType;
1341 	}
1342 	return RDP_CHANNEL_UNKNOWN;
1343 }
1344 
1345 
1346 static int
dissect_rdp_channelPDU(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)1347 dissect_rdp_channelPDU(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
1348   rdp_known_channel_t channelType;
1349   guint32 length = 0;
1350   tvbuff_t *subtvb;
1351   guint32 compressed;
1352 
1353   rdp_field_info_t flag_fields[] = {
1354     {&hf_rdp_channelFlagFirst,        4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1355     {&hf_rdp_channelFlagLast,         4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1356     {&hf_rdp_channelFlagShowProtocol, 4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1357     {&hf_rdp_channelFlagSuspend,      4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1358     {&hf_rdp_channelFlagResume,       4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1359     {&hf_rdp_channelPacketCompressed, 4, &compressed, 0, RDP_FI_NOINCOFFSET, NULL },
1360     {&hf_rdp_channelPacketAtFront,    4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1361     {&hf_rdp_channelPacketFlushed,    4, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1362     {&hf_rdp_channelPacketCompressionType,  4, NULL, 0, 0, NULL },
1363     FI_TERMINATOR
1364   };
1365 
1366   rdp_field_info_t channel_fields[] =   {
1367     FI_VALUE(&hf_rdp_length, 4, length),
1368     FI_SUBTREE(&hf_rdp_channelFlags, 4, ett_rdp_channelFlags, flag_fields),
1369     FI_TERMINATOR
1370   };
1371 
1372   rdp_field_info_t channelPDU_fields[] =   {
1373     FI_SUBTREE(&hf_rdp_channelPDUHeader, 8, ett_rdp_channelPDUHeader, channel_fields),
1374     FI_FIXEDLEN(&hf_rdp_virtualChannelData, -1),
1375     FI_TERMINATOR
1376   };
1377 
1378 
1379   channelType = find_channel_type(pinfo, t124_get_last_channelId());
1380   switch (channelType) {
1381   case RDP_CHANNEL_DRDYNVC:
1382 	  channelPDU_fields[1].pfield = NULL;
1383 	  break;
1384   default:
1385 	  break;
1386   }
1387 
1388   /* length is the uncompressed length, and the PDU may be compressed */
1389   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, channelPDU_fields, 0);
1390 
1391   if (compressed & CHANNEL_PACKET_COMPRESSED) {
1392 	  dissect_rdp_nyi(tvb, offset, pinfo, tree, "Compressed channel PDU not implemented");
1393 	  return offset;
1394   }
1395 
1396   switch (channelType) {
1397   case RDP_CHANNEL_DRDYNVC:
1398 	  subtvb = tvb_new_subset_length(tvb, offset, length);
1399 	  offset += call_dissector(drdynvc_handle, subtvb, pinfo, tree);
1400 	  break;
1401   default:
1402 	  break;
1403   }
1404 
1405   return offset;
1406 }
1407 
1408 static int
dissect_rdp_shareDataHeader(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)1409 dissect_rdp_shareDataHeader(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
1410   guint32 pduType2 = 0;
1411   guint32 compressedType;
1412   guint32 action = 0;
1413 
1414   rdp_field_info_t compressed_fields[] =   {
1415     {&hf_rdp_compressedTypeType, 1, &compressedType, 0, RDP_FI_NOINCOFFSET, NULL },
1416     {&hf_rdp_compressedTypeCompressed, 1, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1417     {&hf_rdp_compressedTypeAtFront,    1, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1418     {&hf_rdp_compressedTypeFlushed,    1, NULL, 0, 0, NULL },
1419     FI_TERMINATOR
1420   };
1421   rdp_field_info_t share_fields[] =   {
1422     {&hf_rdp_shareId,            4, NULL, 0, 0, NULL },
1423     {&hf_rdp_pad1,               1, NULL, 0, 0, NULL },
1424     {&hf_rdp_streamId,           1, NULL, 0, 0, NULL },
1425     {&hf_rdp_uncompressedLength, 2, NULL, 0, 0, NULL },
1426     {&hf_rdp_pduType2,           1, &pduType2, 0, 0, NULL },
1427     FI_SUBTREE(&hf_rdp_compressedType, 1, ett_rdp_compressedType, compressed_fields),
1428     {&hf_rdp_compressedLength,   2, NULL, 0, 0, NULL },
1429     FI_TERMINATOR
1430   };
1431   rdp_field_info_t control_fields[] = {
1432     {&hf_rdp_action,             2, &action, 0, 0, NULL },
1433     {&hf_rdp_grantId,            2, NULL, 0, 0, NULL },
1434     {&hf_rdp_controlId,          4, NULL, 0, 0, NULL },
1435     FI_TERMINATOR
1436   };
1437   rdp_field_info_t sync_fields[] = {
1438     {&hf_rdp_messageType,        2, NULL, 0, 0, NULL },
1439     {&hf_rdp_targetUser,         2, NULL, 0, 0, NULL },
1440     FI_TERMINATOR
1441   };
1442   rdp_field_info_t mapflags_fields[] = {
1443     {&hf_rdp_fontMapFirst, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1444     {&hf_rdp_fontMapLast, 2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
1445     FI_TERMINATOR
1446   };
1447   rdp_field_info_t fontmap_fields[] = {
1448     {&hf_rdp_numberEntries,      2, NULL, 0, 0, NULL },
1449     {&hf_rdp_totalNumberEntries, 2, NULL, 0, 0, NULL },
1450     FI_SUBTREE(&hf_rdp_mapFlags, 2, ett_rdp_mapFlags, mapflags_fields),
1451     {&hf_rdp_entrySize,          2, NULL, 0, 0, NULL },
1452     FI_TERMINATOR
1453   };
1454   rdp_field_info_t persistent_fields[] = {
1455     {&hf_rdp_numEntriesCache0,   2, NULL, 0, 0, NULL },
1456     {&hf_rdp_numEntriesCache1,   2, NULL, 0, 0, NULL },
1457     {&hf_rdp_numEntriesCache2,   2, NULL, 0, 0, NULL },
1458     {&hf_rdp_numEntriesCache3,   2, NULL, 0, 0, NULL },
1459     {&hf_rdp_numEntriesCache4,   2, NULL, 0, 0, NULL },
1460     {&hf_rdp_totalEntriesCache0, 2, NULL, 0, 0, NULL },
1461     {&hf_rdp_totalEntriesCache1, 2, NULL, 0, 0, NULL },
1462     {&hf_rdp_totalEntriesCache2, 2, NULL, 0, 0, NULL },
1463     {&hf_rdp_totalEntriesCache3, 2, NULL, 0, 0, NULL },
1464     {&hf_rdp_totalEntriesCache4, 2, NULL, 0, 0, NULL },
1465     {&hf_rdp_bBitMask,           1, NULL, 0, 0, NULL },
1466     {&hf_rdp_Pad2,               1, NULL, 0, 0, NULL },
1467     {&hf_rdp_Pad3,               2, NULL, 0, 0, NULL },
1468     FI_TERMINATOR
1469   };
1470 
1471   const rdp_field_info_t *fields;
1472 
1473   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, share_fields, 0);
1474 
1475   col_append_str(pinfo->cinfo, COL_INFO, "RDP PDU Type: ");
1476   col_append_sep_str(pinfo->cinfo, COL_INFO, "", val_to_str_const(pduType2, rdp_pduType2_vals, "Unknown"));
1477 
1478   fields = NULL;
1479   switch(pduType2) {
1480   case PDUTYPE2_UPDATE:
1481     break;
1482   case PDUTYPE2_CONTROL:
1483     fields = control_fields;
1484     break;
1485   case PDUTYPE2_POINTER:
1486     break;
1487   case PDUTYPE2_INPUT:
1488     break;
1489   case PDUTYPE2_SYNCHRONIZE:
1490     fields = sync_fields;
1491     break;
1492   case PDUTYPE2_REFRESH_RECT:
1493     break;
1494   case PDUTYPE2_PLAY_SOUND:
1495     break;
1496   case PDUTYPE2_SUPPRESS_OUTPUT:
1497     break;
1498   case PDUTYPE2_SHUTDOWN_REQUEST:
1499     break;
1500   case PDUTYPE2_SHUTDOWN_DENIED:
1501     break;
1502   case PDUTYPE2_SAVE_SESSION_INFO:
1503     break;
1504   case PDUTYPE2_FONTLIST:
1505     break;
1506   case PDUTYPE2_FONTMAP:
1507     fields = fontmap_fields;
1508     break;
1509   case PDUTYPE2_SET_KEYBOARD_INDICATORS:
1510     break;
1511   case PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST:
1512     fields = persistent_fields;
1513     break;
1514   case PDUTYPE2_BITMAPCACHE_ERROR_PDU:
1515     break;
1516   case PDUTYPE2_SET_KEYBOARD_IME_STATUS:
1517     break;
1518   case PDUTYPE2_OFFSCRCACHE_ERROR_PDU:
1519     break;
1520   case PDUTYPE2_SET_ERROR_INFO_PDU:
1521     break;
1522   case PDUTYPE2_DRAWNINEGRID_ERROR_PDU:
1523     break;
1524   case PDUTYPE2_DRAWGDIPLUS_ERROR_PDU:
1525     break;
1526   case PDUTYPE2_ARC_STATUS_PDU:
1527     break;
1528   case PDUTYPE2_STATUS_INFO_PDU:
1529     break;
1530   case PDUTYPE2_MONITOR_LAYOUT_PDU:
1531     break;
1532   default:
1533     break;
1534   }
1535 
1536   if (fields) {
1537     offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
1538   }
1539 
1540   if (pduType2 == PDUTYPE2_CONTROL) {
1541     col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Action: ");
1542     col_append_sep_str(pinfo->cinfo, COL_INFO, "", val_to_str_const(action, rdp_action_vals, "Unknown"));
1543   }
1544 
1545   return offset;
1546 }
1547 
1548 static int
dissect_rdp_capabilitySets(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint32 numberCapabilities)1549 dissect_rdp_capabilitySets(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 numberCapabilities) {
1550   guint   i;
1551   guint32 lengthCapability;
1552 
1553   rdp_field_info_t cs_fields[] = {
1554     {&hf_rdp_capabilitySetType, 2, NULL, 0, 0, NULL },
1555     {&hf_rdp_lengthCapability, 2, &lengthCapability, -4, 0, NULL },
1556     {&hf_rdp_capabilityData, 0, &lengthCapability, 0, 0, NULL },
1557     FI_TERMINATOR
1558   };
1559 
1560   rdp_field_info_t set_fields[] = {
1561     FI_SUBTREE(&hf_rdp_capabilitySet, 0, ett_rdp_capabilitySet, cs_fields),
1562     FI_TERMINATOR
1563   };
1564 
1565   for (i = 0; i < numberCapabilities; i++) {
1566     offset = dissect_rdp_fields(tvb, offset, pinfo, tree, set_fields, 0);
1567   }
1568 
1569   return offset;
1570 }
1571 
1572 static int
dissect_rdp_demandActivePDU(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)1573 dissect_rdp_demandActivePDU(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
1574 
1575   guint32 lengthSourceDescriptor;
1576   guint32 numberCapabilities = 0;
1577 
1578   rdp_field_info_t fields[] = {
1579     {&hf_rdp_shareId,                    4, NULL, 0, 0, NULL },
1580     {&hf_rdp_lengthSourceDescriptor,     2, &lengthSourceDescriptor, 0, 0, NULL },
1581     {&hf_rdp_lengthCombinedCapabilities, 2, NULL, 0, 0, NULL },
1582     {&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 */
1583     {&hf_rdp_numberCapabilities,         2, &numberCapabilities, 0, 0, NULL },
1584     {&hf_rdp_pad2Octets,                 2, NULL, 0, 0, NULL },
1585     FI_TERMINATOR
1586   };
1587   rdp_field_info_t final_fields[] = {
1588     {&hf_rdp_sessionId,                    4, NULL, 0, 0, NULL },
1589     FI_TERMINATOR
1590   };
1591 
1592   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
1593 
1594   offset = dissect_rdp_capabilitySets(tvb, offset, pinfo, tree, numberCapabilities);
1595 
1596   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, final_fields, 0);
1597 
1598   return offset;
1599 }
1600 
1601 static int
dissect_rdp_confirmActivePDU(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)1602 dissect_rdp_confirmActivePDU(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
1603 
1604   guint32 lengthSourceDescriptor;
1605   guint32 numberCapabilities = 0;
1606 
1607   rdp_field_info_t fields[] = {
1608     {&hf_rdp_shareId,                    4, NULL, 0, 0, NULL },
1609     {&hf_rdp_originatorId,               2, NULL, 0, 0, NULL },
1610     {&hf_rdp_lengthSourceDescriptor,     2, &lengthSourceDescriptor, 0, 0, NULL },
1611     {&hf_rdp_lengthCombinedCapabilities, 2, NULL, 0, 0, NULL },
1612     {&hf_rdp_sourceDescriptor,           0, &lengthSourceDescriptor, 0, 0, NULL },
1613     {&hf_rdp_numberCapabilities,         2, &numberCapabilities, 0, 0, NULL },
1614     {&hf_rdp_pad2Octets,                 2, NULL, 0, 0, NULL },
1615     FI_TERMINATOR
1616   };
1617 
1618   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, fields, 0);
1619 
1620   offset = dissect_rdp_capabilitySets(tvb, offset, pinfo, tree, numberCapabilities);
1621 
1622   return offset;
1623 }
1624 
1625 
1626 static proto_tree *
dissect_rdp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree)1627 dissect_rdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
1628 {
1629   proto_item *item;
1630   proto_tree *tree;
1631 
1632   col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDP");
1633   col_clear(pinfo->cinfo, COL_INFO);
1634 
1635   item = proto_tree_add_item(parent_tree, proto_rdp, tvb, 0, -1, ENC_NA);
1636   tree = proto_item_add_subtree(item, ett_rdp);
1637 
1638   return tree;
1639 }
1640 
1641 
1642 gint
dissect_rdp_bandwidth_req(tvbuff_t * tvb,gint offset,packet_info * pinfo,proto_tree * tree,gboolean from_server)1643 dissect_rdp_bandwidth_req(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree,	gboolean from_server)
1644 {
1645 	guint16 payloadLength;
1646 	rdp_field_info_t bandwidth_fields[] = {
1647 		{&hf_rdp_bandwidth_header_len,   1, NULL  , 0, 0, NULL },
1648 		{&hf_rdp_bandwidth_header_type,  1, NULL  , 0, 0, NULL },
1649 		{&hf_rdp_bandwidth_seqnumber,  	 2, NULL  , 0, 0, NULL },
1650 		{&hf_rdp_bandwidth_reqtype,  	 2, NULL  , 0, 0, NULL },
1651 		FI_TERMINATOR
1652 	};
1653 	guint8 typeId = tvb_get_guint8(tvb, offset + 1);
1654 	guint16 reqRespType = tvb_get_guint8(tvb, offset + 4);
1655 
1656 	if (typeId == TYPE_ID_AUTODETECT_RESPONSE)
1657 		bandwidth_fields[3].pfield = &hf_rdp_bandwidth_resptype;
1658 
1659 	offset = dissect_rdp_fields(tvb, offset, pinfo, tree, bandwidth_fields, 0);
1660 
1661 	if (from_server) {
1662 		switch (reqRespType) {
1663 		case 0x0001:
1664 		case 0x1001:
1665 			/* RTT Measure Request*/
1666 			break;
1667 
1668 		case 0x0014:
1669 		case 0x0114:
1670 		case 0x1014:
1671 			/* Bandwidth Measure Start message */
1672 			break;
1673 
1674 		case 0x0002:
1675 			/* Bandwidth Measure Payload */
1676 			payloadLength = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN);
1677 			proto_tree_add_item(tree, hf_rdp_bandwidth_measure_payload_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1678 			offset += 2;
1679 
1680 			proto_tree_add_item(tree, hf_rdp_bandwidth_measure_payload_data, tvb, offset, payloadLength, ENC_NA);
1681 			offset += payloadLength;
1682 			break;
1683 
1684 		case 0x002B:
1685 		case 0x0429:
1686 		case 0x0629:
1687 			/* Bandwidth Measure Stop */
1688 			if (reqRespType == 0x002B) {
1689 				payloadLength = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN);
1690 				proto_tree_add_item(tree, hf_rdp_bandwidth_measure_payload_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1691 				offset += 2;
1692 
1693 				proto_tree_add_item(tree, hf_rdp_bandwidth_measure_payload_data, tvb, offset, payloadLength, ENC_NA);
1694 				offset += payloadLength;
1695 			}
1696 			break;
1697 
1698 		case 0x0840:
1699 		case 0x0880:
1700 		case 0x08C0:
1701 			/* Network Characteristics Result*/
1702 			if (reqRespType == 0x840 || reqRespType == 0x8C0) {
1703 				proto_tree_add_item(tree, hf_rdp_network_characteristics_basertt, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1704 				offset += 4;
1705 			}
1706 			if (reqRespType == 0x880 || reqRespType == 0x8C0) {
1707 				proto_tree_add_item(tree, hf_rdp_network_characteristics_bandwidth, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1708 				offset += 4;
1709 			}
1710 			if (reqRespType == 0x840 || reqRespType == 0x8C0) {
1711 				proto_tree_add_item(tree, hf_rdp_network_characteristics_averagertt, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1712 				offset += 4;
1713 			}
1714 			break;
1715 		}
1716 	} else {
1717 		switch (reqRespType) {
1718 		case 0x0000:
1719 			/* RTT Measure Response */
1720 			break;
1721 		case 0x0003:
1722 		case 0x000B:
1723 			/* Bandwidth Measure Results */
1724 			proto_tree_add_item(tree, hf_rdp_rtt_measure_time_delta, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1725 			offset += 4;
1726 
1727 			proto_tree_add_item(tree, hf_rdp_rtt_measure_time_bytecount, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1728 			offset += 4;
1729 			break;
1730 		}
1731 	}
1732 
1733 	return offset;
1734 }
1735 
1736 static gboolean
rdp_isServerAddressTarget(packet_info * pinfo)1737 rdp_isServerAddressTarget(packet_info *pinfo)
1738 {
1739 	conversation_t *conv;
1740 	rdp_conv_info_t *rdp_info;
1741 
1742 	conv = find_conversation_pinfo(pinfo, 0);
1743 	if (!conv)
1744 		return FALSE;
1745 
1746 	rdp_info = (rdp_conv_info_t *)conversation_get_proto_data(conv, proto_rdp);
1747 	if (rdp_info) {
1748 		rdp_server_address_t *server = &rdp_info->serverAddr;
1749 		return addresses_equal(&server->addr, &pinfo->dst) && (pinfo->destport == server->port);
1750 	}
1751 
1752 	return FALSE;
1753 }
1754 
1755 void
rdp_transport_set_udp_conversation(const address * serverAddr,guint16 serverPort,gboolean reliable,guint32 reqId,guint8 * cookie,conversation_t * conv)1756 rdp_transport_set_udp_conversation(const address *serverAddr, guint16 serverPort, gboolean reliable, guint32 reqId, guint8 *cookie, conversation_t *conv)
1757 {
1758 	rdp_transports_key_t key;
1759 	rdp_transports_link_t *transport_link;
1760 
1761 	key.reliable = reliable;
1762 	key.requestId = reqId;
1763 	memcpy(key.securityCookie, cookie, 16);
1764 	copy_address(&key.serverAddr, serverAddr);
1765 	key.serverPort = serverPort;
1766 
1767 	transport_link = (rdp_transports_link_t *)wmem_map_lookup(rdp_transport_links, &key);
1768 	if (!transport_link) {
1769 		transport_link = wmem_new(wmem_file_scope(), rdp_transports_link_t);
1770 
1771 		memcpy(&transport_link->key, &key, sizeof(key));
1772 		copy_address_wmem(wmem_file_scope(), &key.serverAddr, serverAddr);
1773 	}
1774 
1775 	transport_link->udp_conversation = conv;
1776 }
1777 
1778 typedef struct {
1779 	conversation_t *udp;
1780 	conversation_t *result;
1781 } find_tcp_conversation_t;
1782 
1783 static void
map_find_tcp_conversation_fn(rdp_transports_key_t * key _U_,rdp_transports_link_t * transport,find_tcp_conversation_t * criteria)1784 map_find_tcp_conversation_fn(rdp_transports_key_t *key _U_, rdp_transports_link_t *transport, find_tcp_conversation_t *criteria)
1785 {
1786 	if (criteria->udp == transport->udp_conversation)
1787 		criteria->result = transport->tcp_conversation;
1788 }
1789 
1790 conversation_t *
rdp_find_tcp_conversation_from_udp(conversation_t * udp)1791 rdp_find_tcp_conversation_from_udp(conversation_t *udp)
1792 {
1793 	find_tcp_conversation_t criteria = { udp, NULL };
1794 
1795 	wmem_map_foreach(rdp_transport_links, (GHFunc)map_find_tcp_conversation_fn, &criteria);
1796 	return criteria.result;
1797 }
1798 
1799 static int
dissect_rdp_MessageChannelData(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1800 dissect_rdp_MessageChannelData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
1801 	proto_item *pi;
1802 	proto_tree *next_tree;
1803 	int offset = 0;
1804 	guint32 flags = 0;
1805 
1806 	rdp_field_info_t secFlags_fields[] = {
1807 		{&hf_rdp_flagsTransportReq,  2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1808 		{&hf_rdp_flagsTransportResp, 2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1809 		{&hf_rdp_flagsAutodetectReq, 2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1810 		{&hf_rdp_flagsAutodetectResp,2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1811 		{&hf_rdp_flagsHeartbeat,	 2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1812 		FI_TERMINATOR
1813 	};
1814 
1815 	rdp_field_info_t se_fields[] = {
1816 		FI_SUBTREE(&hf_rdp_flags, 2, ett_rdp_flags, secFlags_fields),
1817 		FI_FIXEDLEN(&hf_rdp_flagsHi, 2),
1818 		FI_TERMINATOR
1819 	};
1820 
1821 	tree = dissect_rdp(tvb, pinfo, tree);
1822 	pi   = proto_tree_add_item(tree, hf_rdp_MessageData, tvb, offset, -1, ENC_NA);
1823 	tree = proto_item_add_subtree(pi, ett_rdp_MessageData);
1824 
1825 	flags = tvb_get_letohs(tvb, offset);
1826 	offset = dissect_rdp_fields(tvb, offset, pinfo, tree, se_fields, 0);
1827 
1828 	if (flags & SEC_TRANSPORT_REQ) {
1829 		guint16 reqProto;
1830 		rdp_transports_key_t transport_key;
1831 		rdp_transports_link_t *transport_link;
1832 
1833 		rdp_field_info_t mt_req_fields[] = {
1834 			{ &hf_rdp_mt_req_requestId, 4, NULL, 0, 0, NULL },
1835 			{ &hf_rdp_mt_req_protocol, 2, NULL, 0, 0, NULL },
1836 			{ &hf_rdp_mt_req_reserved, 2, NULL, 0, 0, NULL },
1837 			{ &hf_rdp_mt_req_securityCookie, 16, NULL, 0, 0, NULL },
1838 			FI_TERMINATOR
1839 		};
1840 		col_append_sep_str(pinfo->cinfo, COL_INFO, " ",	"MultiTransportRequest");
1841 
1842 		reqProto = tvb_get_guint16(tvb, offset + 4, ENC_LITTLE_ENDIAN);
1843 
1844 		transport_key.reliable = !!(reqProto & INITITATE_REQUEST_PROTOCOL_UDPFECR);
1845 		transport_key.requestId = tvb_get_guint32(tvb, offset, ENC_LITTLE_ENDIAN);
1846 		copy_address(&transport_key.serverAddr, &pinfo->src);
1847 		transport_key.serverPort = pinfo->srcport;
1848 		tvb_memcpy(tvb, transport_key.securityCookie, offset + 8, 16);
1849 
1850 		transport_link = (rdp_transports_link_t *)wmem_map_lookup(rdp_transport_links, &transport_key);
1851 		if (!transport_link) {
1852 			transport_link = wmem_new(wmem_file_scope(), rdp_transports_link_t);
1853 
1854 			memcpy(&transport_link->key, &transport_key, sizeof(transport_key));
1855 			copy_address_wmem(wmem_file_scope(), &transport_key.serverAddr, &pinfo->src);
1856 			transport_link->tcp_conversation = find_or_create_conversation(pinfo);
1857 
1858 			wmem_map_insert(rdp_transport_links, &transport_link->key , transport_link);
1859 		}
1860 
1861 		next_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
1862 				ett_rdp_mt_req, NULL, "MultiTransport request");
1863 		offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, mt_req_fields, 0);
1864 
1865 	} else if (flags & SEC_TRANSPORT_RSP) {
1866 		rdp_field_info_t mt_resp_fields[] = {
1867 			{ &hf_rdp_mt_rsp_requestId, 4, NULL, 0, 0, NULL },
1868 			{ &hf_rdp_mt_rsp_hrResponse, 4, NULL, 0, 0, NULL },
1869 			FI_TERMINATOR
1870 		};
1871 
1872 		col_append_sep_str(pinfo->cinfo, COL_INFO, " ",	"MultiTransport response");
1873 
1874 		next_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
1875 				ett_rdp_mt_rsp, NULL, "MultiTransport response");
1876 		dissect_rdp_fields(tvb, offset, pinfo, next_tree, mt_resp_fields, 0);
1877 
1878 	} else if (flags & SEC_AUTODETECT_REQ) {
1879 		col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Autodetect Req");
1880 
1881 		next_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
1882 				ett_rdp_mt_req, NULL, "Autodetect request");
1883 		offset = dissect_rdp_bandwidth_req(tvb, offset, pinfo, next_tree, rdp_isServerAddressTarget(pinfo));
1884 	} else if (flags & SEC_AUTODETECT_RSP) {
1885 		col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Autodetect Resp");
1886 
1887 		next_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
1888 				ett_rdp_mt_req, NULL, "Autodetect response");
1889 		offset = dissect_rdp_bandwidth_req(tvb, offset, pinfo, next_tree, rdp_isServerAddressTarget(pinfo));
1890 	} else if (flags & SEC_HEARTBEAT) {
1891 		rdp_field_info_t heartbeat_fields[] = {
1892 			{ &hf_rdp_heartbeat_reserved, 1, NULL, 0, 0, NULL },
1893 			{ &hf_rdp_heartbeat_period, 1, NULL, 0, 0, NULL },
1894 			{ &hf_rdp_heartbeat_count1, 1, NULL, 0, 0, NULL },
1895 			{ &hf_rdp_heartbeat_count2, 1, NULL, 0, 0, NULL },
1896 			FI_TERMINATOR
1897 		};
1898 
1899 		col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Heartbeat");
1900 
1901 		next_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
1902 				ett_rdp_heartbeat, NULL, "Heartbeat");
1903 
1904 		offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree,
1905 				heartbeat_fields, 0);
1906 	}
1907 
1908 	return offset;
1909 }
1910 
1911 static int
dissect_rdp_SendData(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1912 dissect_rdp_SendData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
1913   proto_item      *pi;
1914   int              offset       = 0;
1915   guint32          flags        = 0;
1916   guint32          cbDomain, cbUserName, cbPassword, cbAlternateShell, cbWorkingDir,
1917                    cbClientAddress, cbClientDir, cbAutoReconnectLen, wBlobLen, pduType = 0;
1918   guint32          bMsgType = 0xffffffff;
1919   guint32          encryptedLen = 0;
1920   conversation_t  *conversation;
1921   rdp_conv_info_t *rdp_info;
1922 
1923   rdp_field_info_t secFlags_fields[] = {
1924     {&hf_rdp_flagsPkt,           2, &flags, 0, RDP_FI_NOINCOFFSET, NULL },
1925     {&hf_rdp_flagsEncrypt,       2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1926     {&hf_rdp_flagsResetSeqno,    2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1927     {&hf_rdp_flagsIgnoreSeqno,   2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1928     {&hf_rdp_flagsLicenseEncrypt,2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1929     {&hf_rdp_flagsSecureChecksum,2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1930     {&hf_rdp_flagsFlagsHiValid,  2, NULL  , 0, RDP_FI_NOINCOFFSET, NULL },
1931     FI_TERMINATOR
1932   };
1933 
1934   rdp_field_info_t se_fields[] = {
1935     FI_SUBTREE(&hf_rdp_flags, 2, ett_rdp_flags, secFlags_fields),
1936     FI_FIXEDLEN(&hf_rdp_flagsHi, 2),
1937     {&hf_rdp_length,                4, &encryptedLen, 0, 0, NULL },
1938     {&hf_rdp_encryptedClientRandom, 0, &encryptedLen, 0, 0, NULL },
1939     FI_TERMINATOR
1940   };
1941   rdp_field_info_t systime_fields [] = {
1942     FI_FIXEDLEN(&hf_rdp_wYear        , 2),
1943     FI_FIXEDLEN(&hf_rdp_wMonth       , 2),
1944     FI_FIXEDLEN(&hf_rdp_wDayOfWeek   , 2),
1945     FI_FIXEDLEN(&hf_rdp_wDay         , 2),
1946     FI_FIXEDLEN(&hf_rdp_wHour        , 2),
1947     FI_FIXEDLEN(&hf_rdp_wMinute      , 2),
1948     FI_FIXEDLEN(&hf_rdp_wSecond      , 2),
1949     FI_FIXEDLEN(&hf_rdp_wMilliseconds, 2),
1950     FI_TERMINATOR,
1951   };
1952   rdp_field_info_t tz_info_fields [] = {
1953     FI_FIXEDLEN(&hf_rdp_Bias, 4),
1954     {&hf_rdp_StandardName,           64, NULL, 0, RDP_FI_STRING|RDP_FI_UNICODE, NULL },
1955     FI_SUBTREE(&hf_rdp_StandardDate, 16, ett_rdp_StandardDate, systime_fields),
1956     FI_FIXEDLEN(&hf_rdp_StandardBias, 4),
1957     {&hf_rdp_DaylightName,           64, NULL, 0, RDP_FI_STRING|RDP_FI_UNICODE, NULL },
1958     FI_SUBTREE(&hf_rdp_DaylightDate, 16, ett_rdp_DaylightDate, systime_fields),
1959     FI_FIXEDLEN(&hf_rdp_DaylightBias, 4),
1960     FI_TERMINATOR,
1961   };
1962 
1963   rdp_field_info_t ue_fields[] = {
1964     {&hf_rdp_codePage,           4, NULL, 0, 0, NULL },
1965     {&hf_rdp_optionFlags,        4, NULL, 0, RDP_FI_INFO_FLAGS, NULL },
1966     {&hf_rdp_cbDomain,           2, &cbDomain, 2, 0, NULL },
1967     {&hf_rdp_cbUserName,         2, &cbUserName, 2, 0, NULL },
1968     {&hf_rdp_cbPassword,         2, &cbPassword, 2, 0, NULL },
1969     {&hf_rdp_cbAlternateShell,   2, &cbAlternateShell, 2, 0, NULL },
1970     {&hf_rdp_cbWorkingDir,       2, &cbWorkingDir, 2, 0, NULL },
1971     {&hf_rdp_domain,             0, &cbDomain, 0, RDP_FI_STRING, NULL },
1972     {&hf_rdp_userName,           0, &cbUserName, 0, RDP_FI_STRING, NULL },
1973     {&hf_rdp_password,           0, &cbPassword, 0, RDP_FI_STRING, NULL },
1974     {&hf_rdp_alternateShell,     0, &cbAlternateShell, 0, RDP_FI_STRING, NULL },
1975     {&hf_rdp_workingDir,         0, &cbWorkingDir, 0, RDP_FI_STRING, NULL },
1976     {&hf_rdp_clientAddressFamily,2, NULL, 0, 0, NULL },
1977     {&hf_rdp_cbClientAddress,    2, &cbClientAddress, 0, 0, NULL },
1978     {&hf_rdp_clientAddress,      0, &cbClientAddress, 0, RDP_FI_STRING, NULL },
1979     {&hf_rdp_cbClientDir,        2, &cbClientDir, 0, 0, NULL },
1980     {&hf_rdp_clientDir,          0, &cbClientDir, 0, RDP_FI_STRING, NULL },
1981     FI_SUBTREE(&hf_rdp_clientTimeZone, 172, ett_rdp_clientTimeZone, tz_info_fields),
1982     {&hf_rdp_clientSessionId,    4, NULL, 0, 0, NULL },
1983     {&hf_rdp_performanceFlags,   4, NULL, 0, 0, NULL },
1984     {&hf_rdp_cbAutoReconnectLen, 2, &cbAutoReconnectLen, 0, 0, NULL },
1985     {&hf_rdp_autoReconnectCookie,0, &cbAutoReconnectLen, 0, 0, NULL },
1986     {&hf_rdp_reserved1,          2, NULL, 0, 0, NULL },
1987     {&hf_rdp_reserved2,          2, NULL, 0, 0, NULL },
1988     FI_TERMINATOR
1989   };
1990   rdp_field_info_t msg_fields[] = {
1991     {&hf_rdp_bMsgType,           1, &bMsgType, 0, 0, NULL },
1992     {&hf_rdp_bVersion,           1, NULL, 0, 0, NULL },
1993     {&hf_rdp_wMsgSize,           2, NULL, 0, 0, NULL },
1994     FI_TERMINATOR
1995   };
1996   rdp_field_info_t error_fields[] = {
1997     {&hf_rdp_wErrorCode,         4, NULL, 0, 0, NULL },
1998     {&hf_rdp_wStateTransition,   4, NULL, 0, 0, NULL },
1999     {&hf_rdp_wBlobType,          2, NULL, 0, 0, NULL },
2000     {&hf_rdp_wBlobLen,           2, &wBlobLen, 0, 0, NULL },
2001     {&hf_rdp_blobData,           0, &wBlobLen, 0, 0, NULL },
2002     FI_TERMINATOR
2003   };
2004 
2005   rdp_field_info_t pdu_fields[] = {
2006     {&hf_rdp_pduTypeType,        2, &pduType, 0, RDP_FI_NOINCOFFSET, NULL },
2007     {&hf_rdp_pduTypeVersionLow,  2, NULL, 0, RDP_FI_NOINCOFFSET, NULL },
2008     {&hf_rdp_pduTypeVersionHigh, 2, NULL, 0, 0, NULL },
2009     FI_TERMINATOR
2010   };
2011   rdp_field_info_t ctrl_fields[] = {
2012     {&hf_rdp_totalLength,        2, NULL, 0, 0, NULL },
2013     {&hf_rdp_pduType,            2, NULL, ett_rdp_pduType, RDP_FI_SUBTREE,
2014      pdu_fields },
2015     {&hf_rdp_pduSource,          2, NULL, 0, 0, NULL },
2016     FI_TERMINATOR
2017   };
2018 
2019   tree = dissect_rdp(tvb, pinfo, tree);
2020 
2021   pi   = proto_tree_add_item(tree, hf_rdp_SendData, tvb, offset, -1, ENC_NA);
2022   tree = proto_item_add_subtree(pi, ett_rdp_SendData);
2023 
2024   conversation = find_or_create_conversation(pinfo);
2025   rdp_info = (rdp_conv_info_t *)conversation_get_proto_data(conversation, proto_rdp);
2026 
2027   if (rdp_info &&
2028       ((rdp_info->licenseAgreed == 0) ||
2029        (pinfo->num <= rdp_info->licenseAgreed))) {
2030     /* licensing stage hasn't been completed */
2031     proto_tree *next_tree;
2032 
2033     flags = tvb_get_letohs(tvb, offset);
2034 
2035     switch(flags & SEC_PKT_MASK) {
2036     case SEC_EXCHANGE_PKT:
2037       pi        = proto_tree_add_item(tree, hf_rdp_securityExchangePDU, tvb, offset, -1, ENC_NA);
2038       next_tree = proto_item_add_subtree(pi, ett_rdp_securityExchangePDU);
2039 
2040       col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "SecurityExchange");
2041 
2042       /*offset=*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, se_fields, 0);
2043 
2044       break;
2045 
2046     case SEC_INFO_PKT:
2047       pi        = proto_tree_add_item(tree, hf_rdp_clientInfoPDU, tvb, offset, -1, ENC_NA);
2048       next_tree = proto_item_add_subtree(pi, ett_rdp_clientInfoPDU);
2049 
2050       col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ClientInfo");
2051 
2052       offset = dissect_rdp_securityHeader(tvb, offset, pinfo, next_tree, rdp_info, TRUE, NULL);
2053 
2054       if (!(flags & SEC_ENCRYPT)) {
2055 
2056         /*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, ue_fields, 0);
2057       } else {
2058 
2059         /*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, next_tree, NULL);
2060       }
2061       break;
2062 
2063     case SEC_LICENSE_PKT:
2064       pi        = proto_tree_add_item(tree, hf_rdp_validClientLicenseData, tvb, offset, -1, ENC_NA);
2065       next_tree = proto_item_add_subtree(pi, ett_rdp_validClientLicenseData);
2066 
2067       offset = dissect_rdp_securityHeader(tvb, offset, pinfo, next_tree, rdp_info, TRUE, NULL);
2068       if (!(flags & SEC_ENCRYPT)) {
2069 
2070         offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, msg_fields, 0);
2071 
2072         col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str_const(bMsgType, rdp_bMsgType_vals, "Unknown"));
2073 
2074         switch(bMsgType) {
2075         case LICENSE_REQUEST:
2076         case PLATFORM_CHALLENGE:
2077         case NEW_LICENSE:
2078         case UPGRADE_LICENSE:
2079         case LICENSE_INFO:
2080         case NEW_LICENSE_REQUEST:
2081         case PLATFORM_CHALLENGE_RESPONSE:
2082           /* RDPELE Not supported */
2083           /*offset =*/ dissect_rdp_nyi(tvb, offset, pinfo, next_tree, "RDPELE not implemented");
2084           break;
2085         case ERROR_ALERT:
2086           /*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, error_fields, 0);
2087           rdp_info->licenseAgreed = pinfo->num;
2088           break;
2089         default:
2090           /* Unknown msgType */
2091           break;
2092         }
2093       } else {
2094         /*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, next_tree, NULL);
2095 
2096         /* XXX: we assume the license is agreed in this exchange */
2097         rdp_info->licenseAgreed = pinfo->num;
2098       }
2099       break;
2100 
2101     case SEC_REDIRECTION_PKT:
2102       /* NotYetImplemented */
2103       break;
2104 
2105     default:
2106       break;
2107     }
2108 
2109     return tvb_captured_length(tvb);
2110   } /* licensing stage */
2111 
2112   if (rdp_info && (t124_get_last_channelId() == rdp_info->staticChannelId)) {
2113 
2114     offset = dissect_rdp_securityHeader(tvb, offset, pinfo, tree, rdp_info, FALSE, &flags);
2115 
2116     if (!(flags & SEC_ENCRYPT)) {
2117       proto_tree *next_tree;
2118       pi        = proto_tree_add_item(tree, hf_rdp_shareControlHeader, tvb, offset, -1, ENC_NA);
2119       next_tree = proto_item_add_subtree(pi, ett_rdp_shareControlHeader);
2120 
2121       offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, ctrl_fields, 0);
2122 
2123       pduType &= PDUTYPE_TYPE_MASK; /* mask out just the type */
2124 
2125       if (pduType != PDUTYPE_DATAPDU)
2126         col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str_const(pduType, rdp_pduTypeType_vals, "Unknown"));
2127 
2128       switch(pduType) {
2129       case PDUTYPE_DEMANDACTIVEPDU:
2130         /*offset =*/ dissect_rdp_demandActivePDU(tvb, offset, pinfo, next_tree);
2131         break;
2132       case PDUTYPE_CONFIRMACTIVEPDU:
2133         /*offset =*/ dissect_rdp_confirmActivePDU(tvb, offset, pinfo, next_tree);
2134         break;
2135       case PDUTYPE_DEACTIVATEALLPDU:
2136         break;
2137       case PDUTYPE_DATAPDU:
2138         /*offset =*/ dissect_rdp_shareDataHeader(tvb, offset, pinfo, next_tree);
2139         break;
2140       case PDUTYPE_SERVER_REDIR_PKT:
2141         break;
2142       default:
2143         break;
2144       }
2145     } else {
2146 
2147       /*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, tree, NULL);
2148     }
2149 
2150     /* we may get multiple control headers in a single frame */
2151     col_set_fence(pinfo->cinfo, COL_INFO);
2152 
2153     return tvb_captured_length(tvb);
2154   } /* (rdp_info && (t124_get_last_channelId() == rdp_info->staticChannelId)) */
2155 
2156   /* Virtual Channel */
2157   col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Virtual Channel PDU");
2158 
2159   offset = dissect_rdp_securityHeader(tvb, offset, pinfo, tree, rdp_info, FALSE, &flags);
2160 
2161   if (!(flags & SEC_ENCRYPT))
2162     /*offset =*/ dissect_rdp_channelPDU(tvb, offset, pinfo, tree);
2163   else
2164     /*offset =*/ dissect_rdp_encrypted(tvb, offset, pinfo, tree, "Channel PDU");
2165 
2166   return tvb_captured_length(tvb);
2167 }
2168 
2169 static int
dissect_rdp_monitor(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)2170 dissect_rdp_monitor(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
2171 
2172   guint32 monitorCount, i;
2173   proto_item *monitorDef_item;
2174   proto_tree *monitorDef_tree;
2175 
2176   rdp_field_info_t monitor_fields[] = {
2177     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2178     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2179     {&hf_rdp_monitorFlags,           4, NULL, 0, 0, NULL },
2180     {&hf_rdp_monitorCount,           4, &monitorCount, 0, 0, NULL },
2181     FI_TERMINATOR
2182   };
2183 
2184   rdp_field_info_t monitorDef_fields[] = {
2185     {&hf_rdp_monitorDefLeft,         4, NULL, 0, 0, NULL },
2186     {&hf_rdp_monitorDefTop,          4, NULL, 0, 0, NULL },
2187     {&hf_rdp_monitorDefRight,        4, NULL, 0, 0, NULL },
2188     {&hf_rdp_monitorDefBottom,       4, NULL, 0, 0, NULL },
2189     {&hf_rdp_monitorDefFlags,        4, NULL, 0, 0, NULL },
2190     FI_TERMINATOR
2191   };
2192 
2193   offset = dissect_rdp_fields(tvb, offset, pinfo, tree, monitor_fields, 0);
2194   for (i = 0; i < monitorCount; i++) {
2195     monitorDef_item = proto_tree_add_item(tree, hf_rdp_clientMonitorDefData, tvb, offset, 20, ENC_NA);
2196     monitorDef_tree = proto_item_add_subtree(monitorDef_item, ett_rdp_clientMonitorDefData);
2197 
2198     offset = dissect_rdp_fields(tvb, offset, pinfo, monitorDef_tree, monitorDef_fields, 0);
2199   }
2200 
2201   return offset;
2202 }
2203 
2204 static int
dissect_rdp_ClientData(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2205 dissect_rdp_ClientData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
2206   int              offset    = 0;
2207   proto_item      *pi;
2208   proto_tree      *next_tree;
2209   guint16          type;
2210   guint            length;
2211   rdp_conv_info_t *rdp_info;
2212 
2213   rdp_field_info_t header_fields[] = {
2214     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2215     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2216     FI_TERMINATOR
2217   };
2218   rdp_field_info_t core_fields[] = {
2219     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2220     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2221     {&hf_rdp_versionMajor,           2, NULL, 0, 0, NULL },
2222     {&hf_rdp_versionMinor,           2, NULL, 0, 0, NULL },
2223     {&hf_rdp_desktopWidth,           2, NULL, 0, 0, NULL },
2224     {&hf_rdp_desktopHeight,          2, NULL, 0, 0, NULL },
2225     {&hf_rdp_colorDepth,             2, NULL, 0, 0, NULL },
2226     {&hf_rdp_SASSequence,            2, NULL, 0, 0, NULL },
2227     {&hf_rdp_keyboardLayout,         4, NULL, 0, 0, NULL },
2228     {&hf_rdp_clientBuild,            4, NULL, 0, 0, NULL },
2229     {&hf_rdp_clientName,            32, NULL, 0, RDP_FI_STRING|RDP_FI_UNICODE, NULL },
2230     {&hf_rdp_keyboardType,           4, NULL, 0, 0, NULL },
2231     {&hf_rdp_keyboardSubType,        4, NULL, 0, 0, NULL },
2232     {&hf_rdp_keyboardFunctionKey,    4, NULL, 0, 0, NULL },
2233     {&hf_rdp_imeFileName,           64, NULL, 0, 0, NULL },
2234     /* The following fields are *optional*.                   */
2235     /*  I.E., a sequence of one or more of the trailing       */
2236     /*  fields at the end of the Data Block need not be       */
2237     /*  present. The length from the header field determines  */
2238     /*  the actual number of fields which are present.        */
2239     {&hf_rdp_postBeta2ColorDepth,    2, NULL, 0, 0, NULL },
2240     {&hf_rdp_clientProductId,        2, NULL, 0, 0, NULL },
2241     {&hf_rdp_serialNumber,           4, NULL, 0, 0, NULL },
2242     {&hf_rdp_highColorDepth,         2, NULL, 0, 0, NULL },
2243     {&hf_rdp_supportedColorDepths,   2, NULL, 0, 0, NULL },
2244     {&hf_rdp_earlyCapabilityFlags,   2, NULL, 0, 0, NULL },
2245     {&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 */
2246     {&hf_rdp_connectionType,         1, NULL, 0, 0, NULL },
2247     {&hf_rdp_pad1octet,              1, NULL, 0, 0, NULL },
2248     {&hf_rdp_serverSelectedProtocol, 4, NULL, 0, 0, NULL },
2249     FI_TERMINATOR
2250   };
2251   rdp_field_info_t security_fields[] = {
2252     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2253     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2254     {&hf_rdp_encryptionMethods,      4, NULL, 0, 0, NULL },
2255     {&hf_rdp_extEncryptionMethods,   4, NULL, 0, 0, NULL },
2256     FI_TERMINATOR
2257   };
2258   rdp_field_info_t cluster_fields[] = {
2259     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2260     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2261     {&hf_rdp_cluster_flags,          4, NULL, 0, 0, NULL },
2262     {&hf_rdp_redirectedSessionId,    4, NULL, 0, 0, NULL },
2263     FI_TERMINATOR
2264   };
2265   rdp_field_info_t msgchannel_fields[] = {
2266     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2267     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2268     {&hf_rdp_msgChannelFlags,        4, NULL, 0, 0, NULL },
2269     FI_TERMINATOR
2270   };
2271   rdp_field_info_t monitorex_fields[] = {
2272     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2273     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2274     {&hf_rdp_monitorExFlags,         4, NULL, 0, 0, NULL },
2275     {&hf_rdp_monitorAttributeSize,   4, NULL, 0, 0, NULL },
2276     {&hf_rdp_monitorCount,           4, NULL, 0, 0, NULL },
2277     FI_TERMINATOR
2278   };
2279 
2280   rdp_field_info_t multitransport_fields[] = {
2281     {&hf_rdp_headerType,             2, NULL, 0, 0, NULL },
2282     {&hf_rdp_headerLength,           2, NULL, 0, 0, NULL },
2283     {&hf_rdp_multiTransportFlags,    4, NULL, 0, 0, NULL },
2284     FI_TERMINATOR
2285   };
2286 
2287   tree = dissect_rdp(tvb, pinfo, tree);
2288 
2289   rdp_info = rdp_get_conversation_data(pinfo);
2290 
2291   copy_address(&rdp_info->serverAddr.addr, &pinfo->dst);
2292   rdp_info->serverAddr.port = pinfo->destport;
2293 
2294   col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ClientData");
2295 
2296   pi   = proto_tree_add_item(tree, hf_rdp_ClientData, tvb, offset, -1, ENC_NA);
2297   tree = proto_item_add_subtree(pi, ett_rdp_ClientData);
2298 
2299   /* Advance through the data blocks using the length from the header for each block.
2300    *  ToDo: Expert if actual amount dissected (based upon field array) is not equal to length ??
2301    *  Note: If length is less than the header size (4 bytes) offset is advanced by 4 bytes
2302    *        to ensure that dissection eventually terminates.
2303    */
2304 
2305   while (tvb_reported_length_remaining(tvb, offset) > 0) {
2306 
2307     type   = tvb_get_letohs(tvb, offset);
2308     length = tvb_get_letohs(tvb, offset+2);
2309 
2310 #if 0
2311     printf("offset=%d, type=%x, length=%d, remaining=%d\n",
2312            offset, type, length, tvb_captured_length_remaining(tvb, offset));
2313 #endif
2314 
2315     switch(type) {
2316     case CS_CORE:
2317       pi        = proto_tree_add_item(tree, hf_rdp_clientCoreData, tvb, offset, length, ENC_NA);
2318       next_tree = proto_item_add_subtree(pi, ett_rdp_clientCoreData);
2319       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, core_fields, length);
2320       break;
2321 
2322     case CS_SECURITY:
2323       pi        = proto_tree_add_item(tree, hf_rdp_clientSecurityData, tvb, offset, length, ENC_NA);
2324       next_tree = proto_item_add_subtree(pi, ett_rdp_clientSecurityData);
2325       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, security_fields, 0);
2326       break;
2327 
2328     case CS_NET:
2329       /*offset    =*/ dissect_rdp_clientNetworkData(tvb, offset, pinfo, tree, length, rdp_info);
2330       break;
2331 
2332     case CS_CLUSTER:
2333       pi        = proto_tree_add_item(tree, hf_rdp_clientClusterData, tvb, offset, length, ENC_NA);
2334       next_tree = proto_item_add_subtree(pi, ett_rdp_clientClusterData);
2335       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, cluster_fields, 0);
2336 
2337       break;
2338 
2339     case CS_MONITOR:
2340       pi        = proto_tree_add_item(tree, hf_rdp_clientMonitorData, tvb, offset, length, ENC_NA);
2341       next_tree = proto_item_add_subtree(pi, ett_rdp_clientMonitorData);
2342       /*offset    =*/ dissect_rdp_monitor(tvb, offset, pinfo, next_tree);
2343       break;
2344 
2345     case CS_MONITOR_EX:
2346       pi        = proto_tree_add_item(tree, hf_rdp_clientMonitorExData, tvb, offset, length, ENC_NA);
2347       next_tree = proto_item_add_subtree(pi, ett_rdp_clientMonitorExData);
2348       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, monitorex_fields, 0);
2349       break;
2350 
2351     case CS_MCS_MSGCHANNEL:
2352       pi        = proto_tree_add_item(tree, hf_rdp_clientMsgChannelData, tvb, offset, length, ENC_NA);
2353       next_tree = proto_item_add_subtree(pi, ett_rdp_clientMsgChannelData);
2354       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, msgchannel_fields, 0);
2355       break;
2356 
2357     case CS_MULTITRANSPORT:
2358       pi        = proto_tree_add_item(tree, hf_rdp_clientMultiTransportData, tvb, offset, length, ENC_NA);
2359       next_tree = proto_item_add_subtree(pi, ett_rdp_clientMultiTransportData);
2360       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, multitransport_fields, 0);
2361       break;
2362 
2363     default: /* unknown */
2364         pi        = proto_tree_add_item(tree, hf_rdp_clientUnknownData, tvb, offset, length, ENC_NA);
2365         next_tree = proto_item_add_subtree(pi, ett_rdp_clientUnknownData);
2366         /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, header_fields, 0);
2367         break;
2368     }
2369     offset += MAX(4, length);   /* Use length from header, but advance at least 4 bytes */
2370   }
2371   return tvb_captured_length(tvb);
2372 }
2373 
2374 static int
dissect_rdp_ServerData(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2375 dissect_rdp_ServerData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
2376   int              offset           = 0;
2377   proto_item      *pi;
2378   proto_tree      *next_tree;
2379   guint16          type;
2380   guint            length;
2381   guint32          serverRandomLen  = 0;
2382   guint32          serverCertLen    = 0;
2383   guint32          encryptionMethod = 0;
2384   guint32          encryptionLevel  = 0;
2385   guint32          channelCount     = 0;
2386   guint32          channelId     = 0;
2387   guint32          messageChannelId     = 0;
2388   guint            i;
2389   rdp_conv_info_t *rdp_info;
2390 
2391   rdp_field_info_t header_fields[] = {
2392     {&hf_rdp_headerType,               2, NULL, 0, 0, NULL },
2393     {&hf_rdp_headerLength,             2, NULL, 0, 0, NULL },
2394     FI_TERMINATOR
2395   };
2396   rdp_field_info_t sc_fields[] = {
2397     {&hf_rdp_headerType,               2, NULL, 0, 0, NULL },
2398     {&hf_rdp_headerLength,             2, NULL, 0, 0, NULL },
2399     {&hf_rdp_versionMajor,             2, NULL, 0, 0, NULL },
2400     {&hf_rdp_versionMinor,             2, NULL, 0, 0, NULL },
2401     /* The following fields are *optional*.                   */
2402     /*  I.E., a sequence of one or more of the trailing       */
2403     /*  fields at the end of the Data Block need not be       */
2404     /*  present. The length from the header field determines  */
2405     /*  the actual number of fields which are present.        */
2406     {&hf_rdp_clientRequestedProtocols, 4, NULL, 0, 0, NULL },
2407     {&hf_rdp_earlyCapabilityFlags,     2, NULL, 0, 0, NULL },
2408     FI_TERMINATOR
2409   };
2410   rdp_field_info_t ss_fields[] = {
2411     {&hf_rdp_headerType,               2, NULL, 0, 0, NULL },
2412     {&hf_rdp_headerLength,             2, NULL, 0, 0, NULL },
2413     {&hf_rdp_encryptionMethod,         4, &encryptionMethod, 0, 0, NULL },
2414     {&hf_rdp_encryptionLevel,          4, &encryptionLevel,  0, 0, NULL },
2415     FI_TERMINATOR
2416   };
2417   rdp_field_info_t encryption_fields[] = {
2418     {&hf_rdp_serverRandomLen,          4, &serverRandomLen,  0, 0, NULL },
2419     {&hf_rdp_serverCertLen,            4, &serverCertLen,    0, 0, NULL },
2420     {&hf_rdp_serverRandom,             0, &serverRandomLen,  0, 0, NULL },
2421     {&hf_rdp_serverCertificate,        0, &serverCertLen,    0, 0, NULL },
2422     FI_TERMINATOR
2423   };
2424   rdp_field_info_t sn_fields[] = {
2425     {&hf_rdp_headerType,               2, NULL, 0, 0, NULL },
2426     {&hf_rdp_headerLength,             2, NULL, 0, 0, NULL },
2427     {&hf_rdp_MCSChannelId,             2, &channelId, 0, 0, NULL },
2428     {&hf_rdp_channelCount,             2, &channelCount, 0, 0, NULL },
2429     FI_TERMINATOR
2430   };
2431   rdp_field_info_t array_fields[] = {
2432       {&hf_rdp_channelIdArray, 0 /*(channelCount * 2)*/, NULL, 0, 0, NULL },
2433     FI_TERMINATOR
2434   };
2435   rdp_field_info_t channel_fields[] = {
2436     {&hf_rdp_MCSChannelId, 2, &channelId, 0, 0, NULL },
2437     FI_TERMINATOR
2438   };
2439   rdp_field_info_t pad_fields[] = {
2440     {&hf_rdp_Pad, 2, NULL, 0, 0, NULL },
2441     FI_TERMINATOR
2442   };
2443   rdp_field_info_t msgchannel_fields[] = {
2444     {&hf_rdp_headerType,               2, NULL, 0, 0, NULL },
2445     {&hf_rdp_headerLength,             2, NULL, 0, 0, NULL },
2446     {&hf_rdp_msgChannelId,             2, &messageChannelId, 0, 0, NULL },
2447     FI_TERMINATOR
2448   };
2449   rdp_field_info_t multitransport_fields[] = {
2450     {&hf_rdp_headerType,               2, NULL, 0, 0, NULL },
2451     {&hf_rdp_headerLength,             2, NULL, 0, 0, NULL },
2452     {&hf_rdp_multiTransportFlags,      4, NULL, 0, 0, NULL },
2453     FI_TERMINATOR
2454   };
2455 
2456   tree   = dissect_rdp(tvb, pinfo, tree);
2457 
2458   rdp_info = rdp_get_conversation_data(pinfo);
2459 
2460   col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ServerData");
2461 
2462   pi   = proto_tree_add_item(tree, hf_rdp_ServerData, tvb, offset, -1, ENC_NA);
2463   tree = proto_item_add_subtree(pi, ett_rdp_ServerData);
2464 
2465   /* Advance through the data blocks using the length from the header for each block.
2466    *  ToDo: Expert if actual amount dissected (based upon field array) is not equal to length ??
2467    *  Note: If length is less than the header size (4 bytes) offset is advanced by 4 bytes
2468    *        to ensure that dissection eventually terminates.
2469    */
2470   while (tvb_reported_length_remaining(tvb, offset) > 0) {
2471 
2472     type   = tvb_get_letohs(tvb, offset);
2473     length = tvb_get_letohs(tvb, offset+2);
2474 
2475     /*    printf("offset=%d, type=%x, length=%d, remaining=%d\n",
2476           offset, type, length, tvb_captured_length_remaining(tvb, offset)); */
2477 
2478     switch(type) {
2479     case SC_CORE:
2480       pi        = proto_tree_add_item(tree, hf_rdp_serverCoreData, tvb, offset, length, ENC_NA);
2481       next_tree = proto_item_add_subtree(pi, ett_rdp_serverCoreData);
2482       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, sc_fields, length);
2483       break;
2484 
2485     case SC_SECURITY: {
2486       gint lcl_offset;
2487       pi         = proto_tree_add_item(tree, hf_rdp_serverSecurityData, tvb, offset, length, ENC_NA);
2488       next_tree  = proto_item_add_subtree(pi, ett_rdp_serverSecurityData);
2489 
2490       lcl_offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, ss_fields, 0);
2491 
2492       col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "Encryption: %s (%s)",
2493                           val_to_str_const(encryptionMethod, rdp_encryptionMethod_vals, "Unknown"),
2494                           val_to_str_const(encryptionLevel, rdp_encryptionLevel_vals, "Unknown"));
2495 
2496       if ((encryptionLevel != 0) || (encryptionMethod != 0)) {
2497         /*lcl_offset =*/ dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, encryption_fields, 0);
2498       }
2499 
2500       rdp_info->encryptionMethod = encryptionMethod;
2501       rdp_info->encryptionLevel  = encryptionLevel;
2502       break;
2503     }
2504 
2505     case SC_NET: {
2506       gint lcl_offset;
2507       pi        = proto_tree_add_item(tree, hf_rdp_serverNetworkData, tvb, offset, length, ENC_NA);
2508       next_tree = proto_item_add_subtree(pi, ett_rdp_serverNetworkData);
2509 
2510       lcl_offset = dissect_rdp_fields(tvb, offset, pinfo, next_tree, sn_fields, 0);
2511 
2512       rdp_info->staticChannelId = channelId;
2513       register_t124_sd_dissector(pinfo, channelId, dissect_rdp_SendData, proto_rdp);
2514 
2515       if (channelCount > 0) {
2516         array_fields[0].fixedLength = channelCount * 2;
2517         dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, array_fields, 0);
2518 
2519         if (next_tree)
2520           next_tree = proto_item_add_subtree(next_tree->last_child, ett_rdp_channelIdArray);
2521         for (i = 0; i < channelCount; i++) {
2522           lcl_offset = dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, channel_fields, 0);
2523           if (i < RDP_MAX_CHANNELS)
2524             rdp_info->staticChannels[i].value = channelId;
2525 
2526           /* register SendData on this for now */
2527           register_t124_sd_dissector(pinfo, channelId, dissect_rdp_SendData, proto_rdp);
2528         }
2529         if (channelCount % 2)
2530           /*lcl_offset =*/ dissect_rdp_fields(tvb, lcl_offset, pinfo, next_tree, pad_fields, 0);
2531       }
2532       break;
2533     }
2534 
2535     case SC_MCS_MSGCHANNEL:
2536       pi        = proto_tree_add_item(tree, hf_rdp_serverMsgChannelData, tvb, offset, length, ENC_NA);
2537       next_tree = proto_item_add_subtree(pi, ett_rdp_serverMsgChannelData);
2538       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, msgchannel_fields, length);
2539       rdp_info->messageChannelId = messageChannelId;
2540       register_t124_sd_dissector(pinfo, messageChannelId, dissect_rdp_MessageChannelData, proto_rdp);
2541       break;
2542 
2543     case SC_MULTITRANSPORT:
2544       pi        = proto_tree_add_item(tree, hf_rdp_serverMultiTransportData, tvb, offset, length, ENC_NA);
2545       next_tree = proto_item_add_subtree(pi, ett_rdp_serverMultiTransportData);
2546       /*offset    =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, multitransport_fields, length);
2547       break;
2548 
2549     default:  /* unknown */
2550       pi        = proto_tree_add_item(tree, hf_rdp_serverUnknownData, tvb, offset, length, ENC_NA);
2551       next_tree = proto_item_add_subtree(pi, ett_rdp_serverUnknownData);
2552 
2553       /*offset =*/ dissect_rdp_fields(tvb, offset, pinfo, next_tree, header_fields, 0);
2554       break;
2555     }
2556     offset += MAX(4, length);   /* Use length from header, but advance at least 4 bytes */
2557   }
2558   return tvb_captured_length(tvb);
2559 }
2560 
2561 /* Dissect extra data in a CR PDU */
2562 static int
dissect_rdpCorrelationInfo(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)2563 dissect_rdpCorrelationInfo(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
2564   guint32 type;
2565   guint32 length;
2566   proto_item *type_item, *length_item;
2567 
2568   type_item = proto_tree_add_item_ret_uint(tree, hf_rdp_neg_type, tvb, offset, 1, ENC_NA, &type);
2569   offset += 1;
2570   if (type != TYPE_RDP_CORRELATION_INFO) {
2571     expert_add_info(pinfo, type_item, &ei_rdp_not_correlation_info);
2572     return offset;
2573   }
2574   proto_tree_add_item(tree, hf_rdp_correlationInfo_flags, tvb, offset, 1, ENC_NA);
2575   offset += 1;
2576   length_item = proto_tree_add_item_ret_uint(tree, hf_rdp_neg_length, tvb, offset, 1, ENC_LITTLE_ENDIAN, &length);
2577   offset += 2;
2578   if (length != 36) {
2579     expert_add_info_format(pinfo, length_item, &ei_rdp_neg_len_invalid, "RDP Correlation Info length is %u, not 36", length);
2580     return offset;
2581   }
2582   proto_tree_add_item(tree, hf_rdp_correlationId, tvb, offset, 16, ENC_NA);
2583   offset += 16;
2584   proto_tree_add_item(tree, hf_rdp_correlationInfo_reserved, tvb, offset, 16, ENC_NA);
2585   offset += 16;
2586   return offset;
2587 }
2588 
2589 static int
dissect_rdpNegReq(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)2590 dissect_rdpNegReq(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
2591   guint64 flags;
2592   guint32 length;
2593   proto_item *length_item;
2594   static int * const flag_bits[] = {
2595     &hf_rdp_negReq_flag_restricted_admin_mode_req,
2596     &hf_rdp_negReq_flag_correlation_info_present,
2597     NULL
2598   };
2599   static int * const requestedProtocols_bits[] = {
2600     &hf_rdp_requestedProtocols_flag_ssl,
2601     &hf_rdp_requestedProtocols_flag_hybrid,
2602     &hf_rdp_requestedProtocols_flag_rdstls,
2603     &hf_rdp_requestedProtocols_flag_hybrid_ex,
2604     NULL
2605   };
2606 
2607   col_append_str(pinfo->cinfo, COL_INFO, "Negotiate Request");
2608 
2609   proto_tree_add_item(tree, hf_rdp_neg_type, tvb, offset, 1, ENC_NA);
2610   offset += 1;
2611   proto_tree_add_bitmask_ret_uint64(tree, tvb, offset, hf_rdp_negReq_flags,
2612                                     ett_negReq_flags, flag_bits,
2613                                     ENC_LITTLE_ENDIAN, &flags);
2614   offset += 1;
2615   length_item = proto_tree_add_item_ret_uint(tree, hf_rdp_neg_length, tvb, offset, 1, ENC_LITTLE_ENDIAN, &length);
2616   offset += 2;
2617   if (length != 8) {
2618     expert_add_info_format(pinfo, length_item, &ei_rdp_neg_len_invalid, "RDP Negotiate Request length is %u, not 8", length);
2619     return offset;
2620   }
2621   proto_tree_add_bitmask(tree, tvb, offset, hf_rdp_requestedProtocols,
2622                          ett_requestedProtocols, requestedProtocols_bits,
2623                          ENC_LITTLE_ENDIAN);
2624   offset += 4;
2625   if (flags & CORRELATION_INFO_PRESENT)
2626     offset = dissect_rdpCorrelationInfo(tvb, offset, pinfo, tree);
2627   return offset;
2628 }
2629 
2630 static int
dissect_rdp_cr(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data _U_)2631 dissect_rdp_cr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2632 {
2633   int offset = 0;
2634   gboolean have_cookie = FALSE;
2635   gboolean have_rdpNegRequest = FALSE;
2636   proto_item *item;
2637   proto_tree *tree;
2638   gint linelen, next_offset;
2639   const guint8 *stringval;
2640   const char *sep = "";
2641 
2642   /*
2643    * routingToken or cookie?  Both begin with "Cookie: ".
2644    */
2645   if (tvb_memeql(tvb, offset, "Cookie: ", 8) == 0) {
2646     /* Looks like a routing token or cookie */
2647     have_cookie = TRUE;
2648   } else if (tvb_bytes_exist(tvb, offset, 4) &&
2649              tvb_get_guint8(tvb, offset) == TYPE_RDP_NEG_REQ &&
2650              tvb_get_letohs(tvb, offset + 2) == 8) {
2651     /* Looks like a Negotiate Request (TYPE_RDP_NEG_REQ, length 8) */
2652     have_rdpNegRequest = TRUE;
2653   }
2654   if (!have_cookie && !have_rdpNegRequest) {
2655     /* Doesn't look like our data */
2656     return 0;
2657   }
2658 
2659   col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDP");
2660   col_clear(pinfo->cinfo, COL_INFO);
2661 
2662   item = proto_tree_add_item(parent_tree, proto_rdp, tvb, 0, -1, ENC_NA);
2663   tree = proto_item_add_subtree(item, ett_rdp);
2664 
2665   if (have_cookie) {
2666     /* XXX - distinguish between routing token and cookie? */
2667     linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, TRUE);
2668     proto_tree_add_item_ret_string(tree, hf_rdp_rt_cookie, tvb, offset,
2669                                    linelen, ENC_ASCII|ENC_NA,
2670                                    pinfo->pool, &stringval);
2671     offset = (linelen == -1) ? (gint)tvb_captured_length(tvb) : next_offset;
2672     col_append_str(pinfo->cinfo, COL_INFO, format_text(pinfo->pool, stringval, strlen(stringval)));
2673     sep = ", ";
2674   }
2675   /*
2676    * rdpNegRequest?
2677    */
2678   if (tvb_reported_length_remaining(tvb, offset) > 0) {
2679     col_append_str(pinfo->cinfo, COL_INFO, sep);
2680     offset = dissect_rdpNegReq(tvb, offset, pinfo, tree);
2681   }
2682   return offset; /* returns 0 if nothing was dissected, which is what we want */
2683 }
2684 
2685 /* Dissect extra data in a CC PDU */
2686 static int
dissect_rdpNegRsp(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)2687 dissect_rdpNegRsp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
2688   guint32 length;
2689   proto_item *length_item;
2690   static int * const flag_bits[] = {
2691     &hf_rdp_negRsp_flag_extended_client_data_supported,
2692     &hf_rdp_negRsp_flag_dynvc_gfx_protocol_supported,
2693     &hf_rdp_negRsp_flag_restricted_admin_mode_supported,
2694     &hf_rdp_negRsp_flag_restricted_authentication_mode_supported,
2695     NULL
2696   };
2697 
2698   col_append_str(pinfo->cinfo, COL_INFO, "Negotiate Response");
2699 
2700   proto_tree_add_item(tree, hf_rdp_neg_type, tvb, offset, 1, ENC_NA);
2701   offset += 1;
2702   proto_tree_add_bitmask(tree, tvb, offset, hf_rdp_negRsp_flags,
2703                          ett_negRsp_flags, flag_bits,
2704                          ENC_LITTLE_ENDIAN);
2705   offset += 1;
2706   length_item = proto_tree_add_item_ret_uint(tree, hf_rdp_neg_length, tvb, offset, 1, ENC_LITTLE_ENDIAN, &length);
2707   offset += 2;
2708   if (length != 8) {
2709     expert_add_info_format(pinfo, length_item, &ei_rdp_neg_len_invalid, "RDP Negotiate Response length is %u, not 8", length);
2710     return offset;
2711   }
2712   proto_tree_add_item(tree, hf_rdp_selectedProtocol, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2713   offset += 4;
2714   return offset;
2715 }
2716 
2717 static int
dissect_rdpNegFailure(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)2718 dissect_rdpNegFailure(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
2719   guint32 length;
2720   proto_item *length_item;
2721   guint32 failureCode;
2722 
2723   col_append_str(pinfo->cinfo, COL_INFO, "Negotiate Failure");
2724 
2725   proto_tree_add_item(tree, hf_rdp_neg_type, tvb, offset, 1, ENC_NA);
2726   offset += 1;
2727   proto_tree_add_item(tree, hf_rdp_negReq_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2728   offset += 1;
2729   length_item = proto_tree_add_item_ret_uint(tree, hf_rdp_neg_length, tvb, offset, 1, ENC_LITTLE_ENDIAN, &length);
2730   offset += 2;
2731   if (length != 8) {
2732     expert_add_info_format(pinfo, length_item, &ei_rdp_neg_len_invalid, "RDP Negotiate Failure length is %u, not 8", length);
2733     return offset;
2734   }
2735   proto_tree_add_item_ret_uint(tree, hf_rdp_negFailure_failureCode, tvb, offset, 4, ENC_LITTLE_ENDIAN, &failureCode);
2736   offset += 4;
2737   col_append_fstr(pinfo->cinfo, COL_INFO, ", failureCode %s",
2738                   val_to_str(failureCode, failure_code_vals, "Unknown (0x%08x)"));
2739   return offset;
2740 }
2741 
2742 static int
dissect_rdp_cc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data _U_)2743 dissect_rdp_cc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2744 {
2745   int offset = 0;
2746   guint8 type;
2747   guint16 length;
2748   gboolean ours = FALSE;
2749   proto_item *item;
2750   proto_tree *tree;
2751 
2752   if (tvb_bytes_exist(tvb, offset, 4)) {
2753     type = tvb_get_guint8(tvb, offset);
2754     length = tvb_get_letohs(tvb, offset + 2);
2755     if ((type == TYPE_RDP_NEG_RSP || type == TYPE_RDP_NEG_FAILURE) &&
2756         length == 8) {
2757       /* Looks like a Negotiate Response (TYPE_RDP_NEG_RSP, length 8)
2758          or a Negotaiate Failure (TYPE_RDP_NEG_FAILURE, length 8) */
2759       ours = TRUE;
2760     }
2761   }
2762   if (!ours) {
2763     /* Doesn't look like our data */
2764     return 0;
2765   }
2766 
2767   col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDP");
2768   col_clear(pinfo->cinfo, COL_INFO);
2769 
2770   item = proto_tree_add_item(parent_tree, proto_rdp, tvb, 0, -1, ENC_NA);
2771   tree = proto_item_add_subtree(item, ett_rdp);
2772 
2773   switch (type) {
2774 
2775   case TYPE_RDP_NEG_RSP:
2776     offset = dissect_rdpNegRsp(tvb, offset, pinfo, tree);
2777     break;
2778 
2779   case TYPE_RDP_NEG_FAILURE:
2780     offset = dissect_rdpNegFailure(tvb, offset, pinfo, tree);
2781     break;
2782   }
2783   return offset;
2784 }
2785 
2786 static gboolean
dissect_rdp_fastpath(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data _U_)2787 dissect_rdp_fastpath(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2788 {
2789   guint8 fp_hdr;
2790   proto_item *item;
2791   proto_tree *tree;
2792   guint16 pdu_length;
2793   guint8 len_size = 1;
2794 
2795   if (tvb_captured_length(tvb) < 3)
2796     return FALSE;
2797 
2798   fp_hdr = tvb_get_guint8(tvb, 0);
2799 
2800   if (fp_hdr & 0x3)
2801     return FALSE;
2802 
2803   pdu_length = tvb_get_guint8(tvb, 1);
2804 
2805   if (pdu_length == 0)
2806     return FALSE;
2807 
2808   if (pdu_length & 0x80) {
2809     pdu_length &= ~(0x80);
2810     pdu_length = (pdu_length << 8);
2811     pdu_length += tvb_get_guint8(tvb, 2);
2812     len_size = 2;
2813   }
2814 
2815   if (pdu_length != tvb_captured_length(tvb))
2816     return FALSE;
2817 
2818   col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDP");
2819   col_clear(pinfo->cinfo, COL_INFO);
2820   col_set_str(pinfo->cinfo, COL_INFO, "Fast-Path PDU");
2821 
2822   item = proto_tree_add_item(parent_tree, proto_rdp, tvb, 0, pdu_length, ENC_NA);
2823   tree = proto_item_add_subtree(item, ett_rdp);
2824   proto_tree_add_uint(tree, hf_rdp_fastpathPDULength, tvb, 1, len_size, pdu_length);
2825 
2826   return TRUE;
2827 }
2828 
2829 static gboolean
dissect_rdp_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data _U_)2830 dissect_rdp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_) {
2831     heur_dtbl_entry_t *hdtbl_entry;
2832 
2833     if (dissector_try_heuristic(rdp_heur_subdissector_list, tvb, pinfo, parent_tree,
2834                                 &hdtbl_entry, NULL)) {
2835         return TRUE;
2836     }
2837     return dissect_rdp_fastpath(tvb, pinfo, parent_tree, NULL);
2838 }
2839 
2840 
2841 static void
init_server_conversations(void)2842 init_server_conversations(void)
2843 {
2844 	rdp_transport_links = wmem_map_new(wmem_file_scope(), rdp_udp_conversation_hash, rdp_udp_conversation_equal_matched);
2845 }
2846 
2847 
2848 /*--- proto_register_rdp -------------------------------------------*/
2849 void
proto_register_rdp(void)2850 proto_register_rdp(void) {
2851 
2852   /* List of fields */
2853   static hf_register_info hf[] = {
2854     { &hf_rdp_rt_cookie,
2855       { "Routing Token/Cookie", "rdp.rt_cookie",
2856         FT_STRING, BASE_NONE, NULL, 0,
2857 	NULL, HFILL }},
2858     { &hf_rdp_neg_type,
2859       { "Type", "rdp.neg_type",
2860         FT_UINT8, BASE_HEX, VALS(neg_type_vals), 0,
2861 	NULL, HFILL }},
2862     { &hf_rdp_negReq_flags,
2863       { "Flags", "rdp.negReq.flags",
2864         FT_UINT8, BASE_HEX, NULL, 0,
2865 	NULL, HFILL }},
2866     { &hf_rdp_negReq_flag_restricted_admin_mode_req,
2867       { "Restricted admin mode required", "rdp.negReq.flags.restricted_admin_mode_req",
2868         FT_BOOLEAN, 8, NULL, RESTRICTED_ADMIN_MODE_REQUIRED,
2869 	NULL, HFILL }},
2870     { &hf_rdp_negReq_flag_correlation_info_present,
2871       { "Correlation info present", "rdp.negReq.flags.correlation_info_present",
2872         FT_BOOLEAN, 8, NULL, CORRELATION_INFO_PRESENT,
2873 	NULL, HFILL }},
2874     { &hf_rdp_neg_length,
2875       { "Length", "rdp.neg_length",
2876         FT_UINT16, BASE_DEC, NULL, 0,
2877 	NULL, HFILL }},
2878     { &hf_rdp_requestedProtocols,
2879       { "requestedProtocols", "rdp.negReq.requestedProtocols",
2880         FT_UINT32, BASE_HEX, NULL, 0,
2881 	NULL, HFILL }},
2882     { &hf_rdp_requestedProtocols_flag_ssl,
2883       { "TLS security supported", "rdp.negReq.requestedProtocols.ssl",
2884         FT_BOOLEAN, 32, NULL, 0x00000001,
2885 	NULL, HFILL }},
2886     { &hf_rdp_requestedProtocols_flag_hybrid,
2887       { "CredSSP supported", "rdp.negReq.requestedProtocols.hybrid",
2888         FT_BOOLEAN, 32, NULL, 0x00000002,
2889 	NULL, HFILL }},
2890     { &hf_rdp_requestedProtocols_flag_rdstls,
2891       { "RDSTLS supported", "rdp.negReq.requestedProtocols.rdstls",
2892         FT_BOOLEAN, 32, NULL, 0x00000004,
2893 	NULL, HFILL }},
2894     { &hf_rdp_requestedProtocols_flag_hybrid_ex,
2895       { "CredSSP with Early User Authorization Result PDU supported", "rdp.negReq.requestedProtocols.hybrid_ex",
2896         FT_BOOLEAN, 32, NULL, 0x00000008,
2897 	NULL, HFILL }},
2898     { &hf_rdp_correlationInfo_flags,
2899       { "Flags", "rdp.correlationInfo.flags",
2900         FT_UINT8, BASE_HEX, NULL, 0,
2901 	NULL, HFILL }},
2902     { &hf_rdp_correlationId,
2903       { "correlationId", "rdp.correlationInfo.correlationId",
2904         FT_BYTES, BASE_NONE, NULL, 0,
2905         NULL, HFILL }},
2906     { &hf_rdp_correlationInfo_reserved,
2907       { "Reserved", "rdp.correlationInfo.reserved",
2908         FT_BYTES, BASE_NONE, NULL, 0,
2909         NULL, HFILL }},
2910     { &hf_rdp_negRsp_flags,
2911       { "Flags", "rdp.negRsp.flags",
2912         FT_UINT8, BASE_HEX, NULL, 0,
2913 	NULL, HFILL }},
2914     { &hf_rdp_negRsp_flag_extended_client_data_supported,
2915       { "Extended Client Data Blocks supported", "rdp.negRsp.flags.extended_client_data_supported",
2916         FT_BOOLEAN, 8, NULL, 0x01,
2917 	NULL, HFILL }},
2918     { &hf_rdp_negRsp_flag_dynvc_gfx_protocol_supported,
2919       { "Graphics Pipeline Extension Protocol supported", "rdp.negRsp.flags.dynvc_gfx_protocol_supported",
2920         FT_BOOLEAN, 8, NULL, 0x02,
2921 	NULL, HFILL }},
2922     { &hf_rdp_negRsp_flag_restricted_admin_mode_supported,
2923       { "Restricted admin mode supported", "rdp.negRsp.flags.restricted_admin_mode_supported",
2924         FT_BOOLEAN, 8, NULL, 0x08,
2925 	NULL, HFILL }},
2926     { &hf_rdp_negRsp_flag_restricted_authentication_mode_supported,
2927       { "Restricted authentication mode supported", "rdp.negRsp.flags.restricted_authentication_mode_supported",
2928         FT_BOOLEAN, 8, NULL, 0x10,
2929 	NULL, HFILL }},
2930     { &hf_rdp_selectedProtocol,
2931       { "selectedProtocol", "rdp.negReq.selectedProtocol",
2932         FT_UINT32, BASE_HEX, VALS(rdp_selectedProtocol_vals), 0,
2933 	NULL, HFILL }},
2934     { &hf_rdp_negFailure_failureCode,
2935       { "failureCode", "rdp.negFailure.failureCode",
2936         FT_UINT32, BASE_HEX, VALS(failure_code_vals), 0,
2937 	NULL, HFILL }},
2938     { &hf_rdp_ClientData,
2939       { "ClientData", "rdp.clientData",
2940         FT_NONE, BASE_NONE, NULL, 0,
2941         NULL, HFILL }},
2942     { &hf_rdp_SendData,
2943       { "SendData", "rdp.sendData",
2944         FT_NONE, BASE_NONE, NULL, 0,
2945         NULL, HFILL }},
2946 	{ &hf_rdp_MessageData,
2947 	  { "MessageData", "rdp.messageData",
2948 		FT_NONE, BASE_NONE, NULL, 0,
2949 		NULL, HFILL }},
2950     { &hf_rdp_clientCoreData,
2951       { "clientCoreData", "rdp.client.coreData",
2952         FT_NONE, BASE_NONE, NULL, 0,
2953         NULL, HFILL }},
2954     { &hf_rdp_clientSecurityData,
2955       { "clientSecurityData", "rdp.client.securityData",
2956         FT_NONE, BASE_NONE, NULL, 0,
2957         NULL, HFILL }},
2958     { &hf_rdp_clientNetworkData,
2959       { "clientNetworkData", "rdp.client.networkData",
2960         FT_NONE, BASE_NONE, NULL, 0,
2961         NULL, HFILL }},
2962     { &hf_rdp_clientClusterData,
2963       { "clientClusterData", "rdp.client.clusterData",
2964         FT_NONE, BASE_NONE, NULL, 0,
2965         NULL, HFILL }},
2966     { &hf_rdp_clientMonitorData,
2967       { "clientMonitorData", "rdp.client.monitorData",
2968         FT_NONE, BASE_NONE, NULL, 0,
2969         NULL, HFILL }},
2970     { &hf_rdp_clientMonitorDefData,
2971       { "clientMonitorDefData", "rdp.client.monitorDefData",
2972         FT_NONE, BASE_NONE, NULL, 0,
2973         NULL, HFILL }},
2974     { &hf_rdp_clientMsgChannelData,
2975       { "clientMsgChannelData", "rdp.client.msgChannelData",
2976         FT_NONE, BASE_NONE, NULL, 0,
2977         NULL, HFILL }},
2978     { &hf_rdp_clientMonitorExData,
2979       { "clientMonitorExData", "rdp.client.monitorExData",
2980         FT_NONE, BASE_NONE, NULL, 0,
2981         NULL, HFILL }},
2982     { &hf_rdp_clientMultiTransportData,
2983       { "clientMultiTransportData", "rdp.client.multiTransportData",
2984         FT_NONE, BASE_NONE, NULL, 0,
2985         NULL, HFILL }},
2986     { &hf_rdp_clientUnknownData,
2987       { "clientUnknownData", "rdp.unknownData.client",
2988         FT_NONE, BASE_NONE, NULL, 0,
2989         NULL, HFILL }},
2990     { &hf_rdp_ServerData,
2991       { "ServerData", "rdp.serverData",
2992         FT_NONE, BASE_NONE, NULL, 0,
2993         NULL, HFILL }},
2994     { &hf_rdp_serverCoreData,
2995       { "serverCoreData", "rdp.server.coreData",
2996         FT_NONE, BASE_NONE, NULL, 0,
2997         NULL, HFILL }},
2998     { &hf_rdp_serverSecurityData,
2999       { "serverSecurityData", "rdp.server.securityData",
3000         FT_NONE, BASE_NONE, NULL, 0,
3001         NULL, HFILL }},
3002     { &hf_rdp_serverNetworkData,
3003       { "serverNetworkData", "rdp.server.networkData",
3004         FT_NONE, BASE_NONE, NULL, 0,
3005         NULL, HFILL }},
3006     { &hf_rdp_serverMsgChannelData,
3007       { "serverMsgChannelData", "rdp.server.msgChannelData",
3008         FT_NONE, BASE_NONE, NULL, 0,
3009         NULL, HFILL }},
3010     { &hf_rdp_serverMultiTransportData,
3011       { "serverMultiTransportData", "rdp.server.multiTransportData",
3012         FT_NONE, BASE_NONE, NULL, 0,
3013         NULL, HFILL }},
3014     { &hf_rdp_serverUnknownData,
3015       { "serverUnknownData", "rdp.unknownData.server",
3016         FT_NONE, BASE_NONE, NULL, 0,
3017         NULL, HFILL }},
3018     { &hf_rdp_securityExchangePDU,
3019       { "securityExchangePDU", "rdp.securityExchangePDU",
3020         FT_NONE, BASE_NONE, NULL, 0,
3021         NULL, HFILL }},
3022     { &hf_rdp_clientInfoPDU,
3023       { "clientInfoPDU", "rdp.clientInfoPDU",
3024         FT_NONE, BASE_NONE, NULL, 0,
3025         NULL, HFILL }},
3026     { &hf_rdp_validClientLicenseData,
3027       { "validClientLicenseData", "rdp.validClientLicenseData",
3028         FT_NONE, BASE_NONE, NULL, 0,
3029         NULL, HFILL }},
3030     { &hf_rdp_headerType,
3031       { "headerType", "rdp.header.type",
3032         FT_UINT16, BASE_HEX, VALS(rdp_headerType_vals), 0,
3033         NULL, HFILL }},
3034     { &hf_rdp_headerLength,
3035       { "headerLength", "rdp.header.length",
3036         FT_UINT16, BASE_DEC, NULL, 0,
3037         NULL, HFILL }},
3038     { &hf_rdp_versionMajor,
3039       { "versionMajor", "rdp.version.major",
3040         FT_UINT16, BASE_DEC, NULL, 0,
3041         NULL, HFILL }},
3042     { &hf_rdp_versionMinor,
3043       { "versionMinor", "rdp.version.minor",
3044         FT_UINT16, BASE_DEC, NULL, 0,
3045         NULL, HFILL }},
3046     { &hf_rdp_desktopWidth,
3047       { "desktopWidth", "rdp.desktop.width",
3048         FT_UINT16, BASE_DEC, NULL, 0,
3049         NULL, HFILL }},
3050     { &hf_rdp_desktopHeight,
3051       { "desktopHeight", "rdp.desktop.height",
3052         FT_UINT16, BASE_DEC, NULL, 0,
3053         NULL, HFILL }},
3054     { &hf_rdp_colorDepth,
3055       { "colorDepth", "rdp.colorDepth",
3056         FT_UINT16, BASE_HEX, VALS(rdp_colorDepth_vals), 0,
3057         NULL, HFILL }},
3058     { &hf_rdp_SASSequence,
3059       { "SASSequence", "rdp.SASSequence",
3060         FT_UINT16, BASE_DEC, NULL, 0,
3061         NULL, HFILL }},
3062     { &hf_rdp_keyboardLayout,
3063       { "keyboardLayout", "rdp.keyboardLayout",
3064         FT_UINT32, BASE_DEC, NULL, 0,
3065         NULL, HFILL }},
3066     { &hf_rdp_clientBuild,
3067       { "clientBuild", "rdp.client.build",
3068         FT_UINT32, BASE_DEC, NULL, 0,
3069         NULL, HFILL }},
3070     { &hf_rdp_clientName,
3071       { "clientName", "rdp.client.name",
3072         FT_STRINGZ, BASE_NONE, NULL, 0, /* supposed to be null-terminated */
3073         NULL, HFILL }},
3074     { &hf_rdp_keyboardType,
3075       { "keyboardType", "rdp.keyboard.type",
3076         FT_UINT32, BASE_DEC, VALS(rdp_keyboardType_vals), 0,
3077         NULL, HFILL }},
3078     { &hf_rdp_keyboardSubType,
3079       { "keyboardSubType", "rdp.keyboard.subtype",
3080         FT_UINT32, BASE_DEC, NULL, 0,
3081         NULL, HFILL }},
3082     { &hf_rdp_keyboardFunctionKey,
3083       { "keyboardFunctionKey", "rdp.keyboard.functionkey",
3084         FT_UINT32, BASE_DEC, NULL, 0,
3085         NULL, HFILL }},
3086     { &hf_rdp_imeFileName,
3087       { "imeFileName", "rdp.imeFileName",
3088         FT_BYTES, BASE_NONE, NULL, 0,
3089         NULL, HFILL }},
3090     { &hf_rdp_postBeta2ColorDepth,
3091       { "postBeta2ColorDepth", "rdp.postBeta2ColorDepth",
3092         FT_UINT16, BASE_HEX, VALS(rdp_colorDepth_vals), 0,
3093         NULL, HFILL }},
3094     { &hf_rdp_clientProductId,
3095       { "clientProductId", "rdp.client.productId",
3096         FT_UINT16, BASE_DEC, NULL, 0,
3097         NULL, HFILL }},
3098     { &hf_rdp_serialNumber,
3099       { "serialNumber", "rdp.serialNumber",
3100         FT_UINT32, BASE_DEC, NULL, 0,
3101         NULL, HFILL }},
3102     { &hf_rdp_highColorDepth,
3103       { "highColorDepth", "rdp.highColorDepth",
3104         FT_UINT16, BASE_HEX, VALS(rdp_highColorDepth_vals), 0,
3105         NULL, HFILL }},
3106     { &hf_rdp_supportedColorDepths,
3107       { "supportedColorDepths", "rdp.supportedColorDepths",
3108         FT_UINT16, BASE_HEX, NULL, 0,
3109         NULL, HFILL }},
3110     { &hf_rdp_earlyCapabilityFlags,
3111       { "earlyCapabilityFlags", "rdp.earlyCapabilityFlags",
3112         FT_UINT16, BASE_DEC, NULL, 0,
3113         NULL, HFILL }},
3114     { &hf_rdp_clientDigProductId,
3115       { "clientDigProductId", "rdp.client.digProductId",
3116         FT_STRINGZ, BASE_NONE, NULL, 0, /* XXX - is this always a string?  MS-RDPBCGR doesn't say so */
3117         NULL, HFILL }},
3118     { &hf_rdp_connectionType,
3119       { "connectionType", "rdp.connectionType",
3120         FT_UINT8, BASE_DEC, VALS(rdp_connectionType_vals), 0,
3121         NULL, HFILL }},
3122     { &hf_rdp_pad1octet,
3123       { "pad1octet", "rdp.pad1octet",
3124         FT_UINT8, BASE_HEX, NULL, 0,
3125         NULL, HFILL }},
3126     { &hf_rdp_serverSelectedProtocol,
3127       { "serverSelectedProtocol", "rdp.serverSelectedProtocol",
3128         FT_UINT32, BASE_DEC, NULL, 0,
3129         NULL, HFILL }},
3130     { &hf_rdp_encryptionMethods,
3131       { "encryptionMethods", "rdp.encryptionMethods",
3132         FT_BYTES, BASE_NONE, NULL, 0,
3133         NULL, HFILL }},
3134     { &hf_rdp_extEncryptionMethods,
3135       { "extEncryptionMethods", "rdp.extEncryptionMethods",
3136         FT_BYTES, BASE_NONE, NULL, 0,
3137         NULL, HFILL }},
3138     { &hf_rdp_cluster_flags,    /* ToDo: Display flags in detail */
3139       { "clusterFlags", "rdp.clusterFlags",
3140         FT_UINT32, BASE_HEX, NULL, 0,
3141         NULL, HFILL }},
3142     { &hf_rdp_redirectedSessionId,
3143       { "redirectedSessionId", "rdp.redirectedSessionId",
3144         FT_UINT32, BASE_HEX, NULL, 0,
3145         NULL, HFILL }},
3146     { &hf_rdp_msgChannelFlags,
3147       { "msgChannelFlags", "rdp.msgChannelFlags",
3148         FT_UINT32, BASE_HEX, NULL, 0,
3149         NULL, HFILL }},
3150     { &hf_rdp_msgChannelId,
3151       { "msgChannelId", "rdp.msgChannelId",
3152         FT_UINT16, BASE_DEC, NULL, 0,
3153         NULL, HFILL }},
3154     { &hf_rdp_monitorFlags,
3155       { "monitorFlags", "rdp.monitorFlags",
3156         FT_UINT32, BASE_HEX, NULL, 0,
3157         NULL, HFILL }},
3158     { &hf_rdp_monitorExFlags,
3159       { "monitorExFlags", "rdp.monitorExFlags",
3160         FT_UINT32, BASE_HEX, NULL, 0,
3161         NULL, HFILL }},
3162     { &hf_rdp_monitorAttributeSize,
3163       { "monitorAttributeSize", "rdp.monitorAttributeSize",
3164         FT_UINT32, BASE_DEC, NULL, 0,
3165         NULL, HFILL }},
3166     { &hf_rdp_monitorCount,
3167       { "monitorCount", "rdp.monitorCount",
3168         FT_UINT32, BASE_DEC, NULL, 0,
3169         NULL, HFILL }},
3170     { &hf_rdp_monitorDefLeft,
3171       { "left", "rdp.monitorDef.left",
3172         FT_INT32, BASE_DEC, NULL, 0,
3173         NULL, HFILL }},
3174     { &hf_rdp_monitorDefTop,
3175       { "top", "rdp.monitorDef.top",
3176         FT_INT32, BASE_DEC, NULL, 0,
3177         NULL, HFILL }},
3178     { &hf_rdp_monitorDefRight,
3179       { "right", "rdp.monitorDef.right",
3180         FT_INT32, BASE_DEC, NULL, 0,
3181         NULL, HFILL }},
3182     { &hf_rdp_monitorDefBottom,
3183       { "bottom", "rdp.monitorDef.bottom",
3184         FT_INT32, BASE_DEC, NULL, 0,
3185         NULL, HFILL }},
3186     { &hf_rdp_monitorDefFlags,
3187       { "flags", "rdp.monitorDef.flags",
3188         FT_UINT32, BASE_DEC, VALS(rdp_monitorDefFlags_vals), 0,
3189         NULL, HFILL }},
3190     { &hf_rdp_multiTransportFlags,
3191       { "multiTransportFlags", "rdp.multiTransportFlags",
3192         FT_UINT32, BASE_HEX, NULL, 0,
3193         NULL, HFILL }},
3194     { &hf_rdp_encryptionMethod,
3195       { "encryptionMethod", "rdp.encryptionMethod",
3196         FT_UINT32, BASE_HEX, VALS(rdp_encryptionMethod_vals), 0,
3197         NULL, HFILL }},
3198     { &hf_rdp_encryptionLevel,
3199       { "encryptionLevel", "rdp.encryptionLevel",
3200         FT_UINT32, BASE_HEX, VALS(rdp_encryptionLevel_vals), 0,
3201         NULL, HFILL }},
3202     { &hf_rdp_serverRandomLen,
3203       { "serverRandomLen", "rdp.serverRandomLen",
3204         FT_UINT32, BASE_DEC, NULL, 0,
3205         NULL, HFILL }},
3206     { &hf_rdp_serverCertLen,
3207       { "serverCertLen", "rdp.serverCertLen",
3208         FT_UINT32, BASE_DEC, NULL, 0,
3209         NULL, HFILL }},
3210     { &hf_rdp_serverRandom,
3211       { "serverRandom", "rdp.serverRandom",
3212         FT_BYTES, BASE_NONE, NULL, 0,
3213         NULL, HFILL }},
3214     { &hf_rdp_serverCertificate,
3215       { "serverCertificate", "rdp.serverCertificate",
3216         FT_BYTES, BASE_NONE, NULL, 0,
3217         NULL, HFILL }},
3218     { &hf_rdp_clientRequestedProtocols,
3219       { "clientRequestedProtocols", "rdp.client.requestedProtocols",
3220         FT_UINT32, BASE_HEX, NULL, 0,
3221         NULL, HFILL }},
3222     { &hf_rdp_MCSChannelId,
3223       { "MCSChannelId", "rdp.MCSChannelId",
3224         FT_UINT16, BASE_DEC, NULL, 0,
3225         NULL, HFILL }},
3226     { &hf_rdp_channelCount,
3227       { "channelCount", "rdp.channelCount",
3228         FT_UINT16, BASE_DEC, NULL, 0,
3229         NULL, HFILL }},
3230     { &hf_rdp_channelIdArray,
3231       { "channelIdArray", "rdp.channelIdArray",
3232         FT_NONE, BASE_NONE, NULL, 0,
3233         NULL, HFILL }},
3234     { &hf_rdp_Pad,
3235       { "Pad", "rdp.Pad",
3236         FT_UINT16, BASE_DEC, NULL, 0,
3237         NULL, HFILL }},
3238     { &hf_rdp_flags,
3239       { "flags", "rdp.flags",
3240         FT_UINT16, BASE_HEX, NULL, 0,
3241         NULL, HFILL }},
3242     { &hf_rdp_channelFlags,
3243       { "channelFlags", "rdp.channelFlags",
3244         FT_UINT32, BASE_HEX, NULL, 0,
3245         NULL, HFILL }},
3246     { &hf_rdp_flagsPkt,
3247       { "flagsPkt", "rdp.flags.pkt",
3248         FT_UINT16, BASE_HEX, VALS(rdp_flagsPkt_vals), SEC_PKT_MASK,
3249         NULL, HFILL }},
3250     { &hf_rdp_flagsEncrypt,
3251       { "flagsEncrypt", "rdp.flags.encrypt",
3252         FT_UINT16, BASE_HEX, NULL, SEC_ENCRYPT,
3253         NULL, HFILL }},
3254     { &hf_rdp_flagsResetSeqno,
3255       { "flagsResetSeqno", "rdp.flags.resetseqno",
3256         FT_UINT16, BASE_HEX, NULL, SEC_RESET_SEQNO,
3257         NULL, HFILL }},
3258     { &hf_rdp_flagsIgnoreSeqno,
3259       { "flagsIgnoreSeqno", "rdp.flags.ignoreseqno",
3260         FT_UINT16, BASE_HEX, NULL, SEC_IGNORE_SEQNO,
3261         NULL, HFILL }},
3262     { &hf_rdp_flagsLicenseEncrypt,
3263       { "flagsLicenseEncrypt", "rdp.flags.licenseencrypt",
3264         FT_UINT16, BASE_HEX, NULL, SEC_LICENSE_ENCRYPT_CS,
3265         NULL, HFILL }},
3266     { &hf_rdp_flagsSecureChecksum,
3267       { "flagsSecureChecksum", "rdp.flags.securechecksum",
3268         FT_UINT16, BASE_HEX, NULL, SEC_SECURE_CHECKSUM,
3269         NULL, HFILL }},
3270     { &hf_rdp_flagsFlagsHiValid,
3271       { "flagsHiValid", "rdp.flags.flagshivalid",
3272         FT_UINT16, BASE_HEX, NULL, SEC_FLAGSHI_VALID,
3273         NULL, HFILL }},
3274 	{ &hf_rdp_flagsAutodetectReq,
3275 	  { "autodetect request", "rdp.flags.autodetectreq",
3276 		FT_UINT16, BASE_HEX, NULL, SEC_AUTODETECT_REQ,
3277 		NULL, HFILL }},
3278 	{ &hf_rdp_flagsAutodetectResp,
3279 	  { "autodetect response", "rdp.flags.autodetectresp",
3280 		FT_UINT16, BASE_HEX, NULL, SEC_AUTODETECT_RSP,
3281 		NULL, HFILL }},
3282 	{ &hf_rdp_flagsHeartbeat,
3283 	  { "heartbeat", "rdp.flags.heartbeat",
3284 		FT_UINT16, BASE_HEX, NULL, SEC_HEARTBEAT,
3285 		NULL, HFILL }},
3286 	{ &hf_rdp_flagsTransportReq,
3287 	  { "multiTransport request", "rdp.flags.transportreq",
3288 		FT_UINT16, BASE_HEX, NULL, SEC_TRANSPORT_REQ,
3289 		NULL, HFILL }},
3290 	{ &hf_rdp_flagsTransportResp,
3291 	  { "transport response", "rdp.flags.transportrsp",
3292 		FT_UINT16, BASE_HEX, NULL, SEC_TRANSPORT_RSP,
3293 		NULL, HFILL }},
3294     { &hf_rdp_flagsHi,
3295       { "flagsHi", "rdp.flagsHi",
3296         FT_UINT16, BASE_HEX, NULL, 0,
3297         NULL, HFILL }},
3298     { &hf_rdp_length,
3299       { "length", "rdp.length",
3300         FT_UINT32, BASE_DEC, NULL, 0,
3301         NULL, HFILL }},
3302 	{ &hf_rdp_heartbeat_reserved,
3303 		{ "reserved", "rdp.heartbeat.reserved",
3304 		  FT_UINT8, BASE_HEX, NULL, 0,
3305 		  NULL, HFILL}},
3306 	{ &hf_rdp_heartbeat_period,
3307 		{ "Period", "rdp.heartbeat.period",
3308 		  FT_UINT8, BASE_DEC, NULL, 0,
3309 		  NULL, HFILL}},
3310 	{ &hf_rdp_heartbeat_count1,
3311 		{ "Count1", "rdp.heartbeat.count1",
3312 		  FT_UINT8, BASE_DEC, NULL, 0,
3313 		  NULL, HFILL}},
3314 	{ &hf_rdp_heartbeat_count2,
3315 		{ "Count2", "rdp.heartbeat.count2",
3316 		  FT_UINT8, BASE_DEC, NULL, 0,
3317 		  NULL, HFILL}},
3318 	{ &hf_rdp_bandwidth_header_len,
3319 		{ "HeaderLength", "rdp.bandwidth.headerlen",
3320 		  FT_UINT8, BASE_HEX, NULL, 0,
3321 		  NULL, HFILL}
3322 	},
3323 	{ &hf_rdp_bandwidth_header_type,
3324 		{ "HeaderTypeId", "rdp.bandwidth.typeid",
3325 		  FT_UINT8, BASE_HEX, VALS(bandwidth_typeid_vals), 0,
3326 		  NULL, HFILL}
3327 	},
3328 	{ &hf_rdp_bandwidth_seqnumber,
3329 		{ "Sequence number", "rdp.bandwidth.sequencenumber",
3330 		  FT_UINT16, BASE_HEX, NULL, 0,
3331 		  NULL, HFILL}
3332 	},
3333 	{ &hf_rdp_bandwidth_reqtype,
3334 		{ "Request type", "rdp.bandwidth.reqtype",
3335 		  FT_UINT16, BASE_HEX, VALS(bandwidth_request_vals), 0,
3336 		  NULL, HFILL}
3337 	},
3338 	{ &hf_rdp_bandwidth_resptype,
3339 		{ "Response type", "rdp.bandwidth.resptype",
3340 		  FT_UINT16, BASE_HEX, VALS(bandwidth_response_vals), 0,
3341 		  NULL, HFILL}
3342 	},
3343 	{ &hf_rdp_bandwidth_measure_payload_len,
3344 		{ "Payload length", "rdp.bandwidth.measure.len",
3345 		  FT_UINT16, BASE_DEC, NULL, 0,
3346 		  NULL, HFILL}
3347 	},
3348 	{ &hf_rdp_bandwidth_measure_payload_data,
3349 		{ "Payload data", "rdp.bandwidth.measure.payload",
3350 		  FT_BYTES, BASE_NONE, NULL, 0,
3351 		  NULL, HFILL}
3352 	},
3353 	{ &hf_rdp_network_characteristics_basertt,
3354 		{ "Base RTT", "rdp.networkcharacteristics.basertt",
3355 		  FT_UINT32, BASE_DEC, NULL, 0,
3356 		  NULL, HFILL}
3357 	},
3358 	{ &hf_rdp_network_characteristics_bandwidth,
3359 		{ "Bandwidth", "rdp.networkcharacteristics.bandwidth",
3360 		  FT_UINT32, BASE_DEC, NULL, 0,
3361 		  NULL, HFILL}
3362 	},
3363 	{ &hf_rdp_network_characteristics_averagertt,
3364 		{ "Average RTT", "rdp.networkcharacteristics.averagertt",
3365 		  FT_UINT32, BASE_DEC, NULL, 0,
3366 		  NULL, HFILL}
3367 	},
3368 	{ &hf_rdp_rtt_measure_time_delta,
3369 		{ "Time delta", "rdp.rttmeasure.timedelta",
3370 		  FT_UINT32, BASE_DEC, NULL, 0,
3371 		  NULL, HFILL}
3372 	},
3373 	{ &hf_rdp_rtt_measure_time_bytecount,
3374 		{ "Byte count", "rdp.rttmeasure.bytecount",
3375 		  FT_UINT32, BASE_DEC, NULL, 0,
3376 		  NULL, HFILL}
3377 	},
3378 	{ &hf_rdp_mt_req_requestId,
3379 	  { "Request id", "rdp.mtreq.requestid",
3380 	    FT_UINT32, BASE_HEX, NULL, 0,
3381 	    NULL, HFILL }},
3382 	{ &hf_rdp_mt_req_protocol,
3383 	  { "Protocol", "rdp.mtreq.protocol",
3384 		FT_UINT16, BASE_HEX, VALS(rdp_mt_protocol_vals), 0,
3385 		NULL, HFILL }},
3386 	{ &hf_rdp_mt_req_reserved,
3387 	  { "Reserved", "rdp.mtreq.reserved",
3388 		FT_UINT16, BASE_HEX, NULL, 0,
3389 		NULL, HFILL }},
3390 	{ &hf_rdp_mt_req_securityCookie,
3391 	  { "Security cookie", "rdp.mtreq.securitycookie",
3392 		FT_BYTES, BASE_NONE, NULL, 0,
3393 		NULL, HFILL }},
3394 	{ &hf_rdp_mt_rsp_requestId,
3395 	  { "Request id", "rdp.mtresp.requestid",
3396 		FT_UINT32, BASE_HEX, NULL, 0,
3397 		NULL, HFILL }},
3398 	{ &hf_rdp_mt_rsp_hrResponse,
3399 	  { "hrResponse", "rdp.mtresp.hrresponse",
3400 		FT_UINT32, BASE_HEX, VALS(rdp_mt_response_vals), 0,
3401 		NULL, HFILL }},
3402     { &hf_rdp_encryptedClientRandom,
3403       { "encryptedClientRandom", "rdp.encryptedClientRandom",
3404         FT_BYTES, BASE_NONE, NULL, 0,
3405         NULL, HFILL }},
3406     { &hf_rdp_dataSignature,
3407       { "dataSignature", "rdp.dataSignature",
3408         FT_BYTES, BASE_NONE, NULL, 0,
3409         NULL, HFILL }},
3410     { &hf_rdp_fipsLength,
3411       { "fipsLength", "rdp.fipsLength",
3412         FT_UINT16, BASE_DEC, NULL, 0,
3413         NULL, HFILL }},
3414     { &hf_rdp_fipsVersion,
3415       { "fipsVersion", "rdp.fipsVersion",
3416         FT_UINT8, BASE_HEX, NULL, 0,
3417         NULL, HFILL }},
3418     { &hf_rdp_padlen,
3419       { "padlen", "rdp.padlen",
3420         FT_UINT8, BASE_DEC, NULL, 0,
3421         NULL, HFILL }},
3422     { &hf_rdp_codePage,
3423       { "codePage", "rdp.codePage",
3424         FT_UINT32, BASE_DEC, NULL, 0,
3425         NULL, HFILL }},
3426     { &hf_rdp_optionFlags,
3427       { "optionFlags", "rdp.optionFlags",
3428         FT_UINT32, BASE_HEX, NULL, 0,
3429         NULL, HFILL }},
3430     { &hf_rdp_cbDomain,
3431       { "cbDomain", "rdp.domain.length",
3432         FT_UINT16, BASE_DEC, NULL, 0,
3433         NULL, HFILL }},
3434     { &hf_rdp_cbUserName,
3435       { "cbUserName", "rdp.userName.length",
3436         FT_UINT16, BASE_DEC, NULL, 0,
3437         NULL, HFILL }},
3438     { &hf_rdp_cbPassword,
3439       { "cbPassword", "rdp.password.length",
3440         FT_UINT16, BASE_DEC, NULL, 0,
3441         NULL, HFILL }},
3442     { &hf_rdp_cbAlternateShell,
3443       { "cbAlternateShell", "rdp.alternateShell.length",
3444         FT_UINT16, BASE_DEC, NULL, 0,
3445         NULL, HFILL }},
3446     { &hf_rdp_cbWorkingDir,
3447       { "cbWorkingDir", "rdp.workingDir.length",
3448         FT_UINT16, BASE_DEC, NULL, 0,
3449         NULL, HFILL }},
3450     { &hf_rdp_cbClientAddress,
3451       { "cbClientAddress", "rdp.client.address.length",
3452         FT_UINT16, BASE_DEC, NULL, 0,
3453         NULL, HFILL }},
3454     { &hf_rdp_cbClientDir,
3455       { "cbClientDir", "rdp.client.dir.length",
3456         FT_UINT16, BASE_DEC, NULL, 0,
3457         NULL, HFILL }},
3458     { &hf_rdp_cbAutoReconnectLen,
3459       { "cbAutoReconnectLen", "rdp.autoReconnectCookie.length",
3460         FT_UINT16, BASE_DEC, NULL, 0,
3461         NULL, HFILL }},
3462     { &hf_rdp_domain,
3463       { "domain", "rdp.domain",
3464         FT_STRINGZ, BASE_NONE, NULL, 0,  /* null-terminated, count includes terminator */
3465         NULL, HFILL }},
3466     { &hf_rdp_userName,
3467       { "userName", "rdp.userName",
3468         FT_STRINGZ, BASE_NONE, NULL, 0,  /* null-terminated, count includes terminator */
3469         NULL, HFILL }},
3470     { &hf_rdp_password,
3471       { "password", "rdp.password",
3472         FT_STRINGZ, BASE_NONE, NULL, 0,  /* null-terminated, count includes terminator */
3473         NULL, HFILL }},
3474     { &hf_rdp_alternateShell,
3475       { "alternateShell", "rdp.alternateShell",
3476         FT_STRINGZ, BASE_NONE, NULL, 0,  /* null-terminated, count includes terminator */
3477         NULL, HFILL }},
3478     { &hf_rdp_workingDir,
3479       { "workingDir", "rdp.workingDir",
3480         FT_STRINGZ, BASE_NONE, NULL, 0,  /* null-terminated, count includes terminator */
3481         NULL, HFILL }},
3482     { &hf_rdp_clientAddressFamily,
3483       { "clientAddressFamily", "rdp.client.addressFamily",
3484         FT_UINT16, BASE_HEX, NULL, 0,
3485         NULL, HFILL }},
3486     { &hf_rdp_clientAddress,
3487       { "clientAddress", "rdp.client.address",
3488         FT_STRINGZ, BASE_NONE, NULL, 0,  /* null-terminated, count includes terminator */
3489         NULL, HFILL }},
3490     { &hf_rdp_clientDir,
3491       { "clientDir", "rdp.client.dir",
3492         FT_STRINGZ, BASE_NONE, NULL, 0,  /* null-terminated, count includes terminator */
3493         NULL, HFILL }},
3494     { &hf_rdp_clientTimeZone,
3495       { "clientTimeZone", "rdp.client.timeZone",
3496         FT_NONE, BASE_NONE, NULL, 0,
3497         NULL, HFILL }},
3498     { &hf_rdp_clientSessionId,
3499       { "clientSessionId", "rdp.client.sessionId",
3500         FT_BYTES, BASE_NONE, NULL, 0,
3501         NULL, HFILL }},
3502     { &hf_rdp_performanceFlags,
3503       { "performanceFlags", "rdp.performanceFlags",
3504         FT_UINT32, BASE_HEX, NULL, 0,
3505         NULL, HFILL }},
3506     { &hf_rdp_autoReconnectCookie,
3507       { "autoReconnectCookie", "rdp.autoReconnectCookie",
3508         FT_BYTES, BASE_NONE, NULL, 0,
3509         NULL, HFILL }},
3510     { &hf_rdp_reserved1,
3511       { "reserved1", "rdp.reserved1",
3512         FT_UINT16, BASE_HEX, NULL, 0,
3513         NULL, HFILL }},
3514     { &hf_rdp_reserved2,
3515       { "reserved2", "rdp.reserved2",
3516         FT_UINT16, BASE_HEX, NULL, 0,
3517         NULL, HFILL }},
3518     { &hf_rdp_bMsgType,
3519       { "bMsgType", "rdp.bMsgType",
3520         FT_UINT8, BASE_HEX, VALS(rdp_bMsgType_vals), 0,
3521         NULL, HFILL }},
3522     { &hf_rdp_bVersion,
3523       { "bVersion", "rdp.bVersion",
3524         FT_UINT8, BASE_DEC, NULL, 0,
3525         NULL, HFILL }},
3526     { &hf_rdp_wMsgSize,
3527       { "wMsgSize", "rdp.wMsgSize",
3528         FT_UINT16, BASE_DEC, NULL, 0,
3529         NULL, HFILL }},
3530     { &hf_rdp_wBlobType,
3531       { "wBlobType", "rdp.wBlobType",
3532         FT_UINT16, BASE_DEC, VALS(rdp_wBlobType_vals), 0,
3533         NULL, HFILL }},
3534     { &hf_rdp_wBlobLen,
3535       { "wBlobLen", "rdp.wBlobLen",
3536         FT_UINT16, BASE_DEC, NULL, 0,
3537         NULL, HFILL }},
3538     { &hf_rdp_blobData,
3539       { "blobData", "rdp.blobData",
3540         FT_BYTES, BASE_NONE, NULL, 0,
3541         NULL, HFILL }},
3542     { &hf_rdp_shareControlHeader,
3543       { "shareControlHeader", "rdp.shareControlHeader",
3544         FT_BYTES, BASE_NONE, NULL, 0,
3545         NULL, HFILL }},
3546     { &hf_rdp_channelPDUHeader,
3547       { "channelPDUHeader", "rdp.channelPDUHeader",
3548         FT_BYTES, BASE_NONE, NULL, 0,
3549         NULL, HFILL }},
3550     { &hf_rdp_virtualChannelData,
3551       { "virtualChannelData", "rdp.virtualChannelData",
3552         FT_BYTES, BASE_NONE, NULL, 0,
3553         NULL, HFILL }},
3554     { &hf_rdp_fastpathPDULength,
3555       { "fastpathPDULength", "rdp.fastpathPDULength",
3556         FT_UINT16, BASE_DEC, NULL, 0,
3557         NULL, HFILL }},
3558     { &hf_rdp_totalLength,
3559       { "totalLength", "rdp.totalLength",
3560         FT_UINT16, BASE_DEC, NULL, 0,
3561         NULL, HFILL }},
3562     { &hf_rdp_pduType,
3563       { "pduType", "rdp.pduType",
3564         FT_UINT16, BASE_HEX, NULL, 0,
3565         NULL, HFILL }},
3566     { &hf_rdp_pduTypeType,
3567       { "pduTypeType", "rdp.pduType.type",
3568         FT_UINT16, BASE_HEX, VALS(rdp_pduTypeType_vals), PDUTYPE_TYPE_MASK,
3569         NULL, HFILL }},
3570     { &hf_rdp_pduTypeVersionLow,
3571       { "pduTypeVersionLow", "rdp.pduType.versionLow",
3572         FT_UINT16, BASE_DEC, NULL, PDUTYPE_VERSIONLOW_MASK,
3573         NULL, HFILL }},
3574     { &hf_rdp_pduTypeVersionHigh,
3575       { "pduTypeVersionHigh", "rdp.pduType.versionHigh",
3576         FT_UINT16, BASE_DEC, NULL, PDUTYPE_VERSIONHIGH_MASK,
3577         NULL, HFILL }},
3578     { &hf_rdp_pduSource,
3579       { "pduSource", "rdp.pduSource",
3580         FT_UINT16, BASE_DEC, NULL, 0,
3581         NULL, HFILL }},
3582     { &hf_rdp_shareId,
3583       { "shareId", "rdp.shareId",
3584         FT_UINT32, BASE_HEX, NULL, 0,
3585         NULL, HFILL }},
3586     { &hf_rdp_pad1,
3587       { "pad1", "rdp.pad1",
3588         FT_UINT8, BASE_HEX, NULL, 0,
3589         NULL, HFILL }},
3590     { &hf_rdp_streamId,
3591       { "streamId", "rdp.streamId",
3592         FT_UINT8, BASE_DEC, NULL, 0,
3593         NULL, HFILL }},
3594     { &hf_rdp_uncompressedLength,
3595       { "uncompressedLength", "rdp.uncompressedLength",
3596         FT_UINT16, BASE_DEC, NULL, 0,
3597         NULL, HFILL }},
3598     { &hf_rdp_pduType2,
3599       { "pduType2", "rdp.pduType2",
3600         FT_UINT8, BASE_DEC, VALS(rdp_pduType2_vals), 0,
3601         NULL, HFILL }},
3602     { &hf_rdp_compressedType,
3603       { "compressedType", "rdp.compressedType",
3604         FT_UINT8, BASE_HEX, NULL, 0,
3605         NULL, HFILL }},
3606     { &hf_rdp_compressedTypeType,
3607       { "compressedTypeType", "rdp.compressedType.type",
3608         FT_UINT8, BASE_HEX, VALS(rdp_compressionType_vals),
3609         PacketCompressionTypeMask,
3610         NULL, HFILL }},
3611     { &hf_rdp_compressedTypeCompressed,
3612       { "compressedTypeCompressed", "rdp.compressedType.compressed",
3613         FT_UINT8, BASE_HEX, NULL, PACKET_COMPRESSED,
3614         NULL, HFILL }},
3615     { &hf_rdp_compressedTypeAtFront,
3616       { "compressedTypeAtFront", "rdp.compressedType.atFront",
3617         FT_UINT8, BASE_HEX, NULL, PACKET_AT_FRONT,
3618         NULL, HFILL }},
3619     { &hf_rdp_compressedTypeFlushed,
3620       { "compressedTypeFlushed", "rdp.compressedType.flushed",
3621         FT_UINT8, BASE_HEX, NULL, PACKET_FLUSHED,
3622         NULL, HFILL }},
3623     { &hf_rdp_compressedLength,
3624       { "compressedLength", "rdp.compressedLength",
3625         FT_UINT16, BASE_DEC, NULL, 0,
3626         NULL, HFILL }},
3627     { &hf_rdp_wErrorCode,
3628       { "errorCode", "rdp.errorCode",
3629         FT_UINT32, BASE_DEC, VALS(rdp_wErrorCode_vals), 0,
3630         NULL, HFILL }},
3631     { &hf_rdp_wStateTransition,
3632       { "stateTransition", "rdp.stateTransition",
3633         FT_UINT32, BASE_DEC, VALS(rdp_wStateTransition_vals), 0,
3634         NULL, HFILL }},
3635     { &hf_rdp_numberEntries,
3636       { "numberEntries", "rdp.numberEntries",
3637         FT_UINT16, BASE_DEC, NULL, 0,
3638         NULL, HFILL }},
3639     { &hf_rdp_totalNumberEntries,
3640       { "totalNumberEntries", "rdp.totalNumberEntries",
3641         FT_UINT16, BASE_DEC, NULL, 0,
3642         NULL, HFILL }},
3643     { &hf_rdp_mapFlags,
3644       { "mapFlags", "rdp.mapFlags",
3645         FT_UINT16, BASE_HEX, NULL, 0,
3646         NULL, HFILL }},
3647     { &hf_rdp_fontMapFirst,
3648       { "fontMapFirst", "rdp.mapFlags.fontMapFirst",
3649         FT_UINT16, BASE_HEX, NULL, FONTMAP_FIRST,
3650         NULL, HFILL }},
3651     { &hf_rdp_fontMapLast,
3652       { "fontMapLast", "rdp.mapFlags.fontMapLast",
3653         FT_UINT16, BASE_HEX, NULL, FONTMAP_LAST,
3654         NULL, HFILL }},
3655     { &hf_rdp_entrySize,
3656       { "entrySize", "rdp.entrySize",
3657         FT_UINT16, BASE_DEC, NULL, 0,
3658         NULL, HFILL }},
3659     { &hf_rdp_action,
3660       { "action", "rdp.action",
3661         FT_UINT16, BASE_HEX, VALS(rdp_action_vals),
3662         0,
3663         NULL, HFILL }},
3664     { &hf_rdp_grantId,
3665       { "grantId", "rdp.grantId",
3666         FT_UINT16, BASE_DEC, NULL, 0,
3667         NULL, HFILL }},
3668     { &hf_rdp_controlId,
3669       { "controlId", "rdp.controlId",
3670         FT_UINT32, BASE_DEC, NULL, 0,
3671         NULL, HFILL }},
3672     { &hf_rdp_messageType,
3673       { "messageType", "rdp.messageType",
3674         FT_UINT16, BASE_DEC, NULL, 0,
3675         NULL, HFILL }},
3676     { &hf_rdp_targetUser,
3677       { "targetUser", "rdp.targetUser",
3678         FT_UINT16, BASE_DEC, NULL, 0,
3679         NULL, HFILL }},
3680     { &hf_rdp_numEntriesCache0,
3681       { "numEntriesCache0", "rdp.numEntriesCache0",
3682         FT_UINT16, BASE_DEC, NULL, 0,
3683         NULL, HFILL }},
3684     { &hf_rdp_numEntriesCache1,
3685       { "numEntriesCache1", "rdp.numEntriesCache1",
3686         FT_UINT16, BASE_DEC, NULL, 0,
3687         NULL, HFILL }},
3688     { &hf_rdp_numEntriesCache2,
3689       { "numEntriesCache2", "rdp.numEntriesCache2",
3690         FT_UINT16, BASE_DEC, NULL, 0,
3691         NULL, HFILL }},
3692     { &hf_rdp_numEntriesCache3,
3693       { "numEntriesCache3", "rdp.numEntriesCache3",
3694         FT_UINT16, BASE_DEC, NULL, 0,
3695         NULL, HFILL }},
3696     { &hf_rdp_numEntriesCache4,
3697       { "numEntriesCache4", "rdp.numEntriesCache4",
3698         FT_UINT16, BASE_DEC, NULL, 0,
3699         NULL, HFILL }},
3700     { &hf_rdp_totalEntriesCache0,
3701       { "totalEntriesCache0", "rdp.totalEntriesCache0",
3702         FT_UINT16, BASE_DEC, NULL, 0,
3703         NULL, HFILL }},
3704     { &hf_rdp_totalEntriesCache1,
3705       { "totalEntriesCache1", "rdp.totalEntriesCache1",
3706         FT_UINT16, BASE_DEC, NULL, 0,
3707         NULL, HFILL }},
3708     { &hf_rdp_totalEntriesCache2,
3709       { "totalEntriesCache2", "rdp.totalEntriesCache2",
3710         FT_UINT16, BASE_DEC, NULL, 0,
3711         NULL, HFILL }},
3712     { &hf_rdp_totalEntriesCache3,
3713       { "totalEntriesCache3", "rdp.totalEntriesCache3",
3714         FT_UINT16, BASE_DEC, NULL, 0,
3715         NULL, HFILL }},
3716     { &hf_rdp_totalEntriesCache4,
3717       { "totalEntriesCache4", "rdp.totalEntriesCache4",
3718         FT_UINT16, BASE_DEC, NULL, 0,
3719         NULL, HFILL }},
3720     { &hf_rdp_bBitMask,
3721       { "bBitMask", "rdp.bBitMask",
3722         FT_UINT8, BASE_HEX, NULL, 0,
3723         NULL, HFILL }},
3724     { &hf_rdp_Pad2,
3725       { "Pad2", "rdp.Pad2",
3726         FT_UINT8, BASE_HEX, NULL, 0,
3727         NULL, HFILL }},
3728     { &hf_rdp_Pad3,
3729       { "Pad3", "rdp.Pad3",
3730         FT_UINT16, BASE_HEX, NULL, 0,
3731         NULL, HFILL }},
3732 #if 0
3733     { &hf_rdp_Key1,
3734       { "Key1", "rdp.Key1",
3735         FT_UINT32, BASE_HEX, NULL, 0,
3736         NULL, HFILL }},
3737 #endif
3738 #if 0
3739     { &hf_rdp_Key2,
3740       { "Key2", "rdp.Key2",
3741         FT_UINT32, BASE_HEX, NULL, 0,
3742         NULL, HFILL }},
3743 #endif
3744     { &hf_rdp_originatorId,
3745       { "originatorId", "rdp.OriginatorId",
3746         FT_UINT32, BASE_DEC, NULL, 0,
3747         NULL, HFILL }},
3748     { &hf_rdp_lengthSourceDescriptor,
3749       { "lengthSourceDescriptor", "rdp.lengthSourceDescriptor",
3750         FT_UINT16, BASE_DEC, NULL, 0,
3751         NULL, HFILL }},
3752     { &hf_rdp_lengthCombinedCapabilities,
3753       { "lengthCombinedCapabilities", "rdp.lengthCombinedCapabilities",
3754         FT_UINT16, BASE_DEC, NULL, 0,
3755         NULL, HFILL }},
3756     { &hf_rdp_sourceDescriptor,
3757       { "sourceDescriptor", "rdp.sourceDescriptor",
3758         FT_STRING, BASE_NONE, NULL, 0,
3759         NULL, HFILL }},
3760     { &hf_rdp_numberCapabilities,
3761       { "numberCapabilities", "rdp.numberCapabilities",
3762         FT_UINT16, BASE_DEC, NULL, 0,
3763         NULL, HFILL }},
3764     { &hf_rdp_pad2Octets,
3765       { "pad2Octets", "rdp.pad2Octets",
3766         FT_UINT16, BASE_DEC, NULL, 0,
3767         NULL, HFILL }},
3768     { &hf_rdp_capabilitySetType,
3769       { "capabilitySetType", "rdp.capabilitySetType",
3770         FT_UINT16, BASE_HEX, VALS(rdp_capabilityType_vals), 0,
3771         NULL, HFILL }},
3772     { &hf_rdp_capabilitySet,
3773       { "capabilitySet", "rdp.capabilitySet",
3774         FT_NONE, BASE_NONE, NULL, 0,
3775         NULL, HFILL }},
3776     { &hf_rdp_lengthCapability,
3777       { "lengthCapability", "rdp.lengthCapability",
3778         FT_UINT16, BASE_DEC, NULL, 0,
3779         NULL, HFILL }},
3780     { &hf_rdp_capabilityData,
3781       { "capabilityData", "rdp.capabilityData",
3782         FT_NONE, BASE_NONE, NULL, 0,
3783         NULL, HFILL }},
3784 #if 0
3785     { &hf_rdp_unknownData,
3786       { "unknownData", "rdp.unknownData",
3787         FT_NONE, BASE_NONE, NULL, 0,
3788         NULL, HFILL }},
3789 #endif
3790     { &hf_rdp_notYetImplemented,
3791       { "notYetImplemented", "rdp.notYetImplemented",
3792         FT_NONE, BASE_NONE, NULL, 0,
3793         NULL, HFILL }},
3794     { &hf_rdp_encrypted,
3795       { "encryptedData", "rdp.encryptedData",
3796         FT_NONE, BASE_NONE, NULL, 0,
3797         NULL, HFILL }},
3798 #if 0
3799     { &hf_rdp_compressed,
3800       { "compressedData", "rdp.compressedData",
3801         FT_NONE, BASE_NONE, NULL, 0,
3802         NULL, HFILL }},
3803 #endif
3804     { &hf_rdp_sessionId,
3805       { "sessionId", "rdp.sessionId",
3806         FT_UINT32, BASE_HEX, NULL, 0,
3807         NULL, HFILL }},
3808     { &hf_rdp_channelDefArray,
3809       { "channelDefArray", "rdp.channelDefArray",
3810         FT_NONE, BASE_NONE, NULL, 0,
3811         NULL, HFILL }},
3812     { &hf_rdp_channelDef,
3813       { "channelDef", "rdp.channelDef",
3814         FT_NONE, BASE_NONE, NULL, 0,
3815         NULL, HFILL }},
3816     { &hf_rdp_name,
3817       { "name", "rdp.name",
3818         FT_STRING, BASE_NONE, NULL, 0,
3819         NULL, HFILL }},
3820     { &hf_rdp_options,
3821       { "options", "rdp.options",
3822         FT_UINT32, BASE_HEX, NULL, 0,
3823         NULL, HFILL }},
3824     { &hf_rdp_optionsInitialized,
3825       { "optionsInitialized", "rdp.options.initialized",
3826         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_INITIALIZED,
3827         NULL, HFILL }},
3828     { &hf_rdp_optionsEncryptRDP,
3829       { "encryptRDP", "rdp.options.encrypt.rdp",
3830         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_ENCRYPT_RDP,
3831         NULL, HFILL }},
3832     { &hf_rdp_optionsEncryptSC,
3833       { "encryptSC", "rdp.options.encrypt.sc",
3834         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_ENCRYPT_SC,
3835         NULL, HFILL }},
3836     { &hf_rdp_optionsEncryptCS,
3837       { "encryptCS", "rdp.options.encrypt.cs",
3838         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_ENCRYPT_CS,
3839         NULL, HFILL }},
3840     { &hf_rdp_optionsPriHigh,
3841       { "priorityHigh", "rdp.options.priority.high",
3842         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_PRI_HIGH,
3843         NULL, HFILL }},
3844     { &hf_rdp_optionsPriMed,
3845       { "priorityMed", "rdp.options.priority.med",
3846         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_PRI_MED,
3847         NULL, HFILL }},
3848     { &hf_rdp_optionsPriLow,
3849       { "priorityLow", "rdp.options.priority.low",
3850         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_PRI_LOW,
3851         NULL, HFILL }},
3852     { &hf_rdp_optionsCompressRDP,
3853       { "compressRDP", "rdp.options.compress.rdp",
3854         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_COMPRESS_RDP,
3855         NULL, HFILL }},
3856     { &hf_rdp_optionsCompress,
3857       { "compress", "rdp.options.compress",
3858         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_COMPRESS,
3859         NULL, HFILL }},
3860     { &hf_rdp_optionsShowProtocol,
3861       { "showProtocol", "rdp.options.showprotocol",
3862         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_SHOW_PROTOCOL,
3863         NULL, HFILL }},
3864     { &hf_rdp_optionsRemoteControlPersistent,
3865       { "remoteControlPersistent", "rdp.options.remotecontrolpersistent",
3866         FT_UINT32, BASE_HEX, NULL, CHANNEL_OPTION_REMOTE_CONTROL_PERSISTENT,
3867         NULL, HFILL }},
3868     { &hf_rdp_channelFlagFirst,
3869       { "channelFlagFirst", "rdp.channelFlag.first",
3870         FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_FIRST,
3871         NULL, HFILL }},
3872     { &hf_rdp_channelFlagLast,
3873       { "channelFlagLast", "rdp.channelFlag.last",
3874         FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_LAST,
3875         NULL, HFILL }},
3876     { &hf_rdp_channelFlagShowProtocol,
3877       { "channelFlagShowProtocol", "rdp.channelFlag.showProtocol",
3878         FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_SHOW_PROTOCOL,
3879         NULL, HFILL }},
3880     { &hf_rdp_channelFlagSuspend,
3881       { "channelFlagSuspend", "rdp.channelFlag.suspend",
3882         FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_SUSPEND,
3883         NULL, HFILL }},
3884     { &hf_rdp_channelFlagResume,
3885       { "channelFlagResume", "rdp.channelFlag.resume",
3886         FT_UINT32, BASE_HEX, NULL, CHANNEL_FLAG_RESUME,
3887         NULL, HFILL }},
3888     { &hf_rdp_channelPacketCompressed,
3889       { "channelPacketCompressed", "rdp.channelPacket.compressed",
3890         FT_UINT32, BASE_HEX, NULL, CHANNEL_PACKET_COMPRESSED,
3891         NULL, HFILL }},
3892     { &hf_rdp_channelPacketAtFront,
3893       { "channelPacketAtFront", "rdp.channelPacket.atFront",
3894         FT_UINT32, BASE_HEX, NULL, CHANNEL_PACKET_AT_FRONT,
3895         NULL, HFILL }},
3896     { &hf_rdp_channelPacketFlushed,
3897       { "channelPacketFlushed", "rdp.channelPacket.flushed",
3898         FT_UINT32, BASE_HEX, NULL, CHANNEL_PACKET_FLUSHED,
3899         NULL, HFILL }},
3900     { &hf_rdp_channelPacketCompressionType,
3901       { "channelPacketCompresssionType", "rdp.channelPacket.compressionType",
3902         FT_UINT32, BASE_HEX, VALS(rdp_channelCompressionType_vals), ChannelCompressionTypeMask,
3903         NULL, HFILL }},
3904     { &hf_rdp_wYear,
3905       { "wYear", "rdp.wYear",
3906         FT_UINT16, BASE_DEC, NULL, 0,
3907         NULL, HFILL }},
3908     { &hf_rdp_wMonth,
3909       { "wMonth", "rdp.wMonth",
3910         FT_UINT16, BASE_DEC, VALS(rdp_wMonth_vals), 0,
3911         NULL, HFILL }},
3912     { &hf_rdp_wDayOfWeek,
3913       { "wDayOfWeek", "rdp.wDayOfWeek",
3914         FT_UINT16, BASE_DEC, VALS(rdp_wDayOfWeek_vals), 0,
3915         NULL, HFILL }},
3916     { &hf_rdp_wDay,
3917       { "wDay", "rdp.wDay",
3918         FT_UINT16, BASE_DEC, VALS(rdp_wDay_vals), 0,
3919         NULL, HFILL }},
3920     { &hf_rdp_wHour,
3921       { "wHour", "rdp.wHour",
3922         FT_UINT16, BASE_DEC, NULL, 0,
3923         NULL, HFILL }},
3924     { &hf_rdp_wMinute,
3925       { "wMinute", "rdp.wMinute",
3926         FT_UINT16, BASE_DEC, NULL, 0,
3927         NULL, HFILL }},
3928     { &hf_rdp_wSecond,
3929       { "wSecond", "rdp.wSecond",
3930         FT_UINT16, BASE_DEC, NULL, 0,
3931         NULL, HFILL }},
3932     { &hf_rdp_wMilliseconds,
3933       { "wMilliseconds", "rdp.wMilliseconds",
3934         FT_UINT16, BASE_DEC, NULL, 0,
3935         NULL, HFILL }},
3936     { &hf_rdp_Bias,
3937       { "Bias", "rdp.Bias",
3938         FT_UINT32, BASE_DEC, NULL, 0,
3939         NULL, HFILL }},
3940     { &hf_rdp_StandardBias,
3941       { "StandardBias", "rdp.Bias.standard",
3942         FT_UINT32, BASE_DEC, NULL, 0,
3943         NULL, HFILL }},
3944     { &hf_rdp_DaylightBias,
3945       { "DaylightBias", "rdp.Bias.daylight",
3946         FT_UINT32, BASE_DEC, NULL, 0,
3947         NULL, HFILL }},
3948     { &hf_rdp_StandardName,
3949       { "StandardName", "rdp.Name.Standard",
3950         FT_STRINGZ, BASE_NONE, NULL, 0,      /* zero-padded, not null-terminated */
3951         NULL, HFILL }},
3952     { &hf_rdp_StandardDate,
3953       { "StandardDate", "rdp.Date.Standard",
3954         FT_NONE, BASE_NONE, NULL, 0,
3955         NULL, HFILL }},
3956     { &hf_rdp_DaylightName,
3957       { "DaylightName", "rdp.Name.Daylight",
3958         FT_STRINGZ, BASE_NONE, NULL, 0,      /* zero-padded, not null-terminated */
3959         NULL, HFILL }},
3960     { &hf_rdp_DaylightDate,
3961       { "DaylightDate", "rdp.Date.Daylight",
3962         FT_NONE, BASE_NONE, NULL, 0,
3963         NULL, HFILL }},
3964   };
3965 
3966   /* List of subtrees */
3967   static gint *ett[] = {
3968     &ett_rdp,
3969     &ett_negReq_flags,
3970     &ett_requestedProtocols,
3971     &ett_negRsp_flags,
3972     &ett_selectedProtocol,
3973     &ett_rdp_ClientData,
3974     &ett_rdp_ServerData,
3975     &ett_rdp_SendData,
3976     &ett_rdp_MessageData,
3977     &ett_rdp_capabilitySet,
3978     &ett_rdp_channelDef,
3979     &ett_rdp_channelDefArray,
3980     &ett_rdp_channelFlags,
3981     &ett_rdp_channelIdArray,
3982     &ett_rdp_channelPDUHeader,
3983     &ett_rdp_clientClusterData,
3984     &ett_rdp_clientCoreData,
3985     &ett_rdp_clientInfoPDU,
3986     &ett_rdp_clientMonitorData,
3987     &ett_rdp_clientMonitorDefData,
3988     &ett_rdp_clientMonitorExData,
3989     &ett_rdp_clientMsgChannelData,
3990     &ett_rdp_clientMultiTransportData,
3991     &ett_rdp_clientNetworkData,
3992     &ett_rdp_clientSecurityData,
3993     &ett_rdp_clientUnknownData,
3994     &ett_rdp_compressedType,
3995 	&ett_rdp_mt_req,
3996 	&ett_rdp_mt_rsp,
3997 	&ett_rdp_heartbeat,
3998     &ett_rdp_flags,
3999     &ett_rdp_mapFlags,
4000     &ett_rdp_options,
4001     &ett_rdp_pduType,
4002     &ett_rdp_securityExchangePDU,
4003     &ett_rdp_serverCoreData,
4004     &ett_rdp_serverMsgChannelData,
4005     &ett_rdp_serverMultiTransportData,
4006     &ett_rdp_serverNetworkData,
4007     &ett_rdp_serverSecurityData,
4008     &ett_rdp_serverUnknownData,
4009     &ett_rdp_shareControlHeader,
4010     &ett_rdp_validClientLicenseData,
4011     &ett_rdp_StandardDate,
4012     &ett_rdp_DaylightDate,
4013     &ett_rdp_clientTimeZone,
4014   };
4015   static ei_register_info ei[] = {
4016      { &ei_rdp_neg_len_invalid, { "rdp.neg_len.invalid", PI_PROTOCOL, PI_ERROR, "Invalid length", EXPFILL }},
4017      { &ei_rdp_not_correlation_info, { "rdp.not_correlation_info", PI_PROTOCOL, PI_ERROR, "What follows RDP Negotiation Request is not an RDP Correlation Info", EXPFILL }},
4018   };
4019   module_t *rdp_module;
4020   expert_module_t* expert_rdp;
4021 
4022   /* Register protocol */
4023   proto_rdp = proto_register_protocol(PNAME, PSNAME, PFNAME);
4024   /* Register fields and subtrees */
4025   proto_register_field_array(proto_rdp, hf, array_length(hf));
4026   proto_register_subtree_array(ett, array_length(ett));
4027   expert_rdp = expert_register_protocol(proto_rdp);
4028   expert_register_field_array(expert_rdp, ei, array_length(ei));
4029 
4030   register_init_routine(init_server_conversations);
4031 
4032   /* Register our configuration options for RDP, particularly our port */
4033   rdp_module = prefs_register_protocol(proto_rdp, NULL);
4034 
4035   prefs_register_obsolete_preference(rdp_module, "tcp.port");
4036 
4037   prefs_register_static_text_preference(rdp_module, "tcp_port_info",
4038             "The TCP ports used by the RDP protocol should be added to the TPKT preference \"TPKT TCP ports\", or by selecting \"TPKT\" as the \"Transport\" protocol in the \"Decode As\" dialog.",
4039             "RDP TCP Port preference moved information");
4040 
4041   rdp_heur_subdissector_list = register_heur_dissector_list("rdp", proto_rdp);
4042 }
4043 
4044 void
proto_reg_handoff_rdp(void)4045 proto_reg_handoff_rdp(void)
4046 {
4047   drdynvc_handle = find_dissector("rdp_drdynvc");
4048 
4049   heur_dissector_add("cotp_cr", dissect_rdp_cr, "RDP", "rdp_cr", proto_rdp, HEURISTIC_ENABLE);
4050   heur_dissector_add("cotp_cc", dissect_rdp_cc, "RDP", "rdp_cc", proto_rdp, HEURISTIC_ENABLE);
4051 
4052   heur_dissector_add("tpkt", dissect_rdp_heur, "RDP", "rdp_fastpath", proto_rdp, HEURISTIC_ENABLE);
4053 
4054   register_t124_ns_dissector("Duca", dissect_rdp_ClientData, proto_rdp);
4055   register_t124_ns_dissector("McDn", dissect_rdp_ServerData, proto_rdp);
4056 }
4057 
4058 /*
4059  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4060  *
4061  * Local Variables:
4062  * c-basic-offset: 2
4063  * tab-width: 8
4064  * indent-tabs-mode: nil
4065  * End:
4066  *
4067  * ex: set shiftwidth=2 tabstop=8 expandtab:
4068  * :indentSize=2:tabSize=8:noTabs=true:
4069  */
4070