Coverage Report

Created: 2026-01-02 06:13

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