/* packet-fmp.c * Routines for fmp dissection * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "packet-fmp.h" #include "packet-rpc.h" void proto_register_fmp(void); void proto_reg_handoff_fmp(void); static int hf_fmp_procedure = -1; static int hf_fmp_fsID = -1; static int hf_fmp_fsBlkSz = -1; static int hf_fmp_sessionHandle = -1; static int hf_fmp_fmpFHandle = -1; static int hf_fmp_msgNum = -1; static int hf_fmp_fileSize = -1; static int hf_fmp_cookie = -1; static int hf_fmp_firstLogBlk = -1; static int hf_fmp_numBlksReq = -1; static int proto_fmp = -1; static int hf_fmp_hostID = -1; static int hf_fmp_status = -1; static int hf_fmp_btime = -1; static int hf_fmp_time_sec = -1; static int hf_fmp_time_nsec = -1; static int hf_fmp_notifyPort = -1; static int hf_fmp_minBlks = -1; static int hf_fmp_eof = -1; static int hf_fmp_path = -1; static int hf_fmp_plugInID = -1; static int hf_fmp_plugInBuf = -1; static int hf_fmp_nfsFHandle = -1; static int hf_fmp_extentList_len = -1; static int hf_fmp_extent_state = -1; static int hf_fmp_numBlks = -1; static int hf_fmp_volID = -1; static int hf_fmp_startOffset = -1; static int hf_fmp_volHandle = -1; static int hf_fmp_devSignature = -1; static int hf_fmp_dskSigEnt_val = -1; static int hf_fmp_mount_path = -1; static int hf_fmp_sig_offset = -1; static int hf_fmp_os_major = -1; static int hf_fmp_os_minor = -1; static int hf_fmp_os_name = -1; static int hf_fmp_os_patch = -1; static int hf_fmp_os_build = -1; static int hf_fmp_server_version_string = -1; static int hf_fmp_description = -1; static int hf_fmp_nfsv3Attr_type = -1; static int hf_fmp_nfsv3Attr_mode = -1; static int hf_fmp_nfsv3Attr_nlink = -1; static int hf_fmp_nfsv3Attr_uid = -1; static int hf_fmp_nfsv3Attr_gid = -1; static int hf_fmp_nfsv3Attr_used = -1; static int hf_fmp_nfsv3Attr_rdev = -1; static int hf_fmp_nfsv3Attr_fsid = -1; static int hf_fmp_nfsv3Attr_fileid = -1; static int hf_fmp_cmd = -1; static int hf_fmp_topVolumeId = -1; static int hf_fmp_cursor = -1; static int hf_fmp_offset64 = -1; static int hf_fmp_start_offset64 = -1; static int hf_fmp_slice_size = -1; static int hf_fmp_volume = -1; static int hf_fmp_stripeSize = -1; static int hf_fmp_firstLogBlk64 =-1; static int hf_fmp_native_protocol = -1; static int hf_fmp_encoding_mode = -1; static int hf_fmp_capability = -1; static int hf_fmp_devSerial_query_cmd = -1; static int hf_fmp_volume_desc = -1; static int hf_fmp_disk_identifier = -1; static int hf_fmp_volume_mgmt_type = -1; static int hf_fmp_notify_protocol = -1; static int hf_fmp_client_error_number = -1; /* Generated from convert_proto_tree_add_text.pl */ static int hf_fmp_cap = -1; static int hf_fmp_cap_revoke_handle_list = -1; static int hf_fmp_length_of_volume_list = -1; static int hf_fmp_cap_unc_names = -1; static int hf_fmp_length_of_list = -1; static int hf_fmp_sigoffset = -1; static int hf_fmp_uid = -1; static int hf_fmp_fid = -1; static int hf_fmp_fsid = -1; static int hf_fmp_tid = -1; static int hf_fmp_cifsport = -1; static int hf_fmp_blockindex = -1; static int hf_fmp_number_of_disk = -1; static int hf_fmp_cap_cifsv2 = -1; static int hf_fmp_mtime = -1; static int hf_fmp_atime = -1; static int hf_fmp_ctime = -1; static int hf_fmp_heartbeat_interval = -1; static int hf_fmp_volindex = -1; static gint ett_fmp = -1; static gint ett_fmp_timeval = -1; static gint ett_fmp_extList = -1; static gint ett_fmp_ext = -1; static gint ett_fmp_fileHandle = -1; static gint ett_capabilities = -1; static gint ett_HierVolumeDescription = -1; static gint ett_attrs = -1; static const value_string fmp_encoding_mode_vals[] = { {FMP_ASCII, "ASCII"}, {FMP_UTF8, "UTF8"}, {FMP_UNICODE1, "UNICODE"}, {0,NULL} }; static gboolean fmp_fhandle_reqrep_matching = FALSE; static int dissect_fmp_genString(tvbuff_t *tvb, int offset, proto_tree *tree) { proto_tree_add_item(tree, hf_fmp_encoding_mode, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; if (try_val_to_str(tvb_get_ntohl(tvb, offset), fmp_encoding_mode_vals) == NULL) return offset; offset = dissect_rpc_string(tvb, tree, hf_fmp_path, offset, NULL); return offset; } static int get_fileHandleSrc_size(tvbuff_t *tvb, int offset) { int length; nativeProtocol np; np = (nativeProtocol)tvb_get_ntohl(tvb, offset); switch (np) { case FMP_PATH: length = 4 + FMP_MAX_PATH_LEN; break; case FMP_NFS: length = 8 + tvb_get_ntohl(tvb, offset + 4); break; case FMP_CIFS: length = 10; break; case FMP_FMP: length = 8 + tvb_get_ntohl(tvb, offset + 4); break; case FMP_FS_ONLY: length = 8; break; case FMP_SHARE: /* FALLTHROUGH */ case FMP_MOUNT: length = 8 + FMP_MAX_PATH_LEN; break; default: length = 4; break; } return length; } static int dissect_fmp_fileHandleSrc(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { nativeProtocol np; proto_tree *fileHandleTree; int length; length = get_fileHandleSrc_size(tvb, offset); fileHandleTree = proto_tree_add_subtree(tree, tvb, offset, length, ett_fmp_fileHandle, NULL, "Source File Handle"); np = (nativeProtocol)tvb_get_ntohl(tvb, offset); proto_tree_add_item(fileHandleTree, hf_fmp_native_protocol, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; switch (np) { case FMP_PATH: offset = dissect_rpc_string(tvb, fileHandleTree, hf_fmp_mount_path, offset, NULL); break; case FMP_NFS: offset = dissect_rpc_data(tvb, fileHandleTree, hf_fmp_nfsFHandle, offset); break; case FMP_CIFS: proto_tree_add_item(fileHandleTree, hf_fmp_fid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(fileHandleTree, hf_fmp_tid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(fileHandleTree, hf_fmp_uid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; break; case FMP_FMP: offset = dissect_rpc_string(tvb, fileHandleTree, hf_fmp_fmpFHandle, offset, NULL); break; case FMP_FS_ONLY: proto_tree_add_item(fileHandleTree, hf_fmp_fsid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case FMP_SHARE: offset = dissect_fmp_genString(tvb, offset, fileHandleTree); break; case FMP_MOUNT: offset = dissect_fmp_genString(tvb, offset, fileHandleTree); break; case FMP_CIFSV2: proto_tree_add_item(fileHandleTree, hf_fmp_fid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(fileHandleTree, hf_fmp_tid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(fileHandleTree, hf_fmp_uid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(fileHandleTree, hf_fmp_cifsport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; break; case FMP_UNC: offset = dissect_fmp_genString(tvb, offset, fileHandleTree); break; default: break; } return offset; } static int dissect_fmp_extentState(tvbuff_t *tvb, int offset, proto_tree *tree) { offset = dissect_rpc_uint32(tvb, tree, hf_fmp_extent_state, offset); return offset; } static int dissect_fmp_extent(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint32 ext_num) { proto_tree *extTree; extTree = proto_tree_add_subtree_format(tree, tvb, offset, 20 , ett_fmp_ext, NULL, "Extent (%u)", (guint32) ext_num); offset = dissect_rpc_uint32(tvb, extTree, hf_fmp_firstLogBlk, offset); offset = dissect_rpc_uint32(tvb, extTree, hf_fmp_numBlks, offset); offset = dissect_rpc_uint32(tvb, extTree, hf_fmp_volID, offset); offset = dissect_rpc_uint32(tvb, extTree, hf_fmp_startOffset, offset); offset = dissect_fmp_extentState(tvb, offset, extTree); return offset; } static int dissect_fmp_extentList(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint32 numExtents; guint32 totalLength; proto_tree *extListTree; guint32 i; numExtents = tvb_get_ntohl(tvb, offset); totalLength = 4 + (20 * numExtents); extListTree = proto_tree_add_subtree(tree, tvb, offset, totalLength, ett_fmp_extList, NULL, "Extent List"); offset = dissect_rpc_uint32(tvb, extListTree, hf_fmp_extentList_len, offset); for (i = 0; i < numExtents; i++) { offset = dissect_fmp_extent(tvb, offset, pinfo, extListTree, i+1); } return offset; } static int dissect_fmp_extentListEx(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { guint32 numExtents; proto_tree *extListTree; guint32 i; numExtents = tvb_get_ntohl(tvb, offset); offset += 4; for (i = 0; i < numExtents; i++) { extListTree = proto_tree_add_subtree(tree, tvb, offset, 28, ett_fmp_extList, NULL, "Extent List"); offset = dissect_rpc_uint64(tvb,extListTree , hf_fmp_firstLogBlk64, offset); offset = dissect_rpc_uint32(tvb,extListTree , hf_fmp_numBlksReq, offset); offset = dissect_rpc_uint32(tvb,extListTree , hf_fmp_volID, offset); offset = dissect_rpc_uint64(tvb,extListTree , hf_fmp_start_offset64, offset); offset = dissect_fmp_extentState(tvb, offset, extListTree); } return offset; } static int dissect_plugInID(tvbuff_t *tvb, int offset, proto_tree *tree) { if (!tree) { return offset; } proto_tree_add_item(tree, hf_fmp_plugInID, tvb, offset, FMP_PLUG_IN_ID_SZ, ENC_NA); return offset; } static int dissect_fmp_flushCmd(tvbuff_t *tvb, int offset, proto_tree *tree) { guint32 cmd; char msg[MAX_MSG_SIZE]; guint32 bitValue; int i; if (tree) { cmd = tvb_get_ntohl(tvb, offset); /* Initialize the message for an empty string */ msg[0] = '\0'; for (i = 0; cmd != 0 && i < 32; i++) { bitValue = 1 << i; if (cmd & bitValue) { switch (bitValue) { case FMP_COMMIT_SPECIFIED: g_strlcat(msg, "COMMIT_SPECIFIED", MAX_MSG_SIZE); break; case FMP_RELEASE_SPECIFIED: g_strlcat(msg, "RELEASE_SPECIFIED", MAX_MSG_SIZE); break; case FMP_RELEASE_ALL: g_strlcat(msg, "RELEASE_ALL", MAX_MSG_SIZE); break; case FMP_CLOSE_FILE: g_strlcat(msg, "CLOSE_FILE", MAX_MSG_SIZE); break; case FMP_UPDATE_TIME: g_strlcat(msg, "UPDATE_TIME", MAX_MSG_SIZE); break; case FMP_ACCESS_TIME: g_strlcat(msg, "ACCESS_TIME", MAX_MSG_SIZE); break; default: g_strlcat(msg, "UNKNOWN", MAX_MSG_SIZE); break; } /* clear the bit that we processed */ cmd &= ~bitValue; /* add a "bitwise inclusive OR" symbol between cmds */ if (cmd) { g_strlcat(msg, " | ", MAX_MSG_SIZE); } } } if (strlen(msg) == 0) { g_strlcpy(msg, "No command specified", MAX_MSG_SIZE); } proto_tree_add_uint_format_value(tree, hf_fmp_cmd, tvb, offset, 4, cmd, "%s", msg); } offset += 4; return offset; } static int dissect_InterpretVolMgtStuff(tvbuff_t *tvb, int offset, proto_tree *tree) { int length, numdisks, i, j; numdisks = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_fmp_number_of_disk, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; for (i=0; i