[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ethereal-dev
Subject:    [Ethereal-dev] packet-smb-pipe
From:       "Pia Sahlberg" <piabar () hotmail ! com>
Date:       2001-07-29 13:37:29
[Download RAW message or body]

Hi list.
(different mailaddress, Im traveling)

3 patches are attached :
the patches must be applied in the order listed below. they depend on 
eachother.


smb.patch.1  (tiny): changes to packet_info structure and smb dissector so 
the smb dissector can pass important data to subdissector instead of using 
hundreds of call parameters.

smb.patch.2  (tiny): one more parameter smb dissector needs to tell 
subdissectors.


patch.smb.pipe.diff  (54kb): this is the tvbuffified dissector for lanman 
protocol.
It is different to the original dissector in several ways.

The patch now correctly matches a response to the Correct request and doesnt 
just assume every response matches the last read request.

The patch correctly handles when lanman inserts an extra pad byte between 
the parameters and the list of servers/shares in netshareenum-response and 
netserverenum2-response.

All implemented calls have all parameters with hf_* fields.

The only calls implemented are netshareenum,netserverenum2.
The other calls in the original implementation could not be converted to 
tvbuff and were removed. As soon as I, or anyone else, gets capture files 
with any other calls, the remaining calls can be implemented.

I am currently travelling so I have no access to create any interesting 
captures at the moment.
The only captures I had on my laptop contained only these two calls.

If anyone mails the list a capturefile with other calls not implemented, I 
can implement and test those calls.


Lots of functionality was removed (all calls except netshareenum 
netserverenum2) but I think it was nessesary, the other calls could not be 
converted in their current implementation.


Use your own judgement for this patch.


_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp

["smb.patch.1" (application/octet-stream)]

diff -u -r -x *.[^ch]|nmake|am ethereal-orig/epan/packet_info.h ethereal/epan/packet_info.h
--- ethereal-orig/epan/packet_info.h	Mon Jun  4 17:27:50 2001
+++ ethereal/epan/packet_info.h	Sat Jul 28 03:34:17 2001
@@ -119,6 +119,13 @@
       guint32	callnumber;
       guint32	seq;
     } rx;			/* fields specific for RX protocol */
+    struct {
+      gboolean  request;	/* is this a smb request ? */
+      guint16   tid;
+      guint16   pid;
+      guint16   uid;
+      guint16   mid;
+    } smb;
   } ps;				/* protocol specific data */
 } packet_info;
 
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb.c ethereal/packet-smb.c
--- ethereal-orig/packet-smb.c	Wed Jun 20 11:58:48 2001
+++ ethereal/packet-smb.c	Sat Jul 28 03:34:12 2001
@@ -10804,6 +10804,7 @@
 						      "Notify all",
 						      "Notify open only"));
 
+	  pi.ps.smb.request = !(flags&0x80);
 	  proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
 			      decode_boolean_bitfield(flags, SMB_FLAGS_DIRN,
 						      8, "Response to client/redirector", "Request to server"));
@@ -10898,6 +10899,7 @@
 
 	tid = GSHORT(pd, offset);
 	si.tid = tid;
+	pi.ps.smb.tid = tid;
 
 	if (tree) {
 
@@ -10911,6 +10913,7 @@
 
 	pid = GSHORT(pd, offset);
 	si.pid = pid;
+	pi.ps.smb.pid = pid;
 
 	if (tree) {
 
@@ -10924,6 +10927,7 @@
 
 	uid = GSHORT(pd, offset);
 	si.uid = uid;
+	pi.ps.smb.uid = uid;
 
 	if (tree) {
 
@@ -10937,6 +10941,7 @@
 
 	mid = GSHORT(pd, offset);
 	si.mid = mid;
+	pi.ps.smb.mid = mid;
 
 	if (tree) {
 

["smb.patch.2" (application/octet-stream)]

diff -u -r -x *.[^ch]|nmake|am ethereal-orig/epan/packet_info.h ethereal/epan/packet_info.h
--- ethereal-orig/epan/packet_info.h	Sat Jul 28 03:57:55 2001
+++ ethereal/epan/packet_info.h	Sat Jul 28 04:28:12 2001
@@ -125,6 +125,7 @@
       guint16   pid;
       guint16   uid;
       guint16   mid;
+      guint16   ddisp;		/* data displacement for trans commands */
     } smb;
   } ps;				/* protocol specific data */
 } packet_info;
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb.c ethereal/packet-smb.c
--- ethereal-orig/packet-smb.c	Sat Jul 28 03:57:55 2001
+++ ethereal/packet-smb.c	Sat Jul 28 04:30:11 2001
@@ -9405,6 +9405,7 @@
     /* Build display for: Data Displacement */
 
     DataDisplacement = GSHORT(pd, offset);
+    pi.ps.smb.ddisp = DataDisplacement;
 
     if (tree) {
 
@@ -10148,6 +10149,7 @@
     /* Build display for: Data Displacement */
 
     DataDisplacement = GSHORT(pd, offset);
+    pi.ps.smb.ddisp = DataDisplacement;
 
     if (tree) {
 

["patch.smb.pipe.diff" (application/octet-stream)]

diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb-browse.c \
                ethereal/packet-smb-browse.c
--- ethereal-orig/packet-smb-browse.c	Fri Jul 20 17:11:57 2001
+++ ethereal/packet-smb-browse.c	Sun Jul 29 23:05:38 2001
@@ -449,8 +449,8 @@
 }
 
 
-static void
-dissect_server_type_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree \
*parent_tree, int offset) +void
+dissect_smb_server_type_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree \
*parent_tree, int offset, gboolean infoflag)  {
 	proto_tree *tree = NULL;
 	proto_item *item = NULL;
@@ -464,13 +464,15 @@
 	      	tree = proto_item_add_subtree(item, ett_browse_flags);
 	}
 
-	/* Append the type(s) of the system to the COL_INFO line ... */
-	if (check_col(pinfo->fd, COL_INFO)) {
-		for (i = 0; i < 32; i++) {
-			if (flags & (1<<i)) {
-				col_append_fstr(pinfo->fd, COL_INFO, ", %s",
-					val_to_str(i, server_types,
-					"Unknown server type:%d"));
+	if(infoflag){
+		/* Append the type(s) of the system to the COL_INFO line ... */
+		if (check_col(pinfo->fd, COL_INFO)) {
+			for (i = 0; i < 32; i++) {
+				if (flags & (1<<i)) {
+					col_append_fstr(pinfo->fd, COL_INFO, ", %s",
+						val_to_str(i, server_types,
+						"Unknown server type:%d"));
+				}
 			}
 		}
 	}
@@ -612,7 +614,7 @@
 		offset += 1;
 
 		/* server type flags */
-		dissect_server_type_flags(tvb, pinfo, tree, offset);
+		dissect_smb_server_type_flags(tvb, pinfo, tree, offset, TRUE);
 		offset += 4;
 
 		if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT) {
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb-browse.h \
                ethereal/packet-smb-browse.h
--- ethereal-orig/packet-smb-browse.h	Fri Jul 13 09:37:48 2001
+++ ethereal/packet-smb-browse.h	Sun Jul 29 23:04:39 2001
@@ -29,4 +29,7 @@
 gboolean
 dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
+void
+dissect_smb_server_type_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, \
int offset, gboolean infoflag); +
 #endif
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb-mailslot.c \
                ethereal/packet-smb-mailslot.c
--- ethereal-orig/packet-smb-mailslot.c	Fri Jul 13 09:37:48 2001
+++ ethereal/packet-smb-mailslot.c	Sat Jul 28 23:03:43 2001
@@ -131,10 +131,11 @@
   	}
 
   	else if (command != NULL && strcmp(command, "LANMAN") == 0) {
+		tvbuff_t *tvb;
+		packet_info *pinfo = &pi;
+		tvb = tvb_create_from_top(DataOffset);
 
-    		return dissect_pipe_lanman(pd, offset, fd, parent, tree, si,
-    			max_data, SMB_offset, errcode, dirn, command,
-    			DataOffset, DataCount, ParameterOffset, ParameterCount);
+		return dissect_pipe_lanman(tvb, pinfo, parent);
   	}
 
 /* NOTE: use TEMP\\NETLOGON and MSSP because they seems very common,	*/
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb-pipe.c \
                ethereal/packet-smb-pipe.c
--- ethereal-orig/packet-smb-pipe.c	Thu Mar 22 11:50:44 2001
+++ ethereal/packet-smb-pipe.c	Sun Jul 29 23:15:04 2001
@@ -1,6 +1,12 @@
+/*
+XXX  Fixme : continuation stuff removed, should be solved by smb reassembly
+XXX  Fixme : shouldnt show [malformed frame] for long packets
+*/
+
 /* packet-smb-pipe.c
  * Routines for SMB named pipe packet dissection
  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
+ * significant rewrite to tvbuffify the dissector  Ronnie Sahlberg 2001
  *
  * $Id: packet-smb-pipe.c,v 1.21 2001/03/22 00:50:44 guy Exp $
  *
@@ -46,18 +52,34 @@
 #include "packet.h"
 #include "conversation.h"
 #include "smb.h"
-#include "alignment.h"
-#include "strutil.h"
 #include "packet-smb-pipe.h"
+#include "packet-smb-browse.h"
 
 static int proto_smb_lanman = -1;
+static int hf_command = -1;
+static int hf_param_desc = -1;
+static int hf_return_desc = -1;
+static int hf_not_implemented = -1;
+static int hf_detail_level = -1;
+static int hf_recv_buf_len = -1;
+static int hf_response_to = -1;
+static int hf_status = -1;
+static int hf_convert = -1;
+static int hf_ecount = -1;
+static int hf_acount = -1;
+static int hf_share_name = -1;
+static int hf_share_type = -1;
+static int hf_share_comment = -1;
+static int hf_server_name = -1;
+static int hf_server_major = -1;
+static int hf_server_minor = -1;
+static int hf_server_comment = -1;
 
 static gint ett_lanman = -1;
 static gint ett_lanman_servers = -1;
 static gint ett_lanman_server = -1;
 static gint ett_lanman_shares = -1;
 static gint ett_lanman_share = -1;
-static gint ett_lanman_flags = -1;
 
 /*
  * See
@@ -67,1086 +89,537 @@
  * among other documents.
  */
 
-/* 
- * The following data structure describes the LANMAN requests we understand
- *
- * Simply fill in the number, name, and parameter names if you know them
- * Try to keep them in order 
- *
- * We will extend this data structure as we try to decode more ...
- */
-
-struct lanman_desc {
-  int   lanman_num;
-  char  *lanman_name;
-  char  **req;
-  char  **req_data;     /* Hmmm, not flexible enough */
-  char  **resp;
-  char  **resp_data;
+static const value_string share_status_vals[] = {
+	{0,	"Success"},
+	{5,	"Access Denied"},
+	{65,	"Network Access Denied"},
+	{234,	"More Data Available"},
+	{2114,	"Server Not Started"},
+	{2141,	"Bad Transact Config"},
+	{0, NULL}
 };
 
-static char *lm_params_req_0[]   = {"Detail Level", "Return Buffer Size", NULL};
-static char *lm_params_req_1[]   = {"Share Name", "Detail Level", "Receive Buffer \
                Size", NULL};
-static char *lm_params_resp_1[]  = {"Returned Data Len", NULL};
-static char *lm_params_req_13[]  = {"Detail Level", "Receive Buffer Size", NULL};
-static char *lm_params_req_56[]  = {"User Name", "Detail Level", "Receive Buffer \
                Size", NULL};
-static char *lm_params_req_104[] = {"Detail Level", "Return Buffer Size", "Server \
                Type", "Domain", NULL};
-static char *lm_params_req_132[] = {"Reserved1", "Reserved2", "Detail Level", \
                "UserInfoStruct?", "Length of UStruct", "Receive Buffer Size", NULL};
-static char *lm_params_req_133[] = {"Reserved1", "Reserved2", "Detail Level", \
                "UserInfoStruct?", "Length of UStruct", "Receive Buffer Size", NULL};
-
-static char *lm_null_params[] = {NULL};
-
-struct lanman_desc lmd[] = {
-  {0, "NetShareEnum", lm_params_req_0, lm_null_params, lm_null_params, \
                lm_null_params},
-  {1, "NetShareGetInfo", lm_params_req_1, lm_null_params, lm_params_resp_1, \
                lm_null_params},
-  {13, "NetServerGetInfo", lm_params_req_13, lm_null_params, lm_null_params, \
                lm_null_params},
-  {52, "NetGroupGetUsers", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {56, "NetUserGetInfo", lm_params_req_56, lm_null_params, lm_null_params, \
                lm_null_params},
-  {59, "NetUserGetGroups", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {63, "NetWkstaGetInfo", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {69, "DOSPrintQEnum", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {70, "DOSPrintQGetInfo", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {74, "WPrintQueuePause", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {75, "WPrintQueueResume", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {76, "WPrintJobEnumerate", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {77, "WPrintJobGetInfo", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {81, "RDOSPrintJobDel", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {82, "RDOSPrintJobPause", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {83, "RDOSPrintJobResume", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {84, "WPrintDestEnum", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {85, "WPrintDestGetInfo", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {91, "NetRemoteTOD", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {103, "WPrintQueuePurge", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {104, "NetServerEnum2", lm_params_req_104, lm_null_params, lm_null_params, \
                lm_null_params},
-  {105, "WAccessGetUserPerms", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {115, "SetUserPassword", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {132, "NetWkstaUserLogon", lm_params_req_132, lm_null_params, lm_null_params, \
                lm_null_params},
-  {133, "NetWkstaUserLogoff", lm_params_req_133, lm_null_params, lm_null_params, \
                lm_null_params},
-  {147, "PrintJobInfo", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {205, "WPrintDriverEnum", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {206, "WPrintQProcEnum", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {207, "WPrintPortEnum", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {214, "SamOEMChangePassword", lm_null_params, lm_null_params, lm_null_params, \
                lm_null_params},
-  {-1, NULL, NULL,NULL, NULL, NULL}
+static const value_string share_type_vals[] = {
+        {0, "Directory tree"},
+        {1, "Printer queue"},
+        {2, "Communications device"},
+        {3, "IPC"},
+        {0, NULL}
 };
 
-static struct lanman_desc *
-find_lanman(int lanman_num)
-{
-  int i = 0;
-
-  /* FIXME, This could be more efficient */
-
-  while (lmd[i].lanman_num != -1) {
-
-    if (lmd[i].lanman_num == lanman_num) {
-
-      return &lmd[i];
-
-    }
-
-    i++;
-
-  }
-
-  return NULL;
-
-}
-
-
-#define NETSHAREENUM   0x00  /* 00  */
-#define NETSERVERENUM2 0x68  /* 104 */
-
-static void
-dissect_server_flags(proto_tree *tree, int offset, int length, int flags)
-{
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0001, length*8, "Workstation", "Not \
                Workstation"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0002, length*8, "Server", "Not Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0004, length*8, "SQL Server", "Not SQL \
                Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0008, length*8, "Domain Controller", "Not \
                Domain Controller"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0010, length*8, "Backup Controller", "Not \
                Backup Controller"));
-  proto_tree_add_text(tree, NullTVB, offset, 4, "%s",
-		      decode_boolean_bitfield(flags, 0x0020, length*8, "Time Source", "Not Time \
                Source"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0040, length*8, "Apple Server", "Not Apple \
                Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0080, length*8, "Novell Server", "Not \
                Novell Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0100, length*8, "Domain Member Server", \
                "Not Domain Member Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0200, length*8, "Print Queue Server", "Not \
                Print Queue Server"));      
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0400, length*8, "Dialin Server", "Not \
                Dialin Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x0800, length*8, "Xenix Server", "Not Xenix \
                Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x1000, length*8, "NT Workstation", "Not NT \
                Workstation"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x2000, length*8, "Windows for Workgroups", \
                "Not Windows for Workgroups"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x8000, length*8, "NT Server", "Not NT \
                Server"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x10000, length*8, "Potential Browser", "Not \
                Potential Browser"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x20000, length*8, "Backup Browser", "Not \
                Backup Browser"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x40000, length*8, "Master Browser", "Not \
                Master Browser"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x80000, length*8, "Domain Master Browser", \
                "Not Domain Master Browser"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x100000, length*8, "OSF", "Not OSF"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x200000, length*8, "VMS", "Not VMS"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x400000, length*8, "Windows 95 or above", \
                "Not Windows 95 or above"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x40000000, length*8, "Local List Only", "Not \
                Local List Only"));
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s",
-		      decode_boolean_bitfield(flags, 0x80000000, length*8, "Domain Enum", "Not \
                Domain Enum"));
-
-}
-
-
-
-static char *p_desc = NULL, *d_desc = NULL, *data = NULL, *params = NULL;
-static int p_count, d_count, p_offset, d_offset, d_current = 0, p_current = 0;
-static int pd_p_current = 0, pd_d_current = 0, in_params = 0, need_data = 0;
-static int lm_ent_count = 0, lm_act_count = 0; 
-
-/* Initialize the various data structure */
-static void 
-dissect_transact_engine_init(const u_char *pd, const char *param_desc,
-    const char *data_desc, int SMB_offset, int ParameterOffset,
-    int ParameterCount, int DataOffset, int DataCount)
-{
-
-  d_count = DataCount;
-  p_count = ParameterCount;
-  d_offset = 0;
-  p_offset = 0;
-  d_current = 0;
-  p_current = 0;
-  lm_ent_count = lm_act_count = 0;
-  pd_d_current = DataOffset;
-  pd_p_current = ParameterOffset;
-  in_params = need_data = 0;
-
-  if (p_desc) g_free(p_desc);
-  p_desc = g_malloc(strlen(param_desc) + 1);
-  strcpy(p_desc, param_desc);
-
-  if (d_desc) g_free(d_desc);
-  d_desc= g_malloc(strlen(data_desc) + 1);
-  strcpy(d_desc, data_desc);
-
-  if (params) g_free(params);
-  params = g_malloc(p_count);
-  memcpy(params, pd + ParameterOffset, ParameterCount);
-
-  if (data) g_free(data);
-  data = g_malloc(d_count);
-  memcpy(data, pd + DataOffset, DataCount);
-
-}
-
-int get_ent_count()
-{
-
-  return lm_ent_count;
-
-}
-
-int get_act_count()
+static int
+not_implemented(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
 {
+	proto_tree_add_item(tree, hf_not_implemented, tvb, offset, \
tvb_length_remaining(tvb, offset), TRUE);  
-  return lm_act_count;
-
+	return offset+tvb_length_remaining(tvb,offset);
 }
 
-static int get_byte_count(const u_char *p_data)
-
+static int
+netshareenum_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int \
offset)  {
-  int count = 0, off = 0;
-
-  while (p_data[off] && isdigit(p_data[off])) {
-
-    count = (count * 10) + (int)p_data[off++] - (int)'0';
+	/* detail level */
+	proto_tree_add_uint(tree, hf_detail_level, tvb, offset, 2, tvb_get_letohs(tvb, \
offset)); +	offset += 2;
+
+	/* receiver buffer length */
+	proto_tree_add_uint(tree, hf_recv_buf_len, tvb, offset, 2, tvb_get_letohs(tvb, \
offset)); +	offset += 2;
 
-  }
-
-  return count;
+	return offset;
 }
 
-
-/* Dissect the next item, if Name is null, call it by its data type  */
-/* We pull out the next item in the appropriate place and display it */
-/* We display the parameters first, then the data, then any auxilliary data */
-
 static int
-dissect_transact_next(const u_char *pd, char *Name, int dirn, proto_tree *tree)
+netshareenum_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int \
offset)  {
-  /*  guint8        BParam; */
-  guint16       WParam = 0;
-  guint32       LParam = 0;
-  const char    /**Bytes,*/ *AsciiZ = NULL;
-  int           bc;
-
-  while (1) {
-
-    if (p_desc[p_offset] == 0) return 0;  /* No more ... */
-
-    switch (in_params) {
-
-    case 0:   /* We are in the params area ... */
-
-      switch (p_desc[p_offset++]) {
-
-      case 'r':
-
-	if (dirn == 0) { /* We need to process the data ... */
-	  
-	  need_data = 1;
-
+	proto_item *it = NULL;
+	proto_tree *tr = NULL;
+	guint16 acount,ecount;
+	int i;
+	guint16 convert;
+	int pad;
+	int totlen;
+
+	/* status */
+	proto_tree_add_uint(tree, hf_status, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* convert */
+	convert = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_convert, tvb, offset, 2, convert);
+	offset += 2;
+
+	/* entry count */
+	ecount = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2, ecount);
+	offset += 2;
+
+	/* available count */
+	acount = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_acount, tvb, offset, 2, acount);
+	offset += 2;
+
+	/* pad to guint16 */
+	pad = 0;
+	if (tvb_raw_offset(tvb)&0x01) {
+		offset += 1;
+		pad = 1;
 	}
 
-	break;
-
-      case 'h':  /* A WORD parameter received */
-
-	if (dirn == 0) {
-
-	  WParam = GSHORT(pd, pd_p_current);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 2, "%s: %u (%04X)", (Name) ? \
                Name : "Returned Word", WParam, WParam);
-
-	  pd_p_current += 2;
-
-	  lm_act_count = WParam;
-
-	  return 1;
-
-	}
-
-	break;
-
-      case 'e':  /* An ent count ..  */
-
-	if (dirn == 0) { /* Only relevant in a response */
-
-	  WParam = GSHORT(pd, pd_p_current);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 2, "%s: (%04X)", (Name) ? Name : \
                "Entry Count", WParam);
-
-	  pd_p_current += 2;
-
-	  lm_ent_count = WParam;  /* Save this for later retrieval */
-
-	  return 1;
-
-	}
-
-	break;
-
-      case 'W':  /* Word Parameter */
-
-	if (dirn == 1) {  /* A request ... */
-	
-	  /* Insert a word param */
-
-	  WParam = GSHORT(pd, pd_p_current);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 2, "%s: %u (%04X)", (Name) ? \
                Name : "Word Param", WParam, WParam);
-
-	  pd_p_current += 2;
-
-	  return 1;  /* That's it here ... we have dissected a param */
-
-	}
-
-	break;
-
-      case 'i':  /* A long word is returned */
-
-	if (dirn == 0) {
-
-	  LParam = GWORD(pd, pd_p_current);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 4, "%s: %u (0x%08X)", (Name) ? \
                Name : "Returned Long Word", LParam, LParam);
-
-	  pd_p_current += 2;
-
-	  return 1;
-
-	}
-
-	break;
-
-      case 'D':  /* Double Word parameter */
-
-	if (dirn == 1) {
-
-	  LParam = GWORD(pd, pd_p_current);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 4, "%s: %u (0x%08X)", (Name) ? \
                Name : "DWord Param", LParam, LParam);
-
-	  pd_p_current += 4;
-	  
-	  return 1;  /* That's it here */
-
-	}
-
-	break;
-
-      case 'g':  /* A byte or series of bytes is returned */
-
-	if (dirn == 0) {
- 
-	  bc = get_byte_count(p_desc + p_offset);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, bc, "%s%u: %s", (Name) ? Name : \
                "B", (bc) ? bc : 1, format_text( pd + pd_p_current, (bc) ? bc : 1));
-
-	  pd_p_current += (bc) ? bc : 1;
-
-	  return 1;
-
-	}
-
-	break;
-
-      case 'b':  /* A byte or series of bytes */
-
-	if (dirn == 1) {
-
-	  bc = get_byte_count(p_desc + p_offset);  /* This is not clean */
-
-	  /*Bytes = g_malloc(bc + 1); / * Is this needed ? */
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, bc, "%s%u: %s", (Name) ? Name : \
                "B", (bc) ? bc : 1, format_text(pd + pd_p_current, (bc) ? bc : 1));
-
-	  pd_p_current += (bc) ? bc : 1;
-
-	  return 1;  /* That's it here ... */
-
-	}
-
-	break;
-
-      case 'O': /* A null pointer */
-
-	if (dirn == 1) {
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 0, "%s: Null Pointer", (Name) ? \
                Name : "Unknown");
-
-	  return 1;  /* That's it here */
-
-	}
-
-	break;
-
-      case 'z': /* An AsciiZ string */
-
-	if (dirn == 1) {
-
-	  AsciiZ = pd + pd_p_current;
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, strlen(AsciiZ) + 1, "%s: %s", \
                (Name) ? Name : "AsciiZ", AsciiZ);
-
-	  pd_p_current += strlen(AsciiZ) + 1;
-
-	  return 1;  /* That's it here ... */
-
-	}
-
-	break;
-
-      case 'F': /* One or more pad bytes */
-
-	if (dirn == 1) {
-
-	  bc = get_byte_count(pd);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, bc, "%s%u: %s", (Name) ? Name : \
                "Pad", bc, format_text(pd + pd_p_current, bc));
-
-	  pd_p_current += bc;
-
-	  return 1;  /* That's it here */
-
-	}
-
-	break;
-
-      case 'L': /* Receive buffer len: Short */
-
-	if (dirn == 1) {
-
-	  WParam = GSHORT(pd, pd_p_current);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 2, "%s: %u (0x%04X)", (Name) ? \
                Name : "Receive Buffer Len", WParam, WParam);
-
-	  pd_p_current += 2;
-
-	  return 1;  /* That's it here ... */
-
+	/* create a subtree for all available shares */
+	if (tree) {
+		it = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), \
"Available Shares"); +		tr = proto_item_add_subtree(it, ett_lanman_shares);
 	}
 
-	break;
+	totlen = tvb_length(tvb);
+	for(i=0;i<ecount;i++){
+		proto_item *si = NULL;
+		proto_tree *st = NULL;
+		char *share;
+		int old_offset = offset;
+		int cptr;
 
-      case 's': /* Send buf ... */
+		share = (char *)tvb_get_ptr(tvb, offset, 1);
 
-	if (dirn == 1) {
+		if (tree) {
+			si = proto_tree_add_text(tr, tvb, offset, 0, "Share %s", share);
+			st = proto_item_add_subtree(si, ett_lanman_shares);
+		}
 
-	  need_data = 1;
+		/* share name */
+		proto_tree_add_item(st, hf_share_name, tvb, offset, 13, TRUE);
+		offset += 13;
 
-	  LParam = GWORD(pd, pd_p_current);
+		/* pad byte */
+		offset += 1;
 
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 4, "%s: %u", (Name) ? Name : \
"Send Buffer Ptr", LParam); +		/* share type */
+		proto_tree_add_uint(st, hf_share_type, tvb, offset, 2, tvb_get_letohs(tvb, \
offset)); +		offset += 2;
 
-	  pd_p_current += 4;
+		/* pointer to comment */
+		/* +8 is hte first 4 guint16s in the packet */
+		cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert+8+pad;
+		offset += 4;
 
-	  return 1;  /* That's it here ... */
+		/* share comment */
+		if(cptr<totlen){
+			proto_tree_add_item(st, hf_share_comment, tvb, cptr, tvb_strsize(tvb, cptr), \
TRUE); +		} else {
+			proto_tree_add_text(st, tvb, 0, 0, "Share Comment: <String goes past end of \
frame>"); +		}
 
+		proto_item_set_len(si, offset-old_offset);
 	}
 
-	break;
-
-      case 'T':
-
-	if (dirn == 1) {
-
-	  WParam = GSHORT(pd, pd_p_current);
-
-	  proto_tree_add_text(tree, NullTVB, pd_p_current, 2, "%s: %u", (Name) ? Name : \
                "Send Buffer Len", WParam);
-
-	  pd_p_current += 2;
-
-	  return 1;
-
-	}
-
-	break;
-	
-      default:
-
-	break;
-
-      }
-
-      break;
-
-    case 1:   /* We are in the data area ... */
-
-      
-      break;
-	
-    }
-  }
-
-  return 0;
-
+	return offset;
 }
 
-static const value_string share_type_vals[] = {
-        {0, "Directory tree"},
-        {1, "Printer queue"},
-        {2, "Communications device"},
-        {3, "IPC"},
-        {0, NULL}
-};
-
-/*
- * Per-frame data needed to dissect replies.
- */
-typedef struct {
-  guint16 FunctionCode;
-  gboolean is_continuation;
-} response_data;
-
-static GMemChunk  *lanman_proto_data;
-
-gboolean
-dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd,
-	proto_tree *parent, proto_tree *tree, struct smb_info si,
-	int max_data, int SMB_offset, int errcode, int dirn,
-	const u_char *command, int DataOffset, int DataCount,
-	int ParameterOffset, int ParameterCount)
+static int
+netserverenum2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int \
offset)  {
-  gboolean            is_interim_response;
-  guint32             loc_offset;
-  guint16             FunctionCode;
-  guint16             Level;
-  guint16             RecvBufLen;
-  guint32             Flags;
-  const char          *ParameterDescriptor;
-  const char          *ReturnDescriptor;
-  proto_tree          *lanman_tree = NULL, *flags_tree = NULL;
-  proto_item          *ti;
-  struct lanman_desc  *lanman;
-  guint32             string_offset;
-
-  if (DataOffset < 0) {
-
-    /* Interim response; we weren't given any data. */
-
-    is_interim_response = TRUE;
-    loc_offset = SMB_offset;
-
-  }
-  else {
-
-    /* Offset of the data we should dissect. */
-
-    is_interim_response = FALSE;
-    loc_offset = SMB_offset + ParameterOffset;
-
-  }
-
-  if (check_col(fd, COL_PROTOCOL))
-    col_set_str(fd, COL_PROTOCOL, "LANMAN");
-
-  if (dirn == 1) { /* The request side */
-
-    FunctionCode = GSHORT(pd, loc_offset);
-
-    si.request_val -> last_lanman_cmd = FunctionCode;
-
-    lanman = find_lanman(FunctionCode);
-
-    if (check_col(fd, COL_INFO)) {
-
-      if (lanman) { 
-	col_add_fstr(fd, COL_INFO, "%s Request", lanman -> lanman_name);
-      }
-      else {
-	col_add_fstr(fd, COL_INFO, "Unknown LANMAN Request: %u", FunctionCode);
-      }
-    }
-
-    if (tree) {
-
-      ti = proto_tree_add_item(parent, proto_smb_lanman, NullTVB, loc_offset, \
                ParameterCount, FALSE);
-      lanman_tree = proto_item_add_subtree(ti, ett_lanman);
-
-      if (lanman) {
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Function Code: %s", \
                lanman -> lanman_name);
-      }
-      else {
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Function Code: Unknown \
                LANMAN Request: %u", FunctionCode);
-      }
-
-    }
-
-    loc_offset += 2;
+	/* detail level */
+	proto_tree_add_uint(tree, hf_detail_level, tvb, offset, 2, tvb_get_letohs(tvb, \
offset)); +	offset += 2;
+
+	/* receiver buffer length */
+	proto_tree_add_uint(tree, hf_recv_buf_len, tvb, offset, 2, tvb_get_letohs(tvb, \
offset)); +	offset += 2;
+
+	/* server type flags */
+	dissect_smb_server_type_flags(tvb, pinfo, tree, offset, TRUE);
+	offset += 4;
 
-    ParameterDescriptor = pd + loc_offset;
-
-    /* Now, save these for later */
-
-    si.request_val -> trans_response_seen = 0; 
-
-    if (si.request_val -> last_param_descrip)
-      g_free(si.request_val -> last_param_descrip);
-    si.request_val -> last_param_descrip = g_malloc(strlen(ParameterDescriptor) + \
                1);
-    if (si.request_val -> last_param_descrip)
-      strcpy(si.request_val -> last_param_descrip, ParameterDescriptor);
-
-    if (tree) {
-
-      proto_tree_add_text(lanman_tree, NullTVB, loc_offset, \
                strlen(ParameterDescriptor) + 1, "Parameter Descriptor: %s", \
                ParameterDescriptor);
-
-    }
-
-    loc_offset += strlen(ParameterDescriptor) + 1;
-
-    ReturnDescriptor = pd + loc_offset;
-
-    if (si.request_val -> last_data_descrip)
-      g_free(si.request_val -> last_data_descrip);
-    si.request_val -> last_data_descrip = g_malloc(strlen(ReturnDescriptor) + 1);
-    if (si.request_val -> last_data_descrip)
-      strcpy(si.request_val -> last_data_descrip, ReturnDescriptor);
-
-    if (tree) {
-
-      proto_tree_add_text(lanman_tree, NullTVB, loc_offset, strlen(ReturnDescriptor) \
                + 1, "Return Descriptor: %s", ReturnDescriptor);
-
-    }
-
-    loc_offset += strlen(ReturnDescriptor) + 1;
-
-    switch (FunctionCode) {
-
-    case NETSHAREENUM:   /* Never decode this at the moment ... */
-
-      Level = GSHORT(pd, loc_offset);
-      
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Detail Level: %u", \
                Level);
-
-      }
-
-      loc_offset += 2;
-
-      RecvBufLen = GSHORT(pd, loc_offset);
-      
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Receive Buffer Length: \
                %u", RecvBufLen);
-
-      }
-
-      loc_offset += 2;
-      
-      break;
-
-    case NETSERVERENUM2:  /* Process a NetServerEnum2 */
-
-      Level = GSHORT(pd, loc_offset);
-      si.request_val -> last_level = Level;
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Info Detail Level: %u", \
                Level);
-
-      }
-
-      loc_offset += 2;
-      
-      RecvBufLen = GSHORT(pd, loc_offset);
-      
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Receive Buffer Length: \
                %u", RecvBufLen);
-
-      }
-
-      loc_offset += 2;
-
-      Flags = GWORD(pd, loc_offset);
-
-      if (tree) {
-
-	ti = proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 4, "Server Types \
                Required: 0x%08X", Flags);
-	flags_tree = proto_item_add_subtree(ti, ett_lanman_flags);
-	dissect_server_flags(flags_tree, loc_offset, 4, Flags);
-
-      }
-
-      loc_offset += 4;
-
-      return TRUE;
-      break;
-
-    default:   /* Just try to handle what is there ... */
-
-      if (tree) {
-
-	int i = 0;  /* Counter for names below */
-	char *name = NULL;
-
-	dissect_transact_engine_init(pd, ParameterDescriptor, ReturnDescriptor,SMB_offset, \
                loc_offset, ParameterCount, DataOffset, DataCount);
-
-	if (lanman) name = lanman -> req[i];  /* Must be OK ... */
-
-	while (dissect_transact_next(pd, name, dirn, lanman_tree))
-	  if (name) name = lanman -> req[++i];
-      }
-
-      break;
-    
-    }
-  }
-  else {  /* dirn == 0, response */
-    response_data    *proto_data;
-    guint16          Status;
-    guint16          Convert;
-    guint16          EntCount;
-    guint16          AvailCount;
-    int              i;
-    proto_tree       *server_tree = NULL, *flags_tree = NULL, *share_tree = NULL;
-
-    /* Is there any per-frame LANMAN data for this frame? */
-    proto_data = p_get_proto_data(fd, proto_smb_lanman);
-    if (proto_data == NULL) {
-      /* No.  Allocate some, and set it up. */
-      proto_data = g_mem_chunk_alloc(lanman_proto_data);
-      proto_data->FunctionCode = si.request_val -> last_lanman_cmd;
-
-      /*
-       * If we've already seen a response to the request, this must
-       * be a continuation of that response.
-       */
-      proto_data->is_continuation = si.request_val -> trans_response_seen;
-
-      /*
-       * Attach it to the frame.
-       */
-      p_add_proto_data(fd, proto_smb_lanman, proto_data);
-    }
-
-    FunctionCode = proto_data->FunctionCode;
-
-    /*
-     * If we have already seen the response to this transact, simply
-     * record it as a continuation ...
-     */
-    if (proto_data->is_continuation) {
-
-      if (check_col(fd, COL_INFO)) {
-	  col_set_str(fd, COL_INFO, "Transact Continuation");
-      }
-      
-      if (tree) {
-
-	ti = proto_tree_add_item(parent, proto_smb_lanman, NullTVB, loc_offset, \
                END_OF_FRAME, FALSE);
-
-	lanman_tree = proto_item_add_subtree(ti, ett_lanman);
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, END_OF_FRAME, "Payload: %s", \
                format_text(pd + loc_offset, END_OF_FRAME));
-
-      }
-
-      return TRUE;
-
-    } 
-
-    si.request_val -> trans_response_seen = 1; 
-
-    lanman = find_lanman(FunctionCode);
-
-    if (check_col(fd, COL_INFO)) {
-
-      if (lanman) {
-	col_add_fstr(fd, COL_INFO, "%s %sResponse", lanman -> lanman_name,
-		is_interim_response ? "Interim " : "");
-      }
-      else {
-	col_add_fstr(fd, COL_INFO, "Unknown LANMAN %sResponse: %u",
-		is_interim_response ? "Interim " : "", FunctionCode);
-      }
-    }
-
-    if (tree) {
-
-      ti = proto_tree_add_item(parent, proto_smb_lanman, NullTVB, loc_offset, \
                END_OF_FRAME, FALSE);
-      lanman_tree = proto_item_add_subtree(ti, ett_lanman);
-      if (lanman) {
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 0, "Function Code: %s", \
                lanman -> lanman_name);
-      }
-      else {
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 0, "Function Code: Unknown \
                LANMAN Response: %u", FunctionCode);
-      }
-    }
-
-    if (is_interim_response) {
-
-      return TRUE;	/* no data to dissect */
-
-    }
-
-    switch (FunctionCode) {
-
-    case NETSHAREENUM:
-
-      Status = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Status: %u", Status);
-
-      }
-
-      loc_offset += 2;
-
-      Convert = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Convert: %u", Convert);
-
-      }
-
-      loc_offset += 2;
-
-      EntCount = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Entry Count: %u", \
                EntCount);
-
-      }
-
-      loc_offset += 2;
-
-      AvailCount = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Available Entries: %u", \
                AvailCount);
-
-      }
-
-      loc_offset += 2;
-
-      if (tree) {
-
-	ti = proto_tree_add_text(lanman_tree, NullTVB, loc_offset, AvailCount * 20, \
                "Available Shares");
-
-	share_tree = proto_item_add_subtree(ti, ett_lanman_shares);
-
-      }
-
-      for (i = 1; i <= EntCount; i++) {
-	const gchar *Share = pd + loc_offset;
-	guint32     Flags;
-	const gchar *Comment;
-	proto_tree  *share = NULL;
-	proto_item  *ti = NULL;
-
-	if (tree) {
-
-	  ti = proto_tree_add_text(share_tree, NullTVB, loc_offset, 20, "Share %s", Share);
-	  share = proto_item_add_subtree(ti, ett_lanman_share);
-
-
-	}
-
-	if (tree) {
-	  
-	  proto_tree_add_text(share, NullTVB, loc_offset, 13, "Share Name: %s", Share);
-
-	}
-
-	loc_offset += 13;
-
-	loc_offset += 1;  /* Pad byte ... */
-
-	Flags = GSHORT(pd, loc_offset);
-
-	if (tree) {
-
-	  proto_tree_add_text(share, NullTVB, loc_offset, 2, "Share Type: %s",
-		val_to_str(Flags, share_type_vals, "Unknown (%u)"));
+	return offset;
+}
 
+static int
+netserverenum2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int \
offset) +{
+	guint16 ecount,acount,convert;
+	proto_item *it = NULL;
+	proto_tree *tr = NULL;
+	int i,pad,totlen;
+
+	/* status */
+	proto_tree_add_uint(tree, hf_status, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* convert */
+	convert = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_convert, tvb, offset, 2, convert);
+	offset += 2;
+
+	/* entry count */
+	ecount = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2, ecount);
+	offset += 2;
+
+	/* antry count */
+	acount = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_acount, tvb, offset, 2, acount);
+	offset += 2;
+
+	/* pad to guint16 */
+	pad = 0;
+	if (tvb_raw_offset(tvb)&0x01) {
+		offset += 1;
+		pad = 1;
 	}
 
