aboutsummaryrefslogtreecommitdiffstats
path: root/packet-tds.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet-tds.c')
-rw-r--r--packet-tds.c92
1 files changed, 65 insertions, 27 deletions
diff --git a/packet-tds.c b/packet-tds.c
index 0c9a4cf697..561501c614 100644
--- a/packet-tds.c
+++ b/packet-tds.c
@@ -3,7 +3,7 @@
* Copyright 2000-2002, Brian Bruns <camber@ais.org>
* Copyright 2002, Steve Langasek <vorlon@netexpress.net>
*
- * $Id: packet-tds.c,v 1.5 2002/11/17 21:47:41 gerald Exp $
+ * $Id: packet-tds.c,v 1.6 2002/11/23 07:29:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -26,20 +26,41 @@
/*
* The NETLIB protocol is a small blocking protocol designed to allow TDS
- * to be placed within different transports (TCP, DECNet, IPX/SPX). It
- * consist of an eight byte header containing a two byte size field, a last
- * packet indicator, a one byte packet type field, and a 4 byte field used in
- * RPC communications whose purpose is unknown (it is most likely a conversation
- * number to multiplex multiple conversations over a single socket).
+ * to be placed within different transports (TCP, DECNet, IPX/SPX). A
+ * NETLIB packet starts with an eight byte header containing:
*
- * The TDS protocol consists of a number of protocol data units (PDUs) marked
- * by a one byte field at the start of the PDU. Some PDUs are fixed length
- * some are variable length with a two byte size field following the type, and
- * then there is TDS_ROW_TOKEN in which size is determined by analyzing the
- * result set returned from the server. This in effect means that we are
- * hopelessly lost if we haven't seen the result set. Also, TDS 4/5 is byte
- * order negotiable, which is specified in the login packet. We can attempt to
- * determine it later on, but not with 100% accuracy.
+ * a one-byte packet type field;
+ *
+ * a one-byte "last packet" indicator;
+ *
+ * a two-byte size field giving the size of the packet, including
+ * the header;
+ *
+ * a four-byte field used in RPC communications whose purpose is
+ * unknown;
+ *
+ * followed by payload whose size is the value in the size field minus
+ * 8.
+ *
+ * Microsoft Network Monitor 2.x dissects the 4 byte field (and indicates
+ * that the one-byte last packet indicator also contains other bits).
+ *
+ * The TDS protocol consists of a number of protocol data units (PDUs) that
+ * appear to be assembled from NETLIB packets, in the form of zero or more
+ * NETLIB packets with the last packet indicator clear and a final NETLIB
+ * packet with the last packet indicator set. The type of the TDS PDU is
+ * specified by the packet type field of the NETLIB header (presumably that
+ * field has the same value for all NETLIB packets that make up a TDS PDU).
+ *
+ * The "server response" PDU consists of a sequence of multiple items, each
+ * one beginning with a one byte type field at the start of the PDU. Some
+ * items are fixed length, some are variable length with a two byte size
+ * field following the item type, and then there is TDS_ROW_TOKEN in which
+ * size is determined by analyzing the result set returned from the server.
+ * This in effect means that we are hopelessly lost if we haven't seen the
+ * result set. Also, TDS 4/5 is byte order negotiable, which is specified
+ * in the login packet. We can attempt to determine it later on, but not
+ * with 100% accuracy.
*
* Some preliminary documentation on the packet format can be found at
* http://www.freetds.org/tds.html
@@ -84,6 +105,24 @@
* All that said, the code does deal gracefully with different boudary
* conditions and what remains are the easier bits, IMHO.
*
+ * XXX - "real packets" means "TCP segments", for TCP.
+ *
+ * XXX - is it *REALLY* true that you can have more than one TDS PDU (as
+ * opposed to more than one server response item) per NETLIB packet? Or is
+ * all the data in a NETLIB packet put into a single TDS PDU? If so, then
+ * we can reassemble NETLIB packets using the standard TCP desegmentation
+ * code, and can reassemble TDS PDUs using "fragment_add_seq_next()",
+ * and more cleanly separate the NETLIB and TDS dissectors (although the
+ * "is this NETLIB" heuristic would have to look at TDS information past
+ * the NETLIB header, in order to make the heuristic strong enough not
+ * to get too many false positives; note that the heuristic should reject
+ * any putative NETLIB packet with a length field with a value < 8).
+ *
+ * That would substantially clean the dissector up, eliminating most of
+ * the per-packet data (we might still need information to handle
+ * TDS_ROW_TOKEN), getting rid of the stuff to handle data split across
+ * TCP segment boundaries in favor of simple reassembly code, and
+ * fixing some otherwise nasty-looking crashing bugs.
*/
#ifdef HAVE_CONFIG_H
@@ -199,9 +238,9 @@
/* Initialize the protocol and registered fields */
static int proto_tds = -1;
-static int hf_netlib_size = -1;
static int hf_netlib_type = -1;
static int hf_netlib_last = -1;
+static int hf_netlib_size = -1;
/* Initialize the subtree pointers */
static gint ett_netlib = -1;
@@ -1017,9 +1056,8 @@ dissect_netlib_hdr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, stru
"Netlib Header");
netlib_tree = proto_item_add_subtree(netlib_hdr, ett_netlib);
- proto_tree_add_text(netlib_tree, tvb, offset, 1, "Packet Type: %02x %s",
- nl_data->packet_type, val_to_str(nl_data->packet_type,
- packet_type_names, "Unknown Packet Type"));
+ proto_tree_add_uint(netlib_tree, hf_netlib_type, tvb, offset, 1,
+ nl_data->packet_type);
proto_tree_add_uint(netlib_tree, hf_netlib_last, tvb, offset+1, 1,
nl_data->packet_last);
proto_tree_add_uint(netlib_tree, hf_netlib_size, tvb, offset+2, 2,
@@ -1039,6 +1077,8 @@ dissect_netlib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint offset = 0;
guint bytes_remaining;
+ memset(&nl_data, '\0', sizeof nl_data);
+
p_data = p_get_proto_data(pinfo->fd, proto_tds);
/* check for an existing conversation */
@@ -1157,21 +1197,21 @@ proto_register_netlib(void)
/* Setup list of header fields See Section 1.6.1 for details*/
static hf_register_info hf[] = {
- { &hf_netlib_size,
- { "Size", "netlib.size",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "Packet Size", HFILL }
- },
{ &hf_netlib_type,
{ "Type", "netlib.type",
- FT_UINT8, BASE_HEX, NULL, 0x0,
+ FT_UINT8, BASE_HEX, VALS(packet_type_names), 0x0,
"Packet Type", HFILL }
},
{ &hf_netlib_last,
- { "Last Packet", "netlib.last",
+ { "Last Packet", "netlib.last",
FT_UINT8, BASE_DEC, NULL, 0x0,
"Last Packet Indicator", HFILL }
},
+ { &hf_netlib_size,
+ { "Size", "netlib.size",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Packet Size", HFILL }
+ },
};
/* Setup protocol subtree array */
@@ -1238,5 +1278,3 @@ proto_reg_handoff_netlib(void)
ntlmssp_handle = find_dissector("ntlmssp");
}
-
-