/src/wireshark/epan/dissectors/packet-rdp_dr.c
Line | Count | Source |
1 | | /* packet-rdp_dr.c |
2 | | * Routines for the DR RDP channel |
3 | | * Copyright 2025, David Fort <contact@hardening-consulting.com> |
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-RDPEFS] " |
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/expert.h> |
22 | | |
23 | | #include "packet-rdp.h" |
24 | | #include "packet-rdpudp.h" |
25 | | #include "packet-dcerpc.h" |
26 | | #include "packet-dcerpc-rdpdr_smartcard.h" |
27 | | |
28 | | void proto_register_rdpdr(void); |
29 | | void proto_reg_handoff_rdpdr(void); |
30 | | |
31 | | static int proto_rdpdr; |
32 | | |
33 | | static int hf_rdpdr_component; |
34 | | static int hf_rdpdr_packetid; |
35 | | static int hf_rdpdr_deviceCount; |
36 | | static int hf_rdpdr_deviceType; |
37 | | static int hf_rdpdr_deviceId; |
38 | | static int hf_rdpdr_dosName; |
39 | | static int hf_rdpdr_deviceDataLen; |
40 | | static int hf_rdpdr_deviceData; |
41 | | static int hf_rdpdr_numCapabilities; |
42 | | static int hf_rdpdr_padding; |
43 | | static int hf_rdpdr_capaType; |
44 | | static int hf_rdpdr_capaLen; |
45 | | static int hf_rdpdr_capaVersion; |
46 | | static int hf_rdpdr_capa_gen_osType; |
47 | | static int hf_rdpdr_capa_gen_osVersion; |
48 | | static int hf_rdpdr_capa_gen_protocolMajor; |
49 | | static int hf_rdpdr_capa_gen_protocolMinor; |
50 | | static int hf_rdpdr_capa_gen_ioCode1; |
51 | | static int hf_rdpdr_capa_gen_ioCode2; |
52 | | static int hf_rdpdr_capa_gen_extendedPdu; |
53 | | static int hf_rdpdr_capa_gen_extraFlags1; |
54 | | static int hf_rdpdr_capa_gen_extraFlags2; |
55 | | static int hf_rdpdr_capa_gen_specialTypeDeviceCap; |
56 | | static int hf_rdpdr_fileId; |
57 | | static int hf_rdpdr_completionId; |
58 | | static int hf_rdpdr_ioreq_dr_majorFunction; |
59 | | static int hf_rdpdr_ioreq_dr_minorFunction; |
60 | | static int hf_rdpdr_ioreq_sc_majorFunction; |
61 | | static int hf_rdpdr_ioreq_sc_minorFunction; |
62 | | static int hf_rdpdr_ioreq_sc_command; |
63 | | static int hf_rdpdr_ioreq_sc_returnCode; |
64 | | static int hf_rdpdr_printer_cacheEvent; |
65 | | static int hf_rdpdr_pnpNameLength; |
66 | | static int hf_rdpdr_pnpName; |
67 | | static int hf_rdpdr_driverNameLength; |
68 | | static int hf_rdpdr_driverName; |
69 | | static int hf_rdpdr_printerNameLength; |
70 | | static int hf_rdpdr_printerName; |
71 | | static int hf_rdpdr_cachedFieldsLength; |
72 | | static int hf_rdpdr_cachedFields; |
73 | | static int hf_rdpdr_resultCode; |
74 | | static int hf_rdpdr_ioStatus; |
75 | | static int hf_rdpdr_io_request_control_outputBufLen; |
76 | | static int hf_rdpdr_io_request_control_inputBufLen; |
77 | | static int hf_rdpdr_io_request_control_ioControlCode; |
78 | | static int hf_rdpdr_io_request_control_padding; |
79 | | static int hf_rdpdr_io_request_frame; |
80 | | static int hf_rdpdr_io_result_frame; |
81 | | static int hf_rdpdr_create_info; |
82 | | static int hf_rdpdr_device_name; |
83 | | |
84 | | |
85 | | static int ett_rdpdr; |
86 | | static int ett_rdpdr_device; |
87 | | static int ett_rdpdr_capabilities; |
88 | | |
89 | | enum { |
90 | | RDPDR_CTYP_CORE = 0x4472, |
91 | | RDPDR_CTYP_PRN = 0x5052, |
92 | | }; |
93 | | |
94 | | enum { |
95 | | PAKID_CORE_SERVER_ANNOUNCE = 0x496E, |
96 | | PAKID_CORE_CLIENTID_CONFIRM = 0x4343, |
97 | | PAKID_CORE_CLIENT_NAME = 0x434E, |
98 | | PAKID_CORE_DEVICELIST_ANNOUNCE = 0x4441, |
99 | | PAKID_CORE_DEVICE_REPLY = 0x6472, |
100 | | PAKID_CORE_DEVICE_IOREQUEST = 0x4952, |
101 | | PAKID_CORE_DEVICE_IOCOMPLETION = 0x4943, |
102 | | PAKID_CORE_SERVER_CAPABILITY = 0x5350, |
103 | | PAKID_CORE_CLIENT_CAPABILITY = 0x4350, |
104 | | PAKID_CORE_DEVICELIST_REMOVE = 0x444D, |
105 | | PAKID_PRN_CACHE_DATA = 0x5043, |
106 | | PAKID_CORE_USER_LOGGEDON = 0x554C, |
107 | | PAKID_PRN_USING_XPS = 0x5543, |
108 | | }; |
109 | | |
110 | | enum { |
111 | | RDPDR_DTYP_SERIAL = 0x01, |
112 | | RDPDR_DTYP_PARALLEL = 0x02, |
113 | | RDPDR_DTYP_PRINT = 0x04, |
114 | | RDPDR_DTYP_FILESYSTEM = 0x08, |
115 | | RDPDR_DTYP_SMARTCARD = 0x20, |
116 | | }; |
117 | | |
118 | | enum { |
119 | | CAP_GENERAL_TYPE = 0x0001, |
120 | | CAP_PRINTER_TYPE = 0x0002, |
121 | | CAP_PORT_TYPE = 0x0003, |
122 | | CAP_DRIVE_TYPE = 0x0004, |
123 | | CAP_SMARTCARD_TYPE = 0x0005 |
124 | | }; |
125 | | |
126 | | static const value_string rdpdr_capaType_vals[] = { |
127 | | { CAP_GENERAL_TYPE, "General" }, |
128 | | { CAP_PRINTER_TYPE, "Printer" }, |
129 | | { CAP_PORT_TYPE, "Port" }, |
130 | | { CAP_DRIVE_TYPE, "Drive" }, |
131 | | { CAP_SMARTCARD_TYPE, "Smartcard" }, |
132 | | { 0x0, NULL}, |
133 | | }; |
134 | | |
135 | | enum { |
136 | | IRP_MJ_CREATE = 0x00000000, |
137 | | IRP_MJ_CLOSE = 0x00000002, |
138 | | IRP_MJ_READ = 0x00000003, |
139 | | IRP_MJ_WRITE = 0x00000004, |
140 | | IRP_MJ_DEVICE_CONTROL = 0x0000000E, |
141 | | IRP_MJ_QUERY_VOLUME_INFORMATION = 0x0000000A, |
142 | | IRP_MJ_SET_VOLUME_INFORMATION = 0x0000000B, |
143 | | IRP_MJ_QUERY_INFORMATION = 0x00000005, |
144 | | IRP_MJ_SET_INFORMATION = 0x00000006, |
145 | | IRP_MJ_DIRECTORY_CONTROL = 0x0000000C, |
146 | | IRP_MJ_LOCK_CONTROL = 0x00000011, |
147 | | |
148 | | IRP_MN_QUERY_DIRECTORY = 0x00000001, |
149 | | IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002, |
150 | | }; |
151 | | |
152 | | enum { |
153 | | FILE_SUPERSEDED = 0x00000000, |
154 | | FILE_OPENED = 0x00000001, |
155 | | FILE_OVERWRITTEN = 0x00000003, |
156 | | }; |
157 | | |
158 | | static const value_string rdpdr_component_vals[] = { |
159 | | { RDPDR_CTYP_CORE, "RDPDR_CTYP_CORE"}, |
160 | | { RDPDR_CTYP_PRN, "RDPDR_CTYP_PRN"}, |
161 | | { 0x0, NULL}, |
162 | | }; |
163 | | |
164 | | static const value_string rdpdr_packetid_vals[] = { |
165 | | { PAKID_CORE_SERVER_ANNOUNCE, "PAKID_CORE_SERVER_ANNOUNCE" }, |
166 | | { PAKID_CORE_CLIENTID_CONFIRM, "PAKID_CORE_CLIENTID_CONFIRM" }, |
167 | | { PAKID_CORE_CLIENT_NAME, "PAKID_CORE_CLIENT_NAME" }, |
168 | | { PAKID_CORE_DEVICELIST_ANNOUNCE, "PAKID_CORE_DEVICELIST_ANNOUNCE"}, |
169 | | { PAKID_CORE_DEVICE_REPLY, "PAKID_CORE_DEVICE_REPLY"}, |
170 | | { PAKID_CORE_DEVICE_IOREQUEST, "PAKID_CORE_DEVICE_IOREQUEST"}, |
171 | | { PAKID_CORE_DEVICE_IOCOMPLETION, "PAKID_CORE_DEVICE_IOCOMPLETION"}, |
172 | | { PAKID_CORE_SERVER_CAPABILITY, "PAKID_CORE_SERVER_CAPABILITY"}, |
173 | | { PAKID_CORE_CLIENT_CAPABILITY, "PAKID_CORE_CLIENT_CAPABILITY"}, |
174 | | { PAKID_CORE_DEVICELIST_REMOVE, "PAKID_CORE_DEVICELIST_REMOVE"}, |
175 | | { PAKID_PRN_CACHE_DATA, "PAKID_PRN_CACHE_DATA"}, |
176 | | { PAKID_CORE_USER_LOGGEDON, "PAKID_CORE_USER_LOGGEDON"}, |
177 | | { PAKID_PRN_USING_XPS, "PAKID_PRN_USING_XPS"}, |
178 | | { 0x0, NULL}, |
179 | | }; |
180 | | |
181 | | static const value_string rdpdr_deviceType_vals[] = { |
182 | | { RDPDR_DTYP_SERIAL, "RDPDR_DTYP_SERIAL"}, |
183 | | { RDPDR_DTYP_PARALLEL, "RDPDR_DTYP_PARALLEL"}, |
184 | | { RDPDR_DTYP_PRINT, "RDPDR_DTYP_PRINT"}, |
185 | | { RDPDR_DTYP_FILESYSTEM, "RDPDR_DTYP_FILESYSTEM"}, |
186 | | { RDPDR_DTYP_SMARTCARD, "RDPDR_DTYP_SMARTCARD"}, |
187 | | { 0x0, NULL}, |
188 | | }; |
189 | | |
190 | | static const value_string rdpdr_dr_majorF_vals[] = { |
191 | | { IRP_MJ_CREATE, "IRP_MJ_CREATE" }, |
192 | | { IRP_MJ_CLOSE, "IRP_MJ_CLOSE" }, |
193 | | { IRP_MJ_READ, "IRP_MJ_READ" }, |
194 | | { IRP_MJ_WRITE, "IRP_MJ_WRITE" }, |
195 | | { IRP_MJ_DEVICE_CONTROL, "IRP_MJ_DEVICE_CONTROL" }, |
196 | | { IRP_MJ_QUERY_VOLUME_INFORMATION, "IRP_MJ_QUERY_VOLUME_INFORMATION" }, |
197 | | { IRP_MJ_SET_VOLUME_INFORMATION, "IRP_MJ_SET_VOLUME_INFORMATION" }, |
198 | | { IRP_MJ_QUERY_INFORMATION, "IRP_MJ_QUERY_INFORMATION" }, |
199 | | { IRP_MJ_SET_INFORMATION, "IRP_MJ_SET_INFORMATION" }, |
200 | | { IRP_MJ_DIRECTORY_CONTROL, "IRP_MJ_DIRECTORY_CONTROL" }, |
201 | | { IRP_MJ_LOCK_CONTROL, "IRP_MJ_LOCK_CONTROL" }, |
202 | | { 0x0, NULL}, |
203 | | }; |
204 | | |
205 | | static const value_string rdpdr_dr_minorF_vals[] = { |
206 | | { IRP_MN_QUERY_DIRECTORY, "IRP_MN_QUERY_DIRECTORY" }, |
207 | | { IRP_MN_NOTIFY_CHANGE_DIRECTORY, "IRP_MN_NOTIFY_CHANGE_DIRECTORY" }, |
208 | | { 0x0, NULL}, |
209 | | }; |
210 | | |
211 | | static const value_string rdpdr_dr_createinfo_vals[] = { |
212 | | { FILE_SUPERSEDED, "FILE_SUPERSEDED" }, |
213 | | { FILE_OPENED, "FILE_OPENED" }, |
214 | | { FILE_OVERWRITTEN, "FILE_OVERWRITTEN" }, |
215 | | { 0x0, NULL}, |
216 | | }; |
217 | | |
218 | | enum { |
219 | | SCARD_IOCTL_ESTABLISHCONTEXT = 0x00090014, |
220 | | SCARD_IOCTL_RELEASECONTEXT = 0x00090018, |
221 | | SCARD_IOCTL_ISVALIDCONTEXT = 0x0009001C, |
222 | | SCARD_IOCTL_LISTREADERGROUPSA = 0x00090020, |
223 | | SCARD_IOCTL_LISTREADERGROUPSW = 0x00090024, |
224 | | SCARD_IOCTL_LISTREADERSA = 0x00090028, |
225 | | SCARD_IOCTL_LISTREADERSW = 0x0009002C, |
226 | | SCARD_IOCTL_INTRODUCEREADERGROUPA = 0x00090050, |
227 | | SCARD_IOCTL_INTRODUCEREADERGROUPW = 0x00090054, |
228 | | SCARD_IOCTL_FORGETREADERGROUPA = 0x00090058, |
229 | | SCARD_IOCTL_FORGETREADERGROUPW = 0x0009005C, |
230 | | SCARD_IOCTL_INTRODUCEREADERA = 0x00090060, |
231 | | SCARD_IOCTL_INTRODUCEREADERW = 0x00090064, |
232 | | SCARD_IOCTL_FORGETREADERA = 0x00090068, |
233 | | SCARD_IOCTL_FORGETREADERW = 0x0009006C, |
234 | | SCARD_IOCTL_ADDREADERTOGROUPA = 0x00090070, |
235 | | SCARD_IOCTL_ADDREADERTOGROUPW = 0x00090074, |
236 | | SCARD_IOCTL_REMOVEREADERFROMGROUPA = 0x00090078, |
237 | | SCARD_IOCTL_REMOVEREADERFROMGROUPW = 0x0009007C, |
238 | | SCARD_IOCTL_LOCATECARDSA = 0x00090098, |
239 | | SCARD_IOCTL_LOCATECARDSW = 0x0009009C, |
240 | | SCARD_IOCTL_GETSTATUSCHANGEA = 0x000900A0, |
241 | | SCARD_IOCTL_GETSTATUSCHANGEW = 0x000900A4, |
242 | | SCARD_IOCTL_CANCEL = 0x000900A8, |
243 | | SCARD_IOCTL_CONNECTA = 0x000900AC, |
244 | | SCARD_IOCTL_CONNECTW = 0x000900B0, |
245 | | SCARD_IOCTL_RECONNECT = 0x000900B4, |
246 | | SCARD_IOCTL_DISCONNECT = 0x000900B8, |
247 | | SCARD_IOCTL_BEGINTRANSACTION = 0x000900BC, |
248 | | SCARD_IOCTL_ENDTRANSACTION = 0x000900C0, |
249 | | SCARD_IOCTL_STATE = 0x000900C4, |
250 | | SCARD_IOCTL_STATUSA = 0x000900C8, |
251 | | SCARD_IOCTL_STATUSW = 0x000900CC, |
252 | | SCARD_IOCTL_TRANSMIT = 0x000900D0, |
253 | | SCARD_IOCTL_CONTROL = 0x000900D4, |
254 | | SCARD_IOCTL_GETATTRIB = 0x000900D8, |
255 | | SCARD_IOCTL_SETATTRIB = 0x000900DC, |
256 | | SCARD_IOCTL_ACCESSSTARTEDEVENT = 0x000900E0, |
257 | | SCARD_IOCTL_LOCATECARDSBYATRA = 0x000900E8, |
258 | | SCARD_IOCTL_LOCATECARDSBYATRW = 0x000900EC, |
259 | | SCARD_IOCTL_READCACHEA = 0x000900F0, |
260 | | SCARD_IOCTL_READCACHEW = 0x000900F4, |
261 | | SCARD_IOCTL_WRITECACHEA = 0x000900F8, |
262 | | SCARD_IOCTL_WRITECACHEW = 0x000900FC, |
263 | | SCARD_IOCTL_GETTRANSMITCOUNT = 0x00090100, |
264 | | SCARD_IOCTL_RELEASETARTEDEVENT = 0x000900E4, |
265 | | SCARD_IOCTL_GETREADERICON = 0x00090104, |
266 | | SCARD_IOCTL_GETDEVICETYPEID = 0x00090108, |
267 | | }; |
268 | | |
269 | | enum { |
270 | | RDPDR_ADD_PRINTER_EVENT = 0x00000001, |
271 | | RDPDR_UPDATE_PRINTER_EVENT = 0x00000002, |
272 | | RDPDR_DELETE_PRINTER_EVENT = 0x00000003, |
273 | | RDPDR_RENAME_PRINTER_EVENT = 0x00000004, |
274 | | }; |
275 | | |
276 | | #define STR_VALUE(v) { v, #v } |
277 | | static const value_string rdpdr_dr_ioControlCode_vals[] = { |
278 | | STR_VALUE(SCARD_IOCTL_ESTABLISHCONTEXT), |
279 | | STR_VALUE(SCARD_IOCTL_RELEASECONTEXT), |
280 | | STR_VALUE(SCARD_IOCTL_ISVALIDCONTEXT), |
281 | | STR_VALUE(SCARD_IOCTL_LISTREADERGROUPSA), |
282 | | STR_VALUE(SCARD_IOCTL_LISTREADERGROUPSW), |
283 | | STR_VALUE(SCARD_IOCTL_LISTREADERSA), |
284 | | STR_VALUE(SCARD_IOCTL_LISTREADERSW), |
285 | | STR_VALUE(SCARD_IOCTL_INTRODUCEREADERGROUPA), |
286 | | STR_VALUE(SCARD_IOCTL_INTRODUCEREADERGROUPW), |
287 | | STR_VALUE(SCARD_IOCTL_FORGETREADERGROUPA), |
288 | | STR_VALUE(SCARD_IOCTL_FORGETREADERGROUPW), |
289 | | STR_VALUE(SCARD_IOCTL_INTRODUCEREADERA), |
290 | | STR_VALUE(SCARD_IOCTL_INTRODUCEREADERW), |
291 | | STR_VALUE(SCARD_IOCTL_FORGETREADERA), |
292 | | STR_VALUE(SCARD_IOCTL_FORGETREADERW), |
293 | | STR_VALUE(SCARD_IOCTL_ADDREADERTOGROUPA), |
294 | | STR_VALUE(SCARD_IOCTL_ADDREADERTOGROUPW), |
295 | | STR_VALUE(SCARD_IOCTL_REMOVEREADERFROMGROUPA), |
296 | | STR_VALUE(SCARD_IOCTL_REMOVEREADERFROMGROUPW), |
297 | | STR_VALUE(SCARD_IOCTL_LOCATECARDSA), |
298 | | STR_VALUE(SCARD_IOCTL_LOCATECARDSW), |
299 | | STR_VALUE(SCARD_IOCTL_GETSTATUSCHANGEA), |
300 | | STR_VALUE(SCARD_IOCTL_GETSTATUSCHANGEW), |
301 | | STR_VALUE(SCARD_IOCTL_CANCEL), |
302 | | STR_VALUE(SCARD_IOCTL_CONNECTA), |
303 | | STR_VALUE(SCARD_IOCTL_CONNECTW), |
304 | | STR_VALUE(SCARD_IOCTL_RECONNECT), |
305 | | STR_VALUE(SCARD_IOCTL_DISCONNECT), |
306 | | STR_VALUE(SCARD_IOCTL_BEGINTRANSACTION), |
307 | | STR_VALUE(SCARD_IOCTL_ENDTRANSACTION), |
308 | | STR_VALUE(SCARD_IOCTL_STATE), |
309 | | STR_VALUE(SCARD_IOCTL_STATUSA), |
310 | | STR_VALUE(SCARD_IOCTL_STATUSW), |
311 | | STR_VALUE(SCARD_IOCTL_TRANSMIT), |
312 | | STR_VALUE(SCARD_IOCTL_CONTROL), |
313 | | STR_VALUE(SCARD_IOCTL_GETATTRIB), |
314 | | STR_VALUE(SCARD_IOCTL_SETATTRIB), |
315 | | STR_VALUE(SCARD_IOCTL_ACCESSSTARTEDEVENT), |
316 | | STR_VALUE(SCARD_IOCTL_LOCATECARDSBYATRA), |
317 | | STR_VALUE(SCARD_IOCTL_LOCATECARDSBYATRW), |
318 | | STR_VALUE(SCARD_IOCTL_READCACHEA), |
319 | | STR_VALUE(SCARD_IOCTL_READCACHEW), |
320 | | STR_VALUE(SCARD_IOCTL_WRITECACHEA), |
321 | | STR_VALUE(SCARD_IOCTL_WRITECACHEW), |
322 | | STR_VALUE(SCARD_IOCTL_GETTRANSMITCOUNT), |
323 | | STR_VALUE(SCARD_IOCTL_RELEASETARTEDEVENT), |
324 | | STR_VALUE(SCARD_IOCTL_GETREADERICON), |
325 | | STR_VALUE(SCARD_IOCTL_GETDEVICETYPEID), |
326 | | { 0x0, NULL}, |
327 | | }; |
328 | | |
329 | | static const value_string rdpdr_printer_cacheEvent_vals[] = { |
330 | | STR_VALUE(RDPDR_ADD_PRINTER_EVENT), |
331 | | STR_VALUE(RDPDR_UPDATE_PRINTER_EVENT), |
332 | | STR_VALUE(RDPDR_DELETE_PRINTER_EVENT), |
333 | | STR_VALUE(RDPDR_RENAME_PRINTER_EVENT), |
334 | | { 0x0, NULL}, |
335 | | }; |
336 | | |
337 | | #undef STR_VALUE |
338 | | |
339 | | typedef struct { |
340 | | uint32_t completionId; |
341 | | uint32_t reqFrame; |
342 | | uint32_t resFrame; |
343 | | uint32_t majorFn; |
344 | | uint32_t minorFn; |
345 | | uint32_t ioControlCode; |
346 | | } DrIoRequest; |
347 | | |
348 | | typedef struct { |
349 | | uint32_t deviceType; |
350 | | uint32_t deviceId; |
351 | | char name[9]; |
352 | | wmem_multimap_t *ioRequests; |
353 | | } DrDevice; |
354 | | |
355 | | typedef struct { |
356 | | wmem_multimap_t *channels; |
357 | | } rdpdr_conv_info_t; |
358 | | |
359 | 0 | static unsigned idptr_hashFunc(const void *key) { |
360 | 0 | uint32_t *intPtr = (uint32_t *)key; |
361 | |
|
362 | 0 | return *intPtr; |
363 | 0 | } |
364 | | |
365 | 0 | static gboolean idptr_equalFunc(const void *a, const void *b) { |
366 | 0 | uint32_t *aPtr = (uint32_t *)a; |
367 | 0 | uint32_t *bPtr = (uint32_t *)b; |
368 | |
|
369 | 0 | return (*aPtr == *bPtr); |
370 | 0 | } |
371 | | |
372 | | |
373 | | static rdpdr_conv_info_t * |
374 | | rdpdr_get_conversation_data(packet_info *pinfo) |
375 | 0 | { |
376 | 0 | conversation_t *conversation, *conversation_tcp; |
377 | 0 | rdpdr_conv_info_t *info; |
378 | |
|
379 | 0 | conversation = find_or_create_conversation(pinfo); |
380 | |
|
381 | 0 | info = (rdpdr_conv_info_t *)conversation_get_proto_data(conversation, proto_rdpdr); |
382 | 0 | if (!info) { |
383 | 0 | conversation_tcp = rdp_find_tcp_conversation_from_udp(conversation); |
384 | 0 | if (conversation_tcp) |
385 | 0 | info = (rdpdr_conv_info_t *)conversation_get_proto_data(conversation_tcp, proto_rdpdr); |
386 | 0 | } |
387 | |
|
388 | 0 | if (info == NULL) { |
389 | 0 | info = wmem_new0(wmem_file_scope(), rdpdr_conv_info_t); |
390 | 0 | info->channels = wmem_multimap_new(wmem_file_scope(), idptr_hashFunc, idptr_equalFunc); |
391 | 0 | conversation_add_proto_data(conversation, proto_rdpdr, info); |
392 | 0 | } |
393 | |
|
394 | 0 | return info; |
395 | 0 | } |
396 | | |
397 | | static int |
398 | | dissect_smartcard_req(tvbuff_t *in_tvb, int in_offset, packet_info *pinfo, proto_tree *tree, uint32_t ioControlCode) |
399 | 0 | { |
400 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s req", val_to_str_const(ioControlCode, rdpdr_dr_ioControlCode_vals, "<unknown>")); |
401 | 0 | if (ioControlCode == SCARD_IOCTL_ACCESSSTARTEDEVENT) |
402 | 0 | return in_offset + 4; |
403 | | |
404 | 0 | dcerpc_info di = { 0 }; |
405 | 0 | uint8_t drep[4] = { 0x10, 0x00, 0x00, 0x00}; |
406 | |
|
407 | 0 | dcerpc_call_value call_data = { 0 }; |
408 | 0 | di.conformant_run = 0; |
409 | 0 | di.call_data = &call_data; |
410 | 0 | init_ndr_pointer_list(&di); |
411 | |
|
412 | 0 | int offset = 16; |
413 | 0 | tvbuff_t *tvb = tvb_new_subset_remaining(in_tvb, in_offset); |
414 | |
|
415 | 0 | switch (ioControlCode) { |
416 | 0 | case SCARD_IOCTL_ESTABLISHCONTEXT: |
417 | 0 | offset = scard_pack_dissect_struct_EstablishContext_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
418 | 0 | break; |
419 | 0 | case SCARD_IOCTL_ISVALIDCONTEXT: |
420 | 0 | case SCARD_IOCTL_RELEASECONTEXT: |
421 | 0 | case SCARD_IOCTL_CANCEL: |
422 | 0 | offset = scard_pack_dissect_struct_Context_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
423 | 0 | break; |
424 | 0 | case SCARD_IOCTL_LISTREADERSA: |
425 | 0 | offset = scard_pack_dissect_struct_ListReadersA_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
426 | 0 | break; |
427 | 0 | case SCARD_IOCTL_LISTREADERSW: |
428 | 0 | offset = scard_pack_dissect_struct_ListReadersW_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
429 | 0 | break; |
430 | 0 | case SCARD_IOCTL_GETDEVICETYPEID: |
431 | 0 | offset = scard_pack_dissect_struct_GetDeviceTypeId_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
432 | 0 | break; |
433 | 0 | case SCARD_IOCTL_GETSTATUSCHANGEA: |
434 | 0 | offset = scard_pack_dissect_struct_GetStatusChangeA_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
435 | 0 | break; |
436 | 0 | case SCARD_IOCTL_GETSTATUSCHANGEW: |
437 | 0 | offset = scard_pack_dissect_struct_GetStatusChangeW_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
438 | 0 | break; |
439 | 0 | case SCARD_IOCTL_CONNECTA: |
440 | 0 | offset = scard_pack_dissect_struct_ConnectA_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
441 | 0 | break; |
442 | 0 | case SCARD_IOCTL_CONNECTW: |
443 | 0 | offset = scard_pack_dissect_struct_ConnectW_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
444 | 0 | break; |
445 | 0 | case SCARD_IOCTL_DISCONNECT: |
446 | 0 | case SCARD_IOCTL_BEGINTRANSACTION: |
447 | 0 | case SCARD_IOCTL_ENDTRANSACTION: |
448 | 0 | offset = scard_pack_dissect_struct_HCardAndDisposition_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
449 | 0 | break; |
450 | 0 | case SCARD_IOCTL_STATE: |
451 | 0 | offset = scard_pack_dissect_struct_State_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
452 | 0 | break; |
453 | 0 | case SCARD_IOCTL_STATUSA: |
454 | 0 | case SCARD_IOCTL_STATUSW: |
455 | 0 | offset = scard_pack_dissect_struct_Status_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
456 | 0 | break; |
457 | 0 | case SCARD_IOCTL_TRANSMIT: |
458 | 0 | offset = scard_pack_dissect_struct_Transmit_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
459 | 0 | break; |
460 | 0 | case SCARD_IOCTL_READCACHEA: |
461 | 0 | offset = scard_pack_dissect_struct_ReadCacheA_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
462 | 0 | break; |
463 | 0 | case SCARD_IOCTL_READCACHEW: |
464 | 0 | offset = scard_pack_dissect_struct_ReadCacheW_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
465 | 0 | break; |
466 | 0 | case SCARD_IOCTL_WRITECACHEA: |
467 | 0 | offset = scard_pack_dissect_struct_WriteCacheA_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
468 | 0 | break; |
469 | 0 | case SCARD_IOCTL_WRITECACHEW: |
470 | 0 | offset = scard_pack_dissect_struct_WriteCacheW_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
471 | 0 | break; |
472 | 0 | case SCARD_IOCTL_GETATTRIB: |
473 | 0 | offset = scard_pack_dissect_struct_GetAttrib_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
474 | 0 | break; |
475 | 0 | case SCARD_IOCTL_RECONNECT: |
476 | 0 | offset = scard_pack_dissect_struct_Reconnect_Call(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
477 | 0 | break; |
478 | 0 | default: |
479 | 0 | return in_offset; |
480 | 0 | } |
481 | 0 | return in_offset + dissect_deferred_pointers(pinfo, tvb, offset, &di, drep); |
482 | 0 | } |
483 | | |
484 | | static int |
485 | | dissect_smartcard_resp(tvbuff_t *in_tvb, int in_offset, packet_info *pinfo, proto_tree *tree, uint32_t ioControlCode) |
486 | 0 | { |
487 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s resp", val_to_str_const(ioControlCode, rdpdr_dr_ioControlCode_vals, "<unknown>")); |
488 | |
|
489 | 0 | dcerpc_info di = { 0 }; |
490 | 0 | uint8_t drep[4] = { 0x10, 0x00, 0x00, 0x00}; |
491 | |
|
492 | 0 | dcerpc_call_value call_data = { 0 }; |
493 | 0 | di.conformant_run = 0; |
494 | 0 | di.call_data = &call_data; |
495 | 0 | init_ndr_pointer_list(&di); |
496 | |
|
497 | 0 | int offset = 16; |
498 | 0 | proto_tree_add_item(tree, hf_rdpdr_ioreq_sc_returnCode, in_tvb, in_offset + 16, 4, ENC_LITTLE_ENDIAN); |
499 | 0 | offset += 4; |
500 | 0 | tvbuff_t *tvb = tvb_new_subset_remaining(in_tvb, in_offset); |
501 | |
|
502 | 0 | switch (ioControlCode) { |
503 | 0 | case SCARD_IOCTL_ESTABLISHCONTEXT: |
504 | 0 | offset = scard_pack_dissect_struct_EstablishContext_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
505 | 0 | break; |
506 | 0 | case SCARD_IOCTL_ACCESSSTARTEDEVENT: |
507 | 0 | case SCARD_IOCTL_ISVALIDCONTEXT: |
508 | 0 | case SCARD_IOCTL_RELEASECONTEXT: |
509 | 0 | case SCARD_IOCTL_DISCONNECT: |
510 | 0 | case SCARD_IOCTL_CANCEL: |
511 | 0 | case SCARD_IOCTL_BEGINTRANSACTION: |
512 | 0 | case SCARD_IOCTL_ENDTRANSACTION: |
513 | 0 | case SCARD_IOCTL_WRITECACHEA: |
514 | 0 | case SCARD_IOCTL_WRITECACHEW: |
515 | 0 | case SCARD_IOCTL_SETATTRIB: |
516 | 0 | case SCARD_IOCTL_INTRODUCEREADERGROUPA: |
517 | 0 | case SCARD_IOCTL_INTRODUCEREADERGROUPW: |
518 | 0 | case SCARD_IOCTL_FORGETREADERGROUPA: |
519 | 0 | case SCARD_IOCTL_FORGETREADERGROUPW: |
520 | 0 | case SCARD_IOCTL_INTRODUCEREADERA: |
521 | 0 | case SCARD_IOCTL_INTRODUCEREADERW: |
522 | 0 | case SCARD_IOCTL_FORGETREADERA: |
523 | 0 | case SCARD_IOCTL_FORGETREADERW: |
524 | 0 | case SCARD_IOCTL_ADDREADERTOGROUPA: |
525 | 0 | case SCARD_IOCTL_ADDREADERTOGROUPW: |
526 | 0 | case SCARD_IOCTL_REMOVEREADERFROMGROUPA: |
527 | 0 | case SCARD_IOCTL_REMOVEREADERFROMGROUPW: |
528 | 0 | offset = scard_pack_dissect_struct_long_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
529 | 0 | break; |
530 | 0 | case SCARD_IOCTL_LISTREADERSA: |
531 | 0 | case SCARD_IOCTL_LISTREADERSW: |
532 | 0 | offset = scard_pack_dissect_struct_ListReaders_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
533 | 0 | break; |
534 | 0 | case SCARD_IOCTL_GETDEVICETYPEID: |
535 | 0 | offset = scard_pack_dissect_struct_GetDeviceTypeId_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
536 | 0 | break; |
537 | 0 | case SCARD_IOCTL_GETSTATUSCHANGEA: |
538 | 0 | case SCARD_IOCTL_GETSTATUSCHANGEW: |
539 | 0 | offset = scard_pack_dissect_struct_GetStatusChange_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
540 | 0 | break; |
541 | 0 | case SCARD_IOCTL_CONNECTA: |
542 | 0 | case SCARD_IOCTL_CONNECTW: |
543 | 0 | offset = scard_pack_dissect_struct_Connect_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
544 | 0 | break; |
545 | 0 | case SCARD_IOCTL_RECONNECT: |
546 | 0 | offset = scard_pack_dissect_struct_Reconnect_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
547 | 0 | break; |
548 | 0 | case SCARD_IOCTL_STATUSA: |
549 | 0 | case SCARD_IOCTL_STATUSW: |
550 | 0 | offset = scard_pack_dissect_struct_Status_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
551 | 0 | break; |
552 | 0 | case SCARD_IOCTL_TRANSMIT: |
553 | 0 | offset = scard_pack_dissect_struct_Transmit_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
554 | 0 | break; |
555 | 0 | case SCARD_IOCTL_READCACHEA: |
556 | 0 | case SCARD_IOCTL_READCACHEW: |
557 | 0 | offset = scard_pack_dissect_struct_ReadCache_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
558 | 0 | break; |
559 | 0 | case SCARD_IOCTL_GETATTRIB: |
560 | 0 | offset = scard_pack_dissect_struct_GetAttrib_Return(tvb, offset, pinfo, tree, &di, drep, hf_rdpdr_ioreq_sc_command, 0); |
561 | 0 | break; |
562 | 0 | default: |
563 | 0 | return in_offset; |
564 | 0 | } |
565 | | |
566 | 0 | return in_offset + dissect_deferred_pointers(pinfo, tvb, offset, &di, drep); |
567 | 0 | } |
568 | | |
569 | | |
570 | | static int |
571 | | dissect_rdpdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree _U_, void *data _U_) |
572 | 0 | { |
573 | 0 | proto_item *item; |
574 | 0 | unsigned offset = 0; |
575 | 0 | proto_tree *tree; |
576 | | //bool packetToServer = rdp_isServerAddressTarget(pinfo); |
577 | |
|
578 | 0 | parent_tree = proto_tree_get_root(parent_tree); |
579 | 0 | item = proto_tree_add_item(parent_tree, proto_rdpdr, tvb, 0, -1, ENC_NA); |
580 | 0 | tree = proto_item_add_subtree(item, ett_rdpdr); |
581 | |
|
582 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDPDR"); |
583 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
584 | |
|
585 | 0 | uint32_t component, packetId; |
586 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_component, tvb, offset, 2, ENC_LITTLE_ENDIAN, &component); |
587 | 0 | offset += 2; |
588 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_packetid, tvb, offset, 2, ENC_LITTLE_ENDIAN, &packetId); |
589 | 0 | offset += 2; |
590 | |
|
591 | 0 | rdpdr_conv_info_t *info = rdpdr_get_conversation_data(pinfo); |
592 | 0 | uint32_t deviceId; |
593 | |
|
594 | 0 | if (component == RDPDR_CTYP_CORE) { |
595 | 0 | switch(packetId) { |
596 | 0 | case PAKID_CORE_SERVER_ANNOUNCE: |
597 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "Server announce"); |
598 | 0 | break; |
599 | 0 | case PAKID_CORE_DEVICELIST_ANNOUNCE: { |
600 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "Device list announce"); |
601 | 0 | uint32_t deviceCount; |
602 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_deviceCount, tvb, offset, 4, ENC_LITTLE_ENDIAN, &deviceCount); |
603 | 0 | offset += 4; |
604 | |
|
605 | 0 | for (uint32_t i = 0; i < deviceCount; i++) { |
606 | 0 | uint32_t deviceDataLen = tvb_get_uint32(tvb, offset + 16, ENC_LITTLE_ENDIAN); |
607 | 0 | char dosName[8]; |
608 | 0 | tvb_get_raw_bytes_as_string(tvb, offset + 8, dosName, 8); |
609 | |
|
610 | 0 | proto_tree *dev_tree = proto_tree_add_subtree(tree, tvb, offset, 16 + deviceDataLen, ett_rdpdr_device, NULL, dosName); |
611 | |
|
612 | 0 | uint32_t deviceType; |
613 | 0 | proto_tree_add_item_ret_uint(dev_tree, hf_rdpdr_deviceType, tvb, offset, 4, ENC_LITTLE_ENDIAN, &deviceType); |
614 | 0 | offset += 4; |
615 | 0 | proto_tree_add_item_ret_uint(dev_tree, hf_rdpdr_deviceId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &deviceId); |
616 | 0 | offset += 4; |
617 | 0 | proto_tree_add_item(dev_tree, hf_rdpdr_dosName, tvb, offset, 8, ENC_ASCII); |
618 | 0 | offset += 8; |
619 | 0 | proto_tree_add_item(dev_tree, hf_rdpdr_deviceDataLen, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
620 | 0 | offset += 4; |
621 | 0 | proto_tree_add_item(dev_tree, hf_rdpdr_deviceData, tvb, offset, deviceDataLen, ENC_NA); |
622 | 0 | offset += deviceDataLen; |
623 | |
|
624 | 0 | if (!PINFO_FD_VISITED(pinfo)) { |
625 | 0 | DrDevice *device = wmem_alloc(wmem_file_scope(), sizeof(*device)); |
626 | 0 | device->deviceId = deviceId; |
627 | 0 | device->deviceType = deviceType; |
628 | 0 | memcpy(device->name, dosName, 8); |
629 | 0 | device->name[8] = 0; |
630 | 0 | device->ioRequests = wmem_multimap_new(wmem_file_scope(), idptr_hashFunc, idptr_equalFunc); |
631 | |
|
632 | 0 | wmem_multimap_insert32(info->channels, &device->deviceId, pinfo->num, device); |
633 | 0 | } |
634 | 0 | } |
635 | 0 | break; |
636 | 0 | } |
637 | 0 | case PAKID_CORE_DEVICE_IOREQUEST: { |
638 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_deviceId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &deviceId); |
639 | 0 | offset += 4; |
640 | |
|
641 | 0 | DrDevice *device = wmem_multimap_lookup32_le(info->channels, &deviceId, pinfo->num); |
642 | |
|
643 | 0 | uint32_t dtype = RDPDR_DTYP_FILESYSTEM; |
644 | 0 | if (device) |
645 | 0 | dtype = device->deviceType; |
646 | |
|
647 | 0 | int majorFnIdx; |
648 | 0 | int minorFnIdx; |
649 | 0 | switch(dtype) { |
650 | 0 | case RDPDR_DTYP_SMARTCARD: |
651 | 0 | majorFnIdx = hf_rdpdr_ioreq_sc_majorFunction; |
652 | 0 | minorFnIdx = hf_rdpdr_ioreq_sc_minorFunction; |
653 | 0 | break; |
654 | 0 | case RDPDR_DTYP_FILESYSTEM: |
655 | 0 | default: |
656 | 0 | majorFnIdx = hf_rdpdr_ioreq_dr_majorFunction; |
657 | 0 | minorFnIdx = hf_rdpdr_ioreq_dr_minorFunction; |
658 | 0 | break; |
659 | 0 | } |
660 | | |
661 | 0 | uint32_t fileId, completionId; |
662 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_fileId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &fileId); |
663 | 0 | offset += 4; |
664 | |
|
665 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_completionId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &completionId); |
666 | 0 | offset += 4; |
667 | |
|
668 | 0 | uint32_t majorFn; |
669 | 0 | proto_tree_add_item_ret_uint(tree, majorFnIdx, tvb, offset, 4, ENC_LITTLE_ENDIAN, &majorFn); |
670 | 0 | offset += 4; |
671 | |
|
672 | 0 | uint32_t minorFn; |
673 | 0 | proto_tree_add_item_ret_uint(tree, minorFnIdx, tvb, offset, 4, ENC_LITTLE_ENDIAN, &minorFn); |
674 | 0 | offset += 4; |
675 | |
|
676 | 0 | DrIoRequest *ioReq = NULL; |
677 | 0 | if (!PINFO_FD_VISITED(pinfo)) { |
678 | 0 | if (device) { |
679 | 0 | ioReq = wmem_alloc(wmem_file_scope(), sizeof(*ioReq)); |
680 | |
|
681 | 0 | ioReq->completionId = completionId; |
682 | 0 | ioReq->majorFn = majorFn; |
683 | 0 | ioReq->minorFn = minorFn; |
684 | 0 | ioReq->reqFrame = pinfo->num; |
685 | 0 | ioReq->resFrame = 0; |
686 | |
|
687 | 0 | wmem_multimap_insert32(device->ioRequests, &ioReq->completionId, pinfo->num, ioReq); |
688 | 0 | } |
689 | 0 | } else { |
690 | 0 | if (device) |
691 | 0 | ioReq = wmem_multimap_lookup32_le(device->ioRequests, &completionId, pinfo->num); |
692 | 0 | } |
693 | |
|
694 | 0 | switch(majorFn) { |
695 | 0 | case IRP_MJ_CREATE: |
696 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_CREATE"); |
697 | 0 | break; |
698 | 0 | case IRP_MJ_CLOSE: |
699 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_CLOSE"); |
700 | 0 | break; |
701 | 0 | case IRP_MJ_READ: |
702 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_READ"); |
703 | 0 | break; |
704 | 0 | case IRP_MJ_WRITE: |
705 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_WRITE"); |
706 | 0 | break; |
707 | 0 | case IRP_MJ_DEVICE_CONTROL: { |
708 | 0 | uint32_t inputBufLen; |
709 | 0 | uint32_t ioControlCode; |
710 | | //col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_DEVICE_CONTROL"); |
711 | 0 | proto_tree_add_item(tree, hf_rdpdr_io_request_control_outputBufLen, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
712 | 0 | offset += 4; |
713 | |
|
714 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_io_request_control_inputBufLen, tvb, offset, 4, ENC_LITTLE_ENDIAN, &inputBufLen); |
715 | 0 | offset += 4; |
716 | |
|
717 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_io_request_control_ioControlCode, tvb, offset, 4, ENC_LITTLE_ENDIAN, &ioControlCode); |
718 | 0 | offset += 4; |
719 | |
|
720 | 0 | proto_tree_add_item(tree, hf_rdpdr_io_request_control_padding, tvb, offset, 20, ENC_NA); |
721 | 0 | offset += 20; |
722 | |
|
723 | 0 | if (!PINFO_FD_VISITED(pinfo) && ioReq) |
724 | 0 | ioReq->ioControlCode = ioControlCode; |
725 | |
|
726 | 0 | if (device && device->deviceType == RDPDR_DTYP_SMARTCARD) |
727 | 0 | dissect_smartcard_req(tvb, offset, pinfo, tree, ioControlCode); |
728 | 0 | break; |
729 | 0 | } |
730 | 0 | case IRP_MJ_QUERY_VOLUME_INFORMATION: |
731 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_QUERY_VOLUME_INFORMATION"); |
732 | 0 | break; |
733 | 0 | case IRP_MJ_SET_VOLUME_INFORMATION: |
734 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_SET_VOLUME_INFORMATION"); |
735 | 0 | break; |
736 | 0 | case IRP_MJ_QUERY_INFORMATION: |
737 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_QUERY_INFORMATION"); |
738 | 0 | break; |
739 | 0 | case IRP_MJ_SET_INFORMATION: |
740 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_SET_INFORMATION"); |
741 | 0 | break; |
742 | 0 | case IRP_MJ_DIRECTORY_CONTROL: |
743 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_DIRECTORY_CONTROL"); |
744 | 0 | break; |
745 | 0 | case IRP_MJ_LOCK_CONTROL: |
746 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS IRP_MJ_LOCK_CONTROL"); |
747 | 0 | break; |
748 | 0 | default: |
749 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "FS unhandled"); |
750 | 0 | break; |
751 | 0 | } |
752 | | |
753 | 0 | if (ioReq) { |
754 | 0 | if (ioReq->resFrame) { |
755 | 0 | proto_item_set_generated( |
756 | 0 | proto_tree_add_uint(tree, hf_rdpdr_io_result_frame, tvb, 0, 0, ioReq->resFrame) |
757 | 0 | ); |
758 | 0 | } |
759 | 0 | } |
760 | 0 | break; |
761 | 0 | } |
762 | 0 | case PAKID_CORE_DEVICE_REPLY: { |
763 | 0 | uint32_t statusCode; |
764 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_deviceId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &deviceId); |
765 | 0 | offset += 4; |
766 | |
|
767 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_resultCode, tvb, offset, 4, ENC_LITTLE_ENDIAN, &statusCode); |
768 | 0 | offset += 4; |
769 | |
|
770 | 0 | DrDevice *device = wmem_multimap_lookup32_le(info->channels, &deviceId, pinfo->num); |
771 | 0 | if (device) |
772 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s, status=0x%x", device->name, statusCode); |
773 | 0 | break; |
774 | 0 | } |
775 | 0 | case PAKID_CORE_DEVICE_IOCOMPLETION: { |
776 | 0 | uint32_t statusCode, completionId; |
777 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_deviceId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &deviceId); |
778 | 0 | offset += 4; |
779 | |
|
780 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_completionId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &completionId); |
781 | 0 | offset += 4; |
782 | |
|
783 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_ioStatus, tvb, offset, 4, ENC_LITTLE_ENDIAN, &statusCode); |
784 | 0 | offset += 4; |
785 | | |
786 | | //const char *name = NULL; |
787 | 0 | DrIoRequest *ioReq = NULL; |
788 | 0 | DrDevice *device = wmem_multimap_lookup32_le(info->channels, &deviceId, pinfo->num); |
789 | 0 | if (device) { |
790 | | //name = device->name; |
791 | 0 | ioReq = wmem_multimap_lookup32_le(device->ioRequests, &completionId, pinfo->num); |
792 | 0 | if (ioReq) { |
793 | 0 | if (!PINFO_FD_VISITED(pinfo)) |
794 | 0 | ioReq->resFrame = pinfo->num; |
795 | 0 | } |
796 | 0 | } |
797 | |
|
798 | 0 | if (ioReq) { |
799 | 0 | proto_item_set_generated( |
800 | 0 | proto_tree_add_uint(tree, hf_rdpdr_io_request_frame, tvb, 0, 0, ioReq->reqFrame) |
801 | 0 | ); |
802 | |
|
803 | 0 | if (device->deviceType == RDPDR_DTYP_FILESYSTEM) { |
804 | 0 | switch(ioReq->majorFn) { |
805 | 0 | case IRP_MJ_CREATE: |
806 | 0 | if (tvb_captured_length_remaining(tvb, offset)) { |
807 | 0 | proto_tree_add_item(tree, hf_rdpdr_create_info, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
808 | 0 | } |
809 | 0 | break; |
810 | 0 | } |
811 | 0 | } else if (device->deviceType == RDPDR_DTYP_SMARTCARD) { |
812 | 0 | if (ioReq->majorFn == IRP_MJ_DEVICE_CONTROL) |
813 | 0 | return dissect_smartcard_resp(tvb, offset, pinfo, tree, ioReq->ioControlCode); |
814 | 0 | } |
815 | 0 | } |
816 | | //col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s%sIO completion completionId=0x%x status=0x%x", name ? name : "", name ? " " : "", completionId, statusCode); |
817 | 0 | break; |
818 | 0 | } |
819 | | |
820 | 0 | case PAKID_CORE_CLIENT_CAPABILITY: |
821 | 0 | case PAKID_CORE_SERVER_CAPABILITY: { |
822 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s", val_to_str_const(packetId, rdpdr_packetid_vals, "<unknown command>")); |
823 | |
|
824 | 0 | uint32_t ncapa; |
825 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_numCapabilities, tvb, offset, 2, ENC_LITTLE_ENDIAN, &ncapa); |
826 | 0 | offset += 2; |
827 | |
|
828 | 0 | proto_tree_add_item(tree, hf_rdpdr_padding, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
829 | 0 | offset += 2; |
830 | | |
831 | |
|
832 | 0 | for (uint32_t i = 0; i < ncapa; i++) { |
833 | 0 | uint32_t capaType = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN); |
834 | 0 | uint32_t capaLen = tvb_get_uint16(tvb, offset + 2, ENC_LITTLE_ENDIAN); |
835 | | |
836 | |
|
837 | 0 | tvbuff_t *capaTvb = tvb_new_subset_length(tvb, offset, capaLen); |
838 | 0 | offset += capaLen; |
839 | |
|
840 | 0 | int subOffset = 0; |
841 | 0 | proto_tree *subtree = proto_tree_add_subtree(tree, capaTvb, 0, capaLen, ett_rdpdr_capabilities, NULL, val_to_str_const(capaType, rdpdr_capaType_vals, "<unknown>")); |
842 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capaType, capaTvb, subOffset, 2, ENC_LITTLE_ENDIAN); |
843 | 0 | subOffset += 2; |
844 | |
|
845 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capaLen, capaTvb, subOffset, 2, ENC_LITTLE_ENDIAN); |
846 | 0 | subOffset += 2; |
847 | |
|
848 | 0 | uint32_t capaVersion; |
849 | 0 | proto_tree_add_item_ret_uint(subtree, hf_rdpdr_capaVersion, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN, &capaVersion); |
850 | 0 | subOffset += 4; |
851 | |
|
852 | 0 | switch (capaType) { |
853 | 0 | case CAP_GENERAL_TYPE: |
854 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_osType, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
855 | 0 | subOffset += 4; |
856 | |
|
857 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_osVersion, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
858 | 0 | subOffset += 4; |
859 | |
|
860 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_protocolMajor, capaTvb, subOffset, 2, ENC_LITTLE_ENDIAN); |
861 | 0 | subOffset += 2; |
862 | |
|
863 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_protocolMinor, capaTvb, subOffset, 2, ENC_LITTLE_ENDIAN); |
864 | 0 | subOffset += 2; |
865 | |
|
866 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_ioCode1, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
867 | 0 | subOffset += 4; |
868 | |
|
869 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_ioCode2, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
870 | 0 | subOffset += 4; |
871 | |
|
872 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_extendedPdu, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
873 | 0 | subOffset += 4; |
874 | |
|
875 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_extraFlags1, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
876 | 0 | subOffset += 4; |
877 | |
|
878 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_extraFlags2, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
879 | 0 | subOffset += 4; |
880 | |
|
881 | 0 | if (capaVersion == 0x00000002) |
882 | 0 | proto_tree_add_item(subtree, hf_rdpdr_capa_gen_specialTypeDeviceCap, capaTvb, subOffset, 4, ENC_LITTLE_ENDIAN); |
883 | 0 | break; |
884 | | |
885 | 0 | case CAP_PRINTER_TYPE: |
886 | 0 | case CAP_SMARTCARD_TYPE: |
887 | 0 | case CAP_PORT_TYPE: |
888 | 0 | case CAP_DRIVE_TYPE: |
889 | 0 | break; |
890 | 0 | } |
891 | 0 | } |
892 | 0 | break; |
893 | 0 | } |
894 | 0 | default: |
895 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s", val_to_str_const(packetId, rdpdr_packetid_vals, "<unknown command>")); |
896 | 0 | break; |
897 | 0 | } |
898 | 0 | } else if (component == RDPDR_CTYP_PRN) { |
899 | 0 | switch (packetId) { |
900 | 0 | case PAKID_PRN_USING_XPS: { |
901 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_deviceId, tvb, offset, 4, ENC_LITTLE_ENDIAN, &deviceId); |
902 | 0 | offset += 4; |
903 | |
|
904 | 0 | DrDevice *device = wmem_multimap_lookup32_le(info->channels, &deviceId, pinfo->num); |
905 | 0 | if (device) { |
906 | 0 | proto_item_set_generated( |
907 | 0 | proto_tree_add_string(tree, hf_rdpdr_device_name, tvb, 0, 0, device->name) |
908 | 0 | ); |
909 | |
|
910 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "PAKID_PRN_USING_XPS %s", device->name); |
911 | 0 | } else { |
912 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ",", "PAKID_PRN_USING_XPS"); |
913 | 0 | } |
914 | 0 | break; |
915 | 0 | } |
916 | 0 | case PAKID_PRN_CACHE_DATA: { |
917 | 0 | uint32_t eventId; |
918 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_printer_cacheEvent, tvb, offset, 4, ENC_LITTLE_ENDIAN, &eventId); |
919 | 0 | offset += 4; |
920 | |
|
921 | 0 | col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s", val_to_str_const(eventId, rdpdr_printer_cacheEvent_vals, "<unknown command>")); |
922 | 0 | switch (eventId) { |
923 | 0 | case RDPDR_ADD_PRINTER_EVENT: { |
924 | 0 | uint32_t pnpNameLength, driveNameLength, printerNameLength, cachedFieldsLength; |
925 | |
|
926 | 0 | proto_tree_add_item(tree, hf_rdpdr_dosName, tvb, offset, 8, ENC_ASCII); |
927 | 0 | offset += 8; |
928 | |
|
929 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_pnpNameLength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &pnpNameLength); |
930 | 0 | offset += 4; |
931 | |
|
932 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_driverNameLength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &driveNameLength); |
933 | 0 | offset += 4; |
934 | |
|
935 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_printerNameLength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &printerNameLength); |
936 | 0 | offset += 4; |
937 | |
|
938 | 0 | proto_tree_add_item_ret_uint(tree, hf_rdpdr_cachedFieldsLength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &cachedFieldsLength); |
939 | 0 | offset += 4; |
940 | |
|
941 | 0 | proto_tree_add_item(tree, hf_rdpdr_pnpName, tvb, offset, pnpNameLength, ENC_UTF_16|ENC_LITTLE_ENDIAN); |
942 | 0 | offset += pnpNameLength; |
943 | |
|
944 | 0 | proto_tree_add_item(tree, hf_rdpdr_driverName, tvb, offset, driveNameLength, ENC_UTF_16|ENC_LITTLE_ENDIAN); |
945 | 0 | offset += driveNameLength; |
946 | |
|
947 | 0 | proto_tree_add_item(tree, hf_rdpdr_printerName, tvb, offset, printerNameLength, ENC_UTF_16|ENC_LITTLE_ENDIAN); |
948 | 0 | offset += printerNameLength; |
949 | |
|
950 | 0 | proto_tree_add_item(tree, hf_rdpdr_cachedFields, tvb, offset, cachedFieldsLength, ENC_NA); |
951 | 0 | break; |
952 | 0 | } |
953 | 0 | case RDPDR_UPDATE_PRINTER_EVENT: |
954 | 0 | break; |
955 | 0 | case RDPDR_DELETE_PRINTER_EVENT: |
956 | 0 | break; |
957 | 0 | case RDPDR_RENAME_PRINTER_EVENT: |
958 | 0 | break; |
959 | 0 | default: |
960 | 0 | break; |
961 | 0 | } |
962 | 0 | break; |
963 | 0 | } |
964 | 0 | default: |
965 | 0 | break; |
966 | 0 | } |
967 | |
|
968 | 0 | } |
969 | | |
970 | 0 | return offset; |
971 | 0 | } |
972 | | |
973 | | |
974 | 16 | void proto_register_rdpdr(void) { |
975 | 16 | static hf_register_info hf[] = { |
976 | 16 | { &hf_rdpdr_component, |
977 | 16 | { "Component", "rdpdr.component", |
978 | 16 | FT_UINT16, BASE_HEX, VALS(rdpdr_component_vals), 0x0, |
979 | 16 | NULL, HFILL } |
980 | 16 | }, |
981 | 16 | { &hf_rdpdr_packetid, |
982 | 16 | { "PacketId", "rdpdr.packetid", |
983 | 16 | FT_UINT16, BASE_HEX, VALS(rdpdr_packetid_vals), 0x0, |
984 | 16 | NULL, HFILL } |
985 | 16 | }, |
986 | 16 | { &hf_rdpdr_deviceCount, |
987 | 16 | { "Device count", "rdpdr.devicecount", |
988 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
989 | 16 | NULL, HFILL } |
990 | 16 | }, |
991 | 16 | { &hf_rdpdr_deviceType, |
992 | 16 | { "Device type", "rdpdr.devicetype", |
993 | 16 | FT_UINT32, BASE_HEX, VALS(rdpdr_deviceType_vals), 0x0, |
994 | 16 | NULL, HFILL } |
995 | 16 | }, |
996 | 16 | { &hf_rdpdr_deviceId, |
997 | 16 | { "Device id", "rdpdr.deviceid", |
998 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
999 | 16 | NULL, HFILL } |
1000 | 16 | }, |
1001 | 16 | { &hf_rdpdr_dosName, |
1002 | 16 | { "DOS name", "rdpdr.dosname", |
1003 | 16 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
1004 | 16 | NULL, HFILL } |
1005 | 16 | }, |
1006 | 16 | { &hf_rdpdr_deviceDataLen, |
1007 | 16 | { "Device data length", "rdpdr.devicedatalen", |
1008 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1009 | 16 | NULL, HFILL } |
1010 | 16 | }, |
1011 | 16 | { &hf_rdpdr_deviceData, |
1012 | 16 | { "Device data", "rdpdr.devicedata", |
1013 | 16 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1014 | 16 | NULL, HFILL } |
1015 | 16 | }, |
1016 | 16 | { &hf_rdpdr_fileId, |
1017 | 16 | { "File id", "rdpdr.fileid", |
1018 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1019 | 16 | NULL, HFILL } |
1020 | 16 | }, |
1021 | 16 | { &hf_rdpdr_completionId, |
1022 | 16 | { "Completion id", "rdpdr.completionid", |
1023 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1024 | 16 | NULL, HFILL } |
1025 | 16 | }, |
1026 | 16 | { &hf_rdpdr_ioreq_dr_majorFunction, |
1027 | 16 | { "Major function", "rdpdr.majorfunction", |
1028 | 16 | FT_UINT32, BASE_HEX, VALS(rdpdr_dr_majorF_vals), 0x0, |
1029 | 16 | NULL, HFILL } |
1030 | 16 | }, |
1031 | 16 | { &hf_rdpdr_ioreq_dr_minorFunction, |
1032 | 16 | { "Minor function", "rdpdr.minorfunction", |
1033 | 16 | FT_UINT32, BASE_HEX, VALS(rdpdr_dr_minorF_vals), 0x0, |
1034 | 16 | NULL, HFILL } |
1035 | 16 | }, |
1036 | 16 | { &hf_rdpdr_ioreq_sc_majorFunction, |
1037 | 16 | { "Major function", "rdpdr.majorfunction", |
1038 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1039 | 16 | NULL, HFILL } |
1040 | 16 | }, |
1041 | 16 | { &hf_rdpdr_ioreq_sc_minorFunction, |
1042 | 16 | { "Minor function", "rdpdr.minorfunction", |
1043 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1044 | 16 | NULL, HFILL } |
1045 | 16 | }, |
1046 | 16 | { &hf_rdpdr_resultCode, |
1047 | 16 | { "Result code", "rdpdr.resultcode", |
1048 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1049 | 16 | NULL, HFILL } |
1050 | 16 | }, |
1051 | 16 | { &hf_rdpdr_ioStatus, |
1052 | 16 | { "IoStatus", "rdpdr.iostatus", |
1053 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1054 | 16 | NULL, HFILL } |
1055 | 16 | }, |
1056 | 16 | { &hf_rdpdr_io_request_control_outputBufLen, |
1057 | 16 | { "OutputBufferLen", "rdpdr.outputbuflen", |
1058 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1059 | 16 | NULL, HFILL } |
1060 | 16 | }, |
1061 | 16 | { &hf_rdpdr_io_request_control_inputBufLen, |
1062 | 16 | { "InputBufferLen", "rdpdr.inputbuflen", |
1063 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1064 | 16 | NULL, HFILL } |
1065 | 16 | }, |
1066 | 16 | { &hf_rdpdr_io_request_control_ioControlCode, |
1067 | 16 | { "IoControlCode", "rdpdr.iocontrolcode", |
1068 | 16 | FT_UINT32, BASE_HEX, VALS(rdpdr_dr_ioControlCode_vals), 0x0, |
1069 | 16 | NULL, HFILL } |
1070 | 16 | }, |
1071 | 16 | { &hf_rdpdr_io_request_control_padding, |
1072 | 16 | { "Padding", "rdpdr.padding20", |
1073 | 16 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1074 | 16 | NULL, HFILL } |
1075 | 16 | }, |
1076 | 16 | { &hf_rdpdr_io_request_frame, |
1077 | 16 | { "Request in frame", "rdpdr.iorequestframe", |
1078 | 16 | FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0, |
1079 | 16 | NULL, HFILL } |
1080 | 16 | }, |
1081 | 16 | { &hf_rdpdr_io_result_frame, |
1082 | 16 | { "IO result in frame", "rdpdr.ioresultframe", |
1083 | 16 | FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0, |
1084 | 16 | NULL, HFILL } |
1085 | 16 | }, |
1086 | 16 | { &hf_rdpdr_create_info, |
1087 | 16 | { "Information", "rdpdr.dr.create.info", |
1088 | 16 | FT_UINT8, BASE_HEX, VALS(rdpdr_dr_createinfo_vals), 0x0, |
1089 | 16 | NULL, HFILL } |
1090 | 16 | }, |
1091 | 16 | { &hf_rdpdr_numCapabilities, |
1092 | 16 | { "numCapabilities", "rdpdr.numcapabilities", |
1093 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1094 | 16 | NULL, HFILL } |
1095 | 16 | }, |
1096 | 16 | { &hf_rdpdr_padding, |
1097 | 16 | { "Padding", "rdpdr.padding", |
1098 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1099 | 16 | NULL, HFILL } |
1100 | 16 | }, |
1101 | 16 | { &hf_rdpdr_capaType, |
1102 | 16 | { "Type", "rdpdr.capa.type", |
1103 | 16 | FT_UINT16, BASE_HEX, VALS(rdpdr_capaType_vals), 0x0, |
1104 | 16 | NULL, HFILL } |
1105 | 16 | }, |
1106 | 16 | { &hf_rdpdr_capaLen, |
1107 | 16 | { "Length", "rdpdr.capa.length", |
1108 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1109 | 16 | NULL, HFILL } |
1110 | 16 | }, |
1111 | 16 | { &hf_rdpdr_capaVersion, |
1112 | 16 | { "Version", "rdpdr.capa.version", |
1113 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1114 | 16 | NULL, HFILL } |
1115 | 16 | }, |
1116 | 16 | { &hf_rdpdr_capa_gen_osType, |
1117 | 16 | { "osType", "rdpdr.capa.gen.ostype", |
1118 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1119 | 16 | NULL, HFILL } |
1120 | 16 | }, |
1121 | 16 | { &hf_rdpdr_capa_gen_osVersion, |
1122 | 16 | { "osVersion", "rdpdr.capa.gen.osversion", |
1123 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1124 | 16 | NULL, HFILL } |
1125 | 16 | }, |
1126 | 16 | { &hf_rdpdr_capa_gen_protocolMajor, |
1127 | 16 | { "protocolMajorVersion", "rdpdr.capa.gen.protocolmajor", |
1128 | 16 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1129 | 16 | NULL, HFILL } |
1130 | 16 | }, |
1131 | 16 | { &hf_rdpdr_capa_gen_protocolMinor, |
1132 | 16 | { "protocolMinorVersion", "rdpdr.capa.gen.protocolminor", |
1133 | 16 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1134 | 16 | NULL, HFILL } |
1135 | 16 | }, |
1136 | 16 | { &hf_rdpdr_capa_gen_ioCode1, |
1137 | 16 | { "ioCode1", "rdpdr.capa.gen.iocode1", |
1138 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1139 | 16 | NULL, HFILL } |
1140 | 16 | }, |
1141 | 16 | { &hf_rdpdr_capa_gen_ioCode2, |
1142 | 16 | { "ioCode2", "rdpdr.capa.gen.iocode2", |
1143 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1144 | 16 | NULL, HFILL } |
1145 | 16 | }, |
1146 | 16 | { &hf_rdpdr_capa_gen_extendedPdu, |
1147 | 16 | { "extendedPDU", "rdpdr.capa.gen.extendedpdu", |
1148 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1149 | 16 | NULL, HFILL } |
1150 | 16 | }, |
1151 | 16 | { &hf_rdpdr_capa_gen_extraFlags1, |
1152 | 16 | { "extraFlags1", "rdpdr.capa.gen.extraflags1", |
1153 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1154 | 16 | NULL, HFILL } |
1155 | 16 | }, |
1156 | 16 | { &hf_rdpdr_capa_gen_extraFlags2, |
1157 | 16 | { "extraFlags2", "rdpdr.capa.gen.extraflags2", |
1158 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1159 | 16 | NULL, HFILL } |
1160 | 16 | }, |
1161 | 16 | { &hf_rdpdr_capa_gen_specialTypeDeviceCap, |
1162 | 16 | { "specialTypeDeviceCap", "rdpdr.capa.gen.specialtypedevicecap", |
1163 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1164 | 16 | NULL, HFILL } |
1165 | 16 | }, |
1166 | 16 | { &hf_rdpdr_ioreq_sc_command, |
1167 | 16 | { "Command", "rdpdr.sc.command", |
1168 | 16 | FT_BYTES, BASE_NONE, NULL, 0, |
1169 | 16 | NULL, HFILL } |
1170 | 16 | }, |
1171 | 16 | { &hf_rdpdr_ioreq_sc_returnCode, |
1172 | 16 | { "ReturnCode", "rdpdr.sc.returnCode", |
1173 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1174 | 16 | NULL, HFILL } |
1175 | 16 | }, |
1176 | | |
1177 | 16 | { &hf_rdpdr_device_name, |
1178 | 16 | { "Device", "rdpdr.device", |
1179 | 16 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
1180 | 16 | NULL, HFILL } |
1181 | 16 | }, |
1182 | 16 | { &hf_rdpdr_printer_cacheEvent, |
1183 | 16 | { "EventId", "rdpdr.printer.eventid", |
1184 | 16 | FT_UINT32, BASE_HEX, VALS(rdpdr_printer_cacheEvent_vals), 0x0, |
1185 | 16 | NULL, HFILL } |
1186 | 16 | }, |
1187 | 16 | { &hf_rdpdr_pnpNameLength, |
1188 | 16 | { "PnPNameLen", "rdpdr.printer.pnpnamelen", |
1189 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1190 | 16 | NULL, HFILL } |
1191 | 16 | }, |
1192 | 16 | { &hf_rdpdr_pnpName, |
1193 | 16 | { "PnPName", "rdpdr.printer.pnpname", |
1194 | 16 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
1195 | 16 | NULL, HFILL } |
1196 | 16 | }, |
1197 | 16 | { &hf_rdpdr_driverNameLength, |
1198 | 16 | { "DriverNameLen", "rdpdr.printer.drivernamelen", |
1199 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1200 | 16 | NULL, HFILL } |
1201 | 16 | }, |
1202 | 16 | { &hf_rdpdr_driverName, |
1203 | 16 | { "DriverName", "rdpdr.printer.drivername", |
1204 | 16 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
1205 | 16 | NULL, HFILL } |
1206 | 16 | }, |
1207 | 16 | { &hf_rdpdr_printerNameLength, |
1208 | 16 | { "PrintNameLen", "rdpdr.printer.printnamelen", |
1209 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1210 | 16 | NULL, HFILL } |
1211 | 16 | }, |
1212 | 16 | { &hf_rdpdr_printerName, |
1213 | 16 | { "PrinterName", "rdpdr.printer.printername", |
1214 | 16 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
1215 | 16 | NULL, HFILL } |
1216 | 16 | }, |
1217 | 16 | { &hf_rdpdr_cachedFieldsLength, |
1218 | 16 | { "CacheFieldsLen", "rdpdr.printer.cachefieldslen", |
1219 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1220 | 16 | NULL, HFILL } |
1221 | 16 | }, |
1222 | 16 | { &hf_rdpdr_cachedFields, |
1223 | 16 | { "CacheFields", "rdpdr.printer.cachefields", |
1224 | 16 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1225 | 16 | NULL, HFILL } |
1226 | 16 | }, |
1227 | 16 | }; |
1228 | | |
1229 | 16 | static int *ett[] = { |
1230 | 16 | &ett_rdpdr, |
1231 | 16 | &ett_rdpdr_device, |
1232 | 16 | &ett_rdpdr_capabilities, |
1233 | 16 | }; |
1234 | | |
1235 | 16 | proto_rdpdr = proto_register_protocol("RDP disk redirection virtual channel Protocol", "RDPDR", "rdpdr"); |
1236 | | |
1237 | | /* Register fields and subtrees */ |
1238 | 16 | proto_register_field_array(proto_rdpdr, hf, array_length(hf)); |
1239 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
1240 | | |
1241 | 16 | register_dissector("rdpdr", dissect_rdpdr, proto_rdpdr); |
1242 | 16 | } |
1243 | | |
1244 | 16 | void proto_reg_handoff_rdpdr(void) { |
1245 | 16 | } |