[Ocfs2-tools-devel] [PATCH 1/1] wireshark-ocfs2: add dlm_query_join handler to support both ocfs2-1.2 and the newer format
Jeff Liu
jeff.liu at oracle.com
Fri Jul 10 06:37:40 PDT 2009
dlm_query_join(request/response) messages structure have been changed from ocfs2-1.4.
we want the dissector can handle both ocfs2-1.2 and the newer format.
the method used to distinct the different ocfs2 version:
1.to handle the dlm_query_join_request
check whether the name_len is eqaul to the left msg length or not.
if name_len == left_msg_len, dissect the domain_name as ocfs2-1.2,
else if the name_len > left_msg_len, dissect domain_name as ocfs2-1.4 and newer.
2.to handle the dlm_query_join_response
for ocfs-1.2, the response value is converted to big-endian before
putting on the wire, so swap it back to little-endian in dissector,
then check if its value is less-than or eual to 2(JOIN_OK_NO_MAP),
if so, NOP here.
for ocfs-1.4 and newer, the response code is in big-endian before sending over wire as well,
tvb_get_ntohl() convert it to little-endian, but it is made up of four one-byte fields and in
big-endian order originally, so convert it to big-endian first.
Also, the 2nd and 3rd byte are valid only if the first byte is JOIN_OK. In this case, wrap these 3 values
in parenthesis separated by colon, then append to status line, otherwise, just the code value appended.
Signed-off-by: Jeff Liu <jeff.liu at oracle.com>
---
epan/dissectors/packet-ocfs2.c | 123 ++++++++++++++++++++++++++++++++++-----
1 files changed, 107 insertions(+), 16 deletions(-)
diff --git a/epan/dissectors/packet-ocfs2.c b/epan/dissectors/packet-ocfs2.c
index ce57c3f..f89d85d 100644
--- a/epan/dissectors/packet-ocfs2.c
+++ b/epan/dissectors/packet-ocfs2.c
@@ -229,12 +229,6 @@ const char * decode_enumerated_bitfield_full(guint32 val, guint32 mask, int widt
#define DLM_LVB_LEN 64
#define DLM_MOD_KEY (0x666c6172)
-enum dlm_query_join_response {
- JOIN_DISALLOW = 0,
- JOIN_OK,
- JOIN_OK_NO_MAP,
-};
-
/* DLM lock modes */
enum {
@@ -811,6 +805,46 @@ struct dlm_finalize_reco
guint32 pad2; // unused
};
+struct dlm_protocol_version {
+ guint8 pv_major;
+ guint8 pv_minor;
+};
+
+#define O2NM_MAX_NODES 255
+#define BITS_PER_BYTE 8
+#define BITS_TO_BYTES(bits) (((bits)+BITS_PER_BYTE-1)/BITS_PER_BYTE)
+struct dlm_query_join_request_latest {
+ guint8 node_idx;
+ guint8 pad1[2];
+ guint8 name_len;
+ struct dlm_protocol_version dlm_proto;
+ struct dlm_protocol_version fs_proto;
+ guint8 domain[O2NM_MAX_NAME_LEN];
+ guint8 node_map[BITS_TO_BYTES(O2NM_MAX_NODES)];
+};
+
+enum dlm_query_join_response_code {
+ JOIN_DISALLOW = 0,
+ JOIN_OK,
+ JOIN_OK_NO_MAP,
+ JOIN_PROTOCOL_MISMATCH,
+};
+
+struct dlm_query_join_packet {
+ guint8 code; /* Response code. dlm_minor and fs_minor
+ are only valid if this is JOIN_OK */
+ guint8 dlm_minor; /* The minor version of the protocol the
+ dlm is speaking. */
+ guint8 fs_minor; /* The minor version of the protocol the
+ filesystem is speaking. */
+ guint8 reserved;
+};
+
+union dlm_query_join_response {
+ guint32 intval;
+ struct dlm_query_join_packet packet;
+};
+
#define DLM_FIELD_BYTES_LEN 24
#define LVB_REMAIN_BYTES_LEN (DLM_LVB_LEN - (DLM_FIELD_BYTES_LEN << 1))
#define LVB1_OFFSET(x) offsetof(x, lvb[0])
@@ -946,12 +980,6 @@ static struct dlm_msg_struct_def dlm_struct_defs[] = {
{ "dead_node", &hf_dlm_dead_node, FIELD_OFFSET_AND_SIZE(struct dlm_begin_reco,dead_node), dlm_node_idx_handler},
{ DLM_MSG_STRUCT_DEF_END } }
},
-{ "dlm_query_join_request", "DLM Query Join Request", DLM_QUERY_JOIN_MSG, &ett_dlm_query_join, {
- { "node_idx", &hf_dlm_node_idx, FIELD_OFFSET_AND_SIZE(struct dlm_query_join_request,node_idx), dlm_node_idx_handler},
- { "name_len", &hf_dlm_domain_name_len,FIELD_OFFSET_AND_SIZE(struct dlm_query_join_request,name_len), dlm_domain_namelen_handler},
- { "domain", &hf_dlm_domain_name, FIELD_OFFSET_AND_SIZE(struct dlm_query_join_request,domain), dlm_domain_name_handler},
- { DLM_MSG_STRUCT_DEF_END } }
-},
{ "dlm_assert_joined", "DLM Assert Joined", DLM_ASSERT_JOINED_MSG, &ett_dlm_assert_joined, {
{ "node_idx", &hf_dlm_node_idx, FIELD_OFFSET_AND_SIZE(struct dlm_assert_joined,node_idx), dlm_node_idx_handler},
{ "name_len", &hf_dlm_domain_name_len,FIELD_OFFSET_AND_SIZE(struct dlm_assert_joined,name_len), dlm_domain_namelen_handler},
@@ -1148,10 +1176,64 @@ static void msg_struct_enumerate_fields(struct dlm_msg_struct_def *def, proto_tr
}
}
+static void dissect_dlm_query_join_request(proto_tree *tree, tvbuff_t *tvb,
+ int offset)
+{
+ guint8 namelen;
+ gint len;
+
+ proto_tree_add_item(tree, hf_dlm_node_idx, tvb, offset, 1, FALSE);
+
+ /* skip the following 2 padding bytes */
+ offset += 3;
+ namelen = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_dlm_namelen, tvb, offset, 1, FALSE);
+
+ len = tvb_reported_length_remaining(tvb, offset);
+
+ ++offset;
+ /* if the left message length more than namelen, its most likely
+ * ocfs2-1.4 or later we are dealing with, or else ocfs2-1.2 or
+ * mismatch */
+ if (len > namelen)
+ proto_tree_add_item(tree, hf_dlm_domain_name, tvb,
+ offset + 4, namelen, FALSE);
+ else if (len == namelen)
+ proto_tree_add_item(tree, hf_dlm_domain_name, tvb,
+ offset, namelen, FALSE);
+}
+
+static void dissect_dlm_query_join_response(proto_tree *tree,
+ proto_item *item,
+ tvbuff_t *tvb,
+ int offset)
+{
+ union dlm_query_join_response response;
+ struct dlm_query_join_packet packet;
+ guint32 status;
+
+ status = tvb_get_ntohl(tvb, offset);
+
+ /* NOP if ocfs2-1.2.x message coming */
+ if (status < JOIN_PROTOCOL_MISMATCH)
+ return ;
+
+ /* for ocfs2-1.4.x and newer */
+ response.intval = htonl(status);
+ packet = response.packet;
+ proto_item_append_text(item, " (%u:", packet.code);
+
+ if (packet.code == JOIN_OK)
+ proto_item_append_text(item, "%u:%u",
+ packet.dlm_minor, packet.fs_minor);
+
+ proto_item_append_text(item, ")");
+}
+
static int dissect_ocfs2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *subtree = NULL;
- proto_item *ti;
+ proto_item *ti, *si;
guint16 len, magic, msg_type;
int ret;
@@ -1188,9 +1270,9 @@ static int dissect_ocfs2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(subtree, hf_msg_sys_status,
tvb, O2NET_MSG_HDR_OFF_SYS_STATUS, 4,
FALSE);
- proto_tree_add_item(subtree, hf_msg_status,
- tvb, O2NET_MSG_HDR_OFF_STATUS, 4,
- FALSE);
+ si = proto_tree_add_item(subtree, hf_msg_status,
+ tvb, O2NET_MSG_HDR_OFF_STATUS, 4,
+ FALSE);
proto_tree_add_item(subtree, hf_msg_key,
tvb, O2NET_MSG_HDR_OFF_KEY, 4,
FALSE);
@@ -1247,6 +1329,15 @@ static int dissect_ocfs2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (def)
msg_struct_enumerate_fields(def, subtree, tvb, O2NET_MSG_HDR_OFF_PAYLOAD);
}
+
+ if (msg_type == DLM_QUERY_JOIN_MSG) {
+ if (magic == O2NET_MSG_MAGIC)
+ dissect_dlm_query_join_request(subtree,
+ tvb, O2NET_MSG_HDR_OFF_PAYLOAD);
+ else if (magic == O2NET_MSG_STATUS_MAGIC)
+ dissect_dlm_query_join_response(subtree,
+ si, tvb, O2NET_MSG_HDR_OFF_STATUS);
+ }
}
out:
return ret;
--
1.5.4.3
More information about the Ocfs2-tools-devel
mailing list