diff options
author | Ronnie Sahlberg <ronnie_sahlberg@ozemail.com.au> | 2007-04-23 09:44:13 +0000 |
---|---|---|
committer | Ronnie Sahlberg <ronnie_sahlberg@ozemail.com.au> | 2007-04-23 09:44:13 +0000 |
commit | c84eda3a80250e06b2b777d45231ce42c992f0cf (patch) | |
tree | 2bec7c00b27dd3d5599b5cf6e563359092475080 /epan | |
parent | 117eaaf9483004ef08930c10cf411b8380345d60 (diff) |
add request/response matching for ctdb
svn path=/trunk/; revision=21523
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-ctdb.c | 306 |
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"); } |