wireshark/epan/dissectors/packet-fmp_notify.c

621 lines
15 KiB
C

/* packet-fmp_notify.c
* Routines for fmp dissection
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <epan/packet.h>
#include "packet-rpc.h"
#include "packet-fmp.h"
void proto_register_fmp_notify(void);
void proto_reg_handoff_fmp_notify(void);
#define FMP_NOTIFY_PROG 1001912
#define FMP_NOTIFY_VERSION_2 2
/*
* FMP/NOTIFY Procedures
*/
#define FMP_NOTIFY_DownGrade 1
#define FMP_NOTIFY_RevokeList 2
#define FMP_NOTIFY_RevokeAll 3
#define FMP_NOTIFY_FileSetEof 4
#define FMP_NOTIFY_RequestDone 5
#define FMP_NOTIFY_volFreeze 6
#define FMP_NOTIFY_revokeHandleList 7
typedef enum {
FMP_LIST_USER_QUOTA_EXCEEDED = 0,
FMP_LIST_GROUP_QUOTA_EXCEEDED = 1,
FMP_LIST_SERVER_RESOURCE_LOW = 2
} revokeHandleListReason;
static int proto_fmp_notify = -1;
static int hf_fmp_handleListLen = -1;
static int hf_fmp_notify_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 hf_fmp_status = -1;
static int hf_fmp_extentList_len = -1;
static int hf_fmp_numBlks = -1;
static int hf_fmp_volID = -1;
static int hf_fmp_startOffset = -1;
static int hf_fmp_extent_state = -1;
static int hf_fmp_revokeHandleListReason = -1;
static gint ett_fmp_notify = -1;
static gint ett_fmp_notify_hlist = -1;
static gint ett_fmp_extList = -1;
static gint ett_fmp_ext = -1;
static int dissect_fmp_notify_extentList(tvbuff_t *, int, packet_info *, proto_tree *);
static int
dissect_fmp_notify_status(tvbuff_t *tvb, int offset, proto_tree *tree, int *rval)
{
fmpStat status;
status = (fmpStat)tvb_get_ntohl(tvb, offset);
switch (status) {
case FMP_OK:
*rval = 0;
break;
case FMP_IOERROR:
*rval = 1;
break;
case FMP_NOMEM:
*rval = 1;
break;
case FMP_NOACCESS:
*rval = 1;
break;
case FMP_INVALIDARG:
*rval = 1;
break;
case FMP_FSFULL:
*rval = 0;
break;
case FMP_QUEUE_FULL:
*rval = 1;
break;
case FMP_WRONG_MSG_NUM:
*rval = 1;
break;
case FMP_SESSION_LOST:
*rval = 1;
break;
case FMP_HOT_SESSION:
*rval = 0;
break;
case FMP_COLD_SESSION:
*rval = 0;
break;
case FMP_CLIENT_TERMINATED:
*rval = 0;
break;
case FMP_WRITER_LOST_BLK:
*rval = 1;
break;
case FMP_REQUEST_QUEUED:
*rval = 0;
break;
case FMP_FALL_BACK:
*rval = 0;
break;
case FMP_REQUEST_CANCELLED:
*rval = 1;
break;
case FMP_WRITER_ZEROED_BLK:
*rval = 0;
break;
case FMP_NOTIFY_ERROR:
*rval = 1;
break;
case FMP_WRONG_HANDLE:
*rval = 0;
break;
case FMP_DUPLICATE_OPEN:
*rval = 1;
break;
case FMP_PLUGIN_NOFUNC:
*rval = 1;
break;
default:
*rval = 1;
break;
}
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_status , offset);
return offset;
}
static int
dissect_revokeHandleListReason(tvbuff_t *tvb, int offset, proto_tree *tree)
{
proto_tree_add_item(tree, hf_fmp_revokeHandleListReason, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
return offset;
}
static int
dissect_handleList(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
proto_tree *tree)
{
int numHandles;
int listLength;
int i;
proto_tree *handleListTree;
numHandles = tvb_get_ntohl(tvb, offset);
listLength = 4;
for (i = 0; i < numHandles; i++) {
listLength += (4 + tvb_get_ntohl(tvb, offset + listLength));
}
handleListTree = proto_tree_add_subtree(tree, tvb, offset, listLength,
ett_fmp_notify_hlist, NULL, "Handle List");
offset = dissect_rpc_uint32(tvb, handleListTree,
hf_fmp_handleListLen, offset);
for (i = 0; i < numHandles; i++) {
offset = dissect_rpc_data(tvb, handleListTree,
hf_fmp_fmpFHandle, offset);/* changed */
}
return offset;
}
static int
dissect_FMP_NOTIFY_DownGrade_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int offset = 0;
offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
offset);
offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_firstLogBlk,
offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_numBlksReq, offset);
return offset;
}
static int
dissect_FMP_NOTIFY_DownGrade_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int rval;
return dissect_fmp_notify_status(tvb, 0,tree, &rval);
}
static int
dissect_FMP_NOTIFY_RevokeList_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int offset = 0;
offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
offset);
offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_firstLogBlk,
offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_numBlksReq, offset);
return offset;
}
static int
dissect_FMP_NOTIFY_RevokeList_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int rval;
return dissect_fmp_notify_status(tvb, 0, tree, &rval);
}
static int
dissect_FMP_NOTIFY_RevokeAll_request(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int offset = 0;
offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
offset);
offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
return offset;
}
static int
dissect_FMP_NOTIFY_RevokeAll_reply(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int rval;
return dissect_fmp_notify_status(tvb, 0, tree, &rval);
}
static int
dissect_FMP_NOTIFY_FileSetEof_request(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int offset = 0;
offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
offset);
offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle, offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum, offset);
offset = dissect_rpc_uint64(tvb, tree, hf_fmp_fileSize, offset);
return offset;
}
static int
dissect_FMP_NOTIFY_FileSetEof_reply(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int rval;
return dissect_fmp_notify_status(tvb, 0, tree, &rval);
}
static int
dissect_FMP_NOTIFY_RequestDone_request(tvbuff_t *tvb,
packet_info *pinfo, proto_tree *tree, void* data _U_)
{
int rval;
int offset = 0;
offset = dissect_fmp_notify_status(tvb, offset,tree, &rval);
if (rval == 0) {
offset = dissect_rpc_data(tvb, tree,
hf_fmp_sessionHandle, offset);
offset = dissect_rpc_data(tvb, tree, hf_fmp_fmpFHandle,
offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_msgNum,
offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_cookie,
offset);
offset = dissect_fmp_notify_extentList(tvb, offset, pinfo, tree);
}
return offset;
}
static int
dissect_FMP_NOTIFY_RequestDone_reply(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int rval;
return dissect_fmp_notify_status(tvb, 0, tree, &rval);
}
static int
dissect_FMP_NOTIFY_volFreeze_request(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int offset = 0;
offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
offset);
offset = dissect_rpc_uint32(tvb, tree, hf_fmp_fsID, offset);
return offset;
}
static int
dissect_FMP_NOTIFY_volFreeze_reply(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int rval;
return dissect_fmp_notify_status(tvb, 0, tree, &rval);
}
static int
dissect_FMP_NOTIFY_revokeHandleList_request(tvbuff_t *tvb,
packet_info *pinfo, proto_tree *tree, void* data _U_)
{
int offset = 0;
offset = dissect_rpc_data(tvb, tree, hf_fmp_sessionHandle,
offset);
offset = dissect_revokeHandleListReason(tvb, offset, tree);
offset = dissect_handleList(tvb, offset, pinfo, tree);
return offset;
}
static int
dissect_FMP_NOTIFY_revokeHandleList_reply(tvbuff_t *tvb,
packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
int rval;
return dissect_fmp_notify_status(tvb, 0, tree, &rval);
}
/*
* proc number, "proc name", dissect_request, dissect_reply
*/
static const vsff fmp_notify2_proc[] = {
{ 0, "NULL",
dissect_rpc_void,
dissect_rpc_void, },
{ FMP_NOTIFY_DownGrade, "DownGrade",
dissect_FMP_NOTIFY_DownGrade_request,
dissect_FMP_NOTIFY_DownGrade_reply },
{ FMP_NOTIFY_RevokeList, "RevokeList",
dissect_FMP_NOTIFY_RevokeList_request,
dissect_FMP_NOTIFY_RevokeList_reply },
{ FMP_NOTIFY_RevokeAll, "RevokeAll",
dissect_FMP_NOTIFY_RevokeAll_request,
dissect_FMP_NOTIFY_RevokeAll_reply },
{ FMP_NOTIFY_FileSetEof, "FileSetEof",
dissect_FMP_NOTIFY_FileSetEof_request,
dissect_FMP_NOTIFY_FileSetEof_reply },
{ FMP_NOTIFY_RequestDone, "RequestDone",
dissect_FMP_NOTIFY_RequestDone_request,
dissect_FMP_NOTIFY_RequestDone_reply },
{ FMP_NOTIFY_volFreeze, "volFreeze",
dissect_FMP_NOTIFY_volFreeze_request,
dissect_FMP_NOTIFY_volFreeze_reply },
{ FMP_NOTIFY_revokeHandleList, "revokeHandleList",
dissect_FMP_NOTIFY_revokeHandleList_request,
dissect_FMP_NOTIFY_revokeHandleList_reply },
{ 0, NULL, NULL, NULL }
};
static const rpc_prog_vers_info fmp_notify_vers_info[] = {
{ FMP_NOTIFY_VERSION_2, fmp_notify2_proc, &hf_fmp_notify_procedure }
};
static const value_string fmp_notify_proc_vals[] = {
{ 0, "NULL" },
{ 1, "DownGrade" },
{ 2, "RevokeList" },
{ 3, "RevokeAll" },
{ 4, "FileSetEof" },
{ 5, "RequestDone" },
{ 6, "VolFreeze" },
{ 7, "RevokeHandleList" },
{ 0,NULL}
};
static const value_string fmp_status_vals[] = {
{ 0, "OK"},
{ 5, "IOERROR"},
{ 12, "NOMEM"},
{ 13, "NOACCESS"},
{ 22, "INVALIDARG"},
{ 28, "FSFULL"},
{ 79, "QUEUE_FULL"},
{500, "WRONG_MSG_NUM"},
{501, "SESSION_LOST"},
{502, "HOT_SESSION"},
{503, "COLD_SESSION"},
{504, "CLIENT_TERMINATED"},
{505, "WRITER_LOST_BLK"},
{506, "FMP_REQUEST_QUEUED"},
{507, "FMP_FALL_BACK"},
{508, "REQUEST_CANCELLED"},
{509, "WRITER_ZEROED_BLK"},
{510, "NOTIFY_ERROR"},
{511, "FMP_WRONG_HANDLE"},
{512, "DUPLICATE_OPEN"},
{600, "PLUGIN_NOFUNC"},
{0,NULL}
};
static const value_string fmp_revokeHandleListReason_vals[] = {
{FMP_LIST_USER_QUOTA_EXCEEDED, "LIST_USER_QUOTA_EXCEEDED"},
{FMP_LIST_GROUP_QUOTA_EXCEEDED, "LIST_GROUP_QUOTA_EXCEEDED"},
{FMP_LIST_SERVER_RESOURCE_LOW, "LIST_SERVER_RESOURCE_LOW"},
{0,NULL}
};
static int
dissect_fmp_notify_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_notify_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_notify_extentState(tvb, offset, extTree);
return offset;
}
static int
dissect_fmp_notify_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_notify_extent(tvb, offset, pinfo, extListTree, i+1);
}
return offset;
}
void
proto_register_fmp_notify(void)
{
static hf_register_info hf[] = {
{ &hf_fmp_notify_procedure, {
"Procedure", "fmp_notify.notify_procedure", FT_UINT32, BASE_DEC,
VALS(fmp_notify_proc_vals) , 0, NULL, HFILL }}, /* New addition */
{ &hf_fmp_status, {
"Status", "fmp_notify.status", FT_UINT32, BASE_DEC,
VALS(fmp_status_vals), 0, "Reply Status", HFILL }},
{ &hf_fmp_extentList_len, {
"Extent List length", "fmp_notify.extentListLength",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_fmp_numBlks, {
"Number Blocks", "fmp_notify.numBlks", FT_UINT32,
BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_fmp_volID, {
"Volume ID", "fmp_notify.volID", FT_UINT32,
BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_fmp_startOffset, {
"Start Offset", "fmp_notify.startOffset", FT_UINT32,
BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_fmp_extent_state, {
"Extent State", "fmp_notify.extentState", FT_UINT32,
BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_fmp_handleListLen, {
"Number of File Handles", "fmp_notify.handleListLength",
FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_fmp_sessionHandle, {
"Session Handle", "fmp_notify.sessHandle", FT_BYTES, BASE_NONE,
NULL, 0, NULL, HFILL }},
{ &hf_fmp_fsID, {
"File System ID", "fmp_notify.fsID", FT_UINT32, BASE_HEX,
NULL, 0, NULL, HFILL }},
#if 0
{ &hf_fmp_fsBlkSz, {
"FS Block Size", "fmp_notify.fsBlkSz", FT_UINT32, BASE_DEC,
NULL, 0, NULL, HFILL }},
#endif
{ &hf_fmp_numBlksReq, {
"Number Blocks Requested", "fmp_notify.numBlksReq", FT_UINT32,
BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_fmp_msgNum, {
"Message Number", "fmp_notify.msgNum", FT_UINT32, BASE_DEC,
NULL, 0, NULL, HFILL }},
{ &hf_fmp_cookie, {
"Cookie", "fmp_notify.cookie", FT_UINT32, BASE_HEX,
NULL, 0, "Cookie for FMP_REQUEST_QUEUED Resp", HFILL }},
{ &hf_fmp_firstLogBlk, {
"First Logical Block", "fmp_notify.firstLogBlk", FT_UINT32,
BASE_DEC, NULL, 0, "First Logical File Block", HFILL }},
{ &hf_fmp_fileSize, {
"File Size", "fmp_notify.fileSize", FT_UINT64, BASE_DEC,
NULL, 0, NULL, HFILL }},
{ &hf_fmp_fmpFHandle, {
"FMP File Handle", "fmp_notify.fmpFHandle",
FT_BYTES, BASE_NONE, NULL, 0, NULL,
HFILL }},
{ &hf_fmp_revokeHandleListReason,
{ "Reason", "fmp.revokeHandleListReason",
FT_UINT32, BASE_DEC, VALS(fmp_revokeHandleListReason_vals), 0,
NULL, HFILL }},
};
static gint *ett[] = {
&ett_fmp_notify,
&ett_fmp_notify_hlist,
&ett_fmp_extList,
&ett_fmp_ext
};
proto_fmp_notify =
proto_register_protocol("File Mapping Protocol Notify",
"FMP/NOTIFY", "fmp_notify");
proto_register_field_array(proto_fmp_notify, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_fmp_notify(void)
{
/* Register the protocol as RPC */
rpc_init_prog(proto_fmp_notify, FMP_NOTIFY_PROG, ett_fmp_notify,
G_N_ELEMENTS(fmp_notify_vers_info), fmp_notify_vers_info);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/