-	loc_offset += 2;
-
-	/* XXX - should check whether all of the string is within the
-	   frame. */
-	string_offset = SMB_offset + DataOffset + (GWORD(pd, loc_offset) & 0xFFFF) - \
                Convert;
-	if (IS_DATA_IN_FRAME(string_offset))
-	  Comment = pd + string_offset;
-	else
-	  Comment = "<String goes past end of frame>";
-
 	if (tree) {
-
-	  proto_tree_add_text(share, NullTVB, loc_offset, 4, "Share Comment: %s", Comment);
-
+		it = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), \
"Servers"); +		tr = proto_item_add_subtree(it, ett_lanman_servers);
 	}
 
-	loc_offset += 4;
-
-      }
-
-      break;
-
-    case NETSERVERENUM2:
-
-      Status = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Status: %u", Status);
-
-      }
-
-      loc_offset += 2;
-
-      Convert = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Convert: %u", Convert);
-
-      }
-
-      loc_offset += 2;
-
-      EntCount = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Entry Count: %u", \
                EntCount);
-
-      }
-
-      loc_offset += 2;
-
-      AvailCount = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Available Entries: %u", \
                AvailCount);
-
-      }
-
-      loc_offset += 2;
-
-      if (tree) {
-
-	ti = proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 26 * AvailCount, \
                "Servers");
-	if (ti == NULL) { 
-
-	  printf("Null value returned from proto_tree_add_text\n");
-	  exit(1);
-
-	}
-
-	server_tree = proto_item_add_subtree(ti, ett_lanman_servers);
-
-      }
-
-      /* Make sure we don't go past the end of the capture buffer */
-
-      for (i = 1; (i <= EntCount) && ((pi.captured_len - loc_offset) >= 16); i++) {
-	const gchar *Server = pd + loc_offset;
-	gint8       ServerMajor;
-	guint       ServerMinor;
-	guint32     ServerFlags;
-	const gchar *Comment;
-	proto_tree  *server = NULL;
-	proto_item  *ti;
-
-	if (tree) {
-
-	  ti = proto_tree_add_text(server_tree, NullTVB, loc_offset, 
-				   (si.request_val -> last_level) ? 26 : 16,
-				   "Server %s", Server);
-	  server = proto_item_add_subtree(ti, ett_lanman_server);
-
+	totlen = tvb_length(tvb);
+	for(i=0;i<ecount;i++){
+		proto_item *si = NULL;
+		proto_tree *st = NULL;
+		char *server;
+		int cptr;
+		int old_offset = offset;
+
+		server = (char *)tvb_get_ptr(tvb, offset, 1);
+		if (tree) {
+			si = proto_tree_add_text(tr, tvb, offset, 
+				   0,
+				   "Server %s", server);
+			st = proto_item_add_subtree(si, ett_lanman_server);
+		}
+
+		/* server name */
+		proto_tree_add_item(st, hf_server_name, tvb, offset, 16, TRUE);
+		offset += 16;
+
+		if(tvb_length_remaining(tvb, offset)){
+			/* major version */
+			proto_tree_add_uint(st, hf_server_major, tvb, offset, 1, tvb_get_guint8(tvb, \
offset)); +			offset += 1;
+
+			/* minor version */
+			proto_tree_add_uint(st, hf_server_minor, tvb, offset, 1, tvb_get_guint8(tvb, \
offset)); +			offset += 1;
+
+			/* server type flags */
+			dissect_smb_server_type_flags(tvb, pinfo, st, offset, FALSE);
+			offset += 4;
+
+			/* pointer to comment */
+			/* +8 is hte first 4 guint16s in the packet */
+			cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert+8+pad;
+			offset += 4;
+
+			/* share comment */
+			if(cptr<totlen){
+				proto_tree_add_item(st, hf_server_comment, tvb, cptr, tvb_strsize(tvb, cptr), \
TRUE); +			} else {
+				proto_tree_add_text(st, tvb, 0, 0, "Share Comment: <String goes past end of \
frame>"); +			}
+
+		}
+
+		proto_item_set_len(si, offset-old_offset);
+	}
+
+	return offset;
+}
+
+#define LANMAN_NETSHAREENUM		0
+#define LANMAN_NETSHAREGETINFO		1
+#define LANMAN_NETSERVERGETINFO		13
+#define LANMAN_NETGROUPGETUSERS		52
+#define LANMAN_NETUSERGETINFO		56
+#define LANMAN_NETUSERGETGROUPS		59
+#define LANMAN_NETWKSTAGETINFO		63
+#define LANMAN_DOSPRINTQENUM		69
+#define LANMAN_DOSPRINTQGETINFO		70
+#define LANMAN_WPRINTQUEUEPAUSE		74
+#define LANMAN_WPRINTQUEUERESUME	75
+#define LANMAN_WPRINTJOBENUMERATE	76
+#define LANMAN_WPRINTJOBGETINFO		77
+#define LANMAN_RDOSPRINTJOBDEL		81
+#define LANMAN_RDOSPRINTJOBPAUSE	82
+#define LANMAN_RDOSPRINTJOBRESUME	83
+#define LANMAN_WPRINTDESTENUM		84
+#define LANMAN_WPRINTDESTGETINFO	85
+#define LANMAN_NETREMOTETOD		91
+#define LANMAN_WPRINTQUEUEPURGE		103
+#define LANMAN_NETSERVERENUM2		104
+#define LANMAN_WACCESSGETUSERPERMS	105
+#define LANMAN_SETUSERPASSWORD		115
+#define LANMAN_NETWKSTAUSERLOGON	132
+#define LANMAN_NETWKSTAUSERLOGOFF	133
+#define LANMAN_PRINTJOBINFO		147
+#define LANMAN_WPRINTDRIVERENUM		205
+#define LANMAN_WPRINTQPROCENUM		206
+#define LANMAN_WPRINTPORTENUM		207
+#define LANMAN_SAMOEMCHANGEPASSWORD	214
+
+static const value_string commands[] = {
+	{LANMAN_NETSHAREENUM,		"NetShareEnum"},
+	{LANMAN_NETSHAREGETINFO,	"NetShareGetInfo"},
+	{LANMAN_NETSERVERGETINFO,	"NetServerGetInfo"},
+	{LANMAN_NETGROUPGETUSERS,	"NetGroupGetUsers"},
+	{LANMAN_NETUSERGETINFO,		"NetUserGetInfo"},
+	{LANMAN_NETUSERGETGROUPS,	"NetUserGetGroups"},
+	{LANMAN_NETWKSTAGETINFO,	"NetWkstaGetInfo"},
+	{LANMAN_DOSPRINTQENUM,		"DOSPrintQEnum"},
+	{LANMAN_DOSPRINTQGETINFO,	"DOSPrintQGetInfo"},
+	{LANMAN_WPRINTQUEUEPAUSE,	"WPrintQueuePause"},
+	{LANMAN_WPRINTQUEUERESUME,	"WPrintQueueResume"},
+	{LANMAN_WPRINTJOBENUMERATE,	"WPrintJobEnumerate"},
+	{LANMAN_WPRINTJOBGETINFO,	"WPrintJobGetInfo"},
+	{LANMAN_RDOSPRINTJOBDEL,	"RDOSPrintJobDel"},
+	{LANMAN_RDOSPRINTJOBPAUSE,	"RDOSPrintJobPause"},
+	{LANMAN_RDOSPRINTJOBRESUME,	"RDOSPrintJobResume"},
+	{LANMAN_WPRINTDESTENUM,		"WPrintDestEnum"},
+	{LANMAN_WPRINTDESTGETINFO,	"WPrintDestGetInfo"},
+	{LANMAN_NETREMOTETOD,		"NetRemoteTOD"},
+	{LANMAN_WPRINTQUEUEPURGE,	"WPrintQueuePurge"},
+	{LANMAN_NETSERVERENUM2,		"NetServerEnum2"},
+	{LANMAN_WACCESSGETUSERPERMS,	"WAccessGetUserPerms"},
+	{LANMAN_SETUSERPASSWORD,	"SetUserPassword"},
+	{LANMAN_NETWKSTAUSERLOGON,	"NetWkstaUserLogon"},
+	{LANMAN_NETWKSTAUSERLOGOFF,	"NetWkstaUserLogoff"},
+	{LANMAN_PRINTJOBINFO,		"PrintJobInfo"},
+	{LANMAN_WPRINTDRIVERENUM,	"WPrintDriverEnum"},
+	{LANMAN_WPRINTQPROCENUM,	"WPrintQProcEnum"},
+	{LANMAN_WPRINTPORTENUM,		"WPrintPortEnum"},
+	{LANMAN_SAMOEMCHANGEPASSWORD,	"SamOEMChangePassword"},
+	{0,	NULL}
+};
 
-	}
+struct lanman_dissector {
+	int	command;
+	int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
+	int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
+};
 
-	if (tree) {
-	  
-	  proto_tree_add_text(server, NullTVB, loc_offset, 16, "Server Name: %s", Server);
+struct lanman_dissector lmd[] = {
+	{LANMAN_NETSHAREENUM,	netshareenum_request,	netshareenum_response},
+	{LANMAN_NETSERVERENUM2, netserverenum2_request,	netserverenum2_response},
+	{-1,			not_implemented,	not_implemented}
+};
 
+struct lanman_dissector *find_lanman_dissector(int cmd)
+{
+	int i;
+	for(i=0;1;i++){
+		if(lmd[i].command==-1){
+			return(&lmd[i]);
+		}
+		if(lmd[i].command==cmd){
+			return(&lmd[i]);
+		}
 	}
+	return NULL; /*never reached, to keep the compiler happy*/
+}
 
-	loc_offset += 16;
-
-	if (si.request_val -> last_level) { /* Print out the rest of the info */
-
-	  ServerMajor = GBYTE(pd, loc_offset);
-
-	  if (tree) {
-
-	    proto_tree_add_text(server, NullTVB, loc_offset, 1, "Major Version: %u", \
                ServerMajor);
-
-	  }
-
-	  loc_offset += 1;
-
-	  ServerMinor = GBYTE(pd, loc_offset);
-
-	  if (tree) {
-
-	    proto_tree_add_text(server, NullTVB, loc_offset, 1, "Minor Version: %u", \
                ServerMinor);
-
-	  }
-
-	  loc_offset += 1;
-
-	  ServerFlags = GWORD(pd, loc_offset);
-
-	  if (tree) {
-
-	    ti = proto_tree_add_text(server, NullTVB, loc_offset, 4, "Server Type: 0x%08X", \
                ServerFlags);
-	    flags_tree = proto_item_add_subtree(ti, ett_lanman_flags);
-	    dissect_server_flags(flags_tree, loc_offset, 4, ServerFlags);
-
-	  }
-
-	  loc_offset += 4;
-
-	  /* XXX - should check whether all of the string is within the
-	     frame. */
-	  string_offset = SMB_offset + DataOffset + (GWORD(pd, loc_offset) & 0xFFFF) - \
                Convert;
-	  if (IS_DATA_IN_FRAME(string_offset))
-	    Comment = pd + string_offset;
-	  else
-	    Comment = "<String goes past end of frame>";
 
-	  if (tree) {
 
-	    proto_tree_add_text(server, NullTVB, loc_offset, 4, "Server Comment: %s", \
Comment); +/*
+ * Functions to track and match responses with requests 
+ */
 
-	  }
+GHashTable *lm_table;
+static GMemChunk *lm_key_chunk = NULL;
+static GMemChunk *lm_data_chunk = NULL;
+static int lm_init_count = 200;
+
+/* XXX FIXME should also check src/dst address which can be IP/IPX/etc */
+struct lm_key {
+	guint16	tid;
+	guint16	pid;
+	guint16	uid;
+	guint16	mid;
+};
+struct lm_data {
+	int command;
+	int frame;
+};
 
-	  loc_offset += 4;
+static gint
+lm_equal(gconstpointer k1, gconstpointer k2)
+{
+	struct lm_key *key1 = (struct lm_key *)k1;
+	struct lm_key *key2 = (struct lm_key *)k2;
 
+	if ( (key1->tid==key2->tid)
+	   &&(key1->pid==key2->pid)
+	   &&(key1->uid==key2->uid)
+	   &&(key1->mid==key2->mid) ){
+		return TRUE;
 	}
 
-      }
-
-      break;
-
-    default:
-
-      Status = GSHORT(pd, loc_offset);
-
-      if (tree) {
-
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Status: %u", Status);
-
-      }
-
-      loc_offset += 2;
-
-      Convert = GSHORT(pd, loc_offset);
-
-      if (tree) {
+	return FALSE;
+}
 
-	proto_tree_add_text(lanman_tree, NullTVB, loc_offset, 2, "Convert: %u", Convert);
+static guint
+lm_hash(gconstpointer k)
+{
+	struct lm_key *key = (struct lm_key *)k;
+	guint hash_val;
 
-      }
+	hash_val = (key->tid) | (key->pid) 
+			| (key->uid) | (key->mid);
 
-      loc_offset += 2;
+	return hash_val;
+}
 
-      if (tree) {
+static gboolean
+lm_table_free_all(gpointer key_arg, gpointer value, gpointer user_data)
+{
+	/* key/data removed by g_mem_chunk_destroy */
 
-	int i = 0;
-	char *name = NULL;
+	return TRUE;
+}
 
-	dissect_transact_engine_init(pd, si.request_val -> last_param_descrip, \
si.request_val -> last_data_descrip, SMB_offset, loc_offset, ParameterCount, \
DataOffset, DataCount); +static void
+lm_init_protocol(void)
+{
+	if(lm_table != NULL){
+		g_hash_table_foreach_remove(lm_table, lm_table_free_all, NULL);
+	} else {
+		lm_table = g_hash_table_new(lm_hash, lm_equal);
+	}
+
+	if(lm_key_chunk){
+		g_mem_chunk_destroy(lm_key_chunk);
+	}
+	lm_key_chunk = g_mem_chunk_new("lm_key_chunk",
+		sizeof(struct lm_key),
+		lm_init_count*sizeof(struct lm_key),
+		G_ALLOC_ONLY);
+
+	if(lm_data_chunk){
+		g_mem_chunk_destroy(lm_data_chunk);
+	}
+	lm_data_chunk = g_mem_chunk_new("lm_data_chunk",
+		sizeof(struct lm_data),
+		lm_init_count*sizeof(struct lm_data),
+		G_ALLOC_ONLY);
 
-	if (lanman) name = lanman -> resp[i];
-	  
-	while (dissect_transact_next(pd, name, dirn, lanman_tree))
-	  if (name) name = lanman -> resp[++i];
-	  
-      }
+}
 
-      return TRUE;
-      break;
 
-    }
 
