summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Morris <GMORRIS@novell.com>2012-11-14 19:28:29 +0000
committerGreg Morris <GMORRIS@novell.com>2012-11-14 19:28:29 +0000
commitd2c35240ee633ff453a1c30f9419361b2bbb7d81 (patch)
treef42ca3fd05c598e00768c2c7dbb7e2b705055d82
parent89d76b0af382f9f91ae9777e1bfd8be4a3d962a3 (diff)
downloadwireshark-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.c12
-rw-r--r--epan/dissectors/packet-ncp2222.inc142
-rwxr-xr-xtools/ncp2222.py22
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