aboutsummaryrefslogtreecommitdiffstats
path: root/packet-nbns.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet-nbns.c')
-rw-r--r--packet-nbns.c182
1 files changed, 143 insertions, 39 deletions
diff --git a/packet-nbns.c b/packet-nbns.c
index 6df0fc8c38..68f9665c03 100644
--- a/packet-nbns.c
+++ b/packet-nbns.c
@@ -4,7 +4,7 @@
* Gilbert Ramirez <gram@xiexie.org>
* Much stuff added by Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-nbns.c,v 1.60 2001/09/29 01:19:00 guy Exp $
+ * $Id: packet-nbns.c,v 1.61 2001/09/30 23:14:43 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -40,6 +40,7 @@
#include "packet.h"
#include "packet-dns.h"
#include "packet-netbios.h"
+#include "packet-tcp.h"
#include "prefs.h"
static int proto_nbns = -1;
@@ -1365,7 +1366,7 @@ dissect_nbss_packet(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_item *tf;
guint8 msg_type;
guint8 flags;
- guint16 length;
+ int length;
int len;
char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME];
int name_type;
@@ -1503,25 +1504,25 @@ dissect_nbss_packet(tvbuff_t *tvb, int offset, packet_info *pinfo,
static void
dissect_nbss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
+ struct tcpinfo *tcpinfo = pinfo->private;
int offset = 0;
- guint8 msg_type;
int max_data;
+ guint8 msg_type;
+ guint8 flags;
+ guint32 length;
int len;
gboolean is_cifs;
- static const char zeroes[4] = { 0x00, 0x00, 0x00, 0x00 };
+ proto_tree *nbss_tree;
+ proto_item *ti;
if (check_col(pinfo->fd, COL_PROTOCOL))
col_set_str(pinfo->fd, COL_PROTOCOL, "NBSS");
if (check_col(pinfo->fd, COL_INFO))
col_clear(pinfo->fd, COL_INFO);
- msg_type = tvb_get_guint8(tvb, offset);
+ max_data = tvb_length(tvb);
- /*
- * XXX - we should set this based on both the length remaining
- * and "length"....
- */
- max_data = tvb_length_remaining(tvb, offset);
+ msg_type = tvb_get_guint8(tvb, offset);
if (pinfo->match_port == TCP_PORT_CIFS) {
/*
@@ -1537,40 +1538,126 @@ dissect_nbss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
is_cifs = FALSE;
}
- /* Hmmm, it may be a continuation message ... */
-
-#define RJSHACK 1
-#ifdef RJSHACK
- if (max_data < 4 ||
- ((msg_type != SESSION_REQUEST) &&
- (msg_type != POSITIVE_SESSION_RESPONSE) &&
- (msg_type != NEGATIVE_SESSION_RESPONSE) &&
- (msg_type != RETARGET_SESSION_RESPONSE) &&
- (msg_type != SESSION_KEEP_ALIVE) &&
- (msg_type != SESSION_MESSAGE)) ||
- ((msg_type == SESSION_MESSAGE) &&
- (tvb_memeql(tvb, offset, zeroes, 4) == 0))) {
-
- /*
- * We don't have the first 4 bytes of an NBNS header, or
- * the first byte isn't one of the known message types,
- * or it looks like a session message with a zero header.
- * Assume it's a continuation message.
- */
- if (check_col(pinfo->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "NBSS Continuation Message");
- }
+ /*
+ * This might be a continuation of an earlier message.
+ * (Yes, that might be true even if we're doing TCP reassembly,
+ * as the first TCP segment in the capture might start in the
+ * middle of an NBNS message.)
+ */
- if (tree)
- proto_tree_add_text(tree, tvb, offset, max_data, "Continuation data");
+ /*
+ * If this isn't reassembled data, check to see whether it
+ * looks like a continuation of a message.
+ * (If it is reassembled data, it shouldn't be a continuation,
+ * as reassembly should've gathered the continuations together
+ * into a message.)
+ */
+ if (!tcpinfo->is_reassembled) {
+ if (max_data < 4) {
+ /*
+ * Not enough data for an NBSS header; assume
+ * it's a continuation of a message.
+ *
+ * XXX - if there's not enough data, we should
+ * attempt to reassemble the data, if the first byte
+ * is a valid message type.
+ */
+ goto continuation;
+ }
- return;
- }
-#endif
+ /*
+ * We have enough data for an NBSS header.
+ * Get the flags and length of the message,
+ * and see if they're sane.
+ */
+ if (is_cifs) {
+ flags = 0;
+ length = tvb_get_ntoh24(tvb, offset + 1);
+ } else {
+ flags = tvb_get_guint8(tvb, offset + 1);
+ length = tvb_get_ntohs(tvb, offset + 2);
+ if (flags & NBSS_FLAGS_E)
+ length += 65536;
+ }
+ if ((flags & (~NBSS_FLAGS_E)) != 0) {
+ /*
+ * A bogus flag was set; assume it's a continuation.
+ */
+ goto continuation;
+ }
+
+ switch (msg_type) {
+
+ case SESSION_MESSAGE:
+ /*
+ * This is variable-length.
+ * All we know is that it shouldn't be zero.
+ * (XXX - can we get zero-length messages?
+ * Not with SMB, but perhaps other NetBIOS-based
+ * protocols have them.)
+ */
+ if (length == 0)
+ goto continuation;
+ break;
+ case SESSION_REQUEST:
+ /*
+ * This is variable-length.
+ * The names are DNS-encoded 32-byte values;
+ * we need at least 2 bytes (one for each name;
+ * actually, we should have more for the first
+ * name, as there's no name preceding it so
+ * there should be no compression), and we
+ * shouldn't have more than 128 bytes (actually,
+ * we shouldn't have that many).
+ */
+ if (length < 2 || length > 128)
+ goto continuation;
+ break;
+
+ case POSITIVE_SESSION_RESPONSE:
+ /*
+ * This has no data, so the length must be zero.
+ */
+ if (length != 0)
+ goto continuation;
+ break;
+
+ case NEGATIVE_SESSION_RESPONSE:
+ /*
+ * This has 1 byte of data.
+ */
+ if (length != 1)
+ goto continuation;
+ break;
+
+ case RETARGET_SESSION_RESPONSE:
+ /*
+ * This has 6 bytes of data.
+ */
+ if (length != 6)
+ goto continuation;
+ break;
+
+ case SESSION_KEEP_ALIVE:
+ /*
+ * This has no data, so the length must be zero.
+ */
+ if (length != 0)
+ goto continuation;
+ break;
+
+ default:
+ /*
+ * Unknown message type; assume it's a continuation.
+ */
+ goto continuation;
+ }
+ }
+
if (check_col(pinfo->fd, COL_INFO)) {
col_add_fstr(pinfo->fd, COL_INFO,
- val_to_str(msg_type, message_types, "Unknown (%x)"));
+ val_to_str(msg_type, message_types, "Unknown (%02x)"));
}
while (max_data > 0) {
@@ -1579,6 +1666,23 @@ dissect_nbss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += len;
max_data -= len;
}
+
+ return;
+
+continuation:
+ /*
+ * It looks like a continuation.
+ */
+ if (check_col(pinfo->fd, COL_INFO))
+ col_add_fstr(pinfo->fd, COL_INFO, "NBSS Continuation Message");
+
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_nbss, tvb, 0,
+ max_data, FALSE);
+ nbss_tree = proto_item_add_subtree(ti, ett_nbss);
+ proto_tree_add_text(nbss_tree, tvb, 0, max_data,
+ "Continuation data");
+ }
}
void