Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ndmp.c
blob149151c99151f787aaf9f710ccca5194678ce54e
1 /* TODO: fixup LUN tracking so we can pass the proper LUN across to
2 dissect_scsi_xxx()
3 */
4 /* packet-ndmp.c
5 * Routines for NDMP dissection
6 * 2001 Ronnie Sahlberg (see AUTHORS for email)
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 /* see www.ndmp.org for protocol specifications.
16 this file implements version 3 of ndmp
19 #include "config.h"
21 #include <epan/packet.h>
22 #include <epan/expert.h>
23 #include <wsutil/str_util.h>
24 #include "packet-rpc.h"
25 #include "packet-ndmp.h"
26 #include "packet-tcp.h"
27 #include "packet-scsi.h"
28 #include <epan/prefs.h>
29 #include <epan/reassemble.h>
30 #include <epan/tfs.h>
31 #include <wsutil/array.h>
33 void proto_register_ndmp(void);
34 void proto_reg_handoff_ndmp(void);
36 #define TCP_PORT_NDMP 10000
38 static dissector_handle_t ndmp_handle;
40 static int proto_ndmp;
41 static int hf_ndmp_request_frame;
42 static int hf_ndmp_response_frame;
43 static int hf_ndmp_time;
44 static int hf_ndmp_lastfrag;
45 static int hf_ndmp_fraglen;
46 static int hf_ndmp_version;
47 static int hf_ndmp_header;
48 static int hf_ndmp_sequence;
49 static int hf_ndmp_reply_sequence;
50 static int hf_ndmp_timestamp;
51 static int hf_ndmp_msgtype;
52 static int hf_ndmp_msg;
53 static int hf_ndmp_error;
54 static int hf_ndmp_hostname;
55 static int hf_ndmp_os_type;
56 static int hf_ndmp_os_vers;
57 static int hf_ndmp_hostid;
58 static int hf_ndmp_addr_types;
59 static int hf_ndmp_addr_type;
60 static int hf_ndmp_auth_type;
61 static int hf_ndmp_auth_types;
62 static int hf_ndmp_auth_challenge;
63 static int hf_ndmp_auth_digest;
64 static int hf_ndmp_auth_id;
65 static int hf_ndmp_auth_password;
66 static int hf_ndmp_butype_info;
67 static int hf_ndmp_butype_name;
68 static int hf_ndmp_butype_default_env;
69 static int hf_ndmp_butype_attr;
70 static int hf_ndmp_butype_attr_backup_file_history;
71 static int hf_ndmp_butype_attr_backup_filelist;
72 static int hf_ndmp_butype_attr_recover_filelist;
73 static int hf_ndmp_butype_attr_backup_direct;
74 static int hf_ndmp_butype_attr_recover_direct;
75 static int hf_ndmp_butype_attr_backup_incremental;
76 static int hf_ndmp_butype_attr_recover_incremental;
77 static int hf_ndmp_butype_attr_backup_utf8;
78 static int hf_ndmp_butype_attr_recover_utf8;
79 static int hf_ndmp_butype_env_name;
80 static int hf_ndmp_butype_env_value;
81 static int hf_ndmp_tcp_env_name;
82 static int hf_ndmp_tcp_env_value;
83 static int hf_ndmp_tcp_default_env;
84 static int hf_ndmp_tcp_addr_list;
85 static int hf_ndmp_fs_info;
86 static int hf_ndmp_fs_invalid;
87 static int hf_ndmp_fs_invalid_total_size;
88 static int hf_ndmp_fs_invalid_used_size;
89 static int hf_ndmp_fs_invalid_avail_size;
90 static int hf_ndmp_fs_invalid_total_inodes;
91 static int hf_ndmp_fs_invalid_used_inodes;
92 static int hf_ndmp_fs_fs_type;
93 static int hf_ndmp_fs_logical_device;
94 static int hf_ndmp_fs_physical_device;
95 static int hf_ndmp_fs_total_size;
96 static int hf_ndmp_fs_used_size;
97 static int hf_ndmp_fs_avail_size;
98 static int hf_ndmp_fs_total_inodes;
99 static int hf_ndmp_fs_used_inodes;
100 static int hf_ndmp_fs_env;
101 static int hf_ndmp_fs_env_name;
102 static int hf_ndmp_fs_env_value;
103 static int hf_ndmp_fs_status;
104 static int hf_ndmp_tape_info;
105 static int hf_ndmp_tape_model;
106 static int hf_ndmp_tape_dev_cap;
107 static int hf_ndmp_tape_device;
108 static int hf_ndmp_tape_open_mode;
109 static int hf_ndmp_tape_attr;
110 static int hf_ndmp_tape_attr_rewind;
111 static int hf_ndmp_tape_attr_unload;
112 static int hf_ndmp_tape_capability;
113 static int hf_ndmp_tape_capability_name;
114 static int hf_ndmp_tape_capability_value;
115 static int hf_ndmp_scsi_info;
116 static int hf_ndmp_scsi_model;
117 static int hf_ndmp_server_vendor;
118 static int hf_ndmp_server_product;
119 static int hf_ndmp_server_revision;
120 static int hf_ndmp_scsi_device;
121 static int hf_ndmp_scsi_controller;
122 static int hf_ndmp_scsi_id;
123 static int hf_ndmp_scsi_lun;
124 static int hf_ndmp_execute_cdb_flags;
125 static int hf_ndmp_execute_cdb_flags_data_in;
126 static int hf_ndmp_execute_cdb_flags_data_out;
127 static int hf_ndmp_execute_cdb_timeout;
128 static int hf_ndmp_execute_cdb_datain_len;
129 static int hf_ndmp_execute_cdb_cdb_len;
130 /* static int hf_ndmp_execute_cdb_dataout; */
131 static int hf_ndmp_execute_cdb_status;
132 static int hf_ndmp_execute_cdb_dataout_len;
133 /* static int hf_ndmp_execute_cdb_datain; */
134 static int hf_ndmp_execute_cdb_sns_len;
135 static int hf_ndmp_tape_invalid;
136 static int hf_ndmp_tape_invalid_file_num;
137 static int hf_ndmp_tape_invalid_soft_errors;
138 static int hf_ndmp_tape_invalid_block_size;
139 static int hf_ndmp_tape_invalid_block_no;
140 static int hf_ndmp_tape_invalid_total_space;
141 static int hf_ndmp_tape_invalid_space_remain;
142 static int hf_ndmp_tape_invalid_partition;
143 static int hf_ndmp_tape_flags;
144 static int hf_ndmp_tape_flags_no_rewind;
145 static int hf_ndmp_tape_flags_write_protect;
146 static int hf_ndmp_tape_flags_error;
147 static int hf_ndmp_tape_flags_unload;
148 static int hf_ndmp_tape_file_num;
149 static int hf_ndmp_tape_soft_errors;
150 static int hf_ndmp_tape_block_size;
151 static int hf_ndmp_tape_block_no;
152 static int hf_ndmp_tape_total_space;
153 static int hf_ndmp_tape_space_remain;
154 static int hf_ndmp_tape_partition;
155 static int hf_ndmp_tape_mtio_op;
156 static int hf_ndmp_count;
157 static int hf_ndmp_resid_count;
158 static int hf_ndmp_mover_state;
159 static int hf_ndmp_mover_pause;
160 static int hf_ndmp_halt;
161 static int hf_ndmp_halt_reason;
162 static int hf_ndmp_record_size;
163 static int hf_ndmp_record_num;
164 static int hf_ndmp_data_written;
165 static int hf_ndmp_seek_position;
166 static int hf_ndmp_bytes_left_to_read;
167 static int hf_ndmp_window_offset;
168 static int hf_ndmp_window_length;
169 static int hf_ndmp_addr_ip;
170 static int hf_ndmp_addr_tcp;
171 static int hf_ndmp_addr_fcal_loop_id;
172 static int hf_ndmp_addr_ipc;
173 static int hf_ndmp_mover_mode;
174 static int hf_ndmp_file_name;
175 static int hf_ndmp_nt_file_name;
176 static int hf_ndmp_dos_file_name;
177 static int hf_ndmp_log_type;
178 static int hf_ndmp_log_message_id;
179 static int hf_ndmp_log_message;
180 static int hf_ndmp_connected;
181 static int hf_ndmp_connected_reason;
182 static int hf_ndmp_data;
183 static int hf_ndmp_files;
184 static int hf_ndmp_file_fs_type;
185 static int hf_ndmp_file_names;
186 static int hf_ndmp_file_stats;
187 static int hf_ndmp_file_node;
188 static int hf_ndmp_file_parent;
189 static int hf_ndmp_file_fh_info;
190 static int hf_ndmp_file_invalid;
191 static int hf_ndmp_file_invalid_atime;
192 static int hf_ndmp_file_invalid_ctime;
193 static int hf_ndmp_file_invalid_group;
194 static int hf_ndmp_file_type;
195 static int hf_ndmp_file_mtime;
196 static int hf_ndmp_file_atime;
197 static int hf_ndmp_file_ctime;
198 static int hf_ndmp_file_owner;
199 static int hf_ndmp_file_group;
200 static int hf_ndmp_file_fattr;
201 static int hf_ndmp_file_size;
202 static int hf_ndmp_file_links;
203 static int hf_ndmp_dirs;
204 static int hf_ndmp_nodes;
205 static int hf_ndmp_nlist;
206 static int hf_ndmp_bu_original_path;
207 static int hf_ndmp_bu_destination_dir;
208 static int hf_ndmp_bu_new_name;
209 static int hf_ndmp_bu_other_name;
210 static int hf_ndmp_state_invalid;
211 static int hf_ndmp_state_invalid_ebr;
212 static int hf_ndmp_state_invalid_etr;
213 static int hf_ndmp_bu_operation;
214 static int hf_ndmp_data_state;
215 static int hf_ndmp_data_halted;
216 static int hf_ndmp_data_bytes_processed;
217 static int hf_ndmp_data_est_bytes_remain;
218 static int hf_ndmp_data_est_time_remain;
219 static int hf_ndmp_ex_class_id;
220 static int hf_ndmp_class_list;
221 static int hf_ndmp_ext_version;
222 static int hf_ndmp_ext_version_list;
223 static int hf_ndmp_class_version;
224 static int hf_ndmp_ex_class_version;
226 static int hf_ndmp_fragment_data;
227 static int hf_ndmp_fragments;
228 static int hf_ndmp_fragment;
229 static int hf_ndmp_fragment_overlap;
230 static int hf_ndmp_fragment_overlap_conflicts;
231 static int hf_ndmp_fragment_multiple_tails;
232 static int hf_ndmp_fragment_too_long_fragment;
233 static int hf_ndmp_fragment_error;
234 static int hf_ndmp_fragment_count;
235 static int hf_ndmp_reassembled_in;
236 static int hf_ndmp_reassembled_length;
238 static int ett_ndmp;
239 static int ett_ndmp_fraghdr;
240 static int ett_ndmp_header;
241 static int ett_ndmp_butype_attrs;
242 static int ett_ndmp_fs_invalid;
243 static int ett_ndmp_tape_attr;
244 static int ett_ndmp_execute_cdb_flags;
245 static int ett_ndmp_execute_cdb_cdb;
246 static int ett_ndmp_execute_cdb_sns;
247 static int ett_ndmp_execute_cdb_payload;
248 static int ett_ndmp_tape_invalid;
249 static int ett_ndmp_tape_flags;
250 static int ett_ndmp_addr;
251 static int ett_ndmp_file;
252 static int ett_ndmp_file_name;
253 static int ett_ndmp_file_stats;
254 static int ett_ndmp_file_invalids;
255 static int ett_ndmp_state_invalids;
256 static int ett_ndmp_fragment;
257 static int ett_ndmp_fragments;
259 static expert_field ei_ndmp_msg;
261 static const fragment_items ndmp_frag_items = {
262 /* Fragment subtrees */
263 &ett_ndmp_fragment,
264 &ett_ndmp_fragments,
265 /* Fragment fields */
266 &hf_ndmp_fragments,
267 &hf_ndmp_fragment,
268 &hf_ndmp_fragment_overlap,
269 &hf_ndmp_fragment_overlap_conflicts,
270 &hf_ndmp_fragment_multiple_tails,
271 &hf_ndmp_fragment_too_long_fragment,
272 &hf_ndmp_fragment_error,
273 &hf_ndmp_fragment_count,
274 /* Reassembled in field */
275 &hf_ndmp_reassembled_in,
276 /* Reassembled length field */
277 &hf_ndmp_reassembled_length,
278 /* Reassembled data field */
279 NULL,
280 /* Tag */
281 "NDMP fragments"
284 static reassembly_table ndmp_reassembly_table;
286 /* XXX someone should start adding the new stuff from v3, v4 and v5*/
287 #define NDMP_PROTOCOL_UNKNOWN 0
288 #define NDMP_PROTOCOL_V2 2
289 #define NDMP_PROTOCOL_V3 3
290 #define NDMP_PROTOCOL_V4 4
291 #define NDMP_PROTOCOL_V5 5
292 static const enum_val_t ndmp_protocol_versions[] = {
293 { "version2", "Version 2", NDMP_PROTOCOL_V2 },
294 { "version3", "Version 3", NDMP_PROTOCOL_V3 },
295 { "version4", "Version 4", NDMP_PROTOCOL_V4 },
296 { "version5", "Version 5", NDMP_PROTOCOL_V5 },
297 { NULL, NULL, 0 }
300 static int ndmp_default_protocol_version = NDMP_PROTOCOL_V4;
302 typedef struct _ndmp_frag_info {
303 uint32_t first_seq;
304 uint16_t offset;
305 } ndmp_frag_info;
307 typedef struct _ndmp_task_data_t {
308 uint32_t request_frame;
309 uint32_t response_frame;
310 nstime_t ndmp_time;
311 itlq_nexus_t *itlq;
312 } ndmp_task_data_t;
314 typedef struct _ndmp_conv_data_t {
315 uint8_t version;
316 wmem_map_t *tasks; /* indexed by Sequence# */
317 wmem_tree_t *itl; /* indexed by packet# */
318 wmem_map_t *fragsA; /* indexed by Sequence# */
319 wmem_map_t *fragsB;
320 ndmp_task_data_t *task;
321 conversation_t *conversation;
322 } ndmp_conv_data_t;
323 static ndmp_conv_data_t *ndmp_conv_data;
324 static proto_tree *top_tree;
326 static itl_nexus_t *
327 get_itl_nexus(packet_info *pinfo, bool create_new)
329 itl_nexus_t *itl;
331 if(create_new || !(itl=(itl_nexus_t *)wmem_tree_lookup32_le(ndmp_conv_data->itl, pinfo->num))){
332 itl=wmem_new(wmem_file_scope(), itl_nexus_t);
333 itl->cmdset=0xff;
334 itl->conversation=ndmp_conv_data->conversation;
335 wmem_tree_insert32(ndmp_conv_data->itl, pinfo->num, itl);
337 return itl;
340 static uint8_t
341 get_ndmp_protocol_version(void)
343 if(!ndmp_conv_data || (ndmp_conv_data->version==NDMP_PROTOCOL_UNKNOWN)){
344 return ndmp_default_protocol_version;
346 return ndmp_conv_data->version;
349 struct ndmp_header {
350 uint32_t seq;
351 uint32_t timestamp;
352 uint32_t type;
353 uint32_t msg;
354 uint32_t rep_seq;
355 uint32_t err;
358 /* desegmentation of NDMP packets */
359 static bool ndmp_desegment = true;
361 /* defragmentation of fragmented NDMP records */
362 static bool ndmp_defragment = true;
364 #define NDMP_MESSAGE_REQUEST 0x00
365 #define NDMP_MESSAGE_REPLY 0x01
366 static const value_string msg_type_vals[] = {
367 {NDMP_MESSAGE_REQUEST, "Request"},
368 {NDMP_MESSAGE_REPLY, "Reply"},
369 {0, NULL}
372 #define NDMP_NO_ERR 0x00
373 #define NDMP_NOT_SUPPORTED_ERR 0x01
374 #define NDMP_DEVICE_BUSY_ERR 0x02
375 #define NDMP_DEVICE_OPENED_ERR 0x03
376 #define NDMP_NOT_AUTHORIZED_ERR 0x04
377 #define NDMP_PERMISSION_ERR 0x05
378 #define NDMP_DEV_NOT_OPEN_ERR 0x06
379 #define NDMP_IO_ERR 0x07
380 #define NDMP_TIMEOUT_ERR 0x08
381 #define NDMP_ILLEGAL_ARGS_ERR 0x09
382 #define NDMP_NO_TAPE_LOADED_ERR 0x0a
383 #define NDMP_WRITE_PROTECT_ERR 0x0b
384 #define NDMP_EOF_ERR 0x0c
385 #define NDMP_EOM_ERR 0x0d
386 #define NDMP_FILE_NOT_FOUND_ERR 0x0e
387 #define NDMP_BAD_FILE_ERR 0x0f
388 #define NDMP_NO_DEVICE_ERR 0x10
389 #define NDMP_NO_BUS_ERR 0x11
390 #define NDMP_XDR_DECODE_ERR 0x12
391 #define NDMP_ILLEGAL_STATE_ERR 0x13
392 #define NDMP_UNDEFINED_ERR 0x14
393 #define NDMP_XDR_ENCODE_ERR 0x15
394 #define NDMP_NO_MEM_ERR 0x16
395 #define NDMP_CONNECT_ERR 0x17
396 #define NDMP_SEQUENCE_NUM_ERR 0x18
397 #define NDMP_READ_IN_PROGRESS_ERR 0x19
398 #define NDMP_PRECONDITION_ERR 0x1a
399 #define NDMP_CLASS_NOT_SUPPORTED_ERR 0x1b
400 #define NDMP_VERSION_NOT_SUPPORTED_ERR 0x1c
401 #define NDMP_EXT_DUPL_CLASSES_ERR 0x1d
402 #define NDMP_EXT_DANDN_ILLEGAL_ERR 0x1e
404 static const value_string error_vals[] = {
405 {NDMP_NO_ERR, "NO_ERR"},
406 {NDMP_NOT_SUPPORTED_ERR, "NOT_SUPPORTED_ERR"},
407 {NDMP_DEVICE_BUSY_ERR, "DEVICE_BUSY_ERR"},
408 {NDMP_DEVICE_OPENED_ERR, "DEVICE_OPENED_ERR"},
409 {NDMP_NOT_AUTHORIZED_ERR, "NOT_AUTHORIZED_ERR"},
410 {NDMP_PERMISSION_ERR, "PERMISSION_ERR"},
411 {NDMP_DEV_NOT_OPEN_ERR, "DEV_NOT_OPEN_ERR"},
412 {NDMP_IO_ERR, "IO_ERR"},
413 {NDMP_TIMEOUT_ERR, "TIMEOUT_ERR"},
414 {NDMP_ILLEGAL_ARGS_ERR, "ILLEGAL_ARGS_ERR"},
415 {NDMP_NO_TAPE_LOADED_ERR, "NO_TAPE_LOADED_ERR"},
416 {NDMP_WRITE_PROTECT_ERR, "WRITE_PROTECT_ERR"},
417 {NDMP_EOF_ERR, "EOF_ERR"},
418 {NDMP_EOM_ERR, "EOM_ERR"},
419 {NDMP_FILE_NOT_FOUND_ERR, "FILE_NOT_FOUND_ERR"},
420 {NDMP_BAD_FILE_ERR, "BAD_FILE_ERR"},
421 {NDMP_NO_DEVICE_ERR, "NO_DEVICE_ERR"},
422 {NDMP_NO_BUS_ERR, "NO_BUS_ERR"},
423 {NDMP_XDR_DECODE_ERR, "XDR_DECODE_ERR"},
424 {NDMP_ILLEGAL_STATE_ERR, "ILLEGAL_STATE_ERR"},
425 {NDMP_UNDEFINED_ERR, "UNDEFINED_ERR"},
426 {NDMP_XDR_ENCODE_ERR, "XDR_ENCODE_ERR"},
427 {NDMP_NO_MEM_ERR, "NO_MEM_ERR"},
428 {NDMP_CONNECT_ERR, "CONNECT_ERR"},
429 {NDMP_SEQUENCE_NUM_ERR, "NDMP_SEQUENCE_NUM_ERR"},
430 {NDMP_READ_IN_PROGRESS_ERR, "NDMP_READ_IN_PROGRESS_ERR"},
431 {NDMP_PRECONDITION_ERR, "NDMP_PRECONDITION_ERR"},
432 {NDMP_CLASS_NOT_SUPPORTED_ERR, "NDMP_CLASS_NOT_SUPPORTED_ERR"},
433 {NDMP_VERSION_NOT_SUPPORTED_ERR,"NDMP_VERSION_NOT_SUPPORTED_ERR"},
434 {NDMP_EXT_DUPL_CLASSES_ERR, "NDMP_EXT_DUPL_CLASSES_ERR"},
435 {NDMP_EXT_DANDN_ILLEGAL_ERR, "NDMP_EXT_DANDN_ILLEGAL_ERR"},
436 {0, NULL}
441 #define NDMP_CONFIG_GET_HOST_INFO 0x100
442 #define NDMP_CONFIG_GET_CONNECTION_TYPE 0x102
443 #define NDMP_CONFIG_GET_AUTH_ATTR 0x103
444 #define NDMP_CONFIG_GET_BUTYPE_INFO 0x104
445 #define NDMP_CONFIG_GET_FS_INFO 0x105
446 #define NDMP_CONFIG_GET_TAPE_INFO 0x106
447 #define NDMP_CONFIG_GET_SCSI_INFO 0x107
448 #define NDMP_CONFIG_GET_SERVER_INFO 0x108
449 #define NDMP_CONFIG_SET_EXT_LIST 0x109
450 #define NDMP_CONFIG_GET_EXT_LIST 0x10a
451 #define NDMP_SCSI_OPEN 0x200
452 #define NDMP_SCSI_CLOSE 0x201
453 #define NDMP_SCSI_GET_STATE 0x202
454 #define NDMP_SCSI_SET_TARGET 0x203
455 #define NDMP_SCSI_RESET_DEVICE 0x204
456 #define NDMP_SCSI_RESET_BUS 0x205
457 #define NDMP_SCSI_EXECUTE_CDB 0x206
458 #define NDMP_TAPE_OPEN 0x300
459 #define NDMP_TAPE_CLOSE 0x301
460 #define NDMP_TAPE_GET_STATE 0x302
461 #define NDMP_TAPE_MTIO 0x303
462 #define NDMP_TAPE_WRITE 0x304
463 #define NDMP_TAPE_READ 0x305
464 #define NDMP_TAPE_EXECUTE_CDB 0x307
465 #define NDMP_DATA_GET_STATE 0x400
466 #define NDMP_DATA_START_BACKUP 0x401
467 #define NDMP_DATA_START_RECOVER 0x402
468 #define NDMP_DATA_ABORT 0x403
469 #define NDMP_DATA_GET_ENV 0x404
470 #define NDMP_DATA_STOP 0x407
471 #define NDMP_DATA_LISTEN 0x409
472 #define NDMP_DATA_CONNECT 0x40a
473 #define NDMP_NOTIFY_DATA_HALTED 0x501
474 #define NDMP_NOTIFY_CONNECTED 0x502
475 #define NDMP_NOTIFY_MOVER_HALTED 0x503
476 #define NDMP_NOTIFY_MOVER_PAUSED 0x504
477 #define NDMP_NOTIFY_DATA_READ 0x505
478 #define NDMP_LOG_FILE 0x602
479 #define NDMP_LOG_MESSAGE 0x603
480 #define NDMP_FH_ADD_FILE 0x703
481 #define NDMP_FH_ADD_DIR 0x704
482 #define NDMP_FH_ADD_NODE 0x705
483 #define NDMP_CONNECT_OPEN 0x900
484 #define NDMP_CONNECT_CLIENT_AUTH 0x901
485 #define NDMP_CONNECT_CLOSE 0x902
486 #define NDMP_CONNECT_SERVER_AUTH 0x903
487 #define NDMP_MOVER_GET_STATE 0xa00
488 #define NDMP_MOVER_LISTEN 0xa01
489 #define NDMP_MOVER_CONTINUE 0xa02
490 #define NDMP_MOVER_ABORT 0xa03
491 #define NDMP_MOVER_STOP 0xa04
492 #define NDMP_MOVER_SET_WINDOW 0xa05
493 #define NDMP_MOVER_READ 0xa06
494 #define NDMP_MOVER_CLOSE 0xa07
495 #define NDMP_MOVER_SET_RECORD_SIZE 0xa08
496 #define NDMP_MOVER_CONNECT 0xa09
501 static const value_string msg_vals[] = {
502 {NDMP_CONFIG_GET_HOST_INFO, "CONFIG_GET_HOST_INFO"},
503 {NDMP_CONFIG_GET_CONNECTION_TYPE, "CONFIG_GET_CONNECTION_TYPE"},
504 {NDMP_CONFIG_GET_AUTH_ATTR, "CONFIG_GET_AUTH_ATTR"},
505 {NDMP_CONFIG_GET_BUTYPE_INFO, "CONFIG_GET_BUTYPE_INFO"},
506 {NDMP_CONFIG_GET_FS_INFO, "CONFIG_GET_FS_INFO"},
507 {NDMP_CONFIG_GET_TAPE_INFO, "CONFIG_GET_TAPE_INFO"},
508 {NDMP_CONFIG_GET_SCSI_INFO, "CONFIG_GET_SCSI_INFO"},
509 {NDMP_CONFIG_GET_SERVER_INFO, "CONFIG_GET_SERVER_INFO"},
510 {NDMP_CONFIG_GET_EXT_LIST, "CONFIG_GET_EXT_LIST"},
511 {NDMP_CONFIG_SET_EXT_LIST, "CONFIG_SET_EXT_LIST"},
512 {NDMP_SCSI_OPEN, "SCSI_OPEN"},
513 {NDMP_SCSI_CLOSE, "SCSI_CLOSE"},
514 {NDMP_SCSI_GET_STATE, "SCSI_GET_STATE"},
515 {NDMP_SCSI_SET_TARGET, "SCSI_SET_TARGET"},
516 {NDMP_SCSI_RESET_DEVICE, "SCSI_RESET_DEVICE"},
517 {NDMP_SCSI_RESET_BUS, "SCSI_RESET_BUS"},
518 {NDMP_SCSI_EXECUTE_CDB, "SCSI_EXECUTE_CDB"},
519 {NDMP_TAPE_OPEN, "TAPE_OPEN"},
520 {NDMP_TAPE_CLOSE, "TAPE_CLOSE"},
521 {NDMP_TAPE_GET_STATE, "TAPE_GET_STATE"},
522 {NDMP_TAPE_MTIO, "TAPE_MTIO"},
523 {NDMP_TAPE_WRITE, "TAPE_WRITE"},
524 {NDMP_TAPE_READ, "TAPE_READ"},
525 {NDMP_TAPE_EXECUTE_CDB, "TAPE_EXECUTE_CDB"},
526 {NDMP_DATA_GET_STATE, "DATA_GET_STATE"},
527 {NDMP_DATA_START_BACKUP, "DATA_START_BACKUP"},
528 {NDMP_DATA_START_RECOVER, "DATA_START_RECOVER"},
529 {NDMP_DATA_ABORT, "DATA_ABORT"},
530 {NDMP_DATA_GET_ENV, "DATA_GET_ENV"},
531 {NDMP_DATA_STOP, "DATA_STOP"},
532 {NDMP_DATA_LISTEN, "DATA_LISTEN"},
533 {NDMP_DATA_CONNECT, "DATA_CONNECT"},
534 {NDMP_NOTIFY_DATA_HALTED, "NOTIFY_DATA_HALTED"},
535 {NDMP_NOTIFY_CONNECTED, "NOTIFY_CONNECTED"},
536 {NDMP_NOTIFY_MOVER_HALTED, "NOTIFY_MOVER_HALTED"},
537 {NDMP_NOTIFY_MOVER_PAUSED, "NOTIFY_MOVER_PAUSED"},
538 {NDMP_NOTIFY_DATA_READ, "NOTIFY_DATA_READ"},
539 {NDMP_LOG_FILE, "LOG_FILE"},
540 {NDMP_LOG_MESSAGE, "LOG_MESSAGE"},
541 {NDMP_FH_ADD_FILE, "FH_ADD_FILE"},
542 {NDMP_FH_ADD_DIR, "FH_ADD_DIR"},
543 {NDMP_FH_ADD_NODE, "FH_ADD_NODE"},
544 {NDMP_CONNECT_OPEN, "CONNECT_OPEN"},
545 {NDMP_CONNECT_CLIENT_AUTH, "CONNECT_CLIENT_AUTH"},
546 {NDMP_CONNECT_CLOSE, "CONNECT_CLOSE"},
547 {NDMP_CONNECT_SERVER_AUTH, "CONNECT_SERVER_AUTH"},
548 {NDMP_MOVER_GET_STATE, "MOVER_GET_STATE"},
549 {NDMP_MOVER_LISTEN, "MOVER_LISTEN"},
550 {NDMP_MOVER_CONTINUE, "MOVER_CONTINUE"},
551 {NDMP_MOVER_ABORT, "MOVER_ABORT"},
552 {NDMP_MOVER_STOP, "MOVER_STOP"},
553 {NDMP_MOVER_SET_WINDOW, "MOVER_SET_WINDOW"},
554 {NDMP_MOVER_READ, "MOVER_READ"},
555 {NDMP_MOVER_CLOSE, "MOVER_CLOSE"},
556 {NDMP_MOVER_SET_RECORD_SIZE, "MOVER_SET_RECORD_SIZE"},
557 {NDMP_MOVER_CONNECT, "MOVER_CONNECT"},
558 {0, NULL}
561 static bool
562 check_ndmp_rm(tvbuff_t *tvb, packet_info *pinfo)
564 unsigned len;
565 uint32_t tmp;
567 /* verify that the tcp port is 10000, ndmp always runs on port 10000*/
568 if ((pinfo->srcport!=TCP_PORT_NDMP)&&(pinfo->destport!=TCP_PORT_NDMP)) {
569 return false;
572 /* check that the header looks sane */
573 len=tvb_captured_length(tvb);
574 /* check the record marker that it looks sane.
575 * It has to be >=0 bytes or (arbitrary limit) <1Mbyte
577 if(len>=4){
578 tmp=(tvb_get_ntohl(tvb, 0)&RPC_RM_FRAGLEN);
579 if( (tmp<1)||(tmp>1000000) ){
580 return false;
584 return true;
587 static bool
588 check_ndmp_hdr(tvbuff_t *tvb )
590 unsigned len;
591 uint32_t tmp;
593 len=tvb_captured_length(tvb);
595 /* If the length is less than 24, it isn't a valid
596 header */
597 if (len<24){
598 return false;
601 /* check the timestamp, timestamps are valid if they
602 * (arbitrary) lie between 1980-jan-1 and 2030-jan-1
604 if(len>=8){
605 tmp=tvb_get_ntohl(tvb, 4);
606 if( (tmp<0x12ceec50)||(tmp>0x70dc1ed0) ){
607 return false;
611 /* check the type */
612 if(len>=12){
613 tmp=tvb_get_ntohl(tvb, 8);
614 if( tmp>1 ){
615 return false;
619 /* check message */
620 if(len>=16){
621 tmp=tvb_get_ntohl(tvb, 12);
622 if( (tmp>0xa09) || (tmp==0) ){
623 return false;
627 /* check error */
628 if(len>=24){
629 tmp=tvb_get_ntohl(tvb, 20);
630 if( (tmp>0x17) ){
631 return false;
635 return true;
638 static int
639 dissect_connect_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
640 proto_tree *tree, uint32_t seq _U_)
642 uint32_t version;
644 /* version number */
645 proto_tree_add_item(tree, hf_ndmp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
646 version=tvb_get_ntohl(tvb, offset);
647 ndmp_conv_data->version=version;
648 offset += 4;
650 return offset;
653 static int
654 dissect_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
655 proto_tree *tree, uint32_t seq _U_)
657 uint32_t err;
659 /* error */
660 err=tvb_get_ntohl(tvb, offset);
661 proto_tree_add_item(tree, hf_ndmp_error, tvb, offset, 4, ENC_BIG_ENDIAN);
662 if(err) {
663 col_append_fstr(pinfo->cinfo, COL_INFO,
664 " NDMP Error:%s ",
665 val_to_str(err, error_vals,
666 "Unknown NDMP error code %#x"));
669 offset += 4;
671 return offset;
674 static int
675 dissect_ndmp_get_host_info_reply(tvbuff_t *tvb, int offset,
676 packet_info *pinfo, proto_tree *tree, uint32_t seq)
678 /* error */
679 offset=dissect_error(tvb, offset, pinfo, tree, seq);
681 /* hostname */
682 offset = dissect_rpc_string(tvb, tree,
683 hf_ndmp_hostname, offset, NULL);
685 /* os type */
686 offset = dissect_rpc_string(tvb, tree,
687 hf_ndmp_os_type, offset, NULL);
689 /* os version */
690 offset = dissect_rpc_string(tvb, tree,
691 hf_ndmp_os_vers, offset, NULL);
693 /* hostid */
694 offset = dissect_rpc_string(tvb, tree,
695 hf_ndmp_hostid, offset, NULL);
697 return offset;
700 #define NDMP_ADDR_LOCAL 0
701 #define NDMP_ADDR_TCP 1
702 #define NDMP_ADDR_FC 2
703 #define NDMP_ADDR_IPC 3
704 static const value_string addr_type_vals[] = {
705 {NDMP_ADDR_LOCAL, "Local"},
706 {NDMP_ADDR_TCP, "TCP"},
707 {NDMP_ADDR_FC, "FC"},
708 {NDMP_ADDR_IPC, "IPC"},
709 {0,NULL}
712 static int
713 dissect_ndmp_addr_type(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
714 proto_tree *tree, void* data _U_)
716 proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, ENC_BIG_ENDIAN);
717 offset += 4;
719 return offset;
722 static int
723 dissect_ndmp_addr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
724 proto_tree *tree, uint32_t seq _U_)
726 /*address type*/
727 return dissect_ndmp_addr_type(tvb, offset, pinfo, tree, NULL);
730 static int
731 dissect_ndmp_config_get_connection_type_reply(tvbuff_t *tvb, int offset,
732 packet_info *pinfo, proto_tree *tree, uint32_t seq)
734 /* error */
735 offset=dissect_error(tvb, offset, pinfo, tree, seq);
737 /* addr types */
738 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
739 dissect_ndmp_addr_type, hf_ndmp_addr_types);
741 return offset;
744 #define NDMP_AUTH_NONE 0
745 #define NDMP_AUTH_TEXT 1
746 #define NDMP_AUTH_MD5 2
747 static const value_string auth_type_vals[] = {
748 {NDMP_AUTH_NONE, "None"},
749 {NDMP_AUTH_TEXT, "Text"},
750 {NDMP_AUTH_MD5, "MD5"},
751 {0,NULL}
753 static int
754 dissect_auth_type(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
755 proto_tree *tree, void* data _U_)
757 proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, ENC_BIG_ENDIAN);
758 offset += 4;
760 return offset;
763 static int
764 dissect_get_auth_type_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
765 proto_tree *tree, uint32_t seq _U_)
767 /* auth type */
768 return dissect_auth_type(tvb, offset, pinfo, tree, NULL);
771 static int
772 dissect_auth_attr_msg(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
773 proto_tree *tree, uint32_t seq _U_)
775 unsigned type;
777 type=tvb_get_ntohl(tvb,offset);
779 /* auth type */
780 proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, ENC_BIG_ENDIAN);
781 offset += 4;
783 switch(type){
784 case NDMP_AUTH_NONE:
785 break;
786 case NDMP_AUTH_TEXT:
787 break;
788 case NDMP_AUTH_MD5:
789 proto_tree_add_item(tree, hf_ndmp_auth_challenge,
790 tvb, offset, 64, ENC_NA);
791 offset+=64;
794 return offset;
797 static int
798 dissect_ndmp_config_get_auth_attr_reply(tvbuff_t *tvb, int offset,
799 packet_info *pinfo, proto_tree *tree, uint32_t seq)
801 /* error */
802 offset = dissect_error(tvb, offset, pinfo, tree, seq);
804 /* auth_attr */
805 offset = dissect_auth_attr_msg(tvb, offset, pinfo, tree, seq);
807 return offset;
810 static int
811 dissect_default_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
812 proto_tree *tree, void* data _U_)
814 /* name */
815 offset = dissect_rpc_string(tvb, tree,
816 hf_ndmp_butype_env_name, offset, NULL);
818 /* value */
819 offset = dissect_rpc_string(tvb, tree,
820 hf_ndmp_butype_env_value, offset, NULL);
822 return offset;
826 static const true_false_string tfs_butype_attr_backup_file_history = {
827 "Backup FILE HISTORY",
828 "Do NOT backup file history"
830 static const true_false_string tfs_butype_attr_backup_filelist = {
831 "Backup FILELIST",
832 "Do NOT backup filelist"
834 static const true_false_string tfs_butype_attr_recover_filelist = {
835 "Recover FILELIST",
836 "Do NOT recover filelist"
838 static const true_false_string tfs_butype_attr_backup_direct = {
839 "Perform DIRECT backup",
840 "Do NOT perform direct backup"
842 static const true_false_string tfs_butype_attr_recover_direct = {
843 "Perform DIRECT recovery",
844 "Do NOT perform direct recovery"
846 static const true_false_string tfs_butype_attr_backup_incremental = {
847 "Perform INCREMENTAL backup",
848 "Perform FULL backup"
850 static const true_false_string tfs_butype_attr_recover_incremental = {
851 "Perform INCREMENTAL recovery",
852 "Perform FULL recovery"
854 static const true_false_string tfs_butype_attr_backup_utf8 = {
855 "Backup using UTF8",
856 "Normal backup. Do NOT use utf8"
858 static const true_false_string tfs_butype_attr_recover_utf8 = {
859 "Recover using UTF8",
860 "Normal recover. Do NOT use utf8"
862 static int
863 dissect_butype_attrs(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
864 proto_tree *parent_tree)
866 static int * const attribute_flags[] = {
867 &hf_ndmp_butype_attr_recover_utf8,
868 &hf_ndmp_butype_attr_backup_utf8,
869 &hf_ndmp_butype_attr_recover_incremental,
870 &hf_ndmp_butype_attr_backup_incremental,
871 &hf_ndmp_butype_attr_recover_direct,
872 &hf_ndmp_butype_attr_backup_direct,
873 &hf_ndmp_butype_attr_recover_filelist,
874 &hf_ndmp_butype_attr_backup_filelist,
875 &hf_ndmp_butype_attr_backup_file_history,
876 NULL
879 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_butype_attr, ett_ndmp_butype_attrs, attribute_flags, ENC_NA);
881 offset += 4;
882 return offset;
885 static int
886 dissect_butype_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
888 /*butype name*/
889 offset = dissect_rpc_string(tvb, tree,
890 hf_ndmp_butype_name, offset, NULL);
892 /* default env */
893 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
894 dissect_default_env, hf_ndmp_butype_default_env);
896 /* attrs */
897 offset = dissect_butype_attrs(tvb, offset, pinfo, tree);
899 return offset;
902 static int
903 dissect_get_butype_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
904 proto_tree *tree, uint32_t seq)
906 /* error */
907 offset=dissect_error(tvb, offset, pinfo, tree, seq);
909 /* butype */
910 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
911 dissect_butype_info, hf_ndmp_butype_info);
913 return offset;
916 static const true_false_string tfs_fs_invalid_total_size = {
917 "Total size is INVALID",
918 "Total size is VALID"
920 static const true_false_string tfs_fs_invalid_used_size = {
921 "Used size is INVALID",
922 "Used size is VALID"
924 static const true_false_string tfs_fs_invalid_avail_size = {
925 "Available size is INVALID",
926 "Available size is VALID"
928 static const true_false_string tfs_fs_invalid_total_inodes = {
929 "Total inode count is INVALID",
930 "Total inode count is VALID"
932 static const true_false_string tfs_fs_invalid_used_inodes = {
933 "Used inode count is INVALID",
934 "Used inode count is VALID"
936 static int
937 dissect_fs_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
938 proto_tree *parent_tree)
940 static int * const invalid_flags[] = {
941 &hf_ndmp_fs_invalid_used_inodes,
942 &hf_ndmp_fs_invalid_total_inodes,
943 &hf_ndmp_fs_invalid_avail_size,
944 &hf_ndmp_fs_invalid_used_size,
945 &hf_ndmp_fs_invalid_total_size,
946 NULL
949 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_fs_invalid, ett_ndmp_fs_invalid, invalid_flags, ENC_NA);
951 offset+=4;
952 return offset;
955 static int
956 dissect_fs_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
957 proto_tree *tree, void* data _U_)
959 /* name */
960 offset = dissect_rpc_string(tvb, tree,
961 hf_ndmp_fs_env_name, offset, NULL);
963 /* value */
964 offset = dissect_rpc_string(tvb, tree,
965 hf_ndmp_fs_env_value, offset, NULL);
967 return offset;
970 static int
971 dissect_fs_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
973 /* invalid bits */
974 offset=dissect_fs_invalid(tvb, offset, pinfo, tree);
976 /* fs type */
977 offset = dissect_rpc_string(tvb, tree,
978 hf_ndmp_fs_fs_type, offset, NULL);
980 /* fs logical device */
981 offset = dissect_rpc_string(tvb, tree,
982 hf_ndmp_fs_logical_device, offset, NULL);
984 /* fs physical device */
985 offset = dissect_rpc_string(tvb, tree,
986 hf_ndmp_fs_physical_device, offset, NULL);
988 /*total_size*/
989 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_total_size,
990 offset);
992 /*used_size*/
993 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_used_size,
994 offset);
996 /*avail_size*/
997 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_avail_size,
998 offset);
1000 /*total_inodes*/
1001 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_total_inodes,
1002 offset);
1004 /*used_inodes*/
1005 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_fs_used_inodes,
1006 offset);
1008 /* env */
1009 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1010 dissect_fs_env, hf_ndmp_fs_env);
1012 /* status */
1013 offset = dissect_rpc_string(tvb, tree,
1014 hf_ndmp_fs_status, offset, NULL);
1016 return offset;
1019 static int
1020 dissect_get_fs_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1021 proto_tree *tree, uint32_t seq)
1023 /* error */
1024 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1026 /* fs */
1027 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1028 dissect_fs_info, hf_ndmp_fs_info);
1030 return offset;
1033 static const true_false_string tfs_tape_attr_rewind = {
1034 "Device supports REWIND",
1035 "Device does NOT support rewind"
1037 static const true_false_string tfs_tape_attr_unload = {
1038 "Device supports UNLOAD",
1039 "Device does NOT support unload"
1041 static int
1042 dissect_tape_attr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1043 proto_tree *parent_tree)
1045 static int * const attribute_flags[] = {
1046 &hf_ndmp_tape_attr_unload,
1047 &hf_ndmp_tape_attr_rewind,
1048 NULL
1051 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_tape_attr, ett_ndmp_tape_attr, attribute_flags, ENC_NA);
1053 offset+=4;
1054 return offset;
1057 static int
1058 dissect_tape_capability(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1059 proto_tree *tree, void* data _U_)
1061 /* name */
1062 offset = dissect_rpc_string(tvb, tree,
1063 hf_ndmp_tape_capability_name, offset, NULL);
1065 /* value */
1066 offset = dissect_rpc_string(tvb, tree,
1067 hf_ndmp_tape_capability_value, offset, NULL);
1069 return offset;
1072 static int
1073 dissect_tape_dev_cap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1075 /* device */
1076 offset = dissect_rpc_string(tvb, tree,
1077 hf_ndmp_tape_device, offset, NULL);
1079 /* tape attributes */
1080 offset = dissect_tape_attr(tvb, offset, pinfo, tree);
1082 /* capability */
1083 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1084 dissect_tape_capability, hf_ndmp_tape_capability);
1086 return offset;
1089 static int
1090 dissect_tape_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1092 /* model */
1093 offset = dissect_rpc_string(tvb, tree,
1094 hf_ndmp_tape_model, offset, NULL);
1096 /* device capabilities */
1097 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1098 dissect_tape_dev_cap, hf_ndmp_tape_dev_cap);
1100 return offset;
1103 static int
1104 dissect_get_tape_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1105 proto_tree *tree, uint32_t seq)
1107 /* error */
1108 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1110 /* tape */
1111 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1112 dissect_tape_info, hf_ndmp_tape_info);
1114 return offset;
1117 static int
1118 dissect_scsi_info(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1120 /* model */
1121 offset = dissect_rpc_string(tvb, tree,
1122 hf_ndmp_scsi_model, offset, NULL);
1124 /* device capabilities */
1125 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1126 dissect_tape_dev_cap, hf_ndmp_tape_dev_cap);
1128 return offset;
1131 static int
1132 dissect_get_scsi_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1133 proto_tree *tree, uint32_t seq)
1135 /* error */
1136 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1138 /* scsi */
1139 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1140 dissect_scsi_info, hf_ndmp_scsi_info);
1142 return offset;
1145 static int
1146 dissect_get_server_info_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1147 proto_tree *tree, uint32_t seq)
1149 /* error */
1150 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1152 /* vendor */
1153 offset = dissect_rpc_string(tvb, tree,
1154 hf_ndmp_server_vendor, offset, NULL);
1156 /* product */
1157 offset = dissect_rpc_string(tvb, tree,
1158 hf_ndmp_server_product, offset, NULL);
1160 /* revision */
1161 offset = dissect_rpc_string(tvb, tree,
1162 hf_ndmp_server_revision, offset, NULL);
1165 /* server */
1166 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1167 dissect_auth_type, hf_ndmp_auth_types);
1169 return offset;
1172 static int
1173 dissect_ext_version(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1174 proto_tree *tree, void* data _U_) {
1176 /* extension version */
1177 proto_tree_add_item(tree, hf_ndmp_ext_version, tvb, offset, 4, ENC_BIG_ENDIAN);
1178 offset += 4;
1180 return offset;
1184 static int
1185 dissect_class_list(tvbuff_t *tvb, int offset, packet_info *pinfo,
1186 proto_tree *tree, void* data _U_) {
1188 /* class id */
1189 proto_tree_add_item(tree, hf_ndmp_ex_class_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1190 offset += 4;
1192 /* ext version */
1193 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1194 dissect_ext_version, hf_ndmp_ext_version_list);
1196 return offset;
1199 static int
1200 dissect_get_ext_list_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1201 proto_tree *tree, uint32_t seq)
1203 /* error */
1204 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1206 /* Class list */
1207 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1208 dissect_class_list, hf_ndmp_class_list);
1210 return offset;
1214 static int
1215 dissect_class_version(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1216 proto_tree *tree, void* data _U_) {
1218 /* class id */
1219 proto_tree_add_item(tree, hf_ndmp_ex_class_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1220 offset += 4;
1222 /* ext version */
1223 proto_tree_add_item(tree, hf_ndmp_ex_class_version, tvb, offset, 4, ENC_BIG_ENDIAN);
1224 offset += 4;
1226 return offset;
1229 static int
1230 dissect_set_ext_list_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1231 proto_tree *tree, uint32_t seq _U_)
1233 /* class version */
1234 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1235 dissect_class_version, hf_ndmp_class_version);
1237 return offset;
1241 static int
1242 dissect_set_ext_list_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1243 proto_tree *tree, uint32_t seq _U_)
1245 /* error */
1246 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1248 return offset;
1251 static int
1252 dissect_scsi_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1253 proto_tree *tree, uint32_t seq _U_)
1255 /* device */
1256 offset = dissect_rpc_string(tvb, tree,
1257 hf_ndmp_scsi_device, offset, NULL);
1260 if(!pinfo->fd->visited){
1261 /* new scsi device addressed, create a new itl structure */
1262 get_itl_nexus(pinfo, true);
1265 return offset;
1268 static int
1269 dissect_scsi_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1270 proto_tree *tree, uint32_t seq)
1272 /* error */
1273 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1275 /* controller */
1276 proto_tree_add_item(tree, hf_ndmp_scsi_controller, tvb, offset, 4, ENC_BIG_ENDIAN);
1277 offset += 4;
1279 /* id */
1280 proto_tree_add_item(tree, hf_ndmp_scsi_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1281 offset += 4;
1283 /* lun */
1284 proto_tree_add_item(tree, hf_ndmp_scsi_lun, tvb, offset, 4, ENC_BIG_ENDIAN);
1285 offset += 4;
1287 return offset;
1290 static int
1291 dissect_scsi_set_state_request(tvbuff_t *tvb, int offset,
1292 packet_info *pinfo _U_, proto_tree *tree, uint32_t seq _U_)
1294 /* device */
1295 offset = dissect_rpc_string(tvb, tree,
1296 hf_ndmp_scsi_device, offset, NULL);
1298 /* controller */
1299 proto_tree_add_item(tree, hf_ndmp_scsi_controller, tvb, offset, 4, ENC_BIG_ENDIAN);
1300 offset += 4;
1302 /* id */
1303 proto_tree_add_item(tree, hf_ndmp_scsi_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1304 offset += 4;
1306 /* lun */
1307 proto_tree_add_item(tree, hf_ndmp_scsi_lun, tvb, offset, 4, ENC_BIG_ENDIAN);
1308 offset += 4;
1310 return offset;
1313 static int
1314 dissect_execute_cdb_flags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1315 proto_tree *parent_tree)
1317 static int * const cdb_flags[] = {
1318 &hf_ndmp_execute_cdb_flags_data_in,
1319 &hf_ndmp_execute_cdb_flags_data_out,
1320 NULL
1323 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_execute_cdb_flags, ett_ndmp_execute_cdb_flags, cdb_flags, ENC_NA);
1325 offset += 4;
1326 return offset;
1329 static int
1330 dissect_execute_cdb_cdb(tvbuff_t *tvb, int offset, packet_info *pinfo,
1331 proto_tree *parent_tree, int devtype)
1333 proto_tree* tree;
1334 uint32_t cdb_len;
1335 uint32_t cdb_len_full;
1337 cdb_len = tvb_get_ntohl(tvb, offset);
1338 cdb_len_full = rpc_roundup(cdb_len);
1340 tree = proto_tree_add_subtree(parent_tree, tvb, offset,
1341 4+cdb_len_full, ett_ndmp_execute_cdb_cdb, NULL, "CDB");
1343 proto_tree_add_uint(tree, hf_ndmp_execute_cdb_cdb_len, tvb, offset, 4,
1344 cdb_len);
1345 offset += 4;
1347 if (cdb_len != 0) {
1348 tvbuff_t *cdb_tvb;
1349 int tvb_len, tvb_rlen;
1351 tvb_len=tvb_captured_length_remaining(tvb, offset);
1352 if(tvb_len>16)
1353 tvb_len=16;
1354 tvb_rlen=tvb_reported_length_remaining(tvb, offset);
1355 if(tvb_rlen>16)
1356 tvb_rlen=16;
1357 cdb_tvb=tvb_new_subset_length_caplen(tvb, offset, tvb_len, tvb_rlen);
1359 if(ndmp_conv_data->task && !ndmp_conv_data->task->itlq){
1360 ndmp_conv_data->task->itlq=wmem_new(wmem_file_scope(), itlq_nexus_t);
1361 ndmp_conv_data->task->itlq->lun=0xffff;
1362 ndmp_conv_data->task->itlq->first_exchange_frame=pinfo->num;
1363 ndmp_conv_data->task->itlq->last_exchange_frame=0;
1364 ndmp_conv_data->task->itlq->scsi_opcode=0xffff;
1365 ndmp_conv_data->task->itlq->task_flags=0;
1366 ndmp_conv_data->task->itlq->data_length=0;
1367 ndmp_conv_data->task->itlq->bidir_data_length=0;
1368 ndmp_conv_data->task->itlq->flags=0;
1369 ndmp_conv_data->task->itlq->alloc_len=0;
1370 ndmp_conv_data->task->itlq->fc_time=pinfo->abs_ts;
1371 ndmp_conv_data->task->itlq->extra_data=NULL;
1373 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1374 dissect_scsi_cdb(cdb_tvb, pinfo, top_tree, devtype, ndmp_conv_data->task->itlq, get_itl_nexus(pinfo, false));
1376 offset += cdb_len_full;
1379 return offset;
1383 static int
1384 dissect_execute_cdb_payload(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree,
1385 const char *name, int hf_len, bool isreq)
1387 proto_tree* tree;
1388 uint32_t payload_len;
1389 uint32_t payload_len_full;
1391 payload_len = tvb_get_ntohl(tvb, offset);
1392 payload_len_full = rpc_roundup(payload_len);
1394 tree = proto_tree_add_subtree(parent_tree, tvb, offset,
1395 4+payload_len_full, ett_ndmp_execute_cdb_payload, NULL, name);
1397 proto_tree_add_uint(tree, hf_len, tvb, offset, 4, payload_len);
1398 offset += 4;
1400 if ((int) payload_len > 0) {
1401 tvbuff_t *data_tvb;
1402 int tvb_len, tvb_rlen;
1404 tvb_len=tvb_captured_length_remaining(tvb, offset);
1405 if(tvb_len>(int)payload_len)
1406 tvb_len=payload_len;
1407 tvb_rlen=tvb_reported_length_remaining(tvb, offset);
1408 if(tvb_rlen>(int)payload_len)
1409 tvb_rlen=payload_len;
1410 data_tvb=tvb_new_subset_length_caplen(tvb, offset, tvb_len, tvb_rlen);
1412 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1413 /* ndmp conceptually always send both read and write
1414 * data and always a full nonfragmented pdu
1416 ndmp_conv_data->task->itlq->task_flags=SCSI_DATA_READ|SCSI_DATA_WRITE;
1417 ndmp_conv_data->task->itlq->data_length=payload_len;
1418 ndmp_conv_data->task->itlq->bidir_data_length=payload_len;
1419 dissect_scsi_payload(data_tvb, pinfo, top_tree, isreq,
1420 ndmp_conv_data->task->itlq,
1421 get_itl_nexus(pinfo, false),
1424 offset += payload_len_full;
1427 return offset;
1431 * XXX - we assume that NDMP_SCSI_EXECUTE_CDB requests only go to SCSI Media
1432 * Changer devices and NDMP_TAPE_EXECUTE_CDB only go to SCSI Sequential
1433 * Access devices.
1435 * If that's not the case, we'll have to use the SCSI dissector's mechanisms
1436 * for saving inquiry data for devices, and use inquiry data when available.
1437 * Unfortunately, that means we need to save the name of the device, and
1438 * use it as a device identifier; as the name isn't available in the
1439 * NDMP_SCSI_EXECUTE_CDB or NDMP_TAPE_EXECUTE_CDB messages, that means
1440 * we need to remember the currently-opened "SCSI" and "TAPE" devices
1441 * from NDMP_SCSI_OPEN and NDMP_TAPE_OPEN, and attach to all frames
1442 * that are the ones that trigger the dissection of NDMP_SCSI_EXECUTE_CDB
1443 * or NDMP_TAPE_EXECUTE_CDB requests pointers to those names.
1445 static int
1446 dissect_execute_cdb_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1447 proto_tree *tree, uint32_t seq _U_, int devtype)
1449 /* flags */
1450 offset = dissect_execute_cdb_flags(tvb, offset, pinfo, tree);
1452 /* timeout */
1453 proto_tree_add_item(tree, hf_ndmp_execute_cdb_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
1454 offset += 4;
1456 /* datain_len */
1457 proto_tree_add_item(tree, hf_ndmp_execute_cdb_datain_len, tvb, offset, 4, ENC_BIG_ENDIAN);
1458 offset += 4;
1460 /* CDB */
1461 offset = dissect_execute_cdb_cdb(tvb, offset, pinfo, tree, devtype);
1463 /* dataout */
1464 offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
1465 "Data out", hf_ndmp_execute_cdb_dataout_len, true);
1467 return offset;
1470 static int
1471 dissect_execute_cdb_request_mc(tvbuff_t *tvb, int offset, packet_info *pinfo,
1472 proto_tree *tree, uint32_t seq)
1474 return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
1475 SCSI_DEV_SMC);
1478 static int
1479 dissect_execute_cdb_request_tape(tvbuff_t *tvb, int offset, packet_info *pinfo,
1480 proto_tree *tree, uint32_t seq)
1482 return dissect_execute_cdb_request(tvb, offset, pinfo, tree, seq,
1483 SCSI_DEV_SSC);
1486 static int
1487 dissect_execute_cdb_sns(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1489 proto_tree* tree;
1490 uint32_t sns_len;
1491 uint32_t sns_len_full;
1493 sns_len = tvb_get_ntohl(tvb, offset);
1494 sns_len_full = rpc_roundup(sns_len);
1496 tree = proto_tree_add_subtree(parent_tree, tvb, offset,
1497 4+sns_len_full, ett_ndmp_execute_cdb_sns, NULL, "Sense data");
1499 proto_tree_add_uint(tree, hf_ndmp_execute_cdb_sns_len, tvb, offset, 4,
1500 sns_len);
1501 offset += 4;
1503 if (sns_len != 0) {
1504 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1505 dissect_scsi_snsinfo(tvb, pinfo, top_tree, offset, sns_len, ndmp_conv_data->task->itlq, get_itl_nexus(pinfo, false));
1507 offset += sns_len_full;
1510 return offset;
1513 static int
1514 dissect_execute_cdb_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1515 proto_tree *tree, uint32_t seq)
1517 uint32_t status;
1519 /* error */
1520 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1522 /* status */
1523 proto_tree_add_item_ret_uint(tree, hf_ndmp_execute_cdb_status, tvb, offset, 4, ENC_BIG_ENDIAN, &status);
1524 if(ndmp_conv_data->task && ndmp_conv_data->task->itlq){
1525 dissect_scsi_rsp(tvb, pinfo, top_tree, ndmp_conv_data->task->itlq, get_itl_nexus(pinfo, false), (uint8_t)status);
1527 offset += 4;
1530 /* dataout_len */
1531 proto_tree_add_item(tree, hf_ndmp_execute_cdb_dataout_len, tvb, offset, 4, ENC_BIG_ENDIAN);
1532 offset += 4;
1534 /* datain */
1535 offset = dissect_execute_cdb_payload(tvb, offset, pinfo, tree,
1536 "Data in", hf_ndmp_execute_cdb_datain_len, false);
1538 /* ext_sense */
1539 offset = dissect_execute_cdb_sns(tvb, offset, pinfo, tree);
1541 return offset;
1544 #define NDMP_TAPE_OPEN_MODE_READ 0
1545 #define NDMP_TAPE_OPEN_MODE_RDWR 1
1546 static const value_string tape_open_mode_vals[] = {
1547 {NDMP_TAPE_OPEN_MODE_READ, "Read"},
1548 {NDMP_TAPE_OPEN_MODE_RDWR, "Read/Write"},
1549 {0, NULL}
1552 static int
1553 dissect_tape_open_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
1554 proto_tree *tree, uint32_t seq _U_)
1556 /* device */
1557 offset = dissect_rpc_string(tvb, tree,
1558 hf_ndmp_tape_device, offset, NULL);
1560 /* open mode */
1561 proto_tree_add_item(tree, hf_ndmp_tape_open_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
1562 offset += 4;
1564 if(!pinfo->fd->visited){
1565 /* new scsi device addressed, create a new itl structure */
1566 get_itl_nexus(pinfo, true);
1569 return offset;
1573 static const true_false_string tfs_ndmp_tape_invalid_file_num = {
1574 "File num is INVALID",
1575 "File num is VALID"
1577 static const true_false_string tfs_ndmp_tape_invalid_soft_errors = {
1578 "Soft errors is INVALID",
1579 "Soft errors is VALID"
1581 static const true_false_string tfs_ndmp_tape_invalid_block_size = {
1582 "Block size is INVALID",
1583 "Block size is VALID"
1585 static const true_false_string tfs_ndmp_tape_invalid_block_no = {
1586 "Block no is INVALID",
1587 "Block no is VALID"
1589 static const true_false_string tfs_ndmp_tape_invalid_total_space = {
1590 "Total space is INVALID",
1591 "Total space is VALID"
1593 static const true_false_string tfs_ndmp_tape_invalid_space_remain = {
1594 "Space remaining is INVALID",
1595 "Space remaining is VALID"
1597 static const true_false_string tfs_ndmp_tape_invalid_partition = {
1598 "Partition is INVALID",
1599 "Partition is VALID"
1601 static int
1602 dissect_tape_invalid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1603 proto_tree *parent_tree)
1605 static int * const invalid_tapes[] = {
1606 &hf_ndmp_tape_invalid_partition,
1607 &hf_ndmp_tape_invalid_space_remain,
1608 &hf_ndmp_tape_invalid_total_space,
1609 &hf_ndmp_tape_invalid_block_no,
1610 &hf_ndmp_tape_invalid_block_size,
1611 &hf_ndmp_tape_invalid_soft_errors,
1612 &hf_ndmp_tape_invalid_file_num,
1613 NULL
1616 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_tape_invalid, ett_ndmp_tape_invalid, invalid_tapes, ENC_NA);
1618 offset+=4;
1619 return offset;
1622 static const true_false_string tfs_ndmp_tape_flags_no_rewind = {
1623 "This is a NON-REWINDING device",
1624 "This device supports rewind"
1626 static const true_false_string tfs_ndmp_tape_flags_write_protect = {
1627 "This device is WRITE-PROTECTED",
1628 "This device is NOT write-protected"
1630 static const true_false_string tfs_ndmp_tape_flags_error = {
1631 "This device shows ERROR",
1632 "This device shows NO errors"
1634 static const true_false_string tfs_ndmp_tape_flags_unload = {
1635 "This device supports UNLOAD",
1636 "This device does NOT support unload"
1638 static int
1639 dissect_tape_flags(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1640 proto_tree *parent_tree)
1642 static int * const tape_flags[] = {
1643 &hf_ndmp_tape_flags_unload,
1644 &hf_ndmp_tape_flags_error,
1645 &hf_ndmp_tape_flags_write_protect,
1646 &hf_ndmp_tape_flags_no_rewind,
1647 NULL
1650 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_tape_flags, ett_ndmp_tape_flags, tape_flags, ENC_NA);
1652 offset+=4;
1653 return offset;
1656 static int
1657 dissect_tape_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1658 proto_tree *tree, uint32_t seq)
1660 /* invalid bits */
1661 offset=dissect_tape_invalid(tvb, offset, pinfo, tree);
1663 /* error */
1664 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1666 /* flags */
1667 offset=dissect_tape_flags(tvb, offset, pinfo, tree);
1669 /* file_num */
1670 proto_tree_add_item(tree, hf_ndmp_tape_file_num, tvb, offset, 4, ENC_BIG_ENDIAN);
1671 offset += 4;
1673 /* soft_errors */
1674 proto_tree_add_item(tree, hf_ndmp_tape_soft_errors, tvb, offset, 4, ENC_BIG_ENDIAN);
1675 offset += 4;
1677 /* block_size */
1678 proto_tree_add_item(tree, hf_ndmp_tape_block_size, tvb, offset, 4, ENC_BIG_ENDIAN);
1679 offset += 4;
1681 /* block_no */
1682 proto_tree_add_item(tree, hf_ndmp_tape_block_no, tvb, offset, 4, ENC_BIG_ENDIAN);
1683 offset += 4;
1685 /* total_space */
1686 offset = dissect_rpc_uint64(tvb, tree,hf_ndmp_tape_total_space,
1687 offset);
1689 /* space_remain */
1690 offset = dissect_rpc_uint64(tvb, tree,hf_ndmp_tape_space_remain,
1691 offset);
1693 /* NDMP Version 4 does not have a partition field here, so just return now. */
1694 if (get_ndmp_protocol_version() == NDMP_PROTOCOL_V4)
1695 return offset;
1697 /* partition */
1698 proto_tree_add_item(tree, hf_ndmp_tape_partition, tvb, offset, 4, ENC_BIG_ENDIAN);
1699 offset += 4;
1701 return offset;
1704 #define NDMP_TAPE_MTIO_FSF 0
1705 #define NDMP_TAPE_MTIO_BSF 1
1706 #define NDMP_TAPE_MTIO_FSR 2
1707 #define NDMP_TAPE_MTIO_BSR 3
1708 #define NDMP_TAPE_MTIO_REW 4
1709 #define NDMP_TAPE_MTIO_EOF 5
1710 #define NDMP_TAPE_MTIO_OFF 6
1711 static const value_string tape_mtio_vals[] = {
1712 {NDMP_TAPE_MTIO_FSF, "FSF"},
1713 {NDMP_TAPE_MTIO_BSF, "BSF"},
1714 {NDMP_TAPE_MTIO_FSR, "FSR"},
1715 {NDMP_TAPE_MTIO_BSR, "BSR"},
1716 {NDMP_TAPE_MTIO_REW, "REW"},
1717 {NDMP_TAPE_MTIO_EOF, "EOF"},
1718 {NDMP_TAPE_MTIO_OFF, "OFF"},
1719 {0, NULL}
1722 static int
1723 dissect_tape_mtio_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1724 proto_tree *tree, uint32_t seq _U_)
1726 /* op */
1727 proto_tree_add_item(tree, hf_ndmp_tape_mtio_op, tvb, offset, 4, ENC_BIG_ENDIAN);
1728 offset += 4;
1730 /* count */
1731 proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, ENC_BIG_ENDIAN);
1732 offset += 4;
1734 return offset;
1737 static int
1738 dissect_tape_mtio_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1739 proto_tree *tree, uint32_t seq)
1741 /* error */
1742 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1744 /* resid count */
1745 proto_tree_add_item(tree, hf_ndmp_resid_count, tvb, offset, 4, ENC_BIG_ENDIAN);
1746 offset += 4;
1748 return offset;
1751 #define NDMP_MOVER_STATE_IDLE 0
1752 #define NDMP_MOVER_STATE_LISTEN 1
1753 #define NDMP_MOVER_STATE_ACTIVE 2
1754 #define NDMP_MOVER_STATE_PAUSED 3
1755 #define NDMP_MOVER_STATE_HALTED 4
1756 static const value_string mover_state_vals[] = {
1757 {NDMP_MOVER_STATE_IDLE, "MOVER_STATE_IDLE"},
1758 {NDMP_MOVER_STATE_LISTEN, "MOVER_STATE_LISTEN"},
1759 {NDMP_MOVER_STATE_ACTIVE, "MOVER_STATE_ACTIVE"},
1760 {NDMP_MOVER_STATE_PAUSED, "MOVER_STATE_PAUSED"},
1761 {NDMP_MOVER_STATE_HALTED, "MOVER_STATE_HALTED"},
1762 {0, NULL}
1765 #define NDMP_MOVER_PAUSE_NA 0
1766 #define NDMP_MOVER_PAUSE_EOM 1
1767 #define NDMP_MOVER_PAUSE_EOF 2
1768 #define NDMP_MOVER_PAUSE_SEEK 3
1769 #define NDMP_MOVER_PAUSE_MEDIA_ERROR 4
1770 #define NDMP_MOVER_PAUSE_EOW 5
1771 static const value_string mover_pause_vals[] = {
1772 {NDMP_MOVER_PAUSE_NA, "MOVER_PAUSE_NA"},
1773 {NDMP_MOVER_PAUSE_EOM, "MOVER_PAUSE_EOM"},
1774 {NDMP_MOVER_PAUSE_EOF, "MOVER_PAUSE_EOF"},
1775 {NDMP_MOVER_PAUSE_SEEK, "MOVER_PAUSE_SEEK"},
1776 {NDMP_MOVER_PAUSE_MEDIA_ERROR, "MOVER_PAUSE_MEDIA_ERROR"},
1777 {NDMP_MOVER_PAUSE_EOW, "MOVER_PAUSE_EOW"},
1778 {0, NULL}
1781 #define NDMP_HALT_NA 0
1782 #define NDMP_HALT_CONNECT_CLOSE 1
1783 #define NDMP_HALT_ABORTED 2
1784 #define NDMP_HALT_INTERNAL_ERROR 3
1785 #define NDMP_HALT_CONNECT_ERROR 4
1786 static const value_string halt_vals[] = {
1787 {NDMP_HALT_NA, "HALT_NA"},
1788 {NDMP_HALT_CONNECT_CLOSE, "HALT_CONNECT_CLOSE"},
1789 {NDMP_HALT_ABORTED, "HALT_ABORTED"},
1790 {NDMP_HALT_INTERNAL_ERROR, "HALT_INTERNAL_ERROR"},
1791 {NDMP_HALT_CONNECT_ERROR, "HALT_CONNECT_ERROR"},
1792 {0, NULL}
1795 static int
1796 dissect_tcp_env(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1798 /* name */
1799 offset = dissect_rpc_string(tvb, tree,
1800 hf_ndmp_tcp_env_name, offset, NULL);
1802 /* value */
1803 offset = dissect_rpc_string(tvb, tree,
1804 hf_ndmp_tcp_env_value, offset, NULL);
1806 return offset;
1810 static int
1811 dissect_ndmp_v4_tcp_addr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
1813 /* IP addr */
1814 proto_tree_add_item(tree, hf_ndmp_addr_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1815 offset+=4;
1817 /* TCP port */
1818 proto_tree_add_item(tree, hf_ndmp_addr_tcp, tvb, offset, 4, ENC_BIG_ENDIAN);
1819 offset+=4;
1821 /* addr_env */
1822 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1823 dissect_tcp_env, hf_ndmp_tcp_default_env);
1825 return offset;
1828 static int
1829 dissect_ndmp_addr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1830 proto_tree *parent_tree)
1832 proto_tree* tree;
1833 uint32_t type;
1835 type=tvb_get_ntohl(tvb, offset);
1836 tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, 4, ett_ndmp_addr, NULL,
1837 "Type: %s ", val_to_str(type, addr_type_vals,"Unknown addr type (0x%02x)") );
1839 /*address type*/
1840 proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1841 offset += 4;
1844 switch(type){
1845 case NDMP_ADDR_LOCAL:
1846 break;
1847 case NDMP_ADDR_TCP:
1848 /* this became an array in version 4 and beyond */
1849 if(get_ndmp_protocol_version()<NDMP_PROTOCOL_V4){
1850 /* IP addr */
1851 proto_tree_add_item(tree, hf_ndmp_addr_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1852 offset+=4;
1854 /* TCP port */
1855 proto_tree_add_item(tree, hf_ndmp_addr_tcp, tvb, offset, 4, ENC_BIG_ENDIAN);
1856 offset+=4;
1857 } else {
1858 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
1859 dissect_ndmp_v4_tcp_addr, hf_ndmp_tcp_addr_list);
1863 break;
1864 case NDMP_ADDR_FC:
1865 /* FCAL loop id */
1866 proto_tree_add_item(tree, hf_ndmp_addr_fcal_loop_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1867 offset+=4;
1869 break;
1870 case NDMP_ADDR_IPC:
1871 /* IPC address */
1872 offset = dissect_rpc_data(tvb, tree, hf_ndmp_addr_ipc, offset);
1873 break;
1876 return offset;
1879 static int
1880 dissect_data_connect_msg(tvbuff_t *tvb, int offset, packet_info *pinfo,
1881 proto_tree *tree, uint32_t seq _U_)
1883 /* ndmp addr */
1884 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
1885 return offset;
1889 static int
1890 dissect_mover_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1891 proto_tree *tree, uint32_t seq)
1893 /* error */
1894 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1896 /* mode is only present in version 4 and beyond */
1897 if(get_ndmp_protocol_version()>=NDMP_PROTOCOL_V4){
1898 proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
1899 offset += 4;
1902 /* mover state */
1903 proto_tree_add_item(tree, hf_ndmp_mover_state, tvb, offset, 4, ENC_BIG_ENDIAN);
1904 offset += 4;
1906 /* mover pause */
1907 proto_tree_add_item(tree, hf_ndmp_mover_pause, tvb, offset, 4, ENC_BIG_ENDIAN);
1908 offset += 4;
1910 /* halt */
1911 proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, ENC_BIG_ENDIAN);
1912 offset += 4;
1914 /* record size */
1915 proto_tree_add_item(tree, hf_ndmp_record_size, tvb, offset, 4, ENC_BIG_ENDIAN);
1916 offset += 4;
1918 /* record num */
1919 proto_tree_add_item(tree, hf_ndmp_record_num, tvb, offset, 4, ENC_BIG_ENDIAN);
1920 offset += 4;
1922 /* data written */
1923 proto_tree_add_item(tree, hf_ndmp_data_written, tvb, offset, 8, ENC_BIG_ENDIAN);
1924 offset += 8;
1926 /* seek position */
1927 proto_tree_add_item(tree, hf_ndmp_seek_position, tvb, offset, 8, ENC_BIG_ENDIAN);
1928 offset += 8;
1930 /* bytes left to read */
1931 proto_tree_add_item(tree, hf_ndmp_bytes_left_to_read, tvb, offset, 8, ENC_BIG_ENDIAN);
1932 offset += 8;
1934 /* window offset */
1935 proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
1936 offset += 8;
1938 /* window length */
1939 proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, ENC_BIG_ENDIAN);
1940 offset += 8;
1942 /* this is where v2 ends */
1943 if(get_ndmp_protocol_version()==NDMP_PROTOCOL_V2){
1944 return offset;
1948 /* ndmp addr */
1949 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
1951 return offset;
1954 #define NDMP_MOVER_MODE_READ 0
1955 #define NDMP_MOVER_MODE_WRITE 1
1956 #define NDMP_MOVER_MODE_NOACTION 2
1957 static const value_string mover_mode_vals[] = {
1958 {NDMP_MOVER_MODE_READ, "MOVER_MODE_READ"},
1959 {NDMP_MOVER_MODE_WRITE, "MOVER_MODE_WRITE"},
1960 {NDMP_MOVER_MODE_NOACTION, "MOVER_MODE_NOACTION"},
1961 {0, NULL}
1964 static int
1965 dissect_mover_listen_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1966 proto_tree *tree, uint32_t seq _U_)
1968 /* mode */
1969 proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
1970 offset += 4;
1972 /*address type*/
1973 proto_tree_add_item(tree, hf_ndmp_addr_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1974 offset += 4;
1976 return offset;
1979 static int
1980 dissect_mover_listen_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
1981 proto_tree *tree, uint32_t seq)
1983 /* error */
1984 offset=dissect_error(tvb, offset, pinfo, tree, seq);
1986 /* ndmp addr */
1987 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
1989 return offset;
1992 static int
1993 dissect_mover_set_window_request(tvbuff_t *tvb, int offset,
1994 packet_info *pinfo _U_, proto_tree *tree, uint32_t seq _U_)
1996 /* window offset */
1997 proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
1998 offset += 8;
2000 /* window length */
2001 proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, ENC_BIG_ENDIAN);
2002 offset += 8;
2004 return offset;
2007 static int
2008 dissect_mover_set_record_size_request(tvbuff_t *tvb, int offset,
2009 packet_info *pinfo _U_, proto_tree *tree, uint32_t seq _U_)
2011 /* record size */
2012 proto_tree_add_item(tree, hf_ndmp_record_size, tvb, offset, 4, ENC_BIG_ENDIAN);
2013 offset += 4;
2015 return offset;
2018 static int
2019 dissect_mover_connect_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2020 proto_tree *tree, uint32_t seq _U_)
2022 /* mode */
2023 proto_tree_add_item(tree, hf_ndmp_mover_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
2024 offset += 4;
2026 /* ndmp addr */
2027 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2029 return offset;
2032 static int
2033 dissect_log_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2034 proto_tree *tree, uint32_t seq)
2036 /* file */
2037 offset = dissect_rpc_string(tvb, tree,
2038 hf_ndmp_file_name, offset, NULL);
2040 /* error */
2041 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2043 return offset;
2046 #define NDMP_LOG_TYPE_NORMAL 0
2047 #define NDMP_LOG_TYPE_DEBUG 1
2048 #define NDMP_LOG_TYPE_ERROR 2
2049 #define NDMP_LOG_TYPE_WARNING 3
2050 static const value_string log_type_vals[] = {
2051 {NDMP_LOG_TYPE_NORMAL, "NORMAL"},
2052 {NDMP_LOG_TYPE_DEBUG, "DEBUG"},
2053 {NDMP_LOG_TYPE_ERROR, "ERROR"},
2054 {NDMP_LOG_TYPE_WARNING, "WARNING"},
2055 {0, NULL}
2058 static int
2059 dissect_log_message_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2060 proto_tree *tree, uint32_t seq _U_)
2062 /* type */
2063 proto_tree_add_item(tree, hf_ndmp_log_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2064 offset += 4;
2066 /* message id */
2067 proto_tree_add_item(tree, hf_ndmp_log_message_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2068 offset += 4;
2070 /* message */
2071 offset = dissect_rpc_string(tvb, tree,
2072 hf_ndmp_log_message, offset, NULL);
2074 return offset;
2077 static int
2078 dissect_notify_data_halted_request(tvbuff_t *tvb, int offset,
2079 packet_info *pinfo _U_, proto_tree *tree, uint32_t seq _U_)
2081 /* halt */
2082 proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, ENC_BIG_ENDIAN);
2083 offset += 4;
2085 switch(get_ndmp_protocol_version()){
2086 case NDMP_PROTOCOL_V2:
2087 case NDMP_PROTOCOL_V3:
2088 /* reason : only in version 2, 3 */
2089 offset = dissect_rpc_string(tvb, tree,
2090 hf_ndmp_halt_reason, offset, NULL);
2091 break;
2094 return offset;
2097 static int
2098 dissect_notify_mover_halted_request(tvbuff_t *tvb, int offset,
2099 packet_info *pinfo _U_, proto_tree *tree, uint32_t seq _U_)
2101 /* halt */
2102 proto_tree_add_item(tree, hf_ndmp_halt, tvb, offset, 4, ENC_BIG_ENDIAN);
2103 offset += 4;
2105 switch(get_ndmp_protocol_version()){
2106 case NDMP_PROTOCOL_V2:
2107 case NDMP_PROTOCOL_V3:
2108 /* reason : only in version 2, 3 */
2109 offset = dissect_rpc_string(tvb, tree,
2110 hf_ndmp_halt_reason, offset, NULL);
2111 break;
2114 return offset;
2117 #define NDMP_CONNECTED_CONNECTED 0
2118 #define NDMP_CONNECTED_SHUTDOWN 1
2119 #define NDMP_CONNECTED_REFUSED 2
2120 static const value_string connected_vals[] = {
2121 {NDMP_CONNECTED_CONNECTED, "CONNECTED"},
2122 {NDMP_CONNECTED_SHUTDOWN, "SHUTDOWN"},
2123 {NDMP_CONNECTED_REFUSED, "REFUSED"},
2124 {0, NULL}
2127 static int
2128 dissect_notify_connected_request(tvbuff_t *tvb, int offset,
2129 packet_info *pinfo _U_, proto_tree *tree, uint32_t seq _U_)
2131 /* connected */
2132 proto_tree_add_item(tree, hf_ndmp_connected, tvb, offset, 4, ENC_BIG_ENDIAN);
2133 offset += 4;
2135 /* version number */
2136 proto_tree_add_item(tree, hf_ndmp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
2137 offset += 4;
2139 /* reason */
2140 offset = dissect_rpc_string(tvb, tree,
2141 hf_ndmp_connected_reason, offset, NULL);
2143 return offset;
2147 static int
2148 dissect_notify_mover_paused_request(tvbuff_t *tvb, int offset,
2149 packet_info *pinfo _U_, proto_tree *tree, uint32_t seq _U_)
2151 /* mover pause */
2152 proto_tree_add_item(tree, hf_ndmp_mover_pause, tvb, offset, 4, ENC_BIG_ENDIAN);
2153 offset += 4;
2155 /* seek position */
2156 proto_tree_add_item(tree, hf_ndmp_seek_position, tvb, offset, 8, ENC_BIG_ENDIAN);
2157 offset += 8;
2159 return offset;
2162 static int
2163 dissect_auth_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2164 proto_tree *tree)
2166 unsigned type;
2168 type=tvb_get_ntohl(tvb,offset);
2170 /* auth type */
2171 proto_tree_add_item(tree, hf_ndmp_auth_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2172 offset += 4;
2174 switch(type){
2175 case NDMP_AUTH_NONE:
2176 break;
2177 case NDMP_AUTH_TEXT:
2178 /* auth id */
2179 offset = dissect_rpc_string(tvb, tree,
2180 hf_ndmp_auth_id, offset, NULL);
2182 /* auth password */
2183 offset = dissect_rpc_string(tvb, tree,
2184 hf_ndmp_auth_password, offset, NULL);
2187 break;
2188 case NDMP_AUTH_MD5:
2189 /* auth id */
2190 offset = dissect_rpc_string(tvb, tree,
2191 hf_ndmp_auth_id, offset, NULL);
2193 /* digest */
2194 proto_tree_add_item(tree, hf_ndmp_auth_digest,
2195 tvb, offset, 16, ENC_NA);
2196 offset+=16;
2199 return offset;
2202 static int
2203 dissect_connect_client_auth_request(tvbuff_t *tvb, int offset,
2204 packet_info *pinfo, proto_tree *tree, uint32_t seq _U_)
2206 return dissect_auth_data(tvb, offset, pinfo, tree);
2209 static int
2210 dissect_connect_server_auth_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2211 proto_tree *tree, uint32_t seq)
2213 /* error */
2214 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2216 /* auth data */
2217 offset = dissect_auth_data(tvb, offset, pinfo, tree);
2219 return offset;
2222 static int
2223 dissect_tape_write_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2224 proto_tree *tree, uint32_t seq _U_)
2226 /* data */
2227 offset = dissect_rpc_data(tvb, tree, hf_ndmp_data, offset);
2229 return offset;
2232 static int
2233 dissect_tape_write_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2234 proto_tree *tree, uint32_t seq)
2236 /* error */
2237 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2239 /* count */
2240 proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2241 offset += 4;
2243 return offset;
2246 static int
2247 dissect_tape_read_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2248 proto_tree *tree, uint32_t seq _U_)
2250 /* count */
2251 proto_tree_add_item(tree, hf_ndmp_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2252 offset += 4;
2254 return offset;
2257 static int
2258 dissect_tape_read_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2259 proto_tree *tree, uint32_t seq)
2261 /* error */
2262 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2264 /* data */
2265 offset = dissect_rpc_data(tvb, tree, hf_ndmp_data, offset);
2267 return offset;
2270 #define NDMP_FS_UNIX 0
2271 #define NDMP_FS_NT 1
2272 #define NDMP_FS_OTHER 2
2273 static const value_string file_fs_type_vals[] = {
2274 {NDMP_FS_UNIX, "UNIX"},
2275 {NDMP_FS_NT, "NT"},
2276 {NDMP_FS_OTHER, "OTHER"},
2277 {0, NULL}
2280 static int
2281 dissect_file_name(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2283 proto_item* item;
2284 proto_tree* tree;
2285 int old_offset=offset;
2286 uint32_t type;
2287 const char *name;
2289 tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1,
2290 ett_ndmp_file_name, &item, "File");
2292 /* file type */
2293 type=tvb_get_ntohl(tvb, offset);
2294 proto_tree_add_item(tree, hf_ndmp_file_fs_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2295 offset += 4;
2297 switch(type){
2298 case NDMP_FS_UNIX:
2299 /* file */
2300 offset = dissect_rpc_string(tvb, tree,
2301 hf_ndmp_file_name, offset, &name);
2302 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
2303 break;
2304 case NDMP_FS_NT:
2305 /* nt file */
2306 offset = dissect_rpc_string(tvb, tree,
2307 hf_ndmp_nt_file_name, offset, &name);
2308 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
2310 /* dos file */
2311 offset = dissect_rpc_string(tvb, tree,
2312 hf_ndmp_dos_file_name, offset, NULL);
2313 break;
2314 default:
2315 /* file */
2316 offset = dissect_rpc_string(tvb, tree,
2317 hf_ndmp_file_name, offset, &name);
2318 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
2321 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
2322 val_to_str_const(type, file_fs_type_vals, "Unknown type") );
2324 proto_item_set_len(item, offset-old_offset);
2325 return offset;
2329 static const true_false_string tfs_ndmp_file_invalid_atime = {
2330 "Atime is INVALID",
2331 "Atime is valid"
2333 static const true_false_string tfs_ndmp_file_invalid_ctime = {
2334 "Ctime is INVALID",
2335 "Ctime is valid"
2337 static const true_false_string tfs_ndmp_file_invalid_group = {
2338 "Group is INVALID",
2339 "Group is valid"
2341 static int
2342 dissect_file_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2343 proto_tree *parent_tree)
2345 static int * const invalid_files[] = {
2346 &hf_ndmp_file_invalid_group,
2347 &hf_ndmp_file_invalid_ctime,
2348 &hf_ndmp_file_invalid_atime,
2349 NULL
2352 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_file_invalid, ett_ndmp_file_invalids, invalid_files, ENC_NA);
2354 offset+=4;
2355 return offset;
2358 #define NDMP_FILE_TYPE_DIR 0
2359 #define NDMP_FILE_TYPE_FIFO 1
2360 #define NDMP_FILE_TYPE_CSPEC 2
2361 #define NDMP_FILE_TYPE_BSPEC 3
2362 #define NDMP_FILE_TYPE_REG 4
2363 #define NDMP_FILE_TYPE_SLINK 5
2364 #define NDMP_FILE_TYPE_SOCK 6
2365 #define NDMP_FILE_TYPE_REGISTRY 7
2366 #define NDMP_FILE_TYPE_OTHER 8
2367 static const value_string file_type_vals[] = {
2368 {NDMP_FILE_TYPE_DIR, "DIR"},
2369 {NDMP_FILE_TYPE_FIFO, "FIFO"},
2370 {NDMP_FILE_TYPE_CSPEC, "CSPEC"},
2371 {NDMP_FILE_TYPE_BSPEC, "BSPEC"},
2372 {NDMP_FILE_TYPE_REG, "REG"},
2373 {NDMP_FILE_TYPE_SLINK, "SLINK"},
2374 {NDMP_FILE_TYPE_SOCK, "SOCK"},
2375 {NDMP_FILE_TYPE_REGISTRY, "REGISTRY"},
2376 {NDMP_FILE_TYPE_OTHER, "OTHER"},
2377 {0, NULL}
2380 static int
2381 dissect_file_stats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2383 proto_item* item;
2384 proto_tree* tree;
2385 int old_offset=offset;
2387 tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1,
2388 ett_ndmp_file_stats, &item, "Stats:");
2390 /* invalids */
2391 offset = dissect_file_invalids(tvb, offset, pinfo, tree);
2393 /* file fs type */
2394 proto_tree_add_item(tree, hf_ndmp_file_fs_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2395 offset += 4;
2397 /* file type */
2398 proto_tree_add_item(tree, hf_ndmp_file_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2399 offset += 4;
2401 /* mtime */
2402 proto_tree_add_item(tree, hf_ndmp_file_mtime, tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
2403 offset += 4;
2405 /* atime */
2406 proto_tree_add_item(tree, hf_ndmp_file_atime, tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
2407 offset += 4;
2409 /* ctime */
2410 proto_tree_add_item(tree, hf_ndmp_file_ctime, tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
2411 offset += 4;
2413 /* owner */
2414 proto_tree_add_item(tree, hf_ndmp_file_owner, tvb, offset, 4, ENC_BIG_ENDIAN);
2415 offset += 4;
2417 /* group */
2418 proto_tree_add_item(tree, hf_ndmp_file_group, tvb, offset, 4, ENC_BIG_ENDIAN);
2419 offset += 4;
2421 /*XXX here we should do proper dissection of mode for unix or
2422 fattr for nt, call appropriate functions in nfs/smb*/
2423 /* fattr */
2424 proto_tree_add_item(tree, hf_ndmp_file_fattr, tvb, offset, 4, ENC_BIG_ENDIAN);
2425 offset += 4;
2427 /*file size*/
2428 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_file_size,
2429 offset);
2431 /* links */
2432 proto_tree_add_item(tree, hf_ndmp_file_links, tvb, offset, 4, ENC_BIG_ENDIAN);
2433 offset += 4;
2435 proto_item_set_len(item, offset-old_offset);
2436 return offset;
2440 static int
2441 dissect_ndmp_file(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2443 proto_item* item;
2444 proto_tree* tree;
2445 int old_offset=offset;
2447 tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1,
2448 ett_ndmp_file, &item, "File:");
2450 /* file names */
2451 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2452 dissect_file_name, hf_ndmp_file_names);
2454 /* file stats */
2455 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2456 dissect_file_stats, hf_ndmp_file_stats);
2458 /* node */
2459 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2460 offset += 8;
2462 /* fh_info */
2463 proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, ENC_BIG_ENDIAN);
2464 offset += 8;
2466 proto_item_set_len(item, offset-old_offset);
2467 return offset;
2470 static int
2471 dissect_fh_add_file_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2472 proto_tree *tree, uint32_t seq _U_)
2474 /* files */
2475 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2476 dissect_ndmp_file, hf_ndmp_files);
2478 return offset;
2481 static int
2482 dissect_dir(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
2484 /* file names */
2485 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2486 dissect_file_name, hf_ndmp_file_names);
2488 /* node */
2489 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2490 offset += 8;
2492 /* parent */
2493 proto_tree_add_item(tree, hf_ndmp_file_parent, tvb, offset, 8, ENC_BIG_ENDIAN);
2494 offset += 8;
2496 return offset;
2499 static int
2500 dissect_fh_add_dir_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2501 proto_tree *tree, uint32_t seq _U_)
2503 /* dirs */
2504 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2505 dissect_dir, hf_ndmp_dirs);
2507 return offset;
2510 static int
2511 dissect_node(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
2513 /* file stats */
2514 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2515 dissect_file_stats, hf_ndmp_file_stats);
2517 /* node */
2518 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2519 offset += 8;
2521 /* fh_info */
2522 proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, ENC_BIG_ENDIAN);
2523 offset += 8;
2525 return offset;
2529 static int
2530 dissect_fh_add_node_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2531 proto_tree *tree, uint32_t seq _U_)
2533 /* node */
2534 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2535 dissect_node, hf_ndmp_nodes);
2537 return offset;
2540 static int
2541 dissect_data_start_backup_request(tvbuff_t *tvb, int offset, packet_info *pinfo,
2542 proto_tree *tree, uint32_t seq _U_)
2544 /*butype name*/
2545 offset = dissect_rpc_string(tvb, tree,
2546 hf_ndmp_butype_name, offset, NULL);
2548 /* default env */
2549 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2550 dissect_default_env, hf_ndmp_butype_default_env);
2552 return offset;
2555 static int
2556 dissect_nlist(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2557 proto_tree *tree, void* data _U_)
2559 /*original path*/
2560 offset = dissect_rpc_string(tvb, tree,
2561 hf_ndmp_bu_original_path, offset, NULL);
2563 /*destination dir*/
2564 offset = dissect_rpc_string(tvb, tree,
2565 hf_ndmp_bu_destination_dir, offset, NULL);
2567 if(get_ndmp_protocol_version()==NDMP_PROTOCOL_V2){
2568 /* just 2 reserved bytes (4 with padding) */
2569 offset += 4;
2570 } else {
2571 /*new name*/
2572 offset = dissect_rpc_string(tvb, tree,
2573 hf_ndmp_bu_new_name, offset, NULL);
2575 /*other name*/
2576 offset = dissect_rpc_string(tvb, tree,
2577 hf_ndmp_bu_other_name, offset, NULL);
2579 /* node */
2580 proto_tree_add_item(tree, hf_ndmp_file_node, tvb, offset, 8, ENC_BIG_ENDIAN);
2581 offset += 8;
2584 /* fh_info */
2585 proto_tree_add_item(tree, hf_ndmp_file_fh_info, tvb, offset, 8, ENC_BIG_ENDIAN);
2586 offset += 8;
2588 return offset;
2592 static int
2593 dissect_data_start_recover_request(tvbuff_t *tvb, int offset,
2594 packet_info *pinfo, proto_tree *tree, uint32_t seq _U_)
2596 if(get_ndmp_protocol_version()==NDMP_PROTOCOL_V2){
2597 /* ndmp addr */
2598 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2601 /* default env */
2602 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2603 dissect_default_env, hf_ndmp_butype_default_env);
2605 /* nlist */
2606 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2607 dissect_nlist, hf_ndmp_nlist);
2609 /*butype name*/
2610 offset = dissect_rpc_string(tvb, tree,
2611 hf_ndmp_butype_name, offset, NULL);
2613 return offset;
2616 static int
2617 dissect_data_get_env_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2618 proto_tree *tree, uint32_t seq)
2620 /* error */
2621 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2623 /* default env */
2624 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
2625 dissect_default_env, hf_ndmp_butype_default_env);
2627 return offset;
2631 static const true_false_string tfs_ndmp_state_invalid_ebr = {
2632 "Estimated Bytes Remaining is INVALID",
2633 "Estimated Bytes Remaining is valid"
2635 static const true_false_string tfs_ndmp_state_invalid_etr = {
2636 "Estimated Time Remaining is INVALID",
2637 "Estimated Time Remaining is valid"
2639 static int
2640 dissect_state_invalids(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2641 proto_tree *parent_tree)
2643 static int * const invalid_states[] = {
2644 &hf_ndmp_state_invalid_etr,
2645 &hf_ndmp_state_invalid_ebr,
2646 NULL
2649 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_ndmp_state_invalid, ett_ndmp_state_invalids, invalid_states, ENC_NA);
2651 offset+=4;
2652 return offset;
2655 #define NDMP_DATA_OP_NOACTION 0
2656 #define NDMP_DATA_OP_BACKUP 1
2657 #define NDMP_DATA_OP_RESTORE 2
2658 static const value_string bu_operation_vals[] = {
2659 {NDMP_DATA_OP_NOACTION, "NOACTION"},
2660 {NDMP_DATA_OP_BACKUP, "BACKUP"},
2661 {NDMP_DATA_OP_RESTORE, "RESTORE"},
2662 {0, NULL}
2665 #define NDMP_DATA_STATE_IDLE 0
2666 #define NDMP_DATA_STATE_ACTIVE 1
2667 #define NDMP_DATA_STATE_HALTED 2
2668 #define NDMP_DATA_STATE_LISTEN 3
2669 #define NDMP_DATA_STATE_CONNECTED 4
2670 static const value_string data_state_vals[] = {
2671 {NDMP_DATA_STATE_IDLE, "IDLE"},
2672 {NDMP_DATA_STATE_ACTIVE, "ACTIVE"},
2673 {NDMP_DATA_STATE_HALTED, "HALTED"},
2674 {NDMP_DATA_STATE_LISTEN, "LISTEN"},
2675 {NDMP_DATA_STATE_CONNECTED, "CONNECTED"},
2676 {0, NULL}
2679 #define NDMP_DATA_HALTED_NA 0
2680 #define NDMP_DATA_HALTED_SUCCESSFUL 1
2681 #define NDMP_DATA_HALTED_ABORTED 2
2682 #define NDMP_DATA_HALTED_INTERNAL_ERROR 3
2683 #define NDMP_DATA_HALTED_CONNECT_ERROR 4
2684 static const value_string data_halted_vals[] = {
2685 {NDMP_DATA_HALTED_NA, "HALTED_NA"},
2686 {NDMP_DATA_HALTED_SUCCESSFUL, "HALTED_SUCCESSFUL"},
2687 {NDMP_DATA_HALTED_ABORTED, "HALTED_ABORTED"},
2688 {NDMP_DATA_HALTED_INTERNAL_ERROR, "HALTED_INTERNAL_ERROR"},
2689 {NDMP_DATA_HALTED_CONNECT_ERROR, "HALTED_CONNECT_ERROR"},
2690 {0, NULL}
2693 static int
2694 dissect_data_get_state_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
2695 proto_tree *tree, uint32_t seq)
2697 /* invalids */
2698 offset = dissect_state_invalids(tvb, offset, pinfo, tree);
2700 /* error */
2701 offset=dissect_error(tvb, offset, pinfo, tree, seq);
2703 /* operation */
2704 proto_tree_add_item(tree, hf_ndmp_bu_operation, tvb, offset, 4, ENC_BIG_ENDIAN);
2705 offset += 4;
2707 /* state */
2708 proto_tree_add_item(tree, hf_ndmp_data_state, tvb, offset, 4, ENC_BIG_ENDIAN);
2709 offset += 4;
2711 /* halted reason */
2712 proto_tree_add_item(tree, hf_ndmp_data_halted, tvb, offset, 4, ENC_BIG_ENDIAN);
2713 offset += 4;
2715 /*bytes processed*/
2716 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_data_bytes_processed,
2717 offset);
2719 /*est bytes remain*/
2720 offset = dissect_rpc_uint64(tvb, tree, hf_ndmp_data_est_bytes_remain,
2721 offset);
2723 /* est time remain */
2724 proto_tree_add_item(tree, hf_ndmp_data_est_time_remain, tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
2725 offset += 4;
2727 /* ndmp addr */
2728 offset=dissect_ndmp_addr(tvb, offset, pinfo, tree);
2730 /* window offset */
2731 proto_tree_add_item(tree, hf_ndmp_window_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
2732 offset += 8;
2734 /* window length */
2735 proto_tree_add_item(tree, hf_ndmp_window_length, tvb, offset, 8, ENC_BIG_ENDIAN);
2736 offset += 8;
2738 return offset;
2741 typedef struct _ndmp_command {
2742 uint32_t cmd;
2743 int (*request) (tvbuff_t *tvb, int offset, packet_info *pinfo,
2744 proto_tree *tree, uint32_t seq);
2745 int (*response)(tvbuff_t *tvb, int offset, packet_info *pinfo,
2746 proto_tree *tree, uint32_t seq);
2747 } ndmp_command;
2749 static const ndmp_command ndmp_commands[] = {
2750 {NDMP_CONFIG_GET_HOST_INFO,
2751 NULL, dissect_ndmp_get_host_info_reply},
2752 {NDMP_CONFIG_GET_CONNECTION_TYPE,
2753 NULL, dissect_ndmp_config_get_connection_type_reply},
2754 {NDMP_CONFIG_GET_AUTH_ATTR,
2755 dissect_get_auth_type_request, dissect_ndmp_config_get_auth_attr_reply},
2756 {NDMP_CONFIG_GET_BUTYPE_INFO,
2757 NULL, dissect_get_butype_info_reply},
2758 {NDMP_CONFIG_GET_FS_INFO,
2759 NULL, dissect_get_fs_info_reply},
2760 {NDMP_CONFIG_GET_TAPE_INFO,
2761 NULL, dissect_get_tape_info_reply},
2762 {NDMP_CONFIG_GET_SCSI_INFO,
2763 NULL, dissect_get_scsi_info_reply},
2764 {NDMP_CONFIG_GET_SERVER_INFO,
2765 NULL, dissect_get_server_info_reply},
2766 {NDMP_CONFIG_GET_EXT_LIST,
2767 NULL, dissect_get_ext_list_reply},
2768 {NDMP_CONFIG_SET_EXT_LIST,
2769 dissect_set_ext_list_request, dissect_set_ext_list_reply},
2770 {NDMP_SCSI_OPEN,
2771 dissect_scsi_open_request, dissect_error},
2772 {NDMP_SCSI_CLOSE,
2773 NULL, dissect_error},
2774 {NDMP_SCSI_GET_STATE,
2775 NULL, dissect_scsi_get_state_reply},
2776 {NDMP_SCSI_SET_TARGET,
2777 dissect_scsi_set_state_request, dissect_error},
2778 {NDMP_SCSI_RESET_DEVICE,
2779 NULL, dissect_error},
2780 {NDMP_SCSI_RESET_BUS,
2781 NULL, dissect_error},
2782 {NDMP_SCSI_EXECUTE_CDB,
2783 dissect_execute_cdb_request_mc, dissect_execute_cdb_reply},
2784 {NDMP_TAPE_OPEN,
2785 dissect_tape_open_request, dissect_error},
2786 {NDMP_TAPE_CLOSE,
2787 NULL, dissect_error},
2788 {NDMP_TAPE_GET_STATE,
2789 NULL, dissect_tape_get_state_reply},
2790 {NDMP_TAPE_MTIO,
2791 dissect_tape_mtio_request, dissect_tape_mtio_reply},
2792 {NDMP_TAPE_WRITE,
2793 dissect_tape_write_request, dissect_tape_write_reply},
2794 {NDMP_TAPE_READ,
2795 dissect_tape_read_request, dissect_tape_read_reply},
2796 {NDMP_TAPE_EXECUTE_CDB,
2797 dissect_execute_cdb_request_tape, dissect_execute_cdb_reply},
2798 {NDMP_DATA_GET_STATE,
2799 NULL, dissect_data_get_state_reply},
2800 {NDMP_DATA_START_BACKUP,
2801 dissect_data_start_backup_request, dissect_error },
2802 {NDMP_DATA_START_RECOVER,
2803 dissect_data_start_recover_request, dissect_error },
2804 {NDMP_DATA_ABORT,
2805 NULL, dissect_error},
2806 {NDMP_DATA_GET_ENV,
2807 NULL, dissect_data_get_env_reply},
2808 {NDMP_DATA_STOP,
2809 NULL, dissect_error},
2810 {NDMP_DATA_LISTEN,
2811 dissect_ndmp_addr_msg, dissect_mover_listen_reply},
2812 {NDMP_DATA_CONNECT,
2813 dissect_data_connect_msg, dissect_error},
2814 {NDMP_NOTIFY_DATA_HALTED,
2815 dissect_notify_data_halted_request, NULL},
2816 {NDMP_NOTIFY_CONNECTED,
2817 dissect_notify_connected_request, NULL},
2818 {NDMP_NOTIFY_MOVER_HALTED,
2819 dissect_notify_mover_halted_request, NULL},
2820 {NDMP_NOTIFY_MOVER_PAUSED,
2821 dissect_notify_mover_paused_request, NULL},
2822 {NDMP_NOTIFY_DATA_READ,
2823 dissect_mover_set_window_request, NULL},
2824 {NDMP_LOG_FILE,
2825 dissect_log_file_request, NULL},
2826 {NDMP_LOG_MESSAGE,
2827 dissect_log_message_request, NULL},
2828 {NDMP_FH_ADD_FILE,
2829 dissect_fh_add_file_request, NULL},
2830 {NDMP_FH_ADD_DIR,
2831 dissect_fh_add_dir_request, NULL},
2832 {NDMP_FH_ADD_NODE,
2833 dissect_fh_add_node_request, NULL},
2834 {NDMP_CONNECT_OPEN,
2835 dissect_connect_open_request, dissect_error},
2836 {NDMP_CONNECT_CLIENT_AUTH,
2837 dissect_connect_client_auth_request, dissect_error},
2838 {NDMP_CONNECT_CLOSE,
2839 NULL,NULL},
2840 {NDMP_CONNECT_SERVER_AUTH,
2841 dissect_auth_attr_msg, dissect_connect_server_auth_reply},
2842 {NDMP_MOVER_GET_STATE,
2843 NULL, dissect_mover_get_state_reply},
2844 {NDMP_MOVER_LISTEN,
2845 dissect_mover_listen_request, dissect_mover_listen_reply},
2846 {NDMP_MOVER_CONTINUE,
2847 NULL, dissect_error},
2848 {NDMP_MOVER_ABORT,
2849 NULL, dissect_error},
2850 {NDMP_MOVER_STOP,
2851 NULL, dissect_error},
2852 {NDMP_MOVER_SET_WINDOW,
2853 dissect_mover_set_window_request, dissect_error},
2854 {NDMP_MOVER_READ,
2855 dissect_mover_set_window_request, dissect_error},
2856 {NDMP_MOVER_CLOSE,
2857 NULL, dissect_error},
2858 {NDMP_MOVER_SET_RECORD_SIZE,
2859 dissect_mover_set_record_size_request, dissect_error},
2860 {NDMP_MOVER_CONNECT,
2861 dissect_mover_connect_request, dissect_error},
2862 {0, NULL,NULL}
2866 static int
2867 dissect_ndmp_header(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, struct ndmp_header *nh, proto_item** msg_item)
2869 proto_item* item;
2870 proto_tree* tree;
2871 nstime_t ns;
2873 item = proto_tree_add_item(parent_tree, hf_ndmp_header, tvb,
2874 offset, 24, ENC_NA);
2875 tree = proto_item_add_subtree(item, ett_ndmp_header);
2877 /* sequence number */
2878 proto_tree_add_uint(tree, hf_ndmp_sequence, tvb, offset, 4, nh->seq);
2879 offset += 4;
2881 /* timestamp */
2882 ns.secs=nh->timestamp;
2883 ns.nsecs=0;
2884 proto_tree_add_time(tree, hf_ndmp_timestamp, tvb, offset, 4, &ns);
2885 offset += 4;
2887 /* Message Type */
2888 proto_tree_add_uint(tree, hf_ndmp_msgtype, tvb, offset, 4, nh->type);
2889 offset += 4;
2891 /* Message */
2892 *msg_item = proto_tree_add_uint(tree, hf_ndmp_msg, tvb, offset, 4, nh->msg);
2893 offset += 4;
2895 /* Reply sequence number */
2896 proto_tree_add_uint(tree, hf_ndmp_reply_sequence, tvb, offset, 4, nh->rep_seq);
2897 offset += 4;
2899 /* error */
2900 offset=dissect_error(tvb, offset, pinfo, tree, nh->seq);
2902 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s ",
2903 val_to_str(nh->msg, msg_vals, "Unknown Message (0x%02x)"),
2904 val_to_str(nh->type, msg_type_vals, "Unknown Type (0x%02x)")
2907 return offset;
2911 static int
2912 dissect_ndmp_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, struct ndmp_header *nh)
2914 int i;
2915 proto_tree *cmd_tree=NULL;
2916 proto_item *msg_item=NULL;
2918 offset=dissect_ndmp_header(tvb, offset, pinfo, tree, nh, &msg_item);
2920 for(i=0;ndmp_commands[i].cmd!=0;i++){
2921 if(ndmp_commands[i].cmd==nh->msg){
2922 break;
2927 if(ndmp_commands[i].cmd==0){
2928 /* we do not know this message */
2929 expert_add_info(pinfo, msg_item, &ei_ndmp_msg);
2930 offset+=tvb_captured_length_remaining(tvb, offset);
2931 return offset;
2934 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2935 if(tree){
2936 cmd_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_ndmp, NULL, msg_vals[i].strptr);
2940 if(nh->type==NDMP_MESSAGE_REQUEST){
2941 if(ndmp_commands[i].request){
2942 offset=ndmp_commands[i].request(tvb, offset, pinfo, cmd_tree,
2943 nh->seq);
2945 } else {
2946 if(ndmp_commands[i].response){
2947 offset=ndmp_commands[i].response(tvb, offset, pinfo, cmd_tree,
2948 nh->rep_seq);
2952 return offset;
2955 static int
2956 dissect_ndmp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2958 int offset = 0;
2959 uint32_t ndmp_rm;
2960 struct ndmp_header nh;
2961 uint32_t size;
2962 uint32_t seq, len, nxt, frag_num;
2963 int direction;
2964 struct tcpinfo *tcpinfo;
2965 ndmp_frag_info* nfi;
2966 proto_item *ndmp_item = NULL;
2967 proto_tree *ndmp_tree = NULL;
2968 proto_tree *hdr_tree;
2969 wmem_map_t *frags;
2970 conversation_t *conversation;
2971 proto_item *vers_item;
2972 bool save_fragmented, save_info_writable, save_proto_writable;
2973 bool do_frag = true;
2974 tvbuff_t* new_tvb = NULL;
2975 fragment_head *frag_msg = NULL;
2977 /* Reject the packet if data is NULL under conditions where it'll be used */
2978 if (data == NULL && ndmp_defragment && ndmp_desegment)
2979 return 0;
2981 top_tree=tree; /* scsi should open its expansions on the top level */
2984 * We need to keep track of conversations so that we can track NDMP
2985 * versions.
2987 conversation = find_or_create_conversation(pinfo);
2989 ndmp_conv_data=(ndmp_conv_data_t *)conversation_get_proto_data(conversation, proto_ndmp);
2990 if(!ndmp_conv_data){
2991 ndmp_conv_data=wmem_new(wmem_file_scope(), ndmp_conv_data_t);
2992 ndmp_conv_data->version = NDMP_PROTOCOL_UNKNOWN;
2993 ndmp_conv_data->tasks = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
2994 ndmp_conv_data->itl = wmem_tree_new(wmem_file_scope());
2995 ndmp_conv_data->conversation = conversation;
2996 ndmp_conv_data->fragsA = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
2997 ndmp_conv_data->fragsB = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
2999 conversation_add_proto_data(conversation, proto_ndmp, ndmp_conv_data);
3001 /* Ensure that any & all frames/fragments belonging to this conversation */
3002 /* are dissected as NDMP even if another dissector (eg: IPSEC-TCP) might */
3003 /* decide to dissect an NDMP fragment. This works because the TCP */
3004 /* dissector dispatches to a conversation associated dissector before */
3005 /* dispatching by port or by heuristic. Associating NDMP with this */
3006 /* conversation is necessary because otherwise the IPSEC-TCP(TCPENCAP) */
3007 /* dissector may think NDMP fragments are really TCPENCAP since that */
3008 /* dissector also registers on TCP Port 10000. (See packet-ipsec-tcp.c). */
3009 conversation_set_dissector(conversation, ndmp_handle);
3013 * Read the NDMP record marker, if we have it.
3015 ndmp_rm=tvb_get_ntohl(tvb, offset);
3017 /* Save the flag indicating whether this packet is a fragment */
3018 save_fragmented = pinfo->fragmented;
3020 /* Reassemble if desegmentation and reassembly are enabled, otherwise
3021 * just pass through and use the data in tvb for dissection */
3022 if (data && ndmp_defragment && ndmp_desegment)
3026 * Determine the direction of the flow, so we can use the correct fragment tree
3028 direction=cmp_address(&pinfo->src, &pinfo->dst);
3029 if(direction==0) {
3030 direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
3032 if(direction>=0){
3033 frags = ndmp_conv_data->fragsA;
3034 } else {
3035 frags = ndmp_conv_data->fragsB;
3039 * Figure out the tcp seq and pdu length. Fragment tree is indexed based on seq;
3041 tcpinfo = (struct tcpinfo *)data;
3043 seq = tcpinfo->seq;
3044 len = (ndmp_rm & RPC_RM_FRAGLEN) + 4;
3045 nxt = seq + len;
3048 * In case there are multiple PDUs in the same frame, advance the tcp seq
3049 * so that they can be distinguished from one another
3051 tcpinfo->seq = nxt;
3053 nfi = (ndmp_frag_info *)wmem_map_lookup(frags, GUINT_TO_POINTER(seq));
3055 if (!nfi)
3057 frag_num = 0;
3060 * If nfi doesn't exist, then there are no fragments before this one.
3061 * If there are fragments after this one, create the entry in the frag
3062 * tree so the next fragment can find it.
3063 * If we've already seen this frame, no need to create the entry again.
3065 if ( !(ndmp_rm & RPC_RM_LASTFRAG))
3067 if ( !(pinfo->fd->visited))
3069 nfi=wmem_new(wmem_file_scope(), ndmp_frag_info);
3070 nfi->first_seq = seq;
3071 nfi->offset = 1;
3072 wmem_map_insert(frags, GUINT_TO_POINTER(nxt), (void *)nfi);
3076 * If this is both the first and the last fragment, then there
3077 * is no reason to even engage the reassembly routines. Just
3078 * create the new_tvb directly from tvb.
3080 else
3082 do_frag = false;
3083 new_tvb = tvb_new_subset_remaining(tvb, 4);
3086 else
3089 * An entry was found, so we know the offset of this fragment
3091 frag_num = nfi->offset;
3092 seq = nfi->first_seq;
3095 * If this isn't the last frag, add another entry so the next fragment can find it.
3096 * If we've already seen this frame, no need to create the entry again.
3098 if ( !(ndmp_rm & RPC_RM_LASTFRAG))
3100 if ( !(pinfo->fd->visited))
3102 nfi=wmem_new(wmem_file_scope(), ndmp_frag_info);
3103 nfi->first_seq = seq;
3104 nfi->offset = frag_num+1;
3105 wmem_map_insert(frags, GUINT_TO_POINTER(nxt), (void *)nfi);
3110 /* If fragmentation is necessary */
3111 if (do_frag)
3113 pinfo->fragmented = true;
3115 frag_msg = fragment_add_seq_check(&ndmp_reassembly_table,
3116 tvb, 4, pinfo, seq, NULL,
3117 frag_num,
3118 tvb_captured_length_remaining(tvb, offset)-4,
3119 !(ndmp_rm & RPC_RM_LASTFRAG));
3121 new_tvb = process_reassembled_data(tvb, 4, pinfo, "Reassembled NDMP", frag_msg, &ndmp_frag_items, NULL, tree);
3125 * Check if this is the last fragment.
3127 if (!(ndmp_rm & RPC_RM_LASTFRAG)) {
3129 * Update the column info.
3131 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
3133 col_set_str(pinfo->cinfo, COL_INFO, "[NDMP fragment] ");
3136 * Add the record marker information to the tree
3138 if (tree) {
3139 ndmp_item = proto_tree_add_item(tree, proto_ndmp, tvb, 0, -1, ENC_NA);
3140 ndmp_tree = proto_item_add_subtree(ndmp_item, ett_ndmp);
3142 hdr_tree = proto_tree_add_subtree_format(ndmp_tree, tvb, 0, 4,
3143 ett_ndmp_fraghdr, NULL, "Fragment header: %s%u %s",
3144 (ndmp_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
3145 ndmp_rm & RPC_RM_FRAGLEN, plurality(ndmp_rm & RPC_RM_FRAGLEN, "byte", "bytes"));
3146 proto_tree_add_boolean(hdr_tree, hf_ndmp_lastfrag, tvb, 0, 4, ndmp_rm);
3147 proto_tree_add_uint(hdr_tree, hf_ndmp_fraglen, tvb, 0, 4, ndmp_rm);
3150 * Decode the remaining bytes as generic NDMP fragment data
3152 proto_tree_add_item(ndmp_tree, hf_ndmp_fragment_data, tvb, 4, -1, ENC_NA);
3154 pinfo->fragmented = save_fragmented;
3155 return tvb_captured_length(tvb);
3158 else
3160 new_tvb = tvb_new_subset_remaining(tvb, 4);
3164 /* size of this NDMP PDU */
3165 size = tvb_captured_length_remaining(new_tvb, offset);
3166 if (size < 24) {
3167 /* too short to be NDMP */
3168 pinfo->fragmented = save_fragmented;
3169 return tvb_captured_length(tvb);
3173 * If it doesn't look like a valid NDMP header at this point, there is
3174 * no reason to move forward
3176 if (!check_ndmp_hdr(new_tvb))
3178 pinfo->fragmented = save_fragmented;
3179 return tvb_captured_length(tvb);
3182 nh.seq = tvb_get_ntohl(new_tvb, offset);
3183 nh.timestamp = tvb_get_ntohl(new_tvb, offset+4);
3184 nh.type = tvb_get_ntohl(new_tvb, offset+8);
3185 nh.msg = tvb_get_ntohl(new_tvb, offset+12);
3186 nh.rep_seq = tvb_get_ntohl(new_tvb, offset+16);
3187 nh.err = tvb_get_ntohl(new_tvb, offset+20);
3189 /* When the last fragment is small and the final frame contains
3190 * multiple fragments, the column becomes unwritable.
3191 * Temporarily change that so that the correct header can be
3192 * applied */
3193 save_info_writable = col_get_writable(pinfo->cinfo, COL_INFO);
3194 save_proto_writable = col_get_writable(pinfo->cinfo, COL_PROTOCOL);
3195 col_set_writable(pinfo->cinfo, COL_PROTOCOL, true);
3196 col_set_writable(pinfo->cinfo, COL_INFO, true);
3198 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDMP");
3199 col_clear(pinfo->cinfo, COL_INFO);
3200 if (tree) {
3201 ndmp_item = proto_tree_add_item(tree, proto_ndmp, tvb, 0, -1, ENC_NA);
3202 ndmp_tree = proto_item_add_subtree(ndmp_item, ett_ndmp);
3205 /* ndmp version (and autodetection) */
3206 if(ndmp_conv_data->version!=NDMP_PROTOCOL_UNKNOWN){
3207 vers_item=proto_tree_add_uint(ndmp_tree, hf_ndmp_version, new_tvb, offset, 0, ndmp_conv_data->version);
3208 } else {
3209 vers_item=proto_tree_add_uint_format(ndmp_tree, hf_ndmp_version, new_tvb, offset, 0, ndmp_default_protocol_version, "Unknown NDMP version, using default:%d", ndmp_default_protocol_version);
3211 proto_item_set_generated(vers_item);
3213 /* request response matching */
3214 ndmp_conv_data->task=NULL;
3215 switch(nh.type){
3216 case NDMP_MESSAGE_REQUEST:
3217 if(!pinfo->fd->visited){
3218 ndmp_conv_data->task=wmem_new(wmem_file_scope(), ndmp_task_data_t);
3219 ndmp_conv_data->task->request_frame=pinfo->num;
3220 ndmp_conv_data->task->response_frame=0;
3221 ndmp_conv_data->task->ndmp_time=pinfo->abs_ts;
3222 ndmp_conv_data->task->itlq=NULL;
3223 wmem_map_insert(ndmp_conv_data->tasks, GUINT_TO_POINTER(nh.seq), ndmp_conv_data->task);
3224 } else {
3225 ndmp_conv_data->task=(ndmp_task_data_t *)wmem_map_lookup(ndmp_conv_data->tasks, GUINT_TO_POINTER(nh.seq));
3227 if(ndmp_conv_data->task && ndmp_conv_data->task->response_frame){
3228 proto_item *it;
3229 it=proto_tree_add_uint(ndmp_tree, hf_ndmp_response_frame, new_tvb, 0, 0, ndmp_conv_data->task->response_frame);
3231 proto_item_set_generated(it);
3233 break;
3234 case NDMP_MESSAGE_REPLY:
3235 ndmp_conv_data->task=(ndmp_task_data_t *)wmem_map_lookup(ndmp_conv_data->tasks, GUINT_TO_POINTER(nh.rep_seq));
3237 if(ndmp_conv_data->task && !pinfo->fd->visited){
3238 ndmp_conv_data->task->response_frame=pinfo->num;
3239 if(ndmp_conv_data->task->itlq){
3240 ndmp_conv_data->task->itlq->last_exchange_frame=pinfo->num;
3243 if(ndmp_conv_data->task && ndmp_conv_data->task->request_frame){
3244 proto_item *it;
3245 nstime_t delta_ts;
3247 it=proto_tree_add_uint(ndmp_tree, hf_ndmp_request_frame, new_tvb, 0, 0, ndmp_conv_data->task->request_frame);
3249 proto_item_set_generated(it);
3251 nstime_delta(&delta_ts, &pinfo->abs_ts, &ndmp_conv_data->task->ndmp_time);
3252 it=proto_tree_add_time(ndmp_tree, hf_ndmp_time, new_tvb, 0, 0, &delta_ts);
3253 proto_item_set_generated(it);
3255 break;
3258 /* Add the record marker information to the tree */
3259 hdr_tree = proto_tree_add_subtree_format(ndmp_tree, tvb, 0, 4,
3260 ett_ndmp_fraghdr, NULL, "Fragment header: %s%u %s",
3261 (ndmp_rm & RPC_RM_LASTFRAG) ? "Last fragment, " : "",
3262 ndmp_rm & RPC_RM_FRAGLEN, plurality(ndmp_rm & RPC_RM_FRAGLEN, "byte", "bytes"));
3263 proto_tree_add_boolean(hdr_tree, hf_ndmp_lastfrag, tvb, 0, 4, ndmp_rm);
3264 proto_tree_add_uint(hdr_tree, hf_ndmp_fraglen, tvb, 0, 4, ndmp_rm);
3267 * We cannot trust what dissect_ndmp_cmd() tells us, as there
3268 * are implementations which pad some additional data after
3269 * the PDU. We MUST use size.
3271 dissect_ndmp_cmd(new_tvb, offset, pinfo, ndmp_tree, &nh);
3273 /* restore saved variables */
3274 pinfo->fragmented = save_fragmented;
3275 col_set_writable(pinfo->cinfo, COL_INFO, save_info_writable);
3276 col_set_writable(pinfo->cinfo, COL_PROTOCOL, save_proto_writable);
3278 return tvb_captured_length(tvb);
3281 static unsigned
3282 get_ndmp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
3284 unsigned len;
3286 len=tvb_get_ntohl(tvb, offset)&0x7fffffff;
3287 /* Get the length of the NDMP packet. */
3289 /*XXX check header for sanity */
3290 return len+4;
3293 bool
3294 check_if_ndmp(tvbuff_t *tvb, packet_info *pinfo)
3296 unsigned len;
3297 uint32_t tmp;
3299 /* verify that the tcp port is 10000, ndmp always runs on port 10000*/
3300 if ((pinfo->srcport!=TCP_PORT_NDMP)&&(pinfo->destport!=TCP_PORT_NDMP)) {
3301 return false;
3304 /* check that the header looks sane */
3305 len=tvb_captured_length(tvb);
3306 /* check the record marker that it looks sane.
3307 * It has to be >=24 bytes or (arbitrary limit) <1Mbyte
3309 if(len>=4){
3310 tmp=(tvb_get_ntohl(tvb, 0)&RPC_RM_FRAGLEN);
3311 if( (tmp<24)||(tmp>1000000) ){
3312 return false;
3316 /* check the timestamp, timestamps are valid if they
3317 * (arbitrary) lie between 1980-jan-1 and 2030-jan-1
3319 if(len>=12){
3320 tmp=tvb_get_ntohl(tvb, 8);
3321 if( (tmp<0x12ceec50)||(tmp>0x70dc1ed0) ){
3322 return false;
3326 /* check the type */
3327 if(len>=16){
3328 tmp=tvb_get_ntohl(tvb, 12);
3329 if( tmp>1 ){
3330 return false;
3334 /* check message */
3335 if(len>=20){
3336 tmp=tvb_get_ntohl(tvb, 16);
3337 if( (tmp>0xa09) || (tmp==0) ){
3338 return false;
3342 /* check error */
3343 if(len>=28){
3344 tmp=tvb_get_ntohl(tvb, 24);
3345 if( (tmp>0x17) ){
3346 return false;
3350 return true;
3353 /* Called because the frame has been identified as part of a conversation
3354 * assigned to the NDMP protocol.
3355 * At this point we may have either an NDMP PDU or an NDMP PDU fragment.
3357 static int
3358 dissect_ndmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3360 /* If we are doing defragmentation, don't check more than the record mark here,
3361 * because if this is a continuation of a fragmented NDMP PDU there won't be a
3362 * NDMP header after the RM */
3363 if(ndmp_defragment && !check_ndmp_rm(tvb, pinfo)) {
3364 return 0;
3367 /* If we aren't doing both desegmentation and fragment reassembly,
3368 * check for the entire NDMP header before proceeding */
3369 if(!(ndmp_desegment && ndmp_defragment) && !check_if_ndmp(tvb, pinfo)) {
3370 return 0;
3373 tcp_dissect_pdus(tvb, pinfo, tree, ndmp_desegment, 4,
3374 get_ndmp_pdu_len, dissect_ndmp_message, data);
3375 return tvb_captured_length(tvb);
3378 /* Called when doing a heuristic check;
3379 * Accept as NDMP only if the full header seems reasonable.
3380 * Note that once the first PDU (or PDU fragment) has been found
3381 * dissect_ndmp_message will register a dissect_ndmp NDMP handle
3382 * as the protocol dissector for this conversation.
3384 static bool
3385 dissect_ndmp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3387 if (tvb_captured_length(tvb) < 28)
3388 return false;
3389 if (!check_if_ndmp(tvb, pinfo))
3390 return false;
3392 tcp_dissect_pdus(tvb, pinfo, tree, ndmp_desegment, 28,
3393 get_ndmp_pdu_len, dissect_ndmp_message, data);
3394 return true;
3398 void
3399 proto_register_ndmp(void)
3402 static hf_register_info hf_ndmp[] = {
3403 { &hf_ndmp_header, {
3404 "NDMP Header", "ndmp.header", FT_NONE, BASE_NONE,
3405 NULL, 0, NULL, HFILL }},
3407 { &hf_ndmp_response_frame, {
3408 "Response In", "ndmp.response_frame", FT_FRAMENUM, BASE_NONE,
3409 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0, "The response to this NDMP command is in this frame", HFILL }},
3411 { &hf_ndmp_time, {
3412 "Time from request", "ndmp.time", FT_RELATIVE_TIME, BASE_NONE,
3413 NULL,0, "Time since the request packet", HFILL }},
3415 { &hf_ndmp_request_frame, {
3416 "Request In", "ndmp.request_frame", FT_FRAMENUM, BASE_NONE,
3417 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0, "The request to this NDMP command is in this frame", HFILL }},
3419 { &hf_ndmp_sequence, {
3420 "Sequence", "ndmp.sequence", FT_UINT32, BASE_DEC,
3421 NULL, 0, "Sequence number for NDMP PDU", HFILL }},
3423 { &hf_ndmp_reply_sequence, {
3424 "Reply Sequence", "ndmp.reply_sequence", FT_UINT32, BASE_DEC,
3425 NULL, 0, "Reply Sequence number for NDMP PDU", HFILL }},
3427 { &hf_ndmp_timestamp, {
3428 "Time", "ndmp.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3429 NULL, 0, "Timestamp for this NDMP PDU", HFILL }},
3431 { &hf_ndmp_msgtype, {
3432 "Type", "ndmp.msg_type", FT_UINT32, BASE_DEC,
3433 VALS(msg_type_vals), 0, "Is this a Request or Response?", HFILL }},
3435 { &hf_ndmp_msg, {
3436 "Message", "ndmp.msg", FT_UINT32, BASE_HEX,
3437 VALS(msg_vals), 0, "Type of NDMP PDU", HFILL }},
3439 { &hf_ndmp_error, {
3440 "Error", "ndmp.error", FT_UINT32, BASE_DEC,
3441 VALS(error_vals), 0, "Error code for this NDMP PDU", HFILL }},
3443 { &hf_ndmp_version, {
3444 "Version", "ndmp.version", FT_UINT32, BASE_DEC,
3445 NULL, 0, "Version of NDMP protocol", HFILL }},
3447 { &hf_ndmp_hostname, {
3448 "Hostname", "ndmp.hostname", FT_STRING, BASE_NONE,
3449 NULL, 0, NULL, HFILL }},
3451 { &hf_ndmp_hostid, {
3452 "HostID", "ndmp.hostid", FT_STRING, BASE_NONE,
3453 NULL, 0, NULL, HFILL }},
3455 { &hf_ndmp_os_type, {
3456 "OS Type", "ndmp.os.type", FT_STRING, BASE_NONE,
3457 NULL, 0, NULL, HFILL }},
3459 { &hf_ndmp_os_vers, {
3460 "OS Version", "ndmp.os.version", FT_STRING, BASE_NONE,
3461 NULL, 0, NULL, HFILL }},
3463 { &hf_ndmp_addr_types, {
3464 "Addr Types", "ndmp.addr_types", FT_NONE, BASE_NONE,
3465 NULL, 0, "List Of Address Types", HFILL }},
3467 { &hf_ndmp_addr_type, {
3468 "Addr Type", "ndmp.addr_type", FT_UINT32, BASE_DEC,
3469 VALS(addr_type_vals), 0, "Address Type", HFILL }},
3471 { &hf_ndmp_auth_type, {
3472 "Auth Type", "ndmp.auth_type", FT_UINT32, BASE_DEC,
3473 VALS(auth_type_vals), 0, "Authentication Type", HFILL }},
3475 { &hf_ndmp_auth_challenge, {
3476 "Challenge", "ndmp.auth.challenge", FT_BYTES, BASE_NONE,
3477 NULL, 0, "Authentication Challenge", HFILL }},
3479 { &hf_ndmp_auth_digest, {
3480 "Digest", "ndmp.auth.digest", FT_BYTES, BASE_NONE,
3481 NULL, 0, "Authentication Digest", HFILL }},
3483 { &hf_ndmp_butype_info, {
3484 "Butype Info", "ndmp.butype.info", FT_NONE, BASE_NONE,
3485 NULL, 0, NULL, HFILL }},
3487 { &hf_ndmp_butype_name, {
3488 "Butype Name", "ndmp.butype.name", FT_STRING, BASE_NONE,
3489 NULL, 0, "Name of Butype", HFILL }},
3491 { &hf_ndmp_butype_default_env, {
3492 "Default Env", "ndmp.butype.default_env", FT_NONE, BASE_NONE,
3493 NULL, 0, "Default Env's for this Butype Info", HFILL }},
3495 { &hf_ndmp_tcp_addr_list, {
3496 "TCP Ports", "ndmp.tcp.port_list", FT_NONE, BASE_NONE,
3497 NULL, 0, "List of TCP ports", HFILL }},
3499 { &hf_ndmp_tcp_default_env, {
3500 "Default Env", "ndmp.tcp.default_env", FT_NONE, BASE_NONE,
3501 NULL, 0, "Default Env's for this Butype Info", HFILL }},
3503 { &hf_ndmp_butype_attr, {
3504 "Attributes", "ndmp.butype.attr", FT_UINT32, BASE_HEX,
3505 NULL, 0, NULL, HFILL }},
3507 { &hf_ndmp_butype_attr_backup_file_history, {
3508 "Backup file history", "ndmp.butype.attr.backup_file_history", FT_BOOLEAN, 32,
3509 TFS(&tfs_butype_attr_backup_file_history), 0x00000001, "backup_file_history", HFILL }},
3511 { &hf_ndmp_butype_attr_backup_filelist, {
3512 "Backup file list", "ndmp.butype.attr.backup_filelist", FT_BOOLEAN, 32,
3513 TFS(&tfs_butype_attr_backup_filelist), 0x00000002, "backup_filelist", HFILL }},
3515 { &hf_ndmp_butype_attr_recover_filelist, {
3516 "Recover file list", "ndmp.butype.attr.recover_filelist", FT_BOOLEAN, 32,
3517 TFS(&tfs_butype_attr_recover_filelist), 0x00000004, "recover_filelist", HFILL }},
3519 { &hf_ndmp_butype_attr_backup_direct, {
3520 "Backup direct", "ndmp.butype.attr.backup_direct", FT_BOOLEAN, 32,
3521 TFS(&tfs_butype_attr_backup_direct), 0x00000008, "backup_direct", HFILL }},
3523 { &hf_ndmp_butype_attr_recover_direct, {
3524 "Recover direct", "ndmp.butype.attr.recover_direct", FT_BOOLEAN, 32,
3525 TFS(&tfs_butype_attr_recover_direct), 0x00000010, "recover_direct", HFILL }},
3527 { &hf_ndmp_butype_attr_backup_incremental, {
3528 "Backup incremental", "ndmp.butype.attr.backup_incremental", FT_BOOLEAN, 32,
3529 TFS(&tfs_butype_attr_backup_incremental), 0x00000020, "backup_incremental", HFILL }},
3531 { &hf_ndmp_butype_attr_recover_incremental, {
3532 "Recover incremental", "ndmp.butype.attr.recover_incremental", FT_BOOLEAN, 32,
3533 TFS(&tfs_butype_attr_recover_incremental), 0x00000040, "recover_incremental", HFILL }},
3535 { &hf_ndmp_butype_attr_backup_utf8, {
3536 "Backup UTF8", "ndmp.butype.attr.backup_utf8", FT_BOOLEAN, 32,
3537 TFS(&tfs_butype_attr_backup_utf8), 0x00000080, "backup_utf8", HFILL }},
3539 { &hf_ndmp_butype_attr_recover_utf8, {
3540 "Recover UTF8", "ndmp.butype.attr.recover_utf8", FT_BOOLEAN, 32,
3541 TFS(&tfs_butype_attr_recover_utf8), 0x00000100, "recover_utf8", HFILL }},
3543 { &hf_ndmp_butype_env_name, {
3544 "Name", "ndmp.butype.env.name", FT_STRING, BASE_NONE,
3545 NULL, 0, "Name for this env-variable", HFILL }},
3547 { &hf_ndmp_butype_env_value, {
3548 "Value", "ndmp.butype.env.value", FT_STRING, BASE_NONE,
3549 NULL, 0, "Value for this env-variable", HFILL }},
3551 { &hf_ndmp_tcp_env_name, {
3552 "Name", "ndmp.tcp.env.name", FT_STRING, BASE_NONE,
3553 NULL, 0, "Name for this env-variable", HFILL }},
3555 { &hf_ndmp_tcp_env_value, {
3556 "Value", "ndmp.tcp.env.value", FT_STRING, BASE_NONE,
3557 NULL, 0, "Value for this env-variable", HFILL }},
3559 { &hf_ndmp_fs_info, {
3560 "FS Info", "ndmp.fs.info", FT_NONE, BASE_NONE,
3561 NULL, 0, NULL, HFILL }},
3563 { &hf_ndmp_fs_invalid, {
3564 "Invalids", "ndmp.fs.invalid", FT_UINT32, BASE_HEX,
3565 NULL, 0, NULL, HFILL }},
3567 { &hf_ndmp_fs_invalid_total_size, {
3568 "Total size invalid", "ndmp.fs.invalid.total_size", FT_BOOLEAN, 32,
3569 TFS(&tfs_fs_invalid_total_size), 0x00000001, "If total size is invalid", HFILL }},
3571 { &hf_ndmp_fs_invalid_used_size, {
3572 "Used size invalid", "ndmp.fs.invalid.used_size", FT_BOOLEAN, 32,
3573 TFS(&tfs_fs_invalid_used_size), 0x00000002, "If used size is invalid", HFILL }},
3575 { &hf_ndmp_fs_invalid_avail_size, {
3576 "Available size invalid", "ndmp.fs.invalid.avail_size", FT_BOOLEAN, 32,
3577 TFS(&tfs_fs_invalid_avail_size), 0x00000004, "If available size is invalid", HFILL }},
3579 { &hf_ndmp_fs_invalid_total_inodes, {
3580 "Total number of inodes invalid", "ndmp.fs.invalid.total_inodes", FT_BOOLEAN, 32,
3581 TFS(&tfs_fs_invalid_total_inodes), 0x00000008, "If total number of inodes is invalid", HFILL }},
3583 { &hf_ndmp_fs_invalid_used_inodes, {
3584 "Used number of inodes is invalid", "ndmp.fs.invalid.used_inodes", FT_BOOLEAN, 32,
3585 TFS(&tfs_fs_invalid_used_inodes), 0x00000010, "If used number of inodes is invalid", HFILL }},
3587 { &hf_ndmp_fs_fs_type, {
3588 "Type", "ndmp.fs.type", FT_STRING, BASE_NONE,
3589 NULL, 0, "Type of FS", HFILL }},
3591 { &hf_ndmp_fs_logical_device, {
3592 "Logical Device", "ndmp.fs.logical_device", FT_STRING, BASE_NONE,
3593 NULL, 0, "Name of logical device", HFILL }},
3595 { &hf_ndmp_fs_physical_device, {
3596 "Physical Device", "ndmp.fs.physical_device", FT_STRING, BASE_NONE,
3597 NULL, 0, "Name of physical device", HFILL }},
3599 { &hf_ndmp_fs_total_size, {
3600 "Total Size", "ndmp.fs.total_size", FT_UINT64, BASE_DEC,
3601 NULL, 0, "Total size of FS", HFILL }},
3603 { &hf_ndmp_fs_used_size, {
3604 "Used Size", "ndmp.fs.used_size", FT_UINT64, BASE_DEC,
3605 NULL, 0, "Total used size of FS", HFILL }},
3607 { &hf_ndmp_fs_avail_size, {
3608 "Avail Size", "ndmp.fs.avail_size", FT_UINT64, BASE_DEC,
3609 NULL, 0, "Total available size on FS", HFILL }},
3611 { &hf_ndmp_fs_total_inodes, {
3612 "Total Inodes", "ndmp.fs.total_inodes", FT_UINT64, BASE_DEC,
3613 NULL, 0, "Total number of inodes on FS", HFILL }},
3615 { &hf_ndmp_fs_used_inodes, {
3616 "Used Inodes", "ndmp.fs.used_inodes", FT_UINT64, BASE_DEC,
3617 NULL, 0, "Number of used inodes on FS", HFILL }},
3619 { &hf_ndmp_fs_env, {
3620 "Env variables", "ndmp.fs.env", FT_NONE, BASE_NONE,
3621 NULL, 0, "Environment variables for FS", HFILL }},
3623 { &hf_ndmp_fs_env_name, {
3624 "Name", "ndmp.fs.env.name", FT_STRING, BASE_NONE,
3625 NULL, 0, "Name for this env-variable", HFILL }},
3627 { &hf_ndmp_fs_env_value, {
3628 "Value", "ndmp.fs.env.value", FT_STRING, BASE_NONE,
3629 NULL, 0, "Value for this env-variable", HFILL }},
3631 { &hf_ndmp_fs_status, {
3632 "Status", "ndmp.fs.status", FT_STRING, BASE_NONE,
3633 NULL, 0, "Status for this FS", HFILL }},
3635 { &hf_ndmp_tape_info, {
3636 "Tape Info", "ndmp.tape.info", FT_NONE, BASE_NONE,
3637 NULL, 0, NULL, HFILL }},
3639 { &hf_ndmp_tape_model, {
3640 "Model", "ndmp.tape.model", FT_STRING, BASE_NONE,
3641 NULL, 0, "Model of the TAPE drive", HFILL }},
3643 { &hf_ndmp_tape_dev_cap, {
3644 "Device Capability", "ndmp.tape.dev_cap", FT_NONE, BASE_NONE,
3645 NULL, 0, "Tape Device Capability", HFILL }},
3647 { &hf_ndmp_tape_device, {
3648 "Device", "ndmp.tape.device", FT_STRING, BASE_NONE,
3649 NULL, 0, "Name of TAPE Device", HFILL }},
3651 { &hf_ndmp_tape_attr, {
3652 "Attributes", "ndmp.tape.attr", FT_UINT32, BASE_HEX,
3653 NULL, 0, NULL, HFILL }},
3655 { &hf_ndmp_tape_attr_rewind, {
3656 "Device supports rewind", "ndmp.tape.attr.rewind", FT_BOOLEAN, 32,
3657 TFS(&tfs_tape_attr_rewind), 0x00000001, "If this device supports rewind", HFILL }},
3659 { &hf_ndmp_tape_attr_unload, {
3660 "Device supports unload", "ndmp.tape.attr.unload", FT_BOOLEAN, 32,
3661 TFS(&tfs_tape_attr_unload), 0x00000002, "If this device supports unload", HFILL }},
3663 { &hf_ndmp_tape_capability, {
3664 "Tape Capabilities", "ndmp.tape.capability", FT_NONE, BASE_NONE,
3665 NULL, 0, NULL, HFILL }},
3667 { &hf_ndmp_tape_capability_name, {
3668 "Name", "ndmp.tape.cap.name", FT_STRING, BASE_NONE,
3669 NULL, 0, "Name for this env-variable", HFILL }},
3671 { &hf_ndmp_tape_capability_value, {
3672 "Value", "ndmp.tape.cap.value", FT_STRING, BASE_NONE,
3673 NULL, 0, "Value for this env-variable", HFILL }},
3675 { &hf_ndmp_scsi_info, {
3676 "SCSI Info", "ndmp.scsi.info", FT_NONE, BASE_NONE,
3677 NULL, 0, NULL, HFILL }},
3679 { &hf_ndmp_scsi_model, {
3680 "Model", "ndmp.scsi.model", FT_STRING, BASE_NONE,
3681 NULL, 0, "Model of the SCSI device", HFILL }},
3683 { &hf_ndmp_server_vendor, {
3684 "Vendor", "ndmp.server.vendor", FT_STRING, BASE_NONE,
3685 NULL, 0, "Name of vendor", HFILL }},
3687 { &hf_ndmp_server_product, {
3688 "Product", "ndmp.server.product", FT_STRING, BASE_NONE,
3689 NULL, 0, "Name of product", HFILL }},
3691 { &hf_ndmp_server_revision, {
3692 "Revision", "ndmp.server.revision", FT_STRING, BASE_NONE,
3693 NULL, 0, "Revision of this product", HFILL }},
3695 { &hf_ndmp_auth_types, {
3696 "Auth types", "ndmp.auth.types", FT_NONE, BASE_NONE,
3697 NULL, 0, NULL, HFILL }},
3699 { &hf_ndmp_scsi_device, {
3700 "Device", "ndmp.scsi.device", FT_STRING, BASE_NONE,
3701 NULL, 0, "Name of SCSI Device", HFILL }},
3703 { &hf_ndmp_scsi_controller, {
3704 "Controller", "ndmp.scsi.controller", FT_UINT32, BASE_DEC,
3705 NULL, 0, "Target Controller", HFILL }},
3707 { &hf_ndmp_scsi_id, {
3708 "ID", "ndmp.scsi.id", FT_UINT32, BASE_DEC,
3709 NULL, 0, "Target ID", HFILL }},
3711 { &hf_ndmp_scsi_lun, {
3712 "LUN", "ndmp.scsi.lun", FT_UINT32, BASE_DEC,
3713 NULL, 0, "Target LUN", HFILL }},
3715 { &hf_ndmp_execute_cdb_flags, {
3716 "Flags", "ndmp.execute_cdb.flags", FT_UINT32, BASE_HEX,
3717 NULL, 0, NULL, HFILL }},
3719 { &hf_ndmp_execute_cdb_flags_data_in, {
3720 "DATA_IN", "ndmp.execute_cdb.flags.data_in", FT_BOOLEAN, 32,
3721 NULL, 0x00000001, NULL, HFILL }},
3723 { &hf_ndmp_execute_cdb_flags_data_out, {
3724 "DATA_OUT", "ndmp.execute_cdb.flags.data_out", FT_BOOLEAN, 32,
3725 NULL, 0x00000002, NULL, HFILL }},
3727 { &hf_ndmp_execute_cdb_timeout, {
3728 "Timeout", "ndmp.execute_cdb.timeout", FT_UINT32, BASE_DEC,
3729 NULL, 0, "Reselect timeout, in milliseconds", HFILL }},
3731 { &hf_ndmp_execute_cdb_datain_len, {
3732 "Data in length", "ndmp.execute_cdb.datain_len", FT_UINT32, BASE_DEC,
3733 NULL, 0, "Expected length of data bytes to read", HFILL }},
3735 { &hf_ndmp_execute_cdb_cdb_len, {
3736 "CDB length", "ndmp.execute_cdb.cdb_len", FT_UINT32, BASE_DEC,
3737 NULL, 0, "Length of CDB", HFILL }},
3739 #if 0
3740 { &hf_ndmp_execute_cdb_dataout, {
3741 "Data out", "ndmp.execute_cdb.dataout", FT_BYTES, BASE_NONE,
3742 NULL, 0, "Data to be transferred to the SCSI device", HFILL }},
3743 #endif
3745 { &hf_ndmp_execute_cdb_status, {
3746 "Status", "ndmp.execute_cdb.status", FT_UINT32, BASE_DEC,
3747 VALS(scsi_status_val), 0, "SCSI status", HFILL }},
3749 { &hf_ndmp_execute_cdb_dataout_len, {
3750 "Data out length", "ndmp.execute_cdb.dataout_len", FT_UINT32, BASE_DEC,
3751 NULL, 0, "Number of bytes transferred to the device", HFILL }},
3753 #if 0
3754 { &hf_ndmp_execute_cdb_datain, {
3755 "Data in", "ndmp.execute_cdb.datain", FT_BYTES, BASE_NONE,
3756 NULL, 0, "Data transferred from the SCSI device", HFILL }},
3757 #endif
3759 { &hf_ndmp_execute_cdb_sns_len, {
3760 "Sense data length", "ndmp.execute_cdb.sns_len", FT_UINT32, BASE_DEC,
3761 NULL, 0, "Length of sense data", HFILL }},
3763 { &hf_ndmp_tape_open_mode, {
3764 "Mode", "ndmp.tape.open_mode", FT_UINT32, BASE_DEC,
3765 VALS(tape_open_mode_vals), 0, "Mode to open tape in", HFILL }},
3767 { &hf_ndmp_tape_invalid, {
3768 "Invalids", "ndmp.tape.invalid", FT_UINT32, BASE_HEX,
3769 NULL, 0, NULL, HFILL }},
3771 { &hf_ndmp_tape_invalid_file_num, {
3772 "Invalid file num", "ndmp.tape.invalid.file_num", FT_BOOLEAN, 32,
3773 TFS(&tfs_ndmp_tape_invalid_file_num), 0x00000001, NULL, HFILL }},
3775 { &hf_ndmp_tape_invalid_soft_errors, {
3776 "Soft errors", "ndmp.tape.invalid.soft_errors", FT_BOOLEAN, 32,
3777 TFS(&tfs_ndmp_tape_invalid_soft_errors), 0x00000002, NULL, HFILL }},
3779 { &hf_ndmp_tape_invalid_block_size, {
3780 "Block size", "ndmp.tape.invalid.block_size", FT_BOOLEAN, 32,
3781 TFS(&tfs_ndmp_tape_invalid_block_size), 0x00000004, NULL, HFILL }},
3783 { &hf_ndmp_tape_invalid_block_no, {
3784 "Block no", "ndmp.tape.invalid.block_no", FT_BOOLEAN, 32,
3785 TFS(&tfs_ndmp_tape_invalid_block_no), 0x00000008, NULL, HFILL }},
3787 { &hf_ndmp_tape_invalid_total_space, {
3788 "Total space", "ndmp.tape.invalid.total_space", FT_BOOLEAN, 32,
3789 TFS(&tfs_ndmp_tape_invalid_total_space), 0x00000010, NULL, HFILL }},
3791 { &hf_ndmp_tape_invalid_space_remain, {
3792 "Space remain", "ndmp.tape.invalid.space_remain", FT_BOOLEAN, 32,
3793 TFS(&tfs_ndmp_tape_invalid_space_remain), 0x00000020, NULL, HFILL }},
3795 { &hf_ndmp_tape_invalid_partition, {
3796 "Invalid partition", "ndmp.tape.invalid.partition", FT_BOOLEAN, 32,
3797 TFS(&tfs_ndmp_tape_invalid_partition), 0x00000040, NULL, HFILL }},
3799 { &hf_ndmp_tape_flags, {
3800 "Flags", "ndmp.tape.flags", FT_UINT32, BASE_HEX,
3801 NULL, 0, NULL, HFILL }},
3803 { &hf_ndmp_tape_flags_no_rewind, {
3804 "No rewind", "ndmp.tape.flags.no_rewind", FT_BOOLEAN, 32,
3805 TFS(&tfs_ndmp_tape_flags_no_rewind), 0x00000008, NULL, HFILL, }},
3807 { &hf_ndmp_tape_flags_write_protect, {
3808 "Write protect", "ndmp.tape.flags.write_protect", FT_BOOLEAN, 32,
3809 TFS(&tfs_ndmp_tape_flags_write_protect), 0x00000010, NULL, HFILL, }},
3811 { &hf_ndmp_tape_flags_error, {
3812 "Error", "ndmp.tape.flags.error", FT_BOOLEAN, 32,
3813 TFS(&tfs_ndmp_tape_flags_error), 0x00000020, NULL, HFILL, }},
3815 { &hf_ndmp_tape_flags_unload, {
3816 "Unload", "ndmp.tape.flags.unload", FT_BOOLEAN, 32,
3817 TFS(&tfs_ndmp_tape_flags_unload), 0x00000040, NULL, HFILL, }},
3819 { &hf_ndmp_tape_file_num, {
3820 "file_num", "ndmp.tape.status.file_num", FT_UINT32, BASE_DEC,
3821 NULL, 0, NULL, HFILL }},
3823 { &hf_ndmp_tape_soft_errors, {
3824 "soft_errors", "ndmp.tape.status.soft_errors", FT_UINT32, BASE_DEC,
3825 NULL, 0, NULL, HFILL }},
3827 { &hf_ndmp_tape_block_size, {
3828 "block_size", "ndmp.tape.status.block_size", FT_UINT32, BASE_DEC,
3829 NULL, 0, NULL, HFILL }},
3831 { &hf_ndmp_tape_block_no, {
3832 "block_no", "ndmp.tape.status.block_no", FT_UINT32, BASE_DEC,
3833 NULL, 0, NULL, HFILL }},
3835 { &hf_ndmp_tape_total_space, {
3836 "total_space", "ndmp.tape.status.total_space", FT_UINT64, BASE_DEC,
3837 NULL, 0, NULL, HFILL }},
3839 { &hf_ndmp_tape_space_remain, {
3840 "space_remain", "ndmp.tape.status.space_remain", FT_UINT64, BASE_DEC,
3841 NULL, 0, NULL, HFILL }},
3843 { &hf_ndmp_tape_partition, {
3844 "partition", "ndmp.tape.status.partition", FT_UINT32, BASE_DEC,
3845 NULL, 0, NULL, HFILL }},
3847 { &hf_ndmp_tape_mtio_op, {
3848 "Operation", "ndmp.tape.mtio.op", FT_UINT32, BASE_DEC,
3849 VALS(tape_mtio_vals), 0, "MTIO Operation", HFILL }},
3851 { &hf_ndmp_count, {
3852 "Count", "ndmp.count", FT_UINT32, BASE_DEC,
3853 NULL, 0, "Number of bytes/objects/operations", HFILL }},
3855 { &hf_ndmp_resid_count, {
3856 "Resid Count", "ndmp.resid_count", FT_UINT32, BASE_DEC,
3857 NULL, 0, "Number of remaining bytes/objects/operations", HFILL }},
3859 { &hf_ndmp_mover_state, {
3860 "State", "ndmp.mover.state", FT_UINT32, BASE_DEC,
3861 VALS(mover_state_vals), 0, "State of the selected mover", HFILL }},
3863 { &hf_ndmp_mover_pause, {
3864 "Pause", "ndmp.mover.pause", FT_UINT32, BASE_DEC,
3865 VALS(mover_pause_vals), 0, "Reason why the mover paused", HFILL }},
3867 { &hf_ndmp_halt, {
3868 "Halt", "ndmp.halt", FT_UINT32, BASE_DEC,
3869 VALS(halt_vals), 0, "Reason why it halted", HFILL }},
3871 { &hf_ndmp_record_size, {
3872 "Record Size", "ndmp.record.size", FT_UINT32, BASE_DEC,
3873 NULL, 0, "Record size in bytes", HFILL }},
3875 { &hf_ndmp_record_num, {
3876 "Record Num", "ndmp.record.num", FT_UINT32, BASE_DEC,
3877 NULL, 0, "Number of records", HFILL }},
3879 { &hf_ndmp_data_written, {
3880 "Data Written", "ndmp.data.written", FT_UINT64, BASE_DEC,
3881 NULL, 0, "Number of data bytes written", HFILL }},
3883 { &hf_ndmp_seek_position, {
3884 "Seek Position", "ndmp.seek.position", FT_UINT64, BASE_DEC,
3885 NULL, 0, "Current seek position on device", HFILL }},
3887 { &hf_ndmp_bytes_left_to_read, {
3888 "Bytes left to read", "ndmp.bytes_left_to_read", FT_UINT64, BASE_DEC,
3889 NULL, 0, "Number of bytes left to be read from the device", HFILL }},
3891 { &hf_ndmp_window_offset, {
3892 "Window Offset", "ndmp.window.offset", FT_UINT64, BASE_DEC,
3893 NULL, 0, "Offset to window in bytes", HFILL }},
3895 { &hf_ndmp_window_length, {
3896 "Window Length", "ndmp.window.length", FT_UINT64, BASE_DEC,
3897 NULL, 0, "Size of window in bytes", HFILL }},
3899 { &hf_ndmp_addr_ip, {
3900 "IP Address", "ndmp.addr.ip", FT_IPv4, BASE_NONE,
3901 NULL, 0, NULL, HFILL }},
3903 { &hf_ndmp_addr_tcp, {
3904 "TCP Port", "ndmp.addr.tcp_port", FT_UINT32, BASE_DEC,
3905 NULL, 0, NULL, HFILL }},
3907 { &hf_ndmp_addr_fcal_loop_id, {
3908 "Loop ID", "ndmp.addr.loop_id", FT_UINT32, BASE_HEX,
3909 NULL, 0, "FCAL Loop ID", HFILL }},
3911 { &hf_ndmp_addr_ipc, {
3912 "IPC", "ndmp.addr.ipc", FT_BYTES, BASE_NONE,
3913 NULL, 0, "IPC identifier", HFILL }},
3915 { &hf_ndmp_mover_mode, {
3916 "Mode", "ndmp.mover.mode", FT_UINT32, BASE_HEX,
3917 VALS(mover_mode_vals), 0, "Mover Mode", HFILL }},
3919 { &hf_ndmp_file_name, {
3920 "File", "ndmp.file", FT_STRING, BASE_NONE,
3921 NULL, 0, "Name of File", HFILL }},
3923 { &hf_ndmp_nt_file_name, {
3924 "NT File", "ndmp.file", FT_STRING, BASE_NONE,
3925 NULL, 0, "NT Name of File", HFILL }},
3927 { &hf_ndmp_dos_file_name, {
3928 "DOS File", "ndmp.file", FT_STRING, BASE_NONE,
3929 NULL, 0, "DOS Name of File", HFILL }},
3931 { &hf_ndmp_log_type, {
3932 "Type", "ndmp.log.type", FT_UINT32, BASE_HEX,
3933 VALS(log_type_vals), 0, "Type of log entry", HFILL }},
3935 { &hf_ndmp_log_message_id, {
3936 "Message ID", "ndmp.log.message.id", FT_UINT32, BASE_DEC,
3937 NULL, 0, "ID of this log entry", HFILL }},
3939 { &hf_ndmp_log_message, {
3940 "Message", "ndmp.log.message", FT_STRING, BASE_NONE,
3941 NULL, 0, "Log entry", HFILL }},
3943 { &hf_ndmp_halt_reason, {
3944 "Reason", "ndmp.halt.reason", FT_STRING, BASE_NONE,
3945 NULL, 0, "Textual reason for why it halted", HFILL }},
3947 { &hf_ndmp_connected, {
3948 "Connected", "ndmp.connected", FT_UINT32, BASE_DEC,
3949 VALS(connected_vals), 0, "Status of connection", HFILL }},
3951 { &hf_ndmp_connected_reason, {
3952 "Reason", "ndmp.connected.reason", FT_STRING, BASE_NONE,
3953 NULL, 0, "Textual description of the connection status", HFILL }},
3955 { &hf_ndmp_auth_id, {
3956 "ID", "ndmp.auth.id", FT_STRING, BASE_NONE,
3957 NULL, 0, "ID of client authenticating", HFILL }},
3959 { &hf_ndmp_auth_password, {
3960 "Password", "ndmp.auth.password", FT_STRING, BASE_NONE,
3961 NULL, 0, "Password of client authenticating", HFILL }},
3963 { &hf_ndmp_data, {
3964 "Data", "ndmp.data", FT_BYTES, BASE_NONE,
3965 NULL, 0, "Data written/read", HFILL }},
3967 { &hf_ndmp_files, {
3968 "Files", "ndmp.files", FT_NONE, BASE_NONE,
3969 NULL, 0, "List of files", HFILL }},
3971 { &hf_ndmp_file_names, {
3972 "File Names", "ndmp.file.names", FT_NONE, BASE_NONE,
3973 NULL, 0, "List of file names", HFILL }},
3975 { &hf_ndmp_file_fs_type, {
3976 "File FS Type", "ndmp.file.fs_type", FT_UINT32, BASE_DEC,
3977 VALS(file_fs_type_vals), 0, "Type of file permissions (UNIX or NT)", HFILL }},
3979 { &hf_ndmp_file_type, {
3980 "File Type", "ndmp.file.type", FT_UINT32, BASE_DEC,
3981 VALS(file_type_vals), 0, "Type of file", HFILL }},
3983 { &hf_ndmp_file_stats, {
3984 "File Stats", "ndmp.file.stats", FT_NONE, BASE_NONE,
3985 NULL, 0, "List of file stats", HFILL }},
3987 { &hf_ndmp_file_node, {
3988 "Node", "ndmp.file.node", FT_UINT64, BASE_DEC,
3989 NULL, 0, "Node used for direct access", HFILL }},
3991 { &hf_ndmp_file_parent, {
3992 "Parent", "ndmp.file.parent", FT_UINT64, BASE_DEC,
3993 NULL, 0, "Parent node(directory) for this node", HFILL }},
3995 { &hf_ndmp_file_fh_info, {
3996 "FH Info", "ndmp.file.fh_info", FT_UINT64, BASE_DEC,
3997 NULL, 0, "FH Info used for direct access", HFILL }},
3999 { &hf_ndmp_file_invalid, {
4000 "Invalids", "ndmp.file.invalid", FT_UINT32, BASE_HEX,
4001 VALS(file_type_vals), 0, NULL, HFILL }},
4003 { &hf_ndmp_file_invalid_atime, {
4004 "Invalid atime", "ndmp.file.invalid.atime", FT_BOOLEAN, 32,
4005 TFS(&tfs_ndmp_file_invalid_atime), 0x00000001, NULL, HFILL, }},
4007 { &hf_ndmp_file_invalid_ctime, {
4008 "Invalid ctime", "ndmp.file.invalid.ctime", FT_BOOLEAN, 32,
4009 TFS(&tfs_ndmp_file_invalid_ctime), 0x00000002, NULL, HFILL, }},
4011 { &hf_ndmp_file_invalid_group, {
4012 "Invalid group", "ndmp.file.invalid.group", FT_BOOLEAN, 32,
4013 TFS(&tfs_ndmp_file_invalid_group), 0x00000004, NULL, HFILL, }},
4015 { &hf_ndmp_file_mtime, {
4016 "mtime", "ndmp.file.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
4017 NULL, 0, "Timestamp for mtime for this file", HFILL }},
4019 { &hf_ndmp_file_atime, {
4020 "atime", "ndmp.file.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
4021 NULL, 0, "Timestamp for atime for this file", HFILL }},
4023 { &hf_ndmp_file_ctime, {
4024 "ctime", "ndmp.file.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
4025 NULL, 0, "Timestamp for ctime for this file", HFILL }},
4027 { &hf_ndmp_file_owner, {
4028 "Owner", "ndmp.file.owner", FT_UINT32, BASE_DEC,
4029 NULL, 0, "UID for UNIX, owner for NT", HFILL }},
4031 { &hf_ndmp_file_group, {
4032 "Group", "ndmp.file.group", FT_UINT32, BASE_DEC,
4033 NULL, 0, "GID for UNIX, NA for NT", HFILL }},
4035 { &hf_ndmp_file_fattr, {
4036 "Fattr", "ndmp.file.fattr", FT_UINT32, BASE_HEX,
4037 NULL, 0, "Mode for UNIX, fattr for NT", HFILL }},
4039 { &hf_ndmp_file_size, {
4040 "Size", "ndmp.file.size", FT_UINT64, BASE_DEC,
4041 NULL, 0, "File Size", HFILL }},
4043 { &hf_ndmp_file_links, {
4044 "Links", "ndmp.file.links", FT_UINT32, BASE_DEC,
4045 NULL, 0, "Number of links to this file", HFILL }},
4047 { &hf_ndmp_dirs, {
4048 "Dirs", "ndmp.dirs", FT_NONE, BASE_NONE,
4049 NULL, 0, "List of directories", HFILL }},
4051 { &hf_ndmp_nodes, {
4052 "Nodes", "ndmp.nodes", FT_NONE, BASE_NONE,
4053 NULL, 0, "List of nodes", HFILL }},
4055 { &hf_ndmp_nlist, {
4056 "Nlist", "ndmp.nlist", FT_NONE, BASE_NONE,
4057 NULL, 0, "List of names", HFILL }},
4059 { &hf_ndmp_bu_original_path, {
4060 "Original Path", "ndmp.bu.original_path", FT_STRING, BASE_NONE,
4061 NULL, 0, "Original path where backup was created", HFILL }},
4063 { &hf_ndmp_bu_destination_dir, {
4064 "Destination Dir", "ndmp.bu.destination_dir", FT_STRING, BASE_NONE,
4065 NULL, 0, "Destination directory to restore backup to", HFILL }},
4067 { &hf_ndmp_bu_new_name, {
4068 "New Name", "ndmp.bu.new_name", FT_STRING, BASE_NONE,
4069 NULL, 0, NULL, HFILL }},
4071 { &hf_ndmp_bu_other_name, {
4072 "Other Name", "ndmp.bu.other_name", FT_STRING, BASE_NONE,
4073 NULL, 0, NULL, HFILL }},
4075 { &hf_ndmp_state_invalid, {
4076 "Invalids", "ndmp.bu.state.invalid", FT_UINT32, BASE_HEX,
4077 VALS(file_type_vals), 0, NULL, HFILL }},
4079 { &hf_ndmp_state_invalid_ebr, {
4080 "EstimatedBytesLeft valid", "ndmp.bu.state.invalid.ebr", FT_BOOLEAN, 32,
4081 TFS(&tfs_ndmp_state_invalid_ebr), 0x00000001, "Whether EstimatedBytesLeft is valid or not", HFILL, }},
4083 { &hf_ndmp_state_invalid_etr, {
4084 "EstimatedTimeLeft valid", "ndmp.bu.state.invalid.etr", FT_BOOLEAN, 32,
4085 TFS(&tfs_ndmp_state_invalid_etr), 0x00000002, "Whether EstimatedTimeLeft is valid or not", HFILL, }},
4087 { &hf_ndmp_bu_operation, {
4088 "Operation", "ndmp.bu.operation", FT_UINT32, BASE_DEC,
4089 VALS(bu_operation_vals), 0, "BU Operation", HFILL, }},
4091 { &hf_ndmp_data_state, {
4092 "State", "ndmp.data.state", FT_UINT32, BASE_DEC,
4093 VALS(data_state_vals), 0, "Data state", HFILL, }},
4095 { &hf_ndmp_data_halted, {
4096 "Halted Reason", "ndmp.data.halted", FT_UINT32, BASE_DEC,
4097 VALS(data_halted_vals), 0, "Data halted reason", HFILL, }},
4099 { &hf_ndmp_data_bytes_processed, {
4100 "Bytes Processed", "ndmp.data.bytes_processed", FT_UINT64, BASE_DEC,
4101 NULL, 0, "Number of bytes processed", HFILL }},
4103 { &hf_ndmp_data_est_bytes_remain, {
4104 "Est Bytes Remain", "ndmp.data.est_bytes_remain", FT_UINT64, BASE_DEC,
4105 NULL, 0, "Estimated number of bytes remaining", HFILL }},
4107 { &hf_ndmp_data_est_time_remain, {
4108 "Est Time Remain", "ndmp.data.est_time_remain", FT_RELATIVE_TIME, BASE_NONE,
4109 NULL, 0, "Estimated time remaining", HFILL }},
4110 { &hf_ndmp_lastfrag, {
4111 "Last Fragment", "ndmp.lastfrag", FT_BOOLEAN, 32,
4112 TFS(&tfs_yes_no), RPC_RM_LASTFRAG, NULL, HFILL }},
4113 { &hf_ndmp_fraglen, {
4114 "Fragment Length", "ndmp.fraglen", FT_UINT32, BASE_DEC,
4115 NULL, RPC_RM_FRAGLEN, NULL, HFILL }},
4116 { &hf_ndmp_class_list, {
4117 "Ext Class List", "ndmp.class_list", FT_NONE, BASE_NONE,
4118 NULL, 0, "List of extension classes", HFILL }},
4119 { &hf_ndmp_ex_class_id, {
4120 "Class ID", "ndmp.class.id", FT_UINT32, BASE_HEX,
4121 NULL, 0, NULL, HFILL }},
4122 { &hf_ndmp_ext_version_list, {
4123 "Ext Version List", "ndmp.ext_version_list", FT_NONE, BASE_NONE,
4124 NULL, 0, "List of extension versions", HFILL }},
4125 { &hf_ndmp_ext_version, {
4126 "Ext Version", "ndmp.ext_version_list.version", FT_UINT32, BASE_HEX,
4127 NULL, 0, "Extension version", HFILL }},
4128 { &hf_ndmp_class_version, {
4129 "Class and version", "ndmp.ext_version", FT_NONE, BASE_NONE,
4130 NULL, 0, NULL, HFILL }},
4131 { &hf_ndmp_ex_class_version, {
4132 "Class Version", "ndmp.class.version", FT_UINT32, BASE_HEX,
4133 NULL, 0, NULL, HFILL }},
4134 { &hf_ndmp_fragment_data, {
4135 "NDMP fragment data", "ndmp.fragment_data", FT_BYTES, BASE_NONE,
4136 NULL, 0, NULL, HFILL }},
4137 {&hf_ndmp_fragments, {
4138 "NDMP fragments", "ndmp.fragments", FT_NONE, BASE_NONE,
4139 NULL, 0x00, NULL, HFILL } },
4140 {&hf_ndmp_fragment,
4141 {"NDMP fragment", "ndmp.fragment",
4142 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4143 {&hf_ndmp_fragment_overlap,
4144 {"NDMP fragment overlap", "ndmp.fragment.overlap",
4145 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4146 {&hf_ndmp_fragment_overlap_conflicts,
4147 {"NDMP fragment overlapping with conflicting data",
4148 "ndmp.fragment.overlap.conflicts",
4149 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4150 {&hf_ndmp_fragment_multiple_tails,
4151 {"NDMP has multiple tail fragments",
4152 "ndmp.fragment.multiple_tails",
4153 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4154 {&hf_ndmp_fragment_too_long_fragment,
4155 {"NDMP fragment too long", "ndmp.fragment.too_long_fragment",
4156 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4157 {&hf_ndmp_fragment_error,
4158 {"NDMP defragmentation error", "ndmp.fragment.error",
4159 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4160 {&hf_ndmp_fragment_count,
4161 {"NDMP fragment count", "ndmp.fragment.count",
4162 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
4163 {&hf_ndmp_reassembled_in,
4164 {"Reassembled in", "ndmp.reassembled.in",
4165 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4166 {&hf_ndmp_reassembled_length,
4167 {"Reassembled NDMP length", "ndmp.reassembled.length",
4168 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
4171 static int *ett[] = {
4172 &ett_ndmp,
4173 &ett_ndmp_fraghdr,
4174 &ett_ndmp_header,
4175 &ett_ndmp_butype_attrs,
4176 &ett_ndmp_fs_invalid,
4177 &ett_ndmp_tape_attr,
4178 &ett_ndmp_execute_cdb_flags,
4179 &ett_ndmp_execute_cdb_cdb,
4180 &ett_ndmp_execute_cdb_sns,
4181 &ett_ndmp_execute_cdb_payload,
4182 &ett_ndmp_tape_invalid,
4183 &ett_ndmp_tape_flags,
4184 &ett_ndmp_addr,
4185 &ett_ndmp_file,
4186 &ett_ndmp_file_name,
4187 &ett_ndmp_file_stats,
4188 &ett_ndmp_file_invalids,
4189 &ett_ndmp_state_invalids,
4190 &ett_ndmp_fragment,
4191 &ett_ndmp_fragments,
4194 static ei_register_info ei[] = {
4195 { &ei_ndmp_msg, { "ndmp.msg.unknown", PI_PROTOCOL, PI_WARN, "Unknown type of NDMP message", EXPFILL }},
4198 module_t *ndmp_module;
4199 expert_module_t* expert_ndmp;
4201 proto_ndmp = proto_register_protocol("Network Data Management Protocol", "NDMP", "ndmp");
4202 proto_register_field_array(proto_ndmp, hf_ndmp, array_length(hf_ndmp));
4204 proto_register_subtree_array(ett, array_length(ett));
4205 expert_ndmp = expert_register_protocol(proto_ndmp);
4206 expert_register_field_array(expert_ndmp, ei, array_length(ei));
4208 ndmp_handle = register_dissector("ndmp", dissect_ndmp, proto_ndmp);
4210 /* desegmentation */
4211 ndmp_module = prefs_register_protocol(proto_ndmp, NULL);
4212 prefs_register_obsolete_preference(ndmp_module, "protocol_version");
4213 prefs_register_enum_preference(ndmp_module,
4214 "default_protocol_version",
4215 "Default protocol version",
4216 "Version of the NDMP protocol to assume if the version can not be automatically detected from the capture",
4217 &ndmp_default_protocol_version,
4218 ndmp_protocol_versions,
4219 false);
4220 prefs_register_bool_preference(ndmp_module, "desegment",
4221 "Reassemble NDMP messages spanning multiple TCP segments",
4222 "Whether the NDMP dissector should reassemble messages spanning multiple TCP segments."
4223 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
4224 &ndmp_desegment);
4225 prefs_register_bool_preference(ndmp_module, "defragment",
4226 "Reassemble fragmented NDMP messages spanning multiple packets",
4227 "Whether the dissector should defragment NDMP messages spanning multiple packets.",
4228 &ndmp_defragment);
4229 reassembly_table_register(&ndmp_reassembly_table,
4230 &addresses_reassembly_table_functions);
4233 void
4234 proto_reg_handoff_ndmp(void)
4236 dissector_add_uint_with_preference("tcp.port",TCP_PORT_NDMP, ndmp_handle);
4237 heur_dissector_add("tcp", dissect_ndmp_heur, "NDMP over TCP", "ndmp_tcp", proto_ndmp, HEURISTIC_ENABLE);
4241 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4243 * Local variables:
4244 * c-basic-offset: 8
4245 * tab-width: 8
4246 * indent-tabs-mode: t
4247 * End:
4249 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4250 * :indentSize=8:tabSize=8:noTabs=false: