diff options
author | Greg Morris <GMORRIS@novell.com> | 2012-11-14 19:28:29 +0000 |
---|---|---|
committer | Greg Morris <GMORRIS@novell.com> | 2012-11-14 19:28:29 +0000 |
commit | d2c35240ee633ff453a1c30f9419361b2bbb7d81 (patch) | |
tree | f42ca3fd05c598e00768c2c7dbb7e2b705055d82 | |
parent | 89d76b0af382f9f91ae9777e1bfd8be4a3d962a3 (diff) | |
download | wireshark-d2c35240ee633ff453a1c30f9419361b2bbb7d81.tar.gz |
Fix for NCP malformed packets due to hash table corruption
Fix for NCP 89,6 request packet not displaying 1 char path
Fix for NMAS malformed packet
Fix for OES Linux server flag
svn path=/trunk-1.8/; revision=46030
-rw-r--r-- | epan/dissectors/packet-ncp-nmas.c | 12 | ||||
-rw-r--r-- | epan/dissectors/packet-ncp2222.inc | 142 | ||||
-rwxr-xr-x | tools/ncp2222.py | 22 |
3 files changed, 123 insertions, 53 deletions
diff --git a/epan/dissectors/packet-ncp-nmas.c b/epan/dissectors/packet-ncp-nmas.c index cc24d3bd26..15abdf8aa6 100644 --- a/epan/dissectors/packet-ncp-nmas.c +++ b/epan/dissectors/packet-ncp-nmas.c @@ -21,12 +21,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #include <glib.h> #include <epan/packet.h> @@ -527,10 +525,10 @@ dissect_nmas_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, guin { switch (subverb) { case 0: /* Fragmented Ping */ - proto_tree_add_item(atree, hf_ping_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN); - foffset += 4; - proto_tree_add_item(atree, hf_nmas_version, tvb, foffset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(atree, hf_session_ident, tvb, foffset, 4, ENC_BIG_ENDIAN); foffset += 4; + /*proto_tree_add_item(atree, hf_nmas_version, tvb, foffset, 4, ENC_LITTLE_ENDIAN); + foffset += 4;*/ break; case 2: /* Client Put Data */ proto_tree_add_item(atree, hf_squeue_bytes, tvb, foffset, 4, ENC_LITTLE_ENDIAN); diff --git a/epan/dissectors/packet-ncp2222.inc b/epan/dissectors/packet-ncp2222.inc index 79f8fa4d65..5d357ae7aa 100644 --- a/epan/dissectors/packet-ncp2222.inc +++ b/epan/dissectors/packet-ncp2222.inc @@ -37,7 +37,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define PROTO_LENGTH_UNTIL_END -1 @@ -78,6 +78,8 @@ static const fragment_items nds_frag_items = { &hf_nds_segment_count, NULL, &hf_nds_reassembled_length, + /* Reassembled data field */ + NULL, "segments" }; @@ -1590,6 +1592,18 @@ static const value_string nds_verb2b_flag_vals[] = { { 0, NULL } }; +static const value_string serv_type_vals[] = { + { 0, "NetWare" }, + { 1, "OES" }, + { 0, NULL } +}; + +static const value_string kernel_type_vals[] = { + { 0, "NetWare" }, + { 1, "Linux" }, + { 0, NULL } +}; + static void process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec, gboolean *req_cond_results, gboolean really_decode, @@ -1617,7 +1631,7 @@ process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec, */ typedef struct { conversation_t *conversation; - guint8 nw_sequence; + guint32 nw_sequence_long; } ncp_req_hash_key; @@ -1641,7 +1655,7 @@ ncp_equal(gconstpointer v, gconstpointer v2) const ncp_req_hash_key *val2 = (const ncp_req_hash_key*)v2; if (val1->conversation == val2->conversation && - val1->nw_sequence == val2->nw_sequence ) { + val1->nw_sequence_long == val2->nw_sequence_long ) { return TRUE; } return FALSE; @@ -1663,7 +1677,7 @@ static guint ncp_hash(gconstpointer v) { const ncp_req_hash_key *ncp_key = (const ncp_req_hash_key*)v; - return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence; + return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence_long; } static guint @@ -1716,9 +1730,14 @@ ncp_postseq_cleanup(void) * needed during random-access processing of the proto_tree.*/ } +/* NCP sequence numbers are from 0 - 255. After reaching 255 the + * sequence number wraps back to 0. Change nw_sequence to nw_sequence_long + * and use upper bits to make sequence numbers unique. This way + * future attempts to locate initiating packet will succeed. + */ static ncp_req_hash_value* ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence, - const ncp_record *ncp_rec) + const ncp_record *ncp_rec, guint32 pkt_num) { ncp_req_hash_key *request_key; ncp_req_hash_value *request_value; @@ -1727,7 +1746,8 @@ ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence, a reply to it. */ request_key = se_alloc(sizeof(ncp_req_hash_key)); request_key->conversation = conversation; - request_key->nw_sequence = nw_sequence; + /* Make sequence number unique */ + request_key->nw_sequence_long = (0x10000 + ((pkt_num/255)<<16)) | nw_sequence; request_value = se_alloc(sizeof(ncp_req_hash_value)); request_value->ncp_rec = ncp_rec; @@ -1764,14 +1784,32 @@ ncp_eid_hash_insert(guint32 nw_eid) /* Returns the ncp_rec*, or NULL if not found. */ static ncp_req_hash_value* -ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence) +ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence, guint32 pkt_num) { ncp_req_hash_key request_key; + ncp_req_hash_value *temp_value; request_key.conversation = conversation; - request_key.nw_sequence = nw_sequence; - - return g_hash_table_lookup(ncp_req_hash, &request_key); + /* Find unique sequence number */ + request_key.nw_sequence_long = (0x10000+((pkt_num/255)<<16)) | nw_sequence; + + /* Since masking of sequence number utilizes the packet number as + * part of it's algorythm it is possible for a packet to sit right + * on the boundary and fail. (depending on number of packets in trace) + * Loop through all the previous sequence numbers in the hash to see + * if the original request packet can be found. + */ + temp_value = g_hash_table_lookup(ncp_req_hash, &request_key); + while(!temp_value) + { + request_key.nw_sequence_long = request_key.nw_sequence_long-0x10000; + if((request_key.nw_sequence_long & 0xffff0000) == 0){ + break; + } + temp_value = g_hash_table_lookup(ncp_req_hash, &request_key); + } + + return temp_value; } /* Returns the value_rec* for needed EID, or NULL if not found. */ @@ -2811,7 +2849,7 @@ trap_for_expert_event(proto_tree *ncp_tree, packet_info *pinfo, const ncp_record } expert_add_info_format(pinfo, NULL, PI_REQUEST_CODE, PI_CHAT, "%s: %s, Rights:(%s)", - val_to_str((atoi(oaction) & 0xeb), open_create_mode_vals, "Unknown: %d"), + val_to_str((strtoul(oaction, NULL, 16) & 0xeb), open_create_mode_vals, "Unknown: %d"), p_filename, val_to_str((atoi(p_rights) & 0x5f), ncp_rights_vals, "Unknown: %d")); } @@ -2897,6 +2935,8 @@ trap_for_expert_event(proto_tree *ncp_tree, packet_info *pinfo, const ncp_record char p_min_ver[3]="\0"; char p_rev[3]="\0"; char p_lang[3]="\0"; + char p_serv_type[3]="\0"; + char p_kernel[3]="\0"; /* Get Server name and version info */ build_expert_data(ncp_tree, "ncp.server_name", @@ -2909,8 +2949,13 @@ trap_for_expert_event(proto_tree *ncp_tree, packet_info *pinfo, const ncp_record p_rev, sizeof p_rev, 0, FALSE); build_expert_data(ncp_tree, "ncp.os_language_id", p_lang, sizeof p_lang, 0, FALSE); - expert_add_info_format(pinfo, NULL, PI_RESPONSE_CODE, PI_CHAT, "Server %s, version %s.%s, support pack %s, language %s", fsname, - p_maj_ver, p_min_ver, p_rev, p_lang); + build_expert_data(ncp_tree, "ncp.oes_server", + p_serv_type, sizeof p_serv_type, 0, FALSE); + build_expert_data(ncp_tree, "ncp.oeslinux_or_netware", + p_kernel, sizeof p_kernel, 0, FALSE); + + expert_add_info_format(pinfo, NULL, PI_RESPONSE_CODE, PI_CHAT, "Server %s, version %s.%s, support pack %s, language %s, server type %s, kernel %s", fsname, + p_maj_ver, p_min_ver, p_rev, p_lang, val_to_str((atoi(p_serv_type) & 0x01), serv_type_vals, "Unknown: %d"), val_to_str((atoi(p_kernel) & 0x01), kernel_type_vals, "Unknown: %d") ); } } } @@ -3179,7 +3224,7 @@ print_nds_values(proto_tree *vtree, tvbuff_t *tvb, guint32 syntax_type, nds_val proto_tree_add_uint_format(nvtree, hf_replica_number, tvb, voffset, 4, value3, "Replica Number %d", value3); voffset = voffset+4; - if(vvalues->pflags & 0x8000) + if((vvalues->pflags & 0x8000) | (vvalues->pflags & 0x4000)) { /* If this request flag is set then this is a server. Server structures * include the RootID as part of the replica data. */ @@ -6571,7 +6616,8 @@ dissect_ncp_89_6_request(tvbuff_t *tvb, proto_tree *volatile ncp_tree, guint32 o proto_tree_add_item(ncp_tree, hf_ncp_directory_path, tvb, offset+2, string_len-2, TRUE); } offset += string_len; - if(tvb_length_remaining(tvb, offset) < 4 ) + /* string length count field of 2 plus 1 char value minumum (0x010053) */ + if(tvb_length_remaining(tvb, offset) < 3 ) { break; } @@ -7096,7 +7142,7 @@ nds_defrag(tvbuff_t *tvb, packet_info *pinfo, guint32 nw_connection, guint8 sequ if (conversation != NULL) { /* find the record telling us the request made that caused this reply */ - request_value = ncp_hash_lookup(conversation, sequence); + request_value = ncp_hash_lookup(conversation, sequence, pinfo->fd->num); if (!request_value) { dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap); return; @@ -7487,7 +7533,7 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo, conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_NCP, nw_connection, nw_connection, 0); } - request_value = ncp_hash_insert(conversation, sequence, ncp_rec); + request_value = ncp_hash_insert(conversation, sequence, ncp_rec, pinfo->fd->num); request_value->req_frame_num = pinfo->fd->num; request_value->req_frame_time = pinfo->fd->abs_ts; @@ -7510,7 +7556,7 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo, if ((run_info_str || run_req_cond) && !ncp_tree) { proto_item *ti; - temp_tree = proto_tree_create_root(); + temp_tree = proto_tree_create_root(pinfo); proto_tree_set_visible(temp_tree, FALSE); ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE); ncp_tree = proto_item_add_subtree(ti, ett_ncp); @@ -7622,14 +7668,6 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo, ENDTRY; } ptvcursor_free(ptvc); - /* SecretStore packets are dessected in packet-ncp-sss.c */ - if (func == 0x5c && ncp_tree) { - dissect_sss_request(tvb, pinfo, ncp_tree, request_value); - } - /* NMAS packets are dessected in packet-ncp-nmas.c */ - if (func == 0x5e && ncp_tree) { - dissect_nmas_request(tvb, pinfo, ncp_tree, request_value); - } /* Now that the dissection is done, do we need to run * some display filters on the resulting tree in order @@ -7670,7 +7708,7 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo, if (conversation != NULL) { /* find the record telling us the request made that caused this reply */ - request_value = ncp_hash_lookup(conversation, sequence); + request_value = ncp_hash_lookup(conversation, sequence, pinfo->fd->num); } if (!conversation || !request_value) { @@ -7760,6 +7798,25 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo, } } } + if (!request_value) + { + conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + if (conversation != NULL) { + /* find the record telling us the request made that caused + this reply */ + request_value = ncp_hash_lookup(conversation, sequence, pinfo->fd->num); + } + } + /* SecretStore packets are dessected in packet-ncp-sss.c */ + if (func == 0x5c && ncp_tree) { + dissect_sss_request(tvb, pinfo, ncp_tree, request_value); + } + /* NMAS packets are dessected in packet-ncp-nmas.c */ + if (func == 0x5e && ncp_tree) { + dissect_nmas_request(tvb, pinfo, ncp_tree, request_value); + } + /* Store NCP request specific flags for manual dissection */ if ((func == 0x57 || func == 0x59) && subfunc == 0x14 && ncp_tree && request_value) { char ret_info_string[16]; @@ -7767,11 +7824,11 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo, build_expert_data(ncp_tree, "ncp.ret_info_mask", ret_info_string, sizeof ret_info_string, 0, FALSE); - request_value->req_mask = atoi(ret_info_string); + request_value->req_mask = (guint32) atoi(ret_info_string); build_expert_data(ncp_tree, "ncp.ext_info", ret_info_string_ext, sizeof ret_info_string_ext, 0, FALSE); - request_value->req_mask_ext = atoi(ret_info_string_ext); + request_value->req_mask_ext = (guint32) atoi(ret_info_string_ext); } /* NCP function 89/6 passes either ASCII or UTF8 data */ /* Decode manually since it is not possible to SREC the request */ @@ -8823,7 +8880,7 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo, if (conversation != NULL) { /* find the record telling us the request made that caused this reply */ - request_value = ncp_hash_lookup(conversation, sequence); + request_value = ncp_hash_lookup(conversation, sequence, pinfo->fd->num); if (request_value) { ncp_rec = request_value->ncp_rec; } @@ -8844,7 +8901,7 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo, /* find the record telling us the request made that caused this reply */ request_value = ncp_hash_lookup(conversation, - sequence); + sequence, pinfo->fd->num); if (request_value) { ncp_rec = request_value->ncp_rec; } @@ -8858,7 +8915,7 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo, /* find the record telling us the request made that caused this reply */ request_value = ncp_hash_lookup(conversation, - sequence); + sequence, pinfo->fd->num); if (request_value) { ncp_rec = request_value->ncp_rec; } @@ -8871,7 +8928,14 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo, } } else { - request_value = p_get_proto_data(pinfo->fd, proto_ncp); + /*request_value = p_get_proto_data(pinfo->fd, proto_ncp);*/ + conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + if (conversation != NULL) { + + request_value = ncp_hash_lookup(conversation, + sequence, pinfo->fd->num); + } if (request_value) { ncp_rec = request_value->ncp_rec; } @@ -11081,7 +11145,6 @@ dissect_nds_request(tvbuff_t *tvb, packet_info *pinfo, pvalues[2].voffset = foffset; pvalues[2].hfname= hf_nds_eid; foffset = foffset+pvalues[2].vlength; - resolve_eid = TRUE; global_eid = pvalues[2].vvalue; pvalues[3].vtype = VTYPE_STRING; pvalues[3].vdesc = "New RDN: %s"; @@ -11513,7 +11576,7 @@ dissect_nds_request(tvbuff_t *tvb, packet_info *pinfo, } if (!pinfo->fd->flags.visited) { - request_value = ncp_hash_insert(conversation, sequence, ncp_rec); + request_value = ncp_hash_insert(conversation, sequence, ncp_rec, pinfo->fd->num); request_value->req_frame_num = pinfo->fd->num; request_value->req_frame_time=pinfo->fd->abs_ts; @@ -11538,7 +11601,7 @@ dissect_nds_request(tvbuff_t *tvb, packet_info *pinfo, if ((run_info_str || run_req_cond) && !ncp_tree) { proto_item *ti; - temp_tree = proto_tree_create_root(); + temp_tree = proto_tree_create_root(pinfo); proto_tree_set_visible(temp_tree, FALSE); ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE); ncp_tree = proto_item_add_subtree(ti, ett_ncp); @@ -11559,7 +11622,7 @@ dissect_nds_request(tvbuff_t *tvb, packet_info *pinfo, PTREE_DATA(ncp_tree)->visible=1; #endif - request_value = ncp_hash_lookup(conversation, sequence); + request_value = ncp_hash_lookup(conversation, sequence, pinfo->fd->num); switch (type) { case NCP_BROADCAST_SLOT: ; /* nothing */ @@ -11840,7 +11903,7 @@ dissect_ping_req(tvbuff_t *tvb, packet_info *pinfo, PT_NCP, nw_connection, nw_connection, 0); } - request_value = ncp_hash_insert(conversation, sequence, ncp_rec); + request_value = ncp_hash_insert(conversation, sequence, ncp_rec, pinfo->fd->num); request_value->req_frame_num = pinfo->fd->num; request_value->req_frame_time=pinfo->fd->abs_ts; @@ -11854,7 +11917,7 @@ dissect_ping_req(tvbuff_t *tvb, packet_info *pinfo, if (ncp_rec && !ncp_tree) { proto_item *ti; - temp_tree = proto_tree_create_root(); + temp_tree = proto_tree_create_root(pinfo); proto_tree_set_visible(temp_tree, FALSE); ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE); ncp_tree = proto_item_add_subtree(ti, ett_ncp); @@ -12005,4 +12068,3 @@ dissect_ping_req(tvbuff_t *tvb, packet_info *pinfo, CLEANUP_CALL_AND_POP; } } - diff --git a/tools/ncp2222.py b/tools/ncp2222.py index f2ab27e504..83837da9e8 100755 --- a/tools/ncp2222.py +++ b/tools/ncp2222.py @@ -43,7 +43,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """ import os @@ -3198,6 +3198,16 @@ OCRetFlags = val_string8("o_c_ret_flags", "Open Create Return Flags", [ [ 0x00, "No CallBack has been registered (No Op-Lock)" ], [ 0x01, "Request has been registered for CallBack (Op-Lock)" ], ]) +OESServer = val_string8("oes_server", "Type of Novell Server", [ + [ 0x00, "NetWare" ], + [ 0x01, "OES" ], +]) + +OESLinuxOrNetWare = val_string8("oeslinux_or_netware", "Kernel Type", [ + [ 0x00, "NetWare" ], + [ 0x01, "Linux" ], +]) + OldestDeletedFileAgeInTicks = uint32("oldest_deleted_file_age_in_ticks", "Oldest Deleted File Age in Ticks") OldFileName = bytes("old_file_name", "Old File Name", 15) OldFileSize = uint32("old_file_size", "Old File Size") @@ -5716,12 +5726,10 @@ def produce_code(): * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #include <string.h> #include <glib.h> @@ -9580,7 +9588,9 @@ def define_ncp2222(): rec( 82, 2, ProductRevisionVersion, BE ), rec( 84, 1, OSLanguageID, LE ), rec( 85, 1, SixtyFourBitOffsetsSupportedFlag ), - rec( 86, 50, Reserved50 ), + rec( 86, 1, OESServer ), + rec( 87, 1, OESLinuxOrNetWare ), + rec( 88, 48, Reserved48 ), ]) pkt.CompletionCodes([0x0000, 0x9600]) # 2222/1712, 23/18 |