/* packet-fmp.c * Routines for fmp dissection * * $Id$ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "packet-fmp.h" #include "packet-rpc.h" int hf_fmp_procedure = -1; int hf_fmp_fsID = -1; int hf_fmp_fsBlkSz = -1; int hf_fmp_sessionHandle = -1; int hf_fmp_fmpFHandle = -1; int hf_fmp_msgNum = -1; int hf_fmp_fileSize = -1; int hf_fmp_cookie = -1; int hf_fmp_firstLogBlk = -1; 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 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; gboolean fmp_fhandle_reqrep_matching = FALSE; int dissect_fmp_genString(tvbuff_t *tvb, int offset, proto_tree *tree) { encoding mode; mode = tvb_get_ntohl(tvb, offset); switch (mode) { case FMP_ASCII: proto_tree_add_text(tree, tvb, offset, 4, "Encoding Mode: ASCII (%d)", mode); break; case FMP_UTF8: proto_tree_add_text(tree, tvb, offset, 4, "Encoding Mode: UTF8 (%d)", mode); break; case FMP_UNICODE1: proto_tree_add_text(tree, tvb, offset, 4, "Encoding Mode: UNICODE (%d)", mode); break; default: proto_tree_add_text(tree, tvb, offset, 4, "Encoding Mode: UNKNOWN (%d)", mode); offset += 4; return offset; } offset += 4; 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 = 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; } int dissect_fmp_fileHandleSrc(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { nativeProtocol np; proto_item *fileHandleItem; proto_tree *fileHandleTree; int length; length = get_fileHandleSrc_size(tvb, offset); np = tvb_get_ntohl(tvb, offset); fileHandleItem = proto_tree_add_text(tree, tvb, offset, length, "Source File Handle"); fileHandleTree = proto_item_add_subtree(fileHandleItem, ett_fmp_fileHandle); switch (np) { case FMP_PATH: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: PATH (%d)", np); offset += 4; offset = dissect_rpc_string(tvb, fileHandleTree, hf_fmp_mount_path, offset, NULL); break; case FMP_NFS: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: NFS (%d)", np); offset += 4; offset = dissect_rpc_data(tvb, fileHandleTree, hf_fmp_nfsFHandle, offset); break; case FMP_CIFS: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: CIFS (%d)", np); offset += 4; proto_tree_add_text(fileHandleTree, tvb, offset, 2, "fid: %d", tvb_get_ntohs(tvb, offset)); offset += 2; proto_tree_add_text(fileHandleTree, tvb, offset, 2, "tid: %d", tvb_get_ntohs(tvb, offset)); offset += 2; proto_tree_add_text(fileHandleTree, tvb, offset, 2, "uid: %d", tvb_get_ntohs(tvb, offset)); offset += 2; break; case FMP_FMP: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: FMP (%d)", np); offset += 4; offset = dissect_rpc_string(tvb, fileHandleTree, hf_fmp_fmpFHandle, offset, NULL); break; case FMP_FS_ONLY: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: FS_ONLY (%d)", np); offset += 4; proto_tree_add_text(fileHandleTree, tvb, offset, 4, "FsID: %d", tvb_get_ntohl(tvb, offset)); offset += 4; break; case FMP_SHARE: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: SHARE (%d)", np); offset += 4; offset = dissect_fmp_genString(tvb, offset, fileHandleTree); break; case FMP_MOUNT: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: MOUNT (%d)", np); offset += 4; offset = dissect_fmp_genString(tvb, offset, fileHandleTree); break; case FMP_CIFSV2: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: CIFSV2: (%d)", np); offset += 4; proto_tree_add_text(fileHandleTree, tvb, offset, 2, "fid : %d", tvb_get_ntohs(tvb, offset)); offset += 2; proto_tree_add_text(fileHandleTree, tvb, offset, 2, "tid : %d", tvb_get_ntohs(tvb, offset)); offset += 2; proto_tree_add_text(fileHandleTree, tvb, offset, 2, "uid : %d", tvb_get_ntohs(tvb, offset)); offset += 2; proto_tree_add_text(fileHandleTree, tvb, offset, 2, "cifsPort: %d", tvb_get_ntohs(tvb, offset)); offset += 2; break; case FMP_UNC: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: UNC: (%d)", np); offset += 4; offset = dissect_fmp_genString(tvb, offset, fileHandleTree); break; default: proto_tree_add_text(fileHandleTree, tvb, offset, 4, "Native Protocol: UNKNOWN (%d)", np); offset += 4; break; } return offset; } int dissect_fmp_extentState(tvbuff_t *tvb, int offset, proto_tree *tree) { extentState state; if (!tree) { return offset; } state = tvb_get_ntohl(tvb, offset); offset = dissect_rpc_uint32(tvb, tree, hf_fmp_extent_state, offset); return offset; } int dissect_fmp_extent(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint32 ext_num) { proto_item *extItem; proto_tree *extTree; if (!tree) { return offset; } extItem = proto_tree_add_text(tree, tvb, offset, 20 , "Extent (%u)", (guint32) ext_num); extTree = proto_item_add_subtree(extItem, ett_fmp_ext); 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; } int dissect_fmp_extentList(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint32 numExtents; guint32 totalLength; proto_item *extListItem; proto_tree *extListTree; guint32 i; if (!tree) { return offset; } numExtents = tvb_get_ntohl(tvb, offset); totalLength = 4 + (20 * numExtents); extListItem = proto_tree_add_text(tree, tvb, offset, totalLength, "Extent List"); extListTree = proto_item_add_subtree(extListItem, ett_fmp_extList); offset = dissect_rpc_uint32(tvb, extListTree, hf_fmp_extentList_len, offset); for (i = 1; i <= numExtents; i++) { offset = dissect_fmp_extent(tvb, offset, pinfo, extListTree, i); } return offset; } int dissect_fmp_extentListEx(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { guint32 numExtents; proto_item *extListItem; proto_tree *extListTree; guint32 i; if (!tree) { return offset; } numExtents = tvb_get_ntohl(tvb, offset); offset += 4; for (i = 1; i <= numExtents; i++) { extListItem = proto_tree_add_text(tree, tvb, offset, 28, "Extent List"); extListTree = proto_item_add_subtree(extListItem, ett_fmp_extList); 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; } int dissect_plugInID(tvbuff_t *tvb, int offset, proto_tree *tree) { const guint8 *plugInID; if (!tree) { return offset; } plugInID = tvb_get_ptr(tvb, offset, FMP_PLUG_IN_ID_SZ); proto_tree_add_bytes(tree, hf_fmp_plugInID, tvb, offset, FMP_PLUG_IN_ID_SZ, plugInID); return offset; } 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) { return offset; } 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_text(tree, tvb, offset, 4, "Cmd: %s", msg); offset += 4; return offset; } 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_text(tree, tvb, offset, 4, "Number of Disk: %d", numdisks); offset += 4; for(i=0;i