-  }
+gboolean
+dissect_pipe_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
+{
+	int offset = 0;
+	guint16 cmd;
+	proto_item *item = NULL;
+	proto_tree *tree = NULL;
+	struct lanman_dissector *dis;
+	struct lm_key key;
+	struct lm_data *dt;
+
+
+	if (check_col(pinfo->fd, COL_PROTOCOL)) {
+		col_set_str(pinfo->fd, COL_PROTOCOL, "LANMAN");
+	}
+
+	if (parent_tree) {
+		item = proto_tree_add_item(parent_tree, proto_smb_lanman, 
+			tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+		tree = proto_item_add_subtree(item, ett_lanman);
+	}
+
+	/* continuation messages, dont try to decode them */
+	if (pinfo->ps.smb.ddisp) { 
+		if (check_col(pinfo->fd, COL_INFO)) {
+			col_set_str(pinfo->fd, COL_INFO, "Transact Continuation");
+		}
+		return TRUE;
+	}
+
+
+
+	if (pinfo->ps.smb.request) { /* this is a request */
+
+		/* function code */
+		cmd = tvb_get_letohs(tvb, offset);
+		if (check_col(pinfo->fd, COL_INFO)) {
+			col_add_fstr(pinfo->fd, COL_INFO, "%s Request", val_to_str(cmd, commands, \
"Unknown Command:0x%02x")); +		}
+		proto_tree_add_uint(tree, hf_command, tvb, offset, 2, cmd);
+		offset += 2;
+
+		/* remember this request so we can match responses with it */
+		/* first just check if we have already added this one */
+		key.tid = pinfo->ps.smb.tid;
+		key.pid = pinfo->ps.smb.pid;
+		key.uid = pinfo->ps.smb.uid;
+		key.mid = pinfo->ps.smb.mid;
+		if (!g_hash_table_lookup(lm_table, &key)) {
+			/* we have not seen this request before
+			   add it so we can match responses to it */
+			struct lm_key *new_key;
+			struct lm_data *new_data;
+
+			new_key = g_mem_chunk_alloc(lm_key_chunk);
+			new_key->tid = key.tid;
+			new_key->pid = key.pid;
+			new_key->uid = key.uid;
+			new_key->mid = key.mid;
+
+			new_data = g_mem_chunk_alloc(lm_data_chunk);
+			new_data->command = cmd;
+			new_data->frame = pinfo->fd->num;
+
+			g_hash_table_insert(lm_table, new_key, new_data);
+		};
+
+
+		/* parameter descriptor */
+		proto_tree_add_item(tree, hf_param_desc, tvb, offset, tvb_strsize(tvb, offset), \
TRUE); +		offset += tvb_strsize(tvb, offset);
+
+		/* return descriptor */
+		proto_tree_add_item(tree, hf_return_desc, tvb, offset, tvb_strsize(tvb, offset), \
TRUE); +		offset += tvb_strsize(tvb, offset);
+
+		/* command parameters */
+ 		dis = find_lanman_dissector(cmd);
+		if(dis->request){
+			offset = (*(dis->request))(tvb, pinfo, tree, offset);
+		}
+
+	} else { /* this is a response */
+		/* check if we know this one */
+		key.tid = pinfo->ps.smb.tid;
+		key.pid = pinfo->ps.smb.pid;
+		key.uid = pinfo->ps.smb.uid;
+		key.mid = pinfo->ps.smb.mid;
+		if ((dt = g_hash_table_lookup(lm_table, &key))) {
+			/* ok we have seen this one before */
+
+			/* response to the request in frame xx */
+			proto_tree_add_uint(tree, hf_response_to, tvb, 0, 0, dt->frame);
+			/* command */
+			if (check_col(pinfo->fd, COL_INFO)) {
+				col_add_fstr(pinfo->fd, COL_INFO, "%s Response", val_to_str(dt->command, \
commands, "Unknown Command:0x%02x")); +			}
+			proto_tree_add_uint(tree, hf_command, tvb, 0, 0, dt->command);
+
+			/* command parameters */
+ 			dis = find_lanman_dissector(dt->command);
+			if(dis->response){
+				offset = (*(dis->response))(tvb, pinfo, tree, offset);
+			}
+		}	
+	} 		
 
   return FALSE;
 
 }
 
+
+
 gboolean
-dissect_pipe_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, \
proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int \
dirn, const u_char *command, int DataOffset, int DataCount, int ParameterOffset, int \
ParameterCount) +dissect_pipe_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree \
*tree, char *command)  {
 
   if (!proto_is_protocol_enabled(proto_smb_lanman))
@@ -1155,9 +628,7 @@
   if (command != NULL && strcmp(command, "LANMAN") == 0) {
     /* Try to decode a LANMAN */
 
-    return dissect_pipe_lanman(pd, offset, fd, parent, tree, si, max_data,
-			       SMB_offset, errcode, dirn, command, DataOffset,
-			       DataCount, ParameterOffset, ParameterCount);
+    return dissect_pipe_lanman(tvb, pinfo, tree);
 
   }
 
@@ -1165,21 +636,84 @@
 
 }
 
