summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-tds.c
diff options
context:
space:
mode:
authorNathan Cole <nath@thecoleresidence.co.uk>2015-10-16 17:35:22 +0100
committerAnders Broman <a.broman58@gmail.com>2015-10-20 06:07:50 +0000
commitb4386568ed49e103e3e3247cd5cadc9e2cbd7e75 (patch)
treeb34a95c8fce22894e339c326c64c9900cd81facd /epan/dissectors/packet-tds.c
parent82ec0bb0fc6bf551693d26c8a575bb3fbd9d0264 (diff)
downloadwireshark-b4386568ed49e103e3e3247cd5cadc9e2cbd7e75.tar.gz
Update TDS dissector to latest version of protocol.
Dissector updated to recognise and dissect up to TDS 7.4. Most response tokens now fully parsed and registered, allowing for much more granular filtering and output. Virtually all TDS datatypes now parsed and presented in human readable format. Version dependent decisions now default to TDS 7.2 in the absence of version information in the data, making successful dissection more likely. Bug: 11603 Change-Id: Iabaa35c74b104d56eda7e043302d14e99cb7aa06 Reviewed-on: https://code.wireshark.org/review/11100 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-tds.c')
-rw-r--r--epan/dissectors/packet-tds.c4532
1 files changed, 3415 insertions, 1117 deletions
diff --git a/epan/dissectors/packet-tds.c b/epan/dissectors/packet-tds.c
index d0035d4382..0f7af17caf 100644
--- a/epan/dissectors/packet-tds.c
+++ b/epan/dissectors/packet-tds.c
@@ -152,14 +152,15 @@
#include <epan/reassemble.h>
#include <epan/prefs.h>
#include <epan/expert.h>
+#include "packet-tcp.h"
-#define TDS_QUERY_PKT 1
+#define TDS_QUERY_PKT 1 /* SQLBatch in MS-TDS revision 18.0 */
#define TDS_LOGIN_PKT 2
#define TDS_RPC_PKT 3
#define TDS_RESP_PKT 4
#define TDS_RAW_PKT 5
#define TDS_ATTENTION_PKT 6
-#define TDS_BULK_DATA_PKT 7
+#define TDS_BULK_DATA_PKT 7 /* Bulk Load BCP in MS-TDS revision 18.0 */
#define TDS_OPEN_CHN_PKT 8
#define TDS_CLOSE_CHN_PKT 9
#define TDS_RES_ERROR_PKT 10
@@ -172,14 +173,16 @@
#define TDS_SSPI_PKT 17
#define TDS_PRELOGIN_PKT 18
#define TDS_INVALID_PKT 19
+#define TDS_TLS_PKT 23
-#define is_valid_tds_type(x) ((x) >= TDS_QUERY_PKT && (x) < TDS_INVALID_PKT)
+#define is_valid_tds_type(x) (((x) >= TDS_QUERY_PKT && (x) < TDS_INVALID_PKT) || x == TDS_TLS_PKT)
/* The following constants are imported more or less directly from FreeTDS */
/* Updated from FreeTDS v0.63 tds.h */
/* "$Id: tds.h,v 1.192 2004/10/28 12:42:12 freddy77]" */
/* Note: [###] below means 'not defined in FreeTDS tds.h' */
+#define TDS_TVPROW_TOKEN 1 /* 0x01 */
#define TDS5_PARAMFMT2_TOKEN 32 /* 0x20 TDS 5.0 only */
#define TDS_LANG_TOKEN 33 /* 0x21 TDS 5.0 only */
#define TDS5_ORDERBY2_TOKEN 34 /* 0x22 TDS 5.0 only */
@@ -187,49 +190,51 @@
#define TDS5_ROWFMT2_TOKEN 97 /* 0x61 TDS 5.0 only */
#define TDS5_MSG_TOKEN 101 /* 0x65 TDS 5.0 only [###] */
#define TDS_LOGOUT_TOKEN 113 /* 0x71 TDS 5.0 only? ct_close() */
+#define TDS_OFFSET_TOKEN 120 /* 0x78 Removed in TDS 7.2 */
#define TDS_RET_STAT_TOKEN 121 /* 0x79 */
#define TDS_PROCID_TOKEN 124 /* 0x7C TDS 4.2 only - TDS_PROCID */
#define TDS_CURCLOSE_TOKEN 128 /* 0x80 TDS 5.0 only */
-#define TDS7_RESULT_TOKEN 129 /* 0x81 TDS 7.0 only */
+#define TDS7_COL_METADATA_TOKEN 129 /* 0x81 */
#define TDS_CURFETCH_TOKEN 130 /* 0x82 TDS 5.0 only */
#define TDS_CURINFO_TOKEN 131 /* 0x83 TDS 5.0 only */
#define TDS_CUROPEN_TOKEN 132 /* 0x84 TDS 5.0 only */
#define TDS_CURDECLARE_TOKEN 134 /* 0x86 TDS 5.0 only */
-#define TDS7_COMPUTE_RESULT_TOKEN 136 /* 0x88 TDS 7.0 only */
+#define TDS7_ALTMETADATA_TOKEN 136 /* 0x88 */
#define TDS_COL_NAME_TOKEN 160 /* 0xA0 TDS 4.2 only */
#define TDS_COL_INFO_TOKEN 161 /* 0xA1 TDS 4.2 only - TDS_COLFMT */
#define TDS5_DYNAMIC2_TOKEN 163 /* 0xA3 TDS 5.0 only */
-#if 0 /* XX: Why commented out ? These are 'live' in FreeTDS tds.h */
-#define TDS_TABNAME 164 /* 0xA4 */
-#define TDS_COL_INFO 165 /* 0xA5 */
-#endif
+#define TDS_TABNAME_TOKEN 164 /* 0xA4 */
+#define TDS7_COL_INFO_TOKEN 165 /* 0xA5 */
#define TDS_OPTIONCMD_TOKEN 166 /* 0xA6 */
#define TDS_COMPUTE_NAMES_TOKEN 167 /* 0xA7 */
#define TDS_COMPUTE_RESULT_TOKEN 168 /* 0xA8 */
-#define TDS_ORDER_BY_TOKEN 169 /* 0xA9 TDS_ORDER */
+#define TDS_ORDER_TOKEN 169 /* 0xA9 TDS_ORDER */
#define TDS_ERR_TOKEN 170 /* 0xAA */
-#define TDS_MSG_TOKEN 171 /* 0xAB */
-#define TDS_PARAM_TOKEN 172 /* 0xAC RETURNVALUE? */
+#define TDS_INFO_TOKEN 171 /* 0xAB */
+#define TDS_RETURNVAL_TOKEN 172 /* 0xAC */
#define TDS_LOGIN_ACK_TOKEN 173 /* 0xAD */
-#define TDS_CONTROL_TOKEN 174 /* 0xAE TDS_CONTROL */
+#define TDS_FEATUREEXTACK_TOKEN 174 /* 0xAE Introduced TDS 7.4 */
#define TDS_KEY_TOKEN 202 /* 0xCA [###] */
#define TDS_ROW_TOKEN 209 /* 0xD1 */
-#define TDS_CMP_ROW_TOKEN 211 /* 0xD3 */
+#define TDS_NBCROW_TOKEN 210 /* 0xD2 Introduced TDS 7.3 */
+#define TDS_ALTROW_TOKEN 211 /* 0xD3 */
#define TDS5_PARAMS_TOKEN 215 /* 0xD7 TDS 5.0 only */
#define TDS_CAP_TOKEN 226 /* 0xE2 */
-#define TDS_ENV_CHG_TOKEN 227 /* 0xE3 */
+#define TDS_ENVCHG_TOKEN 227 /* 0xE3 */
+#define TDS_SESSIONSTATE_TOKEN 228 /* 0xE4 Introduced TDS 7.4 */
#define TDS_EED_TOKEN 229 /* 0xE5 */
#define TDS_DBRPC_TOKEN 230 /* 0xE6 */
#define TDS5_DYNAMIC_TOKEN 231 /* 0xE7 TDS 5.0 only */
#define TDS5_PARAMFMT_TOKEN 236 /* 0xEC TDS 5.0 only */
-#define TDS_AUTH_TOKEN 237 /* 0xED */
-#define TDS_RESULT_TOKEN 238 /* 0xEE */
-#define TDS_DONE_TOKEN 253 /* 0xFD TDS_DONE */
-#define TDS_DONEPROC_TOKEN 254 /* 0xFE TDS_DONEPROC */
-#define TDS_DONEINPROC_TOKEN 255 /* 0xFF TDS_DONEINPROC */
+#define TDS_AUTH_TOKEN 237 /* 0xED */ /* DUPLICATE! */
+#define TDS_SSPI_TOKEN 237 /* 0xED */ /* DUPLICATE! */
+#define TDS_RESULT_TOKEN 238 /* 0xEE */ /* DUPLICATE! */
+#define TDS_FEDAUTHINFO_TOKEN 238 /* 0xEE Introduced TDS 7.4 */ /* DUPLICATE! */
+#define TDS_DONE_TOKEN 253 /* 0xFD */
+#define TDS_DONEPROC_TOKEN 254 /* 0xFE */
+#define TDS_DONEINPROC_TOKEN 255 /* 0xFF */
/* Microsoft internal stored procedure id's */
-
#define TDS_SP_CURSOR 1
#define TDS_SP_CURSOROPEN 2
#define TDS_SP_CURSORPREPARE 3
@@ -246,7 +251,6 @@
#define TDS_SP_PREPEXECRPC 14
#define TDS_SP_UNPREPARE 15
-
#define TDS_RPC_OPT_WITH_RECOMP 0x01
#define TDS_RPC_OPT_NO_METADATA 0x02
#define TDS_RPC_OPT_REUSE_METADATA 0x04
@@ -297,65 +301,120 @@
#define SYBUNIQUE 36 /* 0x24 */
#define SYBVARIANT 98 /* 0x62 */
-#define is_fixed_coltype(x) (x==SYBINT1 || \
- x==SYBINT2 || \
- x==SYBINT4 || \
- x==SYBINT8 || \
- x==SYBREAL || \
- x==SYBFLT8 || \
- x==SYBDATETIME || \
- x==SYBDATETIME4 || \
- x==SYBBIT || \
- x==SYBMONEY || \
- x==SYBMONEY4 || \
- x==SYBUNIQUE)
-
/* FIXEDLENTYPE */
-#define TDS_DATA_TYPE_NULL 0x1F /* Null (no data associated with this type) */
-#define TDS_DATA_TYPE_INT1 0x30 /* TinyInt (1 byte data representation) */
-#define TDS_DATA_TYPE_BIT 0x32 /* Bit (1 byte data representation) */
-#define TDS_DATA_TYPE_INT2 0x34 /* SmallInt (2 byte data representation) */
-#define TDS_DATA_TYPE_INT4 0x38 /* Int (4 byte data representation) */
-#define TDS_DATA_TYPE_DATETIM4 0x3A /* SmallDateTime (4 byte data representation) */
-#define TDS_DATA_TYPE_FLT4 0x3B /* Real (4 byte data representation) */
-#define TDS_DATA_TYPE_MONEY 0x3C /* Money (8 byte data representation) */
-#define TDS_DATA_TYPE_DATETIME 0x3D /* DateTime (8 byte data representation) */
-#define TDS_DATA_TYPE_FLT8 0x3E /* Float (8 byte data representation) */
-#define TDS_DATA_TYPE_MONEY4 0x7A /* SmallMoney (4 byte data representation) */
-#define TDS_DATA_TYPE_INT8 0x7F /* BigInt (8 byte data representation) */
+#define TDS_DATA_TYPE_NULL 0x1F /* 31 = Null (no data associated with this type) */
+#define TDS_DATA_TYPE_INT1 0x30 /* 48 = TinyInt (1 byte data representation) */
+#define TDS_DATA_TYPE_BIT 0x32 /* 50 = Bit (1 byte data representation) */
+#define TDS_DATA_TYPE_INT2 0x34 /* 52 = SmallInt (2 byte data representation) */
+#define TDS_DATA_TYPE_INT4 0x38 /* 56 = Int (4 byte data representation) */
+#define TDS_DATA_TYPE_DATETIME4 0x3A /* 58 = SmallDateTime (4 byte data representation) */
+#define TDS_DATA_TYPE_FLT4 0x3B /* 59 = Real (4 byte data representation) */
+#define TDS_DATA_TYPE_MONEY 0x3C /* 60 = Money (8 byte data representation) */
+#define TDS_DATA_TYPE_DATETIME 0x3D /* 61 = DateTime (8 byte data representation) */
+#define TDS_DATA_TYPE_FLT8 0x3E /* 62 = Float (8 byte data representation) */
+#define TDS_DATA_TYPE_MONEY4 0x7A /* 122 = SmallMoney (4 byte data representation) */
+#define TDS_DATA_TYPE_INT8 0x7F /* 127 = BigInt (8 byte data representation) */
/* BYTELEN_TYPE */
-#define TDS_DATA_TYPE_GUID 0x24 /* UniqueIdentifier */
-#define TDS_DATA_TYPE_INTN 0x26
-#define TDS_DATA_TYPE_DECIMAL 0x37 /* Decimal (legacy support) */
-#define TDS_DATA_TYPE_NUMERIC 0x3F /* Numeric (legacy support) */
-#define TDS_DATA_TYPE_BITN 0x68
-#define TDS_DATA_TYPE_DECIMALN 0x6A /* Decimal */
-#define TDS_DATA_TYPE_NUMERICN 0x6C /* Numeric */
-#define TDS_DATA_TYPE_FLTN 0x6D
-#define TDS_DATA_TYPE_MONEYN 0x6E
-#define TDS_DATA_TYPE_DATETIMN 0x6F
-#define TDS_DATA_TYPE_DATEN 0x28 /* (introduced in TDS 7.3) */
-#define TDS_DATA_TYPE_TIMEN 0x29 /* (introduced in TDS 7.3) */
-#define TDS_DATA_TYPE_DATETIME2N 0x2A /* (introduced in TDS 7.3) */
-#define TDS_DATA_TYPE_DATETIMEOFFSETN 0x2B /* (introduced in TDS 7.3) */
-#define TDS_DATA_TYPE_CHAR 0x2F /* Char (legacy support) */
-#define TDS_DATA_TYPE_VARCHAR 0x27 /* VarChar (legacy support) */
-#define TDS_DATA_TYPE_BINARY 0x2D /* Binary (legacy support) */
-#define TDS_DATA_TYPE_VARBINARY 0x25 /* VarBinary (legacy support) */
+#define TDS_DATA_TYPE_GUID 0x24 /* 36 = UniqueIdentifier */
+#define TDS_DATA_TYPE_INTN 0x26 /* 38 */
+#define TDS_DATA_TYPE_DECIMAL 0x37 /* 55 = Decimal (legacy support) */
+#define TDS_DATA_TYPE_NUMERIC 0x3F /* 63 = Numeric (legacy support) */
+#define TDS_DATA_TYPE_BITN 0x68 /* 104 */
+#define TDS_DATA_TYPE_DECIMALN 0x6A /* 106 = Decimal */
+#define TDS_DATA_TYPE_NUMERICN 0x6C /* 108 = Numeric */
+#define TDS_DATA_TYPE_FLTN 0x6D /* 109 */
+#define TDS_DATA_TYPE_MONEYN 0x6E /* 110 */
+#define TDS_DATA_TYPE_DATETIMN 0x6F /* 111 */
+#define TDS_DATA_TYPE_DATEN 0x28 /* 40 (introduced in TDS 7.3) */
+#define TDS_DATA_TYPE_TIMEN 0x29 /* 41 (introduced in TDS 7.3) */
+#define TDS_DATA_TYPE_DATETIME2N 0x2A /* 42 (introduced in TDS 7.3) */
+#define TDS_DATA_TYPE_DATETIMEOFFSETN 0x2B /* 43 (introduced in TDS 7.3) */
+#define TDS_DATA_TYPE_CHAR 0x2F /* 47 = Char (legacy support) */
+#define TDS_DATA_TYPE_VARCHAR 0x27 /* 39 = VarChar (legacy support) */
+#define TDS_DATA_TYPE_BINARY 0x2D /* 45 = Binary (legacy support) */
+#define TDS_DATA_TYPE_VARBINARY 0x25 /* 37 = VarBinary (legacy support) */
/* USHORTLEN_TYPE */
-#define TDS_DATA_TYPE_BIGVARBIN 0xA5 /* VarBinary */
-#define TDS_DATA_TYPE_BIGVARCHR 0xA7 /* VarChar */
-#define TDS_DATA_TYPE_BIGBINARY 0xAD /* Binary */
-#define TDS_DATA_TYPE_BIGCHAR 0xAF /* Char */
-#define TDS_DATA_TYPE_NVARCHAR 0xE7 /* NVarChar */
-#define TDS_DATA_TYPE_NCHAR 0xEF /* NChar */
+#define TDS_DATA_TYPE_BIGVARBIN 0xA5 /* 165 = VarBinary */
+#define TDS_DATA_TYPE_BIGVARCHR 0xA7 /* 167 = VarChar */
+#define TDS_DATA_TYPE_BIGBINARY 0xAD /* 173 = Binary */
+#define TDS_DATA_TYPE_BIGCHAR 0xAF /* 175 = Char */
+#define TDS_DATA_TYPE_NVARCHAR 0xE7 /* 231 = NVarChar */
+#define TDS_DATA_TYPE_NCHAR 0xEF /* 239 = NChar */
/* LONGLEN_TYPE */
-#define TDS_DATA_TYPE_XML 0xF1 /* XML (introduced in TDS 7.2) */
-#define TDS_DATA_TYPE_UDT 0xF0 /* CLR-UDT (introduced in TDS 7.2) */
-#define TDS_DATA_TYPE_TEXT 0x23 /* Text */
-#define TDS_DATA_TYPE_IMAGE 0x22 /* Image */
-#define TDS_DATA_TYPE_NTEXT 0x63 /* NText */
-#define TDS_DATA_TYPE_SSVARIANT 0x62 /* Sql_Variant (introduced in TDS 7.2) */
+#define TDS_DATA_TYPE_XML 0xF1 /* 241 = XML (introduced in TDS 7.2) */
+#define TDS_DATA_TYPE_UDT 0xF0 /* 240 = CLR-UDT (introduced in TDS 7.2) */
+#define TDS_DATA_TYPE_TEXT 0x23 /* 35 = Text */
+#define TDS_DATA_TYPE_IMAGE 0x22 /* 34 = Image */
+#define TDS_DATA_TYPE_NTEXT 0x63 /* 99 = NText */
+#define TDS_DATA_TYPE_SSVARIANT 0x62 /* 98 = Sql_Variant (introduced in TDS 7.2) */
+
+#define is_fixedlen_type_sybase(x) (x==SYBINT1 || \
+ x==SYBINT2 || \
+ x==SYBINT4 || \
+ x==SYBINT8 || \
+ x==SYBREAL || \
+ x==SYBFLT8 || \
+ x==SYBDATETIME || \
+ x==SYBDATETIME4 || \
+ x==SYBBIT || \
+ x==SYBMONEY || \
+ x==SYBMONEY4 || \
+ x==SYBUNIQUE \
+ )
+
+#define is_fixedlen_type_tds(x) (x==TDS_DATA_TYPE_NULL || \
+ x==TDS_DATA_TYPE_INT1 || \
+ x==TDS_DATA_TYPE_BIT || \
+ x==TDS_DATA_TYPE_INT2 || \
+ x==TDS_DATA_TYPE_INT4 || \
+ x==TDS_DATA_TYPE_DATETIME4 || \
+ x==TDS_DATA_TYPE_FLT4 || \
+ x==TDS_DATA_TYPE_MONEY || \
+ x==TDS_DATA_TYPE_DATETIME || \
+ x==TDS_DATA_TYPE_FLT8 || \
+ x==TDS_DATA_TYPE_MONEY4 || \
+ x==TDS_DATA_TYPE_INT8 \
+ )
+
+#define is_varlen_type_tds(x) (x==TDS_DATA_TYPE_GUID || \
+ x==TDS_DATA_TYPE_INTN || \
+ x==TDS_DATA_TYPE_DECIMAL || \
+ x==TDS_DATA_TYPE_NUMERIC || \
+ x==TDS_DATA_TYPE_BITN || \
+ x==TDS_DATA_TYPE_DECIMALN || \
+ x==TDS_DATA_TYPE_NUMERICN || \
+ x==TDS_DATA_TYPE_FLTN || \
+ x==TDS_DATA_TYPE_MONEYN || \
+ x==TDS_DATA_TYPE_DATETIMN || \
+ x==TDS_DATA_TYPE_DATEN || \
+ x==TDS_DATA_TYPE_TIMEN || \
+ x==TDS_DATA_TYPE_DATETIME2N || \
+ x==TDS_DATA_TYPE_DATETIMEOFFSETN || \
+ x==TDS_DATA_TYPE_CHAR || \
+ x==TDS_DATA_TYPE_VARCHAR || \
+ x==TDS_DATA_TYPE_BINARY || \
+ x==TDS_DATA_TYPE_VARBINARY || \
+ x==TDS_DATA_TYPE_BIGVARBIN || \
+ x==TDS_DATA_TYPE_BIGVARCHR || \
+ x==TDS_DATA_TYPE_BIGBINARY || \
+ x==TDS_DATA_TYPE_BIGCHAR || \
+ x==TDS_DATA_TYPE_NVARCHAR || \
+ x==TDS_DATA_TYPE_NCHAR || \
+ x==TDS_DATA_TYPE_XML || \
+ x==TDS_DATA_TYPE_UDT || \
+ x==TDS_DATA_TYPE_TEXT || \
+ x==TDS_DATA_TYPE_IMAGE || \
+ x==TDS_DATA_TYPE_NTEXT || \
+ x==TDS_DATA_TYPE_SSVARIANT \
+ )
+
+#define TDS_GEN_NULL 0x00U
+#define TDS_CHARBIN_NULL 0xFFFFU
+#define TDS_CHARBIN_NULL32 0xFFFFFFFFU
+
+#define TDS_PLP_TERMINATOR G_GUINT64_CONSTANT(0x0000000000000000)
+#define TDS_UNKNOWN_PLP_LEN G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFE)
+#define TDS_PLP_NULL G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)
static const value_string tds_data_type_names[] = {
/* FIXEDLENTYPE */
@@ -364,7 +423,7 @@ static const value_string tds_data_type_names[] = {
{TDS_DATA_TYPE_BIT, "BITTYPE - Bit (1 byte data representation)"},
{TDS_DATA_TYPE_INT2, "INT2TYPE - SmallInt (2 byte data representation)"},
{TDS_DATA_TYPE_INT4, "INT4TYPE - Int (4 byte data representation)"},
- {TDS_DATA_TYPE_DATETIM4, "DATETIM4TYPE - SmallDateTime (4 byte data representation)"},
+ {TDS_DATA_TYPE_DATETIME4, "DATETIME4TYPE - SmallDateTime (4 byte data representation)"},
{TDS_DATA_TYPE_FLT4, "FLT4TYPE - Real (4 byte data representation)"},
{TDS_DATA_TYPE_MONEY, "MONEYTYPE - Money (8 byte data representation)"},
{TDS_DATA_TYPE_DATETIME, "DATETIMETYPE - DateTime (8 byte data representation)"},
@@ -410,55 +469,259 @@ static const value_string tds_data_type_names[] = {
void proto_reg_handoff_tds(void);
void proto_register_tds(void);
-/* Initialize the protocol and registered fields */
-static int proto_tds = -1;
-static int hf_tds_type = -1;
-static int hf_tds_status = -1;
-static int hf_tds_status_eom = -1;
-static int hf_tds_status_ignore = -1;
-static int hf_tds_status_event_notif = -1;
-static int hf_tds_status_reset_conn = -1;
-static int hf_tds_status_reset_conn_skip_tran = -1;
-static int hf_tds_length = -1;
-static int hf_tds_channel = -1;
-static int hf_tds_packet_number = -1;
-static int hf_tds_window = -1;
-static int hf_tds_reassembled_in = -1;
-static int hf_tds_reassembled_length = -1;
-static int hf_tds_fragments = -1;
-static int hf_tds_fragment = -1;
-static int hf_tds_fragment_overlap = -1;
-static int hf_tds_fragment_overlap_conflict = -1;
-static int hf_tds_fragment_multiple_tails = -1;
-static int hf_tds_fragment_too_long_fragment = -1;
-static int hf_tds_fragment_error = -1;
-static int hf_tds_fragment_count = -1;
-static int hf_tds_collate_codepage = -1;
-static int hf_tds_collate_flags = -1;
-static int hf_tds_collate_charset_id = -1;
-static int hf_tds_table_name = -1;
-static int hf_tds_text = -1;
-
-static int hf_tds7_login_total_size = -1;
-static int hf_tds7_version = -1;
-static int hf_tds7_packet_size = -1;
-static int hf_tds7_client_version = -1;
-static int hf_tds7_client_pid = -1;
-static int hf_tds7_connection_id = -1;
-static int hf_tds7_option_flags1 = -1;
-static int hf_tds7_option_flags2 = -1;
-static int hf_tds7_sql_type_flags = -1;
-static int hf_tds7_reserved_flags = -1;
-static int hf_tds7_time_zone = -1;
-static int hf_tds7_collation = -1;
-static int hf_tds7_loginack_version = -1;
+/************************ Message definitions ***********************/
+
+/* Bulk Load BCP stream */
+
+/* Bulk Load Update Text/Write Text */
+
+/* Federated Authentication Token */
+
+/* LOGIN7 Token */
+static int hf_tds7login_total_size = -1;
+static int hf_tds7login_version = -1;
+static int hf_tds7login_packet_size = -1;
+static int hf_tds7login_client_version = -1;
+static int hf_tds7login_client_pid = -1;
+static int hf_tds7login_connection_id = -1;
+static int hf_tds7login_option_flags1 = -1;
+static int hf_tds7login_option_flags2 = -1;
+static int hf_tds7login_sql_type_flags = -1;
+static int hf_tds7login_reserved_flags = -1;
+static int hf_tds7login_time_zone = -1;
+static int hf_tds7login_collation = -1;
+static int hf_tds7login_offset = -1;
+static int hf_tds7login_length = -1;
+static int hf_tds7login_password = -1;
+
+/* PRELOGIN stream */
+static int hf_tds_prelogin = -1;
+static int hf_tds_prelogin_option_token = -1;
+static int hf_tds_prelogin_option_offset = -1;
+static int hf_tds_prelogin_option_length = -1;
+static int hf_tds_prelogin_option_version = -1;
+static int hf_tds_prelogin_option_subbuild = -1;
+static int hf_tds_prelogin_option_encryption = -1;
+static int hf_tds_prelogin_option_instopt = -1;
+static int hf_tds_prelogin_option_threadid = -1;
+static int hf_tds_prelogin_option_mars = -1;
+static int hf_tds_prelogin_option_traceid = -1;
+static int hf_tds_prelogin_option_fedauthrequired = -1;
+static int hf_tds_prelogin_option_nonceopt = -1;
+
+/* RPC Request Stream */
+static int hf_tds_rpc = -1;
+static int hf_tds_rpc_name_length8 = -1;
+static int hf_tds_rpc_name_length = -1;
+static int hf_tds_rpc_name = -1;
+static int hf_tds_rpc_proc_id = -1;
+static int hf_tds_rpc_options = -1;
+static int hf_tds_rpc_options_with_recomp = -1;
+static int hf_tds_rpc_options_no_metadata = -1;
+static int hf_tds_rpc_options_reuse_metadata = -1;
+static int hf_tds_rpc_separator = -1;
+static int hf_tds_rpc_parameter = -1;
+static int hf_tds_rpc_parameter_name_length = -1;
+static int hf_tds_rpc_parameter_name = -1;
+static int hf_tds_rpc_parameter_status = -1;
+static int hf_tds_rpc_parameter_status_by_ref = -1;
+static int hf_tds_rpc_parameter_status_default = -1;
+static int hf_tds_rpc_parameter_value = -1;
-static int hf_tds_all_headers = -1;
-static int hf_tds_all_headers_total_length = -1;
-static int hf_tds_all_headers_header_length = -1;
-static int hf_tds_all_headers_header_type = -1;
-static int hf_tds_all_headers_trans_descr = -1;
-static int hf_tds_all_headers_request_cnt = -1;
+/* SQLBatch Stream */
+static int hf_tds_query = -1;
+
+/* SSPI Message Stream */
+
+/* Transaction Manager Request Stream */
+static int hf_tds_transmgr = -1;
+static int hf_tds_transmgr_payload = -1;
+
+/************************ Token definitions ************************/
+
+/* ALTMETADATA token */
+
+/* ALTROW token */
+
+/* COLINFO token (TDS_COL_INFO_TOKEN) */
+static int hf_tds_colinfo = -1;
+
+/* COLMETADATA token (TDS7_COL_METADATA_TOKEN) */
+static int hf_tds_colmetadata = -1;
+static int hf_tds_colmetadata_results_token_flags = -1;
+static int hf_tds_colmetadata_columns = -1;
+static int hf_tds_colmetadata_large_type_size = -1;
+static int hf_tds_colmetadata_usertype32 = -1;
+static int hf_tds_colmetadata_usertype16 = -1;
+static int hf_tds_colmetadata_results_token_type = -1;
+static int hf_tds_colmetadata_collate_codepage = -1;
+static int hf_tds_colmetadata_collate_flags = -1;
+static int hf_tds_colmetadata_collate_charset_id = -1;
+static int hf_tds_colmetadata_colname = -1;
+static int hf_tds_colmetadata_colname_length = -1;
+static int hf_tds_colmetadata_table_name_parts = -1;
+static int hf_tds_colmetadata_table_name = -1;
+static int hf_tds_colmetadata_table_name_length = -1;
+static int hf_tds_colmetadata_csize = -1;
+static int hf_tds_colmetadata_precision = -1;
+static int hf_tds_colmetadata_scale = -1;
+static int hf_tds_colmetadata_field = -1;
+static int hf_tds_colmetadata_flags_nullable = -1;
+static int hf_tds_colmetadata_flags_updateable = -1;
+static int hf_tds_colmetadata_flags_casesen = -1;
+static int hf_tds_colmetadata_flags_identity = -1;
+static int hf_tds_colmetadata_flags_computed = -1;
+static int hf_tds_colmetadata_flags_reservedodbc = -1;
+static int hf_tds_colmetadata_flags_sparsecolumnset = -1;
+static int hf_tds_colmetadata_flags_encrypted = -1;
+static int hf_tds_colmetadata_flags_fixedlenclrtype = -1;
+static int hf_tds_colmetadata_flags_hidden = -1;
+static int hf_tds_colmetadata_flags_key = -1;
+static int hf_tds_colmetadata_flags_nullableunknown = -1;
+static int hf_tds_colmetadata_maxbytesize = -1;
+static int hf_tds_colmetadata_dbname_length = -1;
+static int hf_tds_colmetadata_dbname = -1;
+static int hf_tds_colmetadata_schemaname_length = -1;
+static int hf_tds_colmetadata_schemaname = -1;
+static int hf_tds_colmetadata_typename_length = -1;
+static int hf_tds_colmetadata_typename = -1;
+static int hf_tds_colmetadata_assemblyqualifiedname_length = -1;
+static int hf_tds_colmetadata_assemblyqualifiedname = -1;
+static int hf_tds_colmetadata_owningschema_length = -1;
+static int hf_tds_colmetadata_owningschema = -1;
+static int hf_tds_colmetadata_xmlschemacollection_length = -1;
+static int hf_tds_colmetadata_xmlschemacollection = -1;
+
+/* DONE token (TDS_DONE_TOKEN) */
+static int hf_tds_done = -1;
+static int hf_tds_done_curcmd = -1;
+static int hf_tds_done_status = -1;
+static int hf_tds_done_donerowcount_32 = -1;
+static int hf_tds_done_donerowcount_64 = -1;
+
+/* DONEPROC token (TDS_DONEPROC_TOKEN) */
+static int hf_tds_doneproc = -1;
+static int hf_tds_doneproc_curcmd = -1;
+static int hf_tds_doneproc_status = -1;
+static int hf_tds_doneproc_donerowcount_32 = -1;
+static int hf_tds_doneproc_donerowcount_64 = -1;
+
+/* DONEINPROC token () */
+static int hf_tds_doneinproc = -1;
+static int hf_tds_doneinproc_curcmd = -1;
+static int hf_tds_doneinproc_status = -1;
+static int hf_tds_doneinproc_donerowcount_32 = -1;
+static int hf_tds_doneinproc_donerowcount_64 = -1;
+
+/* ENVCHANGE token (TDS_ENVCHG_TOKEN) */
+static int hf_tds_envchg = -1;
+static int hf_tds_envchg_length = -1;
+static int hf_tds_envchg_type = -1;
+static int hf_tds_envchg_oldvalue_length = -1;
+static int hf_tds_envchg_newvalue_length = -1;
+static int hf_tds_envchg_oldvalue_string = -1;
+static int hf_tds_envchg_newvalue_string = -1;
+static int hf_tds_envchg_oldvalue_bytes = -1;
+static int hf_tds_envchg_newvalue_bytes = -1;
+static int hf_tds_envchg_collate_codepage = -1;
+static int hf_tds_envchg_collate_flags = -1;
+static int hf_tds_envchg_collate_charset_id = -1;
+
+/* ERROR token (TDS_ERR_TOKEN) */
+static int hf_tds_error = -1;
+static int hf_tds_error_length = -1;
+static int hf_tds_error_number = -1;
+static int hf_tds_error_state = -1;
+static int hf_tds_error_class = -1;
+static int hf_tds_error_msgtext_length = -1;
+static int hf_tds_error_msgtext = -1;
+static int hf_tds_error_servername_length = -1;
+static int hf_tds_error_servername = -1;
+static int hf_tds_error_procname_length = -1;
+static int hf_tds_error_procname = -1;
+static int hf_tds_error_linenumber_32 = -1;
+static int hf_tds_error_linenumber_16 = -1;
+
+/* FEATUREEXTACK token (TDS_FEATUREEXTACK_TOKEN) */
+static int hf_tds_featureextack = -1;
+static int hf_tds_featureextack_feature = -1;
+static int hf_tds_featureextack_featureid = -1;
+static int hf_tds_featureextack_featureackdata = -1;
+static int hf_tds_featureextack_featureackdatalen = -1;
+
+/* FEDAUTHINFO token */
+
+/* INFO token */
+static int hf_tds_info = -1;
+static int hf_tds_info_length = -1;
+static int hf_tds_info_number = -1;
+static int hf_tds_info_state = -1;
+static int hf_tds_info_class = -1;
+static int hf_tds_info_msgtext_length = -1;
+static int hf_tds_info_msgtext = -1;
+static int hf_tds_info_servername_length = -1;
+static int hf_tds_info_servername = -1;
+static int hf_tds_info_procname_length = -1;
+static int hf_tds_info_procname = -1;
+static int hf_tds_info_linenumber_32 = -1;
+static int hf_tds_info_linenumber_16 = -1;
+
+/* LOGINACK token (TDS_LOGIN_ACK_TOKEN) */
+static int hf_tds_loginack = -1;
+static int hf_tds_loginack_length = -1;
+static int hf_tds_loginack_interface = -1;
+static int hf_tds_loginack_tdsversion = -1;
+static int hf_tds_loginack_progversion = -1;
+static int hf_tds_loginack_progname = -1;
+
+/* NBCROW token (TDS_NBCROW_TOKEN) */
+static int hf_tds_nbcrow = -1;
+
+/* OFFSET token */
+static int hf_tds_offset = -1;
+static int hf_tds_offset_id = -1;
+static int hf_tds_offset_len = -1;
+
+/* ORDER token (TDS_ORDER_TOKEN) */
+static int hf_tds_order = -1;
+static int hf_tds_order_length = -1;
+static int hf_tds_order_colnum = -1;
+
+/* RETURNSTATUS token (TDS_RET_STAT_TOKEN) */
+static int hf_tds_returnstatus = -1;
+static int hf_tds_returnstatus_value = -1;
+
+/* RETURNVALUE token (TDS_RETURNVAL_TOKEN) */
+
+/* ROW token (TDS_ROW_TOKEN) */
+static int hf_tds_row = -1;
+static int hf_tds_row_field = -1;
+
+/* SESSIONSTATE token (TDS_SESSIONSTATE_TOKEN) */
+static int hf_tds_sessionstate = -1;
+static int hf_tds_sessionstate_length = -1;
+static int hf_tds_sessionstate_seqno = -1;
+static int hf_tds_sessionstate_status = -1;
+static int hf_tds_sessionstate_stateid = -1;
+static int hf_tds_sessionstate_statelen = -1;
+static int hf_tds_sessionstate_statevalue = -1;
+
+/* SSPI token */
+static int hf_tds_sspi = -1;
+static int hf_tds_sspi_buffer = -1;
+
+/* TABNAME token */
+
+/* TVPROW Token */
+
+/* TDS5 Lang Token */
+static int hf_tds_lang_language_text = -1;
+static int hf_tds_lang_token_status = -1;
+
+/* Unknown token */
+static int hf_tds_unknown_tds_token = -1;
+
+/*********************** Basic types *******************************/
static int hf_tds_type_info = -1;
static int hf_tds_type_info_type = -1;
@@ -486,68 +749,43 @@ static int hf_tds_type_varbyte_data_double = -1;
static int hf_tds_type_varbyte_data_bytes = -1;
static int hf_tds_type_varbyte_data_guid = -1;
static int hf_tds_type_varbyte_data_string = -1;
+static int hf_tds_type_varbyte_data_absdatetime = -1;
+static int hf_tds_type_varbyte_data_reltime = -1;
+static int hf_tds_type_varbyte_data_sign = -1;
static int hf_tds_type_varbyte_plp_len = -1;
static int hf_tds_type_varbyte_plp_chunk_len = -1;
-static int hf_tds_rpc = -1;
-static int hf_tds_rpc_name_length8 = -1;
-static int hf_tds_rpc_name_length = -1;
-static int hf_tds_rpc_name = -1;
-static int hf_tds_rpc_proc_id = -1;
-static int hf_tds_rpc_options = -1;
-static int hf_tds_rpc_options_with_recomp = -1;
-static int hf_tds_rpc_options_no_metadata = -1;
-static int hf_tds_rpc_options_reuse_metadata = -1;
-static int hf_tds_rpc_separator = -1;
-static int hf_tds_rpc_parameter = -1;
-static int hf_tds_rpc_parameter_name_length = -1;
-static int hf_tds_rpc_parameter_name = -1;
-static int hf_tds_rpc_parameter_status = -1;
-static int hf_tds_rpc_parameter_status_by_ref = -1;
-static int hf_tds_rpc_parameter_status_default = -1;
-static int hf_tds_rpc_parameter_value = -1;
+/****************************** Top level TDS ******************************/
-/* Generated from convert_proto_tree_add_text.pl */
-static int hf_tds_unknown_bytes_3 = -1;
-static int hf_tds_results_token_flags = -1;
-static int hf_tds_process_name = -1;
-static int hf_tds_columns = -1;
-static int hf_tds_severity_level = -1;
-static int hf_tds_server_name = -1;
-static int hf_tds_tds_packet = -1;
-static int hf_tds_new_value = -1;
-static int hf_tds_text_length = -1;
-static int hf_tds_done_token_status_flags = -1;
-static int hf_tds_large_type_size = -1;
-static int hf_tds_usertype32 = -1;
-static int hf_tds_usertype16 = -1;
-static int hf_tds_language_text = -1;
-static int hf_tds_row_count32 = -1;
-static int hf_tds_error_message_length = -1;
-static int hf_tds_error = -1;
-static int hf_tds_sql_error_number = -1;
-static int hf_tds_new_value_length = -1;
-static int hf_tds_old_value = -1;
-static int hf_tds_operation = -1;
-static int hf_tds_ack = -1;
-static int hf_tds_unknown_bytes_1 = -1;
-static int hf_tds_results_token_type = -1;
-static int hf_tds_env_chg_type = -1;
-static int hf_tds_lang_token_status = -1;
-static int hf_tds_unknown_bytes_4 = -1;
-static int hf_tds_old_value_length = -1;
-static int hf_tds_message_length = -1;
-static int hf_tds_server_version = -1;
-static int hf_tds_row_count64 = -1;
-static int hf_tds_line_number32 = -1;
-static int hf_tds_query = -1;
-static int hf_tds_server_name_length = -1;
-static int hf_tds_state = -1;
-static int hf_tds_line_number16 = -1;
-static int hf_tds_process_name_length = -1;
-static int hf_tds_login_offset = -1;
-static int hf_tds_login_length = -1;
-static int hf_tds_login_password = -1;
+static int proto_tds = -1;
+static int hf_tds_type = -1;
+static int hf_tds_status = -1;
+static int hf_tds_status_eom = -1;
+static int hf_tds_status_ignore = -1;
+static int hf_tds_status_event_notif = -1;
+static int hf_tds_status_reset_conn = -1;
+static int hf_tds_status_reset_conn_skip_tran = -1;
+static int hf_tds_length = -1;
+static int hf_tds_channel = -1;
+static int hf_tds_packet_number = -1;
+static int hf_tds_window = -1;
+static int hf_tds_reassembled_in = -1;
+static int hf_tds_reassembled_length = -1;
+static int hf_tds_fragments = -1;
+static int hf_tds_fragment = -1;
+static int hf_tds_fragment_overlap = -1;
+static int hf_tds_fragment_overlap_conflict = -1;
+static int hf_tds_fragment_multiple_tails = -1;
+static int hf_tds_fragment_too_long_fragment = -1;
+static int hf_tds_fragment_error = -1;
+static int hf_tds_fragment_count = -1;
+static int hf_tds_all_headers = -1;
+static int hf_tds_all_headers_total_length = -1;
+static int hf_tds_all_headers_header_length = -1;
+static int hf_tds_all_headers_header_type = -1;
+static int hf_tds_all_headers_trans_descr = -1;
+static int hf_tds_all_headers_request_cnt = -1;
+static int hf_tds_unknown_tds_packet = -1;
static int hf_tds_token_len = -1;
/* Initialize the subtree pointers */
@@ -566,9 +804,14 @@ static gint ett_tds_rpc_options = -1;
static gint ett_tds_rpc_parameter = -1;
static gint ett_tds_rpc_parameter_status = -1;
static gint ett_tds7_query = -1;
+static gint ett_tds7_prelogin = -1;
static gint ett_tds7_login = -1;
static gint ett_tds7_hdr = -1;
static gint ett_tds_col = -1;
+static gint ett_tds_flags = -1;
+static gint ett_tds_prelogin_option = -1;
+static gint ett_tds7_featureextack = -1;
+static gint ett_tds7_featureextack_feature = -1;
static expert_field ei_tds_type_info_type_undecoded = EI_INIT;
static expert_field ei_tds_invalid_length = EI_INIT;
@@ -576,6 +819,7 @@ static expert_field ei_tds_token_length_invalid = EI_INIT;
static expert_field ei_tds_type_info_type = EI_INIT;
static expert_field ei_tds_all_headers_header_type = EI_INIT;
static expert_field ei_tds_token_stats = EI_INIT;
+static expert_field ei_tds_invalid_plp_type = EI_INIT;
/* Desegmentation of Netlib buffers crossing TCP segment boundaries. */
static gboolean tds_desegment = TRUE;
@@ -605,7 +849,6 @@ static reassembly_table tds_reassembly_table;
static gboolean tds_defragment = TRUE;
static dissector_handle_t tds_tcp_handle;
-
static dissector_handle_t ntlmssp_handle;
static dissector_handle_t gssapi_handle;
static dissector_handle_t data_handle;
@@ -620,13 +863,16 @@ typedef struct {
/* TODO: Consider storing protocol type with each conversation */
/* (when type is determined and using the preference as a default) ?? */
-#define TDS_PROTOCOL_NOT_SPECIFIED 0
-#define TDS_PROTOCOL_4 0x40
-#define TDS_PROTOCOL_5 0x50
-#define TDS_PROTOCOL_7_0 0x70
-#define TDS_PROTOCOL_7_1 0x71
-#define TDS_PROTOCOL_7_2 0x72
-#define TDS_PROTOCOL_7_3 0x73
+#define TDS_PROTOCOL_NOT_SPECIFIED 0xFFFF
+#define TDS_PROTOCOL_4 0x4000
+#define TDS_PROTOCOL_5 0x5000
+#define TDS_PROTOCOL_7_0 0x7000
+#define TDS_PROTOCOL_7_1 0x7100
+#define TDS_PROTOCOL_7_2 0x7200
+#define TDS_PROTOCOL_7_3 0x7300
+#define TDS_PROTOCOL_7_3A 0x730a
+#define TDS_PROTOCOL_7_3B 0x730b
+#define TDS_PROTOCOL_7_4 0x7400
static gint tds_protocol_type = TDS_PROTOCOL_NOT_SPECIFIED;
@@ -638,6 +884,9 @@ static const enum_val_t tds_protocol_type_options[] = {
{"tds71", "TDS 7.1", TDS_PROTOCOL_7_1},
{"tds72", "TDS 7.2", TDS_PROTOCOL_7_2},
{"tds73", "TDS 7.3", TDS_PROTOCOL_7_3},
+ {"tds73a", "TDS 7.3A", TDS_PROTOCOL_7_3A},
+ {"tds73b", "TDS 7.3B", TDS_PROTOCOL_7_3B},
+ {"tds74", "TDS 7.4", TDS_PROTOCOL_7_4},
{NULL, NULL, -1}
};
@@ -648,13 +897,24 @@ static const enum_val_t tds_protocol_type_options[] = {
#define TDS_PROTO_PREF_TDS7_1 (tds_protocol_type == TDS_PROTOCOL_7_1)
#define TDS_PROTO_PREF_TDS7_2 (tds_protocol_type == TDS_PROTOCOL_7_2)
#define TDS_PROTO_PREF_TDS7_3 (tds_protocol_type == TDS_PROTOCOL_7_3)
-#define TDS_PROTO_PREF_TDS7 (tds_protocol_type >= TDS_PROTOCOL_7_0 && tds_protocol_type <= TDS_PROTOCOL_7_3)
+#define TDS_PROTO_PREF_TDS7_3A (tds_protocol_type == TDS_PROTOCOL_7_3A)
+#define TDS_PROTO_PREF_TDS7_3B (tds_protocol_type == TDS_PROTOCOL_7_3B)
+#define TDS_PROTO_PREF_TDS7_4 (tds_protocol_type == TDS_PROTOCOL_7_4)
+#define TDS_PROTO_PREF_TDS7 (tds_protocol_type >= TDS_PROTOCOL_7_0 && tds_protocol_type <= TDS_PROTOCOL_7_4)
#define TDS_PROTO_TDS4 TDS_PROTO_PREF_TDS4
#define TDS_PROTO_TDS7 (TDS_PROTO_PREF_TDS7 || \
(TDS_PROTO_PREF_NOT_SPECIFIED && (tds_info->tds7_version != TDS_PROTOCOL_NOT_SPECIFIED)))
+#define TDS_PROTO_TDS7_1_OR_LESS ((tds_protocol_type <= TDS_PROTOCOL_7_1) || \
+ (TDS_PROTO_PREF_NOT_SPECIFIED && (tds_info->tds7_version <= TDS_PROTOCOL_7_1)))
#define TDS_PROTO_TDS7_2_OR_GREATER ((tds_protocol_type >= TDS_PROTOCOL_7_2) || \
(TDS_PROTO_PREF_NOT_SPECIFIED && (tds_info->tds7_version >= TDS_PROTOCOL_7_2)))
+#define TDS_PROTO_TDS7_3A_OR_LESS ((tds_protocol_type <= TDS_PROTOCOL_7_3A) || \
+ (TDS_PROTO_PREF_NOT_SPECIFIED && (tds_info->tds7_version <= TDS_PROTOCOL_7_3A)))
+#define TDS_PROTO_TDS7_3B_OR_GREATER ((tds_protocol_type >= TDS_PROTOCOL_7_3B) || \
+ (TDS_PROTO_PREF_NOT_SPECIFIED && (tds_info->tds7_version >= TDS_PROTOCOL_7_3B)))
+#define TDS_PROTO_TDS7_4_OR_GREATER ((tds_protocol_type >= TDS_PROTOCOL_7_4) || \
+ (TDS_PROTO_PREF_NOT_SPECIFIED && (tds_info->tds7_version >= TDS_PROTOCOL_7_4)))
/* TDS "endian type" */
/* XXX: Assumption is that all TDS conversations being decoded in a particular capture */
@@ -671,22 +931,29 @@ static const enum_val_t tds_endian_type_options[] = {
};
/* TCP port preferences for TDS decode */
-
static range_t *tds_tcp_ports = NULL;
/* These correspond to the netlib packet type field */
static const value_string packet_type_names[] = {
- {TDS_QUERY_PKT, "SQL batch"},
- {TDS_LOGIN_PKT, "Pre-TDS7 login"},
- {TDS_RPC_PKT, "Remote Procedure Call"},
- {TDS_RESP_PKT, "Response"},
- {TDS_RAW_PKT, "Unused"},
- {TDS_ATTENTION_PKT, "Attention"},
- {TDS_BULK_DATA_PKT, "Bulk load data"},
- {TDS_QUERY5_PKT, "TDS5 query"},
- {TDS_LOGIN7_PKT, "TDS7 login"},
- {TDS_SSPI_PKT, "SSPI message"},
- {TDS_PRELOGIN_PKT, "TDS7 pre-login message"},
+ {TDS_QUERY_PKT, "SQL batch"},
+ {TDS_LOGIN_PKT, "Pre-TDS7 login"},
+ {TDS_RPC_PKT, "Remote Procedure Call"},
+ {TDS_RESP_PKT, "Response"},
+ {TDS_RAW_PKT, "Unused"},
+ {TDS_ATTENTION_PKT, "Attention"},
+ {TDS_BULK_DATA_PKT, "Bulk load data"},
+ {TDS_OPEN_CHN_PKT, "Unused"},
+ {TDS_CLOSE_CHN_PKT, "Unused"},
+ {TDS_RES_ERROR_PKT, "Unused"},
+ {TDS_LOG_CHN_ACK_PKT, "Unused"},
+ {TDS_ECHO_PKT, "Unused"},
+ {TDS_LOGOUT_CHN_PKT, "Unused"},
+ {TDS_TRANS_MGR_PKT, "Transaction Manager Request"},
+ {TDS_QUERY5_PKT, "TDS5 query"},
+ {TDS_LOGIN7_PKT, "TDS7 login"},
+ {TDS_SSPI_PKT, "SSPI message"},
+ {TDS_PRELOGIN_PKT, "TDS7 pre-login message"},
+ {TDS_TLS_PKT, "TLS exchange"},
{0, NULL}
};
@@ -702,7 +969,6 @@ static const value_string header_type_names[] = {
};
/* The status field */
-
#define is_valid_tds_status(x) ((x) <= STATUS_EVENT_NOTIFICATION)
#define STATUS_LAST_BUFFER 0x01
@@ -721,22 +987,18 @@ static const value_string token_names[] = {
{TDS_LOGOUT_TOKEN, "Logout"},
{TDS_RET_STAT_TOKEN, "Return Status"},
{TDS_PROCID_TOKEN, "Proc ID"},
- {TDS7_RESULT_TOKEN, "TDS7+ Results"},
{TDS_COL_NAME_TOKEN, "Column Names"},
{TDS_COL_INFO_TOKEN, "Column Info"},
{TDS_COMPUTE_NAMES_TOKEN, "Compute Names"},
{TDS_COMPUTE_RESULT_TOKEN, "Compute Results"},
- {TDS_ORDER_BY_TOKEN, "Order By"},
+ {TDS_ORDER_TOKEN, "Order"},
{TDS_ERR_TOKEN, "Error Message"},
- {TDS_MSG_TOKEN, "Info Message"},
- {TDS_PARAM_TOKEN, "Parameter"},
+ {TDS_INFO_TOKEN, "Info Message"},
{TDS_LOGIN_ACK_TOKEN, "Login Acknowledgement"},
- {TDS_CONTROL_TOKEN, "TDS Control"},
{TDS_KEY_TOKEN, "TDS Key"},
{TDS_ROW_TOKEN, "Row"},
- {TDS_CMP_ROW_TOKEN, "Compute Row"},
{TDS_CAP_TOKEN, "Capabilities"},
- {TDS_ENV_CHG_TOKEN, "Environment Change"},
+ {TDS_ENVCHG_TOKEN, "Environment Change"},
{TDS_EED_TOKEN, "Extended Error"},
{TDS_AUTH_TOKEN, "Authentication"},
{TDS_RESULT_TOKEN, "Results"},
@@ -748,6 +1010,25 @@ static const value_string token_names[] = {
{TDS5_CURDECLARE2_TOKEN, "TDS5 CurDeclare2"},
{TDS5_ROWFMT2_TOKEN, "TDS5 RowFmt2"},
{TDS5_MSG_TOKEN, "TDS5 Msg"},
+ {TDS_OFFSET_TOKEN, "Offset"},
+ {TDS_CURCLOSE_TOKEN, "CurClose"},
+ {TDS7_COL_METADATA_TOKEN, "Column Metadata"},
+ {TDS_CURFETCH_TOKEN, "CurFetch"},
+ {TDS_CURINFO_TOKEN, "CurInfo"},
+ {TDS_CUROPEN_TOKEN, "CurOpen"},
+ {TDS_CURDECLARE_TOKEN, "CurDeclare"},
+ {TDS7_ALTMETADATA_TOKEN, "AltMetaData"},
+ {TDS_TABNAME_TOKEN, "Table Name"},
+ {TDS7_COL_INFO_TOKEN, "Column Info"},
+ {TDS_OPTIONCMD_TOKEN, "OptionCmd"},
+ {TDS_RETURNVAL_TOKEN, "Return Value"},
+ {TDS_FEATUREEXTACK_TOKEN, "FeatureExt Acknowledgement"},
+ {TDS_NBCROW_TOKEN, "Row (with Null Bitmap Compression)"},
+ {TDS_ALTROW_TOKEN, "ALTROW"},
+ {TDS_SESSIONSTATE_TOKEN, "Session State"},
+ {TDS_DBRPC_TOKEN, "DBRPC"},
+ {TDS_SSPI_TOKEN, "SSPI"},
+ {TDS_FEDAUTHINFO_TOKEN, "FEDAUTHINFO"},
{0, NULL}
};
@@ -778,18 +1059,30 @@ static const value_string internal_stored_proc_id_names[] = {
{TDS_SP_PREPEXEC, "sp_prepexec" },
{TDS_SP_PREPEXECRPC, "sp_prepexecrpc" },
{TDS_SP_UNPREPARE, "sp_unprepare" },
- {0, NULL },
+ {0, NULL }
};
-static const value_string env_chg_names[] = {
+static const value_string envchg_names[] = {
{1, "Database"},
{2, "Language"},
- {3, "Sort Order"},
- {4, "Blocksize"},
- {5, "Unicode Locale ID"},
- {6, "Unicode Comparison Style"},
- {7, "Collation Info"},
- {0, NULL},
+ {3, "Character set"},
+ {4, "Packet size"},
+ {5, "Unicode data sorting local id"},
+ {6, "Unicode data sorting comparison flags"},
+ {7, "SQL Collation"},
+ {8, "Begin Transaction"},
+ {9, "Commit Transaction"},
+ {10, "Rollback Transaction"},
+ {11, "Enlist DTC Transaction"},
+ {12, "Defect Transaction"},
+ {13, "Real Time Log Shipping"},
+ {15, "Promote Transaction"},
+ {16, "Transaction Manager Address"},
+ {17, "Transaction ended"},
+ {18, "RESETCONNECTION/RESETCONNECTIONSKIPTRAN Completion Acknowledgement"},
+ {19, "Sends back name of user instance started per login request"},
+ {20, "Sends routing information to client"},
+ {0, NULL}
};
static const value_string login_field_names[] = {
@@ -802,11 +1095,50 @@ static const value_string login_field_names[] = {
{6, "Library Name"},
{7, "Locale"},
{8, "Database Name"},
- {0, NULL},
+ {0, NULL}
+};
+
+static const value_string prelogin_token_names[] = {
+ {0, "Version"},
+ {1, "Encryption"},
+ {2, "InstOpt"},
+ {3, "ThreadID"},
+ {4, "MARS"},
+ {5, "TraceID"},
+ {6, "FedAuthRequired"},
+ {7, "NonceOpt"},
+ {255, "Terminator"},
+ {0, NULL}
+};
+
+static const value_string featureextack_feature_names[] = {
+ {0, "Reserved"},
+ {1, "SessionRecovery"},
+ {2, "FedAuth"},
+ {255, "Terminator"},
+ {0, NULL}
+};
+
+static const value_string transmgr_types[] = {
+ {0, "TM_GET_DTC_ADDRESS"},
+ {1, "TM_PROPAGATE_XACT"},
+ {5, "TM_BEGIN_XACT"},
+ {6, "TM_PROMOTE_XACT"},
+ {7, "TM_COMMIT_XACT"},
+ {8, "TM_ROLLBACK_XACT"},
+ {9, "TM_SAVE_XACT"},
+ {0, NULL}
};
+static const value_string prelogin_encryption_options[] = {
+ {0, "Encryption is available but off"},
+ {1, "Encryption is available and on"},
+ {2, "Encryption is not available"},
+ {3, "Encryption is required"},
+ {0, NULL}
+};
-#define MAX_COLUMNS 256
+#define TDS_MAX_COLUMNS 256
/*
* This is where we store the column information to be used in decoding the
@@ -814,14 +1146,16 @@ static const value_string login_field_names[] = {
*/
struct _tds_col {
gchar name[256];
- guint16 utype;
+ guint32 utype;
guint8 ctype;
+ guint8 precision;
+ guint8 scale;
guint csize;
};
struct _netlib_data {
guint num_cols;
- struct _tds_col *columns[MAX_COLUMNS];
+ struct _tds_col *columns[TDS_MAX_COLUMNS];
};
struct tds7_login_packet_hdr {
@@ -854,24 +1188,6 @@ dissect_tds_nt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
call_dissector(gssapi_handle, nt_tvb, pinfo, tree);
}
-/* */
-
-static guint16
-tds_tvb_get_xxtohs(tvbuff_t *tvb, gint offset, gboolean tds_little_endian_flag) {
- if (tds_little_endian_flag)
- return tvb_get_letohs(tvb, offset);
- else
- return tvb_get_ntohs(tvb, offset);
-}
-
-static guint32
-tds_tvb_get_xxtohl(tvbuff_t *tvb, gint offset, gboolean tds_little_endian_flag) {
- if (tds_little_endian_flag)
- return tvb_get_letohl(tvb, offset);
- else
- return tvb_get_ntohl(tvb, offset);
-}
-
static int
tds_token_is_fixed_size(guint8 token)
{
@@ -880,16 +1196,15 @@ tds_token_is_fixed_size(guint8 token)
case TDS_DONEPROC_TOKEN:
case TDS_DONEINPROC_TOKEN:
case TDS_RET_STAT_TOKEN:
- case TDS7_RESULT_TOKEN:
case TDS_PROCID_TOKEN:
case TDS_LOGOUT_TOKEN:
+ case TDS_OFFSET_TOKEN:
return 1;
default:
return 0;
}
}
-
static int
tds_get_fixed_token_size(guint8 token, tds_conv_info_t *tds_info)
{
@@ -897,10 +1212,10 @@ tds_get_fixed_token_size(guint8 token, tds_conv_info_t *tds_info)
case TDS_DONE_TOKEN:
case TDS_DONEPROC_TOKEN:
case TDS_DONEINPROC_TOKEN:
- if (TDS_PROTO_TDS7_2_OR_GREATER) {
- return 12;
- } else {
+ if (TDS_PROTO_TDS7_1_OR_LESS) {
return 8;
+ } else {
+ return 12;
}
case TDS_PROCID_TOKEN:
return 8;
@@ -908,7 +1223,8 @@ tds_get_fixed_token_size(guint8 token, tds_conv_info_t *tds_info)
return 4;
case TDS_LOGOUT_TOKEN:
return 1;
- case TDS7_RESULT_TOKEN:
+ case TDS_OFFSET_TOKEN:
+ return 4;
default:
return 0;
}
@@ -918,6 +1234,8 @@ static guint
tds_get_variable_token_size(tvbuff_t *tvb, gint offset, guint8 token,
guint *len_field_size_p, guint *len_field_val_p)
{
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
+
switch(token) {
/* some tokens have a 4 byte length field */
case TDS5_PARAMFMT2_TOKEN:
@@ -926,8 +1244,9 @@ tds_get_variable_token_size(tvbuff_t *tvb, gint offset, guint8 token,
case TDS5_CURDECLARE2_TOKEN:
case TDS5_ROWFMT2_TOKEN:
case TDS5_DYNAMIC2_TOKEN:
+ case TDS_SESSIONSTATE_TOKEN:
*len_field_size_p = 4;
- *len_field_val_p = tds_tvb_get_xxtohl(tvb, offset, tds_little_endian);
+ *len_field_val_p = tvb_get_guint32(tvb, offset, encoding);
break;
/* some have a 1 byte length field */
case TDS5_MSG_TOKEN:
@@ -937,13 +1256,12 @@ tds_get_variable_token_size(tvbuff_t *tvb, gint offset, guint8 token,
/* and most have a 2 byte length field */
default:
*len_field_size_p = 2;
- *len_field_val_p = tds_tvb_get_xxtohs(tvb, offset, tds_little_endian);
+ *len_field_val_p = tvb_get_guint16(tvb, offset, encoding);
break;
}
return *len_field_val_p + *len_field_size_p + 1;
}
-
static void
dissect_tds_all_headers(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tree *tree)
{
@@ -971,9 +1289,8 @@ dissect_tds_all_headers(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_
guint32 header_length;
guint16 header_type;
- header_length = tvb_get_letohl(tvb, *offset);
header_sub_tree = proto_tree_add_subtree(sub_tree, tvb, *offset, header_length, ett_tds_all_headers_header, NULL, "Header");
- length_item = proto_tree_add_item(header_sub_tree, hf_tds_all_headers_header_length, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
+ length_item = proto_tree_add_item_ret_uint(header_sub_tree, hf_tds_all_headers_header_length, tvb, *offset, 4, ENC_LITTLE_ENDIAN, &header_length);
if(header_length == 0 ) {
expert_add_info_format(pinfo, length_item, &ei_tds_invalid_length, "Empty header");
break;
@@ -1003,13 +1320,11 @@ dissect_tds_all_headers(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_
}
}
-
static void
dissect_tds_query_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
{
guint offset, len;
guint string_encoding = ENC_UTF_16|ENC_LITTLE_ENDIAN;
-
proto_tree *query_tree;
offset = 0;
@@ -1026,19 +1341,43 @@ dissect_tds_query_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, td
/* offset += len; */
}
-
static void
dissect_tds5_lang_token(tvbuff_t *tvb, guint offset, guint len, proto_tree *tree) {
-
+
proto_tree_add_item(tree, hf_tds_lang_token_status, tvb, offset, 1, ENC_NA);
offset += 1;
len -= 1;
- proto_tree_add_item(tree, hf_tds_language_text, tvb, offset, len, ENC_ASCII|ENC_NA);
+ proto_tree_add_item(tree, hf_tds_lang_language_text, tvb, offset, len, ENC_ASCII|ENC_NA);
+}
+
+static void
+dissect_tds_transmgr_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_tree *request_tree;
+ proto_item *token_item;
+ guint offset = 0, len;
+ guint16 requesttype;
+
+ request_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_query, NULL, "Transaction Manager Request Packet");
+ dissect_tds_all_headers(tvb, &offset, pinfo, request_tree);
+ len = tvb_reported_length_remaining(tvb, offset);
+
+ if(len >= 2)
+ {
+ requesttype = tvb_get_letohs(tvb, offset);
+ token_item = proto_tree_add_item(request_tree, hf_tds_transmgr, tvb, offset, 2, ENC_NA);
+ proto_item_append_text(token_item, " (%s)", val_to_str(requesttype, transmgr_types, "Unknown"));
+
+ if(len > 2)
+ {
+ proto_tree_add_item(request_tree, hf_tds_transmgr_payload, tvb, offset + 2, len - 2, ENC_NA);
+ }
+ }
}
static void
-dissect_tds_query5_packet(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, tds_conv_info_t *tds_info)
+dissect_tds_query5_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
{
guint offset;
guint pos;
@@ -1099,6 +1438,105 @@ dissect_tds_query5_packet(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
} /* while */
}
+static int detect_tls(tvbuff_t *tvb)
+{
+ guint8 tls_type, tls_maj_ver, tls_min_ver;
+ gint offset = 0, tls_len;
+
+ tls_type = tvb_get_guint8(tvb, offset);
+ tls_maj_ver = tvb_get_guint8(tvb, offset + 1);
+ tls_min_ver = tvb_get_guint8(tvb, offset + 2);
+ tls_len = tvb_get_ntohs(tvb, offset + 3);
+
+ if( (tls_type >= 0x14) && (tls_type <= 0x18) &&
+ (tls_maj_ver == 3) && (tls_min_ver <= 3) &&
+ ((tls_len + 5 <= tvb_reported_length_remaining(tvb, offset)))
+ )
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+dissect_tds7_prelogin_packet(tvbuff_t *tvb, proto_tree *tree)
+{
+ guint8 token;
+ gint offset = 0;
+ guint16 tokenoffset, tokenlen;
+ proto_tree *prelogin_tree = NULL, *option_tree;
+ proto_item * ti;
+
+ if(detect_tls(tvb))
+ {
+ proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_prelogin, NULL, "TDS Pre-Login Packet - TLS exchange");
+ return;
+ }
+
+ prelogin_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_prelogin, NULL, "TDS Pre-Login Packet");
+
+ while(tvb_reported_length_remaining(tvb, offset) > 0)
+ {
+ token = tvb_get_guint8(tvb, offset);
+ option_tree = proto_tree_add_subtree(prelogin_tree, tvb, offset, token == 0xff ? 1 : 5, ett_tds_prelogin_option, NULL, "Option");
+ ti = proto_tree_add_item(option_tree, hf_tds_prelogin_option_token, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(ti, " (%s)", val_to_str(token, prelogin_token_names, "Unknown"));
+ offset += 1;
+
+ if(token == 0xff)
+ break;
+
+ tokenoffset = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ tokenlen = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ if(tokenlen != 0)
+ {
+ switch(token)
+ {
+ case 0: {
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_version, tvb, tokenoffset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_subbuild, tvb, tokenoffset + 4, 2, ENC_LITTLE_ENDIAN);
+ break;
+ }
+ case 1: {
+ ti = proto_tree_add_item(option_tree, hf_tds_prelogin_option_encryption, tvb, tokenoffset, tokenlen, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(ti, " (%s)", val_to_str(tvb_get_guint8(tvb, tokenoffset), prelogin_encryption_options, "Unknown value"));
+ break;
+ }
+ case 2: {
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_instopt, tvb, tokenoffset, tokenlen, ENC_ASCII | ENC_NA);
+ break;
+ }
+ case 3: {
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_threadid, tvb, tokenoffset, tokenlen, ENC_BIG_ENDIAN);
+ break;
+ }
+ case 4: {
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_mars, tvb, tokenoffset, tokenlen, ENC_LITTLE_ENDIAN);
+ break;
+ }
+ case 5: {
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_traceid, tvb, tokenoffset, tokenlen, ENC_NA);
+ break;
+ }
+ case 6: {
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_fedauthrequired, tvb, tokenoffset, tokenlen, ENC_LITTLE_ENDIAN);
+ break;
+ }
+ case 7: {
+ proto_tree_add_item(option_tree, hf_tds_prelogin_option_nonceopt, tvb, tokenoffset, tokenlen, ENC_NA);
+ break;
+ }
+ }
+ }
+ }
+}
static void
dissect_tds7_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -1113,59 +1551,49 @@ dissect_tds7_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
struct tds7_login_packet_hdr td7hdr;
gint length_remaining;
-
/* create display subtree for the protocol */
offset = 0;
login_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_login, NULL, "TDS7 Login Packet");
header_tree = proto_tree_add_subtree(login_tree, tvb, offset, 36, ett_tds7_hdr, NULL, "Login Packet Header");
- td7hdr.total_packet_size = tvb_get_letohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_login_total_size, tvb, offset,
- sizeof(td7hdr.total_packet_size), td7hdr.total_packet_size);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_total_size, tvb, offset, sizeof(td7hdr.total_packet_size), ENC_LITTLE_ENDIAN, &(td7hdr.total_packet_size));
offset += (int)sizeof(td7hdr.total_packet_size);
- td7hdr.tds_version = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_version, tvb, offset, sizeof(td7hdr.tds_version), td7hdr.tds_version);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_version, tvb, offset, sizeof(td7hdr.tds_version), ENC_LITTLE_ENDIAN, &(td7hdr.tds_version));
offset += (int)sizeof(td7hdr.tds_version);
- td7hdr.packet_size = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_packet_size, tvb, offset, sizeof(td7hdr.packet_size), td7hdr.packet_size);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_packet_size, tvb, offset, sizeof(td7hdr.packet_size), ENC_LITTLE_ENDIAN, &(td7hdr.packet_size));
offset += (int)sizeof(td7hdr.packet_size);
- td7hdr.client_version = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_client_version, tvb, offset, sizeof(td7hdr.client_version), td7hdr.client_version);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_client_version, tvb, offset, sizeof(td7hdr.client_version), ENC_LITTLE_ENDIAN, &(td7hdr.client_version));
offset += (int)sizeof(td7hdr.client_version);
- td7hdr.client_pid = tvb_get_letohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_client_pid, tvb, offset, sizeof(td7hdr.client_pid), td7hdr.client_pid);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_client_pid, tvb, offset, sizeof(td7hdr.client_pid), ENC_LITTLE_ENDIAN, &(td7hdr.client_pid));
offset += (int)sizeof(td7hdr.client_pid);
- td7hdr.connection_id= tvb_get_letohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_connection_id, tvb, offset, sizeof(td7hdr.connection_id), td7hdr.connection_id);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_connection_id, tvb, offset, sizeof(td7hdr.connection_id), ENC_LITTLE_ENDIAN, &(td7hdr.connection_id));
offset += (int)sizeof(td7hdr.connection_id);
td7hdr.option_flags1 = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_option_flags1, tvb, offset, sizeof(td7hdr.option_flags1), td7hdr.option_flags1);
+ proto_tree_add_uint(header_tree, hf_tds7login_option_flags1, tvb, offset, sizeof(td7hdr.option_flags1), td7hdr.option_flags1);
offset += (int)sizeof(td7hdr.option_flags1);
td7hdr.option_flags2 = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_option_flags2, tvb, offset, sizeof(td7hdr.option_flags2), td7hdr.option_flags2);
+ proto_tree_add_uint(header_tree, hf_tds7login_option_flags2, tvb, offset, sizeof(td7hdr.option_flags2), td7hdr.option_flags2);
offset += (int)sizeof(td7hdr.option_flags2);
td7hdr.sql_type_flags = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_sql_type_flags, tvb, offset, sizeof(td7hdr.sql_type_flags), td7hdr.sql_type_flags);
+ proto_tree_add_uint(header_tree, hf_tds7login_sql_type_flags, tvb, offset, sizeof(td7hdr.sql_type_flags), td7hdr.sql_type_flags);
offset += (int)sizeof(td7hdr.sql_type_flags);
td7hdr.reserved_flags = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_reserved_flags, tvb, offset, sizeof(td7hdr.reserved_flags), td7hdr.reserved_flags);
+ proto_tree_add_uint(header_tree, hf_tds7login_reserved_flags, tvb, offset, sizeof(td7hdr.reserved_flags), td7hdr.reserved_flags);
offset += (int)sizeof(td7hdr.reserved_flags);
- td7hdr.time_zone = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_time_zone, tvb, offset, sizeof(td7hdr.time_zone), td7hdr.time_zone);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_time_zone, tvb, offset, sizeof(td7hdr.time_zone), ENC_LITTLE_ENDIAN, &(td7hdr.time_zone));
offset += (int)sizeof(td7hdr.time_zone);
- td7hdr.collation = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint(header_tree, hf_tds7_collation, tvb, offset, sizeof(td7hdr.collation), td7hdr.collation);
+ proto_tree_add_item_ret_uint(header_tree, hf_tds7login_collation, tvb, offset, sizeof(td7hdr.collation), ENC_LITTLE_ENDIAN, &(td7hdr.collation));
offset += (int)sizeof(td7hdr.collation);
length_tree = proto_tree_add_subtree(login_tree, tvb, offset, 50, ett_tds7_hdr, NULL, "Lengths and offsets");
@@ -1173,11 +1601,11 @@ dissect_tds7_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
for (i = 0; i < 9; i++) {
offset2 = tvb_get_letohs(tvb, offset + i*4);
len = tvb_get_letohs(tvb, offset + i*4 + 2);
- proto_tree_add_uint_format(length_tree, hf_tds_login_offset, tvb, offset + i*4, 2,
+ proto_tree_add_uint_format(length_tree, hf_tds7login_offset, tvb, offset + i*4, 2,
offset2, "%s offset: %u",
val_to_str_const(i, login_field_names, "Unknown"),
offset2);
- proto_tree_add_uint_format(length_tree, hf_tds_login_length, tvb, offset + i*4 + 2, 2,
+ proto_tree_add_uint_format(length_tree, hf_tds7login_length, tvb, offset + i*4 + 2, 2,
len, "%s length: %u",
val_to_str_const(i, login_field_names, "Unknown"),
len);
@@ -1186,7 +1614,7 @@ dissect_tds7_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* tds 7 is always unicode */
len *= 2;
val = tvb_get_string_enc(wmem_packet_scope(), tvb, offset2, len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- proto_tree_add_string_format(login_tree, hf_tds_login_password, tvb, offset2, len, val,
+ proto_tree_add_string_format(login_tree, hf_tds7login_password, tvb, offset2, len, val,
"%s: %s", val_to_str_const(i, login_field_names, "Unknown"), val);
} else {
/* This field is the password. We retrieve it from the packet
@@ -1210,7 +1638,7 @@ dissect_tds7_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
val2[k] = '\0'; /* Null terminate our new string */
- proto_tree_add_string_format(login_tree, hf_tds_login_password, tvb, offset2, len, val2,
+ proto_tree_add_string_format(login_tree, hf_tds7login_password, tvb, offset2, len, val2,
"%s: %s", val_to_str_const(i, login_field_names, "Unknown"), val2);
}
}
@@ -1244,63 +1672,571 @@ get_size_by_coltype(int servertype)
case SYBMONEY: return 8;
case SYBMONEY4: return 4;
case SYBUNIQUE: return 16;
+
default: return -1;
}
}
-# if 0
-/*
- * data_to_string should take column data and turn it into something we can
- * display on the tree.
- */
-static char *data_to_string(void *data, guint col_type, guint col_size)
+
+static guint8 variant_propbytes(guint8 type)
{
- char *result;
- guint i;
+ switch (type)
+ {
+ /* FIXEDLENTYPE */
+ case TDS_DATA_TYPE_BIT: return 0;
+ case TDS_DATA_TYPE_INT1: return 0;
+ case TDS_DATA_TYPE_INT2: return 0;
+ case TDS_DATA_TYPE_INT4: return 0;
+ case TDS_DATA_TYPE_INT8: return 0;
+ case TDS_DATA_TYPE_DATETIME: return 0;
+ case TDS_DATA_TYPE_DATETIME4: return 0;
+ case TDS_DATA_TYPE_FLT4: return 0;
+ case TDS_DATA_TYPE_FLT8: return 0;
+ case TDS_DATA_TYPE_MONEY: return 0;
+ case TDS_DATA_TYPE_MONEY4: return 0;
+
+ /* BYTELEN_TYPE */
+ case TDS_DATA_TYPE_DATEN: return 0;
+ case TDS_DATA_TYPE_GUID: return 0;
+ case TDS_DATA_TYPE_TIMEN: return 1;
+ case TDS_DATA_TYPE_DATETIME2N: return 1;
+ case TDS_DATA_TYPE_DATETIMEOFFSETN: return 1;
+ case TDS_DATA_TYPE_DECIMALN: return 2;
+ case TDS_DATA_TYPE_NUMERICN: return 2;
+
+ /* USHORTLEN_TYPE */
+ case TDS_DATA_TYPE_BIGVARBIN: return 2;
+ case TDS_DATA_TYPE_BIGVARCHR: return 7;
+ case TDS_DATA_TYPE_BIGBINARY: return 2;
+ case TDS_DATA_TYPE_BIGCHAR: return 7;
+ case TDS_DATA_TYPE_NVARCHAR: return 7;
+ case TDS_DATA_TYPE_NCHAR: return 7;
+
+ default: return 0;
+ }
+}
+
+static void
+dissect_tds_type_varbyte(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tree *tree, int hf, guint8 data_type, guint8 scale, gboolean plp, gint fieldnum)
+{
+ guint32 length;
+ proto_tree *sub_tree = NULL;
+ proto_item *item = NULL, *length_item = NULL;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
+
+ item = proto_tree_add_item(tree, hf, tvb, *offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(item, ett_tds_type_varbyte);
+
+ if(fieldnum != -1)
+ proto_item_append_text(item, " %i", fieldnum);
+
+ proto_item_append_text(item, " (%s)", val_to_str(data_type, tds_data_type_names, "Invalid data type: %02X"));
- result=wmem_alloc(wmem_packet_scope(), 256);
- switch(col_type) {
- case SYBVARCHAR:
- /* strncpy(result, (char *)data, col_size); */
- for (i=0;i<col_size && i<(256-1);i++)
- if (!g_ascii_isprint(((char *)data)[i])) result[i]='.';
- else result[i]=((char *)data)[i];
- result[i] = '\0';
+ if(plp) {
+ guint64 plp_length = tvb_get_letoh64(tvb, *offset);
+ length_item = proto_tree_add_item(sub_tree, hf_tds_type_varbyte_plp_len, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
+ *offset += 8;
+ if(plp_length == TDS_PLP_NULL)
+ proto_item_append_text(length_item, " (PLP_NULL)");
+ else {
+ if(plp_length == TDS_UNKNOWN_PLP_LEN)
+ proto_item_append_text(length_item, " (UNKNOWN_PLP_LEN)");
+ while(TRUE) {
+ length_item = proto_tree_add_item_ret_uint(sub_tree, hf_tds_type_varbyte_plp_chunk_len, tvb, *offset, 4, ENC_LITTLE_ENDIAN, &length);
+ *offset += 4;
+ if(length == TDS_PLP_TERMINATOR) {
+ proto_item_append_text(length_item, " (PLP_TERMINATOR)");
+ break;
+ }
+ switch(data_type) {
+ case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
+ break;
+ case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_ASCII|ENC_NA);
+ break;
+ case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ break;
+ case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
+ case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
+ break;
+ default:
+ /* no other data type sets plp = TRUE */
+ expert_add_info_format(pinfo, length_item, &ei_tds_invalid_plp_type, "This type should not use PLP");
+ }
+ *offset += length;
+ }
+ }
+ }
+ else switch(data_type) {
+ /* FIXEDLENTYPE */
+ case TDS_DATA_TYPE_NULL: /* Null (no data associated with this type) */
break;
- case SYBINT2:
- g_snprintf(result, 256, "%d", *(short *)data);
+ case TDS_DATA_TYPE_BIT: /* Bit (1 byte data representation) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_boolean, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
+ *offset += 1;
break;
- case SYBINT4:
- g_snprintf(result, 256, "%d", *(int *)data);
+ case TDS_DATA_TYPE_INT1: /* TinyInt (1 byte data representation) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int1, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
+ *offset += 1;
break;
- default:
- g_snprintf(result, 256, "Unexpected column_type %d", col_type);
+ case TDS_DATA_TYPE_INT2: /* SmallInt (2 byte data representation) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
+ *offset += 2;
+ break;
+ case TDS_DATA_TYPE_INT4: /* Int (4 byte data representation) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int4, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
+ *offset += 4;
+ break;
+ case TDS_DATA_TYPE_INT8: /* BigInt (8 byte data representation) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int8, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
+ *offset += 8;
+ break;
+ case TDS_DATA_TYPE_FLT4: /* Real (4 byte data representation) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_float, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
+ *offset += 4;
+ break;
+ case TDS_DATA_TYPE_FLT8: /* Float (8 byte data representation) */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
+ *offset += 8;
+ break;
+ case TDS_DATA_TYPE_MONEY4: /* SmallMoney (4 byte data representation) */
+ case TDS_DATA_TYPE_DATETIME4: /* SmallDateTime (4 byte data representation) */
+ /*TODO*/
+ *offset += 4;
+ break;
+ case TDS_DATA_TYPE_MONEY: /* Money (8 byte data representation) */
+ case TDS_DATA_TYPE_DATETIME: /* DateTime (8 byte data representation) */
+ /*TODO*/
+ *offset += 8;
+ break;
+
+
+ /* BYTELEN_TYPE - types prefixed with 1-byte length */
+ case TDS_DATA_TYPE_GUID: /* UniqueIdentifier */
+ length = tvb_get_guint8(tvb, *offset);
+ length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ switch(length) {
+ case TDS_GEN_NULL:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
+ break;
+ case 16:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_guid, tvb, *offset + 1, length, ENC_LITTLE_ENDIAN);
+ break;
+ default:
+ expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
+ }
+ *offset += 1 + length;
+ break;
+
+ case TDS_DATA_TYPE_BITN:
+ length = tvb_get_guint8(tvb, *offset);
+ length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ switch(length) {
+ case TDS_GEN_NULL:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
+ break;
+ case 1:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_boolean, tvb, *offset + 1, 1, ENC_LITTLE_ENDIAN);
+ break;
+ default:
+ expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
+ }
+ *offset += 1 + length;
+ break;
+
+ case TDS_DATA_TYPE_INTN:
+ length = tvb_get_guint8(tvb, *offset);
+ length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ switch(length) {
+ case TDS_GEN_NULL:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
+ break;
+ case 1:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int1, tvb, *offset + 1, 1, ENC_LITTLE_ENDIAN);
+ break;
+ case 2:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int2, tvb, *offset + 1, 2, ENC_LITTLE_ENDIAN);
+ break;
+ case 4:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int4, tvb, *offset + 1, 4, ENC_LITTLE_ENDIAN);
+ break;
+ case 8:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int8, tvb, *offset + 1, 8, ENC_LITTLE_ENDIAN);
+ break;
+ default:
+ expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
+ }
+ *offset += 1 + length;
+ break;
+
+ case TDS_DATA_TYPE_FLTN:
+ length = tvb_get_guint8(tvb, *offset);
+ length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ switch(length) {
+ case TDS_GEN_NULL:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
+ break;
+ case 4:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_float, tvb, *offset + 1, 4, ENC_LITTLE_ENDIAN);
+ break;
+ case 8:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset + 1, 8, ENC_LITTLE_ENDIAN);
+ break;
+ default:
+ expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
+ }
+ *offset += 1 + length;
+ break;
+
+ case TDS_DATA_TYPE_MONEYN:
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+ if(length > 0) {
+ if(length == 4)
+ {
+ gdouble dblvalue = (gfloat)tvb_get_guint32(tvb, *offset, encoding);
+ proto_tree_add_double_format_value(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset, 4, dblvalue, "%.4f", dblvalue/10000);
+ }
+ if(length == 8)
+ {
+ gdouble dblvalue;
+ guint64 moneyval;
+
+ moneyval = tvb_get_guint32(tvb, *offset, encoding);
+ dblvalue = (moneyval << 32) + tvb_get_guint32(tvb, *offset + 4, encoding);
+ proto_tree_add_double_format_value(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset, 8, dblvalue, "%.4f", dblvalue/10000);
+ }
+ *offset += length;
+ }
+ break;
+
+ case TDS_DATA_TYPE_DATEN: /* (introduced in TDS 7.3) */
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+ if(length == 3) {
+ guint days = 0;
+ nstime_t tv;
+
+ days += tvb_get_guint8(tvb, *offset + 2) << 16;
+ days += tvb_get_guint8(tvb, *offset + 1) << 8;
+ days += tvb_get_guint8(tvb, *offset);
+
+ tv.secs = (days * G_GUINT64_CONSTANT(86400)) - G_GUINT64_CONSTANT(62135596800); /* 62135596800 - seconds between Jan 1, 1 and Jan 1, 1970 */
+ tv.nsecs = 0;
+ proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
+ }
+ *offset += length;
+ break;
+
+ case TDS_DATA_TYPE_TIMEN: /* (introduced in TDS 7.3) */
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+ if(length > 0) {
+
+ int i;
+ guint64 value = 0;
+ gdouble dblvalue;
+ nstime_t tv;
+
+ for(i = length - 1; i > 0; i--)
+ {
+ value = value + tvb_get_guint8(tvb, *offset + i);
+ value = value << 8;
+ }
+ value = value + tvb_get_guint8(tvb, *offset);
+
+ dblvalue = value;
+ for(i = 0; i < scale; i++)
+ {
+ dblvalue = dblvalue / 10;
+ }
+
+ tv.secs = dblvalue;
+ tv.nsecs = (dblvalue - tv.secs) * 1000000000;
+ proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_reltime, tvb, *offset, length, &tv);
+
+ *offset += length;
+ }
+ break;
+
+ case TDS_DATA_TYPE_DATETIMN:
+
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+ if(length > 0) {
+ if(length == 4)
+ {
+ /* SQL smalldatetime */
+ nstime_t tv;
+ guint days = tvb_get_guint16(tvb, *offset, encoding);
+ guint minutes = tvb_get_guint16(tvb, *offset + 2, encoding);
+
+ tv.secs = (days * G_GUINT64_CONSTANT(86400)) + (minutes * 60) - G_GUINT64_CONSTANT(2208988800); /* 2208988800 - seconds between Jan 1, 1900 and Jan 1, 1970 */
+ tv.nsecs = 0;
+ proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
+ }
+ if(length == 8)
+ {
+ /* SQL datetime */
+ nstime_t tv;
+ guint days = tvb_get_guint32(tvb, *offset, encoding);
+ guint threehndths = tvb_get_guint32(tvb, *offset + 4, encoding);
+
+ tv.secs = (days * G_GUINT64_CONSTANT(86400)) + (threehndths/300) - G_GUINT64_CONSTANT(2208988800); /* 2208988800 - seconds between Jan 1, 1900 and Jan 1, 1970 */
+ tv.nsecs = (threehndths%300) * 10000000 / 3;
+ proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
+ }
+ *offset += length;
+ }
+ break;
+
+ case TDS_DATA_TYPE_DATETIME2N: /* (introduced in TDS 7.3) */
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+ if(length > 0) {
+
+ int i, bytestoread = 0;
+ guint64 value = 0;
+ gdouble dblvalue;
+ guint days = 0;
+ guint64 secs;
+ nstime_t tv;
+
+ if(scale <= 2) bytestoread = 3;
+ if((scale >= 3) && (scale <= 4)) bytestoread = 4;
+ if((scale >= 5) && (scale <= 7)) bytestoread = 5;
+
+ for(i = bytestoread - 1; i > 0; i--)
+ {
+ value = value + tvb_get_guint8(tvb, *offset + i);
+ value = value << 8;
+ }
+ value = value + tvb_get_guint8(tvb, *offset);
+
+ dblvalue = value;
+ for(i = 0; i < scale; i++)
+ {
+ dblvalue = dblvalue / 10;
+ }
+
+ days += tvb_get_guint8(tvb, *offset + bytestoread + 2) << 16;
+ days += tvb_get_guint8(tvb, *offset + bytestoread + 1) << 8;
+ days += tvb_get_guint8(tvb, *offset + bytestoread);
+
+ secs = (days * G_GUINT64_CONSTANT(86400)) - G_GUINT64_CONSTANT(62135596800); /* 62135596800 - seconds between Jan 1, 1 and Jan 1, 1970 */
+
+ value = dblvalue;
+ tv.secs = secs + value;
+ dblvalue = dblvalue - value;
+ tv.nsecs = dblvalue * 1000000000;
+ proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
+
+ *offset += bytestoread + 3;
+ }
+ break;
+
+ case TDS_DATA_TYPE_DATETIMEOFFSETN: /* (introduced in TDS 7.3) */
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+ if(length > 0) {
+
+ int i, bytestoread = 0;
+ guint64 value = 0;
+ gdouble dblvalue;
+ guint days = 0;
+ gshort timeoffset = 0;
+ guint64 secs;
+ nstime_t tv;
+ proto_item *timeitem = NULL;
+
+ if(scale <= 2) bytestoread = 3;
+ if((scale >= 3) && (scale <= 4)) bytestoread = 4;
+ if((scale >= 5) && (scale <= 7)) bytestoread = 5;
+
+ for(i = bytestoread - 1; i > 0; i--)
+ {
+ value = value + tvb_get_guint8(tvb, *offset + i);
+ value = value << 8;
+ }
+ value = value + tvb_get_guint8(tvb, *offset);
+
+ dblvalue = value;
+ for(i = 0; i < scale; i++)
+ {
+ dblvalue = dblvalue / 10;
+ }
+
+ days += tvb_get_guint8(tvb, *offset + bytestoread + 2) << 16;
+ days += tvb_get_guint8(tvb, *offset + bytestoread + 1) << 8;
+ days += tvb_get_guint8(tvb, *offset + bytestoread);
+
+ secs = (days * G_GUINT64_CONSTANT(86400)) - G_GUINT64_CONSTANT(62135596800); /* 62135596800 - seconds between Jan 1, 1 and Jan 1, 1970 */
+
+ value = dblvalue;
+ tv.secs = secs + value;
+ dblvalue = dblvalue - value;
+ tv.nsecs = dblvalue * 1000000000;
+ timeitem = proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
+
+ timeoffset = tvb_get_letohs(tvb, *offset + bytestoread + 3);
+
+ /* TODO: Need to find a way to convey the time and the offset in a single item, rather than appending text */
+ proto_item_append_text(timeitem, " %c%02i:%02i", timeoffset > 0 ? '+':'-', timeoffset / 60, timeoffset % 60);
+ *offset += bytestoread + 5;
+ }
+ break;
+
+ case TDS_DATA_TYPE_DECIMAL: /* Decimal (legacy support) */
+ case TDS_DATA_TYPE_NUMERIC: /* Numeric (legacy support) */
+ case TDS_DATA_TYPE_DECIMALN: /* Decimal */
+ case TDS_DATA_TYPE_NUMERICN: /* Numeric */
+ {
+ proto_item *numericitem = NULL;
+
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+
+ if(length > 0) {
+
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_sign, tvb, *offset, 1, ENC_NA);
+
+ switch(length - 1)
+ {
+ case 4:
+ {
+ numericitem = proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int4, tvb, *offset + 1, 4, ENC_LITTLE_ENDIAN);
+
+ if(scale != 0)
+ proto_item_append_text(numericitem, " x 10^%u", scale);
+ break;
+ }
+ case 8:
+ {
+ numericitem = proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int8, tvb, *offset + 1, 8, ENC_LITTLE_ENDIAN);
+
+ if(scale != 0)
+ proto_item_append_text(numericitem, " x 10^%u", scale);
+ break;
+ }
+ case 12:
+ case 16:
+ {
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset + 1, length, ENC_NA);
+ break;
+ }
+ }
+ *offset += length;
+ }
+ break;
+ }
+ case TDS_DATA_TYPE_CHAR: /* Char (legacy support) */
+ case TDS_DATA_TYPE_VARCHAR: /* VarChar (legacy support) */
+ case TDS_DATA_TYPE_BINARY: /* Binary (legacy support) */
+ case TDS_DATA_TYPE_VARBINARY: /* VarBinary (legacy support) */
+ length = tvb_get_guint8(tvb, *offset);
+ proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
+ *offset += 1;
+ if(length > 0) {
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
+ *offset += length;
+ }
+ break;
+
+ /* USHORTLEN_TYPE - types prefixed with 2-byte length */
+ case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
+ case TDS_DATA_TYPE_BIGBINARY: /* Binary */
+ case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
+ case TDS_DATA_TYPE_BIGCHAR: /* Char */
+ case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
+ case TDS_DATA_TYPE_NCHAR: /* NChar */
+ length = tvb_get_letohs(tvb, *offset);
+ length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 2, length);
+ *offset += 2;
+ if(length == TDS_CHARBIN_NULL) {
+ proto_item_append_text(length_item, " (CHARBIN_NULL)");
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
+ }
+ else {
+ switch(data_type) {
+ case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
+ case TDS_DATA_TYPE_BIGBINARY: /* Binary */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
+ break;
+ case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
+ case TDS_DATA_TYPE_BIGCHAR: /* Char */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_ASCII|ENC_NA);
+ break;
+ case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
+ case TDS_DATA_TYPE_NCHAR: /* NChar */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ break;
+ }
+ *offset += length;
+ }
+ break;
+
+ /* LONGLEN_TYPE - types prefixed with 4-byte length */
+ case TDS_DATA_TYPE_NTEXT: /* NText */
+ case TDS_DATA_TYPE_TEXT: /* Text */
+ case TDS_DATA_TYPE_IMAGE: /* Image */
+ case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
+ case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
+ case TDS_DATA_TYPE_SSVARIANT: /* Sql_Variant (introduced in TDS 7.2) */
+ length_item = proto_tree_add_item_ret_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 4, ENC_LITTLE_ENDIAN, &length);
+ *offset += 4;
+ if(length == TDS_CHARBIN_NULL32) {
+ proto_item_append_text(length_item, " (CHARBIN_NULL)");
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
+ }
+ else {
+ switch(data_type) {
+ case TDS_DATA_TYPE_NTEXT: /* NText */
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ break;
+ case TDS_DATA_TYPE_TEXT:
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_ASCII|ENC_NA);
+ break;
+ default: /*TODO*/
+ proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
+ }
+ *offset += length;
+ }
break;
}
- return result;
+ proto_item_set_end(item, tvb, *offset);
}
-#endif
-/*
- * Since rows are special PDUs in that they are not fixed and lack a size field,
- * the length must be computed using the column information seen in the result
- * PDU. This function does just that.
- */
-static guint
-tds_get_row_size(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset)
+static void
+dissect_tds_type_info_minimal(guint8 data_type, guint size, gboolean *plp)
{
- guint cur, i, csize;
+ *plp = FALSE; /* most types are not Partially Length-Prefixed */
- cur = offset;
- for (i = 0; i < nl_data->num_cols; i++) {
- if (!is_fixed_coltype(nl_data->columns[i]->ctype)) {
- csize = tvb_get_guint8(tvb, cur);
- cur++;
- } else
- csize = get_size_by_coltype(nl_data->columns[i]->ctype);
- cur += csize;
+ /* optional TYPE_VARLEN for variable length types */
+ switch(data_type) {
+ /* USHORTLEN_TYPE */
+ case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
+ case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
+ case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
+ /* A type with unlimited max size, known as varchar(max), varbinary(max) and nvarchar(max),
+ which has a max size of 0xFFFF, defined by PARTLENTYPE. This class of types was introduced in TDS 7.2. */
+ if(size == 0xFFFF)
+ *plp = TRUE;
+ break;
+ /* LONGLEN_TYPE */
+ case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
+ case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
+ *plp = TRUE;
+ break;
}
-
- return (cur - offset + 1);
}
/*
@@ -1315,23 +2251,22 @@ dissect_tds_col_info_token(tvbuff_t *tvb, struct _netlib_data *nl_data, guint of
{
guint next, cur;
guint col;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
- next = offset + tds_tvb_get_xxtohs(tvb, offset+1, tds_little_endian) + 3;
+ next = offset + tvb_get_guint16(tvb, offset+1, encoding) + 3;
cur = offset + 3;
col = 0;
while (cur < next) {
- if (col >= MAX_COLUMNS) {
+ if (col >= TDS_MAX_COLUMNS) {
nl_data->num_cols = 0;
return FALSE;
}
nl_data->columns[col] = wmem_new(wmem_packet_scope(), struct _tds_col);
-
nl_data->columns[col]->name[0] ='\0';
-
- nl_data->columns[col]->utype = tds_tvb_get_xxtohs(tvb, cur, tds_little_endian);
+ nl_data->columns[col]->utype = tvb_get_guint16(tvb, cur, encoding);
cur += 2;
cur += 2; /* unknown */
@@ -1339,7 +2274,7 @@ dissect_tds_col_info_token(tvbuff_t *tvb, struct _netlib_data *nl_data, guint of
nl_data->columns[col]->ctype = tvb_get_guint8(tvb,cur);
cur++;
- if (!is_fixed_coltype(nl_data->columns[col]->ctype)) {
+ if (!is_fixedlen_type_tds(nl_data->columns[col]->ctype)) {
nl_data->columns[col]->csize = tvb_get_guint8(tvb,cur);
cur ++;
} else {
@@ -1355,7 +2290,6 @@ dissect_tds_col_info_token(tvbuff_t *tvb, struct _netlib_data *nl_data, guint of
return TRUE;
}
-
/*
* Read the results token and store the relevant information in the
* _netlib_data structure for later use (see tds_get_row_size).
@@ -1363,11 +2297,12 @@ dissect_tds_col_info_token(tvbuff_t *tvb, struct _netlib_data *nl_data, guint of
* TODO: check we don't go past end of the token
*/
static gboolean
-read_results_tds5(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset, guint len _U_)
+read_results_tds5_token(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset)
{
guint name_len;
guint cur;
guint i;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
cur = offset;
@@ -1376,8 +2311,8 @@ read_results_tds5(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset, gui
* if we didn't see the login packet.
* XXX: We'll take a hint
*/
- nl_data->num_cols = tds_tvb_get_xxtohs(tvb, cur, tds_little_endian);
- if (nl_data->num_cols > MAX_COLUMNS) {
+ nl_data->num_cols = tvb_get_guint16(tvb, cur, encoding);
+ if (nl_data->num_cols > TDS_MAX_COLUMNS) {
nl_data->num_cols = 0;
return FALSE;
}
@@ -1392,7 +2327,7 @@ read_results_tds5(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset, gui
cur++; /* unknown */
- nl_data->columns[i]->utype = tds_tvb_get_xxtohs(tvb, cur, tds_little_endian);
+ nl_data->columns[i]->utype = tvb_get_guint16(tvb, cur, encoding);
cur += 2;
cur += 2; /* unknown */
@@ -1400,7 +2335,7 @@ read_results_tds5(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset, gui
nl_data->columns[i]->ctype = tvb_get_guint8(tvb,cur);
cur++;
- if (!is_fixed_coltype(nl_data->columns[i]->ctype)) {
+ if (!is_fixedlen_type_tds(nl_data->columns[i]->ctype)) {
nl_data->columns[i]->csize = tvb_get_guint8(tvb,cur);
cur ++;
} else {
@@ -1465,140 +2400,447 @@ netlib_check_login_pkt(tvbuff_t *tvb, guint offset, packet_info *pinfo, guint8 t
return TRUE;
}
-static void
-dissect_tds_env_chg(tvbuff_t *tvb, guint offset, guint token_sz,
- proto_tree *tree)
+static int
+dissect_tds_prelogin_response(tvbuff_t *tvb, guint offset, proto_tree *tree)
{
- guint8 env_type;
- guint old_len, new_len, old_len_offset;
- guint32 string_offset;
- gboolean is_unicode = FALSE;
+ guint8 token = 0;
+ gint tokenoffset, tokenlen, cur = offset, valid = 0;
- env_type = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_tds_env_chg_type, tvb, offset, 1, ENC_NA);
+ /* Test for prelogin format compliance */
+ while(tvb_reported_length_remaining(tvb, cur) > 0)
+ {
+ token = tvb_get_guint8(tvb, cur);
+ cur += 1;
+
+ if((token <= 8) || (token == 0xff))
+ {
+ valid = 1;
+ } else {
+ valid = 0;
+ break;
+ }
+
+ if(token == 0xff)
+ break;
- new_len = tvb_get_guint8(tvb, offset+1);
- old_len_offset = offset + new_len + 2;
- old_len = tvb_get_guint8(tvb, old_len_offset);
+ tokenoffset = tvb_get_ntohs(tvb, cur);
+ if(tokenoffset > tvb_captured_length_remaining(tvb, 0))
+ {
+ valid = 0;
+ break;
+ }
+ cur += 2;
+
+ tokenlen = tvb_get_ntohs(tvb, cur);
+ if(tokenlen > tvb_captured_length_remaining(tvb, 0))
+ {
+ valid = 0;
+ break;
+ }
+ cur += 2;
+ }
- /*
- * If our lengths plus the lengths of the type and the lengths
- * don't add up to the token size, it must be UCS2.
- */
- if (old_len + new_len + 3 != token_sz) {
- is_unicode = TRUE;
- old_len_offset = offset + (new_len * 2) + 2;
- old_len = tvb_get_guint8(tvb, old_len_offset);
+ if(token != 0xff)
+ {
+ valid = 0;
+ }
+
+
+ if(valid)
+ {
+ dissect_tds7_prelogin_packet(tvb, tree);
+ }
+
+ return valid;
+}
+
+static int
+dissect_tds_order_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
+{
+ guint cur = offset;
+ guint i;
+ guint16 length;
+
+ length = tvb_get_letohs(tvb, cur);
+ proto_tree_add_item(tree, hf_tds_order_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+
+ for (i = 0; i < length / 2; i++) {
+ proto_tree_add_item(tree, hf_tds_order_colnum, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ }
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_offset_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
+{
+ guint cur = offset;
+
+ proto_tree_add_item(tree, hf_tds_offset_id, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_tds_offset_len, tvb, cur + 2, 2, ENC_LITTLE_ENDIAN);
+ cur += 4;
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_row_token(tvbuff_t *tvb, packet_info *pinfo, struct _netlib_data *nl_data, guint offset, proto_tree *tree)
+{
+ guint cur = offset, i, type;
+ gboolean plp = FALSE;
+
+ for (i = 0; i < nl_data->num_cols; i++) {
+ type = nl_data->columns[i]->ctype;
+ dissect_tds_type_info_minimal(type, nl_data->columns[i]->csize, &plp);
+
+ if(nl_data->columns[i]->ctype == TDS_DATA_TYPE_NTEXT ||
+ nl_data->columns[i]->ctype == TDS_DATA_TYPE_TEXT ||
+ nl_data->columns[i]->ctype == TDS_DATA_TYPE_IMAGE)
+ {
+ /* TextPointer */
+ cur += 1 + tvb_get_guint8(tvb, cur);
+
+ /* Timestamp */
+ cur += 8;
+ }
+
+ dissect_tds_type_varbyte(tvb, &cur, pinfo, tree, hf_tds_row_field, type, nl_data->columns[i]->scale, plp, i+1);
+ }
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_nbc_row_token(tvbuff_t *tvb, packet_info *pinfo, struct _netlib_data *nl_data, guint offset, proto_tree *tree)
+{
+ guint relbyte, relbit, i, cur;
+ gboolean plp = FALSE;
+
+ cur = offset + nl_data->num_cols/8;
+ if((nl_data->num_cols%8) != 0) cur++;
+
+ for (i = 0; i < nl_data->num_cols; i++) {
+
+ relbyte = tvb_get_guint8(tvb, offset + i/8);
+ relbit = relbyte & (1 << (i%8));
+
+ if(relbit == 0)
+ {
+ dissect_tds_type_info_minimal(nl_data->columns[i]->ctype, nl_data->columns[i]->csize, &plp);
+
+ if(nl_data->columns[i]->ctype == TDS_DATA_TYPE_NTEXT ||
+ nl_data->columns[i]->ctype == TDS_DATA_TYPE_TEXT ||
+ nl_data->columns[i]->ctype == TDS_DATA_TYPE_IMAGE)
+ {
+ /* TextPointer */
+ cur += 1 + tvb_get_guint8(tvb, cur);
+
+ /* Timestamp */
+ cur += 8;
+ }
+
+ dissect_tds_type_varbyte(tvb, &cur, pinfo, tree, hf_tds_row_field, nl_data->columns[i]->ctype, nl_data->columns[i]->scale, plp, i+1);
+ }
}
- proto_tree_add_item(tree, hf_tds_new_value_length, tvb, offset + 1, 1, ENC_NA);
- if (new_len) {
- if (env_type != 7) { /* if it's not 'Collation Info - which is not textual! */
- string_offset = offset + 2;
- if (is_unicode == TRUE) {
- new_len *= 2;
- proto_tree_add_item(tree, hf_tds_new_value, tvb, string_offset, new_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- } else
- proto_tree_add_item(tree, hf_tds_new_value, tvb, string_offset, new_len, ENC_ASCII|ENC_NA);
+ return cur - offset;
+}
+
+static int
+dissect_tds_returnstatus_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
+{
+ guint cur = offset;
+
+ proto_tree_add_item(tree, hf_tds_returnstatus_value, tvb, cur, 4, ENC_LITTLE_ENDIAN);
+ cur += 4;
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_sspi_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
+{
+ guint cur = offset, len_field_val;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
+
+ len_field_val = tvb_get_guint16(tvb, cur, encoding) * 2;
+ cur += 2;
+
+ if (len_field_val) {
+ proto_tree_add_item(tree, hf_tds_sspi_buffer, tvb, cur, len_field_val, ENC_NA);
+ cur += len_field_val;
+ }
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_envchg_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
+{
+ guint cur = offset;
+ guint8 env_type;
+ guint new_len, old_len;
+
+ proto_tree_add_item(tree, hf_tds_envchg_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+
+ env_type = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(tree, hf_tds_envchg_type, tvb, cur, 1, ENC_NA);
+ cur += 1;
+
+ /* Read new value */
+ switch(env_type)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 13:
+ case 19:
+ /* B_VARCHAR, Unicode strings */
+ new_len = tvb_get_guint8(tvb, cur) * 2;
+ proto_tree_add_item(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(new_len > 0)
+ {
+ proto_tree_add_item(tree, hf_tds_envchg_newvalue_string, tvb, cur, new_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += new_len;
}
- else { /* parse collation info structure. From http://www.freetds.org/tds.html#collate */
- offset +=2;
- proto_tree_add_item(tree, hf_tds_collate_codepage, tvb, offset, 2, ENC_LITTLE_ENDIAN );
- offset += 2;
- proto_tree_add_item(tree, hf_tds_collate_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN );
- offset += 2;
- proto_tree_add_item(tree, hf_tds_collate_charset_id, tvb, offset, 1, ENC_LITTLE_ENDIAN );
- /*offset +=1;*/
+
+ break;
+
+ case 7:
+ /* parse collation info structure. From http://www.freetds.org/tds.html#collate */
+ new_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA);
+ cur +=1;
+
+ proto_tree_add_item(tree, hf_tds_envchg_collate_codepage, tvb, cur, 2, ENC_LITTLE_ENDIAN );
+ proto_tree_add_item(tree, hf_tds_envchg_collate_flags, tvb, cur + 2, 2, ENC_LITTLE_ENDIAN );
+ proto_tree_add_item(tree, hf_tds_envchg_collate_charset_id, tvb, cur + 4, 1, ENC_LITTLE_ENDIAN );
+ cur += new_len;
+
+ break;
+
+ case 8:
+ case 12:
+ case 16:
+ /* B_VARBYTE */
+ new_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(new_len > 0)
+ {
+ proto_tree_add_item(tree, hf_tds_envchg_newvalue_bytes, tvb, cur, new_len, ENC_NA);
+ cur += new_len;
}
+ break;
+
+ case 9:
+ case 10:
+ case 11:
+ case 17:
+ case 18:
+ /* %x00 */
+ proto_tree_add_item(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ break;
+
+ case 15:
+ /* L_VARBYTE */
+ break;
+
+ case 20:
+ break;
+
}
- proto_tree_add_item(tree, hf_tds_old_value_length, tvb, old_len_offset, 1, ENC_NA);
- if (old_len) {
- string_offset = old_len_offset + 1;
- if (is_unicode == TRUE) {
- old_len *= 2;
- proto_tree_add_item(tree, hf_tds_old_value, tvb, string_offset, old_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- } else
- proto_tree_add_item(tree, hf_tds_old_value, tvb, string_offset, old_len, ENC_ASCII|ENC_NA);
+ /* Read old value */
+ switch(env_type)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ /* B_VARCHAR, Unicode strings */
+ old_len = tvb_get_guint8(tvb, cur) * 2;
+ proto_tree_add_item(tree, hf_tds_envchg_oldvalue_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(old_len > 0)
+ {
+ proto_tree_add_item(tree, hf_tds_envchg_oldvalue_string, tvb, cur, old_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += old_len;
+ }
+ break;
+
+ case 5:
+ case 6:
+ case 8:
+ case 12:
+ case 13:
+ case 15:
+ case 16:
+ case 18:
+ case 19:
+ /* %x00 */
+ proto_tree_add_item(tree, hf_tds_envchg_oldvalue_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ break;
+
+ case 7:
+ case 9:
+ case 10:
+ case 11:
+ case 17:
+ /* B_VARBYTE */
+ old_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(tree, hf_tds_envchg_oldvalue_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(old_len > 0)
+ {
+ proto_tree_add_item(tree, hf_tds_envchg_oldvalue_bytes, tvb, cur, old_len, ENC_NA);
+ cur += old_len;
+ }
+ break;
+
+ case 20:
+ break;
}
+
+ return cur - offset;
}
-static void
-dissect_tds_err_token(tvbuff_t *tvb, guint offset, guint token_sz _U_, proto_tree *tree, tds_conv_info_t *tds_info)
+static int
+dissect_tds_error_token(tvbuff_t *tvb, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
{
+ guint cur = offset;
guint16 msg_len;
guint8 srvr_len, proc_len;
int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
- gboolean is_unicode = FALSE;
- proto_tree_add_item(tree, hf_tds_sql_error_number, tvb, offset, 4, encoding);
- offset += 4;
- proto_tree_add_item(tree, hf_tds_state, tvb, offset, 1, ENC_NA);
- offset +=1;
- proto_tree_add_item(tree, hf_tds_severity_level, tvb, offset, 1, ENC_NA);
- offset +=1;
+ proto_tree_add_item(tree, hf_tds_error_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
- msg_len = tds_tvb_get_xxtohs(tvb, offset, tds_little_endian);
- proto_tree_add_uint_format_value(tree, hf_tds_error_message_length, tvb, offset, 2, msg_len, "%u characters", msg_len);
- offset +=2;
+ proto_tree_add_item(tree, hf_tds_error_number, tvb, cur, 4, encoding);
+ cur += 4;
+ proto_tree_add_item(tree, hf_tds_error_state, tvb, cur, 1, ENC_NA);
+ cur +=1;
+ proto_tree_add_item(tree, hf_tds_error_class, tvb, cur, 1, ENC_NA);
+ cur +=1;
- if(tvb_get_guint8(tvb, offset+1) == 0) /* FIXME: It's probably unicode, if the 2nd byte of the message is zero. It's not a good detection method, but it works */
- is_unicode = TRUE;
+ msg_len = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_uint_format_value(tree, hf_tds_error_msgtext_length, tvb, cur, 2, msg_len, "%u characters", msg_len);
+ cur +=2;
- if(is_unicode) {
- msg_len *= 2;
- proto_tree_add_item(tree, hf_tds_error, tvb, offset, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ msg_len *= 2;
+ proto_tree_add_item(tree, hf_tds_error_msgtext, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+
+ srvr_len = tvb_get_guint8(tvb, cur);
+
+ proto_tree_add_uint_format_value(tree, hf_tds_error_servername_length, tvb, cur, 1, srvr_len, "%u characters", srvr_len);
+ cur +=1;
+ if(srvr_len) {
+ srvr_len *=2;
+ proto_tree_add_item(tree, hf_tds_error_servername, tvb, cur, srvr_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += srvr_len;
+ }
+
+ proc_len = tvb_get_guint8(tvb, cur);
+
+ proto_tree_add_uint_format_value(tree, hf_tds_error_procname_length, tvb, cur, 1, proc_len, "%u characters", proc_len);
+ cur +=1;
+ if(proc_len) {
+ proc_len *=2;
+ proto_tree_add_item(tree, hf_tds_error_procname, tvb, cur, proc_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += proc_len;
+ }
+
+ if (TDS_PROTO_TDS7_1_OR_LESS) {
+ proto_tree_add_item(tree, hf_tds_error_linenumber_16, tvb, cur, 2, encoding);
+ cur += 2;
} else {
- proto_tree_add_item(tree, hf_tds_error, tvb, offset, msg_len, ENC_ASCII|ENC_NA);;
+ proto_tree_add_item(tree, hf_tds_error_linenumber_32, tvb, cur, 4, encoding);
+ cur += 4;
}
- offset += msg_len;
- srvr_len = tvb_get_guint8(tvb, offset);
+ return cur - offset;
+}
- proto_tree_add_uint_format_value(tree, hf_tds_server_name_length, tvb, offset, 1, srvr_len, "%u characters", srvr_len);
- offset +=1;
+static int
+dissect_tds_info_token(tvbuff_t *tvb, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
+{
+ guint cur = offset;
+ guint16 msg_len;
+ guint8 srvr_len, proc_len;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
+
+ proto_tree_add_item(tree, hf_tds_info_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+
+ proto_tree_add_item(tree, hf_tds_info_number, tvb, cur, 4, encoding);
+ cur += 4;
+ proto_tree_add_item(tree, hf_tds_info_state, tvb, cur, 1, ENC_NA);
+ cur +=1;
+ proto_tree_add_item(tree, hf_tds_info_class, tvb, cur, 1, ENC_NA);
+ cur +=1;
+
+ msg_len = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_uint_format_value(tree, hf_tds_info_msgtext_length, tvb, cur, 2, msg_len, "%u characters", msg_len);
+ cur +=2;
+
+ msg_len *= 2;
+ proto_tree_add_item(tree, hf_tds_info_msgtext, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+
+ srvr_len = tvb_get_guint8(tvb, cur);
+
+ proto_tree_add_uint_format_value(tree, hf_tds_info_servername_length, tvb, cur, 1, srvr_len, "%u characters", srvr_len);
+ cur +=1;
if(srvr_len) {
- if (is_unicode) {
- srvr_len *=2;
- proto_tree_add_item(tree, hf_tds_server_name, tvb, offset, srvr_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- } else {
- proto_tree_add_item(tree, hf_tds_server_name, tvb, offset, srvr_len, ENC_ASCII|ENC_NA);
- }
- offset += srvr_len;
+ srvr_len *=2;
+ proto_tree_add_item(tree, hf_tds_info_servername, tvb, cur, srvr_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += srvr_len;
}
- proc_len = tvb_get_guint8(tvb, offset);
+ proc_len = tvb_get_guint8(tvb, cur);
- proto_tree_add_uint_format_value(tree, hf_tds_process_name_length, tvb, offset, 1, proc_len, "%u characters", proc_len);
- offset +=1;
+ proto_tree_add_uint_format_value(tree, hf_tds_info_procname_length, tvb, cur, 1, proc_len, "%u characters", proc_len);
+ cur +=1;
if(proc_len) {
- if (is_unicode) {
- proc_len *=2;
- proto_tree_add_item(tree, hf_tds_process_name, tvb, offset, proc_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- } else {
- proto_tree_add_item(tree, hf_tds_process_name, tvb, offset, proc_len, ENC_ASCII|ENC_NA);
- }
- offset += proc_len;
+ proc_len *=2;
+ proto_tree_add_item(tree, hf_tds_info_procname, tvb, cur, proc_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += proc_len;
}
- if (TDS_PROTO_TDS7_2_OR_GREATER) {
- proto_tree_add_item(tree, hf_tds_line_number32, tvb, offset, 4, encoding);
+ if (TDS_PROTO_TDS7_1_OR_LESS) {
+ proto_tree_add_item(tree, hf_tds_info_linenumber_16, tvb, cur, 2, encoding);
+ cur += 2;
} else {
- proto_tree_add_item(tree, hf_tds_line_number16, tvb, offset, 2, encoding);
+ proto_tree_add_item(tree, hf_tds_info_linenumber_32, tvb, cur, 4, encoding);
+ cur += 4;
}
+
+ return cur - offset;
}
static int
-dissect_tds_login_ack_token(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint token_sz, proto_tree *tree, tds_conv_info_t *tds_info)
+dissect_tds_login_ack_token(tvbuff_t *tvb, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
{
guint8 msg_len;
guint32 tds_version;
- gboolean is_unicode = FALSE;
- proto_item* ti;
+ guint cur = offset;
+
+ proto_tree_add_item(tree, hf_tds_loginack_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
- proto_tree_add_item(tree, hf_tds_ack, tvb, offset, 1, ENC_NA);
- offset +=1;
- tds_version = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item(tree, hf_tds_loginack_interface, tvb, cur, 1, ENC_NA);
+ cur +=1;
+ proto_tree_add_item_ret_uint(tree, hf_tds_loginack_tdsversion, tvb, cur, 4, ENC_BIG_ENDIAN, &tds_version);
switch (tds_version) {
case 0x07000000:
tds_info->tds7_version = TDS_PROTOCOL_7_0;
@@ -1611,127 +2853,442 @@ dissect_tds_login_ack_token(tvbuff_t *tvb, packet_info *pinfo, guint offset, gui
tds_info->tds7_version = TDS_PROTOCOL_7_2;
break;
case 0x730A0003:
+ tds_info->tds7_version = TDS_PROTOCOL_7_3A;
+ break;
case 0x730B0003:
+ tds_info->tds7_version = TDS_PROTOCOL_7_3B;
+ break;
+ case 0x74000004:
+ tds_info->tds7_version = TDS_PROTOCOL_7_4;
+ break;
default:
- tds_info->tds7_version = TDS_PROTOCOL_7_3;
+ tds_info->tds7_version = TDS_PROTOCOL_7_4;
break;
}
- proto_tree_add_uint(tree, hf_tds7_loginack_version, tvb, offset, 4, tds_version);
- offset += 4;
-
- msg_len = tvb_get_guint8(tvb, offset);
- ti = proto_tree_add_uint_format_value(tree, hf_tds_text_length, tvb, offset, 1, msg_len, "%u characters", msg_len);
- offset +=1;
-
- if(msg_len + 6U + 3U != token_sz - 1) /* 6 is the length of ack(1), version (4), text length (1) fields */
- is_unicode = TRUE;
- expert_add_info_format(pinfo, ti, &ei_tds_token_stats, "msg_len: %d, token_sz: %d, total: %d",msg_len, token_sz, msg_len + 6U + 3U);
- if(is_unicode) {
- msg_len *= 2;
- proto_tree_add_item(tree, hf_tds_text, tvb, offset, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- } else {
- proto_tree_add_item(tree, hf_tds_text, tvb, offset, msg_len, ENC_ASCII|ENC_NA);
- }
- offset += msg_len;
+ cur += 4;
+
+ msg_len = tvb_get_guint8(tvb, cur);
+ cur +=1;
+
+ msg_len *= 2;
+ proto_tree_add_item(tree, hf_tds_loginack_progname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+
+ proto_tree_add_item(tree, hf_tds_loginack_progversion, tvb, cur, 4, ENC_NA);
- proto_tree_add_item(tree, hf_tds_server_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ cur += 4;
- return offset;
+ return cur - offset;
}
static int
-dissect_tds7_results_token(tvbuff_t *tvb, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
+dissect_tds7_colmetadata_token(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
{
- guint16 num_columns, table_len;
- guint8 type, msg_len;
- int i;
- proto_tree* col_tree;
-
- num_columns = tvb_get_letohs(tvb, offset);
- proto_tree_add_item(tree, hf_tds_columns, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset +=2;
+ guint cur = offset;
+ guint16 num_columns, flags, numparts, parti, partlen, msg_len;
+ guint8 type;
+ int i, col_offset;
+ proto_tree* col_tree, *flags_tree;
+ proto_item* flags_item, * type_item, *col_item;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
+
+ num_columns = tvb_get_letohs(tvb, cur);
+ nl_data->num_cols = num_columns;
+ proto_tree_add_item(tree, hf_tds_colmetadata_columns, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur +=2;
+
for(i=0; i != num_columns; i++) {
- col_tree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_tds_col, NULL, "Column %d", i + 1);
- if (TDS_PROTO_TDS7_2_OR_GREATER) {
- proto_tree_add_item(col_tree, hf_tds_usertype32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset +=4;
+
+ col_offset = cur;
+
+ col_item = proto_tree_add_item(tree, hf_tds_colmetadata_field, tvb, cur, 0, ENC_NA);
+ col_tree = proto_item_add_subtree(col_item, ett_tds_col);
+ proto_item_set_text(col_item, "Column %d", i + 1);
+
+ nl_data->columns[i] = wmem_new(wmem_packet_scope(), struct _tds_col);
+ nl_data->columns[i]->name[0] ='\0';
+
+ if (TDS_PROTO_TDS7_1_OR_LESS) {
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_usertype16, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ nl_data->columns[i]->utype = tvb_get_guint16(tvb, cur, encoding);
+ cur +=2;
} else {
- proto_tree_add_item(col_tree, hf_tds_usertype16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset +=2;
+ proto_tree_add_item_ret_uint(col_tree, hf_tds_colmetadata_usertype32, tvb, cur, 4, ENC_LITTLE_ENDIAN, &(nl_data->columns[i]->utype));
+ cur +=4;
}
- proto_tree_add_item(col_tree, hf_tds_results_token_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset +=2;
- type = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(col_tree, hf_tds_results_token_type, tvb, offset, 1, ENC_NA);
- offset +=1;
- if(type == 38 || type == 104 || type == 109 || type == 111) { /* ugly, ugly hack. Wish I knew what it really means!*/
- proto_tree_add_item(col_tree, hf_tds_unknown_bytes_1, tvb, offset, 1, ENC_NA);
- offset +=1;
- }
- else if (type == 35) {
- proto_tree_add_item(col_tree, hf_tds_unknown_bytes_4, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(col_tree, hf_tds_collate_codepage, tvb, offset, 2, ENC_LITTLE_ENDIAN );
- offset += 2;
- proto_tree_add_item(col_tree, hf_tds_collate_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN );
- offset += 2;
- proto_tree_add_item(col_tree, hf_tds_collate_charset_id, tvb, offset, 1, ENC_LITTLE_ENDIAN );
- offset +=1;
- table_len = tvb_get_letohs(tvb, offset);
- offset +=2;
- if(table_len != 0) {
- table_len *= 2;
- proto_tree_add_item(col_tree, hf_tds_table_name, tvb, offset, table_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- offset += table_len;
+
+ flags = tvb_get_letohs(tvb, cur);
+ flags_item = proto_tree_add_uint(col_tree, hf_tds_colmetadata_results_token_flags, tvb, cur, 2, flags);
+ if(flags_item)
+ {
+ flags_tree = proto_item_add_subtree(flags_item, ett_tds_flags);
+ if(flags_tree)
+ {
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_nullable, tvb, cur, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_casesen, tvb, cur, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_updateable, tvb, cur, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_identity, tvb, cur, 2, ENC_BIG_ENDIAN);
+ if(TDS_PROTO_TDS7_2_OR_GREATER) {
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_computed, tvb, cur, 2, ENC_BIG_ENDIAN);
+ }
+ if(TDS_PROTO_TDS7_3A_OR_LESS) {
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_reservedodbc, tvb, cur, 2, ENC_BIG_ENDIAN);
+ }
+ if(TDS_PROTO_TDS7_2_OR_GREATER) {
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_fixedlenclrtype, tvb, cur, 2, ENC_BIG_ENDIAN);
+ }
+ if(TDS_PROTO_TDS7_3B_OR_GREATER) {
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_sparsecolumnset, tvb, cur, 2, ENC_BIG_ENDIAN);
+ }
+ if(TDS_PROTO_TDS7_4_OR_GREATER) {
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_encrypted, tvb, cur, 2, ENC_BIG_ENDIAN);
+ }
+ if(TDS_PROTO_TDS7_2_OR_GREATER) {
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_hidden, tvb, cur, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_key, tvb, cur, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_nullableunknown, tvb, cur, 2, ENC_BIG_ENDIAN);
+ }
}
}
- else if (type == 106 || type == 108) {
- proto_tree_add_item(col_tree, hf_tds_unknown_bytes_3, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- offset +=3;
- }
- else if(type > 128) {
- proto_tree_add_item(col_tree, hf_tds_large_type_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- if (type != 165) {
- proto_tree_add_item(col_tree, hf_tds_collate_codepage, tvb, offset, 2, ENC_LITTLE_ENDIAN );
- offset += 2;
- proto_tree_add_item(col_tree, hf_tds_collate_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN );
- offset += 2;
- proto_tree_add_item(col_tree, hf_tds_collate_charset_id, tvb, offset, 1, ENC_LITTLE_ENDIAN );
- offset +=1;
+ cur +=2;
+
+ /* TYPE_INFO */
+ type = tvb_get_guint8(tvb, cur);
+ type_item = proto_tree_add_item(col_tree, hf_tds_colmetadata_results_token_type, tvb, cur, 1, ENC_NA);
+ proto_item_append_text(type_item, " (%s)", val_to_str(type, tds_data_type_names, "Invalid data type: %02X"));
+ nl_data->columns[i]->ctype = type;
+ cur++;
+
+ if(is_fixedlen_type_tds(type))
+ {
+ nl_data->columns[i]->csize = get_size_by_coltype(type);
+ } else
+
+ if(is_varlen_type_tds(type))
+ {
+ switch(type)
+ {
+ case TDS_DATA_TYPE_GUID:
+ case TDS_DATA_TYPE_INTN:
+ case TDS_DATA_TYPE_BITN:
+ case TDS_DATA_TYPE_FLTN:
+ case TDS_DATA_TYPE_MONEYN:
+ case TDS_DATA_TYPE_DATETIMN:
+ case TDS_DATA_TYPE_CHAR:
+ case TDS_DATA_TYPE_VARCHAR:
+ case TDS_DATA_TYPE_BINARY:
+ case TDS_DATA_TYPE_VARBINARY:
+ {
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_csize, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ nl_data->columns[i]->csize = tvb_get_guint8(tvb, cur);
+ cur++;
+ break;
+ }
+ case TDS_DATA_TYPE_DATEN:
+ {
+ break;
+ }
+ case TDS_DATA_TYPE_DECIMAL:
+ case TDS_DATA_TYPE_NUMERIC:
+ case TDS_DATA_TYPE_DECIMALN:
+ case TDS_DATA_TYPE_NUMERICN:
+ {
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_csize, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ nl_data->columns[i]->csize = tvb_get_guint8(tvb,cur);
+ cur++;
+
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_precision, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ nl_data->columns[i]->precision = tvb_get_guint8(tvb,cur);
+ cur++;
+
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_scale, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ nl_data->columns[i]->scale = tvb_get_guint8(tvb,cur);
+ cur++;
+ break;
+ }
+ case TDS_DATA_TYPE_TIMEN:
+ case TDS_DATA_TYPE_DATETIME2N:
+ case TDS_DATA_TYPE_DATETIMEOFFSETN:
+ {
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_scale, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ nl_data->columns[i]->scale = tvb_get_guint8(tvb,cur);
+ cur++;
+ break;
+ }
+ case TDS_DATA_TYPE_BIGVARBIN:
+ {
+ nl_data->columns[i]->csize = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_large_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ break;
+ }
+ case TDS_DATA_TYPE_BIGVARCHR:
+ {
+ nl_data->columns[i]->csize = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_large_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_codepage, tvb, cur, 2, ENC_LITTLE_ENDIAN );
+ cur += 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_flags, tvb, cur, 2, ENC_LITTLE_ENDIAN );
+ cur += 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_charset_id, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ cur +=1;
+ break;
+ }
+ case TDS_DATA_TYPE_BIGBINARY:
+ {
+ nl_data->columns[i]->csize = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_large_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ break;
+ }
+ case TDS_DATA_TYPE_BIGCHAR:
+ case TDS_DATA_TYPE_NVARCHAR:
+ case TDS_DATA_TYPE_NCHAR:
+ {
+ nl_data->columns[i]->csize = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_large_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_codepage, tvb, cur, 2, ENC_LITTLE_ENDIAN );
+ cur += 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_flags, tvb, cur, 2, ENC_LITTLE_ENDIAN );
+ cur += 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_charset_id, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ cur +=1;
+ break;
+ }
+ case TDS_DATA_TYPE_XML:
+ {
+ guint8 schema_present;
+ schema_present = tvb_get_guint8(tvb, cur);
+ cur += 1;
+
+ if(schema_present)
+ {
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_owningschema_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_owningschema, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_typename_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_typename, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_xmlschemacollection_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_xmlschemacollection, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+ }
+
+ break;
+ }
+ case TDS_DATA_TYPE_UDT:
+ {
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_maxbytesize, tvb, cur, 2, ENC_NA|ENC_LITTLE_ENDIAN);
+ cur += 2;
+
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_schemaname_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_schemaname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_typename_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_typename, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+
+ msg_len = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_assemblyqualifiedname_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ if(msg_len != 0) {
+ msg_len *= 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_assemblyqualifiedname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
+ }
+
+ break;
+ }
+ case TDS_DATA_TYPE_IMAGE:
+ {
+ cur += 4;
+
+ /* Table name */
+ numparts = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_parts, tvb, cur, 1, ENC_LITTLE_ENDIAN);
+ cur += 1;
+
+ for(parti = 0; parti < numparts; parti++)
+ {
+ partlen = tvb_get_letohs(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name, tvb, cur + 2, partlen * 2, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += 2 + (partlen * 2);
+ }
+ break;
+ }
+ case TDS_DATA_TYPE_TEXT:
+ case TDS_DATA_TYPE_NTEXT:
+ {
+ /* Not sure what we are stepping over here */
+ cur += 2;
+
+ nl_data->columns[i]->csize = tvb_get_guint16(tvb, cur, encoding);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_large_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_codepage, tvb, cur, 2, ENC_LITTLE_ENDIAN );
+ cur += 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_flags, tvb, cur, 2, ENC_LITTLE_ENDIAN );
+ cur += 2;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_charset_id, tvb, cur, 1, ENC_LITTLE_ENDIAN );
+ cur +=1;
+
+ /* Table name */
+ numparts = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_parts, tvb, cur, 1, ENC_LITTLE_ENDIAN);
+ cur += 1;
+
+ for(parti = 0; parti < numparts; parti++)
+ {
+ partlen = tvb_get_letohs(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name, tvb, cur + 2, partlen * 2, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += 2 + (partlen * 2);
+ }
+
+ break;
+ }
+ case TDS_DATA_TYPE_SSVARIANT:
+ {
+ cur += 4;
+ break;
+ }
}
}
- msg_len = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(col_tree, hf_tds_message_length, tvb, offset, 1, ENC_NA);
- offset += 1;
+
+ /* ColName */
+ msg_len = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_colname_length, tvb, cur, 1, ENC_NA);
+ cur += 1;
if(msg_len != 0) {
msg_len *= 2;
- proto_tree_add_item(col_tree, hf_tds_text, tvb, offset, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- offset += msg_len;
+ proto_tree_add_item(col_tree, hf_tds_colmetadata_colname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
+ cur += msg_len;
}
+
+ proto_item_set_len(col_item, cur - col_offset);
}
- return offset;
+
+ return cur - offset;
}
-static void
+static int
dissect_tds_done_token(tvbuff_t *tvb, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
{
+ guint cur = offset;
+
int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
- proto_tree_add_item(tree, hf_tds_done_token_status_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_tds_operation, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- if (TDS_PROTO_TDS7_2_OR_GREATER) {
- proto_tree_add_item(tree, hf_tds_row_count64, tvb, offset, 8, encoding);
+ proto_tree_add_item(tree, hf_tds_done_status, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ proto_tree_add_item(tree, hf_tds_done_curcmd, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ if (TDS_PROTO_TDS7_1_OR_LESS) {
+ proto_tree_add_item(tree, hf_tds_done_donerowcount_32, tvb, cur, 4, encoding);
+ cur += 4;
} else {
- proto_tree_add_item(tree, hf_tds_row_count32, tvb, offset, 4, encoding);
+ proto_tree_add_item(tree, hf_tds_done_donerowcount_64, tvb, cur, 8, encoding);
+ cur += 8;
}
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_doneproc_token(tvbuff_t *tvb, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
+{
+ guint cur = offset;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
+
+ proto_tree_add_item(tree, hf_tds_doneproc_status, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ proto_tree_add_item(tree, hf_tds_doneproc_curcmd, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ if (TDS_PROTO_TDS7_1_OR_LESS) {
+ proto_tree_add_item(tree, hf_tds_doneproc_donerowcount_32, tvb, cur, 4, encoding);
+ cur += 4;
+ } else {
+ proto_tree_add_item(tree, hf_tds_doneproc_donerowcount_64, tvb, cur, 8, encoding);
+ cur += 8;
+ }
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_doneinproc_token(tvbuff_t *tvb, guint offset, proto_tree *tree, tds_conv_info_t *tds_info)
+{
+ guint cur = offset;
+ int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
+
+ proto_tree_add_item(tree, hf_tds_doneinproc_status, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ proto_tree_add_item(tree, hf_tds_doneinproc_curcmd, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ if (TDS_PROTO_TDS7_1_OR_LESS) {
+ proto_tree_add_item(tree, hf_tds_doneinproc_donerowcount_32, tvb, cur, 4, encoding);
+ cur += 4;
+ } else {
+ proto_tree_add_item(tree, hf_tds_doneinproc_donerowcount_64, tvb, cur, 8, encoding);
+ cur += 8;
+ }
+
+ return cur - offset;
}
static guint8
-dissect_tds_type_info(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tree *tree, gboolean *plp)
+dissect_tds_type_info(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tree *tree, gboolean *plp, gboolean variantprop)
{
proto_item *item = NULL, *item1 = NULL, *data_type_item = NULL;
proto_tree *sub_tree = NULL, *collation_tree;
@@ -1746,6 +3303,12 @@ dissect_tds_type_info(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tr
data_type_item = proto_tree_add_item(sub_tree, hf_tds_type_info_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
*offset += 1;
+ if(variantprop)
+ {
+ guint8 prop_bytes = variant_propbytes(data_type);
+ *offset += prop_bytes;
+ }
+
/* optional TYPE_VARLEN for variable length types */
switch(data_type) {
/* FIXEDLENTYPE */
@@ -1755,7 +3318,7 @@ dissect_tds_type_info(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tr
case TDS_DATA_TYPE_INT2: /* SmallInt (2 byte data representation) */
case TDS_DATA_TYPE_INT4: /* Int (4 byte data representation) */
case TDS_DATA_TYPE_FLT4: /* Real (4 byte data representation) */
- case TDS_DATA_TYPE_DATETIM4: /* SmallDateTime (4 byte data representation) */
+ case TDS_DATA_TYPE_DATETIME4: /* SmallDateTime (4 byte data representation) */
case TDS_DATA_TYPE_MONEY4: /* SmallMoney (4 byte data representation) */
case TDS_DATA_TYPE_INT8: /* BigInt (8 byte data representation) */
case TDS_DATA_TYPE_FLT8: /* Float (8 byte data representation) */
@@ -1835,6 +3398,7 @@ dissect_tds_type_info(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tr
case TDS_DATA_TYPE_NUMERICN: /* Numeric */
proto_tree_add_item(sub_tree, hf_tds_type_info_precision, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
*offset += 1;
+ break;
/* SCALE */
case TDS_DATA_TYPE_TIMEN: /* (introduced in TDS 7.3) */
case TDS_DATA_TYPE_DATETIME2N: /* (introduced in TDS 7.3) */
@@ -1868,241 +3432,6 @@ dissect_tds_type_info(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tr
}
static void
-dissect_tds_type_varbyte(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto_tree *tree, int hf, guint8 data_type, gboolean plp)
-{
-#define GEN_NULL 0x00U
-#define CHARBIN_NULL 0xFFFFU
-#define CHARBIN_NULL32 0xFFFFFFFFU
- guint32 length;
- proto_tree *sub_tree = NULL;
- proto_item *item = NULL, *length_item = NULL;
-
- item = proto_tree_add_item(tree, hf, tvb, *offset, 0, ENC_NA);
- sub_tree = proto_item_add_subtree(item, ett_tds_type_varbyte);
-
- if(plp) {
-#define PLP_TERMINATOR G_GUINT64_CONSTANT(0x0000000000000000)
-#define UNKNOWN_PLP_LEN G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFE)
-#define PLP_NULL G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)
- guint64 plp_length = tvb_get_letoh64(tvb, *offset);
- length_item = proto_tree_add_item(sub_tree, hf_tds_type_varbyte_plp_len, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
- *offset += 8;
- if(plp_length == PLP_NULL)
- proto_item_append_text(length_item, " (PLP_NULL)");
- else {
- if(plp_length == UNKNOWN_PLP_LEN)
- proto_item_append_text(length_item, " (UNKNOWN_PLP_LEN)");
- while(TRUE) {
- length = tvb_get_letohl(tvb, *offset);
- length_item = proto_tree_add_item(sub_tree, hf_tds_type_varbyte_plp_chunk_len, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
- *offset += 4;
- if(length == PLP_TERMINATOR) {
- proto_item_append_text(length_item, " (PLP_TERMINATOR)");
- break;
- }
- switch(data_type) {
- case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
- break;
- case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_ASCII|ENC_NA);
- break;
- case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- break;
- case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
- case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
- proto_tree_add_expert_format(sub_tree, pinfo, &ei_tds_type_info_type_undecoded, tvb, *offset, length, "Data type %d not supported yet", data_type);
- /* No point in continuing: we need to parse the full data_type to know where it ends */
- THROW(ReportedBoundsError);
- break;
- default:
- /* no other data type sets plp = TRUE */
- DISSECTOR_ASSERT_NOT_REACHED();
- }
- *offset += length;
- }
- }
- }
- else switch(data_type) {
- /* FIXEDLENTYPE */
- case TDS_DATA_TYPE_NULL: /* Null (no data associated with this type) */
- break;
- case TDS_DATA_TYPE_BIT: /* Bit (1 byte data representation) */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_boolean, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
- *offset += 1;
- break;
- case TDS_DATA_TYPE_INT1: /* TinyInt (1 byte data representation) */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int1, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
- *offset += 1;
- break;
- case TDS_DATA_TYPE_INT2: /* SmallInt (2 byte data representation) */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
- *offset += 2;
- break;
- case TDS_DATA_TYPE_INT4: /* Int (4 byte data representation) */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int4, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
- *offset += 4;
- break;
- case TDS_DATA_TYPE_INT8: /* BigInt (8 byte data representation) */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int8, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
- *offset += 8;
- break;
- case TDS_DATA_TYPE_FLT4: /* Real (4 byte data representation) */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_float, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
- *offset += 4;
- break;
- case TDS_DATA_TYPE_FLT8: /* Float (8 byte data representation) */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
- *offset += 8;
- break;
- case TDS_DATA_TYPE_MONEY4: /* SmallMoney (4 byte data representation) */
- case TDS_DATA_TYPE_DATETIM4: /* SmallDateTime (4 byte data representation) */
- /*TODO*/
- *offset += 4;
- break;
- case TDS_DATA_TYPE_MONEY: /* Money (8 byte data representation) */
- case TDS_DATA_TYPE_DATETIME: /* DateTime (8 byte data representation) */
- /*TODO*/
- *offset += 8;
- break;
-
-
- /* BYTELEN_TYPE - types prefixed with 1-byte length */
- case TDS_DATA_TYPE_GUID: /* UniqueIdentifier */
- length = tvb_get_guint8(tvb, *offset);
- length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
- switch(length) {
- case GEN_NULL: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA); break;
- case 16: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_guid, tvb, *offset + 1, length, ENC_LITTLE_ENDIAN); break;
- default: expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
- }
- *offset += 1 + length;
- break;
- case TDS_DATA_TYPE_BITN:
- length = tvb_get_guint8(tvb, *offset);
- length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
- switch(length) {
- case GEN_NULL: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA); break;
- case 1: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_boolean, tvb, *offset + 1, 1, ENC_LITTLE_ENDIAN); break;
- default: expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
- }
- *offset += 1 + length;
- break;
- case TDS_DATA_TYPE_INTN:
- length = tvb_get_guint8(tvb, *offset);
- length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
- switch(length) {
- case GEN_NULL: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA); break;
- case 1: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int1, tvb, *offset + 1, 1, ENC_LITTLE_ENDIAN); break;
- case 2: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int2, tvb, *offset + 1, 2, ENC_LITTLE_ENDIAN); break;
- case 4: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int4, tvb, *offset + 1, 4, ENC_LITTLE_ENDIAN); break;
- case 8: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int8, tvb, *offset + 1, 8, ENC_LITTLE_ENDIAN); break;
- default: expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
- }
- *offset += 1 + length;
- break;
- case TDS_DATA_TYPE_FLTN:
- length = tvb_get_guint8(tvb, *offset);
- length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
- switch(length) {
- case GEN_NULL: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA); break;
- case 4: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_float, tvb, *offset + 1, 4, ENC_LITTLE_ENDIAN); break;
- case 8: proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset + 1, 8, ENC_LITTLE_ENDIAN); break;
- default: expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
- }
- *offset += 1 + length;
- break;
- case TDS_DATA_TYPE_DECIMAL: /* Decimal (legacy support) */
- case TDS_DATA_TYPE_NUMERIC: /* Numeric (legacy support) */
- case TDS_DATA_TYPE_DECIMALN: /* Decimal */
- case TDS_DATA_TYPE_NUMERICN: /* Numeric */
- case TDS_DATA_TYPE_MONEYN:
- case TDS_DATA_TYPE_DATETIMN:
- case TDS_DATA_TYPE_DATEN: /* (introduced in TDS 7.3) */
- case TDS_DATA_TYPE_TIMEN: /* (introduced in TDS 7.3) */
- case TDS_DATA_TYPE_DATETIME2N: /* (introduced in TDS 7.3) */
- case TDS_DATA_TYPE_DATETIMEOFFSETN: /* (introduced in TDS 7.3) */
- case TDS_DATA_TYPE_CHAR: /* Char (legacy support) */
- case TDS_DATA_TYPE_VARCHAR: /* VarChar (legacy support) */
- case TDS_DATA_TYPE_BINARY: /* Binary (legacy support) */
- case TDS_DATA_TYPE_VARBINARY: /* VarBinary (legacy support) */
- length = tvb_get_guint8(tvb, *offset);
- proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
- *offset += 1;
- if(length > 0) {
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
- *offset += length;
- }
- break;
-
- /* USHORTLEN_TYPE - types prefixed with 2-byte length */
- case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
- case TDS_DATA_TYPE_BIGBINARY: /* Binary */
- case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
- case TDS_DATA_TYPE_BIGCHAR: /* Char */
- case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
- case TDS_DATA_TYPE_NCHAR: /* NChar */
- length = tvb_get_letohs(tvb, *offset);
- length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 2, length);
- *offset += 2;
- if(length == CHARBIN_NULL) {
- proto_item_append_text(length_item, " (CHARBIN_NULL)");
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
- }
- else {
- switch(data_type) {
- case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
- case TDS_DATA_TYPE_BIGBINARY: /* Binary */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
- break;
- case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
- case TDS_DATA_TYPE_BIGCHAR: /* Char */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_ASCII|ENC_NA);
- break;
- case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
- case TDS_DATA_TYPE_NCHAR: /* NChar */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- break;
- default:
- DISSECTOR_ASSERT_NOT_REACHED();
- }
- *offset += length;
- }
- break;
-
- /* LONGLEN_TYPE - types prefixed with 2-byte length */
- case TDS_DATA_TYPE_NTEXT: /* NText */
- case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
- case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
- case TDS_DATA_TYPE_TEXT: /* Text */
- case TDS_DATA_TYPE_IMAGE: /* Image */
- case TDS_DATA_TYPE_SSVARIANT: /* Sql_Variant (introduced in TDS 7.2) */
- length = tvb_get_letohl(tvb, *offset);
- length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 4, length);
- *offset += 4;
- if(length == CHARBIN_NULL32) {
- proto_item_append_text(length_item, " (CHARBIN_NULL)");
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
- }
- else {
- switch(data_type) {
- case TDS_DATA_TYPE_NTEXT: /* NText */
- proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
- break;
- default: /*TODO*/
- proto_tree_add_expert_format(sub_tree, pinfo, &ei_tds_type_info_type_undecoded, tvb, *offset, length, "Data type %d not supported yet", data_type);
- /* No point in continuing: we need to parse the full data_type to know where it ends */
- THROW(ReportedBoundsError);
- }
- *offset += length;
- }
- break;
- }
- proto_item_set_end(item, tvb, *offset);
-}
-
-static void
dissect_tds_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *item = NULL, *param_item = NULL;
@@ -2131,6 +3460,7 @@ dissect_tds_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case TDS_PROTOCOL_7_1:
case TDS_PROTOCOL_7_2:
case TDS_PROTOCOL_7_3:
+ case TDS_PROTOCOL_7_4:
default: /* unspecified: try as if TDS7 */
len = tvb_get_letohs(tvb, offset);
proto_tree_add_item(tree, hf_tds_rpc_name_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -2178,127 +3508,259 @@ dissect_tds_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(status_sub_tree, hf_tds_rpc_parameter_status_by_ref, tvb, offset, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(status_sub_tree, hf_tds_rpc_parameter_status_default, tvb, offset, 1, ENC_LITTLE_ENDIAN);
++offset;
- data_type = dissect_tds_type_info(tvb, &offset, pinfo, sub_tree, &plp);
- dissect_tds_type_varbyte(tvb, &offset, pinfo, sub_tree, hf_tds_rpc_parameter_value, data_type, plp);
+ data_type = dissect_tds_type_info(tvb, &offset, pinfo, sub_tree, &plp, FALSE);
+ dissect_tds_type_varbyte(tvb, &offset, pinfo, sub_tree, hf_tds_rpc_parameter_value, data_type, 0, plp, -1); /* TODO: Precision needs setting? */
proto_item_set_end(param_item, tvb, offset);
}
}
}
+static int
+dissect_tds_featureextack_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
+{
+ guint8 featureid;
+ gint featureackdatalen;
+ proto_tree *feature_tree = NULL;
+ proto_item * ti, * feature_item;
+ guint cur = offset;
+
+ while(tvb_reported_length_remaining(tvb, cur) > 0)
+ {
+ featureid = tvb_get_guint8(tvb, cur);
+ featureackdatalen = tvb_get_guint32(tvb, cur + 1, ENC_LITTLE_ENDIAN);
+
+ feature_item = proto_tree_add_item(tree, hf_tds_featureextack_feature, tvb, cur, featureid == 0xff ? 1 : 5 + featureackdatalen, ENC_NA);
+ feature_tree = proto_item_add_subtree(feature_item, ett_tds_col);
+
+ ti = proto_tree_add_item(feature_tree, hf_tds_featureextack_featureid, tvb, cur, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(ti, " (%s)", val_to_str(featureid, featureextack_feature_names, "Unknown"));
+ cur += 1;
+
+ if(featureid == 0xff)
+ break;
+
+ proto_tree_add_item(feature_tree, hf_tds_featureextack_featureackdatalen, tvb, cur, 4, ENC_LITTLE_ENDIAN);
+ cur += 4;
+
+ proto_tree_add_item(feature_tree, hf_tds_featureextack_featureackdata, tvb, cur, featureackdatalen, ENC_NA);
+ cur += featureackdatalen;
+ }
+
+ return cur - offset;
+}
+
+static int
+dissect_tds_sessionstate_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
+{
+ guint16 statelen;
+ guint cur = offset, len;
+
+ proto_tree_add_item_ret_uint(tree, hf_tds_sessionstate_length, tvb, cur, 4, ENC_LITTLE_ENDIAN, &len);
+ cur += 4;
+
+ proto_tree_add_item(tree, hf_tds_sessionstate_seqno, tvb, cur, 4, ENC_LITTLE_ENDIAN);
+ cur += 4;
+
+ proto_tree_add_item(tree, hf_tds_sessionstate_status, tvb, cur, 1, ENC_LITTLE_ENDIAN);
+ cur += 1;
+
+ while((cur - offset - 3) < len)
+ {
+ proto_tree_add_item(tree, hf_tds_sessionstate_stateid, tvb, cur, 1, ENC_LITTLE_ENDIAN);
+ cur += 1;
+
+ if(tvb_get_guint8(tvb, cur) == 0xFF)
+ {
+ cur += 1;
+ statelen = tvb_get_ntohs(tvb, cur + 2);
+ proto_tree_add_item(tree, hf_tds_sessionstate_statelen, tvb, cur, 2, ENC_LITTLE_ENDIAN);
+ cur += 2;
+ } else {
+ statelen = tvb_get_guint8(tvb, cur);
+ proto_tree_add_item(tree, hf_tds_sessionstate_statelen, tvb, cur, 1, ENC_LITTLE_ENDIAN);
+ cur += 1;
+ }
+
+ proto_tree_add_item(tree, hf_tds_sessionstate_statevalue, tvb, cur, statelen, ENC_NA);
+ cur += statelen;
+ }
+
+ return cur - offset;
+}
+
+static gint
+token_to_idx(guint8 token)
+{
+ /* TODO: Commented out entries are token types which are not currently dissected
+ * Although they are known values, we cannot step over the bytes as token length is unknown
+ * Better therefore to return unknown token type and highlight to user
+ */
+
+ switch(token)
+ {
+ /*case TDS7_ALTMETADATA_TOKEN: return hf_tds_altmetadata;*/
+ /*case TDS_ALTROW_TOKEN: return hf_tds_altrow;*/
+ /*case TDS_COL_NAME_TOKEN: return hf_tds_colname;*/
+ case TDS_COL_INFO_TOKEN: return hf_tds_colinfo;
+ case TDS7_COL_METADATA_TOKEN: return hf_tds_colmetadata;
+ case TDS_DONE_TOKEN: return hf_tds_done;
+ case TDS_DONEPROC_TOKEN: return hf_tds_doneproc;
+ case TDS_DONEINPROC_TOKEN: return hf_tds_doneinproc;
+ case TDS_ENVCHG_TOKEN: return hf_tds_envchg;
+ case TDS_ERR_TOKEN: return hf_tds_error;
+ case TDS_FEATUREEXTACK_TOKEN: return hf_tds_featureextack;
+ /*case TDS_FEDAUTHINFO_TOKEN: return hf_tds_fedauthinfo;*/
+ case TDS_INFO_TOKEN: return hf_tds_info;
+ case TDS_LOGIN_ACK_TOKEN: return hf_tds_loginack;
+ case TDS_NBCROW_TOKEN: return hf_tds_nbcrow;
+ case TDS_OFFSET_TOKEN: return hf_tds_offset;
+ case TDS_ORDER_TOKEN: return hf_tds_order;
+ case TDS_RET_STAT_TOKEN: return hf_tds_returnstatus;
+ /*case TDS_RETURNVAL_TOKEN: return hf_tds_returnvalue;*/
+ case TDS_ROW_TOKEN: return hf_tds_row;
+ case TDS_SESSIONSTATE_TOKEN: return hf_tds_sessionstate;
+ case TDS_SSPI_TOKEN: return hf_tds_sspi;
+ /*case TDS_TABNAME_TOKEN: return hf_tds_tabname;*/
+ /*case TDS_TVPROW_TOKEN: return hf_tds_tvprow;*/
+ }
+
+ return hf_tds_unknown_tds_token;
+}
+
static void
dissect_tds_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
{
- int offset = 0;
proto_item *token_item;
proto_tree *token_tree;
- guint pos, token_sz = 0;
- guint token_len_field_size = 2;
- guint token_len_field_val = 0;
+ guint pos = 0, token_sz = 0;
guint8 token;
struct _netlib_data nl_data;
- gint length_remaining;
memset(&nl_data, '\0', sizeof nl_data);
+ /* Test for pre-login response in case this response is not a token stream */
+ if(dissect_tds_prelogin_response(tvb, pos, tree) == 1)
+ {
+ return;
+ }
+
/*
* Until we reach the end of the packet, read tokens.
*/
- pos = offset;
while (tvb_reported_length_remaining(tvb, pos) > 0) {
/* our token */
token = tvb_get_guint8(tvb, pos);
- /* TODO Handle TDS_PARAMFMT, TDS_PARAMS [similar to TDS_RESULTS, TDS_ROW] */
- if (tds_token_is_fixed_size(token)) {
- token_sz = tds_get_fixed_token_size(token, tds_info) + 1;
- } else if (token == TDS_ROW_TOKEN) {
- /*
- * Rows are special; they have no size field and
- * aren't fixed length.
- */
- token_sz = tds_get_row_size(tvb, &nl_data, pos + 1);
- } else
- token_sz = tds_get_variable_token_size(tvb, pos + 1,
- token, &token_len_field_size, &token_len_field_val);
-
- length_remaining = tvb_reported_length_remaining(tvb, pos);
+ token_item = proto_tree_add_item(tree, token_to_idx(token), tvb, pos, tvb_reported_length_remaining(tvb, pos), ENC_NA);
+ token_tree = proto_item_add_subtree(token_item, ett_tds_type_varbyte);
- token_tree = proto_tree_add_subtree_format(tree, tvb, pos, token_sz,
- ett_tds_token, &token_item, "Token 0x%02x %s", token,
- val_to_str_const(token, token_names, "Unknown Token Type"));
- if ((int) token_sz < 0) {
- expert_add_info_format(pinfo, token_item, &ei_tds_token_length_invalid, "Bogus token size: %u", token_sz);
- break;
- }
+ if(TDS_PROTO_TDS4)
+ {
+ guint8 nomatch = 0;
+
+ switch (token) {
+ case TDS_COL_NAME_TOKEN:
+ /*
+ * TDS 4.2
+ * TODO dissect token to get "column names" to fill in _netlib_data
+ */
+ break;
- if ((int) token_len_field_size < 0) {
- expert_add_info_format(pinfo, token_item, &ei_tds_token_length_invalid, "Bogus token length field size: %u", token_len_field_size);
- break;
- }
+ case TDS_COL_INFO_TOKEN:
+ /*
+ * TDS 4.2: get the column info
+ */
+ dissect_tds_col_info_token(tvb, &nl_data, pos);
+ break;
- /*
- * If it's a variable token, put the length field in here
- * instead of replicating this for each token subdissector.
- */
- if (!tds_token_is_fixed_size(token) && token != TDS_ROW_TOKEN) {
- token_item = proto_tree_add_uint(token_tree, hf_tds_token_len, tvb, pos + 1, 1, token_len_field_val);
- proto_item_set_len(token_item, token_len_field_size);
- }
+ case TDS_RESULT_TOKEN:
+ /*
+ * If it's a result token, we need to stash the
+ * column info.
+ */
+ read_results_tds5_token(tvb, &nl_data, pos + 3);
+ break;
- if (token_sz > (guint)length_remaining)
- token_sz = (guint)length_remaining;
+ case TDS_AUTH_TOKEN:
+ dissect_tds_nt(tvb, pinfo, token_tree, pos + 3, token_sz - 3);
+ break;
- switch (token) {
+ default:
+ nomatch = 1;
+ break;
+ }
- case TDS_COL_NAME_TOKEN:
- /*
- * TDS 4.2
- * TODO dissect token to get "column names" to fill in _netlib_data
- */
+ if(nomatch)
+ {
break;
+ }
- case TDS_COL_INFO_TOKEN:
- /*
- * TDS 4.2: get the column info
- */
- dissect_tds_col_info_token(tvb, &nl_data, pos);
- break;
+ } else {
- case TDS_RESULT_TOKEN:
- /*
- * If it's a result token, we need to stash the
- * column info.
- */
- read_results_tds5(tvb, &nl_data, pos + 3, token_sz - 3);
- break;
+ /* Tokens from MS-TDS specification, revision 18.0 (up to TDS 7.4) */
+ switch (token) {
+ case TDS7_COL_METADATA_TOKEN:
+ token_sz = dissect_tds7_colmetadata_token(tvb, &nl_data, pos + 1, token_tree, tds_info) + 1;
+ break;
+ case TDS_DONE_TOKEN:
+ token_sz = dissect_tds_done_token(tvb, pos + 1, token_tree, tds_info) + 1;
+ break;
+ case TDS_DONEPROC_TOKEN:
+ token_sz = dissect_tds_doneproc_token(tvb, pos + 1, token_tree, tds_info) + 1;
+ break;
+ case TDS_DONEINPROC_TOKEN:
+ token_sz = dissect_tds_doneinproc_token(tvb, pos + 1, token_tree, tds_info) + 1;
+ break;
+ case TDS_ENVCHG_TOKEN:
+ token_sz = dissect_tds_envchg_token(tvb, pos + 1, token_tree) + 1;
+ break;
+ case TDS_ERR_TOKEN:
+ token_sz = dissect_tds_error_token(tvb, pos + 1, token_tree, tds_info) + 1;
+ break;
+ case TDS_INFO_TOKEN:
+ token_sz = dissect_tds_info_token(tvb, pos + 1, token_tree, tds_info) + 1;
+ break;
+ case TDS_FEATUREEXTACK_TOKEN:
+ token_sz = dissect_tds_featureextack_token(tvb, pos + 1, token_tree) + 1;
+ break;
+ case TDS_LOGIN_ACK_TOKEN:
+ token_sz = dissect_tds_login_ack_token(tvb, pos + 1, token_tree, tds_info) + 1;
+ break;
+ case TDS_NBCROW_TOKEN:
+ token_sz = dissect_tds_nbc_row_token(tvb, pinfo, &nl_data, pos + 1, token_tree) + 1;
+ break;
+ case TDS_OFFSET_TOKEN:
+ token_sz = dissect_tds_offset_token(tvb, pos + 1, token_tree) + 1;
+ break;
+ case TDS_ORDER_TOKEN:
+ token_sz = dissect_tds_order_token(tvb, pos + 1, token_tree) + 1;
+ break;
+ case TDS_RET_STAT_TOKEN:
+ token_sz = dissect_tds_returnstatus_token(tvb, pos + 1, token_tree) + 1;
+ break;
+ case TDS_ROW_TOKEN:
+ token_sz = dissect_tds_row_token(tvb, pinfo, &nl_data, pos + 1, token_tree) + 1;
+ break;
+ case TDS_SESSIONSTATE_TOKEN:
+ token_sz = dissect_tds_sessionstate_token(tvb, pos + 1, token_tree) + 1;
+ break;
+ case TDS_SSPI_TOKEN:
+ token_sz = dissect_tds_sspi_token(tvb, pos + 1, token_tree) + 1;
+ break;
+ default:
+ token_sz = 0;
+ break;
+ }
- case TDS_ENV_CHG_TOKEN:
- dissect_tds_env_chg(tvb, pos + 3, token_sz - 3, token_tree);
+ /* Move on if nothing identifiable found */
+ if(token_sz == 0)
break;
- case TDS_AUTH_TOKEN:
- dissect_tds_nt(tvb, pinfo, token_tree, pos + 3, token_sz - 3);
- break;
- case TDS_ERR_TOKEN:
- case TDS_MSG_TOKEN:
- dissect_tds_err_token(tvb, pos + 3, token_sz - 3, token_tree, tds_info);
- break;
+ proto_item_set_len(token_item, token_sz);
- case TDS_DONE_TOKEN:
- case TDS_DONEPROC_TOKEN:
- case TDS_DONEINPROC_TOKEN:
- dissect_tds_done_token(tvb, pos + 1, token_tree, tds_info);
- break;
- case TDS_LOGIN_ACK_TOKEN:
- dissect_tds_login_ack_token(tvb, pinfo, pos + 3, token_sz - 3, token_tree, tds_info);
- break;
- case TDS7_RESULT_TOKEN:
- pos = (dissect_tds7_results_token(tvb, pos + 1, token_tree, tds_info)-1);
- break;
+ /* and step to the end of the token, rinse, lather, repeat */
+ pos += token_sz;
}
-
- /* and step to the end of the token, rinse, lather, repeat */
- pos += token_sz;
}
}
@@ -2313,13 +3775,19 @@ dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint8 status;
guint16 channel;
guint8 packet_number;
- gboolean save_fragmented;
+ gboolean save_fragmented, last_buffer;
int len;
fragment_head *fd_head;
tvbuff_t *next_tvb;
conversation_t *conv;
tds_conv_info_t *tds_info;
+ if(detect_tls(tvb))
+ {
+ proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_prelogin, NULL, "TDS Pre-Login Packet - TLS exchange");
+ return;
+ }
+
conv = find_or_create_conversation(pinfo);
tds_info = (tds_conv_info_t*)conversation_get_proto_data(conv, proto_tds);
if (!tds_info) {
@@ -2358,20 +3826,29 @@ dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*
*/
save_fragmented = pinfo->fragmented;
- if (tds_defragment &&
- (packet_number > 1 || (status & STATUS_LAST_BUFFER) == 0)) {
- if ((status & STATUS_LAST_BUFFER) == 0) {
- col_append_str(pinfo->cinfo, COL_INFO,
- " (Not last buffer)");
+
+ if (tds_defragment && (packet_number > 1 || (status & STATUS_LAST_BUFFER) == 0)) {
+
+ if (((status & STATUS_LAST_BUFFER) == 0)) {
+ col_append_str(pinfo->cinfo, COL_INFO, " (Not last buffer)");
}
len = tvb_reported_length_remaining(tvb, offset);
/*
* XXX - I've seen captures that start with a login
* packet with a sequence number of 2.
*/
+
+ last_buffer = ((status & STATUS_LAST_BUFFER) == 1);
+ /*
+ if(tvb_reported_length(tvb) == tvb_captured_length(tvb))
+ {
+ last_buffer = TRUE;
+ }
+ */
+
fd_head = fragment_add_seq_check(&tds_reassembly_table, tvb, offset,
pinfo, channel, NULL,
- packet_number - 1, len, (status & STATUS_LAST_BUFFER) == 0);
+ packet_number - 1, len, !last_buffer);
next_tvb = process_reassembled_data(tvb, offset, pinfo,
"Reassembled TDS", fd_head, &tds_frag_items, NULL,
tds_tree);
@@ -2387,8 +3864,10 @@ dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* of a fragmented message, but we'd need to do reassembly
* in order to discover that.)
*/
- if ((status & STATUS_LAST_BUFFER) == 0)
+ if (((status & STATUS_LAST_BUFFER) == 0))
+ {
next_tvb = NULL;
+ }
else {
next_tvb = tvb_new_subset_remaining(tvb, offset);
}
@@ -2401,11 +3880,9 @@ dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case TDS_RPC_PKT:
dissect_tds_rpc(next_tvb, pinfo, tds_tree);
break;
-
case TDS_RESP_PKT:
dissect_tds_resp(next_tvb, pinfo, tds_tree, tds_info);
break;
-
case TDS_LOGIN7_PKT:
dissect_tds7_login(next_tvb, pinfo, tds_tree);
break;
@@ -2418,8 +3895,17 @@ dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case TDS_SSPI_PKT:
dissect_tds_nt(next_tvb, pinfo, tds_tree, offset - 8, -1);
break;
+ case TDS_TRANS_MGR_PKT:
+ dissect_tds_transmgr_packet(next_tvb, pinfo, tds_tree);
+ break;
+ case TDS_ATTENTION_PKT:
+ break;
+ case TDS_PRELOGIN_PKT:
+ dissect_tds7_prelogin_packet(next_tvb, tds_tree);
+ break;
+
default:
- proto_tree_add_item(tds_tree, hf_tds_tds_packet, next_tvb, 0, -1, ENC_NA);
+ proto_tree_add_item(tds_tree, hf_tds_unknown_tds_packet, next_tvb, 0, -1, ENC_NA);
break;
}
} else {
@@ -2429,20 +3915,21 @@ dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->fragmented = save_fragmented;
}
-static void
-dissect_tds_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_tds_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_)
{
volatile gboolean first_time = TRUE;
volatile int offset = 0;
guint length_remaining;
guint8 type;
- guint16 plen;
+ volatile guint16 plen;
guint length;
tvbuff_t *volatile next_tvb;
proto_item *tds_item = NULL;
proto_tree *tds_tree = NULL;
while ((length_remaining = tvb_reported_length_remaining(tvb, offset)) > 0) {
+
/*
* Can we do reassembly?
*/
@@ -2461,16 +3948,19 @@ dissect_tds_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/
pinfo->desegment_offset = offset;
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
- return;
+ return tvb_captured_length(tvb);
}
}
type = tvb_get_guint8(tvb, offset);
- /*
- * Get the length of the PDU.
- */
- plen = tvb_get_ntohs(tvb, offset + 2);
+ /* Special test for TLS to that we don't have lots of incorrect reports of malformed packets */
+ if(type == TDS_TLS_PKT)
+ {
+ plen = tvb_get_ntohs(tvb, offset + 3) + 5;
+ } else
+ plen = tvb_get_ntohs(tvb, offset + 2);
+
if (plen < 8) {
/*
* The length is less than the header length.
@@ -2486,10 +3976,14 @@ dissect_tds_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ett_tds);
proto_tree_add_uint(tds_tree, hf_tds_type, tvb,
offset, 1, type);
- proto_tree_add_item(tds_tree, hf_tds_status,
+
+ if(type != TDS_TLS_PKT)
+ {
+ proto_tree_add_item(tds_tree, hf_tds_status,
tvb, offset + 1, 1, ENC_BIG_ENDIAN);
- tds_item = proto_tree_add_uint(tds_tree, hf_tds_length, tvb, offset + 2, 2, plen);
- expert_add_info_format(pinfo, tds_item, &ei_tds_invalid_length, "bogus, should be >= 8");
+ tds_item = proto_tree_add_uint(tds_tree, hf_tds_length, tvb, offset + 2, 2, plen);
+ expert_add_info_format(pinfo, tds_item, &ei_tds_invalid_length, "bogus, should be >= 8");
+ }
}
/*
@@ -2515,7 +4009,7 @@ dissect_tds_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/
pinfo->desegment_offset = offset;
pinfo->desegment_len = plen - length_remaining;
- return;
+ return tvb_captured_length(tvb);
}
}
@@ -2579,10 +4073,12 @@ dissect_tds_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/
offset += plen;
}
+
+ return tvb_captured_length(tvb);
}
static gboolean
-dissect_tds_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+dissect_tds_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
int offset = 0;
guint8 type;
@@ -2657,7 +4153,8 @@ dissect_tds_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
/*
* Now dissect it as TDS.
*/
- dissect_tds_tcp(tvb, pinfo, tree);
+ dissect_tds_message(tvb, pinfo, tree, data);
+
return TRUE;
}
@@ -2670,6 +4167,7 @@ tds_init(void)
* XXX - should fragments be reassembled across multiple TCP
* connections?
*/
+
reassembly_table_init(&tds_reassembly_table,
&addresses_ports_reassembly_table_functions);
}
@@ -2680,6 +4178,13 @@ tds_cleanup(void)
reassembly_table_destroy(&tds_reassembly_table);
}
+static void
+version_convert( gchar *result, guint32 hexver )
+{
+ g_snprintf( result, ITEM_LABEL_LENGTH, "%d.%d.%d.%d",
+ (hexver >> 24) & 0xFF, (hexver >> 16) & 0xFF, (hexver >> 8) & 0xFF, hexver & 0xFF);
+}
+
/* Register the protocol with Wireshark */
/* this format is required because a script is used to build the C function
@@ -2690,499 +4195,1286 @@ void
proto_register_tds(void)
{
static hf_register_info hf[] = {
- { &hf_tds_type,
- { "Type", "tds.type",
- FT_UINT8, BASE_DEC, VALS(packet_type_names), 0x0,
- "Packet type", HFILL }
+
+ /************************ Token definitions ************************/
+
+ /* ALTMETADATA token */
+
+ /* ALTROW token */
+
+ /* COLINFO token (TDS_COL_INFO_TOKEN) */
+ { &hf_tds_colinfo,
+ { "Token - ColInfo", "tds.colinfo",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_status,
- { "Status", "tds.status",
- FT_UINT8, BASE_HEX, NULL, 0x0,
- "Packet status", HFILL }
+
+ /* COLMETADATA token (TDS7_COL_METADATA_TOKEN) */
+ { &hf_tds_colmetadata,
+ { "Token - ColumnMetaData", "tds.colmetadata",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_status_eom,
- { "End of message", "tds.status.eom",
- FT_BOOLEAN, 8, NULL, STATUS_LAST_BUFFER,
- "The packet is the last packet in the whole request", HFILL }
+ { &hf_tds_colmetadata_columns,
+ { "Columns", "tds.colmetadata.columns",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_status_ignore,
- { "Ignore this event", "tds.status.ignore",
- FT_BOOLEAN, 8, NULL, STATUS_IGNORE_EVENT,
- "(From client to server) Ignore this event (EOM MUST also be set)", HFILL }
+ { &hf_tds_colmetadata_usertype32,
+ { "Usertype", "tds.colmetadata.usertype",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_status_event_notif,
- { "Event notification", "tds.status.event_notif",
- FT_BOOLEAN, 8, NULL, STATUS_EVENT_NOTIFICATION,
+ { &hf_tds_colmetadata_usertype16,
+ { "Usertype", "tds.colmetadata.usertype",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_status_reset_conn,
- { "Reset connection", "tds.status.reset_conn",
- FT_BOOLEAN, 8, NULL, STATUS_RESETCONNECTION,
- "(From client to server) Reset this connection before processing event", HFILL }
+ { &hf_tds_colmetadata_results_token_flags,
+ { "Flags", "tds.colmetadata.results_token_flags",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_status_reset_conn_skip_tran,
- { "Reset connection keeping transaction state", "tds.status.reset_conn_skip_tran",
- FT_BOOLEAN, 8, NULL, STATUS_RESETCONNECTIONSKIPTRAN,
- "(From client to server) Reset the connection before processing event but do not modify the transaction state", HFILL }
+ { &hf_tds_colmetadata_results_token_type,
+ { "Type", "tds.colmetadata.results_token_type",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_length,
- { "Length", "tds.length",
+ { &hf_tds_colmetadata_csize,
+ { "Type size", "tds.colmetadata.type_size",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_large_type_size,
+ { "Large type size", "tds.colmetadata.large_type_size",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_collate_codepage,
+ { "Collate codepage", "tds.colmetadata.collate_codepage",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "Packet length", HFILL }
+ NULL, HFILL }
},
- { &hf_tds_channel,
- { "Channel", "tds.channel",
+ { &hf_tds_colmetadata_collate_flags,
+ { "Collate flags", "tds.colmetadata.collate_flags",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_collate_charset_id,
+ { "Collate charset ID", "tds.colmetadata.collate_charset_id",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_precision,
+ { "Precision", "tds.colmetadata.precision",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_scale,
+ { "Scale", "tds.colmetadata.scale",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_colname_length,
+ { "Column name length", "tds.colmetadata.colname_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_colname,
+ { "Column Name", "tds.colmetadata.colname",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_table_name_parts,
+ { "Table name parts", "tds.colmetadata.table_name_parts",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_table_name,
+ { "Table name", "tds.colmetadata.table_name",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_table_name_length,
+ { "Table name length", "tds.colmetadata.table_name_length",
FT_UINT16, BASE_DEC, NULL, 0x0,
- "Channel Number", HFILL }
+ NULL, HFILL }
},
- { &hf_tds_packet_number,
- { "Packet Number", "tds.packet_number",
+ { &hf_tds_colmetadata_field,
+ { "Field", "tds.colmetadata.field",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_nullable,
+ { "Nullable", "tds.colmetadata.flags.nullable",
+ FT_BOOLEAN, 16, NULL, 0x8000,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_casesen,
+ { "Case sensitive", "tds.colmetadata.flags.casesen",
+ FT_BOOLEAN, 16, NULL, 0x4000,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_updateable,
+ { "Updateable", "tds.colmetadata.flags.updateable",
+ FT_BOOLEAN, 16, NULL, 0x3000,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_identity,
+ { "Identity", "tds.colmetadata.flags.identity",
+ FT_BOOLEAN, 16, NULL, 0x0800,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_computed,
+ { "Computed", "tds.colmetadata.flags.computed",
+ FT_BOOLEAN, 16, NULL, 0x0400,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_reservedodbc,
+ { "Reserved ODBC", "tds.colmetadata.flags.reservedodbc",
+ FT_BOOLEAN, 16, NULL, 0x0300,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_fixedlenclrtype,
+ { "Fixed length CLR type", "tds.colmetadata.flags.fixedlenclrtype",
+ FT_BOOLEAN, 16, NULL, 0x0080,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_sparsecolumnset,
+ { "Sparse column set", "tds.colmetadata.flags.sparsecolumnset",
+ FT_BOOLEAN, 16, NULL, 0x0020,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_encrypted,
+ { "Encrypted", "tds.colmetadata.flags.encrypted",
+ FT_BOOLEAN, 16, NULL, 0x0010,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_hidden,
+ { "Hidden", "tds.colmetadata.flags.hidden",
+ FT_BOOLEAN, 16, NULL, 0x0004,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_key,
+ { "Flags", "tds.colmetadata.flags.key",
+ FT_BOOLEAN, 16, NULL, 0x0002,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_flags_nullableunknown,
+ { "Nullable unknown", "tds.colmetadata.flags.nullableunknown",
+ FT_BOOLEAN, 16, NULL, 0x0001,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_maxbytesize,
+ { "Max byte size", "tds.colmetadata.maxbytesize",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_dbname_length,
+ { "Database name length", "tds.colmetadata.dbname_length",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_window,
- { "Window", "tds.window",
+ { &hf_tds_colmetadata_dbname,
+ { "Database name length", "tds.colmetadata.dbname",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_schemaname_length,
+ { "Schema name length", "tds.colmetadata.schemaname_length",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_collate_codepage,
- { "Codepage", "tds.collate_codepage",
+ { &hf_tds_colmetadata_schemaname,
+ { "Schema name", "tds.colmetadata.schemaname",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_typename_length,
+ { "Type name length", "tds.colmetadata.typename_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_typename,
+ { "Type name", "tds.colmetadata.typename",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_assemblyqualifiedname_length,
+ { "Assembly qualified name length", "tds.colmetadata.assemblyqualifiedname_length",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_collate_flags,
- { "Flags", "tds.collate_flags",
- FT_UINT16, BASE_HEX, NULL, 0x0,
+ { &hf_tds_colmetadata_assemblyqualifiedname,
+ { "Assembly qualified name", "tds.colmetadata.assemblyqualifiedname",
+ FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_collate_charset_id,
- { "Charset ID", "tds.collate_charset_id",
+ { &hf_tds_colmetadata_owningschema_length,
+ { "Owning schema name length", "tds.colmetadata.owningschema_length",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_table_name,
- { "Table name", "tds.table_name",
+ { &hf_tds_colmetadata_owningschema,
+ { "Owning schema name", "tds.colmetadata.owningschema",
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_text,
- { "Text", "tds.text",
+ { &hf_tds_colmetadata_xmlschemacollection_length,
+ { "XML schema collection length", "tds.colmetadata.xmlschemacollection_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_colmetadata_xmlschemacollection,
+ { "XML schema collection", "tds.colmetadata.xmlschemacollection",
FT_STRING, STR_UNICODE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_fragment_overlap,
- { "Segment overlap", "tds.fragment.overlap",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "Fragment overlaps with other fragments", HFILL }
+
+ /* DONE token (TDS_DONE_TOKEN) */
+ { &hf_tds_done,
+ { "Token - Done", "tds.done",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_fragment_overlap_conflict,
- { "Conflicting data in fragment overlap", "tds.fragment.overlap.conflict",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "Overlapping fragments contained conflicting data", HFILL }
+ { &hf_tds_done_donerowcount_64,
+ { "Row count", "tds.done.donerowcount",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_fragment_multiple_tails,
- { "Multiple tail fragments found", "tds.fragment.multipletails",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "Several tails were found when defragmenting the packet", HFILL }
+ { &hf_tds_done_donerowcount_32,
+ { "Row count", "tds.done.donerowcount",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_fragment_too_long_fragment,
- { "Segment too long", "tds.fragment.toolongfragment",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "Segment contained data past end of packet", HFILL }
+ { &hf_tds_done_status,
+ { "Status flags", "tds.done.status",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_fragment_error,
- { "Defragmentation error", "tds.fragment.error",
- FT_FRAMENUM, BASE_NONE, NULL, 0x0,
- "Defragmentation error due to illegal fragments", HFILL }
+ { &hf_tds_done_curcmd,
+ { "Operation", "tds.done.curcmd",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_fragment_count,
- { "Segment count", "tds.fragment.count",
+
+ /* DONEPROC token (TDS_DONEPROC_TOKEN - implemented the same as TDS_DONE_TOKEN) */
+ { &hf_tds_doneproc,
+ { "Token - DoneProc", "tds.doneproc",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_doneproc_donerowcount_64,
+ { "Row count", "tds.doneproc.donerowcount",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_doneproc_donerowcount_32,
+ { "Row count", "tds.doneproc.donerowcount",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_fragment,
- { "TDS Fragment", "tds.fragment",
- FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ { &hf_tds_doneproc_status,
+ { "Status flags", "tds.doneproc.status",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_fragments,
- { "TDS Fragments", "tds.fragments",
+ { &hf_tds_doneproc_curcmd,
+ { "Operation", "tds.doneproc.curcmd",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* DONEINPROC token (TDS_DONEINPROC_TOKEN - implemented the same as TDS_DONE_TOKEN) */
+ { &hf_tds_doneinproc,
+ { "Token - DoneInProc", "tds.doneinproc",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_reassembled_in,
- { "Reassembled TDS in frame", "tds.reassembled_in",
- FT_FRAMENUM, BASE_NONE, NULL, 0x0,
- "This TDS packet is reassembled in this frame", HFILL }
+ { &hf_tds_doneinproc_donerowcount_64,
+ { "Row count", "tds.doneinproc.donerowcount",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_reassembled_length,
- { "Reassembled TDS length", "tds.reassembled.length",
+ { &hf_tds_doneinproc_donerowcount_32,
+ { "Row count", "tds.doneinproc.donerowcount",
FT_UINT32, BASE_DEC, NULL, 0x0,
- "The total length of the reassembled payload", HFILL }
+ NULL, HFILL }
+ },
+ { &hf_tds_doneinproc_status,
+ { "Status flags", "tds.doneinproc.status",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_doneinproc_curcmd,
+ { "Operation", "tds.doneinproc.curcmd",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* ENVCHANGE token (TDS_ENVCHG_TOKEN) */
+ { &hf_tds_envchg,
+ { "Token - EnvChange", "tds.envchange",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_length,
+ { "Token length", "tds.envchange.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_type,
+ { "Type", "tds.envchange.type",
+ FT_UINT8, BASE_DEC, VALS(envchg_names), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_newvalue_length,
+ { "New Value Length", "tds.envchange.newvalue_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_newvalue_string,
+ { "New Value", "tds.envchange.newvalue",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_newvalue_bytes,
+ { "New Value", "tds.envchange.newvalue",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_oldvalue_length,
+ { "Old Value Length", "tds.envchange.oldvalue_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_oldvalue_string,
+ { "Old Value", "tds.envchange.oldvalue",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_oldvalue_bytes,
+ { "Old Value", "tds.envchange.oldvalue",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_collate_codepage,
+ { "Collate codepage", "tds.envchange.collate_codepage",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_collate_flags,
+ { "Collate flags", "tds.envchange.collate_flags",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_envchg_collate_charset_id,
+ { "Collate charset ID", "tds.envchange.collate_charset_id",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* ERROR token (TDS_ERR_TOKEN) */
+ { &hf_tds_error,
+ { "Token - Error", "tds.error",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_length,
+ { "Token length", "tds.error.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_number,
+ { "SQL Error Number", "tds.error.number",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_state,
+ { "State", "tds.error.state",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_class,
+ { "Class (Severity)", "tds.error.class",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_msgtext_length,
+ { "Error message length", "tds.error.msgtext_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_msgtext,
+ { "Error message", "tds.error.msgtext",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_servername_length,
+ { "Server name length", "tds.error.servername_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_servername,
+ { "Server name", "tds.error.servername",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_procname_length,
+ { "Process name length", "tds.error.procname_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_procname,
+ { "Process name", "tds.error.procname",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_linenumber_16,
+ { "Line number", "tds.error.linenumber",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_error_linenumber_32,
+ { "Line number", "tds.error.linenumber",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* FEATUREEXTACK token (TDS_FEATUREEXTACK_TOKEN) */
+ { &hf_tds_featureextack,
+ { "Token - FeatureExtAct", "tds.featureextack",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_featureextack_feature,
+ { "Feature", "tds.featureextack.feature",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_featureextack_featureid,
+ { "Feature ID", "tds.featureextack.featureid",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_featureextack_featureackdatalen,
+ { "Feature length", "tds.featureextack.featureackdatalen",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_featureextack_featureackdata,
+ { "Feature data", "tds.featureextack.featureackdata",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* FEDAUTHINFO token */
+
+ /* INFO token */
+ { &hf_tds_info,
+ { "Token - Info", "tds.info",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_length,
+ { "Token length", "tds.info.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_number,
+ { "SQL Error Number", "tds.info.number",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_state,
+ { "State", "tds.info.state",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_class,
+ { "Class (Severity)", "tds.info.class",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_msgtext_length,
+ { "Error message length", "tds.info.msgtext_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_msgtext,
+ { "Error message", "tds.info.msgtext",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_servername_length,
+ { "Server name length", "tds.info.servername_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_servername,
+ { "Server name", "tds.info.servername",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_procname_length,
+ { "Process name length", "tds.info.procname_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_procname,
+ { "Process name", "tds.info.procname",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_linenumber_16,
+ { "Line number", "tds.info.linenumber",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_info_linenumber_32,
+ { "Line number", "tds.info.linenumber",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* LOGINACK token (TDS_LOGIN_ACK_TOKEN) */
+ { &hf_tds_loginack,
+ { "Token - LoginAck", "tds.loginack",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_loginack_length,
+ { "Token length", "tds.loginack.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_loginack_interface,
+ { "Interface", "tds.loginack.interface",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_loginack_tdsversion,
+ { "TDS version", "tds.loginack.tdsversion",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_loginack_progversion,
+ { "Server Version", "tds.loginack.progversion",
+ FT_UINT32, BASE_CUSTOM, CF_FUNC(version_convert), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_loginack_progname,
+ { "Server name", "tds.loginack.progname",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* NBCROW token (TDS_NBCROW_TOKEN) */
+ { &hf_tds_nbcrow,
+ { "Token - NBCRow", "tds.nbcrow",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* OFFSET token */
+ { &hf_tds_offset,
+ { "Token - Offset", "tds.offset",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_offset_id,
+ { "Offset ID", "tds.offset.id",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_offset_len,
+ { "Offset length", "tds.offset.len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* ORDER token (TDS_ORDER_TOKEN) */
+ { &hf_tds_order,
+ { "Token - Order", "tds.order",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_order_length,
+ { "Token length", "tds.order.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_order_colnum,
+ { "Order column", "tds.order.colnum",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* RETURNSTATUS token (TDS_RET_STAT_TOKEN) */
+ { &hf_tds_returnstatus,
+ { "Token - ReturnStatus", "tds.returnstatus",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_returnstatus_value,
+ { "Value", "tds.returnstatus.value",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* RETURNVALUE token (TDS_RETURNVAL_TOKEN) */
+
+ /* ROW token (TDS_ROW_TOKEN) */
+ { &hf_tds_row,
+ { "Token - Row", "tds.row",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_row_field,
+ { "Field", "tds.row.field",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* SESSIONSTATE token (TDS_SESSIONSTATE_TOKEN) */
+ { &hf_tds_sessionstate,
+ { "Token - Session state", "tds.sessionstate",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_sessionstate_length,
+ { "Token length", "tds.sessionstate.length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_sessionstate_seqno,
+ { "Sequence number", "tds.sessionstate.seqno",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_sessionstate_status,
+ { "Status", "tds.sessionstate.status",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_sessionstate_stateid,
+ { "State ID", "tds.sessionstate.stateid",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_sessionstate_statelen,
+ { "State Length", "tds.sessionstate.statelen",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_sessionstate_statevalue,
+ { "State Value", "tds.sessionstate.statevalue",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* SSPI token */
+ { &hf_tds_sspi,
+ { "Token - SSPI", "tds.sspi",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_sspi_buffer,
+ { "State Value", "tds.sspi.buffer",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* TABNAME token */
+
+ /* TVPROW Token */
+
+ /* TDS5 Lang Token */
+ { &hf_tds_lang_token_status,
+ { "Status", "tds.lang.token_status",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_lang_language_text,
+ { "Language text", "tds.lang.language_text",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds7_login_total_size,
+
+ /* Unknown token type */
+ { &hf_tds_unknown_tds_token,
+ { "Token - Unknown", "tds.unknown_tds_token",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /************************ Message definitions ***********************/
+
+ /* Bulk Load BCP stream */
+
+ /* Bulk Load Update Text/Write Text */
+
+ /* Federated Authentication Token */
+
+ /* LOGIN7 Token */
+ { &hf_tds7login_total_size,
{ "Total Packet Length", "tds.7login.total_len",
FT_UINT32, BASE_DEC, NULL, 0x0,
"TDS7 Login Packet total packet length", HFILL }
},
- { &hf_tds7_version,
+ { &hf_tds7login_version,
{ "TDS version", "tds.7login.version",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_packet_size,
+ { &hf_tds7login_packet_size,
{ "Packet Size", "tds.7login.packet_size",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_client_version,
+ { &hf_tds7login_client_version,
{ "Client version", "tds.7login.client_version",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_client_pid,
+ { &hf_tds7login_client_pid,
{ "Client PID", "tds.7login.client_pid",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_connection_id,
+ { &hf_tds7login_connection_id,
{ "Connection ID", "tds.7login.connection_id",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_option_flags1,
+ { &hf_tds7login_option_flags1,
{ "Option Flags 1", "tds.7login.option_flags1",
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_option_flags2,
+ { &hf_tds7login_option_flags2,
{ "Option Flags 2", "tds.7login.option_flags2",
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_sql_type_flags,
+ { &hf_tds7login_sql_type_flags,
{ "SQL Type Flags", "tds.7login.sql_type_flags",
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_reserved_flags,
+ { &hf_tds7login_reserved_flags,
{ "Reserved Flags", "tds.7login.reserved_flags",
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_time_zone,
+ { &hf_tds7login_time_zone,
{ "Time Zone", "tds.7login.time_zone",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_collation,
+ { &hf_tds7login_collation,
{ "Collation", "tds.7login.collation",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds7_loginack_version,
- { "TDS version", "tds.7loginack.version",
- FT_UINT32, BASE_HEX, NULL, 0x0,
+ { &hf_tds7login_offset,
+ { "Offset", "tds.7login.offset",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_all_headers,
- { "Packet data stream headers", "tds.all_headers",
+ { &hf_tds7login_length,
+ { "Length", "tds.7login.length",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds7login_password,
+ { "Password", "tds.7login.password",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* PRELOGIN stream */
+
+ { &hf_tds_prelogin,
+ { "Pre-Login Message", "tds.prelogin",
FT_NONE, BASE_NONE, NULL, 0x0,
- "The ALL_HEADERS rule", HFILL }
+ NULL, HFILL }
},
- { &hf_tds_all_headers_total_length,
- { "Total length", "tds.all_headers.total_length",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "Total length of ALL_HEADERS stream", HFILL }
+ { &hf_tds_prelogin_option_token,
+ { "Option Token", "tds.prelogin.option.token",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_all_headers_header_length,
- { "Length", "tds.all_headers.header.length",
+ { &hf_tds_prelogin_option_offset,
+ { "Option offset", "tds.prelogin.option.offset",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_prelogin_option_length,
+ { "Option length", "tds.prelogin.option.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_prelogin_option_version,
+ { "Version", "tds.prelogin.option.version",
FT_UINT32, BASE_DEC, NULL, 0x0,
- "Total length of an individual header", HFILL }
+ NULL, HFILL }
},
- { &hf_tds_all_headers_header_type,
- { "Type", "tds.all_headers.header.type",
- FT_UINT16, BASE_HEX, VALS(header_type_names), 0x0,
+ { &hf_tds_prelogin_option_subbuild,
+ { "Sub-build", "tds.prelogin.option.subbuild",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_all_headers_trans_descr,
- { "Transaction descriptor", "tds.all_headers.header.trans_descr",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- "For each connection, a number that uniquely identifies the transaction the request is associated with. Initially generated by the server when a new transaction is created and returned to the client as part of the ENVCHANGE token stream.", HFILL }
+ { &hf_tds_prelogin_option_encryption,
+ { "Encryption", "tds.prelogin.option.encryption",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
- { &hf_tds_all_headers_request_cnt,
- { "Outstanding request count", "tds.all_headers.header.request_cnt",
+ { &hf_tds_prelogin_option_instopt,
+ { "InstOpt", "tds.prelogin.option.instopt",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_prelogin_option_threadid,
+ { "ThreadID", "tds.prelogin.option.threadid",
FT_UINT32, BASE_DEC, NULL, 0x0,
- "Number of requests currently active on the connection", HFILL }
+ NULL, HFILL }
},
+ { &hf_tds_prelogin_option_mars,
+ { "MARS", "tds.prelogin.option.mars",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_prelogin_option_traceid,
+ { "TraceID", "tds.prelogin.option.traceid",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_prelogin_option_fedauthrequired,
+ { "FedAuthRequired", "tds.prelogin.option.fedauthrequired",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_prelogin_option_nonceopt,
+ { "NonceOpt", "tds.prelogin.option.nonceopt",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* RPC Request Stream */
+
+ { &hf_tds_rpc,
+ { "Remote Procedure Call", "tds.rpc",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_name_length8,
+ { "Procedure name length", "tds.rpc.name_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_name_length,
+ { "Procedure name length", "tds.rpc.name_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_name,
+ { "Procedure name", "tds.rpc.name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_proc_id,
+ { "Stored procedure ID", "tds.rpc.proc_id",
+ FT_UINT16, BASE_DEC, VALS(internal_stored_proc_id_names), 0x0,
+ "The number identifying the special stored procedure to be executed", HFILL }
+ },
+ { &hf_tds_rpc_options,
+ { "Option flags", "tds.rpc.options",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "The number identifying the special stored procedure to be executed", HFILL }
+ },
+ { &hf_tds_rpc_options_with_recomp,
+ { "With recompile", "tds.rpc.options.with_recomp",
+ FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_WITH_RECOMP,
+ "The number identifying the special stored procedure to be executed", HFILL }
+ },
+ { &hf_tds_rpc_options_no_metadata,
+ { "No metadata", "tds.rpc.options.no_metadata",
+ FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_NO_METADATA,
+ "The number identifying the special stored procedure to be executed", HFILL }
+ },
+ { &hf_tds_rpc_options_reuse_metadata,
+ { "Reuse metadata", "tds.rpc.options.reuse_metadata",
+ FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_REUSE_METADATA,
+ "The number identifying the special stored procedure to be executed", HFILL }
+ },
+ { &hf_tds_rpc_separator,
+ { "RPC batch separator", "tds.rpc.separator",
+ FT_UINT8, BASE_DEC, VALS(tds_rpc_separators), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_parameter,
+ { "Parameter", "tds.rpc.parameter",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_parameter_name_length,
+ { "Name length", "tds.rpc.parameter.name_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_parameter_name,
+ { "Name", "tds.rpc.parameter.name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_parameter_status,
+ { "Status flags", "tds.rpc.parameter.status",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ "Information on how the parameter is passed", HFILL }
+ },
+ { &hf_tds_rpc_parameter_status_by_ref,
+ { "By reference", "tds.rpc.parameter.status.by_ref",
+ FT_BOOLEAN, 16, NULL, TDS_RPC_PARAMETER_STATUS_BY_REF,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_parameter_status_default,
+ { "Default value", "tds.rpc.parameter.status.default",
+ FT_BOOLEAN, 16, NULL, TDS_RPC_PARAMETER_STATUS_DEFAULT,
+ NULL, HFILL }
+ },
+ { &hf_tds_rpc_parameter_value,
+ { "Value", "tds.rpc.parameter.value",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* SQLBatch Stream */
+ { &hf_tds_query,
+ { "Query", "tds.query",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /* SSPI Message Stream */
+
+ /* Transaction Manager Request Stream */
+ { &hf_tds_transmgr,
+ { "Transaction Manager Request", "tds.transmgr",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_transmgr_payload,
+ { "Payload", "tds.transmgr.payload",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ /****************************** Basic types **********************************/
+
{ &hf_tds_type_info,
- { "Type info", "tds.type_info",
+ { "Type info", "tds.type_info",
FT_NONE, BASE_NONE, NULL, 0x0,
"The TYPE_INFO rule applies to several messages used to describe column information", HFILL }
},
{ &hf_tds_type_info_type,
- { "Type", "tds.type_info.type",
- FT_UINT8, BASE_HEX, VALS(tds_data_type_names), 0x0,
+ { "Type", "tds.type_info.type",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_info_varlen,
- { "Maximal length", "tds.type_info.varlen",
+ { "Maximal length", "tds.type_info.varlen",
FT_UINT32, BASE_DEC, NULL, 0x0,
"Defines the length of the data contained within the column", HFILL }
},
{ &hf_tds_type_info_precision,
- { "Precision", "tds.type_info.precision",
+ { "Precision", "tds.type_info.precision",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_info_scale,
- { "Scale", "tds.type_info.scale",
+ { "Scale", "tds.type_info.scale",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_info_collation,
- { "Collation", "tds.type_info.collation",
+ { "Collation", "tds.type_info.collation",
FT_NONE, BASE_NONE, NULL, 0x0,
"Specifies collation information for character data or metadata describing character data", HFILL }
},
{ &hf_tds_type_info_collation_lcid,
- { "LCID", "tds.type_info.collation.lcid",
+ { "LCID", "tds.type_info.collation.lcid",
FT_UINT32, BASE_HEX, NULL, 0x000FFFFF,
"For a SortId==0 collation, the LCID bits correspond to a LocaleId as defined by the National Language Support (NLS) functions", HFILL }
},
{ &hf_tds_type_info_collation_ign_case,
- { "Ignore case", "tds.type_info.collation.ignore_case",
+ { "Ignore case", "tds.type_info.collation.ignore_case",
FT_BOOLEAN, 32, NULL, 0x00100000,
NULL, HFILL }
},
{ &hf_tds_type_info_collation_ign_accent,
- { "Ignore accent", "tds.type_info.collation.ignore_accent",
+ { "Ignore accent", "tds.type_info.collation.ignore_accent",
FT_BOOLEAN, 32, NULL, 0x00200000,
NULL, HFILL }
},
{ &hf_tds_type_info_collation_ign_kana,
- { "Ignore kana", "tds.type_info.collation.ignore_kana",
+ { "Ignore kana", "tds.type_info.collation.ignore_kana",
FT_BOOLEAN, 32, NULL, 0x00400000,
NULL, HFILL }
},
{ &hf_tds_type_info_collation_ign_width,
- { "Ignore width", "tds.type_info.collation.ignore_width",
+ { "Ignore width", "tds.type_info.collation.ignore_width",
FT_BOOLEAN, 32, NULL, 0x00800000,
NULL, HFILL }
},
{ &hf_tds_type_info_collation_binary,
- { "Binary", "tds.type_info.collation.binary",
+ { "Binary", "tds.type_info.collation.binary",
FT_BOOLEAN, 32, NULL, 0x01000000,
NULL, HFILL }
},
{ &hf_tds_type_info_collation_version,
- { "Version", "tds.type_info.collation.version",
+ { "Version", "tds.type_info.collation.version",
FT_UINT32, BASE_DEC, NULL, 0xF0000000,
NULL, HFILL }
},
{ &hf_tds_type_info_collation_sortid,
- { "SortId", "tds.type_info.collation.sortid",
+ { "SortId", "tds.type_info.collation.sortid",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_length,
- { "Length", "tds.type_varbyte.length",
+ { "Length", "tds.type_varbyte.length",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_null,
- { "Data: NULL", "tds.type_varbyte.data.null",
+ { "Data: NULL", "tds.type_varbyte.data.null",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_boolean,
- { "Data", "tds.type_varbyte.data.bool",
+ { "Data", "tds.type_varbyte.data.bool",
FT_BOOLEAN, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_int1,
- { "Data", "tds.type_varbyte.data.int",
+ { "Data", "tds.type_varbyte.data.int",
FT_INT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_int2,
- { "Data", "tds.type_varbyte.data.int",
+ { "Data", "tds.type_varbyte.data.int",
FT_INT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_int4,
- { "Data", "tds.type_varbyte.data.int",
+ { "Data", "tds.type_varbyte.data.int",
FT_INT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_int8,
- { "Data", "tds.type_varbyte.data.int64",
+ { "Data", "tds.type_varbyte.data.int64",
FT_INT64, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_float,
- { "Data", "tds.type_varbyte.data.float",
+ { "Data", "tds.type_varbyte.data.float",
FT_FLOAT, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_double,
- { "Data", "tds.type_varbyte.data.float",
+ { "Data", "tds.type_varbyte.data.float",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_bytes,
- { "Data", "tds.type_varbyte.data.bytes",
+ { "Data", "tds.type_varbyte.data.bytes",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_guid,
- { "Data", "tds.type_varbyte.data.guid",
+ { "Data", "tds.type_varbyte.data.guid",
FT_GUID, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_data_string,
- { "Data", "tds.type_varbyte.data.string",
+ { "Data", "tds.type_varbyte.data.string",
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_tds_type_varbyte_data_absdatetime,
+ { "Data", "tds.type_varbyte.data.datetime",
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_type_varbyte_data_reltime,
+ { "Time", "tds.type_varbyte.data.time",
+ FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_tds_type_varbyte_data_sign,
+ { "Sign", "tds.type_varbyte.data.sign",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_tds_type_varbyte_plp_len,
- { "PLP length", "tds.type_varbyte.plp_len",
+ { "PLP length", "tds.type_varbyte.plp_len",
FT_INT64, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_tds_type_varbyte_plp_chunk_len,
{ "PLP chunk length", "tds.type_varbyte.plp_chunk_len",
- FT_INT32, BASE_DEC, NULL, 0x0,
+ FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_rpc,
- { "Remote Procedure Call", "tds.rpc",
- FT_NONE, BASE_NONE, NULL, 0x0,
- NULL, HFILL }
+
+ /***************************** Top level TDS *******************************/
+
+ { &hf_tds_type,
+ { "Type", "tds.type",
+ FT_UINT8, BASE_DEC, VALS(packet_type_names), 0x0,
+ "Packet type", HFILL }
},
- { &hf_tds_rpc_name_length8,
- { "Procedure name length", "tds.rpc.name_length",
- FT_UINT8, BASE_DEC, NULL, 0x0,
+ { &hf_tds_status,
+ { "Status", "tds.status",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ "Packet status", HFILL }
+ },
+ { &hf_tds_status_eom,
+ { "End of message", "tds.status.eom",
+ FT_BOOLEAN, 8, NULL, STATUS_LAST_BUFFER,
+ "The packet is the last packet in the whole request", HFILL }
+ },
+ { &hf_tds_status_ignore,
+ { "Ignore this event", "tds.status.ignore",
+ FT_BOOLEAN, 8, NULL, STATUS_IGNORE_EVENT,
+ "(From client to server) Ignore this event (EOM MUST also be set)", HFILL }
+ },
+ { &hf_tds_status_event_notif,
+ { "Event notification", "tds.status.event_notif",
+ FT_BOOLEAN, 8, NULL, STATUS_EVENT_NOTIFICATION,
NULL, HFILL }
},
- { &hf_tds_rpc_name_length,
- { "Procedure name length", "tds.rpc.name_length",
+ { &hf_tds_status_reset_conn,
+ { "Reset connection", "tds.status.reset_conn",
+ FT_BOOLEAN, 8, NULL, STATUS_RESETCONNECTION,
+ "(From client to server) Reset this connection before processing event", HFILL }
+ },
+ { &hf_tds_status_reset_conn_skip_tran,
+ { "Reset connection keeping transaction state", "tds.status.reset_conn_skip_tran",
+ FT_BOOLEAN, 8, NULL, STATUS_RESETCONNECTIONSKIPTRAN,
+ "(From client to server) Reset the connection before processing event but do not modify the transaction state", HFILL }
+ },
+ { &hf_tds_length,
+ { "Length", "tds.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Packet length", HFILL }
+ },
+ { &hf_tds_channel,
+ { "Channel", "tds.channel",
FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Channel Number", HFILL }
+ },
+ { &hf_tds_packet_number,
+ { "Packet Number", "tds.packet_number",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_rpc_name,
- { "Procedure name", "tds.rpc.name",
- FT_STRING, BASE_NONE, NULL, 0x0,
+ { &hf_tds_window,
+ { "Window", "tds.window",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_rpc_proc_id,
- { "Stored procedure ID", "tds.rpc.proc_id",
- FT_UINT16, BASE_DEC, VALS(internal_stored_proc_id_names), 0x0,
- "The number identifying the special stored procedure to be executed", HFILL }
+ { &hf_tds_fragment_overlap,
+ { "Segment overlap", "tds.fragment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment overlaps with other fragments", HFILL }
},
- { &hf_tds_rpc_options,
- { "Option flags", "tds.rpc.options",
- FT_UINT16, BASE_HEX, NULL, 0x0,
- "The number identifying the special stored procedure to be executed", HFILL }
+ { &hf_tds_fragment_overlap_conflict,
+ { "Conflicting data in fragment overlap", "tds.fragment.overlap.conflict",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping fragments contained conflicting data", HFILL }
},
- { &hf_tds_rpc_options_with_recomp,
- { "With recompile", "tds.rpc.options.with_recomp",
- FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_WITH_RECOMP,
- "The number identifying the special stored procedure to be executed", HFILL }
+ { &hf_tds_fragment_multiple_tails,
+ { "Multiple tail fragments found", "tds.fragment.multipletails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when defragmenting the packet", HFILL }
},
- { &hf_tds_rpc_options_no_metadata,
- { "No metadata", "tds.rpc.options.no_metadata",
- FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_NO_METADATA,
- "The number identifying the special stored procedure to be executed", HFILL }
+ { &hf_tds_fragment_too_long_fragment,
+ { "Segment too long", "tds.fragment.toolongfragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Segment contained data past end of packet", HFILL }
},
- { &hf_tds_rpc_options_reuse_metadata,
- { "Reuse metadata", "tds.rpc.options.reuse_metadata",
- FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_REUSE_METADATA,
- "The number identifying the special stored procedure to be executed", HFILL }
+ { &hf_tds_fragment_error,
+ { "Defragmentation error", "tds.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Defragmentation error due to illegal fragments", HFILL }
},
- { &hf_tds_rpc_separator,
- { "RPC batch separator", "tds.rpc.separator",
- FT_UINT8, BASE_DEC, VALS(tds_rpc_separators), 0x0,
+ { &hf_tds_fragment_count,
+ { "Segment count", "tds.fragment.count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_rpc_parameter,
- { "Parameter", "tds.rpc.parameter",
- FT_NONE, BASE_NONE, NULL, 0x0,
+ { &hf_tds_fragment,
+ { "TDS Fragment", "tds.fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_rpc_parameter_name_length,
- { "Name length", "tds.rpc.parameter.name_length",
- FT_UINT8, BASE_DEC, NULL, 0x0,
+ { &hf_tds_fragments,
+ { "TDS Fragments", "tds.fragments",
+ FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_tds_rpc_parameter_name,
- { "Name", "tds.rpc.parameter.name",
- FT_STRING, BASE_NONE, NULL, 0x0,
- NULL, HFILL }
+ { &hf_tds_reassembled_in,
+ { "Reassembled TDS in frame", "tds.reassembled_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This TDS packet is reassembled in this frame", HFILL }
},
- { &hf_tds_rpc_parameter_status,
- { "Status flags", "tds.rpc.parameter.status",
- FT_UINT8, BASE_HEX, NULL, 0x0,
- "Information on how the parameter is passed", HFILL }
+ { &hf_tds_reassembled_length,
+ { "Reassembled TDS length", "tds.reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "The total length of the reassembled payload", HFILL }
},
- { &hf_tds_rpc_parameter_status_by_ref,
- { "By reference", "tds.rpc.parameter.status.by_ref",
- FT_BOOLEAN, 16, NULL, TDS_RPC_PARAMETER_STATUS_BY_REF,
- NULL, HFILL }
+ { &hf_tds_all_headers,
+ { "Packet data stream headers", "tds.all_headers",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ "The ALL_HEADERS rule", HFILL }
},
- { &hf_tds_rpc_parameter_status_default,
- { "Default value", "tds.rpc.parameter.status.default",
- FT_BOOLEAN, 16, NULL, TDS_RPC_PARAMETER_STATUS_DEFAULT,
+ { &hf_tds_all_headers_total_length,
+ { "Total length", "tds.all_headers.total_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Total length of ALL_HEADERS stream", HFILL }
+ },
+ { &hf_tds_all_headers_header_length,
+ { "Length", "tds.all_headers.header.length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Total length of an individual header", HFILL }
+ },
+ { &hf_tds_all_headers_header_type,
+ { "Type", "tds.all_headers.header.type",
+ FT_UINT16, BASE_HEX, VALS(header_type_names), 0x0,
NULL, HFILL }
},
- { &hf_tds_rpc_parameter_value,
- { "Value", "tds.rpc.parameter.value",
- FT_NONE, BASE_NONE, NULL, 0x0,
+ { &hf_tds_all_headers_trans_descr,
+ { "Transaction descriptor", "tds.all_headers.header.trans_descr",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ "For each connection, a number that uniquely identifies the transaction the request is associated with. Initially generated by the server when a new transaction is created and returned to the client as part of the ENVCHANGE token stream.", HFILL }
+ },
+ { &hf_tds_all_headers_request_cnt,
+ { "Outstanding request count", "tds.all_headers.header.request_cnt",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Number of requests currently active on the connection", HFILL }
+ },
+ { &hf_tds_unknown_tds_packet,
+ { "TDS Packet", "tds.unknown_tds_packet",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
-
- /* Generated from convert_proto_tree_add_text.pl */
- { &hf_tds_query, { "Query", "tds.query", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_lang_token_status, { "Status", "tds.lang_token_status", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_language_text, { "Language text", "tds.language_text", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_env_chg_type, { "Type", "tds.env_chg_type", FT_UINT8, BASE_DEC, VALS(env_chg_names), 0x0, NULL, HFILL }},
- { &hf_tds_new_value_length, { "New Value Length", "tds.new_value_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_new_value, { "New Value", "tds.new_value", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_old_value_length, { "Old Value Length", "tds.old_value_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_old_value, { "Old Value", "tds.old_value", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_sql_error_number, { "SQL Error Number", "tds.sql_error_number", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_state, { "State", "tds.state", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_severity_level, { "Severity Level", "tds.severity_level", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_error_message_length, { "Error message length", "tds.error_message_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_error, { "Error", "tds.error", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_server_name_length, { "Server name length", "tds.server_name_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_server_name, { "Server name", "tds.server_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_process_name_length, { "Process name length", "tds.process_name_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_process_name, { "Process name", "tds.process_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_line_number16, { "line number", "tds.line_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_line_number32, { "line number", "tds.line_number", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_ack, { "Ack", "tds.ack", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_text_length, { "Text length", "tds.text_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_server_version, { "Server Version", "tds.server_version", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_columns, { "Columns", "tds.columns", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_usertype32, { "usertype", "tds.usertype", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_usertype16, { "usertype", "tds.usertype", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_results_token_flags, { "flags", "tds.results_token_flags", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_results_token_type, { "Type", "tds.results_token_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_unknown_bytes_1, { "Unknown byte", "tds.unknown_bytes", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_unknown_bytes_4, { "Unknown bytes", "tds.unknown_bytes", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_unknown_bytes_3, { "Unknown bytes", "tds.unknown_bytes", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_large_type_size, { "Large type size", "tds.large_type_size", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_message_length, { "message length", "tds.message_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_done_token_status_flags, { "Status flags", "tds.done_token.status_flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_operation, { "Operation", "tds.operation", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_row_count64, { "row count", "tds.row_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_row_count32, { "row count", "tds.row_count", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_tds_packet, { "TDS Packet", "tds.tds_packet", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_login_offset, { "Offset", "tds.login_offset", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_login_length, { "Length", "tds.login_length", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_login_password, { "Password", "tds.login_password", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_tds_token_len, { "Length", "tds.token_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_tds_token_len,
+ { "Length", "tds.token_len",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ }
};
static gint *ett[] = {
@@ -3199,11 +5491,16 @@ proto_register_tds(void)
&ett_tds_rpc_options,
&ett_tds_rpc_parameter,
&ett_tds_rpc_parameter_status,
+ &ett_tds_prelogin_option,
&ett_tds_token,
&ett_tds7_query,
+ &ett_tds7_prelogin,
&ett_tds7_login,
&ett_tds7_hdr,
&ett_tds_col,
+ &ett_tds_flags,
+ &ett_tds7_featureextack,
+ &ett_tds7_featureextack_feature
};
static ei_register_info ei[] = {
@@ -3213,6 +5510,7 @@ proto_register_tds(void)
{ &ei_tds_invalid_length, { "tds.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
{ &ei_tds_token_length_invalid, { "tds.token.length.invalid", PI_PROTOCOL, PI_WARN, "Bogus token size", EXPFILL }},
{ &ei_tds_token_stats, { "tds.token.stats", PI_PROTOCOL, PI_NOTE, "Token stats", EXPFILL }},
+ { &ei_tds_invalid_plp_type, { "tds.type_info.type.invalidplp", PI_PROTOCOL, PI_NOTE, "Invalid PLP type", EXPFILL }}
};
module_t *tds_module;
@@ -3228,7 +5526,7 @@ proto_register_tds(void)
expert_register_field_array(expert_tds, ei, array_length(ei));
/* Allow dissector to be found by name. */
- tds_tcp_handle = register_dissector("tds", dissect_tds_tcp, proto_tds);
+ tds_tcp_handle = new_register_dissector("tds", dissect_tds_message, proto_tds);
tds_module = prefs_register_protocol(proto_tds, NULL);
prefs_register_bool_preference(tds_module, "desegment_buffers",