HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-ndmp.c
blob08ea2de56cb3ac3a80e9a0fac2270f77380f6b50
1 /* TODO: fixup LUN tracking so we can pass the proper LUN across to
2 dissect_scsi_xxx()
3 */
4 /* packet-ndmp.c
5 * Routines for NDMP dissection
6 * 2001 Ronnie Sahlberg (see AUTHORS for email)
8 * $Id$
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 /* see www.ndmp.org for protocol specifications.
30 this file implements version 3 of ndmp
33 #include "config.h"
35 #include <string.h>
36 #include <glib.h>
38 #include <epan/packet.h>
39 #include <epan/conversation.h>
40 #include <epan/wmem/wmem.h>
41 #include "packet-rpc.h"
42 #include "packet-ndmp.h"
43 #include "packet-tcp.h"
44 #include "packet-scsi.h"
45 #include <epan/prefs.h>
46 #include <epan/reassemble.h>
48 #define TCP_PORT_NDMP 10000
50 static dissector_handle_t ndmp_handle;
52 static int proto_ndmp = -1;
53 static int hf_ndmp_request_frame = -1;
54 static int hf_ndmp_response_frame = -1;
55 static int hf_ndmp_time = -1;
56 static int hf_ndmp_lastfrag = -1;
57 static int hf_ndmp_fraglen = -1;
58 static int hf_ndmp_version = -1;
59 static int hf_ndmp_header = -1;
60 static int hf_ndmp_sequence = -1;
61 static int hf_ndmp_reply_sequence = -1;
62 static int hf_ndmp_timestamp = -1;
63 static int hf_ndmp_msgtype = -1;
64 static int hf_ndmp_msg = -1;
65 static int hf_ndmp_error = -1;
66 static int hf_ndmp_hostname = -1;
67 static int hf_ndmp_os_type = -1;
68 static int hf_ndmp_os_vers = -1;
69 static int hf_ndmp_hostid = -1;
70 static int hf_ndmp_addr_types = -1;
71 static int hf_ndmp_addr_type = -1;
72 static int hf_ndmp_auth_type = -1;
73 static int hf_ndmp_auth_types = -1;
74 static int hf_ndmp_auth_challenge = -1;
75 static int hf_ndmp_auth_digest = -1;
76 static int hf_ndmp_auth_id = -1;
77 static int hf_ndmp_auth_password = -1;
78 static int hf_ndmp_butype_info = -1;
79 static int hf_ndmp_butype_name = -1;
80 static int hf_ndmp_butype_default_env = -1;
81 static int hf_ndmp_butype_attr_backup_file_history = -1;
82 static int hf_ndmp_butype_attr_backup_filelist = -1;
83 static int hf_ndmp_butype_attr_recover_filelist = -1;
84 static int hf_ndmp_butype_attr_backup_direct = -1;
85 static int hf_ndmp_butype_attr_recover_direct = -1;
86 static int hf_ndmp_butype_attr_backup_incremental = -1;
87 static int hf_ndmp_butype_attr_recover_incremental = -1;
88 static int hf_ndmp_butype_attr_backup_utf8 = -1;
89 static int hf_ndmp_butype_attr_recover_utf8 = -1;
90 static int hf_ndmp_butype_env_name = -1;
91 static int hf_ndmp_butype_env_value = -1;
92 static int hf_ndmp_tcp_env_name = -1;
93 static int hf_ndmp_tcp_env_value = -1;
94 static int hf_ndmp_tcp_default_env = -1;
95 static int hf_ndmp_tcp_addr_list = -1;
96 static int hf_ndmp_fs_info = -1;
97 static int hf_ndmp_fs_invalid_total_size = -1;
98 static int hf_ndmp_fs_invalid_used_size = -1;
99 static int hf_ndmp_fs_invalid_avail_size = -1;
100 static int hf_ndmp_fs_invalid_total_inodes = -1;
101 static int hf_ndmp_fs_invalid_used_inodes = -1;
102 static int hf_ndmp_fs_fs_type = -1;
103 static int hf_ndmp_fs_logical_device = -1;
104 static int hf_ndmp_fs_physical_device = -1;
105 static int hf_ndmp_fs_total_size = -1;
106 static int hf_ndmp_fs_used_size = -1;
107 static int hf_ndmp_fs_avail_size = -1;
108 static int hf_ndmp_fs_total_inodes = -1;
109 static int hf_ndmp_fs_used_inodes = -1;
110 static int hf_ndmp_fs_env = -1;
111 static int hf_ndmp_fs_env_name = -1;
112 static int hf_ndmp_fs_env_value = -1;
113 static int hf_ndmp_fs_status = -1;
114 static int hf_ndmp_tape_info = -1;
115 static int hf_ndmp_tape_model = -1;
116 static int hf_ndmp_tape_dev_cap = -1;
117 static int hf_ndmp_tape_device = -1;
118 static int hf_ndmp_tape_open_mode = -1;
119 static int hf_ndmp_tape_attr_rewind = -1;
120 static int hf_ndmp_tape_attr_unload = -1;
121 static int hf_ndmp_tape_capability = -1;
122 static int hf_ndmp_tape_capability_name = -1;
123 static int hf_ndmp_tape_capability_value = -1;
124 static int hf_ndmp_scsi_info = -1;
125 static int hf_ndmp_scsi_model = -1;
126 static int hf_ndmp_server_vendor = -1;
127 static int hf_ndmp_server_product = -1;
128 static int hf_ndmp_server_revision = -1;
129 static int hf_ndmp_scsi_device = -1;
130 static int hf_ndmp_scsi_controller = -1;
131 static int hf_ndmp_scsi_id = -1;
132 static int hf_ndmp_scsi_lun = -1;
133 static int hf_ndmp_execute_cdb_flags_data_in = -1;
134 static int hf_ndmp_execute_cdb_flags_data_out = -1;
135 static int hf_ndmp_execute_cdb_timeout = -1;
136 static int hf_ndmp_execute_cdb_datain_len = -1;
137 static int hf_ndmp_execute_cdb_cdb_len = -1;
138 /* static int hf_ndmp_execute_cdb_dataout = -1; */
139 static int hf_ndmp_execute_cdb_status = -1;
140 static int hf_ndmp_execute_cdb_dataout_len = -1;
141 /* static int hf_ndmp_execute_cdb_datain = -1; */
142 static int hf_ndmp_execute_cdb_sns_len = -1;
143 static int hf_ndmp_tape_invalid_file_num = -1;
144 static int hf_ndmp_tape_invalid_soft_errors = -1;
145 static int hf_ndmp_tape_invalid_block_size = -1;
146 static int hf_ndmp_tape_invalid_block_no = -1;
147 static int hf_ndmp_tape_invalid_total_space = -1;
148 static int hf_ndmp_tape_invalid_space_remain = -1;
149 static int hf_ndmp_tape_invalid_partition = -1;
150 static int hf_ndmp_tape_flags_no_rewind = -1;
151 static int hf_ndmp_tape_flags_write_protect = -1;
152 static int hf_ndmp_tape_flags_error = -1;
153 static int hf_ndmp_tape_flags_unload = -1;
154 static int hf_ndmp_tape_file_num = -1;
155 static int hf_ndmp_tape_soft_errors = -1;
156 static int hf_ndmp_tape_block_size = -1;
157 static int hf_ndmp_tape_block_no = -1;
158 static int hf_ndmp_tape_total_space = -1;
159 static int hf_ndmp_tape_space_remain = -1;
160 static int hf_ndmp_tape_partition = -1;
161 static int hf_ndmp_tape_mtio_op = -1;
162 static int hf_ndmp_count = -1;
163 static int hf_ndmp_resid_count = -1;
164 static int hf_ndmp_mover_state = -1;
165 static int hf_ndmp_mover_pause = -1;
166 static int hf_ndmp_halt = -1;
167 static int hf_ndmp_halt_reason = -1;
168 static int hf_ndmp_record_size = -1;
169 static int hf_ndmp_record_num = -1;
170 static int hf_ndmp_data_written = -1;
171 static int hf_ndmp_seek_position = -1;
172 static int hf_ndmp_bytes_left_to_read = -1;
173 static int hf_ndmp_window_offset = -1;
174 static int hf_ndmp_window_length = -1;
175 static int hf_ndmp_addr_ip = -1;
176 static int hf_ndmp_addr_tcp = -1;
177 static int hf_ndmp_addr_fcal_loop_id = -1;
178 static int hf_ndmp_addr_ipc = -1;
179 static int hf_ndmp_mover_mode = -1;
180 static int hf_ndmp_file_name = -1;
181 static int hf_ndmp_nt_file_name = -1;
182 static int hf_ndmp_dos_file_name = -1;
183 static int hf_ndmp_log_type = -1;
184 static int hf_ndmp_log_message_id = -1;
185 static int hf_ndmp_log_message = -1;
186 static int hf_ndmp_connected = -1;
187 static int hf_ndmp_connected_reason = -1;
188 static int hf_ndmp_data = -1;
189 static int hf_ndmp_files = -1;
190 static int hf_ndmp_file_fs_type = -1;
191 static int hf_ndmp_file_names = -1;
192 static int hf_ndmp_file_stats = -1;
193 static int hf_ndmp_file_node = -1;
194 static int hf_ndmp_file_parent = -1;
195 static int hf_ndmp_file_fh_info = -1;
196 static int hf_ndmp_file_invalid_atime = -1;
197 static int hf_ndmp_file_invalid_ctime = -1;
198 static int hf_ndmp_file_invalid_group = -1;
199 static int hf_ndmp_file_type = -1;
200 static int hf_ndmp_file_mtime = -1;
201 static int hf_ndmp_file_atime = -1;
202 static int hf_ndmp_file_ctime = -1;
203 static int hf_ndmp_file_owner = -1;
204 static int hf_ndmp_file_group = -1;
205 static int hf_ndmp_file_fattr = -1;
206 static int hf_ndmp_file_size = -1;
207 static int hf_ndmp_file_links = -1;
208 static int hf_ndmp_dirs = -1;
209 static int hf_ndmp_nodes = -1;
210 static int hf_ndmp_nlist = -1;
211 static int hf_ndmp_bu_original_path = -1;
212 static int hf_ndmp_bu_destination_dir = -1;
213 static int hf_ndmp_bu_new_name = -1;
214 static int hf_ndmp_bu_other_name = -1;
215 static int hf_ndmp_state_invalid_ebr = -1;
216 static int hf_ndmp_state_invalid_etr = -1;
217 static int hf_ndmp_bu_operation = -1;
218 static int hf_ndmp_data_state = -1;
219 static int hf_ndmp_data_halted = -1;
220 static int hf_ndmp_data_bytes_processed = -1;
221 static int hf_ndmp_data_est_bytes_remain = -1;
222 static int hf_ndmp_data_est_time_remain = -1;
223 static int hf_ndmp_ex_class_id = -1;
224 static int hf_ndmp_class_list = -1;
225 static int hf_ndmp_ext_version = -1;
226 static int hf_ndmp_ext_version_list = -1;
227 static int hf_ndmp_class_version = -1;
228 static int hf_ndmp_ex_class_version = -1;
230 static int hf_ndmp_fragments = -1;
231 static int hf_ndmp_fragment = -1;
232 static int hf_ndmp_fragment_overlap = -1;
233 static int hf_ndmp_fragment_overlap_conflicts = -1;
234 static int hf_ndmp_fragment_multiple_tails = -1;
235 static int hf_ndmp_fragment_too_long_fragment = -1;
236 static int hf_ndmp_fragment_error = -1;
237 static int hf_ndmp_fragment_count = -1;
238 static int hf_ndmp_reassembled_in = -1;
239 static int hf_ndmp_reassembled_length = -1;
241 static gint ett_ndmp = -1;
242 static gint ett_ndmp_fraghdr = -1;
243 static gint ett_ndmp_header = -1;
244 static gint ett_ndmp_butype_attrs = -1;
245 static gint ett_ndmp_fs_invalid = -1;
246 static gint ett_ndmp_tape_attr = -1;
247 static gint ett_ndmp_execute_cdb_flags = -1;
248 static gint ett_ndmp_execute_cdb_cdb = -1;
249 static gint ett_ndmp_execute_cdb_sns = -1;
250 static gint ett_ndmp_execute_cdb_payload = -1;
251 static gint ett_ndmp_tape_invalid = -1;
252 static gint ett_ndmp_tape_flags = -1;
253 static gint ett_ndmp_addr = -1;
254 static gint ett_ndmp_file = -1;
255 static gint ett_ndmp_file_name = -1;
256 static gint ett_ndmp_file_stats = -1;
257 static gint ett_ndmp_file_invalids = -1;
258 static gint ett_ndmp_state_invalids = -1;
259 static gint ett_ndmp_fragment = -1;
260 static gint ett_ndmp_fragments = -1;
262 static const fragment_items ndmp_frag_items = {
263 /* Fragment subtrees */
264 &ett_ndmp_fragment,
265 &ett_ndmp_fragments,
266 /* Fragment fields */
267 &hf_ndmp_fragments,
268 &hf_ndmp_fragment,
269 &hf_ndmp_fragment_overlap,
270 &hf_ndmp_fragment_overlap_conflicts,
271 &hf_ndmp_fragment_multiple_tails,
272 &hf_ndmp_fragment_too_long_fragment,
273 &hf_ndmp_fragment_error,
274 &hf_ndmp_fragment_count,
275 /* Reassembled in field */
276 &hf_ndmp_reassembled_in,
277 /* Reassembled length field */
278 &hf_ndmp_reassembled_length,
279 /* Reassembled data field */
280 NULL,
281 /* Tag */
282 "NDMP fragments"
285 static reassembly_table ndmp_reassembly_table;
287 /* XXX someone should start adding the new stuff from v3, v4 and v5*/
288 #define NDMP_PROTOCOL_UNKNOWN 0
289 #define NDMP_PROTOCOL_V2 2
290 #define NDMP_PROTOCOL_V3 3
291 #define NDMP_PROTOCOL_V4 4
292 #define NDMP_PROTOCOL_V5 5
293 static const enum_val_t ndmp_protocol_versions[] = {
294 { "version2", "Version 2", NDMP_PROTOCOL_V2 },
295 { "version3", "Version 3", NDMP_PROTOCOL_V3 },
296 { "version4", "Version 4", NDMP_PROTOCOL_V4 },
297 { "version5", "Version 5", NDMP_PROTOCOL_V5 },
298 { NULL, NULL, 0 }
301 static gint ndmp_default_protocol_version = NDMP_PROTOCOL_V4;
303 typedef struct _ndmp_frag_info {
304 guint32 first_seq;
305 guint16 offset;
306 } ndmp_frag_info;
308 typedef struct _ndmp_task_data_t {
309 guint32 request_frame;
310 guint32 response_frame;
311 nstime_t ndmp_time;
312 itlq_nexus_t *itlq;
313 } ndmp_task_data_t;
315 typedef struct _ndmp_conv_data_t {
316 guint8 version;
317 wmem_tree_t *tasks; /* indexed by Sequence# */
318 wmem_tree_t *itl; /* indexed by packet# */
319 wmem_tree_t *fragsA; /* indexed by Sequence# */
320 wmem_tree_t *fragsB;
321 ndmp_task_data_t *task;
322 conversation_t *conversation;
323 } ndmp_conv_data_t;
324 static ndmp_conv_data_t *ndmp_conv_data=NULL;
325 static proto_tree *top_tree;
327 static itl_nexus_t *
328 get_itl_nexus(packet_info *pinfo, gboolean create_new)
330 itl_nexus_t *itl;
332 if(create_new || !(itl=(itl_nexus_t *)wmem_tree_lookup32_le(ndmp_conv_data->itl, pinfo->fd->num))){
333 itl=wmem_new(wmem_file_scope(), itl_nexus_t);
334 itl->cmdset=0xff;
335 itl->conversation=ndmp_conv_data->conversation;
336 wmem_tree_insert32(ndmp_conv_data->itl, pinfo->fd->num, itl);
338 return itl;
341 static guint8
342 get_ndmp_protocol_version(void)
344 if(!ndmp_conv_data || (ndmp_conv_data->version==NDMP_PROTOCOL_UNKNOWN)){
345 return ndmp_default_protocol_version;
347 return ndmp_conv_data->version;
350 struct ndmp_header {
351 guint32 seq;
352 guint32 time;
353 guint32 type;
354 guint32 msg;
355 guint32 rep_seq;
356 guint32 err;
359 /* desegmentation of NDMP packets */
360 static gboolean ndmp_desegment = TRUE;
362 /* defragmentation of fragmented NDMP records */
363 static gboolean ndmp_defragment = TRUE;
365 #define NDMP_MESSAGE_REQUEST 0x00
366 #define NDMP_MESSAGE_REPLY 0x01
367 static const value_string msg_type_vals[] = {
368 {NDMP_MESSAGE_REQUEST, "Request"},
369 {NDMP_MESSAGE_REPLY, "Reply"},
370 {0, NULL}
373 #define NDMP_NO_ERR 0x00
374 #define NDMP_NOT_SUPPORTED_ERR 0x01
375 #define NDMP_DEVICE_BUSY_ERR 0x02
376 #define NDMP_DEVICE_OPENED_ERR 0x03
377 #define NDMP_NOT_AUTHORIZED_ERR 0x04
378 #define NDMP_PERMISSION_ERR 0x05
379 #define NDMP_DEV_NOT_OPEN_ERR 0x06
380 #define NDMP_IO_ERR 0x07
381 #define NDMP_TIMEOUT_ERR 0x08
382 #define NDMP_ILLEGAL_ARGS_ERR 0x09
383 #define NDMP_NO_TAPE_LOADED_ERR 0x0a
384 #define NDMP_WRITE_PROTECT_ERR 0x0b
385 #define NDMP_EOF_ERR 0x0c
386 #define NDMP_EOM_ERR 0x0d
387 #define NDMP_FILE_NOT_FOUND_ERR 0x0e
388 #define NDMP_BAD_FILE_ERR 0x0f
389 #define NDMP_NO_DEVICE_ERR 0x10
390 #define NDMP_NO_BUS_ERR 0x11
391 #define NDMP_XDR_DECODE_ERR 0x12
392 #define NDMP_ILLEGAL_STATE_ERR 0x13
393 #define NDMP_UNDEFINED_ERR 0x14
394 #define NDMP_XDR_ENCODE_ERR 0x15
395 #define NDMP_NO_MEM_ERR 0x16
396 #define NDMP_CONNECT_ERR 0x17
397 #define NDMP_SEQUENCE_NUM_ERR 0x18
398 #define NDMP_READ_IN_PROGRESS_ERR 0x19
399 #define NDMP_PRECONDITION_ERR 0x1a
400 #define NDMP_CLASS_NOT_SUPPORTED_ERR 0x1b
401 #define NDMP_VERSION_NOT_SUPPORTED_ERR 0x1c
402 #define NDMP_EXT_DUPL_CLASSES_ERR 0x1d
403 #define NDMP_EXT_DANDN_ILLEGAL_ERR 0x1e
405 static const value_string error_vals[] = {
406 {NDMP_NO_ERR, "NO_ERR"},
407 {NDMP_NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR"},
408 {NDMP_DEVICE_BUSY_ERR, "DEVICE_BUSY_ERR"},
409 {NDMP_DEVICE_OPENED_ERR, "DEVICE_OPENED_ERR"},
410 {NDMP_NOT_AUTHORIZED_ERR, "NOT_AUTHORIZED_ERR"},
411 {NDMP_PERMISSION_ERR, "PERMISSION_ERR"},
412 {NDMP_DEV_NOT_OPEN_ERR, "DEV_NOT_OPEN_ERR"},
413 {NDMP_IO_ERR, "IO_ERR"},
414 {NDMP_TIMEOUT_ERR, "TIMEOUT_ERR"},
415 {NDMP_ILLEGAL_ARGS_ERR, "ILLEGAL_ARGS_ERR"},
416 {NDMP_NO_TAPE_LOADED_ERR, "NO_TAPE_LOADED_ERR"},
417 {NDMP_WRITE_PROTECT_ERR, "WRITE_PROTECT_ERR"},
418 {NDMP_EOF_ERR, "EOF_ERR"},
419 {NDMP_EOM_ERR, "EOM_ERR"},
420 {NDMP_FILE_NOT_FOUND_ERR, "FILE_NOT_FOUND_ERR"},
421 {NDMP_BAD_FILE_ERR, "BAD_FILE_ERR"},
422 {NDMP_NO_DEVICE_ERR, "NO_DEVICE_ERR"},
423 {NDMP_NO_BUS_ERR, "NO_BUS_ERR"},
424 {NDMP_XDR_DECODE_ERR, "XDR_DECODE_ERR"},
425 {NDMP_ILLEGAL_STATE_ERR, "ILLEGAL_STATE_ERR"},
426 {NDMP_UNDEFINED_ERR, "UNDEFINED_ERR"},
427 {NDMP_XDR_ENCODE_ERR, "XDR_ENCODE_ERR"},
428 {NDMP_NO_MEM_ERR, "NO_MEM_ERR"},
429 {NDMP_CONNECT_ERR, "CONNECT_ERR"},
430 {NDMP_SEQUENCE_NUM_ERR, "NDMP_SEQUENCE_NUM_ERR"},
431 {NDMP_READ_IN_PROGRESS_ERR, "NDMP_READ_IN_PROGRESS_ERR"},
432 {NDMP_PRECONDITION_ERR, "NDMP_PRECONDITION_ERR"},
433 {NDMP_CLASS_NOT_SUPPORTED_ERR, "NDMP_CLASS_NOT_SUPPORTED_ERR"},
434 {NDMP_VERSION_NOT_SUPPORTED_ERR,"NDMP_VERSION_NOT_SUPPORTED_ERR"},
435 {NDMP_EXT_DUPL_CLASSES_ERR, "NDMP_EXT_DUPL_CLASSES_ERR"},
436 {NDMP_EXT_DANDN_ILLEGAL_ERR, "NDMP_EXT_DANDN_ILLEGAL_ERR"},
437 {0, NULL}
442 #define NDMP_CONFIG_GET_HOST_INFO 0x100
443 #define NDMP_CONFIG_GET_CONNECTION_TYPE 0x102
444 #define NDMP_CONFIG_GET_AUTH_ATTR 0x103
445 #define NDMP_CONFIG_GET_BUTYPE_INFO 0x104
446 #define NDMP_CONFIG_GET_FS_INFO 0x105
447 #define NDMP_CONFIG_GET_TAPE_INFO 0x106
448 #define NDMP_CONFIG_GET_SCSI_INFO 0x107
449 #define NDMP_CONFIG_GET_SERVER_INFO 0x108
450 #define NDMP_CONFIG_SET_EXT_LIST 0x109
451 #define NDMP_CONFIG_GET_EXT_LIST 0x10a
452 #define NDMP_SCSI_OPEN 0x200
453 #define NDMP_SCSI_CLOSE 0x201
454 #define NDMP_SCSI_GET_STATE 0x202
455 #define NDMP_SCSI_SET_TARGET 0x203
456 #define NDMP_SCSI_RESET_DEVICE 0x204
457 #define NDMP_SCSI_RESET_BUS 0x205
458 #define NDMP_SCSI_EXECUTE_CDB 0x206
459 #define NDMP_TAPE_OPEN 0x300
460 #define NDMP_TAPE_CLOSE 0x301
461 #define NDMP_TAPE_GET_STATE 0x302
462 #define NDMP_TAPE_MTIO 0x303
463 #define NDMP_TAPE_WRITE 0x304
464 #define NDMP_TAPE_READ 0x305
465 #define NDMP_TAPE_EXECUTE_CDB 0x307
466 #define NDMP_DATA_GET_STATE 0x400
467 #define NDMP_DATA_START_BACKUP 0x401
468 #define NDMP_DATA_START_RECOVER 0x402
469 #define NDMP_DATA_ABORT 0x403
470 #define NDMP_DATA_GET_ENV 0x404
471 #define NDMP_DATA_STOP 0x407
472 #define NDMP_DATA_LISTEN 0x409
473 #define NDMP_DATA_CONNECT 0x40a
474 #define NDMP_NOTIFY_DATA_HALTED 0x501
475 #define NDMP_NOTIFY_CONNECTED 0x502
476 #define NDMP_NOTIFY_MOVER_HALTED 0x503
477 #define NDMP_NOTIFY_MOVER_PAUSED 0x504
478 #define NDMP_NOTIFY_DATA_READ 0x505
479 #define NDMP_LOG_FILE 0x602
480 #define NDMP_LOG_MESSAGE 0x603
481 #define NDMP_FH_ADD_FILE 0x703
482 #define NDMP_FH_ADD_DIR 0x704
483 #define NDMP_FH_ADD_NODE 0x705
484 #define NDMP_CONNECT_OPEN 0x900
485 #define NDMP_CONNECT_CLIENT_AUTH 0x901
486 #define NDMP_CONNECT_CLOSE 0x902
487 #define NDMP_CONNECT_SERVER_AUTH 0x903
488 #define NDMP_MOVER_GET_STATE 0xa00
489 #define NDMP_MOVER_LISTEN 0xa01
490 #define NDMP_MOVER_CONTINUE 0xa02
491 #define NDMP_MOVER_ABORT 0xa03
492 #define NDMP_MOVER_STOP 0xa04
493 #define NDMP_MOVER_SET_WINDOW 0xa05
494 #define NDMP_MOVER_READ 0xa06
495 #define NDMP_MOVER_CLOSE 0xa07
496 #define NDMP_MOVER_SET_RECORD_SIZE 0xa08
497 #define NDMP_MOVER_CONNECT 0xa09
502 static const value_string msg_vals[] = {
503 {NDMP_CONFIG_GET_HOST_INFO, "CONFIG_GET_HOST_INFO"},
504 {NDMP_CONFIG_GET_CONNECTION_TYPE, "CONFIG_GET_CONNECTION_TYPE"},
505 {NDMP_CONFIG_GET_AUTH_ATTR, "CONFIG_GET_AUTH_ATTR"},
506 {NDMP_CONFIG_GET_BUTYPE_INFO, "CONFIG_GET_BUTYPE_INFO"},
507 {NDMP_CONFIG_GET_FS_INFO, "CONFIG_GET_FS_INFO"},
508 {NDMP_CONFIG_GET_TAPE_INFO, "CONFIG_GET_TAPE_INFO"},
509 {NDMP_CONFIG_GET_SCSI_INFO, "CONFIG_GET_SCSI_INFO"},
510 {NDMP_CONFIG_GET_SERVER_INFO, "CONFIG_GET_SERVER_INFO"},
511 {NDMP_CONFIG_GET_EXT_LIST, "CONFIG_GET_EXT_LIST"},
512 {NDMP_CONFIG_SET_EXT_LIST, "CONFIG_SET_EXT_LIST"},
513 {NDMP_SCSI_OPEN, "SCSI_OPEN"},
514 {NDMP_SCSI_CLOSE, "SCSI_CLOSE"},
515 {NDMP_SCSI_GET_STATE, "SCSI_GET_STATE"},
516 {NDMP_SCSI_SET_TARGET, "SCSI_SET_TARGET"},
517 {NDMP_SCSI_RESET_DEVICE, "SCSI_RESET_DEVICE"},
518 {NDMP_SCSI_RESET_BUS, "SCSI_RESET_BUS"},
519 {NDMP_SCSI_EXECUTE_CDB, "SCSI_EXECUTE_CDB"},
520 {NDMP_TAPE_OPEN, "TAPE_OPEN"},
521 {NDMP_TAPE_CLOSE, "TAPE_CLOSE"},
522 {NDMP_TAPE_GET_STATE, "TAPE_GET_STATE"},
523 {NDMP_TAPE_MTIO, "TAPE_MTIO"},
524 {NDMP_TAPE_WRITE, "TAPE_WRITE"},
525 {NDMP_TAPE_READ, "TAPE_READ"},
526 {NDMP_TAPE_EXECUTE_CDB, "TAPE_EXECUTE_CDB"},
527 {NDMP_DATA_GET_STATE, "DATA_GET_STATE"},
528 {NDMP_DATA_START_BACKUP, "DATA_START_BACKUP"},
529 {NDMP_DATA_START_RECOVER, "DATA_START_RECOVER"},
530 {NDMP_DATA_ABORT, "DATA_ABORT"},
531 {NDMP_DATA_GET_ENV, "DATA_GET_ENV"},
532 {NDMP_DATA_STOP, "DATA_STOP"},
533 {NDMP_DATA_LISTEN, "DATA_LISTEN"},
534 {NDMP_DATA_CONNECT, "DATA_CONNECT"},
535 {NDMP_NOTIFY_DATA_HALTED, "NOTIFY_DATA_HALTED"},
536 {NDMP_NOTIFY_CONNECTED, "NOTIFY_CONNECTED"},
537 {NDMP_NOTIFY_MOVER_HALTED, "NOTIFY_MOVER_HALTED"},
538 {NDMP_NOTIFY_MOVER_PAUSED, "NOTIFY_MOVER_PAUSED"},
539 {NDMP_NOTIFY_DATA_READ, "NOTIFY_DATA_READ"},
540 {NDMP_LOG_FILE, "LOG_FILE"},
541 {NDMP_LOG_MESSAGE, "LOG_MESSAGE"},
542 {NDMP_FH_ADD_FILE, "FH_ADD_FILE"},
543 {NDMP_FH_ADD_DIR, "FH_ADD_DIR"},
544 {NDMP_FH_ADD_NODE, "FH_ADD_NODE"},
545 {NDMP_CONNECT_OPEN, "CONNECT_OPEN"},
546 {NDMP_CONNECT_CLIENT_AUTH, "CONNECT_CLIENT_AUTH"},
547 {NDMP_CONNECT_CLOSE, "CONNECT_CLOSE"},
548 {NDMP_CONNECT_SERVER_AUTH, "CONNECT_SERVER_AUTH"},
549 {NDMP_MOVER_GET_STATE, "MOVER_GET_STATE"},
550 {NDMP_MOVER_LISTEN, "MOVER_LISTEN"},
551 {NDMP_MOVER_CONTINUE, "MOVER_CONTINUE"},
552 {NDMP_MOVER_ABORT, "MOVER_ABORT"},
553 {NDMP_MOVER_STOP, "MOVER_STOP"},
554 {NDMP_MOVER_SET_WINDOW, "MOVER_SET_WINDOW"},
555 {NDMP_MOVER_READ, "MOVER_READ"},
556 {NDMP_MOVER_CLOSE, "MOVER_CLOSE"},
557 {NDMP_MOVER_SET_RECORD_SIZE, "MOVER_SET_RECORD_SIZE"},
558 {NDMP_MOVER_CONNECT, "MOVER_CONNECT"},
559 {0, NULL}
562 static gboolean
563 check_ndmp_rm(tvbuff_t *tvb, packet_info *pinfo)
565 guint len;
566 guint32 tmp;
568 /* verify that the tcp port is 10000, ndmp always runs on port 10000*/
569 if ((pinfo->srcport!=TCP_PORT_NDMP)&&(pinfo->destport!=TCP_PORT_NDMP)) {
570 return FALSE;
573 /* check that the header looks sane */
574 len=tvb_length(tvb);
575 /* check the record marker that it looks sane.
576 * It has to be >=0 bytes or (arbitrary limit) <1Mbyte
578 if(len>=4){
579 tmp=(tvb_get_ntohl(tvb, 0)&RPC_RM_FRAGLEN);
580 if( (tmp<1)||(tmp>1000000) ){
581 return FALSE;
585 return TRUE;
588 static gboolean
589 check_ndmp_hdr(tvbuff_t *tvb )
591 guint len;
592 guint32 tmp;
594 len=tvb_length(tvb);
596 /* If the length is less than 24, it isn't a valid
597 header */
598 if (len<24){
599 return FALSE;
602 /* check the timestamp, timestamps are valid if they
603 * (arbitrary) lie between 1980-jan-1 and 2030-jan-1
605 if(len>=8){
606 tmp=tvb_get_ntohl(tvb, 4);
607 if( (tmp<0x12ceec50)||(tmp>0x70dc1ed0) ){
608 return FALSE;
612 /* check the type */
613 if(len>=12){
614 tmp=tvb_get_ntohl(tvb, 8);
615 if( tmp>1 ){
616 return FALSE;
620 /* check message */
621 if(len>=16){
622 tmp=tvb_get_ntohl(tvb, 12);
623 if( (tmp>0xa09) || (tmp==0) ){
624 return FALSE;
628 /* check error */
629 if(len>=24){
630 tmp=tvb_get_ntohl(tvb, 20);
631 if( (tmp>0x17) ){
632 return FALSE;
636 return TRUE;
639 static int
640 dissect_connect_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
641 proto_tree *tree, guint32 seq _U_)
643 guint32 version;
645 /* version number */
646 proto_tree_add_item(tree, hf_ndmp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
647 version=tvb_get_ntohl(tvb, offset);
648 ndmp_conv_data->version=version;
649 offset += 4;
651 return offset;
654 static int
655 dissect_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
656 proto_tree *tree, guint32 seq _U_)
658 guint32 err;
660 /* error */
661 err=tvb_get_ntohl(tvb, offset);
662 proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, ENC_BIG_ENDIAN);
663 if(err) {
664 col_append_fstr(pinfo->cinfo, COL_INFO,
665 " NDMP Error:%s ",
666 val_to_str(err, error_vals,
667 "Unknown NDMP error code %#x"));
670 offset += 4;
672 return offset;
675 static int
676 dissect_ndmp_get_host_info_reply(tvbuff_t *tvb, int offset,
677 packet_info *pinfo, proto_tree *tree, guint32 seq)
679 /* error */
680 offset=dissect_error(tvb, offset, pinfo, tree, seq);
682 /* hostname */
683 offset = dissect_rpc_string(tvb, tree,
684 hf_ndmp_hostname, offset, NULL);
686 /* os type */
687 offset = dissect_rpc_string(tvb, tree,
688 hf_ndmp_os_type, offset, NULL);
690 /* os version */
691 offset = dissect_rpc_string(tvb, tree,
692 hf_ndmp_os_vers, offset, NULL);
694 /* hostid */
695 offset = dissect_rpc_string(tvb, tree,
696 hf_ndmp_hostid, offset, NULL);
698 return offset;
701 #define NDMP_ADDR_LOCAL 0
702 #define NDMP_ADDR_TCP 1
703 #define NDMP_ADDR_FC 2
704 #define NDMP_ADDR_IPC 3
705 static const value_string addr_type_vals[] = {
706 {NDMP_ADDR_LOCAL, "Local"},
707 {NDMP_ADDR_TCP, "TCP"},
708 {NDMP_ADDR_FC, "FC"},
709 {NDMP_ADDR_IPC, "IPC"},
710 {0,NULL}
713 static int
714 dissect_ndmp_addr_type(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
715 proto_tree *tree, void* data _U_)
717 proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, ENC_BIG_ENDIAN);
718 offset += 4;
720 return offset;
723 static int
724 dissect_ndmp_addr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
725 proto_tree *tree, guint32 seq _U_)
727 /*address type*/
728 return dissect_ndmp_addr_type(tvb, offset, pinfo, tree, NULL);
731 static int
732 dissect_ndmp_config_get_connection_type_reply(tvbuff_t *tvb, int offset,
733 packet_info *pinfo, proto_tree *tree, guint32 seq)
735 /* error */
736 offset=dissect_error(tvb, offset, pinfo, tree, seq);
738 /* addr types */
739 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
740 dissect_ndmp_addr_type, hf_ndmp_addr_types);
742 return offset;
745 #define NDMP_AUTH_NONE 0
746 #define NDMP_AUTH_TEXT 1
747 #define NDMP_AUTH_MD5 2
748 static const value_string auth_type_vals[] = {
749 {NDMP_AUTH_NONE, "None"},
750 {NDMP_AUTH_TEXT, "Text"},
751 {NDMP_AUTH_MD5, "MD5"},
752 {0,NULL}
754 static int
755 dissect_auth_type(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
756 proto_tree *tree, void* data _U_)
758 proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, ENC_BIG_ENDIAN);
759 offset += 4;
761 return offset;
764 static int
765 dissect_get_auth_type_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
766 proto_tree *tree, guint32 seq _U_)
768 /* auth type */
769 return dissect_auth_type(tvb, offset, pinfo, tree, NULL);
772 static int
773 dissect_auth_attr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
774 proto_tree *tree, guint32 seq _U_)
776 guint type;
778 type=tvb_get_ntohl(tvb,offset);
780 /* auth type */
781 proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, ENC_BIG_ENDIAN);
782 offset += 4;
784 switch(type){
785 case NDMP_AUTH_NONE:
786 break;
787 case NDMP_AUTH_TEXT:
788 break;
789 case NDMP_AUTH_MD5:
790 proto_tree_add_item(tree, hf_ndmp_auth_challenge,
791 tvb, offset, 64, ENC_NA);
792 offset+=64;
795 return offset;
798 static int
799 dissect_ndmp_config_get_auth_attr_reply(tvbuff_t *tvb, int offset,
800 packet_info *pinfo, proto_tree *tree, guint32 seq)
802 /* error */
803 offset = dissect_error(tvb, offset, pinfo, tree, seq);
805 /* auth_attr */
806 offset = dissect_auth_attr_msg(tvb, offset, pinfo, tree, seq);
808 return offset;
811 static int
812 dissect_default_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
813 proto_tree *tree, void* data _U_)
815 /* name */
816 offset = dissect_rpc_string(tvb, tree,
817 hf_ndmp_butype_env_name, offset, NULL);
819 /* value */
820 offset = dissect_rpc_string(tvb, tree,
821 hf_ndmp_butype_env_value, offset, NULL);
823 return offset;
827 static const true_false_string tfs_butype_attr_backup_file_history = {
828 "Backup FILE HISTORY",
829 "Do NOT backup file history"
831 static const true_false_string tfs_butype_attr_backup_filelist = {
832 "Backup FILELIST",
833 "Do NOT backup filelist"
835 static const true_false_string tfs_butype_attr_recover_filelist = {
836 "Recover FILELIST",
837 "Do NOT recover filelist"
839 static const true_false_string tfs_butype_attr_backup_direct = {
840 "Perform DIRECT backup",
841 "Do NOT perform direct backup"
843 static const true_false_string tfs_butype_attr_recover_direct = {
844 "Perform DIRECT recovery",
845 "Do NOT perform direct recovery"
847 static const true_false_string tfs_butype_attr_backup_incremental = {
848 "Perform INCREMENTAL backup",
849 "Perform FULL backup"
851 static const true_false_string tfs_butype_attr_recover_incremental = {
852 "Perform INCREMENTAL recovery",
853 "Perform FULL recovery"
855 static const true_false_string tfs_butype_attr_backup_utf8 = {
856 "Backup using UTF8",
857 "Normal backup. Do NOT use utf8"
859 static const true_false_string tfs_butype_attr_recover_utf8 = {
860 "Recover using UTF8",
861 "Normal recover. Do NOT use utf8"
863 static int
864 dissect_butype_attrs(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
865 proto_tree *parent_tree)
867 proto_item* item = NULL;
868 proto_tree* tree = NULL;
869 guint32 flags;
871 flags=tvb_get_ntohl(tvb, offset);
872 if (parent_tree) {
873 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
874 "Attributes: 0x%08x", flags);
875 tree = proto_item_add_subtree(item, ett_ndmp_butype_attrs);
878 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_utf8,
879 tvb, offset, 4, flags);
880 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_utf8,
881 tvb, offset, 4, flags);
882 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_incremental,
883 tvb, offset, 4, flags);
884 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_incremental,
885 tvb, offset, 4, flags);
886 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_direct,
887 tvb, offset, 4, flags);
888 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_direct,
889 tvb, offset, 4, flags);
890 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_filelist,
891 tvb, offset, 4, flags);
892 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_filelist,
893 tvb, offset, 4, flags);
894 proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_file_history,
895 tvb, offset, 4, flags);
897 offset += 4;
898 return offset;
901 static int
902 dissect_butype_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
904 /*butype name*/
905 offset = dissect_rpc_string(tvb, tree,
906 hf_ndmp_butype_name, offset, NULL);
908 /* default env */
909 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
910 dissect_default_env, hf_ndmp_butype_default_env);
912 /* attrs */
913 offset = dissect_butype_attrs(tvb, offset, pinfo, tree);
915 return offset;
918 static int
919 dissect_get_butype_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
920 proto_tree *tree, guint32 seq)
922 /* error */
923 offset=dissect_error(tvb, offset, pinfo, tree, seq);
925 /* butype */
926 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
927 dissect_butype_info, hf_ndmp_butype_info);
929 return offset;
932 static const true_false_string tfs_fs_invalid_total_size = {
933 "Total size is INVALID",
934 "Total size is VALID"
936 static const true_false_string tfs_fs_invalid_used_size = {
937 "Used size is INVALID",
938 "Used size is VALID"
940 static const true_false_string tfs_fs_invalid_avail_size = {
941 "Available size is INVALID",
942 "Available size is VALID"
944 static const true_false_string tfs_fs_invalid_total_inodes = {
945 "Total inode count is INVALID",
946 "Total inode count is VALID"
948 static const true_false_string tfs_fs_invalid_used_inodes = {
949 "Used inode count is INVALID",
950 "Used inode count is VALID"
952 static int
953 dissect_fs_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
954 proto_tree *parent_tree)
956 proto_item* item = NULL;
957 proto_tree* tree = NULL;
958 guint32 flags;
960 flags=tvb_get_ntohl(tvb, offset);
961 if (parent_tree) {
962 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
963 "Invalids: 0x%08x", flags);
964 tree = proto_item_add_subtree(item, ett_ndmp_fs_invalid);
967 proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_used_inodes,
968 tvb, offset, 4, flags);
969 proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_total_inodes,
970 tvb, offset, 4, flags);
971 proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_avail_size,
972 tvb, offset, 4, flags);
973 proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_used_size,
974 tvb, offset, 4, flags);
975 proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_total_size,
976 tvb, offset, 4, flags);
978 offset+=4;
979 return offset;
982 static int
983 dissect_fs_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
984 proto_tree *tree, void* data _U_)
986 /* name */
987 offset = dissect_rpc_string(tvb, tree,
988 hf_ndmp_fs_env_name, offset, NULL);
990 /* value */
991 offset = dissect_rpc_string(tvb, tree,
992 hf_ndmp_fs_env_value, offset, NULL);
994 return offset;
997 static int
998 dissect_fs_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1000 /* invalid bits */
1001 offset=dissect_fs_invalid(tvb, offset, pinfo, tree);
1003 /* fs type */
1004 offset = dissect_rpc_string(tvb, tree,
1005 hf_ndmp_fs_fs_type, offset, NULL);
1007 /* fs logical device */
1008 offset = dissect_rpc_string(tvb, tree,
1009 hf_ndmp_fs_logical_device, offset, NULL);
1011 /* fs physical device */
1012 offset = dissect_rpc_string(tvb, tree,
1013 hf_ndmp_fs_physical_device, offset, NULL);
1015 /*total_size*/
1016 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_total_size,
1017 offset);
1019 /*used_size*/
1020 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_used_size,
1021 offset);
1023 /*avail_size*/
1024 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_avail_size,
1025 offset);
1027 /*total_inodes*/
1028 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_total_inodes,
1029 offset);
1031 /*used_inodes*/
1032 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_used_inodes,
1033 offset);
1035 /* env */
1036 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1037 dissect_fs_env, hf_ndmp_fs_env);
1039 /* status */
1040 offset = dissect_rpc_string(tvb, tree,
1041 hf_ndmp_fs_status, offset, NULL);
1043 return offset;
1046 static int
1047 dissect_get_fs_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1048 proto_tree *tree, guint32 seq)
1050 /* error */
1051 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1053 /* fs */
1054 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1055 dissect_fs_info, hf_ndmp_fs_info);
1057 return offset;
1060 static const true_false_string tfs_tape_attr_rewind = {
1061 "Device supports REWIND",
1062 "Device does NOT support rewind"
1064 static const true_false_string tfs_tape_attr_unload = {
1065 "Device supports UNLOAD",
1066 "Device does NOT support unload"
1068 static int
1069 dissect_tape_attr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1070 proto_tree *parent_tree)
1072 proto_item* item = NULL;
1073 proto_tree* tree = NULL;
1074 guint32 flags;
1076 flags=tvb_get_ntohl(tvb, offset);
1077 if (parent_tree) {
1078 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1079 "Attributes: 0x%08x", flags);
1080 tree = proto_item_add_subtree(item, ett_ndmp_tape_attr);
1083 proto_tree_add_boolean(tree, hf_ndmp_tape_attr_unload,
1084 tvb, offset, 4, flags);
1085 proto_tree_add_boolean(tree, hf_ndmp_tape_attr_rewind,
1086 tvb, offset, 4, flags);
1088 offset+=4;
1089 return offset;
1092 static int
1093 dissect_tape_capability(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1094 proto_tree *tree, void* data _U_)
1096 /* name */
1097 offset = dissect_rpc_string(tvb, tree,
1098 hf_ndmp_tape_capability_name, offset, NULL);
1100 /* value */
1101 offset = dissect_rpc_string(tvb, tree,
1102 hf_ndmp_tape_capability_value, offset, NULL);
1104 return offset;
1107 static int
1108 dissect_tape_dev_cap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1110 /* device */
1111 offset = dissect_rpc_string(tvb, tree,
1112 hf_ndmp_tape_device, offset, NULL);
1114 /* tape attributes */
1115 offset = dissect_tape_attr(tvb, offset, pinfo, tree);
1117 /* capability */
1118 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1119 dissect_tape_capability, hf_ndmp_tape_capability);
1121 return offset;
1124 static int
1125 dissect_tape_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1127 /* model */
1128 offset = dissect_rpc_string(tvb, tree,
1129 hf_ndmp_tape_model, offset, NULL);
1131 /* device capabilites */
1132 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1133 dissect_tape_dev_cap, hf_ndmp_tape_dev_cap);
1135 return offset;
1138 static int
1139 dissect_get_tape_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1140 proto_tree *tree, guint32 seq)
1142 /* error */
1143 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1145 /* tape */
1146 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1147 dissect_tape_info, hf_ndmp_tape_info);
1149 return offset;
1152 static int
1153 dissect_scsi_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1155 /* model */
1156 offset = dissect_rpc_string(tvb, tree,
1157 hf_ndmp_scsi_model, offset, NULL);
1159 /* device capabilites */
1160 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1161 dissect_tape_dev_cap, hf_ndmp_tape_dev_cap);
1163 return offset;
1166 static int
1167 dissect_get_scsi_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1168 proto_tree *tree, guint32 seq)
1170 /* error */
1171 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1173 /* scsi */
1174 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1175 dissect_scsi_info, hf_ndmp_scsi_info);
1177 return offset;
1180 static int
1181 dissect_get_server_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1182 proto_tree *tree, guint32 seq)
1184 /* error */
1185 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1187 /* vendor */
1188 offset = dissect_rpc_string(tvb, tree,
1189 hf_ndmp_server_vendor, offset, NULL);
1191 /* product */
1192 offset = dissect_rpc_string(tvb, tree,
1193 hf_ndmp_server_product, offset, NULL);
1195 /* revision */
1196 offset = dissect_rpc_string(tvb, tree,
1197 hf_ndmp_server_revision, offset, NULL);
1200 /* server */
1201 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1202 dissect_auth_type, hf_ndmp_auth_types);
1204 return offset;
1207 static int
1208 dissect_ext_version(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1209 proto_tree *tree, void* data _U_) {
1211 /* extension version */
1212 proto_tree_add_item(tree, hf_ndmp_ext_version, tvb, offset, 4, ENC_BIG_ENDIAN);
1213 offset += 4;
1215 return offset;
1219 static int
1220 dissect_class_list(tvbuff_t *tvb, int offset, packet_info *pinfo,
1221 proto_tree *tree, void* data _U_) {
1223 /* class id */
1224 proto_tree_add_item(tree, hf_ndmp_ex_class_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1225 offset += 4;
1227 /* ext version */
1228 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1229 dissect_ext_version, hf_ndmp_ext_version_list);
1231 return offset;
1234 static int
1235 dissect_get_ext_list_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1236 proto_tree *tree, guint32 seq)
1238 /* error */
1239 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1241 /* Class list */
1242 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1243 dissect_class_list, hf_ndmp_class_list);
1245 return offset;
1249 static int
1250 dissect_class_version(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1251 proto_tree *tree, void* data _U_) {
1253 /* class id */
1254 proto_tree_add_item(tree, hf_ndmp_ex_class_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1255 offset += 4;
1257 /* ext version */
1258 proto_tree_add_item(tree, hf_ndmp_ex_class_version, tvb, offset, 4, ENC_BIG_ENDIAN);
1259 offset += 4;
1261 return offset;
1264 static int
1265 dissect_set_ext_list_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1266 proto_tree *tree, guint32 seq _U_)
1268 /* class version */
1269 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1270 dissect_class_version, hf_ndmp_class_version);
1272 return offset;
1276 static int
1277 dissect_set_ext_list_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1278 proto_tree *tree, guint32 seq _U_)
1280 /* error */
1281 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1283 return offset;
1286 static int
1287 dissect_scsi_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1288 proto_tree *tree, guint32 seq _U_)
1290 /* device */
1291 offset = dissect_rpc_string(tvb, tree,
1292 hf_ndmp_scsi_device, offset, NULL);
1295 if(!pinfo->fd->flags.visited){
1296 /* new scsi device addressed, create a new itl structure */
1297 get_itl_nexus(pinfo, TRUE);
1300 return offset;
1303 static int
1304 dissect_scsi_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1305 proto_tree *tree, guint32 seq)
1307 /* error */
1308 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1310 /* controller */
1311 proto_tree_add_item(tree, hf_ndmp_scsi_controller, tvb, offset, 4, ENC_BIG_ENDIAN);
1312 offset += 4;
1314 /* id */
1315 proto_tree_add_item(tree, hf_ndmp_scsi_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1316 offset += 4;
1318 /* lun */
1319 proto_tree_add_item(tree, hf_ndmp_scsi_lun, tvb, offset, 4, ENC_BIG_ENDIAN);
1320 offset += 4;
1322 return offset;
1325 static int
1326 dissect_scsi_set_state_request(tvbuff_t *tvb, int offset,
1327 packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
1329 /* device */
1330 offset = dissect_rpc_string(tvb, tree,
1331 hf_ndmp_scsi_device, offset, NULL);
1333 /* controller */
1334 proto_tree_add_item(tree, hf_ndmp_scsi_controller, tvb, offset, 4, ENC_BIG_ENDIAN);
1335 offset += 4;
1337 /* id */
1338 proto_tree_add_item(tree, hf_ndmp_scsi_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1339 offset += 4;
1341 /* lun */
1342 proto_tree_add_item(tree, hf_ndmp_scsi_lun, tvb, offset, 4, ENC_BIG_ENDIAN);
1343 offset += 4;
1345 return offset;
1348 static int
1349 dissect_execute_cdb_flags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1350 proto_tree *parent_tree)
1352 proto_item* item = NULL;
1353 proto_tree* tree = NULL;
1354 guint32 flags;
1356 flags = tvb_get_ntohl(tvb, offset);
1357 if (parent_tree) {
1358 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1359 "Flags: 0x%08x", flags);
1360 tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_flags);
1363 proto_tree_add_boolean(tree, hf_ndmp_execute_cdb_flags_data_in,
1364 tvb, offset, 4, flags);
1365 proto_tree_add_boolean(tree, hf_ndmp_execute_cdb_flags_data_out,
1366 tvb, offset, 4, flags);
1367 offset += 4;
1368 return offset;
1371 static int
1372 dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo,
1373 proto_tree *parent_tree, gint devtype)
1375 proto_item* item = NULL;
1376 proto_tree* tree = NULL;
1377 guint32 cdb_len;
1378 guint32 cdb_len_full;
1380 cdb_len = tvb_get_ntohl(tvb, offset);
1381 cdb_len_full = rpc_roundup(cdb_len);
1383 if (parent_tree) {
1384 item = proto_tree_add_text(parent_tree, tvb, offset,
1385 4+cdb_len_full, "CDB");
1386 tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_cdb);
1389 proto_tree_add_uint(tree, hf_ndmp_execute_cdb_cdb_len, tvb, offset, 4,
1390 cdb_len);
1391 offset += 4;
1393 if (cdb_len != 0) {
1394 tvbuff_t *cdb_tvb;
1395 int tvb_len, tvb_rlen;
1397 tvb_len=tvb_length_remaining(tvb, offset);
1398 if(tvb_len>16)
1399 tvb_len=16;
1400 tvb_rlen=tvb_reported_length_remaining(tvb, offset);
1401 if(tvb_rlen>16)
1402 tvb_rlen=16;
1403 cdb_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
1405 if(ndmp_conv_data->task && !ndmp_conv_data->task->itlq){
1406 ndmp_conv_data->task->itlq=wmem_new(wmem_file_scope(), itlq_nexus_t);
1407 ndmp_conv_data->task->itlq->lun=0xffff;
1408 ndmp_conv_data->task->itlq->first_exchange_frame=pinfo->fd->num;
1409 ndmp_conv_data->task->itlq->last_exchange_frame=0;
1410 ndmp_conv_data->task->itlq->scsi_opcode=0xffff;
1411 ndmp_conv_data->task->itlq->task_flags=0;
1412 ndmp_conv_data->task->itlq->data_length=0;
1413 ndmp_conv_data->task->itlq->bidir_data_length=0;
1414 ndmp_conv_data->task->itlq->flags=0;
1415 ndmp_conv_data->task->itlq->alloc_len=0;
1416 ndmp_conv_data->task->itlq->fc_time=pinfo->fd->abs_ts;
1417 ndmp_conv_data->task->itlq->extra_data=NULL;
1419 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1420 dissect_scsi_cdb(cdb_tvb, pinfo, top_tree, devtype, ndmp_conv_data->task->itlq, get_itl_nexus(pinfo, FALSE));
1422 offset += cdb_len_full;
1425 return offset;
1429 static int
1430 dissect_execute_cdb_payload(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree,
1431 const char *name, int hf_len, gboolean isreq)
1433 proto_item* item = NULL;
1434 proto_tree* tree = NULL;
1435 guint32 payload_len;
1436 guint32 payload_len_full;
1438 payload_len = tvb_get_ntohl(tvb, offset);
1439 payload_len_full = rpc_roundup(payload_len);
1441 if (parent_tree) {
1442 item = proto_tree_add_text(parent_tree, tvb, offset,
1443 4+payload_len_full, "%s", name);
1444 tree = proto_item_add_subtree(item,
1445 ett_ndmp_execute_cdb_payload);
1448 proto_tree_add_uint(tree, hf_len, tvb, offset, 4, payload_len);
1449 offset += 4;
1451 if ((int) payload_len > 0) {
1452 tvbuff_t *data_tvb;
1453 int tvb_len, tvb_rlen;
1455 tvb_len=tvb_length_remaining(tvb, offset);
1456 if(tvb_len>(int)payload_len)
1457 tvb_len=payload_len;
1458 tvb_rlen=tvb_reported_length_remaining(tvb, offset);
1459 if(tvb_rlen>(int)payload_len)
1460 tvb_rlen=payload_len;
1461 data_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
1463 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1464 /* ndmp conceptually always send both read and write
1465 * data and always a full nonfragmented pdu
1467 ndmp_conv_data->task->itlq->task_flags=SCSI_DATA_READ|SCSI_DATA_WRITE;
1468 ndmp_conv_data->task->itlq->data_length=payload_len;
1469 ndmp_conv_data->task->itlq->bidir_data_length=payload_len;
1470 dissect_scsi_payload(data_tvb, pinfo, top_tree, isreq,
1471 ndmp_conv_data->task->itlq,
1472 get_itl_nexus(pinfo, FALSE),
1475 offset += payload_len_full;
1478 return offset;
1482 * XXX - we assume that NDMP_SCSI_EXECUTE_CDB requests only go to SCSI Media
1483 * Changer devices and NDMP_TAPE_EXECUTE_CDB only go to SCSI Sequential
1484 * Access devices.
1486 * If that's not the case, we'll have to use the SCSI dissector's mechanisms
1487 * for saving inquiry data for devices, and use inquiry data when available.
1488 * Unfortunately, that means we need to save the name of the device, and
1489 * use it as a device identifier; as the name isn't available in the
1490 * NDMP_SCSI_EXECUTE_CDB or NDMP_TAPE_EXECUTE_CDB messages, that means
1491 * we need to remember the currently-opened "SCSI" and "TAPE" devices
1492 * from NDMP_SCSI_OPEN and NDMP_TAPE_OPEN, and attach to all frames
1493 * that are the ones that trigger the dissection of NDMP_SCSI_EXECUTE_CDB
1494 * or NDMP_TAPE_EXECUTE_CDB requests pointers to those names.
1496 static int
1497 dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1498 proto_tree *tree, guint32 seq _U_, gint devtype)
1500 /* flags */
1501 offset = dissect_execute_cdb_flags(tvb, offset, pinfo, tree);
1503 /* timeout */
1504 proto_tree_add_item(tree, hf_ndmp_execute_cdb_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
1505 offset += 4;
1507 /* datain_len */
1508 proto_tree_add_item(tree, hf_ndmp_execute_cdb_datain_len, tvb, offset, 4, ENC_BIG_ENDIAN);
1509 offset += 4;
1511 /* CDB */
1512 offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree, devtype);
1514 /* dataout */
1515 offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
1516 "Data out", hf_ndmp_execute_cdb_dataout_len, TRUE);
1518 return offset;
1521 static int
1522 dissect_execute_cdb_request_mc(tvbuff_t *tvb, int offset, packet_info *pinfo,
1523 proto_tree *tree, guint32 seq)
1525 return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
1526 SCSI_DEV_SMC);
1529 static int
1530 dissect_execute_cdb_request_tape(tvbuff_t *tvb, int offset, packet_info *pinfo,
1531 proto_tree *tree, guint32 seq)
1533 return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
1534 SCSI_DEV_SSC);
1537 static int
1538 dissect_execute_cdb_sns(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1540 proto_item* item = NULL;
1541 proto_tree* tree = NULL;
1542 guint32 sns_len;
1543 guint32 sns_len_full;
1545 sns_len = tvb_get_ntohl(tvb, offset);
1546 sns_len_full = rpc_roundup(sns_len);
1548 if (parent_tree) {
1549 item = proto_tree_add_text(parent_tree, tvb, offset,
1550 4+sns_len_full, "Sense data");
1551 tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_sns);
1554 proto_tree_add_uint(tree, hf_ndmp_execute_cdb_sns_len, tvb, offset, 4,
1555 sns_len);
1556 offset += 4;
1558 if (sns_len != 0) {
1559 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1560 dissect_scsi_snsinfo(tvb, pinfo, top_tree, offset, sns_len, ndmp_conv_data->task->itlq, get_itl_nexus(pinfo, FALSE));
1562 offset += sns_len_full;
1565 return offset;
1568 static int
1569 dissect_execute_cdb_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1570 proto_tree *tree, guint32 seq)
1572 guint32 status;
1574 /* error */
1575 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1577 /* status */
1578 proto_tree_add_item(tree, hf_ndmp_execute_cdb_status, tvb, offset, 4, ENC_BIG_ENDIAN);
1579 status=tvb_get_ntohl(tvb, offset);
1580 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1581 dissect_scsi_rsp(tvb, pinfo, top_tree, ndmp_conv_data->task->itlq, get_itl_nexus(pinfo, FALSE), (guint8)status);
1583 offset += 4;
1586 /* dataout_len */
1587 proto_tree_add_item(tree, hf_ndmp_execute_cdb_dataout_len, tvb, offset, 4, ENC_BIG_ENDIAN);
1588 offset += 4;
1590 /* datain */
1591 offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
1592 "Data in", hf_ndmp_execute_cdb_datain_len, FALSE);
1594 /* ext_sense */
1595 offset = dissect_execute_cdb_sns(tvb, offset, pinfo, tree);
1597 return offset;
1600 #define NDMP_TAPE_OPEN_MODE_READ 0
1601 #define NDMP_TAPE_OPEN_MODE_RDWR 1
1602 static const value_string tape_open_mode_vals[] = {
1603 {NDMP_TAPE_OPEN_MODE_READ, "Read"},
1604 {NDMP_TAPE_OPEN_MODE_RDWR, "Read/Write"},
1605 {0, NULL}
1608 static int
1609 dissect_tape_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1610 proto_tree *tree, guint32 seq _U_)
1612 /* device */
1613 offset = dissect_rpc_string(tvb, tree,
1614 hf_ndmp_tape_device, offset, NULL);
1616 /* open mode */
1617 proto_tree_add_item(tree, hf_ndmp_tape_open_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
1618 offset += 4;
1620 if(!pinfo->fd->flags.visited){
1621 /* new scsi device addressed, create a new itl structure */
1622 get_itl_nexus(pinfo, TRUE);
1625 return offset;
1629 static const true_false_string tfs_ndmp_tape_invalid_file_num = {
1630 "File num is INVALID",
1631 "File num is VALID"
1633 static const true_false_string tfs_ndmp_tape_invalid_soft_errors = {
1634 "Soft errors is INVALID",
1635 "Soft errors is VALID"
1637 static const true_false_string tfs_ndmp_tape_invalid_block_size = {
1638 "Block size is INVALID",
1639 "Block size is VALID"
1641 static const true_false_string tfs_ndmp_tape_invalid_block_no = {
1642 "Block no is INVALID",
1643 "Block no is VALID"
1645 static const true_false_string tfs_ndmp_tape_invalid_total_space = {
1646 "Total space is INVALID",
1647 "Total space is VALID"
1649 static const true_false_string tfs_ndmp_tape_invalid_space_remain = {
1650 "Space remaining is INVALID",
1651 "Space remaining is VALID"
1653 static const true_false_string tfs_ndmp_tape_invalid_partition = {
1654 "Partition is INVALID",
1655 "Partition is VALID"
1657 static int
1658 dissect_tape_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1659 proto_tree *parent_tree)
1661 proto_item* item = NULL;
1662 proto_tree* tree = NULL;
1663 guint32 flags;
1665 flags=tvb_get_ntohl(tvb, offset);
1666 if (parent_tree) {
1667 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1668 "Invalids: 0x%08x", flags);
1669 tree = proto_item_add_subtree(item, ett_ndmp_tape_invalid);
1672 proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_partition,
1673 tvb, offset, 4, flags);
1674 proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_space_remain,
1675 tvb, offset, 4, flags);
1676 proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_total_space,
1677 tvb, offset, 4, flags);
1678 proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_block_no,
1679 tvb, offset, 4, flags);
1680 proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_block_size,
1681 tvb, offset, 4, flags);
1682 proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_soft_errors,
1683 tvb, offset, 4, flags);
1684 proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_file_num,
1685 tvb, offset, 4, flags);
1687 offset+=4;
1688 return offset;
1691 static const true_false_string tfs_ndmp_tape_flags_no_rewind = {
1692 "This is a NON-REWINDING device",
1693 "This device supports rewind"
1695 static const true_false_string tfs_ndmp_tape_flags_write_protect = {
1696 "This device is WRITE-PROTECTED",
1697 "This device is NOT write-protected"
1699 static const true_false_string tfs_ndmp_tape_flags_error = {
1700 "This device shows ERROR",
1701 "This device shows NO errors"
1703 static const true_false_string tfs_ndmp_tape_flags_unload = {
1704 "This device supports UNLOAD",
1705 "This device does NOT support unload"
1707 static int
1708 dissect_tape_flags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1709 proto_tree *parent_tree)
1711 proto_item* item = NULL;
1712 proto_tree* tree = NULL;
1713 guint32 flags;
1715 flags=tvb_get_ntohl(tvb, offset);
1716 if (parent_tree) {
1717 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1718 "Flags: 0x%08x", flags);
1719 tree = proto_item_add_subtree(item, ett_ndmp_tape_flags);
1723 proto_tree_add_boolean(tree, hf_ndmp_tape_flags_unload,
1724 tvb, offset, 4, flags);
1725 proto_tree_add_boolean(tree, hf_ndmp_tape_flags_error,
1726 tvb, offset, 4, flags);
1727 proto_tree_add_boolean(tree, hf_ndmp_tape_flags_write_protect,
1728 tvb, offset, 4, flags);
1729 proto_tree_add_boolean(tree, hf_ndmp_tape_flags_no_rewind,
1730 tvb, offset, 4, flags);
1732 offset+=4;
1733 return offset;
1736 static int
1737 dissect_tape_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1738 proto_tree *tree, guint32 seq)
1740 /* invalid bits */
1741 offset=dissect_tape_invalid(tvb, offset, pinfo, tree);
1743 /* error */
1744 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1746 /* flags */
1747 offset=dissect_tape_flags(tvb, offset, pinfo, tree);
1749 /* file_num */
1750 proto_tree_add_item(tree, hf_ndmp_tape_file_num, tvb, offset, 4, ENC_BIG_ENDIAN);
1751 offset += 4;
1753 /* soft_errors */
1754 proto_tree_add_item(tree, hf_ndmp_tape_soft_errors, tvb, offset, 4, ENC_BIG_ENDIAN);
1755 offset += 4;
1757 /* block_size */
1758 proto_tree_add_item(tree, hf_ndmp_tape_block_size, tvb, offset, 4, ENC_BIG_ENDIAN);
1759 offset += 4;
1761 /* block_no */
1762 proto_tree_add_item(tree, hf_ndmp_tape_block_no, tvb, offset, 4, ENC_BIG_ENDIAN);
1763 offset += 4;
1765 /* total_space */
1766 offset = dissect_rpc_uint64(tvb, tree,hf_ndmp_tape_total_space,
1767 offset);
1769 /* space_remain */
1770 offset = dissect_rpc_uint64(tvb, tree,hf_ndmp_tape_space_remain,
1771 offset);
1773 /* NDMP Version 4 does not have a partition field here, so just return now. */
1774 if (get_ndmp_protocol_version() == NDMP_PROTOCOL_V4)
1775 return offset;
1777 /* partition */
1778 proto_tree_add_item(tree, hf_ndmp_tape_partition, tvb, offset, 4, ENC_BIG_ENDIAN);
1779 offset += 4;
1781 return offset;
1784 #define NDMP_TAPE_MTIO_FSF 0
1785 #define NDMP_TAPE_MTIO_BSF 1
1786 #define NDMP_TAPE_MTIO_FSR 2
1787 #define NDMP_TAPE_MTIO_BSR 3
1788 #define NDMP_TAPE_MTIO_REW 4
1789 #define NDMP_TAPE_MTIO_EOF 5
1790 #define NDMP_TAPE_MTIO_OFF 6
1791 static const value_string tape_mtio_vals[] = {
1792 {NDMP_TAPE_MTIO_FSF, "FSF"},
1793 {NDMP_TAPE_MTIO_BSF, "BSF"},
1794 {NDMP_TAPE_MTIO_FSR, "FSR"},
1795 {NDMP_TAPE_MTIO_BSR, "BSR"},
1796 {NDMP_TAPE_MTIO_REW, "REW"},
1797 {NDMP_TAPE_MTIO_EOF, "EOF"},
1798 {NDMP_TAPE_MTIO_OFF, "OFF"},
1799 {0, NULL}
1802 static int
1803 dissect_tape_mtio_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1804 proto_tree *tree, guint32 seq _U_)
1806 /* op */
1807 proto_tree_add_item(tree, hf_ndmp_tape_mtio_op, tvb, offset, 4, ENC_BIG_ENDIAN);
1808 offset += 4;
1810 /* count */
1811 proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, ENC_BIG_ENDIAN);
1812 offset += 4;
1814 return offset;
1817 static int
1818 dissect_tape_mtio_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1819 proto_tree *tree, guint32 seq)
1821 /* error */
1822 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1824 /* resid count */
1825 proto_tree_add_item(tree, hf_ndmp_resid_count, tvb, offset, 4, ENC_BIG_ENDIAN);
1826 offset += 4;
1828 return offset;
1831 #define NDMP_MOVER_STATE_IDLE 0
1832 #define NDMP_MOVER_STATE_LISTEN 1
1833 #define NDMP_MOVER_STATE_ACTIVE 2
1834 #define NDMP_MOVER_STATE_PAUSED 3
1835 #define NDMP_MOVER_STATE_HALTED 4
1836 static const value_string mover_state_vals[] = {
1837 {NDMP_MOVER_STATE_IDLE, "MOVER_STATE_IDLE"},
1838 {NDMP_MOVER_STATE_LISTEN, "MOVER_STATE_LISTEN"},
1839 {NDMP_MOVER_STATE_ACTIVE, "MOVER_STATE_ACTIVE"},
1840 {NDMP_MOVER_STATE_PAUSED, "MOVER_STATE_PAUSED"},
1841 {NDMP_MOVER_STATE_HALTED, "MOVER_STATE_HALTED"},
1842 {0, NULL}
1845 #define NDMP_MOVER_PAUSE_NA 0
1846 #define NDMP_MOVER_PAUSE_EOM 1
1847 #define NDMP_MOVER_PAUSE_EOF 2
1848 #define NDMP_MOVER_PAUSE_SEEK 3
1849 #define NDMP_MOVER_PAUSE_MEDIA_ERROR 4
1850 #define NDMP_MOVER_PAUSE_EOW 5
1851 static const value_string mover_pause_vals[] = {
1852 {NDMP_MOVER_PAUSE_NA, "MOVER_PAUSE_NA"},
1853 {NDMP_MOVER_PAUSE_EOM, "MOVER_PAUSE_EOM"},
1854 {NDMP_MOVER_PAUSE_EOF, "MOVER_PAUSE_EOF"},
1855 {NDMP_MOVER_PAUSE_SEEK, "MOVER_PAUSE_SEEK"},
1856 {NDMP_MOVER_PAUSE_MEDIA_ERROR, "MOVER_PAUSE_MEDIA_ERROR"},
1857 {NDMP_MOVER_PAUSE_EOW, "MOVER_PAUSE_EOW"},
1858 {0, NULL}
1861 #define NDMP_HALT_NA 0
1862 #define NDMP_HALT_CONNECT_CLOSE 1
1863 #define NDMP_HALT_ABORTED 2
1864 #define NDMP_HALT_INTERNAL_ERROR 3
1865 #define NDMP_HALT_CONNECT_ERROR 4
1866 static const value_string halt_vals[] = {
1867 {NDMP_HALT_NA, "HALT_NA"},
1868 {NDMP_HALT_CONNECT_CLOSE, "HALT_CONNECT_CLOSE"},
1869 {NDMP_HALT_ABORTED, "HALT_ABORTED"},
1870 {NDMP_HALT_INTERNAL_ERROR, "HALT_INTERNAL_ERROR"},
1871 {NDMP_HALT_CONNECT_ERROR, "HALT_CONNECT_ERROR"},
1872 {0, NULL}
1875 static int
1876 dissect_tcp_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1878 /* name */
1879 offset = dissect_rpc_string(tvb, tree,
1880 hf_ndmp_tcp_env_name, offset, NULL);
1882 /* value */
1883 offset = dissect_rpc_string(tvb, tree,
1884 hf_ndmp_tcp_env_value, offset, NULL);
1886 return offset;
1890 static int
1891 dissect_ndmp_v4_tcp_addr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1893 /* IP addr */
1894 proto_tree_add_item(tree, hf_ndmp_addr_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1895 offset+=4;
1897 /* TCP port */
1898 proto_tree_add_item(tree, hf_ndmp_addr_tcp, tvb, offset, 4, ENC_BIG_ENDIAN);
1899 offset+=4;
1901 /* addr_env */
1902 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1903 dissect_tcp_env, hf_ndmp_tcp_default_env);
1905 return offset;
1908 static int
1909 dissect_ndmp_addr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1910 proto_tree *parent_tree)
1912 proto_item* item = NULL;
1913 proto_tree* tree = NULL;
1914 guint32 type;
1916 type=tvb_get_ntohl(tvb, offset);
1917 if (parent_tree) {
1918 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1919 "Type: %s ", val_to_str(type, addr_type_vals,"Unknown addr type (0x%02x)") );
1920 tree = proto_item_add_subtree(item, ett_ndmp_addr);
1923 /*address type*/
1924 proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1925 offset += 4;
1928 switch(type){
1929 case NDMP_ADDR_LOCAL:
1930 break;
1931 case NDMP_ADDR_TCP:
1932 /* this became an array in version 4 and beyond */
1933 if(get_ndmp_protocol_version()<NDMP_PROTOCOL_V4){
1934 /* IP addr */
1935 proto_tree_add_item(tree, hf_ndmp_addr_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1936 offset+=4;
1938 /* TCP port */
1939 proto_tree_add_item(tree, hf_ndmp_addr_tcp, tvb, offset, 4, ENC_BIG_ENDIAN);
1940 offset+=4;
1941 } else {
1942 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1943 dissect_ndmp_v4_tcp_addr, hf_ndmp_tcp_addr_list);
1947 break;
1948 case NDMP_ADDR_FC:
1949 /* FCAL loop id */
1950 proto_tree_add_item(tree, hf_ndmp_addr_fcal_loop_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1951 offset+=4;
1953 break;
1954 case NDMP_ADDR_IPC:
1955 /* IPC address */
1956 offset = dissect_rpc_data(tvb, tree, hf_ndmp_addr_ipc, offset);
1957 break;
1960 return offset;
1963 static int
1964 dissect_data_connect_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
1965 proto_tree *tree, guint32 seq _U_)
1967 /* ndmp addr */
1968 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
1969 return offset;
1973 static int
1974 dissect_mover_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1975 proto_tree *tree, guint32 seq)
1977 /* error */
1978 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1980 /* mode is only present in version 4 and beyond */
1981 if(get_ndmp_protocol_version()>=NDMP_PROTOCOL_V4){
1982 proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
1983 offset += 4;
1986 /* mover state */
1987 proto_tree_add_item(tree, hf_ndmp_mover_state, tvb, offset, 4, ENC_BIG_ENDIAN);
1988 offset += 4;
1990 /* mover pause */
1991 proto_tree_add_item(tree, hf_ndmp_mover_pause, tvb, offset, 4, ENC_BIG_ENDIAN);
1992 offset += 4;
1994 /* halt */
1995 proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, ENC_BIG_ENDIAN);
1996 offset += 4;
1998 /* record size */
1999 proto_tree_add_item(tree, hf_ndmp_record_size, tvb, offset, 4, ENC_BIG_ENDIAN);
2000 offset += 4;
2002 /* record num */
2003 proto_tree_add_item(tree, hf_ndmp_record_num, tvb, offset, 4, ENC_BIG_ENDIAN);
2004 offset += 4;
2006 /* data written */
2007 proto_tree_add_item(tree, hf_ndmp_data_written, tvb, offset, 8, ENC_BIG_ENDIAN);
2008 offset += 8;
2010 /* seek position */
2011 proto_tree_add_item(tree, hf_ndmp_seek_position, tvb, offset, 8, ENC_BIG_ENDIAN);
2012 offset += 8;
2014 /* bytes left to read */
2015 proto_tree_add_item(tree, hf_ndmp_bytes_left_to_read, tvb, offset, 8, ENC_BIG_ENDIAN);
2016 offset += 8;
2018 /* window offset */
2019 proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
2020 offset += 8;
2022 /* window length */
2023 proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, ENC_BIG_ENDIAN);
2024 offset += 8;
2026 /* this is where v2 ends */
2027 if(get_ndmp_protocol_version()==NDMP_PROTOCOL_V2){
2028 return offset;
2032 /* ndmp addr */
2033 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2035 return offset;
2038 #define NDMP_MOVER_MODE_READ 0
2039 #define NDMP_MOVER_MODE_WRITE 1
2040 #define NDMP_MOVER_MODE_NOACTION 2
2041 static const value_string mover_mode_vals[] = {
2042 {NDMP_MOVER_MODE_READ, "MOVER_MODE_READ"},
2043 {NDMP_MOVER_MODE_WRITE, "MOVER_MODE_WRITE"},
2044 {NDMP_MOVER_MODE_NOACTION, "MOVER_MODE_NOACTION"},
2045 {0, NULL}
2048 static int
2049 dissect_mover_listen_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2050 proto_tree *tree, guint32 seq _U_)
2052 /* mode */
2053 proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
2054 offset += 4;
2056 /*address type*/
2057 proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2058 offset += 4;
2060 return offset;
2063 static int
2064 dissect_mover_listen_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2065 proto_tree *tree, guint32 seq)
2067 /* error */
2068 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2070 /* ndmp addr */
2071 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2073 return offset;
2076 static int
2077 dissect_mover_set_window_request(tvbuff_t *tvb, int offset,
2078 packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
2080 /* window offset */
2081 proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
2082 offset += 8;
2084 /* window length */
2085 proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, ENC_BIG_ENDIAN);
2086 offset += 8;
2088 return offset;
2091 static int
2092 dissect_mover_set_record_size_request(tvbuff_t *tvb, int offset,
2093 packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
2095 /* record size */
2096 proto_tree_add_item(tree, hf_ndmp_record_size, tvb, offset, 4, ENC_BIG_ENDIAN);
2097 offset += 4;
2099 return offset;
2102 static int
2103 dissect_mover_connect_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2104 proto_tree *tree, guint32 seq _U_)
2106 /* mode */
2107 proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
2108 offset += 4;
2110 /* ndmp addr */
2111 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2113 return offset;
2116 static int
2117 dissect_log_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2118 proto_tree *tree, guint32 seq)
2120 /* file */
2121 offset = dissect_rpc_string(tvb, tree,
2122 hf_ndmp_file_name, offset, NULL);
2124 /* error */
2125 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2127 return offset;
2130 #define NDMP_LOG_TYPE_NORMAL 0
2131 #define NDMP_LOG_TYPE_DEBUG 1
2132 #define NDMP_LOG_TYPE_ERROR 2
2133 #define NDMP_LOG_TYPE_WARNING 3
2134 static const value_string log_type_vals[] = {
2135 {NDMP_LOG_TYPE_NORMAL, "NORMAL"},
2136 {NDMP_LOG_TYPE_DEBUG, "DEBUG"},
2137 {NDMP_LOG_TYPE_ERROR, "ERROR"},
2138 {NDMP_LOG_TYPE_WARNING, "WARNING"},
2139 {0, NULL}
2142 static int
2143 dissect_log_message_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2144 proto_tree *tree, guint32 seq _U_)
2146 /* type */
2147 proto_tree_add_item(tree, hf_ndmp_log_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2148 offset += 4;
2150 /* message id */
2151 proto_tree_add_item(tree, hf_ndmp_log_message_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2152 offset += 4;
2154 /* message */
2155 offset = dissect_rpc_string(tvb, tree,
2156 hf_ndmp_log_message, offset, NULL);
2158 return offset;
2161 static int
2162 dissect_notify_data_halted_request(tvbuff_t *tvb, int offset,
2163 packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
2165 /* halt */
2166 proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, ENC_BIG_ENDIAN);
2167 offset += 4;
2169 switch(get_ndmp_protocol_version()){
2170 case NDMP_PROTOCOL_V2:
2171 case NDMP_PROTOCOL_V3:
2172 /* reason : only in version 2, 3 */
2173 offset = dissect_rpc_string(tvb, tree,
2174 hf_ndmp_halt_reason, offset, NULL);
2175 break;
2178 return offset;
2181 static int
2182 dissect_notify_mover_halted_request(tvbuff_t *tvb, int offset,
2183 packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
2185 /* halt */
2186 proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, ENC_BIG_ENDIAN);
2187 offset += 4;
2189 switch(get_ndmp_protocol_version()){
2190 case NDMP_PROTOCOL_V2:
2191 case NDMP_PROTOCOL_V3:
2192 /* reason : only in version 2, 3 */
2193 offset = dissect_rpc_string(tvb, tree,
2194 hf_ndmp_halt_reason, offset, NULL);
2195 break;
2198 return offset;
2201 #define NDMP_CONNECTED_CONNECTED 0
2202 #define NDMP_CONNECTED_SHUTDOWN 1
2203 #define NDMP_CONNECTED_REFUSED 2
2204 static const value_string connected_vals[] = {
2205 {NDMP_CONNECTED_CONNECTED, "CONNECTED"},
2206 {NDMP_CONNECTED_SHUTDOWN, "SHUTDOWN"},
2207 {NDMP_CONNECTED_REFUSED, "REFUSED"},
2208 {0, NULL}
2211 static int
2212 dissect_notify_connected_request(tvbuff_t *tvb, int offset,
2213 packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
2215 /* connected */
2216 proto_tree_add_item(tree, hf_ndmp_connected, tvb, offset, 4, ENC_BIG_ENDIAN);
2217 offset += 4;
2219 /* version number */
2220 proto_tree_add_item(tree, hf_ndmp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
2221 offset += 4;
2223 /* reason */
2224 offset = dissect_rpc_string(tvb, tree,
2225 hf_ndmp_connected_reason, offset, NULL);
2227 return offset;
2231 static int
2232 dissect_notify_mover_paused_request(tvbuff_t *tvb, int offset,
2233 packet_info *pinfo _U_, proto_tree *tree, guint32 seq _U_)
2235 /* mover pause */
2236 proto_tree_add_item(tree, hf_ndmp_mover_pause, tvb, offset, 4, ENC_BIG_ENDIAN);
2237 offset += 4;
2239 /* seek position */
2240 proto_tree_add_item(tree, hf_ndmp_seek_position, tvb, offset, 8, ENC_BIG_ENDIAN);
2241 offset += 8;
2243 return offset;
2246 static int
2247 dissect_auth_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2248 proto_tree *tree)
2250 guint type;
2252 type=tvb_get_ntohl(tvb,offset);
2254 /* auth type */
2255 proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2256 offset += 4;
2258 switch(type){
2259 case NDMP_AUTH_NONE:
2260 break;
2261 case NDMP_AUTH_TEXT:
2262 /* auth id */
2263 offset = dissect_rpc_string(tvb, tree,
2264 hf_ndmp_auth_id, offset, NULL);
2266 /* auth password */
2267 offset = dissect_rpc_string(tvb, tree,
2268 hf_ndmp_auth_password, offset, NULL);
2271 break;
2272 case NDMP_AUTH_MD5:
2273 /* auth id */
2274 offset = dissect_rpc_string(tvb, tree,
2275 hf_ndmp_auth_id, offset, NULL);
2277 /* digest */
2278 proto_tree_add_item(tree, hf_ndmp_auth_digest,
2279 tvb, offset, 16, ENC_NA);
2280 offset+=16;
2283 return offset;
2286 static int
2287 dissect_connect_client_auth_request(tvbuff_t *tvb, int offset,
2288 packet_info *pinfo, proto_tree *tree, guint32 seq _U_)
2290 return dissect_auth_data(tvb, offset, pinfo, tree);
2293 static int
2294 dissect_connect_server_auth_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2295 proto_tree *tree, guint32 seq)
2297 /* error */
2298 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2300 /* auth data */
2301 offset = dissect_auth_data(tvb, offset, pinfo, tree);
2303 return offset;
2306 static int
2307 dissect_tape_write_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2308 proto_tree *tree, guint32 seq _U_)
2310 /* data */
2311 offset = dissect_rpc_data(tvb, tree, hf_ndmp_data, offset);
2313 return offset;
2316 static int
2317 dissect_tape_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2318 proto_tree *tree, guint32 seq)
2320 /* error */
2321 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2323 /* count */
2324 proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2325 offset += 4;
2327 return offset;
2330 static int
2331 dissect_tape_read_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2332 proto_tree *tree, guint32 seq _U_)
2334 /* count */
2335 proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2336 offset += 4;
2338 return offset;
2341 static int
2342 dissect_tape_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2343 proto_tree *tree, guint32 seq)
2345 /* error */
2346 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2348 /* data */
2349 offset = dissect_rpc_data(tvb, tree, hf_ndmp_data, offset);
2351 return offset;
2354 #define NDMP_FS_UNIX 0
2355 #define NDMP_FS_NT 1
2356 #define NDMP_FS_OTHER 2
2357 static const value_string file_fs_type_vals[] = {
2358 {NDMP_FS_UNIX, "UNIX"},
2359 {NDMP_FS_NT, "NT"},
2360 {NDMP_FS_OTHER, "OTHER"},
2361 {0, NULL}
2364 static int
2365 dissect_file_name(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2367 proto_item* item = NULL;
2368 proto_tree* tree = NULL;
2369 int old_offset=offset;
2370 guint32 type;
2371 const char *name;
2373 if (parent_tree) {
2374 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2375 "File");
2376 tree = proto_item_add_subtree(item, ett_ndmp_file_name);
2379 /* file type */
2380 type=tvb_get_ntohl(tvb, offset);
2381 proto_tree_add_item(tree, hf_ndmp_file_fs_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2382 offset += 4;
2384 switch(type){
2385 case NDMP_FS_UNIX:
2386 /* file */
2387 offset = dissect_rpc_string(tvb, tree,
2388 hf_ndmp_file_name, offset, &name);
2389 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
2390 break;
2391 case NDMP_FS_NT:
2392 /* nt file */
2393 offset = dissect_rpc_string(tvb, tree,
2394 hf_ndmp_nt_file_name, offset, &name);
2395 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
2397 /* dos file */
2398 offset = dissect_rpc_string(tvb, tree,
2399 hf_ndmp_dos_file_name, offset, NULL);
2400 break;
2401 default:
2402 /* file */
2403 offset = dissect_rpc_string(tvb, tree,
2404 hf_ndmp_file_name, offset, &name);
2405 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
2408 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
2409 val_to_str_const(type, file_fs_type_vals, "Unknown type") );
2411 proto_item_set_len(item, offset-old_offset);
2412 return offset;
2416 static const true_false_string tfs_ndmp_file_invalid_atime = {
2417 "Atime is INVALID",
2418 "Atime is valid"
2420 static const true_false_string tfs_ndmp_file_invalid_ctime = {
2421 "Ctime is INVALID",
2422 "Ctime is valid"
2424 static const true_false_string tfs_ndmp_file_invalid_group = {
2425 "Group is INVALID",
2426 "Group is valid"
2428 static int
2429 dissect_file_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2430 proto_tree *parent_tree)
2432 proto_item* item = NULL;
2433 proto_tree* tree = NULL;
2434 guint32 flags;
2436 flags=tvb_get_ntohl(tvb, offset);
2437 if (parent_tree) {
2438 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
2439 "Invalids: 0x%08x", flags);
2440 tree = proto_item_add_subtree(item, ett_ndmp_file_invalids);
2443 proto_tree_add_boolean(tree, hf_ndmp_file_invalid_group,
2444 tvb, offset, 4, flags);
2445 proto_tree_add_boolean(tree, hf_ndmp_file_invalid_ctime,
2446 tvb, offset, 4, flags);
2447 proto_tree_add_boolean(tree, hf_ndmp_file_invalid_atime,
2448 tvb, offset, 4, flags);
2450 offset+=4;
2451 return offset;
2454 #define NDMP_FILE_TYPE_DIR 0
2455 #define NDMP_FILE_TYPE_FIFO 1
2456 #define NDMP_FILE_TYPE_CSPEC 2
2457 #define NDMP_FILE_TYPE_BSPEC 3
2458 #define NDMP_FILE_TYPE_REG 4
2459 #define NDMP_FILE_TYPE_SLINK 5
2460 #define NDMP_FILE_TYPE_SOCK 6
2461 #define NDMP_FILE_TYPE_REGISTRY 7
2462 #define NDMP_FILE_TYPE_OTHER 8
2463 static const value_string file_type_vals[] = {
2464 {NDMP_FILE_TYPE_DIR, "DIR"},
2465 {NDMP_FILE_TYPE_FIFO, "FIFO"},
2466 {NDMP_FILE_TYPE_CSPEC, "CSPEC"},
2467 {NDMP_FILE_TYPE_BSPEC, "BSPEC"},
2468 {NDMP_FILE_TYPE_REG, "REG"},
2469 {NDMP_FILE_TYPE_SLINK, "SLINK"},
2470 {NDMP_FILE_TYPE_SOCK, "SOCK"},
2471 {NDMP_FILE_TYPE_REGISTRY, "REGISTRY"},
2472 {NDMP_FILE_TYPE_OTHER, "OTHER"},
2473 {0, NULL}
2476 static int
2477 dissect_file_stats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2479 proto_item* item = NULL;
2480 proto_tree* tree = NULL;
2481 int old_offset=offset;
2482 nstime_t ns;
2484 if (parent_tree) {
2485 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2486 "Stats:");
2487 tree = proto_item_add_subtree(item, ett_ndmp_file_stats);
2490 /* invalids */
2491 offset = dissect_file_invalids(tvb, offset, pinfo, tree);
2493 /* file fs type */
2494 proto_tree_add_item(tree, hf_ndmp_file_fs_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2495 offset += 4;
2497 /* file type */
2498 proto_tree_add_item(tree, hf_ndmp_file_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2499 offset += 4;
2501 /* mtime */
2502 ns.secs=tvb_get_ntohl(tvb, offset);
2503 ns.nsecs=0;
2504 proto_tree_add_time(tree, hf_ndmp_file_mtime, tvb, offset, 4, &ns);
2505 offset += 4;
2507 /* atime */
2508 ns.secs=tvb_get_ntohl(tvb, offset);
2509 ns.nsecs=0;
2510 proto_tree_add_time(tree, hf_ndmp_file_atime, tvb, offset, 4, &ns);
2511 offset += 4;
2513 /* ctime */
2514 ns.secs=tvb_get_ntohl(tvb, offset);
2515 ns.nsecs=0;
2516 proto_tree_add_time(tree, hf_ndmp_file_ctime, tvb, offset, 4, &ns);
2517 offset += 4;
2519 /* owner */
2520 proto_tree_add_item(tree, hf_ndmp_file_owner, tvb, offset, 4, ENC_BIG_ENDIAN);
2521 offset += 4;
2523 /* group */
2524 proto_tree_add_item(tree, hf_ndmp_file_group, tvb, offset, 4, ENC_BIG_ENDIAN);
2525 offset += 4;
2527 /*XXX here we should do proper dissection of mode for unix or
2528 fattr for nt, call appropriate functions in nfs/smb*/
2529 /* fattr */
2530 proto_tree_add_item(tree, hf_ndmp_file_fattr, tvb, offset, 4, ENC_BIG_ENDIAN);
2531 offset += 4;
2533 /*file size*/
2534 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_file_size,
2535 offset);
2537 /* links */
2538 proto_tree_add_item(tree, hf_ndmp_file_links, tvb, offset, 4, ENC_BIG_ENDIAN);
2539 offset += 4;
2541 proto_item_set_len(item, offset-old_offset);
2542 return offset;
2546 static int
2547 dissect_file(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2549 proto_item* item = NULL;
2550 proto_tree* tree = NULL;
2551 int old_offset=offset;
2553 if (parent_tree) {
2554 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2555 "File:");
2556 tree = proto_item_add_subtree(item, ett_ndmp_file);
2559 /* file names */
2560 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2561 dissect_file_name, hf_ndmp_file_names);
2563 /* file stats */
2564 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2565 dissect_file_stats, hf_ndmp_file_stats);
2567 /* node */
2568 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2569 offset += 8;
2571 /* fh_info */
2572 proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, ENC_BIG_ENDIAN);
2573 offset += 8;
2575 proto_item_set_len(item, offset-old_offset);
2576 return offset;
2579 static int
2580 dissect_fh_add_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2581 proto_tree *tree, guint32 seq _U_)
2583 /* files */
2584 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2585 dissect_file, hf_ndmp_files);
2587 return offset;
2590 static int
2591 dissect_dir(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
2593 /* file names */
2594 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2595 dissect_file_name, hf_ndmp_file_names);
2597 /* node */
2598 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2599 offset += 8;
2601 /* parent */
2602 proto_tree_add_item(tree, hf_ndmp_file_parent, tvb, offset, 8, ENC_BIG_ENDIAN);
2603 offset += 8;
2605 return offset;
2608 static int
2609 dissect_fh_add_dir_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2610 proto_tree *tree, guint32 seq _U_)
2612 /* dirs */
2613 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2614 dissect_dir, hf_ndmp_dirs);
2616 return offset;
2619 static int
2620 dissect_node(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
2622 /* file stats */
2623 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2624 dissect_file_stats, hf_ndmp_file_stats);
2626 /* node */
2627 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2628 offset += 8;
2630 /* fh_info */
2631 proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, ENC_BIG_ENDIAN);
2632 offset += 8;
2634 return offset;
2638 static int
2639 dissect_fh_add_node_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2640 proto_tree *tree, guint32 seq _U_)
2642 /* node */
2643 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2644 dissect_node, hf_ndmp_nodes);
2646 return offset;
2649 static int
2650 dissect_data_start_backup_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2651 proto_tree *tree, guint32 seq _U_)
2653 /*butype name*/
2654 offset = dissect_rpc_string(tvb, tree,
2655 hf_ndmp_butype_name, offset, NULL);
2657 /* default env */
2658 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2659 dissect_default_env, hf_ndmp_butype_default_env);
2661 return offset;
2664 static int
2665 dissect_nlist(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2666 proto_tree *tree, void* data _U_)
2668 /*original path*/
2669 offset = dissect_rpc_string(tvb, tree,
2670 hf_ndmp_bu_original_path, offset, NULL);
2672 /*destination dir*/
2673 offset = dissect_rpc_string(tvb, tree,
2674 hf_ndmp_bu_destination_dir, offset, NULL);
2676 if(get_ndmp_protocol_version()==NDMP_PROTOCOL_V2){
2677 /* just 2 reserved bytes (4 with padding) */
2678 offset += 4;
2679 } else {
2680 /*new name*/
2681 offset = dissect_rpc_string(tvb, tree,
2682 hf_ndmp_bu_new_name, offset, NULL);
2684 /*other name*/
2685 offset = dissect_rpc_string(tvb, tree,
2686 hf_ndmp_bu_other_name, offset, NULL);
2688 /* node */
2689 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2690 offset += 8;
2693 /* fh_info */
2694 proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, ENC_BIG_ENDIAN);
2695 offset += 8;
2697 return offset;
2701 static int
2702 dissect_data_start_recover_request(tvbuff_t *tvb, int offset,
2703 packet_info *pinfo, proto_tree *tree, guint32 seq _U_)
2705 if(get_ndmp_protocol_version()==NDMP_PROTOCOL_V2){
2706 /* ndmp addr */
2707 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2710 /* default env */
2711 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2712 dissect_default_env, hf_ndmp_butype_default_env);
2714 /* nlist */
2715 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2716 dissect_nlist, hf_ndmp_nlist);
2718 /*butype name*/
2719 offset = dissect_rpc_string(tvb, tree,
2720 hf_ndmp_butype_name, offset, NULL);
2722 return offset;
2725 static int
2726 dissect_data_get_env_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2727 proto_tree *tree, guint32 seq)
2729 /* error */
2730 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2732 /* default env */
2733 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2734 dissect_default_env, hf_ndmp_butype_default_env);
2736 return offset;
2740 static const true_false_string tfs_ndmp_state_invalid_ebr = {
2741 "Estimated Bytes Remaining is INVALID",
2742 "Estimated Bytes Remaining is valid"
2744 static const true_false_string tfs_ndmp_state_invalid_etr = {
2745 "Estimated Time Remaining is INVALID",
2746 "Estimated Time Remaining is valid"
2748 static int
2749 dissect_state_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2750 proto_tree *parent_tree)
2752 proto_item* item = NULL;
2753 proto_tree* tree = NULL;
2754 guint32 flags;
2756 flags=tvb_get_ntohl(tvb, offset);
2757 if (parent_tree) {
2758 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
2759 "Invalids: 0x%08x", flags);
2760 tree = proto_item_add_subtree(item, ett_ndmp_state_invalids);
2763 proto_tree_add_boolean(tree, hf_ndmp_state_invalid_etr,
2764 tvb, offset, 4, flags);
2765 proto_tree_add_boolean(tree, hf_ndmp_state_invalid_ebr,
2766 tvb, offset, 4, flags);
2768 offset+=4;
2769 return offset;
2772 #define NDMP_DATA_OP_NOACTION 0
2773 #define NDMP_DATA_OP_BACKUP 1
2774 #define NDMP_DATA_OP_RESTORE 2
2775 static const value_string bu_operation_vals[] = {
2776 {NDMP_DATA_OP_NOACTION, "NOACTION"},
2777 {NDMP_DATA_OP_BACKUP, "BACKUP"},
2778 {NDMP_DATA_OP_RESTORE, "RESTORE"},
2779 {0, NULL}
2782 #define NDMP_DATA_STATE_IDLE 0
2783 #define NDMP_DATA_STATE_ACTIVE 1
2784 #define NDMP_DATA_STATE_HALTED 2
2785 #define NDMP_DATA_STATE_LISTEN 3
2786 #define NDMP_DATA_STATE_CONNECTED 4
2787 static const value_string data_state_vals[] = {
2788 {NDMP_DATA_STATE_IDLE, "IDLE"},
2789 {NDMP_DATA_STATE_ACTIVE, "ACTIVE"},
2790 {NDMP_DATA_STATE_HALTED, "HALTED"},
2791 {NDMP_DATA_STATE_LISTEN, "LISTEN"},
2792 {NDMP_DATA_STATE_CONNECTED, "CONNECTED"},
2793 {0, NULL}
2796 #define NDMP_DATA_HALTED_NA 0
2797 #define NDMP_DATA_HALTED_SUCCESSFUL 1
2798 #define NDMP_DATA_HALTED_ABORTED 2
2799 #define NDMP_DATA_HALTED_INTERNAL_ERROR 3
2800 #define NDMP_DATA_HALTED_CONNECT_ERROR 4
2801 static const value_string data_halted_vals[] = {
2802 {NDMP_DATA_HALTED_NA, "HALTED_NA"},
2803 {NDMP_DATA_HALTED_SUCCESSFUL, "HALTED_SUCCESSFUL"},
2804 {NDMP_DATA_HALTED_ABORTED, "HALTED_ABORTED"},
2805 {NDMP_DATA_HALTED_INTERNAL_ERROR, "HALTED_INTERNAL_ERROR"},
2806 {NDMP_DATA_HALTED_CONNECT_ERROR, "HALTED_CONNECT_ERROR"},
2807 {0, NULL}
2810 static int
2811 dissect_data_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2812 proto_tree *tree, guint32 seq)
2814 nstime_t ns;
2816 /* invalids */
2817 offset = dissect_state_invalids(tvb, offset, pinfo, tree);
2819 /* error */
2820 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2822 /* operation */
2823 proto_tree_add_item(tree, hf_ndmp_bu_operation, tvb, offset, 4, ENC_BIG_ENDIAN);
2824 offset += 4;
2826 /* state */
2827 proto_tree_add_item(tree, hf_ndmp_data_state, tvb, offset, 4, ENC_BIG_ENDIAN);
2828 offset += 4;
2830 /* halted reason */
2831 proto_tree_add_item(tree, hf_ndmp_data_halted, tvb, offset, 4, ENC_BIG_ENDIAN);
2832 offset += 4;
2834 /*bytes processed*/
2835 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_data_bytes_processed,
2836 offset);
2838 /*est bytes remain*/
2839 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_data_est_bytes_remain,
2840 offset);
2842 /* est time remain */
2843 ns.secs=tvb_get_ntohl(tvb, offset);
2844 ns.nsecs=0;
2845 proto_tree_add_time(tree, hf_ndmp_data_est_time_remain, tvb, offset, 4, &ns);
2846 offset += 4;
2848 /* ndmp addr */
2849 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2851 /* window offset */
2852 proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
2853 offset += 8;
2855 /* window length */
2856 proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, ENC_BIG_ENDIAN);
2857 offset += 8;
2859 return offset;
2862 typedef struct _ndmp_command {
2863 guint32 cmd;
2864 int (*request) (tvbuff_t *tvb, int offset, packet_info *pinfo,
2865 proto_tree *tree, guint32 seq);
2866 int (*response)(tvbuff_t *tvb, int offset, packet_info *pinfo,
2867 proto_tree *tree, guint32 seq);
2868 } ndmp_command;
2870 static const ndmp_command ndmp_commands[] = {
2871 {NDMP_CONFIG_GET_HOST_INFO,
2872 NULL, dissect_ndmp_get_host_info_reply},
2873 {NDMP_CONFIG_GET_CONNECTION_TYPE,
2874 NULL, dissect_ndmp_config_get_connection_type_reply},
2875 {NDMP_CONFIG_GET_AUTH_ATTR,
2876 dissect_get_auth_type_request, dissect_ndmp_config_get_auth_attr_reply},
2877 {NDMP_CONFIG_GET_BUTYPE_INFO,
2878 NULL, dissect_get_butype_info_reply},
2879 {NDMP_CONFIG_GET_FS_INFO,
2880 NULL, dissect_get_fs_info_reply},
2881 {NDMP_CONFIG_GET_TAPE_INFO,
2882 NULL, dissect_get_tape_info_reply},
2883 {NDMP_CONFIG_GET_SCSI_INFO,
2884 NULL, dissect_get_scsi_info_reply},
2885 {NDMP_CONFIG_GET_SERVER_INFO,
2886 NULL, dissect_get_server_info_reply},
2887 {NDMP_CONFIG_GET_EXT_LIST,
2888 NULL, dissect_get_ext_list_reply},
2889 {NDMP_CONFIG_SET_EXT_LIST,
2890 dissect_set_ext_list_request, dissect_set_ext_list_reply},
2891 {NDMP_SCSI_OPEN,
2892 dissect_scsi_open_request, dissect_error},
2893 {NDMP_SCSI_CLOSE,
2894 NULL, dissect_error},
2895 {NDMP_SCSI_GET_STATE,
2896 NULL, dissect_scsi_get_state_reply},
2897 {NDMP_SCSI_SET_TARGET,
2898 dissect_scsi_set_state_request, dissect_error},
2899 {NDMP_SCSI_RESET_DEVICE,
2900 NULL, dissect_error},
2901 {NDMP_SCSI_RESET_BUS,
2902 NULL, dissect_error},
2903 {NDMP_SCSI_EXECUTE_CDB,
2904 dissect_execute_cdb_request_mc, dissect_execute_cdb_reply},
2905 {NDMP_TAPE_OPEN,
2906 dissect_tape_open_request, dissect_error},
2907 {NDMP_TAPE_CLOSE,
2908 NULL, dissect_error},
2909 {NDMP_TAPE_GET_STATE,
2910 NULL, dissect_tape_get_state_reply},
2911 {NDMP_TAPE_MTIO,
2912 dissect_tape_mtio_request, dissect_tape_mtio_reply},
2913 {NDMP_TAPE_WRITE,
2914 dissect_tape_write_request, dissect_tape_write_reply},
2915 {NDMP_TAPE_READ,
2916 dissect_tape_read_request, dissect_tape_read_reply},
2917 {NDMP_TAPE_EXECUTE_CDB,
2918 dissect_execute_cdb_request_tape, dissect_execute_cdb_reply},
2919 {NDMP_DATA_GET_STATE,
2920 NULL, dissect_data_get_state_reply},
2921 {NDMP_DATA_START_BACKUP,
2922 dissect_data_start_backup_request, dissect_error },
2923 {NDMP_DATA_START_RECOVER,
2924 dissect_data_start_recover_request, dissect_error },
2925 {NDMP_DATA_ABORT,
2926 NULL, dissect_error},
2927 {NDMP_DATA_GET_ENV,
2928 NULL, dissect_data_get_env_reply},
2929 {NDMP_DATA_STOP,
2930 NULL, dissect_error},
2931 {NDMP_DATA_LISTEN,
2932 dissect_ndmp_addr_msg, dissect_mover_listen_reply},
2933 {NDMP_DATA_CONNECT,
2934 dissect_data_connect_msg, dissect_error},
2935 {NDMP_NOTIFY_DATA_HALTED,
2936 dissect_notify_data_halted_request, NULL},
2937 {NDMP_NOTIFY_CONNECTED,
2938 dissect_notify_connected_request, NULL},
2939 {NDMP_NOTIFY_MOVER_HALTED,
2940 dissect_notify_mover_halted_request, NULL},
2941 {NDMP_NOTIFY_MOVER_PAUSED,
2942 dissect_notify_mover_paused_request, NULL},
2943 {NDMP_NOTIFY_DATA_READ,
2944 dissect_mover_set_window_request, NULL},
2945 {NDMP_LOG_FILE,
2946 dissect_log_file_request, NULL},
2947 {NDMP_LOG_MESSAGE,
2948 dissect_log_message_request, NULL},
2949 {NDMP_FH_ADD_FILE,
2950 dissect_fh_add_file_request, NULL},
2951 {NDMP_FH_ADD_DIR,
2952 dissect_fh_add_dir_request, NULL},
2953 {NDMP_FH_ADD_NODE,
2954 dissect_fh_add_node_request, NULL},
2955 {NDMP_CONNECT_OPEN,
2956 dissect_connect_open_request, dissect_error},
2957 {NDMP_CONNECT_CLIENT_AUTH,
2958 dissect_connect_client_auth_request, dissect_error},
2959 {NDMP_CONNECT_CLOSE,
2960 NULL,NULL},
2961 {NDMP_CONNECT_SERVER_AUTH,
2962 dissect_auth_attr_msg, dissect_connect_server_auth_reply},
2963 {NDMP_MOVER_GET_STATE,
2964 NULL, dissect_mover_get_state_reply},
2965 {NDMP_MOVER_LISTEN,
2966 dissect_mover_listen_request, dissect_mover_listen_reply},
2967 {NDMP_MOVER_CONTINUE,
2968 NULL, dissect_error},
2969 {NDMP_MOVER_ABORT,
2970 NULL, dissect_error},
2971 {NDMP_MOVER_STOP,
2972 NULL, dissect_error},
2973 {NDMP_MOVER_SET_WINDOW,
2974 dissect_mover_set_window_request, dissect_error},
2975 {NDMP_MOVER_READ,
2976 dissect_mover_set_window_request, dissect_error},
2977 {NDMP_MOVER_CLOSE,
2978 NULL, dissect_error},
2979 {NDMP_MOVER_SET_RECORD_SIZE,
2980 dissect_mover_set_record_size_request, dissect_error},
2981 {NDMP_MOVER_CONNECT,
2982 dissect_mover_connect_request, dissect_error},
2983 {0, NULL,NULL}
2987 static int
2988 dissect_ndmp_header(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, struct ndmp_header *nh)
2990 proto_item* item = NULL;
2991 proto_tree* tree = NULL;
2992 nstime_t ns;
2994 if (parent_tree) {
2995 item = proto_tree_add_item(parent_tree, hf_ndmp_header, tvb,
2996 offset, 24, ENC_NA);
2997 tree = proto_item_add_subtree(item, ett_ndmp_header);
3000 /* sequence number */
3001 proto_tree_add_uint(tree, hf_ndmp_sequence, tvb, offset, 4, nh->seq);
3002 offset += 4;
3004 /* timestamp */
3005 ns.secs=nh->time;
3006 ns.nsecs=0;
3007 proto_tree_add_time(tree, hf_ndmp_timestamp, tvb, offset, 4, &ns);
3008 offset += 4;
3010 /* Message Type */
3011 proto_tree_add_uint(tree, hf_ndmp_msgtype, tvb, offset, 4, nh->type);
3012 offset += 4;
3014 /* Message */
3015 proto_tree_add_uint(tree, hf_ndmp_msg, tvb, offset, 4, nh->msg);
3016 offset += 4;
3018 /* Reply sequence number */
3019 proto_tree_add_uint(tree, hf_ndmp_reply_sequence, tvb, offset, 4, nh->rep_seq);
3020 offset += 4;
3022 /* error */
3023 offset=dissect_error(tvb, offset, pinfo, tree, nh->seq);
3025 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s ",
3026 val_to_str(nh->msg, msg_vals, "Unknown Message (0x%02x)"),
3027 val_to_str(nh->type, msg_type_vals, "Unknown Type (0x%02x)")
3030 return offset;
3034 static int
3035 dissect_ndmp_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, struct ndmp_header *nh)
3037 int i;
3038 proto_item *cmd_item=NULL;
3039 proto_tree *cmd_tree=NULL;
3041 offset=dissect_ndmp_header(tvb, offset, pinfo, tree, nh);
3043 for(i=0;ndmp_commands[i].cmd!=0;i++){
3044 if(ndmp_commands[i].cmd==nh->msg){
3045 break;
3050 if(ndmp_commands[i].cmd==0){
3051 /* we do not know this message */
3052 proto_tree_add_text(tree, tvb, offset, -1, "Unknown type of NDMP message: 0x%02x", nh->msg);
3053 offset+=tvb_length_remaining(tvb, offset);
3054 return offset;
3057 if (tvb_reported_length_remaining(tvb, offset) > 0) {
3058 if(tree){
3059 cmd_item = proto_tree_add_text(tree, tvb, offset, -1, "%s",
3060 msg_vals[i].strptr);
3061 cmd_tree = proto_item_add_subtree(cmd_item, ett_ndmp);
3065 if(nh->type==NDMP_MESSAGE_REQUEST){
3066 if(ndmp_commands[i].request){
3067 offset=ndmp_commands[i].request(tvb, offset, pinfo, cmd_tree,
3068 nh->seq);
3070 } else {
3071 if(ndmp_commands[i].response){
3072 offset=ndmp_commands[i].response(tvb, offset, pinfo, cmd_tree,
3073 nh->rep_seq);
3077 return offset;
3080 static int
3081 dissect_ndmp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
3083 int offset = 0;
3084 guint32 ndmp_rm;
3085 struct ndmp_header nh;
3086 guint32 size;
3087 guint32 seq, len, nxt, frag_num;
3088 gint nbytes;
3089 int direction;
3090 struct tcpinfo *tcpinfo;
3091 ndmp_frag_info* nfi;
3092 proto_item *ndmp_item = NULL;
3093 proto_tree *ndmp_tree = NULL;
3094 proto_item *hdr_item = NULL;
3095 proto_tree *hdr_tree = NULL;
3096 wmem_tree_t *frags;
3097 conversation_t *conversation;
3098 proto_item *vers_item;
3099 gboolean save_fragmented, save_writable;
3100 gboolean do_frag = TRUE;
3101 tvbuff_t* new_tvb = NULL;
3102 fragment_head *frag_msg = NULL;
3104 top_tree=tree; /* scsi should open its expansions on the top level */
3107 * We need to keep track of conversations so that we can track NDMP
3108 * versions.
3110 conversation = find_or_create_conversation(pinfo);
3112 ndmp_conv_data=(ndmp_conv_data_t *)conversation_get_proto_data(conversation, proto_ndmp);
3113 if(!ndmp_conv_data){
3114 ndmp_conv_data=wmem_new(wmem_file_scope(), ndmp_conv_data_t);
3115 ndmp_conv_data->version = NDMP_PROTOCOL_UNKNOWN;
3116 ndmp_conv_data->tasks = wmem_tree_new(wmem_file_scope());
3117 ndmp_conv_data->itl = wmem_tree_new(wmem_file_scope());
3118 ndmp_conv_data->conversation = conversation;
3119 ndmp_conv_data->fragsA = wmem_tree_new(wmem_file_scope());
3120 ndmp_conv_data->fragsB = wmem_tree_new(wmem_file_scope());
3122 conversation_add_proto_data(conversation, proto_ndmp, ndmp_conv_data);
3124 /* Ensure that any & all frames/fragments belonging to this conversation */
3125 /* are dissected as NDMP even if another dissector (eg: IPSEC-TCP) might */
3126 /* decide to dissect an NDMP fragment. This works because the TCP */
3127 /* dissector dispatches to a conversation associated dissector before */
3128 /* dispatching by port or by heuristic. Associating NDMP with this */
3129 /* conversation is necessary because otherwise the IPSEC-TCP(TCPENCAP) */
3130 /* dissector may think NDMP fragments are really TCPENCAP since that */
3131 /* dissector also registers on TCP Port 10000. (See packet-ipsec-tcp.c). */
3132 conversation_set_dissector(conversation, ndmp_handle);
3136 * Read the NDMP record marker, if we have it.
3138 ndmp_rm=tvb_get_ntohl(tvb, offset);
3140 /* Save the flag indicating whether this packet is a fragment */
3141 save_fragmented = pinfo->fragmented;
3143 /* Reassemble if desegmentation and reassembly are enabled, otherwise
3144 * just pass through and use the data in tvb for dissection */
3145 if (ndmp_defragment && ndmp_desegment)
3149 * Determine the direction of the flow, so we can use the correct fragment tree
3151 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
3152 if(direction==0) {
3153 direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
3155 if(direction>=0){
3156 frags = ndmp_conv_data->fragsA;
3157 } else {
3158 frags = ndmp_conv_data->fragsB;
3162 * Figure out the tcp seq and pdu length. Fragment tree is indexed based on seq;
3164 tcpinfo = (struct tcpinfo *)data;
3166 seq = tcpinfo->seq;
3167 len = (ndmp_rm & RPC_RM_FRAGLEN) + 4;
3168 nxt = seq + len;
3171 * In case there are multiple PDUs in the same frame, advance the tcp seq
3172 * so that they can be distinguished from one another
3174 tcpinfo->seq = nxt;
3176 nfi = (ndmp_frag_info *)wmem_tree_lookup32(frags, seq);
3178 if (!nfi)
3180 frag_num = 0;
3183 * If nfi doesn't exist, then there are no fragments before this one.
3184 * If there are fragments after this one, create the entry in the frag
3185 * tree so the next fragment can find it.
3186 * If we've already seen this frame, no need to create the entry again.
3188 if ( !(ndmp_rm & RPC_RM_LASTFRAG))
3190 if ( !(pinfo->fd->flags.visited))
3192 nfi=wmem_new(wmem_file_scope(), ndmp_frag_info);
3193 nfi->first_seq = seq;
3194 nfi->offset = 1;
3195 wmem_tree_insert32(frags, nxt, (void *)nfi);
3199 * If this is both the first and the last fragment, then there
3200 * is no reason to even engage the reassembly routines. Just
3201 * create the new_tvb directly from tvb.
3203 else
3205 do_frag = FALSE;
3206 new_tvb = tvb_new_subset_remaining(tvb, 4);
3209 else
3212 * An entry was found, so we know the offset of this fragment
3214 frag_num = nfi->offset;
3215 seq = nfi->first_seq;
3218 * If this isn't the last frag, add another entry so the next fragment can find it.
3219 * If we've already seen this frame, no need to create the entry again.
3221 if ( !(ndmp_rm & RPC_RM_LASTFRAG))
3223 if ( !(pinfo->fd->flags.visited))
3225 nfi=wmem_new(wmem_file_scope(), ndmp_frag_info);
3226 nfi->first_seq = seq;
3227 nfi->offset = frag_num+1;
3228 wmem_tree_insert32(frags, nxt, (void *)nfi);
3233 /* If fragmentation is necessary */
3234 if (do_frag)
3236 pinfo->fragmented = TRUE;
3238 frag_msg = fragment_add_seq_check(&ndmp_reassembly_table,
3239 tvb, 4, pinfo, seq, NULL,
3240 frag_num,
3241 tvb_length_remaining(tvb, offset)-4,
3242 !(ndmp_rm & RPC_RM_LASTFRAG));
3244 new_tvb = process_reassembled_data(tvb, 4, pinfo, "Reassembled NDMP", frag_msg, &ndmp_frag_items, NULL, tree);
3248 * Check if this is the last fragment.
3250 if (!(ndmp_rm & RPC_RM_LASTFRAG)) {
3252 * Update the column info.
3254 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
3256 col_set_str(pinfo->cinfo, COL_INFO, "[NDMP fragment] ");
3259 * Add the record marker information to the tree
3261 if (tree) {
3262 ndmp_item = proto_tree_add_item(tree, proto_ndmp, tvb, 0, -1, ENC_NA);
3263 ndmp_tree = proto_item_add_subtree(ndmp_item, ett_ndmp);
3265 hdr_item = proto_tree_add_text(ndmp_tree, tvb, 0, 4,
3266 "Fragment header: %s%u %s",
3267 (ndmp_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
3268 ndmp_rm & RPC_RM_FRAGLEN, plurality(ndmp_rm & RPC_RM_FRAGLEN, "byte", "bytes"));
3269 hdr_tree = proto_item_add_subtree(hdr_item, ett_ndmp_fraghdr);
3270 proto_tree_add_boolean(hdr_tree, hf_ndmp_lastfrag, tvb, 0, 4, ndmp_rm);
3271 proto_tree_add_uint(hdr_tree, hf_ndmp_fraglen, tvb, 0, 4, ndmp_rm);
3274 * Decode the remaining bytes as generic NDMP fragment data
3276 nbytes = tvb_reported_length_remaining(tvb, 4);
3277 proto_tree_add_text(ndmp_tree, tvb, 4, nbytes, "NDMP fragment data (%u byte%s)", nbytes, plurality(nbytes, "", "s"));
3279 pinfo->fragmented = save_fragmented;
3280 return tvb_length(tvb);
3283 else
3285 new_tvb = tvb_new_subset_remaining(tvb, 4);
3289 /* size of this NDMP PDU */
3290 size = tvb_length_remaining(new_tvb, offset);
3291 if (size < 24) {
3292 /* too short to be NDMP */
3293 pinfo->fragmented = save_fragmented;
3294 return tvb_length(tvb);
3298 * If it doesn't look like a valid NDMP header at this point, there is
3299 * no reason to move forward
3301 if (!check_ndmp_hdr(new_tvb))
3303 pinfo->fragmented = save_fragmented;
3304 return tvb_length(tvb);
3307 nh.seq = tvb_get_ntohl(new_tvb, offset);
3308 nh.time = tvb_get_ntohl(new_tvb, offset+4);
3309 nh.type = tvb_get_ntohl(new_tvb, offset+8);
3310 nh.msg = tvb_get_ntohl(new_tvb, offset+12);
3311 nh.rep_seq = tvb_get_ntohl(new_tvb, offset+16);
3312 nh.err = tvb_get_ntohl(new_tvb, offset+20);
3314 /* When the last fragment is small and the final frame contains
3315 * multiple fragments, the column becomes unwritable.
3316 * Temporarily change that so that the correct header can be
3317 * applied */
3318 save_writable = col_get_writable(pinfo->cinfo);
3319 col_set_writable(pinfo->cinfo, TRUE);
3321 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
3322 col_clear(pinfo->cinfo, COL_INFO);
3323 if (tree) {
3324 ndmp_item = proto_tree_add_item(tree, proto_ndmp, tvb, 0, -1, ENC_NA);
3325 ndmp_tree = proto_item_add_subtree(ndmp_item, ett_ndmp);
3328 /* ndmp version (and autodetection) */
3329 if(ndmp_conv_data->version!=NDMP_PROTOCOL_UNKNOWN){
3330 vers_item=proto_tree_add_uint(ndmp_tree, hf_ndmp_version, new_tvb, offset, 0, ndmp_conv_data->version);
3331 } else {
3332 vers_item=proto_tree_add_uint_format(ndmp_tree, hf_ndmp_version, new_tvb, offset, 0, ndmp_default_protocol_version, "Unknown NDMP version, using default:%d", ndmp_default_protocol_version);
3334 PROTO_ITEM_SET_GENERATED(vers_item);
3336 /* request response matching */
3337 ndmp_conv_data->task=NULL;
3338 switch(nh.type){
3339 case NDMP_MESSAGE_REQUEST:
3340 if(!pinfo->fd->flags.visited){
3341 ndmp_conv_data->task=wmem_new(wmem_file_scope(), ndmp_task_data_t);
3342 ndmp_conv_data->task->request_frame=pinfo->fd->num;
3343 ndmp_conv_data->task->response_frame=0;
3344 ndmp_conv_data->task->ndmp_time=pinfo->fd->abs_ts;
3345 ndmp_conv_data->task->itlq=NULL;
3346 wmem_tree_insert32(ndmp_conv_data->tasks, nh.seq, ndmp_conv_data->task);
3347 } else {
3348 ndmp_conv_data->task=(ndmp_task_data_t *)wmem_tree_lookup32(ndmp_conv_data->tasks, nh.seq);
3350 if(ndmp_conv_data->task && ndmp_conv_data->task->response_frame){
3351 proto_item *it;
3352 it=proto_tree_add_uint(ndmp_tree, hf_ndmp_response_frame, new_tvb, 0, 0, ndmp_conv_data->task->response_frame);
3354 PROTO_ITEM_SET_GENERATED(it);
3356 break;
3357 case NDMP_MESSAGE_REPLY:
3358 ndmp_conv_data->task=(ndmp_task_data_t *)wmem_tree_lookup32(ndmp_conv_data->tasks, nh.rep_seq);
3360 if(ndmp_conv_data->task && !pinfo->fd->flags.visited){
3361 ndmp_conv_data->task->response_frame=pinfo->fd->num;
3362 if(ndmp_conv_data->task->itlq){
3363 ndmp_conv_data->task->itlq->last_exchange_frame=pinfo->fd->num;
3366 if(ndmp_conv_data->task && ndmp_conv_data->task->request_frame){
3367 proto_item *it;
3368 nstime_t delta_ts;
3370 it=proto_tree_add_uint(ndmp_tree, hf_ndmp_request_frame, new_tvb, 0, 0, ndmp_conv_data->task->request_frame);
3372 PROTO_ITEM_SET_GENERATED(it);
3374 nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &ndmp_conv_data->task->ndmp_time);
3375 it=proto_tree_add_time(ndmp_tree, hf_ndmp_time, new_tvb, 0, 0, &delta_ts);
3376 PROTO_ITEM_SET_GENERATED(it);
3378 break;
3381 /* Add the record marker information to the tree */
3382 hdr_item = proto_tree_add_text(ndmp_tree, tvb, 0, 4,
3383 "Fragment header: %s%u %s",
3384 (ndmp_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
3385 ndmp_rm & RPC_RM_FRAGLEN, plurality(ndmp_rm & RPC_RM_FRAGLEN, "byte", "bytes"));
3386 hdr_tree = proto_item_add_subtree(hdr_item, ett_ndmp_fraghdr);
3387 proto_tree_add_boolean(hdr_tree, hf_ndmp_lastfrag, tvb, 0, 4, ndmp_rm);
3388 proto_tree_add_uint(hdr_tree, hf_ndmp_fraglen, tvb, 0, 4, ndmp_rm);
3391 * We cannot trust what dissect_ndmp_cmd() tells us, as there
3392 * are implementations which pad some additional data after
3393 * the PDU. We MUST use size.
3395 dissect_ndmp_cmd(new_tvb, offset, pinfo, ndmp_tree, &nh);
3397 /* restore saved variables */
3398 pinfo->fragmented = save_fragmented;
3399 col_set_writable(pinfo->cinfo, save_writable);
3401 return tvb_length(tvb);
3404 static guint
3405 get_ndmp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
3407 guint len;
3409 len=tvb_get_ntohl(tvb, offset)&0x7fffffff;
3410 /* Get the length of the NDMP packet. */
3412 /*XXX check header for sanity */
3413 return len+4;
3416 gboolean
3417 check_if_ndmp(tvbuff_t *tvb, packet_info *pinfo)
3419 guint len;
3420 guint32 tmp;
3422 /* verify that the tcp port is 10000, ndmp always runs on port 10000*/
3423 if ((pinfo->srcport!=TCP_PORT_NDMP)&&(pinfo->destport!=TCP_PORT_NDMP)) {
3424 return FALSE;
3427 /* check that the header looks sane */
3428 len=tvb_length(tvb);
3429 /* check the record marker that it looks sane.
3430 * It has to be >=24 bytes or (arbitrary limit) <1Mbyte
3432 if(len>=4){
3433 tmp=(tvb_get_ntohl(tvb, 0)&RPC_RM_FRAGLEN);
3434 if( (tmp<24)||(tmp>1000000) ){
3435 return FALSE;
3439 /* check the timestamp, timestamps are valid if they
3440 * (arbitrary) lie between 1980-jan-1 and 2030-jan-1
3442 if(len>=12){
3443 tmp=tvb_get_ntohl(tvb, 8);
3444 if( (tmp<0x12ceec50)||(tmp>0x70dc1ed0) ){
3445 return FALSE;
3449 /* check the type */
3450 if(len>=16){
3451 tmp=tvb_get_ntohl(tvb, 12);
3452 if( tmp>1 ){
3453 return FALSE;
3457 /* check message */
3458 if(len>=20){
3459 tmp=tvb_get_ntohl(tvb, 16);
3460 if( (tmp>0xa09) || (tmp==0) ){
3461 return FALSE;
3465 /* check error */
3466 if(len>=28){
3467 tmp=tvb_get_ntohl(tvb, 24);
3468 if( (tmp>0x17) ){
3469 return FALSE;
3473 return TRUE;
3476 /* Called because the frame has been identified as part of a conversation
3477 * assigned to the NDMP protocol.
3478 * At this point we may have either an NDMP PDU or an NDMP PDU fragment.
3480 static int
3481 dissect_ndmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3483 /* If we are doing defragmentation, don't check more than the record mark here,
3484 * because if this is a continuation of a fragmented NDMP PDU there won't be a
3485 * NDMP header after the RM */
3486 if(ndmp_defragment && !check_ndmp_rm(tvb, pinfo)) {
3487 return 0;
3490 /* If we aren't doing both desegmentation and fragment reassembly,
3491 * check for the entire NDMP header before proceeding */
3492 if(!(ndmp_desegment && ndmp_defragment) && !check_if_ndmp(tvb, pinfo)) {
3493 return 0;
3496 tcp_dissect_pdus(tvb, pinfo, tree, ndmp_desegment, 4,
3497 get_ndmp_pdu_len, dissect_ndmp_message, data);
3498 return tvb_length(tvb);
3501 /* Called when doing a heuristic check;
3502 * Accept as NDMP only if the full header seems reasonable.
3503 * Note that once the first PDU (or PDU fragment) has been found
3504 * dissect_ndmp_message will register a dissect_ndmp NDMP handle
3505 * as the protocol dissector for this conversation.
3507 static int
3508 dissect_ndmp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3510 if (tvb_length(tvb) < 28)
3511 return 0;
3512 if (!check_if_ndmp(tvb, pinfo))
3513 return 0;
3515 tcp_dissect_pdus(tvb, pinfo, tree, ndmp_desegment, 28,
3516 get_ndmp_pdu_len, dissect_ndmp_message, data);
3517 return tvb_length(tvb);
3520 static void
3521 ndmp_init(void)
3523 reassembly_table_init(&ndmp_reassembly_table,
3524 &addresses_reassembly_table_functions);
3528 void
3529 proto_register_ndmp(void)
3532 static hf_register_info hf_ndmp[] = {
3533 { &hf_ndmp_header, {
3534 "NDMP Header", "ndmp.header", FT_NONE, BASE_NONE,
3535 NULL, 0, NULL, HFILL }},
3537 { &hf_ndmp_response_frame, {
3538 "Response In", "ndmp.response_frame", FT_FRAMENUM, BASE_NONE,
3539 NULL, 0, "The response to this NDMP command is in this frame", HFILL }},
3541 { &hf_ndmp_time,
3542 { "Time from request", "ndmp.time", FT_RELATIVE_TIME, BASE_NONE, NULL,
3543 0, "Time since the request packet", HFILL }},
3545 { &hf_ndmp_request_frame, {
3546 "Request In", "ndmp.request_frame", FT_FRAMENUM, BASE_NONE,
3547 NULL, 0, "The request to this NDMP command is in this frame", HFILL }},
3549 { &hf_ndmp_sequence, {
3550 "Sequence", "ndmp.sequence", FT_UINT32, BASE_DEC,
3551 NULL, 0, "Sequence number for NDMP PDU", HFILL }},
3553 { &hf_ndmp_reply_sequence, {
3554 "Reply Sequence", "ndmp.reply_sequence", FT_UINT32, BASE_DEC,
3555 NULL, 0, "Reply Sequence number for NDMP PDU", HFILL }},
3557 { &hf_ndmp_timestamp, {
3558 "Time", "ndmp.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3559 NULL, 0, "Timestamp for this NDMP PDU", HFILL }},
3561 { &hf_ndmp_msgtype, {
3562 "Type", "ndmp.msg_type", FT_UINT32, BASE_DEC,
3563 VALS(msg_type_vals), 0, "Is this a Request or Response?", HFILL }},
3565 { &hf_ndmp_msg, {
3566 "Message", "ndmp.msg", FT_UINT32, BASE_HEX,
3567 VALS(msg_vals), 0, "Type of NDMP PDU", HFILL }},
3569 { &hf_ndmp_error, {
3570 "Error", "ndmp.error", FT_UINT32, BASE_DEC,
3571 VALS(error_vals), 0, "Error code for this NDMP PDU", HFILL }},
3573 { &hf_ndmp_version, {
3574 "Version", "ndmp.version", FT_UINT32, BASE_DEC,
3575 NULL, 0, "Version of NDMP protocol", HFILL }},
3577 { &hf_ndmp_hostname, {
3578 "Hostname", "ndmp.hostname", FT_STRING, BASE_NONE,
3579 NULL, 0, NULL, HFILL }},
3581 { &hf_ndmp_hostid, {
3582 "HostID", "ndmp.hostid", FT_STRING, BASE_NONE,
3583 NULL, 0, NULL, HFILL }},
3585 { &hf_ndmp_os_type, {
3586 "OS Type", "ndmp.os.type", FT_STRING, BASE_NONE,
3587 NULL, 0, NULL, HFILL }},
3589 { &hf_ndmp_os_vers, {
3590 "OS Version", "ndmp.os.version", FT_STRING, BASE_NONE,
3591 NULL, 0, NULL, HFILL }},
3593 { &hf_ndmp_addr_types, {
3594 "Addr Types", "ndmp.addr_types", FT_NONE, BASE_NONE,
3595 NULL, 0, "List Of Address Types", HFILL }},
3597 { &hf_ndmp_addr_type, {
3598 "Addr Type", "ndmp.addr_type", FT_UINT32, BASE_DEC,
3599 VALS(addr_type_vals), 0, "Address Type", HFILL }},
3601 { &hf_ndmp_auth_type, {
3602 "Auth Type", "ndmp.auth_type", FT_UINT32, BASE_DEC,
3603 VALS(auth_type_vals), 0, "Authentication Type", HFILL }},
3605 { &hf_ndmp_auth_challenge, {
3606 "Challenge", "ndmp.auth.challenge", FT_BYTES, BASE_NONE,
3607 NULL, 0, "Authentication Challenge", HFILL }},
3609 { &hf_ndmp_auth_digest, {
3610 "Digest", "ndmp.auth.digest", FT_BYTES, BASE_NONE,
3611 NULL, 0, "Authentication Digest", HFILL }},
3613 { &hf_ndmp_butype_info, {
3614 "Butype Info", "ndmp.butype.info", FT_NONE, BASE_NONE,
3615 NULL, 0, NULL, HFILL }},
3617 { &hf_ndmp_butype_name, {
3618 "Butype Name", "ndmp.butype.name", FT_STRING, BASE_NONE,
3619 NULL, 0, "Name of Butype", HFILL }},
3621 { &hf_ndmp_butype_default_env, {
3622 "Default Env", "ndmp.butype.default_env", FT_NONE, BASE_NONE,
3623 NULL, 0, "Default Env's for this Butype Info", HFILL }},
3625 { &hf_ndmp_tcp_addr_list, {
3626 "TCP Ports", "ndmp.tcp.port_list", FT_NONE, BASE_NONE,
3627 NULL, 0, "List of TCP ports", HFILL }},
3629 { &hf_ndmp_tcp_default_env, {
3630 "Default Env", "ndmp.tcp.default_env", FT_NONE, BASE_NONE,
3631 NULL, 0, "Default Env's for this Butype Info", HFILL }},
3633 { &hf_ndmp_butype_attr_backup_file_history, {
3634 "Backup file history", "ndmp.butype.attr.backup_file_history", FT_BOOLEAN, 32,
3635 TFS(&tfs_butype_attr_backup_file_history), 0x00000001, "backup_file_history", HFILL }},
3637 { &hf_ndmp_butype_attr_backup_filelist, {
3638 "Backup file list", "ndmp.butype.attr.backup_filelist", FT_BOOLEAN, 32,
3639 TFS(&tfs_butype_attr_backup_filelist), 0x00000002, "backup_filelist", HFILL }},
3641 { &hf_ndmp_butype_attr_recover_filelist, {
3642 "Recover file list", "ndmp.butype.attr.recover_filelist", FT_BOOLEAN, 32,
3643 TFS(&tfs_butype_attr_recover_filelist), 0x00000004, "recover_filelist", HFILL }},
3645 { &hf_ndmp_butype_attr_backup_direct, {
3646 "Backup direct", "ndmp.butype.attr.backup_direct", FT_BOOLEAN, 32,
3647 TFS(&tfs_butype_attr_backup_direct), 0x00000008, "backup_direct", HFILL }},
3649 { &hf_ndmp_butype_attr_recover_direct, {
3650 "Recover direct", "ndmp.butype.attr.recover_direct", FT_BOOLEAN, 32,
3651 TFS(&tfs_butype_attr_recover_direct), 0x00000010, "recover_direct", HFILL }},
3653 { &hf_ndmp_butype_attr_backup_incremental, {
3654 "Backup incremental", "ndmp.butype.attr.backup_incremental", FT_BOOLEAN, 32,
3655 TFS(&tfs_butype_attr_backup_incremental), 0x00000020, "backup_incremental", HFILL }},
3657 { &hf_ndmp_butype_attr_recover_incremental, {
3658 "Recover incremental", "ndmp.butype.attr.recover_incremental", FT_BOOLEAN, 32,
3659 TFS(&tfs_butype_attr_recover_incremental), 0x00000040, "recover_incremental", HFILL }},
3661 { &hf_ndmp_butype_attr_backup_utf8, {
3662 "Backup UTF8", "ndmp.butype.attr.backup_utf8", FT_BOOLEAN, 32,
3663 TFS(&tfs_butype_attr_backup_utf8), 0x00000080, "backup_utf8", HFILL }},
3665 { &hf_ndmp_butype_attr_recover_utf8, {
3666 "Recover UTF8", "ndmp.butype.attr.recover_utf8", FT_BOOLEAN, 32,
3667 TFS(&tfs_butype_attr_recover_utf8), 0x00000100, "recover_utf8", HFILL }},
3669 { &hf_ndmp_butype_env_name, {
3670 "Name", "ndmp.butype.env.name", FT_STRING, BASE_NONE,
3671 NULL, 0, "Name for this env-variable", HFILL }},
3673 { &hf_ndmp_butype_env_value, {
3674 "Value", "ndmp.butype.env.value", FT_STRING, BASE_NONE,
3675 NULL, 0, "Value for this env-variable", HFILL }},
3677 { &hf_ndmp_tcp_env_name, {
3678 "Name", "ndmp.tcp.env.name", FT_STRING, BASE_NONE,
3679 NULL, 0, "Name for this env-variable", HFILL }},
3681 { &hf_ndmp_tcp_env_value, {
3682 "Value", "ndmp.tcp.env.value", FT_STRING, BASE_NONE,
3683 NULL, 0, "Value for this env-variable", HFILL }},
3685 { &hf_ndmp_fs_info, {
3686 "FS Info", "ndmp.fs.info", FT_NONE, BASE_NONE,
3687 NULL, 0, NULL, HFILL }},
3689 { &hf_ndmp_fs_invalid_total_size, {
3690 "Total size invalid", "ndmp.fs.invalid.total_size", FT_BOOLEAN, 32,
3691 TFS(&tfs_fs_invalid_total_size), 0x00000001, "If total size is invalid", HFILL }},
3693 { &hf_ndmp_fs_invalid_used_size, {
3694 "Used size invalid", "ndmp.fs.invalid.used_size", FT_BOOLEAN, 32,
3695 TFS(&tfs_fs_invalid_used_size), 0x00000002, "If used size is invalid", HFILL }},
3697 { &hf_ndmp_fs_invalid_avail_size, {
3698 "Available size invalid", "ndmp.fs.invalid.avail_size", FT_BOOLEAN, 32,
3699 TFS(&tfs_fs_invalid_avail_size), 0x00000004, "If available size is invalid", HFILL }},
3701 { &hf_ndmp_fs_invalid_total_inodes, {
3702 "Total number of inodes invalid", "ndmp.fs.invalid.total_inodes", FT_BOOLEAN, 32,
3703 TFS(&tfs_fs_invalid_total_inodes), 0x00000008, "If total number of inodes is invalid", HFILL }},
3705 { &hf_ndmp_fs_invalid_used_inodes, {
3706 "Used number of inodes is invalid", "ndmp.fs.invalid.used_inodes", FT_BOOLEAN, 32,
3707 TFS(&tfs_fs_invalid_used_inodes), 0x00000010, "If used number of inodes is invalid", HFILL }},
3709 { &hf_ndmp_fs_fs_type, {
3710 "Type", "ndmp.fs.type", FT_STRING, BASE_NONE,
3711 NULL, 0, "Type of FS", HFILL }},
3713 { &hf_ndmp_fs_logical_device, {
3714 "Logical Device", "ndmp.fs.logical_device", FT_STRING, BASE_NONE,
3715 NULL, 0, "Name of logical device", HFILL }},
3717 { &hf_ndmp_fs_physical_device, {
3718 "Physical Device", "ndmp.fs.physical_device", FT_STRING, BASE_NONE,
3719 NULL, 0, "Name of physical device", HFILL }},
3721 { &hf_ndmp_fs_total_size, {
3722 "Total Size", "ndmp.fs.total_size", FT_UINT64, BASE_DEC,
3723 NULL, 0, "Total size of FS", HFILL }},
3725 { &hf_ndmp_fs_used_size, {
3726 "Used Size", "ndmp.fs.used_size", FT_UINT64, BASE_DEC,
3727 NULL, 0, "Total used size of FS", HFILL }},
3729 { &hf_ndmp_fs_avail_size, {
3730 "Avail Size", "ndmp.fs.avail_size", FT_UINT64, BASE_DEC,
3731 NULL, 0, "Total available size on FS", HFILL }},
3733 { &hf_ndmp_fs_total_inodes, {
3734 "Total Inodes", "ndmp.fs.total_inodes", FT_UINT64, BASE_DEC,
3735 NULL, 0, "Total number of inodes on FS", HFILL }},
3737 { &hf_ndmp_fs_used_inodes, {
3738 "Used Inodes", "ndmp.fs.used_inodes", FT_UINT64, BASE_DEC,
3739 NULL, 0, "Number of used inodes on FS", HFILL }},
3741 { &hf_ndmp_fs_env, {
3742 "Env variables", "ndmp.fs.env", FT_NONE, BASE_NONE,
3743 NULL, 0, "Environment variables for FS", HFILL }},
3745 { &hf_ndmp_fs_env_name, {
3746 "Name", "ndmp.fs.env.name", FT_STRING, BASE_NONE,
3747 NULL, 0, "Name for this env-variable", HFILL }},
3749 { &hf_ndmp_fs_env_value, {
3750 "Value", "ndmp.fs.env.value", FT_STRING, BASE_NONE,
3751 NULL, 0, "Value for this env-variable", HFILL }},
3753 { &hf_ndmp_fs_status, {
3754 "Status", "ndmp.fs.status", FT_STRING, BASE_NONE,
3755 NULL, 0, "Status for this FS", HFILL }},
3757 { &hf_ndmp_tape_info, {
3758 "Tape Info", "ndmp.tape.info", FT_NONE, BASE_NONE,
3759 NULL, 0, NULL, HFILL }},
3761 { &hf_ndmp_tape_model, {
3762 "Model", "ndmp.tape.model", FT_STRING, BASE_NONE,
3763 NULL, 0, "Model of the TAPE drive", HFILL }},
3765 { &hf_ndmp_tape_dev_cap, {
3766 "Device Capability", "ndmp.tape.dev_cap", FT_NONE, BASE_NONE,
3767 NULL, 0, "Tape Device Capability", HFILL }},
3769 { &hf_ndmp_tape_device, {
3770 "Device", "ndmp.tape.device", FT_STRING, BASE_NONE,
3771 NULL, 0, "Name of TAPE Device", HFILL }},
3773 { &hf_ndmp_tape_attr_rewind, {
3774 "Device supports rewind", "ndmp.tape.attr.rewind", FT_BOOLEAN, 32,
3775 TFS(&tfs_tape_attr_rewind), 0x00000001, "If this device supports rewind", HFILL }},
3777 { &hf_ndmp_tape_attr_unload, {
3778 "Device supports unload", "ndmp.tape.attr.unload", FT_BOOLEAN, 32,
3779 TFS(&tfs_tape_attr_unload), 0x00000002, "If this device supports unload", HFILL }},
3781 { &hf_ndmp_tape_capability, {
3782 "Tape Capabilities", "ndmp.tape.capability", FT_NONE, BASE_NONE,
3783 NULL, 0, NULL, HFILL }},
3785 { &hf_ndmp_tape_capability_name, {
3786 "Name", "ndmp.tape.cap.name", FT_STRING, BASE_NONE,
3787 NULL, 0, "Name for this env-variable", HFILL }},
3789 { &hf_ndmp_tape_capability_value, {
3790 "Value", "ndmp.tape.cap.value", FT_STRING, BASE_NONE,
3791 NULL, 0, "Value for this env-variable", HFILL }},
3793 { &hf_ndmp_scsi_info, {
3794 "SCSI Info", "ndmp.scsi.info", FT_NONE, BASE_NONE,
3795 NULL, 0, NULL, HFILL }},
3797 { &hf_ndmp_scsi_model, {
3798 "Model", "ndmp.scsi.model", FT_STRING, BASE_NONE,
3799 NULL, 0, "Model of the SCSI device", HFILL }},
3801 { &hf_ndmp_server_vendor, {
3802 "Vendor", "ndmp.server.vendor", FT_STRING, BASE_NONE,
3803 NULL, 0, "Name of vendor", HFILL }},
3805 { &hf_ndmp_server_product, {
3806 "Product", "ndmp.server.product", FT_STRING, BASE_NONE,
3807 NULL, 0, "Name of product", HFILL }},
3809 { &hf_ndmp_server_revision, {
3810 "Revision", "ndmp.server.revision", FT_STRING, BASE_NONE,
3811 NULL, 0, "Revision of this product", HFILL }},
3813 { &hf_ndmp_auth_types, {
3814 "Auth types", "ndmp.auth.types", FT_NONE, BASE_NONE,
3815 NULL, 0, NULL, HFILL }},
3817 { &hf_ndmp_scsi_device, {
3818 "Device", "ndmp.scsi.device", FT_STRING, BASE_NONE,
3819 NULL, 0, "Name of SCSI Device", HFILL }},
3821 { &hf_ndmp_scsi_controller, {
3822 "Controller", "ndmp.scsi.controller", FT_UINT32, BASE_DEC,
3823 NULL, 0, "Target Controller", HFILL }},
3825 { &hf_ndmp_scsi_id, {
3826 "ID", "ndmp.scsi.id", FT_UINT32, BASE_DEC,
3827 NULL, 0, "Target ID", HFILL }},
3829 { &hf_ndmp_scsi_lun, {
3830 "LUN", "ndmp.scsi.lun", FT_UINT32, BASE_DEC,
3831 NULL, 0, "Target LUN", HFILL }},
3833 { &hf_ndmp_execute_cdb_flags_data_in, {
3834 "DATA_IN", "ndmp.execute_cdb.flags.data_in", FT_BOOLEAN, 32,
3835 NULL, 0x00000001, NULL, HFILL }},
3837 { &hf_ndmp_execute_cdb_flags_data_out, {
3838 "DATA_OUT", "ndmp.execute_cdb.flags.data_out", FT_BOOLEAN, 32,
3839 NULL, 0x00000002, NULL, HFILL }},
3841 { &hf_ndmp_execute_cdb_timeout, {
3842 "Timeout", "ndmp.execute_cdb.timeout", FT_UINT32, BASE_DEC,
3843 NULL, 0, "Reselect timeout, in milliseconds", HFILL }},
3845 { &hf_ndmp_execute_cdb_datain_len, {
3846 "Data in length", "ndmp.execute_cdb.datain_len", FT_UINT32, BASE_DEC,
3847 NULL, 0, "Expected length of data bytes to read", HFILL }},
3849 { &hf_ndmp_execute_cdb_cdb_len, {
3850 "CDB length", "ndmp.execute_cdb.cdb_len", FT_UINT32, BASE_DEC,
3851 NULL, 0, "Length of CDB", HFILL }},
3853 #if 0
3854 { &hf_ndmp_execute_cdb_dataout, {
3855 "Data out", "ndmp.execute_cdb.dataout", FT_BYTES, BASE_NONE,
3856 NULL, 0, "Data to be transferred to the SCSI device", HFILL }},
3857 #endif
3859 { &hf_ndmp_execute_cdb_status, {
3860 "Status", "ndmp.execute_cdb.status", FT_UINT8, BASE_DEC,
3861 VALS(scsi_status_val), 0, "SCSI status", HFILL }},
3863 { &hf_ndmp_execute_cdb_dataout_len, {
3864 "Data out length", "ndmp.execute_cdb.dataout_len", FT_UINT32, BASE_DEC,
3865 NULL, 0, "Number of bytes transferred to the device", HFILL }},
3867 #if 0
3868 { &hf_ndmp_execute_cdb_datain, {
3869 "Data in", "ndmp.execute_cdb.datain", FT_BYTES, BASE_NONE,
3870 NULL, 0, "Data transferred from the SCSI device", HFILL }},
3871 #endif
3873 { &hf_ndmp_execute_cdb_sns_len, {
3874 "Sense data length", "ndmp.execute_cdb.sns_len", FT_UINT32, BASE_DEC,
3875 NULL, 0, "Length of sense data", HFILL }},
3877 { &hf_ndmp_tape_open_mode, {
3878 "Mode", "ndmp.tape.open_mode", FT_UINT32, BASE_DEC,
3879 VALS(tape_open_mode_vals), 0, "Mode to open tape in", HFILL }},
3881 { &hf_ndmp_tape_invalid_file_num, {
3882 "Invalid file num", "ndmp.tape.invalid.file_num", FT_BOOLEAN, 32,
3883 TFS(&tfs_ndmp_tape_invalid_file_num), 0x00000001, "invalid_file_num", HFILL }},
3885 { &hf_ndmp_tape_invalid_soft_errors, {
3886 "Soft errors", "ndmp.tape.invalid.soft_errors", FT_BOOLEAN, 32,
3887 TFS(&tfs_ndmp_tape_invalid_soft_errors), 0x00000002, "soft_errors", HFILL }},
3889 { &hf_ndmp_tape_invalid_block_size, {
3890 "Block size", "ndmp.tape.invalid.block_size", FT_BOOLEAN, 32,
3891 TFS(&tfs_ndmp_tape_invalid_block_size), 0x00000004, "block_size", HFILL }},
3893 { &hf_ndmp_tape_invalid_block_no, {
3894 "Block no", "ndmp.tape.invalid.block_no", FT_BOOLEAN, 32,
3895 TFS(&tfs_ndmp_tape_invalid_block_no), 0x00000008, "block_no", HFILL }},
3897 { &hf_ndmp_tape_invalid_total_space, {
3898 "Total space", "ndmp.tape.invalid.total_space", FT_BOOLEAN, 32,
3899 TFS(&tfs_ndmp_tape_invalid_total_space), 0x00000010, "total_space", HFILL }},
3901 { &hf_ndmp_tape_invalid_space_remain, {
3902 "Space remain", "ndmp.tape.invalid.space_remain", FT_BOOLEAN, 32,
3903 TFS(&tfs_ndmp_tape_invalid_space_remain), 0x00000020, "space_remain", HFILL }},
3905 { &hf_ndmp_tape_invalid_partition, {
3906 "Invalid partition", "ndmp.tape.invalid.partition", FT_BOOLEAN, 32,
3907 TFS(&tfs_ndmp_tape_invalid_partition), 0x00000040, "partition", HFILL }},
3909 { &hf_ndmp_tape_flags_no_rewind, {
3910 "No rewind", "ndmp.tape.flags.no_rewind", FT_BOOLEAN, 32,
3911 TFS(&tfs_ndmp_tape_flags_no_rewind), 0x00000008, "no_rewind", HFILL, }},
3913 { &hf_ndmp_tape_flags_write_protect, {
3914 "Write protect", "ndmp.tape.flags.write_protect", FT_BOOLEAN, 32,
3915 TFS(&tfs_ndmp_tape_flags_write_protect), 0x00000010, "write_protect", HFILL, }},
3917 { &hf_ndmp_tape_flags_error, {
3918 "Error", "ndmp.tape.flags.error", FT_BOOLEAN, 32,
3919 TFS(&tfs_ndmp_tape_flags_error), 0x00000020, NULL, HFILL, }},
3921 { &hf_ndmp_tape_flags_unload, {
3922 "Unload", "ndmp.tape.flags.unload", FT_BOOLEAN, 32,
3923 TFS(&tfs_ndmp_tape_flags_unload), 0x00000040, NULL, HFILL, }},
3925 { &hf_ndmp_tape_file_num, {
3926 "file_num", "ndmp.tape.status.file_num", FT_UINT32, BASE_DEC,
3927 NULL, 0, NULL, HFILL }},
3929 { &hf_ndmp_tape_soft_errors, {
3930 "soft_errors", "ndmp.tape.status.soft_errors", FT_UINT32, BASE_DEC,
3931 NULL, 0, NULL, HFILL }},
3933 { &hf_ndmp_tape_block_size, {
3934 "block_size", "ndmp.tape.status.block_size", FT_UINT32, BASE_DEC,
3935 NULL, 0, NULL, HFILL }},
3937 { &hf_ndmp_tape_block_no, {
3938 "block_no", "ndmp.tape.status.block_no", FT_UINT32, BASE_DEC,
3939 NULL, 0, NULL, HFILL }},
3941 { &hf_ndmp_tape_total_space, {
3942 "total_space", "ndmp.tape.status.total_space", FT_UINT64, BASE_DEC,
3943 NULL, 0, NULL, HFILL }},
3945 { &hf_ndmp_tape_space_remain, {
3946 "space_remain", "ndmp.tape.status.space_remain", FT_UINT64, BASE_DEC,
3947 NULL, 0, NULL, HFILL }},
3949 { &hf_ndmp_tape_partition, {
3950 "partition", "ndmp.tape.status.partition", FT_UINT32, BASE_DEC,
3951 NULL, 0, NULL, HFILL }},
3953 { &hf_ndmp_tape_mtio_op, {
3954 "Operation", "ndmp.tape.mtio.op", FT_UINT32, BASE_DEC,
3955 VALS(tape_mtio_vals), 0, "MTIO Operation", HFILL }},
3957 { &hf_ndmp_count, {
3958 "Count", "ndmp.count", FT_UINT32, BASE_DEC,
3959 NULL, 0, "Number of bytes/objects/operations", HFILL }},
3961 { &hf_ndmp_resid_count, {
3962 "Resid Count", "ndmp.resid_count", FT_UINT32, BASE_DEC,
3963 NULL, 0, "Number of remaining bytes/objects/operations", HFILL }},
3965 { &hf_ndmp_mover_state, {
3966 "State", "ndmp.mover.state", FT_UINT32, BASE_DEC,
3967 VALS(mover_state_vals), 0, "State of the selected mover", HFILL }},
3969 { &hf_ndmp_mover_pause, {
3970 "Pause", "ndmp.mover.pause", FT_UINT32, BASE_DEC,
3971 VALS(mover_pause_vals), 0, "Reason why the mover paused", HFILL }},
3973 { &hf_ndmp_halt, {
3974 "Halt", "ndmp.halt", FT_UINT32, BASE_DEC,
3975 VALS(halt_vals), 0, "Reason why it halted", HFILL }},
3977 { &hf_ndmp_record_size, {
3978 "Record Size", "ndmp.record.size", FT_UINT32, BASE_DEC,
3979 NULL, 0, "Record size in bytes", HFILL }},
3981 { &hf_ndmp_record_num, {
3982 "Record Num", "ndmp.record.num", FT_UINT32, BASE_DEC,
3983 NULL, 0, "Number of records", HFILL }},
3985 { &hf_ndmp_data_written, {
3986 "Data Written", "ndmp.data.written", FT_UINT64, BASE_DEC,
3987 NULL, 0, "Number of data bytes written", HFILL }},
3989 { &hf_ndmp_seek_position, {
3990 "Seek Position", "ndmp.seek.position", FT_UINT64, BASE_DEC,
3991 NULL, 0, "Current seek position on device", HFILL }},
3993 { &hf_ndmp_bytes_left_to_read, {
3994 "Bytes left to read", "ndmp.bytes_left_to_read", FT_UINT64, BASE_DEC,
3995 NULL, 0, "Number of bytes left to be read from the device", HFILL }},
3997 { &hf_ndmp_window_offset, {
3998 "Window Offset", "ndmp.window.offset", FT_UINT64, BASE_DEC,
3999 NULL, 0, "Offset to window in bytes", HFILL }},
4001 { &hf_ndmp_window_length, {
4002 "Window Length", "ndmp.window.length", FT_UINT64, BASE_DEC,
4003 NULL, 0, "Size of window in bytes", HFILL }},
4005 { &hf_ndmp_addr_ip, {
4006 "IP Address", "ndmp.addr.ip", FT_IPv4, BASE_NONE,
4007 NULL, 0, NULL, HFILL }},
4009 { &hf_ndmp_addr_tcp, {
4010 "TCP Port", "ndmp.addr.tcp_port", FT_UINT32, BASE_DEC,
4011 NULL, 0, NULL, HFILL }},
4013 { &hf_ndmp_addr_fcal_loop_id, {
4014 "Loop ID", "ndmp.addr.loop_id", FT_UINT32, BASE_HEX,
4015 NULL, 0, "FCAL Loop ID", HFILL }},
4017 { &hf_ndmp_addr_ipc, {
4018 "IPC", "ndmp.addr.ipc", FT_BYTES, BASE_NONE,
4019 NULL, 0, "IPC identifier", HFILL }},
4021 { &hf_ndmp_mover_mode, {
4022 "Mode", "ndmp.mover.mode", FT_UINT32, BASE_HEX,
4023 VALS(mover_mode_vals), 0, "Mover Mode", HFILL }},
4025 { &hf_ndmp_file_name, {
4026 "File", "ndmp.file", FT_STRING, BASE_NONE,
4027 NULL, 0, "Name of File", HFILL }},
4029 { &hf_ndmp_nt_file_name, {
4030 "NT File", "ndmp.file", FT_STRING, BASE_NONE,
4031 NULL, 0, "NT Name of File", HFILL }},
4033 { &hf_ndmp_dos_file_name, {
4034 "DOS File", "ndmp.file", FT_STRING, BASE_NONE,
4035 NULL, 0, "DOS Name of File", HFILL }},
4037 { &hf_ndmp_log_type, {
4038 "Type", "ndmp.log.type", FT_UINT32, BASE_HEX,
4039 VALS(log_type_vals), 0, "Type of log entry", HFILL }},
4041 { &hf_ndmp_log_message_id, {
4042 "Message ID", "ndmp.log.message.id", FT_UINT32, BASE_DEC,
4043 NULL, 0, "ID of this log entry", HFILL }},
4045 { &hf_ndmp_log_message, {
4046 "Message", "ndmp.log.message", FT_STRING, BASE_NONE,
4047 NULL, 0, "Log entry", HFILL }},
4049 { &hf_ndmp_halt_reason, {
4050 "Reason", "ndmp.halt.reason", FT_STRING, BASE_NONE,
4051 NULL, 0, "Textual reason for why it halted", HFILL }},
4053 { &hf_ndmp_connected, {
4054 "Connected", "ndmp.connected", FT_UINT32, BASE_DEC,
4055 VALS(connected_vals), 0, "Status of connection", HFILL }},
4057 { &hf_ndmp_connected_reason, {
4058 "Reason", "ndmp.connected.reason", FT_STRING, BASE_NONE,
4059 NULL, 0, "Textual description of the connection status", HFILL }},
4061 { &hf_ndmp_auth_id, {
4062 "ID", "ndmp.auth.id", FT_STRING, BASE_NONE,
4063 NULL, 0, "ID of client authenticating", HFILL }},
4065 { &hf_ndmp_auth_password, {
4066 "Password", "ndmp.auth.password", FT_STRING, BASE_NONE,
4067 NULL, 0, "Password of client authenticating", HFILL }},
4069 { &hf_ndmp_data, {
4070 "Data", "ndmp.data", FT_BYTES, BASE_NONE,
4071 NULL, 0, "Data written/read", HFILL }},
4073 { &hf_ndmp_files, {
4074 "Files", "ndmp.files", FT_NONE, BASE_NONE,
4075 NULL, 0, "List of files", HFILL }},
4077 { &hf_ndmp_file_names, {
4078 "File Names", "ndmp.file.names", FT_NONE, BASE_NONE,
4079 NULL, 0, "List of file names", HFILL }},
4081 { &hf_ndmp_file_fs_type, {
4082 "File FS Type", "ndmp.file.fs_type", FT_UINT32, BASE_DEC,
4083 VALS(file_fs_type_vals), 0, "Type of file permissions (UNIX or NT)", HFILL }},
4085 { &hf_ndmp_file_type, {
4086 "File Type", "ndmp.file.type", FT_UINT32, BASE_DEC,
4087 VALS(file_type_vals), 0, "Type of file", HFILL }},
4089 { &hf_ndmp_file_stats, {
4090 "File Stats", "ndmp.file.stats", FT_NONE, BASE_NONE,
4091 NULL, 0, "List of file stats", HFILL }},
4093 { &hf_ndmp_file_node, {
4094 "Node", "ndmp.file.node", FT_UINT64, BASE_DEC,
4095 NULL, 0, "Node used for direct access", HFILL }},
4097 { &hf_ndmp_file_parent, {
4098 "Parent", "ndmp.file.parent", FT_UINT64, BASE_DEC,
4099 NULL, 0, "Parent node(directory) for this node", HFILL }},
4101 { &hf_ndmp_file_fh_info, {
4102 "FH Info", "ndmp.file.fh_info", FT_UINT64, BASE_DEC,
4103 NULL, 0, "FH Info used for direct access", HFILL }},
4105 { &hf_ndmp_file_invalid_atime, {
4106 "Invalid atime", "ndmp.file.invalid_atime", FT_BOOLEAN, 32,
4107 TFS(&tfs_ndmp_file_invalid_atime), 0x00000001, "invalid_atime", HFILL, }},
4109 { &hf_ndmp_file_invalid_ctime, {
4110 "Invalid ctime", "ndmp.file.invalid_ctime", FT_BOOLEAN, 32,
4111 TFS(&tfs_ndmp_file_invalid_ctime), 0x00000002, "invalid_ctime", HFILL, }},
4113 { &hf_ndmp_file_invalid_group, {
4114 "Invalid group", "ndmp.file.invalid_group", FT_BOOLEAN, 32,
4115 TFS(&tfs_ndmp_file_invalid_group), 0x00000004, "invalid_group", HFILL, }},
4117 { &hf_ndmp_file_mtime, {
4118 "mtime", "ndmp.file.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
4119 NULL, 0, "Timestamp for mtime for this file", HFILL }},
4121 { &hf_ndmp_file_atime, {
4122 "atime", "ndmp.file.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
4123 NULL, 0, "Timestamp for atime for this file", HFILL }},
4125 { &hf_ndmp_file_ctime, {
4126 "ctime", "ndmp.file.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
4127 NULL, 0, "Timestamp for ctime for this file", HFILL }},
4129 { &hf_ndmp_file_owner, {
4130 "Owner", "ndmp.file.owner", FT_UINT32, BASE_DEC,
4131 NULL, 0, "UID for UNIX, owner for NT", HFILL }},
4133 { &hf_ndmp_file_group, {
4134 "Group", "ndmp.file.group", FT_UINT32, BASE_DEC,
4135 NULL, 0, "GID for UNIX, NA for NT", HFILL }},
4137 { &hf_ndmp_file_fattr, {
4138 "Fattr", "ndmp.file.fattr", FT_UINT32, BASE_HEX,
4139 NULL, 0, "Mode for UNIX, fattr for NT", HFILL }},
4141 { &hf_ndmp_file_size, {
4142 "Size", "ndmp.file.size", FT_UINT64, BASE_DEC,
4143 NULL, 0, "File Size", HFILL }},
4145 { &hf_ndmp_file_links, {
4146 "Links", "ndmp.file.links", FT_UINT32, BASE_DEC,
4147 NULL, 0, "Number of links to this file", HFILL }},
4149 { &hf_ndmp_dirs, {
4150 "Dirs", "ndmp.dirs", FT_NONE, BASE_NONE,
4151 NULL, 0, "List of directories", HFILL }},
4153 { &hf_ndmp_nodes, {
4154 "Nodes", "ndmp.nodes", FT_NONE, BASE_NONE,
4155 NULL, 0, "List of nodes", HFILL }},
4157 { &hf_ndmp_nlist, {
4158 "Nlist", "ndmp.nlist", FT_NONE, BASE_NONE,
4159 NULL, 0, "List of names", HFILL }},
4161 { &hf_ndmp_bu_original_path, {
4162 "Original Path", "ndmp.bu.original_path", FT_STRING, BASE_NONE,
4163 NULL, 0, "Original path where backup was created", HFILL }},
4165 { &hf_ndmp_bu_destination_dir, {
4166 "Destination Dir", "ndmp.bu.destination_dir", FT_STRING, BASE_NONE,
4167 NULL, 0, "Destination directory to restore backup to", HFILL }},
4169 { &hf_ndmp_bu_new_name, {
4170 "New Name", "ndmp.bu.new_name", FT_STRING, BASE_NONE,
4171 NULL, 0, NULL, HFILL }},
4173 { &hf_ndmp_bu_other_name, {
4174 "Other Name", "ndmp.bu.other_name", FT_STRING, BASE_NONE,
4175 NULL, 0, NULL, HFILL }},
4177 { &hf_ndmp_state_invalid_ebr, {
4178 "EstimatedBytesLeft valid", "ndmp.bu.state.invalid_ebr", FT_BOOLEAN, 32,
4179 TFS(&tfs_ndmp_state_invalid_ebr), 0x00000001, "Whether EstimatedBytesLeft is valid or not", HFILL, }},
4181 { &hf_ndmp_state_invalid_etr, {
4182 "EstimatedTimeLeft valid", "ndmp.bu.state.invalid_etr", FT_BOOLEAN, 32,
4183 TFS(&tfs_ndmp_state_invalid_etr), 0x00000002, "Whether EstimatedTimeLeft is valid or not", HFILL, }},
4185 { &hf_ndmp_bu_operation, {
4186 "Operation", "ndmp.bu.operation", FT_UINT32, BASE_DEC,
4187 VALS(bu_operation_vals), 0, "BU Operation", HFILL, }},
4189 { &hf_ndmp_data_state, {
4190 "State", "ndmp.data.state", FT_UINT32, BASE_DEC,
4191 VALS(data_state_vals), 0, "Data state", HFILL, }},
4193 { &hf_ndmp_data_halted, {
4194 "Halted Reason", "ndmp.data.halted", FT_UINT32, BASE_DEC,
4195 VALS(data_halted_vals), 0, "Data halted reason", HFILL, }},
4197 { &hf_ndmp_data_bytes_processed, {
4198 "Bytes Processed", "ndmp.data.bytes_processed", FT_UINT64, BASE_DEC,
4199 NULL, 0, "Number of bytes processed", HFILL }},
4201 { &hf_ndmp_data_est_bytes_remain, {
4202 "Est Bytes Remain", "ndmp.data.est_bytes_remain", FT_UINT64, BASE_DEC,
4203 NULL, 0, "Estimated number of bytes remaining", HFILL }},
4205 { &hf_ndmp_data_est_time_remain, {
4206 "Est Time Remain", "ndmp.data.est_time_remain", FT_RELATIVE_TIME, BASE_NONE,
4207 NULL, 0, "Estimated time remaining", HFILL }},
4208 { &hf_ndmp_lastfrag, {
4209 "Last Fragment", "ndmp.lastfrag", FT_BOOLEAN, 32,
4210 TFS(&tfs_yes_no), RPC_RM_LASTFRAG, NULL, HFILL }},
4211 { &hf_ndmp_fraglen, {
4212 "Fragment Length", "ndmp.fraglen", FT_UINT32, BASE_DEC,
4213 NULL, RPC_RM_FRAGLEN, NULL, HFILL }},
4214 { &hf_ndmp_class_list, {
4215 "Ext Class List", "ndmp.class_list", FT_NONE, BASE_NONE,
4216 NULL, 0, "List of extension classes", HFILL }},
4217 { &hf_ndmp_ex_class_id, {
4218 "Class ID", "ndmp.class.id", FT_UINT32, BASE_HEX,
4219 NULL, 0, NULL, HFILL }},
4220 { &hf_ndmp_ext_version_list, {
4221 "Ext Version List", "ndmp.ext_version_list", FT_NONE, BASE_NONE,
4222 NULL, 0, "List of extension versions", HFILL }},
4223 { &hf_ndmp_ext_version, {
4224 "Ext Version", "ndmp.ext_version_list.version", FT_UINT32, BASE_HEX,
4225 NULL, 0, "Extension version", HFILL }},
4226 { &hf_ndmp_class_version, {
4227 "Class and version", "ndmp.ext_version", FT_NONE, BASE_NONE,
4228 NULL, 0, NULL, HFILL }},
4229 { &hf_ndmp_ex_class_version, {
4230 "Class Version", "ndmp.class.version", FT_UINT32, BASE_HEX,
4231 NULL, 0, NULL, HFILL }},
4232 {&hf_ndmp_fragments, {
4233 "NDMP fragments", "ndmp.fragments", FT_NONE, BASE_NONE,
4234 NULL, 0x00, NULL, HFILL } },
4235 {&hf_ndmp_fragment,
4236 {"NDMP fragment", "ndmp.fragment",
4237 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4238 {&hf_ndmp_fragment_overlap,
4239 {"NDMP fragment overlap", "ndmp.fragment.overlap",
4240 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4241 {&hf_ndmp_fragment_overlap_conflicts,
4242 {"NDMP fragment overlapping with conflicting data",
4243 "ndmp.fragment.overlap.conflicts",
4244 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4245 {&hf_ndmp_fragment_multiple_tails,
4246 {"NDMP has multiple tail fragments",
4247 "ndmp.fragment.multiple_tails",
4248 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4249 {&hf_ndmp_fragment_too_long_fragment,
4250 {"NDMP fragment too long", "ndmp.fragment.too_long_fragment",
4251 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4252 {&hf_ndmp_fragment_error,
4253 {"NDMP defragmentation error", "ndmp.fragment.error",
4254 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4255 {&hf_ndmp_fragment_count,
4256 {"NDMP fragment count", "ndmp.fragment.count",
4257 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
4258 {&hf_ndmp_reassembled_in,
4259 {"Reassembled in", "ndmp.reassembled.in",
4260 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4261 {&hf_ndmp_reassembled_length,
4262 {"Reassembled NDMP length", "ndmp.reassembled.length",
4263 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
4266 static gint *ett[] = {
4267 &ett_ndmp,
4268 &ett_ndmp_fraghdr,
4269 &ett_ndmp_header,
4270 &ett_ndmp_butype_attrs,
4271 &ett_ndmp_fs_invalid,
4272 &ett_ndmp_tape_attr,
4273 &ett_ndmp_execute_cdb_flags,
4274 &ett_ndmp_execute_cdb_cdb,
4275 &ett_ndmp_execute_cdb_sns,
4276 &ett_ndmp_execute_cdb_payload,
4277 &ett_ndmp_tape_invalid,
4278 &ett_ndmp_tape_flags,
4279 &ett_ndmp_addr,
4280 &ett_ndmp_file,
4281 &ett_ndmp_file_name,
4282 &ett_ndmp_file_stats,
4283 &ett_ndmp_file_invalids,
4284 &ett_ndmp_state_invalids,
4285 &ett_ndmp_fragment,
4286 &ett_ndmp_fragments,
4289 module_t *ndmp_module;
4291 proto_ndmp = proto_register_protocol("Network Data Management Protocol", "NDMP", "ndmp");
4292 proto_register_field_array(proto_ndmp, hf_ndmp, array_length(hf_ndmp));
4294 proto_register_subtree_array(ett, array_length(ett));
4296 /* desegmentation */
4297 ndmp_module = prefs_register_protocol(proto_ndmp, NULL);
4298 prefs_register_obsolete_preference(ndmp_module, "protocol_version");
4299 prefs_register_enum_preference(ndmp_module,
4300 "default_protocol_version",
4301 "Default protocol version",
4302 "Version of the NDMP protocol to assume if the version can not be automatically detected from the capture",
4303 &ndmp_default_protocol_version,
4304 ndmp_protocol_versions,
4305 FALSE);
4306 prefs_register_bool_preference(ndmp_module, "desegment",
4307 "Reassemble NDMP messages spanning multiple TCP segments",
4308 "Whether the NDMP dissector should reassemble messages spanning multiple TCP segments."
4309 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
4310 &ndmp_desegment);
4311 prefs_register_bool_preference(ndmp_module, "defragment",
4312 "Reassemble fragmented NDMP messages spanning multiple packets",
4313 "Whether the dissector should defragment NDMP messages spanning multiple packets.",
4314 &ndmp_defragment);
4315 register_init_routine(ndmp_init);
4318 void
4319 proto_reg_handoff_ndmp(void)
4321 ndmp_handle = new_create_dissector_handle(dissect_ndmp, proto_ndmp);
4322 dissector_add_uint("tcp.port",TCP_PORT_NDMP, ndmp_handle);
4323 heur_dissector_add("tcp", dissect_ndmp_heur, proto_ndmp);
4327 * Editor modelines - http://www.wireshark.org/tools/modelines.html
4329 * Local variables:
4330 * c-basic-offset: 8
4331 * tab-width: 8
4332 * indent-tabs-mode: t
4333 * End:
4335 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4336 * :indentSize=8:tabSize=8:noTabs=false: