From 050138a9adacb8dcde5418c39c2ea25869e22f7e Mon Sep 17 00:00:00 2001 From: guy Date: Thu, 30 Sep 2004 01:04:33 +0000 Subject: [PATCH] Handle continuation replies to transactions better - try to match them 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 | 46 ++++++++++++++++++++++-------------- smb.h | 1 + 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; -- 2.34.1