-static void
-pipe_lanman_init_protocol(void)
-{
-  if (lanman_proto_data != NULL)
-    g_mem_chunk_destroy(lanman_proto_data);
-
-  lanman_proto_data = g_mem_chunk_new("lanman_proto_data",
-				      sizeof(response_data),
-				      100 * sizeof(response_data),
-				      G_ALLOC_AND_FREE);
-}
 
 void
 register_proto_smb_pipe( void){
 
+	static hf_register_info hf[] = {
+		{ &hf_command,
+			{ "Command", "lanman.command", FT_UINT16, BASE_HEX,
+			VALS(commands), 0, "LANMAN Function Code/Command", HFILL }},
+
+		{ &hf_param_desc,
+			{ "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE,
+			NULL, 0, "LANMAN Parameter Descriptor", HFILL }},
+
+		{ &hf_return_desc,
+			{ "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE,
+			NULL, 0, "LANMAN Return Descriptor", HFILL }},
+
+		{ &hf_not_implemented,
+			{ "Unknown Data", "lanman.not_implemented", FT_BYTES, BASE_HEX,
+			NULL, 0, "Decoding of this data is not implemented yet", HFILL }},
+
+		{ &hf_detail_level,
+			{ "Detail Level", "lanman.level", FT_UINT16, BASE_DEC,
+			NULL, 0, "LANMAN Detail Level", HFILL }},
+
+		{ &hf_recv_buf_len,
+			{ "Recv Buf Len", "lanman.recv_buf_len", FT_UINT16, BASE_DEC,
+			NULL, 0, "LANMAN Receive Buffer Length", HFILL }},
+
+		{ &hf_response_to,
+			{ "Response to request in frame", "lanman.response_to", FT_UINT32, BASE_DEC,
+			NULL, 0, "This is a LANMAN response to the request in frame", HFILL }},
+
+		{ &hf_status,
+			{ "Status", "lanman.status", FT_UINT16, BASE_DEC,
+			VALS(share_status_vals), 0, "LANMAN Return status", HFILL }},
+
+		{ &hf_convert,
+			{ "Convert", "lanman.convert", FT_UINT16, BASE_DEC,
+			NULL, 0, "LANMAN Convert", HFILL }},
+
+		{ &hf_ecount,
+			{ "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC,
+			NULL, 0, "LANMAN Number of Entries", HFILL }},
+
+		{ &hf_acount,
+			{ "Available Count", "lanman.available_count", FT_UINT16, BASE_DEC,
+			NULL, 0, "LANMAN Number of Available Entries", HFILL }},
+
+		{ &hf_share_name,
+			{ "Name", "lanman.share.name", FT_STRING, BASE_NONE,
+			NULL, 0, "LANMAN Name of Share", HFILL }},
+
+		{ &hf_share_type,
+			{ "Type", "lanman.share.type", FT_UINT16, BASE_DEC,
+			VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }},
+
+		{ &hf_share_comment,
+			{ "Comment", "lanman.share.comment", FT_STRING, BASE_NONE,
+			NULL, 0, "LANMAN Share Comment", HFILL }},
+
+		{ &hf_server_name,
+			{ "Name", "lanman.server.name", FT_STRING, BASE_NONE,
+			NULL, 0, "LANMAN Name of Server", HFILL }},
+
+		{ &hf_server_major,
+			{ "Major", "lanman.server.major", FT_UINT8, BASE_DEC,
+			NULL, 0, "LANMAN Server Major Version", HFILL }},
+
+		{ &hf_server_minor,
+			{ "Minor", "lanman.server.minor", FT_UINT8, BASE_DEC,
+			NULL, 0, "LANMAN Server Minor Version", HFILL }},
+
+		{ &hf_server_comment,
+			{ "Comment", "lanman.server.comment", FT_STRING, BASE_NONE,
+			NULL, 0, "LANMAN Server Comment", HFILL }},
+
+	};
 
 	static gint *ett[] = {
 
@@ -1188,13 +722,14 @@
 		&ett_lanman_server,
 		&ett_lanman_shares,
 		&ett_lanman_share,
-		&ett_lanman_flags
 	};
 
 
     	proto_smb_lanman = proto_register_protocol(
     		"Microsoft Windows Lanman Protocol", "LANMAN", "lanman");
 
+	proto_register_field_array(proto_smb_lanman, hf, array_length(hf));
 	proto_register_subtree_array(ett, array_length(ett));
-	register_init_routine(&pipe_lanman_init_protocol);
+	register_init_routine(lm_init_protocol);
 }
+
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb-pipe.h \
                ethereal/packet-smb-pipe.h
--- ethereal-orig/packet-smb-pipe.h	Sun Mar 18 14:23:30 2001
+++ ethereal/packet-smb-pipe.h	Sat Jul 28 23:24:07 2001
@@ -23,15 +23,14 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+#ifndef _PACKET_SMB_PIPE_H_
+#define _PACKET_SMB_PIPE_H_
+
 gboolean
-dissect_pipe_lanman(const u_char *pd, int offset, frame_data *fd,
-	proto_tree *parent, proto_tree *tree, struct smb_info si,
-	int max_data, int SMB_offset, int errcode, int dirn,
-	const u_char *command, int DataOffset, int DataCount,
-	int ParameterOffset, int ParameterCount);
+dissect_pipe_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
 gboolean
-dissect_pipe_smb(const u_char *pd, int offset, frame_data *fd,
-    proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data,
-    int SMB_offset, int errcode, int dirn, const u_char *command,
-    int DataOffset, int DataCount, int ParameterOffset, int ParameterCount);
+dissect_pipe_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, char \
*command); +
+#endif
+
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb.c ethereal/packet-smb.c
--- ethereal-orig/packet-smb.c	Sat Jul 28 04:53:58 2001
+++ ethereal/packet-smb.c	Sun Jul 29 00:29:47 2001
@@ -9547,6 +9547,8 @@
   char             *trans_type = NULL, *trans_cmd, *loc_of_slash = NULL;
   int              index;
   const gchar      *Data;
+  tvbuff_t *newtvb;
+  packet_info *pinfo;
 
   if (!TransactName)
 	  return;
@@ -9569,6 +9571,13 @@
   else
     trans_cmd = NULL;
 
+  pinfo = &pi;
+  if(DataOffset<0){
+    newtvb = tvb_create_from_top(SMB_offset);
+  } else {
+    newtvb = tvb_create_from_top(SMB_offset+ParameterOffset);
+  }
+
   if ((trans_cmd == NULL) ||
       (((trans_type == NULL || strcmp(trans_type, "MAILSLOT") != 0) ||
        !dissect_mailslot_smb(pd, SetupAreaOffset, fd, parent, tree, si,
@@ -9576,9 +9585,7 @@
 			     SMB_offset + DataOffset, DataCount,
 			     SMB_offset + ParameterOffset, ParameterCount)) &&
       ((trans_type == NULL || strcmp(trans_type, "PIPE") != 0) ||
-       !dissect_pipe_smb(pd, offset, fd, parent, tree, si, max_data,
-			 SMB_offset, errcode, dirn, trans_cmd, DataOffset,
-			 DataCount, ParameterOffset, ParameterCount)))) {
+       !dissect_pipe_smb(newtvb, pinfo, parent, trans_cmd)))) {
     
     if (ParameterCount > 0) {
 
@@ -10673,6 +10680,8 @@
 	guint32         status;
 	int             SMB_offset = offset;
 	struct smb_info si;
+
+    	pi.ps.smb.ddisp = 0;
 
 	OLD_CHECK_DISPLAY_AS_DATA(proto_smb, pd, offset, fd, tree);
 


_______________________________________________
Ethereal-dev mailing list
Ethereal-dev@ethereal.com
http://www.ethereal.com/mailman/listinfo/ethereal-dev

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic