epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-tds.c
bloba7b5660629c6f5571a6e93f0ab0448378193a9af
1 /* packet-tds.c
2 * Routines for TDS NetLib dissection
3 * Copyright 2000-2002, Brian Bruns <camber@ais.org>
4 * Copyright 2002, Steve Langasek <vorlon@netexpress.net>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 * The NETLIB protocol is a small blocking protocol designed to allow TDS
15 * to be placed within different transports (TCP, DECNet, IPX/SPX). A
16 * NETLIB packet starts with an eight byte header containing:
18 * a one-byte packet type field;
20 * a one-byte status field;
22 * a two-byte big-endian size field giving the size of the packet,
23 * including the header;
25 * a two-byte big-endian channel number, used when multiple sessions
26 * are being multiplexed on a single connection;
28 * a one-byte packet number, giving "the frame number of a multiplexed
29 * message, modulo 256";
31 * a one-byte window, which is the number of frames to be sent
32 * before an acknowledgment message is received.
34 * followed by payload whose size is the value in the size field minus
35 * 8.
37 * Microsoft Network Monitor 2.x dissects the 4 byte field (and indicates
38 * that the one-byte last packet indicator also contains other bits).
40 * The TDS protocol consists of a number of protocol data units (PDUs) that
41 * appear to be assembled from NETLIB packets, in the form of zero or more
42 * NETLIB packets with the last packet indicator clear and a final NETLIB
43 * packet with the last packet indicator set. The type of the TDS PDU is
44 * specified by the packet type field of the NETLIB header (presumably that
45 * field has the same value for all NETLIB packets that make up a TDS PDU).
47 * The "server response" PDU consists of a sequence of multiple items, each
48 * one beginning with a one byte type field at the start of the PDU. Some
49 * items are fixed length, some are variable length with a two byte size
50 * field following the item type, and then there is TDS_ROW_TOKEN in which
51 * size is determined by analyzing the result set returned from the server.
52 * This in effect means that we are hopelessly lost if we haven't seen the
53 * result set. Also, TDS 4/5 is byte order negotiable, which is specified
54 * in the login packet. We can attempt to determine it later on, but not
55 * with 100% accuracy.
57 * Some preliminary documentation on the packet format can be found at
58 * http://www.freetds.org/tds.html
60 * Some more information can be found in
61 * https://web.archive.org/web/20140611233513/http://www.sybase.com/content/1013412/tds34.pdf
62 * https://web.archive.org/web/20140611233501/http://www.sybase.com/content/1040983/Sybase-tds38-102306.pdf
63 * Microsoft's [MS-TDS] protocol specification
64 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/
65 * Microsoft's TDS 4.2 [MS-SSTDS] protocol specification
66 * https://docs.microsoft.com/en-us/openspecs/sql_server_protocols/ms-sstds/
68 * This document is no longer available here, and does not appear to
69 * have been archived by the Wayback Machine:
70 * http://download.nai.com/products/media/sniffer/support/sdos/sybase.pdf
72 * Much of this code was originally developed for the FreeTDS project.
73 * http://www.freetds.org
77 * Excerpts from Brian's posting to wireshark-dev:
79 * The TDS Protocol is actually a protocol within a protocol. On the outside
80 * there is netlib which is not so much a encapsulation as a blocking of the
81 * data, typically to 512 or 4096 bytes. Between this are the protocol data
82 * units for TDS. Netlib packets may be split over real packets, multiple
83 * netlib packets may appear in single real packets. TDS PDUs may be split
84 * over netlib packets (and real packets) and most certainly can appear
85 * multiple times within a netlib packet.
87 * Because of this, I abandoned my earlier attempt at making two dissectors,
88 * one for netlib and one for TDS. Counterintuitively, a single dissector
89 * turned out to be simpler than splitting it up.
91 * Here are some of the (hefty) limitations of the current code
93 * . I probably could have used the packet reassembly stuff, but I started
94 * this at version 0.8.20, so c'est la vie. It wouldn't have covered the
95 * netlib stuff anyway, so no big loss.
96 * . The older two layer version of the code dissected the PDU's, but the new
97 * version does not yet, it only labels the names. I need an elegant way to
98 * deal with dissecting data crossing (netlib and tcp) packet boundaries. I
99 * think I have one, but ran out of time to do it.
100 * . It will only work on little endian platforms. Or rather I should say,
101 * the client that was captured must be little endian. TDS 7.0/8.0 is
102 * always LE; for TDS 4.2/5.0 look in the code for tvb_get_le*() functions,
103 * there are fields in the login packet which determine byte order.
104 * . result sets that span netlib packets are not working
105 * . TDS 7 and 4.2 result sets are not working yet
107 * All that said, the code does deal gracefully with different boundary
108 * conditions and what remains are the easier bits, IMHO.
110 * XXX - "real packets" means "TCP segments", for TCP.
112 * XXX - is it *REALLY* true that you can have more than one TDS PDU (as
113 * opposed to more than one server response item) per NETLIB packet? Or is
114 * all the data in a NETLIB packet put into a single TDS PDU? If so, then
115 * we can reassemble NETLIB packets using the standard TCP desegmentation
116 * code, and can reassemble TDS PDUs using "fragment_add_seq_check()",
117 * and more cleanly separate the NETLIB and TDS dissectors (although the
118 * "is this NETLIB" heuristic would have to look at TDS information past
119 * the NETLIB header, in order to make the heuristic strong enough not
120 * to get too many false positives; note that the heuristic should reject
121 * any putative NETLIB packet with a length field with a value < 8).
123 * That would substantially clean the dissector up, eliminating most of
124 * the per-packet data (we might still need information to handle
125 * TDS_ROW_TOKEN), getting rid of the stuff to handle data split across
126 * TCP segment boundaries in favor of simple reassembly code, and
127 * fixing some otherwise nasty-looking crashing bugs.
129 * NOTE: we assume that all the data in a NETLIB packet *can* be put into
130 * a single TDS PTU, so that we have separate reassembly of NETLIB
131 * packets and TDS PDUs; it seems to work, and it really did clean stuff
132 * up and fix crashes.
135 #include "config.h"
138 #include <epan/packet.h>
139 #include <epan/conversation.h>
140 #include <epan/reassemble.h>
141 #include <epan/prefs.h>
142 #include <epan/expert.h>
143 #include <epan/proto_data.h>
144 #include <epan/strutil.h>
145 #include <epan/tfs.h>
146 #include <epan/unit_strings.h>
148 #include <wsutil/array.h>
149 #include <wsutil/epochs.h>
151 #include <math.h>
153 #include "packet-tcp.h"
154 #include "packet-ber.h"
156 #define TDS_QUERY_PKT 1 /* SQLBatch in MS-TDS revision 18.0 */
157 #define TDS_LOGIN_PKT 2
158 #define TDS_RPC_PKT 3
159 #define TDS_RESP_PKT 4
160 #define TDS_RAW_PKT 5
161 #define TDS_ATTENTION_PKT 6
162 #define TDS_BULK_DATA_PKT 7 /* Bulk Load BCP in MS-TDS revision 18.0 */
163 #define TDS_OPEN_CHN_PKT 8
164 #define TDS_CLOSE_CHN_PKT 9
165 #define TDS_RES_ERROR_PKT 10
166 #define TDS_LOG_CHN_ACK_PKT 11
167 #define TDS_ECHO_PKT 12
168 #define TDS_LOGOUT_CHN_PKT 13
169 #define TDS_TRANS_MGR_PKT 14
170 #define TDS5_QUERY_PKT 15 /* or "Normal tokenized request or response */
171 #define TDS_LOGIN7_PKT 16 /* or "Urgent tokenized request or response */
172 #define TDS_SSPI_PKT 17
173 #define TDS_PRELOGIN_PKT 18
174 #define TDS_INVALID_PKT 19
175 #define TDS_TLS_PKT 23
176 #define TDS_SMP_PKT 83 /* Session Multiplex Protocol; MARS option */
178 #define is_valid_tds_type(x) (((x) >= TDS_QUERY_PKT && (x) < TDS_INVALID_PKT) || x == TDS_TLS_PKT)
180 /* The following constants are imported more or less directly from FreeTDS */
181 /* Updated from FreeTDS v0.63 tds.h */
182 /* "$Id: tds.h,v 1.192 2004/10/28 12:42:12 freddy77]" */
183 /* Note: [###] below means 'not defined in FreeTDS tds.h' */
185 #define TDS_TVPROW_TOKEN 1 /* 0x01 */
186 #define TDS5_PARAMFMT2_TOKEN 32 /* 0x20 TDS 5.0 only */
187 #define TDS_LANG_TOKEN 33 /* 0x21 TDS 5.0 only */
188 #define TDS5_ORDERBY2_TOKEN 34 /* 0x22 TDS 5.0 only */
189 #define TDS5_CURDECLARE2_TOKEN 35 /* 0x23 TDS 5.0 only [###] */
190 #define TDS5_ROWFMT2_TOKEN 97 /* 0x61 TDS 5.0 only */
191 #define TDS5_MSG_TOKEN 101 /* 0x65 TDS 5.0 only [###] */
192 #define TDS5_LOGOUT_TOKEN 113 /* 0x71 TDS 5.0 only? ct_close() */
193 #define TDS_OFFSET_TOKEN 120 /* 0x78 Removed in TDS 7.2 */
194 #define TDS_RET_STAT_TOKEN 121 /* 0x79 */
195 #define TDS_PROCID_TOKEN 124 /* 0x7C TDS 4.x only - TDS_PROCID */
196 #define TDS_CURCLOSE_TOKEN 128 /* 0x80 TDS 5.0 only */
197 #define TDS7_COL_METADATA_TOKEN 129 /* 0x81 */
198 #define TDS_CURFETCH_TOKEN 130 /* 0x82 TDS 5.0 only */
199 #define TDS_CURINFO_TOKEN 131 /* 0x83 TDS 5.0 only */
200 #define TDS_CUROPEN_TOKEN 132 /* 0x84 TDS 5.0 only */
201 #define TDS_CURDECLARE_TOKEN 134 /* 0x86 TDS 5.0 only */
202 #define TDS7_ALTMETADATA_TOKEN 136 /* 0x88 */
203 #define TDS_COL_NAME_TOKEN 160 /* 0xA0 TDS 4.x only */
204 #define TDS_COLFMT_TOKEN 161 /* 0xA1 TDS 4.2 only - TDS_COLFMT */
205 #define TDS5_DYNAMIC2_TOKEN 163 /* 0xA3 TDS 5.0 only */
206 #define TDS_TABNAME_TOKEN 164 /* 0xA4 */
207 #define TDS7_COL_INFO_TOKEN 165 /* 0xA5 */
208 #define TDS_OPTIONCMD_TOKEN 166 /* 0xA6 */
209 #define TDS_COMPUTE_NAMES_TOKEN 167 /* 0xA7 */
210 #define TDS_COMPUTE_RESULT_TOKEN 168 /* 0xA8 */
211 #define TDS_ORDER_TOKEN 169 /* 0xA9 TDS_ORDER */
212 #define TDS_ERR_TOKEN 170 /* 0xAA */
213 #define TDS_INFO_TOKEN 171 /* 0xAB */
214 #define TDS_RETURNVAL_TOKEN 172 /* 0xAC */
215 #define TDS_LOGIN_ACK_TOKEN 173 /* 0xAD */
216 #define TDS_CONTROL_TOKEN 174 /* 0xAE TDS 4.x only */
217 #define TDS_FEATUREEXTACK_TOKEN 174 /* 0xAE Introduced TDS 7.4 */
218 #define TDS_KEY_TOKEN 202 /* 0xCA [###] */
219 #define TDS_ROW_TOKEN 209 /* 0xD1 */
220 #define TDS_NBCROW_TOKEN 210 /* 0xD2 Introduced TDS 7.3 */
221 #define TDS_ALTROW_TOKEN 211 /* 0xD3 */
222 #define TDS5_PARAMS_TOKEN 215 /* 0xD7 TDS 5.0 only */
223 #define TDS_CAPABILITY_TOKEN 226 /* 0xE2 */
224 #define TDS_ENVCHG_TOKEN 227 /* 0xE3 */
225 #define TDS_SESSIONSTATE_TOKEN 228 /* 0xE4 Introduced TDS 7.4 */
226 #define TDS5_EED_TOKEN 229 /* 0xE5 TDS 5.0 only */
227 #define TDS5_DBRPC_TOKEN 230 /* 0xE6 */
228 #define TDS5_DYNAMIC_TOKEN 231 /* 0xE7 TDS 5.0 only */
229 #define TDS5_PARAMFMT_TOKEN 236 /* 0xEC TDS 5.0 only */
230 #define TDS_AUTH_TOKEN 237 /* 0xED */ /* DUPLICATE! */
231 #define TDS_SSPI_TOKEN 237 /* 0xED */ /* DUPLICATE! */
232 #define TDS5_ROWFMT_TOKEN 238 /* 0xEE TDS 5.0 only */ /* DUPLICATE! */
233 #define TDS_FEDAUTHINFO_TOKEN 238 /* 0xEE Introduced TDS 7.4 */ /* DUPLICATE! */
234 #define TDS_DONE_TOKEN 253 /* 0xFD */
235 #define TDS_DONEPROC_TOKEN 254 /* 0xFE */
236 #define TDS_DONEINPROC_TOKEN 255 /* 0xFF */
238 /* Capability token fields (TDS5) */
239 #define TDS_CAP_REQUEST 1
240 #define TDS_CAP_RESPONSE 2
242 /* TDS 5 Cursor fetch options */
243 #define TDS_CUR_NEXT 1
244 #define TDS_CUR_PREV 2
245 #define TDS_CUR_FIRST 3
246 #define TDS_CUR_LAST 4
247 #define TDS_CUR_ABS 5
248 #define TDS_CUR_REL 6
250 /* TDS 5 Cursor Info Commands */
251 #define TDS_CURINFO_SET_FETCH_COUNT 1
252 #define TDS_CURINFO_INQUIRE 2
253 #define TDS_CURINFO_INFORM 3
254 #define TDS_CURINFO_LISTALL 4
256 /* TDS 7 Prelogin options */
257 #define TDS7_PRELOGIN_OPTION_VERSION 0x00
258 #define TDS7_PRELOGIN_OPTION_ENCRYPTION 0x01
259 #define TDS7_PRELOGIN_OPTION_INSTOPT 0x02
260 #define TDS7_PRELOGIN_OPTION_THREADID 0x03
261 #define TDS7_PRELOGIN_OPTION_MARS 0x04
262 #define TDS7_PRELOGIN_OPTION_TRACEID 0x05
263 #define TDS7_PRELOGIN_OPTION_FEDAUTHREQUIRED 0x06
264 #define TDS7_PRELOGIN_OPTION_NONCEOPT 0x07
265 #define TDS7_PRELOGIN_OPTION_TERMINATOR 0xff
267 /* Microsoft internal stored procedure id's */
268 #define TDS_SP_CURSOR 1
269 #define TDS_SP_CURSOROPEN 2
270 #define TDS_SP_CURSORPREPARE 3
271 #define TDS_SP_CURSOREXECUTE 4
272 #define TDS_SP_CURSORPREPEXEC 5
273 #define TDS_SP_CURSORUNPREPARE 6
274 #define TDS_SP_CURSORFETCH 7
275 #define TDS_SP_CURSOROPTION 8
276 #define TDS_SP_CURSORCLOSE 9
277 #define TDS_SP_EXECUTESQL 10
278 #define TDS_SP_PREPARE 11
279 #define TDS_SP_EXECUTE 12
280 #define TDS_SP_PREPEXEC 13
281 #define TDS_SP_PREPEXECRPC 14
282 #define TDS_SP_UNPREPARE 15
284 #define TDS_RPC_OPT_WITH_RECOMP 0x0001
285 #define TDS_RPC_OPT_NO_METADATA 0x0002
286 #define TDS_RPC_OPT_REUSE_METADATA 0x0004
288 #define TDS_RPC_PARAMETER_STATUS_BY_REF 0x01
289 #define TDS_RPC_PARAMETER_STATUS_DEFAULT 0x02
291 /* Sybase Data Types */
293 #define SYBCHAR 47 /* 0x2F */
294 #define SYBVARCHAR 39 /* 0x27 */
295 #define SYBINTN 38 /* 0x26 */
296 #define SYBINT1 48 /* 0x30 */
297 #define SYBINT2 52 /* 0x34 */
298 #define SYBINT4 56 /* 0x38 */
299 #define SYBINT8 127 /* 0x7F */
300 #define SYBFLT8 62 /* 0x3E */
301 #define SYBDATETIME 61 /* 0x3D */
302 #define SYBBIT 50 /* 0x32 */
303 #define SYBTEXT 35 /* 0x23 */
304 #define SYBNTEXT 99 /* 0x63 */
305 #define SYBIMAGE 34 /* 0x22 */
306 #define SYBMONEY4 122 /* 0x7A */
307 #define SYBMONEY 60 /* 0x3C */
308 #define SYBDATETIME4 58 /* 0x3A */
309 #define SYBREAL 59 /* 0x3B */
310 #define SYBBINARY 45 /* 0x2D */
311 #define SYBVOID 31 /* 0x1F */
312 #define SYBVARBINARY 37 /* 0x25 */
313 #define SYBNVARCHAR 103 /* 0x67 */
314 #define SYBBITN 104 /* 0x68 */
315 #define SYBNUMERIC 108 /* 0x6C */
316 #define SYBDECIMAL 106 /* 0x6A */
317 #define SYBFLTN 109 /* 0x6D */
318 #define SYBMONEYN 110 /* 0x6E */
319 #define SYBDATETIMN 111 /* 0x6F */
320 #define SYBLONGCHAR 175 /* 0xAF */
321 #define XSYBNVARCHAR 231 /* 0xE7 */
322 #define XSYBNCHAR 239 /* 0xEF */
323 #define XSYBVARBINARY 165 /* 0xA5 */
324 #define XSYBBINARY 173 /* 0xAD */
325 #define SYBLONGBINARY 225 /* 0xE1 */
326 #define SYBSINT1 64 /* 0x40 */
327 #define SYBUINT2 65 /* 0x41 */
328 #define SYBUINT4 66 /* 0x42 */
329 #define SYBUINT8 67 /* 0x43 */
330 #define SYBUNIQUE 36 /* 0x24 */
331 #define SYBVARIANT 98 /* 0x62 */
333 /* FIXEDLENTYPE */
334 #define TDS_DATA_TYPE_NULL 0x1F /* 31 = Null (no data associated with this type) */
335 #define TDS_DATA_TYPE_INT1 0x30 /* 48 = TinyInt (1 byte data representation) */
336 #define TDS_DATA_TYPE_BIT 0x32 /* 50 = Bit (1 byte data representation) */
337 #define TDS_DATA_TYPE_INT2 0x34 /* 52 = SmallInt (2 byte data representation) */
338 #define TDS_DATA_TYPE_INT4 0x38 /* 56 = Int (4 byte data representation) */
339 #define TDS_DATA_TYPE_DATETIME4 0x3A /* 58 = SmallDateTime (4 byte data representation) */
340 #define TDS_DATA_TYPE_FLT4 0x3B /* 59 = Real (4 byte data representation) */
341 #define TDS_DATA_TYPE_MONEY 0x3C /* 60 = Money (8 byte data representation) */
342 #define TDS_DATA_TYPE_DATETIME 0x3D /* 61 = DateTime (8 byte data representation) */
343 #define TDS_DATA_TYPE_FLT8 0x3E /* 62 = Float (8 byte data representation) */
344 #define TDS_DATA_TYPE_MONEY4 0x7A /* 122 = SmallMoney (4 byte data representation) */
345 #define TDS_DATA_TYPE_INT8 0x7F /* 127 = BigInt (8 byte data representation) */
346 /* BYTELEN_TYPE */
347 #define TDS_DATA_TYPE_GUID 0x24 /* 36 = UniqueIdentifier */
348 #define TDS_DATA_TYPE_INTN 0x26 /* 38 */
349 #define TDS_DATA_TYPE_DECIMAL 0x37 /* 55 = Decimal (TDS 4/5) */
350 #define TDS_DATA_TYPE_NUMERIC 0x3F /* 63 = Numeric (TDS 4/5) */
351 #define TDS_DATA_TYPE_BITN 0x68 /* 104 */
352 #define TDS_DATA_TYPE_DECIMALN 0x6A /* 106 = Decimal */
353 #define TDS_DATA_TYPE_NUMERICN 0x6C /* 108 = Numeric */
354 #define TDS_DATA_TYPE_FLTN 0x6D /* 109 */
355 #define TDS_DATA_TYPE_MONEYN 0x6E /* 110 */
356 #define TDS_DATA_TYPE_DATETIMN 0x6F /* 111 */
357 #define TDS_DATA_TYPE_DATEN 0x28 /* 40 (introduced in TDS 7.3) */
358 #define TDS_DATA_TYPE_TIMEN 0x29 /* 41 (introduced in TDS 7.3) */
359 #define TDS_DATA_TYPE_DATETIME2N 0x2A /* 42 (introduced in TDS 7.3) */
360 #define TDS_DATA_TYPE_DATETIMEOFFSETN 0x2B /* 43 (introduced in TDS 7.3) */
361 #define TDS_DATA_TYPE_CHAR 0x2F /* 47 = Char (TDS 4/5) */
362 #define TDS_DATA_TYPE_VARCHAR 0x27 /* 39 = VarChar (TDS 4/5) */
363 #define TDS_DATA_TYPE_BINARY 0x2D /* 45 = Binary (TDS 4/5) */
364 #define TDS_DATA_TYPE_VARBINARY 0x25 /* 37 = VarBinary (TDS 4/5) */
365 /* USHORTLEN_TYPE */
366 #define TDS_DATA_TYPE_BIGVARBIN 0xA5 /* 165 = VarBinary */
367 #define TDS_DATA_TYPE_BIGVARCHR 0xA7 /* 167 = VarChar */
368 #define TDS_DATA_TYPE_BIGBINARY 0xAD /* 173 = Binary */
369 #define TDS_DATA_TYPE_BIGCHAR 0xAF /* 175 = Char, AKA SYBLONGCHAR (TDS 5) */
370 #define TDS_DATA_TYPE_NVARCHAR 0xE7 /* 231 = NVarChar */
371 #define TDS_DATA_TYPE_NCHAR 0xEF /* 239 = NChar */
372 /* LONGLEN_TYPE */
373 #define TDS_DATA_TYPE_XML 0xF1 /* 241 = XML (introduced in TDS 7.2) */
374 #define TDS_DATA_TYPE_UDT 0xF0 /* 240 = CLR-UDT (introduced in TDS 7.2) */
375 #define TDS_DATA_TYPE_TEXT 0x23 /* 35 = Text */
376 #define TDS_DATA_TYPE_IMAGE 0x22 /* 34 = Image */
377 #define TDS_DATA_TYPE_LONGBINARY 0xE1 /* 225 = Long Binary (TDS 5.0) */
378 #define TDS_DATA_TYPE_NTEXT 0x63 /* 99 = NText */
379 #define TDS_DATA_TYPE_SSVARIANT 0x62 /* 98 = Sql_Variant (introduced in TDS 7.2) */
380 /* no official data type, used only as error indication */
381 #define TDS_DATA_TYPE_INVALID UINT8_MAX
383 #define is_fixedlen_type_sybase(x) (x==SYBINT1 || \
384 x==SYBINT2 || \
385 x==SYBINT4 || \
386 x==SYBINT8 || \
387 x==SYBREAL || \
388 x==SYBFLT8 || \
389 x==SYBDATETIME || \
390 x==SYBDATETIME4 || \
391 x==SYBBIT || \
392 x==SYBMONEY || \
393 x==SYBMONEY4 || \
394 x==SYBUNIQUE \
397 #define is_longlen_type_sybase(x) ((x)==SYBLONGCHAR || \
398 (x)==SYBLONGBINARY \
401 #define is_fixedlen_type_tds(x) (x==TDS_DATA_TYPE_NULL || \
402 x==TDS_DATA_TYPE_INT1 || \
403 x==TDS_DATA_TYPE_BIT || \
404 x==TDS_DATA_TYPE_INT2 || \
405 x==TDS_DATA_TYPE_INT4 || \
406 x==TDS_DATA_TYPE_DATETIME4 || \
407 x==TDS_DATA_TYPE_FLT4 || \
408 x==TDS_DATA_TYPE_MONEY || \
409 x==TDS_DATA_TYPE_DATETIME || \
410 x==TDS_DATA_TYPE_FLT8 || \
411 x==TDS_DATA_TYPE_MONEY4 || \
412 x==TDS_DATA_TYPE_INT8 \
415 #define is_numeric_type_tds(x) ((x)==TDS_DATA_TYPE_NUMERIC || \
416 (x)==TDS_DATA_TYPE_NUMERICN || \
417 (x)==TDS_DATA_TYPE_DECIMAL || \
418 (x)==TDS_DATA_TYPE_DECIMALN \
421 #define is_varlen_type_tds(x) (x==TDS_DATA_TYPE_GUID || \
422 x==TDS_DATA_TYPE_INTN || \
423 x==TDS_DATA_TYPE_DECIMAL || \
424 x==TDS_DATA_TYPE_NUMERIC || \
425 x==TDS_DATA_TYPE_BITN || \
426 x==TDS_DATA_TYPE_DECIMALN || \
427 x==TDS_DATA_TYPE_NUMERICN || \
428 x==TDS_DATA_TYPE_FLTN || \
429 x==TDS_DATA_TYPE_MONEYN || \
430 x==TDS_DATA_TYPE_DATETIMN || \
431 x==TDS_DATA_TYPE_DATEN || \
432 x==TDS_DATA_TYPE_TIMEN || \
433 x==TDS_DATA_TYPE_DATETIME2N || \
434 x==TDS_DATA_TYPE_DATETIMEOFFSETN || \
435 x==TDS_DATA_TYPE_CHAR || \
436 x==TDS_DATA_TYPE_VARCHAR || \
437 x==TDS_DATA_TYPE_BINARY || \
438 x==TDS_DATA_TYPE_VARBINARY || \
439 x==TDS_DATA_TYPE_BIGVARBIN || \
440 x==TDS_DATA_TYPE_BIGVARCHR || \
441 x==TDS_DATA_TYPE_BIGBINARY || \
442 x==TDS_DATA_TYPE_BIGCHAR || \
443 x==TDS_DATA_TYPE_NVARCHAR || \
444 x==TDS_DATA_TYPE_NCHAR || \
445 x==TDS_DATA_TYPE_XML || \
446 x==TDS_DATA_TYPE_UDT || \
447 x==TDS_DATA_TYPE_TEXT || \
448 x==TDS_DATA_TYPE_IMAGE || \
449 x==TDS_DATA_TYPE_NTEXT || \
450 x==TDS_DATA_TYPE_SSVARIANT \
453 #define is_image_type_tds(x) ((x)==TDS_DATA_TYPE_TEXT || \
454 (x)==TDS_DATA_TYPE_IMAGE || \
455 (x)==TDS_DATA_TYPE_NTEXT \
458 #define TDS_GEN_NULL 0x00U
459 #define TDS_CHARBIN_NULL 0xFFFFU
460 #define TDS_CHARBIN_NULL32 0xFFFFFFFFU
462 #define TDS_PLP_TERMINATOR UINT64_C(0x0000000000000000)
463 #define TDS_UNKNOWN_PLP_LEN UINT64_C(0xFFFFFFFFFFFFFFFE)
464 #define TDS_PLP_NULL UINT64_C(0xFFFFFFFFFFFFFFFF)
466 /* Fixed field lengths */
468 #define TDS_MAXNAME 30
469 #define TDS_RPLEN 255
470 #define TDS_PROGNLEN 10
471 #define TDS_PKTLEN 6
473 /* Encodings */
475 #define TDS_INT2_BIG_ENDIAN 2
476 #define TDS_INT2_LITTLE_ENDIAN 3
477 #define TDS_INT4_BIG_ENDIAN 0
478 #define TDS_INT4_LITTLE_ENDIAN 1
479 #define TDS_FLT8_BIG_ENDIAN 4
480 #define TDS_FLT8_VAX_D 5
481 #define TDS_FLT8_LITTLE_ENDIAN 10
482 #define TDS_FLT8_ND5000 11
483 #define TDS_CHAR_ASCII 6
484 #define TDS_CHAR_EBCDIC 7
485 #define TDS_DATE4_TIME_FIRST 16
486 #define TDS_DATE4_DATE_FIRST 17
487 #define TDS_DATE8_TIME_FIRST 8
488 #define TDS_DATE8_DATE_FIRST 9
489 /* Artificial, for TDS 7 */
490 #define TDS_CHAR_UTF16 120
492 static const value_string tds_data_type_names[] = {
493 /* FIXEDLENTYPE */
494 {TDS_DATA_TYPE_NULL, "NULLTYPE - Null (no data associated with this type)"},
495 {TDS_DATA_TYPE_INT1, "INT1TYPE - TinyInt (1 byte data representation)"},
496 {TDS_DATA_TYPE_BIT, "BITTYPE - Bit (1 byte data representation)"},
497 {TDS_DATA_TYPE_INT2, "INT2TYPE - SmallInt (2 byte data representation)"},
498 {TDS_DATA_TYPE_INT4, "INT4TYPE - Int (4 byte data representation)"},
499 {TDS_DATA_TYPE_DATETIME4, "DATETIME4TYPE - SmallDateTime (4 byte data representation)"},
500 {TDS_DATA_TYPE_FLT4, "FLT4TYPE - Real (4 byte data representation)"},
501 {TDS_DATA_TYPE_MONEY, "MONEYTYPE - Money (8 byte data representation)"},
502 {TDS_DATA_TYPE_DATETIME, "DATETIMETYPE - DateTime (8 byte data representation)"},
503 {TDS_DATA_TYPE_FLT8, "FLT8TYPE - Float (8 byte data representation)"},
504 {TDS_DATA_TYPE_MONEY4, "MONEY4TYPE - SmallMoney (4 byte data representation)"},
505 {TDS_DATA_TYPE_INT8, "INT8TYPE - BigInt (8 byte data representation)"},
506 /* BYTELEN_TYPE */
507 {TDS_DATA_TYPE_GUID, "GUIDTYPE - UniqueIdentifier"},
508 {TDS_DATA_TYPE_INTN, "INTNTYPE"},
509 {TDS_DATA_TYPE_DECIMAL, "DECIMALTYPE - Decimal (TDS 4/5)"},
510 {TDS_DATA_TYPE_NUMERIC, "NUMERICTYPE - Numeric (TDS 4/5)"},
511 {TDS_DATA_TYPE_BITN, "BITNTYPE"},
512 {TDS_DATA_TYPE_DECIMALN, "DECIMALNTYPE - Decimal"},
513 {TDS_DATA_TYPE_NUMERICN, "NUMERICNTYPE - Numeric"},
514 {TDS_DATA_TYPE_FLTN, "FLTNTYPE"},
515 {TDS_DATA_TYPE_MONEYN, "MONEYNTYPE"},
516 {TDS_DATA_TYPE_DATETIMN, "DATETIMNTYPE"},
517 {TDS_DATA_TYPE_DATEN, "DATENTYPE - (introduced in TDS 7.3)"},
518 {TDS_DATA_TYPE_TIMEN, "TIMENTYPE - (introduced in TDS 7.3)"},
519 {TDS_DATA_TYPE_DATETIME2N, "DATETIME2NTYPE - (introduced in TDS 7.3)"},
520 {TDS_DATA_TYPE_DATETIMEOFFSETN, "DATETIMEOFFSETNTYPE - (introduced in TDS 7.3)"},
521 {TDS_DATA_TYPE_CHAR, "CHARTYPE - Char (TDS 4/5)"},
522 {TDS_DATA_TYPE_VARCHAR, "VARCHARTYPE - VarChar (TDS 4/5)"},
523 {TDS_DATA_TYPE_BINARY, "BINARYTYPE - Binary (TDS 4/5)"},
524 {TDS_DATA_TYPE_VARBINARY, "VARBINARYTYPE - VarBinary (TDS 4/5)"},
525 /* USHORTLEN_TYPE */
526 {TDS_DATA_TYPE_BIGVARBIN, "BIGVARBINTYPE - VarBinary"},
527 {TDS_DATA_TYPE_BIGVARCHR, "BIGVARCHRTYPE - VarChar"},
528 {TDS_DATA_TYPE_BIGBINARY, "BIGBINARYTYPE - Binary"},
529 {TDS_DATA_TYPE_BIGCHAR, "BIGCHARTYPE - Char"},
530 {TDS_DATA_TYPE_NVARCHAR, "NVARCHARTYPE - NVarChar"},
531 {TDS_DATA_TYPE_NCHAR, "NCHARTYPE - NChar"},
532 /* LONGLEN_TYPE */
533 {TDS_DATA_TYPE_XML, "XMLTYPE - XML (introduced in TDS 7.2)"},
534 {TDS_DATA_TYPE_UDT, "UDTTYPE - CLR-UDT (introduced in TDS 7.2)"},
535 {TDS_DATA_TYPE_TEXT, "TEXTTYPE - Text"},
536 {TDS_DATA_TYPE_IMAGE, "IMAGETYPE - Image"},
537 {TDS_DATA_TYPE_LONGBINARY, "LONGBINARY - Binary"},
538 {TDS_DATA_TYPE_NTEXT, "NTEXTTYPE - NText"},
539 {TDS_DATA_TYPE_SSVARIANT, "SSVARIANTTYPE - Sql_Variant (introduced in TDS 7.2)"},
540 {0, NULL }
543 void proto_reg_handoff_tds(void);
544 void proto_register_tds(void);
546 #define TDS_PORT_RANGE "1433,2433" /* Not IANA registered */
548 /************************ Message definitions ***********************/
550 /* Bulk Load BCP stream */
552 /* Bulk Load Update Text/Write Text */
554 /* Federated Authentication Token */
556 /* LOGIN fields */
558 static int hf_tdslogin;
559 static int hf_tdslogin_hostname_length;
560 static int hf_tdslogin_hostname;
561 static int hf_tdslogin_username_length;
562 static int hf_tdslogin_username;
563 static int hf_tdslogin_password_length;
564 static int hf_tdslogin_password;
565 static int hf_tdslogin_hostprocess_length;
566 static int hf_tdslogin_hostprocess;
567 static int hf_tdslogin_appname_length;
568 static int hf_tdslogin_appname;
569 static int hf_tdslogin_servername_length;
570 static int hf_tdslogin_servername;
571 static int hf_tdslogin_remotepassword_length;
572 static int hf_tdslogin_rempw_servername_length;
573 static int hf_tdslogin_rempw_servername;
574 static int hf_tdslogin_rempw_password_length;
575 static int hf_tdslogin_rempw_password;
576 static int hf_tdslogin_option_int2;
577 static int hf_tdslogin_option_int4;
578 static int hf_tdslogin_option_char;
579 static int hf_tdslogin_option_float;
580 static int hf_tdslogin_option_date8;
581 static int hf_tdslogin_option_usedb;
582 static int hf_tdslogin_option_bulk;
583 static int hf_tdslogin_option_server_to_server;
584 static int hf_tdslogin_option_server_to_server_loginack;
585 static int hf_tdslogin_option_conversation_type;
586 static int hf_tdslogin_proto_version;
587 static int hf_tdslogin_progname_length;
588 static int hf_tdslogin_progname;
589 static int hf_tdslogin_progvers;
590 static int hf_tdslogin_option2_noshort;
591 static int hf_tdslogin_option2_flt4;
592 static int hf_tdslogin_option2_date4;
593 static int hf_tdslogin_language;
594 static int hf_tdslogin_language_length;
595 static int hf_tdslogin_setlang;
596 static int hf_tdslogin_seclogin;
597 static int hf_tdslogin_secbulk;
598 static int hf_tdslogin_halogin;
599 static int hf_tdslogin_hasessionid;
600 static int hf_tdslogin_charset;
601 static int hf_tdslogin_charset_length;
602 static int hf_tdslogin_setcharset;
603 static int hf_tdslogin_packetsize;
604 static int hf_tdslogin_packetsize_length;
606 /* LOGIN7 Token */
607 static int hf_tds7login_total_size;
608 static int hf_tds7login_version;
609 static int hf_tds7login_packet_size;
610 static int hf_tds7login_client_version;
611 static int hf_tds7login_client_pid;
612 static int hf_tds7login_connection_id;
613 static int hf_tds7login_option_flags1;
614 static int hf_tds7login_option_flags2;
615 static int hf_tds7login_sql_type_flags;
616 static int hf_tds7login_reserved_flags;
617 static int hf_tds7login_time_zone;
618 static int hf_tds7login_collation;
619 static int hf_tds7login_offset;
620 static int hf_tds7login_length;
621 static int hf_tds7login_password;
622 static int hf_tds7login_clientname;
623 static int hf_tds7login_username;
624 static int hf_tds7login_appname;
625 static int hf_tds7login_servername;
626 static int hf_tds7login_libraryname;
627 static int hf_tds7login_locale;
628 static int hf_tds7login_databasename;
630 /* PRELOGIN stream */
631 static int hf_tds_prelogin;
632 static int hf_tds_prelogin_option_token;
633 static int hf_tds_prelogin_option_offset;
634 static int hf_tds_prelogin_option_length;
635 static int hf_tds_prelogin_option_version;
636 static int hf_tds_prelogin_option_subbuild;
637 static int hf_tds_prelogin_option_encryption;
638 static int hf_tds_prelogin_option_instopt;
639 static int hf_tds_prelogin_option_threadid;
640 static int hf_tds_prelogin_option_mars;
641 static int hf_tds_prelogin_option_traceid;
642 static int hf_tds_prelogin_option_fedauthrequired;
643 static int hf_tds_prelogin_option_nonceopt;
645 /* RPC Request Stream */
646 static int hf_tds_rpc;
647 static int hf_tds_rpc_name_length8;
648 static int hf_tds_rpc_name_length;
649 static int hf_tds_rpc_name;
650 static int hf_tds_rpc_proc_id;
651 static int hf_tds_rpc_options;
652 static int hf_tds_rpc_options_with_recomp;
653 static int hf_tds_rpc_options_no_metadata;
654 static int hf_tds_rpc_options_reuse_metadata;
655 static int hf_tds_rpc_separator;
656 static int hf_tds_rpc_parameter;
657 static int hf_tds_rpc_parameter_name_length;
658 static int hf_tds_rpc_parameter_name;
659 static int hf_tds_rpc_parameter_status;
660 static int hf_tds_rpc_parameter_status_by_ref;
661 static int hf_tds_rpc_parameter_status_default;
662 static int hf_tds_rpc_parameter_value;
664 /* SQLBatch Stream */
665 static int hf_tds_query;
667 /* SSPI Message Stream */
669 /* Transaction Manager Request Stream */
670 static int hf_tds_transmgr;
671 static int hf_tds_transmgr_payload;
673 /************************ Token definitions ************************/
675 /* ALTMETADATA token */
677 /* ALTROW token */
679 /* CAPABILITY token */
680 static int hf_tds_capability;
681 static int hf_tds_capability_length;
682 static int hf_tds_capability_captype;
683 static int hf_tds_capability_caplen;
684 static int hf_tds_capability_req_lang;
685 static int hf_tds_capability_req_rpc;
686 static int hf_tds_capability_req_evt;
687 static int hf_tds_capability_req_mstmt;
688 static int hf_tds_capability_req_bcp;
689 static int hf_tds_capability_req_cursor;
690 static int hf_tds_capability_req_dynf;
691 static int hf_tds_capability_req_msg;
692 static int hf_tds_capability_req_param;
693 static int hf_tds_capability_data_int1;
694 static int hf_tds_capability_data_int2;
695 static int hf_tds_capability_data_int4;
696 static int hf_tds_capability_data_bit;
697 static int hf_tds_capability_data_char;
698 static int hf_tds_capability_data_vchar;
699 static int hf_tds_capability_data_bin;
700 static int hf_tds_capability_data_vbin;
701 static int hf_tds_capability_data_mny8;
702 static int hf_tds_capability_data_mny4;
703 static int hf_tds_capability_data_date8;
704 static int hf_tds_capability_data_date4;
705 static int hf_tds_capability_data_flt4;
706 static int hf_tds_capability_data_flt8;
707 static int hf_tds_capability_data_num;
708 static int hf_tds_capability_data_text;
709 static int hf_tds_capability_data_image;
710 static int hf_tds_capability_data_dec;
711 static int hf_tds_capability_data_lchar;
712 static int hf_tds_capability_data_lbin;
713 static int hf_tds_capability_data_intn;
714 static int hf_tds_capability_data_datetimen;
715 static int hf_tds_capability_data_moneyn;
716 static int hf_tds_capability_csr_prev;
717 static int hf_tds_capability_csr_first;
718 static int hf_tds_capability_csr_last;
719 static int hf_tds_capability_csr_abs;
720 static int hf_tds_capability_csr_rel;
721 static int hf_tds_capability_csr_multi;
722 static int hf_tds_capability_con_oob;
723 static int hf_tds_capability_con_inband;
724 static int hf_tds_capability_con_logical;
725 static int hf_tds_capability_proto_text;
726 static int hf_tds_capability_proto_bulk;
727 static int hf_tds_capability_req_urgevt;
728 static int hf_tds_capability_data_sensitivity;
729 static int hf_tds_capability_data_boundary;
730 static int hf_tds_capability_proto_dynamic;
731 static int hf_tds_capability_proto_dynproc;
732 static int hf_tds_capability_data_fltn;
733 static int hf_tds_capability_data_bitn;
734 static int hf_tds_capability_data_int8;
735 static int hf_tds_capability_data_void;
736 static int hf_tds_capability_dol_bulk;
737 static int hf_tds_capability_object_java1;
738 static int hf_tds_capability_object_char;
739 static int hf_tds_capability_data_columnstatus;
740 static int hf_tds_capability_object_binary;
741 static int hf_tds_capability_widetable;
742 static int hf_tds_capability_data_uint2;
743 static int hf_tds_capability_data_uint4;
744 static int hf_tds_capability_data_uint8;
745 static int hf_tds_capability_data_uintn;
746 static int hf_tds_capability_cur_implicit;
747 static int hf_tds_capability_data_nlbin;
748 static int hf_tds_capability_image_nchar;
749 static int hf_tds_capability_blob_nchar_16;
750 static int hf_tds_capability_blob_nchar_8;
751 static int hf_tds_capability_blob_nchar_scsu;
752 static int hf_tds_capability_data_date;
753 static int hf_tds_capability_data_time;
754 static int hf_tds_capability_data_interval;
755 static int hf_tds_capability_csr_scroll;
756 static int hf_tds_capability_csr_sensitive;
757 static int hf_tds_capability_csr_insensitive;
758 static int hf_tds_capability_csr_semisensitive;
759 static int hf_tds_capability_csr_keysetdriven;
760 static int hf_tds_capability_req_srvpktsize;
761 static int hf_tds_capability_data_unitext;
762 static int hf_tds_capability_cap_clusterfailover;
763 static int hf_tds_capability_data_sint1;
764 static int hf_tds_capability_req_largeident;
765 static int hf_tds_capability_req_blob_nchar_16;
766 static int hf_tds_capability_data_xml;
767 static int hf_tds_capability_req_curinfo3;
768 static int hf_tds_capability_req_dbrpc2;
769 static int hf_tds_capability_res_nomsg;
770 static int hf_tds_capability_res_noeed;
771 static int hf_tds_capability_res_noparam;
772 static int hf_tds_capability_data_noint1;
773 static int hf_tds_capability_data_noint2;
774 static int hf_tds_capability_data_noint4;
775 static int hf_tds_capability_data_nobit;
776 static int hf_tds_capability_data_nochar;
777 static int hf_tds_capability_data_novchar;
778 static int hf_tds_capability_data_nobin;
779 static int hf_tds_capability_data_novbin;
780 static int hf_tds_capability_data_nomny8;
781 static int hf_tds_capability_data_nomny4;
782 static int hf_tds_capability_data_nodate8;
783 static int hf_tds_capability_data_nodate4;
784 static int hf_tds_capability_data_noflt4;
785 static int hf_tds_capability_data_noflt8;
786 static int hf_tds_capability_data_nonum;
787 static int hf_tds_capability_data_notext;
788 static int hf_tds_capability_data_noimage;
789 static int hf_tds_capability_data_nodec;
790 static int hf_tds_capability_data_nolchar;
791 static int hf_tds_capability_data_nolbin;
792 static int hf_tds_capability_data_nointn;
793 static int hf_tds_capability_data_nodatetimen;
794 static int hf_tds_capability_data_nomoneyn;
795 static int hf_tds_capability_con_nooob;
796 static int hf_tds_capability_con_noinband;
797 static int hf_tds_capability_proto_notext;
798 static int hf_tds_capability_proto_nobulk;
799 static int hf_tds_capability_data_nosensitivity;
800 static int hf_tds_capability_data_noboundary;
801 static int hf_tds_capability_res_notdsdebug;
802 static int hf_tds_capability_res_nostripblanks;
803 static int hf_tds_capability_data_noint8;
804 static int hf_tds_capability_object_nojava1;
805 static int hf_tds_capability_object_nochar;
806 static int hf_tds_capability_data_nocolumnstatus;
807 static int hf_tds_capability_object_nobinary;
808 static int hf_tds_capability_data_nouint2;
809 static int hf_tds_capability_data_nouint4;
810 static int hf_tds_capability_data_nouint8;
811 static int hf_tds_capability_data_nouintn;
812 static int hf_tds_capability_no_widetables;
813 static int hf_tds_capability_data_nonlbin;
814 static int hf_tds_capability_image_nonchar;
815 static int hf_tds_capability_blob_nonchar_16;
816 static int hf_tds_capability_blob_nonchar_8;
817 static int hf_tds_capability_blob_nonchar_scsu;
818 static int hf_tds_capability_data_nodate;
819 static int hf_tds_capability_data_notime;
820 static int hf_tds_capability_data_nointerval;
821 static int hf_tds_capability_data_nounitext;
822 static int hf_tds_capability_data_nosint1;
823 static int hf_tds_capability_no_largeident;
824 static int hf_tds_capability_no_blob_nchar_16;
825 static int hf_tds_capability_no_srvpktsize;
826 static int hf_tds_capability_data_noxml;
827 static int hf_tds_capability_no_nint_return_value;
828 static int hf_tds_capability_res_noxnldata;
829 static int hf_tds_capability_res_suppress_fmt;
830 static int hf_tds_capability_res_suppress_doneinproc;
831 static int hf_tds_capability_res_force_rowfmt2;
833 /* COLINFO token (TDS_COLFMT_TOKEN) */
834 static int hf_tds_colfmt;
835 static int hf_tds_colfmt_length;
836 static int hf_tds_colfmt_column;
837 static int hf_tds_colfmt_utype;
838 static int hf_tds_colfmt_ctype;
839 static int hf_tds_colfmt_csize;
840 static int hf_tds_colfmt_csize_long;
841 static int hf_tds_colfmt_text_tablename;
843 /* COLNAME token (TDS_COL_NAME_TOKEN) */
844 static int hf_tds_colname;
845 static int hf_tds_colname_length;
846 static int hf_tds_colname_column;
847 static int hf_tds_colname_name;
849 /* COLMETADATA token (TDS7_COL_METADATA_TOKEN) */
850 static int hf_tds_colmetadata;
851 static int hf_tds_colmetadata_results_token_flags;
852 static int hf_tds_colmetadata_columns;
853 static int hf_tds_colmetadata_large2_type_size;
854 static int hf_tds_colmetadata_large4_type_size;
855 static int hf_tds_colmetadata_usertype32;
856 static int hf_tds_colmetadata_usertype16;
857 static int hf_tds_colmetadata_results_token_type;
858 static int hf_tds_colmetadata_collate_codepage;
859 static int hf_tds_colmetadata_collate_flags;
860 static int hf_tds_colmetadata_collate_charset_id;
861 static int hf_tds_colmetadata_colname;
862 static int hf_tds_colmetadata_colname_length;
863 static int hf_tds_colmetadata_table_name_parts;
864 static int hf_tds_colmetadata_table_name;
865 static int hf_tds_colmetadata_table_name_length;
866 static int hf_tds_colmetadata_csize;
867 static int hf_tds_colmetadata_precision;
868 static int hf_tds_colmetadata_scale;
869 static int hf_tds_colmetadata_field;
870 static int hf_tds_colmetadata_flags_nullable;
871 static int hf_tds_colmetadata_flags_updateable;
872 static int hf_tds_colmetadata_flags_casesen;
873 static int hf_tds_colmetadata_flags_identity;
874 static int hf_tds_colmetadata_flags_computed;
875 static int hf_tds_colmetadata_flags_reservedodbc;
876 static int hf_tds_colmetadata_flags_sparsecolumnset;
877 static int hf_tds_colmetadata_flags_encrypted;
878 static int hf_tds_colmetadata_flags_fixedlenclrtype;
879 static int hf_tds_colmetadata_flags_hidden;
880 static int hf_tds_colmetadata_flags_key;
881 static int hf_tds_colmetadata_flags_nullableunknown;
882 static int hf_tds_colmetadata_maxbytesize;
883 static int hf_tds_colmetadata_dbname_length;
884 static int hf_tds_colmetadata_dbname;
885 static int hf_tds_colmetadata_schemaname_length;
886 static int hf_tds_colmetadata_schemaname;
887 static int hf_tds_colmetadata_typename_length;
888 static int hf_tds_colmetadata_typename;
889 static int hf_tds_colmetadata_assemblyqualifiedname_length;
890 static int hf_tds_colmetadata_assemblyqualifiedname;
891 static int hf_tds_colmetadata_owningschema_length;
892 static int hf_tds_colmetadata_owningschema;
893 static int hf_tds_colmetadata_xmlschemacollection_length;
894 static int hf_tds_colmetadata_xmlschemacollection;
896 /* CONTROL token (TDS_CONTROL_TOKEN) */
897 static int hf_tds_control;
898 static int hf_tds_control_length;
899 static int hf_tds_control_fmt;
901 /* CURCLOSE token (TDS_CURCLOSE_TOKEN) */
902 static int hf_tds_curclose;
903 static int hf_tds_curclose_length;
904 static int hf_tds_curclose_cursorid;
905 static int hf_tds_curclose_cursor_name;
906 static int hf_tds_curclose_option_deallocate;
908 /* CURDECLARE token (TDS_CURDECLARE_TOKEN) */
909 static int hf_tds_curdeclare;
910 static int hf_tds_curdeclare_length;
911 static int hf_tds_curdeclare_cursor_name;
912 static int hf_tds_curdeclare_options;
913 static int hf_tds_curdeclare_options_rdonly;
914 static int hf_tds_curdeclare_options_updatable;
915 static int hf_tds_curdeclare_options_sensitive;
916 static int hf_tds_curdeclare_options_dynamic;
917 static int hf_tds_curdeclare_options_implicit;
918 static int hf_tds_curdeclare_status_parameterized;
919 static int hf_tds_curdeclare_statement;
920 static int hf_tds_curdeclare_update_columns_num;
921 static int hf_tds_curdeclare_update_columns_name;
923 /* CURFETCH token (TDS_CURFETCH_TOKEN) */
924 static int hf_tds_curfetch;
925 static int hf_tds_curfetch_length;
926 static int hf_tds_curfetch_cursorid;
927 static int hf_tds_curfetch_cursor_name;
928 static int hf_tds_curfetch_type;
929 static int hf_tds_curfetch_rowcnt;
931 /* CURINFO token (TDS_CURINFO_TOKEN) */
932 static int hf_tds_curinfo;
933 static int hf_tds_curinfo_length;
934 static int hf_tds_curinfo_cursorid;
935 static int hf_tds_curinfo_cursor_name;
936 static int hf_tds_curinfo_cursor_command;
937 static int hf_tds_curinfo_cursor_status;
938 static int hf_tds_curinfo_cursor_status_declared;
939 static int hf_tds_curinfo_cursor_status_open;
940 static int hf_tds_curinfo_cursor_status_closed;
941 static int hf_tds_curinfo_cursor_status_rdonly;
942 static int hf_tds_curinfo_cursor_status_updatable;
943 static int hf_tds_curinfo_cursor_status_rowcnt;
944 static int hf_tds_curinfo_cursor_status_dealloc;
945 static int hf_tds_curinfo_cursor_rowcnt;
947 /* CUROPEN token (TDS_CUROPEN_TOKEN) */
948 static int hf_tds_curopen;
949 static int hf_tds_curopen_length;
950 static int hf_tds_curopen_cursorid;
951 static int hf_tds_curopen_cursor_name;
952 static int hf_tds_curopen_status_parameterized;
954 /* TDS5 DBRPC Token (TDS5_DBRPC_TOKEN) */
955 static int hf_tds_dbrpc;
956 static int hf_tds_dbrpc_length;
957 static int hf_tds_dbrpc_rpcname_len;
958 static int hf_tds_dbrpc_rpcname;
959 static int hf_tds_dbrpc_options;
960 static int hf_tds_dbrpc_options_recompile;
961 static int hf_tds_dbrpc_options_params;
963 /* DONE token (TDS_DONE_TOKEN) */
964 static int hf_tds_done;
965 static int hf_tds_done_curcmd;
966 static int hf_tds_done_status;
967 static int hf_tds_done_status_more;
968 static int hf_tds_done_status_error;
969 static int hf_tds_done_status_inxact;
970 static int hf_tds_done_status_proc;
971 static int hf_tds_done_status_count;
972 static int hf_tds_done_status_attn;
973 static int hf_tds_done_status_event;
974 static int hf_tds_done_status_rpcinbatch;
975 static int hf_tds_done_status_srverror;
976 static int hf_tds_done_donerowcount_32;
977 static int hf_tds_done_donerowcount_64;
979 /* DONEPROC token (TDS_DONEPROC_TOKEN) */
980 static int hf_tds_doneproc;
981 static int hf_tds_doneproc_curcmd;
982 static int hf_tds_doneproc_status;
983 static int hf_tds_doneproc_donerowcount_32;
984 static int hf_tds_doneproc_donerowcount_64;
986 /* DONEINPROC token () */
987 static int hf_tds_doneinproc;
988 static int hf_tds_doneinproc_curcmd;
989 static int hf_tds_doneinproc_status;
990 static int hf_tds_doneinproc_donerowcount_32;
991 static int hf_tds_doneinproc_donerowcount_64;
993 /* EED token (TDS5_EED_TOKEN) */
994 static int hf_tds_eed;
995 static int hf_tds_eed_length;
996 static int hf_tds_eed_number;
997 static int hf_tds_eed_state;
998 static int hf_tds_eed_class;
999 static int hf_tds_eed_sql_state;
1000 static int hf_tds_eed_status;
1001 static int hf_tds_eed_transtate;
1002 static int hf_tds_eed_msgtext;
1003 static int hf_tds_eed_servername;
1004 static int hf_tds_eed_procname;
1005 static int hf_tds_eed_linenumber;
1007 /* ENVCHANGE token (TDS_ENVCHG_TOKEN) */
1008 static int hf_tds_envchg;
1009 static int hf_tds_envchg_length;
1010 static int hf_tds_envchg_type;
1011 static int hf_tds_envchg_oldvalue_length;
1012 static int hf_tds_envchg_newvalue_length;
1013 static int hf_tds_envchg_oldvalue_string;
1014 static int hf_tds_envchg_newvalue_string;
1015 static int hf_tds_envchg_oldvalue_bytes;
1016 static int hf_tds_envchg_newvalue_bytes;
1017 static int hf_tds_envchg_collate_codepage;
1018 static int hf_tds_envchg_collate_flags;
1019 static int hf_tds_envchg_collate_charset_id;
1021 /* ERROR token (TDS_ERR_TOKEN) */
1022 static int hf_tds_error;
1023 static int hf_tds_error_length;
1024 static int hf_tds_error_number;
1025 static int hf_tds_error_state;
1026 static int hf_tds_error_class;
1027 static int hf_tds_error_msgtext_length;
1028 static int hf_tds_error_msgtext;
1029 static int hf_tds_error_servername_length;
1030 static int hf_tds_error_servername;
1031 static int hf_tds_error_procname_length;
1032 static int hf_tds_error_procname;
1033 static int hf_tds_error_linenumber_32;
1034 static int hf_tds_error_linenumber_16;
1036 /* FEATUREEXTACK token (TDS_FEATUREEXTACK_TOKEN) */
1037 static int hf_tds_featureextack;
1038 static int hf_tds_featureextack_feature;
1039 static int hf_tds_featureextack_featureid;
1040 static int hf_tds_featureextack_featureackdata;
1041 static int hf_tds_featureextack_featureackdatalen;
1043 /* FEDAUTHINFO token */
1045 /* INFO token */
1046 static int hf_tds_info;
1047 static int hf_tds_info_length;
1048 static int hf_tds_info_number;
1049 static int hf_tds_info_state;
1050 static int hf_tds_info_class;
1051 static int hf_tds_info_msgtext_length;
1052 static int hf_tds_info_msgtext;
1053 static int hf_tds_info_servername_length;
1054 static int hf_tds_info_servername;
1055 static int hf_tds_info_procname_length;
1056 static int hf_tds_info_procname;
1057 static int hf_tds_info_linenumber_32;
1058 static int hf_tds_info_linenumber_16;
1060 /* LOGINACK token (TDS_LOGIN_ACK_TOKEN) */
1061 static int hf_tds_loginack;
1062 static int hf_tds_loginack_length;
1063 static int hf_tds_loginack_interface;
1064 static int hf_tds_loginack_tdsversion;
1065 static int hf_tds_loginack_progversion;
1066 static int hf_tds_loginack_progname;
1068 /* LOGOUT token (TDS5_LOGOUT_TOKEN) */
1069 static int hf_tds_logout;
1070 static int hf_tds_logout_options;
1072 /* MSG token (TDS5_MSG_TOKEN) */
1073 static int hf_tds_msg;
1074 static int hf_tds_msg_length;
1075 static int hf_tds_msg_status;
1076 static int hf_tds_msg_msgid;
1078 /* NBCROW token (TDS_NBCROW_TOKEN) */
1079 static int hf_tds_nbcrow;
1081 /* OFFSET token */
1082 static int hf_tds_offset;
1083 static int hf_tds_offset_id;
1084 static int hf_tds_offset_len;
1086 /* ORDER token (TDS_ORDER_TOKEN) */
1087 static int hf_tds_order;
1088 static int hf_tds_order_length;
1089 static int hf_tds_order_colnum;
1091 /* PARAMFMT token (TDS5_PARAMFMT_TOKEN) */
1092 static int hf_tds_paramfmt;
1093 static int hf_tds_paramfmt_length;
1094 static int hf_tds_paramfmt_numparams;
1095 static int hf_tds_paramfmt_colname;
1096 static int hf_tds_paramfmt_status;
1097 static int hf_tds_paramfmt_utype;
1098 static int hf_tds_paramfmt_ctype;
1099 static int hf_tds_paramfmt_csize;
1100 static int hf_tds_paramfmt_locale_info;
1102 /* PARAMFMT2 token (TDS5_PARAM_TOKEN) */
1103 static int hf_tds_paramfmt2;
1104 static int hf_tds_paramfmt2_length;
1105 static int hf_tds_paramfmt2_numparams;
1106 static int hf_tds_paramfmt2_colname;
1107 static int hf_tds_paramfmt2_status;
1108 static int hf_tds_paramfmt2_utype;
1109 static int hf_tds_paramfmt2_ctype;
1110 static int hf_tds_paramfmt2_csize;
1111 static int hf_tds_paramfmt2_locale_info;
1113 /* PARAMS token (TDS5_PARAMS_TOKEN) */
1114 static int hf_tds_params;
1115 static int hf_tds_params_field;
1117 /* PROCID token (TDS_PROCID_TOKEN) */
1118 static int hf_tds_procid;
1119 static int hf_tds_procid_value;
1121 /* RETURNSTATUS token (TDS_RET_STAT_TOKEN) */
1122 static int hf_tds_returnstatus;
1123 static int hf_tds_returnstatus_value;
1125 /* RETURNVALUE token (TDS_RETURNVAL_TOKEN) */
1127 /* ROW token (TDS_ROW_TOKEN) */
1128 static int hf_tds_row;
1129 static int hf_tds_row_field;
1131 /* ROWFMT token (TDS5_ROWFMT_TOKEN) */
1132 static int hf_tds_rowfmt;
1133 static int hf_tds_rowfmt_length;
1134 static int hf_tds_rowfmt_numcols;
1135 static int hf_tds_rowfmt_colname;
1136 static int hf_tds_rowfmt_status;
1137 static int hf_tds_rowfmt_utype;
1138 static int hf_tds_rowfmt_ctype;
1139 static int hf_tds_rowfmt_csize;
1140 static int hf_tds_rowfmt_text_tablename;
1141 static int hf_tds_rowfmt_precision;
1142 static int hf_tds_rowfmt_scale;
1143 static int hf_tds_rowfmt_locale_info;
1145 /* ROWFMT2 token (TDS5_ROW_TOKEN) */
1146 static int hf_tds_rowfmt2;
1147 static int hf_tds_rowfmt2_length;
1148 static int hf_tds_rowfmt2_numcols;
1149 static int hf_tds_rowfmt2_labelname;
1150 static int hf_tds_rowfmt2_catalogname;
1151 static int hf_tds_rowfmt2_schemaname;
1152 static int hf_tds_rowfmt2_tablename;
1153 static int hf_tds_rowfmt2_colname;
1154 static int hf_tds_rowfmt2_status;
1155 static int hf_tds_rowfmt2_utype;
1156 static int hf_tds_rowfmt2_ctype;
1157 static int hf_tds_rowfmt2_csize;
1158 static int hf_tds_rowfmt2_text_tablename;
1159 static int hf_tds_rowfmt2_precision;
1160 static int hf_tds_rowfmt2_scale;
1161 static int hf_tds_rowfmt2_locale_info;
1163 /* SESSIONSTATE token (TDS_SESSIONSTATE_TOKEN) */
1164 static int hf_tds_sessionstate;
1165 static int hf_tds_sessionstate_length;
1166 static int hf_tds_sessionstate_seqno;
1167 static int hf_tds_sessionstate_status;
1168 static int hf_tds_sessionstate_stateid;
1169 static int hf_tds_sessionstate_statelen;
1170 static int hf_tds_sessionstate_statevalue;
1172 /* SSPI token */
1173 static int hf_tds_sspi;
1174 static int hf_tds_sspi_buffer;
1176 /* TABNAME token */
1178 /* TVPROW Token */
1180 /* TDS5 LANG Token */
1181 static int hf_tds_lang_length;
1182 static int hf_tds_lang_language_text;
1183 static int hf_tds_lang_token_status;
1184 static int hf_tds_lang_status_parameterized;
1186 /* Unknown token */
1187 static int hf_tds_unknown_tds_token;
1189 /*********************** Basic types *******************************/
1191 static int hf_tds_type_info;
1192 static int hf_tds_type_info_type;
1193 static int hf_tds_type_info_varlen;
1194 static int hf_tds_type_info_precision;
1195 static int hf_tds_type_info_scale;
1196 static int hf_tds_type_info_collation;
1197 static int hf_tds_type_info_collation_lcid;
1198 static int hf_tds_type_info_collation_ign_case;
1199 static int hf_tds_type_info_collation_ign_accent;
1200 static int hf_tds_type_info_collation_ign_kana;
1201 static int hf_tds_type_info_collation_ign_width;
1202 static int hf_tds_type_info_collation_binary;
1203 static int hf_tds_type_info_collation_version;
1204 static int hf_tds_type_info_collation_sortid;
1205 static int hf_tds_type_varbyte_length;
1206 static int hf_tds_type_varbyte_data_null;
1207 static int hf_tds_type_varbyte_data_boolean;
1208 static int hf_tds_type_varbyte_data_int1;
1209 static int hf_tds_type_varbyte_data_int2;
1210 static int hf_tds_type_varbyte_data_int4;
1211 static int hf_tds_type_varbyte_data_int8;
1212 static int hf_tds_type_varbyte_data_float;
1213 static int hf_tds_type_varbyte_data_double;
1214 static int hf_tds_type_varbyte_data_bytes;
1215 static int hf_tds_type_varbyte_data_uint_bytes;
1216 static int hf_tds_type_varbyte_data_guid;
1217 static int hf_tds_type_varbyte_data_string;
1218 static int hf_tds_type_varbyte_data_uint_string;
1219 static int hf_tds_type_varbyte_data_absdatetime;
1220 static int hf_tds_type_varbyte_data_reltime;
1221 static int hf_tds_type_varbyte_data_sign;
1222 static int hf_tds_type_varbyte_data_textptr_len;
1223 static int hf_tds_type_varbyte_data_textptr;
1224 static int hf_tds_type_varbyte_data_text_ts;
1225 static int hf_tds_type_varbyte_plp_len;
1226 static int hf_tds_type_varbyte_plp_chunk_len;
1227 static int hf_tds_type_varbyte_plp_chunk;
1228 static int hf_tds_type_varbyte_column_name;
1230 /****************************** Top level TDS ******************************/
1232 static int proto_tds;
1233 static int hf_tds_type;
1234 static int hf_tds_status;
1235 static int hf_tds_status_eom;
1236 static int hf_tds_status_ignore;
1237 static int hf_tds_status_event_notif;
1238 static int hf_tds_status_reset_conn;
1239 static int hf_tds_status_reset_conn_skip_tran;
1240 static int hf_tds_length;
1241 static int hf_tds_channel;
1242 static int hf_tds_packet_number;
1243 static int hf_tds_window;
1244 static int hf_tds_reassembled_in;
1245 static int hf_tds_reassembled_length;
1246 static int hf_tds_fragments;
1247 static int hf_tds_fragment;
1248 static int hf_tds_fragment_overlap;
1249 static int hf_tds_fragment_overlap_conflict;
1250 static int hf_tds_fragment_multiple_tails;
1251 static int hf_tds_fragment_too_long_fragment;
1252 static int hf_tds_fragment_error;
1253 static int hf_tds_fragment_count;
1254 static int hf_tds_all_headers;
1255 static int hf_tds_all_headers_total_length;
1256 static int hf_tds_all_headers_header_length;
1257 static int hf_tds_all_headers_header_type;
1258 static int hf_tds_all_headers_trans_descr;
1259 static int hf_tds_all_headers_request_cnt;
1260 static int hf_tds_unknown_tds_packet;
1262 /* Initialize the subtree pointers */
1263 static int ett_tds;
1264 static int ett_tds_status;
1265 static int ett_tds_fragments;
1266 static int ett_tds_fragment;
1267 static int ett_tds_token;
1268 static int ett_tds_capability_req;
1269 static int ett_tds_capability_resp;
1270 static int ett_tds_done_status;
1271 static int ett_tds_all_headers;
1272 static int ett_tds_all_headers_header;
1273 static int ett_tds_type_info;
1274 static int ett_tds_type_info_collation;
1275 static int ett_tds_type_varbyte;
1276 static int ett_tds_message;
1277 static int ett_tds_rpc_options;
1278 static int ett_tds_rpc_parameter;
1279 static int ett_tds_rpc_parameter_status;
1280 static int ett_tds7_query;
1281 static int ett_tds7_prelogin;
1282 static int ett_tds_login;
1283 static int ett_tds_login_options;
1284 static int ett_tds_login_options2;
1285 static int ett_tds_login_rempw;
1286 static int ett_tds7_login;
1287 static int ett_tds7_hdr;
1288 static int ett_tds_col;
1289 static int ett_tds_flags;
1290 static int ett_tds_prelogin_option;
1291 static int ett_tds7_featureextack;
1292 static int ett_tds7_featureextack_feature;
1293 static int ett_tds5_dbrpc_options;
1294 static int ett_tds5_curdeclare_options;
1295 static int ett_tds5_curinfo_status;
1297 /* static expert_field ei_tds_type_info_type_undecoded; */
1298 static expert_field ei_tds_invalid_length;
1299 static expert_field ei_tds_token_length_invalid;
1300 static expert_field ei_tds_invalid_plp_length;
1301 static expert_field ei_tds_type_info_type;
1302 static expert_field ei_tds_all_headers_header_type;
1303 /* static expert_field ei_tds_token_stats; */
1304 static expert_field ei_tds_invalid_plp_type;
1305 static expert_field ei_tds_cursor_name_mismatch;
1307 /* Desegmentation of Netlib buffers crossing TCP segment boundaries. */
1308 static bool tds_desegment = true;
1310 static const fragment_items tds_frag_items = {
1311 &ett_tds_fragment,
1312 &ett_tds_fragments,
1313 &hf_tds_fragments,
1314 &hf_tds_fragment,
1315 &hf_tds_fragment_overlap,
1316 &hf_tds_fragment_overlap_conflict,
1317 &hf_tds_fragment_multiple_tails,
1318 &hf_tds_fragment_too_long_fragment,
1319 &hf_tds_fragment_error,
1320 &hf_tds_fragment_count,
1321 &hf_tds_reassembled_in,
1322 &hf_tds_reassembled_length,
1323 /* Reassembled data field */
1324 NULL,
1325 "fragments"
1328 /* Tables for reassembly of fragments. */
1329 static reassembly_table tds_reassembly_table;
1331 /* defragmentation of multi-buffer TDS PDUs */
1332 static bool tds_defragment = true;
1334 static dissector_handle_t tds_tcp_handle;
1335 static dissector_handle_t ntlmssp_handle;
1336 static dissector_handle_t gssapi_handle;
1337 static dissector_handle_t spnego_handle;
1338 static dissector_handle_t smp_handle;
1339 static dissector_handle_t tls_handle;
1341 #define TDS_CURSOR_NAME_VALID 0x01
1342 #define TDS_CURSOR_ID_VALID 0x02
1343 #define TDS_CURSOR_ROWINFO_VALID 0x04
1344 #define TDS_CURSOR_IN_CONV_TABLE 0x08
1345 #define TDS_CURSOR_FETCH_PENDING 0x10
1347 typedef struct {
1348 const char *tds_cursor_name;
1349 unsigned tds_cursor_id;
1350 struct _netlib_data *tds_cursor_rowinfo;
1351 unsigned tds_cursor_flags;
1352 } tds_cursor_info_t;
1354 typedef struct {
1355 tds_cursor_info_t *tds_conv_cursor_current;
1356 wmem_tree_t *tds_conv_cursor_table;
1357 } tds_conv_cursor_info_t;
1359 typedef struct {
1360 tds_conv_cursor_info_t *tds_conv_cursor_info;
1361 int tds_version;
1362 uint32_t client_version;
1363 uint32_t server_version;
1364 unsigned tds_encoding_int2;
1365 unsigned tds_encoding_int4;
1366 unsigned tds_encoding_char;
1367 unsigned tds_encoding_date8;
1368 unsigned tds_encoding_date4;
1369 bool tds_packets_in_order;
1370 } tds_conv_info_t;
1372 /* The actual TDS protocol values used on the wire. */
1373 #define TDS_PROTOCOL_VALUE_4_2 0x04020000
1374 #define TDS_PROTOCOL_VALUE_4_6 0x04060000
1375 #define TDS_PROTOCOL_VALUE_5 0x05000000
1376 #define TDS_PROTOCOL_VALUE_7_0 0x07000000
1377 #define TDS_PROTOCOL_VALUE_7_1 0x07010000
1378 #define TDS_PROTOCOL_VALUE_7_1_1 0x71000001
1379 #define TDS_PROTOCOL_VALUE_7_2 0x72090002
1380 #define TDS_PROTOCOL_VALUE_7_3A 0x730A0003
1381 #define TDS_PROTOCOL_VALUE_7_3B 0x730B0003
1382 #define TDS_PROTOCOL_VALUE_7_4 0x74000004
1384 /* TDS protocol type preference */
1385 /* XXX: This preference is used as a 'hint' for cases where interpretation is ambiguous */
1386 /* Currently the hint is global */
1387 /* TODO: Consider storing protocol type with each conversation */
1388 /* (when type is determined and using the preference as a default) ?? */
1390 #define TDS_PROTOCOL_NOT_SPECIFIED 0xFFFF
1391 #define TDS_PROTOCOL_4 0x4000
1392 #define TDS_PROTOCOL_5 0x5000
1393 #define TDS_PROTOCOL_7_0 0x7000
1394 #define TDS_PROTOCOL_7_1 0x7100
1395 #define TDS_PROTOCOL_7_2 0x7200
1396 #define TDS_PROTOCOL_7_3 0x7300
1397 #define TDS_PROTOCOL_7_3A 0x730a
1398 #define TDS_PROTOCOL_7_3B 0x730b
1399 #define TDS_PROTOCOL_7_4 0x7400
1401 static int tds_protocol_type = TDS_PROTOCOL_NOT_SPECIFIED;
1403 static const enum_val_t tds_protocol_type_options[] = {
1404 {"not_specified", "Not Specified", TDS_PROTOCOL_NOT_SPECIFIED},
1405 {"tds4", "TDS 4.x", TDS_PROTOCOL_4},
1406 {"tds5", "TDS 5.0", TDS_PROTOCOL_5},
1407 {"tds70", "TDS 7.0", TDS_PROTOCOL_7_0},
1408 {"tds71", "TDS 7.1", TDS_PROTOCOL_7_1},
1409 {"tds72", "TDS 7.2", TDS_PROTOCOL_7_2},
1410 {"tds73", "TDS 7.3", TDS_PROTOCOL_7_3},
1411 {"tds73a", "TDS 7.3A", TDS_PROTOCOL_7_3A},
1412 {"tds73b", "TDS 7.3B", TDS_PROTOCOL_7_3B},
1413 {"tds74", "TDS 7.4", TDS_PROTOCOL_7_4},
1414 {NULL, NULL, -1}
1417 #define TDS_PROTO_PREF_NOT_SPECIFIED (tds_protocol_type == TDS_PROTOCOL_NOT_SPECIFIED)
1419 #define TDS_PROTO_LESS_THAN_TDS7(tds_info) \
1420 (TDS_PROTO_PREF_NOT_SPECIFIED ? ((tds_info)->tds_version <= TDS_PROTOCOL_7_0) \
1421 : (tds_protocol_type <= TDS_PROTOCOL_7_0))
1422 #define TDS_PROTO_TDS5(tds_info) \
1423 (TDS_PROTO_PREF_NOT_SPECIFIED ? ((tds_info)->tds_version == TDS_PROTOCOL_5) \
1424 : (tds_protocol_type == TDS_PROTOCOL_5))
1425 #define TDS_PROTO_TDS7(tds_info) \
1426 (TDS_PROTO_PREF_NOT_SPECIFIED ? ((tds_info)->tds_version >= TDS_PROTOCOL_7_0) && \
1427 ((tds_info)->tds_version <= TDS_PROTOCOL_7_4) \
1428 : (tds_protocol_type >= TDS_PROTOCOL_7_0 && \
1429 tds_protocol_type <= TDS_PROTOCOL_7_4))
1430 #define TDS_PROTO_TDS7_1_OR_LESS(tds_info) \
1431 (TDS_PROTO_PREF_NOT_SPECIFIED ? ((tds_info)->tds_version <= TDS_PROTOCOL_7_1) \
1432 : (tds_protocol_type <= TDS_PROTOCOL_7_1))
1433 #define TDS_PROTO_TDS7_2_OR_GREATER(tds_info) \
1434 (TDS_PROTO_PREF_NOT_SPECIFIED ? ((tds_info)->tds_version >= TDS_PROTOCOL_7_2) \
1435 : (tds_protocol_type >= TDS_PROTOCOL_7_2))
1436 #define TDS_PROTO_TDS7_3A_OR_LESS(tds_info) \
1437 (TDS_PROTO_PREF_NOT_SPECIFIED ? ((tds_info)->tds_version <= TDS_PROTOCOL_7_3A) \
1438 : (tds_protocol_type <= TDS_PROTOCOL_7_3A))
1439 #define TDS_PROTO_TDS7_3B_OR_GREATER(tds_info) \
1440 (TDS_PROTO_PREF_NOT_SPECIFIED ? (tds_info->tds_version >= TDS_PROTOCOL_7_3B) \
1441 : (tds_protocol_type >= TDS_PROTOCOL_7_3B))
1442 #define TDS_PROTO_TDS7_4_OR_GREATER(tds_info) \
1443 (TDS_PROTO_PREF_NOT_SPECIFIED ? ((tds_info)->tds_version >= TDS_PROTOCOL_7_4) \
1444 : (tds_protocol_type >= TDS_PROTOCOL_7_4))
1446 /* TDS "endian type" */
1447 /* XXX: Assumption is that all TDS conversations being decoded in a particular capture */
1448 /* have the same endian type */
1449 /* TODO: consider storing endian type with each conversation */
1450 /* (using pref as the default) */
1452 static gboolean tds_little_endian = TRUE;
1454 static const enum_val_t tds_endian_type_options[] = {
1455 {"little_endian", "Little Endian", true},
1456 {"big_endian" , "Big Endian" , false},
1457 {NULL, NULL, -1}
1460 /* TCP port preferences for TDS decode */
1461 static range_t *tds_tcp_ports;
1463 /* These correspond to the netlib packet type field */
1464 static const value_string packet_type_names[] = {
1465 {TDS_QUERY_PKT, "SQL batch"},
1466 {TDS_LOGIN_PKT, "TDS4/5 login"},
1467 {TDS_RPC_PKT, "Remote Procedure Call"},
1468 {TDS_RESP_PKT, "Response"},
1469 {TDS_RAW_PKT, "Unused"},
1470 {TDS_ATTENTION_PKT, "Attention"},
1471 {TDS_BULK_DATA_PKT, "Bulk load data"},
1472 {TDS_OPEN_CHN_PKT, "Unused"},
1473 {TDS_CLOSE_CHN_PKT, "Unused"},
1474 {TDS_RES_ERROR_PKT, "Unused"},
1475 {TDS_LOG_CHN_ACK_PKT, "Unused"},
1476 {TDS_ECHO_PKT, "Unused"},
1477 {TDS_LOGOUT_CHN_PKT, "Unused"},
1478 {TDS_TRANS_MGR_PKT, "Transaction Manager Request"},
1479 {TDS5_QUERY_PKT, "TDS5 query"},
1480 {TDS_LOGIN7_PKT, "TDS7 login"},
1481 {TDS_SSPI_PKT, "SSPI message"},
1482 {TDS_PRELOGIN_PKT, "TDS7 pre-login message"},
1483 {TDS_TLS_PKT, "TLS exchange"},
1484 {0, NULL}
1487 enum {
1488 TDS_HEADER_QUERY_NOTIF = 0x0001,
1489 TDS_HEADER_TRANS_DESCR = 0x0002
1492 static const value_string header_type_names[] = {
1493 {TDS_HEADER_QUERY_NOTIF, "Query notifications"},
1494 {TDS_HEADER_TRANS_DESCR, "Transaction descriptor"},
1495 {0, NULL}
1498 /* The status field */
1499 #define is_valid_tds_status(x) ((x) == 0x00 || /* Normal, not last buffer */ \
1500 (x) == 0x01 || /* Normal, last buffer */ \
1501 (x) == 0x02 || /* TDS7: Attention ack, but not last buffer. TDS45 invalid. */ \
1502 (x) == 0x03 || /* TDS7: Attention Ack, last buffer. */ \
1503 (x) == 0x05 || /* TDS45: Attention, last buffer */ \
1504 (x) == 0x09 || /* TDS45: Event, last buffer. TDS7: Reset connection, last buffer */ \
1505 (x) == 0x11 || /* TDS45: Seal, last buffer. TDS7: Reset connection skip tran, last buffer */ \
1506 (x) == 0x21) /* TDS45: Encrypt, last buffer. */
1508 #define STATUS_LAST_BUFFER 0x01
1509 #define STATUS_IGNORE_EVENT 0x02
1510 #define STATUS_EVENT_NOTIFICATION 0x04
1511 #define STATUS_RESETCONNECTION 0x08
1512 #define STATUS_RESETCONNECTIONSKIPTRAN 0x10
1514 /* The one byte token at the start of each TDS PDU */
1515 static const value_string token_names[] = {
1516 {TDS5_DYNAMIC_TOKEN, "TDS5 Dynamic SQL"},
1517 {TDS5_PARAMFMT_TOKEN, "TDS5 Parameter Format"},
1518 {TDS5_PARAMFMT2_TOKEN, "TDS5 Parameter2 Format"},
1519 {TDS5_PARAMS_TOKEN, "TDS5 Parameters"},
1520 {TDS_LANG_TOKEN, "Language"},
1521 {TDS5_LOGOUT_TOKEN, "Logout"},
1522 {TDS_RET_STAT_TOKEN, "Return Status"},
1523 {TDS_PROCID_TOKEN, "Proc ID"},
1524 {TDS_COL_NAME_TOKEN, "Column Names"},
1525 {TDS_COLFMT_TOKEN, "Column Format"},
1526 {TDS_COMPUTE_NAMES_TOKEN, "Compute Names"},
1527 {TDS_COMPUTE_RESULT_TOKEN, "Compute Results"},
1528 {TDS_ORDER_TOKEN, "Order"},
1529 {TDS_ERR_TOKEN, "Error Message"},
1530 {TDS_INFO_TOKEN, "Info Message"},
1531 {TDS_LOGIN_ACK_TOKEN, "Login Acknowledgement"},
1532 {TDS_KEY_TOKEN, "TDS Key"},
1533 {TDS_ROW_TOKEN, "Row"},
1534 {TDS_CAPABILITY_TOKEN, "Capabilities"},
1535 {TDS_ENVCHG_TOKEN, "Environment Change"},
1536 {TDS5_EED_TOKEN, "Extended Error"},
1537 {TDS_AUTH_TOKEN, "Authentication"},
1538 {TDS5_ROWFMT_TOKEN, "Rowfmt"},
1539 {TDS_DONE_TOKEN, "Done"},
1540 {TDS_DONEPROC_TOKEN, "Done Proc"},
1541 {TDS_DONEINPROC_TOKEN, "Done In Proc"},
1542 {TDS5_DYNAMIC2_TOKEN, "TDS5 Dynamic2"},
1543 {TDS5_ORDERBY2_TOKEN, "TDS5 OrderBy2"},
1544 {TDS5_CURDECLARE2_TOKEN, "TDS5 CurDeclare2"},
1545 {TDS5_ROWFMT2_TOKEN, "TDS5 RowFmt2"},
1546 {TDS5_MSG_TOKEN, "TDS5 Msg"},
1547 {TDS_OFFSET_TOKEN, "Offset"},
1548 {TDS_CURCLOSE_TOKEN, "CurClose"},
1549 {TDS7_COL_METADATA_TOKEN, "Column Metadata"},
1550 {TDS_CURFETCH_TOKEN, "CurFetch"},
1551 {TDS_CURINFO_TOKEN, "CurInfo"},
1552 {TDS_CUROPEN_TOKEN, "CurOpen"},
1553 {TDS_CURDECLARE_TOKEN, "CurDeclare"},
1554 {TDS7_ALTMETADATA_TOKEN, "AltMetaData"},
1555 {TDS_TABNAME_TOKEN, "Table Name"},
1556 {TDS7_COL_INFO_TOKEN, "Column Info"},
1557 {TDS_OPTIONCMD_TOKEN, "OptionCmd"},
1558 {TDS_RETURNVAL_TOKEN, "Return Value"},
1559 {TDS_FEATUREEXTACK_TOKEN, "FeatureExt Acknowledgement"},
1560 {TDS_NBCROW_TOKEN, "Row (with Null Bitmap Compression)"},
1561 {TDS_ALTROW_TOKEN, "ALTROW"},
1562 {TDS_SESSIONSTATE_TOKEN, "Session State"},
1563 {TDS5_DBRPC_TOKEN, "DBRPC"},
1564 {TDS_SSPI_TOKEN, "SSPI"},
1565 {TDS_FEDAUTHINFO_TOKEN, "FEDAUTHINFO"},
1566 {0, NULL}
1569 #define TDS_RPC_SEPARATOR_BATCH_FLAG 0x80
1570 #define TDS_RPC_SEPARATOR_BATCH_FLAG_7_2 0xFF
1571 #define TDS_RPC_SEPARATOR_NO_EXEC_FLAG 0xFE
1573 static const value_string tds_rpc_separators[] = {
1574 {TDS_RPC_SEPARATOR_BATCH_FLAG, "Batch flag"},
1575 {TDS_RPC_SEPARATOR_BATCH_FLAG_7_2, "Batch flag 7.2"},
1576 {TDS_RPC_SEPARATOR_NO_EXEC_FLAG, "No exec flag"},
1577 {0, NULL }
1580 static const value_string internal_stored_proc_id_names[] = {
1581 {TDS_SP_CURSOR, "sp_cursor" },
1582 {TDS_SP_CURSOROPEN, "sp_cursoropen" },
1583 {TDS_SP_CURSORPREPARE, "sp_cursorprepare" },
1584 {TDS_SP_CURSOREXECUTE, "sp_cursorexecute" },
1585 {TDS_SP_CURSORPREPEXEC, "sp_cursorprepexec" },
1586 {TDS_SP_CURSORUNPREPARE, "sp_cursorunprepare"},
1587 {TDS_SP_CURSORFETCH, "sp_cursorfetch" },
1588 {TDS_SP_CURSOROPTION, "sp_cursoroption" },
1589 {TDS_SP_CURSORCLOSE, "sp_cursorclose" },
1590 {TDS_SP_EXECUTESQL, "sp_executesql" },
1591 {TDS_SP_PREPARE, "sp_prepare" },
1592 {TDS_SP_EXECUTE, "sp_execute" },
1593 {TDS_SP_PREPEXEC, "sp_prepexec" },
1594 {TDS_SP_PREPEXECRPC, "sp_prepexecrpc" },
1595 {TDS_SP_UNPREPARE, "sp_unprepare" },
1596 {0, NULL }
1599 static const value_string envchg_names[] = {
1600 {1, "Database"},
1601 {2, "Language"},
1602 {3, "Character set"},
1603 {4, "Packet size"},
1604 {5, "Unicode data sorting local id"},
1605 {6, "Unicode data sorting comparison flags"},
1606 {7, "SQL Collation"},
1607 {8, "Begin Transaction"},
1608 {9, "Commit Transaction"},
1609 {10, "Rollback Transaction"},
1610 {11, "Enlist DTC Transaction"},
1611 {12, "Defect Transaction"},
1612 {13, "Real Time Log Shipping"},
1613 /* 14 not assigned */
1614 {15, "Promote Transaction"},
1615 {16, "Transaction Manager Address"},
1616 {17, "Transaction ended"},
1617 {18, "RESETCONNECTION/RESETCONNECTIONSKIPTRAN Completion Acknowledgement"},
1618 {19, "Sends back name of user instance started per login request"},
1619 {20, "Sends routing information to client"},
1620 {0, NULL}
1623 static const value_string login_options[] = {
1624 {TDS_INT4_BIG_ENDIAN, "Big-endian"},
1625 {TDS_INT4_LITTLE_ENDIAN, "Little-endian"},
1626 {TDS_INT2_BIG_ENDIAN, "Big-endian"},
1627 {TDS_INT2_LITTLE_ENDIAN, "Little-endian"},
1628 {TDS_FLT8_BIG_ENDIAN, "IEEE Big-endian"},
1629 {TDS_FLT8_VAX_D, "VAX D"},
1630 {TDS_CHAR_ASCII, "ASCII"},
1631 {TDS_CHAR_EBCDIC, "EBCDIC"},
1632 {TDS_DATE8_TIME_FIRST, "Time first"},
1633 {TDS_DATE8_DATE_FIRST, "Date first"},
1634 {TDS_FLT8_LITTLE_ENDIAN, "IEEE Little-endian"},
1635 {TDS_FLT8_ND5000, "ND5000"},
1636 {12, "IEEE Big-endian"},
1637 {13, "IEEE Little-endian"},
1638 {14, "VAX F"},
1639 {15, "ND5000 4"},
1640 {TDS_DATE4_TIME_FIRST, "Time first"},
1641 {TDS_DATE4_DATE_FIRST, "Date first"},
1642 {0, NULL}
1645 static const value_string login_conversation_type[] = {
1646 {0, "Client to server"},
1647 {1, "Server to server"},
1648 {2, "Server remote login"},
1649 {4, "Internal RPC"},
1650 {0, NULL}
1653 static const value_string login_server_to_server[] = {
1654 {0, "Server's Default SQL"},
1655 {1, "Transact-SQL"},
1656 {2, "ANSI SQL, version 1"},
1657 {3, "ANSI SQL, version 2, level 1"},
1658 {4, "ANSI SQL, version 2, level 2"},
1659 {5, "Log in succeeded"},
1660 {6, "Log in failed"},
1661 {7, "Negotiate further"},
1662 {0, NULL}
1665 static const value_string tds_capability_type[] = {
1666 {TDS_CAP_REQUEST, "Request capabilities"},
1667 {TDS_CAP_RESPONSE, "Response capabilities"},
1668 {0, NULL}
1671 static const value_string tds_curfetch_types[] = {
1672 {TDS_CUR_NEXT, "Next"},
1673 {TDS_CUR_PREV, "Previous"},
1674 {TDS_CUR_FIRST, "First"},
1675 {TDS_CUR_LAST, "Last"},
1676 {TDS_CUR_ABS, "Absolute"},
1677 {TDS_CUR_REL, "Relative"},
1678 {0, NULL}
1681 static const value_string tds_curinfo_commands[] = {
1682 {TDS_CURINFO_SET_FETCH_COUNT, "Set fetch count"},
1683 {TDS_CURINFO_INQUIRE, "Inquire cursor state"},
1684 {TDS_CURINFO_INFORM, "Report information about a cursor"},
1685 {TDS_CURINFO_LISTALL, "List all open cursors"},
1686 {0, NULL}
1689 static const value_string login_field_names[] = {
1690 {0, "Client Name"},
1691 {1, "Username"},
1692 {2, "Password"},
1693 {3, "App Name"},
1694 {4, "Server Name"},
1695 {5, "Unknown1"},
1696 {6, "Library Name"},
1697 {7, "Locale"},
1698 {8, "Database Name"},
1699 {0, NULL}
1702 static const value_string prelogin_token_names[] = {
1703 {0, "Version"},
1704 {1, "Encryption"},
1705 {2, "InstOpt"},
1706 {3, "ThreadID"},
1707 {4, "MARS"},
1708 {5, "TraceID"},
1709 {6, "FedAuthRequired"},
1710 {7, "NonceOpt"},
1711 {255, "Terminator"},
1712 {0, NULL}
1715 static const value_string featureextack_feature_names[] = {
1716 {0, "Reserved"},
1717 {1, "SessionRecovery"},
1718 {2, "FedAuth"},
1719 {4, "ColumnEncryption"},
1720 {5, "GlobalTransactions"},
1721 {8, "AzureSQLSupport"},
1722 {9, "DataClassification"},
1723 {10, "UTF8Support"},
1724 {255, "Terminator"},
1725 {0, NULL}
1728 static const value_string transmgr_types[] = {
1729 {0, "TM_GET_DTC_ADDRESS"},
1730 {1, "TM_PROPAGATE_XACT"},
1731 {5, "TM_BEGIN_XACT"},
1732 {6, "TM_PROMOTE_XACT"},
1733 {7, "TM_COMMIT_XACT"},
1734 {8, "TM_ROLLBACK_XACT"},
1735 {9, "TM_SAVE_XACT"},
1736 {0, NULL}
1739 static const value_string prelogin_encryption_options[] = {
1740 {0, "Encryption is available but off"},
1741 {1, "Encryption is available and on"},
1742 {2, "Encryption is not available"},
1743 {3, "Encryption is required"},
1744 {0, NULL}
1747 static const true_false_string tds_tfs_more_final = {"More tokens follow", "Final done token"};
1749 static const unit_name_string units_characters = { " character", " characters" };
1751 static const value_string tds_mars_type[] = {
1752 {0, "Off"},
1753 {1, "On"},
1754 {0, NULL}
1757 #define TDS_MAX_COLUMNS 256
1760 * This is where we store the column information to be used in decoding the
1761 * TDS_ROW_TOKEN tokens.
1763 struct _tds_col {
1764 const char *name;
1765 unsigned csize;
1766 uint32_t utype;
1767 uint8_t ctype;
1768 uint8_t precision;
1769 uint8_t scale;
1772 struct _netlib_data {
1773 unsigned num_cols;
1774 struct _tds_col *columns[TDS_MAX_COLUMNS];
1777 struct tds7_login_packet_hdr {
1778 uint32_t total_packet_size;
1779 uint32_t tds_version;
1780 uint32_t packet_size;
1781 uint32_t client_version;
1782 uint32_t client_pid;
1783 uint32_t connection_id;
1784 uint8_t option_flags1;
1785 uint8_t option_flags2;
1786 uint8_t sql_type_flags;
1787 uint8_t reserved_flags;
1788 uint32_t time_zone;
1789 uint32_t collation;
1792 /* support routines */
1795 * https://github.com/FreeTDS/freetds/blob/master/src/tds/gssapi.c
1796 * " There are some differences between this implementation and MS on
1797 * - MS use SPNEGO with 3 mechnisms (MS KRB5, KRB5, NTLMSSP..."
1799 * FreeTDS uses a GSS-API implementation, but MS uses SPNEGO (both
1800 * in 4.2 [MS-SSTDS] and 7.x and 8 [MS-TSD]) that is incompatible.
1801 * Both report similar TDS versions, so check for either.
1803 static void
1804 dissect_tds_nt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1805 unsigned offset)
1807 tvbuff_t *nt_tvb;
1808 int8_t ber_class;
1809 bool pc;
1810 int32_t tag;
1812 nt_tvb = tvb_new_subset_remaining(tvb, offset);
1813 if(tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0)
1814 call_dissector(ntlmssp_handle, nt_tvb, pinfo, tree);
1815 else {
1816 get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
1817 if (ber_class == BER_CLASS_CON && pc && (tag == 0 || tag == 1)) {
1818 call_dissector(spnego_handle, nt_tvb, pinfo, tree);
1819 } else {
1820 call_dissector(gssapi_handle, nt_tvb, pinfo, tree);
1825 static unsigned
1826 tds_get_int2_encoding(tds_conv_info_t *tds_info)
1828 return (tds_info->tds_encoding_int2 == TDS_INT2_BIG_ENDIAN) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
1831 static unsigned
1832 tds_get_int4_encoding(tds_conv_info_t *tds_info)
1834 return (tds_info->tds_encoding_int4 == TDS_INT4_BIG_ENDIAN) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
1836 static unsigned
1837 tds_get_char_encoding(tds_conv_info_t *tds_info)
1839 switch (tds_info->tds_encoding_char) {
1840 case TDS_CHAR_ASCII:
1841 return ENC_ASCII;
1843 case TDS_CHAR_EBCDIC:
1844 return ENC_EBCDIC;
1846 case TDS_CHAR_UTF16:
1847 return (ENC_UTF_16|ENC_LITTLE_ENDIAN);
1849 return 0;
1852 static unsigned
1853 tds_char_encoding_is_two_byte(tds_conv_info_t *tds_info)
1855 return (tds_info->tds_encoding_char == TDS_CHAR_UTF16);
1858 static int
1859 tds_token_is_fixed_size_sybase(uint8_t token)
1861 switch (token) {
1862 case TDS_DONE_TOKEN:
1863 case TDS_DONEPROC_TOKEN:
1864 case TDS_DONEINPROC_TOKEN:
1865 case TDS_RET_STAT_TOKEN:
1866 case TDS_PROCID_TOKEN:
1867 case TDS5_LOGOUT_TOKEN:
1868 case TDS_OFFSET_TOKEN:
1869 return 1;
1870 default:
1871 return 0;
1875 static int
1876 tds_get_fixed_token_size_sybase(uint8_t token, tds_conv_info_t *tds_info _U_)
1878 switch(token) {
1879 case TDS_DONE_TOKEN:
1880 case TDS_DONEPROC_TOKEN:
1881 case TDS_DONEINPROC_TOKEN:
1882 return 8;
1883 case TDS_PROCID_TOKEN:
1884 return 8;
1885 case TDS_RET_STAT_TOKEN:
1886 return 4;
1887 case TDS5_LOGOUT_TOKEN:
1888 return 1;
1889 case TDS_OFFSET_TOKEN:
1890 return 4;
1891 default:
1892 return 0;
1896 static unsigned
1897 tds_get_variable_token_size_sybase(tvbuff_t *tvb, int offset, uint8_t token,
1898 tds_conv_info_t *tds_info,
1899 unsigned *len_field_size_p,
1900 unsigned *len_field_val_p)
1902 switch(token) {
1903 /* some tokens have a 4 byte length field */
1904 case TDS5_PARAMFMT2_TOKEN:
1905 case TDS_LANG_TOKEN:
1906 case TDS5_ORDERBY2_TOKEN:
1907 case TDS5_CURDECLARE2_TOKEN:
1908 case TDS5_ROWFMT2_TOKEN:
1909 case TDS5_DYNAMIC2_TOKEN:
1910 case TDS_SESSIONSTATE_TOKEN:
1911 *len_field_size_p = 4;
1912 *len_field_val_p = tvb_get_uint32(tvb, offset,
1913 tds_get_int4_encoding(tds_info));
1914 break;
1915 /* some have a 1 byte length field */
1916 case TDS5_MSG_TOKEN:
1917 *len_field_size_p = 1;
1918 *len_field_val_p = tvb_get_uint8(tvb, offset);
1919 break;
1920 /* Some have no length field at all. */
1921 case TDS5_PARAMS_TOKEN:
1922 case TDS_ROW_TOKEN:
1923 *len_field_size_p = 0;
1924 *len_field_val_p = 0;
1925 break;
1926 /* and most have a 2 byte length field */
1927 default:
1928 *len_field_size_p = 2;
1929 *len_field_val_p = tvb_get_uint16(tvb, offset,
1930 tds_get_int2_encoding(tds_info));
1931 break;
1933 return *len_field_val_p + *len_field_size_p + 1;
1936 static int
1937 get_size_by_coltype(int servertype)
1939 switch(servertype)
1941 case SYBINT1: return 1;
1942 case SYBINT2: return 2;
1943 case SYBINT4: return 4;
1944 case SYBINT8: return 8;
1945 case SYBREAL: return 4;
1946 case SYBFLT8: return 8;
1947 case SYBDATETIME: return 8;
1948 case SYBDATETIME4: return 4;
1949 case SYBBIT: return 1;
1950 case SYBBITN: return 1;
1951 case SYBMONEY: return 8;
1952 case SYBMONEY4: return 4;
1953 case SYBUNIQUE: return 16;
1955 default: return -1;
1959 static struct _netlib_data *
1960 copy_nl_data(wmem_allocator_t *allocator, struct _netlib_data *nl_data)
1962 struct _netlib_data *new_nl_data;
1963 unsigned col;
1966 new_nl_data = wmem_new0(allocator, struct _netlib_data);
1967 new_nl_data->num_cols = nl_data->num_cols;
1968 for (col=0; col < nl_data->num_cols; col++) {
1969 struct _tds_col *old_column = nl_data->columns[col];
1970 struct _tds_col *new_column = wmem_new0(allocator, struct _tds_col);
1971 new_nl_data->columns[col] = new_column;
1972 if (old_column->name) {
1973 new_column->name = wmem_strdup(allocator, old_column->name);
1975 new_column->csize = old_column->csize;
1976 new_column->utype = old_column->utype;
1977 new_column->ctype = old_column->ctype;
1978 new_column->precision = old_column->precision;
1979 new_column->scale = old_column->scale;
1982 return new_nl_data;
1985 static void
1986 dissect_tds_all_headers(tvbuff_t *tvb, int *offset, packet_info *pinfo, proto_tree *tree)
1988 proto_item *item = NULL, *total_length_item = NULL;
1989 proto_tree *sub_tree = NULL;
1990 uint32_t total_length;
1991 int final_offset;
1993 total_length = tvb_get_letohl(tvb, *offset);
1994 /* Try to find out heuristically whether the ALL_HEADERS rule is actually present.
1995 * In practice total_length is a single byte value, so if the extracted value exceeds 1 byte,
1996 * then the headers are most likely absent. */
1997 if(total_length >= 0x100)
1998 return;
1999 item = proto_tree_add_item(tree, hf_tds_all_headers, tvb, *offset, total_length, ENC_NA);
2000 sub_tree = proto_item_add_subtree(item, ett_tds_all_headers);
2001 total_length_item = proto_tree_add_item(sub_tree, hf_tds_all_headers_total_length, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
2003 final_offset = *offset + total_length;
2004 *offset += 4;
2005 do {
2006 /* dissect a stream header */
2007 proto_tree *header_sub_tree = NULL;
2008 proto_item *header_item, *length_item = NULL, *type_item = NULL;
2009 uint32_t header_length = 0;
2010 uint16_t header_type;
2012 header_sub_tree = proto_tree_add_subtree(sub_tree, tvb, *offset, header_length, ett_tds_all_headers_header, &header_item, "Header");
2013 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);
2014 proto_item_set_len(header_item, header_length);
2015 if(header_length == 0 ) {
2016 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_length, "Empty header");
2017 break;
2020 header_type = tvb_get_letohs(tvb, *offset + 4);
2021 type_item = proto_tree_add_item(header_sub_tree, hf_tds_all_headers_header_type, tvb, *offset + 4, 2, ENC_LITTLE_ENDIAN);
2023 switch(header_type) {
2024 case TDS_HEADER_QUERY_NOTIF:
2025 break;
2026 case TDS_HEADER_TRANS_DESCR:
2027 if(header_length != 18)
2028 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_length, "Length should equal 18");
2029 proto_tree_add_item(header_sub_tree, hf_tds_all_headers_trans_descr, tvb, *offset + 6, 8, ENC_LITTLE_ENDIAN);
2030 proto_tree_add_item(header_sub_tree, hf_tds_all_headers_request_cnt, tvb, *offset + 14, 4, ENC_LITTLE_ENDIAN);
2031 break;
2032 default:
2033 expert_add_info(pinfo, type_item, &ei_tds_all_headers_header_type);
2036 *offset += header_length;
2037 } while(*offset < final_offset);
2038 if(*offset != final_offset) {
2039 expert_add_info_format(pinfo, total_length_item, &ei_tds_invalid_length, "Sum of headers' lengths (%d) differs from total headers length (%d)", total_length + *offset - final_offset, total_length);
2040 return;
2044 static void
2045 handle_tds_sql_datetime(tvbuff_t *tvb, unsigned offset, proto_tree *sub_tree, tds_conv_info_t *tds_info)
2047 /* SQL datetime */
2048 nstime_t tv = NSTIME_INIT_ZERO;
2049 int64_t days; /* Note that days is signed, allowing dates back to 1753. */
2050 uint64_t threehndths;
2052 if (tds_info->tds_encoding_date8 == TDS_DATE8_DATE_FIRST) {
2053 days = tvb_get_int32(tvb, offset, tds_get_int4_encoding(tds_info));
2054 threehndths = tvb_get_uint32(tvb, offset + 4, tds_get_int4_encoding(tds_info));
2056 else if (tds_info->tds_encoding_date8 == TDS_DATE8_TIME_FIRST) {
2057 threehndths = tvb_get_uint32(tvb, offset, tds_get_int4_encoding(tds_info));
2058 days = tvb_get_int32(tvb, offset + 4, tds_get_int4_encoding(tds_info));
2060 else {
2061 /* TODO Check these values in the login packet and offer expert information.
2062 * Here just make sure they're initialized.
2064 days = threehndths = 0;
2067 tv.secs = (time_t)((days * UINT64_C(86400)) + (threehndths/300) - EPOCH_DELTA_1900_01_01_00_00_00_UTC); /* seconds between Jan 1, 1900 and Jan 1, 1970 */
2068 tv.nsecs = (int)((threehndths%300) * 10000000 / 3);
2069 proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, offset, 8, &tv);
2072 static void
2073 handle_tds_sql_smalldatetime(tvbuff_t *tvb, unsigned offset, proto_tree *sub_tree, tds_conv_info_t *tds_info)
2075 /* SQL smalldatetime */
2076 nstime_t tv = NSTIME_INIT_ZERO;
2077 uint64_t days, minutes;
2079 if (tds_info->tds_encoding_date4 == TDS_DATE4_DATE_FIRST) {
2080 days = tvb_get_uint16(tvb, offset, tds_get_int2_encoding(tds_info));
2081 minutes = tvb_get_uint16(tvb, offset + 2, tds_get_int2_encoding(tds_info));
2083 else if (tds_info->tds_encoding_date4 == TDS_DATE4_TIME_FIRST) {
2084 minutes = tvb_get_uint16(tvb, offset, tds_get_int2_encoding(tds_info));
2085 days = tvb_get_uint16(tvb, offset + 2, tds_get_int2_encoding(tds_info));
2087 else {
2088 /* TODO Check these values in the login packet and offer expert information.
2089 * Here just make sure they're initialized.
2091 days = minutes = 0;
2095 tv.secs = (time_t)((days * UINT64_C(86400)) + (minutes * 60) - EPOCH_DELTA_1900_01_01_00_00_00_UTC); /* seconds between Jan 1, 1900 and Jan 1, 1970 */
2096 tv.nsecs = 0;
2097 proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, offset, 8, &tv);
2100 static void
2101 handle_tds_sql_smallmoney(tvbuff_t *tvb, unsigned offset, proto_tree *sub_tree, tds_conv_info_t *tds_info)
2103 double dblvalue = (float)tvb_get_uint32(tvb, offset, tds_get_int4_encoding(tds_info));
2104 proto_tree_add_double_format_value(sub_tree, hf_tds_type_varbyte_data_double,
2105 tvb, offset, 4, dblvalue, "%.4f", dblvalue/10000);
2108 static void
2109 handle_tds_sql_money(tvbuff_t *tvb, unsigned offset, proto_tree *sub_tree, tds_conv_info_t *tds_info)
2111 uint64_t moneyval = tvb_get_uint32(tvb, offset, tds_get_int4_encoding(tds_info));
2112 double dblvalue = (double)((moneyval << 32) + tvb_get_uint32(tvb, offset + 4,
2113 tds_get_int4_encoding(tds_info)));
2115 proto_tree_add_double_format_value(sub_tree, hf_tds_type_varbyte_data_double,
2116 tvb, offset, 8, dblvalue, "%.4f", dblvalue/10000);
2119 static void
2120 dissect_tds_type_varbyte(tvbuff_t *tvb, unsigned *offset, packet_info *pinfo, proto_tree *tree, int hf, tds_conv_info_t *tds_info,
2121 uint8_t data_type, uint8_t scale, bool plp, int fieldnum, const char *name)
2123 unsigned length, textptrlen;
2124 proto_tree *sub_tree = NULL;
2125 proto_item *item = NULL, *length_item = NULL;
2126 int32_t data_value;
2128 item = proto_tree_add_item(tree, hf, tvb, *offset, 0, ENC_NA);
2129 sub_tree = proto_item_add_subtree(item, ett_tds_type_varbyte);
2131 if(fieldnum != -1)
2132 proto_item_append_text(item, " %i", fieldnum);
2134 if (name && strlen(name) > 0) {
2135 proto_item *pi;
2136 pi = proto_tree_add_string(sub_tree, hf_tds_type_varbyte_column_name, tvb, 0, (int) strlen(name),
2137 (const char *)name);
2138 proto_item_set_generated(pi);
2141 if(plp) {
2142 uint64_t plp_length = tvb_get_letoh64(tvb, *offset);
2143 length_item = proto_tree_add_item(sub_tree, hf_tds_type_varbyte_plp_len, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
2144 *offset += 8;
2145 if(plp_length == TDS_PLP_NULL)
2146 proto_item_append_text(length_item, " (PLP_NULL)");
2147 else {
2148 tvbuff_t *combined_chunks_tvb;
2149 unsigned combined_length;
2151 if(plp_length == TDS_UNKNOWN_PLP_LEN) {
2152 proto_item_append_text(length_item, " (UNKNOWN_PLP_LEN)");
2155 * XXX - composite tvbuffs with no compontents aren't supported,
2156 * so we create the tvbuff when the first non-terminator chunk
2157 * is found.
2159 combined_chunks_tvb = NULL;
2160 while(true) {
2161 length_item = proto_tree_add_item_ret_uint(sub_tree, hf_tds_type_varbyte_plp_chunk_len, tvb, *offset, 4, ENC_LITTLE_ENDIAN, &length);
2162 *offset += 4;
2163 if(length == TDS_PLP_TERMINATOR) {
2164 proto_item_append_text(length_item, " (PLP_TERMINATOR)");
2165 break;
2168 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_plp_chunk, tvb, *offset, length, ENC_NA);
2169 if (combined_chunks_tvb == NULL)
2170 combined_chunks_tvb = tvb_new_composite();
2171 /* Add this chunk to the composite tvbuff */
2172 tvbuff_t *chunk_tvb = tvb_new_subset_length(tvb, *offset, length);
2173 tvb_composite_append(combined_chunks_tvb, chunk_tvb);
2174 *offset += length;
2176 if (combined_chunks_tvb != NULL) {
2177 tvb_composite_finalize(combined_chunks_tvb);
2180 * If a length was specified, report an error if it's not
2181 * the same as the reassembled length.
2183 combined_length = tvb_reported_length(combined_chunks_tvb);
2184 if(plp_length != TDS_UNKNOWN_PLP_LEN) {
2185 if(plp_length != combined_length) {
2186 expert_add_info(pinfo, length_item, &ei_tds_invalid_plp_length);
2191 * Now dissect the reassembled data.
2193 * XXX - can we make this item cover multiple ranges?
2194 * If so, do so.
2196 const uint8_t *strval = NULL;
2197 switch(data_type) {
2198 case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
2199 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, combined_chunks_tvb, 0, combined_length, ENC_NA);
2200 break;
2201 case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
2202 proto_tree_add_item_ret_string(sub_tree,
2203 hf_tds_type_varbyte_data_string,
2204 combined_chunks_tvb, 0, combined_length, ENC_ASCII|ENC_NA,
2205 wmem_packet_scope(), &strval);
2206 if (strval) {
2207 proto_item_append_text(item, " (%s)", strval);
2209 break;
2210 case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
2211 proto_tree_add_item_ret_string(sub_tree,
2212 hf_tds_type_varbyte_data_string,
2213 combined_chunks_tvb, 0, combined_length, ENC_UTF_16|ENC_LITTLE_ENDIAN,
2214 wmem_packet_scope(), &strval);
2215 if (strval) {
2216 proto_item_append_text(item, " (%s)", strval);
2218 break;
2219 case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
2220 case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
2221 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, combined_chunks_tvb, 0, combined_length, ENC_NA);
2222 break;
2223 default:
2224 /* no other data type sets plp = true */
2225 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_plp_type, "This type should not use PLP");
2227 } else {
2229 * If a length was specified, report an error if it's not
2230 * zero.
2232 if(plp_length != TDS_UNKNOWN_PLP_LEN) {
2233 if(plp_length != 0) {
2234 expert_add_info(pinfo, length_item, &ei_tds_invalid_plp_length);
2239 * The data is empty.
2241 switch(data_type) {
2242 case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
2243 proto_tree_add_bytes(sub_tree, hf_tds_type_varbyte_data_bytes, NULL, 0, 0, NULL);
2244 break;
2245 case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
2246 proto_tree_add_string(sub_tree, hf_tds_type_varbyte_data_string, NULL, 0, 0, "");
2247 break;
2248 case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
2249 proto_tree_add_string(sub_tree, hf_tds_type_varbyte_data_string, NULL, 0, 0, "");
2250 break;
2251 case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
2252 case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
2253 proto_tree_add_bytes(sub_tree, hf_tds_type_varbyte_data_bytes, NULL, 0, 0, NULL);
2254 break;
2255 default:
2256 /* no other data type sets plp = true */
2257 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_plp_type, "This type should not use PLP");
2262 else switch(data_type) {
2263 /* FIXEDLENTYPE */
2264 case TDS_DATA_TYPE_NULL: /* Null (no data associated with this type) */
2265 break;
2266 case TDS_DATA_TYPE_BIT: /* Bit (1 byte data representation) */
2267 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_boolean, tvb, *offset, 1, ENC_NA);
2268 *offset += 1;
2269 break;
2270 case TDS_DATA_TYPE_INT1: /* TinyInt (1 byte data representation) */
2271 proto_tree_add_item_ret_int(sub_tree, hf_tds_type_varbyte_data_int1, tvb, *offset, 1, ENC_NA, &data_value);
2272 proto_item_append_text(item, " (%d)", data_value);
2273 *offset += 1;
2274 break;
2275 case TDS_DATA_TYPE_INT2: /* SmallInt (2 byte data representation) */
2276 proto_tree_add_item_ret_int(sub_tree, hf_tds_type_varbyte_data_int2, tvb, *offset, 2, tds_get_int2_encoding(tds_info), &data_value);
2277 proto_item_append_text(item, " (%d)", data_value);
2278 *offset += 2;
2279 break;
2280 case TDS_DATA_TYPE_INT4: /* Int (4 byte data representation) */
2281 proto_tree_add_item_ret_int(sub_tree, hf_tds_type_varbyte_data_int4, tvb, *offset, 4, tds_get_int4_encoding(tds_info), &data_value);
2282 proto_item_append_text(item, " (%d)", data_value);
2283 *offset += 4;
2284 break;
2285 case TDS_DATA_TYPE_INT8: /* BigInt (8 byte data representation) */
2286 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int8, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
2287 *offset += 8;
2288 break;
2289 case TDS_DATA_TYPE_FLT4: /* Real (4 byte data representation) */
2290 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_float, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
2291 *offset += 4;
2292 break;
2293 case TDS_DATA_TYPE_FLT8: /* Float (8 byte data representation) */
2294 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
2295 *offset += 8;
2296 break;
2297 case TDS_DATA_TYPE_DATETIME4: /* SmallDateTime (4 byte data representation) */
2298 handle_tds_sql_smalldatetime(tvb, *offset, sub_tree, tds_info);
2299 *offset += 4;
2300 break;
2301 case TDS_DATA_TYPE_MONEY4: /* SmallMoney (4 byte data representation) */
2302 handle_tds_sql_smallmoney(tvb, *offset, sub_tree, tds_info);
2303 *offset += 4;
2304 break;
2305 case TDS_DATA_TYPE_DATETIME: /* DateTime (8 byte data representation) */
2306 handle_tds_sql_datetime(tvb, *offset, sub_tree, tds_info);
2307 *offset += 8;
2308 break;
2309 case TDS_DATA_TYPE_MONEY: /* Money (8 byte data representation) */
2310 handle_tds_sql_money(tvb, *offset, sub_tree, tds_info);
2311 *offset += 8;
2312 break;
2315 /* BYTELEN_TYPE - types prefixed with 1-byte length */
2316 case TDS_DATA_TYPE_GUID: /* UniqueIdentifier */
2317 length = tvb_get_uint8(tvb, *offset);
2318 length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2319 switch(length) {
2320 case TDS_GEN_NULL:
2321 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
2322 break;
2323 case 16:
2324 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_guid, tvb, *offset + 1, length, ENC_LITTLE_ENDIAN);
2325 break;
2326 default:
2327 expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
2329 *offset += 1 + length;
2330 break;
2332 case TDS_DATA_TYPE_BITN:
2333 length = tvb_get_uint8(tvb, *offset);
2334 length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2335 switch(length) {
2336 case TDS_GEN_NULL:
2337 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
2338 break;
2339 case 1:
2340 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_boolean, tvb, *offset + 1, 1, ENC_NA);
2341 break;
2342 default:
2343 expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
2345 *offset += 1 + length;
2346 break;
2348 case TDS_DATA_TYPE_INTN:
2349 length = tvb_get_uint8(tvb, *offset);
2350 length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2351 switch(length) {
2352 case TDS_GEN_NULL:
2353 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
2354 break;
2355 case 1:
2356 proto_tree_add_item_ret_int(sub_tree, hf_tds_type_varbyte_data_int1, tvb, *offset + 1, 1, ENC_NA, &data_value);
2357 proto_item_append_text(item, " (%d)", data_value);
2358 break;
2359 case 2:
2360 proto_tree_add_item_ret_int(sub_tree, hf_tds_type_varbyte_data_int2, tvb, *offset + 1, 2, tds_get_int2_encoding(tds_info), &data_value);
2361 proto_item_append_text(item, " (%d)", data_value);
2362 break;
2363 case 4:
2364 proto_tree_add_item_ret_int(sub_tree, hf_tds_type_varbyte_data_int4, tvb, *offset + 1, 4, tds_get_int4_encoding(tds_info), &data_value);
2365 proto_item_append_text(item, " (%d)", data_value);
2366 break;
2367 case 8:
2368 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_int8, tvb, *offset + 1, 8, ENC_LITTLE_ENDIAN);
2369 proto_item_append_text(item, " (%"PRId64")", tvb_get_letoh64(tvb, *offset));
2370 break;
2371 default:
2372 expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
2374 *offset += 1 + length;
2375 break;
2377 case TDS_DATA_TYPE_FLTN:
2378 length = tvb_get_uint8(tvb, *offset);
2379 length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2380 switch(length) {
2381 case TDS_GEN_NULL:
2382 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
2383 break;
2384 case 4:
2385 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_float, tvb, *offset + 1, 4, ENC_LITTLE_ENDIAN);
2386 proto_item_append_text(item, " (%f)", tvb_get_letohieee_float(tvb, *offset));
2387 break;
2388 case 8:
2389 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_double, tvb, *offset + 1, 8, ENC_LITTLE_ENDIAN);
2390 proto_item_append_text(item, " (%f)", tvb_get_letohieee_double(tvb, *offset));
2391 break;
2392 default:
2393 expert_add_info(pinfo, length_item, &ei_tds_invalid_length);
2395 *offset += 1 + length;
2396 break;
2398 case TDS_DATA_TYPE_MONEYN:
2399 length = tvb_get_uint8(tvb, *offset);
2400 proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2401 *offset += 1;
2402 if(length > 0) {
2403 if(length == 4)
2405 handle_tds_sql_smallmoney(tvb, *offset, sub_tree, tds_info);
2407 if(length == 8)
2409 handle_tds_sql_money(tvb, *offset, sub_tree, tds_info);
2411 *offset += length;
2413 break;
2415 case TDS_DATA_TYPE_DATEN: /* (introduced in TDS 7.3) */
2416 length = tvb_get_uint8(tvb, *offset);
2417 proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2418 *offset += 1;
2419 if(length == 3) {
2420 unsigned days = 0;
2421 nstime_t tv;
2423 days += tvb_get_uint8(tvb, *offset + 2) << 16;
2424 days += tvb_get_uint8(tvb, *offset + 1) << 8;
2425 days += tvb_get_uint8(tvb, *offset);
2427 tv.secs = (time_t)((days * UINT64_C(86400)) - UINT64_C(62135596800)); /* 62135596800 - seconds between Jan 1, 1 and Jan 1, 1970 */
2428 tv.nsecs = 0;
2429 proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
2431 *offset += length;
2432 break;
2434 case TDS_DATA_TYPE_TIMEN: /* (introduced in TDS 7.3) */
2435 length = tvb_get_uint8(tvb, *offset);
2436 proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2437 *offset += 1;
2438 if(length > 0) {
2440 int i;
2441 uint64_t value = 0;
2442 double dblvalue;
2443 nstime_t tv;
2445 for(i = length - 1; i > 0; i--)
2447 value = value + tvb_get_uint8(tvb, *offset + i);
2448 value = value << 8;
2450 value = value + tvb_get_uint8(tvb, *offset);
2452 dblvalue = (double)value;
2453 for(i = 0; i < scale; i++)
2455 dblvalue = dblvalue / 10;
2458 tv.secs = (time_t)dblvalue;
2459 tv.nsecs = (unsigned)(dblvalue - tv.secs) * 1000000000;
2460 proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_reltime, tvb, *offset, length, &tv);
2462 *offset += length;
2464 break;
2466 case TDS_DATA_TYPE_DATETIMN:
2468 length = tvb_get_uint8(tvb, *offset);
2469 proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2470 *offset += 1;
2471 if(length > 0) {
2472 if(length == 4)
2474 handle_tds_sql_smalldatetime(tvb, *offset, sub_tree, tds_info);
2476 else if(length == 8)
2478 handle_tds_sql_datetime(tvb, *offset, sub_tree, tds_info);
2480 *offset += length;
2482 break;
2484 case TDS_DATA_TYPE_DATETIME2N: /* (introduced in TDS 7.3) */
2485 length = tvb_get_uint8(tvb, *offset);
2486 proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2487 *offset += 1;
2488 if(length > 0) {
2490 int i, bytestoread = 0;
2491 uint64_t value = 0;
2492 double dblvalue;
2493 unsigned days = 0;
2494 uint64_t secs;
2495 nstime_t tv;
2497 if(scale <= 2) bytestoread = 3;
2498 if((scale >= 3) && (scale <= 4)) bytestoread = 4;
2499 if((scale >= 5) && (scale <= 7)) bytestoread = 5;
2501 for(i = bytestoread - 1; i > 0; i--)
2503 value = value + tvb_get_uint8(tvb, *offset + i);
2504 value = value << 8;
2506 value = value + tvb_get_uint8(tvb, *offset);
2508 dblvalue = (double)value;
2509 for(i = 0; i < scale; i++)
2511 dblvalue = dblvalue / 10;
2514 days += tvb_get_uint8(tvb, *offset + bytestoread + 2) << 16;
2515 days += tvb_get_uint8(tvb, *offset + bytestoread + 1) << 8;
2516 days += tvb_get_uint8(tvb, *offset + bytestoread);
2518 secs = (days * UINT64_C(86400)) - UINT64_C(62135596800); /* 62135596800 - seconds between Jan 1, 1 and Jan 1, 1970 */
2520 value = (uint64_t)dblvalue;
2521 tv.secs = (time_t)(secs + value);
2522 dblvalue = dblvalue - value;
2523 tv.nsecs = (unsigned)dblvalue * 1000000000;
2524 proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
2526 *offset += bytestoread + 3;
2528 break;
2530 case TDS_DATA_TYPE_DATETIMEOFFSETN: /* (introduced in TDS 7.3) */
2531 length = tvb_get_uint8(tvb, *offset);
2532 proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2533 *offset += 1;
2534 if(length > 0) {
2536 int i, bytestoread = 0;
2537 uint64_t value = 0;
2538 double dblvalue;
2539 unsigned days = 0;
2540 int16_t timeoffset = 0;
2541 uint64_t secs;
2542 nstime_t tv;
2543 proto_item *timeitem = NULL;
2545 if(scale <= 2) bytestoread = 3;
2546 if((scale >= 3) && (scale <= 4)) bytestoread = 4;
2547 if((scale >= 5) && (scale <= 7)) bytestoread = 5;
2549 for(i = bytestoread - 1; i > 0; i--)
2551 value = value + tvb_get_uint8(tvb, *offset + i);
2552 value = value << 8;
2554 value = value + tvb_get_uint8(tvb, *offset);
2556 dblvalue = (double)value;
2557 for(i = 0; i < scale; i++)
2559 dblvalue = dblvalue / 10;
2562 days += tvb_get_uint8(tvb, *offset + bytestoread + 2) << 16;
2563 days += tvb_get_uint8(tvb, *offset + bytestoread + 1) << 8;
2564 days += tvb_get_uint8(tvb, *offset + bytestoread);
2566 secs = (days * UINT64_C(86400)) - UINT64_C(62135596800); /* 62135596800 - seconds between Jan 1, 1 and Jan 1, 1970 */
2568 value = (uint64_t)dblvalue;
2569 tv.secs = (time_t)(secs + value);
2570 dblvalue = dblvalue - value;
2571 tv.nsecs = (unsigned)dblvalue * 1000000000;
2572 timeitem = proto_tree_add_time(sub_tree, hf_tds_type_varbyte_data_absdatetime, tvb, *offset, length, &tv);
2574 timeoffset = tvb_get_letohs(tvb, *offset + bytestoread + 3);
2576 /* TODO: Need to find a way to convey the time and the offset in a single item, rather than appending text */
2577 proto_item_append_text(timeitem, " %c%02i:%02i", timeoffset > 0 ? '+':'-', timeoffset / 60, timeoffset % 60);
2578 *offset += bytestoread + 5;
2580 break;
2582 case TDS_DATA_TYPE_DECIMAL: /* Decimal (TDS 4/5) */
2583 case TDS_DATA_TYPE_NUMERIC: /* Numeric (TDS 4/5) */
2584 case TDS_DATA_TYPE_DECIMALN: /* Decimal */
2585 case TDS_DATA_TYPE_NUMERICN: /* Numeric */
2587 proto_item *numericitem = NULL;
2589 length = tvb_get_uint8(tvb, *offset);
2590 proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 1, length);
2591 *offset += 1;
2593 if(length > 0) {
2595 if (TDS_PROTO_TDS5(tds_info)) {
2596 /* Sybase rules:
2597 * Data are big-endian.
2598 * The size appears to be variable governed on the Precision specification.
2599 * Sign of true indicates negative.
2601 bool sign = false;
2603 proto_tree_add_item_ret_boolean(sub_tree, hf_tds_type_varbyte_data_sign, tvb, *offset, 1, ENC_NA, &sign);
2604 *offset += 1;
2605 length -= 1;
2607 numericitem = proto_tree_add_item(sub_tree,
2608 hf_tds_type_varbyte_data_bytes, tvb, *offset, length,
2609 ENC_NA);
2610 if (length <= 8) {
2611 uint8_t data_array[8];
2612 unsigned j;
2613 int64_t int64_value = 0;
2615 * XXX - this actually falls down if we have more than
2616 * 53 bits of significance. (Assuming IEEE 754 floating-piont.)
2617 * This isn't likely to happen in practice.
2618 * Decimal/numeric fields are intended to be used
2619 * for precise integers/scaled integers. They would not
2620 * be typically be used for high dynamic range quantities.
2623 (void) tvb_memcpy(tvb, data_array, *offset, length);
2624 for (j = 0; j < length; j++) {
2625 int64_value = (int64_value << 8) | data_array[j];
2627 if(scale == 0) {
2628 proto_item_append_text(numericitem,
2629 " (%" PRId64 ")",
2630 (sign ? -int64_value : int64_value));
2632 else {
2633 proto_item_append_text(numericitem,
2634 " (%.*f)", scale,
2635 (double)(sign ? -int64_value
2636 : int64_value)/pow(10.0, (double)(scale)));
2639 *offset += length;
2641 else {
2643 * Microsoft apparently allowed NUMERIC/DECIMAL while they
2644 * still were negotiating TDS 4.x. Sybase did not, so
2645 * assume any NUMERIC that's not TDS 5.0 is Microsoft's.
2647 * Microsoft rules:
2648 * Data are little-endian.
2649 * The data size is documented as being 4, 8, 12, or 16 bytes,
2650 * but this code does not rely on that.
2651 * Sign of true indicates positive.
2653 bool sign = true;
2655 proto_tree_add_item_ret_boolean(sub_tree,
2656 hf_tds_type_varbyte_data_sign, tvb, *offset, 1,
2657 ENC_NA, &sign);
2658 length -= 1;
2659 *offset += 1;
2661 numericitem = proto_tree_add_item(sub_tree,
2662 hf_tds_type_varbyte_data_bytes, tvb, *offset, length,
2663 ENC_NA);
2664 if (length <= 8) {
2665 uint8_t data_array[8];
2666 int j;
2667 int64_t int64_value = 0;
2669 * XXX - this actually falls down if we have more than
2670 * 53 bits of significance. (Assuming IEEE 754 floating-piont.)
2671 * This isn't likely to happen in practice.
2672 * Decimal/numeric fields are intended to be used
2673 * for precise integers/scaled integers. They would not
2674 * be typically be used for high dynamic range quantities.
2676 * We could change the "length <= 8" criterion above,
2677 * but Microsoft appears to only use length values which
2678 * are multiples of 4. Any numeric/decimal with a
2679 * precision between 9 and 19 will be stored as an
2680 * 8-byte integer.
2683 (void) tvb_memcpy(tvb, data_array, *offset, length);
2684 for (j = length - 1; j >= 0; j--) {
2685 int64_value = (int64_value << 8) | data_array[j];
2687 if(scale == 0) {
2688 proto_item_append_text(numericitem,
2689 " (%" PRId64 ")",
2690 (sign ? -int64_value : int64_value));
2692 else {
2693 proto_item_append_text(numericitem,
2694 " (%.*f)", scale,
2695 (double)(sign ? int64_value
2696 : -int64_value)/pow(10.0, (double)(scale)));
2699 *offset += length;
2702 else {
2703 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset,
2704 0, ENC_NA);
2706 break;
2708 case TDS_DATA_TYPE_CHAR: /* Char (TDS 4/5) */
2709 case TDS_DATA_TYPE_VARCHAR: /* VarChar (TDS 4/5) */
2711 int len;
2712 proto_tree_add_item_ret_length(sub_tree, hf_tds_type_varbyte_data_uint_string,
2713 tvb, *offset, 1, tds_get_char_encoding(tds_info), &len);
2714 *offset += len;
2715 break;
2717 case TDS_DATA_TYPE_BINARY: /* Binary (TDS 4/5) */
2718 case TDS_DATA_TYPE_VARBINARY: /* VarBinary (TDS 4/5) */
2720 int len;
2721 proto_tree_add_item_ret_length(sub_tree, hf_tds_type_varbyte_data_uint_bytes,
2722 tvb, *offset, 1, ENC_NA, &len);
2723 *offset += len;
2724 break;
2726 /* USHORTLEN_TYPE - types prefixed with 2-byte length */
2727 case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
2728 case TDS_DATA_TYPE_BIGBINARY: /* Binary */
2729 case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
2730 case TDS_DATA_TYPE_BIGCHAR: /* Char */
2731 case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
2732 case TDS_DATA_TYPE_NCHAR: /* NChar */
2733 /* Special case where MS and Sybase independently assigned a data type of 0xaf. */
2734 if ((data_type == SYBLONGCHAR) && TDS_PROTO_LESS_THAN_TDS7(tds_info)) {
2735 int len;
2736 proto_tree_add_item_ret_length(sub_tree, hf_tds_type_varbyte_data_uint_string, tvb, *offset, 4,
2737 tds_get_char_encoding(tds_info)|tds_get_int4_encoding(tds_info), &len);
2738 *offset += len;
2739 break;
2741 length = tvb_get_letohs(tvb, *offset);
2742 length_item = proto_tree_add_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 2, length);
2743 *offset += 2;
2744 if(length == TDS_CHARBIN_NULL) {
2745 proto_item_append_text(length_item, " (CHARBIN_NULL)");
2746 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
2748 else {
2749 const uint8_t *strval = NULL;
2750 switch(data_type) {
2751 case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
2752 case TDS_DATA_TYPE_BIGBINARY: /* Binary */
2753 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
2754 break;
2755 case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
2756 case TDS_DATA_TYPE_BIGCHAR: /* Char */
2757 proto_tree_add_item_ret_string(sub_tree, hf_tds_type_varbyte_data_string,
2758 tvb, *offset, length, ENC_ASCII|ENC_NA,
2759 wmem_packet_scope(), &strval);
2760 if (strval) {
2761 proto_item_append_text(item, " (%s)", strval);
2763 break;
2764 case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
2765 case TDS_DATA_TYPE_NCHAR: /* NChar */
2766 proto_tree_add_item_ret_string(sub_tree, hf_tds_type_varbyte_data_string,
2767 tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN,
2768 wmem_packet_scope(), &strval);
2769 if (strval) {
2770 proto_item_append_text(item, " (%s)", strval);
2772 break;
2774 *offset += length;
2776 break;
2778 /* LONGLEN_TYPE - types prefixed with 4-byte length */
2779 /* SYBLONGCHAR would be similar, but there is an ambiguity with TDS 7.x.
2780 * It is handled under TDS_DATA_TYPE_BIGCHAR above. */
2781 case TDS_DATA_TYPE_LONGBINARY: /* Long Binary (TDS 5.0) */
2783 int len;
2784 proto_tree_add_item_ret_length(sub_tree, hf_tds_type_varbyte_data_uint_bytes, tvb, *offset, 4,
2785 tds_get_int4_encoding(tds_info), &len);
2786 *offset += len;
2787 break;
2789 /* LONGLEN_TYPE - types prefixed with 4-byte length using a text pointer*/
2790 case TDS_DATA_TYPE_NTEXT: /* NText */
2791 case TDS_DATA_TYPE_TEXT: /* Text */
2792 case TDS_DATA_TYPE_IMAGE: /* Image */
2793 case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
2794 case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
2795 case TDS_DATA_TYPE_SSVARIANT: /* Sql_Variant (introduced in TDS 7.2) */
2796 /* TextPointer */
2797 length_item =proto_tree_add_item_ret_uint(sub_tree, hf_tds_type_varbyte_data_textptr_len,
2798 tvb, *offset, 1, ENC_NA, &textptrlen);
2799 if (TDS_PROTO_LESS_THAN_TDS7(tds_info) && textptrlen == 0) {
2800 proto_item_append_text(length_item, " (NULL)");
2801 *offset += 1;
2802 break;
2804 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_textptr, tvb,
2805 *offset + 1, textptrlen, ENC_NA);
2806 *offset += 1 + textptrlen;
2808 /* Timestamp */
2809 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_text_ts, tvb,
2810 *offset, 8, ENC_NA);
2811 *offset += 8;
2813 length_item = proto_tree_add_item_ret_uint(sub_tree, hf_tds_type_varbyte_length, tvb, *offset, 4,
2814 tds_get_int4_encoding(tds_info), &length);
2815 *offset += 4;
2816 if(length == TDS_CHARBIN_NULL32) {
2817 proto_item_append_text(length_item, " (CHARBIN_NULL)");
2818 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_null, tvb, *offset, 0, ENC_NA);
2820 else {
2821 switch(data_type) {
2822 case TDS_DATA_TYPE_NTEXT: /* NText */
2823 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
2824 break;
2825 case TDS_DATA_TYPE_TEXT:
2826 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_ASCII);
2827 break;
2828 default: /*TODO*/
2829 proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
2831 *offset += length;
2833 break;
2835 proto_item_set_end(item, tvb, *offset);
2838 static void
2839 dissect_tds_query_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
2841 int offset, len;
2842 unsigned string_encoding = ENC_UTF_16|ENC_LITTLE_ENDIAN;
2843 proto_tree *query_tree;
2845 offset = 0;
2846 query_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_query, NULL, "TDS Query Packet");
2847 dissect_tds_all_headers(tvb, &offset, pinfo, query_tree);
2848 len = tvb_reported_length_remaining(tvb, offset);
2850 if (TDS_PROTO_LESS_THAN_TDS7(tds_info) ||
2851 (!TDS_PROTO_TDS7(tds_info) &&
2852 ((len < 2) || tvb_get_uint8(tvb, offset+1) != 0)))
2853 string_encoding = ENC_ASCII|ENC_NA;
2855 proto_tree_add_item(query_tree, hf_tds_query, tvb, offset, len, string_encoding);
2856 /* offset += len; */
2859 static int * const dbrpc_options_hf_fields[] = {
2860 &hf_tds_dbrpc_options_recompile,
2861 &hf_tds_dbrpc_options_params,
2862 NULL
2865 static unsigned
2866 dissect_tds5_dbrpc_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info) {
2868 unsigned rpcnamelen, cur=offset;
2870 proto_tree_add_item(tree, hf_tds_dbrpc_length, tvb, cur, 2,
2871 tds_get_int2_encoding(tds_info));
2872 cur += 2;
2874 proto_tree_add_item_ret_uint(tree, hf_tds_dbrpc_rpcname_len, tvb, cur, 1,
2875 ENC_NA, &rpcnamelen);
2876 if (rpcnamelen > 0) {
2877 proto_tree_add_item(tree, hf_tds_dbrpc_rpcname, tvb, cur + 1, rpcnamelen,
2878 tds_get_char_encoding(tds_info));
2880 cur += (rpcnamelen + 1);
2882 proto_tree_add_bitmask(tree, tvb, cur, hf_tds_dbrpc_options, ett_tds5_dbrpc_options,
2883 dbrpc_options_hf_fields, tds_get_int2_encoding(tds_info));
2884 cur += 2;
2886 return cur - offset;
2889 static unsigned
2890 dissect_tds5_lang_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info) {
2892 unsigned len, cur=offset;
2894 proto_tree_add_item_ret_uint(tree, hf_tds_lang_length, tvb, cur, 4,
2895 tds_get_int4_encoding(tds_info), &len);
2896 cur += 4;
2898 /* Both of these calls are retained for backwards compatibility. */
2899 proto_tree_add_item(tree, hf_tds_lang_token_status, tvb, cur, 1, ENC_NA);
2900 proto_tree_add_item(tree, hf_tds_lang_status_parameterized, tvb, cur, 1, ENC_NA);
2902 cur += 1;
2903 len -= 1;
2905 proto_tree_add_item(tree, hf_tds_lang_language_text, tvb, cur, len, ENC_ASCII);
2906 cur += len;
2908 return cur - offset;
2911 static void
2912 tds5_check_cursor_name(packet_info *pinfo, proto_item *pi,
2913 tds_cursor_info_t *cursor_current, const uint8_t *cursorname)
2915 if (cursorname && cursor_current &&
2916 ( cursor_current->tds_cursor_flags & TDS_CURSOR_NAME_VALID)) {
2917 if (g_strcmp0((const char *)cursorname,
2918 cursor_current->tds_cursor_name) != 0) {
2919 expert_add_info_format(pinfo, pi, &ei_tds_cursor_name_mismatch,
2920 "Cursor name %s does not match current cursor name %s",
2921 cursorname, cursor_current->tds_cursor_name);
2926 static void
2927 tds_cursor_info_init(tds_conv_info_t *tds_info)
2929 tds_conv_cursor_info_t *conv_cursor_info = tds_info->tds_conv_cursor_info;
2931 if (!conv_cursor_info) {
2932 conv_cursor_info =
2933 wmem_new0(wmem_file_scope(), tds_conv_cursor_info_t);
2934 conv_cursor_info->tds_conv_cursor_table =
2935 wmem_tree_new(wmem_file_scope());
2936 tds_info->tds_conv_cursor_info = conv_cursor_info;
2940 static unsigned
2941 dissect_tds5_curclose_token(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
2942 proto_tree *tree, tds_conv_info_t *tds_info)
2944 unsigned len, cur = offset;
2945 unsigned cursorid;
2946 proto_item *cursor_id_pi;
2947 tds_cursor_info_t *packet_cursor =
2948 (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
2950 proto_tree_add_item_ret_uint(tree, hf_tds_curclose_length, tvb, cur, 2, tds_get_int2_encoding(tds_info), &len);
2951 cur += 2;
2953 cursor_id_pi = proto_tree_add_item_ret_uint(tree, hf_tds_curclose_cursorid,
2954 tvb, cur, 4, tds_get_int4_encoding(tds_info), &cursorid);
2955 cur += 4;
2957 if (cursorid == 0) {
2958 int cursorname_len;
2959 const uint8_t *cursorname;
2960 proto_item *cursor_name_pi;
2962 cursor_name_pi = proto_tree_add_item_ret_string_and_length(tree,
2963 hf_tds_curclose_cursor_name,
2964 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
2965 wmem_packet_scope(), &cursorname, &cursorname_len);
2966 cur += cursorname_len;
2967 tds5_check_cursor_name(pinfo, cursor_name_pi, packet_cursor, cursorname);
2969 else if (packet_cursor && cursor_id_pi &&
2970 (packet_cursor->tds_cursor_flags & TDS_CURSOR_NAME_VALID)) {
2971 proto_item_append_text(cursor_id_pi, " (%s)",
2972 packet_cursor->tds_cursor_name);
2975 proto_tree_add_item(tree, hf_tds_curclose_option_deallocate, tvb, cur, 1, ENC_NA);
2976 cur += 1;
2978 if (!PINFO_FD_VISITED(pinfo) && !packet_cursor) {
2979 tds_conv_cursor_info_t *conv_cursor_info;
2981 tds_cursor_info_init(tds_info);
2982 conv_cursor_info = tds_info->tds_conv_cursor_info;
2983 if (cursorid) {
2984 tds_cursor_info_t *cursor_current;
2985 cursor_current =
2986 (tds_cursor_info_t *) wmem_tree_lookup32(conv_cursor_info->tds_conv_cursor_table,
2987 cursorid);
2988 if (cursor_current) {
2989 p_add_proto_data(wmem_file_scope(),
2990 pinfo, proto_tds, 0, cursor_current);
2995 return cur - offset;
2998 static int * const tds_curdeclare_hf_fields[] = {
2999 &hf_tds_curdeclare_options_rdonly,
3000 &hf_tds_curdeclare_options_updatable,
3001 &hf_tds_curdeclare_options_sensitive,
3002 &hf_tds_curdeclare_options_dynamic,
3003 &hf_tds_curdeclare_options_implicit,
3004 NULL
3007 static unsigned
3008 dissect_tds5_curdeclare_token(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
3009 proto_tree *tree, tds_conv_info_t *tds_info)
3011 unsigned len, cur = offset, num_updatable_columns;
3012 int cursorname_len, stmtlen;
3013 const uint8_t *cursorname;
3014 tds_cursor_info_t *packet_cursor =
3015 (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
3017 proto_tree_add_item_ret_uint(tree, hf_tds_curdeclare_length, tvb, cur, 2,
3018 tds_get_int2_encoding(tds_info), &len);
3019 cur += 2;
3021 proto_tree_add_item_ret_string_and_length(tree, hf_tds_curdeclare_cursor_name,
3022 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
3023 wmem_packet_scope(), &cursorname, &cursorname_len);
3024 cur += cursorname_len;
3026 /* Options is one byte, as is status. */
3027 proto_tree_add_bitmask(tree, tvb, cur, hf_tds_curdeclare_options,
3028 ett_tds5_curdeclare_options, tds_curdeclare_hf_fields, ENC_NA);
3029 proto_tree_add_item(tree, hf_tds_curdeclare_status_parameterized, tvb,
3030 cur + 1, 1, ENC_NA);
3031 cur += 2;
3033 proto_tree_add_item_ret_length(tree, hf_tds_curdeclare_statement, tvb, cur, 2,
3034 tds_get_char_encoding(tds_info)|tds_get_int2_encoding(tds_info), &stmtlen);
3035 cur += stmtlen;
3037 proto_tree_add_item_ret_uint(tree, hf_tds_curdeclare_update_columns_num, tvb, cur, 1,
3038 ENC_NA, &num_updatable_columns);
3039 cur += 1;
3041 if (num_updatable_columns > 0) {
3042 int column_name_len;
3044 proto_tree_add_item_ret_length(tree, hf_tds_curdeclare_update_columns_name,
3045 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA, &column_name_len);
3046 cur += column_name_len;
3050 * If being processed in order (first time through) prepare to correlate the
3051 * curdeclare with the curinfo response.
3053 if (!PINFO_FD_VISITED(pinfo)) {
3054 tds_conv_cursor_info_t *conv_cursor_info;
3055 tds_cursor_info_t *cursor_current;
3057 tds_cursor_info_init(tds_info);
3058 conv_cursor_info = tds_info->tds_conv_cursor_info;
3060 cursor_current = conv_cursor_info->tds_conv_cursor_current;
3061 if (!cursor_current) {
3062 cursor_current = wmem_new0(wmem_file_scope(), tds_cursor_info_t);
3063 conv_cursor_info->tds_conv_cursor_current = cursor_current;
3065 else if (!(cursor_current->tds_cursor_flags & TDS_CURSOR_IN_CONV_TABLE)) {
3067 * The cursor was allocated, but never entered into the table.
3068 * This won't happen normally, but it could happen if the client were
3069 * coded unusually and pending activity were to be aborted mid-sequence.
3070 * Free possible existing values to avoid a file-level leak.
3072 wmem_free(wmem_file_scope(), (void *) cursor_current->tds_cursor_name);
3073 wmem_free(wmem_file_scope(), (void *) cursor_current->tds_cursor_rowinfo);
3074 (void) memset(cursor_current, 0, sizeof (tds_cursor_info_t));
3077 cursor_current->tds_cursor_name = wmem_strdup(wmem_file_scope(), (const char* )cursorname);
3078 cursor_current->tds_cursor_flags |= TDS_CURSOR_NAME_VALID;
3080 if (packet_cursor && packet_cursor != cursor_current) {
3081 p_remove_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
3082 packet_cursor = NULL;
3084 if (!packet_cursor) {
3085 p_add_proto_data(wmem_file_scope(), pinfo, proto_tds, 0, cursor_current);
3089 return cur - offset;
3092 static unsigned
3093 dissect_tds5_curfetch_token(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
3094 proto_tree *tree, tds_conv_info_t *tds_info)
3096 unsigned len, cur = offset;
3097 unsigned cursorid;
3098 unsigned curfetch_type;
3099 const uint8_t *cursorname;
3100 proto_item *cursor_id_pi;
3101 tds_cursor_info_t *packet_cursor =
3102 (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
3104 proto_tree_add_item_ret_uint(tree, hf_tds_curfetch_length, tvb, cur, 2, tds_get_int2_encoding(tds_info), &len);
3105 cur += 2;
3107 cursor_id_pi = proto_tree_add_item_ret_uint(tree, hf_tds_curfetch_cursorid,
3108 tvb, cur, 4, tds_get_int4_encoding(tds_info), &cursorid);
3109 cur += 4;
3111 if (cursorid == 0) {
3112 int cursorname_len;
3113 proto_item *cursor_name_pi;
3115 cursor_name_pi = proto_tree_add_item_ret_string_and_length(tree, hf_tds_curfetch_cursor_name,
3116 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
3117 wmem_packet_scope(), &cursorname, &cursorname_len);
3118 tds5_check_cursor_name(pinfo, cursor_name_pi, packet_cursor, cursorname);
3119 cur += cursorname_len;
3121 else if (packet_cursor && cursor_id_pi &&
3122 (packet_cursor->tds_cursor_flags & TDS_CURSOR_NAME_VALID)) {
3123 proto_item_append_text(cursor_id_pi, " (%s)",
3124 packet_cursor->tds_cursor_name);
3127 proto_tree_add_item_ret_uint(tree, hf_tds_curfetch_type, tvb, cur, 1,
3128 ENC_NA, &curfetch_type);
3129 cur += 1;
3131 if (curfetch_type >= TDS_CUR_ABS) {
3132 proto_tree_add_item(tree, hf_tds_curfetch_rowcnt, tvb, cur, 4,
3133 tds_get_int4_encoding(tds_info));
3134 cur += 4;
3137 if (!PINFO_FD_VISITED(pinfo) && !packet_cursor) {
3138 tds_conv_cursor_info_t *conv_cursor_info = tds_info->tds_conv_cursor_info;
3139 tds_cursor_info_t *cursor_current;
3141 if (!conv_cursor_info) {
3142 conv_cursor_info =
3143 wmem_new0(wmem_file_scope(), tds_conv_cursor_info_t);
3144 conv_cursor_info->tds_conv_cursor_table =
3145 wmem_tree_new(wmem_file_scope());
3146 tds_info->tds_conv_cursor_info = conv_cursor_info;
3148 if (cursorid) {
3149 cursor_current =
3150 (tds_cursor_info_t *) wmem_tree_lookup32(conv_cursor_info->tds_conv_cursor_table,
3151 cursorid);
3152 if (cursor_current) {
3153 p_add_proto_data(wmem_file_scope(),
3154 pinfo, proto_tds, 0, cursor_current);
3155 cursor_current->tds_cursor_flags |= TDS_CURSOR_FETCH_PENDING;
3156 conv_cursor_info->tds_conv_cursor_current = cursor_current;
3161 return cur - offset;
3164 static int * const tds_curinfo_hf_fields[] = {
3165 &hf_tds_curinfo_cursor_status_declared,
3166 &hf_tds_curinfo_cursor_status_open,
3167 &hf_tds_curinfo_cursor_status_closed,
3168 &hf_tds_curinfo_cursor_status_rdonly,
3169 &hf_tds_curinfo_cursor_status_updatable,
3170 &hf_tds_curinfo_cursor_status_rowcnt,
3171 &hf_tds_curinfo_cursor_status_dealloc,
3172 NULL
3175 static unsigned
3176 dissect_tds5_curinfo_token(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
3177 proto_tree *tree, tds_conv_info_t *tds_info)
3179 unsigned len, cur = offset;
3180 const uint8_t *cursorname = NULL;
3181 unsigned cursorid;
3182 unsigned cursor_command;
3183 tds_cursor_info_t *packet_cursor =
3184 (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
3185 proto_item *cursor_id_pi;
3187 proto_tree_add_item_ret_uint(tree, hf_tds_curinfo_length, tvb, cur, 2,
3188 tds_get_int2_encoding(tds_info), &len);
3189 cur += 2;
3191 cursor_id_pi = proto_tree_add_item_ret_uint(tree, hf_tds_curinfo_cursorid,
3192 tvb, cur, 4, tds_get_int4_encoding(tds_info), &cursorid);
3193 cur += 4;
3195 if (cursorid == 0) {
3196 int cursorname_len;
3197 proto_item *cursor_name_pi;
3198 cursor_name_pi = proto_tree_add_item_ret_string_and_length(tree,
3199 hf_tds_curinfo_cursor_name, tvb, cur, 1,
3200 tds_get_char_encoding(tds_info)|ENC_NA,
3201 wmem_packet_scope(), &cursorname, &cursorname_len);
3202 cur += cursorname_len;
3203 tds5_check_cursor_name(pinfo, cursor_name_pi, packet_cursor, cursorname);
3205 else if (packet_cursor && cursor_id_pi &&
3206 (packet_cursor->tds_cursor_flags & TDS_CURSOR_NAME_VALID)) {
3207 proto_item_append_text(cursor_id_pi, " (%s)",
3208 packet_cursor->tds_cursor_name);
3212 proto_tree_add_item_ret_uint(tree, hf_tds_curinfo_cursor_command,
3213 tvb, cur, 1, ENC_NA, &cursor_command);
3214 cur += 1;
3216 proto_tree_add_bitmask(tree, tvb, cur, hf_tds_curinfo_cursor_status,
3217 ett_tds5_curinfo_status, tds_curinfo_hf_fields,
3218 tds_get_int2_encoding(tds_info));
3219 cur += 2;
3221 /* offset + 2 to skip past the length, which does not include itself. */
3222 if (len - (cur - (offset + 2)) == 4) {
3223 proto_tree_add_item(tree, hf_tds_curinfo_cursor_rowcnt, tvb, cur, 4,
3224 tds_get_int4_encoding(tds_info));
3225 cur += 4;
3229 * If we're going through sequentially, and it's an INFORM response,
3230 * try to correlate cursor names with cursor ids.
3232 if (!PINFO_FD_VISITED(pinfo) &&
3233 cursor_command == TDS_CURINFO_INFORM &&
3234 !packet_cursor) {
3235 tds_conv_cursor_info_t *conv_cursor_info = tds_info->tds_conv_cursor_info;
3236 tds_cursor_info_t *cursor_current;
3238 if (!conv_cursor_info) {
3239 conv_cursor_info =
3240 wmem_new0(wmem_file_scope(), tds_conv_cursor_info_t);
3241 conv_cursor_info->tds_conv_cursor_table =
3242 wmem_tree_new(wmem_file_scope());
3243 tds_info->tds_conv_cursor_info = conv_cursor_info;
3245 cursor_current = conv_cursor_info->tds_conv_cursor_current;
3246 if (!cursor_current) {
3247 cursor_current = wmem_new0(wmem_file_scope(), tds_cursor_info_t);
3248 conv_cursor_info->tds_conv_cursor_current = cursor_current;
3250 p_add_proto_data(wmem_file_scope(), pinfo, proto_tds, 0, cursor_current);
3251 if (cursorid != 0) {
3252 if (!(cursor_current->tds_cursor_flags & TDS_CURSOR_ID_VALID)) {
3253 cursor_current->tds_cursor_id = cursorid;
3254 cursor_current->tds_cursor_flags |= TDS_CURSOR_ID_VALID;
3255 wmem_tree_insert32(conv_cursor_info->tds_conv_cursor_table,
3256 cursorid, cursor_current);
3257 cursor_current->tds_cursor_flags |= TDS_CURSOR_IN_CONV_TABLE;
3258 } else if (cursor_current->tds_cursor_id != cursorid) {
3259 tds_cursor_info_t *temp_cursor =
3260 (tds_cursor_info_t *) wmem_tree_lookup32(conv_cursor_info->tds_conv_cursor_table,
3261 cursorid);
3262 if (temp_cursor != cursor_current) {
3263 cursor_current = temp_cursor;
3264 conv_cursor_info->tds_conv_cursor_current = cursor_current;
3265 p_remove_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
3266 p_add_proto_data(wmem_file_scope(), pinfo, proto_tds, 0, cursor_current);
3272 return cur - offset;
3275 static unsigned
3276 dissect_tds5_curopen_token(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
3277 proto_tree *tree, tds_conv_info_t *tds_info)
3279 unsigned len, cur = offset;
3280 unsigned cursorid;
3281 proto_item *cursor_id_pi;
3282 tds_cursor_info_t *packet_cursor =
3283 (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
3285 proto_tree_add_item_ret_uint(tree, hf_tds_curopen_length, tvb, cur, 2, tds_get_int2_encoding(tds_info), &len);
3286 cur += 2;
3288 cursor_id_pi = proto_tree_add_item_ret_uint(tree, hf_tds_curopen_cursorid,
3289 tvb, cur, 4, tds_get_int4_encoding(tds_info), &cursorid);
3290 cur += 4;
3292 if (cursorid == 0) {
3293 int cursorname_len;
3294 const uint8_t *cursorname;
3295 proto_item *pi;
3297 pi = proto_tree_add_item_ret_string_and_length(tree, hf_tds_curopen_cursor_name,
3298 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
3299 wmem_packet_scope(), &cursorname, &cursorname_len);
3300 cur += cursorname_len;
3301 tds5_check_cursor_name(pinfo, pi, packet_cursor, cursorname);
3303 else if (packet_cursor && cursor_id_pi &&
3304 (packet_cursor->tds_cursor_flags & TDS_CURSOR_NAME_VALID)) {
3305 proto_item_append_text(cursor_id_pi, " (%s)",
3306 packet_cursor->tds_cursor_name);
3309 proto_tree_add_item(tree, hf_tds_curopen_status_parameterized, tvb, cur, 1, ENC_NA);
3310 cur += 1;
3312 return cur - offset;
3316 * Each of these covers the 8 bits of a byte, so they have
3317 * 9 elements - one for each bit, plus the terminating NULL.
3319 * Some have early NULLs as placeholders.
3321 static int * const hf_req_0[9] = {
3322 &hf_tds_capability_req_lang,
3323 &hf_tds_capability_req_rpc,
3324 &hf_tds_capability_req_evt,
3325 &hf_tds_capability_req_mstmt,
3326 &hf_tds_capability_req_bcp,
3327 &hf_tds_capability_req_cursor,
3328 &hf_tds_capability_req_dynf,
3329 NULL, NULL}; /* Two nulls until I can figure out the types. */
3331 static int * const hf_req_1[9] = {
3332 &hf_tds_capability_req_msg,
3333 &hf_tds_capability_req_param,
3334 &hf_tds_capability_data_int1,
3335 &hf_tds_capability_data_int2,
3336 &hf_tds_capability_data_int4,
3337 &hf_tds_capability_data_bit,
3338 &hf_tds_capability_data_char,
3339 &hf_tds_capability_data_vchar,
3340 NULL};
3342 static int * const hf_req_2[9] = {
3343 &hf_tds_capability_data_bin,
3344 &hf_tds_capability_data_vbin,
3345 &hf_tds_capability_data_mny8,
3346 &hf_tds_capability_data_mny4,
3347 &hf_tds_capability_data_date8,
3348 &hf_tds_capability_data_date4,
3349 &hf_tds_capability_data_flt4,
3350 &hf_tds_capability_data_flt8,
3351 NULL};
3353 static int * const hf_req_3[9] = {
3354 &hf_tds_capability_data_num,
3355 &hf_tds_capability_data_text,
3356 &hf_tds_capability_data_image,
3357 &hf_tds_capability_data_dec,
3358 &hf_tds_capability_data_lchar,
3359 &hf_tds_capability_data_lbin,
3360 &hf_tds_capability_data_intn,
3361 &hf_tds_capability_data_datetimen,
3362 NULL};
3364 static int * const hf_req_4[9] = {
3365 &hf_tds_capability_data_moneyn,
3366 &hf_tds_capability_csr_prev,
3367 &hf_tds_capability_csr_first,
3368 &hf_tds_capability_csr_last,
3369 &hf_tds_capability_csr_abs,
3370 &hf_tds_capability_csr_rel,
3371 &hf_tds_capability_csr_multi,
3372 &hf_tds_capability_con_oob,
3373 NULL};
3375 static int * const hf_req_5[9] = {
3376 &hf_tds_capability_con_inband,
3377 &hf_tds_capability_con_logical,
3378 &hf_tds_capability_proto_text,
3379 &hf_tds_capability_proto_bulk,
3380 &hf_tds_capability_req_urgevt,
3381 &hf_tds_capability_data_sensitivity,
3382 &hf_tds_capability_data_boundary,
3383 &hf_tds_capability_proto_dynamic,
3384 NULL};
3386 static int * const hf_req_6[9] = {
3387 &hf_tds_capability_proto_dynproc,
3388 &hf_tds_capability_data_fltn,
3389 &hf_tds_capability_data_bitn,
3390 &hf_tds_capability_data_int8,
3391 &hf_tds_capability_data_void,
3392 &hf_tds_capability_dol_bulk,
3393 &hf_tds_capability_object_java1,
3394 &hf_tds_capability_object_char,
3395 NULL};
3397 static int * const hf_req_7[9] = {
3398 &hf_tds_capability_object_binary,
3399 &hf_tds_capability_data_columnstatus,
3400 &hf_tds_capability_widetable,
3401 &hf_tds_capability_data_uint2,
3402 &hf_tds_capability_data_uint4,
3403 &hf_tds_capability_data_uint8,
3404 NULL,NULL, /* 56 and 60 reserved */
3405 NULL};
3407 static int * const hf_req_8[9] = {
3408 &hf_tds_capability_data_uintn,
3409 &hf_tds_capability_cur_implicit,
3410 &hf_tds_capability_data_nlbin,
3411 &hf_tds_capability_image_nchar,
3412 &hf_tds_capability_blob_nchar_16,
3413 &hf_tds_capability_blob_nchar_8,
3414 &hf_tds_capability_blob_nchar_scsu,
3415 &hf_tds_capability_data_date,
3416 NULL};
3418 static int * const hf_req_9[9] = {
3419 &hf_tds_capability_data_time,
3420 &hf_tds_capability_data_interval,
3421 &hf_tds_capability_csr_scroll,
3422 &hf_tds_capability_csr_sensitive,
3423 &hf_tds_capability_csr_insensitive,
3424 &hf_tds_capability_csr_semisensitive,
3425 &hf_tds_capability_csr_keysetdriven,
3426 &hf_tds_capability_req_srvpktsize,
3427 NULL};
3429 static int * const hf_req_10[9] = {
3430 &hf_tds_capability_data_unitext,
3431 &hf_tds_capability_cap_clusterfailover,
3432 &hf_tds_capability_data_sint1,
3433 &hf_tds_capability_req_largeident,
3434 &hf_tds_capability_req_blob_nchar_16,
3435 &hf_tds_capability_data_xml,
3436 &hf_tds_capability_req_curinfo3,
3437 &hf_tds_capability_req_dbrpc2,
3438 NULL};
3440 static int * const hf_resp_0[9] = {
3441 &hf_tds_capability_res_nomsg,
3442 &hf_tds_capability_res_noeed,
3443 &hf_tds_capability_res_noparam,
3444 &hf_tds_capability_data_noint1,
3445 &hf_tds_capability_data_noint2,
3446 &hf_tds_capability_data_noint4,
3447 &hf_tds_capability_data_nobit,
3448 NULL, /* 0 unused */
3449 NULL};
3451 static int * const hf_resp_1[9] = {
3452 &hf_tds_capability_data_nochar,
3453 &hf_tds_capability_data_novchar,
3454 &hf_tds_capability_data_nobin,
3455 &hf_tds_capability_data_novbin,
3456 &hf_tds_capability_data_nomny8,
3457 &hf_tds_capability_data_nomny4,
3458 &hf_tds_capability_data_nodate8,
3459 &hf_tds_capability_data_nodate4,
3460 NULL};
3462 static int * const hf_resp_2[9] = {
3463 &hf_tds_capability_data_noflt4,
3464 &hf_tds_capability_data_noflt8,
3465 &hf_tds_capability_data_nonum,
3466 &hf_tds_capability_data_notext,
3467 &hf_tds_capability_data_noimage,
3468 &hf_tds_capability_data_nodec,
3469 &hf_tds_capability_data_nolchar,
3470 &hf_tds_capability_data_nolbin,
3471 NULL};
3473 static int * const hf_resp_3[9] = {
3474 &hf_tds_capability_data_nointn,
3475 &hf_tds_capability_data_nodatetimen,
3476 &hf_tds_capability_data_nomoneyn,
3477 &hf_tds_capability_con_nooob,
3478 &hf_tds_capability_con_noinband,
3479 &hf_tds_capability_proto_notext,
3480 &hf_tds_capability_proto_nobulk,
3481 &hf_tds_capability_data_nosensitivity,
3482 NULL};
3484 static int * const hf_resp_4[9] = {
3485 &hf_tds_capability_data_noboundary,
3486 &hf_tds_capability_res_notdsdebug,
3487 &hf_tds_capability_res_nostripblanks,
3488 &hf_tds_capability_data_noint8,
3489 &hf_tds_capability_object_nojava1,
3490 &hf_tds_capability_object_nochar,
3491 &hf_tds_capability_data_nocolumnstatus,
3492 &hf_tds_capability_object_nobinary,
3493 NULL};
3495 static int * const hf_resp_5[9] = {
3496 &hf_tds_capability_data_nouint2,
3497 &hf_tds_capability_data_nouint4,
3498 &hf_tds_capability_data_nouint8,
3499 &hf_tds_capability_data_nouintn,
3500 &hf_tds_capability_no_widetables,
3501 &hf_tds_capability_data_nonlbin,
3502 &hf_tds_capability_image_nonchar,
3503 NULL, /* 40 unused */
3504 NULL};
3506 static int * const hf_resp_6[9] = {
3507 &hf_tds_capability_blob_nonchar_16,
3508 &hf_tds_capability_blob_nonchar_8,
3509 &hf_tds_capability_blob_nonchar_scsu,
3510 &hf_tds_capability_data_nodate,
3511 &hf_tds_capability_data_notime,
3512 &hf_tds_capability_data_nointerval,
3513 &hf_tds_capability_data_nounitext,
3514 &hf_tds_capability_data_nosint1,
3515 NULL};
3517 static int * const hf_resp_7[9] = {
3518 &hf_tds_capability_no_largeident,
3519 &hf_tds_capability_no_blob_nchar_16,
3520 &hf_tds_capability_no_srvpktsize,
3521 &hf_tds_capability_data_noxml,
3522 &hf_tds_capability_no_nint_return_value,
3523 &hf_tds_capability_res_noxnldata,
3524 &hf_tds_capability_res_suppress_fmt,
3525 &hf_tds_capability_res_suppress_doneinproc,
3526 NULL};
3528 static int * const hf_resp_8[9] = {
3529 &hf_tds_capability_res_force_rowfmt2,
3530 NULL, NULL, NULL, /* 65-67 reserved */
3531 NULL, NULL, NULL, NULL, /* 68-71 reserved */
3532 NULL};
3534 static int * const *hf_req_array[] = {
3535 hf_req_0,
3536 hf_req_1,
3537 hf_req_2,
3538 hf_req_3,
3539 hf_req_4,
3540 hf_req_5,
3541 hf_req_6,
3542 hf_req_7,
3543 hf_req_8,
3544 hf_req_9,
3545 hf_req_10
3548 static int * const *hf_resp_array[] = {
3549 hf_resp_0,
3550 hf_resp_1,
3551 hf_resp_2,
3552 hf_resp_3,
3553 hf_resp_4,
3554 hf_resp_5,
3555 hf_resp_6,
3556 hf_resp_7,
3557 hf_resp_8
3560 static unsigned
3561 dissect_tds5_capability_token(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
3562 proto_tree *tree, tds_conv_info_t *tds_info)
3564 unsigned len, cur;
3566 proto_tree_add_item_ret_uint(tree, hf_tds_capability_length, tvb, offset, 2, tds_get_int2_encoding(tds_info), &len);
3567 cur = 2;
3569 while (cur < len) {
3570 unsigned captype, caplen, cap;
3571 proto_item *length_item;
3573 proto_tree_add_item_ret_uint(tree, hf_tds_capability_captype, tvb,
3574 offset + cur, 1, ENC_NA, &captype);
3575 length_item = proto_tree_add_item_ret_uint(tree, hf_tds_capability_caplen, tvb,
3576 offset + cur +1 , 1, ENC_NA, &caplen);
3577 cur += 2;
3579 if (caplen > (cur - len)) {
3580 expert_add_info_format(pinfo, length_item, &ei_tds_token_length_invalid,
3581 " Capability length %d", caplen);
3582 caplen = cur - len;
3585 for (cap=0; cap < caplen; cap++) {
3586 int * const *hf_array = NULL;
3587 char name[ITEM_LABEL_LENGTH];
3588 int ett;
3590 switch (captype) {
3591 case TDS_CAP_REQUEST:
3592 if (cap < array_length(hf_req_array)) {
3593 hf_array = hf_req_array[cap];
3594 snprintf(name, ITEM_LABEL_LENGTH, "Req caps %d-%d: ",
3595 cap*8, (cap + 1)*8 - 1);
3596 ett = ett_tds_capability_req;
3598 break;
3599 case TDS_CAP_RESPONSE:
3600 if (cap < array_length(hf_resp_array)) {
3601 hf_array = hf_resp_array[cap];
3602 snprintf(name, ITEM_LABEL_LENGTH, "Resp caps %d-%d: ",
3603 cap*8, (cap + 1)*8 - 1);
3604 ett = ett_tds_capability_resp;
3606 break;
3607 default:
3610 if (hf_array) {
3611 /* Using add_bitmask_text to allow the name to be specified.
3612 * The flags are the same as the add_bitmask defaults. */
3613 proto_tree_add_bitmask_text(tree, tvb,
3614 offset + cur + (caplen - cap - 1), 1,
3615 name, NULL,
3616 ett, hf_array,
3617 ENC_NA, BMT_NO_INT|BMT_NO_TFS);
3621 cur += caplen;
3624 return cur;
3628 static void
3629 dissect_tds_transmgr_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3631 proto_tree *request_tree;
3632 int offset = 0, len;
3634 request_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_query, NULL, "Transaction Manager Request Packet");
3635 dissect_tds_all_headers(tvb, &offset, pinfo, request_tree);
3636 len = tvb_reported_length_remaining(tvb, offset);
3638 if(len >= 2)
3640 proto_tree_add_item(request_tree, hf_tds_transmgr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3642 if(len > 2)
3644 proto_tree_add_item(request_tree, hf_tds_transmgr_payload, tvb, offset + 2, len - 2, ENC_NA);
3649 static unsigned
3650 dissect_tds5_logout_token(proto_tree *tree, tvbuff_t *tvb, unsigned offset, tds_conv_info_t *tds_info _U_)
3652 unsigned cur = offset;
3654 proto_tree_add_item(tree, hf_tds_logout_options, tvb, cur, 1, ENC_NA);
3655 cur += 1;
3657 return cur - offset;
3660 static unsigned
3661 dissect_tds5_msg_token(proto_tree *tree, tvbuff_t *tvb, unsigned offset, tds_conv_info_t *tds_info)
3663 unsigned cur = offset;
3664 proto_tree_add_item(tree, hf_tds_msg_length, tvb, cur, 1, ENC_NA);
3665 cur += 1;
3666 proto_tree_add_item(tree, hf_tds_msg_status, tvb, cur, 1, ENC_NA);
3667 cur += 1;
3668 proto_tree_add_item(tree, hf_tds_msg_msgid, tvb, cur, 2, tds_get_int2_encoding(tds_info));
3669 cur += 2;
3671 return cur - offset;
3675 * Process TDS 5 "PARAMFMT" token and store relevant information in the
3676 * _netlib_data structure for later use (see tds_get_row_size)
3679 static unsigned
3680 dissect_tds_paramfmt_token(proto_tree *tree, tvbuff_t *tvb, unsigned offset, tds_conv_info_t *tds_info,
3681 struct _netlib_data *nl_data)
3683 unsigned next, cur;
3684 unsigned col, len, numcols;
3686 proto_tree_add_item_ret_uint(tree, hf_tds_paramfmt_length, tvb, offset, 2,
3687 tds_get_int4_encoding(tds_info), &len);
3688 proto_tree_add_item_ret_uint(tree, hf_tds_paramfmt_numparams, tvb, offset + 2, 2,
3689 tds_get_int2_encoding(tds_info), &numcols);
3690 next = offset + len + 2; /* Only skip the length field. */
3691 cur = offset + 4; /* Skip the length and numcols field. */
3693 col = 0;
3694 while (cur < next) {
3695 const uint8_t *colname = NULL;
3696 int colnamelen, localelen;
3698 if (col >= TDS_MAX_COLUMNS) {
3699 nl_data->num_cols = TDS_MAX_COLUMNS;
3700 return 0;
3703 if (!(nl_data->columns[col])) {
3704 nl_data->columns[col] = wmem_new0(wmem_packet_scope(), struct _tds_col);
3707 proto_tree_add_item_ret_string_and_length(tree, hf_tds_paramfmt_colname,
3708 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
3709 wmem_packet_scope(), &colname, &colnamelen);
3710 cur += colnamelen;
3711 nl_data->columns[col]->name = (const char*)colname;
3713 proto_tree_add_item(tree, hf_tds_paramfmt_status, tvb, cur, 1, ENC_NA);
3714 cur += 1;
3716 nl_data->columns[col]->utype = tvb_get_uint32(tvb, cur,
3717 tds_get_int4_encoding(tds_info));
3718 proto_tree_add_item(tree, hf_tds_paramfmt_utype, tvb, cur, 4,
3719 tds_get_int4_encoding(tds_info));
3720 cur += 4;
3722 nl_data->columns[col]->ctype = tvb_get_uint8(tvb,cur);
3723 proto_tree_add_item(tree, hf_tds_paramfmt_ctype, tvb, cur, 1, ENC_NA);
3724 cur++;
3726 if (!is_fixedlen_type_tds(nl_data->columns[col]->ctype)) {
3727 if (is_longlen_type_sybase(nl_data->columns[col]->ctype)) {
3728 proto_tree_add_item_ret_uint(tree, hf_tds_paramfmt_csize, tvb, cur, 4,
3729 tds_get_int4_encoding(tds_info),
3730 &nl_data->columns[col]->csize);
3731 cur += 4;
3733 else {
3734 nl_data->columns[col]->csize = tvb_get_uint8(tvb,cur);
3735 proto_tree_add_item(tree, hf_tds_paramfmt_csize, tvb, cur, 1, ENC_NA);
3736 cur ++;
3738 } else {
3739 nl_data->columns[col]->csize =
3740 get_size_by_coltype(nl_data->columns[col]->ctype);
3743 proto_tree_add_item_ret_length(tree, hf_tds_paramfmt_locale_info,
3744 tvb, cur, 1, ENC_NA, &localelen);
3745 cur += localelen;
3747 col += 1;
3749 } /* while */
3751 nl_data->num_cols = col;
3752 return cur - offset;
3756 * Process TDS 5 "PARAMFMT2" token and store relevant information in the
3757 * _netlib_data structure for later use (see tds_get_row_size)
3760 static unsigned
3761 dissect_tds_paramfmt2_token(proto_tree *tree, tvbuff_t *tvb, unsigned offset, tds_conv_info_t *tds_info,
3762 struct _netlib_data *nl_data)
3764 unsigned next, cur;
3765 unsigned col, len, numcols;
3767 proto_tree_add_item_ret_uint(tree, hf_tds_paramfmt2_length, tvb, offset, 4,
3768 tds_get_int4_encoding(tds_info), &len);
3769 proto_tree_add_item_ret_uint(tree, hf_tds_paramfmt2_numparams, tvb, offset + 4, 2,
3770 tds_get_int2_encoding(tds_info), &numcols);
3771 next = offset + len + 4; /* Only skip the length field. */
3772 cur = offset + 6; /* Skip the length and numcols field. */
3774 col = 0;
3775 while (cur < next) {
3776 const uint8_t *colname = NULL;
3777 int colnamelen, localelen;
3779 if (col >= TDS_MAX_COLUMNS) {
3780 nl_data->num_cols = TDS_MAX_COLUMNS;
3781 return 0;
3784 if (!(nl_data->columns[col])) {
3785 nl_data->columns[col] = wmem_new0(wmem_packet_scope(), struct _tds_col);
3788 proto_tree_add_item_ret_string_and_length(tree, hf_tds_paramfmt2_colname,
3789 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
3790 wmem_packet_scope(), &colname, &colnamelen);
3791 cur += colnamelen;
3792 nl_data->columns[col]->name = (const char*)colname;
3794 proto_tree_add_item(tree, hf_tds_paramfmt2_status, tvb, cur, 4, tds_get_int4_encoding(tds_info));
3795 cur += 4;
3797 nl_data->columns[col]->utype = tvb_get_uint32(tvb, cur,
3798 tds_get_int4_encoding(tds_info));
3799 proto_tree_add_item(tree, hf_tds_paramfmt2_utype, tvb, cur, 4,
3800 tds_get_int4_encoding(tds_info));
3801 cur += 4;
3803 nl_data->columns[col]->ctype = tvb_get_uint8(tvb,cur);
3804 proto_tree_add_item(tree, hf_tds_paramfmt2_ctype, tvb, cur, 1, ENC_NA);
3805 cur++;
3807 if (!is_fixedlen_type_tds(nl_data->columns[col]->ctype)) {
3808 if (is_longlen_type_sybase(nl_data->columns[col]->ctype)) {
3809 proto_tree_add_item_ret_uint(tree, hf_tds_paramfmt2_csize, tvb, cur, 4,
3810 tds_get_int4_encoding(tds_info),
3811 &nl_data->columns[col]->csize);
3812 cur += 4;
3814 else {
3815 nl_data->columns[col]->csize = tvb_get_uint8(tvb,cur);
3816 proto_tree_add_item(tree, hf_tds_paramfmt2_csize, tvb, cur, 1, ENC_NA);
3817 cur ++;
3819 } else {
3820 nl_data->columns[col]->csize =
3821 get_size_by_coltype(nl_data->columns[col]->ctype);
3824 proto_tree_add_item_ret_length(tree, hf_tds_paramfmt2_locale_info,
3825 tvb, cur, 1, ENC_NA, &localelen);
3826 cur += localelen;
3828 col += 1;
3830 } /* while */
3832 nl_data->num_cols = col;
3833 return cur - offset;
3836 static int
3837 dissect_tds5_params_token(tvbuff_t *tvb, packet_info *pinfo,
3838 struct _netlib_data *nl_data, unsigned offset,
3839 proto_tree *tree, proto_item *token_item,
3840 tds_conv_info_t *tds_info)
3842 unsigned cur = offset, i;
3844 /* TDS5 does not have the Partially Length-Prefixed concept, so the "plp"
3845 * parameter is always false. */
3846 for (i = 0; i < nl_data->num_cols; i++) {
3847 dissect_tds_type_varbyte(tvb, &cur, pinfo, tree, hf_tds_params_field, tds_info,
3848 nl_data->columns[i]->ctype, nl_data->columns[i]->scale,
3849 false, i+1, nl_data->columns[i]->name);
3852 proto_item_set_len(token_item, cur - offset);
3853 return cur - offset;
3856 static int
3857 tds45_token_to_idx(uint8_t token)
3859 /* TODO: Commented out entries are token types which are not currently dissected
3860 * Although they are known values, we cannot step over the bytes as token length is unknown
3861 * Better therefore to return unknown token type and highlight to user
3865 * Token values for TDS4 and TDS5.
3866 * Microsoft and Sybase have separately expanded the protocol and have
3867 * each used numbers differently.
3870 switch(token)
3872 /*case TDS_ALTROW_TOKEN: return hf_tds_altrow;*/
3873 case TDS_CAPABILITY_TOKEN: return hf_tds_capability;
3874 case TDS_COLFMT_TOKEN: return hf_tds_colfmt;
3875 case TDS_COL_NAME_TOKEN: return hf_tds_colname;
3876 case TDS_CONTROL_TOKEN: return hf_tds_control;
3877 case TDS_CURCLOSE_TOKEN: return hf_tds_curclose;
3878 case TDS_CURDECLARE_TOKEN: return hf_tds_curdeclare;
3879 case TDS_CURFETCH_TOKEN: return hf_tds_curfetch;
3880 case TDS_CURINFO_TOKEN: return hf_tds_curinfo;
3881 case TDS_CUROPEN_TOKEN: return hf_tds_curopen;
3882 case TDS5_DBRPC_TOKEN: return hf_tds_dbrpc;
3883 case TDS_DONE_TOKEN: return hf_tds_done;
3884 case TDS_DONEPROC_TOKEN: return hf_tds_doneproc;
3885 case TDS_DONEINPROC_TOKEN: return hf_tds_doneinproc;
3886 case TDS5_EED_TOKEN: return hf_tds_eed;
3887 case TDS_ENVCHG_TOKEN: return hf_tds_envchg;
3888 case TDS_ERR_TOKEN: return hf_tds_error;
3889 case TDS_INFO_TOKEN: return hf_tds_info;
3890 case TDS_LOGIN_ACK_TOKEN: return hf_tds_loginack;
3891 case TDS5_LOGOUT_TOKEN: return hf_tds_logout;
3892 case TDS5_MSG_TOKEN: return hf_tds_msg;
3893 case TDS_OFFSET_TOKEN: return hf_tds_offset;
3894 case TDS_ORDER_TOKEN: return hf_tds_order;
3895 case TDS5_PARAMFMT_TOKEN: return hf_tds_paramfmt;
3896 case TDS5_PARAMFMT2_TOKEN: return hf_tds_paramfmt2;
3897 case TDS5_PARAMS_TOKEN: return hf_tds_params;
3898 case TDS_PROCID_TOKEN: return hf_tds_procid;
3899 case TDS_RET_STAT_TOKEN: return hf_tds_returnstatus;
3900 /*case TDS_RETURNVAL_TOKEN: return hf_tds_returnvalue;*/
3901 case TDS_ROW_TOKEN: return hf_tds_row;
3902 case TDS5_ROWFMT_TOKEN: return hf_tds_rowfmt;
3903 case TDS5_ROWFMT2_TOKEN: return hf_tds_rowfmt2;
3904 /*case TDS_TABNAME_TOKEN: return hf_tds_tabname;*/
3907 return hf_tds_unknown_tds_token;
3910 static void
3911 dissect_tds5_tokenized_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3912 tds_conv_info_t *tds_info)
3914 unsigned offset;
3915 unsigned pos;
3916 unsigned token_len_field_size = 2;
3917 unsigned token_len_field_val = 0;
3918 uint8_t token;
3919 unsigned token_sz;
3920 proto_tree *query_tree;
3921 proto_tree *token_tree;
3922 proto_item *token_item;
3923 struct _netlib_data nl_data;
3925 (void) memset(&nl_data, '\0', sizeof nl_data);
3927 offset = 0;
3928 query_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_query, NULL, "TDS5 Query Packet");
3931 * Until we reach the end of the packet, read tokens.
3933 pos = offset;
3934 while (tvb_reported_length_remaining(tvb, pos) > 0) {
3936 /* our token */
3937 token = tvb_get_uint8(tvb, pos);
3938 if (tds_token_is_fixed_size_sybase(token))
3939 token_sz = tds_get_fixed_token_size_sybase(token, tds_info) + 1;
3940 else
3941 token_sz = tds_get_variable_token_size_sybase(tvb, pos+1, token, tds_info,
3942 &token_len_field_size,
3943 &token_len_field_val);
3944 token_tree = proto_tree_add_subtree_format(query_tree, tvb, pos, token_sz,
3945 ett_tds_token, &token_item, "Token 0x%02x %s", token,
3946 val_to_str_const(token, token_names, "Unknown Token Type"));
3948 if ((int) token_sz <= 0) {
3949 expert_add_info_format(pinfo, token_item, &ei_tds_token_length_invalid, "Bogus token size: %u", token_sz);
3950 break;
3953 switch (token) {
3954 case TDS_LANG_TOKEN:
3955 token_sz = dissect_tds5_lang_token(tvb, pos + 1, token_tree, tds_info) + 1;
3956 break;
3957 case TDS_CURCLOSE_TOKEN:
3958 token_sz = dissect_tds5_curclose_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
3959 break;
3960 case TDS_CURDECLARE_TOKEN:
3961 token_sz = dissect_tds5_curdeclare_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
3962 break;
3963 case TDS_CURFETCH_TOKEN:
3964 token_sz = dissect_tds5_curfetch_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
3965 break;
3966 case TDS_CURINFO_TOKEN:
3967 token_sz = dissect_tds5_curinfo_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
3968 break;
3969 case TDS_CUROPEN_TOKEN:
3970 token_sz = dissect_tds5_curopen_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
3971 break;
3972 case TDS5_LOGOUT_TOKEN:
3973 token_sz = dissect_tds5_logout_token(token_tree, tvb, pos + 1, tds_info) + 1;
3974 break;
3975 case TDS5_DBRPC_TOKEN:
3976 token_sz = dissect_tds5_dbrpc_token(tvb, pos + 1, token_tree, tds_info) + 1;
3977 break;
3978 case TDS5_PARAMFMT_TOKEN:
3979 token_sz = dissect_tds_paramfmt_token(token_tree, tvb, pos + 1, tds_info, &nl_data) + 1;
3980 break;
3981 case TDS5_PARAMFMT2_TOKEN:
3982 token_sz = dissect_tds_paramfmt2_token(token_tree, tvb, pos + 1, tds_info, &nl_data) + 1;
3983 break;
3984 case TDS5_PARAMS_TOKEN:
3985 token_sz = dissect_tds5_params_token(tvb, pinfo, &nl_data, pos + 1,
3986 token_tree, token_item, tds_info) + 1;
3987 break;
3988 default:
3989 break;
3992 pos += token_sz;
3994 } /* while */
3997 static void
3998 set_tds7_encodings(tds_conv_info_t *tds_info)
4000 tds_info->tds_encoding_int4 = TDS_INT4_LITTLE_ENDIAN;
4001 tds_info->tds_encoding_int2 = TDS_INT2_LITTLE_ENDIAN;
4002 tds_info->tds_encoding_char = TDS_CHAR_UTF16;
4005 static void
4006 set_tds_version(packet_info *pinfo, tds_conv_info_t *tds_info, uint32_t tds_version)
4008 if (PINFO_FD_VISITED(pinfo)) {
4009 return;
4012 switch (tds_version) {
4013 case TDS_PROTOCOL_VALUE_4_2:
4014 tds_info->tds_version = TDS_PROTOCOL_4;
4015 break;
4016 case TDS_PROTOCOL_VALUE_4_6:
4017 tds_info->tds_version = TDS_PROTOCOL_4;
4018 break;
4019 case TDS_PROTOCOL_VALUE_5:
4020 tds_info->tds_version = TDS_PROTOCOL_5;
4021 break;
4022 case TDS_PROTOCOL_VALUE_7_0:
4023 tds_info->tds_version = TDS_PROTOCOL_7_0;
4024 set_tds7_encodings(tds_info);
4025 break;
4026 case TDS_PROTOCOL_VALUE_7_1:
4027 case TDS_PROTOCOL_VALUE_7_1_1:
4028 tds_info->tds_version = TDS_PROTOCOL_7_1;
4029 set_tds7_encodings(tds_info);
4030 break;
4031 case TDS_PROTOCOL_VALUE_7_2:
4032 tds_info->tds_version = TDS_PROTOCOL_7_2;
4033 set_tds7_encodings(tds_info);
4034 break;
4035 case TDS_PROTOCOL_VALUE_7_3A:
4036 tds_info->tds_version = TDS_PROTOCOL_7_3A;
4037 set_tds7_encodings(tds_info);
4038 break;
4039 case TDS_PROTOCOL_VALUE_7_3B:
4040 tds_info->tds_version = TDS_PROTOCOL_7_3B;
4041 set_tds7_encodings(tds_info);
4042 break;
4043 case TDS_PROTOCOL_VALUE_7_4:
4044 tds_info->tds_version = TDS_PROTOCOL_7_4;
4045 set_tds7_encodings(tds_info);
4046 break;
4047 default:
4048 tds_info->tds_version = TDS_PROTOCOL_7_4;
4049 break;
4053 static void
4054 set_tds_version_from_prog_version(packet_info *pinfo, tds_conv_info_t *tds_info, uint32_t prog_version, bool is_server)
4056 if (PINFO_FD_VISITED(pinfo)) {
4057 return;
4060 /* Support the latest version supported by both client and server,
4061 * if known. (It is possible for the LOGIN7 message to be over TLS,
4062 * not decrypted, and then in the response a token such as Info
4063 * that depends on the version appear before the LoginAck token that
4064 * confirms the version. See the capture in !9530.)
4066 if (is_server) {
4067 tds_info->server_version = prog_version;
4068 if (tds_info->client_version != TDS_PROTOCOL_NOT_SPECIFIED &&
4069 tds_info->client_version != 0) {
4070 prog_version = MIN(prog_version, tds_info->client_version);
4072 } else {
4073 tds_info->client_version = prog_version;
4074 if (tds_info->server_version != TDS_PROTOCOL_NOT_SPECIFIED &&
4075 tds_info->server_version != 0) {
4076 prog_version = MIN(prog_version, tds_info->server_version);
4080 uint16_t major_minor = prog_version >> 16;
4082 if (major_minor >= 0x0b00) {
4083 #if 0
4084 case 0x0b000834: /* SQL Server 2012 */
4085 case 0x0b000bb8: /* SQL Server 2012 SP1 */
4086 case 0x0b010bb8: /* SQL Server 2012 SP1 */
4087 case 0x0b0013c2: /* SQL Server 2012 SP2 */
4088 case 0x0b0213c2: /* SQL Server 2012 SP2 */
4089 case 0x0b001784: /* SQL Server 2012 SP3 */
4090 case 0x0b031784: /* SQL Server 2012 SP3 */
4091 case 0x0b001b59: /* SQL Server 2012 SP4 */
4092 case 0x0b041b59: /* SQL Server 2012 SP4 */
4093 case 0x0c0007d0: /* SQL Server 2014 */
4094 case 0x0c001004: /* SQL Server 2014 SP1 */
4095 case 0x0c011004: /* SQL Server 2014 SP1 */
4096 case 0x0c001388: /* SQL Server 2014 SP2 */
4097 case 0x0c021388: /* SQL Server 2014 SP2 */
4098 case 0x0d000641: /* SQL Server 2016 */
4099 case 0x0d000fa1: /* SQL Server 2016 SP1 */
4100 case 0x0d010fa1: /* SQL Server 2016 SP1 */
4101 case 0x0e0003e8: /* SQL Server 2017 */
4102 case 0x0f0007d0: /* SQL Server 2019 */
4103 case 0x100003e8: /* SQL Server 2022 - supports TDS version 8.0,
4104 though this dissector does not yet. */
4105 #endif
4106 tds_info->tds_version = TDS_PROTOCOL_7_4;
4107 } else if (major_minor >= 0x0a32) {
4108 #if 0
4109 case 0x0a320640: /* SQL Server 2008 R2 */
4110 case 0x0a3209c4: /* SQL Server 2008 R2 SP1 */
4111 case 0x0a3309c4: /* SQL Server 2008 R2 SP1 */
4112 case 0x0a320fa0: /* SQL Server 2008 R2 SP2 */
4113 case 0x0a340fa0: /* SQL Server 2008 R2 SP2 */
4114 case 0x0a321770: /* SQL Server 2008 R2 SP3 */
4115 case 0x0a351770: /* SQL Server 2008 R2 SP3 */
4116 #endif
4117 tds_info->tds_version = TDS_PROTOCOL_7_3B;
4118 } else if (major_minor >= 0x0a00) {
4119 #if 0
4120 case 0x0a000640: /* SQL Server 2008 */
4121 case 0x0a0009e3: /* SQL Server 2008 SP1 */
4122 case 0x0a0109e3: /* SQL Server 2008 SP1 */
4123 case 0x0a000fa0: /* SQL Server 2008 SP2 */
4124 case 0x0a020fa0: /* SQL Server 2008 SP2 */
4125 case 0x0a00157c: /* SQL Server 2008 SP3 */
4126 case 0x0a03157c: /* SQL Server 2008 SP3 */
4127 case 0x0a001770: /* SQL Server 2008 SP4 */
4128 case 0x0a041770: /* SQL Server 2008 SP4 */
4129 #endif
4130 tds_info->tds_version = TDS_PROTOCOL_7_3A;
4131 } else if (major_minor >= 0x0900) {
4132 #if 0
4133 case 0x09000577: /* SQL Server 2005 */
4134 case 0x090007ff: /* SQL Server 2005 SP1 */
4135 case 0x09000be2: /* SQL Server 2005 SP2 */
4136 case 0x09000fc3: /* SQL Server 2005 SP3 */
4137 case 0x09001388: /* SQL Server 2005 SP4 */
4138 #endif
4139 tds_info->tds_version = TDS_PROTOCOL_7_2;
4140 } else if (major_minor >= 0x0800) {
4141 #if 0
4142 case 0x080000c2: /* SQL Server 2000 */
4143 case 0x08000180: /* SQL Server 2000 SP1 */
4144 case 0x08000214: /* SQL Server 2000 SP2 */
4145 case 0x080002f8: /* SQL Server 2000 SP3 */
4146 case 0x080007f7: /* SQL Server 2000 SP4 */
4147 #endif
4148 tds_info->tds_version = TDS_PROTOCOL_7_1;
4149 } else if (major_minor >= 0x0700) {
4150 #if 0
4151 case 0x0700026f: /* SQL Server 7.0 */
4152 case 0x070002bb: /* SQL Server 7.0 SP1 */
4153 case 0x0700034a: /* SQL Server 7.0 SP2 */
4154 case 0x070003c1: /* SQL Server 7.0 SP3 */
4155 case 0x07000427: /* SQL Server 7.0 SP4 */
4156 #endif
4157 tds_info->tds_version = TDS_PROTOCOL_7_0;
4158 } else {
4159 /* Shouldn't happen. We only call this from a prelogin packet,
4160 * which implies TDS 7.0 and later. (If we change this to
4161 * call it from elsewhere, change this perhaps.)
4163 tds_info->tds_version = TDS_PROTOCOL_7_0;
4165 set_tds7_encodings(tds_info);
4168 static int detect_tls(tvbuff_t *tvb)
4170 uint8_t tls_type, tls_maj_ver, tls_min_ver;
4171 int offset = 0, tls_len;
4173 tls_type = tvb_get_uint8(tvb, offset);
4174 tls_maj_ver = tvb_get_uint8(tvb, offset + 1);
4175 tls_min_ver = tvb_get_uint8(tvb, offset + 2);
4176 tls_len = tvb_get_ntohs(tvb, offset + 3);
4178 if( (tls_type >= 0x14) && (tls_type <= 0x18) &&
4179 (tls_maj_ver == 3) && (tls_min_ver <= 3) &&
4180 ((tls_len + 5 <= tvb_reported_length_remaining(tvb, offset)))
4183 return 1;
4186 return 0;
4189 static void
4190 dissect_tds7_prelogin_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info,
4191 bool is_response)
4193 uint8_t token;
4194 int offset = 0;
4195 uint16_t tokenoffset, tokenlen;
4196 proto_tree *prelogin_tree = NULL, *option_tree;
4197 proto_item *item, *option_item;
4199 item = proto_tree_add_item(tree, hf_tds_prelogin, tvb, 0, -1, ENC_NA);
4201 if(detect_tls(tvb))
4203 tvbuff_t *next_tvb = tvb_new_subset_remaining(tvb, offset);
4204 call_dissector(tls_handle, next_tvb, pinfo, tree);
4205 return;
4209 * If we get here, we know we're at least TDS 7.0. The actual TDS 7 version
4210 * will be set from the LOGINACK token, which should come after all of
4211 * the prelogin packets. That instance will overwrite the value set here.
4214 set_tds_version(pinfo, tds_info, TDS_PROTOCOL_VALUE_7_0);
4216 prelogin_tree = proto_item_add_subtree(item, ett_tds_message);
4217 while(tvb_reported_length_remaining(tvb, offset) > 0)
4219 token = tvb_get_uint8(tvb, offset);
4220 option_tree = proto_tree_add_subtree(prelogin_tree, tvb, offset, token == 0xff ? 1 : 5,
4221 ett_tds_prelogin_option, &option_item, "Option");
4222 proto_tree_add_item(option_tree, hf_tds_prelogin_option_token, tvb, offset, 1, ENC_NA);
4223 offset += 1;
4225 if(token == TDS7_PRELOGIN_OPTION_TERMINATOR)
4227 proto_item_append_text(option_item, ": Terminator");
4228 break;
4231 tokenoffset = tvb_get_ntohs(tvb, offset);
4232 proto_tree_add_item(option_tree, hf_tds_prelogin_option_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
4233 offset += 2;
4235 tokenlen = tvb_get_ntohs(tvb, offset);
4236 proto_tree_add_item(option_tree, hf_tds_prelogin_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
4237 offset += 2;
4239 switch(token)
4241 case TDS7_PRELOGIN_OPTION_VERSION: {
4242 uint32_t version;
4243 proto_item_append_text(option_item, ": Version");
4244 proto_tree_add_item_ret_uint(option_tree, hf_tds_prelogin_option_version,
4245 tvb, tokenoffset, 4, ENC_BIG_ENDIAN,
4246 &version);
4247 proto_tree_add_item(option_tree, hf_tds_prelogin_option_subbuild, tvb, tokenoffset + 4, 2, ENC_LITTLE_ENDIAN);
4248 /* This gives us a better idea of what protocol we'll see. */
4249 set_tds_version_from_prog_version(pinfo, tds_info, version, is_response);
4250 break;
4252 case TDS7_PRELOGIN_OPTION_ENCRYPTION: {
4253 proto_item_append_text(option_item, ": Encryption");
4254 proto_tree_add_item(option_tree, hf_tds_prelogin_option_encryption, tvb, tokenoffset, tokenlen, ENC_NA);
4255 break;
4257 case TDS7_PRELOGIN_OPTION_INSTOPT: {
4258 proto_item_append_text(option_item, ": InstOpt");
4259 proto_tree_add_item(option_tree, hf_tds_prelogin_option_instopt, tvb, tokenoffset, tokenlen, ENC_ASCII | ENC_NA);
4260 break;
4262 case TDS7_PRELOGIN_OPTION_THREADID: {
4263 proto_item_append_text(option_item, ": ThreadID");
4264 if (tokenlen > 0)
4265 proto_tree_add_item(option_tree, hf_tds_prelogin_option_threadid, tvb, tokenoffset, tokenlen, ENC_BIG_ENDIAN);
4266 break;
4268 case TDS7_PRELOGIN_OPTION_MARS: {
4269 proto_item_append_text(option_item, ": MARS");
4270 proto_tree_add_item(option_tree, hf_tds_prelogin_option_mars, tvb, tokenoffset, tokenlen, ENC_NA);
4271 break;
4273 case TDS7_PRELOGIN_OPTION_TRACEID: {
4274 proto_item_append_text(option_item, ": TraceID");
4275 proto_tree_add_item(option_tree, hf_tds_prelogin_option_traceid, tvb, tokenoffset, tokenlen, ENC_NA);
4276 break;
4278 case TDS7_PRELOGIN_OPTION_FEDAUTHREQUIRED: {
4279 proto_item_append_text(option_item, ": FedAuthRequired");
4280 proto_tree_add_item(option_tree, hf_tds_prelogin_option_fedauthrequired, tvb, tokenoffset, tokenlen, ENC_NA);
4281 break;
4283 case TDS7_PRELOGIN_OPTION_NONCEOPT: {
4284 proto_item_append_text(option_item, ": NonceOpt");
4285 proto_tree_add_item(option_tree, hf_tds_prelogin_option_nonceopt, tvb, tokenoffset, tokenlen, ENC_NA);
4286 break;
4292 static unsigned
4293 dissect_tds45_login_name(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4294 int hf, int hf_length, unsigned offset, const unsigned namesize,
4295 const char *name)
4297 unsigned len;
4298 proto_item *length_item;
4300 len = tvb_get_uint8(tvb,offset + namesize);
4301 length_item = proto_tree_add_item(tree, hf_length,
4302 tvb, offset+namesize, 1, ENC_NA);
4303 if (len > namesize) {
4304 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_length,
4305 "Invalid %s length (%d)", name, len);
4306 len = namesize;
4308 if (len > 0) {
4309 proto_tree_add_item(tree, hf, tvb, offset, len, ENC_ASCII);
4311 return offset + namesize + 1;
4315 static unsigned
4316 dissect_tds45_remotepassword(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
4318 unsigned rplen, cur, server_len, password_len;
4319 proto_item *length_item;
4320 proto_tree *rempw_tree;
4322 rempw_tree = proto_tree_add_subtree(tree, tvb, offset, TDS_RPLEN + 1, ett_tds_login_rempw, NULL, "Remote password");
4324 length_item = proto_tree_add_item_ret_uint(rempw_tree, hf_tdslogin_remotepassword_length, tvb,
4325 offset + TDS_RPLEN, 1, ENC_NA, &rplen);
4326 if (rplen > TDS_RPLEN) {
4327 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_length,
4328 "Invalid %s length (%d)", "remote password field", rplen);
4329 rplen = TDS_RPLEN;
4332 cur = 0;
4333 while (cur < rplen) {
4334 length_item = proto_tree_add_item_ret_uint(rempw_tree, hf_tdslogin_rempw_servername_length, tvb,
4335 offset + cur, 1, ENC_NA, &server_len);
4336 if (server_len > (rplen - cur) - 1) {
4337 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_length,
4338 "Invalid %s length (%d)", "remote password servername", server_len);
4339 server_len = (rplen - cur) - 1;
4341 if (server_len > 0) {
4342 proto_tree_add_item(rempw_tree, hf_tdslogin_rempw_servername, tvb,
4343 offset + cur + 1, server_len, ENC_ASCII);
4345 length_item = proto_tree_add_item_ret_uint(rempw_tree, hf_tdslogin_rempw_password_length, tvb,
4346 offset + cur + 1 + server_len, 1, ENC_NA, &password_len);
4347 if (password_len > (rplen - cur) - 1 - server_len - 1) {
4348 expert_add_info_format(pinfo, length_item, &ei_tds_invalid_length,
4349 "Invalid %s length (%d)", "remote password password", password_len);
4350 password_len = (rplen - cur) - 1 - server_len - 1;
4352 if (password_len > 0) {
4353 proto_tree_add_item(rempw_tree, hf_tdslogin_rempw_password, tvb,
4354 offset + cur + 1 + server_len + 1, password_len, ENC_ASCII);
4356 cur += (1 + server_len + 1 + password_len);
4359 return offset + (TDS_RPLEN + 1);
4362 static void
4363 dissect_tds45_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
4365 unsigned offset, len;
4367 proto_item *login_item;
4368 proto_tree *login_tree, *login_options_tree, *login_options2_tree;
4369 unsigned lval;
4370 uint32_t tds_version;
4372 /* create display subtree for the protocol */
4373 offset = 0;
4374 len = tvb_reported_length(tvb);
4375 login_item = proto_tree_add_item(tree, hf_tdslogin, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA);
4376 login_tree = proto_item_add_subtree(login_item, ett_tds_login);
4377 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4378 hf_tdslogin_hostname, hf_tdslogin_hostname_length,
4379 offset, TDS_MAXNAME, "hostname");
4381 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4382 hf_tdslogin_username, hf_tdslogin_username_length,
4383 offset, TDS_MAXNAME, "username");
4385 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4386 hf_tdslogin_password, hf_tdslogin_password_length,
4387 offset, TDS_MAXNAME, "password");
4389 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4390 hf_tdslogin_hostprocess, hf_tdslogin_hostprocess_length,
4391 offset, TDS_MAXNAME, "host process id");
4393 login_options_tree = proto_tree_add_subtree(login_tree, tvb, offset, 9,
4394 ett_tds_login_options, NULL, "Login Options");
4396 tds_info->tds_encoding_int2 = tvb_get_uint8(tvb, offset);
4397 proto_tree_add_uint(login_options_tree, hf_tdslogin_option_int2, tvb, offset, 1,
4398 tds_info->tds_encoding_int2 );
4399 offset++;
4400 tds_info->tds_encoding_int4 = tvb_get_uint8(tvb, offset);
4401 proto_tree_add_uint(login_options_tree, hf_tdslogin_option_int4, tvb, offset, 1,
4402 tds_info->tds_encoding_int2);
4403 offset++;
4404 tds_info->tds_encoding_char = tvb_get_uint8(tvb, offset);
4405 proto_tree_add_uint(login_options_tree, hf_tdslogin_option_char, tvb, offset, 1,
4406 tds_info->tds_encoding_char);
4407 offset++;
4408 proto_tree_add_item(login_options_tree, hf_tdslogin_option_float, tvb, offset, 1, ENC_NA);
4409 offset++;
4410 proto_tree_add_item_ret_uint(login_options_tree, hf_tdslogin_option_date8, tvb,
4411 offset, 1, ENC_NA, &tds_info->tds_encoding_date8);
4412 offset++;
4413 proto_tree_add_item(login_options_tree, hf_tdslogin_option_usedb, tvb, offset, 1, ENC_NA);
4414 offset++;
4415 proto_tree_add_item(login_options_tree, hf_tdslogin_option_bulk, tvb, offset, 1, ENC_NA);
4416 offset++;
4417 lval = tvb_get_uint8(tvb, offset);
4418 proto_tree_add_uint(login_options_tree, hf_tdslogin_option_server_to_server, tvb, offset, 1, lval & 0x7f);
4419 proto_tree_add_boolean(login_options_tree, hf_tdslogin_option_server_to_server_loginack, tvb, offset, 1, lval);
4420 offset++;
4421 proto_tree_add_item(login_options_tree, hf_tdslogin_option_conversation_type, tvb, offset, 1, ENC_NA);
4422 offset++;
4423 /* TDS 4 packet size */
4424 offset += 4;
4425 /* Spare */
4426 offset += 3;
4428 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4429 hf_tdslogin_appname, hf_tdslogin_appname_length,
4430 offset, TDS_MAXNAME, "appname");
4432 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4433 hf_tdslogin_servername, hf_tdslogin_servername_length,
4434 offset, TDS_MAXNAME, "server name");
4436 offset = dissect_tds45_remotepassword(tvb, pinfo, login_tree, offset);
4438 proto_tree_add_item_ret_uint(login_tree, hf_tdslogin_proto_version, tvb,
4439 offset, 4, ENC_BIG_ENDIAN,
4440 &tds_version);
4441 offset += 4;
4442 set_tds_version(pinfo, tds_info, tds_version);
4443 proto_item_set_text(login_item, (tds_version == TDS_PROTOCOL_5 ? "TDS 5 Login Packet" : "TDS 4 Login Packet"));
4445 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4446 hf_tdslogin_progname, hf_tdslogin_progname_length,
4447 offset, TDS_PROGNLEN, "program name");
4449 proto_tree_add_item(login_tree, hf_tdslogin_progvers, tvb, offset, 4, ENC_BIG_ENDIAN);
4450 offset += 4;
4452 login_options2_tree = proto_tree_add_subtree(login_tree, tvb, offset, 3, ett_tds_login_options2, NULL, "Login Options 2");
4454 proto_tree_add_item(login_options2_tree, hf_tdslogin_option2_noshort, tvb, offset, 1, ENC_NA);
4455 offset++;
4456 proto_tree_add_item(login_options2_tree, hf_tdslogin_option2_flt4, tvb, offset, 1, ENC_NA );
4457 offset++;
4458 proto_tree_add_item_ret_uint(login_options2_tree, hf_tdslogin_option2_date4,
4459 tvb, offset, 1, ENC_NA, &tds_info->tds_encoding_date4);
4460 offset++;
4462 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4463 hf_tdslogin_language, hf_tdslogin_language_length,
4464 offset, TDS_MAXNAME, "language");
4466 proto_tree_add_item(login_tree, hf_tdslogin_setlang, tvb, offset, 1, ENC_NA);
4467 offset++;
4469 /* Two bytes of oldsecure unused, must be zero. */
4470 offset += 2;
4472 proto_tree_add_item(login_tree, hf_tdslogin_seclogin, tvb, offset, 1, ENC_NA);
4473 offset++;
4474 proto_tree_add_item(login_tree, hf_tdslogin_secbulk, tvb, offset, 1, ENC_NA);
4475 offset++;
4476 proto_tree_add_item(login_tree, hf_tdslogin_halogin, tvb, offset, 1, ENC_NA);
4477 offset++;
4479 proto_tree_add_item(login_tree, hf_tdslogin_hasessionid, tvb, offset, 6, ENC_NA);
4480 offset += 6;
4482 /* secspare */
4483 offset += 2;
4485 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4486 hf_tdslogin_charset, hf_tdslogin_charset_length,
4487 offset, TDS_MAXNAME, "charset");
4489 proto_tree_add_item(login_tree, hf_tdslogin_setcharset, tvb, offset, 1, ENC_NA);
4490 offset++;
4492 offset = dissect_tds45_login_name(tvb, pinfo, login_tree,
4493 hf_tdslogin_packetsize, hf_tdslogin_packetsize_length,
4494 offset, TDS_PKTLEN, "packetsize");
4495 /* Unused */
4496 offset += 4;
4498 if (len > offset) {
4499 /* Check for capabilities token */
4500 if (tvb_get_uint8(tvb, offset) == TDS_CAPABILITY_TOKEN) {
4501 proto_item *token_item;
4502 proto_tree *token_tree;
4503 token_item = proto_tree_add_item(login_tree, hf_tds_capability, tvb, offset,
4504 tvb_reported_length_remaining(tvb, offset), ENC_NA);
4505 token_tree = proto_item_add_subtree(token_item, ett_tds_token);
4507 dissect_tds5_capability_token(tvb, pinfo, offset + 1, token_tree, tds_info);
4513 static void
4514 dissect_tds7_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
4516 unsigned offset, i, j, k, offset2, len, login_hf = 0;
4517 proto_tree *login_tree;
4518 proto_tree *header_tree;
4519 proto_tree *length_tree;
4521 struct tds7_login_packet_hdr td7hdr;
4522 int length_remaining;
4524 /* create display subtree for the protocol */
4525 offset = 0;
4526 login_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tds7_login, NULL, "TDS7 Login Packet");
4527 header_tree = proto_tree_add_subtree(login_tree, tvb, offset, 36, ett_tds7_hdr, NULL, "Login Packet Header");
4529 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));
4530 offset += (int)sizeof(td7hdr.total_packet_size);
4532 proto_tree_add_item_ret_uint(header_tree, hf_tds7login_version, tvb, offset, sizeof(td7hdr.tds_version), ENC_LITTLE_ENDIAN, &(td7hdr.tds_version));
4533 set_tds_version(pinfo, tds_info, td7hdr.tds_version);
4534 offset += (int)sizeof(td7hdr.tds_version);
4536 proto_tree_add_item_ret_uint(header_tree, hf_tds7login_packet_size, tvb, offset, sizeof(td7hdr.packet_size), ENC_LITTLE_ENDIAN, &(td7hdr.packet_size));
4537 offset += (int)sizeof(td7hdr.packet_size);
4539 proto_tree_add_item_ret_uint(header_tree, hf_tds7login_client_version, tvb, offset, sizeof(td7hdr.client_version), ENC_BIG_ENDIAN, &(td7hdr.client_version));
4540 offset += (int)sizeof(td7hdr.client_version);
4542 proto_tree_add_item_ret_uint(header_tree, hf_tds7login_client_pid, tvb, offset, sizeof(td7hdr.client_pid), ENC_LITTLE_ENDIAN, &(td7hdr.client_pid));
4543 offset += (int)sizeof(td7hdr.client_pid);
4545 proto_tree_add_item_ret_uint(header_tree, hf_tds7login_connection_id, tvb, offset, sizeof(td7hdr.connection_id), ENC_LITTLE_ENDIAN, &(td7hdr.connection_id));
4546 offset += (int)sizeof(td7hdr.connection_id);
4548 td7hdr.option_flags1 = tvb_get_uint8(tvb, offset);
4549 proto_tree_add_uint(header_tree, hf_tds7login_option_flags1, tvb, offset, sizeof(td7hdr.option_flags1), td7hdr.option_flags1);
4550 offset += (int)sizeof(td7hdr.option_flags1);
4552 td7hdr.option_flags2 = tvb_get_uint8(tvb, offset);
4553 proto_tree_add_uint(header_tree, hf_tds7login_option_flags2, tvb, offset, sizeof(td7hdr.option_flags2), td7hdr.option_flags2);
4554 offset += (int)sizeof(td7hdr.option_flags2);
4556 td7hdr.sql_type_flags = tvb_get_uint8(tvb, offset);
4557 proto_tree_add_uint(header_tree, hf_tds7login_sql_type_flags, tvb, offset, sizeof(td7hdr.sql_type_flags), td7hdr.sql_type_flags);
4558 offset += (int)sizeof(td7hdr.sql_type_flags);
4560 td7hdr.reserved_flags = tvb_get_uint8(tvb, offset);
4561 proto_tree_add_uint(header_tree, hf_tds7login_reserved_flags, tvb, offset, sizeof(td7hdr.reserved_flags), td7hdr.reserved_flags);
4562 offset += (int)sizeof(td7hdr.reserved_flags);
4564 proto_tree_add_item_ret_uint(header_tree, hf_tds7login_time_zone, tvb, offset, sizeof(td7hdr.time_zone), ENC_LITTLE_ENDIAN, &(td7hdr.time_zone));
4565 offset += (int)sizeof(td7hdr.time_zone);
4567 proto_tree_add_item_ret_uint(header_tree, hf_tds7login_collation, tvb, offset, sizeof(td7hdr.collation), ENC_LITTLE_ENDIAN, &(td7hdr.collation));
4568 offset += (int)sizeof(td7hdr.collation);
4570 length_tree = proto_tree_add_subtree(login_tree, tvb, offset, 50, ett_tds7_hdr, NULL, "Lengths and offsets");
4572 for (i = 0; i < 9; i++) {
4573 offset2 = tvb_get_letohs(tvb, offset + i*4);
4574 len = tvb_get_letohs(tvb, offset + i*4 + 2);
4575 proto_tree_add_uint_format(length_tree, hf_tds7login_offset, tvb, offset + i*4, 2,
4576 offset2, "%s offset: %u",
4577 val_to_str_const(i, login_field_names, "Unknown"),
4578 offset2);
4579 proto_tree_add_uint_format(length_tree, hf_tds7login_length, tvb, offset + i*4 + 2, 2,
4580 len, "%s length: %u",
4581 val_to_str_const(i, login_field_names, "Unknown"),
4582 len);
4584 switch(i) {
4585 case 0:
4586 login_hf = hf_tds7login_clientname;
4587 break;
4588 case 1:
4589 login_hf = hf_tds7login_username;
4590 break;
4591 case 2:
4592 login_hf = hf_tds7login_password;
4593 break;
4594 case 3:
4595 login_hf = hf_tds7login_appname;
4596 break;
4597 case 4:
4598 login_hf = hf_tds7login_servername;
4599 break;
4600 case 6:
4601 login_hf = hf_tds7login_libraryname;
4602 break;
4603 case 7:
4604 login_hf = hf_tds7login_locale;
4605 break;
4606 case 8:
4607 login_hf = hf_tds7login_databasename;
4608 break;
4611 if (len != 0) {
4612 if( i != 2) {
4613 /* tds 7 is always unicode */
4614 len *= 2;
4615 proto_tree_add_item(login_tree, login_hf, tvb, offset2, len,
4616 ENC_UTF_16|ENC_LITTLE_ENDIAN);
4617 } else {
4618 /* This field is the password. It is an obfusticated Unicode
4619 * string. This code assumes that the password is composed of
4620 * the 8-bit subset of UCS-16. Retrieve it from the packet
4621 * as a non-unicode string and then perform two operations on it
4622 * to "decrypt" it. Finally, we create a new string that consists
4623 * of ASCII characters instead of unicode by skipping every other
4624 * byte in the original string.
4626 * Optionally, we could make an expert item to warn of non-ASCII
4627 * characters in the string.
4630 unsigned char *val;
4631 wmem_strbuf_t *val2;
4632 len *= 2;
4633 val = tvb_memdup(wmem_packet_scope(), tvb, offset2, len);
4634 val2 = wmem_strbuf_new_sized(wmem_packet_scope(), len/2+1);
4636 for(j = 0, k = 0; j < len; j += 2, k++) {
4637 val[j] ^= 0xA5;
4639 /* Swap the most and least significant bits */
4640 val[j] = ((val[j] & 0x0F) << 4) | ((val[j] & 0xF0) >> 4);
4642 if (val[j] <= 0x7f)
4643 wmem_strbuf_append_c(val2, val[j]); /* ASCII */
4644 else
4645 wmem_strbuf_append_unichar_repl(val2);
4648 proto_tree_add_string(login_tree, login_hf, tvb, offset2, len,
4649 wmem_strbuf_get_str(val2));
4655 * XXX - what about the client MAC address, etc.?
4657 length_remaining = tvb_reported_length_remaining(tvb, offset2 + len);
4658 if (length_remaining > 0) {
4659 dissect_tds_nt(tvb, pinfo, login_tree, offset2 + len);
4663 static uint8_t variant_propbytes(uint8_t type)
4665 switch (type)
4667 /* FIXEDLENTYPE */
4668 case TDS_DATA_TYPE_BIT: return 0;
4669 case TDS_DATA_TYPE_INT1: return 0;
4670 case TDS_DATA_TYPE_INT2: return 0;
4671 case TDS_DATA_TYPE_INT4: return 0;
4672 case TDS_DATA_TYPE_INT8: return 0;
4673 case TDS_DATA_TYPE_DATETIME: return 0;
4674 case TDS_DATA_TYPE_DATETIME4: return 0;
4675 case TDS_DATA_TYPE_FLT4: return 0;
4676 case TDS_DATA_TYPE_FLT8: return 0;
4677 case TDS_DATA_TYPE_MONEY: return 0;
4678 case TDS_DATA_TYPE_MONEY4: return 0;
4680 /* BYTELEN_TYPE */
4681 case TDS_DATA_TYPE_DATEN: return 0;
4682 case TDS_DATA_TYPE_GUID: return 0;
4683 case TDS_DATA_TYPE_TIMEN: return 1;
4684 case TDS_DATA_TYPE_DATETIME2N: return 1;
4685 case TDS_DATA_TYPE_DATETIMEOFFSETN: return 1;
4686 case TDS_DATA_TYPE_DECIMALN: return 2;
4687 case TDS_DATA_TYPE_NUMERICN: return 2;
4689 /* USHORTLEN_TYPE */
4690 case TDS_DATA_TYPE_BIGVARBIN: return 2;
4691 case TDS_DATA_TYPE_BIGVARCHR: return 7;
4692 case TDS_DATA_TYPE_BIGBINARY: return 2;
4693 case TDS_DATA_TYPE_BIGCHAR: return 7;
4694 case TDS_DATA_TYPE_NVARCHAR: return 7;
4695 case TDS_DATA_TYPE_NCHAR: return 7;
4697 default: return 0;
4701 static void
4702 dissect_tds_type_info_minimal(uint8_t data_type, unsigned size, bool *plp)
4704 *plp = false; /* most types are not Partially Length-Prefixed */
4706 /* optional TYPE_VARLEN for variable length types */
4707 switch(data_type) {
4708 /* USHORTLEN_TYPE */
4709 case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
4710 case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
4711 case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
4712 /* A type with unlimited max size, known as varchar(max), varbinary(max) and nvarchar(max),
4713 which has a max size of 0xFFFF, defined by PARTLENTYPE. This class of types was introduced in TDS 7.2. */
4714 if(size == 0xFFFF)
4715 *plp = true;
4716 break;
4717 /* LONGLEN_TYPE */
4718 case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
4719 case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
4720 *plp = true;
4721 break;
4726 * Process TDS 4 "COL_NAME" token and store relevant information in the
4727 * _netlib_data structure for later use (see tds_get_row_size)
4730 static unsigned
4731 dissect_tds_col_name_token(proto_tree *tree, tvbuff_t *tvb, unsigned offset, tds_conv_info_t *tds_info,
4732 struct _netlib_data *nl_data)
4734 unsigned next, cur, col=0;
4735 uint32_t len;
4737 proto_tree_add_item_ret_uint(tree, hf_tds_colname_length, tvb, offset, 2,
4738 tds_get_int2_encoding(tds_info), &len);
4739 cur = offset + 2;
4740 next = cur + len;
4742 while (cur < next) {
4743 proto_item *col_item;
4744 proto_tree *col_tree;
4745 const uint8_t *colname;
4747 if (col >= TDS_MAX_COLUMNS) {
4748 nl_data->num_cols = TDS_MAX_COLUMNS;
4749 return 0;
4752 col_item = proto_tree_add_item(tree, hf_tds_colname_column, tvb, cur, 0, ENC_NA);
4753 col_tree = proto_item_add_subtree(col_item, ett_tds_col);
4755 if (!(nl_data->columns[col])) {
4756 nl_data->columns[col] = wmem_new0(wmem_packet_scope(), struct _tds_col);
4758 proto_tree_add_item_ret_string_and_length(col_tree, hf_tds_colname_name,
4759 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
4760 wmem_packet_scope(), &colname, &len);
4762 nl_data->columns[col]->name = (const char*)colname;
4764 if (len > 1) {
4765 proto_item_set_text(col_item, "Column %d (%s)", col + 1, colname);
4767 else {
4768 proto_item_set_text(col_item, "Column %d", col + 1);
4770 proto_item_set_len(col_item, len);
4772 col++;
4773 cur += len;
4776 nl_data->num_cols = col;
4777 return cur - offset;
4781 * Process TDS 4 "COLFMT" token and store relevant information in the
4782 * _netlib_data structure for later use (see tds_get_row_size)
4785 static unsigned
4786 dissect_tds_colfmt_token(proto_tree *tree, tvbuff_t *tvb, unsigned offset, tds_conv_info_t *tds_info,
4787 struct _netlib_data *nl_data)
4789 unsigned next, cur;
4790 unsigned col = 0, len;
4792 proto_tree_add_item_ret_uint(tree, hf_tds_colfmt_length, tvb, offset, 2,
4793 tds_get_int2_encoding(tds_info), &len);
4794 cur = offset + 2;
4795 next = cur + len;
4797 while (cur < next) {
4798 proto_item *col_item;
4799 proto_tree *col_tree;
4800 unsigned colstart = cur;
4801 bool first = true;
4803 if (col >= TDS_MAX_COLUMNS) {
4804 nl_data->num_cols = TDS_MAX_COLUMNS;
4805 return 0;
4808 col_item = proto_tree_add_item(tree, hf_tds_colfmt_column, tvb, cur, 0, ENC_NA);
4809 col_tree = proto_item_add_subtree(col_item, ett_tds_col);
4811 proto_item_set_text(col_item, "Column %d", col + 1);
4813 if (!(nl_data->columns[col])) {
4814 nl_data->columns[col] = wmem_new0(wmem_packet_scope(), struct _tds_col);
4816 else {
4817 if (nl_data->columns[col]->name) {
4818 proto_item_append_text(col_item, " (%s", nl_data->columns[col]->name);
4819 first = false;
4822 /* This only is correct for Sybase.
4823 * MS says that it's a 2-byte user type and a 2-byte flag field.
4824 * I don't know exactly how MSSQL is distinguished. */
4825 nl_data->columns[col]->utype = tvb_get_uint32(tvb, cur,
4826 tds_get_int4_encoding(tds_info));
4827 proto_tree_add_item(col_tree, hf_tds_colfmt_utype, tvb, cur, 4,
4828 tds_get_int4_encoding(tds_info));
4829 cur += 4;
4831 nl_data->columns[col]->ctype = tvb_get_uint8(tvb,cur);
4832 proto_tree_add_item(col_tree, hf_tds_colfmt_ctype, tvb, cur, 1, ENC_NA);
4833 cur++;
4835 if (first) {
4836 proto_item_append_text(col_item, " (%s)",
4837 val_to_str_const(nl_data->columns[col]->ctype,
4838 tds_data_type_names, "Unknown type"));
4840 else {
4841 proto_item_append_text(col_item, ", %s)",
4842 val_to_str_const(nl_data->columns[col]->ctype,
4843 tds_data_type_names, "Unknown type"));
4846 if (!is_fixedlen_type_tds(nl_data->columns[col]->ctype)) {
4847 if (is_image_type_tds(nl_data->columns[col]->ctype)) {
4848 int tnamelen;
4849 proto_tree_add_item_ret_uint(col_tree, hf_tds_colfmt_csize_long, tvb, cur, 4,
4850 tds_get_int4_encoding(tds_info),
4851 &nl_data->columns[col]->csize);
4852 cur += 4;
4853 proto_tree_add_item_ret_length(col_tree, hf_tds_colfmt_text_tablename,
4854 tvb, cur, 2,
4855 tds_get_char_encoding(tds_info)|tds_get_int2_encoding(tds_info),
4856 &tnamelen);
4857 cur += tnamelen;
4860 else {
4861 nl_data->columns[col]->csize = tvb_get_uint8(tvb,cur);
4862 proto_tree_add_item(col_tree, hf_tds_colfmt_csize, tvb, cur, 1, ENC_NA);
4863 cur += 1;
4865 } else {
4866 nl_data->columns[col]->csize =
4867 get_size_by_coltype(nl_data->columns[col]->ctype);
4870 proto_item_set_len(col_item, cur - colstart);
4872 col += 1;
4874 } /* while */
4876 nl_data->num_cols = col;
4877 return cur - offset;
4881 * Process TDS 5 "ROWFMT" token and store relevant information in the
4882 * _netlib_data structure for later use (see tds_get_row_size)
4885 static unsigned
4886 dissect_tds_rowfmt_token(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
4887 unsigned offset, tds_conv_info_t *tds_info, struct _netlib_data *nl_data)
4889 unsigned next, cur;
4890 unsigned col, len, numcols;
4891 tds_cursor_info_t *packet_cursor =
4892 (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
4894 proto_tree_add_item_ret_uint(tree, hf_tds_rowfmt_length, tvb, offset, 2,
4895 tds_get_int4_encoding(tds_info), &len);
4896 proto_tree_add_item_ret_uint(tree, hf_tds_rowfmt_numcols, tvb, offset + 2, 2,
4897 tds_get_int2_encoding(tds_info), &numcols);
4898 next = offset + len + 2; /* Only skip the length field. */
4899 cur = offset + 4; /* Skip the length and numcols field. */
4901 col = 0;
4902 while (cur < next) {
4903 proto_item *col_item;
4904 proto_tree *col_tree;
4905 unsigned colstart = cur;
4906 bool first = true;
4907 int colnamelen;
4908 int localelen;
4909 const uint8_t *colname = NULL;
4911 if (col >= TDS_MAX_COLUMNS) {
4912 nl_data->num_cols = TDS_MAX_COLUMNS;
4913 return 0;
4916 col_tree = proto_tree_add_subtree_format(tree, tvb, cur, 0,
4917 ett_tds_col, &col_item,
4918 "Column %d", col + 1);
4920 if (!(nl_data->columns[col])) {
4921 nl_data->columns[col] = wmem_new0(wmem_packet_scope(), struct _tds_col);
4924 proto_tree_add_item_ret_string_and_length(col_tree, hf_tds_rowfmt_colname,
4925 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
4926 wmem_packet_scope(), &colname, &colnamelen);
4928 if (colnamelen > 1) {
4929 proto_item_append_text(col_item, " (%s", colname);
4930 first = false;
4932 cur += colnamelen;
4934 proto_tree_add_item(col_tree, hf_tds_rowfmt_status, tvb, cur, 1, ENC_NA);
4935 cur += 1;
4937 nl_data->columns[col]->utype = tvb_get_uint32(tvb, cur,
4938 tds_get_int4_encoding(tds_info));
4939 proto_tree_add_item(col_tree, hf_tds_rowfmt_utype, tvb, cur, 4,
4940 tds_get_int4_encoding(tds_info));
4941 cur += 4;
4943 nl_data->columns[col]->ctype = tvb_get_uint8(tvb,cur);
4944 proto_tree_add_item(col_tree, hf_tds_rowfmt_ctype, tvb, cur, 1, ENC_NA);
4945 cur++;
4947 if (first) {
4948 proto_item_append_text(col_item, " (%s)",
4949 val_to_str_const(nl_data->columns[col]->ctype,
4950 tds_data_type_names, "Unknown type"));
4952 else {
4953 proto_item_append_text(col_item, ", %s)",
4954 val_to_str_const(nl_data->columns[col]->ctype,
4955 tds_data_type_names, "Unknown type"));
4958 if (!is_fixedlen_type_tds(nl_data->columns[col]->ctype)) {
4959 if (is_image_type_tds(nl_data->columns[col]->ctype)) {
4960 int tnamelen;
4961 proto_tree_add_item_ret_uint(col_tree, hf_tds_rowfmt_csize, tvb, cur, 4,
4962 tds_get_int4_encoding(tds_info),
4963 &nl_data->columns[col]->csize);
4964 cur += 4;
4965 proto_tree_add_item_ret_length(col_tree, hf_tds_rowfmt_text_tablename,
4966 tvb, cur, 2,
4967 tds_get_char_encoding(tds_info)|tds_get_int2_encoding(tds_info),
4968 &tnamelen);
4969 cur += tnamelen;
4971 else if (is_longlen_type_sybase(nl_data->columns[col]->ctype)) {
4972 proto_tree_add_item_ret_uint(col_tree, hf_tds_rowfmt_csize, tvb, cur, 4,
4973 tds_get_int4_encoding(tds_info),
4974 &nl_data->columns[col]->csize);
4975 cur += 4;
4977 else {
4978 nl_data->columns[col]->csize = tvb_get_uint8(tvb,cur);
4979 proto_tree_add_item(col_tree, hf_tds_rowfmt_csize, tvb, cur, 1, ENC_NA);
4980 cur ++;
4982 } else {
4983 nl_data->columns[col]->csize =
4984 get_size_by_coltype(nl_data->columns[col]->ctype);
4987 if (is_numeric_type_tds(nl_data->columns[col]->ctype)) {
4988 unsigned col_precision, col_scale;
4989 proto_tree_add_item_ret_uint(col_tree, hf_tds_rowfmt_precision,
4990 tvb, cur, 1, ENC_NA, &col_precision);
4991 proto_tree_add_item_ret_uint(col_tree, hf_tds_rowfmt_scale,
4992 tvb, cur + 1, 1, ENC_NA, &col_scale);
4993 nl_data->columns[col]->precision = col_precision;
4994 nl_data->columns[col]->scale = col_scale;
4995 cur += 2;
4998 proto_tree_add_item_ret_length(col_tree, hf_tds_rowfmt_locale_info,
4999 tvb, cur, 1, ENC_NA, &localelen);
5000 cur += localelen;
5002 proto_item_set_len(col_item, cur - colstart);
5004 col += 1;
5006 } /* while */
5008 nl_data->num_cols = col;
5011 * If there is a packet cursor, we need to copy the struct _netlib_data into it
5012 * for use by later packets referencing the same cursor.
5015 if (packet_cursor && !(packet_cursor->tds_cursor_flags & TDS_CURSOR_ROWINFO_VALID)) {
5016 packet_cursor->tds_cursor_rowinfo = copy_nl_data(wmem_file_scope(), nl_data);
5017 packet_cursor->tds_cursor_flags |= TDS_CURSOR_ROWINFO_VALID;
5020 return cur - offset;
5024 * Process TDS 5 "ROWFMT2" token and store relevant information in the
5025 * _netlib_data structure for later use (see tds_get_row_size)
5028 static unsigned
5029 dissect_tds_rowfmt2_token(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
5030 unsigned offset, tds_conv_info_t *tds_info, struct _netlib_data *nl_data)
5032 unsigned next, cur;
5033 unsigned col, len, numcols;
5034 tds_cursor_info_t *packet_cursor =
5035 (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
5037 proto_tree_add_item_ret_uint(tree, hf_tds_rowfmt2_length, tvb, offset, 4,
5038 tds_get_int4_encoding(tds_info), &len);
5039 proto_tree_add_item_ret_uint(tree, hf_tds_rowfmt2_numcols, tvb, offset + 4, 2,
5040 tds_get_int2_encoding(tds_info), &numcols);
5041 next = offset + len + 4; /* Only skip the length field. */
5042 cur = offset + 6; /* Skip the length and numcols field. */
5044 col = 0;
5045 while (cur < next) {
5046 proto_item *col_item;
5047 proto_tree *col_tree;
5048 unsigned colstart = cur;
5049 unsigned ctype;
5050 int labelnamelen, catalognamelen, schemanamelen, tablenamelen, colnamelen, localelen;
5051 const uint8_t *labelname = NULL, *catalogname = (const uint8_t * )"", *schemaname = (const uint8_t * )"",
5052 *tablename = (const uint8_t*)"", *colname = (const uint8_t*)"";
5053 const char *name;
5055 if (col >= TDS_MAX_COLUMNS) {
5056 nl_data->num_cols = TDS_MAX_COLUMNS;
5057 return 0;
5060 col_tree = proto_tree_add_subtree_format(tree, tvb, cur, 0,
5061 ett_tds_col, &col_item,
5062 "Column %d", col + 1);
5064 if (!(nl_data->columns[col])) {
5065 nl_data->columns[col] = wmem_new0(wmem_packet_scope(), struct _tds_col);
5067 proto_tree_add_item_ret_string_and_length(col_tree, hf_tds_rowfmt2_labelname,
5068 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
5069 wmem_packet_scope(), &labelname, &labelnamelen);
5070 cur += labelnamelen;
5072 proto_tree_add_item_ret_string_and_length(col_tree, hf_tds_rowfmt2_catalogname,
5073 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
5074 wmem_packet_scope(), &catalogname, &catalognamelen);
5075 cur += catalognamelen;
5077 proto_tree_add_item_ret_string_and_length(col_tree, hf_tds_rowfmt2_schemaname,
5078 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
5079 wmem_packet_scope(), &schemaname, &schemanamelen);
5080 cur += schemanamelen;
5082 proto_tree_add_item_ret_string_and_length(col_tree, hf_tds_rowfmt2_tablename,
5083 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
5084 wmem_packet_scope(), &tablename, &tablenamelen);
5085 cur += tablenamelen;
5087 proto_tree_add_item_ret_string_and_length(col_tree, hf_tds_rowfmt2_colname,
5088 tvb, cur, 1, tds_get_char_encoding(tds_info)|ENC_NA,
5089 wmem_packet_scope(), &colname, &colnamelen);
5090 cur += colnamelen;
5092 if (catalognamelen > 1) {
5093 name = wmem_strjoin(wmem_packet_scope(), ".",
5094 catalogname, schemaname, tablename, (const char*)colname, NULL);
5096 else if (schemanamelen > 1) {
5097 name = wmem_strjoin(wmem_packet_scope(), ".",
5098 schemaname, tablename, (const char*)colname, NULL);
5100 else if (tablenamelen > 1) {
5101 name = wmem_strjoin(wmem_packet_scope(), ".",
5102 tablename, (const char*)colname, NULL);
5104 else {
5105 name = (const char*)colname;
5108 if (labelnamelen > 1) {
5109 if (strlen(name) > 0) {
5110 name = wmem_strjoin(wmem_packet_scope(), " AS ",
5111 name, (const char*)labelname, NULL);
5113 else {
5114 name = (const char*)labelname;
5118 nl_data->columns[col]->name = name;
5120 proto_tree_add_item(col_tree, hf_tds_rowfmt2_status, tvb, cur, 4, tds_get_int4_encoding(tds_info));
5121 cur += 4;
5123 nl_data->columns[col]->utype = tvb_get_uint32(tvb, cur,
5124 tds_get_int4_encoding(tds_info));
5125 proto_tree_add_item(col_tree, hf_tds_rowfmt2_utype, tvb, cur, 4,
5126 tds_get_int4_encoding(tds_info));
5127 cur += 4;
5129 proto_tree_add_item_ret_uint(col_tree, hf_tds_rowfmt2_ctype, tvb, cur, 1, ENC_NA, &ctype);
5130 cur++;
5132 nl_data->columns[col]->ctype = ctype;
5134 if (!is_fixedlen_type_tds(ctype)) {
5135 if (is_image_type_tds(ctype)) {
5136 int tnamelen;
5137 proto_tree_add_item_ret_uint(col_tree, hf_tds_rowfmt2_csize, tvb, cur, 4,
5138 tds_get_int4_encoding(tds_info),
5139 &nl_data->columns[col]->csize);
5140 cur += 4;
5141 proto_tree_add_item_ret_length(col_tree, hf_tds_rowfmt2_text_tablename,
5142 tvb, cur, 2,
5143 tds_get_char_encoding(tds_info)|tds_get_int2_encoding(tds_info),
5144 &tnamelen);
5145 cur += tnamelen;
5147 else if (is_longlen_type_sybase(ctype)) {
5148 proto_tree_add_item_ret_uint(col_tree, hf_tds_rowfmt2_csize, tvb, cur, 4,
5149 tds_get_int4_encoding(tds_info),
5150 &nl_data->columns[col]->csize);
5151 cur += 4;
5153 else {
5154 nl_data->columns[col]->csize = tvb_get_uint8(tvb,cur);
5155 proto_tree_add_item(col_tree, hf_tds_rowfmt2_csize, tvb, cur, 1, ENC_NA);
5156 cur ++;
5158 } else {
5159 nl_data->columns[col]->csize = get_size_by_coltype(ctype);
5162 if (is_numeric_type_tds(nl_data->columns[col]->ctype)) {
5163 proto_tree_add_item(col_tree, hf_tds_rowfmt2_precision, tvb, cur, 1, ENC_NA);
5164 proto_tree_add_item(col_tree, hf_tds_rowfmt2_scale, tvb, cur + 1, 1, ENC_NA);
5165 cur += 2;
5168 proto_tree_add_item_ret_length(col_tree, hf_tds_rowfmt2_locale_info,
5169 tvb, cur, 1, ENC_NA, &localelen);
5170 cur += localelen;
5172 proto_item_set_len(col_item, cur - colstart);
5174 col += 1;
5176 } /* while */
5178 nl_data->num_cols = col;
5181 * If there is a packet cursor, we need to copy the struct _netlib_data into it
5182 * for use by later packets referencing the same cursor.
5185 if (packet_cursor && !(packet_cursor->tds_cursor_flags & TDS_CURSOR_ROWINFO_VALID)) {
5186 packet_cursor->tds_cursor_rowinfo = copy_nl_data(wmem_file_scope(), nl_data);
5187 packet_cursor->tds_cursor_flags |= TDS_CURSOR_ROWINFO_VALID;
5190 return cur - offset;
5194 * Process TDS "CONTROL" token and store relevant information in the
5195 * _netlib_data structure for later use (see tds_get_row_size)
5198 static unsigned
5199 dissect_tds_control_token(proto_tree *tree, tvbuff_t *tvb, unsigned offset, tds_conv_info_t *tds_info,
5200 struct _netlib_data *nl_data)
5202 unsigned next, cur, col=0;
5203 uint32_t len;
5204 cur = offset;
5206 /* TODO: fill in nl_data as necessary. */
5208 proto_tree_add_item_ret_uint(tree, hf_tds_control_length, tvb, cur, 2,
5209 tds_get_int2_encoding(tds_info), &len);
5210 cur += 2;
5212 next = cur + len;
5213 while (cur < next) {
5215 if (col >= TDS_MAX_COLUMNS) {
5216 nl_data->num_cols = TDS_MAX_COLUMNS;
5217 return 0;
5220 if (!(nl_data->columns[col])) {
5221 nl_data->columns[col] = wmem_new0(wmem_packet_scope(), struct _tds_col);
5223 proto_tree_add_item_ret_length(tree, hf_tds_control_fmt, tvb, cur, 1, ENC_NA, &len);
5225 cur += len;
5226 col += 1;
5229 return cur - offset;
5233 * If the packet type from the netlib header is a login packet, then dig into
5234 * the packet to see if this is a supported TDS version and verify the otherwise
5235 * weak heuristics of the netlib check.
5237 static bool
5238 netlib_check_login_pkt(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, uint8_t type)
5240 unsigned tds_major, bytes_avail;
5242 bytes_avail = tvb_captured_length(tvb) - offset;
5244 * we have two login packet styles, one for TDS 4.2 and 5.0
5246 if (type==TDS_LOGIN_PKT) {
5247 /* Use major version number to validate TDS 4/5 login
5248 * packet */
5250 /* Login packet is first in stream and should not be fragmented...
5251 * if it is we are screwed
5253 * Note that all of these offsets include the 8-byte netlib
5254 * header. Therefore, they are 8 bytes larger than the ones that
5255 * would be seen in dissect_tds45_login.
5257 if (bytes_avail < 467) return false;
5258 tds_major = tvb_get_uint8(tvb, 466);
5259 if (tds_major != 4 && tds_major != 5) {
5260 return false;
5264 * Ensure that the strings at the front of the login packet
5265 * have valid lengths.
5268 /* Hostname */
5269 if (tvb_get_uint8(tvb, 8 + TDS_MAXNAME) > TDS_MAXNAME)
5270 return false;
5271 /* Username */
5272 if (tvb_get_uint8(tvb, 39 + TDS_MAXNAME) > TDS_MAXNAME)
5273 return false;
5274 /* Password */
5275 if (tvb_get_uint8(tvb, 70 + TDS_MAXNAME) > TDS_MAXNAME)
5276 return false;
5277 /* Client process id */
5278 if (tvb_get_uint8(tvb, 101 + TDS_MAXNAME) > TDS_MAXNAME)
5279 return false;
5282 * and one added by Microsoft in SQL Server 7
5284 else if (type==TDS_LOGIN7_PKT) {
5285 if (bytes_avail < 16) return false;
5286 tds_major = tvb_get_uint8(tvb, 15);
5287 if (tds_major != 0x70 && tds_major != 0x80) {
5288 return false;
5290 } else if (type==TDS5_QUERY_PKT) {
5291 if (bytes_avail < 9) return false;
5292 /* if this is a TDS 5.0 query check the token */
5293 if (tvb_get_uint8(tvb, 8) != TDS_LANG_TOKEN) {
5294 return false;
5298 * See if either tcp.destport or tcp.srcport is specified
5299 * in the preferences as being a TDS port.
5301 else if (!value_is_in_range(tds_tcp_ports, pinfo->srcport) &&
5302 !value_is_in_range(tds_tcp_ports, pinfo->destport)) {
5303 return false;
5306 return true;
5309 static bool
5310 dissect_tds_prelogin_response(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5312 uint8_t token = 0;
5313 int tokenoffset, tokenlen, cur = offset;
5314 bool valid = false;
5317 * Test for prelogin format compliance
5318 * A prelogin response consists solely of "tokens" from 0 to 7, followed by
5319 * a terminator.
5322 while(tvb_reported_length_remaining(tvb, cur) > 0)
5324 token = tvb_get_uint8(tvb, cur);
5325 cur += 1;
5327 if(token == TDS7_PRELOGIN_OPTION_TERMINATOR)
5328 break;
5330 if(token <= TDS7_PRELOGIN_OPTION_NONCEOPT) {
5331 valid = true;
5333 else {
5334 valid = false;
5335 break;
5338 tokenoffset = tvb_get_ntohs(tvb, cur);
5339 if(tokenoffset > tvb_reported_length_remaining(tvb, 0)) {
5340 valid = false;
5341 break;
5343 cur += 2;
5345 tokenlen = tvb_get_ntohs(tvb, cur);
5346 if(tokenlen > tvb_reported_length_remaining(tvb, 0)) {
5347 valid = false;
5348 break;
5350 cur += 2;
5353 if(token != TDS7_PRELOGIN_OPTION_TERMINATOR) {
5354 valid = false;
5358 if(valid) {
5359 /* The prelogin response has the same form as the prelogin request. */
5360 dissect_tds7_prelogin_packet(tvb, pinfo, tree, tds_info, true);
5363 return valid;
5366 static int
5367 dissect_tds_order_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5369 unsigned cur = offset;
5370 unsigned i, length;
5372 proto_tree_add_item_ret_uint(tree, hf_tds_order_length, tvb, cur, 2,
5373 tds_get_int2_encoding(tds_info), &length);
5374 cur += 2;
5376 if (TDS_PROTO_LESS_THAN_TDS7(tds_info)) {
5377 for (i = 0; i < length; i++) {
5378 proto_tree_add_item(tree, hf_tds_order_colnum, tvb, cur, 1, ENC_NA);
5379 cur += 1;
5382 else {
5383 for (i = 0; i < length / 2; i++) {
5384 proto_tree_add_item(tree, hf_tds_order_colnum, tvb, cur, 2, ENC_LITTLE_ENDIAN);
5385 cur += 2;
5389 return cur - offset;
5392 static int
5393 dissect_tds_offset_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
5395 unsigned cur = offset;
5397 proto_tree_add_item(tree, hf_tds_offset_id, tvb, cur, 2, ENC_LITTLE_ENDIAN);
5398 proto_tree_add_item(tree, hf_tds_offset_len, tvb, cur + 2, 2, ENC_LITTLE_ENDIAN);
5399 cur += 4;
5401 return cur - offset;
5404 static int
5405 dissect_tds_row_token(tvbuff_t *tvb, packet_info *pinfo, struct _netlib_data *nl_data, unsigned offset,
5406 proto_tree *tree, tds_conv_info_t *tds_info)
5408 unsigned cur = offset, i, type;
5409 bool plp = false;
5410 tds_cursor_info_t *packet_cursor;
5412 if (!PINFO_FD_VISITED(pinfo)) {
5413 if (tds_info->tds_conv_cursor_info && tds_info->tds_conv_cursor_info->tds_conv_cursor_current) {
5414 tds_cursor_info_t *cursor_current = tds_info->tds_conv_cursor_info->tds_conv_cursor_current;
5415 p_add_proto_data(wmem_file_scope(), pinfo, proto_tds, 0,
5416 cursor_current);
5420 packet_cursor = (tds_cursor_info_t *) p_get_proto_data(wmem_file_scope(), pinfo, proto_tds, 0);
5422 if (packet_cursor && (packet_cursor->tds_cursor_flags & TDS_CURSOR_ROWINFO_VALID)) {
5423 nl_data = packet_cursor->tds_cursor_rowinfo;
5426 for (i = 0; i < nl_data->num_cols; i++) {
5427 type = nl_data->columns[i]->ctype;
5428 dissect_tds_type_info_minimal(type, nl_data->columns[i]->csize, &plp);
5430 dissect_tds_type_varbyte(tvb, &cur, pinfo, tree, hf_tds_row_field, tds_info,
5431 type, nl_data->columns[i]->scale, plp, i+1,
5432 nl_data->columns[i]->name);
5435 return cur - offset;
5438 static int
5439 dissect_tds_nbc_row_token(tvbuff_t *tvb, packet_info *pinfo, struct _netlib_data *nl_data,
5440 unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5442 unsigned relbyte, relbit, i, cur;
5443 bool plp = false;
5445 cur = offset + nl_data->num_cols/8;
5446 if((nl_data->num_cols%8) != 0) cur++;
5448 for (i = 0; i < nl_data->num_cols; i++) {
5450 relbyte = tvb_get_uint8(tvb, offset + i/8);
5451 relbit = relbyte & (1 << (i%8));
5453 if(relbit == 0)
5455 dissect_tds_type_info_minimal(nl_data->columns[i]->ctype, nl_data->columns[i]->csize, &plp);
5457 dissect_tds_type_varbyte(tvb, &cur, pinfo, tree, hf_tds_row_field, tds_info,
5458 nl_data->columns[i]->ctype, nl_data->columns[i]->scale, plp, i+1,
5459 nl_data->columns[i]->name);
5463 return cur - offset;
5466 static int
5467 dissect_tds_returnstatus_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5469 unsigned cur = offset;
5471 proto_tree_add_item(tree, hf_tds_returnstatus_value, tvb, cur, 4, tds_get_int4_encoding(tds_info));
5472 cur += 4;
5474 return cur - offset;
5478 The SSPI token returned during the login process.
5480 2.2.7.22 SSPI
5481 https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/07e2bb7b-8ba6-445f-89b1-cc76d8bfa9c6
5482 Token Stream-Specific Rules:
5483 TokenType = BYTE
5484 SSPIBuffer = US_VARBYTE
5486 Token Stream Definition:
5487 SSPI = TokenType
5488 SSPIBuffer
5490 2.2.5.2 Data Stream Types
5491 https://learn.microsoft.com/en-us/openspecs/sql_server_protocols/ms-sstds/4c628f3a-d824-4371-8201-d65c6c164d14
5492 Generic Bytes
5493 Similar to the variable-length character stream, variable-length byte streams are defined by a length
5494 field followed by the data itself.
5495 US_VARBYTE = USHORTLEN *BYTE
5497 static int
5498 dissect_tds_sspi_token(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
5500 unsigned cur = offset, len_field_val;
5501 int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
5502 uint8_t ber_class;
5503 bool pc;
5504 int32_t tag;
5506 len_field_val = tvb_get_uint16(tvb, cur, encoding);
5507 cur += 2;
5509 if (len_field_val) {
5510 tvbuff_t *nt_tvb= tvb_new_subset_remaining(tvb, cur);
5512 if(tvb_strneql(tvb, cur, "NTLMSSP", 7) == 0)
5513 call_dissector(ntlmssp_handle, nt_tvb, pinfo, tree);
5514 else {
5515 get_ber_identifier(tvb, cur, &ber_class, &pc, &tag);
5516 if (ber_class == BER_CLASS_CON && pc && (tag == 0 || tag == 1)) {
5517 call_dissector(spnego_handle, nt_tvb, pinfo, tree);
5518 } else {
5519 call_dissector(gssapi_handle, nt_tvb, pinfo, tree);
5523 cur += len_field_val;
5526 return cur - offset;
5529 static int
5530 dissect_tds_envchg_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5532 unsigned cur = offset;
5533 uint8_t env_type;
5534 unsigned new_len, old_len;
5536 proto_tree_add_item(tree, hf_tds_envchg_length, tvb, cur, 2,
5537 tds_get_int2_encoding(tds_info));
5538 cur += 2;
5540 env_type = tvb_get_uint8(tvb, cur);
5541 proto_tree_add_item(tree, hf_tds_envchg_type, tvb, cur, 1, ENC_NA);
5542 cur += 1;
5544 /* Read new value */
5545 switch(env_type)
5547 case 1:
5548 case 2:
5549 case 3:
5550 case 4:
5551 case 5:
5552 case 6:
5553 case 13:
5554 case 19:
5555 /* B_VARCHAR, Strings */
5556 proto_tree_add_item_ret_uint(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA, &new_len);
5557 cur += 1;
5558 if(new_len > 0)
5560 if (tds_char_encoding_is_two_byte(tds_info)) {
5561 new_len *= 2;
5563 proto_tree_add_item(tree, hf_tds_envchg_newvalue_string, tvb, cur, new_len,
5564 tds_get_char_encoding(tds_info));
5565 cur += new_len;
5568 break;
5570 case 7:
5571 /* parse collation info structure. From http://www.freetds.org/tds.html#collate */
5572 proto_tree_add_item_ret_uint(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA, &new_len);
5573 cur +=1;
5574 proto_tree_add_item(tree, hf_tds_envchg_collate_codepage, tvb, cur, 2, tds_get_int2_encoding(tds_info));
5575 proto_tree_add_item(tree, hf_tds_envchg_collate_flags, tvb, cur + 2, 2, tds_get_int2_encoding(tds_info));
5577 proto_tree_add_item(tree, hf_tds_envchg_collate_charset_id, tvb, cur + 4, 1, ENC_NA);
5578 cur += new_len;
5580 break;
5582 case 8:
5583 case 12:
5584 case 16:
5585 /* B_VARBYTE */
5586 proto_tree_add_item_ret_uint(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA, &new_len);
5587 cur += 1;
5588 if(new_len > 0)
5590 proto_tree_add_item(tree, hf_tds_envchg_newvalue_bytes, tvb, cur, new_len, ENC_NA);
5591 cur += new_len;
5593 break;
5595 case 9:
5596 case 10:
5597 case 11:
5598 case 17:
5599 case 18:
5600 /* %x00 */
5601 proto_tree_add_item(tree, hf_tds_envchg_newvalue_length, tvb, cur, 1, ENC_NA);
5602 cur += 1;
5603 break;
5605 case 15:
5606 /* L_VARBYTE */
5607 break;
5609 case 20:
5610 break;
5614 /* Read old value */
5615 switch(env_type)
5617 case 1:
5618 case 2:
5619 case 3:
5620 case 4:
5621 /* B_VARCHAR, Strings */
5622 proto_tree_add_item_ret_uint(tree, hf_tds_envchg_oldvalue_length, tvb, cur, 1, ENC_NA, &old_len);
5623 cur += 1;
5624 if(old_len > 0) {
5625 if (tds_char_encoding_is_two_byte(tds_info)) {
5626 old_len *= 2;
5628 proto_tree_add_item(tree, hf_tds_envchg_oldvalue_string, tvb, cur, old_len,
5629 tds_get_char_encoding(tds_info));
5630 cur += old_len;
5632 break;
5634 case 5:
5635 case 6:
5636 case 8:
5637 case 12:
5638 case 13:
5639 case 15:
5640 case 16:
5641 case 18:
5642 case 19:
5643 /* %x00 */
5644 proto_tree_add_item(tree, hf_tds_envchg_oldvalue_length, tvb, cur, 1, ENC_NA);
5645 cur += 1;
5646 break;
5648 case 7:
5649 case 9:
5650 case 10:
5651 case 11:
5652 case 17:
5653 /* B_VARBYTE */
5654 proto_tree_add_item_ret_uint(tree, hf_tds_envchg_oldvalue_length, tvb, cur, 1, ENC_NA, &old_len);
5655 cur += 1;
5656 if(old_len > 0)
5658 proto_tree_add_item(tree, hf_tds_envchg_oldvalue_bytes, tvb, cur, old_len, ENC_NA);
5659 cur += old_len;
5661 break;
5663 case 20:
5664 break;
5667 return cur - offset;
5669 static int
5670 dissect_tds_eed_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5672 unsigned cur = offset;
5673 int32_t msg_len, len;
5675 proto_tree_add_item(tree, hf_tds_eed_length, tvb, cur, 2,
5676 tds_get_int2_encoding(tds_info));
5677 cur += 2;
5679 proto_tree_add_item(tree, hf_tds_eed_number, tvb, cur, 4,
5680 tds_get_int4_encoding(tds_info));
5681 cur += 4;
5682 proto_tree_add_item(tree, hf_tds_eed_state, tvb, cur, 1, ENC_NA);
5683 cur += 1;
5684 proto_tree_add_item(tree, hf_tds_eed_class, tvb, cur, 1, ENC_NA);
5685 cur += 1;
5687 proto_tree_add_item_ret_length(tree, hf_tds_eed_sql_state, tvb, cur, 1,
5688 ENC_NA, &len);
5689 cur += len;
5691 proto_tree_add_item(tree, hf_tds_eed_status, tvb, cur, 1, ENC_NA);
5692 cur += 1;
5694 proto_tree_add_item(tree, hf_tds_eed_transtate, tvb, cur, 2,
5695 tds_get_int2_encoding(tds_info));
5696 cur += 2;
5698 proto_tree_add_item_ret_length(tree, hf_tds_eed_msgtext, tvb, cur, 2,
5699 tds_get_char_encoding(tds_info)|tds_get_int2_encoding(tds_info),
5700 &msg_len);
5701 cur += msg_len;
5703 proto_tree_add_item_ret_length(tree, hf_tds_eed_servername, tvb, cur, 1,
5704 tds_get_char_encoding(tds_info)|ENC_NA, &msg_len);
5705 cur += msg_len;
5707 proto_tree_add_item_ret_length(tree, hf_tds_eed_procname, tvb, cur, 1,
5708 tds_get_char_encoding(tds_info)|ENC_NA, &msg_len);
5709 cur += msg_len;
5711 proto_tree_add_item(tree, hf_tds_eed_linenumber, tvb, cur, 2,
5712 tds_get_int2_encoding(tds_info));
5713 cur += 2;
5715 /* TODO Handle EED follows? Maybe handled as separate tokens. */
5717 return cur - offset;
5720 static int
5721 dissect_tds_error_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5723 unsigned cur = offset;
5724 uint32_t msg_len;
5725 uint32_t srvr_len, proc_len;
5727 proto_tree_add_item(tree, hf_tds_error_length, tvb, cur, 2, tds_get_int2_encoding(tds_info));
5728 cur += 2;
5730 proto_tree_add_item(tree, hf_tds_error_number, tvb, cur, 4, tds_get_int4_encoding(tds_info));
5731 cur += 4;
5732 proto_tree_add_item(tree, hf_tds_error_state, tvb, cur, 1, ENC_NA);
5733 cur +=1;
5734 proto_tree_add_item(tree, hf_tds_error_class, tvb, cur, 1, ENC_NA);
5735 cur +=1;
5737 proto_tree_add_item_ret_uint(tree, hf_tds_error_msgtext_length, tvb, cur, 2,
5738 tds_get_int2_encoding(tds_info), &msg_len);
5739 cur +=2;
5741 if (tds_char_encoding_is_two_byte(tds_info)) {
5742 msg_len *= 2;
5744 proto_tree_add_item(tree, hf_tds_error_msgtext, tvb, cur, msg_len, tds_get_char_encoding(tds_info));
5745 cur += msg_len;
5747 proto_tree_add_item_ret_uint(tree, hf_tds_error_servername_length, tvb, cur, 1, ENC_NA, &srvr_len);
5748 cur +=1;
5749 if(srvr_len) {
5750 if (tds_char_encoding_is_two_byte(tds_info)) {
5751 srvr_len *=2;
5753 proto_tree_add_item(tree, hf_tds_error_servername, tvb, cur, srvr_len, tds_get_char_encoding(tds_info));
5754 cur += srvr_len;
5757 proto_tree_add_item_ret_uint(tree, hf_tds_error_procname_length, tvb, cur, 1, ENC_NA, &proc_len);
5758 cur +=1;
5759 if(proc_len) {
5760 if (tds_char_encoding_is_two_byte(tds_info)) {
5761 proc_len *=2;
5763 proto_tree_add_item(tree, hf_tds_error_procname, tvb, cur, proc_len, tds_get_char_encoding(tds_info));
5764 cur += proc_len;
5767 if (TDS_PROTO_TDS7_1_OR_LESS(tds_info)) {
5768 proto_tree_add_item(tree, hf_tds_error_linenumber_16, tvb, cur, 2, tds_get_int2_encoding(tds_info));
5769 cur += 2;
5770 } else {
5771 proto_tree_add_item(tree, hf_tds_error_linenumber_32, tvb, cur, 4, tds_get_int4_encoding(tds_info));
5772 cur += 4;
5775 return cur - offset;
5778 static int
5779 dissect_tds_info_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5781 unsigned cur = offset;
5782 uint32_t msg_len;
5783 uint32_t srvr_len, proc_len;
5785 proto_tree_add_item(tree, hf_tds_info_length, tvb, cur, 2, tds_get_int2_encoding(tds_info));
5786 cur += 2;
5788 proto_tree_add_item(tree, hf_tds_info_number, tvb, cur, 4, tds_get_int4_encoding(tds_info));
5789 cur += 4;
5790 proto_tree_add_item(tree, hf_tds_info_state, tvb, cur, 1, ENC_NA);
5791 cur +=1;
5792 proto_tree_add_item(tree, hf_tds_info_class, tvb, cur, 1, ENC_NA);
5793 cur +=1;
5795 proto_tree_add_item_ret_uint(tree, hf_tds_info_msgtext_length, tvb, cur, 2,
5796 tds_get_int2_encoding(tds_info), &msg_len);
5797 cur +=2;
5799 if (tds_char_encoding_is_two_byte(tds_info)) {
5800 msg_len *= 2;
5802 proto_tree_add_item(tree, hf_tds_info_msgtext, tvb, cur, msg_len, tds_get_char_encoding(tds_info));
5804 cur += msg_len;
5806 proto_tree_add_item_ret_uint(tree, hf_tds_info_servername_length, tvb, cur, 1, ENC_NA, &srvr_len);
5807 cur +=1;
5808 if(srvr_len) {
5809 if (tds_char_encoding_is_two_byte(tds_info)) {
5810 srvr_len *=2;
5812 proto_tree_add_item(tree, hf_tds_info_servername, tvb, cur, srvr_len, tds_get_char_encoding(tds_info));
5813 cur += srvr_len;
5816 proto_tree_add_item_ret_uint(tree, hf_tds_info_procname_length, tvb, cur, 1, ENC_NA, &proc_len);
5817 cur +=1;
5818 if(proc_len) {
5819 if (tds_char_encoding_is_two_byte(tds_info)) {
5820 proc_len *=2;
5822 proto_tree_add_item(tree, hf_tds_info_procname, tvb, cur, proc_len, tds_get_char_encoding(tds_info));
5823 cur += proc_len;
5826 if (TDS_PROTO_TDS7_1_OR_LESS(tds_info)) {
5827 proto_tree_add_item(tree, hf_tds_info_linenumber_16, tvb, cur, 2, tds_get_int2_encoding(tds_info));
5828 cur += 2;
5829 } else {
5830 proto_tree_add_item(tree, hf_tds_info_linenumber_32, tvb, cur, 4, tds_get_int4_encoding(tds_info));
5831 cur += 4;
5834 return cur - offset;
5837 static int
5838 dissect_tds_login_ack_token(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5840 uint8_t msg_len;
5841 uint32_t tds_version;
5842 unsigned cur = offset;
5844 proto_tree_add_item(tree, hf_tds_loginack_length, tvb, cur, 2, tds_get_int2_encoding(tds_info));
5845 cur += 2;
5847 proto_tree_add_item(tree, hf_tds_loginack_interface, tvb, cur, 1, ENC_NA);
5848 cur +=1;
5849 proto_tree_add_item_ret_uint(tree, hf_tds_loginack_tdsversion, tvb, cur, 4, ENC_BIG_ENDIAN, &tds_version);
5850 set_tds_version(pinfo, tds_info, tds_version);
5852 cur += 4;
5854 msg_len = tvb_get_uint8(tvb, cur);
5855 cur +=1;
5857 if (tds_char_encoding_is_two_byte(tds_info)) {
5858 msg_len *= 2;
5860 proto_tree_add_item(tree, hf_tds_loginack_progname, tvb, cur, msg_len,
5861 tds_get_char_encoding(tds_info));
5862 cur += msg_len;
5864 proto_tree_add_item(tree, hf_tds_loginack_progversion, tvb, cur, 4, ENC_BIG_ENDIAN);
5866 cur += 4;
5868 return cur - offset;
5871 static int
5872 dissect_tds7_colmetadata_token(tvbuff_t *tvb, struct _netlib_data *nl_data, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
5874 unsigned cur = offset;
5875 uint16_t num_columns, flags, msg_len;
5876 uint8_t type;
5877 int i, col_offset;
5878 proto_tree* col_tree, *flags_tree;
5879 proto_item* flags_item, * type_item, *col_item;
5880 int encoding = tds_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
5882 num_columns = tvb_get_letohs(tvb, cur);
5883 nl_data->num_cols = num_columns;
5884 proto_tree_add_item(tree, hf_tds_colmetadata_columns, tvb, cur, 2, ENC_LITTLE_ENDIAN);
5885 if (nl_data->num_cols > TDS_MAX_COLUMNS) {
5886 nl_data->num_cols = 0;
5887 return 2;
5889 cur +=2;
5891 for(i=0; i != num_columns; i++) {
5893 col_offset = cur;
5895 col_item = proto_tree_add_item(tree, hf_tds_colmetadata_field, tvb, cur, 0, ENC_NA);
5896 col_tree = proto_item_add_subtree(col_item, ett_tds_col);
5897 proto_item_set_text(col_item, "Column %d", i + 1);
5899 if (!(nl_data->columns[i])) {
5900 nl_data->columns[i] = wmem_new0(wmem_packet_scope(), struct _tds_col);
5903 if (TDS_PROTO_TDS7_1_OR_LESS(tds_info)) {
5904 proto_tree_add_item(col_tree, hf_tds_colmetadata_usertype16, tvb, cur, 2, ENC_LITTLE_ENDIAN);
5905 nl_data->columns[i]->utype = tvb_get_uint16(tvb, cur, encoding);
5906 cur +=2;
5907 } else {
5908 proto_tree_add_item_ret_uint(col_tree, hf_tds_colmetadata_usertype32, tvb, cur, 4, ENC_LITTLE_ENDIAN, &(nl_data->columns[i]->utype));
5909 cur +=4;
5912 flags = tvb_get_letohs(tvb, cur);
5913 flags_item = proto_tree_add_uint(col_tree, hf_tds_colmetadata_results_token_flags, tvb, cur, 2, flags);
5914 if(flags_item)
5916 flags_tree = proto_item_add_subtree(flags_item, ett_tds_flags);
5917 if(flags_tree)
5919 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_nullable, tvb, cur, 2, ENC_BIG_ENDIAN);
5920 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_casesen, tvb, cur, 2, ENC_BIG_ENDIAN);
5921 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_updateable, tvb, cur, 2, ENC_BIG_ENDIAN);
5922 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_identity, tvb, cur, 2, ENC_BIG_ENDIAN);
5923 if(TDS_PROTO_TDS7_2_OR_GREATER(tds_info)) {
5924 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_computed, tvb, cur, 2, ENC_BIG_ENDIAN);
5926 if(TDS_PROTO_TDS7_3A_OR_LESS(tds_info)) {
5927 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_reservedodbc, tvb, cur, 2, ENC_BIG_ENDIAN);
5929 if(TDS_PROTO_TDS7_2_OR_GREATER(tds_info)) {
5930 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_fixedlenclrtype, tvb, cur, 2, ENC_BIG_ENDIAN);
5932 if(TDS_PROTO_TDS7_3B_OR_GREATER(tds_info)) {
5933 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_sparsecolumnset, tvb, cur, 2, ENC_BIG_ENDIAN);
5935 if(TDS_PROTO_TDS7_4_OR_GREATER(tds_info)) {
5936 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_encrypted, tvb, cur, 2, ENC_BIG_ENDIAN);
5938 if(TDS_PROTO_TDS7_2_OR_GREATER(tds_info)) {
5939 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_hidden, tvb, cur, 2, ENC_BIG_ENDIAN);
5940 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_key, tvb, cur, 2, ENC_BIG_ENDIAN);
5941 proto_tree_add_item(flags_tree, hf_tds_colmetadata_flags_nullableunknown, tvb, cur, 2, ENC_BIG_ENDIAN);
5945 cur +=2;
5947 /* TYPE_INFO */
5948 type = tvb_get_uint8(tvb, cur);
5949 type_item = proto_tree_add_item(col_tree, hf_tds_colmetadata_results_token_type, tvb, cur, 1, ENC_NA);
5950 proto_item_append_text(type_item, " (%s)", val_to_str(type, tds_data_type_names, "Invalid data type: %02X"));
5951 nl_data->columns[i]->ctype = type;
5952 cur++;
5954 if(is_fixedlen_type_tds(type))
5956 nl_data->columns[i]->csize = get_size_by_coltype(type);
5958 else if(is_varlen_type_tds(type))
5960 switch(type)
5962 case TDS_DATA_TYPE_GUID:
5963 case TDS_DATA_TYPE_INTN:
5964 case TDS_DATA_TYPE_BITN:
5965 case TDS_DATA_TYPE_FLTN:
5966 case TDS_DATA_TYPE_MONEYN:
5967 case TDS_DATA_TYPE_DATETIMN:
5968 case TDS_DATA_TYPE_CHAR:
5969 case TDS_DATA_TYPE_VARCHAR:
5970 case TDS_DATA_TYPE_BINARY:
5971 case TDS_DATA_TYPE_VARBINARY:
5973 proto_tree_add_item(col_tree, hf_tds_colmetadata_csize, tvb, cur, 1, ENC_LITTLE_ENDIAN );
5974 nl_data->columns[i]->csize = tvb_get_uint8(tvb, cur);
5975 cur++;
5976 break;
5978 case TDS_DATA_TYPE_DATEN:
5980 break;
5982 case TDS_DATA_TYPE_DECIMAL:
5983 case TDS_DATA_TYPE_NUMERIC:
5984 case TDS_DATA_TYPE_DECIMALN:
5985 case TDS_DATA_TYPE_NUMERICN:
5987 proto_tree_add_item(col_tree, hf_tds_colmetadata_csize, tvb, cur, 1, ENC_LITTLE_ENDIAN );
5988 nl_data->columns[i]->csize = tvb_get_uint8(tvb,cur);
5989 cur++;
5991 proto_tree_add_item(col_tree, hf_tds_colmetadata_precision, tvb, cur, 1, ENC_LITTLE_ENDIAN );
5992 nl_data->columns[i]->precision = tvb_get_uint8(tvb,cur);
5993 cur++;
5995 proto_tree_add_item(col_tree, hf_tds_colmetadata_scale, tvb, cur, 1, ENC_LITTLE_ENDIAN );
5996 nl_data->columns[i]->scale = tvb_get_uint8(tvb,cur);
5997 cur++;
5998 break;
6000 case TDS_DATA_TYPE_TIMEN:
6001 case TDS_DATA_TYPE_DATETIME2N:
6002 case TDS_DATA_TYPE_DATETIMEOFFSETN:
6004 proto_tree_add_item(col_tree, hf_tds_colmetadata_scale, tvb, cur, 1, ENC_LITTLE_ENDIAN );
6005 nl_data->columns[i]->scale = tvb_get_uint8(tvb,cur);
6006 cur++;
6007 break;
6009 case TDS_DATA_TYPE_BIGVARBIN:
6011 nl_data->columns[i]->csize = tvb_get_uint16(tvb, cur, encoding);
6012 proto_tree_add_item(col_tree, hf_tds_colmetadata_large2_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6013 cur += 2;
6014 break;
6016 case TDS_DATA_TYPE_BIGVARCHR:
6018 nl_data->columns[i]->csize = tvb_get_uint16(tvb, cur, encoding);
6019 proto_tree_add_item(col_tree, hf_tds_colmetadata_large2_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6020 cur += 2;
6022 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_codepage, tvb, cur, 2, ENC_LITTLE_ENDIAN );
6023 cur += 2;
6024 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_flags, tvb, cur, 2, ENC_LITTLE_ENDIAN );
6025 cur += 2;
6026 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_charset_id, tvb, cur, 1, ENC_LITTLE_ENDIAN );
6027 cur +=1;
6028 break;
6030 case TDS_DATA_TYPE_BIGBINARY:
6032 nl_data->columns[i]->csize = tvb_get_uint16(tvb, cur, encoding);
6033 proto_tree_add_item(col_tree, hf_tds_colmetadata_large2_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6034 cur += 2;
6035 break;
6037 case TDS_DATA_TYPE_BIGCHAR:
6038 case TDS_DATA_TYPE_NVARCHAR:
6039 case TDS_DATA_TYPE_NCHAR:
6041 nl_data->columns[i]->csize = tvb_get_uint16(tvb, cur, encoding);
6042 proto_tree_add_item(col_tree, hf_tds_colmetadata_large2_type_size, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6043 cur += 2;
6045 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_codepage, tvb, cur, 2, ENC_LITTLE_ENDIAN );
6046 cur += 2;
6047 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_flags, tvb, cur, 2, ENC_LITTLE_ENDIAN );
6048 cur += 2;
6049 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_charset_id, tvb, cur, 1, ENC_LITTLE_ENDIAN );
6050 cur +=1;
6051 break;
6053 case TDS_DATA_TYPE_XML:
6055 uint8_t schema_present;
6056 schema_present = tvb_get_uint8(tvb, cur);
6057 cur += 1;
6059 if(schema_present)
6061 msg_len = tvb_get_uint8(tvb, cur);
6062 proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname_length, tvb, cur, 1, ENC_NA);
6063 cur += 1;
6064 if(msg_len != 0) {
6065 msg_len *= 2;
6066 proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6067 cur += msg_len;
6070 msg_len = tvb_get_uint8(tvb, cur);
6071 proto_tree_add_item(col_tree, hf_tds_colmetadata_owningschema_length, tvb, cur, 1, ENC_NA);
6072 cur += 1;
6073 if(msg_len != 0) {
6074 msg_len *= 2;
6075 proto_tree_add_item(col_tree, hf_tds_colmetadata_owningschema, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6076 cur += msg_len;
6079 msg_len = tvb_get_uint8(tvb, cur);
6080 proto_tree_add_item(col_tree, hf_tds_colmetadata_typename_length, tvb, cur, 1, ENC_NA);
6081 cur += 1;
6082 if(msg_len != 0) {
6083 msg_len *= 2;
6084 proto_tree_add_item(col_tree, hf_tds_colmetadata_typename, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6085 cur += msg_len;
6088 msg_len = tvb_get_uint8(tvb, cur);
6089 proto_tree_add_item(col_tree, hf_tds_colmetadata_xmlschemacollection_length, tvb, cur, 1, ENC_NA);
6090 cur += 1;
6091 if(msg_len != 0) {
6092 msg_len *= 2;
6093 proto_tree_add_item(col_tree, hf_tds_colmetadata_xmlschemacollection, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6094 cur += msg_len;
6098 break;
6100 case TDS_DATA_TYPE_UDT:
6102 proto_tree_add_item(col_tree, hf_tds_colmetadata_maxbytesize, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6103 cur += 2;
6105 msg_len = tvb_get_uint8(tvb, cur);
6106 proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname_length, tvb, cur, 1, ENC_NA);
6107 cur += 1;
6108 if(msg_len != 0) {
6109 msg_len *= 2;
6110 proto_tree_add_item(col_tree, hf_tds_colmetadata_dbname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6111 cur += msg_len;
6114 msg_len = tvb_get_uint8(tvb, cur);
6115 proto_tree_add_item(col_tree, hf_tds_colmetadata_schemaname_length, tvb, cur, 1, ENC_NA);
6116 cur += 1;
6117 if(msg_len != 0) {
6118 msg_len *= 2;
6119 proto_tree_add_item(col_tree, hf_tds_colmetadata_schemaname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6120 cur += msg_len;
6123 msg_len = tvb_get_uint8(tvb, cur);
6124 proto_tree_add_item(col_tree, hf_tds_colmetadata_typename_length, tvb, cur, 1, ENC_NA);
6125 cur += 1;
6126 if(msg_len != 0) {
6127 msg_len *= 2;
6128 proto_tree_add_item(col_tree, hf_tds_colmetadata_typename, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6129 cur += msg_len;
6132 msg_len = tvb_get_uint16(tvb, cur, encoding);
6133 proto_tree_add_item(col_tree, hf_tds_colmetadata_assemblyqualifiedname_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6134 cur += 2;
6135 if(msg_len != 0) {
6136 msg_len *= 2;
6137 proto_tree_add_item(col_tree, hf_tds_colmetadata_assemblyqualifiedname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6138 cur += msg_len;
6141 break;
6143 case TDS_DATA_TYPE_IMAGE:
6145 proto_tree_add_item(col_tree, hf_tds_colmetadata_large4_type_size, tvb, cur, 4, ENC_LITTLE_ENDIAN);
6146 cur += 4;
6148 /* Table name */
6149 if (TDS_PROTO_TDS7_2_OR_GREATER(tds_info)) {
6150 unsigned numparts = tvb_get_uint8(tvb, cur);
6151 unsigned parti;
6152 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_parts, tvb, cur, 1, ENC_LITTLE_ENDIAN);
6153 cur += 1;
6155 for(parti = 0; parti < numparts; parti++)
6157 unsigned partlen = tvb_get_letohs(tvb, cur);
6158 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6159 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name, tvb, cur + 2, partlen * 2, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6160 cur += 2 + (partlen * 2);
6163 else {
6164 unsigned tablenamelen = tvb_get_letohs(tvb, cur);
6165 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6166 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name, tvb, cur + 2, tablenamelen * 2, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6167 cur += 2 + (tablenamelen * 2);
6169 break;
6171 case TDS_DATA_TYPE_TEXT:
6172 case TDS_DATA_TYPE_NTEXT:
6174 nl_data->columns[i]->csize = tvb_get_uint32(tvb, cur, encoding);
6175 proto_tree_add_item(col_tree, hf_tds_colmetadata_large4_type_size, tvb, cur, 4, ENC_LITTLE_ENDIAN);
6176 cur += 4;
6178 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_codepage, tvb, cur, 2, ENC_LITTLE_ENDIAN );
6179 cur += 2;
6180 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_flags, tvb, cur, 2, ENC_LITTLE_ENDIAN );
6181 cur += 2;
6182 proto_tree_add_item(col_tree, hf_tds_colmetadata_collate_charset_id, tvb, cur, 1, ENC_LITTLE_ENDIAN );
6183 cur +=1;
6185 /* Table name */
6186 if (TDS_PROTO_TDS7_2_OR_GREATER(tds_info)) {
6187 unsigned numparts = tvb_get_uint8(tvb, cur);
6188 unsigned parti;
6189 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_parts, tvb, cur, 1, ENC_LITTLE_ENDIAN);
6190 cur += 1;
6192 for(parti = 0; parti < numparts; parti++)
6194 unsigned partlen = tvb_get_letohs(tvb, cur);
6195 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6196 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name, tvb, cur + 2, partlen * 2, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6197 cur += 2 + (partlen * 2);
6200 else {
6201 unsigned tablenamelen = tvb_get_letohs(tvb, cur);
6202 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name_length, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6203 proto_tree_add_item(col_tree, hf_tds_colmetadata_table_name, tvb, cur + 2, tablenamelen * 2, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6204 cur += 2 + (tablenamelen * 2);
6207 break;
6209 case TDS_DATA_TYPE_SSVARIANT:
6211 proto_tree_add_item(col_tree, hf_tds_colmetadata_large4_type_size, tvb, cur, 4, ENC_LITTLE_ENDIAN);
6212 cur += 4;
6213 break;
6218 /* ColName */
6219 msg_len = tvb_get_uint8(tvb, cur);
6220 proto_tree_add_item(col_tree, hf_tds_colmetadata_colname_length, tvb, cur, 1, ENC_NA);
6221 cur += 1;
6222 if(msg_len != 0) {
6223 msg_len *= 2;
6224 proto_tree_add_item(col_tree, hf_tds_colmetadata_colname, tvb, cur, msg_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6225 cur += msg_len;
6228 proto_item_set_len(col_item, cur - col_offset);
6231 return cur - offset;
6234 /* Valid status fields for TDS_DONEINPROC_TOKEN
6235 * One field is not valid in this token.
6238 static int * const done_status_flags[] = {
6239 &hf_tds_done_status_more,
6240 &hf_tds_done_status_error,
6241 &hf_tds_done_status_inxact,
6242 &hf_tds_done_status_proc,
6243 &hf_tds_done_status_count,
6244 &hf_tds_done_status_attn,
6245 &hf_tds_done_status_event,
6246 &hf_tds_done_status_srverror,
6247 NULL
6250 static int
6251 dissect_tds_done_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
6253 unsigned cur = offset;
6255 proto_tree_add_bitmask(tree, tvb, cur, hf_tds_done_status, ett_tds_done_status,
6256 done_status_flags, tds_get_int2_encoding(tds_info));
6257 cur += 2;
6258 proto_tree_add_item(tree, hf_tds_done_curcmd, tvb, cur, 2,
6259 tds_get_int2_encoding(tds_info));
6260 cur += 2;
6261 if (TDS_PROTO_TDS7_1_OR_LESS(tds_info)) {
6262 proto_tree_add_item(tree, hf_tds_done_donerowcount_32, tvb, cur, 4,
6263 tds_get_int4_encoding(tds_info));
6264 cur += 4;
6265 } else {
6266 /* TDS 7 is always little-endian. */
6267 proto_tree_add_item(tree, hf_tds_done_donerowcount_64, tvb, cur, 8, ENC_LITTLE_ENDIAN);
6268 cur += 8;
6271 return cur - offset;
6274 /* Valid status fields for TDS_DONEINPROC_TOKEN
6275 * All fields are valid in this token.
6278 static int * const doneproc_status_flags[] = {
6279 &hf_tds_done_status_more,
6280 &hf_tds_done_status_error,
6281 &hf_tds_done_status_inxact,
6282 &hf_tds_done_status_proc,
6283 &hf_tds_done_status_count,
6284 &hf_tds_done_status_attn,
6285 &hf_tds_done_status_event,
6286 &hf_tds_done_status_rpcinbatch,
6287 &hf_tds_done_status_srverror,
6288 NULL
6291 static int
6292 dissect_tds_doneproc_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
6294 unsigned cur = offset;
6296 proto_tree_add_bitmask(tree, tvb, cur, hf_tds_doneproc_status, ett_tds_done_status,
6297 doneproc_status_flags, tds_get_int2_encoding(tds_info));
6298 cur += 2;
6299 proto_tree_add_item(tree, hf_tds_doneproc_curcmd, tvb, cur, 2,
6300 tds_get_int2_encoding(tds_info));
6301 cur += 2;
6302 if (TDS_PROTO_TDS7_1_OR_LESS(tds_info)) {
6303 proto_tree_add_item(tree, hf_tds_doneproc_donerowcount_32, tvb, cur, 4,
6304 tds_get_int4_encoding(tds_info));
6305 cur += 4;
6306 } else {
6307 /* TDS 7 is always little-endian. */
6308 proto_tree_add_item(tree, hf_tds_doneproc_donerowcount_64, tvb, cur, 8, ENC_LITTLE_ENDIAN);
6309 cur += 8;
6312 return cur - offset;
6315 /* Valid status fields for TDS_DONEINPROC_TOKEN
6316 * A few fields are not valid in this token.
6318 * This token occurs much more frequently when stored procedures are used, so
6319 * it's worthwhile to make a separate list.
6321 static int * const doneinproc_status_flags[] = {
6322 &hf_tds_done_status_more,
6323 &hf_tds_done_status_error,
6324 &hf_tds_done_status_inxact,
6325 &hf_tds_done_status_count,
6326 &hf_tds_done_status_attn,
6327 &hf_tds_done_status_event,
6328 &hf_tds_done_status_srverror,
6329 NULL
6332 static int
6333 dissect_tds_doneinproc_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info)
6335 unsigned cur = offset;
6337 proto_tree_add_bitmask(tree, tvb, cur, hf_tds_doneinproc_status, ett_tds_done_status,
6338 doneinproc_status_flags, tds_get_int2_encoding(tds_info));
6339 cur += 2;
6340 proto_tree_add_item(tree, hf_tds_doneinproc_curcmd, tvb, cur, 2,
6341 tds_get_int2_encoding(tds_info));
6342 cur += 2;
6343 if (TDS_PROTO_TDS7_1_OR_LESS(tds_info)) {
6344 proto_tree_add_item(tree, hf_tds_doneinproc_donerowcount_32, tvb, cur, 4,
6345 tds_get_int4_encoding(tds_info));
6346 cur += 4;
6347 } else {
6348 /* TDS 7 is always little-endian. */
6349 proto_tree_add_item(tree, hf_tds_doneinproc_donerowcount_64, tvb, cur, 8, ENC_LITTLE_ENDIAN);
6350 cur += 8;
6353 return cur - offset;
6356 static int
6357 dissect_tds_procid_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree, tds_conv_info_t *tds_info _U_ )
6359 unsigned cur = offset;
6361 proto_tree_add_item(tree, hf_tds_procid_value, tvb, cur, 8, ENC_NA);
6362 cur += 8;
6364 return cur - offset;
6367 static uint8_t
6368 dissect_tds_type_info(tvbuff_t *tvb, int *offset, packet_info *pinfo, proto_tree *tree, bool *plp, bool variantprop)
6370 proto_item *item = NULL, *item1 = NULL, *data_type_item = NULL;
6371 proto_tree *sub_tree = NULL, *collation_tree;
6372 uint32_t varlen, varlen_len = 0;
6373 uint8_t data_type;
6375 *plp = false; /* most types are not Partially Length-Prefixed */
6376 item = proto_tree_add_item(tree, hf_tds_type_info, tvb, *offset, 0, ENC_NA);
6377 data_type = tvb_get_uint8(tvb, *offset);
6378 proto_item_append_text(item, " (%s)", val_to_str(data_type, tds_data_type_names, "Invalid data type: %02X"));
6379 sub_tree = proto_item_add_subtree(item, ett_tds_type_info);
6380 data_type_item = proto_tree_add_item(sub_tree, hf_tds_type_info_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
6381 *offset += 1;
6383 if(variantprop)
6385 uint8_t prop_bytes = variant_propbytes(data_type);
6386 *offset += prop_bytes;
6389 /* optional TYPE_VARLEN for variable length types */
6390 switch(data_type) {
6391 /* FIXEDLENTYPE */
6392 case TDS_DATA_TYPE_NULL: /* Null (no data associated with this type) */
6393 case TDS_DATA_TYPE_INT1: /* TinyInt (1 byte data representation) */
6394 case TDS_DATA_TYPE_BIT: /* Bit (1 byte data representation) */
6395 case TDS_DATA_TYPE_INT2: /* SmallInt (2 byte data representation) */
6396 case TDS_DATA_TYPE_INT4: /* Int (4 byte data representation) */
6397 case TDS_DATA_TYPE_FLT4: /* Real (4 byte data representation) */
6398 case TDS_DATA_TYPE_DATETIME4: /* SmallDateTime (4 byte data representation) */
6399 case TDS_DATA_TYPE_MONEY4: /* SmallMoney (4 byte data representation) */
6400 case TDS_DATA_TYPE_INT8: /* BigInt (8 byte data representation) */
6401 case TDS_DATA_TYPE_FLT8: /* Float (8 byte data representation) */
6402 case TDS_DATA_TYPE_MONEY: /* Money (8 byte data representation) */
6403 case TDS_DATA_TYPE_DATETIME: /* DateTime (8 byte data representation) */
6404 /* BYTELEN_TYPE with length determined by SCALE */
6405 case TDS_DATA_TYPE_TIMEN: /* (introduced in TDS 7.3) */
6406 case TDS_DATA_TYPE_DATETIME2N: /* (introduced in TDS 7.3) */
6407 case TDS_DATA_TYPE_DATETIMEOFFSETN: /* (introduced in TDS 7.3) */
6408 varlen_len = 0;
6409 break;
6410 /* BYTELEN_TYPE */
6411 case TDS_DATA_TYPE_GUID: /* UniqueIdentifier */
6412 case TDS_DATA_TYPE_INTN:
6413 case TDS_DATA_TYPE_DECIMAL: /* Decimal (TDS 4/5) */
6414 case TDS_DATA_TYPE_NUMERIC: /* Numeric (TDS 4/5) */
6415 case TDS_DATA_TYPE_BITN:
6416 case TDS_DATA_TYPE_DECIMALN: /* Decimal */
6417 case TDS_DATA_TYPE_NUMERICN: /* Numeric */
6418 case TDS_DATA_TYPE_FLTN:
6419 case TDS_DATA_TYPE_MONEYN:
6420 case TDS_DATA_TYPE_DATETIMN:
6421 case TDS_DATA_TYPE_DATEN: /* (introduced in TDS 7.3) */
6422 case TDS_DATA_TYPE_CHAR: /* Char (TDS 4/5) */
6423 case TDS_DATA_TYPE_VARCHAR: /* VarChar (TDS 4/5) */
6424 case TDS_DATA_TYPE_BINARY: /* Binary (TDS 4/5) */
6425 case TDS_DATA_TYPE_VARBINARY: /* VarBinary (TDS 4/5) */
6426 varlen_len = 1;
6427 varlen = tvb_get_uint8(tvb, *offset);
6428 break;
6429 /* USHORTLEN_TYPE */
6430 case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
6431 case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
6432 case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
6433 varlen_len = 2;
6434 varlen = tvb_get_letohs(tvb, *offset);
6435 /* A type with unlimited max size, known as varchar(max), varbinary(max) and nvarchar(max),
6436 which has a max size of 0xFFFF, defined by PARTLENTYPE. This class of types was introduced in TDS 7.2. */
6437 if(varlen == 0xFFFF)
6438 *plp = true;
6439 break;
6440 case TDS_DATA_TYPE_BIGBINARY: /* Binary */
6441 case TDS_DATA_TYPE_BIGCHAR: /* Char */
6442 case TDS_DATA_TYPE_NCHAR: /* NChar */
6443 varlen_len = 2;
6444 varlen = tvb_get_letohs(tvb, *offset);
6445 break;
6446 /* LONGLEN_TYPE */
6447 case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
6448 case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
6449 *plp = true;
6450 /* Fall through */
6451 case TDS_DATA_TYPE_TEXT: /* Text */
6452 case TDS_DATA_TYPE_IMAGE: /* Image */
6453 case TDS_DATA_TYPE_NTEXT: /* NText */
6454 case TDS_DATA_TYPE_SSVARIANT: /* Sql_Variant (introduced in TDS 7.2) */
6455 varlen_len = 4;
6456 varlen = tvb_get_letohl(tvb, *offset);
6457 break;
6458 default:
6459 expert_add_info(pinfo, data_type_item, &ei_tds_type_info_type);
6460 varlen_len = 0;
6461 data_type = TDS_DATA_TYPE_INVALID;
6464 if(varlen_len)
6465 item1 = proto_tree_add_uint(sub_tree, hf_tds_type_info_varlen, tvb, *offset, varlen_len, varlen);
6466 if(*plp)
6467 proto_item_append_text(item1, " (PLP - Partially Length-Prefixed data type)");
6468 *offset += varlen_len;
6470 /* Optional data dependent on type */
6471 switch(data_type) {
6472 /* PRECISION and SCALE */
6473 case TDS_DATA_TYPE_DECIMAL: /* Decimal (TDS 4/5) */
6474 case TDS_DATA_TYPE_NUMERIC: /* Numeric (TDS 4/5) */
6475 case TDS_DATA_TYPE_DECIMALN: /* Decimal */
6476 case TDS_DATA_TYPE_NUMERICN: /* Numeric */
6477 proto_tree_add_item(sub_tree, hf_tds_type_info_precision, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
6478 *offset += 1;
6479 /* fallthrough */
6481 /* SCALE */
6482 case TDS_DATA_TYPE_TIMEN: /* (introduced in TDS 7.3) */
6483 case TDS_DATA_TYPE_DATETIME2N: /* (introduced in TDS 7.3) */
6484 case TDS_DATA_TYPE_DATETIMEOFFSETN: /* (introduced in TDS 7.3) */
6485 proto_tree_add_item(sub_tree, hf_tds_type_info_scale, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
6486 *offset += 1;
6487 break;
6488 /* COLLATION */
6489 case TDS_DATA_TYPE_BIGCHAR: /* Char */
6490 case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
6491 case TDS_DATA_TYPE_TEXT: /* Text */
6492 case TDS_DATA_TYPE_NTEXT: /* NText */
6493 case TDS_DATA_TYPE_NCHAR: /* NChar */
6494 case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
6495 item1 = proto_tree_add_item(sub_tree, hf_tds_type_info_collation, tvb, *offset, 5, ENC_NA);
6496 collation_tree = proto_item_add_subtree(item1, ett_tds_type_info_collation);
6497 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_lcid, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6498 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_ign_case, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6499 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_ign_accent, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6500 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_ign_kana, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6501 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_ign_width, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6502 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_binary, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6503 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_version, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6504 proto_tree_add_item(collation_tree, hf_tds_type_info_collation_sortid, tvb, *offset + 4, 1, ENC_LITTLE_ENDIAN);
6505 *offset += 5;
6506 break;
6509 proto_item_set_end(item, tvb, *offset);
6510 return data_type;
6513 static void
6514 dissect_tds_rpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
6516 proto_item *item = NULL, *param_item = NULL;
6517 proto_tree *sub_tree = NULL, *status_sub_tree = NULL;
6518 int offset = 0;
6519 unsigned len;
6520 uint8_t data_type;
6522 item = proto_tree_add_item(tree, hf_tds_rpc, tvb, 0, -1, ENC_NA);
6523 tree = proto_item_add_subtree(item, ett_tds_message);
6525 dissect_tds_all_headers(tvb, &offset, pinfo, tree);
6526 while(tvb_reported_length_remaining(tvb, offset) > 0) {
6528 * RPC name.
6530 switch(tds_protocol_type) {
6531 case TDS_PROTOCOL_4:
6532 case TDS_PROTOCOL_5:
6533 len = tvb_get_uint8(tvb, offset);
6534 proto_tree_add_item(tree, hf_tds_rpc_name_length8, tvb, offset, 1, ENC_NA);
6535 proto_tree_add_item(tree, hf_tds_rpc_name, tvb, offset + 1, len, ENC_ASCII);
6536 offset += 1 + len;
6537 break;
6539 case TDS_PROTOCOL_7_0:
6540 case TDS_PROTOCOL_7_1:
6541 case TDS_PROTOCOL_7_2:
6542 case TDS_PROTOCOL_7_3:
6543 case TDS_PROTOCOL_7_4:
6544 default: /* unspecified: try as if TDS7 */
6545 len = tvb_get_letohs(tvb, offset);
6546 proto_tree_add_item(tree, hf_tds_rpc_name_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6547 offset += 2;
6548 if (len == 0xFFFF) {
6549 proto_tree_add_item(tree, hf_tds_rpc_proc_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6550 offset += 2;
6552 else if (len != 0) {
6553 len *= 2;
6554 proto_tree_add_item(tree, hf_tds_rpc_name, tvb, offset, len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6555 offset += len;
6557 break;
6559 item = proto_tree_add_item(tree, hf_tds_rpc_options, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6560 sub_tree = proto_item_add_subtree(item, ett_tds_rpc_options);
6561 proto_tree_add_item(sub_tree, hf_tds_rpc_options_with_recomp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6562 proto_tree_add_item(sub_tree, hf_tds_rpc_options_no_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6563 proto_tree_add_item(sub_tree, hf_tds_rpc_options_reuse_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6564 offset += 2;
6566 /* dissect parameters */
6567 while(tvb_reported_length_remaining(tvb, offset) > 0) {
6568 bool plp;
6570 len = tvb_get_uint8(tvb, offset);
6571 /* check for BatchFlag or NoExecFlag */
6572 if((int8_t)len < 0) {
6573 proto_tree_add_item(tree, hf_tds_rpc_separator, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6574 ++offset;
6575 break;
6577 param_item = proto_tree_add_item(tree, hf_tds_rpc_parameter, tvb, offset, 0, ENC_NA);
6578 sub_tree = proto_item_add_subtree(param_item, ett_tds_rpc_parameter);
6579 proto_tree_add_item(sub_tree, hf_tds_rpc_parameter_name_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6580 ++offset;
6581 if(len) {
6582 len *= 2;
6583 proto_tree_add_item(sub_tree, hf_tds_rpc_parameter_name, tvb, offset, len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6584 offset += len;
6586 item = proto_tree_add_item(sub_tree, hf_tds_rpc_parameter_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6587 status_sub_tree = proto_item_add_subtree(item, ett_tds_rpc_parameter_status);
6588 proto_tree_add_item(status_sub_tree, hf_tds_rpc_parameter_status_by_ref, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6589 proto_tree_add_item(status_sub_tree, hf_tds_rpc_parameter_status_default, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6590 ++offset;
6591 data_type = dissect_tds_type_info(tvb, &offset, pinfo, sub_tree, &plp, false);
6592 if (data_type == TDS_DATA_TYPE_INVALID)
6593 break;
6594 dissect_tds_type_varbyte(tvb, &offset, pinfo, sub_tree, hf_tds_rpc_parameter_value, tds_info,
6595 data_type, 0, plp, -1, NULL); /* TODO: Precision needs setting? */
6596 proto_item_set_end(param_item, tvb, offset);
6601 static int
6602 dissect_tds_featureextack_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
6604 uint8_t featureid;
6605 int featureackdatalen;
6606 proto_tree *feature_tree = NULL;
6607 proto_item * feature_item;
6608 unsigned cur = offset;
6610 while(tvb_reported_length_remaining(tvb, cur) > 0)
6612 featureid = tvb_get_uint8(tvb, cur);
6613 featureackdatalen = tvb_get_uint32(tvb, cur + 1, ENC_LITTLE_ENDIAN);
6615 feature_item = proto_tree_add_item(tree, hf_tds_featureextack_feature, tvb, cur, featureid == 0xff ? 1 : 5 + featureackdatalen, ENC_NA);
6616 feature_tree = proto_item_add_subtree(feature_item, ett_tds_col);
6618 proto_tree_add_item(feature_tree, hf_tds_featureextack_featureid, tvb, cur, 1, ENC_LITTLE_ENDIAN);
6619 cur += 1;
6621 if(featureid == 0xff)
6622 break;
6624 proto_tree_add_item(feature_tree, hf_tds_featureextack_featureackdatalen, tvb, cur, 4, ENC_LITTLE_ENDIAN);
6625 cur += 4;
6627 proto_tree_add_item(feature_tree, hf_tds_featureextack_featureackdata, tvb, cur, featureackdatalen, ENC_NA);
6628 cur += featureackdatalen;
6631 return cur - offset;
6634 static int
6635 dissect_tds_sessionstate_token(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
6637 uint16_t statelen;
6638 unsigned cur = offset, len;
6640 proto_tree_add_item_ret_uint(tree, hf_tds_sessionstate_length, tvb, cur, 4, ENC_LITTLE_ENDIAN, &len);
6641 cur += 4;
6643 proto_tree_add_item(tree, hf_tds_sessionstate_seqno, tvb, cur, 4, ENC_LITTLE_ENDIAN);
6644 cur += 4;
6646 proto_tree_add_item(tree, hf_tds_sessionstate_status, tvb, cur, 1, ENC_LITTLE_ENDIAN);
6647 cur += 1;
6649 while((cur - offset - 3) < len)
6651 proto_tree_add_item(tree, hf_tds_sessionstate_stateid, tvb, cur, 1, ENC_LITTLE_ENDIAN);
6652 cur += 1;
6654 if(tvb_get_uint8(tvb, cur) == 0xFF)
6656 cur += 1;
6657 statelen = tvb_get_ntohs(tvb, cur + 2);
6658 proto_tree_add_item(tree, hf_tds_sessionstate_statelen, tvb, cur, 2, ENC_LITTLE_ENDIAN);
6659 cur += 2;
6660 } else {
6661 statelen = tvb_get_uint8(tvb, cur);
6662 proto_tree_add_item(tree, hf_tds_sessionstate_statelen, tvb, cur, 1, ENC_LITTLE_ENDIAN);
6663 cur += 1;
6666 proto_tree_add_item(tree, hf_tds_sessionstate_statevalue, tvb, cur, statelen, ENC_NA);
6667 cur += statelen;
6670 return cur - offset;
6673 static int
6674 tds7_token_to_idx(uint8_t token)
6676 /* TODO: Commented out entries are token types which are not currently dissected
6677 * Although they are known values, we cannot step over the bytes as token length is unknown
6678 * Better therefore to return unknown token type and highlight to user
6682 * Token values for TDS7.
6683 * Microsoft and Sybase have separately expanded the protocol and have
6684 * each used numbers differently.
6687 switch(token)
6689 /*case TDS7_ALTMETADATA_TOKEN: return hf_tds_altmetadata;*/
6690 /*case TDS_ALTROW_TOKEN: return hf_tds_altrow;*/
6691 /*case TDS_COL_NAME_TOKEN: return hf_tds_colname;*/
6692 case TDS_CAPABILITY_TOKEN: return hf_tds_capability;
6693 case TDS_COLFMT_TOKEN: return hf_tds_colfmt;
6694 case TDS7_COL_METADATA_TOKEN: return hf_tds_colmetadata;
6695 case TDS_DONE_TOKEN: return hf_tds_done;
6696 case TDS_DONEPROC_TOKEN: return hf_tds_doneproc;
6697 case TDS_DONEINPROC_TOKEN: return hf_tds_doneinproc;
6698 case TDS_ENVCHG_TOKEN: return hf_tds_envchg;
6699 case TDS_ERR_TOKEN: return hf_tds_error;
6700 case TDS_FEATUREEXTACK_TOKEN: return hf_tds_featureextack;
6701 /*case TDS_FEDAUTHINFO_TOKEN: return hf_tds_fedauthinfo;*/
6702 case TDS_INFO_TOKEN: return hf_tds_info;
6703 case TDS_LOGIN_ACK_TOKEN: return hf_tds_loginack;
6704 case TDS_NBCROW_TOKEN: return hf_tds_nbcrow;
6705 case TDS_OFFSET_TOKEN: return hf_tds_offset;
6706 case TDS_ORDER_TOKEN: return hf_tds_order;
6707 case TDS_RET_STAT_TOKEN: return hf_tds_returnstatus;
6708 /*case TDS_RETURNVAL_TOKEN: return hf_tds_returnvalue;*/
6709 case TDS_ROW_TOKEN: return hf_tds_row;
6710 case TDS_SESSIONSTATE_TOKEN: return hf_tds_sessionstate;
6711 case TDS_SSPI_TOKEN: return hf_tds_sspi;
6712 /*case TDS_TABNAME_TOKEN: return hf_tds_tabname;*/
6713 /*case TDS_TVPROW_TOKEN: return hf_tds_tvprow;*/
6716 return hf_tds_unknown_tds_token;
6719 static void
6720 dissect_tds_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tds_conv_info_t *tds_info)
6722 proto_item *token_item;
6723 proto_tree *token_tree;
6724 unsigned pos = 0, token_sz = 0;
6725 uint8_t token;
6726 struct _netlib_data nl_data;
6728 (void) memset(&nl_data, '\0', sizeof nl_data);
6730 /* Test for pre-login response in case this response is not a token stream */
6731 if(dissect_tds_prelogin_response(tvb, pinfo, pos, tree, tds_info) == true)
6733 return;
6737 * Until we reach the end of the packet, read tokens.
6739 while (tvb_reported_length_remaining(tvb, pos) > 0) {
6740 /* our token */
6741 token = tvb_get_uint8(tvb, pos);
6743 if(TDS_PROTO_LESS_THAN_TDS7(tds_info))
6746 token_item = proto_tree_add_item(tree, tds45_token_to_idx(token), tvb,
6747 pos, tvb_reported_length_remaining(tvb, pos), ENC_NA);
6748 token_tree = proto_item_add_subtree(token_item, ett_tds_token);
6750 token_sz = 0;
6751 switch (token) {
6752 case TDS_CAPABILITY_TOKEN:
6753 token_sz = dissect_tds5_capability_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
6754 break;
6755 case TDS_CURINFO_TOKEN:
6756 token_sz = dissect_tds5_curinfo_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
6757 break;
6758 case TDS_DONE_TOKEN:
6759 token_sz = dissect_tds_done_token(tvb, pos + 1, token_tree, tds_info) + 1;
6760 break;
6761 case TDS_DONEPROC_TOKEN:
6762 token_sz = dissect_tds_doneproc_token(tvb, pos + 1, token_tree, tds_info) + 1;
6763 break;
6764 case TDS_DONEINPROC_TOKEN:
6765 token_sz = dissect_tds_doneinproc_token(tvb, pos + 1, token_tree, tds_info) + 1;
6766 break;
6767 case TDS5_EED_TOKEN:
6768 token_sz = dissect_tds_eed_token(tvb, pos + 1, token_tree, tds_info) + 1;
6769 break;
6770 case TDS_ENVCHG_TOKEN:
6771 token_sz = dissect_tds_envchg_token(tvb, pos + 1, token_tree, tds_info) + 1;
6772 break;
6773 case TDS_COL_NAME_TOKEN:
6774 token_sz = dissect_tds_col_name_token(token_tree, tvb, pos + 1, tds_info, &nl_data) + 1;
6775 break;
6776 case TDS_COLFMT_TOKEN:
6777 token_sz = dissect_tds_colfmt_token(token_tree, tvb, pos + 1, tds_info, &nl_data) + 1;
6778 break;
6779 case TDS_CONTROL_TOKEN:
6780 token_sz = dissect_tds_control_token(token_tree, tvb, pos + 1, tds_info, &nl_data) + 1;
6781 break;
6782 case TDS_ERR_TOKEN:
6783 token_sz = dissect_tds_error_token(tvb, pos + 1, token_tree, tds_info) + 1;
6784 break;
6785 case TDS_INFO_TOKEN:
6786 token_sz = dissect_tds_info_token(tvb, pos + 1, token_tree, tds_info) + 1;
6787 break;
6788 case TDS_LOGIN_ACK_TOKEN:
6789 token_sz = dissect_tds_login_ack_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
6790 break;
6791 case TDS5_MSG_TOKEN:
6792 token_sz = dissect_tds5_msg_token(token_tree, tvb, pos + 1, tds_info) + 1;
6793 break;
6794 case TDS_ORDER_TOKEN:
6795 token_sz = dissect_tds_order_token(tvb, pos + 1, token_tree, tds_info) + 1;
6796 break;
6797 case TDS5_PARAMFMT_TOKEN:
6798 token_sz = dissect_tds_paramfmt_token(token_tree, tvb, pos + 1, tds_info, &nl_data) + 1;
6799 break;
6800 case TDS5_PARAMFMT2_TOKEN:
6801 token_sz = dissect_tds_paramfmt2_token(token_tree, tvb, pos + 1, tds_info, &nl_data) + 1;
6802 break;
6803 case TDS5_PARAMS_TOKEN:
6804 token_sz = dissect_tds5_params_token(tvb, pinfo, &nl_data, pos + 1,
6805 token_tree, token_item, tds_info) + 1;
6806 break;
6807 case TDS_PROCID_TOKEN:
6808 token_sz = dissect_tds_procid_token(tvb, pos + 1, token_tree, tds_info) + 1;
6809 break;
6810 case TDS_RET_STAT_TOKEN:
6811 token_sz = dissect_tds_returnstatus_token(tvb, pos + 1, token_tree, tds_info) + 1;
6812 break;
6813 case TDS_ROW_TOKEN:
6814 token_sz = dissect_tds_row_token(tvb, pinfo, &nl_data, pos + 1, token_tree, tds_info) + 1;
6815 break;
6816 case TDS5_ROWFMT_TOKEN:
6817 token_sz = dissect_tds_rowfmt_token(token_tree, tvb, pinfo, pos + 1, tds_info, &nl_data) + 1;
6818 break;
6819 case TDS5_ROWFMT2_TOKEN:
6820 token_sz = dissect_tds_rowfmt2_token(token_tree, tvb, pinfo, pos + 1, tds_info, &nl_data) + 1;
6821 break;
6823 default:
6824 break;
6826 if (token_sz == 0) {
6827 expert_add_info_format(pinfo, token_item, &ei_tds_token_length_invalid,
6828 "Bogus token size: %u", token_sz);
6829 break;
6831 else {
6832 proto_item_set_len(token_item, token_sz);
6835 pos += token_sz;
6837 } else {
6839 token_item = proto_tree_add_item(tree, tds7_token_to_idx(token), tvb, pos,
6840 tvb_reported_length_remaining(tvb, pos), ENC_NA);
6841 token_tree = proto_item_add_subtree(token_item, ett_tds_token);
6843 /* Tokens from MS-TDS specification, revision 18.0 (up to TDS 7.4) */
6844 switch (token) {
6845 case TDS7_COL_METADATA_TOKEN:
6846 token_sz = dissect_tds7_colmetadata_token(tvb, &nl_data, pos + 1, token_tree, tds_info) + 1;
6847 break;
6848 case TDS_DONE_TOKEN:
6849 token_sz = dissect_tds_done_token(tvb, pos + 1, token_tree, tds_info) + 1;
6850 break;
6851 case TDS_DONEPROC_TOKEN:
6852 token_sz = dissect_tds_doneproc_token(tvb, pos + 1, token_tree, tds_info) + 1;
6853 break;
6854 case TDS_DONEINPROC_TOKEN:
6855 token_sz = dissect_tds_doneinproc_token(tvb, pos + 1, token_tree, tds_info) + 1;
6856 break;
6857 case TDS_ENVCHG_TOKEN:
6858 token_sz = dissect_tds_envchg_token(tvb, pos + 1, token_tree, tds_info) + 1;
6859 break;
6860 case TDS_ERR_TOKEN:
6861 token_sz = dissect_tds_error_token(tvb, pos + 1, token_tree, tds_info) + 1;
6862 break;
6863 case TDS_INFO_TOKEN:
6864 token_sz = dissect_tds_info_token(tvb, pos + 1, token_tree, tds_info) + 1;
6865 break;
6866 case TDS_FEATUREEXTACK_TOKEN:
6867 token_sz = dissect_tds_featureextack_token(tvb, pos + 1, token_tree) + 1;
6868 break;
6869 case TDS_LOGIN_ACK_TOKEN:
6870 token_sz = dissect_tds_login_ack_token(tvb, pinfo, pos + 1, token_tree, tds_info) + 1;
6871 break;
6872 case TDS_NBCROW_TOKEN:
6873 token_sz = dissect_tds_nbc_row_token(tvb, pinfo, &nl_data, pos + 1, token_tree, tds_info) + 1;
6874 break;
6875 case TDS_OFFSET_TOKEN:
6876 token_sz = dissect_tds_offset_token(tvb, pos + 1, token_tree) + 1;
6877 break;
6878 case TDS_ORDER_TOKEN:
6879 token_sz = dissect_tds_order_token(tvb, pos + 1, token_tree, tds_info) + 1;
6880 break;
6881 case TDS_RET_STAT_TOKEN:
6882 token_sz = dissect_tds_returnstatus_token(tvb, pos + 1, token_tree, tds_info) + 1;
6883 break;
6884 case TDS_ROW_TOKEN:
6885 token_sz = dissect_tds_row_token(tvb, pinfo, &nl_data, pos + 1, token_tree, tds_info) + 1;
6886 break;
6887 case TDS_SESSIONSTATE_TOKEN:
6888 token_sz = dissect_tds_sessionstate_token(tvb, pos + 1, token_tree) + 1;
6889 break;
6890 case TDS_SSPI_TOKEN:
6891 token_sz = dissect_tds_sspi_token(tvb, pos + 1, pinfo, token_tree) + 1;
6892 break;
6893 default:
6894 token_sz = 0;
6895 break;
6898 /* Move on if nothing identifiable found */
6899 if(token_sz == 0)
6900 break;
6902 proto_item_set_len(token_item, token_sz);
6904 /* and step to the end of the token, rinse, lather, repeat */
6905 pos += token_sz;
6910 static void
6911 fill_tds_info_defaults(tds_conv_info_t *tds_info)
6913 tds_info->tds_conv_cursor_info = NULL;
6914 if (tds_little_endian) {
6915 tds_info->tds_encoding_int4 = TDS_INT4_LITTLE_ENDIAN;
6916 tds_info->tds_encoding_int2 = TDS_INT2_LITTLE_ENDIAN;
6918 else {
6919 tds_info->tds_encoding_int4 = TDS_INT4_BIG_ENDIAN;
6920 tds_info->tds_encoding_int2 = TDS_INT2_BIG_ENDIAN;
6923 switch (tds_protocol_type) {
6924 case TDS_PROTOCOL_4:
6925 case TDS_PROTOCOL_5:
6926 tds_info->tds_encoding_char = TDS_CHAR_ASCII;
6927 break;
6929 case TDS_PROTOCOL_7_0:
6930 case TDS_PROTOCOL_7_1:
6931 case TDS_PROTOCOL_7_2:
6932 case TDS_PROTOCOL_7_3:
6933 case TDS_PROTOCOL_7_3A:
6934 case TDS_PROTOCOL_7_3B:
6935 case TDS_PROTOCOL_7_4:
6936 case TDS_PROTOCOL_NOT_SPECIFIED:
6937 default:
6938 tds_info->tds_encoding_int4 = TDS_INT4_LITTLE_ENDIAN;
6939 tds_info->tds_encoding_int2 = TDS_INT2_LITTLE_ENDIAN;
6940 tds_info->tds_encoding_char = TDS_CHAR_UTF16;
6941 tds_info->tds_encoding_date8 = TDS_DATE8_DATE_FIRST ;
6942 tds_info->tds_encoding_date4 = TDS_DATE4_DATE_FIRST ;
6943 break;
6947 static void
6948 dissect_netlib_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
6950 int offset = 0;
6951 proto_item *tds_item;
6952 proto_tree *tds_tree;
6953 uint8_t type;
6954 uint8_t status;
6955 uint16_t channel;
6956 uint8_t packet_number;
6957 bool save_fragmented, last_buffer;
6958 int len;
6959 fragment_head *fd_head;
6960 tvbuff_t *next_tvb;
6961 conversation_t *conv;
6962 tds_conv_info_t *tds_info;
6964 static int * const status_flags[] = {
6965 &hf_tds_status_eom,
6966 &hf_tds_status_ignore,
6967 &hf_tds_status_event_notif,
6968 &hf_tds_status_reset_conn,
6969 &hf_tds_status_reset_conn_skip_tran,
6970 NULL
6973 if(detect_tls(tvb))
6975 next_tvb = tvb_new_subset_remaining(tvb, offset);
6976 call_dissector(tls_handle, next_tvb, pinfo, tree);
6977 return;
6980 conv = find_or_create_conversation(pinfo);
6981 tds_info = (tds_conv_info_t*)conversation_get_proto_data(conv, proto_tds);
6982 if (!tds_info) {
6983 tds_info = wmem_new(wmem_file_scope(), tds_conv_info_t);
6984 tds_info->tds_version = TDS_PROTOCOL_NOT_SPECIFIED;
6985 tds_info->client_version = TDS_PROTOCOL_NOT_SPECIFIED;
6986 tds_info->server_version = TDS_PROTOCOL_NOT_SPECIFIED;
6987 tds_info->tds_packets_in_order = 0;
6988 fill_tds_info_defaults(tds_info);
6989 conversation_add_proto_data(conv, proto_tds, tds_info);
6992 /* create display subtree for the protocol */
6993 tds_item = proto_tree_add_item(tree, proto_tds, tvb, offset, -1, ENC_NA);
6994 tds_tree = proto_item_add_subtree(tds_item, ett_tds);
6996 type = tvb_get_uint8(tvb, offset);
6997 proto_tree_add_item(tds_tree, hf_tds_type, tvb, offset, 1, ENC_NA);
6999 status = tvb_get_uint8(tvb, offset + 1);
7000 proto_tree_add_bitmask(tds_tree, tvb, offset+1, hf_tds_status, ett_tds_status, status_flags, ENC_NA);
7001 proto_tree_add_item(tds_tree, hf_tds_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
7002 channel = tvb_get_ntohs(tvb, offset + 4);
7003 proto_tree_add_item(tds_tree, hf_tds_channel, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
7004 packet_number = tvb_get_uint8(tvb, offset + 6);
7005 proto_tree_add_item(tds_tree, hf_tds_packet_number, tvb, offset + 6, 1, ENC_NA);
7006 proto_tree_add_item(tds_tree, hf_tds_window, tvb, offset + 7, 1, ENC_NA);
7008 offset += 8; /* skip Netlib header */
7011 * Deal with fragmentation.
7014 save_fragmented = pinfo->fragmented;
7017 * Don't even try to defragment if it's not a valid TDS type, because we're probably
7018 * not looking at a valid Netlib header. This can occur for partial captures.
7020 if (tds_defragment && is_valid_tds_type(type) && is_valid_tds_status(status)) {
7021 if (((!(status & STATUS_LAST_BUFFER)) &&
7022 (packet_number == 0) &&
7023 (channel == 0)) ||
7024 tds_info->tds_packets_in_order) {
7026 * Assumptions:
7027 * Packet number of zero on a fragment typically will occur only when
7028 * they are going to appear in order. This will happen with DB-Library
7029 * or CT-Library.
7030 * Exception:
7031 * When a more modern stream has a large number of fragments and the packet
7032 * number wraps back to zero.
7033 * Heuristic:
7034 * In the exception case, the channel number will be non-zero. This is what
7035 * has been observed, but it's probably not guaranteed.
7038 tds_info->tds_packets_in_order = 1;
7040 if (!(status & STATUS_LAST_BUFFER)) {
7041 col_append_str(pinfo->cinfo, COL_INFO, " (Not last buffer)");
7043 len = tvb_reported_length_remaining(tvb, offset);
7045 last_buffer = ((status & STATUS_LAST_BUFFER) == STATUS_LAST_BUFFER);
7046 fd_head = fragment_add_seq_next(&tds_reassembly_table, tvb, offset,
7047 pinfo, channel, NULL,
7048 len, !last_buffer);
7049 next_tvb = process_reassembled_data(tvb, offset, pinfo,
7050 "Reassembled TDS", fd_head, &tds_frag_items, NULL,
7051 tds_tree);
7053 else if (packet_number > 1 || !(status & STATUS_LAST_BUFFER)) {
7055 * Assumptions:
7056 * This is TDS7, and the packets are correctly numbered from 1.
7057 * This is either a first fragment, or one of a group of fragments.
7059 * XXX - This might not work if the packet number wraps to zero on
7060 * the very last buffer of a sequence.
7063 if (!(status & STATUS_LAST_BUFFER)) {
7064 col_append_str(pinfo->cinfo, COL_INFO, " (Not last buffer)");
7066 len = tvb_reported_length_remaining(tvb, offset);
7068 * XXX - I've seen captures that start with a login
7069 * packet with a sequence number of 2. In one, there's
7070 * a TDS7 pre-login message with a packet number of 0,
7071 * to which the response has a packet number of 1, and
7072 * then a TDS4/5 login message with a packet number of 2
7073 * and "end of message" not set, followed by a TDS4/5 login
7074 * message with a packet number of 3 and "end of message",
7075 * to which there's a response with a packet number of 1.
7077 * The TCP sequence numbers do *not* indicate that any
7078 * data is missing, so the TDS4/5 login was sent with a
7079 * packet number of 2, immediately after the TDS7 pre-login
7080 * message with a packet number of 0.
7082 * Given that we are running atop a reliable transport,
7083 * we could try doing some form of reassembly that just
7084 * accumulates packets until we get an EOM, just checking
7085 * to make sure that each packet added to the reassembly
7086 * process has a sequence number that - modulo 256! - has
7087 * is one greater than the sequence number of the previous
7088 * packet added to the reassembly.
7091 last_buffer = ((status & STATUS_LAST_BUFFER) == STATUS_LAST_BUFFER);
7093 if(tvb_reported_length(tvb) == tvb_captured_length(tvb))
7095 last_buffer = true;
7099 fd_head = fragment_add_seq_check(&tds_reassembly_table, tvb, offset,
7100 pinfo, channel, NULL,
7101 packet_number - 1, len, !last_buffer);
7102 next_tvb = process_reassembled_data(tvb, offset, pinfo,
7103 "Reassembled TDS", fd_head, &tds_frag_items, NULL,
7104 tds_tree);
7106 else {
7107 /* We're defragmenting, but this isn't a fragment. */
7108 next_tvb = tvb_new_subset_remaining(tvb, offset);
7112 else {
7114 * We're not defragmenting, or this is an invalid Netlib header.
7116 * If this isn't the last buffer, just show it as a fragment.
7117 * (XXX - it'd be nice to dissect it if it's the first
7118 * buffer, but we'd need to do reassembly in order to
7119 * discover that.)
7121 * If this is the last buffer, dissect it.
7122 * (XXX - it'd be nice to show it as a fragment if it's part
7123 * of a fragmented message, but we'd need to do reassembly
7124 * in order to discover that.)
7126 if (((status & STATUS_LAST_BUFFER) == 0))
7128 next_tvb = NULL;
7130 else {
7131 next_tvb = tvb_new_subset_remaining(tvb, offset);
7135 if (next_tvb != NULL) {
7137 switch (type) {
7139 case TDS_RPC_PKT:
7140 dissect_tds_rpc(next_tvb, pinfo, tds_tree, tds_info);
7141 break;
7142 case TDS_RESP_PKT:
7143 dissect_tds_resp(next_tvb, pinfo, tds_tree, tds_info);
7144 break;
7145 case TDS_LOGIN_PKT:
7146 dissect_tds45_login(next_tvb, pinfo, tds_tree, tds_info);
7147 break;
7148 case TDS_LOGIN7_PKT:
7149 dissect_tds7_login(next_tvb, pinfo, tds_tree, tds_info);
7150 break;
7151 case TDS_QUERY_PKT:
7152 dissect_tds_query_packet(next_tvb, pinfo, tds_tree, tds_info);
7153 break;
7154 case TDS5_QUERY_PKT:
7155 dissect_tds5_tokenized_request_packet(next_tvb, pinfo, tds_tree,
7156 tds_info);
7157 break;
7158 case TDS_SSPI_PKT:
7159 dissect_tds_nt(next_tvb, pinfo, tds_tree, offset - 8);
7160 break;
7161 case TDS_TRANS_MGR_PKT:
7162 dissect_tds_transmgr_packet(next_tvb, pinfo, tds_tree);
7163 break;
7164 case TDS_ATTENTION_PKT:
7165 break;
7166 case TDS_PRELOGIN_PKT:
7167 dissect_tds7_prelogin_packet(next_tvb, pinfo, tds_tree, tds_info, false);
7168 break;
7170 default:
7171 proto_tree_add_item(tds_tree, hf_tds_unknown_tds_packet, next_tvb, 0, -1, ENC_NA);
7172 break;
7174 } else {
7175 next_tvb = tvb_new_subset_remaining (tvb, offset);
7176 call_data_dissector(next_tvb, pinfo, tds_tree);
7178 pinfo->fragmented = save_fragmented;
7181 static int
7182 dissect_tds_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
7184 uint32_t type;
7186 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TDS");
7187 col_clear(pinfo->cinfo, COL_INFO);
7189 type = tvb_get_uint8(tvb, 0);
7190 if (type == TDS_SMP_PKT)
7192 /* if the type is SMP, it's shimmed in between TDS and lower layer */
7193 call_dissector(smp_handle, tvb, pinfo, tree);
7194 return tvb_captured_length(tvb);
7196 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "%s", val_to_str(type, packet_type_names, "Unknown Packet Type: %u"));
7198 dissect_netlib_buffer(tvb, pinfo, tree);
7200 col_set_fence(pinfo->cinfo, COL_INFO);
7202 return tvb_captured_length(tvb);
7205 static unsigned
7206 get_tds_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
7208 unsigned plen;
7209 uint8_t type;
7211 type = tvb_get_uint8(tvb, offset);
7213 switch (type)
7215 case TDS_SMP_PKT:
7216 /* Special case for SMP dissector */
7217 plen = tvb_get_letohl(tvb, offset + 4);
7218 break;
7219 case TDS_TLS_PKT:
7220 /* Special test for TLS to that we don't have lots of incorrect reports of malformed packets */
7221 plen = tvb_get_ntohs(tvb, offset + 3) + 5;
7222 break;
7223 default:
7224 plen = tvb_get_ntohs(tvb, offset + 2);
7225 break;
7228 return plen;
7231 static int
7232 dissect_tds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_)
7234 tcp_dissect_pdus(tvb, pinfo, tree, tds_desegment, 8, get_tds_pdu_len, dissect_tds_pdu, data);
7235 return tvb_captured_length(tvb);
7238 static bool
7239 dissect_tds_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
7241 int offset = 0;
7242 uint8_t type;
7243 uint8_t status;
7244 uint16_t plen;
7247 * If we don't have even enough data for a Netlib header,
7248 * just say it's not TDS.
7250 if (tvb_reported_length(tvb) < 8)
7251 return false;
7254 * Quickly scan all the data we have in order to see if
7255 * everything in it looks like Netlib traffic.
7259 * Check the type field.
7261 type = tvb_get_uint8(tvb, offset);
7262 if (!is_valid_tds_type(type))
7263 return false;
7266 * Check the status field
7268 status = tvb_get_uint8(tvb, offset + 1);
7269 if (!is_valid_tds_status(status))
7270 return false;
7273 * Get the length of the PDU.
7275 plen = tvb_get_ntohs(tvb, offset + 2);
7276 if (plen < 8) {
7278 * The length is less than the header length.
7279 * That's bogus.
7281 return false;
7284 if (!netlib_check_login_pkt(tvb, offset, pinfo, type))
7285 return false;
7288 * Now dissect it as TDS.
7290 dissect_tds(tvb, pinfo, tree, data);
7292 return true;
7295 static void
7296 version_convert( char *result, uint32_t hexver )
7298 /* Version string is major(8).minor(8).build(16) in big-endian order.
7299 * By specifying ENC_BIG_ENDIAN, the bytes have been swapped before we
7300 * see them.
7302 snprintf( result, ITEM_LABEL_LENGTH, "%d.%d.%d",
7303 (hexver >> 24) & 0xFF, (hexver >> 16) & 0xFF, (hexver & 0xFFFF));
7306 static void
7307 apply_tds_prefs(void) {
7308 tds_tcp_ports = prefs_get_range_value("tds", "tcp.port");
7311 /* Register the protocol with Wireshark */
7313 /* this format is required because a script is used to build the C function
7314 that calls all the protocol registration.
7317 void
7318 proto_register_tds(void)
7320 static hf_register_info hf[] = {
7322 /************************ Token definitions ************************/
7324 /* ALTMETADATA token */
7326 /* ALTROW token */
7328 /* CAPABILITY token */
7329 { &hf_tds_capability,
7330 { "Token - Capability", "tds.capability",
7331 FT_NONE, BASE_NONE, NULL, 0x0,
7332 NULL, HFILL }
7334 { &hf_tds_capability_length,
7335 { "Token length", "tds.capability.length",
7336 FT_UINT16, BASE_DEC, NULL, 0x0,
7337 NULL, HFILL }
7339 { &hf_tds_capability_captype,
7340 { "Capability type", "tds.capability.captype",
7341 FT_UINT8, BASE_DEC, VALS(tds_capability_type), 0x0,
7342 NULL, HFILL }
7344 { &hf_tds_capability_caplen,
7345 { "Capability len", "tds.capability.caplen",
7346 FT_UINT8, BASE_DEC, NULL, 0x0,
7347 NULL, HFILL }
7349 { &hf_tds_capability_req_lang,
7350 { "Language requests", "tds.capability.req.lang",
7351 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x02,
7352 NULL, HFILL }
7354 { &hf_tds_capability_req_rpc,
7355 { "RPC requests", "tds.capability.req.rpc",
7356 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x04,
7357 NULL, HFILL }
7359 { &hf_tds_capability_req_evt,
7360 { "RPC event notifications", "tds.capability.req.evt",
7361 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x08,
7362 NULL, HFILL }
7364 { &hf_tds_capability_req_mstmt,
7365 { "Multiple commands per request", "tds.capability.req.mstmt",
7366 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x10,
7367 NULL, HFILL }
7369 { &hf_tds_capability_req_bcp,
7370 { "Bulk copy requests", "tds.capability.req.bcp",
7371 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x20,
7372 NULL, HFILL }
7374 { &hf_tds_capability_req_cursor,
7375 { "Cursor command requests", "tds.capability.req.cursor",
7376 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x40,
7377 NULL, HFILL }
7379 { &hf_tds_capability_req_dynf,
7380 { "Dynamic SQL requests", "tds.capability.req.dynf",
7381 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x80,
7382 NULL, HFILL }
7384 { &hf_tds_capability_req_msg,
7385 { "TDS_MSG requests", "tds.capability.req.msg",
7386 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x01,
7387 NULL, HFILL }
7389 { &hf_tds_capability_req_param,
7390 { "TDS_DBRPC/TDS_PARAM requests", "tds.capability.req.param",
7391 FT_BOOLEAN, 8, TFS(&tfs_allowed_not_allowed), 0x02,
7392 NULL, HFILL }
7394 { &hf_tds_capability_data_int1,
7395 { "Support 1-byte unsigned ints", "tds.capability.data.int1",
7396 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7397 NULL, HFILL }
7399 { &hf_tds_capability_data_int2,
7400 { "Support 2-byte ints", "tds.capability.data.int2",
7401 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7402 NULL, HFILL }
7404 { &hf_tds_capability_data_int4,
7405 { "Support 4-byte ints", "tds.capability.data.int4",
7406 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7407 NULL, HFILL }
7409 { &hf_tds_capability_data_bit,
7410 { "Support bits", "tds.capability.data.bit",
7411 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7412 NULL, HFILL }
7414 { &hf_tds_capability_data_char,
7415 { "Support fixed-length character types", "tds.capability.data.char",
7416 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7417 NULL, HFILL }
7419 { &hf_tds_capability_data_vchar,
7420 { "Support variable-length character types", "tds.capability.data.vchar",
7421 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7422 NULL, HFILL }
7424 { &hf_tds_capability_data_bin,
7425 { "Support fixed-length binary", "tds.capability.data.bin",
7426 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7427 NULL, HFILL }
7429 { &hf_tds_capability_data_vbin,
7430 { "Support variable-length binary", "tds.capability.data.vbin",
7431 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7432 NULL, HFILL }
7434 { &hf_tds_capability_data_mny8,
7435 { "Support 8-byte money", "tds.capability.data.mny8",
7436 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7437 NULL, HFILL }
7439 { &hf_tds_capability_data_mny4,
7440 { "Support 4-byte money", "tds.capability.data.mny4",
7441 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7442 NULL, HFILL }
7444 { &hf_tds_capability_data_date8,
7445 { "Support 8-byte datetime", "tds.capability.data.date8",
7446 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7447 NULL, HFILL }
7449 { &hf_tds_capability_data_date4,
7450 { "Support 4-byte datetime", "tds.capability.data.date4",
7451 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7452 NULL, HFILL }
7454 { &hf_tds_capability_data_flt4,
7455 { "Support 4-byte float", "tds.capability.data.flt4",
7456 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7457 NULL, HFILL }
7459 { &hf_tds_capability_data_flt8,
7460 { "Support 8-byte float", "tds.capability.data.flt8",
7461 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7462 NULL, HFILL }
7464 { &hf_tds_capability_data_num,
7465 { "Support numeric", "tds.capability.data.num",
7466 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7467 NULL, HFILL }
7469 { &hf_tds_capability_data_text,
7470 { "Support text data", "tds.capability.data.text",
7471 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7472 NULL, HFILL }
7474 { &hf_tds_capability_data_image,
7475 { "Support image data", "tds.capability.data.image",
7476 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7477 NULL, HFILL }
7479 { &hf_tds_capability_data_dec,
7480 { "Support decimal", "tds.capability.data.dec",
7481 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7482 NULL, HFILL }
7484 { &hf_tds_capability_data_lchar,
7485 { "Support long variable-length character types", "tds.capability.data.lchar",
7486 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7487 NULL, HFILL }
7489 { &hf_tds_capability_data_lbin,
7490 { "Support long variable-length binary types", "tds.capability.data.lbin",
7491 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7492 NULL, HFILL }
7494 { &hf_tds_capability_data_intn,
7495 { "Support nullable ints", "tds.capability.data.intn",
7496 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7497 NULL, HFILL }
7499 { &hf_tds_capability_data_datetimen,
7500 { "Support nullable datetime", "tds.capability.data.datetimen",
7501 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7502 NULL, HFILL }
7504 { &hf_tds_capability_data_moneyn,
7505 { "Support nullable money", "tds.capability.data.moneyn",
7506 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7507 NULL, HFILL }
7509 { &hf_tds_capability_csr_prev,
7510 { "Support fetch previous cursor", "tds.capability.csr.prev",
7511 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7512 NULL, HFILL }
7514 { &hf_tds_capability_csr_first,
7515 { "Support fetch first cursor", "tds.capability.csr.first",
7516 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7517 NULL, HFILL }
7519 { &hf_tds_capability_csr_last,
7520 { "Support fetch last cursor", "tds.capability.csr.last",
7521 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7522 NULL, HFILL }
7524 { &hf_tds_capability_csr_abs,
7525 { "Support fetch absolute cursor", "tds.capability.csr.abs",
7526 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7527 NULL, HFILL }
7529 { &hf_tds_capability_csr_rel,
7530 { "Support fetch relative cursor", "tds.capability.csr.rel",
7531 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7532 NULL, HFILL }
7534 { &hf_tds_capability_csr_multi,
7535 { "Support fetch multi-row cursor", "tds.capability.csr.multi",
7536 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7537 NULL, HFILL }
7539 { &hf_tds_capability_con_oob,
7540 { "Support expedited attention", "tds.capability.con.oob",
7541 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7542 NULL, HFILL }
7544 { &hf_tds_capability_con_inband,
7545 { "Support non-expedited attention", "tds.capability.con.inband",
7546 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7547 NULL, HFILL }
7549 { &hf_tds_capability_con_logical,
7550 { "Support logical logout", "tds.capability.con.logout",
7551 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7552 NULL, HFILL }
7554 { &hf_tds_capability_proto_text,
7555 { "Support tokenized text/image", "tds.capability.proto.text",
7556 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7557 NULL, HFILL }
7559 { &hf_tds_capability_proto_bulk,
7560 { "Support tokenized bcp", "tds.capability.proto.bulk",
7561 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7562 NULL, HFILL }
7564 { &hf_tds_capability_req_urgevt,
7565 { "Use new event notification", "tds.capability.req.urgevt",
7566 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7567 NULL, HFILL }
7569 { &hf_tds_capability_data_sensitivity,
7570 { "Support sensitivity data", "tds.capability.data.sensitivity",
7571 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7572 NULL, HFILL }
7574 { &hf_tds_capability_data_boundary,
7575 { "Support boundary data", "tds.capability.data.boundary",
7576 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7577 NULL, HFILL }
7579 { &hf_tds_capability_proto_dynamic,
7580 { "Use DESCIN/DESCOUT dynamic protocol", "tds.capability.proto.dynamic",
7581 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7582 NULL, HFILL }
7584 { &hf_tds_capability_proto_dynproc,
7585 { "Prepend \"create proc\" to dynamic prepares", "tds.capability.proto.dynproc",
7586 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7587 NULL, HFILL }
7589 { &hf_tds_capability_data_fltn,
7590 { "Support nullable floats", "tds.capability.data.fltn",
7591 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7592 NULL, HFILL }
7594 { &hf_tds_capability_data_bitn,
7595 { "Support nullable bits", "tds.capability.data.bitn",
7596 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7597 NULL, HFILL }
7599 { &hf_tds_capability_data_int8,
7600 { "Support 8-byte ints", "tds.capability.data.int8",
7601 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7602 NULL, HFILL }
7604 { &hf_tds_capability_data_void,
7605 { "Undocumented TDS_DATA_VOID", "tds.capability.data.void",
7606 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7607 NULL, HFILL }
7609 { &hf_tds_capability_dol_bulk,
7610 { "Undocumented TDS_DOL_VOID", "tds.capability.dol.bulk",
7611 FT_BOOLEAN, 8, NULL, 0x20,
7612 NULL, HFILL }
7614 { &hf_tds_capability_object_java1,
7615 { "Support serialized java objects", "tds.capability.object.java1",
7616 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7617 NULL, HFILL }
7619 { &hf_tds_capability_object_char,
7620 { "Support streaming char data", "tds.capability.object.char",
7621 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7622 NULL, HFILL }
7624 { &hf_tds_capability_object_binary,
7625 { "Support streaming binary data", "tds.capability.object.binary",
7626 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7627 NULL, HFILL }
7629 { &hf_tds_capability_data_columnstatus,
7630 { "Add status field to ROW/PARAMS", "tds.capability.data.columnstatus",
7631 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7632 NULL, HFILL }
7634 { &hf_tds_capability_widetable,
7635 { "Allow wide-table tokens", "tds.capability.widetable",
7636 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7637 NULL, HFILL }
7639 { &hf_tds_capability_data_uint2,
7640 { "Support 2-byte unsigned ints", "tds.capability.data.uint2",
7641 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7642 NULL, HFILL }
7644 { &hf_tds_capability_data_uint4,
7645 { "Support 4-byte unsigned ints", "tds.capability.data.uint4",
7646 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7647 NULL, HFILL }
7649 { &hf_tds_capability_data_uint8,
7650 { "Support 8-byte unsigned ints", "tds.capability.data.uint8",
7651 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7652 NULL, HFILL }
7654 { &hf_tds_capability_data_uintn,
7655 { "Support nullable unsigned ints", "tds.capability.data.uintn",
7656 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7657 NULL, HFILL }
7659 { &hf_tds_capability_cur_implicit,
7660 { "Support TDS_CUR_DOPT_IMPLICIT", "tds.capability.cur.implicit",
7661 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7662 NULL, HFILL }
7664 { &hf_tds_capability_data_nlbin,
7665 { "Support UTF-16 LONGBINARY", "tds.capability.data.nlbin",
7666 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7667 NULL, HFILL }
7669 { &hf_tds_capability_image_nchar,
7670 { "Support UTF-16 IMAGE", "tds.capability.image.nchar",
7671 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7672 NULL, HFILL }
7674 { &hf_tds_capability_blob_nchar_16,
7675 { "Support BLOB serialization 0", "tds.capability.blob.nchar_16",
7676 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7677 NULL, HFILL }
7679 { &hf_tds_capability_blob_nchar_8,
7680 { "Support BLOB serialization 1", "tds.capability.blob.nchar_8",
7681 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7682 NULL, HFILL }
7684 { &hf_tds_capability_blob_nchar_scsu,
7685 { "Support BLOB serialization 2", "tds.capability.blob.nchar_scsu",
7686 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7687 NULL, HFILL }
7689 { &hf_tds_capability_data_date,
7690 { "Support DATE", "tds.capability.data.date",
7691 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7692 NULL, HFILL }
7694 { &hf_tds_capability_data_time,
7695 { "Support TIME", "tds.capability.data.time",
7696 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7697 NULL, HFILL }
7699 { &hf_tds_capability_data_interval,
7700 { "Support INTERVAL", "tds.capability.data.interval",
7701 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7702 NULL, HFILL }
7704 { &hf_tds_capability_csr_scroll,
7705 { "Support scrollable cursor", "tds.capability.csr.scroll",
7706 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7707 NULL, HFILL }
7709 { &hf_tds_capability_csr_sensitive,
7710 { "Support sens. scr csr", "tds.capability.csr.sensitive",
7711 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7712 NULL, HFILL }
7714 { &hf_tds_capability_csr_insensitive,
7715 { "Support insens. scr csr", "tds.capability.csr.insensitive",
7716 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7717 NULL, HFILL }
7719 { &hf_tds_capability_csr_semisensitive,
7720 { "Support semisens. scr csr", "tds.capability.csr.semisensitive",
7721 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7722 NULL, HFILL }
7724 { &hf_tds_capability_csr_keysetdriven,
7725 { "Support scr keyset driven csr", "tds.capability.csr.keysetdriven",
7726 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7727 NULL, HFILL }
7729 { &hf_tds_capability_req_srvpktsize,
7730 { "Support server-spec. packet size", "tds.capability.req.srvpktsize",
7731 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7732 NULL, HFILL }
7734 { &hf_tds_capability_data_unitext,
7735 { "Support UTF-16 text", "tds.capability.data.unitext",
7736 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7737 NULL, HFILL }
7739 { &hf_tds_capability_cap_clusterfailover,
7740 { "Support cluster failover", "tds.capability.cap.clusterfailover",
7741 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7742 NULL, HFILL }
7744 { &hf_tds_capability_data_sint1,
7745 { "Support signed 1-byte ints", "tds.capability.data.sint1",
7746 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7747 NULL, HFILL }
7749 { &hf_tds_capability_req_largeident,
7750 { "Support large identifiers", "tds.capability.req.largeident",
7751 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7752 NULL, HFILL }
7754 { &hf_tds_capability_req_blob_nchar_16,
7755 { "Support BLOB serialization 0 (new)", "tds.capability.req.blob_nchar_16",
7756 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7757 NULL, HFILL }
7759 { &hf_tds_capability_data_xml,
7760 { "Support XML type", "tds.capability.data.xml",
7761 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7762 NULL, HFILL }
7764 { &hf_tds_capability_req_curinfo3,
7765 { "Support TDS_CURINFO3 token", "tds.capability.req.curinfo3",
7766 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7767 NULL, HFILL }
7769 { &hf_tds_capability_req_dbrpc2,
7770 { "Support TDS_DBRPC2 token", "tds.capability.req.dbrpc2",
7771 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7772 NULL, HFILL }
7774 { &hf_tds_capability_res_nomsg,
7775 { "No sup. for TDS_MSG result", "tds.capability.res.nomsg",
7776 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7777 NULL, HFILL }
7779 { &hf_tds_capability_res_noeed,
7780 { "No sup. for TDS_EED token", "tds.capability.res.noeed",
7781 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7782 NULL, HFILL }
7784 { &hf_tds_capability_res_noparam,
7785 { "No sup. for TDS_PARAM return param", "tds.capability.res.noparam",
7786 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7787 NULL, HFILL }
7789 { &hf_tds_capability_data_noint1,
7790 { "No sup. for unsigned 1-byte ints", "tds.capability.data.noint1",
7791 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7792 NULL, HFILL }
7794 { &hf_tds_capability_data_noint2,
7795 { "No sup. for 2-byte ints", "tds.capability.data.noint2",
7796 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7797 NULL, HFILL }
7799 { &hf_tds_capability_data_noint4,
7800 { "No sup. for 4-byte ints", "tds.capability.data.noint4",
7801 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7802 NULL, HFILL }
7804 { &hf_tds_capability_data_nobit,
7805 { "No sup. for BIT type", "tds.capability.data.nobit",
7806 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7807 NULL, HFILL }
7809 { &hf_tds_capability_data_nochar,
7810 { "No sup. for fixed-length char", "tds.capability.data.nochar",
7811 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7812 NULL, HFILL }
7814 { &hf_tds_capability_data_novchar,
7815 { "No sup. for variable-length char", "tds.capability.data.novchar",
7816 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7817 NULL, HFILL }
7819 { &hf_tds_capability_data_nobin,
7820 { "No sup. for fixed-length binary", "tds.capability.data.nobin",
7821 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7822 NULL, HFILL }
7824 { &hf_tds_capability_data_novbin,
7825 { "No sup. for variable-length binary", "tds.capability.data.novbin",
7826 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7827 NULL, HFILL }
7829 { &hf_tds_capability_data_nomny8,
7830 { "No sup. for 8-byte money", "tds.capability.data.nomny8",
7831 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7832 NULL, HFILL }
7834 { &hf_tds_capability_data_nomny4,
7835 { "No sup. for 4-byte money", "tds.capability.data.nomny4",
7836 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7837 NULL, HFILL }
7839 { &hf_tds_capability_data_nodate8,
7840 { "No sup. for 8-byte datetime", "tds.capability.data.nodate8",
7841 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7842 NULL, HFILL }
7844 { &hf_tds_capability_data_nodate4,
7845 { "No sup. for 4-byte datetime", "tds.capability.data.nodate4",
7846 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7847 NULL, HFILL }
7849 { &hf_tds_capability_data_noflt4,
7850 { "No sup. for 4-byte floats", "tds.capability.data.noflt4",
7851 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7852 NULL, HFILL }
7854 { &hf_tds_capability_data_noflt8,
7855 { "No sup. for 8-byte floats", "tds.capability.data.noflt8",
7856 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7857 NULL, HFILL }
7859 { &hf_tds_capability_data_nonum,
7860 { "No sup. for NUMERIC", "tds.capability.data.nonum",
7861 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7862 NULL, HFILL }
7864 { &hf_tds_capability_data_notext,
7865 { "No sup. for TEXT", "tds.capability.data.notext",
7866 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7867 NULL, HFILL }
7869 { &hf_tds_capability_data_noimage,
7870 { "No sup. for IMAGE", "tds.capability.data.noimage",
7871 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7872 NULL, HFILL }
7874 { &hf_tds_capability_data_nodec,
7875 { "No sup. for DECIMAL", "tds.capability.data.nodec",
7876 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7877 NULL, HFILL }
7879 { &hf_tds_capability_data_nolchar,
7880 { "No sup. for long character types", "tds.capability.data.nolchar",
7881 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7882 NULL, HFILL }
7884 { &hf_tds_capability_data_nolbin,
7885 { "No sup. for long binary types", "tds.capability.data.nolbin",
7886 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7887 NULL, HFILL }
7889 { &hf_tds_capability_data_nointn,
7890 { "No sup. for nullable ints", "tds.capability.data.nointn",
7891 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7892 NULL, HFILL }
7894 { &hf_tds_capability_data_nodatetimen,
7895 { "No sup. for nullable datetime", "tds.capability.data.nodatetimen",
7896 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7897 NULL, HFILL }
7899 { &hf_tds_capability_data_nomoneyn,
7900 { "No sup. for nullable money", "tds.capability.data.nomoneyn",
7901 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7902 NULL, HFILL }
7904 { &hf_tds_capability_con_nooob,
7905 { "No sup. for expedited attentions", "tds.capability.con.nooob",
7906 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7907 NULL, HFILL }
7909 { &hf_tds_capability_con_noinband,
7910 { "No sup. for non-expedited attentions", "tds.capability.con.noinband",
7911 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7912 NULL, HFILL }
7914 { &hf_tds_capability_proto_notext,
7915 { "No sup. for tokenized text/image", "tds.capability.proto.notext",
7916 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7917 NULL, HFILL }
7919 { &hf_tds_capability_proto_nobulk,
7920 { "No sup. for tokenized BCP", "tds.capability.proto.nobulk",
7921 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7922 NULL, HFILL }
7924 { &hf_tds_capability_data_nosensitivity,
7925 { "No sup. for sensitivity", "tds.capability.data.nosensitivity",
7926 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7927 NULL, HFILL }
7929 { &hf_tds_capability_data_noboundary,
7930 { "No sup. for BOUNDARY", "tds.capability.data.noboundary",
7931 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
7932 NULL, HFILL }
7934 { &hf_tds_capability_res_notdsdebug,
7935 { "No sup. for TDS_DEBUG token", "tds.capability.res.notdsdebug",
7936 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7937 NULL, HFILL }
7939 { &hf_tds_capability_res_nostripblanks,
7940 { "Do not strip blanks from CHAR", "tds.capability.res.nostripblanks",
7941 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7942 NULL, HFILL }
7944 { &hf_tds_capability_data_noint8,
7945 { "No sup. for 8-byte ints", "tds.capability.data.noint8",
7946 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7947 NULL, HFILL }
7949 { &hf_tds_capability_object_nojava1,
7950 { "No sup. for serialized Java objects", "tds.capability.object.nojava1",
7951 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7952 NULL, HFILL }
7954 { &hf_tds_capability_object_nochar,
7955 { "No sup. for streaming char data", "tds.capability.object.nochar",
7956 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7957 NULL, HFILL }
7959 { &hf_tds_capability_data_nocolumnstatus,
7960 { "No sup. for columnstatus byte", "tds.capability.data.nocolumnstatus",
7961 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7962 NULL, HFILL }
7964 { &hf_tds_capability_object_nobinary,
7965 { "No sup. for streaming binary data", "tds.capability.object.nobinary",
7966 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
7967 NULL, HFILL }
7969 { &hf_tds_capability_data_nouint2,
7970 { "No sup. for 2-byte unsigned ints", "tds.capability.data.nouint2",
7971 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
7972 NULL, HFILL }
7974 { &hf_tds_capability_data_nouint4,
7975 { "No sup. for 4-byte unsigned ints", "tds.capability.data.nouint4",
7976 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
7977 NULL, HFILL }
7979 { &hf_tds_capability_data_nouint8,
7980 { "No sup. for 8-byte unsigned ints", "tds.capability.data.nouint8",
7981 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
7982 NULL, HFILL }
7984 { &hf_tds_capability_data_nouintn,
7985 { "No sup. for nullable unsigned ints", "tds.capability.data.nouintn",
7986 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
7987 NULL, HFILL }
7989 { &hf_tds_capability_no_widetables,
7990 { "No sup. for wide-table tokens", "tds.capability.no_widetables",
7991 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
7992 NULL, HFILL }
7994 { &hf_tds_capability_data_nonlbin,
7995 { "No sup. for LONGBINARY with UTF-16", "tds.capability.data.nonlbin",
7996 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
7997 NULL, HFILL }
7999 { &hf_tds_capability_image_nonchar,
8000 { "No sup. for IMAGE with UTF-16", "tds.capability.image.nonchar",
8001 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
8002 NULL, HFILL }
8004 { &hf_tds_capability_blob_nonchar_16,
8005 { "No sup. for BLOB subtype 0", "tds.capability.blob.nonchar_16",
8006 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
8007 NULL, HFILL }
8009 { &hf_tds_capability_blob_nonchar_8,
8010 { "No sup. for BLOB subtype 1", "tds.capability.blob.nonchar_8",
8011 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
8012 NULL, HFILL }
8014 { &hf_tds_capability_blob_nonchar_scsu,
8015 { "No sup. for BLOB subtype 2", "tds.capability.blob.nonchar_scsu",
8016 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
8017 NULL, HFILL }
8019 { &hf_tds_capability_data_nodate,
8020 { "No sup. for DATE", "tds.capability.data.nodate",
8021 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
8022 NULL, HFILL }
8024 { &hf_tds_capability_data_notime,
8025 { "No sup. for TIME", "tds.capability.data.notime",
8026 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
8027 NULL, HFILL }
8029 { &hf_tds_capability_data_nointerval,
8030 { "No sup. for INTERVAL", "tds.capability.data.nointerval",
8031 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
8032 NULL, HFILL }
8034 { &hf_tds_capability_data_nounitext,
8035 { "No sup. for TEXT with UTF-16", "tds.capability.data.nounitext",
8036 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
8037 NULL, HFILL }
8039 { &hf_tds_capability_data_nosint1,
8040 { "No sup. for 1-byte signed ints", "tds.capability.data.nosint1",
8041 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
8042 NULL, HFILL }
8044 { &hf_tds_capability_no_largeident,
8045 { "No sup. for large identifiers", "tds.capability.no_largeident",
8046 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
8047 NULL, HFILL }
8049 { &hf_tds_capability_no_blob_nchar_16,
8050 { "No sup. for BLOB type 0 (replacement)", "tds.capability.no_blob_nchar_16",
8051 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
8052 NULL, HFILL }
8054 { &hf_tds_capability_no_srvpktsize,
8055 { "No sup. for server spec pkt size", "tds.capability.no_srvpktsize",
8056 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
8057 NULL, HFILL }
8059 { &hf_tds_capability_data_noxml,
8060 { "No sup. for XML data", "tds.capability.data.noxml",
8061 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08,
8062 NULL, HFILL }
8064 { &hf_tds_capability_no_nint_return_value,
8065 { "No sup. for non-int return value", "tds.capability.no_nint_return_value",
8066 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
8067 NULL, HFILL }
8069 { &hf_tds_capability_res_noxnldata,
8070 { "No req. for ROWFMT2 data", "tds.capability.res.noxnldata",
8071 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
8072 NULL, HFILL }
8074 { &hf_tds_capability_res_suppress_fmt,
8075 { "Srvr can suppress ROWFMT for DYNAMIC", "tds.capability.res.suppress_fmt",
8076 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
8077 NULL, HFILL }
8079 { &hf_tds_capability_res_suppress_doneinproc,
8080 { "Srvr can suppress DONEINPROC", "tds.capability.res.suppress_doneinproc",
8081 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
8082 NULL, HFILL }
8084 { &hf_tds_capability_res_force_rowfmt2,
8085 { "Force use of ROWFMT2", "tds.capability.res.force_rowfmt2",
8086 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
8087 NULL, HFILL }
8090 /* COLINFO token (TDS_COLFMT_TOKEN) */
8091 { &hf_tds_colfmt,
8092 { "Token - ColFormat", "tds.colfmt",
8093 FT_NONE, BASE_NONE, NULL, 0x0,
8094 NULL, HFILL }
8096 { &hf_tds_colfmt_length,
8097 { "Token length - ColFormat", "tds.colfmt.length",
8098 FT_UINT16, BASE_DEC, NULL, 0x0,
8099 NULL, HFILL }
8101 { &hf_tds_colfmt_column,
8102 { "Column", "tds.colfmt.column",
8103 FT_NONE, BASE_NONE, NULL, 0x0,
8104 NULL, HFILL }
8106 { &hf_tds_colfmt_utype,
8107 { "ColFormat - Column Usertype", "tds.colfmt.utype",
8108 FT_UINT32, BASE_DEC, NULL, 0x0,
8109 NULL, HFILL }
8111 { &hf_tds_colfmt_ctype,
8112 { "ColFormat - Column Datatype", "tds.colfmt.ctype",
8113 FT_UINT8, BASE_DEC, &tds_data_type_names, 0x0,
8114 NULL, HFILL }
8116 { &hf_tds_colfmt_csize,
8117 { "ColFormat - Column size", "tds.colfmt.csize",
8118 FT_UINT8, BASE_DEC, NULL, 0x0,
8119 NULL, HFILL }
8121 { &hf_tds_colfmt_csize_long,
8122 { "ColFormat - Column size - long", "tds.colfmt.csize_long",
8123 FT_UINT32, BASE_DEC, NULL, 0x0,
8124 NULL, HFILL }
8126 { &hf_tds_colfmt_text_tablename,
8127 { "ColFormat - Text Tablename", "tds.colfmt.text_tablename",
8128 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8129 NULL, HFILL }
8132 /* COLNAME token (TDS_COL_NAME_TOKEN) */
8133 { &hf_tds_colname,
8134 { "Token - ColName", "tds.colname",
8135 FT_NONE, BASE_NONE, NULL, 0x0,
8136 NULL, HFILL }
8138 { &hf_tds_colname_length,
8139 { "Token length - ColName", "tds.colname.length",
8140 FT_UINT16, BASE_DEC, NULL, 0x0,
8141 NULL, HFILL }
8143 { &hf_tds_colname_column,
8144 { "Column", "tds.colname.column",
8145 FT_NONE, BASE_NONE, NULL, 0x0,
8146 NULL, HFILL }
8148 { &hf_tds_colname_name,
8149 { "Column name", "tds.colname.name",
8150 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8151 NULL, HFILL }
8154 /* COLMETADATA token (TDS7_COL_METADATA_TOKEN) */
8155 { &hf_tds_colmetadata,
8156 { "Token - ColumnMetaData", "tds.colmetadata",
8157 FT_NONE, BASE_NONE, NULL, 0x0,
8158 NULL, HFILL }
8160 { &hf_tds_colmetadata_columns,
8161 { "Columns", "tds.colmetadata.columns",
8162 FT_UINT16, BASE_DEC, NULL, 0x0,
8163 NULL, HFILL }
8165 { &hf_tds_colmetadata_usertype32,
8166 { "Usertype", "tds.colmetadata.usertype",
8167 FT_UINT32, BASE_DEC, NULL, 0x0,
8168 NULL, HFILL }
8170 { &hf_tds_colmetadata_usertype16,
8171 { "Usertype", "tds.colmetadata.usertype",
8172 FT_UINT16, BASE_DEC, NULL, 0x0,
8173 NULL, HFILL }
8175 { &hf_tds_colmetadata_results_token_flags,
8176 { "Flags", "tds.colmetadata.results_token_flags",
8177 FT_UINT16, BASE_HEX, NULL, 0x0,
8178 NULL, HFILL }
8180 { &hf_tds_colmetadata_results_token_type,
8181 { "Type", "tds.colmetadata.results_token_type",
8182 FT_UINT8, BASE_DEC, NULL, 0x0,
8183 NULL, HFILL }
8185 { &hf_tds_colmetadata_csize,
8186 { "Type size", "tds.colmetadata.type_size",
8187 FT_UINT8, BASE_DEC, NULL, 0x0,
8188 NULL, HFILL }
8190 { &hf_tds_colmetadata_large2_type_size,
8191 { "Large type size", "tds.colmetadata.large_type_size",
8192 FT_UINT16, BASE_HEX, NULL, 0x0,
8193 NULL, HFILL }
8195 { &hf_tds_colmetadata_large4_type_size,
8196 { "Large type size", "tds.colmetadata.large_type_size",
8197 FT_UINT32, BASE_HEX, NULL, 0x0,
8198 NULL, HFILL }
8200 { &hf_tds_colmetadata_collate_codepage,
8201 { "Collate codepage", "tds.colmetadata.collate_codepage",
8202 FT_UINT16, BASE_DEC, NULL, 0x0,
8203 NULL, HFILL }
8205 { &hf_tds_colmetadata_collate_flags,
8206 { "Collate flags", "tds.colmetadata.collate_flags",
8207 FT_UINT16, BASE_HEX, NULL, 0x0,
8208 NULL, HFILL }
8210 { &hf_tds_colmetadata_collate_charset_id,
8211 { "Collate charset ID", "tds.colmetadata.collate_charset_id",
8212 FT_UINT8, BASE_DEC, NULL, 0x0,
8213 NULL, HFILL }
8215 { &hf_tds_colmetadata_precision,
8216 { "Precision", "tds.colmetadata.precision",
8217 FT_UINT8, BASE_DEC, NULL, 0x0,
8218 NULL, HFILL }
8220 { &hf_tds_colmetadata_scale,
8221 { "Scale", "tds.colmetadata.scale",
8222 FT_UINT8, BASE_DEC, NULL, 0x0,
8223 NULL, HFILL }
8225 { &hf_tds_colmetadata_colname_length,
8226 { "Column name length", "tds.colmetadata.colname_length",
8227 FT_UINT8, BASE_DEC, NULL, 0x0,
8228 NULL, HFILL }
8230 { &hf_tds_colmetadata_colname,
8231 { "Column Name", "tds.colmetadata.colname",
8232 FT_STRING, BASE_NONE, NULL, 0x0,
8233 NULL, HFILL }
8235 { &hf_tds_colmetadata_table_name_parts,
8236 { "Table name parts", "tds.colmetadata.table_name_parts",
8237 FT_UINT8, BASE_DEC, NULL, 0x0,
8238 NULL, HFILL }
8240 { &hf_tds_colmetadata_table_name,
8241 { "Table name", "tds.colmetadata.table_name",
8242 FT_STRING, BASE_NONE, NULL, 0x0,
8243 NULL, HFILL }
8245 { &hf_tds_colmetadata_table_name_length,
8246 { "Table name length", "tds.colmetadata.table_name_length",
8247 FT_UINT16, BASE_DEC, NULL, 0x0,
8248 NULL, HFILL }
8250 { &hf_tds_colmetadata_field,
8251 { "Field", "tds.colmetadata.field",
8252 FT_NONE, BASE_NONE, NULL, 0x0,
8253 NULL, HFILL }
8255 { &hf_tds_colmetadata_flags_nullable,
8256 { "Nullable", "tds.colmetadata.flags.nullable",
8257 FT_BOOLEAN, 16, NULL, 0x8000,
8258 NULL, HFILL }
8260 { &hf_tds_colmetadata_flags_casesen,
8261 { "Case sensitive", "tds.colmetadata.flags.casesen",
8262 FT_BOOLEAN, 16, NULL, 0x4000,
8263 NULL, HFILL }
8265 { &hf_tds_colmetadata_flags_updateable,
8266 { "Updateable", "tds.colmetadata.flags.updateable",
8267 FT_BOOLEAN, 16, NULL, 0x3000,
8268 NULL, HFILL }
8270 { &hf_tds_colmetadata_flags_identity,
8271 { "Identity", "tds.colmetadata.flags.identity",
8272 FT_BOOLEAN, 16, NULL, 0x0800,
8273 NULL, HFILL }
8275 { &hf_tds_colmetadata_flags_computed,
8276 { "Computed", "tds.colmetadata.flags.computed",
8277 FT_BOOLEAN, 16, NULL, 0x0400,
8278 NULL, HFILL }
8280 { &hf_tds_colmetadata_flags_reservedodbc,
8281 { "Reserved ODBC", "tds.colmetadata.flags.reservedodbc",
8282 FT_BOOLEAN, 16, NULL, 0x0300,
8283 NULL, HFILL }
8285 { &hf_tds_colmetadata_flags_fixedlenclrtype,
8286 { "Fixed length CLR type", "tds.colmetadata.flags.fixedlenclrtype",
8287 FT_BOOLEAN, 16, NULL, 0x0080,
8288 NULL, HFILL }
8290 { &hf_tds_colmetadata_flags_sparsecolumnset,
8291 { "Sparse column set", "tds.colmetadata.flags.sparsecolumnset",
8292 FT_BOOLEAN, 16, NULL, 0x0020,
8293 NULL, HFILL }
8295 { &hf_tds_colmetadata_flags_encrypted,
8296 { "Encrypted", "tds.colmetadata.flags.encrypted",
8297 FT_BOOLEAN, 16, NULL, 0x0010,
8298 NULL, HFILL }
8300 { &hf_tds_colmetadata_flags_hidden,
8301 { "Hidden", "tds.colmetadata.flags.hidden",
8302 FT_BOOLEAN, 16, NULL, 0x0004,
8303 NULL, HFILL }
8305 { &hf_tds_colmetadata_flags_key,
8306 { "Flags", "tds.colmetadata.flags.key",
8307 FT_BOOLEAN, 16, NULL, 0x0002,
8308 NULL, HFILL }
8310 { &hf_tds_colmetadata_flags_nullableunknown,
8311 { "Nullable unknown", "tds.colmetadata.flags.nullableunknown",
8312 FT_BOOLEAN, 16, NULL, 0x0001,
8313 NULL, HFILL }
8315 { &hf_tds_colmetadata_maxbytesize,
8316 { "Max byte size", "tds.colmetadata.maxbytesize",
8317 FT_UINT16, BASE_DEC, NULL, 0x0,
8318 NULL, HFILL }
8320 { &hf_tds_colmetadata_dbname_length,
8321 { "Database name length", "tds.colmetadata.dbname_length",
8322 FT_UINT8, BASE_DEC, NULL, 0x0,
8323 NULL, HFILL }
8325 { &hf_tds_colmetadata_dbname,
8326 { "Database name length", "tds.colmetadata.dbname",
8327 FT_STRING, BASE_NONE, NULL, 0x0,
8328 NULL, HFILL }
8330 { &hf_tds_colmetadata_schemaname_length,
8331 { "Schema name length", "tds.colmetadata.schemaname_length",
8332 FT_UINT8, BASE_DEC, NULL, 0x0,
8333 NULL, HFILL }
8335 { &hf_tds_colmetadata_schemaname,
8336 { "Schema name", "tds.colmetadata.schemaname",
8337 FT_STRING, BASE_NONE, NULL, 0x0,
8338 NULL, HFILL }
8340 { &hf_tds_colmetadata_typename_length,
8341 { "Type name length", "tds.colmetadata.typename_length",
8342 FT_UINT8, BASE_DEC, NULL, 0x0,
8343 NULL, HFILL }
8345 { &hf_tds_colmetadata_typename,
8346 { "Type name", "tds.colmetadata.typename",
8347 FT_STRING, BASE_NONE, NULL, 0x0,
8348 NULL, HFILL }
8350 { &hf_tds_colmetadata_assemblyqualifiedname_length,
8351 { "Assembly qualified name length", "tds.colmetadata.assemblyqualifiedname_length",
8352 FT_UINT16, BASE_DEC, NULL, 0x0,
8353 NULL, HFILL }
8355 { &hf_tds_colmetadata_assemblyqualifiedname,
8356 { "Assembly qualified name", "tds.colmetadata.assemblyqualifiedname",
8357 FT_STRING, BASE_NONE, NULL, 0x0,
8358 NULL, HFILL }
8360 { &hf_tds_colmetadata_owningschema_length,
8361 { "Owning schema name length", "tds.colmetadata.owningschema_length",
8362 FT_UINT8, BASE_DEC, NULL, 0x0,
8363 NULL, HFILL }
8365 { &hf_tds_colmetadata_owningschema,
8366 { "Owning schema name", "tds.colmetadata.owningschema",
8367 FT_STRING, BASE_NONE, NULL, 0x0,
8368 NULL, HFILL }
8370 { &hf_tds_colmetadata_xmlschemacollection_length,
8371 { "XML schema collection length", "tds.colmetadata.xmlschemacollection_length",
8372 FT_UINT8, BASE_DEC, NULL, 0x0,
8373 NULL, HFILL }
8375 { &hf_tds_colmetadata_xmlschemacollection,
8376 { "XML schema collection", "tds.colmetadata.xmlschemacollection",
8377 FT_STRING, BASE_NONE, NULL, 0x0,
8378 NULL, HFILL }
8381 /* CONTROL token (TDS_CONTROL_TOKEN) */
8382 { &hf_tds_control,
8383 { "Token - Control", "tds.control",
8384 FT_NONE, BASE_NONE, NULL, 0x0,
8385 NULL, HFILL }
8387 { &hf_tds_control_length,
8388 { "Token Length - Control", "tds.control.length",
8389 FT_UINT16, BASE_DEC, NULL, 0x0,
8390 NULL, HFILL }
8392 { &hf_tds_control_fmt,
8393 { "Control - Fmt", "tds.control.fmt",
8394 FT_UINT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
8395 NULL, HFILL }
8398 /* CURCLOSE token (TDS_CURCLOSE_TOKEN) */
8399 { &hf_tds_curclose,
8400 { "Token - CurClose", "tds.curclose",
8401 FT_NONE, BASE_NONE, NULL, 0x0,
8402 NULL, HFILL }
8404 { &hf_tds_curclose_length,
8405 { "Token Length - CurClose", "tds.curclose.length",
8406 FT_UINT16, BASE_DEC, NULL, 0x0,
8407 NULL, HFILL }
8409 { &hf_tds_curclose_cursorid,
8410 { "CursorId", "tds.curclose.cursorid",
8411 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
8412 NULL, HFILL }
8414 { &hf_tds_curclose_cursor_name,
8415 { "Cursorname", "tds.curclose.cursor.name_len",
8416 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8417 NULL, HFILL }
8419 { &hf_tds_curclose_option_deallocate,
8420 { "Deallocate", "tds.curclose.option.deallocate",
8421 FT_BOOLEAN, 8, NULL, 0x01,
8422 NULL, HFILL }
8425 /* CURDECLARE token (TDS_CURDECLARE_TOKEN) */
8426 { &hf_tds_curdeclare,
8427 { "Token - CurDeclare", "tds.curdeclare",
8428 FT_NONE, BASE_NONE, NULL, 0x0,
8429 NULL, HFILL }
8431 { &hf_tds_curdeclare_length,
8432 { "Token Length - CurDeclare", "tds.curdeclare.length",
8433 FT_UINT16, BASE_DEC, NULL, 0x0,
8434 NULL, HFILL }
8436 { &hf_tds_curdeclare_cursor_name,
8437 { "Cursorname", "tds.curdeclare.cursor.name_len",
8438 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8439 NULL, HFILL }
8441 { &hf_tds_curdeclare_options,
8442 { "Options", "tds.curdeclare.options",
8443 FT_UINT8, BASE_HEX, NULL, 0x0,
8444 NULL, HFILL }
8446 { &hf_tds_curdeclare_options_rdonly,
8447 { "Read Only", "tds.curdeclare.options.rdonly",
8448 FT_BOOLEAN, 8, NULL, 0x01,
8449 NULL, HFILL }
8451 { &hf_tds_curdeclare_options_updatable,
8452 { "Updatable", "tds.curdeclare.options.updatable",
8453 FT_BOOLEAN, 8, NULL, 0x02,
8454 NULL, HFILL }
8456 { &hf_tds_curdeclare_options_sensitive,
8457 { "Sensitive", "tds.curdeclare.options.sensitive",
8458 FT_BOOLEAN, 8, NULL, 0x04,
8459 NULL, HFILL }
8461 { &hf_tds_curdeclare_options_dynamic,
8462 { "Dynamic", "tds.curdeclare.options.dynamic",
8463 FT_BOOLEAN, 8, NULL, 0x08,
8464 NULL, HFILL }
8466 { &hf_tds_curdeclare_options_implicit,
8467 { "Implicit", "tds.curdeclare.options.implicit",
8468 FT_BOOLEAN, 8, NULL, 0x10,
8469 NULL, HFILL }
8471 { &hf_tds_curdeclare_status_parameterized,
8472 { "Status Parameterized", "tds.curdeclare.status.parameterized",
8473 FT_BOOLEAN, 8, NULL, 0x01,
8474 NULL, HFILL }
8476 { &hf_tds_curdeclare_statement,
8477 { "Statement", "tds.curdeclare.statement",
8478 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8479 NULL, HFILL }
8481 { &hf_tds_curdeclare_update_columns_num,
8482 { "Number of updatable columns", "tds.curdeclare.update_columns_num",
8483 FT_UINT8, BASE_DEC, NULL, 0x0,
8484 NULL, HFILL }
8486 { &hf_tds_curdeclare_update_columns_name,
8487 { "Updatable Column Name", "tds.curdeclare.update_columns_name",
8488 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8489 NULL, HFILL }
8492 /* CURFETCH token (TDS_CURFETCH_TOKEN) */
8493 { &hf_tds_curfetch,
8494 { "Token - CurFetch", "tds.curfetch",
8495 FT_NONE, BASE_NONE, NULL, 0x0,
8496 NULL, HFILL }
8498 { &hf_tds_curfetch_length,
8499 { "Token Length - CurFetch", "tds.curfetch.length",
8500 FT_UINT16, BASE_DEC, NULL, 0x0,
8501 NULL, HFILL }
8503 { &hf_tds_curfetch_cursorid,
8504 { "CursorId", "tds.curfetch.cursorid",
8505 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
8506 NULL, HFILL }
8508 { &hf_tds_curfetch_cursor_name,
8509 { "CurFetch - Cursorname", "tds.curfetch.cursor.name_len",
8510 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8511 NULL, HFILL }
8513 { &hf_tds_curfetch_type,
8514 { "CurFetch - Type", "tds.curinfo.type",
8515 FT_UINT8, BASE_DEC, VALS(tds_curfetch_types), 0x0,
8516 NULL, HFILL }
8518 { &hf_tds_curfetch_rowcnt,
8519 { "CurFetch - Rowcnt", "tds.curfetch.rowcnt",
8520 FT_INT32, BASE_DEC, NULL, 0x0,
8521 NULL, HFILL }
8524 /* CURINFO token (TDS_CURINFO_TOKEN) */
8525 { &hf_tds_curinfo,
8526 { "Token - CurInfo", "tds.curinfo",
8527 FT_NONE, BASE_NONE, NULL, 0x0,
8528 NULL, HFILL }
8530 { &hf_tds_curinfo_length,
8531 { "Token Length - Curinfo", "tds.curinfo.length",
8532 FT_UINT16, BASE_DEC, NULL, 0x0,
8533 NULL, HFILL }
8535 { &hf_tds_curinfo_cursorid,
8536 { "CursorId", "tds.curinfo.cursorid",
8537 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
8538 NULL, HFILL }
8540 { &hf_tds_curinfo_cursor_name,
8541 { "Cursorname", "tds.curinfo.cursor.name_len",
8542 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8543 NULL, HFILL }
8545 { &hf_tds_curinfo_cursor_command,
8546 { "Cursor Command", "tds.curinfo.cursor.command",
8547 FT_UINT8, BASE_DEC, VALS(tds_curinfo_commands), 0x0,
8548 NULL, HFILL }
8550 { &hf_tds_curinfo_cursor_status,
8551 { "Cursor Status", "tds.curinfo.cursor.status",
8552 FT_UINT16, BASE_HEX, NULL, 0x0,
8553 NULL, HFILL }
8555 { &hf_tds_curinfo_cursor_status_declared,
8556 { "Declared", "tds.curinfo.cursor.status.declared",
8557 FT_BOOLEAN, 16, NULL, 0x0001,
8558 NULL, HFILL }
8560 { &hf_tds_curinfo_cursor_status_open,
8561 { "Open", "tds.curinfo.cursor.status.open",
8562 FT_BOOLEAN, 16, NULL, 0x0002,
8563 NULL, HFILL }
8565 { &hf_tds_curinfo_cursor_status_closed,
8566 { "Closed", "tds.curinfo.cursor.status.closed",
8567 FT_BOOLEAN, 16, NULL, 0x0004,
8568 NULL, HFILL }
8570 { &hf_tds_curinfo_cursor_status_rdonly,
8571 { "Read only", "tds.curinfo.cursor.status.rdonly",
8572 FT_BOOLEAN, 16, NULL, 0x0008,
8573 NULL, HFILL }
8575 { &hf_tds_curinfo_cursor_status_updatable,
8576 { "Updatable", "tds.curinfo.cursor.status.updatable",
8577 FT_BOOLEAN, 16, NULL, 0x0010,
8578 NULL, HFILL }
8580 { &hf_tds_curinfo_cursor_status_rowcnt,
8581 { "Rowcount valid", "tds.curinfo.cursor.status.rowcnt",
8582 FT_BOOLEAN, 16, NULL, 0x0020,
8583 NULL, HFILL }
8585 { &hf_tds_curinfo_cursor_status_dealloc,
8586 { "Deallocated", "tds.curinfo.cursor.status.dealloc",
8587 FT_BOOLEAN, 16, NULL, 0x0040,
8588 NULL, HFILL }
8590 { &hf_tds_curinfo_cursor_rowcnt,
8591 { "Cursor Rowcnt", "tds.curinfo.cursor.rowcnt",
8592 FT_UINT32, BASE_DEC, NULL, 0x0,
8593 NULL, HFILL }
8596 /* CUROPEN token (TDS_CUROPEN_TOKEN) */
8597 { &hf_tds_curopen,
8598 { "Token - CurOpen", "tds.curopen",
8599 FT_NONE, BASE_NONE, NULL, 0x0,
8600 NULL, HFILL }
8602 { &hf_tds_curopen_length,
8603 { "Token Length - CurOpen", "tds.curopen.length",
8604 FT_UINT16, BASE_DEC, NULL, 0x0,
8605 NULL, HFILL }
8607 { &hf_tds_curopen_cursorid,
8608 { "CursorId", "tds.curopen.cursorid",
8609 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
8610 NULL, HFILL }
8612 { &hf_tds_curopen_cursor_name,
8613 { "Cursorname", "tds.curopen.cursor.name_len",
8614 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8615 NULL, HFILL }
8617 { &hf_tds_curopen_status_parameterized,
8618 { "Status Parameterized", "tds.curopen.status.parameterized",
8619 FT_BOOLEAN, 8, NULL, 0x01,
8620 NULL, HFILL }
8623 /* DBRPC token (TDS5_DBRPC_TOKEN) */
8624 { &hf_tds_dbrpc,
8625 { "Token - DBRPC", "tds.dbrpc",
8626 FT_NONE, BASE_NONE, NULL, 0x0,
8627 NULL, HFILL }
8629 { &hf_tds_dbrpc_length,
8630 { "Token Length - DBRPC", "tds.dbrpc.length",
8631 FT_UINT16, BASE_DEC, NULL, 0x0,
8632 NULL, HFILL }
8634 { &hf_tds_dbrpc_rpcname_len,
8635 { "DBRPC - RPC Name Length", "tds.dbrpc.rpcname_len",
8636 FT_UINT16, BASE_DEC, NULL, 0x0,
8637 NULL, HFILL }
8639 { &hf_tds_dbrpc_rpcname,
8640 { "DBRPC - RPC Name", "tds.dbrpc.rpcname",
8641 FT_STRING, BASE_NONE, NULL, 0x0,
8642 NULL, HFILL }
8644 { &hf_tds_dbrpc_options,
8645 { "DBRPC - Options", "tds.dbrpc.options",
8646 FT_UINT16, BASE_HEX, NULL, 0x0,
8647 NULL, HFILL }
8649 { &hf_tds_dbrpc_options_recompile,
8650 { "Recompile", "tds.dbrpc.options.recompile",
8651 FT_BOOLEAN, 16, NULL, 0x0001,
8652 NULL, HFILL }
8654 { &hf_tds_dbrpc_options_params,
8655 { "Has parameters", "tds.dbrpc.options.params",
8656 FT_BOOLEAN, 16, NULL, 0x0002,
8657 NULL, HFILL }
8660 /* DONE token (TDS_DONE_TOKEN) */
8661 { &hf_tds_done,
8662 { "Token - Done", "tds.done",
8663 FT_NONE, BASE_NONE, NULL, 0x0,
8664 NULL, HFILL }
8666 { &hf_tds_done_donerowcount_64,
8667 { "Row count", "tds.done.donerowcount64",
8668 FT_UINT64, BASE_DEC, NULL, 0x0,
8669 NULL, HFILL }
8671 { &hf_tds_done_donerowcount_32,
8672 { "Row count", "tds.done.donerowcount",
8673 FT_UINT32, BASE_DEC, NULL, 0x0,
8674 NULL, HFILL }
8676 { &hf_tds_done_status,
8677 { "Status flags", "tds.done.status",
8678 FT_UINT16, BASE_HEX, NULL, 0x017f,
8679 NULL, HFILL }
8681 { &hf_tds_done_status_more,
8682 { "More", "tds.done.status.more",
8683 FT_BOOLEAN, 16, TFS(&tds_tfs_more_final), 0x0001,
8684 NULL, HFILL }
8686 { &hf_tds_done_status_error,
8687 { "Error", "tds.done.status.error",
8688 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0002,
8689 NULL, HFILL }
8691 { &hf_tds_done_status_inxact,
8692 { "In Transaction", "tds.done.status.inxact",
8693 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0004,
8694 NULL, HFILL }
8696 { &hf_tds_done_status_proc,
8697 { "Procedure", "tds.done.status.proc",
8698 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0008,
8699 NULL, HFILL }
8701 { &hf_tds_done_status_count,
8702 { "Row count valid", "tds.done.status.count",
8703 FT_BOOLEAN, 16, TFS(&tfs_valid_invalid), 0x0010,
8704 NULL, HFILL }
8706 { &hf_tds_done_status_attn,
8707 { "Acknowledge ATTN", "tds.done.status.attn",
8708 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0020,
8709 NULL, HFILL }
8711 { &hf_tds_done_status_event,
8712 { "Event", "tds.done.status.event",
8713 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0040,
8714 NULL, HFILL }
8716 { &hf_tds_done_status_rpcinbatch,
8717 { "RPC in batch", "tds.done.status.rpcinbatch",
8718 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0080,
8719 NULL, HFILL }
8721 { &hf_tds_done_status_srverror,
8722 { "Server Error", "tds.done.status.srverror",
8723 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0100,
8724 NULL, HFILL }
8726 { &hf_tds_done_curcmd,
8727 { "Operation", "tds.done.curcmd",
8728 FT_UINT16, BASE_HEX, NULL, 0x0,
8729 NULL, HFILL }
8732 /* DONEPROC token (TDS_DONEPROC_TOKEN - implemented the same as TDS_DONE_TOKEN) */
8733 { &hf_tds_doneproc,
8734 { "Token - DoneProc", "tds.doneproc",
8735 FT_NONE, BASE_NONE, NULL, 0x0,
8736 NULL, HFILL }
8738 { &hf_tds_doneproc_donerowcount_64,
8739 { "Row count", "tds.doneproc.donerowcount64",
8740 FT_UINT64, BASE_DEC, NULL, 0x0,
8741 NULL, HFILL }
8743 { &hf_tds_doneproc_donerowcount_32,
8744 { "Row count", "tds.doneproc.donerowcount",
8745 FT_UINT32, BASE_DEC, NULL, 0x0,
8746 NULL, HFILL }
8748 { &hf_tds_doneproc_status,
8749 { "Status flags", "tds.doneproc.status",
8750 FT_UINT16, BASE_HEX, NULL, 0x01ff,
8751 NULL, HFILL }
8753 { &hf_tds_doneproc_curcmd,
8754 { "Operation", "tds.doneproc.curcmd",
8755 FT_UINT16, BASE_HEX, NULL, 0x0,
8756 NULL, HFILL }
8759 /* DONEINPROC token (TDS_DONEINPROC_TOKEN - implemented the same as TDS_DONE_TOKEN) */
8760 { &hf_tds_doneinproc,
8761 { "Token - DoneInProc", "tds.doneinproc",
8762 FT_NONE, BASE_NONE, NULL, 0x0,
8763 NULL, HFILL }
8765 { &hf_tds_doneinproc_donerowcount_64,
8766 { "Row count", "tds.doneinproc.donerowcount64",
8767 FT_UINT64, BASE_DEC, NULL, 0x0,
8768 NULL, HFILL }
8770 { &hf_tds_doneinproc_donerowcount_32,
8771 { "Row count", "tds.doneinproc.donerowcount",
8772 FT_UINT32, BASE_DEC, NULL, 0x0,
8773 NULL, HFILL }
8775 { &hf_tds_doneinproc_status,
8776 { "Status flags", "tds.doneinproc.status",
8777 FT_UINT16, BASE_HEX, NULL, 0x01ff,
8778 NULL, HFILL }
8780 { &hf_tds_doneinproc_curcmd,
8781 { "Operation", "tds.doneinproc.curcmd",
8782 FT_UINT16, BASE_HEX, NULL, 0x0,
8783 NULL, HFILL }
8786 /* EED token (TDS5_EED_TOKEN) */
8787 { &hf_tds_eed,
8788 { "Token - ExtendedErrorDiagnostic", "tds.eed",
8789 FT_NONE, BASE_NONE, NULL, 0x0,
8790 NULL, HFILL }
8792 { &hf_tds_eed_length,
8793 { "Token length", "tds.eed.length",
8794 FT_UINT16, BASE_DEC, NULL, 0x0,
8795 NULL, HFILL }
8797 { &hf_tds_eed_number,
8798 { "SQL Error Number", "tds.eed.number",
8799 FT_UINT32, BASE_DEC, NULL, 0x0,
8800 NULL, HFILL }
8802 { &hf_tds_eed_state,
8803 { "State", "tds.eed.state",
8804 FT_UINT8, BASE_DEC, NULL, 0x0,
8805 NULL, HFILL }
8807 { &hf_tds_eed_class,
8808 { "Class (Severity)", "tds.eed.class",
8809 FT_UINT8, BASE_DEC, NULL, 0x0,
8810 NULL, HFILL }
8812 { &hf_tds_eed_sql_state,
8813 { "SQL State", "tds.eed.sql_state",
8814 FT_UINT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
8815 NULL, HFILL }
8817 { &hf_tds_eed_status,
8818 { "EED Following", "tds.eed.status",
8819 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
8820 NULL, HFILL }
8822 { &hf_tds_eed_transtate,
8823 { "Transaction state", "tds.eed.transtate",
8824 FT_UINT16, BASE_DEC, NULL, 0x0,
8825 NULL, HFILL }
8827 { &hf_tds_eed_msgtext,
8828 { "Error message", "tds.eed.msgtext",
8829 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8830 NULL, HFILL }
8832 { &hf_tds_eed_servername,
8833 { "Server name", "tds.eed.servername",
8834 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8835 NULL, HFILL }
8837 { &hf_tds_eed_procname,
8838 { "Procedure name", "tds.eed.procname",
8839 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
8840 NULL, HFILL }
8842 { &hf_tds_eed_linenumber,
8843 { "Line number", "tds.eed.linenumber",
8844 FT_UINT16, BASE_DEC, NULL, 0x0,
8845 NULL, HFILL }
8848 /* ENVCHANGE token (TDS_ENVCHG_TOKEN) */
8849 { &hf_tds_envchg,
8850 { "Token - EnvChange", "tds.envchange",
8851 FT_NONE, BASE_NONE, NULL, 0x0,
8852 NULL, HFILL }
8854 { &hf_tds_envchg_length,
8855 { "Token length", "tds.envchange.length",
8856 FT_UINT16, BASE_DEC, NULL, 0x0,
8857 NULL, HFILL }
8859 { &hf_tds_envchg_type,
8860 { "Type", "tds.envchange.type",
8861 FT_UINT8, BASE_DEC, VALS(envchg_names), 0x0,
8862 NULL, HFILL }
8864 { &hf_tds_envchg_newvalue_length,
8865 { "New Value Length", "tds.envchange.newvalue_length",
8866 FT_UINT8, BASE_DEC, NULL, 0x0,
8867 NULL, HFILL }
8869 { &hf_tds_envchg_newvalue_string,
8870 { "New Value", "tds.envchange.newvalue_string",
8871 FT_STRING, BASE_NONE, NULL, 0x0,
8872 NULL, HFILL }
8874 { &hf_tds_envchg_newvalue_bytes,
8875 { "New Value", "tds.envchange.newvalue",
8876 FT_BYTES, BASE_NONE, NULL, 0x0,
8877 NULL, HFILL }
8879 { &hf_tds_envchg_oldvalue_length,
8880 { "Old Value Length", "tds.envchange.oldvalue_length",
8881 FT_UINT8, BASE_DEC, NULL, 0x0,
8882 NULL, HFILL }
8884 { &hf_tds_envchg_oldvalue_string,
8885 { "Old Value", "tds.envchange.oldvalue_string",
8886 FT_STRING, BASE_NONE, NULL, 0x0,
8887 NULL, HFILL }
8889 { &hf_tds_envchg_oldvalue_bytes,
8890 { "Old Value", "tds.envchange.oldvalue",
8891 FT_BYTES, BASE_NONE, NULL, 0x0,
8892 NULL, HFILL }
8894 { &hf_tds_envchg_collate_codepage,
8895 { "Collate codepage", "tds.envchange.collate_codepage",
8896 FT_UINT16, BASE_DEC, NULL, 0x0,
8897 NULL, HFILL }
8899 { &hf_tds_envchg_collate_flags,
8900 { "Collate flags", "tds.envchange.collate_flags",
8901 FT_UINT16, BASE_HEX, NULL, 0x0,
8902 NULL, HFILL }
8904 { &hf_tds_envchg_collate_charset_id,
8905 { "Collate charset ID", "tds.envchange.collate_charset_id",
8906 FT_UINT8, BASE_DEC, NULL, 0x0,
8907 NULL, HFILL }
8910 /* ERROR token (TDS_ERR_TOKEN) */
8911 { &hf_tds_error,
8912 { "Token - Error", "tds.error",
8913 FT_NONE, BASE_NONE, NULL, 0x0,
8914 NULL, HFILL }
8916 { &hf_tds_error_length,
8917 { "Token length", "tds.error.length",
8918 FT_UINT16, BASE_DEC, NULL, 0x0,
8919 NULL, HFILL }
8921 { &hf_tds_error_number,
8922 { "SQL Error Number", "tds.error.number",
8923 FT_UINT32, BASE_DEC, NULL, 0x0,
8924 NULL, HFILL }
8926 { &hf_tds_error_state,
8927 { "State", "tds.error.state",
8928 FT_UINT8, BASE_DEC, NULL, 0x0,
8929 NULL, HFILL }
8931 { &hf_tds_error_class,
8932 { "Class (Severity)", "tds.error.class",
8933 FT_UINT8, BASE_DEC, NULL, 0x0,
8934 NULL, HFILL }
8936 { &hf_tds_error_msgtext_length,
8937 { "Error message length", "tds.error.msgtext_length",
8938 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_characters), 0x0,
8939 NULL, HFILL }
8941 { &hf_tds_error_msgtext,
8942 { "Error message", "tds.error.msgtext",
8943 FT_STRING, BASE_NONE, NULL, 0x0,
8944 NULL, HFILL }
8946 { &hf_tds_error_servername_length,
8947 { "Server name length", "tds.error.servername_length",
8948 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_characters), 0x0,
8949 NULL, HFILL }
8951 { &hf_tds_error_servername,
8952 { "Server name", "tds.error.servername",
8953 FT_STRING, BASE_NONE, NULL, 0x0,
8954 NULL, HFILL }
8956 { &hf_tds_error_procname_length,
8957 { "Process name length", "tds.error.procname_length",
8958 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_characters), 0x0,
8959 NULL, HFILL }
8961 { &hf_tds_error_procname,
8962 { "Process name", "tds.error.procname",
8963 FT_STRING, BASE_NONE, NULL, 0x0,
8964 NULL, HFILL }
8966 { &hf_tds_error_linenumber_16,
8967 { "Line number", "tds.error.linenumber",
8968 FT_UINT16, BASE_DEC, NULL, 0x0,
8969 NULL, HFILL }
8971 { &hf_tds_error_linenumber_32,
8972 { "Line number", "tds.error.linenumber",
8973 FT_UINT32, BASE_DEC, NULL, 0x0,
8974 NULL, HFILL }
8977 /* FEATUREEXTACK token (TDS_FEATUREEXTACK_TOKEN) */
8978 { &hf_tds_featureextack,
8979 { "Token - FeatureExtAct", "tds.featureextack",
8980 FT_NONE, BASE_NONE, NULL, 0x0,
8981 NULL, HFILL }
8983 { &hf_tds_featureextack_feature,
8984 { "Feature", "tds.featureextack.feature",
8985 FT_NONE, BASE_NONE, NULL, 0x0,
8986 NULL, HFILL }
8988 { &hf_tds_featureextack_featureid,
8989 { "Feature ID", "tds.featureextack.featureid",
8990 FT_UINT8, BASE_DEC, VALS(featureextack_feature_names), 0x0,
8991 NULL, HFILL }
8993 { &hf_tds_featureextack_featureackdatalen,
8994 { "Feature length", "tds.featureextack.featureackdatalen",
8995 FT_UINT32, BASE_DEC, NULL, 0x0,
8996 NULL, HFILL }
8998 { &hf_tds_featureextack_featureackdata,
8999 { "Feature data", "tds.featureextack.featureackdata",
9000 FT_BYTES, BASE_NONE, NULL, 0x0,
9001 NULL, HFILL }
9004 /* FEDAUTHINFO token */
9006 /* INFO token */
9007 { &hf_tds_info,
9008 { "Token - Info", "tds.info",
9009 FT_NONE, BASE_NONE, NULL, 0x0,
9010 NULL, HFILL }
9012 { &hf_tds_info_length,
9013 { "Token length", "tds.info.length",
9014 FT_UINT16, BASE_DEC, NULL, 0x0,
9015 NULL, HFILL }
9017 { &hf_tds_info_number,
9018 { "SQL Error Number", "tds.info.number",
9019 FT_UINT32, BASE_DEC, NULL, 0x0,
9020 NULL, HFILL }
9022 { &hf_tds_info_state,
9023 { "State", "tds.info.state",
9024 FT_UINT8, BASE_DEC, NULL, 0x0,
9025 NULL, HFILL }
9027 { &hf_tds_info_class,
9028 { "Class (Severity)", "tds.info.class",
9029 FT_UINT8, BASE_DEC, NULL, 0x0,
9030 NULL, HFILL }
9032 { &hf_tds_info_msgtext_length,
9033 { "Error message length", "tds.info.msgtext_length",
9034 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_characters), 0x0,
9035 NULL, HFILL }
9037 { &hf_tds_info_msgtext,
9038 { "Error message", "tds.info.msgtext",
9039 FT_STRING, BASE_NONE, NULL, 0x0,
9040 NULL, HFILL }
9042 { &hf_tds_info_servername_length,
9043 { "Server name length", "tds.info.servername_length",
9044 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_characters), 0x0,
9045 NULL, HFILL }
9047 { &hf_tds_info_servername,
9048 { "Server name", "tds.info.servername",
9049 FT_STRING, BASE_NONE, NULL, 0x0,
9050 NULL, HFILL }
9052 { &hf_tds_info_procname_length,
9053 { "Process name length", "tds.info.procname_length",
9054 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_characters), 0x0,
9055 NULL, HFILL }
9057 { &hf_tds_info_procname,
9058 { "Process name", "tds.info.procname",
9059 FT_STRING, BASE_NONE, NULL, 0x0,
9060 NULL, HFILL }
9062 { &hf_tds_info_linenumber_16,
9063 { "Line number", "tds.info.linenumber",
9064 FT_UINT16, BASE_DEC, NULL, 0x0,
9065 NULL, HFILL }
9067 { &hf_tds_info_linenumber_32,
9068 { "Line number", "tds.info.linenumber",
9069 FT_UINT32, BASE_DEC, NULL, 0x0,
9070 NULL, HFILL }
9073 /* LOGINACK token (TDS_LOGIN_ACK_TOKEN) */
9074 { &hf_tds_loginack,
9075 { "Token - LoginAck", "tds.loginack",
9076 FT_NONE, BASE_NONE, NULL, 0x0,
9077 NULL, HFILL }
9079 { &hf_tds_loginack_length,
9080 { "Token length", "tds.loginack.length",
9081 FT_UINT16, BASE_DEC, NULL, 0x0,
9082 NULL, HFILL }
9084 { &hf_tds_loginack_interface,
9085 { "Interface", "tds.loginack.interface",
9086 FT_UINT8, BASE_DEC, NULL, 0x0,
9087 NULL, HFILL }
9089 { &hf_tds_loginack_tdsversion,
9090 { "TDS version", "tds.loginack.tdsversion",
9091 FT_UINT32, BASE_HEX, NULL, 0x0,
9092 NULL, HFILL }
9094 { &hf_tds_loginack_progversion,
9095 { "Server Version", "tds.loginack.progversion",
9096 FT_UINT32, BASE_CUSTOM, CF_FUNC(version_convert), 0x0,
9097 NULL, HFILL }
9099 { &hf_tds_loginack_progname,
9100 { "Server name", "tds.loginack.progname",
9101 FT_STRING, BASE_NONE, NULL, 0x0,
9102 NULL, HFILL }
9105 /* LOGOUT token (TDS5_LOGOUT_TOKEN) */
9106 { &hf_tds_logout,
9107 { "Token - Logout", "tds.logout",
9108 FT_NONE, BASE_NONE, NULL, 0x0,
9109 NULL, HFILL }
9111 { &hf_tds_logout_options,
9112 { "Logout Options", "tds.logout.options",
9113 FT_UINT8, BASE_HEX, NULL, 0x0,
9114 NULL, HFILL }
9117 /* MSG token (TDS5_MSG_TOKEN) */
9118 { &hf_tds_msg,
9119 { "Token - Msg", "tds.msg",
9120 FT_NONE, BASE_NONE, NULL, 0x0,
9121 NULL, HFILL }
9123 { &hf_tds_msg_length,
9124 { "Token length - Msg", "tds.msg.length",
9125 FT_UINT8, BASE_DEC, NULL, 0x0,
9126 NULL, HFILL }
9128 { &hf_tds_msg_status,
9129 { "Status", "tds.msg.status",
9130 FT_UINT8, BASE_HEX, NULL, 0x0,
9131 NULL, HFILL }
9133 { &hf_tds_msg_msgid,
9134 { "Message Id", "tds.msg.msgid",
9135 FT_UINT16, BASE_DEC, NULL, 0x0,
9136 NULL, HFILL }
9139 /* NBCROW token (TDS_NBCROW_TOKEN) */
9140 { &hf_tds_nbcrow,
9141 { "Token - NBCRow", "tds.nbcrow",
9142 FT_NONE, BASE_NONE, NULL, 0x0,
9143 NULL, HFILL }
9146 /* OFFSET token */
9147 { &hf_tds_offset,
9148 { "Token - Offset", "tds.offset",
9149 FT_NONE, BASE_NONE, NULL, 0x0,
9150 NULL, HFILL }
9152 { &hf_tds_offset_id,
9153 { "Offset ID", "tds.offset.id",
9154 FT_UINT16, BASE_DEC, NULL, 0x0,
9155 NULL, HFILL }
9157 { &hf_tds_offset_len,
9158 { "Offset length", "tds.offset.len",
9159 FT_UINT16, BASE_DEC, NULL, 0x0,
9160 NULL, HFILL }
9163 /* ORDER token (TDS_ORDER_TOKEN) */
9164 { &hf_tds_order,
9165 { "Token - Order", "tds.order",
9166 FT_NONE, BASE_NONE, NULL, 0x0,
9167 NULL, HFILL }
9169 { &hf_tds_order_length,
9170 { "Token length", "tds.order.length",
9171 FT_UINT16, BASE_DEC, NULL, 0x0,
9172 NULL, HFILL }
9174 { &hf_tds_order_colnum,
9175 { "Order column", "tds.order.colnum",
9176 FT_UINT16, BASE_DEC, NULL, 0x0,
9177 NULL, HFILL }
9180 /* PARAMFMT token (TDS5_PARAMFMT_TOKEN) */
9181 { &hf_tds_paramfmt,
9182 { "Token - Paramfmt", "tds.paramfmt",
9183 FT_NONE, BASE_NONE, NULL, 0x0,
9184 NULL, HFILL }
9186 { &hf_tds_paramfmt_length,
9187 { "Token length - Paramfmt", "tds.paramfmt.length",
9188 FT_UINT16, BASE_DEC, NULL, 0x0,
9189 NULL, HFILL }
9191 { &hf_tds_paramfmt_numparams,
9192 { "Number of Parameters", "tds.paramfmt.numparams",
9193 FT_UINT16, BASE_DEC, NULL, 0x0,
9194 NULL, HFILL }
9196 { &hf_tds_paramfmt_colname,
9197 { "Parameter name", "tds.paramfmt.colname",
9198 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9199 NULL, HFILL }
9201 { &hf_tds_paramfmt_status,
9202 { "Column Status", "tds.paramfmt.status",
9203 FT_UINT8, BASE_HEX, NULL, 0x0,
9204 NULL, HFILL }
9206 { &hf_tds_paramfmt_utype,
9207 { "Parameter Usertype", "tds.paramfmt.utype",
9208 FT_UINT32, BASE_DEC, NULL, 0x0,
9209 NULL, HFILL }
9211 { &hf_tds_paramfmt_ctype,
9212 { "Parameter Datatype", "tds.paramfmt.ctype",
9213 FT_UINT8, BASE_DEC, &tds_data_type_names, 0x0,
9214 NULL, HFILL }
9216 { &hf_tds_paramfmt_csize,
9217 { "Parameter size", "tds.paramfmt.csize",
9218 FT_UINT32, BASE_DEC, NULL, 0x0,
9219 NULL, HFILL }
9221 { &hf_tds_paramfmt_locale_info,
9222 { "Locale info", "tds.paramfmt.locale_info",
9223 FT_UINT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
9224 NULL, HFILL }
9227 /* PARAMFMT2 token (TDS5_PARAMFMT2_TOKEN) */
9228 { &hf_tds_paramfmt2,
9229 { "Token - Paramfmt2", "tds.paramfmt2",
9230 FT_NONE, BASE_NONE, NULL, 0x0,
9231 NULL, HFILL }
9233 { &hf_tds_paramfmt2_length,
9234 { "Token length - Paramfmt2", "tds.paramfmt2.length",
9235 FT_UINT32, BASE_DEC, NULL, 0x0,
9236 NULL, HFILL }
9238 { &hf_tds_paramfmt2_numparams,
9239 { "Number of Parameters", "tds.paramfmt2.numparams",
9240 FT_UINT16, BASE_DEC, NULL, 0x0,
9241 NULL, HFILL }
9243 { &hf_tds_paramfmt2_colname,
9244 { "Parameter name", "tds.paramfmt2.paramname",
9245 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9246 NULL, HFILL }
9248 { &hf_tds_paramfmt2_status,
9249 { "Parameter Status", "tds.paramfmt2.status",
9250 FT_UINT32, BASE_HEX, NULL, 0x0,
9251 NULL, HFILL }
9253 { &hf_tds_paramfmt2_utype,
9254 { "Parameter Usertype", "tds.paramfmt2.utype",
9255 FT_UINT32, BASE_DEC, NULL, 0x0,
9256 NULL, HFILL }
9258 { &hf_tds_paramfmt2_ctype,
9259 { "Parameter Datatype", "tds.paramfmt2.ctype",
9260 FT_UINT8, BASE_DEC, &tds_data_type_names, 0x0,
9261 NULL, HFILL }
9263 { &hf_tds_paramfmt2_csize,
9264 { "Parameter size", "tds.paramfmt2.csize",
9265 FT_UINT32, BASE_DEC, NULL, 0x0,
9266 NULL, HFILL }
9268 { &hf_tds_paramfmt2_locale_info,
9269 { "Locale info", "tds.paramfmt2.locale_info",
9270 FT_UINT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
9271 NULL, HFILL }
9274 /* PARAMS token (TDS5_PARAMS_TOKEN) */
9275 { &hf_tds_params,
9276 { "Token - Params", "tds.params",
9277 FT_NONE, BASE_NONE, NULL, 0x0,
9278 NULL, HFILL }
9280 { &hf_tds_params_field,
9281 { "Parameter", "tds.params.parameter",
9282 FT_NONE, BASE_NONE, NULL, 0x0,
9283 NULL, HFILL }
9286 /* PROCID token (TDS_PROCID_TOKEN) */
9287 { &hf_tds_procid,
9288 { "Token - Procid", "tds.procid",
9289 FT_NONE, BASE_NONE, NULL, 0x0,
9290 NULL, HFILL }
9292 { &hf_tds_procid_value,
9293 { "Procid Value", "tds.procid.value",
9294 FT_BYTES, BASE_NONE, NULL, 0x0,
9295 NULL, HFILL }
9298 /* RETURNSTATUS token (TDS_RET_STAT_TOKEN) */
9299 { &hf_tds_returnstatus,
9300 { "Token - ReturnStatus", "tds.returnstatus",
9301 FT_NONE, BASE_NONE, NULL, 0x0,
9302 NULL, HFILL }
9304 { &hf_tds_returnstatus_value,
9305 { "Value", "tds.returnstatus.value",
9306 FT_UINT32, BASE_DEC, NULL, 0x0,
9307 NULL, HFILL }
9310 /* RETURNVALUE token (TDS_RETURNVAL_TOKEN) */
9312 /* ROW token (TDS_ROW_TOKEN) */
9313 { &hf_tds_row,
9314 { "Token - Row", "tds.row",
9315 FT_NONE, BASE_NONE, NULL, 0x0,
9316 NULL, HFILL }
9318 { &hf_tds_row_field,
9319 { "Field", "tds.row.field",
9320 FT_NONE, BASE_NONE, NULL, 0x0,
9321 NULL, HFILL }
9324 /* ROWFMT token (TDS5_ROWFMT_TOKEN) */
9325 { &hf_tds_rowfmt,
9326 { "Token - Rowfmt", "tds.rowfmt",
9327 FT_NONE, BASE_NONE, NULL, 0x0,
9328 NULL, HFILL }
9330 { &hf_tds_rowfmt_length,
9331 { "Token length - Rowfmt", "tds.rowfmt.length",
9332 FT_UINT16, BASE_DEC, NULL, 0x0,
9333 NULL, HFILL }
9335 { &hf_tds_rowfmt_numcols,
9336 { "Number of Columns", "tds.rowfmt.numcols",
9337 FT_UINT16, BASE_DEC, NULL, 0x0,
9338 NULL, HFILL }
9340 { &hf_tds_rowfmt_colname,
9341 { "Column name", "tds.rowfmt.colname",
9342 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9343 NULL, HFILL }
9345 { &hf_tds_rowfmt_status,
9346 { "Column Status", "tds.rowfmt.status",
9347 FT_UINT8, BASE_HEX, NULL, 0x0,
9348 NULL, HFILL }
9350 { &hf_tds_rowfmt_utype,
9351 { "Column Usertype", "tds.rowfmt.utype",
9352 FT_UINT32, BASE_DEC, NULL, 0x0,
9353 NULL, HFILL }
9355 { &hf_tds_rowfmt_ctype,
9356 { "Column Datatype", "tds.rowfmt.ctype",
9357 FT_UINT8, BASE_DEC, &tds_data_type_names, 0x0,
9358 NULL, HFILL }
9360 { &hf_tds_rowfmt_csize,
9361 { "Column size", "tds.rowfmt.csize",
9362 FT_UINT32, BASE_DEC, NULL, 0x0,
9363 NULL, HFILL }
9365 { &hf_tds_rowfmt_text_tablename,
9366 { "Text Tablename", "tds.rowfmt.text_tablename",
9367 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9368 NULL, HFILL }
9370 { &hf_tds_rowfmt_precision,
9371 { "Precision", "tds.rowfmt.precision",
9372 FT_UINT8, BASE_DEC, NULL, 0x0,
9373 NULL, HFILL }
9375 { &hf_tds_rowfmt_scale,
9376 { "Scale", "tds.rowfmt.scale",
9377 FT_UINT8, BASE_DEC, NULL, 0x0,
9378 NULL, HFILL }
9380 { &hf_tds_rowfmt_locale_info,
9381 { "Locale info", "tds.rowfmt.locale_info",
9382 FT_UINT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
9383 NULL, HFILL }
9386 /* ROWFMT2 token (TDS5_ROWFMT2_TOKEN) */
9387 { &hf_tds_rowfmt2,
9388 { "Token - Rowfmt2", "tds.rowfmt2",
9389 FT_NONE, BASE_NONE, NULL, 0x0,
9390 NULL, HFILL }
9392 { &hf_tds_rowfmt2_length,
9393 { "Token length - Rowfmt2", "tds.rowfmt2.length",
9394 FT_UINT32, BASE_DEC, NULL, 0x0,
9395 NULL, HFILL }
9397 { &hf_tds_rowfmt2_numcols,
9398 { "Number of Columns", "tds.rowfmt2.numcols",
9399 FT_UINT16, BASE_DEC, NULL, 0x0,
9400 NULL, HFILL }
9402 { &hf_tds_rowfmt2_labelname,
9403 { "Label name", "tds.rowfmt2.labelname",
9404 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9405 NULL, HFILL }
9407 { &hf_tds_rowfmt2_catalogname,
9408 { "Catalog name", "tds.rowfmt2.catalogname",
9409 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9410 NULL, HFILL }
9412 { &hf_tds_rowfmt2_schemaname,
9413 { "Schema name", "tds.rowfmt2.schemaname",
9414 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9415 NULL, HFILL }
9417 { &hf_tds_rowfmt2_tablename,
9418 { "Table name", "tds.rowfmt2.tablename",
9419 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9420 NULL, HFILL }
9422 { &hf_tds_rowfmt2_colname,
9423 { "Column name", "tds.rowfmt2.colname",
9424 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9425 NULL, HFILL }
9427 { &hf_tds_rowfmt2_status,
9428 { "Column Status", "tds.rowfmt2.status",
9429 FT_UINT32, BASE_HEX, NULL, 0x0,
9430 NULL, HFILL }
9432 { &hf_tds_rowfmt2_utype,
9433 { "Column Usertype", "tds.rowfmt2.utype",
9434 FT_UINT32, BASE_DEC, NULL, 0x0,
9435 NULL, HFILL }
9437 { &hf_tds_rowfmt2_ctype,
9438 { "Column Datatype", "tds.rowfmt2.ctype",
9439 FT_UINT8, BASE_DEC, &tds_data_type_names, 0x0,
9440 NULL, HFILL }
9442 { &hf_tds_rowfmt2_csize,
9443 { "Column size", "tds.rowfmt2.csize",
9444 FT_UINT32, BASE_DEC, NULL, 0x0,
9445 NULL, HFILL }
9447 { &hf_tds_rowfmt2_text_tablename,
9448 { "Text Tablename", "tds.rowfmt2.text_tablename",
9449 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
9450 NULL, HFILL }
9452 { &hf_tds_rowfmt2_precision,
9453 { "Precision", "tds.rowfmt2.precision",
9454 FT_UINT8, BASE_DEC, NULL, 0x0,
9455 NULL, HFILL }
9457 { &hf_tds_rowfmt2_scale,
9458 { "Scale", "tds.rowfmt2.scale",
9459 FT_UINT8, BASE_DEC, NULL, 0x0,
9460 NULL, HFILL }
9462 { &hf_tds_rowfmt2_locale_info,
9463 { "Locale info", "tds.rowfmt2.locale_info",
9464 FT_UINT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
9465 NULL, HFILL }
9468 /* SESSIONSTATE token (TDS_SESSIONSTATE_TOKEN) */
9469 { &hf_tds_sessionstate,
9470 { "Token - Session state", "tds.sessionstate",
9471 FT_NONE, BASE_NONE, NULL, 0x0,
9472 NULL, HFILL }
9474 { &hf_tds_sessionstate_length,
9475 { "Token length", "tds.sessionstate.length",
9476 FT_UINT32, BASE_DEC, NULL, 0x0,
9477 NULL, HFILL }
9479 { &hf_tds_sessionstate_seqno,
9480 { "Sequence number", "tds.sessionstate.seqno",
9481 FT_UINT32, BASE_DEC, NULL, 0x0,
9482 NULL, HFILL }
9484 { &hf_tds_sessionstate_status,
9485 { "Status", "tds.sessionstate.status",
9486 FT_UINT8, BASE_DEC, NULL, 0x0,
9487 NULL, HFILL }
9489 { &hf_tds_sessionstate_stateid,
9490 { "State ID", "tds.sessionstate.stateid",
9491 FT_UINT8, BASE_DEC, NULL, 0x0,
9492 NULL, HFILL }
9494 { &hf_tds_sessionstate_statelen,
9495 { "State Length", "tds.sessionstate.statelen",
9496 FT_UINT16, BASE_DEC, NULL, 0x0,
9497 NULL, HFILL }
9499 { &hf_tds_sessionstate_statevalue,
9500 { "State Value", "tds.sessionstate.statevalue",
9501 FT_BYTES, BASE_NONE, NULL, 0x0,
9502 NULL, HFILL }
9505 /* SSPI token */
9506 { &hf_tds_sspi,
9507 { "Token - SSPI", "tds.sspi",
9508 FT_NONE, BASE_NONE, NULL, 0x0,
9509 NULL, HFILL }
9511 { &hf_tds_sspi_buffer,
9512 { "State Value", "tds.sspi.buffer",
9513 FT_BYTES, BASE_NONE, NULL, 0x0,
9514 NULL, HFILL }
9517 /* TABNAME token */
9519 /* TVPROW Token */
9521 /* TDS5 Lang Token */
9522 { &hf_tds_lang_length,
9523 { "Token Length - Language", "tds.lang.length",
9524 FT_UINT32, BASE_DEC, NULL, 0x0,
9525 NULL, HFILL }
9527 { &hf_tds_lang_token_status,
9528 { "Status", "tds.lang.token_status",
9529 FT_UINT8, BASE_HEX, NULL, 0x0,
9530 NULL, HFILL }
9532 { &hf_tds_lang_status_parameterized,
9533 { "Parameters follow", "tds.lang.token_status.parameterized",
9534 FT_BOOLEAN, 8, NULL, 0x01,
9535 NULL, HFILL }
9537 { &hf_tds_lang_language_text,
9538 { "Language text", "tds.lang.language_text",
9539 FT_STRING, BASE_NONE, NULL, 0x0,
9540 NULL, HFILL }
9543 /* Unknown token type */
9544 { &hf_tds_unknown_tds_token,
9545 { "Token - Unknown", "tds.unknown_tds_token",
9546 FT_NONE, BASE_NONE, NULL, 0x0,
9547 NULL, HFILL }
9550 /************************ Message definitions ***********************/
9552 /* Bulk Load BCP stream */
9554 /* Bulk Load Update Text/Write Text */
9556 /* Federated Authentication Token */
9558 /* LOGIN Token */
9559 { &hf_tdslogin,
9560 { "Hostname length", "tds.login",
9561 FT_NONE, BASE_NONE, NULL, 0x0,
9562 NULL, HFILL }
9564 { &hf_tdslogin_hostname_length,
9565 { "Hostname length", "tds.login.hostname_length",
9566 FT_UINT8, BASE_DEC, NULL, 0x0,
9567 NULL, HFILL }
9569 { &hf_tdslogin_hostname,
9570 { "Hostname", "tds.login.hostname",
9571 FT_STRING, BASE_NONE, NULL, 0x0,
9572 NULL, HFILL }
9574 { &hf_tdslogin_username_length,
9575 { "Username length", "tds.login.username_length",
9576 FT_UINT8, BASE_DEC, NULL, 0x0,
9577 NULL, HFILL }
9579 { &hf_tdslogin_username,
9580 { "Username", "tds.login.username",
9581 FT_STRING, BASE_NONE, NULL, 0x0,
9582 NULL, HFILL }
9584 { &hf_tdslogin_password_length,
9585 { "Password length", "tds.login.password_length",
9586 FT_UINT8, BASE_DEC, NULL, 0x0,
9587 NULL, HFILL }
9589 { &hf_tdslogin_password,
9590 { "Password", "tds.login.password",
9591 FT_STRING, BASE_NONE, NULL, 0x0,
9592 NULL, HFILL }
9594 { &hf_tdslogin_hostprocess_length,
9595 { "Host Process Id length", "tds.login.hostprocess_length",
9596 FT_UINT8, BASE_DEC, NULL, 0x0,
9597 NULL, HFILL }
9599 { &hf_tdslogin_hostprocess,
9600 { "Host Process Id", "tds.login.pid",
9601 FT_STRING, BASE_NONE, NULL, 0x0,
9602 NULL, HFILL }
9604 { &hf_tdslogin_option_int2,
9605 { "Short (2-byte) integer format", "tds.login.option.int2",
9606 FT_UINT8, BASE_DEC, VALS(login_options), 0x0,
9607 NULL, HFILL }
9609 { &hf_tdslogin_option_int4,
9610 { "Long (4-byte) integer format", "tds.login.option.int4",
9611 FT_UINT8, BASE_DEC, VALS(login_options), 0x0,
9612 NULL, HFILL }
9614 { &hf_tdslogin_option_char,
9615 { "Character set", "tds.login.option.char",
9616 FT_UINT8, BASE_DEC, VALS(login_options), 0x0,
9617 NULL, HFILL }
9619 { &hf_tdslogin_option_float,
9620 { "Double (8 byte) float format", "tds.login.option.float",
9621 FT_UINT8, BASE_DEC, VALS(login_options), 0x0,
9622 NULL, HFILL }
9624 { &hf_tdslogin_option_date8,
9625 { "Long (8 byte) date format", "tds.login.option.date",
9626 FT_UINT8, BASE_DEC, VALS(login_options), 0x0,
9627 NULL, HFILL }
9629 { &hf_tdslogin_option_usedb,
9630 { "Use DB", "tds.login.option.usedb",
9631 FT_BOOLEAN, BASE_NONE, TFS(&tfs_no_yes), 0x0,
9632 NULL, HFILL }
9634 { &hf_tdslogin_option_bulk,
9635 { "Bulk Copy", "tds.login.option.bulk",
9636 FT_BOOLEAN, BASE_NONE, TFS(&tfs_no_yes), 0x0,
9637 NULL, HFILL }
9639 { &hf_tdslogin_option_server_to_server,
9640 { "Server to server options", "tds.login.option.server_to_server",
9641 FT_UINT8, BASE_DEC, VALS(login_server_to_server), 0x0,
9642 NULL, HFILL }
9644 { &hf_tdslogin_option_server_to_server_loginack,
9645 { "Server to server loginack", "tds.login.option.server_to_server_loginack",
9646 FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0,
9647 NULL, HFILL }
9649 { &hf_tdslogin_option_conversation_type,
9650 { "Conversation type", "tds.login.option.type",
9651 FT_UINT8, BASE_DEC, VALS(login_conversation_type), 0x0,
9652 NULL, HFILL }
9654 { &hf_tdslogin_appname_length,
9655 { "Application name length", "tds.login.appname_length",
9656 FT_UINT8, BASE_DEC, NULL, 0x0,
9657 NULL, HFILL }
9659 { &hf_tdslogin_appname,
9660 { "Application name", "tds.login.appname",
9661 FT_STRING, BASE_NONE, NULL, 0x0,
9662 NULL, HFILL }
9664 { &hf_tdslogin_servername_length,
9665 { "Server name length", "tds.login.servername_length",
9666 FT_UINT8, BASE_DEC, NULL, 0x0,
9667 NULL, HFILL }
9669 { &hf_tdslogin_servername,
9670 { "Server name", "tds.login.servname",
9671 FT_STRING, BASE_NONE, NULL, 0x0,
9672 NULL, HFILL }
9674 { &hf_tdslogin_remotepassword_length,
9675 { "Remote password length", "tds.login.rempw_length",
9676 FT_UINT8, BASE_DEC, NULL, 0x0,
9677 NULL, HFILL }
9679 { &hf_tdslogin_rempw_servername_length,
9680 { "Remote password servername length", "tds.login.rempw_servername_length",
9681 FT_UINT8, BASE_DEC, NULL, 0x0,
9682 NULL, HFILL }
9684 { &hf_tdslogin_rempw_servername,
9685 { "Remote password server name", "tds.login.rempw_servername",
9686 FT_STRING, BASE_NONE, NULL, 0x0,
9687 NULL, HFILL }
9689 { &hf_tdslogin_rempw_password_length,
9690 { "Remote password password length", "tds.login.rempw_password_length",
9691 FT_UINT8, BASE_DEC, NULL, 0x0,
9692 NULL, HFILL }
9694 { &hf_tdslogin_rempw_password,
9695 { "Remote password password", "tds.login.rempw_password",
9696 FT_STRING, BASE_NONE, NULL, 0x0,
9697 NULL, HFILL }
9699 { &hf_tdslogin_proto_version,
9700 { "Protocol version", "tds.login.protoversion",
9701 FT_UINT32, BASE_HEX, NULL, 0x0,
9702 NULL, HFILL }
9704 { &hf_tdslogin_progname_length,
9705 { "Program name length", "tds.login.progname_length",
9706 FT_UINT8, BASE_DEC, NULL, 0x0,
9707 NULL, HFILL }
9709 { &hf_tdslogin_progname,
9710 { "Program name", "tds.login.progname",
9711 FT_STRING, BASE_NONE, NULL, 0x0,
9712 NULL, HFILL }
9714 { &hf_tdslogin_progvers,
9715 { "Program version", "tds.login.progversion",
9716 FT_UINT32, BASE_HEX, NULL, 0x0,
9717 NULL, HFILL }
9719 { &hf_tdslogin_option2_noshort,
9720 { "Convert shorts to longs", "tds.login.option.noshort",
9721 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
9722 NULL, HFILL }
9724 { &hf_tdslogin_option2_flt4,
9725 { "Single (4 byte) float format", "tds.login.option.flt4",
9726 FT_UINT8, BASE_DEC, VALS(login_options), 0x0,
9727 NULL, HFILL }
9729 { &hf_tdslogin_option2_date4,
9730 { "Short (4 byte) date format", "tds.login.option.date4",
9731 FT_UINT8, BASE_DEC, VALS(login_options), 0x0,
9732 NULL, HFILL }
9734 { &hf_tdslogin_language,
9735 { "Language", "tds.login.language",
9736 FT_STRING, BASE_NONE, NULL, 0x0,
9737 NULL, HFILL }
9739 { &hf_tdslogin_language_length,
9740 { "Language name length", "tds.login.language_length",
9741 FT_UINT8, BASE_DEC, NULL, 0x0,
9742 NULL, HFILL }
9744 { &hf_tdslogin_setlang,
9745 { "Notify client of language changes", "tds.login.setlang",
9746 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
9747 NULL, HFILL }
9749 { &hf_tdslogin_seclogin,
9750 { "Secure login", "tds.login.seclogin",
9751 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
9752 NULL, HFILL }
9754 { &hf_tdslogin_secbulk,
9755 { "Secure bulk copy", "tds.login.secbulk",
9756 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
9757 NULL, HFILL }
9759 { &hf_tdslogin_halogin,
9760 { "High Availability login", "tds.login.halogin",
9761 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
9762 NULL, HFILL }
9764 { &hf_tdslogin_hasessionid,
9765 { "High Availability session id", "tds.login.hasessionid",
9766 FT_BYTES, BASE_NONE, NULL, 0x0,
9767 NULL, HFILL }
9769 { &hf_tdslogin_charset,
9770 { "Character set", "tds.login.charset",
9771 FT_STRING, BASE_NONE, NULL, 0x0,
9772 NULL, HFILL }
9774 { &hf_tdslogin_charset_length,
9775 { "Character set name length", "tds.login.charset_length",
9776 FT_UINT8, BASE_DEC, NULL, 0x0,
9777 NULL, HFILL }
9779 { &hf_tdslogin_setcharset,
9780 { "Notify client of character set changes", "tds.login.setcharset",
9781 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
9782 NULL, HFILL }
9784 { &hf_tdslogin_packetsize,
9785 { "Packet size", "tds.login.packetsize",
9786 FT_STRING, BASE_NONE, NULL, 0x0,
9787 NULL, HFILL }
9789 { &hf_tdslogin_packetsize_length,
9790 { "Packet size length", "tds.login.packetsize_length",
9791 FT_UINT8, BASE_DEC, NULL, 0x0,
9792 NULL, HFILL }
9795 /* LOGIN7 Token */
9796 { &hf_tds7login_total_size,
9797 { "Total Packet Length", "tds.7login.total_len",
9798 FT_UINT32, BASE_DEC, NULL, 0x0,
9799 "TDS7 Login Packet total packet length", HFILL }
9801 { &hf_tds7login_version,
9802 { "TDS version", "tds.7login.version",
9803 FT_UINT32, BASE_HEX, NULL, 0x0,
9804 NULL, HFILL }
9806 { &hf_tds7login_packet_size,
9807 { "Packet Size", "tds.7login.packet_size",
9808 FT_UINT32, BASE_DEC, NULL, 0x0,
9809 NULL, HFILL }
9811 { &hf_tds7login_client_version,
9812 { "Client version", "tds.7login.client_version",
9813 FT_UINT32, BASE_CUSTOM, CF_FUNC(version_convert), 0x0,
9814 NULL, HFILL }
9816 { &hf_tds7login_client_pid,
9817 { "Client PID", "tds.7login.client_pid",
9818 FT_UINT32, BASE_DEC, NULL, 0x0,
9819 NULL, HFILL }
9821 { &hf_tds7login_connection_id,
9822 { "Connection ID", "tds.7login.connection_id",
9823 FT_UINT32, BASE_DEC, NULL, 0x0,
9824 NULL, HFILL }
9826 { &hf_tds7login_option_flags1,
9827 { "Option Flags 1", "tds.7login.option_flags1",
9828 FT_UINT8, BASE_HEX, NULL, 0x0,
9829 NULL, HFILL }
9831 { &hf_tds7login_option_flags2,
9832 { "Option Flags 2", "tds.7login.option_flags2",
9833 FT_UINT8, BASE_HEX, NULL, 0x0,
9834 NULL, HFILL }
9836 { &hf_tds7login_sql_type_flags,
9837 { "SQL Type Flags", "tds.7login.sql_type_flags",
9838 FT_UINT8, BASE_HEX, NULL, 0x0,
9839 NULL, HFILL }
9841 { &hf_tds7login_reserved_flags,
9842 { "Reserved Flags", "tds.7login.reserved_flags",
9843 FT_UINT8, BASE_HEX, NULL, 0x0,
9844 NULL, HFILL }
9846 { &hf_tds7login_time_zone,
9847 { "Time Zone", "tds.7login.time_zone",
9848 FT_UINT32, BASE_HEX, NULL, 0x0,
9849 NULL, HFILL }
9851 { &hf_tds7login_collation,
9852 { "Collation", "tds.7login.collation",
9853 FT_UINT32, BASE_HEX, NULL, 0x0,
9854 NULL, HFILL }
9856 { &hf_tds7login_offset,
9857 { "Offset", "tds.7login.offset",
9858 FT_UINT16, BASE_HEX, NULL, 0x0,
9859 NULL, HFILL }
9861 { &hf_tds7login_length,
9862 { "Length", "tds.7login.length",
9863 FT_UINT16, BASE_HEX, NULL, 0x0,
9864 NULL, HFILL }
9866 { &hf_tds7login_password,
9867 { "Password", "tds.7login.password",
9868 FT_STRING, BASE_NONE, NULL, 0x0,
9869 NULL, HFILL }
9871 { &hf_tds7login_clientname,
9872 { "Client name", "tds.7login.clientname",
9873 FT_STRING, BASE_NONE, NULL, 0x0,
9874 NULL, HFILL }
9876 { &hf_tds7login_username,
9877 { "Username", "tds.7login.username",
9878 FT_STRING, BASE_NONE, NULL, 0x0,
9879 NULL, HFILL }
9881 { &hf_tds7login_appname,
9882 { "App name", "tds.7login.appname",
9883 FT_STRING, BASE_NONE, NULL, 0x0,
9884 NULL, HFILL }
9886 { &hf_tds7login_servername,
9887 { "Server name", "tds.7login.servername",
9888 FT_STRING, BASE_NONE, NULL, 0x0,
9889 NULL, HFILL }
9891 { &hf_tds7login_libraryname,
9892 { "Library name", "tds.7login.libraryname",
9893 FT_STRING, BASE_NONE, NULL, 0x0,
9894 NULL, HFILL }
9896 { &hf_tds7login_locale,
9897 { "Locale", "tds.7login.locale",
9898 FT_STRING, BASE_NONE, NULL, 0x0,
9899 NULL, HFILL }
9901 { &hf_tds7login_databasename,
9902 { "Database name", "tds.7login.databasename",
9903 FT_STRING, BASE_NONE, NULL, 0x0,
9904 NULL, HFILL }
9907 /* PRELOGIN stream */
9909 { &hf_tds_prelogin,
9910 { "Pre-Login Message", "tds.prelogin",
9911 FT_NONE, BASE_NONE, NULL, 0x0,
9912 NULL, HFILL }
9914 { &hf_tds_prelogin_option_token,
9915 { "Option Token", "tds.prelogin.option.token",
9916 FT_UINT8, BASE_DEC, VALS(prelogin_token_names), 0x0,
9917 NULL, HFILL }
9919 { &hf_tds_prelogin_option_offset,
9920 { "Option offset", "tds.prelogin.option.offset",
9921 FT_UINT16, BASE_DEC, NULL, 0x0,
9922 NULL, HFILL }
9924 { &hf_tds_prelogin_option_length,
9925 { "Option length", "tds.prelogin.option.length",
9926 FT_UINT16, BASE_DEC, NULL, 0x0,
9927 NULL, HFILL }
9929 { &hf_tds_prelogin_option_version,
9930 { "Version", "tds.prelogin.option.version",
9931 FT_UINT32, BASE_CUSTOM, CF_FUNC(version_convert), 0x0,
9932 NULL, HFILL }
9934 { &hf_tds_prelogin_option_subbuild,
9935 { "Sub-build", "tds.prelogin.option.subbuild",
9936 FT_UINT16, BASE_DEC, NULL, 0x0,
9937 NULL, HFILL }
9939 { &hf_tds_prelogin_option_encryption,
9940 { "Encryption", "tds.prelogin.option.encryption",
9941 FT_UINT8, BASE_DEC, VALS(prelogin_encryption_options), 0x0,
9942 NULL, HFILL }
9944 { &hf_tds_prelogin_option_instopt,
9945 { "InstOpt", "tds.prelogin.option.instopt",
9946 FT_STRINGZ, BASE_NONE, NULL, 0x0,
9947 NULL, HFILL }
9949 { &hf_tds_prelogin_option_threadid,
9950 { "ThreadID", "tds.prelogin.option.threadid",
9951 FT_UINT32, BASE_DEC, NULL, 0x0,
9952 NULL, HFILL }
9954 { &hf_tds_prelogin_option_mars,
9955 { "MARS", "tds.prelogin.option.mars",
9956 FT_UINT8, BASE_DEC, VALS(tds_mars_type), 0x0,
9957 NULL, HFILL }
9959 { &hf_tds_prelogin_option_traceid,
9960 { "TraceID", "tds.prelogin.option.traceid",
9961 FT_BYTES, BASE_NONE, NULL, 0x0,
9962 NULL, HFILL }
9964 { &hf_tds_prelogin_option_fedauthrequired,
9965 { "FedAuthRequired", "tds.prelogin.option.fedauthrequired",
9966 FT_UINT8, BASE_DEC, NULL, 0x0,
9967 NULL, HFILL }
9969 { &hf_tds_prelogin_option_nonceopt,
9970 { "NonceOpt", "tds.prelogin.option.nonceopt",
9971 FT_BYTES, BASE_NONE, NULL, 0x0,
9972 NULL, HFILL }
9975 /* RPC Request Stream */
9977 { &hf_tds_rpc,
9978 { "Remote Procedure Call", "tds.rpc",
9979 FT_NONE, BASE_NONE, NULL, 0x0,
9980 NULL, HFILL }
9982 { &hf_tds_rpc_name_length8,
9983 { "Procedure name length", "tds.rpc.name_length",
9984 FT_UINT8, BASE_DEC, NULL, 0x0,
9985 NULL, HFILL }
9987 { &hf_tds_rpc_name_length,
9988 { "Procedure name length", "tds.rpc.name_length",
9989 FT_UINT16, BASE_DEC, NULL, 0x0,
9990 NULL, HFILL }
9992 { &hf_tds_rpc_name,
9993 { "Procedure name", "tds.rpc.name",
9994 FT_STRING, BASE_NONE, NULL, 0x0,
9995 NULL, HFILL }
9997 { &hf_tds_rpc_proc_id,
9998 { "Stored procedure ID", "tds.rpc.proc_id",
9999 FT_UINT16, BASE_DEC, VALS(internal_stored_proc_id_names), 0x0,
10000 "The number identifying the special stored procedure to be executed", HFILL }
10002 { &hf_tds_rpc_options,
10003 { "Option flags", "tds.rpc.options",
10004 FT_UINT16, BASE_HEX, NULL, 0x0,
10005 "The number identifying the special stored procedure to be executed", HFILL }
10007 { &hf_tds_rpc_options_with_recomp,
10008 { "With recompile", "tds.rpc.options.with_recomp",
10009 FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_WITH_RECOMP,
10010 "The number identifying the special stored procedure to be executed", HFILL }
10012 { &hf_tds_rpc_options_no_metadata,
10013 { "No metadata", "tds.rpc.options.no_metadata",
10014 FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_NO_METADATA,
10015 "The number identifying the special stored procedure to be executed", HFILL }
10017 { &hf_tds_rpc_options_reuse_metadata,
10018 { "Reuse metadata", "tds.rpc.options.reuse_metadata",
10019 FT_BOOLEAN, 16, NULL, TDS_RPC_OPT_REUSE_METADATA,
10020 "The number identifying the special stored procedure to be executed", HFILL }
10022 { &hf_tds_rpc_separator,
10023 { "RPC batch separator", "tds.rpc.separator",
10024 FT_UINT8, BASE_DEC, VALS(tds_rpc_separators), 0x0,
10025 NULL, HFILL }
10027 { &hf_tds_rpc_parameter,
10028 { "Parameter", "tds.rpc.parameter",
10029 FT_NONE, BASE_NONE, NULL, 0x0,
10030 NULL, HFILL }
10032 { &hf_tds_rpc_parameter_name_length,
10033 { "Name length", "tds.rpc.parameter.name_length",
10034 FT_UINT8, BASE_DEC, NULL, 0x0,
10035 NULL, HFILL }
10037 { &hf_tds_rpc_parameter_name,
10038 { "Name", "tds.rpc.parameter.name",
10039 FT_STRING, BASE_NONE, NULL, 0x0,
10040 NULL, HFILL }
10042 { &hf_tds_rpc_parameter_status,
10043 { "Status flags", "tds.rpc.parameter.status",
10044 FT_UINT8, BASE_HEX, NULL, 0x0,
10045 "Information on how the parameter is passed", HFILL }
10047 { &hf_tds_rpc_parameter_status_by_ref,
10048 { "By reference", "tds.rpc.parameter.status.by_ref",
10049 FT_BOOLEAN, 8, NULL, TDS_RPC_PARAMETER_STATUS_BY_REF,
10050 NULL, HFILL }
10052 { &hf_tds_rpc_parameter_status_default,
10053 { "Default value", "tds.rpc.parameter.status.default",
10054 FT_BOOLEAN, 8, NULL, TDS_RPC_PARAMETER_STATUS_DEFAULT,
10055 NULL, HFILL }
10057 { &hf_tds_rpc_parameter_value,
10058 { "Value", "tds.rpc.parameter.value",
10059 FT_NONE, BASE_NONE, NULL, 0x0,
10060 NULL, HFILL }
10063 /* SQLBatch Stream */
10064 { &hf_tds_query,
10065 { "Query", "tds.query",
10066 FT_STRING, BASE_NONE, NULL, 0x0,
10067 NULL, HFILL }
10070 /* SSPI Message Stream */
10072 /* Transaction Manager Request Stream */
10073 { &hf_tds_transmgr,
10074 { "Transaction Manager Request", "tds.transmgr",
10075 FT_UINT16, BASE_DEC, VALS(transmgr_types), 0x0,
10076 NULL, HFILL }
10078 { &hf_tds_transmgr_payload,
10079 { "Payload", "tds.transmgr.payload",
10080 FT_NONE, BASE_NONE, NULL, 0x0,
10081 NULL, HFILL }
10084 /****************************** Basic types **********************************/
10086 { &hf_tds_type_info,
10087 { "Type info", "tds.type_info",
10088 FT_NONE, BASE_NONE, NULL, 0x0,
10089 "The TYPE_INFO rule applies to several messages used to describe column information", HFILL }
10091 { &hf_tds_type_info_type,
10092 { "Type", "tds.type_info.type",
10093 FT_UINT8, BASE_HEX, NULL, 0x0,
10094 NULL, HFILL }
10096 { &hf_tds_type_info_varlen,
10097 { "Maximal length", "tds.type_info.varlen",
10098 FT_UINT32, BASE_DEC, NULL, 0x0,
10099 "Defines the length of the data contained within the column", HFILL }
10101 { &hf_tds_type_info_precision,
10102 { "Precision", "tds.type_info.precision",
10103 FT_UINT8, BASE_DEC, NULL, 0x0,
10104 NULL, HFILL }
10106 { &hf_tds_type_info_scale,
10107 { "Scale", "tds.type_info.scale",
10108 FT_UINT8, BASE_DEC, NULL, 0x0,
10109 NULL, HFILL }
10111 { &hf_tds_type_info_collation,
10112 { "Collation", "tds.type_info.collation",
10113 FT_NONE, BASE_NONE, NULL, 0x0,
10114 "Specifies collation information for character data or metadata describing character data", HFILL }
10116 { &hf_tds_type_info_collation_lcid,
10117 { "LCID", "tds.type_info.collation.lcid",
10118 FT_UINT32, BASE_HEX, NULL, 0x000FFFFF,
10119 "For a SortId==0 collation, the LCID bits correspond to a LocaleId as defined by the National Language Support (NLS) functions", HFILL }
10121 { &hf_tds_type_info_collation_ign_case,
10122 { "Ignore case", "tds.type_info.collation.ignore_case",
10123 FT_BOOLEAN, 32, NULL, 0x00100000,
10124 NULL, HFILL }
10126 { &hf_tds_type_info_collation_ign_accent,
10127 { "Ignore accent", "tds.type_info.collation.ignore_accent",
10128 FT_BOOLEAN, 32, NULL, 0x00200000,
10129 NULL, HFILL }
10131 { &hf_tds_type_info_collation_ign_kana,
10132 { "Ignore kana", "tds.type_info.collation.ignore_kana",
10133 FT_BOOLEAN, 32, NULL, 0x00400000,
10134 NULL, HFILL }
10136 { &hf_tds_type_info_collation_ign_width,
10137 { "Ignore width", "tds.type_info.collation.ignore_width",
10138 FT_BOOLEAN, 32, NULL, 0x00800000,
10139 NULL, HFILL }
10141 { &hf_tds_type_info_collation_binary,
10142 { "Binary", "tds.type_info.collation.binary",
10143 FT_BOOLEAN, 32, NULL, 0x01000000,
10144 NULL, HFILL }
10146 { &hf_tds_type_info_collation_version,
10147 { "Version", "tds.type_info.collation.version",
10148 FT_UINT32, BASE_DEC, NULL, 0xF0000000,
10149 NULL, HFILL }
10151 { &hf_tds_type_info_collation_sortid,
10152 { "SortId", "tds.type_info.collation.sortid",
10153 FT_UINT8, BASE_DEC, NULL, 0x0,
10154 NULL, HFILL }
10156 { &hf_tds_type_varbyte_length,
10157 { "Length", "tds.type_varbyte.length",
10158 FT_UINT32, BASE_DEC, NULL, 0x0,
10159 NULL, HFILL }
10161 { &hf_tds_type_varbyte_data_null,
10162 { "Data: NULL", "tds.type_varbyte.data.null",
10163 FT_NONE, BASE_NONE, NULL, 0x0,
10164 NULL, HFILL }
10166 { &hf_tds_type_varbyte_data_boolean,
10167 { "Data", "tds.type_varbyte.data.bool",
10168 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
10169 NULL, HFILL }
10171 { &hf_tds_type_varbyte_data_int1,
10172 { "Data", "tds.type_varbyte.data.int",
10173 FT_INT8, BASE_DEC, NULL, 0x0,
10174 NULL, HFILL }
10176 { &hf_tds_type_varbyte_data_int2,
10177 { "Data", "tds.type_varbyte.data.int",
10178 FT_INT16, BASE_DEC, NULL, 0x0,
10179 NULL, HFILL }
10181 { &hf_tds_type_varbyte_data_int4,
10182 { "Data", "tds.type_varbyte.data.int",
10183 FT_INT32, BASE_DEC, NULL, 0x0,
10184 NULL, HFILL }
10186 { &hf_tds_type_varbyte_data_int8,
10187 { "Data", "tds.type_varbyte.data.int64",
10188 FT_INT64, BASE_DEC, NULL, 0x0,
10189 NULL, HFILL }
10191 { &hf_tds_type_varbyte_data_float,
10192 { "Data", "tds.type_varbyte.data.float",
10193 FT_FLOAT, BASE_NONE, NULL, 0x0,
10194 NULL, HFILL }
10196 { &hf_tds_type_varbyte_data_double,
10197 { "Data", "tds.type_varbyte.data.float",
10198 FT_DOUBLE, BASE_NONE, NULL, 0x0,
10199 NULL, HFILL }
10201 { &hf_tds_type_varbyte_data_bytes,
10202 { "Data", "tds.type_varbyte.data.bytes",
10203 FT_BYTES, BASE_NONE, NULL, 0x0,
10204 NULL, HFILL }
10206 { &hf_tds_type_varbyte_data_uint_bytes,
10207 { "Data", "tds.type_varbyte.data.uint_bytes",
10208 FT_UINT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
10209 NULL, HFILL }
10211 { &hf_tds_type_varbyte_data_guid,
10212 { "Data", "tds.type_varbyte.data.guid",
10213 FT_GUID, BASE_NONE, NULL, 0x0,
10214 NULL, HFILL }
10216 { &hf_tds_type_varbyte_data_string,
10217 { "Data", "tds.type_varbyte.data.string",
10218 FT_STRING, BASE_NONE, NULL, 0x0,
10219 NULL, HFILL }
10221 { &hf_tds_type_varbyte_data_uint_string,
10222 { "Data", "tds.type_varbyte.data.uint_string",
10223 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
10224 NULL, HFILL }
10226 { &hf_tds_type_varbyte_data_absdatetime,
10227 { "Data", "tds.type_varbyte.data.datetime",
10228 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
10229 NULL, HFILL }
10231 { &hf_tds_type_varbyte_data_reltime,
10232 { "Time", "tds.type_varbyte.data.time",
10233 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
10234 NULL, HFILL }
10236 { &hf_tds_type_varbyte_data_sign,
10237 { "Sign", "tds.type_varbyte.data.sign",
10238 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
10239 NULL, HFILL }
10241 { &hf_tds_type_varbyte_data_textptr_len,
10242 { "Data Textptr Len", "tds.type_varbyte.textptr_len",
10243 FT_UINT8, BASE_DEC, NULL, 0x0,
10244 NULL, HFILL }
10246 { &hf_tds_type_varbyte_data_textptr,
10247 { "Data Textptr", "tds.type_varbyte.data.textptr",
10248 FT_BYTES, BASE_NONE, NULL, 0x0,
10249 NULL, HFILL }
10251 { &hf_tds_type_varbyte_data_text_ts,
10252 { "Data Text timestamp", "tds.type_varbyte.data.text_ts",
10253 FT_BYTES, BASE_NONE, NULL, 0x0,
10254 NULL, HFILL }
10256 { &hf_tds_type_varbyte_plp_len,
10257 { "PLP length", "tds.type_varbyte.plp_len",
10258 FT_INT64, BASE_DEC, NULL, 0x0,
10259 NULL, HFILL }
10261 { &hf_tds_type_varbyte_plp_chunk_len,
10262 { "PLP chunk length", "tds.type_varbyte.plp_chunk_len",
10263 FT_UINT32, BASE_DEC, NULL, 0x0,
10264 NULL, HFILL }
10266 { &hf_tds_type_varbyte_plp_chunk,
10267 { "PLP chunk", "tds.type_varbyte.plp_chunk",
10268 FT_BYTES, BASE_NONE, NULL, 0x0,
10269 NULL, HFILL }
10271 { &hf_tds_type_varbyte_column_name,
10272 { "Column name", "tds.type_varbyte.column.name",
10273 FT_STRING, BASE_NONE, NULL, 0x0,
10274 NULL, HFILL }
10277 /***************************** Top level TDS *******************************/
10279 { &hf_tds_type,
10280 { "Type", "tds.type",
10281 FT_UINT8, BASE_DEC, VALS(packet_type_names), 0x0,
10282 "Packet type", HFILL }
10284 { &hf_tds_status,
10285 { "Status", "tds.status",
10286 FT_UINT8, BASE_HEX, NULL, 0x0,
10287 "Packet status", HFILL }
10289 { &hf_tds_status_eom,
10290 { "End of message", "tds.status.eom",
10291 FT_BOOLEAN, 8, NULL, STATUS_LAST_BUFFER,
10292 "The packet is the last packet in the whole request", HFILL }
10294 { &hf_tds_status_ignore,
10295 { "Ignore this event", "tds.status.ignore",
10296 FT_BOOLEAN, 8, NULL, STATUS_IGNORE_EVENT,
10297 "(From client to server) Ignore this event (EOM MUST also be set)", HFILL }
10299 { &hf_tds_status_event_notif,
10300 { "Event notification", "tds.status.event_notif",
10301 FT_BOOLEAN, 8, NULL, STATUS_EVENT_NOTIFICATION,
10302 NULL, HFILL }
10304 { &hf_tds_status_reset_conn,
10305 { "Reset connection", "tds.status.reset_conn",
10306 FT_BOOLEAN, 8, NULL, STATUS_RESETCONNECTION,
10307 "(From client to server) Reset this connection before processing event", HFILL }
10309 { &hf_tds_status_reset_conn_skip_tran,
10310 { "Reset connection keeping transaction state", "tds.status.reset_conn_skip_tran",
10311 FT_BOOLEAN, 8, NULL, STATUS_RESETCONNECTIONSKIPTRAN,
10312 "(From client to server) Reset the connection before processing event but do not modify the transaction state", HFILL }
10314 { &hf_tds_length,
10315 { "Length", "tds.length",
10316 FT_UINT16, BASE_DEC, NULL, 0x0,
10317 "Packet length", HFILL }
10319 { &hf_tds_channel,
10320 { "Channel", "tds.channel",
10321 FT_UINT16, BASE_DEC, NULL, 0x0,
10322 "Channel Number", HFILL }
10324 { &hf_tds_packet_number,
10325 { "Packet Number", "tds.packet_number",
10326 FT_UINT8, BASE_DEC, NULL, 0x0,
10327 NULL, HFILL }
10329 { &hf_tds_window,
10330 { "Window", "tds.window",
10331 FT_UINT8, BASE_DEC, NULL, 0x0,
10332 NULL, HFILL }
10334 { &hf_tds_fragment_overlap,
10335 { "Segment overlap", "tds.fragment.overlap",
10336 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
10337 "Fragment overlaps with other fragments", HFILL }
10339 { &hf_tds_fragment_overlap_conflict,
10340 { "Conflicting data in fragment overlap", "tds.fragment.overlap.conflict",
10341 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
10342 "Overlapping fragments contained conflicting data", HFILL }
10344 { &hf_tds_fragment_multiple_tails,
10345 { "Multiple tail fragments found", "tds.fragment.multipletails",
10346 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
10347 "Several tails were found when defragmenting the packet", HFILL }
10349 { &hf_tds_fragment_too_long_fragment,
10350 { "Segment too long", "tds.fragment.toolongfragment",
10351 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
10352 "Segment contained data past end of packet", HFILL }
10354 { &hf_tds_fragment_error,
10355 { "Defragmentation error", "tds.fragment.error",
10356 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
10357 "Defragmentation error due to illegal fragments", HFILL }
10359 { &hf_tds_fragment_count,
10360 { "Segment count", "tds.fragment.count",
10361 FT_UINT32, BASE_DEC, NULL, 0x0,
10362 NULL, HFILL }
10364 { &hf_tds_fragment,
10365 { "TDS Fragment", "tds.fragment",
10366 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
10367 NULL, HFILL }
10369 { &hf_tds_fragments,
10370 { "TDS Fragments", "tds.fragments",
10371 FT_NONE, BASE_NONE, NULL, 0x0,
10372 NULL, HFILL }
10374 { &hf_tds_reassembled_in,
10375 { "Reassembled TDS in frame", "tds.reassembled_in",
10376 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
10377 "This TDS packet is reassembled in this frame", HFILL }
10379 { &hf_tds_reassembled_length,
10380 { "Reassembled TDS length", "tds.reassembled.length",
10381 FT_UINT32, BASE_DEC, NULL, 0x0,
10382 "The total length of the reassembled payload", HFILL }
10384 { &hf_tds_all_headers,
10385 { "Packet data stream headers", "tds.all_headers",
10386 FT_NONE, BASE_NONE, NULL, 0x0,
10387 "The ALL_HEADERS rule", HFILL }
10389 { &hf_tds_all_headers_total_length,
10390 { "Total length", "tds.all_headers.total_length",
10391 FT_UINT32, BASE_DEC, NULL, 0x0,
10392 "Total length of ALL_HEADERS stream", HFILL }
10394 { &hf_tds_all_headers_header_length,
10395 { "Length", "tds.all_headers.header.length",
10396 FT_UINT32, BASE_DEC, NULL, 0x0,
10397 "Total length of an individual header", HFILL }
10399 { &hf_tds_all_headers_header_type,
10400 { "Type", "tds.all_headers.header.type",
10401 FT_UINT16, BASE_HEX, VALS(header_type_names), 0x0,
10402 NULL, HFILL }
10404 { &hf_tds_all_headers_trans_descr,
10405 { "Transaction descriptor", "tds.all_headers.header.trans_descr",
10406 FT_UINT64, BASE_DEC, NULL, 0x0,
10407 "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 }
10409 { &hf_tds_all_headers_request_cnt,
10410 { "Outstanding request count", "tds.all_headers.header.request_cnt",
10411 FT_UINT32, BASE_DEC, NULL, 0x0,
10412 "Number of requests currently active on the connection", HFILL }
10414 { &hf_tds_unknown_tds_packet,
10415 { "TDS Packet", "tds.unknown_tds_packet",
10416 FT_BYTES, BASE_NONE, NULL, 0x0,
10417 NULL, HFILL }
10421 static int *ett[] = {
10422 &ett_tds,
10423 &ett_tds_status,
10424 &ett_tds_fragments,
10425 &ett_tds_fragment,
10426 &ett_tds_all_headers,
10427 &ett_tds_all_headers_header,
10428 &ett_tds_type_info,
10429 &ett_tds_type_info_collation,
10430 &ett_tds_type_varbyte,
10431 &ett_tds_message,
10432 &ett_tds_rpc_options,
10433 &ett_tds_rpc_parameter,
10434 &ett_tds_rpc_parameter_status,
10435 &ett_tds_prelogin_option,
10436 &ett_tds_token,
10437 &ett_tds_capability_req,
10438 &ett_tds_capability_resp,
10439 &ett_tds_done_status,
10440 &ett_tds7_query,
10441 &ett_tds7_prelogin,
10442 &ett_tds_login,
10443 &ett_tds_login_options,
10444 &ett_tds_login_options2,
10445 &ett_tds_login_rempw,
10446 &ett_tds7_login,
10447 &ett_tds7_hdr,
10448 &ett_tds_col,
10449 &ett_tds_flags,
10450 &ett_tds7_featureextack,
10451 &ett_tds7_featureextack_feature,
10452 &ett_tds5_dbrpc_options,
10453 &ett_tds5_curdeclare_options,
10454 &ett_tds5_curinfo_status
10457 static ei_register_info ei[] = {
10458 { &ei_tds_all_headers_header_type, { "tds.all_headers.header.type.invalid", PI_PROTOCOL, PI_WARN, "Invalid header type", EXPFILL }},
10459 { &ei_tds_type_info_type, { "tds.type_info.type.invalid", PI_PROTOCOL, PI_WARN, "Invalid data type", EXPFILL }},
10460 #if 0
10461 { &ei_tds_type_info_type_undecoded, { "tds.type_info.type.undecoded", PI_UNDECODED, PI_ERROR, "Data type not supported yet", EXPFILL }},
10462 #endif
10463 { &ei_tds_invalid_length, { "tds.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
10464 { &ei_tds_token_length_invalid, { "tds.token.length.invalid", PI_PROTOCOL, PI_WARN, "Bogus token size", EXPFILL }},
10465 { &ei_tds_invalid_plp_length, { "tds.invalid_plp_length", PI_PROTOCOL, PI_NOTE, "PLP length doesn't equal the sum of the lengths of the chunks", EXPFILL }},
10466 #if 0
10467 { &ei_tds_token_stats, { "tds.token.stats", PI_PROTOCOL, PI_NOTE, "Token stats", EXPFILL }},
10468 #endif
10469 { &ei_tds_invalid_plp_type, { "tds.type_info.type.invalidplp", PI_PROTOCOL, PI_NOTE, "Invalid PLP type", EXPFILL }},
10470 { &ei_tds_cursor_name_mismatch, { "tds.cursor.name_mismatch", PI_PROTOCOL, PI_WARN, "Cursor name mismatch", EXPFILL }}
10473 module_t *tds_module;
10474 expert_module_t* expert_tds;
10476 /* Register the protocol name and description */
10477 proto_tds = proto_register_protocol("Tabular Data Stream", "TDS", "tds");
10479 /* Required function calls to register the header fields and subtrees used */
10480 proto_register_field_array(proto_tds, hf, array_length(hf));
10481 proto_register_subtree_array(ett, array_length(ett));
10482 expert_tds = expert_register_protocol(proto_tds);
10483 expert_register_field_array(expert_tds, ei, array_length(ei));
10485 /* Allow dissector to be found by name. */
10486 tds_tcp_handle = register_dissector("tds", dissect_tds, proto_tds);
10488 tds_module = prefs_register_protocol(proto_tds, apply_tds_prefs);
10489 prefs_register_bool_preference(tds_module, "desegment_buffers",
10490 "Reassemble TDS buffers spanning multiple TCP segments",
10491 "Whether the TDS dissector should reassemble TDS buffers spanning multiple TCP segments. "
10492 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
10493 &tds_desegment);
10494 prefs_register_bool_preference(tds_module, "defragment",
10495 "Reassemble fragmented TDS messages with multiple buffers",
10496 "Whether the TDS dissector should defragment messages spanning multiple Netlib buffers",
10497 &tds_defragment);
10498 prefs_register_enum_preference(tds_module, "protocol_type",
10499 "TDS Protocol Type",
10500 "Hint as to version of TDS protocol being decoded",
10501 &tds_protocol_type, tds_protocol_type_options, false);
10502 prefs_register_enum_preference(tds_module, "endian_type",
10503 "TDS decode as",
10504 "Hint as to whether to decode TDS protocol as little-endian or big-endian. (TDS7/8 always decoded as little-endian)",
10505 &tds_little_endian, tds_endian_type_options, false);
10508 * Initialize the reassembly table.
10510 * XXX - should fragments be reassembled across multiple TCP
10511 * connections?
10514 reassembly_table_register(&tds_reassembly_table,
10515 &addresses_ports_reassembly_table_functions);
10518 /* If this dissector uses sub-dissector registration add a registration routine.
10519 This format is required because a script is used to find these routines and
10520 create the code that calls these routines.
10522 void
10523 proto_reg_handoff_tds(void)
10525 /* Initial TDS ports: MS SQL default ports */
10526 dissector_add_uint_range_with_preference("tcp.port", TDS_PORT_RANGE, tds_tcp_handle);
10527 apply_tds_prefs();
10528 heur_dissector_add("tcp", dissect_tds_tcp_heur, "Tabular Data Stream over TCP", "tds_tcp", proto_tds, HEURISTIC_ENABLE);
10530 ntlmssp_handle = find_dissector_add_dependency("ntlmssp", proto_tds);
10531 gssapi_handle = find_dissector_add_dependency("gssapi", proto_tds);
10532 spnego_handle = find_dissector_add_dependency("spnego", proto_tds);
10533 smp_handle = find_dissector_add_dependency("smp_tds", proto_tds);
10534 tls_handle = find_dissector_add_dependency("tls", proto_tds);
10536 /* Isn't required, but allows user to override current payload */
10537 dissector_add_for_decode_as("smp.payload", create_dissector_handle(dissect_tds_pdu, proto_tds));
10541 * Editor modelines
10543 * Local Variables:
10544 * c-basic-offset: 4
10545 * tab-width: 8
10546 * indent-tabs-mode: nil
10547 * End:
10549 * ex: set shiftwidth=4 tabstop=8 expandtab:
10550 * :indentSize=4:tabSize=8:noTabs=true: