aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packet-smb.c58
-rw-r--r--reassemble.c100
-rw-r--r--reassemble.h28
3 files changed, 162 insertions, 24 deletions
diff --git a/packet-smb.c b/packet-smb.c
index 3321cb9b1a..2b36cef825 100644
--- a/packet-smb.c
+++ b/packet-smb.c
@@ -2,7 +2,7 @@
* Routines for smb packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
- * $Id: packet-smb.c,v 1.166 2001/11/21 06:25:58 guy Exp $
+ * $Id: packet-smb.c,v 1.167 2001/11/24 09:36:39 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -98,6 +98,7 @@ static int hf_smb_uid = -1;
static int hf_smb_mid = -1;
static int hf_smb_response_to = -1;
static int hf_smb_response_in = -1;
+static int hf_smb_continuation_to = -1;
static int hf_smb_nt_status = -1;
static int hf_smb_error_class = -1;
static int hf_smb_error_code = -1;
@@ -7318,28 +7319,8 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
static int
dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
{
- smb_info_t *si;
guint8 wc;
guint16 bc;
- conversation_t *conversation;
- conv_tables_t *ct;
- smb_saved_info_t *old_si;
-
- si = pinfo->private_data;
- 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->matched, (void *)pinfo->fd->num);
- 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;
@@ -12753,6 +12734,35 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
}
}
+
+
+ if(sip && sip->frame_req){
+ switch(si.cmd){
+ case SMB_COM_NT_CANCEL:
+ proto_tree_add_uint(htree, hf_smb_cancel_to,
+ tvb, 0, 0, sip->frame_req);
+ break;
+ case SMB_COM_TRANSACTION_SECONDARY:
+ case SMB_COM_TRANSACTION2_SECONDARY:
+ case SMB_COM_NT_TRANSACT_SECONDARY:
+ proto_tree_add_uint(htree, hf_smb_continuation_to,
+ tvb, 0, 0, sip->frame_req);
+ break;
+ }
+ } else {
+ switch(si.cmd){
+ case SMB_COM_NT_CANCEL:
+ proto_tree_add_text(htree, tvb, 0, 0,
+ "Cancellation to: <unknown frame>");
+ break;
+ case SMB_COM_TRANSACTION_SECONDARY:
+ case SMB_COM_TRANSACTION2_SECONDARY:
+ case SMB_COM_NT_TRANSACT_SECONDARY:
+ proto_tree_add_text(htree, tvb, 0, 0,
+ "Continuation to: <unknown frame>");
+ break;
+ }
+ }
} else { /* normal bidirectional request or response */
conversation_t *conversation;
conv_tables_t *ct;
@@ -12863,7 +12873,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
* frame - if we know the frame number (i.e., it's not 0).
*/
if(si.request){
- if (si.cmd != SMB_COM_NT_CANCEL && sip->frame_res != 0)
+ if (sip->frame_res != 0)
proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
} else {
if (sip->frame_req != 0)
@@ -13023,6 +13033,10 @@ proto_register_smb(void)
{ "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
NULL, 0, "The response to this packet is in this packet", HFILL }},
+ { &hf_smb_continuation_to,
+ { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
+ NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
+
{ &hf_smb_nt_status,
{ "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
VALS(NT_errors), 0, "NT Status code", HFILL }},
diff --git a/reassemble.c b/reassemble.c
index 45cb0daebf..5af1495417 100644
--- a/reassemble.c
+++ b/reassemble.c
@@ -1,7 +1,7 @@
/* reassemble.c
* Routines for {fragment,segment} reassembly
*
- * $Id: reassemble.c,v 1.4 2001/11/21 01:21:08 guy Exp $
+ * $Id: reassemble.c,v 1.5 2001/11/24 09:36:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -177,6 +177,103 @@ reassemble_init(void)
G_ALLOC_ONLY);
}
+/* This function cleans up the stored state and removes the reassembly data and
+ * (with one exception) all allocated memory for matching reassembly.
+ *
+ * The exception is :
+ * If the PDU was already completely reassembled, then the buffer containing the
+ * reassembled data WILL NOT be free()d, and the pointer to that buffer will be
+ * returned.
+ * Othervise the function will return NULL.
+ *
+ * So, if you call fragment_delete and it returns non-NULL, YOU are responsible to
+ * g_free() that buffer.
+ */
+unsigned char *
+fragment_delete(packet_info *pinfo, guint32 id, GHashTable *fragment_table)
+{
+ fragment_data *fd_head, *fd;
+ fragment_key key;
+ unsigned char *data=NULL;
+
+ /* create key to search hash with */
+ key.src = pinfo->src;
+ key.dst = pinfo->dst;
+ key.id = id;
+
+ fd_head = g_hash_table_lookup(fragment_table, &key);
+
+ if(fd_head==NULL){
+ /* We do not recognize this as a PDU we have seen before. return*/
+ return NULL;
+ }
+
+ data=fd_head->data;
+ /* loop over all partial fragments and free any buffers */
+ for(fd=fd_head->next;fd;){
+ fragment_data *tmp_fd;
+ tmp_fd=fd->next;
+
+ g_free(fd->data);
+ g_mem_chunk_free(fragment_data_chunk, fd);
+ fd=tmp_fd;
+ }
+ g_mem_chunk_free(fragment_data_chunk, fd_head);
+ g_hash_table_remove(fragment_table, &key);
+
+ return data;
+}
+
+/* This function is used to check if there is partial or completed reassembly state
+ * matching this packet. I.e. Are there reassembly going on or not for this packet?
+ */
+fragment_data *
+fragment_get(packet_info *pinfo, guint32 id, GHashTable *fragment_table)
+{
+ fragment_data *fd_head;
+ fragment_key key;
+
+ /* create key to search hash with */
+ key.src = pinfo->src;
+ key.dst = pinfo->dst;
+ key.id = id;
+
+ fd_head = g_hash_table_lookup(fragment_table, &key);
+
+ return fd_head;
+}
+
+/* This function can be used to explicitely set the total length (if known)
+ * for reassembly of a PDU.
+ * This is useful for reassembly of PDUs where one may have the total length specified
+ * in the first fragment instead of as for, say, IPv4 where a flag indicates which
+ * is the last fragment.
+ *
+ * Such protocols might fragment_add with a more_frags==TRUE for every fragment
+ * and just tell the reassembly engine the expected total length of the reassembled data
+ * using fragment_set_tot_len immediately after doing fragment_add for the first packet.
+ */
+void
+fragment_set_tot_len(packet_info *pinfo, guint32 id, GHashTable *fragment_table,
+ guint32 tot_len)
+{
+ fragment_data *fd_head;
+ fragment_key key;
+
+ /* create key to search hash with */
+ key.src = pinfo->src;
+ key.dst = pinfo->dst;
+ key.id = id;
+
+ fd_head = g_hash_table_lookup(fragment_table, &key);
+
+ if(fd_head){
+ fd_head->datalen = tot_len;
+ }
+
+ return;
+}
+
/*
* This function adds a new fragment to the fragment hash table.
* If this is the first fragment seen for this datagram, a new entry
@@ -187,6 +284,7 @@ reassemble_init(void)
*
* Returns a pointer to the head of the fragment data list if we have all the
* fragments, NULL otherwise.
+ *
*/
fragment_data *
fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
diff --git a/reassemble.h b/reassemble.h
index 8b96e72d1a..3d3faba8ec 100644
--- a/reassemble.h
+++ b/reassemble.h
@@ -1,7 +1,7 @@
/* reassemble.h
* Declarations of outines for {fragment,segment} reassembly
*
- * $Id: reassemble.h,v 1.1 2001/06/08 06:27:16 guy Exp $
+ * $Id: reassemble.h,v 1.2 2001/11/24 09:36:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -75,3 +75,29 @@ void reassemble_init(void);
fragment_data *fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint32 id, GHashTable *fragment_table, guint32 frag_offset,
guint32 frag_data_len, gboolean more_frags);
+
+/* to specify how much to reassemble, for fragmentation where last fragment can not be
+ * identified by flags or such.
+ */
+void
+fragment_set_tot_len(packet_info *pinfo, guint32 id, GHashTable *fragment_table,
+ guint32 tot_len);
+
+/* This function is used to check if there is partial or completed reassembly state
+ * matching this packet. I.e. Are there reassembly going on or not for this packet?
+ */
+fragment_data *
+fragment_get(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
+
+/* This will free up all resources and delete reassembly state for this PDU.
+ * Except if the PDU is completely reassembled, then it would NOT deallocate the
+ * buffer holding the reassembled data but instead return the pointer to that
+ * buffer.
+ *
+ * So, if you call fragment_delete and it returns non-NULL, YOU are responsible to
+ * g_free() that buffer.
+ */
+unsigned char *
+fragment_delete(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
+
+