/* packet-fmp.c * Routines for fmp dissection * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include #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; static int hf_fmp_fsID; static int hf_fmp_fsBlkSz; static int hf_fmp_sessionHandle; static int hf_fmp_fmpFHandle; static int hf_fmp_msgNum; static int hf_fmp_fileSize; static int hf_fmp_cookie; static int hf_fmp_firstLogBlk; static int hf_fmp_numBlksReq; static int proto_fmp; static int hf_fmp_hostID; static int hf_fmp_status; static int hf_fmp_btime; static int hf_fmp_time_sec; static int hf_fmp_time_nsec; static int hf_fmp_notifyPort; static int hf_fmp_minBlks; static int hf_fmp_eof; static int hf_fmp_path; static int hf_fmp_plugInID; static int hf_fmp_plugInBuf; static int hf_fmp_nfsFHandle; static int hf_fmp_extentList_len; static int hf_fmp_extent_state; static int hf_fmp_numBlks; static int hf_fmp_volID; static int hf_fmp_startOffset; static int hf_fmp_volHandle; static int hf_fmp_devSignature; static int hf_fmp_dskSigEnt_val; static int hf_fmp_mount_path; static int hf_fmp_sig_offset; static int hf_fmp_os_major; static int hf_fmp_os_minor; static int hf_fmp_os_name; static int hf_fmp_os_patch; static int hf_fmp_os_build; static int hf_fmp_server_version_string; static int hf_fmp_description; static int hf_fmp_nfsv3Attr_type; static int hf_fmp_nfsv3Attr_mode; static int hf_fmp_nfsv3Attr_nlink; static int hf_fmp_nfsv3Attr_uid; static int hf_fmp_nfsv3Attr_gid; static int hf_fmp_nfsv3Attr_used; static int hf_fmp_nfsv3Attr_rdev; static int hf_fmp_nfsv3Attr_fsid; static int hf_fmp_nfsv3Attr_fileid; static int hf_fmp_cmd; static int hf_fmp_topVolumeId; static int hf_fmp_cursor; static int hf_fmp_offset64; static int hf_fmp_start_offset64; static int hf_fmp_slice_size; static int hf_fmp_volume; static int hf_fmp_stripeSize; static int hf_fmp_firstLogBlk64; static int hf_fmp_native_protocol; static int hf_fmp_encoding_mode; static int hf_fmp_capability; static int hf_fmp_devSerial_query_cmd; static int hf_fmp_volume_desc; static int hf_fmp_disk_identifier; static int hf_fmp_volume_mgmt_type; static int hf_fmp_notify_protocol; static int hf_fmp_client_error_number; /* Generated from convert_proto_tree_add_text.pl */ static int hf_fmp_cap; static int hf_fmp_cap_revoke_handle_list; static int hf_fmp_length_of_volume_list; static int hf_fmp_cap_unc_names; static int hf_fmp_length_of_list; static int hf_fmp_sigoffset; static int hf_fmp_uid; static int hf_fmp_fid; static int hf_fmp_fsid; static int hf_fmp_tid; static int hf_fmp_cifsport; static int hf_fmp_blockindex; static int hf_fmp_number_of_disk; static int hf_fmp_cap_cifsv2; static int hf_fmp_mtime; static int hf_fmp_atime; static int hf_fmp_ctime; static int hf_fmp_heartbeat_interval; static int hf_fmp_volindex; static int ett_fmp; static int ett_fmp_timeval; static int ett_fmp_extList; static int ett_fmp_ext; static int ett_fmp_fileHandle; static int ett_capabilities; static int ett_HierVolumeDescription; static int ett_attrs; static const value_string fmp_encoding_mode_vals[] = { {FMP_ASCII, "ASCII"}, {FMP_UTF8, "UTF8"}, {FMP_UNICODE1, "UNICODE"}, {0,NULL} }; static bool fmp_fhandle_reqrep_matching; 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, uint32_t ext_num) { proto_tree *extTree; extTree = proto_tree_add_subtree_format(tree, tvb, offset, 20 , ett_fmp_ext, NULL, "Extent (%u)", (uint32_t) 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) { uint32_t numExtents; uint32_t totalLength; proto_tree *extListTree; uint32_t 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) { uint32_t numExtents; proto_tree *extListTree; uint32_t 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) { uint32_t cmd; char msg[MAX_MSG_SIZE]; uint32_t 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 = 1U << i; if (cmd & bitValue) { switch (bitValue) { case FMP_COMMIT_SPECIFIED: (void) g_strlcat(msg, "COMMIT_SPECIFIED", MAX_MSG_SIZE); break; case FMP_RELEASE_SPECIFIED: (void) g_strlcat(msg, "RELEASE_SPECIFIED", MAX_MSG_SIZE); break; case FMP_RELEASE_ALL: (void) g_strlcat(msg, "RELEASE_ALL", MAX_MSG_SIZE); break; case FMP_CLOSE_FILE: (void) g_strlcat(msg, "CLOSE_FILE", MAX_MSG_SIZE); break; case FMP_UPDATE_TIME: (void) g_strlcat(msg, "UPDATE_TIME", MAX_MSG_SIZE); break; case FMP_ACCESS_TIME: (void) g_strlcat(msg, "ACCESS_TIME", MAX_MSG_SIZE); break; default: (void) 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) { (void) g_strlcat(msg, " | ", MAX_MSG_SIZE); } } } if (strlen(msg) == 0) { (void) 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