summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-09-30 01:04:33 +0000
committerGuy Harris <guy@alum.mit.edu>2004-09-30 01:04:33 +0000
commit5f57d42dac4f0941b758fb9446cab1e1535e875c (patch)
treef3f35dfb475f6a167e9c578c63c6134a86bd7d4d
parenta95464b528550d547da0fcb18e05079c1ac27e95 (diff)
downloadwireshark-5f57d42dac4f0941b758fb9446cab1e1535e875c.tar.gz
Handle continuation replies to transactions better - try to match them
up with the original request, without matching unrelated replies with that request. svn path=/trunk/; revision=12145
-rw-r--r--epan/dissectors/packet-smb.c46
-rw-r--r--smb.h1
2 files changed, 29 insertions, 18 deletions
diff --git a/epan/dissectors/packet-smb.c b/epan/dissectors/packet-smb.c
index b788790769..d96a683d11 100644
--- a/epan/dissectors/packet-smb.c
+++ b/epan/dissectors/packet-smb.c
@@ -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 4c9f040032..401ee0165c 100644
--- 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;