wireshark/epan/dissectors/packet-ocfs2.c

1693 lines
47 KiB
C

/*
* packet-ocfs2.c
*
* Routines for OCFS2's networking protocol disassembly (o2net and o2dlm)
* The OCFS2 cluster file system is available in the mainline Linux kernel.
*
* Copyright (C) 2006, 2011 Oracle. All rights reserved.
*
* Authors:
* Kurt Hackel <kurt.hackel@oracle.com>
* Zach Brown <zach.brown@oracle.com>
* Sunil Mushran <sunil.mushran@oracle.com>
* Jeff Liu <jeff.liu@oracle.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <epan/packet.h>
#include "packet-tcp.h"
void proto_register_ocfs2(void);
void proto_reg_handoff_ocfs2(void);
static gint ett_ocfs2 = -1;
static gint ett_dtm_lock_flags = -1;
static gint ett_mres_flags = -1;
static gint ett_migrate_lockres_locks = -1;
static gint ett_query_nodeinfo = -1;
static int proto_ocfs2 = -1;
static int hf_msg_magic = -1;
static int hf_msg_data_len = -1;
static int hf_msg_msg_type = -1;
static int hf_msg_sys_status = -1;
static int hf_msg_status = -1;
static int hf_msg_key = -1;
static int hf_msg_msg_num = -1;
static int hf_msg_pad = -1;
static int hf_dlm_node_idx = -1;
static int hf_dlm_lock_flags = -1;
static int hf_dlm_lock_flag_unused1 = -1;
static int hf_dlm_lock_flag_orphan = -1;
static int hf_dlm_lock_flag_parentable = -1;
static int hf_dlm_lock_flag_block = -1;
static int hf_dlm_lock_flag_local = -1;
static int hf_dlm_lock_flag_valblk = -1;
static int hf_dlm_lock_flag_noqueue = -1;
static int hf_dlm_lock_flag_convert = -1;
static int hf_dlm_lock_flag_nodlckwt = -1;
static int hf_dlm_lock_flag_unlock = -1;
static int hf_dlm_lock_flag_cancel = -1;
static int hf_dlm_lock_flag_deqall = -1;
static int hf_dlm_lock_flag_invvalblk = -1;
static int hf_dlm_lock_flag_syncsts = -1;
static int hf_dlm_lock_flag_timeout = -1;
static int hf_dlm_lock_flag_sngldlck = -1;
static int hf_dlm_lock_flag_findlocal = -1;
static int hf_dlm_lock_flag_proc_owned = -1;
static int hf_dlm_lock_flag_xid = -1;
static int hf_dlm_lock_flag_xid_conflict = -1;
static int hf_dlm_lock_flag_force = -1;
static int hf_dlm_lock_flag_revvalblk = -1;
static int hf_dlm_lock_flag_unused2 = -1;
static int hf_dlm_lock_flag_migration = -1;
static int hf_dlm_lock_flag_put_lvb = -1;
static int hf_dlm_lock_flag_get_lvb = -1;
static int hf_dlm_lock_flag_recovery = -1;
static int hf_dlm_am_flags = -1;
static int hf_dlm_fr_flags = -1;
static int hf_dlm_namelen = -1;
static int hf_dlm_name = -1;
static int hf_dlm_cookie = -1;
static int hf_dlm_requested_type = -1;
static int hf_dlm_lvb1 = -1;
static int hf_dlm_lvb2 = -1;
static int hf_dlm_lvb3 = -1;
static int hf_dlm_ast_type = -1;
static int hf_dlm_blocked_type = -1;
static int hf_dlm_dead_node = -1;
static int hf_dlm_domain_name_len = -1;
static int hf_dlm_domain_name = -1;
static int hf_dlm_proto_ver = -1;
static int hf_dlm_fs_proto_ver = -1;
static int hf_dlm_node_map = -1;
static int hf_dlm_master = -1;
static int hf_dlm_new_master = -1;
static int hf_dlm_mres_num_locks = -1;
static int hf_dlm_mres_flags = -1;
static int hf_dlm_mres_flag_recovery = -1;
static int hf_dlm_mres_flag_migration = -1;
static int hf_dlm_mres_flag_all_done = -1;
static int hf_dlm_mres_total_locks = -1;
static int hf_dlm_mres_mig_cookie = -1;
static int hf_dlm_mres_list = -1;
static int hf_dlm_mres_ml_flags = -1;
static int hf_dlm_mres_type = -1;
static int hf_dlm_mres_convert_type = -1;
static int hf_dlm_mres_highest_blocked = -1;
static int hf_dlm_mres_node = -1;
static int hf_dlm_qr_node = -1;
static int hf_dlm_qr_numregions = -1;
static int hf_dlm_qr_namelen = -1;
static int hf_dlm_qr_domain = -1;
static int hf_dlm_qr_region = -1;
static int hf_dlm_qn_nodenum = -1;
static int hf_dlm_qn_numnodes = -1;
static int hf_dlm_qn_namelen = -1;
static int hf_dlm_qn_domain = -1;
static int hf_dlm_qn_node = -1;
static int hf_dlm_qn_port = -1;
static int hf_dlm_qn_ip = -1;
static int hf_dlm_reco_lvb = -1;
static int hf_dlm_pad8 = -1;
static int hf_dlm_pad16 = -1;
static int hf_dlm_pad32 = -1;
static int hf_dlm_flags = -1;
static int hf_dlm_payload = -1;
#define O2NM_MAX_NAME_LEN 64
#define O2NM_NODE_MAP_IN_BYTES 32
#define OCFS2_DENTRY_LOCK_INO_START 18
/*
* generic o2net constants
*/
#define O2NET_MSG_MAGIC 0xfa55
#define O2NET_MSG_STATUS_MAGIC 0xfa56
#define O2NET_MSG_KEEP_REQ_MAGIC 0xfa57
#define O2NET_MSG_KEEP_RESP_MAGIC 0xfa58
static const value_string o2net_magic[] = {
{ O2NET_MSG_MAGIC, "Request" },
{ O2NET_MSG_STATUS_MAGIC, "Response" },
{ O2NET_MSG_KEEP_REQ_MAGIC, "Keepalive Request" },
{ O2NET_MSG_KEEP_RESP_MAGIC, "Keepalive Response" },
{ 0x0000, NULL }
};
/* DLM constants */
#define DLM_LVB_LEN 64
#define DLM_MOD_KEY (0x666c6172)
#if 0
enum dlm_query_join_response {
JOIN_DISALLOW = 0,
JOIN_OK,
JOIN_OK_NO_MAP,
JOIN_PROTOCOL_MISMATCH
};
#endif
/* DLM lock modes */
enum {
LKM_IVMODE = -1,
LKM_NLMODE = 0,
LKM_CRMODE,
LKM_CWMODE,
LKM_PRMODE,
LKM_PWMODE,
LKM_EXMODE,
LKM_MAXMODE
};
static const value_string dlm_lock_modes[] = {
{ LKM_IVMODE, "IV" },
{ LKM_NLMODE, "NL" },
{ LKM_CRMODE, "CR" },
{ LKM_CWMODE, "CW" },
{ LKM_PRMODE, "PR" },
{ LKM_PWMODE, "PW" },
{ LKM_EXMODE, "EX" },
{ 0x0000, NULL }
};
/* DLM message types */
enum {
DLM_MASTER_REQUEST_MSG = 500,
DLM_UNUSED_MSG1 = 501,
DLM_ASSERT_MASTER_MSG = 502,
DLM_CREATE_LOCK_MSG = 503,
DLM_CONVERT_LOCK_MSG = 504,
DLM_PROXY_AST_MSG = 505,
DLM_UNLOCK_LOCK_MSG = 506,
DLM_DEREF_LOCKRES_MSG = 507,
DLM_MIGRATE_REQUEST_MSG = 508,
DLM_MIG_LOCKRES_MSG = 509,
DLM_QUERY_JOIN_MSG = 510,
DLM_ASSERT_JOINED_MSG = 511,
DLM_CANCEL_JOIN_MSG = 512,
DLM_EXIT_DOMAIN_MSG = 513,
DLM_MASTER_REQUERY_MSG = 514,
DLM_LOCK_REQUEST_MSG = 515,
DLM_RECO_DATA_DONE_MSG = 516,
DLM_BEGIN_RECO_MSG = 517,
DLM_FINALIZE_RECO_MSG = 518,
DLM_QUERY_REGION_MSG = 519,
DLM_QUERY_NODEINFO_MSG = 520
};
static const value_string dlm_magic[] = {
{ DLM_MASTER_REQUEST_MSG, "Master Request" },
{ DLM_UNUSED_MSG1, "Unused 1" },
{ DLM_ASSERT_MASTER_MSG, "Assert Master" },
{ DLM_CREATE_LOCK_MSG, "Create Lock" },
{ DLM_CONVERT_LOCK_MSG, "Convert Lock" },
{ DLM_PROXY_AST_MSG, "Proxy AST" },
{ DLM_UNLOCK_LOCK_MSG, "Unlock Lock" },
{ DLM_DEREF_LOCKRES_MSG, "Deref Lockres" },
{ DLM_MIGRATE_REQUEST_MSG, "Migrate Request" },
{ DLM_MIG_LOCKRES_MSG, "Migrate Lockres" },
{ DLM_QUERY_JOIN_MSG, "Query Join" },
{ DLM_ASSERT_JOINED_MSG, "Assert Join" },
{ DLM_CANCEL_JOIN_MSG, "Cancel Join" },
{ DLM_EXIT_DOMAIN_MSG, "Exit Domain" },
{ DLM_MASTER_REQUERY_MSG, "Master Requery" },
{ DLM_LOCK_REQUEST_MSG, "Lock Request" },
{ DLM_RECO_DATA_DONE_MSG, "Recovery Data Done" },
{ DLM_BEGIN_RECO_MSG, "Begin Recovery" },
{ DLM_FINALIZE_RECO_MSG, "Finalize Recovery" },
{ DLM_QUERY_REGION_MSG, "Query Region" },
{ DLM_QUERY_NODEINFO_MSG, "Query Node Info" },
{ 0x0000, NULL }
};
static value_string_ext ext_dlm_magic = VALUE_STRING_EXT_INIT(dlm_magic);
enum {
DLM_GRANTED_LIST = 0,
DLM_CONVERTING_LIST,
DLM_BLOCKED_LIST,
DLM_MAX_LIST
};
static const value_string dlm_lockres_list[] = {
{ DLM_GRANTED_LIST, "Granted" },
{ DLM_CONVERTING_LIST, "Converting" },
{ DLM_BLOCKED_LIST, "Blocked" },
{ 0x0000, NULL }
};
#if 0
enum dlm_status {
DLM_NORMAL = 0,
DLM_GRANTED,
DLM_DENIED,
DLM_DENIED_NOLOCKS,
DLM_WORKING,
DLM_BLOCKED,
DLM_BLOCKED_ORPHAN,
DLM_DENIED_GRACE_PERIOD,
DLM_SYSERR,
DLM_NOSUPPORT,
DLM_CANCELGRANT,
DLM_IVLOCKID,
DLM_SYNC,
DLM_BADTYPE,
DLM_BADRESOURCE,
DLM_MAXHANDLES,
DLM_NOCLINFO,
DLM_NOLOCKMGR,
DLM_NOPURGED,
DLM_BADARGS,
DLM_VOID,
DLM_NOTQUEUED,
DLM_IVBUFLEN,
DLM_CVTUNGRANT,
DLM_BADPARAM,
DLM_VALNOTVALID,
DLM_REJECTED,
DLM_ABORT,
DLM_CANCEL,
DLM_IVRESHANDLE,
DLM_DEADLOCK,
DLM_DENIED_NOASTS,
DLM_FORWARD,
DLM_TIMEOUT,
DLM_IVGROUPID,
DLM_VERS_CONFLICT,
DLM_BAD_DEVICE_PATH,
DLM_NO_DEVICE_PERMISSION,
DLM_NO_CONTROL_DEVICE,
DLM_RECOVERING,
DLM_MIGRATING,
DLM_MAXSTATS
};
static const value_string dlm_errnames[] = {
{ DLM_NORMAL, "DLM_NORMAL" },
{ DLM_GRANTED, "DLM_GRANTED" },
{ DLM_DENIED, "DLM_DENIED" },
{ DLM_DENIED_NOLOCKS, "DLM_DENIED_NOLOCKS" },
{ DLM_WORKING, "DLM_WORKING" },
{ DLM_BLOCKED, "DLM_BLOCKED" },
{ DLM_BLOCKED_ORPHAN, "DLM_BLOCKED_ORPHAN" },
{ DLM_DENIED_GRACE_PERIOD, "DLM_DENIED_GRACE_PERIOD" },
{ DLM_SYSERR, "DLM_SYSERR" },
{ DLM_NOSUPPORT, "DLM_NOSUPPORT" },
{ DLM_CANCELGRANT, "DLM_CANCELGRANT" },
{ DLM_IVLOCKID, "DLM_IVLOCKID" },
{ DLM_SYNC, "DLM_SYNC" },
{ DLM_BADTYPE, "DLM_BADTYPE" },
{ DLM_BADRESOURCE, "DLM_BADRESOURCE" },
{ DLM_MAXHANDLES, "DLM_MAXHANDLES" },
{ DLM_NOCLINFO, "DLM_NOCLINFO" },
{ DLM_NOLOCKMGR, "DLM_NOLOCKMGR" },
{ DLM_NOPURGED, "DLM_NOPURGED" },
{ DLM_BADARGS, "DLM_BADARGS" },
{ DLM_VOID, "DLM_VOID" },
{ DLM_NOTQUEUED, "DLM_NOTQUEUED" },
{ DLM_IVBUFLEN, "DLM_IVBUFLEN" },
{ DLM_CVTUNGRANT, "DLM_CVTUNGRANT" },
{ DLM_BADPARAM, "DLM_BADPARAM" },
{ DLM_VALNOTVALID, "DLM_VALNOTVALID" },
{ DLM_REJECTED, "DLM_REJECTED" },
{ DLM_ABORT, "DLM_ABORT" },
{ DLM_CANCEL, "DLM_CANCEL" },
{ DLM_IVRESHANDLE, "DLM_IVRESHANDLE" },
{ DLM_DEADLOCK, "DLM_DEADLOCK" },
{ DLM_DENIED_NOASTS, "DLM_DENIED_NOASTS" },
{ DLM_FORWARD, "DLM_FORWARD" },
{ DLM_TIMEOUT, "DLM_TIMEOUT" },
{ DLM_IVGROUPID, "DLM_IVGROUPID" },
{ DLM_VERS_CONFLICT, "DLM_VERS_CONFLICT" },
{ DLM_BAD_DEVICE_PATH, "DLM_BAD_DEVICE_PATH" },
{ DLM_NO_DEVICE_PERMISSION, "DLM_NO_DEVICE_PERMISSION" },
{ DLM_NO_CONTROL_DEVICE , "DLM_NO_CONTROL_DEVICE " },
{ DLM_RECOVERING, "DLM_RECOVERING" },
{ DLM_MIGRATING, "DLM_MIGRATING" },
{ DLM_MAXSTATS, "DLM_MAXSTATS" },
{ 0x0000, NULL }
};
value_string_ext ext_dlm_errnames = VALUE_STRING_EXT_INIT(dlm_errnames);
static const value_string dlm_errmsgs[] = {
{ DLM_NORMAL, "request in progress" },
{ DLM_GRANTED, "request granted" },
{ DLM_DENIED, "request denied" },
{ DLM_DENIED_NOLOCKS, "request denied, out of system resources" },
{ DLM_WORKING, "async request in progress" },
{ DLM_BLOCKED, "lock request blocked" },
{ DLM_BLOCKED_ORPHAN, "lock request blocked by a orphan lock" },
{ DLM_DENIED_GRACE_PERIOD, "topological change in progress" },
{ DLM_SYSERR, "system error" },
{ DLM_NOSUPPORT, "unsupported" },
{ DLM_CANCELGRANT, "can't cancel convert: already granted" },
{ DLM_IVLOCKID, "bad lockid" },
{ DLM_SYNC, "synchronous request granted" },
{ DLM_BADTYPE, "bad resource type" },
{ DLM_BADRESOURCE, "bad resource handle" },
{ DLM_MAXHANDLES, "no more resource handles" },
{ DLM_NOCLINFO, "can't contact cluster manager" },
{ DLM_NOLOCKMGR, "can't contact lock manager" },
{ DLM_NOPURGED, "can't contact purge daemon" },
{ DLM_BADARGS, "bad api args" },
{ DLM_VOID, "no status" },
{ DLM_NOTQUEUED, "NOQUEUE was specified and request failed" },
{ DLM_IVBUFLEN, "invalid resource name length" },
{ DLM_CVTUNGRANT, "attempted to convert ungranted lock" },
{ DLM_BADPARAM, "invalid lock mode specified" },
{ DLM_VALNOTVALID, "value block has been invalidated" },
{ DLM_REJECTED, "request rejected, unrecognized client" },
{ DLM_ABORT, "blocked lock request cancelled" },
{ DLM_CANCEL, "conversion request cancelled" },
{ DLM_IVRESHANDLE, "invalid resource handle" },
{ DLM_DEADLOCK, "deadlock recovery refused this request" },
{ DLM_DENIED_NOASTS, "failed to allocate AST" },
{ DLM_FORWARD, "request must wait for primary's response" },
{ DLM_TIMEOUT, "timeout value for lock has expired" },
{ DLM_IVGROUPID, "invalid group specification" },
{ DLM_VERS_CONFLICT, "version conflicts prevent request handling" },
{ DLM_BAD_DEVICE_PATH, "Locks device does not exist or path wrong" },
{ DLM_NO_DEVICE_PERMISSION, "Client has insufficient perms for device" },
{ DLM_NO_CONTROL_DEVICE, "Cannot set options on opened device " },
{ DLM_RECOVERING, "lock resource being recovered" },
{ DLM_MIGRATING, "lock resource being migrated" },
{ DLM_MAXSTATS, "invalid error number" },
{ 0x0000, NULL }
};
value_string_ext ext_dlm_errmsgs = VALUE_STRING_EXT_INIT(dlm_errmsgs);
#endif
#define DLM_ASSERT_MASTER_MLE_CLEANUP 0x00000001
#define DLM_ASSERT_MASTER_REQUERY 0x00000002
#define DLM_ASSERT_MASTER_FINISH_MIGRATION 0x00000004
static const value_string dlm_assert_master_flags[] = {
{ DLM_ASSERT_MASTER_MLE_CLEANUP, "cleanup" },
{ DLM_ASSERT_MASTER_REQUERY, "requery" },
{ DLM_ASSERT_MASTER_FINISH_MIGRATION, "finish" },
{ 0x0000, NULL }
};
#define DLM_FINALIZE_STAGE2 0x01
static const value_string dlm_finalize_reco_flags[] = {
{ DLM_FINALIZE_STAGE2, "stage2" },
{ 0x0000, NULL }
};
enum dlm_ast_type {
DLM_AST = 0,
DLM_BAST,
DLM_ASTUNLOCK
};
static const value_string dlm_proxy_ast_types[] = {
{ DLM_AST, "AST" },
{ DLM_BAST, "BAST" },
{ DLM_ASTUNLOCK, "Unlock AST (unused)" },
{ 0x0000, NULL }
};
/* DLM lock flag types */
enum {
DLM_LOCK_FLAGS_PUT_LVB = 0x20000000,
DLM_LOCK_FLAGS_GET_LVB = 0x40000000
};
static int dlm_cookie_handler(proto_tree *tree, tvbuff_t *tvb, guint offset, int hf_cookie)
{
proto_item *item;
guint64 cookie;
guint64 seq;
guint8 node_idx;
item = proto_tree_add_item(tree, hf_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
cookie = tvb_get_ntoh64(tvb, offset);
cookie >>= 56;
node_idx = (guint8)((cookie >> 56) & G_GINT64_CONSTANT(0xff));
seq = cookie & G_GINT64_CONSTANT(0x00ffffffffffffff);
proto_item_append_text(item, " (%u:%" PRIu64 ")", node_idx, seq);
return offset + 8;
}
static int dlm_lkm_flags_handler(proto_tree *tree, tvbuff_t *tvb, guint offset,
guint32 *dlm_lock_flags_ptr)
{
static int * const flags[] = {
&hf_dlm_lock_flag_unused1,
&hf_dlm_lock_flag_orphan,
&hf_dlm_lock_flag_parentable,
&hf_dlm_lock_flag_block,
&hf_dlm_lock_flag_local,
&hf_dlm_lock_flag_valblk,
&hf_dlm_lock_flag_noqueue,
&hf_dlm_lock_flag_convert,
&hf_dlm_lock_flag_nodlckwt,
&hf_dlm_lock_flag_unlock,
&hf_dlm_lock_flag_cancel,
&hf_dlm_lock_flag_deqall,
&hf_dlm_lock_flag_invvalblk,
&hf_dlm_lock_flag_syncsts,
&hf_dlm_lock_flag_timeout,
&hf_dlm_lock_flag_sngldlck,
&hf_dlm_lock_flag_findlocal,
&hf_dlm_lock_flag_proc_owned,
&hf_dlm_lock_flag_xid,
&hf_dlm_lock_flag_xid_conflict,
&hf_dlm_lock_flag_force,
&hf_dlm_lock_flag_revvalblk,
&hf_dlm_lock_flag_unused2,
&hf_dlm_lock_flag_migration,
&hf_dlm_lock_flag_put_lvb,
&hf_dlm_lock_flag_get_lvb,
&hf_dlm_lock_flag_recovery,
NULL
};
if(dlm_lock_flags_ptr != NULL){
*dlm_lock_flags_ptr = tvb_get_ntohl(tvb, offset);
}
proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_dlm_lock_flags,
ett_dtm_lock_flags, flags, ENC_BIG_ENDIAN, BMT_NO_INT | BMT_NO_FALSE | BMT_NO_TFS);
return offset + 4;
}
static int dlm_name_handler(proto_tree *tree, tvbuff_t *tvb, guint offset, int namelen)
{
guint8 lock_type;
guint64 blkno;
proto_item *ti;
ti = proto_tree_add_item(tree, hf_dlm_name, tvb, offset, namelen, ENC_ASCII);
lock_type = tvb_get_guint8(tvb, offset);
if (lock_type == 'N') {
blkno = tvb_get_ntoh64(tvb, offset + OCFS2_DENTRY_LOCK_INO_START);
proto_item_append_text(ti, "%08x", (unsigned int)blkno);
}
return offset + namelen;
}
/*
* We would like to get one whole lockres into a single network
* message whenever possible. Generally speaking, there will be
* at most one dlm_lock on a lockres for each node in the cluster,
* plus (infrequently) any additional locks coming in from userdlm.
*
* struct _dlm_lockres_page
* {
* dlm_migratable_lockres mres;
* dlm_migratable_lock ml[DLM_MAX_MIGRATABLE_LOCKS];
* guint8 pad[DLM_MIG_LOCKRES_RESERVED];
* };
*
* from ../cluster/tcp.h
* NET_MAX_PAYLOAD_BYTES (4096 - sizeof(net_msg))
* (roughly 4080 bytes)
* and sizeof(dlm_migratable_lockres) = 112 bytes
* and sizeof(dlm_migratable_lock) = 16 bytes
*
* Choosing DLM_MAX_MIGRATABLE_LOCKS=240 and
* DLM_MIG_LOCKRES_RESERVED=128 means we have this:
*
* (DLM_MAX_MIGRATABLE_LOCKS * sizeof(dlm_migratable_lock)) +
* sizeof(dlm_migratable_lockres) + DLM_MIG_LOCKRES_RESERVED =
* NET_MAX_PAYLOAD_BYTES
* (240 * 16) + 112 + 128 = 4080
*
* So a lockres would need more than 240 locks before it would
* use more than one network packet to recover. Not too bad.
*/
static void dissect_dlm_migrate_lockres(proto_tree *tree, tvbuff_t *tvb, int offset)
{
unsigned int i;
guint32 num_locks;
static int * const mres_flags[] = {
&hf_dlm_mres_flag_recovery,
&hf_dlm_mres_flag_migration,
&hf_dlm_mres_flag_all_done,
NULL
};
/* master */
proto_tree_add_item(tree, hf_dlm_master, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* lockname_len */
proto_tree_add_item(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* num_locks */
proto_tree_add_item_ret_uint(tree, hf_dlm_mres_num_locks, tvb, offset, 1, ENC_BIG_ENDIAN, &num_locks);
offset += 1;
/* no locks were found on this lockres! done! */
if (num_locks == 0)
return;
/* flags */
proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_dlm_mres_flags,
ett_mres_flags, mres_flags, ENC_BIG_ENDIAN, BMT_NO_INT | BMT_NO_FALSE | BMT_NO_TFS);
offset += 1;
/* total_locks */
proto_tree_add_item(tree, hf_dlm_mres_total_locks, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
/* mig_cookie */
offset = dlm_cookie_handler(tree, tvb, offset, hf_dlm_mres_mig_cookie);
/* lockname */
proto_tree_add_item(tree, hf_dlm_name, tvb, offset, 32, ENC_ASCII);
offset += 32;
/* lvb */
proto_tree_add_item(tree, hf_dlm_lvb1, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb2, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb3, tvb, offset, 16, ENC_NA);
offset += 16;
/* dlm_migratable_lock */
for (i = 0; i < num_locks; i++) {
proto_tree *subtree;
subtree = proto_tree_add_subtree_format(tree, tvb, offset, 16,
ett_migrate_lockres_locks, NULL, "Locks%d: ", i + 1);
/* cookie */
offset = dlm_cookie_handler(subtree, tvb, offset, hf_dlm_mres_mig_cookie);
proto_tree_add_item(subtree, hf_dlm_pad8, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* list */
proto_tree_add_item(subtree, hf_dlm_mres_list, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* flags */
proto_tree_add_item(subtree, hf_dlm_mres_ml_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* type */
proto_tree_add_item(subtree, hf_dlm_mres_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* convert_type */
proto_tree_add_item(subtree, hf_dlm_mres_convert_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* highest_blocked */
proto_tree_add_item(subtree, hf_dlm_mres_highest_blocked, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(subtree, hf_dlm_mres_node, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
}
}
static void
dlm_fmt_revision( gchar *result, guint32 revision )
{
snprintf( result, ITEM_LABEL_LENGTH, "%d.%02d", (guint8)(( revision & 0xFF00 ) >> 8), (guint8)(revision & 0xFF) );
}
#define DLM_QUERY_JOIN_REQUEST_OFF_DLMPROTO 4
#define DLM_QUERY_JOIN_REQUEST_OFF_FSPROTO 6
#define DLM_QUERY_JOIN_REQUEST_OFF_DOMAIN 8
#define DLM_QUERY_JOIN_REQUEST_OFF_NODEMAP 72
#define DLM_QUERY_JOIN_REQUEST_LEN_DLMPROTO 2
#define DLM_QUERY_JOIN_REQUEST_LEN_FSPROTO 2
#define DLM_QUERY_JOIN_REQUEST_LEN_DOMAIN 64
#define DLM_QUERY_JOIN_REQUEST_LEN_NODEMAP 32
#define DLM_QUERY_JOIN_REQUEST_OLD_LEN 100
static void dissect_dlm_query_join_request(proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint8 cc, *node_bits_array;
guint8 *node_map;
gint len;
unsigned int i, j;
gboolean oldver = FALSE;
node_bits_array = (guint8 *)wmem_alloc0(wmem_packet_scope(), (DLM_QUERY_JOIN_REQUEST_LEN_NODEMAP*8)+1);
len = tvb_reported_length_remaining(tvb, offset);
if (len == DLM_QUERY_JOIN_REQUEST_OLD_LEN)
oldver = TRUE;
/* node_idx */
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad16, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* name_len */
proto_tree_add_item(tree, hf_dlm_domain_name_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
if (!oldver)
{
/* dlm_proto */
proto_tree_add_item(tree, hf_dlm_proto_ver, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* fs_proto */
proto_tree_add_item(tree, hf_dlm_fs_proto_ver, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
}
/* domain */
proto_tree_add_item(tree, hf_dlm_domain_name, tvb, offset, 64, ENC_ASCII);
offset += 64;
/* node_map */
node_map = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, offset, DLM_QUERY_JOIN_REQUEST_LEN_NODEMAP);
for (i = 0; i < DLM_QUERY_JOIN_REQUEST_LEN_NODEMAP; i++) {
cc = node_map[i];
for (j = 0; j < 8; j++)
node_bits_array[i * 8 + j] =
(((cc >> j) & 1) ? '1' : '0');
}
/* NULL terminate string */
node_bits_array[(DLM_QUERY_JOIN_REQUEST_LEN_NODEMAP*8)] = 0;
proto_tree_add_bytes_format_value(tree, hf_dlm_node_map, tvb, offset, DLM_QUERY_JOIN_REQUEST_LEN_NODEMAP, NULL, "%s", node_bits_array);
}
#define O2HB_MAX_REGION_NAME_LEN 32
static void dissect_dlm_query_region(proto_tree *tree, tvbuff_t *tvb,
guint offset)
{
guint32 i, num_regions;
guchar *region;
/* qr_node */
proto_tree_add_item(tree, hf_dlm_qr_node, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* qr_numregions */
proto_tree_add_item_ret_uint(tree, hf_dlm_qr_numregions, tvb, offset, 1, ENC_BIG_ENDIAN, &num_regions);
offset += 1;
/* qr_namelen */
proto_tree_add_item(tree, hf_dlm_qr_namelen, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad8, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* qr_domain */
proto_tree_add_item(tree, hf_dlm_qr_domain, tvb, offset, 64, ENC_ASCII);
offset += 64;
/* qr_regions */
for (i = 0; i < num_regions; i++, offset += O2HB_MAX_REGION_NAME_LEN) {
region = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, O2HB_MAX_REGION_NAME_LEN, ENC_ASCII);
proto_tree_add_string_format(tree, hf_dlm_qr_region, tvb, offset, 1,
region, "Region%d: %s", i + 1, region);
}
}
static void dissect_dlm_query_nodeinfo(proto_tree *tree, tvbuff_t *tvb, guint offset)
{
guint32 i, num_nodes;
/* qn_nodenum */
proto_tree_add_item(tree, hf_dlm_qn_nodenum, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* qn_numnodes */
proto_tree_add_item_ret_uint(tree, hf_dlm_qn_numnodes, tvb, offset, 1, ENC_BIG_ENDIAN, &num_nodes);
offset += 1;
/* qn_namelen */
proto_tree_add_item(tree, hf_dlm_qn_namelen, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* qn_domain */
proto_tree_add_item(tree, hf_dlm_qn_domain, tvb, offset, 64, ENC_ASCII);
offset += 64;
/* qn_nodes */
for (i = 0; i < num_nodes; i++) {
proto_tree *subtree;
/* ni_nodenum */
subtree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
ett_query_nodeinfo, NULL, "Node%d: ", i+1);
proto_tree_add_item(subtree, hf_dlm_qn_node, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(subtree, hf_dlm_pad8, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(subtree, hf_dlm_qn_port, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(subtree, hf_dlm_qn_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
}
static int dissect_master_msg(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_flag)
{
guint32 namelen;
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item_ret_uint(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN, &namelen);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad16, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
if (hf_flag == -1)
proto_tree_add_item(tree, hf_dlm_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
else
proto_tree_add_item(tree, hf_flag, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
return dlm_name_handler(tree, tvb, offset, namelen);
}
static int dissect_create_lock_msg(proto_tree *tree, tvbuff_t *tvb, int offset,
guint32 *dlm_lock_flags_ptr)
{
guint32 namelen;
offset = dlm_cookie_handler(tree, tvb, offset, hf_dlm_cookie);
offset = dlm_lkm_flags_handler(tree, tvb, offset, dlm_lock_flags_ptr);
proto_tree_add_item(tree, hf_dlm_pad8, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_requested_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item_ret_uint(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN, &namelen);
offset += 1;
dlm_name_handler(tree, tvb, offset, namelen);
return offset + O2NM_MAX_NAME_LEN;
}
static int dissect_convert_lock_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint32 dlm_lock_flags;
offset = dissect_create_lock_msg(tree, tvb, offset, &dlm_lock_flags);
if(dlm_lock_flags & DLM_LOCK_FLAGS_PUT_LVB){
proto_tree_add_item(tree, hf_dlm_lvb1, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb2, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb3, tvb, offset, 16, ENC_NA);
offset += 16;
}
return offset;
}
static int dissect_unlock_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint32 namelen;
guint32 dlm_lock_flags;
offset = dlm_cookie_handler(tree, tvb, offset, hf_dlm_cookie);
offset = dlm_lkm_flags_handler(tree, tvb, offset, &dlm_lock_flags);
proto_tree_add_item(tree, hf_dlm_pad16, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item_ret_uint(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN, &namelen);
offset += 1;
dlm_name_handler(tree, tvb, offset, namelen);
offset += O2NM_MAX_NAME_LEN;
if(dlm_lock_flags & DLM_LOCK_FLAGS_PUT_LVB){
proto_tree_add_item(tree, hf_dlm_lvb1, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb2, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb3, tvb, offset, 16, ENC_NA);
offset += 16;
}
return offset;
}
static int dissect_proxy_ast_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint32 namelen;
guint32 dlm_lock_flags;
offset = dlm_cookie_handler(tree, tvb, offset, hf_dlm_cookie);
offset = dlm_lkm_flags_handler(tree, tvb, offset, &dlm_lock_flags);
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_ast_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(tree, hf_dlm_blocked_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item_ret_uint(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN, &namelen);
offset += 1;
dlm_name_handler(tree, tvb, offset, namelen);
offset += O2NM_MAX_NAME_LEN;
if(dlm_lock_flags & DLM_LOCK_FLAGS_GET_LVB){
proto_tree_add_item(tree, hf_dlm_lvb1, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb2, tvb, offset, 24, ENC_NA);
offset += 24;
proto_tree_add_item(tree, hf_dlm_lvb3, tvb, offset, 16, ENC_NA);
offset += 16;
}
return offset;
}
static int dissect_deref_lockres_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint32 namelen;
proto_tree_add_item(tree, hf_dlm_pad32, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(tree, hf_dlm_pad16, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item_ret_uint(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN, &namelen);
offset += 1;
return dlm_name_handler(tree, tvb, offset, namelen);
}
static int dissect_migrate_request_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint32 namelen;
proto_tree_add_item(tree, hf_dlm_master, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_new_master, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item_ret_uint(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN, &namelen);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad8, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad32, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
return dlm_name_handler(tree, tvb, offset, namelen);
}
static int dissect_dlm_joined_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad16, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_dlm_domain_name_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(tree, hf_dlm_domain_name, tvb, offset, 64, ENC_ASCII);
offset += 64;
return offset;
}
static int dissect_master_requery_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint32 namelen;
proto_tree_add_item(tree, hf_dlm_pad16, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item_ret_uint(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN, &namelen);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad32, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
return dlm_name_handler(tree, tvb, offset, namelen);
}
static int dissect_lock_request_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_dead_node, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad16, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_dlm_pad32, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
return offset;
}
static int dissect_reco_data_done_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
offset = dissect_lock_request_msg(tree, tvb, offset);
proto_tree_add_item(tree, hf_dlm_reco_lvb, tvb, offset, 64, ENC_NA);
offset += 64;
return offset;
}
static int dissect_finalize_reco_msg(proto_tree *tree, tvbuff_t *tvb, int offset)
{
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_dead_node, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_fr_flags, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad8, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(tree, hf_dlm_pad32, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
return offset;
}
static int dissect_ocfs2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_tree *subtree;
proto_item *ti;
guint32 len, msg_type;
guint32 magic;
tvbuff_t *next_tvb;
int offset = 0;
magic = tvb_get_ntohs(tvb, offset);
if (try_val_to_str(magic, o2net_magic) == NULL)
return 0;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "OCFS2");
col_clear(pinfo->cinfo, COL_INFO);
ti = proto_tree_add_item(tree, proto_ocfs2, tvb, offset, -1, ENC_NA);
subtree = proto_item_add_subtree(ti, ett_ocfs2);
proto_tree_add_item(subtree, hf_msg_magic, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item_ret_uint(subtree, hf_msg_data_len, tvb, 2, 2, ENC_BIG_ENDIAN, &len);
offset += 2;
proto_tree_add_item_ret_uint(subtree, hf_msg_msg_type, tvb, 4, 2, ENC_BIG_ENDIAN, &msg_type);
offset += 2;
switch(magic){
case O2NET_MSG_KEEP_REQ_MAGIC:
col_append_sep_str(pinfo->cinfo, COL_INFO, " | ", "Keepalive Request");
break;
case O2NET_MSG_KEEP_RESP_MAGIC:
col_append_sep_str(pinfo->cinfo, COL_INFO, " | ", "Keepalive Response");
break;
default:
col_append_sep_str(pinfo->cinfo, COL_INFO, " | ",
val_to_str_ext(msg_type, &ext_dlm_magic, "Unknown Type (0x%02x)") );
break;
}
col_set_fence(pinfo->cinfo, COL_INFO);
proto_tree_add_item(subtree, hf_msg_pad, tvb, 4, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(subtree, hf_msg_sys_status, tvb, 8, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(subtree, hf_msg_status, tvb, 12, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(subtree, hf_msg_key, tvb, 16, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(subtree, hf_msg_msg_num, tvb, 20, 4, ENC_BIG_ENDIAN);
offset += 4;
if (magic == O2NET_MSG_MAGIC) {
switch (msg_type) {
case DLM_MASTER_REQUEST_MSG:
dissect_master_msg(subtree, tvb, offset, -1);
break;
case DLM_ASSERT_MASTER_MSG:
dissect_master_msg(subtree, tvb, offset, hf_dlm_am_flags);
break;
case DLM_CREATE_LOCK_MSG:
dissect_create_lock_msg(subtree, tvb, offset, NULL);
break;
case DLM_CONVERT_LOCK_MSG:
dissect_convert_lock_msg(subtree, tvb, offset);
break;
case DLM_PROXY_AST_MSG:
dissect_proxy_ast_msg(subtree, tvb, offset);
break;
case DLM_UNLOCK_LOCK_MSG:
dissect_unlock_msg(subtree, tvb, offset);
break;
case DLM_DEREF_LOCKRES_MSG:
dissect_deref_lockres_msg(subtree, tvb, offset);
break;
case DLM_MIGRATE_REQUEST_MSG:
dissect_migrate_request_msg(subtree, tvb, offset);
break;
case DLM_MIG_LOCKRES_MSG:
dissect_dlm_migrate_lockres(subtree, tvb, offset);
break;
case DLM_QUERY_JOIN_MSG:
dissect_dlm_query_join_request(subtree, tvb, offset);
break;
case DLM_ASSERT_JOINED_MSG:
case DLM_CANCEL_JOIN_MSG:
dissect_dlm_joined_msg(subtree, tvb, offset);
break;
case DLM_EXIT_DOMAIN_MSG:
proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, ENC_NA);
break;
case DLM_MASTER_REQUERY_MSG:
dissect_master_requery_msg(subtree, tvb, offset);
break;
case DLM_LOCK_REQUEST_MSG:
case DLM_BEGIN_RECO_MSG:
dissect_lock_request_msg(subtree, tvb, offset);
break;
case DLM_RECO_DATA_DONE_MSG:
dissect_reco_data_done_msg(subtree, tvb, offset);
break;
case DLM_FINALIZE_RECO_MSG:
dissect_finalize_reco_msg(subtree, tvb, offset);
break;
case DLM_QUERY_REGION_MSG:
dissect_dlm_query_region(subtree, tvb, offset);
break;
case DLM_QUERY_NODEINFO_MSG:
dissect_dlm_query_nodeinfo(subtree, tvb, offset);
break;
default:
proto_tree_add_item(tree, hf_dlm_payload, tvb, offset, len, ENC_NA);
break;
}
} else {
next_tvb = tvb_new_subset_length(tvb, offset, len);
call_data_dissector(next_tvb, pinfo, tree);
}
return tvb_reported_length(tvb);
}
static guint
get_ocfs2_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
guint16 plen;
/* Get the length of the data from header. */
plen = tvb_get_ntohs(tvb, offset + 2);
/* That length doesn't include the header itself, add that in. */
return plen + 24;
}
static int dissect_ocfs2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
guint32 magic;
int offset = 0;
if (!tvb_bytes_exist(tvb, offset, 2))
return 0;
magic = tvb_get_ntohs(tvb, offset);
if (try_val_to_str(magic, o2net_magic) == NULL)
return 0;
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 4, get_ocfs2_pdu_len, dissect_ocfs2_pdu, data);
return tvb_captured_length(tvb);
}
void proto_register_ocfs2(void)
{
static hf_register_info hf[] = {
/* ocfs2_msg */
{ &hf_msg_magic,
{ "Magic", "ocfs2.msg.magic", FT_UINT16, BASE_HEX,
VALS(o2net_magic), 0x0,
"Magic number identifier of O2NET-over-TCPmessage",
HFILL
}
},
{ &hf_msg_data_len,
{ "Len", "ocfs2.msg.data_len", FT_UINT16, BASE_DEC,
NULL, 0x0, "Data length", HFILL
}
},
{ &hf_msg_msg_type,
{ "Type", "ocfs2.msg.msg_type", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
&ext_dlm_magic, 0x0, "Message type", HFILL
}
},
{ &hf_msg_pad,
{ "Pad", "ocfs2.msg.pad", FT_UINT16, BASE_HEX,
NULL, 0x0, NULL, HFILL
}
},
{ &hf_msg_sys_status,
{ "Sys Status", "ocfs2.msg.sys_status", FT_UINT32,
BASE_DEC, NULL, 0x0,
"System level status return code", HFILL
}
},
{ &hf_msg_status,
{ "Status", "ocfs2.msg.status", FT_UINT32, BASE_DEC,
NULL, 0x0, "Return code", HFILL
}
},
{ &hf_msg_key,
{ "Key", "ocfs2.msg.key", FT_UINT32, BASE_HEX, NULL,
0x0, NULL, HFILL
}
},
{ &hf_msg_msg_num,
{ "Num", "ocfs2.msg.msg_num", FT_UINT32, BASE_DEC, NULL,
0x0, "Message identification number", HFILL
}
},
{ &hf_dlm_node_idx,
{ "Node", "ocfs2.dlm.node_idx", FT_UINT8, BASE_DEC,
NULL, 0x0, "Node index", HFILL
}
},
{ &hf_dlm_lock_flags,
{ "Flags", "ocfs2.dlm.lock.flags", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_unused1,
{ "unused", "ocfs2.dlm.lock.flags.unused", FT_UINT32, BASE_HEX,
NULL, 0x0000000F, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_orphan,
{ "orphan", "ocfs2.dlm.lock.flags.orphan", FT_BOOLEAN, 32,
NULL, 0x00000010, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_parentable,
{ "parentable", "ocfs2.dlm.lock.flags.parentable", FT_BOOLEAN, 32,
NULL, 0x00000020, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_block,
{ "block", "ocfs2.dlm.lock.flags.block", FT_BOOLEAN, 32,
NULL, 0x00000040, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_local,
{ "local", "ocfs2.dlm.lock.flags.local", FT_BOOLEAN, 32,
NULL, 0x00000080, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_valblk,
{ "valblk", "ocfs2.dlm.lock.flags.valblk", FT_BOOLEAN, 32,
NULL, 0x00000100, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_noqueue,
{ "noqueue", "ocfs2.dlm.lock.flags.noqueue", FT_BOOLEAN, 32,
NULL, 0x00000200, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_convert,
{ "convert", "ocfs2.dlm.lock.flags.convert", FT_BOOLEAN, 32,
NULL, 0x00000400, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_nodlckwt,
{ "nodlckwt", "ocfs2.dlm.lock.flags.nodlckwt", FT_BOOLEAN, 32,
NULL, 0x00000800, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_unlock,
{ "unlock", "ocfs2.dlm.lock.flags.unlock", FT_BOOLEAN, 32,
NULL, 0x00001000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_cancel,
{ "cancel", "ocfs2.dlm.lock.flags.cancel", FT_BOOLEAN, 32,
NULL, 0x00002000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_deqall,
{ "deqall", "ocfs2.dlm.lock.flags.deqall", FT_BOOLEAN, 32,
NULL, 0x00004000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_invvalblk,
{ "invvalblk", "ocfs2.dlm.lock.flags.invvalblk", FT_BOOLEAN, 32,
NULL, 0x00008000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_syncsts,
{ "syncsts", "ocfs2.dlm.lock.flags.syncsts", FT_BOOLEAN, 32,
NULL, 0x00010000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_timeout,
{ "timeout", "ocfs2.dlm.lock.flags.timeout", FT_BOOLEAN, 32,
NULL, 0x00020000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_sngldlck,
{ "sngldlck", "ocfs2.dlm.lock.flags.sngldlck", FT_BOOLEAN, 32,
NULL, 0x00040000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_findlocal,
{ "findlocal", "ocfs2.dlm.lock.flags.findlocal", FT_BOOLEAN, 32,
NULL, 0x00080000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_proc_owned,
{ "proc_owned", "ocfs2.dlm.lock.flags.proc_owned", FT_BOOLEAN, 32,
NULL, 0x00100000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_xid,
{ "xid", "ocfs2.dlm.lock.flags.xid", FT_BOOLEAN, 32,
NULL, 0x00200000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_xid_conflict,
{ "xid_conflict", "ocfs2.dlm.lock.flags.xid_conflict", FT_BOOLEAN, 32,
NULL, 0x00400000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_force,
{ "force", "ocfs2.dlm.lock.flags.force", FT_BOOLEAN, 32,
NULL, 0x00800000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_revvalblk,
{ "revvalblk", "ocfs2.dlm.lock.flags.revvalblk", FT_BOOLEAN, 32,
NULL, 0x01000000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_unused2,
{ "unused", "ocfs2.dlm.lock.flags.unused", FT_UINT32, BASE_HEX,
NULL, 0x0E000000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_migration,
{ "migration", "ocfs2.dlm.lock.flags.migration", FT_BOOLEAN, 32,
NULL, 0x10000000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_put_lvb,
{ "put_lvb", "ocfs2.dlm.lock.flags.put_lvb", FT_BOOLEAN, 32,
NULL, 0x20000000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_get_lvb,
{ "get_lvb", "ocfs2.dlm.lock.flags.get_lvb", FT_BOOLEAN, 32,
NULL, 0x40000000, NULL, HFILL
}
},
{ &hf_dlm_lock_flag_recovery,
{ "recovery", "ocfs2.dlm.lock.flags.recovery", FT_BOOLEAN, 32,
NULL, 0x80000000, NULL, HFILL
}
},
{ &hf_dlm_am_flags,
{ "Flags", "ocfs2.dlm.am_flags", FT_UINT32, BASE_HEX,
VALS(dlm_assert_master_flags), 0x0,
"Assert Master Flags", HFILL
}
},
{ &hf_dlm_fr_flags,
{ "Flags", "ocfs2.dlm.fr_flags", FT_UINT32, BASE_HEX,
VALS(dlm_finalize_reco_flags), 0x0,
"Finalize Recovery Flags", HFILL
}
},
{ &hf_dlm_namelen,
{ "Namelen", "ocfs2.dlm.namelen", FT_UINT8, BASE_DEC,
NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_name,
{ "Name", "ocfs2.dlm.name", FT_STRING, BASE_NONE, NULL,
0x0, NULL, HFILL
}
},
{ &hf_dlm_cookie,
{ "Cookie", "ocfs2.dlm.cookie", FT_UINT64, BASE_HEX,
NULL, 0x0,
"Unique ID for a single lock on a resource", HFILL
}
},
{ &hf_dlm_requested_type,
{ "Requested", "ocfs2.dlm.requested_type", FT_UINT8,
BASE_DEC, VALS(dlm_lock_modes), 0x0,
"Requested lock level", HFILL
}
},
{ &hf_dlm_blocked_type,
{ "Blocked", "ocfs2.dlm.blocked_type", FT_UINT8,
BASE_DEC, VALS(dlm_lock_modes), 0x0,
"Blocked lock type", HFILL
}
},
{ &hf_dlm_ast_type,
{ "AST Type", "ocfs2.dlm.ast_type", FT_UINT8, BASE_DEC,
VALS(dlm_proxy_ast_types), 0x0, NULL, HFILL
}
},
{ &hf_dlm_dead_node,
{ "Dead Node", "ocfs2.dlm.dead_node", FT_UINT8,
BASE_DEC, NULL, 0x0, "Dead node index", HFILL
}
},
{ &hf_dlm_lvb1,
{ "LVB1", "ocfs2.dlm.lvb", FT_BYTES, BASE_NONE, NULL,
0x0, "Lock value block", HFILL
}
},
{ &hf_dlm_lvb2,
{ "LVB2", "ocfs2.dlm.lvb", FT_BYTES, BASE_NONE, NULL,
0x0, "Lock value block", HFILL
}
},
{ &hf_dlm_lvb3,
{ "LVB3", "ocfs2.dlm.lvb", FT_BYTES, BASE_NONE, NULL,
0x0, "Lock value block", HFILL
}
},
{ &hf_dlm_domain_name_len,
{ "Domain Namelen", "ocfs2.dlm.domain_namelen",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_proto_ver,
{ "DLM Protocol", "ocfs2.dlm.proto_ver",
FT_UINT16, BASE_CUSTOM, CF_FUNC(dlm_fmt_revision), 0x0, NULL,
HFILL
}
},
{ &hf_dlm_fs_proto_ver,
{ "FS Protocol", "ocfs2.dlm.fs_proto_ver",
FT_UINT16, BASE_CUSTOM, CF_FUNC(dlm_fmt_revision), 0x0, NULL,
HFILL
}
},
{ &hf_dlm_node_map,
{ "Node Map", "ocfs2.dlm.node_map", FT_BYTES,
BASE_NONE, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_domain_name,
{ "Domain Name", "ocfs2.dlm.domain_name", FT_STRING,
BASE_NONE, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_master,
{ "Master", "ocfs2.dlm.master", FT_UINT8, BASE_DEC,
NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_new_master,
{ "New Master", "ocfs2.dlm.new_master", FT_UINT8,
BASE_DEC, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_mres_num_locks,
{ "Num Locks", "ocfs2.dlm.num_locks", FT_UINT8,
BASE_DEC, NULL, 0x0, "Migres Num Locks", HFILL
}
},
{ &hf_dlm_mres_flags,
{ "Flags", "ocfs2.dlm.mres_flags", FT_UINT8, BASE_HEX,
NULL, 0x01, "Migres Flags", HFILL
}
},
{ &hf_dlm_mres_flag_recovery,
{ "recovery", "ocfs2.dlm.mres_flags.recovery", FT_BOOLEAN, 8,
NULL, 0x02, NULL, HFILL
}
},
{ &hf_dlm_mres_flag_migration,
{ "migration", "ocfs2.dlm.mres_flags.migration", FT_BOOLEAN, 8,
NULL, 0x04, NULL, HFILL
}
},
{ &hf_dlm_mres_flag_all_done,
{ "all_done", "ocfs2.dlm.mres_flags.all_done", FT_BOOLEAN, 8,
NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_mres_total_locks,
{ "Total Locks", "ocfs2.dlm.total_locks", FT_UINT32,
BASE_DEC, NULL, 0x0, "Migres Total Locks", HFILL
}
},
{ &hf_dlm_mres_mig_cookie,
{ "Cookie", "ocfs2.dlm.migratable_lock.mig_cookie",
FT_UINT64, BASE_DEC, NULL, 0x0, "Migres Cookie", HFILL
}
},
{ &hf_dlm_mres_list,
{ "List", "ocfs2.dlm.migratable_lock.list", FT_UINT8,
BASE_DEC, VALS(dlm_lockres_list), 0x0, NULL, HFILL
}
},
{ &hf_dlm_mres_ml_flags,
{ "List", "ocfs2.dlm.migratable_lock.flags", FT_UINT8,
BASE_HEX, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_mres_type,
{ "Type", "ocfs2.dlm.migratable_lock.type", FT_UINT8,
BASE_DEC, VALS(dlm_lock_modes), 0x0, NULL, HFILL
}
},
{ &hf_dlm_mres_convert_type,
{ "Convert type", "ocfs2.dlm.migratable_lock.convert_type", FT_UINT8,
BASE_DEC, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_mres_highest_blocked,
{ "Highest blocked", "ocfs2.dlm.migratable_lock.highest_blocked", FT_UINT8,
BASE_DEC, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_mres_node,
{ "Node", "ocfs2.dlm.migratable_lock.node", FT_UINT8,
BASE_DEC, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_qr_node,
{ "Node", "ocfs2.dlm.query_region.qr_node", FT_UINT8,
BASE_DEC, NULL, 0x0, "Query Region Node", HFILL
}
},
{ &hf_dlm_qr_numregions,
{ "Num Regions", "ocfs2.dlm.query_region.qr_numregions",
FT_UINT8, BASE_DEC, NULL, 0x0,
"The number of regions to compare with", HFILL
}
},
{ &hf_dlm_qr_namelen,
{ "Domain Namelen", "ocfs2.dlm.query_region.qr_namelen",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_qr_domain,
{ "Domain Name", "ocfs2.dlm.query_region.qr_domain",
FT_STRING, BASE_NONE, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_qr_region,
{ "Region", "ocfs2.dlm.query_region.region",
FT_STRING, BASE_NONE, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_qn_nodenum,
{ "Node", "ocfs2.dlm_query_nodeinfo.qn_nodenum",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_qn_numnodes,
{ "Num Nodes", "ocfs2.dlm_query_nodeinfo.qn_numnodes",
FT_UINT8, BASE_DEC, NULL, 0x0,
"The number of nodes to query", HFILL
}
},
{ &hf_dlm_qn_namelen,
{ "Domain Namelen",
"ocfs2.dlm_query_nodeinfo.qn_namelen", FT_UINT8,
BASE_DEC, NULL, 0x0, NULL, HFILL
}
},
{ &hf_dlm_qn_domain,
{ "Domain Name", "ocfs2.dlm_query_nodeinfo.qn_domain",
FT_STRING, BASE_NONE, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_qn_node,
{ "Node", "ocfs2.dlm_query_nodeinfo.node",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_qn_port,
{ "Port", "ocfs2.dlm_query_nodeinfo.port",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_qn_ip,
{ "IP Address", "ocfs2.dlm_query_nodeinfo.ip",
FT_IPv4, BASE_NONE, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_reco_lvb,
{ "Recovery LVB", "ocfs2.reco_lvb",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_pad8,
{ "Pad", "ocfs2.dlm.pad",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_pad16,
{ "Pad", "ocfs2.dlm.pad",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_pad32,
{ "Pad", "ocfs2.dlm.pad",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_flags,
{ "Flags", "ocfs2.dlm.flags",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL,
HFILL
}
},
{ &hf_dlm_payload,
{ "Payload", "ocfs2.dlm.payload",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL,
HFILL
}
},
};
static gint *ett[] = {
&ett_ocfs2,
&ett_dtm_lock_flags,
&ett_mres_flags,
&ett_migrate_lockres_locks,
&ett_query_nodeinfo,
};
proto_ocfs2 = proto_register_protocol("OCFS2 Networking", "OCFS2", "ocfs2");
proto_register_field_array(proto_ocfs2, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void proto_reg_handoff_ocfs2(void)
{
dissector_handle_t ocfs2_handle;
ocfs2_handle = create_dissector_handle(dissect_ocfs2, proto_ocfs2);
dissector_add_for_decode_as_with_preference("tcp.port", ocfs2_handle);
}
/*
* 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:
*/