diff options
-rw-r--r-- | packet-smb.c | 58 | ||||
-rw-r--r-- | reassemble.c | 100 | ||||
-rw-r--r-- | reassemble.h | 28 |
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); + + |