Handle continuation replies to transactions better - try to match them
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 30 Sep 2004 01:04:33 +0000 (01:04 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 30 Sep 2004 01:04:33 +0000 (01:04 +0000)
up with the original request, without matching unrelated replies with
that request.

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

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

index b7887907697a388e6ee16f606c4c80379e99c9d9..d96a683d112b306f6e01fdc3ee08bebbcd951589 100644 (file)
@@ -835,17 +835,6 @@ smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
        if (si->sip == NULL) {
                /*
                 * We don't have the frame number of the request.
-                *
-                * XXX - is there truly nothing we can do here?
-                * Can we not separately keep track of the original
-                * transaction and its continuations, as we did
-                * at one time?
-                *
-                * It is probably not much point in even trying to do something here
-                * if we have never seen the initial request. Without the initial
-                * request we probably miss all parameters and the begining of data
-                * so we cant even call a subdissector since we can not determine
-                * which type of transaction call this is.
                 */
                return NULL;
        }
@@ -858,6 +847,18 @@ smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
                fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
        }
 
+       if (!fd_head || !(fd_head->flags&FD_DEFRAGMENTED)){
+               /* This is continued - mark it as such, so we recognize
+                  continuation responses.
+               */
+               si->sip->flags |= SMB_SIF_IS_CONTINUED;
+       } else {
+               /* We've finished reassembling, so there are no more
+                  continuation responses.
+               */
+               si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
+       }
+
        /* we only show the defragmented packet for the first fragment,
           or else we might end up with dissecting one HUGE transaction PDU
           a LOT of times. (first fragment is the only one containing the setup
@@ -14739,8 +14740,8 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                }
 
                                if( (si->request) || (!cmd_match) ) {
-                                       /* If we are processing an SMB request but there was already
-                                          another "identical" smb resuest we had not matched yet.
+                                       /* We are processing an SMB request but there was already
+                                          another "identical" smb request 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
@@ -14756,12 +14757,21 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                        g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
                                        sip=NULL; /* XXX should free it as well */
                                } 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.
+                                       /* 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
+                                          if it's a response to a request
+                                          for which we've seen an earlier
+                                          response that's continued.
                                        */
-                                       if(sip->frame_res==0){
-                                               /* ok it is the first response we have seen to this packet */
+                                       if(sip->frame_res==0 ||
+                                          sip->flags & SMB_SIF_IS_CONTINUED){
+                                               /* OK, it is the first response
+                                                  we have seen to this packet,
+                                                  or it's a continuation of
+                                                  a response we've seen. */
                                                sip->frame_res = pinfo->fd->num;
                                                new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
                                                new_key->frame = sip->frame_res;
diff --git a/smb.h b/smb.h
index 4c9f040032eeba5b4c0d3dbaa2deb08bc4d3e54f..401ee0165c167159c250e279535d6c8257809627 100644 (file)
--- a/smb.h
+++ b/smb.h
@@ -193,6 +193,7 @@ typedef struct {
  * frame number of the request in the dissection of the reply.
  */
 #define SMB_SIF_TID_IS_IPC     0x0001
+#define SMB_SIF_IS_CONTINUED   0x0002
 typedef struct {
        guint32 frame_req, frame_res;
        nstime_t req_time;