aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ctdb.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2007-04-23 09:44:13 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2007-04-23 09:44:13 +0000
commitc84eda3a80250e06b2b777d45231ce42c992f0cf (patch)
tree2bec7c00b27dd3d5599b5cf6e563359092475080 /epan/dissectors/packet-ctdb.c
parent117eaaf9483004ef08930c10cf411b8380345d60 (diff)
add request/response matching for ctdb
svn path=/trunk/; revision=21523
Diffstat (limited to 'epan/dissectors/packet-ctdb.c')
-rw-r--r--epan/dissectors/packet-ctdb.c306
1 files changed, 299 insertions, 7 deletions
diff --git a/epan/dissectors/packet-ctdb.c b/epan/dissectors/packet-ctdb.c
index a8a6788aae..9c11f99e1f 100644
--- a/epan/dissectors/packet-ctdb.c
+++ b/epan/dissectors/packet-ctdb.c
@@ -52,11 +52,29 @@ static int hf_ctdb_flags_immediate = -1;
static int hf_ctdb_dbid = -1;
static int hf_ctdb_callid = -1;
static int hf_ctdb_status = -1;
+static int hf_ctdb_keylen = -1;
static int hf_ctdb_datalen = -1;
+static int hf_ctdb_key = -1;
+static int hf_ctdb_keyhash = -1;
+static int hf_ctdb_data = -1;
+static int hf_ctdb_dmaster = -1;
+static int hf_ctdb_request_in = -1;
+static int hf_ctdb_response_in = -1;
+static int hf_ctdb_time = -1;
+static int hf_ctdb_xid = -1;
/* Initialize the subtree pointers */
static gint ett_ctdb = -1;
+static gint ett_ctdb_key = -1;
+/* this tree keeps track of caller/reqid for ctdb transactions */
+emem_tree_t *ctdb_transactions=NULL;
+typedef struct _ctdb_trans_t {
+ guint32 key_hash;
+ gint32 request_in;
+ gint32 response_in;
+ nstime_t req_time;
+} ctdb_trans_t;
#define CTDB_REQ_CALL 0
@@ -78,6 +96,73 @@ static const value_string ctdb_opcodes[] = {
};
+static void
+ctdb_display_trans(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, ctdb_trans_t *ctdb_trans)
+{
+ proto_item *item;
+
+ item=proto_tree_add_uint(tree, hf_ctdb_xid, tvb, 0, 0, (int)ctdb_trans);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ if(ctdb_trans->request_in!=(gint32)pinfo->fd->num){
+ item=proto_tree_add_uint(tree, hf_ctdb_request_in, tvb, 0, 0, ctdb_trans->request_in);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if( (ctdb_trans->response_in!=-1)
+ &&(ctdb_trans->response_in!=(gint32)pinfo->fd->num) ){
+ item=proto_tree_add_uint(tree, hf_ctdb_response_in, tvb, 0, 0, ctdb_trans->response_in);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ if((gint32)pinfo->fd->num==ctdb_trans->response_in){
+ nstime_t ns;
+
+ nstime_delta(&ns, &pinfo->fd->abs_ts, &ctdb_trans->req_time);
+ item=proto_tree_add_time(tree, hf_ctdb_time, tvb, 0, 0, &ns);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+}
+
+static guint32
+ctdb_hash(tvbuff_t *tvb, int offset, guint32 len)
+{
+ guint32 value;
+ guint32 i;
+
+ for(value=0x238F13AF*len, i=0; i < len; i++)
+ value=(value+(tvb_get_guint8(tvb, offset+i) << (i*5 % 24)));
+
+ return (1103515243 * value + 12345);
+}
+
+static int
+dissect_ctdb_key(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 keylen, guint32 *key_hash, int endianess)
+{
+ guint32 keyhash;
+ proto_item *key_item=NULL;
+ proto_item *key_tree=NULL;
+
+ if(tree){
+ key_item=proto_tree_add_item(tree, hf_ctdb_key, tvb, offset, keylen, endianess);
+ key_tree=proto_item_add_subtree(key_item, ett_ctdb_key);
+
+ }
+
+ keyhash=ctdb_hash(tvb, offset, keylen);
+ proto_item_append_text(key_item, " (Hash:0x%08x)", keyhash);
+ key_item=proto_tree_add_uint(key_tree, hf_ctdb_keyhash, tvb, 0, 0, keyhash);
+ PROTO_ITEM_SET_GENERATED(key_item);
+
+ offset+=keylen;
+
+ if(key_hash){
+ *key_hash=keyhash;
+ }
+
+ return offset;
+}
+
static int
dissect_ctdb_reply_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int endianess)
{
@@ -95,14 +180,97 @@ dissect_ctdb_reply_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto
}
static int
-dissect_ctdb_reply_dmaster(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int endianess)
+dissect_ctdb_reply_dmaster(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint32 reqid, guint32 dst, int endianess)
{
+ guint32 datalen;
+ emem_tree_key_t tkey[3];
+ ctdb_trans_t *ctdb_trans;
+
/* datalen */
proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
+ if(endianess){
+ datalen=tvb_get_letohl(tvb, offset);
+ } else {
+ datalen=tvb_get_ntohl(tvb, offset);
+ }
offset+=4;
/* data */
+ proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
+ offset+=datalen;
+ tkey[0].length=1;
+ tkey[0].key=&reqid;
+ tkey[1].length=1;
+ tkey[1].key=&dst;
+ tkey[2].length=0;
+ ctdb_trans=se_tree_lookup32_array(ctdb_transactions, &tkey[0]);
+
+ if(ctdb_trans){
+ ctdb_trans->response_in=pinfo->fd->num;
+ ctdb_display_trans(pinfo, tree, tvb, ctdb_trans);
+ }
+
+ return offset;
+}
+
+static int
+dissect_ctdb_req_dmaster(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint32 reqid, int endianess)
+{
+ guint32 keylen, datalen, dmaster;
+ emem_tree_key_t tkey[3];
+ ctdb_trans_t *ctdb_trans;
+
+ /* dbid */
+ proto_tree_add_item(tree, hf_ctdb_dbid, tvb, offset, 4, endianess);
+ offset+=4;
+
+ /* dmaster */
+ proto_tree_add_item(tree, hf_ctdb_dmaster, tvb, offset, 4, endianess);
+ if(endianess){
+ dmaster=tvb_get_letohl(tvb, offset);
+ } else {
+ dmaster=tvb_get_ntohl(tvb, offset);
+ }
+ offset += 4;
+
+ /* keylen */
+ proto_tree_add_item(tree, hf_ctdb_keylen, tvb, offset, 4, endianess);
+ if(endianess){
+ keylen=tvb_get_letohl(tvb, offset);
+ } else {
+ keylen=tvb_get_ntohl(tvb, offset);
+ }
+ offset+=4;
+
+ /* datalen */
+ proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
+ if(endianess){
+ datalen=tvb_get_letohl(tvb, offset);
+ } else {
+ datalen=tvb_get_ntohl(tvb, offset);
+ }
+ offset+=4;
+
+ /* key */
+ offset=dissect_ctdb_key(tree, tvb, offset, keylen, NULL, endianess);
+
+ /* data */
+ proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
+ offset+=datalen;
+
+
+ tkey[0].length=1;
+ tkey[0].key=&reqid;
+ tkey[1].length=1;
+ tkey[1].key=&dmaster;
+ tkey[2].length=0;
+ ctdb_trans=se_tree_lookup32_array(ctdb_transactions, &tkey[0]);
+
+ if(ctdb_trans){
+ ctdb_display_trans(pinfo, tree, tvb, ctdb_trans);
+ }
+
return offset;
}
@@ -112,9 +280,11 @@ static const true_false_string flags_immediate_tfs={
};
static int
-dissect_ctdb_req_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int endianess)
+dissect_ctdb_req_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 reqid, guint32 caller, int endianess)
{
- guint32 flags;
+ guint32 flags, keyhash;
+ guint32 keylen, datalen;
+ ctdb_trans_t *ctdb_trans=NULL;
/* flags */
proto_tree_add_item(tree, hf_ctdb_flags_immediate, tvb, offset, 4, endianess);
@@ -139,11 +309,96 @@ dissect_ctdb_req_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree
offset+=4;
/* keylen */
- /* calldatalen */
+ proto_tree_add_item(tree, hf_ctdb_keylen, tvb, offset, 4, endianess);
+ if(endianess){
+ keylen=tvb_get_letohl(tvb, offset);
+ } else {
+ keylen=tvb_get_ntohl(tvb, offset);
+ }
+ offset+=4;
+
+ /* datalen */
+ proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
+ if(endianess){
+ datalen=tvb_get_letohl(tvb, offset);
+ } else {
+ datalen=tvb_get_ntohl(tvb, offset);
+ }
+ offset+=4;
+
+ /* key */
+ offset=dissect_ctdb_key(tree, tvb, offset, keylen, &keyhash, endianess);
+
/* data */
+ proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
+ offset+=datalen;
+
+ /* setup request/response matching */
+ if(!pinfo->fd->flags.visited){
+ emem_tree_key_t tkey[3];
+
+ ctdb_trans=se_alloc(sizeof(ctdb_trans_t));
+ ctdb_trans->key_hash=keyhash;
+ ctdb_trans->request_in=pinfo->fd->num;
+ ctdb_trans->response_in=-1;
+ ctdb_trans->req_time=pinfo->fd->abs_ts;
+ tkey[0].length=1;
+ tkey[0].key=&reqid;
+ tkey[1].length=1;
+ tkey[1].key=&caller;
+ tkey[2].length=0;
+
+ se_tree_insert32_array(ctdb_transactions, &tkey[0], ctdb_trans);
+ } else {
+ emem_tree_key_t tkey[3];
+
+ tkey[0].length=1;
+ tkey[0].key=&reqid;
+ tkey[1].length=1;
+ tkey[1].key=&caller;
+ tkey[2].length=0;
+ ctdb_trans=se_tree_lookup32_array(ctdb_transactions, &tkey[0]);
+ }
+
+ if(ctdb_trans){
+ ctdb_display_trans(pinfo, tree, tvb, ctdb_trans);
+ }
+
return offset;
}
+static int
+dissect_ctdb_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint32 reqid, guint32 dst, int endianess)
+{
+ guint32 dmaster;
+ emem_tree_key_t tkey[3];
+ ctdb_trans_t *ctdb_trans;
+
+ /* dmaster */
+ proto_tree_add_item(tree, hf_ctdb_dmaster, tvb, offset, 4, endianess);
+ if(endianess){
+ dmaster=tvb_get_letohl(tvb, offset);
+ } else {
+ dmaster=tvb_get_ntohl(tvb, offset);
+ }
+ if(check_col(pinfo->cinfo, COL_INFO)){
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Dmaster:%d", dmaster);
+ }
+ offset+=4;
+
+ tkey[0].length=1;
+ tkey[0].key=&reqid;
+ tkey[1].length=1;
+ tkey[1].key=&dst;
+ tkey[2].length=0;
+ ctdb_trans=se_tree_lookup32_array(ctdb_transactions, &tkey[0]);
+
+ if(ctdb_trans){
+ ctdb_display_trans(pinfo, tree, tvb, ctdb_trans);
+ }
+
+ return offset;
+}
static gboolean
dissect_ctdb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
@@ -151,7 +406,7 @@ dissect_ctdb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
proto_tree *tree=NULL;
proto_item *item=NULL;
int offset=0;
- guint32 opcode, src, dst;
+ guint32 opcode, src, dst, reqid;
int endianess;
/* does this look like CTDB? */
@@ -225,6 +480,11 @@ dissect_ctdb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
/* id */
proto_tree_add_item(tree, hf_ctdb_id, tvb, offset, 4, endianess);
+ if(endianess){
+ reqid=tvb_get_letohl(tvb, offset);
+ } else {
+ reqid=tvb_get_ntohl(tvb, offset);
+ }
offset+=4;
if(check_col(pinfo->cinfo, COL_INFO)){
@@ -235,17 +495,19 @@ dissect_ctdb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
switch(opcode){
case CTDB_REQ_CALL:
- offset=dissect_ctdb_req_call(tvb, offset, pinfo, tree, endianess);
+ offset=dissect_ctdb_req_call(tvb, offset, pinfo, tree, reqid, src, endianess);
break;
case CTDB_REPLY_CALL:
offset=dissect_ctdb_reply_call(tvb, offset, pinfo, tree, endianess);
break;
case CTDB_REPLY_DMASTER:
- offset=dissect_ctdb_reply_dmaster(tvb, offset, pinfo, tree, endianess);
+ offset=dissect_ctdb_reply_dmaster(tvb, offset, pinfo, tree, reqid, dst, endianess);
break;
case CTDB_REPLY_REDIRECT:
+ offset=dissect_ctdb_redirect(tvb, offset, pinfo, tree, reqid, dst, endianess);
break;
case CTDB_REQ_DMASTER:
+ offset=dissect_ctdb_req_dmaster(tvb, offset, pinfo, tree, reqid, endianess);
break;
case CTDB_REPLY_ERROR:
break;
@@ -294,17 +556,45 @@ proto_register_ctdb(void)
{ &hf_ctdb_datalen, {
"Data Length", "ctdb.datalen", FT_UINT32, BASE_DEC,
NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_keylen, {
+ "Key Length", "ctdb.keylen", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "", HFILL }},
{ &hf_ctdb_magic, {
"Magic", "ctdb.magic", FT_UINT32, BASE_HEX,
NULL, 0x0, "", HFILL }},
{ &hf_ctdb_version, {
"Version", "ctdb.version", FT_UINT32, BASE_DEC,
NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_dmaster, {
+ "Dmaster", "ctdb.dmaster", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_key, {
+ "Key", "ctdb.key", FT_BYTES, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_keyhash, {
+ "KeyHash", "ctdb.keyhash", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_data, {
+ "Data", "ctdb.data", FT_BYTES, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_request_in, {
+ "Request In", "ctdb.request_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_response_in, {
+ "Response In", "ctdb.response_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_time, {
+ "Time since request", "ctdb.time", FT_RELATIVE_TIME, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
+ { &hf_ctdb_xid, {
+ "xid", "ctdb.xid", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_ctdb,
+ &ett_ctdb_key,
};
/* Register the protocol name and description */
@@ -325,4 +615,6 @@ proto_reg_handoff_ctdb(void)
dissector_add_handle("tcp.port", ctdb_handle);
heur_dissector_add("tcp", dissect_ctdb, proto_ctdb);
+
+ ctdb_transactions=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "CTDB transactions tree");
}