cleaning up bits and pieces
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 5 Apr 2006 05:51:51 +0000 (05:51 +0000)
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 5 Apr 2006 05:51:51 +0000 (05:51 +0000)
replacing the hashtables with a better exchange   se_tree

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@17809 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-fc.c
epan/dissectors/packet-fc.h

index a48982cf5298de3257c9ba6ae7f420b459aebd2b..77e92c284e07f5387f061de94911937700d839e6 100644 (file)
@@ -134,6 +134,11 @@ static dissector_handle_t data_handle;
 
 static int fc_tap = -1;
 
 
 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;
 /* 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;
 
 
 GHashTable *fcseq_req_hash = NULL;
 
-static GHashTable *fc_exchange_unmatched = NULL;
-static GHashTable *fc_exchange_matched = NULL;
-
 /*
  * Hash Functions
  */
 /*
  * Hash Functions
  */
@@ -175,87 +177,9 @@ fcseq_hash (gconstpointer v)
     return val;
 }
 
     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)
 {
 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)
     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;
 
     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;
 
     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;
     }
        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);
 
     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;
 
     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
     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"));
     }
     
                                           "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);
     }
 
     /* 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) {
 
 
     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.
          */
          * 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,
         ckey.conv_idx = conversation->index;
         
         cdata = (fcseq_conv_data_t *)g_hash_table_lookup (fcseq_req_hash,
index 49f5db32e8b9876035e56b196b009fb0e232f4f2..0602654814d0b8322de48d139c10f6b6ccf5c271 100644 (file)
@@ -129,9 +129,6 @@ ETH_VAR_IMPORT const value_string fc_fc4_val[];
    frames and time deltas 
 */
 typedef struct _fc_exchange_data {
    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;
     guint32 first_exchange_frame;
     guint32 last_exchange_frame;
     nstime_t fc_time;