aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-fc.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-04-05 05:51:51 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-04-05 05:51:51 +0000
commitd06fea3fa6ee25c7a9bcdf8d16a61d42d1520f50 (patch)
tree1adc017423f95c60990dbd9ebf0d870b6ba6dd4c /epan/dissectors/packet-fc.c
parent0d4dbda02bd348ae3bfa9af3cad0e88b7b2d57ce (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/packet-fc.c')
-rw-r--r--epan/dissectors/packet-fc.c245
1 files changed, 78 insertions, 167 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,