Cleanup of request/response matching, from Ronnie Sahlberg.
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 16 Nov 2001 07:56:28 +0000 (07:56 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 16 Nov 2001 07:56:28 +0000 (07:56 +0000)
Get rid of "Response to" stuff in the LANMAN dissector, as that's now
done in the SMB dissector.

Add a routine for dissecting unknown SMBs (gets the word and byte
counts, and just adds text entries for the word and byte parameters, if
any), and replace null pointers in the dissector table with pointers to
that routine.  Get rid of the check for a null dissector pointer.

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

packet-smb-pipe.c
packet-smb.c
smb.h

index bd86aa15f9f51f5f67470bb6bef2a7669c96236c..ed8b54c92c4bb7da0ac17ae0f31c7f710ba10c28 100644 (file)
@@ -8,7 +8,7 @@ XXX  Fixme : shouldnt show [malformed frame] for long packets
  * significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
  * Guy Harris 2001
  *
- * $Id: packet-smb-pipe.c,v 1.40 2001/11/15 10:41:51 guy Exp $
+ * $Id: packet-smb-pipe.c,v 1.41 2001/11/16 07:56:27 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -63,7 +63,6 @@ static int hf_aux_data_desc = -1;
 static int hf_detail_level = -1;
 static int hf_recv_buf_len = -1;
 static int hf_send_buf_len = -1;
-static int hf_response_to = -1;
 static int hf_continuation_from = -1;
 static int hf_status = -1;
 static int hf_convert = -1;
@@ -149,6 +148,21 @@ static gint ett_lanman_server = -1;
  * among other documents.
  */
 
+static GMemChunk *lanman_request_val_chunk = NULL;
+static gint lanman_request_val_init_count = 50;
+
+static void
+lanman_init_protocol(void)
+{
+       if(lanman_request_val_chunk)
+               g_mem_chunk_destroy(lanman_request_val_chunk);
+
+       lanman_request_val_chunk = g_mem_chunk_new("lanman_request_val_chunk", sizeof(struct smb_request_val),
+                                                 lanman_request_val_init_count*sizeof(struct smb_request_val),
+                                                 G_ALLOC_ONLY);
+}
+
+
 static const value_string status_vals[] = {
        {0,     "Success"},
        {5,     "User has insufficient privilege"},
@@ -1978,6 +1992,11 @@ dissect_pipe_lanman(tvbuff_t *t_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
                tree = proto_item_add_subtree(item, ett_lanman);
        }
 
+       if(request_val==NULL){
+               request_val = g_mem_chunk_alloc(lanman_request_val_chunk);
+               smb_info->request_val=request_val;
+       }
+
        if (smb_info->request) { /* this is a request */
                /* function code */
                cmd = tvb_get_letohs(p_tvb, offset);
@@ -1997,6 +2016,9 @@ dissect_pipe_lanman(tvbuff_t *t_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
                if (!pinfo->fd->flags.visited) {
                        request_val->last_lanman_cmd = cmd;
                        request_val->last_level = -1;
+                       request_val->last_param_descrip=NULL;
+                       request_val->last_data_descrip=NULL;
+                       request_val->last_aux_data_descrip=NULL;
                }
 
                /* parameter descriptor */
@@ -2114,10 +2136,6 @@ dissect_pipe_lanman(tvbuff_t *t_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
 
                /* ok we have seen this one before */
 
-               /* response to the request in frame xx */
-               proto_tree_add_uint(tree, hf_response_to, p_tvb, 0, 0,
-                                   request_val->frame);
-
                /* if it looks like an interim response, update COL_INFO and return */
                if( ( (p_tvb==NULL) || (tvb_reported_length(p_tvb)==0) )
                &&  ( (d_tvb==NULL) || (tvb_reported_length(d_tvb)==0) ) ){
@@ -2265,10 +2283,6 @@ register_proto_smb_pipe(void)
                        { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC,
                        NULL, 0, "LANMAN Send Buffer Length", HFILL }},
 
-               { &hf_response_to,
-                       { "Response to request in frame", "lanman.response_to", FT_UINT32, BASE_DEC,
-                       NULL, 0, "This is a LANMAN response to the request in the frame in question", HFILL }},
-
                { &hf_continuation_from,
                        { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC,
                        NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }},
@@ -2566,4 +2580,5 @@ register_proto_smb_pipe(void)
        proto_register_subtree_array(ett, array_length(ett));
 
         register_heur_dissector_list("msrpc", &msrpc_heur_subdissector_list);
+       register_init_routine(&lanman_init_protocol);
 }
index 0dcdc779a42df20bccc2b4003f796804d88dbfb9..2f406e2b70fcf3eeaba28eab9774172781fcfe1f 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for smb packet dissection
  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
  *
- * $Id: packet-smb.c,v 1.150 2001/11/16 02:53:11 guy Exp $
+ * $Id: packet-smb.c,v 1.151 2001/11/16 07:56:27 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -660,475 +660,44 @@ static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 static GMemChunk *smb_info_chunk = NULL;
 static int smb_info_init_count = 200;
-static GHashTable *smb_info_table = NULL;
 
-/*
- * XXX - MID/PID/UID/TID/command/source/destination are *NOT* unique;
- * I have at least one capture with multiple Transaction2 SMB exchanges
- * in a row, all with the *same* MID, PID, UID, and TID, and all between
- * the *same* machines on the *same* connection.  The MID is merely
- * intended to distinguish between replies to multiple *in-flight*
- * requests; once the reply comes back, an SMB client can reused the
- * MID of the request, and, apparently, some clients *do*.
- *
- * To make this work correctly, you have to include the frame number
- * of the matching packet in the hash key, just as is done for the
- * transaction hash table.
- */
-static gint
-smb_info_equal(gconstpointer k1, gconstpointer k2)
-{
-       smb_info_t *key1 = (smb_info_t *)k1;
-       smb_info_t *key2 = (smb_info_t *)k2;
-       gint res;
-
-       /* make sure to always compare mid first since this is most
-          likely to differ ==> shortcircuiting the expression */
-       res= (  (key1->mid==key2->mid)
-               &&      (key1->pid==key2->pid)
-               &&      (key1->uid==key2->uid)
-               &&      (key1->cmd==key2->cmd)
-               &&      (key1->tid==key2->tid)
-               &&      (ADDRESSES_EQUAL(key1->src, key2->src))
-               &&      (ADDRESSES_EQUAL(key1->dst, key2->dst)) );
-
-       return res;
-}
 
-static guint
-smb_info_hash(gconstpointer k)
-{
-       smb_info_t *key = (smb_info_t *)k;
-
-       /* multiplex id is very likely to differ between calls
-          it should be sufficient for a good distribution of hash
-          values.
-       */
-       return key->mid;
-}
-static gboolean
-free_all_smb_info(gpointer key_arg, gpointer value, gpointer user_data)
-{
-       smb_info_t *key = (smb_info_t *)key_arg;
+/* matched smb_info structures.
+  For matched smb_info structures we store the smb_info structure twice in the table
+  using the frame number as the key.
+  The frame number is guaranteed to be unique but if ever someone makes some change
+  that will renumber the frames in a capture we are in BIG trouble.
+  This is not likely though since that would break (among other things) all the
+  reassembly routines as well.
 
-       if((key->src)&&(key->src->data)){
-               g_free((gpointer)key->src->data);
-               key->src->data = NULL;
-               g_free((gpointer)key->src);
-               key->src = NULL;
-       }
-
-       if((key->dst)&&(key->dst->data)){
-               g_free((gpointer)key->dst->data);
-               key->dst->data = NULL;
-               g_free((gpointer)key->dst);
-               key->dst = NULL;
-       }
-       return TRUE;
-}
-
-int smb_packet_init_count = 200;
-
-/*
- * This is a hash table matching transaction requests and replies.
- *
- * Unfortunately, the MID is not a transaction ID in, say, the ONC RPC
- * sense; instead, it's a "multiplex ID" used when there's more than one
- * request *currently* in flight, to distinguish replies.
- *
- * This means that the MID and PID don't uniquely identify a request in
- * a conversation.
- *
- * Therefore, we have to use some other value to distinguish between
- * requests with the same MID and PID.
- *
- * On the first pass through the capture, when we first see a request,
- * we hash it by conversation, MID, and PID.
- *
- * When we first see a reply to it, we add it to a new hash table,
- * hashing it by conversation, MID, PID, and frame number of the reply.
- *
- * This works as long as
- *
- *     1) a client doesn't screw up and have multiple requests outstanding
- *        with the same MID and PID
- *
- * and
- *
- *     2) we don't have, within the same frame, replies to multiple
- *        requests with the same MID and PID.
- *
- * 2) should happen only if the server screws up and puts the wrong MID or
- * PID into a reply (in which case not only can we not handle this, the
- * client can't handle it either) or if the client has screwed up as per
- * 1) and the server's dutifully replied to both of the requests with the
- * same MID and PID (in which case, again, neither we nor the client can
- * handle this).
- *
- * We don't have to correctly dissect screwups; we just have to keep from
- * dumping core on them.
- *
- * XXX - in addition, we need to keep a hash table of replies, so that we
- * can associate continuations with the reply to which they're a continuation.
- */
-struct smb_request_key {
-  guint32 conversation;
-  guint16 mid;
-  guint16 pid;
-  guint32 frame_num;
-};
-
-static GHashTable *smb_request_hash = NULL;
-static GMemChunk *smb_request_keys = NULL;
-static GMemChunk *smb_request_vals = NULL;
-
-/*
- * This is a hash table matching continued transation replies and their
- * continuations.
- *
- * It works similarly to the request/reply hash table.
- */
-static GHashTable *smb_continuation_hash = NULL;
-
-static GMemChunk *smb_continuation_vals = NULL;
-
-/* Hash Functions */
+  Oh, yes, the key is really a pointer, but we use it as if it was an integer.
+  Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
+*/
 static gint
-smb_equal(gconstpointer v, gconstpointer w)
+smb_info_equal_matched(gconstpointer k1, gconstpointer k2)
 {
-  struct smb_request_key *v1 = (struct smb_request_key *)v;
-  struct smb_request_key *v2 = (struct smb_request_key *)w;
-
-#if defined(DEBUG_SMB_HASH)
-  printf("Comparing %08X:%u:%u:%u\n      and %08X:%u:%u:%u\n",
-        v1 -> conversation, v1 -> mid, v1 -> pid, v1 -> frame_num,
-        v2 -> conversation, v2 -> mid, v2 -> pid, v2 -> frame_num);
-#endif
-
-  if (v1 -> conversation == v2 -> conversation &&
-      v1 -> mid          == v2 -> mid &&
-      v1 -> pid          == v2 -> pid &&
-      v1 -> frame_num    == v2 -> frame_num) {
-
-    return 1;
-
-  }
-
-  return 0;
+       register int key1 = (int)k1;
+       register int key2 = (int)k2;
+       return key1==key2;
 }
-
 static guint
-smb_hash (gconstpointer v)
+smb_info_hash_matched(gconstpointer k)
 {
-  struct smb_request_key *key = (struct smb_request_key *)v;
-  guint val;
-
-  val = (key -> conversation) + (key -> mid) + (key -> pid) +
-       (key -> frame_num);
-
-#if defined(DEBUG_SMB_HASH)
-  printf("SMB Hash calculated as %u\n", val);
-#endif
-
-  return val;
-
+       register int key = (int)k;
+       return key;
 }
-
-/*
- * Free up any state information we've saved, and re-initialize the
- * tables of state information.
- */
-
-/*
- * For a hash table entry, free the address data to which the key refers
- * and the fragment data to which the value refers.
- * (The actual key and value structures get freed by "reassemble_init()".)
- */
 static gboolean
-free_request_val_data(gpointer key, gpointer value, gpointer user_data)
-{
-  struct smb_request_val *request_val = value;
-
-  if (request_val->last_transact_command != NULL)
-    g_free(request_val->last_transact_command);
-  if (request_val->last_param_descrip != NULL)
-    g_free(request_val->last_param_descrip);
-  if (request_val->last_data_descrip != NULL)
-    g_free(request_val->last_data_descrip);
-  if (request_val->last_aux_data_descrip != NULL)
-    g_free(request_val->last_aux_data_descrip);
-  return TRUE;
-}
-
-static struct smb_request_val *
-do_transaction_hashing(conversation_t *conversation, struct smb_info si,
-                      frame_data *fd)
-{
-  struct smb_request_key request_key, *new_request_key;
-  struct smb_request_val *request_val = NULL;
-  gpointer               new_request_key_ret, request_val_ret;
-
-  if (si.request) {
-    /*
-     * This is a request.
-     *
-     * If this is the first time the frame has been seen, check for
-     * an entry for the request in the hash table.  If it's not found,
-     * insert an entry for it.
-     *
-     * If it's the first time it's been seen, then we can't have seen
-     * the reply yet, so the reply frame number should be 0, for
-     * "unknown".
-     */
-    if (!fd->flags.visited) {
-      request_key.conversation = conversation->index;
-      request_key.mid          = si.mid;
-      request_key.pid          = si.pid;
-      request_key.frame_num    = 0;
-
-      request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
-
-      if (request_val == NULL) {
-       /*
-        * Not found.
-        */
-       new_request_key = g_mem_chunk_alloc(smb_request_keys);
-       new_request_key -> conversation = conversation->index;
-       new_request_key -> mid          = si.mid;
-       new_request_key -> pid          = si.pid;
-       new_request_key -> frame_num    = 0;
-
-       request_val = g_mem_chunk_alloc(smb_request_vals);
-       request_val -> frame = fd->num;
-       request_val -> last_transact2_command = -1;             /* unknown */
-       request_val -> last_transact_command = NULL;
-       request_val -> last_param_descrip = NULL;
-       request_val -> last_data_descrip = NULL;
-       request_val -> last_aux_data_descrip = NULL;
-
-       g_hash_table_insert(smb_request_hash, new_request_key, request_val);
-      } else {
-       /*
-        * This means that we've seen another request in this conversation
-        * with the same request and reply, and without an intervening
-        * reply to that first request, and thus won't be using this
-        * "request_val" structure for that request (as we'd use it only
-        * for the reply).
-        *
-        * Clean out the structure, and set it to refer to this frame.
-        */
-       request_val -> frame = fd->num;
-       request_val -> last_transact2_command = -1;             /* unknown */
-       if (request_val -> last_transact_command)
-         g_free(request_val -> last_transact_command);
-       request_val -> last_transact_command = NULL;
-       if (request_val -> last_param_descrip)
-         g_free(request_val -> last_param_descrip);
-       request_val -> last_param_descrip = NULL;
-       if (request_val -> last_data_descrip)
-         g_free(request_val -> last_data_descrip);
-       request_val -> last_data_descrip = NULL;
-       if (request_val -> last_aux_data_descrip)
-         g_free(request_val -> last_aux_data_descrip);
-       request_val -> last_aux_data_descrip = NULL;
-      }
-    }
-  } else {
-    /*
-     * This is a reply.
-     */
-    if (!fd->flags.visited) {
-      /*
-       * This is the first time the frame has been seen; check for
-       * an entry for a matching request, with an unknown reply frame
-       * number, in the hash table.
-       *
-       * If we find it, re-hash it with this frame's number as the
-       * reply frame number.
-       */
-      request_key.conversation = conversation->index;
-      request_key.mid          = si.mid;
-      request_key.pid          = si.pid;
-      request_key.frame_num    = 0;
-
-      /*
-       * Look it up - and, if we find it, get pointers to the key and
-       * value structures for it.
-       */
-      if (g_hash_table_lookup_extended(smb_request_hash, &request_key,
-                                      &new_request_key_ret,
-                                      &request_val_ret)) {
-       new_request_key = new_request_key_ret;
-       request_val = request_val_ret;
-
-       /*
-        * We found it.
-        * Remove the old entry.
-        */
-       g_hash_table_remove(smb_request_hash, &request_key);
-
-       /*
-        * Now update the key, and put it back into the hash table with
-        * the new key.
-        */
-       new_request_key->frame_num = fd->num;
-       g_hash_table_insert(smb_request_hash, new_request_key, request_val);
-      }
-    } else {
-      /*
-       * This is not the first time the frame has been seen; check for
-       * an entry for a matching request, with this frame's frame
-       * number as the reply frame number, in the hash table.
-       */
-      request_key.conversation = conversation->index;
-      request_key.mid          = si.mid;
-      request_key.pid          = si.pid;
-      request_key.frame_num    = fd->num;
-
-      request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
-    }
-  }
-
-  return request_val;
-}
-
-static struct smb_continuation_val *
-do_continuation_hashing(conversation_t *conversation, struct smb_info si,
-                      frame_data *fd, guint16 TotalDataCount,
-                      guint16 DataCount, const char **TransactName)
+free_all_smb_info_matched(gpointer key_arg, gpointer value, gpointer user_data)
 {
-  struct smb_request_key request_key, *new_request_key;
-  struct smb_continuation_val *continuation_val, *new_continuation_val;
-  gpointer               new_request_key_ret, continuation_val_ret;
-
-  continuation_val = NULL;
-  if (si.ddisp != 0) {
-    /*
-     * This reply isn't the first in the series; there should be a
-     * reply of which it is a continuation.
-     */
-    if (!fd->flags.visited) {
-      /*
-       * This is the first time the frame has been seen; check for
-       * an entry for a matching continued message, with an unknown
-       * continuation frame number, in the hash table.
-       *
-       * If we find it, re-hash it with this frame's number as the
-       * continuation frame number.
-       */
-      request_key.conversation = conversation->index;
-      request_key.mid          = si.mid;
-      request_key.pid          = si.pid;
-      request_key.frame_num    = 0;
-
-      /*
-       * Look it up - and, if we find it, get pointers to the key and
-       * value structures for it.
-       */
-      if (g_hash_table_lookup_extended(smb_continuation_hash, &request_key,
-                                      &new_request_key_ret,
-                                      &continuation_val_ret)) {
-       new_request_key = new_request_key_ret;
-       continuation_val = continuation_val_ret;
-
-       /*
-        * We found it.
-        * Remove the old entry.
-        */
-       g_hash_table_remove(smb_continuation_hash, &request_key);
-
-       /*
-        * Now update the key, and put it back into the hash table with
-        * the new key.
-        */
-       new_request_key->frame_num = fd->num;
-       g_hash_table_insert(smb_continuation_hash, new_request_key,
-                           continuation_val);
-      }
-    } else {
-      /*
-       * This is not the first time the frame has been seen; check for
-       * an entry for a matching request, with this frame's frame
-       * number as the continuation frame number, in the hash table.
-       */
-      request_key.conversation = conversation->index;
-      request_key.mid          = si.mid;
-      request_key.pid          = si.pid;
-      request_key.frame_num    = fd->num;
-
-      continuation_val = (struct smb_continuation_val *)
-               g_hash_table_lookup(smb_continuation_hash, &request_key);
-    }
-  }
-
-  /*
-   * If we found the entry for the message of which this is a continuation,
-   * and our caller cares, get the transaction name for that message, as
-   * it's the transaction name for this message as well.
-   */
-  if (continuation_val != NULL && TransactName != NULL)
-    *TransactName = continuation_val -> transact_name;
-
-  if (TotalDataCount > DataCount + si.ddisp) {
-    /*
-     * This reply isn't the last in the series; there should be a
-     * continuation for it later in the capture.
-     *
-     * If this is the first time the frame has been seen, check for
-     * an entry for the reply in the hash table.  If it's not found,
-     * insert an entry for it.
-     *
-     * If it's the first time it's been seen, then we can't have seen
-     * the continuation yet, so the continuation frame number should
-     * be 0, for "unknown".
-     */
-    if (!fd->flags.visited) {
-      request_key.conversation = conversation->index;
-      request_key.mid          = si.mid;
-      request_key.pid          = si.pid;
-      request_key.frame_num    = 0;
-
-      new_continuation_val = (struct smb_continuation_val *)
-               g_hash_table_lookup(smb_continuation_hash, &request_key);
-
-      if (new_continuation_val == NULL) {
-       /*
-        * Not found.
-        */
-       new_request_key = g_mem_chunk_alloc(smb_request_keys);
-       new_request_key -> conversation = conversation->index;
-       new_request_key -> mid          = si.mid;
-       new_request_key -> pid          = si.pid;
-       new_request_key -> frame_num    = 0;
-
-       new_continuation_val = g_mem_chunk_alloc(smb_continuation_vals);
-       new_continuation_val -> frame = fd->num;
-       if (TransactName != NULL)
-         new_continuation_val -> transact_name = *TransactName;
-       else
-         new_continuation_val -> transact_name = NULL;
-
-       g_hash_table_insert(smb_continuation_hash, new_request_key,
-                           new_continuation_val);
-      } else {
-       /*
-        * This presumably means we never saw the continuation of
-        * the message we found, and this is a reply to a different
-        * request; as we never saw the continuation of that message,
-        * we won't be using this "request_val" structure for that
-        * message (as we'd use it only for the continuation).
-        *
-        * Clean out the structure, and set it to refer to this frame.
-        */
-       new_continuation_val -> frame = fd->num;
-      }
-    }
-  }
-
-  return continuation_val;
+       return TRUE;
 }
+typedef struct conv_tables {
+       GHashTable *unmatched;
+       GHashTable *matched;
+} conv_tables_t;
+static GMemChunk *conv_tables_chunk = NULL;
+static int conv_tables_count = 10;
+
 
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    End of request/response matching functions
@@ -7630,17 +7199,24 @@ dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        smb_info_t      *sip;
        guint8 wc;
        guint16 bc;
+       conversation_t *conversation;
+       conv_tables_t *ct;
+       smb_info_t *old_si;
 
-       /* XXX I think this correct to find the matching request, must test */
        sip = pinfo->private_data;
-       sip->src = &pinfo->src;
-       sip->dst = &pinfo->dst;
-       sip = g_hash_table_lookup(smb_info_table, sip);
-       if(sip){
-               proto_tree_add_uint(tree, hf_smb_cancel_to, tvb, 0, 0, sip->frame_req);
-       } else {
-               proto_tree_add_text(tree, tvb, 0, 0,
-                       "Cancelation to: <unknown frame>");
+       conversation = find_conversation(&pinfo->src, &pinfo->dst,
+                         pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
+       if(conversation){
+               ct=conversation_get_proto_data(conversation, proto_smb);
+               if(ct){
+                       old_si=g_hash_table_lookup(ct->unmatched, (void *)sip->mid);
+                       if(old_si){
+                               proto_tree_add_uint(tree, hf_smb_cancel_to, tvb, 0, 0, old_si->frame_req);
+                       } else {
+                               proto_tree_add_text(tree, tvb, 0, 0,
+                                                   "Cancellation to: <unknown frame>");
+                       }
+               }
        }
 
        WORD_COUNT;
@@ -7899,13 +7475,11 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
-       struct smb_request_val *request_val;
        int fn_len;
        const char *fn;
        int old_offset = offset;
 
        si = (smb_info_t *)pinfo->private_data;
-       request_val = si->request_val;
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, bc,
@@ -7993,8 +7567,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* Find First2 information level */
                CHECK_BYTE_COUNT_TRANS(2);
                si->info_level = tvb_get_letohs(tvb, offset);
-               if (!pinfo->fd->flags.visited)
-                       request_val->last_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
 
@@ -8032,8 +7604,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* Find First2 information level */
                CHECK_BYTE_COUNT_TRANS(2);
                si->info_level = tvb_get_letohs(tvb, offset);
-               if (!pinfo->fd->flags.visited)
-                       request_val->last_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
 
@@ -8064,8 +7634,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* level of interest */
                CHECK_BYTE_COUNT_TRANS(2);
                si->info_level = tvb_get_letohs(tvb, offset);
-               if (!pinfo->fd->flags.visited)
-                       request_val->last_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
 
@@ -8074,8 +7642,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* level of interest */
                CHECK_BYTE_COUNT_TRANS(2);
                si->info_level = tvb_get_letohs(tvb, offset);
-               if (!pinfo->fd->flags.visited)
-                       request_val->last_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
                
@@ -8101,8 +7667,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* level of interest */
                CHECK_BYTE_COUNT_TRANS(2);
                si->info_level = tvb_get_letohs(tvb, offset);
-               if (!pinfo->fd->flags.visited)
-                       request_val->last_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
                
@@ -8133,8 +7697,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* level of interest */
                CHECK_BYTE_COUNT_TRANS(2);
                si->info_level = tvb_get_letohs(tvb, offset);
-               if (!pinfo->fd->flags.visited)
-                       request_val->last_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
                
@@ -8148,8 +7710,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* level of interest */
                CHECK_BYTE_COUNT_TRANS(2);
                si->info_level = tvb_get_letohs(tvb, offset);
-               if (!pinfo->fd->flags.visited)
-                       request_val->last_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
                
@@ -9130,8 +8690,6 @@ dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
 static int
 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
-       conversation_t *conversation;
-       struct smb_request_val *request_val;
        guint8 wc, sc=0;
        int so=0;
        guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
@@ -9144,26 +8702,6 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        si = (smb_info_t *)pinfo->private_data;
 
-       /*
-        * Find out what conversation this packet is part of.
-        */
-       conversation = find_conversation(&pinfo->src, &pinfo->dst,
-           pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
-
-       if (conversation == NULL) {
-               /*
-                * There isn't one yet; create it.
-                */
-               conversation = conversation_new(&pinfo->src, &pinfo->dst,
-                   pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
-       }
-
-       si->conversation = conversation;  /* Save this */
-
-       request_val = do_transaction_hashing(conversation, *si, pinfo->fd);
-
-       si->request_val = request_val;  /* Save this for later */
-
        WORD_COUNT;
 
        if(wc==8){
@@ -9306,8 +8844,6 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                            val_to_str(si->subcmd, trans2_cmd_vals, 
                                                "Unknown (0x%02x)"));
                                }
-                               if (!pinfo->fd->flags.visited)
-                                       request_val->last_transact2_command = si->subcmd;
                                break;
 
                        case 0x25:
@@ -10647,8 +10183,6 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
 static int
 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
-       conversation_t *conversation;
-       struct smb_request_val *request_val;
        guint8 sc=0, wc;
        guint16 od=0, tf, po=0, pc=0, pd, dc=0, dd=0;
        int so=0;
@@ -10659,66 +10193,33 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 
        si = (smb_info_t *)pinfo->private_data;
 
-       /*
-        * Find out what conversation this packet is part of.
-        */
-       conversation = find_conversation(&pinfo->src, &pinfo->dst,
-           pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
-
-       if (conversation == NULL) {
-               /*
-                * There isn't one yet; create it.
-                */
-               conversation = conversation_new(&pinfo->src, &pinfo->dst,
-                   pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
-       }
-
-       si->conversation = conversation;  /* Save this */
-
-       request_val = do_transaction_hashing(conversation, *si, pinfo->fd);
-
-       si->request_val = request_val;  /* Save this for later */
-
-       if(request_val != NULL){
-               switch(si->cmd){
-
-               case 0x32:
-                       /* transaction2 */
-                       si->subcmd = request_val->last_transact2_command;
-                       if (si->subcmd != -1) {
-                               proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, si->subcmd);
-                               if (check_col(pinfo->fd, COL_INFO)) {
-                                       col_append_fstr(pinfo->fd, COL_INFO, " %s",
-                                               val_to_str(si->subcmd,
-                                                       trans2_cmd_vals, 
-                                                       "<unknown (0x%02x)> "));
-                               }
-                       } else {
-                               /*
-                                * We didn't manage to extract the subcommand
-                                * from the matching request (perhaps because
-                                * the frame was short), so we don't know what
-                                * type of transaction this is.
-                                */
-                               proto_tree_add_text(tree, tvb, 0, 0,
-                                       "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
-                               if (check_col(pinfo->fd, COL_INFO)) {
-                                       col_append_fstr(pinfo->fd, COL_INFO, "<unknown> ");
-                               }
+       switch(si->cmd){
+       case 0x32:
+               /* transaction2 */
+               if (si->subcmd != -1) {
+                       proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, si->subcmd);
+                       if (check_col(pinfo->fd, COL_INFO)) {
+                               col_append_fstr(pinfo->fd, COL_INFO, " %s",
+                                       val_to_str(si->subcmd,
+                                               trans2_cmd_vals, 
+                                               "<unknown (0x%02x)>"));
+                       }
+               } else {
+                       /*
+                        * We didn't manage to extract the subcommand
+                        * from the matching request (perhaps because
+                        * the frame was short), so we don't know what
+                        * type of transaction this is.
+                        * (XXX - Or we didn't even see the matching request
+                        * in the first place.)
+                        */
+                       proto_tree_add_text(tree, tvb, 0, 0,
+                               "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
+                       if (check_col(pinfo->fd, COL_INFO)) {
+                               col_append_fstr(pinfo->fd, COL_INFO, "<unknown>");
                        }
-                       break;
-               }
-               si->info_level = request_val->last_level;
-       } else {
-               /* we have not seen the request yet so we don't know what 
-                  subcommand it was */
-               proto_tree_add_text(tree, tvb, 0, 0,
-                       "Subcommand: <UNKNOWN> since request packet was not captured");
-               if (check_col(pinfo->fd, COL_INFO)) {
-                       col_append_fstr(pinfo->fd, COL_INFO, "<unknown> ");
                }
-               si->subcmd = -1;
-               si->info_level = -1;
+               break;
        }
 
        WORD_COUNT;
@@ -10906,6 +10407,27 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
 
+static int
+dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+       guint8 wc;
+       guint16 bc;
+
+       WORD_COUNT;
+       if (wc != 0)
+               proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
+
+       BYTE_COUNT;
+
+       if (bc != 0)
+               proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
+
+       END_OF_SMB
+
+       return offset;
+}
+
 typedef struct _smb_function {
        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
@@ -10934,28 +10456,28 @@ smb_function smb_dissector[256] = {
   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
-  /* 0x15 */  {NULL, NULL},
-  /* 0x16 */  {NULL, NULL},
-  /* 0x17 */  {NULL, NULL},
-  /* 0x18 */  {NULL, NULL},
-  /* 0x19 */  {NULL, NULL},
-  /* 0x1a Read Raw*/  {dissect_read_raw_request, NULL},
+  /* 0x15 */  {dissect_unknown, dissect_unknown},
+  /* 0x16 */  {dissect_unknown, dissect_unknown},
+  /* 0x17 */  {dissect_unknown, dissect_unknown},
+  /* 0x18 */  {dissect_unknown, dissect_unknown},
+  /* 0x19 */  {dissect_unknown, dissect_unknown},
+  /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
-  /* 0x1c */  {NULL, NULL},
+  /* 0x1c */  {dissect_unknown, dissect_unknown},
   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
-  /* 0x1f */  {NULL, NULL},
+  /* 0x1f */  {dissect_unknown, dissect_unknown},
 
-  /* 0x20 Write Complete*/  {NULL, dissect_write_and_close_response},
-  /* 0x21 */  {NULL, NULL},
+  /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
+  /* 0x21 */  {dissect_unknown, dissect_unknown},
   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
   /* 0x25 Transaction*/                {dissect_transaction_request, dissect_transaction_response},
-  /* 0x26 */  {NULL, NULL},
-  /* 0x27 */  {NULL, NULL},
-  /* 0x28 */  {NULL, NULL},
-  /* 0x29 */  {NULL, NULL},
+  /* 0x26 */  {dissect_unknown, dissect_unknown},
+  /* 0x27 */  {dissect_unknown, dissect_unknown},
+  /* 0x28 */  {dissect_unknown, dissect_unknown},
+  /* 0x29 */  {dissect_unknown, dissect_unknown},
   /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
@@ -10963,73 +10485,73 @@ smb_function smb_dissector[256] = {
   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
 
-  /* 0x30 */  {NULL, NULL},
-  /* 0x31 */  {NULL, NULL},
+  /* 0x30 */  {dissect_unknown, dissect_unknown},
+  /* 0x31 */  {dissect_unknown, dissect_unknown},
   /* 0x32 Transaction2*/               {dissect_transaction_request, dissect_transaction_response},
-  /* 0x33 */  {NULL, NULL},
+  /* 0x33 */  {dissect_unknown, dissect_unknown},
   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
-  /* 0x35 */  {NULL, NULL},
-  /* 0x36 */  {NULL, NULL},
-  /* 0x37 */  {NULL, NULL},
-  /* 0x38 */  {NULL, NULL},
-  /* 0x39 */  {NULL, NULL},
-  /* 0x3a */  {NULL, NULL},
-  /* 0x3b */  {NULL, NULL},
-  /* 0x3c */  {NULL, NULL},
-  /* 0x3d */  {NULL, NULL},
-  /* 0x3e */  {NULL, NULL},
-  /* 0x3f */  {NULL, NULL},
-
-  /* 0x40 */  {NULL, NULL},
-  /* 0x41 */  {NULL, NULL},
-  /* 0x42 */  {NULL, NULL},
-  /* 0x43 */  {NULL, NULL},
-  /* 0x44 */  {NULL, NULL},
-  /* 0x45 */  {NULL, NULL},
-  /* 0x46 */  {NULL, NULL},
-  /* 0x47 */  {NULL, NULL},
-  /* 0x48 */  {NULL, NULL},
-  /* 0x49 */  {NULL, NULL},
-  /* 0x4a */  {NULL, NULL},
-  /* 0x4b */  {NULL, NULL},
-  /* 0x4c */  {NULL, NULL},
-  /* 0x4d */  {NULL, NULL},
-  /* 0x4e */  {NULL, NULL},
-  /* 0x4f */  {NULL, NULL},
-
-  /* 0x50 */  {NULL, NULL},
-  /* 0x51 */  {NULL, NULL},
-  /* 0x52 */  {NULL, NULL},
-  /* 0x53 */  {NULL, NULL},
-  /* 0x54 */  {NULL, NULL},
-  /* 0x55 */  {NULL, NULL},
-  /* 0x56 */  {NULL, NULL},
-  /* 0x57 */  {NULL, NULL},
-  /* 0x58 */  {NULL, NULL},
-  /* 0x59 */  {NULL, NULL},
-  /* 0x5a */  {NULL, NULL},
-  /* 0x5b */  {NULL, NULL},
-  /* 0x5c */  {NULL, NULL},
-  /* 0x5d */  {NULL, NULL},
-  /* 0x5e */  {NULL, NULL},
-  /* 0x5f */  {NULL, NULL},
-
-  /* 0x60 */  {NULL, NULL},
-  /* 0x61 */  {NULL, NULL},
-  /* 0x62 */  {NULL, NULL},
-  /* 0x63 */  {NULL, NULL},
-  /* 0x64 */  {NULL, NULL},
-  /* 0x65 */  {NULL, NULL},
-  /* 0x66 */  {NULL, NULL},
-  /* 0x67 */  {NULL, NULL},
-  /* 0x68 */  {NULL, NULL},
-  /* 0x69 */  {NULL, NULL},
-  /* 0x6a */  {NULL, NULL},
-  /* 0x6b */  {NULL, NULL},
-  /* 0x6c */  {NULL, NULL},
-  /* 0x6d */  {NULL, NULL},
-  /* 0x6e */  {NULL, NULL},
-  /* 0x6f */  {NULL, NULL},
+  /* 0x35 */  {dissect_unknown, dissect_unknown},
+  /* 0x36 */  {dissect_unknown, dissect_unknown},
+  /* 0x37 */  {dissect_unknown, dissect_unknown},
+  /* 0x38 */  {dissect_unknown, dissect_unknown},
+  /* 0x39 */  {dissect_unknown, dissect_unknown},
+  /* 0x3a */  {dissect_unknown, dissect_unknown},
+  /* 0x3b */  {dissect_unknown, dissect_unknown},
+  /* 0x3c */  {dissect_unknown, dissect_unknown},
+  /* 0x3d */  {dissect_unknown, dissect_unknown},
+  /* 0x3e */  {dissect_unknown, dissect_unknown},
+  /* 0x3f */  {dissect_unknown, dissect_unknown},
+
+  /* 0x40 */  {dissect_unknown, dissect_unknown},
+  /* 0x41 */  {dissect_unknown, dissect_unknown},
+  /* 0x42 */  {dissect_unknown, dissect_unknown},
+  /* 0x43 */  {dissect_unknown, dissect_unknown},
+  /* 0x44 */  {dissect_unknown, dissect_unknown},
+  /* 0x45 */  {dissect_unknown, dissect_unknown},
+  /* 0x46 */  {dissect_unknown, dissect_unknown},
+  /* 0x47 */  {dissect_unknown, dissect_unknown},
+  /* 0x48 */  {dissect_unknown, dissect_unknown},
+  /* 0x49 */  {dissect_unknown, dissect_unknown},
+  /* 0x4a */  {dissect_unknown, dissect_unknown},
+  /* 0x4b */  {dissect_unknown, dissect_unknown},
+  /* 0x4c */  {dissect_unknown, dissect_unknown},
+  /* 0x4d */  {dissect_unknown, dissect_unknown},
+  /* 0x4e */  {dissect_unknown, dissect_unknown},
+  /* 0x4f */  {dissect_unknown, dissect_unknown},
+
+  /* 0x50 */  {dissect_unknown, dissect_unknown},
+  /* 0x51 */  {dissect_unknown, dissect_unknown},
+  /* 0x52 */  {dissect_unknown, dissect_unknown},
+  /* 0x53 */  {dissect_unknown, dissect_unknown},
+  /* 0x54 */  {dissect_unknown, dissect_unknown},
+  /* 0x55 */  {dissect_unknown, dissect_unknown},
+  /* 0x56 */  {dissect_unknown, dissect_unknown},
+  /* 0x57 */  {dissect_unknown, dissect_unknown},
+  /* 0x58 */  {dissect_unknown, dissect_unknown},
+  /* 0x59 */  {dissect_unknown, dissect_unknown},
+  /* 0x5a */  {dissect_unknown, dissect_unknown},
+  /* 0x5b */  {dissect_unknown, dissect_unknown},
+  /* 0x5c */  {dissect_unknown, dissect_unknown},
+  /* 0x5d */  {dissect_unknown, dissect_unknown},
+  /* 0x5e */  {dissect_unknown, dissect_unknown},
+  /* 0x5f */  {dissect_unknown, dissect_unknown},
+
+  /* 0x60 */  {dissect_unknown, dissect_unknown},
+  /* 0x61 */  {dissect_unknown, dissect_unknown},
+  /* 0x62 */  {dissect_unknown, dissect_unknown},
+  /* 0x63 */  {dissect_unknown, dissect_unknown},
+  /* 0x64 */  {dissect_unknown, dissect_unknown},
+  /* 0x65 */  {dissect_unknown, dissect_unknown},
+  /* 0x66 */  {dissect_unknown, dissect_unknown},
+  /* 0x67 */  {dissect_unknown, dissect_unknown},
+  /* 0x68 */  {dissect_unknown, dissect_unknown},
+  /* 0x69 */  {dissect_unknown, dissect_unknown},
+  /* 0x6a */  {dissect_unknown, dissect_unknown},
+  /* 0x6b */  {dissect_unknown, dissect_unknown},
+  /* 0x6c */  {dissect_unknown, dissect_unknown},
+  /* 0x6d */  {dissect_unknown, dissect_unknown},
+  /* 0x6e */  {dissect_unknown, dissect_unknown},
+  /* 0x6f */  {dissect_unknown, dissect_unknown},
 
   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
@@ -11037,150 +10559,150 @@ smb_function smb_dissector[256] = {
   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
-  /* 0x76 */  {NULL, NULL},
-  /* 0x77 */  {NULL, NULL},
-  /* 0x78 */  {NULL, NULL},
-  /* 0x79 */  {NULL, NULL},
-  /* 0x7a */  {NULL, NULL},
-  /* 0x7b */  {NULL, NULL},
-  /* 0x7c */  {NULL, NULL},
-  /* 0x7d */  {NULL, NULL},
-  /* 0x7e */  {NULL, NULL},
-  /* 0x7f */  {NULL, NULL},
+  /* 0x76 */  {dissect_unknown, dissect_unknown},
+  /* 0x77 */  {dissect_unknown, dissect_unknown},
+  /* 0x78 */  {dissect_unknown, dissect_unknown},
+  /* 0x79 */  {dissect_unknown, dissect_unknown},
+  /* 0x7a */  {dissect_unknown, dissect_unknown},
+  /* 0x7b */  {dissect_unknown, dissect_unknown},
+  /* 0x7c */  {dissect_unknown, dissect_unknown},
+  /* 0x7d */  {dissect_unknown, dissect_unknown},
+  /* 0x7e */  {dissect_unknown, dissect_unknown},
+  /* 0x7f */  {dissect_unknown, dissect_unknown},
 
   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
-  /* 0x82 */  {NULL, NULL},
-  /* 0x83 */  {NULL, NULL},
-  /* 0x84 */  {NULL, NULL},
-  /* 0x85 */  {NULL, NULL},
-  /* 0x86 */  {NULL, NULL},
-  /* 0x87 */  {NULL, NULL},
-  /* 0x88 */  {NULL, NULL},
-  /* 0x89 */  {NULL, NULL},
-  /* 0x8a */  {NULL, NULL},
-  /* 0x8b */  {NULL, NULL},
-  /* 0x8c */  {NULL, NULL},
-  /* 0x8d */  {NULL, NULL},
-  /* 0x8e */  {NULL, NULL},
-  /* 0x8f */  {NULL, NULL},
-
-  /* 0x90 */  {NULL, NULL},
-  /* 0x91 */  {NULL, NULL},
-  /* 0x92 */  {NULL, NULL},
-  /* 0x93 */  {NULL, NULL},
-  /* 0x94 */  {NULL, NULL},
-  /* 0x95 */  {NULL, NULL},
-  /* 0x96 */  {NULL, NULL},
-  /* 0x97 */  {NULL, NULL},
-  /* 0x98 */  {NULL, NULL},
-  /* 0x99 */  {NULL, NULL},
-  /* 0x9a */  {NULL, NULL},
-  /* 0x9b */  {NULL, NULL},
-  /* 0x9c */  {NULL, NULL},
-  /* 0x9d */  {NULL, NULL},
-  /* 0x9e */  {NULL, NULL},
-  /* 0x9f */  {NULL, NULL},
+  /* 0x82 */  {dissect_unknown, dissect_unknown},
+  /* 0x83 */  {dissect_unknown, dissect_unknown},
+  /* 0x84 */  {dissect_unknown, dissect_unknown},
+  /* 0x85 */  {dissect_unknown, dissect_unknown},
+  /* 0x86 */  {dissect_unknown, dissect_unknown},
+  /* 0x87 */  {dissect_unknown, dissect_unknown},
+  /* 0x88 */  {dissect_unknown, dissect_unknown},
+  /* 0x89 */  {dissect_unknown, dissect_unknown},
+  /* 0x8a */  {dissect_unknown, dissect_unknown},
+  /* 0x8b */  {dissect_unknown, dissect_unknown},
+  /* 0x8c */  {dissect_unknown, dissect_unknown},
+  /* 0x8d */  {dissect_unknown, dissect_unknown},
+  /* 0x8e */  {dissect_unknown, dissect_unknown},
+  /* 0x8f */  {dissect_unknown, dissect_unknown},
+
+  /* 0x90 */  {dissect_unknown, dissect_unknown},
+  /* 0x91 */  {dissect_unknown, dissect_unknown},
+  /* 0x92 */  {dissect_unknown, dissect_unknown},
+  /* 0x93 */  {dissect_unknown, dissect_unknown},
+  /* 0x94 */  {dissect_unknown, dissect_unknown},
+  /* 0x95 */  {dissect_unknown, dissect_unknown},
+  /* 0x96 */  {dissect_unknown, dissect_unknown},
+  /* 0x97 */  {dissect_unknown, dissect_unknown},
+  /* 0x98 */  {dissect_unknown, dissect_unknown},
+  /* 0x99 */  {dissect_unknown, dissect_unknown},
+  /* 0x9a */  {dissect_unknown, dissect_unknown},
+  /* 0x9b */  {dissect_unknown, dissect_unknown},
+  /* 0x9c */  {dissect_unknown, dissect_unknown},
+  /* 0x9d */  {dissect_unknown, dissect_unknown},
+  /* 0x9e */  {dissect_unknown, dissect_unknown},
+  /* 0x9f */  {dissect_unknown, dissect_unknown},
   /* 0xa0 NT Transaction*/     {dissect_nt_transaction_request, dissect_nt_transaction_response},
   /* 0xa1 NT Trans secondary*/ {dissect_nt_transaction_request, dissect_nt_transaction_response},
   /* 0xa2 NT CreateAndX*/              {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
-  /* 0xa3 */  {NULL, NULL},
-  /* 0xa4 NT Cancel*/          {dissect_nt_cancel_request, NULL}, /*no response to this one*/
-  /* 0xa5 */  {NULL, NULL},
-  /* 0xa6 */  {NULL, NULL},
-  /* 0xa7 */  {NULL, NULL},
-  /* 0xa8 */  {NULL, NULL},
-  /* 0xa9 */  {NULL, NULL},
-  /* 0xaa */  {NULL, NULL},
-  /* 0xab */  {NULL, NULL},
-  /* 0xac */  {NULL, NULL},
-  /* 0xad */  {NULL, NULL},
-  /* 0xae */  {NULL, NULL},
-  /* 0xaf */  {NULL, NULL},
-
-  /* 0xb0 */  {NULL, NULL},
-  /* 0xb1 */  {NULL, NULL},
-  /* 0xb2 */  {NULL, NULL},
-  /* 0xb3 */  {NULL, NULL},
-  /* 0xb4 */  {NULL, NULL},
-  /* 0xb5 */  {NULL, NULL},
-  /* 0xb6 */  {NULL, NULL},
-  /* 0xb7 */  {NULL, NULL},
-  /* 0xb8 */  {NULL, NULL},
-  /* 0xb9 */  {NULL, NULL},
-  /* 0xba */  {NULL, NULL},
-  /* 0xbb */  {NULL, NULL},
-  /* 0xbc */  {NULL, NULL},
-  /* 0xbd */  {NULL, NULL},
-  /* 0xbe */  {NULL, NULL},
-  /* 0xbf */  {NULL, NULL},
+  /* 0xa3 */  {dissect_unknown, dissect_unknown},
+  /* 0xa4 NT Cancel*/          {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
+  /* 0xa5 */  {dissect_unknown, dissect_unknown},
+  /* 0xa6 */  {dissect_unknown, dissect_unknown},
+  /* 0xa7 */  {dissect_unknown, dissect_unknown},
+  /* 0xa8 */  {dissect_unknown, dissect_unknown},
+  /* 0xa9 */  {dissect_unknown, dissect_unknown},
+  /* 0xaa */  {dissect_unknown, dissect_unknown},
+  /* 0xab */  {dissect_unknown, dissect_unknown},
+  /* 0xac */  {dissect_unknown, dissect_unknown},
+  /* 0xad */  {dissect_unknown, dissect_unknown},
+  /* 0xae */  {dissect_unknown, dissect_unknown},
+  /* 0xaf */  {dissect_unknown, dissect_unknown},
+
+  /* 0xb0 */  {dissect_unknown, dissect_unknown},
+  /* 0xb1 */  {dissect_unknown, dissect_unknown},
+  /* 0xb2 */  {dissect_unknown, dissect_unknown},
+  /* 0xb3 */  {dissect_unknown, dissect_unknown},
+  /* 0xb4 */  {dissect_unknown, dissect_unknown},
+  /* 0xb5 */  {dissect_unknown, dissect_unknown},
+  /* 0xb6 */  {dissect_unknown, dissect_unknown},
+  /* 0xb7 */  {dissect_unknown, dissect_unknown},
+  /* 0xb8 */  {dissect_unknown, dissect_unknown},
+  /* 0xb9 */  {dissect_unknown, dissect_unknown},
+  /* 0xba */  {dissect_unknown, dissect_unknown},
+  /* 0xbb */  {dissect_unknown, dissect_unknown},
+  /* 0xbc */  {dissect_unknown, dissect_unknown},
+  /* 0xbd */  {dissect_unknown, dissect_unknown},
+  /* 0xbe */  {dissect_unknown, dissect_unknown},
+  /* 0xbf */  {dissect_unknown, dissect_unknown},
   /* 0xc0 Open Print File*/    {dissect_open_print_file_request, dissect_fid},
   /* 0xc1 Write Print File*/   {dissect_write_print_file_request, dissect_empty},
   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
   /* 0xc3 Get Print Queue*/    {dissect_get_print_queue_request, dissect_get_print_queue_response},
-  /* 0xc4 */  {NULL, NULL},
-  /* 0xc5 */  {NULL, NULL},
-  /* 0xc6 */  {NULL, NULL},
-  /* 0xc7 */  {NULL, NULL},
-  /* 0xc8 */  {NULL, NULL},
-  /* 0xc9 */  {NULL, NULL},
-  /* 0xca */  {NULL, NULL},
-  /* 0xcb */  {NULL, NULL},
-  /* 0xcc */  {NULL, NULL},
-  /* 0xcd */  {NULL, NULL},
-  /* 0xce */  {NULL, NULL},
-  /* 0xcf */  {NULL, NULL},
-
-  /* 0xd0 */  {NULL, NULL},
-  /* 0xd1 */  {NULL, NULL},
-  /* 0xd2 */  {NULL, NULL},
-  /* 0xd3 */  {NULL, NULL},
-  /* 0xd4 */  {NULL, NULL},
-  /* 0xd5 */  {NULL, NULL},
-  /* 0xd6 */  {NULL, NULL},
-  /* 0xd7 */  {NULL, NULL},
-  /* 0xd8 */  {NULL, NULL},
-  /* 0xd9 */  {NULL, NULL},
-  /* 0xda */  {NULL, NULL},
-  /* 0xdb */  {NULL, NULL},
-  /* 0xdc */  {NULL, NULL},
-  /* 0xdd */  {NULL, NULL},
-  /* 0xde */  {NULL, NULL},
-  /* 0xdf */  {NULL, NULL},
-
-  /* 0xe0 */  {NULL, NULL},
-  /* 0xe1 */  {NULL, NULL},
-  /* 0xe2 */  {NULL, NULL},
-  /* 0xe3 */  {NULL, NULL},
-  /* 0xe4 */  {NULL, NULL},
-  /* 0xe5 */  {NULL, NULL},
-  /* 0xe6 */  {NULL, NULL},
-  /* 0xe7 */  {NULL, NULL},
-  /* 0xe8 */  {NULL, NULL},
-  /* 0xe9 */  {NULL, NULL},
-  /* 0xea */  {NULL, NULL},
-  /* 0xeb */  {NULL, NULL},
-  /* 0xec */  {NULL, NULL},
-  /* 0xed */  {NULL, NULL},
-  /* 0xee */  {NULL, NULL},
-  /* 0xef */  {NULL, NULL},
-
-  /* 0xf0 */  {NULL, NULL},
-  /* 0xf1 */  {NULL, NULL},
-  /* 0xf2 */  {NULL, NULL},
-  /* 0xf3 */  {NULL, NULL},
-  /* 0xf4 */  {NULL, NULL},
-  /* 0xf5 */  {NULL, NULL},
-  /* 0xf6 */  {NULL, NULL},
-  /* 0xf7 */  {NULL, NULL},
-  /* 0xf8 */  {NULL, NULL},
-  /* 0xf9 */  {NULL, NULL},
-  /* 0xfa */  {NULL, NULL},
-  /* 0xfb */  {NULL, NULL},
-  /* 0xfc */  {NULL, NULL},
-  /* 0xfd */  {NULL, NULL},
-  /* 0xfe */  {NULL, NULL},
-  /* 0xff */  {NULL, NULL},
+  /* 0xc4 */  {dissect_unknown, dissect_unknown},
+  /* 0xc5 */  {dissect_unknown, dissect_unknown},
+  /* 0xc6 */  {dissect_unknown, dissect_unknown},
+  /* 0xc7 */  {dissect_unknown, dissect_unknown},
+  /* 0xc8 */  {dissect_unknown, dissect_unknown},
+  /* 0xc9 */  {dissect_unknown, dissect_unknown},
+  /* 0xca */  {dissect_unknown, dissect_unknown},
+  /* 0xcb */  {dissect_unknown, dissect_unknown},
+  /* 0xcc */  {dissect_unknown, dissect_unknown},
+  /* 0xcd */  {dissect_unknown, dissect_unknown},
+  /* 0xce */  {dissect_unknown, dissect_unknown},
+  /* 0xcf */  {dissect_unknown, dissect_unknown},
+
+  /* 0xd0 */  {dissect_unknown, dissect_unknown},
+  /* 0xd1 */  {dissect_unknown, dissect_unknown},
+  /* 0xd2 */  {dissect_unknown, dissect_unknown},
+  /* 0xd3 */  {dissect_unknown, dissect_unknown},
+  /* 0xd4 */  {dissect_unknown, dissect_unknown},
+  /* 0xd5 */  {dissect_unknown, dissect_unknown},
+  /* 0xd6 */  {dissect_unknown, dissect_unknown},
+  /* 0xd7 */  {dissect_unknown, dissect_unknown},
+  /* 0xd8 */  {dissect_unknown, dissect_unknown},
+  /* 0xd9 */  {dissect_unknown, dissect_unknown},
+  /* 0xda */  {dissect_unknown, dissect_unknown},
+  /* 0xdb */  {dissect_unknown, dissect_unknown},
+  /* 0xdc */  {dissect_unknown, dissect_unknown},
+  /* 0xdd */  {dissect_unknown, dissect_unknown},
+  /* 0xde */  {dissect_unknown, dissect_unknown},
+  /* 0xdf */  {dissect_unknown, dissect_unknown},
+
+  /* 0xe0 */  {dissect_unknown, dissect_unknown},
+  /* 0xe1 */  {dissect_unknown, dissect_unknown},
+  /* 0xe2 */  {dissect_unknown, dissect_unknown},
+  /* 0xe3 */  {dissect_unknown, dissect_unknown},
+  /* 0xe4 */  {dissect_unknown, dissect_unknown},
+  /* 0xe5 */  {dissect_unknown, dissect_unknown},
+  /* 0xe6 */  {dissect_unknown, dissect_unknown},
+  /* 0xe7 */  {dissect_unknown, dissect_unknown},
+  /* 0xe8 */  {dissect_unknown, dissect_unknown},
+  /* 0xe9 */  {dissect_unknown, dissect_unknown},
+  /* 0xea */  {dissect_unknown, dissect_unknown},
+  /* 0xeb */  {dissect_unknown, dissect_unknown},
+  /* 0xec */  {dissect_unknown, dissect_unknown},
+  /* 0xed */  {dissect_unknown, dissect_unknown},
+  /* 0xee */  {dissect_unknown, dissect_unknown},
+  /* 0xef */  {dissect_unknown, dissect_unknown},
+
+  /* 0xf0 */  {dissect_unknown, dissect_unknown},
+  /* 0xf1 */  {dissect_unknown, dissect_unknown},
+  /* 0xf2 */  {dissect_unknown, dissect_unknown},
+  /* 0xf3 */  {dissect_unknown, dissect_unknown},
+  /* 0xf4 */  {dissect_unknown, dissect_unknown},
+  /* 0xf5 */  {dissect_unknown, dissect_unknown},
+  /* 0xf6 */  {dissect_unknown, dissect_unknown},
+  /* 0xf7 */  {dissect_unknown, dissect_unknown},
+  /* 0xf8 */  {dissect_unknown, dissect_unknown},
+  /* 0xf9 */  {dissect_unknown, dissect_unknown},
+  /* 0xfa */  {dissect_unknown, dissect_unknown},
+  /* 0xfb */  {dissect_unknown, dissect_unknown},
+  /* 0xfc */  {dissect_unknown, dissect_unknown},
+  /* 0xfd */  {dissect_unknown, dissect_unknown},
+  /* 0xfe */  {dissect_unknown, dissect_unknown},
+  /* 0xff */  {dissect_unknown, dissect_unknown},
 };
 
 static int
@@ -11212,15 +10734,7 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int
                dissector = (si->request)?
                        smb_dissector[cmd].request:smb_dissector[cmd].response;
 
-               if(dissector){
-                       offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
-               } else {
-                       int len = tvb_length_remaining(tvb, offset);
-
-                       proto_tree_add_text(cmd_tree, tvb, offset, len,
-                           "Data (%u bytes)", len);
-                       offset += len;
-               }
+               offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
                proto_item_set_len(cmd_item, offset-old_offset);
        }
        return offset;
@@ -11514,52 +11028,19 @@ static char *decode_smb_name(unsigned char cmd)
 static void
 smb_init_protocol(void)
 {
-       if (smb_info_table) {
-               g_hash_table_foreach_remove(smb_info_table,
-                   free_all_smb_info, NULL);
-               g_hash_table_destroy(smb_info_table);
-       }
-       if (smb_request_hash) {
-               /*
-                * Remove all entries from the hash table and free all
-                * strings attached to the keys and values.  (The keys
-                * and values themselves are freed with
-                * "g_mem_chunk_destroy()" calls below.)
-                */
-               g_hash_table_foreach_remove(smb_request_hash,
-                   free_request_val_data, NULL);
-               g_hash_table_destroy(smb_request_hash);
-       }
-       if (smb_continuation_hash)
-               g_hash_table_destroy(smb_continuation_hash);
-       if (smb_request_keys)
-               g_mem_chunk_destroy(smb_request_keys);
-       if (smb_request_vals)
-               g_mem_chunk_destroy(smb_request_vals);
-       if (smb_continuation_vals)
-               g_mem_chunk_destroy(smb_continuation_vals);
        if (smb_info_chunk)
                g_mem_chunk_destroy(smb_info_chunk);
+       if (conv_tables_chunk)
+               g_mem_chunk_destroy(conv_tables_chunk);
 
-       smb_info_table = g_hash_table_new(smb_info_hash, smb_info_equal);
-       smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
-       smb_continuation_hash = g_hash_table_new(smb_hash, smb_equal);
-       smb_request_keys = g_mem_chunk_new("smb_request_keys",
-           sizeof(struct smb_request_key),
-           smb_packet_init_count * sizeof(struct smb_request_key),
-           G_ALLOC_AND_FREE);
-       smb_request_vals = g_mem_chunk_new("smb_request_vals",
-           sizeof(struct smb_request_val),
-           smb_packet_init_count * sizeof(struct smb_request_val),
-           G_ALLOC_AND_FREE);
-       smb_continuation_vals = g_mem_chunk_new("smb_continuation_vals",
-           sizeof(struct smb_continuation_val),
-           smb_packet_init_count * sizeof(struct smb_continuation_val),
-           G_ALLOC_AND_FREE);
        smb_info_chunk = g_mem_chunk_new("smb_info_chunk",
            sizeof(smb_info_t),
            smb_info_init_count * sizeof(smb_info_t),
            G_ALLOC_ONLY);
+       conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
+           sizeof(conv_tables_t),
+           conv_tables_count * sizeof(conv_tables_t),
+           G_ALLOC_ONLY);
 }
 
 /* Max string length for displaying Unicode strings.  */
@@ -12752,17 +12233,18 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
         guint32 nt_status = 0;
         guint8 errclass = 0;
         guint16 errcode = 0;
-
+       guint16 uid, pid, tid;
 
        top_tree=parent_tree;
 
        /* must check that this really is a smb packet */
        if (!tvb_bytes_exist(tvb, 0, 4))
-         return FALSE;
+               return FALSE;
+
        if( (tvb_get_guint8(tvb, 0) != 0xff)
-        || (tvb_get_guint8(tvb, 1) != 'S')
-        || (tvb_get_guint8(tvb, 2) != 'M')
-        || (tvb_get_guint8(tvb, 3) != 'B') ){
+           || (tvb_get_guint8(tvb, 1) != 'S')
+           || (tvb_get_guint8(tvb, 2) != 'M')
+           || (tvb_get_guint8(tvb, 3) != 'B') ){
                return FALSE;
        }
         
@@ -12782,9 +12264,9 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        sip->trans_subcmd = -1;
        sip->info_level = -1;
        sip->mid = tvb_get_letohs(tvb, offset+30);
-       sip->uid = tvb_get_letohs(tvb, offset+28);
-       sip->pid = tvb_get_letohs(tvb, offset+26);
-       sip->tid = tvb_get_letohs(tvb, offset+24);
+       uid = tvb_get_letohs(tvb, offset+28);
+       pid = tvb_get_letohs(tvb, offset+26);
+       tid = tvb_get_letohs(tvb, offset+24);
        flags2 = tvb_get_letohs(tvb, offset+10);
        if(flags2 & 0x8000){
                sip->unicode = TRUE; /* Mark them as Unicode */
@@ -12794,7 +12276,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        flags = tvb_get_guint8(tvb, offset+9);
        sip->request = !(flags&SMB_FLAGS_DIRN);
        sip->cmd = tvb_get_guint8(tvb, offset+4);
-       sip->ddisp = 0;
+       sip->request_val=NULL;
 
        if (parent_tree) {
                item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
@@ -12810,39 +12292,115 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
        offset += 4;  /* Skip the marker */
 
-       /* store smb_info structure so we can retreive it from the reply */
-       if(sip->request){
-               sip->src = &pinfo->src;
-               sip->dst = &pinfo->dst;
+
+       if( (sip->request)
+           &&  (sip->mid==0)
+           &&  (uid==0)
+           &&  (pid==0)
+           &&  (tid==0) ){
+               /* this is a broadcast SMB packet, there will not be a reply.
+                  We dont need to do anything 
+               */
+               sip->unidir=FALSE;
+       } else {
+               conversation_t *conversation;
+               conv_tables_t *ct;
+               smb_info_t *old_si;
+               gboolean request;
+               
+               sip->unidir=TRUE;
+               request=sip->request;
+               
+               /* first we try to find which conversation this packet is 
+                  part of 
+               */
+               conversation = find_conversation(&pinfo->src, &pinfo->dst,
+                        pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
+               if(conversation==NULL){
+                       /* OK this is a new conversation, we must create it
+                          and attach appropriate data (matched and unmatched 
+                          table for this conversation)
+                       */
+                       conversation = conversation_new(&pinfo->src, &pinfo->dst, 
+                               pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
+                       ct = g_mem_chunk_alloc(conv_tables_chunk);
+                       ct->matched= g_hash_table_new(smb_info_hash_matched, 
+                               smb_info_equal_matched);                
+                       ct->unmatched= g_hash_table_new(smb_info_hash_matched, 
+                               smb_info_equal_matched);                
+                       conversation_add_proto_data(conversation, proto_smb, ct);
+               } else {
+                       /* this is an old conversation, just get the tables */
+                       ct=conversation_get_proto_data(conversation, proto_smb);
+               }
                if(!pinfo->fd->flags.visited){
-                       if( (sip->mid==0)
-                       &&  (sip->uid==0)
-                       &&  (sip->pid==0)
-                       &&  (sip->tid==0) ){
-                               /* this is a broadcast SMB packet,
-                                  there will not be a reply.
-                                  We dont need to do anything */
-                               sip->unidir=FALSE;
-                       } else {
-                               sip->unidir=TRUE;
+                       /* first see if we find an unmatched smb "equal" to 
+                          the current one 
+                       */
+                       old_si=g_hash_table_lookup(ct->unmatched, 
+                               (void *)sip->mid);
+                       if(old_si!=NULL){
+                               if(request){
+                                       /* ok, we are processing an SMB
+                                          request but there was already
+                                          another "identical" smb resuest
+                                          we had not matched yet.
+                                          This must mean that either we have
+                                          a retransmission or that the
+                                          response to the previous one was
+                                          lost and the client has reused
+                                          the MID for this conversation.
+                                          In either case it's not much more
+                                          we can do than forget the old
+                                          request and concentrate on the 
+                                          present one instead.
+
+                                          XXX - not true for NT Cancel,
+                                          where the Cancel request has
+                                          the same TID/PID/MID/UID as
+                                          the request to be cancelled;
+                                          in that case, we should leave
+                                          the old request in place.
+                                          I'm not sure we can set "sip"
+                                          to point to "old_si", however.
+                                       */
+                                       g_hash_table_remove(ct->unmatched, (void *)sip->mid);
+                               } else {
+                                       /* we have found a response to some request we have seen earlier.
+                                          What we do now depends on whether this is the first response
+                                          to that request we see (id frame_res==0) or not. 
+                                       */
+                                       sip=old_si;
+                                       
+                                       if(sip->frame_res==0){
+                                               /* ok it is the first response we have seen to this packet */
+                                               sip->frame_res = pinfo->fd->num;
+                                               g_hash_table_insert(ct->matched, (void *)sip->frame_req, sip);
+                                               g_hash_table_insert(ct->matched, (void *)sip->frame_res, sip);
+                                       } else {
+                                               /* we have already seen another response to this one, but
+                                                  register it anyway so we see which request it matches 
+                                               */
+                                               g_hash_table_insert(ct->matched, (void *)pinfo->fd->num, sip);
+                                       }
+                               }
+                       }
+                       if(request){
                                sip = g_mem_chunk_alloc(smb_info_chunk);
                                memcpy(sip, &si, sizeof(smb_info_t));
                                sip->frame_req = pinfo->fd->num;
                                sip->frame_res = 0;
-                               sip->src=g_malloc(sizeof(address));
-                               COPY_ADDRESS(sip->src, &pinfo->src);
-                               sip->dst=g_malloc(sizeof(address));
-                               COPY_ADDRESS(sip->dst, &pinfo->dst);
-                               g_hash_table_insert(smb_info_table, sip, sip);
+                               g_hash_table_insert(ct->unmatched, (void *)sip->mid, sip);
+                       }
+               } else {
+                       /* we have seen this packet before, just check matching table and if that
+                          fails, just continue using si
+                       */
+                       old_si=g_hash_table_lookup(ct->matched, (void *)pinfo->fd->num);
+                       if(old_si){
+                               sip=old_si;
                        }
                }
-       } else {
-               sip->src = &pinfo->dst;
-               sip->dst = &pinfo->src;
-       }
-       sip = g_hash_table_lookup(smb_info_table, sip);
-       if(!sip){
-               sip = &si;
        }
        /* need to redo these ones, might have changed if we got a new sip */
        sip->request = !(flags&SMB_FLAGS_DIRN);
@@ -12857,9 +12415,6 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                        proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
                }
        } else {
-               if(!pinfo->fd->flags.visited){
-                       sip->frame_res=pinfo->fd->num;
-               }
                if(sip->frame_req){
                        proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
                }
@@ -12941,18 +12496,15 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        offset += 12;
 
        /* TID */
-       proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2,
-               sip->tid);
+       proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, tid);
        offset += 2;
 
        /* PID */
-       proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2,
-               sip->pid);
+       proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, pid);
        offset += 2;
 
        /* UID */
-       proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2,
-               sip->uid);
+       proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, uid);
        offset += 2;
 
        /* MID */
@@ -12994,6 +12546,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                }
        }
 
+       g_assert(si.request_val==NULL);
        return TRUE;
 }
 
diff --git a/smb.h b/smb.h
index 177b26b17272ad9ca1ce7e3cbc136ec83713dce2..a1882db9544504379602b7d53603c18469e7c857 100644 (file)
--- a/smb.h
+++ b/smb.h
@@ -2,7 +2,7 @@
  * Defines for smb packet dissection
  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
  *
- * $Id: smb.h,v 1.18 2001/11/15 10:41:53 guy Exp $
+ * $Id: smb.h,v 1.19 2001/11/16 07:56:28 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * request.
  */
 struct smb_request_val {
-  int frame;                   /* Frame in which this request appeared */
-  int last_transact2_command;
-  gchar *last_transact_command;
   guint16 last_lanman_cmd;
   guchar *last_param_descrip;  /* Keep these descriptors around */
   guchar *last_data_descrip;
   guchar *last_aux_data_descrip;
-  guint16 trans_response_seen;
-  int last_level;              /* Last level in request */
-};
-
-/*
- * One of these data structures is allocated for a transaction reply
- * that's continued in a later reply; it keeps track of the pathname
- * from the request that generated the reply, as well as the frame
- * number of the continued message.
- */
-struct smb_continuation_val {
-  int frame;                   /* Frame in which this reply appeared */
-  const gchar *transact_name;
+  int last_level;
 };
 
 #define TRANSACTION_PIPE       0x01
@@ -662,23 +647,17 @@ struct smb_continuation_val {
 
 
 typedef struct smb_info {
-  /* this will be cleaned up when all smb is tvbuffified */
-  int cmd, tid, uid, mid, pid; /* Any more? */
-  address *src, *dst;
-  int frame_req, frame_res;
+  int cmd, mid;
+  guint32 frame_req, frame_res;
   gboolean unidir;
   int subcmd;
   int trans_subcmd;
   int info_level;
   int info_count;
 
-
-  conversation_t *conversation;
   struct smb_request_val *request_val;
-  struct smb_continuation_val *continuation_val;
   gboolean unicode;            /* Are strings in this SMB Unicode? */
   gboolean request;            /* Is this a request? */
-  guint16 ddisp;               /* Data displacement for transaction commands */
 } smb_info_t;
 
 #endif