diff options
author | Ronnie Sahlberg <ronnie_sahlberg@ozemail.com.au> | 2006-04-05 05:51:51 +0000 |
---|---|---|
committer | Ronnie Sahlberg <ronnie_sahlberg@ozemail.com.au> | 2006-04-05 05:51:51 +0000 |
commit | d06fea3fa6ee25c7a9bcdf8d16a61d42d1520f50 (patch) | |
tree | 1adc017423f95c60990dbd9ebf0d870b6ba6dd4c /epan/dissectors | |
parent | 0d4dbda02bd348ae3bfa9af3cad0e88b7b2d57ce (diff) |
cleaning up bits and pieces
replacing the hashtables with a better exchange se_tree
svn path=/trunk/; revision=17809
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-fc.c | 245 | ||||
-rw-r--r-- | epan/dissectors/packet-fc.h | 3 |
2 files changed, 78 insertions, 170 deletions
diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c index a48982cf52..77e92c284e 100644 --- a/epan/dissectors/packet-fc.c +++ b/epan/dissectors/packet-fc.c @@ -134,6 +134,11 @@ static dissector_handle_t data_handle; static int fc_tap = -1; +typedef struct _fc_conv_data_t { + se_tree_t *exchanges; +} fc_conv_data_t; + + /* Reassembly stuff */ static gboolean fc_reassemble = TRUE; static guint32 fc_max_frame_size = 1024; @@ -149,9 +154,6 @@ typedef struct _fcseq_conv_data { GHashTable *fcseq_req_hash = NULL; -static GHashTable *fc_exchange_unmatched = NULL; -static GHashTable *fc_exchange_matched = NULL; - /* * Hash Functions */ @@ -175,87 +177,9 @@ fcseq_hash (gconstpointer v) return val; } -static guint -fc_exchange_hash_unmatched(gconstpointer v) -{ - const fc_exchange_data *fced=(const fc_exchange_data *)v; - - return fced->oxid; -} -static gint -fc_exchange_equal_unmatched(gconstpointer v1, gconstpointer v2) -{ - const fc_exchange_data *fced1=(const fc_exchange_data *)v1; - const fc_exchange_data *fced2=(const fc_exchange_data *)v2; - - /* oxid must match */ - if(fced1->oxid!=fced2->oxid){ - return 0; - } - /* compare s_id, d_id and treat the fc address - s_id==00.00.00 as a wildcard matching anything */ - if( ((fced1->s_id.data[0]!=0)||(fced1->s_id.data[1]!=0)||(fced1->s_id.data[2]!=0)) && CMP_ADDRESS(&fced1->s_id, &fced2->s_id) ){ - return 0; - } - if(CMP_ADDRESS(&fced1->d_id, &fced2->d_id)){ - return 0; - } - - return 1; -} - -static guint -fc_exchange_hash_matched(gconstpointer v) -{ - const fc_exchange_data *fced=(const fc_exchange_data *)v; - - return fced->oxid; -} -static gint -fc_exchange_equal_matched(gconstpointer v1, gconstpointer v2) -{ - const fc_exchange_data *fced1=(const fc_exchange_data *)v1; - const fc_exchange_data *fced2=(const fc_exchange_data *)v2; - guint32 fef1, fef2, lef1, lef2; - - /* oxid must match */ - if(fced1->oxid!=fced2->oxid){ - return 0; - } - fef1=fced1->first_exchange_frame; - fef2=fced2->first_exchange_frame; - lef1=fced1->last_exchange_frame; - lef2=fced2->last_exchange_frame; - if(!fef1)fef1=fef2; - if(!fef2)fef2=fef1; - if(!lef1)lef1=lef2; - if(!lef2)lef2=lef1; - - if(fef1!=fef2){ - return 0; - } - if(lef1!=lef2){ - return 0; - } - - return 1; -} - static void fc_exchange_init_protocol(void) { - if(fc_exchange_unmatched){ - g_hash_table_destroy(fc_exchange_unmatched); - fc_exchange_unmatched=NULL; - } - if(fc_exchange_matched){ - g_hash_table_destroy(fc_exchange_matched); - fc_exchange_matched=NULL; - } - - fc_exchange_unmatched=g_hash_table_new(fc_exchange_hash_unmatched, fc_exchange_equal_unmatched); - fc_exchange_matched=g_hash_table_new(fc_exchange_hash_matched, fc_exchange_equal_matched); - fragment_table_init(&fc_fragment_table); if (fcseq_req_hash) @@ -669,6 +593,7 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean static fc_hdr fchdr; fc_exchange_data *fc_ex=NULL; + fc_conv_data_t *fc_conv_data=NULL; conversation_t *conversation; fcseq_conv_data_t *cdata; @@ -705,8 +630,8 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean pinfo->srcport=0; pinfo->destport=0; } - SET_ADDRESS (&fchdr.d_id, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data); - SET_ADDRESS (&fchdr.s_id, pinfo->src.type, pinfo->src.len, pinfo->src.data); + SET_ADDRESS(&fchdr.d_id, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data); + SET_ADDRESS(&fchdr.s_id, pinfo->src.type, pinfo->src.len, pinfo->src.data); fchdr.cs_ctl = tvb_get_guint8 (tvb, offset+4); fchdr.type = tvb_get_guint8 (tvb, offset+8); @@ -722,6 +647,76 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean pinfo->ptype = PT_EXCHG; pinfo->r_ctl = fchdr.r_ctl; + /* set up a conversation and conversation data */ + /* TODO treat the fc address s_id==00.00.00 as a wildcard matching anything */ + conversation=find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + if(!conversation){ + conversation=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, + pinfo->ptype, pinfo->srcport, + pinfo->destport, 0); + } + fc_conv_data=conversation_get_proto_data(conversation, proto_fc); + if(!fc_conv_data){ + fc_conv_data=se_alloc(sizeof(fc_conv_data_t)); + fc_conv_data->exchanges=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "FC Exchanges"); + conversation_add_proto_data(conversation, proto_fc, fc_conv_data); + } + + /* set up the exchange data */ + /* XXX we should come up with a way to handle when the 16bit oxid wraps + * so that large traces will work + */ + fc_ex=(fc_exchange_data *)se_tree_lookup32(fc_conv_data->exchanges, fchdr.oxid); + if(!fc_ex){ + fc_ex=se_alloc(sizeof(fc_exchange_data)); + fc_ex->first_exchange_frame=0; + fc_ex->last_exchange_frame=0; + fc_ex->fc_time=pinfo->fd->abs_ts; + se_tree_insert32(fc_conv_data->exchanges, fchdr.oxid, fc_ex); + } + /* populate the exchange struct */ + if(!pinfo->fd->flags.visited){ + if(fchdr.fctl&FC_FCTL_EXCHANGE_FIRST){ + fc_ex->first_exchange_frame=pinfo->fd->num; + fc_ex->fc_time = pinfo->fd->abs_ts; + } + if(fchdr.fctl&FC_FCTL_EXCHANGE_LAST){ + fc_ex->last_exchange_frame=pinfo->fd->num; + } + } + + + /* In the interest of speed, if "tree" is NULL, don't do any work not + necessary to generate protocol tree items. */ + if (tree) { + ti = proto_tree_add_protocol_format (tree, proto_fc, tvb, offset, + FC_HEADER_SIZE, "Fibre Channel"); + fc_tree = proto_item_add_subtree (ti, ett_fc); + } + + + /* put some nice exchange data in the tree */ + if(!(fchdr.fctl&FC_FCTL_EXCHANGE_FIRST)){ + proto_item *it; + it=proto_tree_add_uint(fc_tree, hf_fc_exchange_first_frame, tvb, 0, 0, fc_ex->first_exchange_frame); + PROTO_ITEM_SET_GENERATED(it); + if(fchdr.fctl&FC_FCTL_EXCHANGE_LAST){ + nstime_t delta_ts; + nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &fc_ex->fc_time); + it=proto_tree_add_time(ti, hf_fc_time, tvb, 0, 0, &delta_ts); + PROTO_ITEM_SET_GENERATED(it); + } + } + if(!(fchdr.fctl&FC_FCTL_EXCHANGE_LAST)){ + proto_item *it; + it=proto_tree_add_uint(fc_tree, hf_fc_exchange_last_frame, tvb, 0, 0, fc_ex->last_exchange_frame); + PROTO_ITEM_SET_GENERATED(it); + } + + fchdr.fced=fc_ex; + is_ack = ((fchdr.r_ctl == 0xC0) || (fchdr.r_ctl == 0xC1)); /* There are two ways to determine if this is the first frame of a @@ -751,86 +746,11 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean "LCTL 0x%x")); } - /* In the interest of speed, if "tree" is NULL, don't do any work not - necessary to generate protocol tree items. */ - if (tree) { - ti = proto_tree_add_protocol_format (tree, proto_fc, tvb, offset, - FC_HEADER_SIZE, "Fibre Channel"); - fc_tree = proto_item_add_subtree (ti, ett_fc); - } - /* Highlight EISL header, if present */ if (eisl_offset != -1) { proto_tree_add_item (fc_tree, hf_fc_eisl, tvb, eisl_offset, 8, 0); } - /* match first exchange with last exchange */ - if(fchdr.fctl&FC_FCTL_EXCHANGE_FIRST){ - if(!pinfo->fd->flags.visited){ - fc_exchange_data fced, *old_fced; - - /* first check if we already have seen this exchange and it - is still open/unmatched. - */ - fced.oxid=fchdr.oxid; - SET_ADDRESS(&fced.s_id, fchdr.s_id.type, fchdr.s_id.len, fchdr.s_id.data); - SET_ADDRESS(&fced.d_id, fchdr.d_id.type, fchdr.d_id.len, fchdr.d_id.data); - old_fced=g_hash_table_lookup(fc_exchange_unmatched, &fced); - if(old_fced){ - g_hash_table_remove(fc_exchange_unmatched, old_fced); - } - old_fced=se_alloc(sizeof(fc_exchange_data)); - old_fced->oxid=fchdr.oxid; - COPY_ADDRESS(&old_fced->s_id, &fchdr.s_id); - COPY_ADDRESS(&old_fced->d_id, &fchdr.d_id); - old_fced->first_exchange_frame=pinfo->fd->num; - old_fced->fc_time = pinfo->fd->abs_ts; - g_hash_table_insert(fc_exchange_unmatched, old_fced, old_fced); - fc_ex=old_fced; - } else { - fc_exchange_data fced, *old_fced; - fced.oxid=fchdr.oxid; - fced.first_exchange_frame=pinfo->fd->num; - fced.last_exchange_frame=0; - old_fced=g_hash_table_lookup(fc_exchange_matched, &fced); - fc_ex=old_fced; - } - } - if(fchdr.fctl&FC_FCTL_EXCHANGE_LAST){ - if(!pinfo->fd->flags.visited){ - fc_exchange_data fced, *old_fced; - - fced.oxid=fchdr.oxid; - SET_ADDRESS(&fced.s_id, fchdr.d_id.type, fchdr.d_id.len, fchdr.d_id.data); - SET_ADDRESS(&fced.d_id, fchdr.s_id.type, fchdr.s_id.len, fchdr.s_id.data); - old_fced=g_hash_table_lookup(fc_exchange_unmatched, &fced); - if(old_fced){ - g_hash_table_remove(fc_exchange_unmatched, old_fced); - old_fced->last_exchange_frame=pinfo->fd->num; - g_hash_table_insert(fc_exchange_matched, old_fced, old_fced); - } - fc_ex=old_fced; - } else { - fc_exchange_data fced, *old_fced; - fced.oxid=fchdr.oxid; - fced.first_exchange_frame=0; - fced.last_exchange_frame=pinfo->fd->num; - old_fced=g_hash_table_lookup(fc_exchange_matched, &fced); - fc_ex=old_fced; - } - } - if(fc_ex){ - if(fchdr.fctl&FC_FCTL_EXCHANGE_FIRST){ - proto_tree_add_uint(fc_tree, hf_fc_exchange_last_frame, tvb, 0, 0, fc_ex->last_exchange_frame); - } - if(fchdr.fctl&FC_FCTL_EXCHANGE_LAST){ - nstime_t delta_ts; - proto_tree_add_uint(fc_tree, hf_fc_exchange_first_frame, tvb, 0, 0, fc_ex->first_exchange_frame); - nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &fc_ex->fc_time); - proto_tree_add_time(ti, hf_fc_time, tvb, 0, 0, &delta_ts); - } - } - fchdr.fced=fc_ex; switch (fchdr.r_ctl & 0xF0) { @@ -1079,15 +999,6 @@ dissect_fc_helper (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean * SEQ_CNT of the first frame in sequence and use this value to * determine the actual offset into a frame. */ - conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, - pinfo->ptype, pinfo->oxid, - pinfo->rxid, NO_PORT2); - if (!conversation) { - conversation = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst, - pinfo->ptype, pinfo->oxid, - pinfo->rxid, NO_PORT2); - } - ckey.conv_idx = conversation->index; cdata = (fcseq_conv_data_t *)g_hash_table_lookup (fcseq_req_hash, diff --git a/epan/dissectors/packet-fc.h b/epan/dissectors/packet-fc.h index 49f5db32e8..0602654814 100644 --- a/epan/dissectors/packet-fc.h +++ b/epan/dissectors/packet-fc.h @@ -129,9 +129,6 @@ ETH_VAR_IMPORT const value_string fc_fc4_val[]; frames and time deltas */ typedef struct _fc_exchange_data { - address s_id; - address d_id; - guint16 oxid; guint32 first_exchange_frame; guint32 last_exchange_frame; nstime_t fc_time; |