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