aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-tds.c
diff options
context:
space:
mode:
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",