Absolute and Relative times were swapped. Also add comment that there seems
[obnox/wireshark/wip.git] / packet-ndmp.c
1 /* packet-ndmp.c
2  * Routines for NDMP dissection
3  * 2001 Ronnie Sahlberg (see AUTHORS for email)
4  *
5  * $Id: packet-ndmp.c,v 1.16 2002/02/18 23:51:55 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 /* see www.ndmp.org for protocol specifications.
27    this file implements version 3 of ndmp 
28 */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
36 #endif
37
38 #include <stdio.h>
39 #include <string.h>
40 #include <glib.h>
41
42 #include <epan/packet.h>
43 #include <epan/conversation.h>
44 #include "packet-rpc.h"
45 #include "packet-scsi.h"
46 #include "packet-frame.h"
47 #include "prefs.h"
48 #include "reassemble.h"
49 #include "rpc_defrag.h"
50
51 #define TCP_PORT_NDMP 10000
52
53 static int proto_ndmp = -1;
54 static int hf_ndmp_version = -1;
55 static int hf_ndmp_header = -1;
56 static int hf_ndmp_sequence = -1;
57 static int hf_ndmp_reply_sequence = -1;
58 static int hf_ndmp_timestamp = -1;
59 static int hf_ndmp_msgtype = -1;
60 static int hf_ndmp_msg = -1;
61 static int hf_ndmp_error = -1;
62 static int hf_ndmp_hostname = -1;
63 static int hf_ndmp_os_type = -1;
64 static int hf_ndmp_os_vers = -1;
65 static int hf_ndmp_hostid = -1;
66 static int hf_ndmp_addr_types = -1;
67 static int hf_ndmp_addr_type = -1;
68 static int hf_ndmp_auth_type = -1;
69 static int hf_ndmp_auth_types = -1;
70 static int hf_ndmp_auth_challenge = -1;
71 static int hf_ndmp_auth_digest = -1;
72 static int hf_ndmp_auth_id = -1;
73 static int hf_ndmp_auth_password = -1;
74 static int hf_ndmp_butype_info = -1;
75 static int hf_ndmp_butype_name = -1;
76 static int hf_ndmp_butype_default_env = -1;
77 static int hf_ndmp_butype_attr_backup_file_history = -1;
78 static int hf_ndmp_butype_attr_backup_filelist = -1;
79 static int hf_ndmp_butype_attr_recover_filelist = -1;
80 static int hf_ndmp_butype_attr_backup_direct = -1;
81 static int hf_ndmp_butype_attr_recover_direct = -1;
82 static int hf_ndmp_butype_attr_backup_incremental = -1;
83 static int hf_ndmp_butype_attr_recover_incremental = -1;
84 static int hf_ndmp_butype_attr_backup_utf8 = -1;
85 static int hf_ndmp_butype_attr_recover_utf8 = -1;
86 static int hf_ndmp_butype_env_name = -1;
87 static int hf_ndmp_butype_env_value = -1;
88 static int hf_ndmp_fs_info = -1;
89 static int hf_ndmp_fs_invalid_total_size = -1;
90 static int hf_ndmp_fs_invalid_used_size = -1;
91 static int hf_ndmp_fs_invalid_avail_size = -1;
92 static int hf_ndmp_fs_invalid_total_inodes = -1;
93 static int hf_ndmp_fs_invalid_used_inodes = -1;
94 static int hf_ndmp_fs_fs_type = -1;
95 static int hf_ndmp_fs_logical_device = -1;
96 static int hf_ndmp_fs_physical_device = -1;
97 static int hf_ndmp_fs_total_size = -1;
98 static int hf_ndmp_fs_used_size = -1;
99 static int hf_ndmp_fs_avail_size = -1;
100 static int hf_ndmp_fs_total_inodes = -1;
101 static int hf_ndmp_fs_used_inodes = -1;
102 static int hf_ndmp_fs_env = -1;
103 static int hf_ndmp_fs_env_name = -1;
104 static int hf_ndmp_fs_env_value = -1;
105 static int hf_ndmp_fs_status = -1;
106 static int hf_ndmp_tape_info = -1;
107 static int hf_ndmp_tape_model = -1;
108 static int hf_ndmp_tape_dev_cap = -1;
109 static int hf_ndmp_tape_device = -1;
110 static int hf_ndmp_tape_open_mode = -1;
111 static int hf_ndmp_tape_attr_rewind = -1;
112 static int hf_ndmp_tape_attr_unload = -1;
113 static int hf_ndmp_tape_capability = -1;
114 static int hf_ndmp_tape_capability_name = -1;
115 static int hf_ndmp_tape_capability_value = -1;
116 static int hf_ndmp_scsi_info = -1;
117 static int hf_ndmp_scsi_model = -1;
118 static int hf_ndmp_server_vendor = -1;
119 static int hf_ndmp_server_product = -1;
120 static int hf_ndmp_server_revision = -1;
121 static int hf_ndmp_scsi_device = -1;
122 static int hf_ndmp_scsi_controller = -1;
123 static int hf_ndmp_scsi_id = -1;
124 static int hf_ndmp_scsi_lun = -1;
125 static int hf_ndmp_execute_cdb_flags_data_in = -1;
126 static int hf_ndmp_execute_cdb_flags_data_out = -1;
127 static int hf_ndmp_execute_cdb_timeout = -1;
128 static int hf_ndmp_execute_cdb_datain_len = -1;
129 static int hf_ndmp_execute_cdb_cdb_len = -1;
130 static int hf_ndmp_execute_cdb_dataout = -1;
131 static int hf_ndmp_execute_cdb_status = -1;
132 static int hf_ndmp_execute_cdb_dataout_len = -1;
133 static int hf_ndmp_execute_cdb_datain = -1;
134 static int hf_ndmp_execute_cdb_sns_len = -1;
135 static int hf_ndmp_tape_invalid_file_num = -1;
136 static int hf_ndmp_tape_invalid_soft_errors = -1;
137 static int hf_ndmp_tape_invalid_block_size = -1;
138 static int hf_ndmp_tape_invalid_block_no = -1;
139 static int hf_ndmp_tape_invalid_total_space = -1;
140 static int hf_ndmp_tape_invalid_space_remain = -1;
141 static int hf_ndmp_tape_invalid_partition = -1;
142 static int hf_ndmp_tape_flags_no_rewind = -1;
143 static int hf_ndmp_tape_flags_write_protect = -1;
144 static int hf_ndmp_tape_flags_error = -1;
145 static int hf_ndmp_tape_flags_unload = -1;
146 static int hf_ndmp_tape_file_num = -1;
147 static int hf_ndmp_tape_soft_errors = -1;
148 static int hf_ndmp_tape_block_size = -1;
149 static int hf_ndmp_tape_block_no = -1;
150 static int hf_ndmp_tape_total_space = -1;
151 static int hf_ndmp_tape_space_remain = -1;
152 static int hf_ndmp_tape_partition = -1;
153 static int hf_ndmp_tape_mtio_op = -1;
154 static int hf_ndmp_count = -1;
155 static int hf_ndmp_resid_count = -1;
156 static int hf_ndmp_mover_state = -1;
157 static int hf_ndmp_mover_pause = -1;
158 static int hf_ndmp_halt = -1;
159 static int hf_ndmp_halt_reason = -1;
160 static int hf_ndmp_record_size = -1;
161 static int hf_ndmp_record_num = -1;
162 static int hf_ndmp_data_written = -1;
163 static int hf_ndmp_seek_position = -1;
164 static int hf_ndmp_bytes_left_to_read = -1;
165 static int hf_ndmp_window_offset = -1;
166 static int hf_ndmp_window_length = -1;
167 static int hf_ndmp_addr_ip = -1;
168 static int hf_ndmp_addr_tcp = -1;
169 static int hf_ndmp_addr_fcal_loop_id = -1;
170 static int hf_ndmp_addr_ipc = -1;
171 static int hf_ndmp_mover_mode = -1;
172 static int hf_ndmp_file_name = -1;
173 static int hf_ndmp_nt_file_name = -1;
174 static int hf_ndmp_dos_file_name = -1;
175 static int hf_ndmp_log_type = -1;
176 static int hf_ndmp_log_message_id = -1;
177 static int hf_ndmp_log_message = -1;
178 static int hf_ndmp_connected = -1;
179 static int hf_ndmp_connected_reason = -1;
180 static int hf_ndmp_data = -1;
181 static int hf_ndmp_files = -1;
182 static int hf_ndmp_file_fs_type = -1;
183 static int hf_ndmp_file_names = -1;
184 static int hf_ndmp_file_stats = -1;
185 static int hf_ndmp_file_node = -1;
186 static int hf_ndmp_file_parent = -1;
187 static int hf_ndmp_file_fh_info = -1;
188 static int hf_ndmp_file_invalid_atime = -1;
189 static int hf_ndmp_file_invalid_ctime = -1;
190 static int hf_ndmp_file_invalid_group = -1;
191 static int hf_ndmp_file_type = -1;
192 static int hf_ndmp_file_mtime = -1;
193 static int hf_ndmp_file_atime = -1;
194 static int hf_ndmp_file_ctime = -1;
195 static int hf_ndmp_file_owner = -1;
196 static int hf_ndmp_file_group = -1;
197 static int hf_ndmp_file_fattr = -1;
198 static int hf_ndmp_file_size = -1;
199 static int hf_ndmp_file_links = -1;
200 static int hf_ndmp_dirs = -1;
201 static int hf_ndmp_nodes = -1;
202 static int hf_ndmp_nlist = -1;
203 static int hf_ndmp_bu_original_path = -1;
204 static int hf_ndmp_bu_destination_dir = -1;
205 static int hf_ndmp_bu_new_name = -1;
206 static int hf_ndmp_bu_other_name = -1;
207 static int hf_ndmp_state_invalid_ebr = -1;
208 static int hf_ndmp_state_invalid_etr = -1;
209 static int hf_ndmp_bu_operation = -1;
210 static int hf_ndmp_data_state = -1;
211 static int hf_ndmp_data_halted = -1;
212 static int hf_ndmp_data_bytes_processed = -1;
213 static int hf_ndmp_data_est_bytes_remain = -1;
214 static int hf_ndmp_data_est_time_remain = -1;
215
216 static gint ett_ndmp = -1;
217 static gint ett_ndmp_header = -1;
218 static gint ett_ndmp_butype_attrs = -1;
219 static gint ett_ndmp_fs_invalid = -1;
220 static gint ett_ndmp_tape_attr = -1;
221 static gint ett_ndmp_execute_cdb_flags = -1;
222 static gint ett_ndmp_execute_cdb_cdb = -1;
223 static gint ett_ndmp_execute_cdb_sns = -1;
224 static gint ett_ndmp_execute_cdb_payload = -1;
225 static gint ett_ndmp_tape_invalid = -1;
226 static gint ett_ndmp_tape_flags = -1;
227 static gint ett_ndmp_addr = -1;
228 static gint ett_ndmp_file = -1;
229 static gint ett_ndmp_file_name = -1;
230 static gint ett_ndmp_file_stats = -1;
231 static gint ett_ndmp_file_invalids = -1;
232 static gint ett_ndmp_state_invalids = -1;
233
234 struct ndmp_header {
235         guint32 seq;
236         guint32 time;
237         guint32 type;
238         guint32 msg;
239         guint32 rep_seq;
240         guint32 err;
241 };
242
243 /* desegmentation of NDMP packets */
244 static gboolean ndmp_desegment = TRUE;
245
246 /* defragmentation of fragmented NDMP records */
247 static gboolean ndmp_defragment = FALSE;
248
249 #define NDMP_MESSAGE_REQUEST    0x00
250 #define NDMP_MESSAGE_REPLY      0x01
251 static const value_string msg_type_vals[] = {
252         {NDMP_MESSAGE_REQUEST,          "Request"},
253         {NDMP_MESSAGE_REPLY,            "Reply"},
254         {0, NULL}
255 };
256
257 #define NDMP_NO_ERR                     0x00
258 #define NDMP_NOT_SUPPORTED_ERR          0x01
259 #define NDMP_DEVICE_BUSY_ERR            0x02
260 #define NDMP_DEVICE_OPENED_ERR          0x03
261 #define NDMP_NOT_AUTHORIZED_ERR         0x04
262 #define NDMP_PERMISSION_ERR             0x05
263 #define NDMP_DEV_NOT_OPEN_ERR           0x06
264 #define NDMP_IO_ERR                     0x07
265 #define NDMP_TIMEOUT_ERR                0x08
266 #define NDMP_ILLEGAL_ARGS_ERR           0x09
267 #define NDMP_NO_TAPE_LOADED_ERR         0x0a
268 #define NDMP_WRITE_PROTECT_ERR          0x0b
269 #define NDMP_EOF_ERR                    0x0c
270 #define NDMP_EOM_ERR                    0x0d
271 #define NDMP_FILE_NOT_FOUND_ERR         0x0e
272 #define NDMP_BAD_FILE_ERR               0x0f
273 #define NDMP_NO_DEVICE_ERR              0x10
274 #define NDMP_NO_BUS_ERR                 0x11
275 #define NDMP_XDR_DECODE_ERR             0x12
276 #define NDMP_ILLEGAL_STATE_ERR          0x13
277 #define NDMP_UNDEFINED_ERR              0x14
278 #define NDMP_XDR_ENCODE_ERR             0x15
279 #define NDMP_NO_MEM_ERR                 0x16
280 #define NDMP_CONNECT_ERR                0x17
281
282 static const value_string error_vals[] = {
283         {NDMP_NO_ERR,                   "NO_ERR"},
284         {NDMP_NOT_SUPPORTED_ERR,        "NOT_SUPPORTED_ERR"},
285         {NDMP_DEVICE_BUSY_ERR,          "DEVICE_BUSY_ERR"},
286         {NDMP_DEVICE_OPENED_ERR,        "DEVICE_OPENED_ERR"},
287         {NDMP_NOT_AUTHORIZED_ERR,       "NOT_AUTHORIZED_ERR"},
288         {NDMP_PERMISSION_ERR,           "PERMISSION_ERR"},
289         {NDMP_DEV_NOT_OPEN_ERR,         "DEV_NOT_OPEN_ERR"},
290         {NDMP_IO_ERR,                   "IO_ERR"},
291         {NDMP_TIMEOUT_ERR,              "TIMEOUT_ERR"},
292         {NDMP_ILLEGAL_ARGS_ERR,         "ILLEGAL_ARGS_ERR"},
293         {NDMP_NO_TAPE_LOADED_ERR,       "NO_TAPE_LOADED_ERR"},
294         {NDMP_WRITE_PROTECT_ERR,        "WRITE_PROTECT_ERR"},
295         {NDMP_EOF_ERR,                  "EOF_ERR"},
296         {NDMP_EOM_ERR,                  "EOM_ERR"},
297         {NDMP_FILE_NOT_FOUND_ERR,       "FILE_NOT_FOUND_ERR"},
298         {NDMP_BAD_FILE_ERR,             "BAD_FILE_ERR"},
299         {NDMP_NO_DEVICE_ERR,            "NO_DEVICE_ERR"},
300         {NDMP_NO_BUS_ERR,               "NO_BUS_ERR"},
301         {NDMP_XDR_DECODE_ERR,           "XDR_DECODE_ERR"},
302         {NDMP_ILLEGAL_STATE_ERR,        "ILLEGAL_STATE_ERR"},
303         {NDMP_UNDEFINED_ERR,            "UNDEFINED_ERR"},
304         {NDMP_XDR_ENCODE_ERR,           "XDR_ENCODE_ERR"},
305         {NDMP_NO_MEM_ERR,               "NO_MEM_ERR"},
306         {NDMP_CONNECT_ERR,              "CONNECT_ERR"},
307         {0, NULL}
308 };
309
310
311
312 #define NDMP_CONFIG_GET_HOST_INFO       0x100
313 #define NDMP_CONFIG_GET_CONNECTION_TYPE 0x102
314 #define NDMP_CONFIG_GET_AUTH_ATTR       0x103
315 #define NDMP_CONFIG_GET_BUTYPE_INFO     0x104
316 #define NDMP_CONFIG_GET_FS_INFO         0x105
317 #define NDMP_CONFIG_GET_TAPE_INFO       0x106
318 #define NDMP_CONFIG_GET_SCSI_INFO       0x107
319 #define NDMP_CONFIG_GET_SERVER_INFO     0x108
320 #define NDMP_SCSI_OPEN                  0x200
321 #define NDMP_SCSI_CLOSE                 0x201
322 #define NDMP_SCSI_GET_STATE             0x202
323 #define NDMP_SCSI_SET_TARGET            0x203
324 #define NDMP_SCSI_RESET_DEVICE          0x204
325 #define NDMP_SCSI_RESET_BUS             0x205
326 #define NDMP_SCSI_EXECUTE_CDB           0x206
327 #define NDMP_TAPE_OPEN                  0x300
328 #define NDMP_TAPE_CLOSE                 0x301
329 #define NDMP_TAPE_GET_STATE             0x302
330 #define NDMP_TAPE_MTIO                  0x303
331 #define NDMP_TAPE_WRITE                 0x304
332 #define NDMP_TAPE_READ                  0x305
333 #define NDMP_TAPE_EXECUTE_CDB           0x307
334 #define NDMP_DATA_GET_STATE             0x400
335 #define NDMP_DATA_START_BACKUP          0x401
336 #define NDMP_DATA_START_RECOVER         0x402
337 #define NDMP_DATA_ABORT                 0x403
338 #define NDMP_DATA_GET_ENV               0x404
339 #define NDMP_DATA_STOP                  0x407
340 #define NDMP_DATA_LISTEN                0x409
341 #define NDMP_DATA_CONNECT               0x40a
342 #define NDMP_NOTIFY_DATA_HALTED         0x501
343 #define NDMP_NOTIFY_CONNECTED           0x502
344 #define NDMP_NOTIFY_MOVER_HALTED        0x503
345 #define NDMP_NOTIFY_MOVER_PAUSED        0x504
346 #define NDMP_NOTIFY_DATA_READ           0x505
347 #define NDMP_LOG_FILE                   0x602
348 #define NDMP_LOG_MESSAGE                0x603
349 #define NDMP_FH_ADD_FILE                0x703
350 #define NDMP_FH_ADD_DIR                 0x704
351 #define NDMP_FH_ADD_NODE                0x705
352 #define NDMP_CONNECT_OPEN               0x900
353 #define NDMP_CONNECT_CLIENT_AUTH        0x901
354 #define NDMP_CONNECT_CLOSE              0x902
355 #define NDMP_CONNECT_SERVER_AUTH        0x903
356 #define NDMP_MOVER_GET_STATE            0xa00
357 #define NDMP_MOVER_LISTEN               0xa01
358 #define NDMP_MOVER_CONTINUE             0xa02
359 #define NDMP_MOVER_ABORT                0xa03
360 #define NDMP_MOVER_STOP                 0xa04
361 #define NDMP_MOVER_SET_WINDOW           0xa05
362 #define NDMP_MOVER_READ                 0xa06
363 #define NDMP_MOVER_CLOSE                0xa07
364 #define NDMP_MOVER_SET_RECORD_SIZE      0xa08
365 #define NDMP_MOVER_CONNECT              0xa09
366
367
368
369
370 static const value_string msg_vals[] = {
371         {NDMP_CONFIG_GET_HOST_INFO,     "CONFIG_GET_HOST_INFO"},
372         {NDMP_CONFIG_GET_CONNECTION_TYPE, "CONFIG_GET_CONNECTION_TYPE"},
373         {NDMP_CONFIG_GET_AUTH_ATTR,     "CONFIG_GET_AUTH_ATTR"},
374         {NDMP_CONFIG_GET_BUTYPE_INFO,   "CONFIG_GET_BUTYPE_INFO"},
375         {NDMP_CONFIG_GET_FS_INFO,       "CONFIG_GET_FS_INFO"},
376         {NDMP_CONFIG_GET_TAPE_INFO,     "CONFIG_GET_TAPE_INFO"},
377         {NDMP_CONFIG_GET_SCSI_INFO,     "CONFIG_GET_SCSI_INFO"},
378         {NDMP_CONFIG_GET_SERVER_INFO,   "CONFIG_GET_SERVER_INFO"},
379         {NDMP_SCSI_OPEN,                "SCSI_OPEN"},
380         {NDMP_SCSI_CLOSE,               "SCSI_CLOSE"},
381         {NDMP_SCSI_GET_STATE,           "SCSI_GET_STATE"},
382         {NDMP_SCSI_SET_TARGET,          "SCSI_SET_TARGET"},
383         {NDMP_SCSI_RESET_DEVICE,        "SCSI_RESET_DEVICE"},
384         {NDMP_SCSI_RESET_BUS,           "SCSI_RESET_BUS"},
385         {NDMP_SCSI_EXECUTE_CDB,         "SCSI_EXECUTE_CDB"},
386         {NDMP_TAPE_OPEN,                "TAPE_OPEN"},
387         {NDMP_TAPE_CLOSE,               "TAPE_CLOSE"},
388         {NDMP_TAPE_GET_STATE,           "TAPE_GET_STATE"},
389         {NDMP_TAPE_MTIO,                "TAPE_MTIO"},
390         {NDMP_TAPE_WRITE,               "TAPE_WRITE"},
391         {NDMP_TAPE_READ,                "TAPE_READ"},
392         {NDMP_TAPE_EXECUTE_CDB,         "TAPE_EXECUTE_CDB"},
393         {NDMP_DATA_GET_STATE,           "DATA_GET_STATE"},
394         {NDMP_DATA_START_BACKUP,        "DATA_START_BACKUP"},
395         {NDMP_DATA_START_RECOVER,       "DATA_START_RECOVER"},
396         {NDMP_DATA_ABORT,               "DATA_ABORT"},
397         {NDMP_DATA_GET_ENV,             "DATA_GET_ENV"},
398         {NDMP_DATA_STOP,                "DATA_STOP"},
399         {NDMP_DATA_LISTEN,              "DATA_LISTEN"},
400         {NDMP_DATA_CONNECT,             "DATA_CONNECT"},
401         {NDMP_NOTIFY_DATA_HALTED,       "NOTIFY_DATA_HALTED"},
402         {NDMP_NOTIFY_CONNECTED,         "NOTIFY_CONNECTED"},
403         {NDMP_NOTIFY_MOVER_HALTED,      "NOTIFY_MOVER_HALTED"},
404         {NDMP_NOTIFY_MOVER_PAUSED,      "NOTIFY_MOVER_PAUSED"},
405         {NDMP_NOTIFY_DATA_READ,         "NOTIFY_DATA_READ"},
406         {NDMP_LOG_FILE,                 "LOG_FILE"},
407         {NDMP_LOG_MESSAGE,              "LOG_MESSAGE"},
408         {NDMP_FH_ADD_FILE,              "FH_ADD_FILE"},
409         {NDMP_FH_ADD_DIR,               "FH_ADD_DIR"},
410         {NDMP_FH_ADD_NODE,              "FH_ADD_NODE"},
411         {NDMP_CONNECT_OPEN,             "CONNECT_OPEN"},
412         {NDMP_CONNECT_CLIENT_AUTH,      "CONNECT_CLIENT_AUTH"},
413         {NDMP_CONNECT_CLOSE,            "CONNECT_CLOSE"},
414         {NDMP_CONNECT_SERVER_AUTH,      "CONNECT_SERVER_AUTH"},
415         {NDMP_MOVER_GET_STATE,          "MOVER_GET_STATE"},
416         {NDMP_MOVER_LISTEN,             "MOVER_LISTEN"},
417         {NDMP_MOVER_CONTINUE,           "MOVER_CONTINUE"},
418         {NDMP_MOVER_ABORT,              "MOVER_ABORT"},
419         {NDMP_MOVER_STOP,               "MOVER_STOP"},
420         {NDMP_MOVER_SET_WINDOW,         "MOVER_SET_WINDOW"},
421         {NDMP_MOVER_READ,               "MOVER_READ"},
422         {NDMP_MOVER_CLOSE,              "MOVER_CLOSE"},
423         {NDMP_MOVER_SET_RECORD_SIZE,    "MOVER_SET_RECORD_SIZE"},
424         {NDMP_MOVER_CONNECT,            "MOVER_CONNECT"},
425         {0, NULL}
426 };
427
428
429 static int
430 dissect_connect_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
431     proto_tree *tree, guint32 seq)
432 {
433         /* version number */
434         proto_tree_add_item(tree, hf_ndmp_version, tvb, offset, 4, FALSE);
435         offset += 4;
436
437         return offset;
438 }
439
440 static int
441 dissect_error(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
442     guint32 seq)
443 {
444         /* error */
445         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
446         offset += 4;
447
448         return offset;
449 }
450
451 static int
452 dissect_ndmp_get_host_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
453     proto_tree *tree, guint32 seq)
454 {
455         /* error */
456         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
457         offset += 4;
458
459         /* hostname */
460         offset = dissect_rpc_string(tvb, pinfo, tree,
461                         hf_ndmp_hostname, offset, NULL);
462
463         /* os type */
464         offset = dissect_rpc_string(tvb, pinfo, tree,
465                         hf_ndmp_os_type, offset, NULL);
466
467         /* os version */
468         offset = dissect_rpc_string(tvb, pinfo, tree,
469                         hf_ndmp_os_vers, offset, NULL);
470
471         /* hostid */
472         offset = dissect_rpc_string(tvb, pinfo, tree,
473                         hf_ndmp_hostid, offset, NULL);
474
475         return offset;
476 }
477
478 #define NDMP_ADDR_LOCAL         0
479 #define NDMP_ADDR_TCP           1
480 #define NDMP_ADDR_FC            2
481 #define NDMP_ADDR_IPC           3
482 static const value_string addr_type_vals[] = {
483         {NDMP_ADDR_LOCAL,       "Local"},
484         {NDMP_ADDR_TCP,         "TCP"},
485         {NDMP_ADDR_FC,          "FC"},
486         {NDMP_ADDR_IPC,         "IPC"},
487         {0,NULL}
488 };
489
490 static int
491 dissect_ndmp_addr_type(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
492 {
493         proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, FALSE);
494         offset += 4;
495
496         return offset;
497 }
498
499 static int
500 dissect_ndmp_addr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
501     proto_tree *tree, guint32 seq)
502 {
503         /*address type*/
504         return dissect_ndmp_addr_type(tvb, offset, pinfo, tree);
505 }
506
507 static int
508 dissect_ndmp_config_get_connection_type_reply(tvbuff_t *tvb, int offset,
509     packet_info *pinfo, proto_tree *tree, guint32 seq)
510 {
511         /* error */
512         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
513         offset += 4;
514
515         /* addr types */
516         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
517                         dissect_ndmp_addr_type, hf_ndmp_addr_types);
518
519         return offset;
520 }
521
522 #define NDMP_AUTH_NONE          0
523 #define NDMP_AUTH_TEXT          1
524 #define NDMP_AUTH_MD5           2
525 static const value_string auth_type_vals[] = {
526         {NDMP_AUTH_NONE,        "None"},
527         {NDMP_AUTH_TEXT,        "Text"},
528         {NDMP_AUTH_MD5,         "MD5"},
529         {0,NULL}
530 };
531 static int
532 dissect_auth_type(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
533 {
534         proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, FALSE);
535         offset += 4;
536
537         return offset;
538 }
539
540 static int
541 dissect_get_auth_type_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
542     proto_tree *tree, guint32 seq)
543 {
544         /* auth type */
545         return dissect_auth_type(tvb, offset, pinfo, tree);
546 }
547
548 static int
549 dissect_auth_attr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
550     proto_tree *tree, guint32 seq)
551 {
552         guint type;
553         
554         type=tvb_get_ntohl(tvb,offset);
555
556         /* auth type */
557         proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, FALSE);
558         offset += 4;
559
560         switch(type){
561         case NDMP_AUTH_NONE:
562                 break;
563         case NDMP_AUTH_TEXT:
564                 break;
565         case NDMP_AUTH_MD5:
566                 proto_tree_add_item(tree, hf_ndmp_auth_challenge, 
567                         tvb, offset, 64, FALSE);
568                 offset+=64;
569         }
570
571         return offset;
572 }
573
574 static int
575 dissect_default_env(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
576 {
577         /* name */
578         offset = dissect_rpc_string(tvb, pinfo, tree,
579                         hf_ndmp_butype_env_name, offset, NULL);
580
581         /* value */
582         offset = dissect_rpc_string(tvb, pinfo, tree,
583                         hf_ndmp_butype_env_value, offset, NULL);
584
585         return offset;
586 }
587
588
589 static const true_false_string tfs_butype_attr_backup_file_history = {
590         "Backup FILE HISTORY",
591         "Do NOT backup file history"
592 };
593 static const true_false_string tfs_butype_attr_backup_filelist = {
594         "Backup FILELIST",
595         "Do NOT backup filelist"
596 };
597 static const true_false_string tfs_butype_attr_recover_filelist = {
598         "Recover FILELIST",
599         "Do NOT recover filelist"
600 };
601 static const true_false_string tfs_butype_attr_backup_direct = {
602         "Perform DIRECT backup",
603         "Do NOT perform direct backup"
604 };
605 static const true_false_string tfs_butype_attr_recover_direct = {
606         "Perform DIRECT recovery",
607         "Do NOT perform direct recovery"
608 };
609 static const true_false_string tfs_butype_attr_backup_incremental = {
610         "Perform INCREMENTAL backup",
611         "Perform FULL backup"
612 };
613 static const true_false_string tfs_butype_attr_recover_incremental = {
614         "Perform INCREMENTAL revocery",
615         "Perform FULL recovery"
616 };
617 static const true_false_string tfs_butype_attr_backup_utf8 = {
618         "Backup using UTF8",
619         "Normal backup. Do NOT use utf8"
620 };
621 static const true_false_string tfs_butype_attr_recover_utf8 = {
622         "Recover using UTF8",
623         "Normal recover. Do NOT use utf8"
624 };
625 static int
626 dissect_butype_attrs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
627 {
628         proto_item* item = NULL;
629         proto_tree* tree = NULL;
630         guint32 flags;
631
632         flags=tvb_get_ntohl(tvb, offset);
633         if (parent_tree) {
634                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
635                                 "Attributes: 0x%08x", flags);
636                 tree = proto_item_add_subtree(item, ett_ndmp_butype_attrs);
637         }
638
639         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_utf8,
640                                 tvb, offset, 4, flags);
641         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_utf8,
642                                 tvb, offset, 4, flags);
643         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_incremental,
644                                 tvb, offset, 4, flags);
645         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_incremental,
646                                 tvb, offset, 4, flags);
647         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_direct,
648                                 tvb, offset, 4, flags);
649         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_direct,
650                                 tvb, offset, 4, flags);
651         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_recover_filelist,
652                                 tvb, offset, 4, flags);
653         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_filelist,
654                                 tvb, offset, 4, flags);
655         proto_tree_add_boolean(tree, hf_ndmp_butype_attr_backup_file_history,
656                                 tvb, offset, 4, flags);
657
658         offset += 4;
659         return offset;
660 }
661
662 static int
663 dissect_butype_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
664 {
665         /*butype name*/
666         offset = dissect_rpc_string(tvb, pinfo, tree,
667                         hf_ndmp_butype_name, offset, NULL);
668
669         /* default env */
670         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
671                         dissect_default_env, hf_ndmp_butype_default_env);
672
673         /* attrs */
674         offset = dissect_butype_attrs(tvb, offset, pinfo, tree);
675
676         return offset;
677 }
678
679 static int
680 dissect_get_butype_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
681     proto_tree *tree, guint32 seq)
682 {
683         /* error */
684         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
685         offset += 4;
686
687         /* butype */
688         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
689                         dissect_butype_info, hf_ndmp_butype_info);
690
691         return offset;
692 }
693
694 static const true_false_string tfs_fs_invalid_total_size = {
695         "Total size is INVALID",
696         "Total size is VALID"
697 };
698 static const true_false_string tfs_fs_invalid_used_size = {
699         "Used size is INVALID",
700         "Used size is VALID"
701 };
702 static const true_false_string tfs_fs_invalid_avail_size = {
703         "Available size is INVALID",
704         "Available size is VALID"
705 };
706 static const true_false_string tfs_fs_invalid_total_inodes = {
707         "Total inode count is INVALID",
708         "Total inode count is VALID"
709 };
710 static const true_false_string tfs_fs_invalid_used_inodes = {
711         "Used inode count is INVALID",
712         "Used inode count is VALID"
713 };
714 static int
715 dissect_fs_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
716 {
717         proto_item* item = NULL;
718         proto_tree* tree = NULL;
719         guint32 flags;
720
721         flags=tvb_get_ntohl(tvb, offset);
722         if (parent_tree) {
723                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
724                                 "Invalids: 0x%08x", flags);
725                 tree = proto_item_add_subtree(item, ett_ndmp_fs_invalid);
726         }
727
728         proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_used_inodes,
729                                 tvb, offset, 4, flags);
730         proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_total_inodes,
731                                 tvb, offset, 4, flags);
732         proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_avail_size,
733                                 tvb, offset, 4, flags);
734         proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_used_size,
735                                 tvb, offset, 4, flags);
736         proto_tree_add_boolean(tree, hf_ndmp_fs_invalid_total_size,
737                                 tvb, offset, 4, flags);
738
739         offset+=4;
740         return offset;
741 }
742
743 static int
744 dissect_fs_env(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
745 {
746         /* name */
747         offset = dissect_rpc_string(tvb, pinfo, tree,
748                         hf_ndmp_fs_env_name, offset, NULL);
749
750         /* value */
751         offset = dissect_rpc_string(tvb, pinfo, tree,
752                         hf_ndmp_fs_env_value, offset, NULL);
753
754         return offset;
755 }
756
757 static int
758 dissect_fs_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
759 {
760         /* invalid bits */
761         offset=dissect_fs_invalid(tvb, offset, pinfo, tree);
762
763         /* fs type */
764         offset = dissect_rpc_string(tvb, pinfo, tree,
765                         hf_ndmp_fs_fs_type, offset, NULL);
766
767         /* fs logical device */
768         offset = dissect_rpc_string(tvb, pinfo, tree,
769                         hf_ndmp_fs_logical_device, offset, NULL);
770
771         /* fs physical device */
772         offset = dissect_rpc_string(tvb, pinfo, tree,
773                         hf_ndmp_fs_physical_device, offset, NULL);
774
775         /*total_size*/
776         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_total_size,
777                         offset);
778
779         /*used_size*/
780         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_used_size,
781                         offset);
782
783         /*avail_size*/
784         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_avail_size,
785                         offset);
786
787         /*total_inodes*/
788         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_total_inodes,
789                         offset);
790
791         /*used_inodes*/
792         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_fs_used_inodes,
793                         offset);
794
795         /* env */
796         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
797                         dissect_fs_env, hf_ndmp_fs_env);
798
799         /* status */
800         offset = dissect_rpc_string(tvb, pinfo, tree,
801                         hf_ndmp_fs_status, offset, NULL);
802
803         return offset;
804 }
805
806 static int
807 dissect_get_fs_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
808     proto_tree *tree, guint32 seq)
809 {
810         /* error */
811         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
812         offset += 4;
813
814         /* fs */
815         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
816                         dissect_fs_info, hf_ndmp_fs_info);
817
818         return offset;
819 }
820
821 static const true_false_string tfs_tape_attr_rewind = {
822         "Device supports REWIND",
823         "Device does NOT support rewind"
824 };
825 static const true_false_string tfs_tape_attr_unload = {
826         "Device supports UNLOAD",
827         "Device does NOT support unload"
828 };
829 static int
830 dissect_tape_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
831 {
832         proto_item* item = NULL;
833         proto_tree* tree = NULL;
834         guint32 flags;
835
836         flags=tvb_get_ntohl(tvb, offset);
837         if (parent_tree) {
838                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
839                                 "Attributes: 0x%08x", flags);
840                 tree = proto_item_add_subtree(item, ett_ndmp_tape_attr);
841         }
842
843         proto_tree_add_boolean(tree, hf_ndmp_tape_attr_unload,
844                                 tvb, offset, 4, flags);
845         proto_tree_add_boolean(tree, hf_ndmp_tape_attr_rewind,
846                                 tvb, offset, 4, flags);
847
848         offset+=4;
849         return offset;
850 }
851
852 static int
853 dissect_tape_capability(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
854 {
855         /* name */
856         offset = dissect_rpc_string(tvb, pinfo, tree,
857                         hf_ndmp_tape_capability_name, offset, NULL);
858
859         /* value */
860         offset = dissect_rpc_string(tvb, pinfo, tree,
861                         hf_ndmp_tape_capability_value, offset, NULL);
862
863         return offset;
864 }
865
866 static int
867 dissect_tape_dev_cap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
868 {
869         /* device */
870         offset = dissect_rpc_string(tvb, pinfo, tree,
871                         hf_ndmp_tape_device, offset, NULL);
872
873         /* tape attributes */
874         offset = dissect_tape_attr(tvb, offset, pinfo, tree);
875
876         /* capability */
877         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
878                         dissect_tape_capability, hf_ndmp_tape_capability);
879
880         return offset;
881 }
882
883 static int
884 dissect_tape_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
885 {
886         /* model */
887         offset = dissect_rpc_string(tvb, pinfo, tree,
888                         hf_ndmp_tape_model, offset, NULL);
889
890         /* device capabilites */
891         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
892                         dissect_tape_dev_cap, hf_ndmp_tape_dev_cap);
893
894         return offset;
895 }
896
897 static int
898 dissect_get_tape_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
899     proto_tree *tree, guint32 seq)
900 {
901         /* error */
902         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
903         offset += 4;
904
905         /* tape */
906         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
907                         dissect_tape_info, hf_ndmp_tape_info);
908
909         return offset;
910 }
911
912 static int
913 dissect_scsi_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
914 {
915         /* model */
916         offset = dissect_rpc_string(tvb, pinfo, tree,
917                         hf_ndmp_scsi_model, offset, NULL);
918
919         /* device capabilites */
920         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
921                         dissect_tape_dev_cap, hf_ndmp_tape_dev_cap);
922
923         return offset;
924 }
925
926 static int
927 dissect_get_scsi_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
928     proto_tree *tree, guint32 seq)
929 {
930         /* error */
931         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
932         offset += 4;
933
934         /* scsi */
935         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
936                         dissect_scsi_info, hf_ndmp_scsi_info);
937
938         return offset;
939 }
940
941 static int
942 dissect_get_server_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
943     proto_tree *tree, guint32 seq)
944 {
945         /* error */
946         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
947         offset += 4;
948
949         /* vendor */
950         offset = dissect_rpc_string(tvb, pinfo, tree,
951                         hf_ndmp_server_vendor, offset, NULL);
952
953         /* product */
954         offset = dissect_rpc_string(tvb, pinfo, tree,
955                         hf_ndmp_server_product, offset, NULL);
956
957         /* revision */
958         offset = dissect_rpc_string(tvb, pinfo, tree,
959                         hf_ndmp_server_revision, offset, NULL);
960
961
962         /* server */
963         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
964                         dissect_auth_type, hf_ndmp_auth_types);
965
966         return offset;
967 }
968
969 static int
970 dissect_scsi_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
971     proto_tree *tree, guint32 seq)
972 {
973         /* device */
974         offset = dissect_rpc_string(tvb, pinfo, tree,
975                         hf_ndmp_scsi_device, offset, NULL);
976
977         return offset;
978 }
979
980 static int
981 dissect_scsi_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
982     proto_tree *tree, guint32 seq)
983 {
984         /* error */
985         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
986         offset += 4;
987
988         /* controller */
989         proto_tree_add_item(tree, hf_ndmp_scsi_controller, tvb, offset, 4, FALSE);
990         offset += 4;
991
992         /* id */
993         proto_tree_add_item(tree, hf_ndmp_scsi_id, tvb, offset, 4, FALSE);
994         offset += 4;
995
996         /* lun */
997         proto_tree_add_item(tree, hf_ndmp_scsi_lun, tvb, offset, 4, FALSE);
998         offset += 4;
999
1000         return offset;
1001 }
1002
1003 static int
1004 dissect_scsi_set_state_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1005     proto_tree *tree, guint32 seq)
1006 {
1007         /* device */
1008         offset = dissect_rpc_string(tvb, pinfo, tree,
1009                         hf_ndmp_scsi_device, offset, NULL);
1010
1011         /* controller */
1012         proto_tree_add_item(tree, hf_ndmp_scsi_controller, tvb, offset, 4, FALSE);
1013         offset += 4;
1014
1015         /* id */
1016         proto_tree_add_item(tree, hf_ndmp_scsi_id, tvb, offset, 4, FALSE);
1017         offset += 4;
1018
1019         /* lun */
1020         proto_tree_add_item(tree, hf_ndmp_scsi_lun, tvb, offset, 4, FALSE);
1021         offset += 4;
1022
1023         return offset;
1024 }
1025
1026 static int
1027 dissect_execute_cdb_flags(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1028 {
1029         proto_item* item = NULL;
1030         proto_tree* tree = NULL;
1031         guint32 flags;
1032
1033         flags = tvb_get_ntohl(tvb, offset);
1034         if (parent_tree) {
1035                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1036                                 "Flags: 0x%08x", flags);
1037                 tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_flags);
1038         }
1039         
1040         proto_tree_add_boolean(tree, hf_ndmp_execute_cdb_flags_data_in,
1041                                 tvb, offset, 4, flags);
1042         proto_tree_add_boolean(tree, hf_ndmp_execute_cdb_flags_data_out,
1043                                 tvb, offset, 4, flags);
1044         offset += 4;
1045         return offset;
1046 }
1047
1048 static int
1049 dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1050 {
1051         proto_item* item = NULL;
1052         proto_tree* tree = NULL;
1053         guint32 cdb_len;
1054         guint32 cdb_len_full;
1055
1056         cdb_len = tvb_get_ntohl(tvb, offset);
1057         cdb_len_full = rpc_roundup(cdb_len);
1058         
1059         if (parent_tree) {
1060                 item = proto_tree_add_text(parent_tree, tvb, offset,
1061                                 4+cdb_len_full, "CDB");
1062                 tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_cdb);
1063         }
1064
1065         proto_tree_add_uint(tree, hf_ndmp_execute_cdb_cdb_len, tvb, offset, 4,
1066                         cdb_len);
1067         offset += 4;
1068
1069         if (cdb_len != 0) {
1070                 dissect_scsi_cdb(tvb, pinfo, tree, offset, cdb_len);
1071                 offset += cdb_len_full;
1072         }
1073
1074         return offset;
1075 }
1076
1077
1078 static int
1079 dissect_execute_cdb_payload(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree,
1080     char *name, int hf_len, gboolean isreq)
1081 {
1082         proto_item* item = NULL;
1083         proto_tree* tree = NULL;
1084         guint32 payload_len;
1085         guint32 payload_len_full;
1086
1087         payload_len = tvb_get_ntohl(tvb, offset);
1088         payload_len_full = rpc_roundup(payload_len);
1089         
1090         if (parent_tree) {
1091                 item = proto_tree_add_text(parent_tree, tvb, offset,
1092                                 4+payload_len_full, "%s", name);
1093                 tree = proto_item_add_subtree(item,
1094                     ett_ndmp_execute_cdb_payload);
1095         }
1096
1097         proto_tree_add_uint(tree, hf_len, tvb, offset, 4, payload_len);
1098         offset += 4;
1099
1100         if (payload_len != 0) {
1101                 dissect_scsi_payload(tvb, pinfo, tree, offset, isreq,
1102                     payload_len);
1103                 offset += payload_len_full;
1104         }
1105
1106         return offset;
1107 }
1108
1109 static int
1110 dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1111     proto_tree *tree, guint32 seq)
1112 {
1113         conversation_t *conversation;
1114         scsi_task_id_t task_key;
1115
1116         /*
1117          * We need to provide SCSI task information to the SCSI
1118          * dissection routines.  We use a conversation plus the
1119          * sequence number in requests and the reply sequence
1120          * number in replies to identify SCSI tasks.
1121          */
1122         conversation = find_conversation(&pinfo->src, &pinfo->dst,
1123             pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1124         if (conversation == NULL) {
1125                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
1126                     pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1127         }
1128         task_key.conv_id = conversation->index;
1129         task_key.task_id = seq;
1130         pinfo->private_data = &task_key;
1131         
1132         /* flags */
1133         offset = dissect_execute_cdb_flags(tvb, offset, pinfo, tree);
1134
1135         /* timeout */
1136         proto_tree_add_item(tree, hf_ndmp_execute_cdb_timeout, tvb, offset, 4, FALSE);
1137         offset += 4;
1138
1139         /* datain_len */
1140         proto_tree_add_item(tree, hf_ndmp_execute_cdb_datain_len, tvb, offset, 4, FALSE);
1141         offset += 4;
1142
1143         /* CDB */
1144         offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree);
1145
1146         /* dataout */
1147         offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
1148             "Data out", hf_ndmp_execute_cdb_dataout_len, TRUE);
1149
1150         return offset;
1151 }
1152
1153 static int
1154 dissect_execute_cdb_sns(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1155 {
1156         proto_item* item = NULL;
1157         proto_tree* tree = NULL;
1158         guint32 sns_len;
1159         guint32 sns_len_full;
1160
1161         sns_len = tvb_get_ntohl(tvb, offset);
1162         sns_len_full = rpc_roundup(sns_len);
1163         
1164         if (parent_tree) {
1165                 item = proto_tree_add_text(parent_tree, tvb, offset,
1166                                 4+sns_len_full, "Sense data");
1167                 tree = proto_item_add_subtree(item, ett_ndmp_execute_cdb_sns);
1168         }
1169
1170         proto_tree_add_uint(tree, hf_ndmp_execute_cdb_sns_len, tvb, offset, 4,
1171                         sns_len);
1172         offset += 4;
1173
1174         if (sns_len != 0) {
1175                 dissect_scsi_snsinfo(tvb, pinfo, tree, offset, sns_len);
1176                 offset += sns_len_full;
1177         }
1178
1179         return offset;
1180 }
1181
1182 static int
1183 dissect_execute_cdb_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1184     proto_tree *tree, guint32 seq)
1185 {
1186         conversation_t *conversation;
1187         scsi_task_id_t task_key;
1188
1189         /*
1190          * We need to provide SCSI task information to the SCSI
1191          * dissection routines.  We use a conversation plus the
1192          * sequence number in requests and the reply sequence
1193          * number in replies to identify SCSI tasks.
1194          */
1195         conversation = find_conversation(&pinfo->src, &pinfo->dst,
1196             pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1197         if (conversation != NULL) {
1198                 task_key.conv_id = conversation->index;
1199                 task_key.task_id = seq;
1200                 pinfo->private_data = &task_key;
1201         } else {
1202                 /* no conversation, meaning we didn't see the request */
1203                 pinfo->private_data = NULL;
1204         }
1205         
1206         /* error */
1207         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1208         offset += 4;
1209
1210         /* status */
1211         proto_tree_add_item(tree, hf_ndmp_execute_cdb_status, tvb, offset, 4, FALSE);
1212         offset += 4;
1213
1214         /* dataout_len */
1215         proto_tree_add_item(tree, hf_ndmp_execute_cdb_dataout_len, tvb, offset, 4, FALSE);
1216         offset += 4;
1217
1218         /* datain */
1219         offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
1220             "Data in", hf_ndmp_execute_cdb_datain_len, FALSE);
1221
1222         /* ext_sense */
1223         offset = dissect_execute_cdb_sns(tvb, offset, pinfo, tree);
1224
1225         return offset;
1226 }
1227
1228 #define NDMP_TAPE_OPEN_MODE_READ        0
1229 #define NDMP_TAPE_OPEN_MODE_RDWR        1
1230 static const value_string tape_open_mode_vals[] = {
1231         {NDMP_TAPE_OPEN_MODE_READ,      "Read"},
1232         {NDMP_TAPE_OPEN_MODE_RDWR,      "Read/Write"},
1233         {0, NULL}
1234 };
1235
1236 static int
1237 dissect_tape_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1238     proto_tree *tree, guint32 seq)
1239 {
1240         /* device */
1241         offset = dissect_rpc_string(tvb, pinfo, tree,
1242                         hf_ndmp_tape_device, offset, NULL);
1243
1244         /* open mode */
1245         proto_tree_add_item(tree, hf_ndmp_tape_open_mode, tvb, offset, 4, FALSE);
1246         offset += 4;
1247
1248         return offset;
1249 }
1250
1251
1252 static const true_false_string tfs_ndmp_tape_invalid_file_num = {
1253         "File num is valid",
1254         "File num is INVALID"
1255 };
1256 static const true_false_string tfs_ndmp_tape_invalid_soft_errors = {
1257         "Soft errors is valid",
1258         "Soft errors is INVALID"
1259 };
1260 static const true_false_string tfs_ndmp_tape_invalid_block_size = {
1261         "Block size is valid",
1262         "Block size is INVALID"
1263 };
1264 static const true_false_string tfs_ndmp_tape_invalid_block_no = {
1265         "Block no is valid",
1266         "Block no is INVALID"
1267 };
1268 static const true_false_string tfs_ndmp_tape_invalid_total_space = {
1269         "Total space is valid",
1270         "Total space is INVALID"
1271 };
1272 static const true_false_string tfs_ndmp_tape_invalid_space_remain = {
1273         "Space remaining is INVALID",
1274         "Space remaining is valid"
1275 };
1276 static const true_false_string tfs_ndmp_tape_invalid_partition = {
1277         "Partition is INVALID",
1278         "Partition is valid"
1279 };
1280 static int
1281 dissect_tape_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1282 {
1283         proto_item* item = NULL;
1284         proto_tree* tree = NULL;
1285         guint32 flags;
1286
1287         flags=tvb_get_ntohl(tvb, offset);
1288         if (parent_tree) {
1289                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1290                                 "Invalids: 0x%08x", flags);
1291                 tree = proto_item_add_subtree(item, ett_ndmp_tape_invalid);
1292         }
1293
1294         proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_partition,
1295                                 tvb, offset, 4, flags);
1296         proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_space_remain,
1297                                 tvb, offset, 4, flags);
1298         proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_total_space,
1299                                 tvb, offset, 4, flags);
1300         proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_block_no,
1301                                 tvb, offset, 4, flags);
1302         proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_block_size,
1303                                 tvb, offset, 4, flags);
1304         proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_soft_errors,
1305                                 tvb, offset, 4, flags);
1306         proto_tree_add_boolean(tree, hf_ndmp_tape_invalid_file_num,
1307                                 tvb, offset, 4, flags);
1308
1309         offset+=4;
1310         return offset;
1311 }
1312
1313 static const true_false_string tfs_ndmp_tape_flags_no_rewind = {
1314         "This is a NON-REWINDING device",
1315         "This device supports rewind"
1316 };
1317 static const true_false_string tfs_ndmp_tape_flags_write_protect = {
1318         "This device is WRITE-PROTECTED",
1319         "This device is NOT write-protected"
1320 };
1321 static const true_false_string tfs_ndmp_tape_flags_error = {
1322         "This device shows ERROR",
1323         "This device shows NO errors"
1324 };
1325 static const true_false_string tfs_ndmp_tape_flags_unload = {
1326         "This device supports UNLOAD",
1327         "This device does NOT support unload"
1328 };
1329 static int
1330 dissect_tape_flags(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1331 {
1332         proto_item* item = NULL;
1333         proto_tree* tree = NULL;
1334         guint32 flags;
1335
1336         flags=tvb_get_ntohl(tvb, offset);
1337         if (parent_tree) {
1338                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1339                                 "Flags: 0x%08x", flags);
1340                 tree = proto_item_add_subtree(item, ett_ndmp_tape_flags);
1341         }
1342
1343
1344         proto_tree_add_boolean(tree, hf_ndmp_tape_flags_unload,
1345                                 tvb, offset, 4, flags);
1346         proto_tree_add_boolean(tree, hf_ndmp_tape_flags_error,
1347                                 tvb, offset, 4, flags);
1348         proto_tree_add_boolean(tree, hf_ndmp_tape_flags_write_protect,
1349                                 tvb, offset, 4, flags);
1350         proto_tree_add_boolean(tree, hf_ndmp_tape_flags_no_rewind,
1351                                 tvb, offset, 4, flags);
1352
1353         offset+=4;
1354         return offset;
1355 }
1356
1357 static int
1358 dissect_tape_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1359     proto_tree *tree, guint32 seq)
1360 {
1361         /* invalid bits */
1362         offset=dissect_tape_invalid(tvb, offset, pinfo, tree);
1363
1364         /* error */
1365         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1366         offset += 4;
1367
1368         /* flags */
1369         offset=dissect_tape_flags(tvb, offset, pinfo, tree);
1370
1371         /* file_num */
1372         proto_tree_add_item(tree, hf_ndmp_tape_file_num, tvb, offset, 4, FALSE);
1373         offset += 4;
1374
1375         /* soft_errors */
1376         proto_tree_add_item(tree, hf_ndmp_tape_soft_errors, tvb, offset, 4, FALSE);
1377         offset += 4;
1378
1379         /* block_size */
1380         proto_tree_add_item(tree, hf_ndmp_tape_block_size, tvb, offset, 4, FALSE);
1381         offset += 4;
1382
1383         /* block_no */
1384         proto_tree_add_item(tree, hf_ndmp_tape_block_no, tvb, offset, 4, FALSE);
1385         offset += 4;
1386
1387         /* total_space */
1388         offset = dissect_rpc_uint64(tvb, pinfo, tree,hf_ndmp_tape_total_space,
1389                         offset);
1390
1391         /* space_remain */
1392         offset = dissect_rpc_uint64(tvb, pinfo, tree,hf_ndmp_tape_space_remain,
1393                         offset);
1394
1395         /* partition */
1396         proto_tree_add_item(tree, hf_ndmp_tape_partition, tvb, offset, 4, FALSE);
1397         offset += 4;
1398
1399         return offset;
1400 }
1401
1402 #define NDMP_TAPE_MTIO_FSF      0
1403 #define NDMP_TAPE_MTIO_BSF      1
1404 #define NDMP_TAPE_MTIO_FSR      2
1405 #define NDMP_TAPE_MTIO_BSR      3
1406 #define NDMP_TAPE_MTIO_REW      4
1407 #define NDMP_TAPE_MTIO_EOF      5
1408 #define NDMP_TAPE_MTIO_OFF      6
1409 static const value_string tape_mtio_vals[] = {
1410         {NDMP_TAPE_MTIO_FSF,    "FSF"},
1411         {NDMP_TAPE_MTIO_BSF,    "BSF"},
1412         {NDMP_TAPE_MTIO_FSR,    "FSR"},
1413         {NDMP_TAPE_MTIO_BSR,    "BSR"},
1414         {NDMP_TAPE_MTIO_REW,    "REW"},
1415         {NDMP_TAPE_MTIO_EOF,    "EOF"},
1416         {NDMP_TAPE_MTIO_OFF,    "OFF"},
1417         {0, NULL}
1418 };
1419
1420 static int
1421 dissect_tape_mtio_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1422     proto_tree *tree, guint32 seq)
1423 {
1424         /* op */
1425         proto_tree_add_item(tree, hf_ndmp_tape_mtio_op, tvb, offset, 4, FALSE);
1426         offset += 4;
1427
1428         /* count */
1429         proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, FALSE);
1430         offset += 4;
1431
1432         return offset;
1433 }
1434
1435 static int
1436 dissect_tape_mtio_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1437     proto_tree *tree, guint32 seq)
1438 {
1439         /* error */
1440         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1441         offset += 4;
1442
1443         /* resid count */
1444         proto_tree_add_item(tree, hf_ndmp_resid_count, tvb, offset, 4, FALSE);
1445         offset += 4;
1446
1447         return offset;
1448 }
1449
1450 #define NDMP_MOVER_STATE_IDLE           0
1451 #define NDMP_MOVER_STATE_LISTEN         1
1452 #define NDMP_MOVER_STATE_ACTIVE         2
1453 #define NDMP_MOVER_STATE_PAUSED         3
1454 #define NDMP_MOVER_STATE_HALTED         4
1455 static const value_string mover_state_vals[] = {
1456         {NDMP_MOVER_STATE_IDLE, "MOVER_STATE_IDLE"},
1457         {NDMP_MOVER_STATE_LISTEN,       "MOVER_STATE_LISTEN"},
1458         {NDMP_MOVER_STATE_ACTIVE,       "MOVER_STATE_ACTIVE"},
1459         {NDMP_MOVER_STATE_PAUSED,       "MOVER_STATE_PAUSED"},
1460         {NDMP_MOVER_STATE_HALTED,       "MOVER_STATE_HALTED"},
1461         {0, NULL}
1462 };
1463
1464 #define NDMP_MOVER_PAUSE_NA             0
1465 #define NDMP_MOVER_PAUSE_EOM            1
1466 #define NDMP_MOVER_PAUSE_EOF            2
1467 #define NDMP_MOVER_PAUSE_SEEK           3
1468 #define NDMP_MOVER_PAUSE_MEDIA_ERROR    4
1469 #define NDMP_MOVER_PAUSE_EOW            5
1470 static const value_string mover_pause_vals[] = {
1471         {NDMP_MOVER_PAUSE_NA,           "MOVER_PAUSE_NA"},
1472         {NDMP_MOVER_PAUSE_EOM,          "MOVER_PAUSE_EOM"},
1473         {NDMP_MOVER_PAUSE_EOF,          "MOVER_PAUSE_EOF"},
1474         {NDMP_MOVER_PAUSE_SEEK,         "MOVER_PAUSE_SEEK"},
1475         {NDMP_MOVER_PAUSE_MEDIA_ERROR,  "MOVER_PAUSE_MEDIA_ERROR"},
1476         {NDMP_MOVER_PAUSE_EOW,          "MOVER_PAUSE_EOW"},
1477         {0, NULL}
1478 };
1479
1480 #define NDMP_HALT_NA            0
1481 #define NDMP_HALT_CONNECT_CLOSE 1
1482 #define NDMP_HALT_ABORTED               2
1483 #define NDMP_HALT_INTERNAL_ERROR        3
1484 #define NDMP_HALT_CONNECT_ERROR 4
1485 static const value_string halt_vals[] = {
1486         {NDMP_HALT_NA,                  "HALT_NA"},
1487         {NDMP_HALT_CONNECT_CLOSE,       "HALT_CONNECT_CLOSE"},
1488         {NDMP_HALT_ABORTED,             "HALT_ABORTED"},
1489         {NDMP_HALT_INTERNAL_ERROR,      "HALT_INTERNAL_ERROR"},
1490         {NDMP_HALT_CONNECT_ERROR,       "HALT_CONNECT_ERROR"},
1491         {0, NULL}
1492 };
1493
1494 static int
1495 dissect_ndmp_addr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1496 {
1497         proto_item* item = NULL;
1498         proto_tree* tree = NULL;
1499         guint32 type;
1500
1501         type=tvb_get_ntohl(tvb, offset);
1502         if (parent_tree) {
1503                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1504                                 "Type: %s ", val_to_str(type, addr_type_vals,"Unknown addr type (0x%02x)") );
1505                 tree = proto_item_add_subtree(item, ett_ndmp_addr);
1506         }
1507
1508         /*address type*/
1509         proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, FALSE);
1510         offset += 4;
1511
1512
1513         switch(type){
1514         case NDMP_ADDR_LOCAL:
1515                 break;
1516         case NDMP_ADDR_TCP:
1517                 /* IP addr */
1518                 proto_tree_add_item(tree, hf_ndmp_addr_ip, tvb, offset, 4, FALSE);
1519                 offset+=4;
1520                 
1521                 /* TCP port */
1522                 proto_tree_add_item(tree, hf_ndmp_addr_tcp, tvb, offset, 4, FALSE);
1523                 offset+=4;
1524                 
1525                 break;
1526         case NDMP_ADDR_FC:
1527                 /* FCAL loop id */
1528                 proto_tree_add_item(tree, hf_ndmp_addr_fcal_loop_id, tvb, offset, 4, FALSE);
1529                 offset+=4;
1530
1531                 break;
1532         case NDMP_ADDR_IPC:
1533                 /* IPC address */
1534                 offset = dissect_rpc_data(tvb, pinfo, tree, hf_ndmp_addr_ipc, offset);
1535                 break;
1536         }
1537
1538         return offset;
1539 }
1540                 
1541 static int
1542 dissect_mover_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1543     proto_tree *tree, guint32 seq)
1544 {
1545         /* error */
1546         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1547         offset += 4;
1548
1549         /* mover state */
1550         proto_tree_add_item(tree, hf_ndmp_mover_state, tvb, offset, 4, FALSE);
1551         offset += 4;
1552
1553         /* mover pause */
1554         proto_tree_add_item(tree, hf_ndmp_mover_pause, tvb, offset, 4, FALSE);
1555         offset += 4;
1556
1557         /* halt */
1558         proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, FALSE);
1559         offset += 4;
1560
1561         /* record size */
1562         proto_tree_add_item(tree, hf_ndmp_record_size, tvb, offset, 4, FALSE);
1563         offset += 4;
1564
1565         /* record num */
1566         proto_tree_add_item(tree, hf_ndmp_record_num, tvb, offset, 4, FALSE);
1567         offset += 4;
1568
1569         /* data written */
1570         proto_tree_add_item(tree, hf_ndmp_data_written, tvb, offset, 8, FALSE);
1571         offset += 8;
1572
1573         /* seek position */
1574         proto_tree_add_item(tree, hf_ndmp_seek_position, tvb, offset, 8, FALSE);
1575         offset += 8;
1576
1577         /* bytes left to read */
1578         proto_tree_add_item(tree, hf_ndmp_bytes_left_to_read, tvb, offset, 8, FALSE);
1579         offset += 8;
1580
1581         /* window offset */
1582         proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, FALSE);
1583         offset += 8;
1584
1585         /* window length */
1586         proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, FALSE);
1587         offset += 8;
1588
1589         /* ndmp addr */
1590         offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
1591
1592         return offset;
1593 }
1594
1595 #define NDMP_MOVER_MODE_READ    0
1596 #define NDMP_MOVER_MODE_WRITE   1
1597 static const value_string mover_mode_vals[] = {
1598         {NDMP_MOVER_MODE_READ,  "MODE_READ"},
1599         {NDMP_MOVER_MODE_WRITE, "MOVER_MODE_WRITE"},
1600         {0, NULL}
1601 };
1602
1603 static int
1604 dissect_mover_listen_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1605     proto_tree *tree, guint32 seq)
1606 {
1607         /* mode */
1608         proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, FALSE);
1609         offset += 4;
1610
1611         /*address type*/
1612         proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, FALSE);
1613         offset += 4;
1614
1615         return offset;
1616 }
1617
1618 static int
1619 dissect_mover_listen_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1620     proto_tree *tree, guint32 seq)
1621 {
1622         /* error */
1623         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1624         offset += 4;
1625
1626         /* ndmp addr */
1627         offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
1628
1629         return offset;
1630 }
1631
1632 static int
1633 dissect_mover_set_window_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1634     proto_tree *tree, guint32 seq)
1635 {
1636         /* window offset */
1637         proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, FALSE);
1638         offset += 8;
1639
1640         /* window length */
1641         proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, FALSE);
1642         offset += 8;
1643
1644         return offset;
1645 }
1646
1647 static int
1648 dissect_mover_set_record_size_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1649     proto_tree *tree, guint32 seq)
1650 {
1651         /* record size */
1652         proto_tree_add_item(tree, hf_ndmp_record_size, tvb, offset, 4, FALSE);
1653         offset += 4;
1654
1655         return offset;
1656 }
1657
1658 static int
1659 dissect_mover_connect_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1660     proto_tree *tree, guint32 seq)
1661 {
1662         /* mode */
1663         proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, FALSE);
1664         offset += 4;
1665
1666         /* ndmp addr */
1667         offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
1668
1669         return offset;
1670 }
1671
1672 static int
1673 dissect_log_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1674     proto_tree *tree, guint32 seq)
1675 {
1676         /* file */
1677         offset = dissect_rpc_string(tvb, pinfo, tree,
1678                         hf_ndmp_file_name, offset, NULL);
1679
1680         /* error */
1681         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1682         offset += 4;
1683
1684         return offset;
1685 }
1686
1687 #define NDMP_LOG_TYPE_NORMAL    0
1688 #define NDMP_LOG_TYPE_DEBUG     1
1689 #define NDMP_LOG_TYPE_ERROR     2
1690 #define NDMP_LOG_TYPE_WARNING   3
1691 static const value_string log_type_vals[] = {
1692         {NDMP_LOG_TYPE_NORMAL,  "NORMAL"},
1693         {NDMP_LOG_TYPE_DEBUG,   "DEBUG"},
1694         {NDMP_LOG_TYPE_ERROR,   "ERROR"},
1695         {NDMP_LOG_TYPE_WARNING, "WARNING"},
1696         {0, NULL}
1697 };
1698
1699 static int
1700 dissect_log_message_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1701     proto_tree *tree, guint32 seq)
1702 {
1703         /* type */
1704         proto_tree_add_item(tree, hf_ndmp_log_type, tvb, offset, 4, FALSE);
1705         offset += 4;
1706
1707         /* message id */
1708         proto_tree_add_item(tree, hf_ndmp_log_message_id, tvb, offset, 4, FALSE);
1709         offset += 4;
1710
1711         /* message */
1712         offset = dissect_rpc_string(tvb, pinfo, tree,
1713                         hf_ndmp_log_message, offset, NULL);
1714
1715         return offset;
1716 }
1717
1718 static int
1719 dissect_notify_data_halted_request(tvbuff_t *tvb, int offset,
1720     packet_info *pinfo, proto_tree *tree, guint32 seq)
1721 {
1722         /* halt */
1723         proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, FALSE);
1724         offset += 4;
1725
1726         /* reason */
1727         offset = dissect_rpc_string(tvb, pinfo, tree,
1728                         hf_ndmp_halt_reason, offset, NULL);
1729
1730         return offset;
1731 }
1732
1733 #define NDMP_CONNECTED_CONNECTED        0
1734 #define NDMP_CONNECTED_SHUTDOWN         1
1735 #define NDMP_CONNECTED_REFUSED          2
1736 static const value_string connected_vals[] = {
1737         {NDMP_CONNECTED_CONNECTED,      "CONNECTED"},
1738         {NDMP_CONNECTED_SHUTDOWN,       "SHUTDOWN"},
1739         {NDMP_CONNECTED_REFUSED,        "REFUSED"},
1740         {0, NULL}
1741 };
1742
1743 static int
1744 dissect_notify_connected_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1745     proto_tree *tree, guint32 seq)
1746 {
1747         /* connected */
1748         proto_tree_add_item(tree, hf_ndmp_connected, tvb, offset, 4, FALSE);
1749         offset += 4;
1750
1751         /* version number */
1752         proto_tree_add_item(tree, hf_ndmp_version, tvb, offset, 4, FALSE);
1753         offset += 4;
1754
1755         /* reason */
1756         offset = dissect_rpc_string(tvb, pinfo, tree,
1757                         hf_ndmp_connected_reason, offset, NULL);
1758
1759         return offset;
1760 }
1761
1762
1763 static int
1764 dissect_notify_mover_paused_request(tvbuff_t *tvb, int offset,
1765     packet_info *pinfo, proto_tree *tree, guint32 seq)
1766 {
1767         /* mover pause */
1768         proto_tree_add_item(tree, hf_ndmp_mover_pause, tvb, offset, 4, FALSE);
1769         offset += 4;
1770
1771         /* seek position */
1772         proto_tree_add_item(tree, hf_ndmp_seek_position, tvb, offset, 8, FALSE);
1773         offset += 8;
1774
1775         return offset;
1776 }
1777
1778 static int
1779 dissect_auth_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1780 {
1781         guint type;
1782         
1783         type=tvb_get_ntohl(tvb,offset);
1784
1785         /* auth type */
1786         proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, FALSE);
1787         offset += 4;
1788
1789         switch(type){
1790         case NDMP_AUTH_NONE:
1791                 break;
1792         case NDMP_AUTH_TEXT:
1793                 /* auth id */
1794                 offset = dissect_rpc_string(tvb, pinfo, tree,
1795                                 hf_ndmp_auth_id, offset, NULL);
1796
1797                 /* auth password */
1798                 offset = dissect_rpc_string(tvb, pinfo, tree,
1799                                 hf_ndmp_auth_password, offset, NULL);
1800
1801                 
1802                 break;
1803         case NDMP_AUTH_MD5:
1804                 /* auth id */
1805                 offset = dissect_rpc_string(tvb, pinfo, tree,
1806                                 hf_ndmp_auth_id, offset, NULL);
1807
1808                 /* digest */
1809                 proto_tree_add_item(tree, hf_ndmp_auth_digest, 
1810                         tvb, offset, 16, FALSE);
1811                 offset+=16;
1812         }
1813
1814         return offset;
1815 }
1816
1817 static int
1818 dissect_connect_client_auth_request(tvbuff_t *tvb, int offset,
1819     packet_info *pinfo, proto_tree *tree, guint32 seq)
1820 {
1821         return dissect_auth_data(tvb, offset, pinfo, tree);
1822 }
1823
1824 static int
1825 dissect_connect_server_auth_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1826     proto_tree *tree, guint32 seq)
1827 {
1828         /* error */
1829         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1830         offset += 4;
1831
1832         /* auth data */
1833         offset = dissect_auth_data(tvb, offset, pinfo, tree);
1834
1835         return offset;
1836 }
1837
1838 static int
1839 dissect_tape_write_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1840     proto_tree *tree, guint32 seq)
1841 {
1842         /* data */
1843         offset = dissect_rpc_data(tvb, pinfo, tree, hf_ndmp_data, offset);
1844
1845         return offset;
1846 }
1847
1848 static int
1849 dissect_tape_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1850     proto_tree *tree, guint32 seq)
1851 {
1852         /* error */
1853         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1854         offset += 4;
1855
1856         /* count */
1857         proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, FALSE);
1858         offset += 4;
1859
1860         return offset;
1861 }
1862
1863 static int
1864 dissect_tape_read_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1865     proto_tree *tree, guint32 seq)
1866 {
1867         /* count */
1868         proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, FALSE);
1869         offset += 4;
1870
1871         return offset;
1872 }
1873
1874 static int
1875 dissect_tape_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1876     proto_tree *tree, guint32 seq)
1877 {
1878         /* error */
1879         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
1880         offset += 4;
1881
1882         /* data */
1883         offset = dissect_rpc_data(tvb, pinfo, tree, hf_ndmp_data, offset);
1884
1885         return offset;
1886 }
1887
1888 #define NDMP_FS_UNIX    0
1889 #define NDMP_FS_NT      1
1890 #define NDMP_FS_OTHER   2
1891 static const value_string file_fs_type_vals[] = {
1892         {NDMP_FS_UNIX,  "UNIX"},
1893         {NDMP_FS_NT,    "NT"},
1894         {NDMP_FS_OTHER, "OTHER"},
1895         {0, NULL}
1896 };
1897
1898 static int
1899 dissect_file_name(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1900 {
1901         proto_item* item = NULL;
1902         proto_tree* tree = NULL;
1903         int old_offset=offset;
1904         guint32 type;
1905         char *name;
1906
1907         if (parent_tree) {
1908                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1909                                 "File");
1910                 tree = proto_item_add_subtree(item, ett_ndmp_file_name);
1911         }
1912
1913         /* file type */
1914         type=tvb_get_ntohl(tvb, offset);
1915         proto_tree_add_item(tree, hf_ndmp_file_fs_type, tvb, offset, 4, FALSE);
1916         offset += 4;
1917
1918         switch(type){
1919         case NDMP_FS_UNIX:
1920                 /* file */
1921                 offset = dissect_rpc_string(tvb, pinfo, tree,
1922                                 hf_ndmp_file_name, offset, &name);
1923                 if (check_col(pinfo->cinfo, COL_INFO)){
1924                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", name);
1925                 }
1926                 break;
1927         case NDMP_FS_NT:
1928                 /* nt file */
1929                 offset = dissect_rpc_string(tvb, pinfo, tree,
1930                                 hf_ndmp_nt_file_name, offset, &name);
1931                 if (check_col(pinfo->cinfo, COL_INFO)){
1932                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", name);
1933                 }
1934
1935                 /* dos file */
1936                 offset = dissect_rpc_string(tvb, pinfo, tree,
1937                                 hf_ndmp_dos_file_name, offset, NULL);
1938                 break;
1939         default:
1940                 /* file */
1941                 offset = dissect_rpc_string(tvb, pinfo, tree,
1942                                 hf_ndmp_file_name, offset, &name);
1943                 if (check_col(pinfo->cinfo, COL_INFO)){
1944                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", name);
1945                 }
1946         }
1947
1948         if (check_col(pinfo->cinfo, COL_INFO)){
1949                 col_append_fstr(pinfo->cinfo, COL_INFO, "(%s)",
1950                         val_to_str(type, file_fs_type_vals, "Unknown type") );
1951         }
1952
1953         proto_item_set_len(item, offset-old_offset);    
1954         return offset;
1955 }
1956
1957
1958 static const true_false_string tfs_ndmp_file_invalid_atime = {
1959         "Atime is INVALID",
1960         "Atime is valid"
1961 };
1962 static const true_false_string tfs_ndmp_file_invalid_ctime = {
1963         "Ctime is INVALID",
1964         "Ctime is valid"
1965 };
1966 static const true_false_string tfs_ndmp_file_invalid_group = {
1967         "Group is INVALID",
1968         "Group is valid"
1969 };
1970 static int
1971 dissect_file_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1972 {
1973         proto_item* item = NULL;
1974         proto_tree* tree = NULL;
1975         guint32 flags;
1976
1977         flags=tvb_get_ntohl(tvb, offset);
1978         if (parent_tree) {
1979                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1980                                 "Invalids: 0x%08x", flags);
1981                 tree = proto_item_add_subtree(item, ett_ndmp_file_invalids);
1982         }
1983
1984         proto_tree_add_boolean(tree, hf_ndmp_file_invalid_group,
1985                         tvb, offset, 4, flags);
1986         proto_tree_add_boolean(tree, hf_ndmp_file_invalid_ctime,
1987                         tvb, offset, 4, flags);
1988         proto_tree_add_boolean(tree, hf_ndmp_file_invalid_atime,
1989                         tvb, offset, 4, flags);
1990
1991         offset+=4;
1992         return offset;
1993 }
1994
1995 #define NDMP_FILE_TYPE_DIR      0
1996 #define NDMP_FILE_TYPE_FIFO     1
1997 #define NDMP_FILE_TYPE_CSPEC    2
1998 #define NDMP_FILE_TYPE_BSPEC    3
1999 #define NDMP_FILE_TYPE_REG      4
2000 #define NDMP_FILE_TYPE_SLINK    5
2001 #define NDMP_FILE_TYPE_SOCK     6
2002 #define NDMP_FILE_TYPE_REGISTRY 7
2003 #define NDMP_FILE_TYPE_OTHER    8
2004 static const value_string file_type_vals[] = {
2005         {NDMP_FILE_TYPE_DIR,    "DIR"},
2006         {NDMP_FILE_TYPE_FIFO,   "FIFO"},
2007         {NDMP_FILE_TYPE_CSPEC,  "CSPEC"},
2008         {NDMP_FILE_TYPE_BSPEC,  "BSPEC"},
2009         {NDMP_FILE_TYPE_REG,    "REG"},
2010         {NDMP_FILE_TYPE_SLINK,  "SLINK"},
2011         {NDMP_FILE_TYPE_SOCK,   "SOCK"},
2012         {NDMP_FILE_TYPE_REGISTRY,       "REGISTRY"},
2013         {NDMP_FILE_TYPE_OTHER,  "OTHER"},
2014         {0, NULL}
2015 };
2016
2017 static int
2018 dissect_file_stats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
2019 {
2020         proto_item* item = NULL;
2021         proto_tree* tree = NULL;
2022         int old_offset=offset;
2023         nstime_t ns;
2024
2025         if (parent_tree) {
2026                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2027                                 "Stats:");
2028                 tree = proto_item_add_subtree(item, ett_ndmp_file_stats);
2029         }
2030
2031         /* invalids */
2032         offset = dissect_file_invalids(tvb, offset, pinfo, tree);
2033
2034         /* file fs type */
2035         proto_tree_add_item(tree, hf_ndmp_file_fs_type, tvb, offset, 4, FALSE);
2036         offset += 4;
2037
2038         /* file type */
2039         proto_tree_add_item(tree, hf_ndmp_file_type, tvb, offset, 4, FALSE);
2040         offset += 4;
2041
2042         /* mtime */
2043         ns.secs=tvb_get_ntohl(tvb, offset);
2044         ns.nsecs=0;
2045         proto_tree_add_time(tree, hf_ndmp_file_mtime, tvb, offset, 4, &ns);
2046         offset += 4;
2047
2048         /* atime */
2049         ns.secs=tvb_get_ntohl(tvb, offset);
2050         ns.nsecs=0;
2051         proto_tree_add_time(tree, hf_ndmp_file_atime, tvb, offset, 4, &ns);
2052         offset += 4;
2053
2054         /* ctime */
2055         ns.secs=tvb_get_ntohl(tvb, offset);
2056         ns.nsecs=0;
2057         proto_tree_add_time(tree, hf_ndmp_file_ctime, tvb, offset, 4, &ns);
2058         offset += 4;
2059
2060         /* owner */
2061         proto_tree_add_item(tree, hf_ndmp_file_owner, tvb, offset, 4, FALSE);
2062         offset += 4;
2063
2064         /* group */
2065         proto_tree_add_item(tree, hf_ndmp_file_group, tvb, offset, 4, FALSE);
2066         offset += 4;
2067
2068         /*XXX here we should do proper dissection of mode for unix or
2069               fattr for nt, call appropriate functions in nfs/smb*/
2070         /* fattr */
2071         proto_tree_add_item(tree, hf_ndmp_file_fattr, tvb, offset, 4, FALSE);
2072         offset += 4;
2073
2074         /*file size*/
2075         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_file_size,
2076                         offset);
2077
2078         /* links */
2079         proto_tree_add_item(tree, hf_ndmp_file_links, tvb, offset, 4, FALSE);
2080         offset += 4;
2081
2082         proto_item_set_len(item, offset-old_offset);    
2083         return offset;
2084 }
2085
2086
2087 static int
2088 dissect_file(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
2089 {
2090         proto_item* item = NULL;
2091         proto_tree* tree = NULL;
2092         int old_offset=offset;
2093
2094         if (parent_tree) {
2095                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2096                                 "File:");
2097                 tree = proto_item_add_subtree(item, ett_ndmp_file);
2098         }
2099
2100         /* file names */
2101         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2102                         dissect_file_name, hf_ndmp_file_names);
2103
2104         /* file stats */
2105         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2106                         dissect_file_stats, hf_ndmp_file_stats);
2107
2108         /* node */
2109         proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, FALSE);
2110         offset += 8;
2111
2112         /* fh_info */
2113         proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, FALSE);
2114         offset += 8;
2115
2116         proto_item_set_len(item, offset-old_offset);    
2117         return offset;
2118 }
2119
2120 static int
2121 dissect_fh_add_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2122     proto_tree *tree, guint32 seq)
2123 {
2124         /* files */
2125         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2126                         dissect_file, hf_ndmp_files);
2127
2128         return offset;
2129 }
2130
2131 static int
2132 dissect_dir(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2133 {
2134         /* file names */
2135         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2136                         dissect_file_name, hf_ndmp_file_names);
2137
2138         /* node */
2139         proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, FALSE);
2140         offset += 8;
2141
2142         /* parent */
2143         proto_tree_add_item(tree, hf_ndmp_file_parent, tvb, offset, 8, FALSE);
2144         offset += 8;
2145
2146         return offset;
2147 }
2148
2149 static int
2150 dissect_fh_add_dir_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2151     proto_tree *tree, guint32 seq)
2152 {
2153         /* dirs */
2154         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2155                         dissect_dir, hf_ndmp_dirs);
2156
2157         return offset;
2158 }
2159
2160 static int
2161 dissect_node(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2162 {
2163         /* file stats */
2164         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2165                         dissect_file_stats, hf_ndmp_file_stats);
2166
2167         /* node */
2168         proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, FALSE);
2169         offset += 8;
2170
2171         /* fh_info */
2172         proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, FALSE);
2173         offset += 8;
2174
2175         return offset;
2176 }
2177
2178
2179 static int
2180 dissect_fh_add_node_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2181     proto_tree *tree, guint32 seq)
2182 {
2183         /* node */
2184         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2185                         dissect_node, hf_ndmp_nodes);
2186
2187         return offset;
2188 }
2189
2190 static int
2191 dissect_data_start_backup_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2192     proto_tree *tree, guint32 seq)
2193 {
2194         /*butype name*/
2195         offset = dissect_rpc_string(tvb, pinfo, tree,
2196                         hf_ndmp_butype_name, offset, NULL);
2197
2198         /* default env */
2199         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2200                         dissect_default_env, hf_ndmp_butype_default_env);
2201
2202         return offset;
2203 }
2204
2205 static int
2206 dissect_nlist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2207 {
2208         /*original path*/
2209         offset = dissect_rpc_string(tvb, pinfo, tree,
2210                         hf_ndmp_bu_original_path, offset, NULL);
2211
2212         /*destination dir*/
2213         offset = dissect_rpc_string(tvb, pinfo, tree,
2214                         hf_ndmp_bu_destination_dir, offset, NULL);
2215
2216         /*new name*/
2217         offset = dissect_rpc_string(tvb, pinfo, tree,
2218                         hf_ndmp_bu_new_name, offset, NULL);
2219
2220         /*other name*/
2221         offset = dissect_rpc_string(tvb, pinfo, tree,
2222                         hf_ndmp_bu_other_name, offset, NULL);
2223
2224         /* node */
2225         proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, FALSE);
2226         offset += 8;
2227
2228         /* fh_info */
2229         proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, FALSE);
2230         offset += 8;
2231
2232         return offset;
2233 }
2234
2235
2236 static int
2237 dissect_data_start_recover_request(tvbuff_t *tvb, int offset,
2238     packet_info *pinfo, proto_tree *tree, guint32 seq)
2239 {
2240         /* default env */
2241         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2242                         dissect_default_env, hf_ndmp_butype_default_env);
2243
2244         /* nlist */
2245         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2246                         dissect_nlist, hf_ndmp_nlist);
2247
2248         /*butype name*/
2249         offset = dissect_rpc_string(tvb, pinfo, tree,
2250                         hf_ndmp_butype_name, offset, NULL);
2251
2252         return offset;
2253 }
2254
2255 static int
2256 dissect_data_get_env_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2257     proto_tree *tree, guint32 seq)
2258 {
2259         /* error */
2260         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
2261         offset += 4;
2262
2263         /* default env */
2264         offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2265                         dissect_default_env, hf_ndmp_butype_default_env);
2266
2267         return offset;
2268 }
2269
2270
2271 static const true_false_string tfs_ndmp_state_invalid_ebr = {
2272         "Estimated Bytes Remaining is INVALID",
2273         "Estimated Bytes Remaining is valid"
2274 };
2275 static const true_false_string tfs_ndmp_state_invalid_etr = {
2276         "Estimated Time Remaining is INVALID",
2277         "Estimated Time Remaining is valid"
2278 };
2279 static int
2280 dissect_state_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
2281 {
2282         proto_item* item = NULL;
2283         proto_tree* tree = NULL;
2284         guint32 flags;
2285
2286         flags=tvb_get_ntohl(tvb, offset);
2287         if (parent_tree) {
2288                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
2289                                 "Invalids: 0x%08x", flags);
2290                 tree = proto_item_add_subtree(item, ett_ndmp_state_invalids);
2291         }
2292
2293         proto_tree_add_boolean(tree, hf_ndmp_state_invalid_etr,
2294                                 tvb, offset, 4, flags);
2295         proto_tree_add_boolean(tree, hf_ndmp_state_invalid_ebr,
2296                                 tvb, offset, 4, flags);
2297
2298         offset+=4;
2299         return offset;
2300 }
2301
2302 #define NDMP_DATA_OP_NOACTION   0
2303 #define NDMP_DATA_OP_BACKUP     1
2304 #define NDMP_DATA_OP_RESTORE    2
2305 static const value_string bu_operation_vals[] = {
2306         {NDMP_DATA_OP_NOACTION, "NOACTION"},
2307         {NDMP_DATA_OP_BACKUP,   "BACKUP"},
2308         {NDMP_DATA_OP_RESTORE,  "RESTORE"},
2309         {0, NULL}
2310 };
2311
2312 #define NDMP_DATA_STATE_IDLE            0
2313 #define NDMP_DATA_STATE_ACTIVE          1
2314 #define NDMP_DATA_STATE_HALTED          2
2315 #define NDMP_DATA_STATE_LISTEN          3
2316 #define NDMP_DATA_STATE_CONNECTED       4
2317 static const value_string data_state_vals[] = {
2318         {NDMP_DATA_STATE_IDLE,          "IDLE"},
2319         {NDMP_DATA_STATE_ACTIVE,        "ACTIVE"},
2320         {NDMP_DATA_STATE_HALTED,        "HALTED"},
2321         {NDMP_DATA_STATE_LISTEN,        "LISTEN"},
2322         {NDMP_DATA_STATE_CONNECTED,     "CONNECTED"},
2323         {0, NULL}
2324 };
2325
2326 #define NDMP_DATA_HALTED_NA             0
2327 #define NDMP_DATA_HALTED_SUCCESSFUL     1
2328 #define NDMP_DATA_HALTED_ABORTED        2
2329 #define NDMP_DATA_HALTED_INTERNAL_ERROR 3
2330 #define NDMP_DATA_HALTED_CONNECT_ERROR  4
2331 static const value_string data_halted_vals[] = {
2332         {NDMP_DATA_HALTED_NA,                   "HALTED_NA"},
2333         {NDMP_DATA_HALTED_SUCCESSFUL,           "HALTED_SUCCESSFUL"},
2334         {NDMP_DATA_HALTED_ABORTED,              "HALTED_ABORTED"},
2335         {NDMP_DATA_HALTED_INTERNAL_ERROR,       "HALTED_INTERNAL_ERROR"},
2336         {NDMP_DATA_HALTED_CONNECT_ERROR,        "HALTED_CONNECT_ERROR"},
2337         {0, NULL}
2338 };
2339
2340 static int
2341 dissect_data_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2342     proto_tree *tree, guint32 seq)
2343 {
2344         nstime_t ns;
2345
2346         /* invalids */
2347         offset = dissect_state_invalids(tvb, offset, pinfo, tree);
2348
2349         /* error */
2350         proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, FALSE);
2351         offset += 4;
2352
2353         /* operation */
2354         proto_tree_add_item(tree, hf_ndmp_bu_operation, tvb, offset, 4, FALSE);
2355         offset += 4;
2356
2357         /* state */
2358         proto_tree_add_item(tree, hf_ndmp_data_state, tvb, offset, 4, FALSE);
2359         offset += 4;
2360
2361         /* halted reason */
2362         proto_tree_add_item(tree, hf_ndmp_data_halted, tvb, offset, 4, FALSE);
2363         offset += 4;
2364
2365         /*bytes processed*/
2366         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_data_bytes_processed,
2367                         offset);
2368
2369         /*est bytes remain*/
2370         offset = dissect_rpc_uint64(tvb, pinfo, tree, hf_ndmp_data_est_bytes_remain,
2371                         offset);
2372
2373         /* est time remain */
2374         ns.secs=tvb_get_ntohl(tvb, offset);
2375         ns.nsecs=0;
2376         proto_tree_add_time(tree, hf_ndmp_data_est_time_remain, tvb, offset, 4, &ns);
2377         offset += 4;
2378
2379         /* ndmp addr */
2380         offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2381
2382         /* window offset */
2383         proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, FALSE);
2384         offset += 8;
2385
2386         /* window length */
2387         proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, FALSE);
2388         offset += 8;
2389
2390         return offset;
2391 }
2392
2393
2394 typedef struct _ndmp_command {
2395         guint32 cmd;
2396         int (*request) (tvbuff_t *tvb, int offset, packet_info *pinfo,
2397             proto_tree *tree, guint32 seq);
2398         int (*response)(tvbuff_t *tvb, int offset, packet_info *pinfo,
2399             proto_tree *tree, guint32 seq);
2400 } ndmp_command;
2401
2402 static const ndmp_command ndmp_commands[] = {
2403         {NDMP_CONFIG_GET_HOST_INFO,    
2404                 NULL, dissect_ndmp_get_host_info_reply},
2405         {NDMP_CONFIG_GET_CONNECTION_TYPE, 
2406                 NULL, dissect_ndmp_config_get_connection_type_reply},
2407         {NDMP_CONFIG_GET_AUTH_ATTR, 
2408                 dissect_get_auth_type_request, dissect_auth_attr_msg},
2409         {NDMP_CONFIG_GET_BUTYPE_INFO,   
2410                 NULL, dissect_get_butype_info_reply},
2411         {NDMP_CONFIG_GET_FS_INFO,       
2412                 NULL, dissect_get_fs_info_reply},
2413         {NDMP_CONFIG_GET_TAPE_INFO,     
2414                 NULL, dissect_get_tape_info_reply},
2415         {NDMP_CONFIG_GET_SCSI_INFO,     
2416                 NULL, dissect_get_scsi_info_reply},
2417         {NDMP_CONFIG_GET_SERVER_INFO,   
2418                 NULL, dissect_get_server_info_reply},
2419         {NDMP_SCSI_OPEN,                
2420                 dissect_scsi_open_request, dissect_error},
2421         {NDMP_SCSI_CLOSE,               
2422                 NULL, dissect_error},
2423         {NDMP_SCSI_GET_STATE,           
2424                 NULL, dissect_scsi_get_state_reply},
2425         {NDMP_SCSI_SET_TARGET,          
2426                 dissect_scsi_set_state_request, dissect_error},
2427         {NDMP_SCSI_RESET_DEVICE,        
2428                 NULL, dissect_error},
2429         {NDMP_SCSI_RESET_BUS,           
2430                 NULL, dissect_error},
2431         {NDMP_SCSI_EXECUTE_CDB,
2432                 dissect_execute_cdb_request, dissect_execute_cdb_reply},
2433         {NDMP_TAPE_OPEN,                
2434                 dissect_tape_open_request, dissect_error},
2435         {NDMP_TAPE_CLOSE,               
2436                 NULL, dissect_error},
2437         {NDMP_TAPE_GET_STATE,           
2438                 NULL, dissect_tape_get_state_reply},
2439         {NDMP_TAPE_MTIO,                
2440                 dissect_tape_mtio_request, dissect_tape_mtio_reply},
2441         {NDMP_TAPE_WRITE,               
2442                 dissect_tape_write_request, dissect_tape_write_reply},
2443         {NDMP_TAPE_READ,        
2444                 dissect_tape_read_request, dissect_tape_read_reply},
2445         {NDMP_TAPE_EXECUTE_CDB,
2446                 dissect_execute_cdb_request, dissect_execute_cdb_reply},
2447         {NDMP_DATA_GET_STATE,           
2448                 NULL, dissect_data_get_state_reply},
2449         {NDMP_DATA_START_BACKUP,
2450                 dissect_data_start_backup_request, dissect_error },
2451         {NDMP_DATA_START_RECOVER,
2452                 dissect_data_start_recover_request, dissect_error },
2453         {NDMP_DATA_ABORT,
2454                 NULL, dissect_error},
2455         {NDMP_DATA_GET_ENV, 
2456                 NULL, dissect_data_get_env_reply},
2457         {NDMP_DATA_STOP, 
2458                 NULL, dissect_error},
2459         {NDMP_DATA_LISTEN, 
2460                 dissect_ndmp_addr_msg, dissect_mover_listen_reply},
2461         {NDMP_DATA_CONNECT,             
2462                 dissect_ndmp_addr_msg, dissect_error},
2463         {NDMP_NOTIFY_DATA_HALTED,       
2464                 dissect_notify_data_halted_request, NULL},
2465         {NDMP_NOTIFY_CONNECTED,         
2466                 dissect_notify_connected_request, NULL},
2467         {NDMP_NOTIFY_MOVER_HALTED, 
2468                 dissect_notify_data_halted_request, NULL},
2469         {NDMP_NOTIFY_MOVER_PAUSED, 
2470                 dissect_notify_mover_paused_request, NULL},
2471         {NDMP_NOTIFY_DATA_READ,         
2472                 dissect_mover_set_window_request, NULL},
2473         {NDMP_LOG_FILE,                 
2474                 dissect_log_file_request, NULL},
2475         {NDMP_LOG_MESSAGE,      
2476                 dissect_log_message_request, NULL},
2477         {NDMP_FH_ADD_FILE, 
2478                 dissect_fh_add_file_request, NULL},
2479         {NDMP_FH_ADD_DIR,               
2480                 dissect_fh_add_dir_request, NULL},
2481         {NDMP_FH_ADD_NODE, 
2482                 dissect_fh_add_node_request, NULL},
2483         {NDMP_CONNECT_OPEN,             
2484                 dissect_connect_open_request, dissect_error},
2485         {NDMP_CONNECT_CLIENT_AUTH, 
2486                 dissect_connect_client_auth_request, dissect_error},
2487         {NDMP_CONNECT_CLOSE,            
2488                 NULL,NULL},
2489         {NDMP_CONNECT_SERVER_AUTH, 
2490                 dissect_auth_attr_msg, dissect_connect_server_auth_reply},
2491         {NDMP_MOVER_GET_STATE,          
2492                 NULL, dissect_mover_get_state_reply},
2493         {NDMP_MOVER_LISTEN,             
2494                 dissect_mover_listen_request, dissect_mover_listen_reply},
2495         {NDMP_MOVER_CONTINUE,           
2496                 NULL, dissect_error},
2497         {NDMP_MOVER_ABORT,              
2498                 NULL, dissect_error},
2499         {NDMP_MOVER_STOP,               
2500                 NULL, dissect_error},
2501         {NDMP_MOVER_SET_WINDOW,         
2502                 dissect_mover_set_window_request, dissect_error},
2503         {NDMP_MOVER_READ, 
2504                 dissect_mover_set_window_request, dissect_error},
2505         {NDMP_MOVER_CLOSE,              
2506                 NULL, dissect_error},
2507         {NDMP_MOVER_SET_RECORD_SIZE, 
2508                 dissect_mover_set_record_size_request, dissect_error},
2509         {NDMP_MOVER_CONNECT,    
2510                 dissect_mover_connect_request, dissect_error},
2511         {0, NULL,NULL}
2512 };
2513
2514
2515 static int
2516 dissect_ndmp_header(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, struct ndmp_header *nh)
2517 {
2518         proto_item* item = NULL;
2519         proto_tree* tree = NULL;
2520         nstime_t ns;
2521
2522         if (parent_tree) {
2523                 item = proto_tree_add_item(parent_tree, hf_ndmp_header, tvb,
2524                                 offset, 24, FALSE);
2525                 tree = proto_item_add_subtree(item, ett_ndmp_header);
2526         }
2527
2528         /* sequence number */
2529         proto_tree_add_uint(tree, hf_ndmp_sequence, tvb, offset, 4, nh->seq);
2530         offset += 4;
2531
2532         /* timestamp */
2533         ns.secs=nh->time;
2534         ns.nsecs=0;
2535         proto_tree_add_time(tree, hf_ndmp_timestamp, tvb, offset, 4, &ns);
2536         offset += 4;
2537
2538         /* Message Type */
2539         proto_tree_add_uint(tree, hf_ndmp_msgtype, tvb, offset, 4, nh->type);
2540         offset += 4;
2541
2542         /* Message */
2543         proto_tree_add_uint(tree, hf_ndmp_msg, tvb, offset, 4, nh->msg);
2544         offset += 4;
2545
2546         /* Reply sequence number */
2547         proto_tree_add_uint(tree, hf_ndmp_reply_sequence, tvb, offset, 4, nh->rep_seq);
2548         offset += 4;
2549
2550         /* error */
2551         proto_tree_add_uint(tree, hf_ndmp_error, tvb, offset, 4, nh->err);
2552         offset += 4;
2553
2554         if (check_col(pinfo->cinfo, COL_INFO)){
2555                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s  ",
2556                         val_to_str(nh->msg, msg_vals, "Unknown Message (0x%02x)"),
2557                         val_to_str(nh->type, msg_type_vals, "Unknown Type (0x%02x)")
2558                         );
2559         }
2560
2561         return offset;
2562 }
2563
2564
2565 static int
2566 dissect_ndmp_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, struct ndmp_header *nh)
2567 {
2568         int i;
2569         proto_item *cmd_item=NULL;
2570         proto_tree *cmd_tree=NULL;
2571
2572         offset=dissect_ndmp_header(tvb, offset, pinfo, tree, nh);
2573
2574         for(i=0;ndmp_commands[i].cmd!=0;i++){
2575                 if(ndmp_commands[i].cmd==nh->msg){
2576                         break;
2577                 }
2578         }
2579
2580
2581         if(ndmp_commands[i].cmd==0){
2582                 /* we do not know this message */
2583                 proto_tree_add_text(tree, tvb, offset, -1, "Unknown type of NDMP message: 0x%02x", nh->msg);
2584                 offset+=tvb_length_remaining(tvb, offset);
2585                 return offset;
2586         }
2587
2588         if(tree){
2589                 cmd_item = proto_tree_add_text(tree, tvb, offset, -1, 
2590                         msg_vals[i].strptr);
2591                 cmd_tree = proto_item_add_subtree(cmd_item, ett_ndmp);
2592         }
2593
2594         if(nh->type==NDMP_MESSAGE_REQUEST){
2595                 if(ndmp_commands[i].request){
2596                         offset=ndmp_commands[i].request(tvb, offset, pinfo, cmd_tree,
2597                             nh->seq);
2598                 }
2599         } else {
2600                 if(ndmp_commands[i].response){
2601                         offset=ndmp_commands[i].response(tvb, offset, pinfo, cmd_tree,
2602                             nh->rep_seq);
2603                 }
2604         }
2605
2606         return offset;
2607 }
2608
2609 static gboolean
2610 dissect_ndmp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2611     tvbuff_t *frag_tvb, fragment_data *ipfd_head, gboolean is_tcp,
2612     guint32 rpc_rm)
2613 {
2614         int offset = (is_tcp && tvb == frag_tvb) ? 4 : 0;
2615         guint32 size;
2616         struct ndmp_header nh;
2617         proto_item *ndmp_item = NULL;
2618         proto_tree *ndmp_tree = NULL;
2619
2620         /* size of this NDMP PDU */
2621         size = tvb_length_remaining(tvb, offset);
2622         if (size < 24) {
2623                 /* too short to be NDMP */
2624                 return FALSE;
2625         }
2626
2627         /*
2628          * Check the NDMP header, if we have it.
2629          */
2630         nh.seq = tvb_get_ntohl(tvb, offset);
2631         nh.time = tvb_get_ntohl(tvb, offset+4);
2632         nh.type = tvb_get_ntohl(tvb, offset+8);
2633         nh.msg = tvb_get_ntohl(tvb, offset+12);
2634         nh.rep_seq = tvb_get_ntohl(tvb, offset+16);
2635         nh.err = tvb_get_ntohl(tvb, offset+20);
2636
2637         if (nh.type > 1)
2638                 return FALSE;
2639         if (nh.msg > 0xa09 || nh.msg == 0)
2640                 return FALSE;
2641         if (nh.err > 0x17)
2642                 return FALSE;
2643
2644         /*
2645          * Check if this is the last fragment.
2646          */
2647         if (!(rpc_rm & RPC_RM_LASTFRAG)) {
2648                 /*
2649                  * This isn't the last fragment.
2650                  * If we're doing reassembly, just return
2651                  * TRUE to indicate that this looks like
2652                  * the beginning of an NDMP message,
2653                  * and let them do reassembly.
2654                  */
2655                 if (ndmp_defragment)
2656                         return TRUE;
2657         }
2658
2659         if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
2660                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
2661         if (check_col(pinfo->cinfo, COL_INFO)) 
2662                 col_clear(pinfo->cinfo, COL_INFO);
2663
2664         if (tree) {
2665                 ndmp_item = proto_tree_add_item(tree, proto_ndmp,
2666                     tvb, 0, -1, FALSE);
2667                 ndmp_tree = proto_item_add_subtree(ndmp_item, ett_ndmp);
2668
2669                 if (is_tcp) {
2670                         show_rpc_fraginfo(tvb, frag_tvb, ndmp_tree, rpc_rm,
2671                             ipfd_head);
2672                 }
2673         }
2674
2675         /*
2676          * We cannot trust what dissect_ndmp_cmd() tells us, as there
2677          * are implementations which pad some additional data after
2678          * the PDU.  We MUST use size.
2679          */
2680         dissect_ndmp_cmd(tvb, offset, pinfo, ndmp_tree, &nh);
2681         return TRUE;
2682 }
2683
2684 static void
2685 dissect_ndmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2686 {
2687         int offset = 0;
2688         int len;
2689         proto_item *ndmp_item = NULL;
2690         proto_tree *ndmp_tree = NULL;
2691
2692         while (tvb_reported_length_remaining(tvb, offset) != 0) {
2693                 /*
2694                  * Process this fragment.
2695                  */
2696                 len = dissect_rpc_fragment(tvb, offset, pinfo, tree,
2697                     dissect_ndmp_message, FALSE, proto_ndmp, ett_ndmp,
2698                     ndmp_defragment);
2699                 if (len < 0) {
2700                         /*
2701                          * We need more data from the TCP stream for
2702                          * this fragment.
2703                          */
2704                         return;
2705                 }
2706                 if (len == 0) {
2707                         /*
2708                          * It's not NDMP.  Stop processing.
2709                          */
2710                         break;
2711                 }
2712
2713                 offset += len;
2714         }
2715 }
2716
2717 void
2718 proto_register_ndmp(void)
2719 {
2720
2721   static hf_register_info hf_ndmp[] = {
2722         { &hf_ndmp_header, {
2723                 "NDMP Header", "ndmp.header", FT_NONE, 0,
2724                 NULL, 0, "NDMP Header", HFILL }},
2725
2726         { &hf_ndmp_sequence, {
2727                 "Sequence", "ndmp.sequence", FT_UINT32, BASE_DEC,
2728                 NULL, 0, "Sequence number for NDMP PDU", HFILL }},
2729
2730         { &hf_ndmp_reply_sequence, {
2731                 "Reply Sequence", "ndmp.reply_sequence", FT_UINT32, BASE_DEC,
2732                 NULL, 0, "Reply Sequence number for NDMP PDU", HFILL }},
2733
2734         { &hf_ndmp_timestamp, {
2735                 "Time", "ndmp.timestamp", FT_ABSOLUTE_TIME, BASE_NONE,
2736                 NULL, 0, "Timestamp for this NDMP PDU", HFILL }},
2737
2738         { &hf_ndmp_msgtype, {
2739                 "Type", "ndmp.msg_type", FT_UINT32, BASE_DEC,
2740                 VALS(msg_type_vals), 0, "Is this a Request or Response?", HFILL }},
2741
2742         { &hf_ndmp_msg, {
2743                 "Message", "ndmp.msg", FT_UINT32, BASE_HEX,
2744                 VALS(msg_vals), 0, "Type of NDMP PDU", HFILL }},
2745
2746         { &hf_ndmp_error, {
2747                 "Error", "ndmp.error", FT_UINT32, BASE_DEC,
2748                 VALS(error_vals), 0, "Error code for this NDMP PDU", HFILL }},
2749
2750         { &hf_ndmp_version, {
2751                 "Version", "ndmp.version", FT_UINT32, BASE_DEC,
2752                 NULL, 0, "Version of NDMP protocol", HFILL }},
2753
2754         { &hf_ndmp_hostname, {
2755                 "Hostname", "ndmp.hostname", FT_STRING, BASE_NONE,
2756                 NULL, 0, "Hostname", HFILL }},
2757
2758         { &hf_ndmp_hostid, {
2759                 "HostID", "ndmp.hostid", FT_STRING, BASE_NONE,
2760                 NULL, 0, "HostID", HFILL }},
2761
2762         { &hf_ndmp_os_type, {
2763                 "OS Type", "ndmp.os.type", FT_STRING, BASE_NONE,
2764                 NULL, 0, "OS Type", HFILL }},
2765
2766         { &hf_ndmp_os_vers, {
2767                 "OS Version", "ndmp.os.version", FT_STRING, BASE_NONE,
2768                 NULL, 0, "OS Version", HFILL }},
2769
2770         { &hf_ndmp_addr_types, {
2771                 "Addr Types", "ndmp.addr_types", FT_NONE, BASE_NONE,
2772                 NULL, 0, "List Of Address Types", HFILL }},
2773
2774         { &hf_ndmp_addr_type, {
2775                 "Addr Type", "ndmp.addr_type", FT_UINT32, BASE_DEC,
2776                 VALS(addr_type_vals), 0, "Address Type", HFILL }},
2777
2778         { &hf_ndmp_auth_type, {
2779                 "Auth Type", "ndmp.auth_type", FT_UINT32, BASE_DEC,
2780                 VALS(auth_type_vals), 0, "Authentication Type", HFILL }},
2781
2782         { &hf_ndmp_auth_challenge, {
2783                 "Challenge", "ndmp.auth.challenge", FT_BYTES, BASE_HEX,
2784                 NULL, 0, "Authentication Challenge", HFILL }},
2785
2786         { &hf_ndmp_auth_digest, {
2787                 "Digest", "ndmp.auth.digest", FT_BYTES, BASE_HEX,
2788                 NULL, 0, "Authentication Digest", HFILL }},
2789
2790         { &hf_ndmp_butype_info, {
2791                 "Butype Info", "ndmp.butype.info", FT_NONE, BASE_NONE,
2792                 NULL, 0, "Butype Info", HFILL }},
2793
2794         { &hf_ndmp_butype_name, {
2795                 "Butype Name", "ndmp.butype.name", FT_STRING, BASE_NONE,
2796                 NULL, 0, "Name of Butype", HFILL }},
2797
2798         { &hf_ndmp_butype_default_env, {
2799                 "Default Env", "ndmp.butype.default_env", FT_NONE, BASE_NONE,
2800                 NULL, 0, "Default Env's for this Butype Info", HFILL }},
2801
2802         { &hf_ndmp_butype_attr_backup_file_history, {
2803                 "", "ndmp.butype.attr.backup_file_history", FT_BOOLEAN, 32,
2804                 TFS(&tfs_butype_attr_backup_file_history), 0x00000001, "backup_file_history", HFILL }},
2805
2806         { &hf_ndmp_butype_attr_backup_filelist, {
2807                 "", "ndmp.butype.attr.backup_filelist", FT_BOOLEAN, 32,
2808                 TFS(&tfs_butype_attr_backup_filelist), 0x00000002, "backup_filelist", HFILL }},
2809
2810         { &hf_ndmp_butype_attr_recover_filelist, {
2811                 "", "ndmp.butype.attr.recover_filelist", FT_BOOLEAN, 32,
2812                 TFS(&tfs_butype_attr_recover_filelist), 0x00000004, "recover_filelist", HFILL }},
2813
2814         { &hf_ndmp_butype_attr_backup_direct, {
2815                 "", "ndmp.butype.attr.backup_direct", FT_BOOLEAN, 32,
2816                 TFS(&tfs_butype_attr_backup_direct), 0x00000008, "backup_direct", HFILL }},
2817
2818         { &hf_ndmp_butype_attr_recover_direct, {
2819                 "", "ndmp.butype.attr.recover_direct", FT_BOOLEAN, 32,
2820                 TFS(&tfs_butype_attr_recover_direct), 0x00000010, "recover_direct", HFILL }},
2821
2822         { &hf_ndmp_butype_attr_backup_incremental, {
2823                 "", "ndmp.butype.attr.backup_incremental", FT_BOOLEAN, 32,
2824                 TFS(&tfs_butype_attr_backup_incremental), 0x00000020, "backup_incremental", HFILL }},
2825
2826         { &hf_ndmp_butype_attr_recover_incremental, {
2827                 "", "ndmp.butype.attr.recover_incremental", FT_BOOLEAN, 32,
2828                 TFS(&tfs_butype_attr_recover_incremental), 0x00000040, "recover_incremental", HFILL }},
2829
2830         { &hf_ndmp_butype_attr_backup_utf8, {
2831                 "", "ndmp.butype.attr.backup_utf8", FT_BOOLEAN, 32,
2832                 TFS(&tfs_butype_attr_backup_utf8), 0x00000080, "backup_utf8", HFILL }},
2833
2834         { &hf_ndmp_butype_attr_recover_utf8, {
2835                 "", "ndmp.butype.attr.recover_utf8", FT_BOOLEAN, 32,
2836                 TFS(&tfs_butype_attr_recover_utf8), 0x00000100, "recover_utf8", HFILL }},
2837
2838         { &hf_ndmp_butype_env_name, {
2839                 "Name", "ndmp.butype.env.name", FT_STRING, BASE_NONE,
2840                 NULL, 0, "Name for this env-variable", HFILL }},
2841
2842         { &hf_ndmp_butype_env_value, {
2843                 "Value", "ndmp.butype.env.value", FT_STRING, BASE_NONE,
2844                 NULL, 0, "Value for this env-variable", HFILL }},
2845
2846         { &hf_ndmp_fs_info, {
2847                 "FS Info", "ndmp.fs.info", FT_NONE, BASE_NONE,
2848                 NULL, 0, "FS Info", HFILL }},
2849
2850         { &hf_ndmp_fs_invalid_total_size, {
2851                 "", "ndmp.fs.invalid.total_size", FT_BOOLEAN, 32,
2852                 TFS(&tfs_fs_invalid_total_size), 0x00000001, "If total size is invalid", HFILL }},
2853
2854         { &hf_ndmp_fs_invalid_used_size, {
2855                 "", "ndmp.fs.invalid.used_size", FT_BOOLEAN, 32,
2856                 TFS(&tfs_fs_invalid_used_size), 0x00000002, "If used size is invalid", HFILL }},
2857
2858         { &hf_ndmp_fs_invalid_avail_size, {
2859                 "", "ndmp.fs.invalid.avail_size", FT_BOOLEAN, 32,
2860                 TFS(&tfs_fs_invalid_avail_size), 0x00000004, "If available size is invalid", HFILL }},
2861
2862         { &hf_ndmp_fs_invalid_total_inodes, {
2863                 "", "ndmp.fs.invalid.total_inodes", FT_BOOLEAN, 32,
2864                 TFS(&tfs_fs_invalid_total_inodes), 0x00000008, "If total number of inodes is invalid", HFILL }},
2865
2866         { &hf_ndmp_fs_invalid_used_inodes, {
2867                 "", "ndmp.fs.invalid.used_inodes", FT_BOOLEAN, 32,
2868                 TFS(&tfs_fs_invalid_used_inodes), 0x00000010, "If used number of inodes is invalid", HFILL }},
2869
2870         { &hf_ndmp_fs_fs_type, {
2871                 "Type", "ndmp.fs.type", FT_STRING, BASE_NONE,
2872                 NULL, 0, "Type of FS", HFILL }},
2873
2874         { &hf_ndmp_fs_logical_device, {
2875                 "Logical Device", "ndmp.fs.logical_device", FT_STRING, BASE_NONE,
2876                 NULL, 0, "Name of logical device", HFILL }},
2877
2878         { &hf_ndmp_fs_physical_device, {
2879                 "Physical Device", "ndmp.fs.physical_device", FT_STRING, BASE_NONE,
2880                 NULL, 0, "Name of physical device", HFILL }},
2881
2882         { &hf_ndmp_fs_total_size, {
2883                 "Total Size", "ndmp.fs.total_size", FT_UINT64, BASE_DEC,
2884                 NULL, 0, "Total size of FS", HFILL }},
2885
2886         { &hf_ndmp_fs_used_size, {
2887                 "Used Size", "ndmp.fs.used_size", FT_UINT64, BASE_DEC,
2888                 NULL, 0, "Total used size of FS", HFILL }},
2889
2890         { &hf_ndmp_fs_avail_size, {
2891                 "Avail Size", "ndmp.fs.avail_size", FT_UINT64, BASE_DEC,
2892                 NULL, 0, "Total available size on FS", HFILL }},
2893
2894         { &hf_ndmp_fs_total_inodes, {
2895                 "Total Inodes", "ndmp.fs.total_inodes", FT_UINT64, BASE_DEC,
2896                 NULL, 0, "Total number of inodes on FS", HFILL }},
2897
2898         { &hf_ndmp_fs_used_inodes, {
2899                 "Used Inodes", "ndmp.fs.used_inodes", FT_UINT64, BASE_DEC,
2900                 NULL, 0, "Number of used inodes on FS", HFILL }},
2901
2902         { &hf_ndmp_fs_env, {
2903                 "Env variables", "ndmp.fs.env", FT_NONE, BASE_NONE,
2904                 NULL, 0, "Environment variables for FS", HFILL }},
2905
2906         { &hf_ndmp_fs_env_name, {
2907                 "Name", "ndmp.fs.env.name", FT_STRING, BASE_NONE,
2908                 NULL, 0, "Name for this env-variable", HFILL }},
2909
2910         { &hf_ndmp_fs_env_value, {
2911                 "Value", "ndmp.fs.env.value", FT_STRING, BASE_NONE,
2912                 NULL, 0, "Value for this env-variable", HFILL }},
2913
2914         { &hf_ndmp_fs_status, {
2915                 "Status", "ndmp.fs.status", FT_STRING, BASE_NONE,
2916                 NULL, 0, "Status for this FS", HFILL }},
2917
2918         { &hf_ndmp_tape_info, {
2919                 "Tape Info", "ndmp.tape.info", FT_NONE, BASE_NONE,
2920                 NULL, 0, "Tape Info", HFILL }},
2921
2922         { &hf_ndmp_tape_model, {
2923                 "Model", "ndmp.tape.model", FT_STRING, BASE_NONE,
2924                 NULL, 0, "Model of the TAPE drive", HFILL }},
2925
2926         { &hf_ndmp_tape_dev_cap, {
2927                 "Device Capability", "ndmp.tape.dev_cap", FT_NONE, BASE_NONE,
2928                 NULL, 0, "Tape Device Capability", HFILL }},
2929
2930         { &hf_ndmp_tape_device, {
2931                 "Device", "ndmp.tape.device", FT_STRING, BASE_NONE,
2932                 NULL, 0, "Name of TAPE Device", HFILL }},
2933
2934         { &hf_ndmp_tape_attr_rewind, {
2935                 "", "ndmp.tape.attr.rewind", FT_BOOLEAN, 32,
2936                 TFS(&tfs_tape_attr_rewind), 0x00000001, "If this device supports rewind", HFILL }},
2937
2938         { &hf_ndmp_tape_attr_unload, {
2939                 "", "ndmp.tape.attr.unload", FT_BOOLEAN, 32,
2940                 TFS(&tfs_tape_attr_unload), 0x00000002, "If this device supports unload", HFILL }},
2941
2942         { &hf_ndmp_tape_capability, {
2943                 "Tape Capabilities", "ndmp.tape.capability", FT_NONE, BASE_NONE,
2944                 NULL, 0, "Tape Capabilities", HFILL }},
2945
2946         { &hf_ndmp_tape_capability_name, {
2947                 "Name", "ndmp.tape.cap.name", FT_STRING, BASE_NONE,
2948                 NULL, 0, "Name for this env-variable", HFILL }},
2949
2950         { &hf_ndmp_tape_capability_value, {
2951                 "Value", "ndmp.tape.cap.value", FT_STRING, BASE_NONE,
2952                 NULL, 0, "Value for this env-variable", HFILL }},
2953
2954         { &hf_ndmp_scsi_info, {
2955                 "SCSI Info", "ndmp.scsi.info", FT_NONE, BASE_NONE,
2956                 NULL, 0, "SCSI Info", HFILL }},
2957
2958         { &hf_ndmp_scsi_model, {
2959                 "Model", "ndmp.scsi.model", FT_STRING, BASE_NONE,
2960                 NULL, 0, "Model of the SCSI device", HFILL }},
2961
2962         { &hf_ndmp_server_vendor, {
2963                 "Vendor", "ndmp.server.vendor", FT_STRING, BASE_NONE,
2964                 NULL, 0, "Name of vendor", HFILL }},
2965
2966         { &hf_ndmp_server_product, {
2967                 "Product", "ndmp.server.product", FT_STRING, BASE_NONE,
2968                 NULL, 0, "Name of product", HFILL }},
2969
2970         { &hf_ndmp_server_revision, {
2971                 "Revision", "ndmp.server.revision", FT_STRING, BASE_NONE,
2972                 NULL, 0, "Revision of this product", HFILL }},
2973
2974         { &hf_ndmp_auth_types, {
2975                 "Auth types", "ndmp.auth.types", FT_NONE, BASE_NONE,
2976                 NULL, 0, "Auth types", HFILL }},
2977
2978         { &hf_ndmp_scsi_device, {
2979                 "Device", "ndmp.scsi.device", FT_STRING, BASE_NONE,
2980                 NULL, 0, "Name of SCSI Device", HFILL }},
2981
2982         { &hf_ndmp_scsi_controller, {
2983                 "Controller", "ndmp.scsi.controller", FT_UINT32, BASE_DEC,
2984                 NULL, 0, "Target Controller", HFILL }},
2985
2986         { &hf_ndmp_scsi_id, {
2987                 "ID", "ndmp.scsi.id", FT_UINT32, BASE_DEC,
2988                 NULL, 0, "Target ID", HFILL }},
2989
2990         { &hf_ndmp_scsi_lun, {
2991                 "LUN", "ndmp.scsi.lun", FT_UINT32, BASE_DEC,
2992                 NULL, 0, "Target LUN", HFILL }},
2993
2994         { &hf_ndmp_execute_cdb_flags_data_in, {
2995                 "DATA_IN", "ndmp.execute_cdb.flags.data_in", FT_BOOLEAN, 32,
2996                 NULL, 0x00000001, "DATA_IN", HFILL }},
2997
2998         { &hf_ndmp_execute_cdb_flags_data_out, {
2999                 "DATA_OUT", "ndmp.execute_cdb.flags.data_out", FT_BOOLEAN, 32,
3000                 NULL, 0x00000002, "DATA_OUT", HFILL }},
3001
3002         { &hf_ndmp_execute_cdb_timeout, {
3003                 "Timeout", "ndmp.execute_cdb.timeout", FT_UINT32, BASE_DEC,
3004                 NULL, 0, "Reselect timeout, in milliseconds", HFILL }},
3005
3006         { &hf_ndmp_execute_cdb_datain_len, {
3007                 "Data in length", "ndmp.execute_cdb.datain_len", FT_UINT32, BASE_DEC,
3008                 NULL, 0, "Expected length of data bytes to read", HFILL }},
3009
3010         { &hf_ndmp_execute_cdb_cdb_len, {
3011                 "CDB length", "ndmp.execute_cdb.cdb_len", FT_UINT32, BASE_DEC,
3012                 NULL, 0, "Length of CDB", HFILL }},
3013
3014         { &hf_ndmp_execute_cdb_dataout, {
3015                 "Data out", "ndmp.execute_cdb.dataout", FT_BYTES, BASE_NONE,
3016                 NULL, 0, "Data to be transferred to the SCSI device", HFILL }},
3017
3018         { &hf_ndmp_execute_cdb_status, {
3019                 "Status", "ndmp.execute_cdb.status", FT_UINT8, BASE_DEC,
3020                 VALS(scsi_status_val), 0, "SCSI status", HFILL }},
3021
3022         { &hf_ndmp_execute_cdb_dataout_len, {
3023                 "Data out length", "ndmp.execute_cdb.dataout_len", FT_UINT32, BASE_DEC,
3024                 NULL, 0, "Number of bytes transferred to the device", HFILL }},
3025
3026         { &hf_ndmp_execute_cdb_datain, {
3027                 "Data in", "ndmp.execute_cdb.datain", FT_BYTES, BASE_NONE,
3028                 NULL, 0, "Data transferred from the SCSI device", HFILL }},
3029
3030         { &hf_ndmp_execute_cdb_sns_len, {
3031                 "Sense data length", "ndmp.execute_cdb.sns_len", FT_UINT32, BASE_DEC,
3032                 NULL, 0, "Length of sense data", HFILL }},
3033
3034         { &hf_ndmp_tape_open_mode, {
3035                 "Mode", "ndmp.tape.open_mode", FT_UINT32, BASE_DEC,
3036                 VALS(tape_open_mode_vals), 0, "Mode to open tape in", HFILL }},
3037
3038         { &hf_ndmp_tape_invalid_file_num, {
3039                 "", "ndmp.tape.invalid.file_num", FT_BOOLEAN, 32,
3040                 TFS(&tfs_ndmp_tape_invalid_file_num), 0x00000001, "invalid_file_num", HFILL }},
3041
3042         { &hf_ndmp_tape_invalid_soft_errors, {
3043                 "", "ndmp.tape.invalid.soft_errors", FT_BOOLEAN, 32,
3044                 TFS(&tfs_ndmp_tape_invalid_soft_errors), 0x00000002, "soft_errors", HFILL }},
3045
3046         { &hf_ndmp_tape_invalid_block_size, {
3047                 "", "ndmp.tape.invalid.block_size", FT_BOOLEAN, 32,
3048                 TFS(&tfs_ndmp_tape_invalid_block_size), 0x00000004, "block_size", HFILL }},
3049
3050         { &hf_ndmp_tape_invalid_block_no, {
3051                 "", "ndmp.tape.invalid.block_no", FT_BOOLEAN, 32,
3052                 TFS(&tfs_ndmp_tape_invalid_block_no), 0x00000008, "block_no", HFILL }},
3053
3054         { &hf_ndmp_tape_invalid_total_space, {
3055                 "", "ndmp.tape.invalid.total_space", FT_BOOLEAN, 32,
3056                 TFS(&tfs_ndmp_tape_invalid_total_space), 0x00000010, "total_space", HFILL }},
3057
3058         { &hf_ndmp_tape_invalid_space_remain, {
3059                 "", "ndmp.tape.invalid.space_remain", FT_BOOLEAN, 32,
3060                 TFS(&tfs_ndmp_tape_invalid_space_remain), 0x00000020, "space_remain", HFILL }},
3061
3062         { &hf_ndmp_tape_invalid_partition, {
3063                 "", "ndmp.tape.invalid.partition", FT_BOOLEAN, 32,
3064                 TFS(&tfs_ndmp_tape_invalid_partition), 0x00000040, "partition", HFILL }},
3065
3066         { &hf_ndmp_tape_flags_no_rewind, {
3067                 "", "ndmp.tape.flags.no_rewind", FT_BOOLEAN, 32,
3068                 TFS(&tfs_ndmp_tape_flags_no_rewind), 0x00000008, "no_rewind", HFILL, }},
3069
3070         { &hf_ndmp_tape_flags_write_protect, {
3071                 "", "ndmp.tape.flags.write_protect", FT_BOOLEAN, 32,
3072                 TFS(&tfs_ndmp_tape_flags_write_protect), 0x00000010, "write_protect", HFILL, }},
3073
3074         { &hf_ndmp_tape_flags_error, {
3075                 "", "ndmp.tape.flags.error", FT_BOOLEAN, 32,
3076                 TFS(&tfs_ndmp_tape_flags_error), 0x00000020, "error", HFILL, }},
3077
3078         { &hf_ndmp_tape_flags_unload, {
3079                 "", "ndmp.tape.flags.unload", FT_BOOLEAN, 32,
3080                 TFS(&tfs_ndmp_tape_flags_unload), 0x00000040, "unload", HFILL, }},
3081
3082         { &hf_ndmp_tape_file_num, {
3083                 "file_num", "ndmp.tape.status.file_num", FT_UINT32, BASE_DEC,
3084                 NULL, 0, "file_num", HFILL }},
3085
3086         { &hf_ndmp_tape_soft_errors, {
3087                 "soft_errors", "ndmp.tape.status.soft_errors", FT_UINT32, BASE_DEC,
3088                 NULL, 0, "soft_errors", HFILL }},
3089
3090         { &hf_ndmp_tape_block_size, {
3091                 "block_size", "ndmp.tape.status.block_size", FT_UINT32, BASE_DEC,
3092                 NULL, 0, "block_size", HFILL }},
3093
3094         { &hf_ndmp_tape_block_no, {
3095                 "block_no", "ndmp.tape.status.block_no", FT_UINT32, BASE_DEC,
3096                 NULL, 0, "block_no", HFILL }},
3097
3098         { &hf_ndmp_tape_total_space, {
3099                 "total_space", "ndmp.tape.status.total_space", FT_UINT64, BASE_DEC,
3100                 NULL, 0, "total_space", HFILL }},
3101
3102         { &hf_ndmp_tape_space_remain, {
3103                 "space_remain", "ndmp.tape.status.space_remain", FT_UINT64, BASE_DEC,
3104                 NULL, 0, "space_remain", HFILL }},
3105
3106         { &hf_ndmp_tape_partition, {
3107                 "partition", "ndmp.tape.status.partition", FT_UINT32, BASE_DEC,
3108                 NULL, 0, "partition", HFILL }},
3109
3110         { &hf_ndmp_tape_mtio_op, {
3111                 "Operation", "ndmp.tape.mtio.op", FT_UINT32, BASE_DEC,
3112                 VALS(tape_mtio_vals), 0, "MTIO Operation", HFILL }},
3113
3114         { &hf_ndmp_count, {
3115                 "Count", "ndmp.count", FT_UINT32, BASE_DEC,
3116                 NULL, 0, "Number of bytes/objects/operations", HFILL }},
3117
3118         { &hf_ndmp_resid_count, {
3119                 "Resid Count", "ndmp.resid_count", FT_UINT32, BASE_DEC,
3120                 NULL, 0, "Number of remaining bytes/objects/operations", HFILL }},
3121
3122         { &hf_ndmp_mover_state, {
3123                 "State", "ndmp.mover.state", FT_UINT32, BASE_DEC,
3124                 VALS(mover_state_vals), 0, "State of the selected mover", HFILL }},
3125
3126         { &hf_ndmp_mover_pause, {
3127                 "Pause", "ndmp.mover.pause", FT_UINT32, BASE_DEC,
3128                 VALS(mover_pause_vals), 0, "Reason why the mover paused", HFILL }},
3129
3130         { &hf_ndmp_halt, {
3131                 "Halt", "ndmp.halt", FT_UINT32, BASE_DEC,
3132                 VALS(halt_vals), 0, "Reason why it halted", HFILL }},
3133
3134         { &hf_ndmp_record_size, {
3135                 "Record Size", "ndmp.record.size", FT_UINT32, BASE_DEC,
3136                 NULL, 0, "Record size in bytes", HFILL }},
3137
3138         { &hf_ndmp_record_num, {
3139                 "Record Num", "ndmp.record.num", FT_UINT32, BASE_DEC,
3140                 NULL, 0, "Number of records", HFILL }},
3141
3142         { &hf_ndmp_data_written, {
3143                 "Data Written", "ndmp.data.written", FT_UINT64, BASE_DEC,
3144                 NULL, 0, "Number of data bytes written", HFILL }},
3145
3146         { &hf_ndmp_seek_position, {
3147                 "Seek Position", "ndmp.seek.position", FT_UINT64, BASE_DEC,
3148                 NULL, 0, "Current seek position on device", HFILL }},
3149
3150         { &hf_ndmp_bytes_left_to_read, {
3151                 "Bytes left to read", "ndmp.bytes_left_to_read", FT_UINT64, BASE_DEC,
3152                 NULL, 0, "Number of bytes left to be read from the device", HFILL }},
3153
3154         { &hf_ndmp_window_offset, {
3155                 "Window Offset", "ndmp.window.offset", FT_UINT64, BASE_DEC,
3156                 NULL, 0, "Offset to window in bytes", HFILL }},
3157
3158         { &hf_ndmp_window_length, {
3159                 "Window Length", "ndmp.window.length", FT_UINT64, BASE_DEC,
3160                 NULL, 0, "Size of window in bytes", HFILL }},
3161
3162         { &hf_ndmp_addr_ip, {
3163                 "IP Address", "ndmp.addr.ip", FT_IPv4, BASE_DEC,
3164                 NULL, 0, "IP Address", HFILL }},
3165
3166         { &hf_ndmp_addr_tcp, {
3167                 "TCP Port", "ndmp.addr.tcp_port", FT_UINT32, BASE_DEC,
3168                 NULL, 0, "TCP Port", HFILL }},
3169
3170         { &hf_ndmp_addr_fcal_loop_id, {
3171                 "Loop ID", "ndmp.addr.loop_id", FT_UINT32, BASE_HEX,
3172                 NULL, 0, "FCAL Loop ID", HFILL }},
3173
3174         { &hf_ndmp_addr_ipc, {
3175                 "IPC", "ndmp.addr.ipc", FT_BYTES, BASE_HEX,
3176                 NULL, 0, "IPC identifier", HFILL }},
3177
3178         { &hf_ndmp_mover_mode, {
3179                 "Mode", "ndmp.mover.mode", FT_UINT32, BASE_HEX,
3180                 VALS(mover_mode_vals), 0, "Mover Mode", HFILL }},
3181
3182         { &hf_ndmp_file_name, {
3183                 "File", "ndmp.file", FT_STRING, BASE_NONE,
3184                 NULL, 0, "Name of File", HFILL }},
3185
3186         { &hf_ndmp_nt_file_name, {
3187                 "NT File", "ndmp.file", FT_STRING, BASE_NONE,
3188                 NULL, 0, "NT Name of File", HFILL }},
3189
3190         { &hf_ndmp_dos_file_name, {
3191                 "DOS File", "ndmp.file", FT_STRING, BASE_NONE,
3192                 NULL, 0, "DOS Name of File", HFILL }},
3193
3194         { &hf_ndmp_log_type, {
3195                 "Type", "ndmp.log.type", FT_UINT32, BASE_HEX,
3196                 VALS(log_type_vals), 0, "Type of log entry", HFILL }},
3197
3198         { &hf_ndmp_log_message_id, {
3199                 "Message ID", "ndmp.log.message.id", FT_UINT32, BASE_DEC,
3200                 NULL, 0, "ID of this log entry", HFILL }},
3201
3202         { &hf_ndmp_log_message, {
3203                 "Message", "ndmp.log.message", FT_STRING, BASE_NONE,
3204                 NULL, 0, "Log entry", HFILL }},
3205
3206         { &hf_ndmp_halt_reason, {
3207                 "Reason", "ndmp.halt.reason", FT_STRING, BASE_NONE,
3208                 NULL, 0, "Textual reason for why it halted", HFILL }},
3209
3210         { &hf_ndmp_connected, {
3211                 "Connected", "ndmp.connected", FT_UINT32, BASE_DEC,
3212                 VALS(connected_vals), 0, "Status of connection", HFILL }},
3213
3214         { &hf_ndmp_connected_reason, {
3215                 "Reason", "ndmp.connected.reason", FT_STRING, BASE_NONE,
3216                 NULL, 0, "Textual description of the connection status", HFILL }},
3217
3218         { &hf_ndmp_auth_id, {
3219                 "ID", "ndmp.auth.id", FT_STRING, BASE_NONE,
3220                 NULL, 0, "ID of client authenticating", HFILL }},
3221
3222         { &hf_ndmp_auth_password, {
3223                 "Password", "ndmp.auth.password", FT_STRING, BASE_NONE,
3224                 NULL, 0, "Password of client authenticating", HFILL }},
3225
3226         { &hf_ndmp_data, {
3227                 "Data", "ndmp.data", FT_BYTES, BASE_HEX,
3228                 NULL, 0, "Data written/read", HFILL }},
3229
3230         { &hf_ndmp_files, {
3231                 "Files", "ndmp.files", FT_NONE, 0,
3232                 NULL, 0, "List of files", HFILL }},
3233
3234         { &hf_ndmp_file_names, {
3235                 "File Names", "ndmp.file.names", FT_NONE, 0,
3236                 NULL, 0, "List of file names", HFILL }},
3237
3238         { &hf_ndmp_file_fs_type, {
3239                 "File FS Type", "ndmp.file.fs_type", FT_UINT32, BASE_DEC,
3240                 VALS(file_fs_type_vals), 0, "Type of file permissions (UNIX or NT)", HFILL }},
3241
3242         { &hf_ndmp_file_type, {
3243                 "File Type", "ndmp.file.type", FT_UINT32, BASE_DEC,
3244                 VALS(file_type_vals), 0, "Type of file", HFILL }},
3245
3246         { &hf_ndmp_file_stats, {
3247                 "File Stats", "ndmp.file.stats", FT_NONE, 0,
3248                 NULL, 0, "List of file stats", HFILL }},
3249
3250         { &hf_ndmp_file_node, {
3251                 "Node", "ndmp.file.node", FT_UINT64, BASE_DEC,
3252                 NULL, 0, "Node used for direct access", HFILL }},
3253
3254         { &hf_ndmp_file_parent, {
3255                 "Parent", "ndmp.file.parent", FT_UINT64, BASE_DEC,
3256                 NULL, 0, "Parent node(directory) for this node", HFILL }},
3257
3258         { &hf_ndmp_file_fh_info, {
3259                 "FH Info", "ndmp.file.fh_info", FT_UINT64, BASE_DEC,
3260                 NULL, 0, "FH Info used for direct access", HFILL }},
3261
3262         { &hf_ndmp_file_invalid_atime, {
3263                 "", "ndmp.file.invalid_atime", FT_BOOLEAN, 32,
3264                 TFS(&tfs_ndmp_file_invalid_atime), 0x00000001, "invalid_atime", HFILL, }},
3265
3266         { &hf_ndmp_file_invalid_ctime, {
3267                 "", "ndmp.file.invalid_ctime", FT_BOOLEAN, 32,
3268                 TFS(&tfs_ndmp_file_invalid_ctime), 0x00000002, "invalid_ctime", HFILL, }},
3269
3270         { &hf_ndmp_file_invalid_group, {
3271                 "", "ndmp.file.invalid_group", FT_BOOLEAN, 32,
3272                 TFS(&tfs_ndmp_file_invalid_group), 0x00000004, "invalid_group", HFILL, }},
3273
3274         { &hf_ndmp_file_mtime, {
3275                 "mtime", "ndmp.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
3276                 NULL, 0, "Timestamp for mtime for this file", HFILL }},
3277
3278         { &hf_ndmp_file_atime, {
3279                 "atime", "ndmp.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
3280                 NULL, 0, "Timestamp for atime for this file", HFILL }},
3281
3282         { &hf_ndmp_file_ctime, {
3283                 "ctime", "ndmp.file.ctime", FT_ABSOLUTE_TIME, BASE_NONE,
3284                 NULL, 0, "Timestamp for ctime for this file", HFILL }},
3285
3286         { &hf_ndmp_file_owner, {
3287                 "Owner", "ndmp.file.owner", FT_UINT32, BASE_DEC,
3288                 NULL, 0, "UID for UNIX, owner for NT", HFILL }},
3289
3290         { &hf_ndmp_file_group, {
3291                 "Group", "ndmp.file.group", FT_UINT32, BASE_DEC,
3292                 NULL, 0, "GID for UNIX, NA for NT", HFILL }},
3293
3294         { &hf_ndmp_file_fattr, {
3295                 "Fattr", "ndmp.file.fattr", FT_UINT32, BASE_HEX,
3296                 NULL, 0, "Mode for UNIX, fattr for NT", HFILL }},
3297
3298         { &hf_ndmp_file_size, {
3299                 "Size", "ndmp.file.size", FT_UINT64, BASE_DEC,
3300                 NULL, 0, "File Size", HFILL }},
3301
3302         { &hf_ndmp_file_links, {
3303                 "Links", "ndmp.file.links", FT_UINT32, BASE_DEC,
3304                 NULL, 0, "Number of links to this file", HFILL }},
3305
3306         { &hf_ndmp_dirs, {
3307                 "Dirs", "ndmp.dirs", FT_NONE, 0,
3308                 NULL, 0, "List of directories", HFILL }},
3309
3310         { &hf_ndmp_nodes, {
3311                 "Nodes", "ndmp.nodes", FT_NONE, 0,
3312                 NULL, 0, "List of nodes", HFILL }},
3313
3314         { &hf_ndmp_nlist, {
3315                 "Nlist", "ndmp.nlist", FT_NONE, 0,
3316                 NULL, 0, "List of names", HFILL }},
3317
3318         { &hf_ndmp_bu_original_path, {
3319                 "Original Path", "ndmp.bu.original_path", FT_STRING, BASE_NONE,
3320                 NULL, 0, "Original path where backup was created", HFILL }},
3321
3322         { &hf_ndmp_bu_destination_dir, {
3323                 "Destination Dir", "ndmp.bu.destination_dir", FT_STRING, BASE_NONE,
3324                 NULL, 0, "Destination directory to restore backup to", HFILL }},
3325
3326         { &hf_ndmp_bu_new_name, {
3327                 "New Name", "ndmp.bu.new_name", FT_STRING, BASE_NONE,
3328                 NULL, 0, "New Name", HFILL }},
3329
3330         { &hf_ndmp_bu_other_name, {
3331                 "Other Name", "ndmp.bu.other_name", FT_STRING, BASE_NONE,
3332                 NULL, 0, "Other Name", HFILL }},
3333
3334         { &hf_ndmp_state_invalid_ebr, {
3335                 "", "ndmp.bu.state.invalid_ebr", FT_BOOLEAN, 32,
3336                 TFS(&tfs_ndmp_state_invalid_ebr), 0x00000001, "Whether EstimatedBytesLeft is valid or not", HFILL, }},
3337
3338         { &hf_ndmp_state_invalid_etr, {
3339                 "", "ndmp.bu.state.invalid_etr", FT_BOOLEAN, 32,
3340                 TFS(&tfs_ndmp_state_invalid_etr), 0x00000002, "Whether EstimatedTimeLeft is valid or not", HFILL, }},
3341
3342         { &hf_ndmp_bu_operation, {
3343                 "Operation", "ndmp.bu.operation", FT_UINT32, BASE_DEC,
3344                 VALS(bu_operation_vals), 0, "BU Operation", HFILL, }},
3345
3346         { &hf_ndmp_data_state, {
3347                 "State", "ndmp.data.state", FT_UINT32, BASE_DEC,
3348                 VALS(data_state_vals), 0, "Data state", HFILL, }},
3349
3350         { &hf_ndmp_data_halted, {
3351                 "Halted Reason", "ndmp.data.halted", FT_UINT32, BASE_DEC,
3352                 VALS(data_halted_vals), 0, "Data halted reason", HFILL, }},
3353
3354         { &hf_ndmp_data_bytes_processed, {
3355                 "Bytes Processed", "ndmp.data.bytes_processed", FT_UINT64, BASE_DEC,
3356                 NULL, 0, "Number of bytes processed", HFILL }},
3357
3358         { &hf_ndmp_data_est_bytes_remain, {
3359                 "Est Bytes Remain", "ndmp.data.est_bytes_remain", FT_UINT64, BASE_DEC,
3360                 NULL, 0, "Estimated number of bytes remaining", HFILL }},
3361
3362         { &hf_ndmp_data_est_time_remain, {
3363                 "Est Time Remain", "ndmp.data.est_time_remain", FT_RELATIVE_TIME, BASE_DEC,
3364                 NULL, 0, "Estimated time remaining", HFILL }},
3365   };
3366
3367   static gint *ett[] = {
3368     &ett_ndmp,
3369     &ett_ndmp_header,
3370     &ett_ndmp_butype_attrs,
3371     &ett_ndmp_fs_invalid,
3372     &ett_ndmp_tape_attr,
3373     &ett_ndmp_execute_cdb_flags,
3374     &ett_ndmp_execute_cdb_cdb,
3375     &ett_ndmp_execute_cdb_sns,
3376     &ett_ndmp_execute_cdb_payload,
3377     &ett_ndmp_tape_invalid,
3378     &ett_ndmp_tape_flags,
3379     &ett_ndmp_addr,
3380     &ett_ndmp_file,
3381     &ett_ndmp_file_name,
3382     &ett_ndmp_file_stats,
3383     &ett_ndmp_file_invalids,
3384     &ett_ndmp_state_invalids,
3385   };
3386
3387   module_t *ndmp_module;
3388
3389   proto_ndmp = proto_register_protocol("Network Data Management Protocol", "NDMP", "ndmp");
3390   proto_register_field_array(proto_ndmp, hf_ndmp, array_length(hf_ndmp));
3391   
3392   proto_register_subtree_array(ett, array_length(ett));
3393
3394   /* desegmentation */
3395   ndmp_module = prefs_register_protocol(proto_ndmp, NULL);
3396   prefs_register_bool_preference(ndmp_module, "desegment",
3397         "Desegment all NDMP messages spanning multiple TCP segments",
3398         "Whether the dissector should desegment NDMP messages",
3399         &ndmp_desegment);
3400   prefs_register_bool_preference(ndmp_module, "defragment",
3401         "Defragment all multi-fragment NDMP messages",
3402         "Whether the dissector should defragment multi-fragment NDMP messages",
3403         &ndmp_defragment);
3404 }
3405
3406 void
3407 proto_reg_handoff_ndmp(void)
3408 {
3409   dissector_handle_t ndmp_handle;
3410
3411   ndmp_handle = create_dissector_handle(dissect_ndmp, proto_ndmp);
3412   dissector_add("tcp.port",TCP_PORT_NDMP, ndmp_handle);
3413 }