1 /* packet-rsvd.c
2 * Routines for RSVD dissection
3 * Copyright 2015, Richard Sharpe <realrichardsharpe@gmail.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 * RSVD, documented in [MS-RSVD].pdf, by Microsoft, the Remote Shared Virtual
14 * Disk protocol.
15 */
16
17 #include "config.h"
18
19 #include <epan/conversation.h>
20 #include <epan/packet.h>
21 #if 0
22 #include "packet-smb-common.h"
23 #endif
24 #include "packet-windows-common.h"
25 #include "packet-scsi.h"
26
27 void proto_register_rsvd(void);
28
29 static int proto_rsvd = -1;
30 static int hf_svhdx_protocol_id = -1;
31 static int hf_svhdx_protocol_version = -1;
32 static int hf_svhdx_operation_code = -1;
33 static int hf_svhdx_status = -1;
34 static int hf_svhdx_request_id = -1;
35 static int hf_svhdx_tunnel_scsi_length = -1;
36 static int hf_svhdx_tunnel_scsi_reserved1 = -1;
37 static int hf_svhdx_tunnel_scsi_cdb_length = -1;
38 static int hf_svhdx_tunnel_scsi_sense_info_ex_length = -1;
39 static int hf_svhdx_tunnel_scsi_data_in = -1;
40 static int hf_svhdx_tunnel_scsi_reserved2 = -1;
41 static int hf_svhdx_tunnel_scsi_srb_flags = -1;
42 static int hf_svhdx_tunnel_scsi_data_transfer_length = -1;
43 static int hf_svhdx_tunnel_scsi_reserved3 = -1;
44 static int hf_svhdx_tunnel_scsi_cdb = -1;
45 static int hf_svhdx_tunnel_scsi_cdb_padding = -1;
46 static int hf_svhdx_tunnel_scsi_data = -1;
47 static int hf_svhdx_tunnel_scsi_auto_generated_sense = -1;
48 static int hf_svhdx_tunnel_scsi_srb_status = -1;
49 static int hf_svhdx_tunnel_scsi_sense_data_ex = -1;
50 static int hf_svhdx_tunnel_scsi_status = -1;
51 static int hf_svhdx_tunnel_file_info_server_version = -1;
52 static int hf_svhdx_tunnel_file_info_sector_size = -1;
53 static int hf_svhdx_tunnel_file_info_physical_sector_size = -1;
54 static int hf_svhdx_tunnel_file_info_reserved = -1;
55 static int hf_svhdx_tunnel_file_info_virtual_size = -1;
56 static int hf_svhdx_tunnel_disk_info_reserved1 = -1;
57 static int hf_svhdx_tunnel_disk_info_blocksize = -1;
58 static int hf_svhdx_tunnel_disk_info_linkage_id = -1;
59 static int hf_svhdx_tunnel_disk_info_disk_type = -1;
60 static int hf_svhdx_tunnel_disk_info_disk_format = -1;
61 static int hf_svhdx_tunnel_disk_info_is_mounted = -1;
62 static int hf_svhdx_tunnel_disk_info_is_4k_aligned = -1;
63 static int hf_svhdx_tunnel_disk_info_reserved = -1;
64 static int hf_svhdx_tunnel_disk_info_file_size = -1;
65 static int hf_svhdx_tunnel_disk_info_virtual_disk_id = -1;
66 static int hf_svhdx_tunnel_validate_disk_reserved = -1;
67 static int hf_svhdx_tunnel_validate_disk_is_valid_disk = -1;
68 static int hf_svhdx_tunnel_srb_status_status_key = -1;
69 static int hf_svhdx_tunnel_srb_status_reserved = -1;
70 static int hf_svhdx_tunnel_srb_status_sense_info_auto_generated = -1;
71 static int hf_svhdx_tunnel_srb_status_srb_status = -1;
72 static int hf_svhdx_tunnel_srb_status_scsi_status = -1;
73 static int hf_svhdx_tunnel_srb_status_sense_info_ex_length = -1;
74 static int hf_svhdx_tunnel_srb_status_sense_data_ex = -1;
75 static int hf_svhdx_tunnel_safe_virtual_size = -1;
76 static int hf_svhdx_tunnel_transaction_id = -1;
77 static int hf_svhdx_tunnel_meta_operation_type = -1;
78 static int hf_svhdx_tunnel_padding = -1;
79 static int hf_svhdx_tunnel_resize_new_size = -1;
80 static int hf_svhdx_tunnel_resize_expand_only_flag = -1;
81 static int hf_svhdx_tunnel_resize_allow_unsafe_virt_size_flag = -1;
82 static int hf_svhdx_tunnel_resize_shrink_to_minimum_safe_size_flag = -1;
83 static int hf_svhdx_tunnel_meta_operation_start_reserved = -1;
84 static int hf_svhdx_tunnel_snapshot_type = -1;
85 static int hf_svhdx_tunnel_snapshot_id = -1;
86 static int hf_svhdx_tunnel_create_snapshot_flags = -1;
87 static int hf_svhdx_tunnel_create_snapshot_flag_enable_change_tracking = -1;
88 static int hf_svhdx_tunnel_create_snapshot_stage1 = -1;
89 static int hf_svhdx_tunnel_create_snapshot_stage2 = -1;
90 static int hf_svhdx_tunnel_create_snapshot_stage3 = -1;
91 static int hf_svhdx_tunnel_create_snapshot_stage4 = -1;
92 static int hf_svhdx_tunnel_create_snapshot_stage5 = -1;
93 static int hf_svhdx_tunnel_create_snapshot_stage6 = -1;
94 static int hf_svhdx_tunnel_create_snapshot_parameters_payload_size = -1;
95 static int hf_svhdx_tunnel_convert_dst_vhdset_name_len = -1;
96 static int hf_svhdx_tunnel_convert_dst_vhdset_name = -1;
97 static int hf_svhdx_tunnel_delete_snapshot_persist_reference = -1;
98 static int hf_svhdx_tunnel_meta_op_query_progress_current_progress = -1;
99 static int hf_svhdx_tunnel_meta_op_query_progress_complete_value = -1;
100 static int hf_svhdx_tunnel_vhdset_information_type = -1;
101 static int hf_svhdx_tunnel_vhdset_snapshot_creation_time = -1;
102 static int hf_svhdx_tunnel_vhdset_is_valid_snapshot = -1;
103 static int hf_svhdx_tunnel_vhdset_parent_snapshot_id = -1;
104 static int hf_svhdx_tunnel_vhdset_log_file_id = -1;
105
106 static gint ett_rsvd = -1;
107 static gint ett_svhdx_tunnel_op_header = -1;
108 static gint ett_svhdx_tunnel_scsi_request = -1;
109 static gint ett_rsvd_create_snapshot_flags = -1;
110
111 static const value_string rsvd_operation_code_vals[] = {
112 { 0x02001001, "RSVD_TUNNEL_GET_INITIAL_INFO" },
113 { 0x02001002, "RSVD_TUNNEL_SCSI" },
114 { 0x02001003, "RSVD_TUNNEL_CHECK_CONNECTION_STATUS" },
115 { 0x02001004, "RSVD_TUNNEL_SRB_STATUS" },
116 { 0x02001005, "RSVD_TUNNEL_GET_DISK_INFO" },
117 { 0x02001006, "RSVD_TUNNEL_VALIDATE_DISK" },
118 { 0x02002101, "RSVD_TUNNEL_META_OPERATION_START" },
119 { 0x02002002, "RSVD_TUNNEL_META_OPERATION_QUERY_PROGRESS" },
120 { 0x02002005, "RSVD_TUNNEL_VHDSET_QUERY_INFORMATION" },
121 { 0x02002006, "RSVD_TUNNEL_DELETE_SNAPSHOT" },
122 { 0x02002008, "RSVD_TUNNEL_CHANGE_TRACKING_GET_PARAMETERS" },
123 { 0x02002009, "RSVD_TUNNEL_CHANGE_TRACKING_START" },
124 { 0x0200200A, "RSVD_TUNNEL_CHANGE_TRACKING_STOP" },
125 { 0x0200200C, "RSVD_TUNNEL_QUERY_VIRTUAL_DISK_CHANGES" },
126 { 0x0200200D, "RSVD_TUNNEL_QUERY_SAFE_SIZE" },
127 { 0, NULL }
128 };
129
130 static const value_string rsvd_sense_info_vals[] = {
131 { 0x0, "Sense Info Not Auto Generated" },
132 { 0x1, "Sense Info Auto Generated" },
133 { 0, NULL }
134 };
135
136 static const value_string rsvd_disk_type_vals[] = {
137 { 0x02, "VHD_TYPE_FIXED" },
138 { 0x03, "VHD_TYPE_DYNAMIC" },
139 { 0, NULL }
140 };
141
142 static const value_string rsvd_disk_format_vals[] = {
143 { 0x03, "VIRTUAL_STORAGE_TYPE_DEVICE_VHDX" },
144 { 0x04, "VIRTUAL_STORAGE_TYPE_DEVICE_VHDSET" },
145 { 0, NULL }
146 };
147
148 /*
149 * We need this data to handle SCSI requests and responses, I think
150 */
151 typedef struct _rsvd_task_data_t {
152 guint32 request_frame;
153 guint32 response_frame;
154 itlq_nexus_t *itlq;
155 } rsvd_task_data_t;
156
157 typedef struct _rsvd_conv_data_t {
158 wmem_map_t *tasks;
159 wmem_tree_t *itl;
160 rsvd_task_data_t *task;
161 conversation_t *conversation;
162 } rsvd_conv_data_t;
163
164 static rsvd_conv_data_t *rsvd_conv_data = NULL;
165
166 static proto_tree *top_tree = NULL;
167
168 static itl_nexus_t *
get_itl_nexus(packet_info * pinfo)169 get_itl_nexus(packet_info *pinfo)
170 {
171 itl_nexus_t *itl = NULL;
172
173 if (!(itl = (itl_nexus_t *)wmem_tree_lookup32_le(rsvd_conv_data->itl, pinfo->num))) {
174 itl = wmem_new(wmem_file_scope(), itl_nexus_t);
175 itl->cmdset = 0xff;
176 itl->conversation = rsvd_conv_data->conversation;
177 wmem_tree_insert32(rsvd_conv_data->itl, pinfo->num, itl);
178 }
179
180 return itl;
181 }
182
183 static int
dissect_RSVD_GET_INITIAL_INFO(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)184 dissect_RSVD_GET_INITIAL_INFO(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
185 {
186 proto_tree *gfi_sub_tree;
187 proto_item *gfi_sub_item;
188
189 if (!request) {
190 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_GET_INITIAL_INFO_RESPONSE");
191
192 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_file_info_server_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
193 offset += 4;
194
195 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_file_info_sector_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
196 offset += 4;
197
198 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_file_info_physical_sector_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
199 offset += 4;
200
201 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_file_info_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
202 offset += 4;
203
204 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_file_info_virtual_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
205 offset += 8;
206 }
207
208 return offset;
209 }
210
211 static const value_string rsvd_data_in_vals[] = {
212 { 0x00, "Client is requesting data from the server" },
213 { 0x01, "Client is sending data to the server" },
214 { 0x02, "Client is neither sending nor requesting an additional data buffer" },
215 { 0, NULL }
216 };
217
218 static void
dissect_scsi_payload_databuffer(tvbuff_t * tvb,packet_info * pinfo,int offset,guint32 data_transfer_length,gboolean request)219 dissect_scsi_payload_databuffer(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 data_transfer_length, gboolean request)
220 {
221 tvbuff_t *data_tvb = NULL;
222 int tvb_len, tvb_rlen;
223
224 tvb_len = tvb_captured_length_remaining(tvb, offset);
225 if (tvb_len > (int)data_transfer_length)
226 tvb_len = data_transfer_length;
227
228 tvb_rlen = tvb_reported_length_remaining(tvb, offset);
229 if (tvb_rlen > (int)data_transfer_length)
230 tvb_rlen = data_transfer_length;
231
232 data_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_len, tvb_rlen);
233
234 if (rsvd_conv_data->task && rsvd_conv_data->task->itlq) {
235 rsvd_conv_data->task->itlq->task_flags = SCSI_DATA_READ |
236 SCSI_DATA_WRITE;
237 rsvd_conv_data->task->itlq->data_length = data_transfer_length;
238 rsvd_conv_data->task->itlq->bidir_data_length = data_transfer_length;
239 dissect_scsi_payload(data_tvb, pinfo, top_tree, request,
240 rsvd_conv_data->task->itlq,
241 get_itl_nexus(pinfo), 0);
242 }
243 }
244
245 /*
246 * Dissect a tunnelled SCSI request and call the SCSI dissector where
247 * needed.
248 */
249 static int
dissect_RSVD_TUNNEL_SCSI(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,gint16 len,gboolean request,guint64 request_id)250 dissect_RSVD_TUNNEL_SCSI(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, gint16 len, gboolean request, guint64 request_id)
251 {
252 proto_tree *sub_tree;
253 proto_item *sub_item;
254 guint32 cdb_length;
255 guint8 data_in;
256 guint32 data_transfer_length;
257 guint32 sense_info_ex_length;
258 conversation_t *conversation;
259
260 conversation = find_or_create_conversation(pinfo);
261 rsvd_conv_data = (rsvd_conv_data_t *)conversation_get_proto_data(conversation, proto_rsvd);
262
263 if (!rsvd_conv_data) {
264 rsvd_conv_data = wmem_new(wmem_file_scope(), rsvd_conv_data_t);
265 rsvd_conv_data->tasks = wmem_map_new(wmem_file_scope(),
266 wmem_int64_hash,
267 g_int64_equal);
268 rsvd_conv_data->itl = wmem_tree_new(wmem_file_scope());
269 rsvd_conv_data->conversation = conversation;
270 conversation_add_proto_data(conversation, proto_rsvd, rsvd_conv_data);
271 }
272
273 rsvd_conv_data->task = NULL;
274 if (!pinfo->fd->visited) {
275 guint64 *key_copy = wmem_new(wmem_file_scope(), guint64);
276
277 *key_copy = request_id;
278 rsvd_conv_data->task = wmem_new(wmem_file_scope(), rsvd_task_data_t);
279 rsvd_conv_data->task->request_frame=pinfo->num;
280 rsvd_conv_data->task->response_frame=0;
281 rsvd_conv_data->task->itlq = NULL;
282 wmem_map_insert(rsvd_conv_data->tasks, (const void *)key_copy,
283 rsvd_conv_data->task);
284 } else {
285 rsvd_conv_data->task = (rsvd_task_data_t *)wmem_map_lookup(rsvd_conv_data->tasks, (const void *)&request_id);
286 }
287
288 sub_tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, len, ett_svhdx_tunnel_scsi_request, &sub_item, "SVHDX_TUNNEL_SCSI_%s", (request ? "REQUEST" : "RESPONSE"));
289
290 if (request) {
291 tvbuff_t *scsi_cdb = NULL;
292
293 /* Length */
294 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
295 offset += 2;
296
297 /* Reserved1 */
298 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_reserved1, tvb, offset, 2, ENC_LITTLE_ENDIAN);
299 offset += 2;
300
301 /* CDBLength */
302 cdb_length = tvb_get_guint8(tvb, offset);
303 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_cdb_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
304 offset++;
305
306 /* SensInfoExLength */
307 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_sense_info_ex_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
308 offset++;
309
310 /* DataIn */
311 data_in = tvb_get_guint8(tvb, offset);
312 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_data_in, tvb, offset, 1, ENC_LITTLE_ENDIAN);
313 offset++;
314
315 /* Reserved2 */
316 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_reserved2, tvb, offset, 1, ENC_LITTLE_ENDIAN);
317 offset++;
318
319 /* SrbFlags */
320 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_srb_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
321 offset += 4;
322
323 /* DataTransferLength */
324 data_transfer_length = tvb_get_letohl(tvb, offset);
325 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_data_transfer_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
326 offset += 4;
327
328 /* CDBBuffer */
329 scsi_cdb = tvb_new_subset_length_caplen(tvb,
330 offset,
331 cdb_length,
332 tvb_reported_length_remaining(tvb, offset));
333 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_cdb, tvb, offset, cdb_length, ENC_NA);
334 offset += cdb_length;
335 if (cdb_length < 16) {
336 /*
337 * CDBBuffer is always 16 bytes - see MS-RSVD section 2.2.4.7
338 * "SVHDX_TUNNEL_SCSI_REQUEST Structure":
339 *
340 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rsvd/e8bcb003-97b3-41ef-9689-cd2d1668a9cc
341 *
342 * If CDB is actually smaller, we need to define padding bytes
343 */
344 guint32 cdb_padding_length = 16 - cdb_length;
345 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_cdb_padding, tvb, offset, cdb_padding_length, ENC_NA);
346 offset += cdb_padding_length;
347 }
348
349 /* Reserved3 */
350 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_reserved3, tvb, offset, 4, ENC_LITTLE_ENDIAN);
351 offset += 4;
352
353 /* DataBuffer */
354 if (data_transfer_length) {
355 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_data, tvb, offset, data_transfer_length, ENC_NA);
356 }
357
358 /*
359 * Now the SCSI Request
360 */
361 if (rsvd_conv_data->task && !rsvd_conv_data->task->itlq) {
362 rsvd_conv_data->task->itlq = wmem_new(wmem_file_scope(),
363 itlq_nexus_t);
364 rsvd_conv_data->task->itlq->first_exchange_frame = pinfo->num;
365 rsvd_conv_data->task->itlq->last_exchange_frame = 0;
366 rsvd_conv_data->task->itlq->lun = 0xffff;
367 rsvd_conv_data->task->itlq->scsi_opcode = 0xffff;
368 rsvd_conv_data->task->itlq->task_flags = 0;
369 rsvd_conv_data->task->itlq->data_length = 0;
370 rsvd_conv_data->task->itlq->bidir_data_length = 0;
371 rsvd_conv_data->task->itlq->flags = 0;
372 rsvd_conv_data->task->itlq->alloc_len = 0;
373 rsvd_conv_data->task->itlq->fc_time = pinfo->abs_ts;
374 rsvd_conv_data->task->itlq->extra_data = NULL;
375 }
376
377 if (rsvd_conv_data->task && rsvd_conv_data->task->itlq) {
378 dissect_scsi_cdb(scsi_cdb, pinfo, top_tree, SCSI_DEV_SMC, rsvd_conv_data->task->itlq, get_itl_nexus(pinfo));
379 if (data_in == 0) { /* Only OUT operations have meaningful SCSI payload in request packet */
380 dissect_scsi_payload_databuffer(tvb, pinfo, offset, data_transfer_length, request);
381 }
382 }
383
384 /* increment after DataBuffer */
385 offset += data_transfer_length;
386 } else {
387 guint8 scsi_status = 0;
388
389 /* Length */
390 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
391 offset += 2;
392
393 /* A */
394 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_auto_generated_sense, tvb, offset, 1, ENC_BIG_ENDIAN);
395
396 /* SrbStatus */
397 proto_tree_add_bits_item(sub_tree, hf_svhdx_tunnel_scsi_srb_status, tvb, offset * 8 + 1, 7, ENC_BIG_ENDIAN);
398 offset++;
399
400 /* ScsiStatus */
401 scsi_status = tvb_get_guint8(tvb, offset);
402 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
403 offset++;
404
405 /* CdbLength */
406 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_cdb_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
407 offset++;
408
409 /* SensInfoExLength */
410 sense_info_ex_length = tvb_get_guint8(tvb, offset);
411 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_sense_info_ex_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
412 offset++;
413
414 /* DataIn */
415 data_in = tvb_get_guint8(tvb, offset);
416 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_data_in, tvb, offset, 1, ENC_LITTLE_ENDIAN);
417 offset++;
418
419 /* Reserved */
420 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_reserved2, tvb, offset, 1, ENC_LITTLE_ENDIAN);
421 offset++;
422
423 /* SrbFlags */
424 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_srb_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
425 offset += 4;
426
427 /* DataTransferLength */
428 data_transfer_length = tvb_get_letohl(tvb, offset);
429 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_data_transfer_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
430 offset += 4;
431
432 /* SenseDataEx */
433 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_sense_data_ex, tvb, offset, sense_info_ex_length, ENC_NA);
434 offset += sense_info_ex_length;
435
436 /* DataBuffer */
437 if (data_transfer_length) {
438 proto_tree_add_item(sub_tree, hf_svhdx_tunnel_scsi_data, tvb, offset, data_transfer_length, ENC_NA);
439
440 if (data_in == 1) { /* Only IN operations have meaningful SCSI payload in reply packet */
441 dissect_scsi_payload_databuffer(tvb, pinfo, offset, data_transfer_length, request);
442 }
443
444 offset += data_transfer_length;
445 }
446
447 /*
448 * Now, the SCSI response
449 */
450 if (rsvd_conv_data->task && rsvd_conv_data->task->itlq) {
451 dissect_scsi_rsp(tvb, pinfo, top_tree, rsvd_conv_data->task->itlq, get_itl_nexus(pinfo), scsi_status);
452 }
453 }
454
455 return offset;
456 }
457
458 static int
dissect_RSVD_SRB_STATUS(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)459 dissect_RSVD_SRB_STATUS(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
460 {
461 proto_tree *gfi_sub_tree;
462 proto_item *gfi_sub_item;
463
464 if (request) {
465 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_SRB_STATUS_REQUEST");
466
467 /* StatusKey */
468 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_status_key, tvb, offset, 1, ENC_LITTLE_ENDIAN);
469 offset += 1;
470
471 /* Reserved */
472 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_reserved, tvb, offset, 1, ENC_NA);
473 offset += 27;
474 } else {
475 guint8 sense_info_length;
476
477 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_SRB_STATUS_RESPONSE");
478
479 /* StatusKey */
480 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_status_key, tvb, offset, 1, ENC_LITTLE_ENDIAN);
481 offset += 1;
482
483 /* SenseInfoAutoGenerated and SrbStatus */
484 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_sense_info_auto_generated, tvb, offset, 1, ENC_BIG_ENDIAN);
485 proto_tree_add_bits_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_srb_status, tvb, offset * 8 + 1, 7, ENC_BIG_ENDIAN);
486 offset += 1;
487
488 /* ScsiStatus */
489 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_scsi_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
490 offset += 1;
491
492 /* SenseInfoExLength */
493 sense_info_length = tvb_get_guint8(tvb, offset);
494 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_sense_info_ex_length, tvb, offset, 1, ENC_NA);
495 offset += 1;
496
497 /* SenseDataEx */
498 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_srb_status_sense_data_ex, tvb, offset, sense_info_length, ENC_NA);
499 offset += sense_info_length;
500 }
501
502 return offset;
503 }
504
505 static int
dissect_RSVD_GET_DISK_INFO(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)506 dissect_RSVD_GET_DISK_INFO(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
507 {
508 proto_tree *gfi_sub_tree;
509 proto_item *gfi_sub_item;
510
511 if (request) {
512 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_GET_DISK_INFO_REQUEST");
513
514 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_reserved1, tvb, offset, 8, ENC_LITTLE_ENDIAN);
515 offset += 8;
516
517 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_blocksize, tvb, offset, 4, ENC_LITTLE_ENDIAN);
518 offset += 4;
519
520 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_linkage_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
521 offset += 16;
522
523 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_is_mounted, tvb, offset, 1, ENC_LITTLE_ENDIAN);
524 offset += 1;
525
526 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_is_4k_aligned, tvb, offset, 1, ENC_LITTLE_ENDIAN);
527 offset += 1;
528
529 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
530 offset += 2;
531
532 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
533 offset += 8;
534
535 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_virtual_disk_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
536 offset += 16;
537 } else {
538 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_GET_DISK_INFO_RESPONSE");
539
540 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_disk_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
541 offset += 4;
542
543 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_disk_format, tvb, offset, 4, ENC_LITTLE_ENDIAN);
544 offset += 4;
545
546 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_blocksize, tvb, offset, 4, ENC_LITTLE_ENDIAN);
547 offset += 4;
548
549 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_linkage_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
550 offset += 16;
551
552 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_is_mounted, tvb, offset, 1, ENC_LITTLE_ENDIAN);
553 offset += 1;
554
555 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_is_4k_aligned, tvb, offset, 1, ENC_LITTLE_ENDIAN);
556 offset += 1;
557
558 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
559 offset += 2;
560
561 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
562 offset += 8;
563
564 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_disk_info_virtual_disk_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
565 offset += 16;
566 }
567
568 return offset;
569 }
570
571 static int
dissect_RSVD_VALIDATE_DISK(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)572 dissect_RSVD_VALIDATE_DISK(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
573 {
574 proto_tree *gfi_sub_tree;
575 proto_item *gfi_sub_item;
576
577 if (request) {
578 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_VALIDATE_DISK_REQUEST");
579
580 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_validate_disk_reserved, tvb, offset, 56, ENC_NA);
581 offset += 56;
582 } else {
583 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_VALIDATE_DISK_RESPONSE");
584
585 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_validate_disk_is_valid_disk, tvb, offset, 1, ENC_NA);
586 offset += 1;
587 }
588
589 return offset;
590 }
591
592 static const value_string rsvd_meta_operation_type_vals[] = {
593 { 0x00, "SvhdxMetaOperationTypeResize" },
594 { 0x01, "SvhdxMetaOperationTypeCreateSnapshot" },
595 { 0x02, "SvhdxMetaOperationTypeOptimize" },
596 { 0x03, "SvhdxMetaOperationTypeExtractVHD" },
597 { 0x04, "SvhdxMetaOperationTypeConvertToVHDSet" },
598 { 0x05, "SvhdxMetaOperationTypeApplySnapshot" },
599 { 0, NULL }
600 };
601
602 static const value_string svhdx_snapshot_type_vals[] = {
603 { 0x01, "SvhdxSnapshotTypeVM" },
604 { 0x03, "SvhdxSnapshotTypeCDP" },
605 { 0x04, "SvhdxSnapshotTypeWriteable" },
606 { 0, NULL }
607 };
608
609 static const value_string svhdx_snapshot_stage_vals[] = {
610 { 0x00, "SvhdxSnapshotStageInvalid" },
611 { 0x01, "SvhdxSnapshotStageInitialize" },
612 { 0x02, "SvhdxSnapshotStageBlockIO" },
613 { 0x03, "SvhdxSnapshotStageSwitchObjectStore" },
614 { 0x04, "SvhdxSnapshotStageUnblockIO" },
615 { 0x05, "SvhdxSnapshotStageFinalize" },
616 { 0, NULL }
617 };
618
619 #define SVHDX_SNAPSHOT_DISK_FLAG_ENABLE_CHANGE_TRACKING 0x00000001
620
621 static int
dissect_RSVD2_META_OPERATION_START(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)622 dissect_RSVD2_META_OPERATION_START(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
623 {
624 static int * const meta_operation_create_snapshot_flags[] = {
625 &hf_svhdx_tunnel_create_snapshot_flag_enable_change_tracking,
626 NULL
627 };
628
629 guint32 operation_type = 0;
630 guint32 length = 0;
631 proto_tree *gfi_sub_tree;
632 proto_item *gfi_sub_item;
633
634 if (request) {
635
636 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_META_OPERATION_START_REQUEST");
637
638 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_transaction_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
639 offset += 16;
640
641 operation_type = tvb_get_letohl(tvb, offset);
642 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_meta_operation_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
643 offset += 4;
644
645 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_padding, tvb, offset, 4, ENC_LITTLE_ENDIAN);
646 offset += 4;
647
648 switch (operation_type) {
649 case 0x00: /* SvhdxMetaOperationTypeResize */
650 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_resize_new_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
651 offset += 8;
652
653 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_resize_expand_only_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
654 offset += 1;
655
656 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_resize_allow_unsafe_virt_size_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
657 offset += 1;
658
659 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_resize_shrink_to_minimum_safe_size_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
660 offset += 1;
661
662 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_meta_operation_start_reserved, tvb, offset, 1, ENC_LITTLE_ENDIAN);
663 offset += 1;
664 break;
665 case 0x01: /* SvhdxMetaOperationTypeCreateSnapshot */
666 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
667 offset += 4;
668
669 proto_tree_add_bitmask(gfi_sub_tree, tvb, offset, hf_svhdx_tunnel_create_snapshot_flags,
670 ett_rsvd_create_snapshot_flags, meta_operation_create_snapshot_flags, ENC_LITTLE_ENDIAN);
671 offset += 4;
672
673 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_create_snapshot_stage1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
674 offset += 4;
675
676 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_create_snapshot_stage2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
677 offset += 4;
678
679 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_create_snapshot_stage3, tvb, offset, 4, ENC_LITTLE_ENDIAN);
680 offset += 4;
681
682 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_create_snapshot_stage4, tvb, offset, 4, ENC_LITTLE_ENDIAN);
683 offset += 4;
684
685 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_create_snapshot_stage5, tvb, offset, 4, ENC_LITTLE_ENDIAN);
686 offset += 4;
687
688 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_create_snapshot_stage6, tvb, offset, 4, ENC_LITTLE_ENDIAN);
689 offset += 4;
690
691 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
692 offset += 16;
693
694 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_create_snapshot_parameters_payload_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
695 offset += 4;
696
697 break;
698 case 0x02: /* SvhdxMetaOperationTypeOptimize */
699 /* No Data, field MUST be empty */
700 break;
701 case 0x03: /* SvhdxMetaOperationTypeExtractVHD */
702 /* TODO */
703 break;
704 case 0x04: /* SvhdxMetaOperationTypeConvertToVHDSet */
705 length = tvb_get_letohl(tvb, offset);
706 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_convert_dst_vhdset_name_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
707 offset += 4;
708
709 if (length) {
710 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_convert_dst_vhdset_name, tvb, offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
711 }
712 break;
713
714 case 0x05: /* SvhdxMetaOperationTypeApplySnapshot */
715 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
716 offset += 4;
717
718 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
719 offset += 16;
720
721 break;
722 }
723 }
724 return offset;
725 }
726
727 static int
dissect_RSVD2_META_OPERATION_QUERY_PROGRESS(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request,guint32 status)728 dissect_RSVD2_META_OPERATION_QUERY_PROGRESS(tvbuff_t *tvb,
729 proto_tree *parent_tree, int offset, gint16 len, gboolean request, guint32 status)
730 {
731 proto_tree *gfi_sub_tree;
732 proto_item *gfi_sub_item;
733
734 if (request) {
735 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_META_OPERATION_QUERY_PROGRESS_REQUEST");
736
737 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_transaction_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
738 offset += 16;
739 } else {
740 if (status == 0) { /* If status is not successful, RSVD response buffer is filled by data from request buffer and we should not parse output structure */
741 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_META_OPERATION_QUERY_PROGRESS_RESPONSE");
742
743 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_meta_op_query_progress_current_progress, tvb, offset, 8, ENC_LITTLE_ENDIAN);
744 offset += 8;
745
746 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_meta_op_query_progress_complete_value, tvb, offset, 8, ENC_LITTLE_ENDIAN);
747 offset += 8;
748 }
749 }
750 return offset;
751 }
752
753 static const value_string svhdx_vhdset_information_type_vals[] = {
754 { 0x02, "SvhdxVHDSetInformationTypeSnapshotList" },
755 { 0x05, "SvhdxVHDSetInformationTypeSnapshotEntry" },
756 { 0x08, "SvhdxVHDSetInformationTypeOptimizeNeeded" },
757 { 0x09, "SvhdxVHDSetInformationTypeCdpSnapshotRoot" },
758 { 0x0A, "SvhdxVHDSetInformationTypeCdpSnapshotActiveList" },
759 { 0x0C, "SvhdxVHDSetInformationTypeCdpSnapshotInactiveList" },
760 { 0, NULL }
761 };
762 static int
dissect_RSVD2_VHDSET_QUERY_INFORMATION(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)763 dissect_RSVD2_VHDSET_QUERY_INFORMATION(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
764 {
765 proto_tree *gfi_sub_tree;
766 proto_item *gfi_sub_item;
767
768 if (request) {
769 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_VHDSET_QUERY_INFORMATION_REQUEST");
770
771 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_vhdset_information_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
772 offset += 4;
773
774 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
775 offset += 4;
776
777 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
778 offset += 16;
779 } else {
780 guint32 vhdset_info_type = tvb_get_letohl(tvb, offset);
781 switch (vhdset_info_type) {
782 case 0x02: /* SvhdxVHDSetInformationTypeSnapshotList */
783 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_VHDSET_QUERY_INFORMATION_SNAPSHOT_LIST_RESPONSE");
784
785 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_vhdset_information_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
786 offset += 4;
787 /* TODO: make full dissection */
788
789 break;
790 case 0x05: /* SvhdxVHDSetInformationTypeSnapshotEntry */
791 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_VHDSET_QUERY_INFORMATION_SNAPSHOT_ENTRY_RESPONSE");
792
793 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_vhdset_information_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
794 offset += 4;
795
796 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_padding, tvb, offset, 4, ENC_LITTLE_ENDIAN);
797 offset += 4;
798
799 offset = dissect_nt_64bit_time(tvb, gfi_sub_tree, offset, hf_svhdx_tunnel_vhdset_snapshot_creation_time);
800
801 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
802 offset += 4;
803
804 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_vhdset_is_valid_snapshot, tvb, offset, 4, ENC_LITTLE_ENDIAN);
805 offset += 4;
806
807 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
808 offset += 16;
809
810 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_vhdset_parent_snapshot_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
811 offset += 16;
812
813 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_vhdset_log_file_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
814 offset += 16;
815
816 break;
817 }
818 }
819 return offset;
820 }
821
822 static int
dissect_RSVD2_DELETE_SNAPSHOT(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)823 dissect_RSVD2_DELETE_SNAPSHOT(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
824 {
825 proto_tree *gfi_sub_tree;
826 proto_item *gfi_sub_item;
827
828 if (request) {
829 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_DELETE_SNAPSHOT_REQUEST");
830
831 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
832 offset += 16;
833
834 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_delete_snapshot_persist_reference, tvb, offset, 4, ENC_LITTLE_ENDIAN);
835 offset += 4;
836
837 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_snapshot_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
838 offset += 4;
839 }
840 return offset;
841 }
842
843 static int
dissect_RSVD2_QUERY_SAFE_SIZE(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gint16 len,gboolean request)844 dissect_RSVD2_QUERY_SAFE_SIZE(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gint16 len, gboolean request)
845 {
846 proto_tree *gfi_sub_tree;
847 proto_item *gfi_sub_item;
848
849 if (!request) {
850 gfi_sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_svhdx_tunnel_op_header, &gfi_sub_item, "RSVD_TUNNEL_QUERY_SAFE_SIZE_RESPONSE");
851
852 proto_tree_add_item(gfi_sub_tree, hf_svhdx_tunnel_safe_virtual_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
853 offset += 8;
854 }
855 return offset;
856 }
857
858 static int
dissect_rsvd(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data)859 dissect_rsvd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
860 {
861 guint32 header_bytes = 0;
862 guint proto_id = 0;
863 guint proto_version = 0;
864 guint32 operation_code = 0;
865 guint32 status;
866 proto_item *ti;
867 proto_tree *rsvd_tree;
868 proto_item *sub_item;
869 proto_tree *sub_tree;
870 guint offset = 0;
871 guint16 len;
872 guint64 request_id = 0;
873 gboolean request = *(gboolean *)data;
874
875 top_tree = parent_tree;
876
877 len = tvb_reported_length(tvb);
878
879 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RSVD");
880
881 col_clear(pinfo->cinfo, COL_INFO);
882
883 /*
884 * The header bytes need to be pulled in as a 32bit LE value. And the
885 * header is the same in a request or a response ...
886 */
887 header_bytes = tvb_get_letohl(tvb, 0); /* Get the header bytes */
888 proto_id = header_bytes >> 24;
889 proto_version = (header_bytes >> 12) & 0x0FFF;
890 operation_code = header_bytes;
891
892 ti = proto_tree_add_item(parent_tree, proto_rsvd, tvb, offset, -1, ENC_NA);
893
894 rsvd_tree = proto_item_add_subtree(ti, ett_rsvd);
895
896 sub_tree = proto_tree_add_subtree(rsvd_tree, tvb, offset, (len>16) ? 16 : len, ett_svhdx_tunnel_op_header, &sub_item, "SVHDX_TUNNEL_OPERATION_HEADER");
897
898 /* ProtocolID */
899 proto_tree_add_uint(sub_tree, hf_svhdx_protocol_id, tvb, offset, 4, proto_id);
900
901 /* ProtocolVersion */
902 proto_tree_add_uint(sub_tree, hf_svhdx_protocol_version, tvb, offset, 4, proto_version);
903
904 /* Operation Code */
905 proto_tree_add_uint(sub_tree, hf_svhdx_operation_code, tvb, offset, 4, operation_code);
906 offset += 4;
907
908 /* Status */
909 status = tvb_get_letohl(tvb, offset);
910 proto_tree_add_item(sub_tree, hf_svhdx_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
911 offset += 4;
912
913 /* RequestId */
914 request_id = tvb_get_ntoh64(tvb, offset);
915 proto_tree_add_item(sub_tree, hf_svhdx_request_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
916 offset += 8;
917
918 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
919 val_to_str(operation_code,
920 rsvd_operation_code_vals,
921 "Unknown Operation Code (0x%08X)"),
922 request ? "Request" : "Response");
923
924 proto_item_append_text(ti, ", %s %s",
925 val_to_str(operation_code,
926 rsvd_operation_code_vals,
927 "Unknown Operation Code (0x%08X)"),
928 request ? "Request" : "Response");
929 /*
930 * Now process the individual requests ...
931 */
932 switch (operation_code) {
933 case 0x02001001:
934 offset += dissect_RSVD_GET_INITIAL_INFO(tvb, rsvd_tree, offset, len - offset, request);
935 break;
936
937 case 0x02001002:
938 offset += dissect_RSVD_TUNNEL_SCSI(tvb, pinfo, rsvd_tree, offset, len - offset, request, request_id);
939 break;
940
941 case 0x02001003:
942
943 /*
944 * There is nothing more here.
945 */
946
947 break;
948
949 case 0x02001004:
950 offset += dissect_RSVD_SRB_STATUS(tvb, rsvd_tree, offset, len - offset, request);
951 break;
952
953 case 0x02001005:
954 offset += dissect_RSVD_GET_DISK_INFO(tvb, rsvd_tree, offset, len - offset, request);
955 break;
956
957 case 0x02001006:
958 offset += dissect_RSVD_VALIDATE_DISK(tvb, rsvd_tree, offset, len - offset, request);
959 break;
960 /* RSVD v2 operations */
961 case 0x02002101:
962 offset += dissect_RSVD2_META_OPERATION_START(tvb, rsvd_tree, offset, len - offset, request);
963 break;
964
965 case 0x02002002:
966 offset += dissect_RSVD2_META_OPERATION_QUERY_PROGRESS(tvb, rsvd_tree, offset, len - offset, request, status);
967 break;
968
969 case 0x02002005:
970 offset += dissect_RSVD2_VHDSET_QUERY_INFORMATION(tvb, rsvd_tree, offset, len - offset, request);
971 break;
972
973 case 0x02002006:
974 offset += dissect_RSVD2_DELETE_SNAPSHOT(tvb, rsvd_tree, offset, len - offset, request);
975 break;
976
977 case 0x0200200D:
978 offset += dissect_RSVD2_QUERY_SAFE_SIZE(tvb, rsvd_tree, offset, len - offset, request);
979 break;
980
981 /* TODO: implement more dissectors for RSVD v2 */
982
983 default:
984 break;
985 }
986
987 return offset;
988 }
989
990 void
proto_register_rsvd(void)991 proto_register_rsvd(void)
992 {
993
994 static hf_register_info hf[] = {
995 { &hf_svhdx_protocol_id,
996 { "ProtocolId", "rsvd.svhdx_protocol_id", FT_UINT8, BASE_DEC,
997 NULL, 0, NULL, HFILL }},
998
999 { &hf_svhdx_protocol_version,
1000 { "ProtocolVersion", "rsvd.svhdx_protocol_version", FT_UINT16, BASE_DEC,
1001 NULL, 0, NULL, HFILL }},
1002
1003 { &hf_svhdx_operation_code,
1004 { "OperationCode", "rsvd.svhdx_operation_code", FT_UINT32, BASE_HEX,
1005 VALS(rsvd_operation_code_vals), 0, "Operation Code", HFILL }},
1006
1007 { &hf_svhdx_status,
1008 { "Status", "rsvd.svhdx_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
1009 &NT_errors_ext, 0, NULL, HFILL }},
1010
1011
1012 { &hf_svhdx_request_id,
1013 { "RequestId", "rsvd.svhdx_request_id", FT_UINT64, BASE_HEX,
1014 NULL, 0, NULL, HFILL }},
1015
1016 { &hf_svhdx_tunnel_scsi_length,
1017 { "Length", "rsvd.svhdx_length", FT_UINT16, BASE_DEC,
1018 NULL, 0, NULL, HFILL }},
1019
1020 { &hf_svhdx_tunnel_scsi_reserved1,
1021 { "Reserved1", "rsvd.svhdx_scsi_reserved1", FT_UINT16, BASE_HEX,
1022 NULL, 0, NULL, HFILL }},
1023
1024 { &hf_svhdx_tunnel_scsi_cdb_length,
1025 { "CDBLength", "rsvd.svhdx_scsi_cdb_length", FT_UINT8, BASE_DEC,
1026 NULL, 0, NULL, HFILL }},
1027
1028 { &hf_svhdx_tunnel_scsi_sense_info_ex_length,
1029 { "SenseInfoExLength", "rsvd.svhdx_scsi_sense_info_ex_length", FT_UINT8, BASE_DEC,
1030 NULL, 0, NULL, HFILL }},
1031
1032 { &hf_svhdx_tunnel_scsi_data_in,
1033 { "DataIn", "rsvd.svhdx_scsi_data_in", FT_UINT8, BASE_HEX,
1034 VALS(rsvd_data_in_vals), 0, "SCSI CDB transfer type", HFILL }},
1035
1036 { &hf_svhdx_tunnel_scsi_reserved2,
1037 { "Reserved2", "rsvd.svhdx_scsi_reserved2", FT_UINT8, BASE_HEX,
1038 NULL, 0, NULL, HFILL }},
1039
1040 { &hf_svhdx_tunnel_scsi_srb_flags,
1041 { "SRBFlags", "rsvd.svhdx_scsi_srbflags", FT_UINT32, BASE_HEX,
1042 NULL, 0, NULL, HFILL }},
1043
1044 { &hf_svhdx_tunnel_scsi_data_transfer_length,
1045 { "DataTransferLength", "rsvd.svhdx_scsi_data_transfer_length", FT_UINT32, BASE_DEC,
1046 NULL, 0, NULL, HFILL }},
1047
1048 { &hf_svhdx_tunnel_scsi_reserved3,
1049 { "Reserved3", "rsvd.svhdx_scsi_reserved3", FT_UINT32, BASE_HEX,
1050 NULL, 0, NULL, HFILL }},
1051
1052 { &hf_svhdx_tunnel_scsi_cdb,
1053 { "CDB", "rsvd.svhdx_scsi_cdb", FT_BYTES, BASE_NONE,
1054 NULL, 0, NULL, HFILL }},
1055
1056 { &hf_svhdx_tunnel_scsi_cdb_padding,
1057 { "CDBPadding", "rsvd.svhdx_scsi_cdb_padding", FT_BYTES, BASE_NONE,
1058 NULL, 0, NULL, HFILL }},
1059
1060 { &hf_svhdx_tunnel_scsi_data,
1061 {"Data", "rsvd.svhdx_scsi_data", FT_BYTES, BASE_NONE,
1062 NULL, 0, NULL, HFILL }},
1063
1064 { &hf_svhdx_tunnel_scsi_auto_generated_sense,
1065 {"AutoGeneratedSenseInfo", "rsvd.svhdx_auto_generated_sense_info", FT_UINT8, BASE_HEX,
1066 VALS(rsvd_sense_info_vals), 0x80, NULL, HFILL }},
1067
1068 { &hf_svhdx_tunnel_scsi_srb_status,
1069 { "SrbStatus", "rsvd.svhdx_srb_status", FT_UINT8, BASE_HEX,
1070 NULL, 0, NULL, HFILL }},
1071
1072 { &hf_svhdx_tunnel_scsi_status,
1073 { "ScsiStatus", "rsvd.svhdx_scsi_status", FT_UINT8, BASE_HEX,
1074 NULL, 0, NULL, HFILL }},
1075
1076 { &hf_svhdx_tunnel_scsi_sense_data_ex,
1077 { "SenseDataEx", "rsvd.svhdx_scsi_sense_data_ex", FT_BYTES, BASE_NONE,
1078 NULL, 0, NULL, HFILL }},
1079
1080 { &hf_svhdx_tunnel_file_info_server_version,
1081 { "ServerVersion", "rsvd.svhdx_file_info_server_version", FT_UINT32, BASE_DEC,
1082 NULL, 0, NULL, HFILL }},
1083
1084 { &hf_svhdx_tunnel_file_info_sector_size,
1085 { "SectorSize", "rsvd.svhdx_file_info_sector_size", FT_UINT32, BASE_DEC,
1086 NULL, 0, NULL, HFILL }},
1087
1088 { &hf_svhdx_tunnel_file_info_physical_sector_size,
1089 { "PhysicalSectorSize", "rsvd.svhdx_file_info_physical_sector_size", FT_UINT32, BASE_DEC,
1090 NULL, 0, NULL, HFILL }},
1091
1092 { &hf_svhdx_tunnel_file_info_reserved,
1093 { "Reserved", "rsvd.svhdx_file_info_reserved", FT_UINT32, BASE_DEC,
1094 NULL, 0, NULL, HFILL }},
1095
1096 { &hf_svhdx_tunnel_file_info_virtual_size,
1097 { "VirtualSize", "rsvd.svhdx_file_info_virtual_size", FT_UINT64, BASE_DEC,
1098 NULL, 0, NULL, HFILL }},
1099
1100
1101 { &hf_svhdx_tunnel_disk_info_reserved1,
1102 { "Reserved1", "rsvd.svhdx_disk_info_reserved1", FT_UINT64, BASE_DEC,
1103 NULL, 0, NULL, HFILL }},
1104
1105 { &hf_svhdx_tunnel_disk_info_blocksize,
1106 { "BlockSize", "rsvd.svhdx_disk_info_blocksize", FT_UINT32, BASE_DEC,
1107 NULL, 0, NULL, HFILL }},
1108
1109 { &hf_svhdx_tunnel_disk_info_linkage_id,
1110 { "LinkageID", "rsvd.svhdx_disk_info_linkage_id", FT_GUID, BASE_NONE,
1111 NULL, 0, NULL, HFILL }},
1112
1113 { &hf_svhdx_tunnel_disk_info_disk_type,
1114 { "DiskType", "rsvd.svhdx_disk_info_disk_type", FT_UINT16, BASE_HEX,
1115 VALS(rsvd_disk_type_vals), 0, "Disk Type", HFILL }},
1116
1117 { &hf_svhdx_tunnel_disk_info_disk_format,
1118 { "DiskFormat", "rsvd.svhdx_disk_info_disk_format", FT_UINT16, BASE_HEX,
1119 VALS(rsvd_disk_format_vals), 0, "Disk Format", HFILL }},
1120
1121 { &hf_svhdx_tunnel_disk_info_is_mounted,
1122 { "IsMounted", "rsvd.svhdx_tunnel_disk_info_is_mounted", FT_UINT8, BASE_DEC,
1123 NULL, 0, NULL, HFILL }},
1124
1125 { &hf_svhdx_tunnel_disk_info_is_4k_aligned,
1126 { "Is4KAligned", "rsvd.svhdx_tunnel_disk_info_is_4k_aligned", FT_UINT8, BASE_DEC,
1127 NULL, 0, NULL, HFILL }},
1128
1129 { &hf_svhdx_tunnel_disk_info_reserved,
1130 { "Reserved", "rsvd.svhdx_disk_info_reserved", FT_UINT16, BASE_DEC,
1131 NULL, 0, NULL, HFILL }},
1132
1133 { &hf_svhdx_tunnel_disk_info_file_size,
1134 { "FileSize", "rsvd.svhdx_disk_info_file_size", FT_UINT64, BASE_DEC,
1135 NULL, 0, NULL, HFILL }},
1136
1137 { &hf_svhdx_tunnel_disk_info_virtual_disk_id,
1138 { "VirtualDiskId", "rsvd.svhdx_disk_info_virtual_disk_id", FT_GUID, BASE_NONE,
1139 NULL, 0, NULL, HFILL }},
1140
1141 { &hf_svhdx_tunnel_validate_disk_reserved,
1142 { "Reserved", "rsvd.svhdx_tunnel_validate_disk_reserved", FT_BYTES, BASE_NONE,
1143 NULL, 0, NULL, HFILL }},
1144
1145 { &hf_svhdx_tunnel_validate_disk_is_valid_disk,
1146 { "IsValidDisk", "rsvd.svhdx_validate_disk_is_valid_disk", FT_BYTES, BASE_NONE,
1147 NULL, 0, NULL, HFILL }},
1148
1149 { &hf_svhdx_tunnel_srb_status_status_key,
1150 { "StatusKey", "rsvd.svhdx_srb_status_key", FT_UINT8, BASE_DEC,
1151 NULL, 0, NULL, HFILL }},
1152
1153 { &hf_svhdx_tunnel_srb_status_reserved,
1154 { "Reserved", "rsvd.svhdx_srb_status_reserved", FT_BYTES, BASE_NONE,
1155 NULL, 0, NULL, HFILL }},
1156
1157 { &hf_svhdx_tunnel_srb_status_sense_info_auto_generated,
1158 { "SenseInfoAutoGenerated", "rsvd.svhdx_sense_info_auto_generated", FT_UINT8, BASE_HEX,
1159 VALS(rsvd_sense_info_vals), 0x80, NULL, HFILL }},
1160
1161 { &hf_svhdx_tunnel_srb_status_srb_status,
1162 { "SrbStatus", "rsvd.svhdx_srb_status_srb_status", FT_UINT8, BASE_HEX,
1163 NULL, 0x7f, NULL, HFILL }},
1164
1165 { &hf_svhdx_tunnel_srb_status_scsi_status,
1166 { "SrbStatus", "rsvd.svhdx_srb_status_scsi_status", FT_UINT8, BASE_DEC,
1167 NULL, 0, NULL, HFILL }},
1168
1169 { &hf_svhdx_tunnel_srb_status_sense_info_ex_length,
1170 { "SenseInfoExLength", "rsvd.svhdx_srb_status_sense_info_ex_length", FT_UINT8, BASE_DEC,
1171 NULL, 0, NULL, HFILL }},
1172
1173 { &hf_svhdx_tunnel_srb_status_sense_data_ex,
1174 { "Reserved", "rsvd.svhdx_srb_status_sense_data_ex", FT_BYTES, BASE_NONE,
1175 NULL, 0, NULL, HFILL }},
1176
1177 { &hf_svhdx_tunnel_safe_virtual_size,
1178 { "SafeVirtualSize", "rsvd.svhdx_safe_size", FT_UINT64, BASE_DEC,
1179 NULL, 0, NULL, HFILL }},
1180
1181 { &hf_svhdx_tunnel_transaction_id,
1182 { "TransactionId", "rsvd.svhdx_meta_operation.transaction_id", FT_GUID, BASE_NONE,
1183 NULL, 0, NULL, HFILL }},
1184
1185 { &hf_svhdx_tunnel_meta_operation_type,
1186 { "OperationType", "rsvd.svhdx_meta_operation.type", FT_UINT32, BASE_HEX,
1187 VALS(rsvd_meta_operation_type_vals), 0, "Type of meta-operation", HFILL }},
1188
1189 { &hf_svhdx_tunnel_padding,
1190 { "Padding", "rsvd.svhdx_padding", FT_UINT32, BASE_DEC,
1191 NULL, 0, NULL, HFILL }},
1192
1193 { &hf_svhdx_tunnel_resize_new_size,
1194 { "NewSize", "rsvd.svhdx_meta_operation.new_size", FT_UINT64, BASE_DEC,
1195 NULL, 0, NULL, HFILL }},
1196
1197 { &hf_svhdx_tunnel_resize_expand_only_flag,
1198 { "ExpandOnly", "rsvd.svhdx_meta_operation.expand_only", FT_BOOLEAN, 8,
1199 NULL, 0, "Indicates that shared virtual disk size can only expand", HFILL }},
1200
1201 { &hf_svhdx_tunnel_resize_allow_unsafe_virt_size_flag,
1202 { "AllowUnsafeVirtualSize", "rsvd.svhdx_meta_operation.allow_unsafe_virt_size", FT_BOOLEAN, 8,
1203 NULL, 0, "Indicates that the shared virtual disk size can be less than the data it currently contains", HFILL }},
1204
1205 { &hf_svhdx_tunnel_resize_shrink_to_minimum_safe_size_flag,
1206 { "ShrinkToMinimumSafeSize", "rsvd.svhdx_meta_operation.shrink_to_minimum_safe_size", FT_BOOLEAN, 8,
1207 NULL, 0, "Indicates that the shared virtual disk size can be shrunk to the data it currently contains", HFILL }},
1208
1209 { &hf_svhdx_tunnel_meta_operation_start_reserved,
1210 { "Reserved", "rsvd.svhdx_meta_operation.reserved", FT_UINT8, BASE_DEC,
1211 NULL, 0, NULL, HFILL }},
1212
1213 { &hf_svhdx_tunnel_snapshot_type,
1214 { "SnapshotType", "rsvd.svhdx_snapshot_type", FT_UINT32, BASE_HEX,
1215 VALS(svhdx_snapshot_type_vals), 0, "Type of snapshot", HFILL }},
1216
1217 { &hf_svhdx_tunnel_snapshot_id,
1218 { "SnapshotId", "rsvd.svhdx_snapshot_id", FT_GUID, BASE_NONE,
1219 NULL, 0, NULL, HFILL }},
1220
1221 { &hf_svhdx_tunnel_create_snapshot_flags,
1222 { "Flags", "rsvd.svhdx_meta_operation.create_snapshot_flags", FT_UINT32, BASE_HEX,
1223 NULL, 0, NULL, HFILL }},
1224
1225 { &hf_svhdx_tunnel_create_snapshot_flag_enable_change_tracking,
1226 { "SVHDX_SNAPSHOT_DISK_FLAG_ENABLE_CHANGE_TRACKING", "rsvd.svhdx_meta_operation.create_snapshot_flag_enable_change_tracking", FT_BOOLEAN, 32,
1227 NULL, SVHDX_SNAPSHOT_DISK_FLAG_ENABLE_CHANGE_TRACKING, "Change tracking to be enabled when snapshot is taken", HFILL }},
1228
1229 { &hf_svhdx_tunnel_create_snapshot_stage1,
1230 { "Stage1", "rsvd.svhdx_meta_operation.create_snapshot_stage1", FT_UINT32, BASE_HEX,
1231 VALS(svhdx_snapshot_stage_vals), 0, "The first stage", HFILL }},
1232
1233 { &hf_svhdx_tunnel_create_snapshot_stage2,
1234 { "Stage2", "rsvd.svhdx_meta_operation.create_snapshot_stage2", FT_UINT32, BASE_HEX,
1235 VALS(svhdx_snapshot_stage_vals), 0, "The second stage", HFILL }},
1236
1237 { &hf_svhdx_tunnel_create_snapshot_stage3,
1238 { "Stage3", "rsvd.svhdx_meta_operation.create_snapshot_stage3", FT_UINT32, BASE_HEX,
1239 VALS(svhdx_snapshot_stage_vals), 0, "The third stage", HFILL }},
1240
1241 { &hf_svhdx_tunnel_create_snapshot_stage4,
1242 { "Stage4", "rsvd.svhdx_meta_operation.create_snapshot_stage4", FT_UINT32, BASE_HEX,
1243 VALS(svhdx_snapshot_stage_vals), 0, "The fourth stage", HFILL }},
1244
1245 { &hf_svhdx_tunnel_create_snapshot_stage5,
1246 { "Stage5", "rsvd.svhdx_meta_operation.create_snapshot_stage5", FT_UINT32, BASE_HEX,
1247 VALS(svhdx_snapshot_stage_vals), 0, "The fifth stage", HFILL }},
1248
1249 { &hf_svhdx_tunnel_create_snapshot_stage6,
1250 { "Stage6", "rsvd.svhdx_meta_operation.create_snapshot_stage6", FT_UINT32, BASE_HEX,
1251 VALS(svhdx_snapshot_stage_vals), 0, "The sixth stage", HFILL }},
1252
1253 { &hf_svhdx_tunnel_create_snapshot_parameters_payload_size,
1254 { "ParametersPayloadSize", "rsvd.svhdx_meta_operation.create_snapshot_params_payload_size", FT_UINT32, BASE_DEC,
1255 NULL, 0, NULL, HFILL }},
1256
1257 { &hf_svhdx_tunnel_convert_dst_vhdset_name_len,
1258 { "DestinationVhdSetNameLength", "rsvd.svhdx_meta_operation.dst_vhdset_name_len", FT_UINT32, BASE_DEC,
1259 NULL, 0, NULL, HFILL }},
1260
1261 { &hf_svhdx_tunnel_convert_dst_vhdset_name,
1262 { "DestinationVhdSetName", "rsvd.svhdx_meta_operation.dst_vhdset_name", FT_STRING, BASE_NONE,
1263 NULL, 0, "Name for the new VHD set be created", HFILL }},
1264
1265 { &hf_svhdx_tunnel_delete_snapshot_persist_reference,
1266 { "PersistReference", "rsvd.svhdx_delete_snapshot_persist_reference", FT_BOOLEAN, 4,
1267 NULL, 0, "Indicate if the snapshot needs to be persisted", HFILL }},
1268
1269 { &hf_svhdx_tunnel_meta_op_query_progress_current_progress,
1270 { "CurrentProgressValue", "rsvd.svhdx_query_progress.current_progress", FT_UINT64, BASE_DEC,
1271 NULL, 0, NULL, HFILL }},
1272
1273 { &hf_svhdx_tunnel_meta_op_query_progress_complete_value,
1274 { "CompleteValue", "rsvd.svhdx_query_progress.complete_value", FT_UINT64, BASE_DEC,
1275 NULL, 0, NULL, HFILL }},
1276
1277 { &hf_svhdx_tunnel_vhdset_information_type,
1278 { "VHDSetInformationType", "rsvd.svhdx_vhdset_information_type", FT_UINT32, BASE_HEX,
1279 VALS(svhdx_vhdset_information_type_vals), 0, "The information type requested", HFILL }},
1280
1281 { &hf_svhdx_tunnel_vhdset_snapshot_creation_time,
1282 { "SnapshotCreationTime", "rsvd.svhdx_vhdset_snapshot_creation_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
1283 NULL, 0, "Time when this object was created", HFILL }},
1284
1285 { &hf_svhdx_tunnel_vhdset_is_valid_snapshot,
1286 { "IsValidSnapshot", "rsvd.svhdx_vhdset_is_valid_snapshot", FT_BOOLEAN, 4,
1287 NULL, 0, "Set to 1 when the snapshot is valid", HFILL }},
1288
1289 { &hf_svhdx_tunnel_vhdset_parent_snapshot_id,
1290 { "ParentSnapshotId", "rsvd.svhdx_vhdxset_parent_snapshot_id", FT_GUID, BASE_NONE,
1291 NULL, 0, NULL, HFILL }},
1292
1293 { &hf_svhdx_tunnel_vhdset_log_file_id,
1294 { "LogFileId", "rsvd.svhdx_vhdxset_log_file_id", FT_GUID, BASE_NONE,
1295 NULL, 0, NULL, HFILL }}
1296 };
1297
1298 static gint *ett[] = {
1299 &ett_rsvd,
1300 &ett_svhdx_tunnel_op_header,
1301 &ett_svhdx_tunnel_scsi_request,
1302 &ett_rsvd_create_snapshot_flags
1303 };
1304
1305 proto_rsvd = proto_register_protocol("Remote Shared Virtual Disk",
1306 "RSVD", "rsvd");
1307
1308 register_dissector("rsvd", dissect_rsvd, proto_rsvd);
1309 proto_register_field_array(proto_rsvd, hf, array_length(hf));
1310 proto_register_subtree_array(ett, array_length(ett));
1311 }
1312
1313 /*
1314 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1315 *
1316 * Local variables:
1317 * c-basic-offset: 4
1318 * tab-width: 8
1319 * indent-tabs-mode: nil
1320 * End:
1321 *
1322 * vi: set shiftwidth=4 tabstop=8 expandtab:
1323 * :indentSize=4:tabSize=8:noTabs=true:
1324 */
1325