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
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
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.
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>
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 */
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) */
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) */
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 */
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 || \
397 #define is_longlen_type_sybase(x) ((x)==SYBLONGCHAR || \
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
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
[] = {
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)"},
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)"},
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"},
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)"},
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 */
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
;
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 */
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 */
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
;
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
;
1173 static int hf_tds_sspi
;
1174 static int hf_tds_sspi_buffer
;
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
;
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 */
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
= {
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 */
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
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
;
1355 tds_cursor_info_t
*tds_conv_cursor_current
;
1356 wmem_tree_t
*tds_conv_cursor_table
;
1357 } tds_conv_cursor_info_t
;
1360 tds_conv_cursor_info_t
*tds_conv_cursor_info
;
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
;
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
},
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},
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"},
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"},
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"},
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"},
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" },
1599 static const value_string envchg_names
[] = {
1602 {3, "Character set"},
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"},
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"},
1640 {TDS_DATE4_TIME_FIRST
, "Time first"},
1641 {TDS_DATE4_DATE_FIRST
, "Date first"},
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"},
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"},
1665 static const value_string tds_capability_type
[] = {
1666 {TDS_CAP_REQUEST
, "Request capabilities"},
1667 {TDS_CAP_RESPONSE
, "Response capabilities"},
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"},
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"},
1689 static const value_string login_field_names
[] = {
1696 {6, "Library Name"},
1698 {8, "Database Name"},
1702 static const value_string prelogin_token_names
[] = {
1709 {6, "FedAuthRequired"},
1711 {255, "Terminator"},
1715 static const value_string featureextack_feature_names
[] = {
1717 {1, "SessionRecovery"},
1719 {4, "ColumnEncryption"},
1720 {5, "GlobalTransactions"},
1721 {8, "AzureSQLSupport"},
1722 {9, "DataClassification"},
1723 {10, "UTF8Support"},
1724 {255, "Terminator"},
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"},
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"},
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
[] = {
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.
1772 struct _netlib_data
{
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
;
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.
1804 dissect_tds_nt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
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
);
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
);
1820 call_dissector(gssapi_handle
, nt_tvb
, pinfo
, tree
);
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
;
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
;
1837 tds_get_char_encoding(tds_conv_info_t
*tds_info
)
1839 switch (tds_info
->tds_encoding_char
) {
1840 case TDS_CHAR_ASCII
:
1843 case TDS_CHAR_EBCDIC
:
1846 case TDS_CHAR_UTF16
:
1847 return (ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
1853 tds_char_encoding_is_two_byte(tds_conv_info_t
*tds_info
)
1855 return (tds_info
->tds_encoding_char
== TDS_CHAR_UTF16
);
1859 tds_token_is_fixed_size_sybase(uint8_t 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
:
1876 tds_get_fixed_token_size_sybase(uint8_t token
, tds_conv_info_t
*tds_info _U_
)
1879 case TDS_DONE_TOKEN
:
1880 case TDS_DONEPROC_TOKEN
:
1881 case TDS_DONEINPROC_TOKEN
:
1883 case TDS_PROCID_TOKEN
:
1885 case TDS_RET_STAT_TOKEN
:
1887 case TDS5_LOGOUT_TOKEN
:
1889 case TDS_OFFSET_TOKEN
:
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
)
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
));
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
);
1920 /* Some have no length field at all. */
1921 case TDS5_PARAMS_TOKEN
:
1923 *len_field_size_p
= 0;
1924 *len_field_val_p
= 0;
1926 /* and most have a 2 byte length field */
1928 *len_field_size_p
= 2;
1929 *len_field_val_p
= tvb_get_uint16(tvb
, offset
,
1930 tds_get_int2_encoding(tds_info
));
1933 return *len_field_val_p
+ *len_field_size_p
+ 1;
1937 get_size_by_coltype(int 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;
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
;
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
;
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
;
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)
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
;
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");
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
:
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
);
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
);
2045 handle_tds_sql_datetime(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*sub_tree
, tds_conv_info_t
*tds_info
)
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
));
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
);
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
));
2088 /* TODO Check these values in the login packet and offer expert information.
2089 * Here just make sure they're initialized.
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 */
2097 proto_tree_add_time(sub_tree
, hf_tds_type_varbyte_data_absdatetime
, tvb
, offset
, 8, &tv
);
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);
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);
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
;
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
);
2132 proto_item_append_text(item
, " %i", fieldnum
);
2134 if (name
&& strlen(name
) > 0) {
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
);
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
);
2145 if(plp_length
== TDS_PLP_NULL
)
2146 proto_item_append_text(length_item
, " (PLP_NULL)");
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
2159 combined_chunks_tvb
= NULL
;
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
);
2163 if(length
== TDS_PLP_TERMINATOR
) {
2164 proto_item_append_text(length_item
, " (PLP_TERMINATOR)");
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
);
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?
2196 const uint8_t *strval
= NULL
;
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
);
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
);
2207 proto_item_append_text(item
, " (%s)", strval
);
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
);
2216 proto_item_append_text(item
, " (%s)", strval
);
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
);
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");
2229 * If a length was specified, report an error if it's not
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.
2242 case TDS_DATA_TYPE_BIGVARBIN
: /* VarBinary */
2243 proto_tree_add_bytes(sub_tree
, hf_tds_type_varbyte_data_bytes
, NULL
, 0, 0, NULL
);
2245 case TDS_DATA_TYPE_BIGVARCHR
: /* VarChar */
2246 proto_tree_add_string(sub_tree
, hf_tds_type_varbyte_data_string
, NULL
, 0, 0, "");
2248 case TDS_DATA_TYPE_NVARCHAR
: /* NVarChar */
2249 proto_tree_add_string(sub_tree
, hf_tds_type_varbyte_data_string
, NULL
, 0, 0, "");
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
);
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
) {
2264 case TDS_DATA_TYPE_NULL
: /* Null (no data associated with this type) */
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
);
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
);
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
);
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
);
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
);
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
);
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
);
2297 case TDS_DATA_TYPE_DATETIME4
: /* SmallDateTime (4 byte data representation) */
2298 handle_tds_sql_smalldatetime(tvb
, *offset
, sub_tree
, tds_info
);
2301 case TDS_DATA_TYPE_MONEY4
: /* SmallMoney (4 byte data representation) */
2302 handle_tds_sql_smallmoney(tvb
, *offset
, sub_tree
, tds_info
);
2305 case TDS_DATA_TYPE_DATETIME
: /* DateTime (8 byte data representation) */
2306 handle_tds_sql_datetime(tvb
, *offset
, sub_tree
, tds_info
);
2309 case TDS_DATA_TYPE_MONEY
: /* Money (8 byte data representation) */
2310 handle_tds_sql_money(tvb
, *offset
, sub_tree
, tds_info
);
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
);
2321 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_null
, tvb
, *offset
, 0, ENC_NA
);
2324 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_guid
, tvb
, *offset
+ 1, length
, ENC_LITTLE_ENDIAN
);
2327 expert_add_info(pinfo
, length_item
, &ei_tds_invalid_length
);
2329 *offset
+= 1 + length
;
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
);
2337 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_null
, tvb
, *offset
, 0, ENC_NA
);
2340 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_boolean
, tvb
, *offset
+ 1, 1, ENC_NA
);
2343 expert_add_info(pinfo
, length_item
, &ei_tds_invalid_length
);
2345 *offset
+= 1 + length
;
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
);
2353 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_null
, tvb
, *offset
, 0, ENC_NA
);
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
);
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
);
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
);
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
));
2372 expert_add_info(pinfo
, length_item
, &ei_tds_invalid_length
);
2374 *offset
+= 1 + length
;
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
);
2382 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_null
, tvb
, *offset
, 0, ENC_NA
);
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
));
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
));
2393 expert_add_info(pinfo
, length_item
, &ei_tds_invalid_length
);
2395 *offset
+= 1 + length
;
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
);
2405 handle_tds_sql_smallmoney(tvb
, *offset
, sub_tree
, tds_info
);
2409 handle_tds_sql_money(tvb
, *offset
, sub_tree
, tds_info
);
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
);
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 */
2429 proto_tree_add_time(sub_tree
, hf_tds_type_varbyte_data_absdatetime
, tvb
, *offset
, length
, &tv
);
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
);
2445 for(i
= length
- 1; i
> 0; i
--)
2447 value
= value
+ tvb_get_uint8(tvb
, *offset
+ i
);
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
);
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
);
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
);
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
);
2490 int i
, bytestoread
= 0;
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
);
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;
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
);
2536 int i
, bytestoread
= 0;
2540 int16_t timeoffset
= 0;
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
);
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;
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
);
2595 if (TDS_PROTO_TDS5(tds_info
)) {
2597 * Data are big-endian.
2598 * The size appears to be variable governed on the Precision specification.
2599 * Sign of true indicates negative.
2603 proto_tree_add_item_ret_boolean(sub_tree
, hf_tds_type_varbyte_data_sign
, tvb
, *offset
, 1, ENC_NA
, &sign
);
2607 numericitem
= proto_tree_add_item(sub_tree
,
2608 hf_tds_type_varbyte_data_bytes
, tvb
, *offset
, length
,
2611 uint8_t data_array
[8];
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
];
2628 proto_item_append_text(numericitem
,
2630 (sign
? -int64_value
: int64_value
));
2633 proto_item_append_text(numericitem
,
2635 (double)(sign
? -int64_value
2636 : int64_value
)/pow(10.0, (double)(scale
)));
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.
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.
2655 proto_tree_add_item_ret_boolean(sub_tree
,
2656 hf_tds_type_varbyte_data_sign
, tvb
, *offset
, 1,
2661 numericitem
= proto_tree_add_item(sub_tree
,
2662 hf_tds_type_varbyte_data_bytes
, tvb
, *offset
, length
,
2665 uint8_t data_array
[8];
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
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
];
2688 proto_item_append_text(numericitem
,
2690 (sign
? -int64_value
: int64_value
));
2693 proto_item_append_text(numericitem
,
2695 (double)(sign
? int64_value
2696 : -int64_value
)/pow(10.0, (double)(scale
)));
2703 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_null
, tvb
, *offset
,
2708 case TDS_DATA_TYPE_CHAR
: /* Char (TDS 4/5) */
2709 case TDS_DATA_TYPE_VARCHAR
: /* VarChar (TDS 4/5) */
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
);
2717 case TDS_DATA_TYPE_BINARY
: /* Binary (TDS 4/5) */
2718 case TDS_DATA_TYPE_VARBINARY
: /* VarBinary (TDS 4/5) */
2721 proto_tree_add_item_ret_length(sub_tree
, hf_tds_type_varbyte_data_uint_bytes
,
2722 tvb
, *offset
, 1, ENC_NA
, &len
);
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
)) {
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
);
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
);
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
);
2749 const uint8_t *strval
= NULL
;
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
);
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
);
2761 proto_item_append_text(item
, " (%s)", strval
);
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
);
2770 proto_item_append_text(item
, " (%s)", strval
);
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) */
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
);
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) */
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)");
2804 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_textptr
, tvb
,
2805 *offset
+ 1, textptrlen
, ENC_NA
);
2806 *offset
+= 1 + textptrlen
;
2809 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_text_ts
, tvb
,
2810 *offset
, 8, ENC_NA
);
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
);
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
);
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
);
2825 case TDS_DATA_TYPE_TEXT
:
2826 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_string
, tvb
, *offset
, length
, ENC_ASCII
);
2829 proto_tree_add_item(sub_tree
, hf_tds_type_varbyte_data_bytes
, tvb
, *offset
, length
, ENC_NA
);
2835 proto_item_set_end(item
, tvb
, *offset
);
2839 dissect_tds_query_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, tds_conv_info_t
*tds_info
)
2842 unsigned string_encoding
= ENC_UTF_16
|ENC_LITTLE_ENDIAN
;
2843 proto_tree
*query_tree
;
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
,
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
));
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
));
2886 return cur
- offset
;
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
);
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
);
2905 proto_tree_add_item(tree
, hf_tds_lang_language_text
, tvb
, cur
, len
, ENC_ASCII
);
2908 return cur
- offset
;
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
);
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
) {
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
;
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
;
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
);
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
);
2957 if (cursorid
== 0) {
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
);
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
;
2984 tds_cursor_info_t
*cursor_current
;
2986 (tds_cursor_info_t
*) wmem_tree_lookup32(conv_cursor_info
->tds_conv_cursor_table
,
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
,
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
);
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
);
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
);
3037 proto_tree_add_item_ret_uint(tree
, hf_tds_curdeclare_update_columns_num
, tvb
, cur
, 1,
3038 ENC_NA
, &num_updatable_columns
);
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
;
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
;
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
);
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
);
3111 if (cursorid
== 0) {
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
);
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
));
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
) {
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
;
3150 (tds_cursor_info_t
*) wmem_tree_lookup32(conv_cursor_info
->tds_conv_cursor_table
,
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
,
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
;
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
);
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
);
3195 if (cursorid
== 0) {
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
);
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
));
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
));
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
&&
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
) {
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
,
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
;
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
;
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
);
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
);
3292 if (cursorid
== 0) {
3294 const uint8_t *cursorname
;
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
);
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
,
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
,
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
,
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
,
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
,
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
,
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 */
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
,
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
,
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
,
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 */
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
,
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
,
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
,
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
,
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 */
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
,
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
,
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 */
3534 static int * const *hf_req_array
[] = {
3548 static int * const *hf_resp_array
[] = {
3561 dissect_tds5_capability_token(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
,
3562 proto_tree
*tree
, tds_conv_info_t
*tds_info
)
3566 proto_tree_add_item_ret_uint(tree
, hf_tds_capability_length
, tvb
, offset
, 2, tds_get_int2_encoding(tds_info
), &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
);
3579 if (caplen
> (cur
- len
)) {
3580 expert_add_info_format(pinfo
, length_item
, &ei_tds_token_length_invalid
,
3581 " Capability length %d", caplen
);
3585 for (cap
=0; cap
< caplen
; cap
++) {
3586 int * const *hf_array
= NULL
;
3587 char name
[ITEM_LABEL_LENGTH
];
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
;
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
;
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,
3617 ENC_NA
, BMT_NO_INT
|BMT_NO_TFS
);
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
);
3640 proto_tree_add_item(request_tree
, hf_tds_transmgr
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3644 proto_tree_add_item(request_tree
, hf_tds_transmgr_payload
, tvb
, offset
+ 2, len
- 2, ENC_NA
);
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
);
3657 return cur
- offset
;
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
);
3666 proto_tree_add_item(tree
, hf_tds_msg_status
, tvb
, cur
, 1, ENC_NA
);
3668 proto_tree_add_item(tree
, hf_tds_msg_msgid
, tvb
, cur
, 2, tds_get_int2_encoding(tds_info
));
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)
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
)
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. */
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
;
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
);
3711 nl_data
->columns
[col
]->name
= (const char*)colname
;
3713 proto_tree_add_item(tree
, hf_tds_paramfmt_status
, tvb
, cur
, 1, ENC_NA
);
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
));
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
);
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
);
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
);
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
);
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)
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
)
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. */
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
;
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
);
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
));
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
));
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
);
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
);
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
);
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
);
3832 nl_data
->num_cols
= col
;
3833 return cur
- offset
;
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
;
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.
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
;
3911 dissect_tds5_tokenized_request_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
3912 tds_conv_info_t
*tds_info
)
3916 unsigned token_len_field_size
= 2;
3917 unsigned token_len_field_val
= 0;
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
);
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.
3934 while (tvb_reported_length_remaining(tvb
, pos
) > 0) {
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;
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
);
3954 case TDS_LANG_TOKEN
:
3955 token_sz
= dissect_tds5_lang_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
3957 case TDS_CURCLOSE_TOKEN
:
3958 token_sz
= dissect_tds5_curclose_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
3960 case TDS_CURDECLARE_TOKEN
:
3961 token_sz
= dissect_tds5_curdeclare_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
3963 case TDS_CURFETCH_TOKEN
:
3964 token_sz
= dissect_tds5_curfetch_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
3966 case TDS_CURINFO_TOKEN
:
3967 token_sz
= dissect_tds5_curinfo_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
3969 case TDS_CUROPEN_TOKEN
:
3970 token_sz
= dissect_tds5_curopen_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
3972 case TDS5_LOGOUT_TOKEN
:
3973 token_sz
= dissect_tds5_logout_token(token_tree
, tvb
, pos
+ 1, tds_info
) + 1;
3975 case TDS5_DBRPC_TOKEN
:
3976 token_sz
= dissect_tds5_dbrpc_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
3978 case TDS5_PARAMFMT_TOKEN
:
3979 token_sz
= dissect_tds_paramfmt_token(token_tree
, tvb
, pos
+ 1, tds_info
, &nl_data
) + 1;
3981 case TDS5_PARAMFMT2_TOKEN
:
3982 token_sz
= dissect_tds_paramfmt2_token(token_tree
, tvb
, pos
+ 1, tds_info
, &nl_data
) + 1;
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;
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
;
4006 set_tds_version(packet_info
*pinfo
, tds_conv_info_t
*tds_info
, uint32_t tds_version
)
4008 if (PINFO_FD_VISITED(pinfo
)) {
4012 switch (tds_version
) {
4013 case TDS_PROTOCOL_VALUE_4_2
:
4014 tds_info
->tds_version
= TDS_PROTOCOL_4
;
4016 case TDS_PROTOCOL_VALUE_4_6
:
4017 tds_info
->tds_version
= TDS_PROTOCOL_4
;
4019 case TDS_PROTOCOL_VALUE_5
:
4020 tds_info
->tds_version
= TDS_PROTOCOL_5
;
4022 case TDS_PROTOCOL_VALUE_7_0
:
4023 tds_info
->tds_version
= TDS_PROTOCOL_7_0
;
4024 set_tds7_encodings(tds_info
);
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
);
4031 case TDS_PROTOCOL_VALUE_7_2
:
4032 tds_info
->tds_version
= TDS_PROTOCOL_7_2
;
4033 set_tds7_encodings(tds_info
);
4035 case TDS_PROTOCOL_VALUE_7_3A
:
4036 tds_info
->tds_version
= TDS_PROTOCOL_7_3A
;
4037 set_tds7_encodings(tds_info
);
4039 case TDS_PROTOCOL_VALUE_7_3B
:
4040 tds_info
->tds_version
= TDS_PROTOCOL_7_3B
;
4041 set_tds7_encodings(tds_info
);
4043 case TDS_PROTOCOL_VALUE_7_4
:
4044 tds_info
->tds_version
= TDS_PROTOCOL_7_4
;
4045 set_tds7_encodings(tds_info
);
4048 tds_info
->tds_version
= TDS_PROTOCOL_7_4
;
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
)) {
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.)
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
);
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) {
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. */
4106 tds_info
->tds_version
= TDS_PROTOCOL_7_4
;
4107 } else if (major_minor
>= 0x0a32) {
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 */
4117 tds_info
->tds_version
= TDS_PROTOCOL_7_3B
;
4118 } else if (major_minor
>= 0x0a00) {
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 */
4130 tds_info
->tds_version
= TDS_PROTOCOL_7_3A
;
4131 } else if (major_minor
>= 0x0900) {
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 */
4139 tds_info
->tds_version
= TDS_PROTOCOL_7_2
;
4140 } else if (major_minor
>= 0x0800) {
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 */
4148 tds_info
->tds_version
= TDS_PROTOCOL_7_1
;
4149 } else if (major_minor
>= 0x0700) {
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 */
4157 tds_info
->tds_version
= TDS_PROTOCOL_7_0
;
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
)))
4190 dissect_tds7_prelogin_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, tds_conv_info_t
*tds_info
,
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
);
4203 tvbuff_t
*next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
4204 call_dissector(tls_handle
, next_tvb
, pinfo
, tree
);
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
);
4225 if(token
== TDS7_PRELOGIN_OPTION_TERMINATOR
)
4227 proto_item_append_text(option_item
, ": Terminator");
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
);
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
);
4241 case TDS7_PRELOGIN_OPTION_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
,
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
);
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
);
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
);
4262 case TDS7_PRELOGIN_OPTION_THREADID
: {
4263 proto_item_append_text(option_item
, ": ThreadID");
4265 proto_tree_add_item(option_tree
, hf_tds_prelogin_option_threadid
, tvb
, tokenoffset
, tokenlen
, ENC_BIG_ENDIAN
);
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
);
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
);
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
);
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
);
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
,
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
);
4309 proto_tree_add_item(tree
, hf
, tvb
, offset
, len
, ENC_ASCII
);
4311 return offset
+ namesize
+ 1;
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
);
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);
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
;
4370 uint32_t tds_version
;
4372 /* create display subtree for the protocol */
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
);
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
);
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
);
4408 proto_tree_add_item(login_options_tree
, hf_tdslogin_option_float
, tvb
, offset
, 1, ENC_NA
);
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
);
4413 proto_tree_add_item(login_options_tree
, hf_tdslogin_option_usedb
, tvb
, offset
, 1, ENC_NA
);
4415 proto_tree_add_item(login_options_tree
, hf_tdslogin_option_bulk
, tvb
, offset
, 1, ENC_NA
);
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
);
4421 proto_tree_add_item(login_options_tree
, hf_tdslogin_option_conversation_type
, tvb
, offset
, 1, ENC_NA
);
4423 /* TDS 4 packet size */
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
,
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
);
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
);
4456 proto_tree_add_item(login_options2_tree
, hf_tdslogin_option2_flt4
, tvb
, offset
, 1, ENC_NA
);
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
);
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
);
4469 /* Two bytes of oldsecure unused, must be zero. */
4472 proto_tree_add_item(login_tree
, hf_tdslogin_seclogin
, tvb
, offset
, 1, ENC_NA
);
4474 proto_tree_add_item(login_tree
, hf_tdslogin_secbulk
, tvb
, offset
, 1, ENC_NA
);
4476 proto_tree_add_item(login_tree
, hf_tdslogin_halogin
, tvb
, offset
, 1, ENC_NA
);
4479 proto_tree_add_item(login_tree
, hf_tdslogin_hasessionid
, tvb
, offset
, 6, ENC_NA
);
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
);
4492 offset
= dissect_tds45_login_name(tvb
, pinfo
, login_tree
,
4493 hf_tdslogin_packetsize
, hf_tdslogin_packetsize_length
,
4494 offset
, TDS_PKTLEN
, "packetsize");
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
);
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 */
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"),
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"),
4586 login_hf
= hf_tds7login_clientname
;
4589 login_hf
= hf_tds7login_username
;
4592 login_hf
= hf_tds7login_password
;
4595 login_hf
= hf_tds7login_appname
;
4598 login_hf
= hf_tds7login_servername
;
4601 login_hf
= hf_tds7login_libraryname
;
4604 login_hf
= hf_tds7login_locale
;
4607 login_hf
= hf_tds7login_databasename
;
4613 /* tds 7 is always unicode */
4615 proto_tree_add_item(login_tree
, login_hf
, tvb
, offset2
, len
,
4616 ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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.
4631 wmem_strbuf_t
*val2
;
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
++) {
4639 /* Swap the most and least significant bits */
4640 val
[j
] = ((val
[j
] & 0x0F) << 4) | ((val
[j
] & 0xF0) >> 4);
4643 wmem_strbuf_append_c(val2
, val
[j
]); /* ASCII */
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
)
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;
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;
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 */
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. */
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) */
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)
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;
4737 proto_tree_add_item_ret_uint(tree
, hf_tds_colname_length
, tvb
, offset
, 2,
4738 tds_get_int2_encoding(tds_info
), &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
;
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
;
4765 proto_item_set_text(col_item
, "Column %d (%s)", col
+ 1, colname
);
4768 proto_item_set_text(col_item
, "Column %d", col
+ 1);
4770 proto_item_set_len(col_item
, 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)
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
)
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
);
4797 while (cur
< next
) {
4798 proto_item
*col_item
;
4799 proto_tree
*col_tree
;
4800 unsigned colstart
= cur
;
4803 if (col
>= TDS_MAX_COLUMNS
) {
4804 nl_data
->num_cols
= TDS_MAX_COLUMNS
;
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
);
4817 if (nl_data
->columns
[col
]->name
) {
4818 proto_item_append_text(col_item
, " (%s", nl_data
->columns
[col
]->name
);
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
));
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
);
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"));
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
)) {
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
);
4853 proto_tree_add_item_ret_length(col_tree
, hf_tds_colfmt_text_tablename
,
4855 tds_get_char_encoding(tds_info
)|tds_get_int2_encoding(tds_info
),
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
);
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
);
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)
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
)
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. */
4902 while (cur
< next
) {
4903 proto_item
*col_item
;
4904 proto_tree
*col_tree
;
4905 unsigned colstart
= cur
;
4909 const uint8_t *colname
= NULL
;
4911 if (col
>= TDS_MAX_COLUMNS
) {
4912 nl_data
->num_cols
= TDS_MAX_COLUMNS
;
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
);
4934 proto_tree_add_item(col_tree
, hf_tds_rowfmt_status
, tvb
, cur
, 1, ENC_NA
);
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
));
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
);
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"));
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
)) {
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
);
4965 proto_tree_add_item_ret_length(col_tree
, hf_tds_rowfmt_text_tablename
,
4967 tds_get_char_encoding(tds_info
)|tds_get_int2_encoding(tds_info
),
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
);
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
);
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
;
4998 proto_tree_add_item_ret_length(col_tree
, hf_tds_rowfmt_locale_info
,
4999 tvb
, cur
, 1, ENC_NA
, &localelen
);
5002 proto_item_set_len(col_item
, cur
- colstart
);
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)
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
)
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. */
5045 while (cur
< next
) {
5046 proto_item
*col_item
;
5047 proto_tree
*col_tree
;
5048 unsigned colstart
= cur
;
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*)"";
5055 if (col
>= TDS_MAX_COLUMNS
) {
5056 nl_data
->num_cols
= TDS_MAX_COLUMNS
;
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
);
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
);
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
);
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
));
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
));
5129 proto_tree_add_item_ret_uint(col_tree
, hf_tds_rowfmt2_ctype
, tvb
, cur
, 1, ENC_NA
, &ctype
);
5132 nl_data
->columns
[col
]->ctype
= ctype
;
5134 if (!is_fixedlen_type_tds(ctype
)) {
5135 if (is_image_type_tds(ctype
)) {
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
);
5141 proto_tree_add_item_ret_length(col_tree
, hf_tds_rowfmt2_text_tablename
,
5143 tds_get_char_encoding(tds_info
)|tds_get_int2_encoding(tds_info
),
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
);
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
);
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
);
5168 proto_tree_add_item_ret_length(col_tree
, hf_tds_rowfmt2_locale_info
,
5169 tvb
, cur
, 1, ENC_NA
, &localelen
);
5172 proto_item_set_len(col_item
, cur
- colstart
);
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)
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;
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
);
5213 while (cur
< next
) {
5215 if (col
>= TDS_MAX_COLUMNS
) {
5216 nl_data
->num_cols
= TDS_MAX_COLUMNS
;
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
);
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.
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
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) {
5264 * Ensure that the strings at the front of the login packet
5265 * have valid lengths.
5269 if (tvb_get_uint8(tvb
, 8 + TDS_MAXNAME
) > TDS_MAXNAME
)
5272 if (tvb_get_uint8(tvb
, 39 + TDS_MAXNAME
) > TDS_MAXNAME
)
5275 if (tvb_get_uint8(tvb
, 70 + TDS_MAXNAME
) > TDS_MAXNAME
)
5277 /* Client process id */
5278 if (tvb_get_uint8(tvb
, 101 + TDS_MAXNAME
) > TDS_MAXNAME
)
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) {
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
) {
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
)) {
5310 dissect_tds_prelogin_response(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, proto_tree
*tree
, tds_conv_info_t
*tds_info
)
5313 int tokenoffset
, tokenlen
, cur
= offset
;
5317 * Test for prelogin format compliance
5318 * A prelogin response consists solely of "tokens" from 0 to 7, followed by
5322 while(tvb_reported_length_remaining(tvb
, cur
) > 0)
5324 token
= tvb_get_uint8(tvb
, cur
);
5327 if(token
== TDS7_PRELOGIN_OPTION_TERMINATOR
)
5330 if(token
<= TDS7_PRELOGIN_OPTION_NONCEOPT
) {
5338 tokenoffset
= tvb_get_ntohs(tvb
, cur
);
5339 if(tokenoffset
> tvb_reported_length_remaining(tvb
, 0)) {
5345 tokenlen
= tvb_get_ntohs(tvb
, cur
);
5346 if(tokenlen
> tvb_reported_length_remaining(tvb
, 0)) {
5353 if(token
!= TDS7_PRELOGIN_OPTION_TERMINATOR
) {
5359 /* The prelogin response has the same form as the prelogin request. */
5360 dissect_tds7_prelogin_packet(tvb
, pinfo
, tree
, tds_info
, true);
5367 dissect_tds_order_token(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
, tds_conv_info_t
*tds_info
)
5369 unsigned cur
= offset
;
5372 proto_tree_add_item_ret_uint(tree
, hf_tds_order_length
, tvb
, cur
, 2,
5373 tds_get_int2_encoding(tds_info
), &length
);
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
);
5383 for (i
= 0; i
< length
/ 2; i
++) {
5384 proto_tree_add_item(tree
, hf_tds_order_colnum
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
5389 return cur
- offset
;
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
);
5401 return cur
- offset
;
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
;
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,
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
;
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
;
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));
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
;
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
));
5474 return cur
- offset
;
5478 The SSPI token returned during the login process.
5481 https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/07e2bb7b-8ba6-445f-89b1-cc76d8bfa9c6
5482 Token Stream-Specific Rules:
5484 SSPIBuffer = US_VARBYTE
5486 Token Stream Definition:
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
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
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
;
5506 len_field_val
= tvb_get_uint16(tvb
, cur
, encoding
);
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
);
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
);
5519 call_dissector(gssapi_handle
, nt_tvb
, pinfo
, tree
);
5523 cur
+= len_field_val
;
5526 return cur
- offset
;
5530 dissect_tds_envchg_token(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
, tds_conv_info_t
*tds_info
)
5532 unsigned cur
= offset
;
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
));
5540 env_type
= tvb_get_uint8(tvb
, cur
);
5541 proto_tree_add_item(tree
, hf_tds_envchg_type
, tvb
, cur
, 1, ENC_NA
);
5544 /* Read new value */
5555 /* B_VARCHAR, Strings */
5556 proto_tree_add_item_ret_uint(tree
, hf_tds_envchg_newvalue_length
, tvb
, cur
, 1, ENC_NA
, &new_len
);
5560 if (tds_char_encoding_is_two_byte(tds_info
)) {
5563 proto_tree_add_item(tree
, hf_tds_envchg_newvalue_string
, tvb
, cur
, new_len
,
5564 tds_get_char_encoding(tds_info
));
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
);
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
);
5586 proto_tree_add_item_ret_uint(tree
, hf_tds_envchg_newvalue_length
, tvb
, cur
, 1, ENC_NA
, &new_len
);
5590 proto_tree_add_item(tree
, hf_tds_envchg_newvalue_bytes
, tvb
, cur
, new_len
, ENC_NA
);
5601 proto_tree_add_item(tree
, hf_tds_envchg_newvalue_length
, tvb
, cur
, 1, ENC_NA
);
5614 /* Read old value */
5621 /* B_VARCHAR, Strings */
5622 proto_tree_add_item_ret_uint(tree
, hf_tds_envchg_oldvalue_length
, tvb
, cur
, 1, ENC_NA
, &old_len
);
5625 if (tds_char_encoding_is_two_byte(tds_info
)) {
5628 proto_tree_add_item(tree
, hf_tds_envchg_oldvalue_string
, tvb
, cur
, old_len
,
5629 tds_get_char_encoding(tds_info
));
5644 proto_tree_add_item(tree
, hf_tds_envchg_oldvalue_length
, tvb
, cur
, 1, ENC_NA
);
5654 proto_tree_add_item_ret_uint(tree
, hf_tds_envchg_oldvalue_length
, tvb
, cur
, 1, ENC_NA
, &old_len
);
5658 proto_tree_add_item(tree
, hf_tds_envchg_oldvalue_bytes
, tvb
, cur
, old_len
, ENC_NA
);
5667 return cur
- offset
;
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
));
5679 proto_tree_add_item(tree
, hf_tds_eed_number
, tvb
, cur
, 4,
5680 tds_get_int4_encoding(tds_info
));
5682 proto_tree_add_item(tree
, hf_tds_eed_state
, tvb
, cur
, 1, ENC_NA
);
5684 proto_tree_add_item(tree
, hf_tds_eed_class
, tvb
, cur
, 1, ENC_NA
);
5687 proto_tree_add_item_ret_length(tree
, hf_tds_eed_sql_state
, tvb
, cur
, 1,
5691 proto_tree_add_item(tree
, hf_tds_eed_status
, tvb
, cur
, 1, ENC_NA
);
5694 proto_tree_add_item(tree
, hf_tds_eed_transtate
, tvb
, cur
, 2,
5695 tds_get_int2_encoding(tds_info
));
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
),
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
);
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
);
5711 proto_tree_add_item(tree
, hf_tds_eed_linenumber
, tvb
, cur
, 2,
5712 tds_get_int2_encoding(tds_info
));
5715 /* TODO Handle EED follows? Maybe handled as separate tokens. */
5717 return cur
- offset
;
5721 dissect_tds_error_token(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
, tds_conv_info_t
*tds_info
)
5723 unsigned cur
= offset
;
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
));
5730 proto_tree_add_item(tree
, hf_tds_error_number
, tvb
, cur
, 4, tds_get_int4_encoding(tds_info
));
5732 proto_tree_add_item(tree
, hf_tds_error_state
, tvb
, cur
, 1, ENC_NA
);
5734 proto_tree_add_item(tree
, hf_tds_error_class
, tvb
, cur
, 1, ENC_NA
);
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
);
5741 if (tds_char_encoding_is_two_byte(tds_info
)) {
5744 proto_tree_add_item(tree
, hf_tds_error_msgtext
, tvb
, cur
, msg_len
, tds_get_char_encoding(tds_info
));
5747 proto_tree_add_item_ret_uint(tree
, hf_tds_error_servername_length
, tvb
, cur
, 1, ENC_NA
, &srvr_len
);
5750 if (tds_char_encoding_is_two_byte(tds_info
)) {
5753 proto_tree_add_item(tree
, hf_tds_error_servername
, tvb
, cur
, srvr_len
, tds_get_char_encoding(tds_info
));
5757 proto_tree_add_item_ret_uint(tree
, hf_tds_error_procname_length
, tvb
, cur
, 1, ENC_NA
, &proc_len
);
5760 if (tds_char_encoding_is_two_byte(tds_info
)) {
5763 proto_tree_add_item(tree
, hf_tds_error_procname
, tvb
, cur
, proc_len
, tds_get_char_encoding(tds_info
));
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
));
5771 proto_tree_add_item(tree
, hf_tds_error_linenumber_32
, tvb
, cur
, 4, tds_get_int4_encoding(tds_info
));
5775 return cur
- offset
;
5779 dissect_tds_info_token(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
, tds_conv_info_t
*tds_info
)
5781 unsigned cur
= offset
;
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
));
5788 proto_tree_add_item(tree
, hf_tds_info_number
, tvb
, cur
, 4, tds_get_int4_encoding(tds_info
));
5790 proto_tree_add_item(tree
, hf_tds_info_state
, tvb
, cur
, 1, ENC_NA
);
5792 proto_tree_add_item(tree
, hf_tds_info_class
, tvb
, cur
, 1, ENC_NA
);
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
);
5799 if (tds_char_encoding_is_two_byte(tds_info
)) {
5802 proto_tree_add_item(tree
, hf_tds_info_msgtext
, tvb
, cur
, msg_len
, tds_get_char_encoding(tds_info
));
5806 proto_tree_add_item_ret_uint(tree
, hf_tds_info_servername_length
, tvb
, cur
, 1, ENC_NA
, &srvr_len
);
5809 if (tds_char_encoding_is_two_byte(tds_info
)) {
5812 proto_tree_add_item(tree
, hf_tds_info_servername
, tvb
, cur
, srvr_len
, tds_get_char_encoding(tds_info
));
5816 proto_tree_add_item_ret_uint(tree
, hf_tds_info_procname_length
, tvb
, cur
, 1, ENC_NA
, &proc_len
);
5819 if (tds_char_encoding_is_two_byte(tds_info
)) {
5822 proto_tree_add_item(tree
, hf_tds_info_procname
, tvb
, cur
, proc_len
, tds_get_char_encoding(tds_info
));
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
));
5830 proto_tree_add_item(tree
, hf_tds_info_linenumber_32
, tvb
, cur
, 4, tds_get_int4_encoding(tds_info
));
5834 return cur
- offset
;
5838 dissect_tds_login_ack_token(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, proto_tree
*tree
, tds_conv_info_t
*tds_info
)
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
));
5847 proto_tree_add_item(tree
, hf_tds_loginack_interface
, tvb
, cur
, 1, ENC_NA
);
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
);
5854 msg_len
= tvb_get_uint8(tvb
, cur
);
5857 if (tds_char_encoding_is_two_byte(tds_info
)) {
5860 proto_tree_add_item(tree
, hf_tds_loginack_progname
, tvb
, cur
, msg_len
,
5861 tds_get_char_encoding(tds_info
));
5864 proto_tree_add_item(tree
, hf_tds_loginack_progversion
, tvb
, cur
, 4, ENC_BIG_ENDIAN
);
5868 return cur
- offset
;
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
;
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;
5891 for(i
=0; i
!= num_columns
; i
++) {
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
);
5908 proto_tree_add_item_ret_uint(col_tree
, hf_tds_colmetadata_usertype32
, tvb
, cur
, 4, ENC_LITTLE_ENDIAN
, &(nl_data
->columns
[i
]->utype
));
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
);
5916 flags_tree
= proto_item_add_subtree(flags_item
, ett_tds_flags
);
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
);
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
;
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
))
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
);
5978 case TDS_DATA_TYPE_DATEN
:
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
);
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
);
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
);
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
);
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
);
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
);
6022 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_codepage
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
6024 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_flags
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
6026 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_charset_id
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
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
);
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
);
6045 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_codepage
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
6047 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_flags
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
6049 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_charset_id
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
6053 case TDS_DATA_TYPE_XML
:
6055 uint8_t schema_present
;
6056 schema_present
= tvb_get_uint8(tvb
, cur
);
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
);
6066 proto_tree_add_item(col_tree
, hf_tds_colmetadata_dbname
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6075 proto_tree_add_item(col_tree
, hf_tds_colmetadata_owningschema
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6084 proto_tree_add_item(col_tree
, hf_tds_colmetadata_typename
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6093 proto_tree_add_item(col_tree
, hf_tds_colmetadata_xmlschemacollection
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
6100 case TDS_DATA_TYPE_UDT
:
6102 proto_tree_add_item(col_tree
, hf_tds_colmetadata_maxbytesize
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
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
);
6110 proto_tree_add_item(col_tree
, hf_tds_colmetadata_dbname
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6119 proto_tree_add_item(col_tree
, hf_tds_colmetadata_schemaname
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6128 proto_tree_add_item(col_tree
, hf_tds_colmetadata_typename
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6137 proto_tree_add_item(col_tree
, hf_tds_colmetadata_assemblyqualifiedname
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6149 if (TDS_PROTO_TDS7_2_OR_GREATER(tds_info
)) {
6150 unsigned numparts
= tvb_get_uint8(tvb
, cur
);
6152 proto_tree_add_item(col_tree
, hf_tds_colmetadata_table_name_parts
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
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);
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);
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
);
6178 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_codepage
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
6180 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_flags
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
6182 proto_tree_add_item(col_tree
, hf_tds_colmetadata_collate_charset_id
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
6186 if (TDS_PROTO_TDS7_2_OR_GREATER(tds_info
)) {
6187 unsigned numparts
= tvb_get_uint8(tvb
, cur
);
6189 proto_tree_add_item(col_tree
, hf_tds_colmetadata_table_name_parts
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
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);
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);
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
);
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
);
6224 proto_tree_add_item(col_tree
, hf_tds_colmetadata_colname
, tvb
, cur
, msg_len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
,
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
));
6258 proto_tree_add_item(tree
, hf_tds_done_curcmd
, tvb
, cur
, 2,
6259 tds_get_int2_encoding(tds_info
));
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
));
6266 /* TDS 7 is always little-endian. */
6267 proto_tree_add_item(tree
, hf_tds_done_donerowcount_64
, tvb
, cur
, 8, ENC_LITTLE_ENDIAN
);
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
,
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
));
6299 proto_tree_add_item(tree
, hf_tds_doneproc_curcmd
, tvb
, cur
, 2,
6300 tds_get_int2_encoding(tds_info
));
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
));
6307 /* TDS 7 is always little-endian. */
6308 proto_tree_add_item(tree
, hf_tds_doneproc_donerowcount_64
, tvb
, cur
, 8, ENC_LITTLE_ENDIAN
);
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
,
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
));
6340 proto_tree_add_item(tree
, hf_tds_doneinproc_curcmd
, tvb
, cur
, 2,
6341 tds_get_int2_encoding(tds_info
));
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
));
6348 /* TDS 7 is always little-endian. */
6349 proto_tree_add_item(tree
, hf_tds_doneinproc_donerowcount_64
, tvb
, cur
, 8, ENC_LITTLE_ENDIAN
);
6353 return cur
- offset
;
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
);
6364 return cur
- offset
;
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;
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
);
6385 uint8_t prop_bytes
= variant_propbytes(data_type
);
6386 *offset
+= prop_bytes
;
6389 /* optional TYPE_VARLEN for variable length types */
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) */
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) */
6427 varlen
= tvb_get_uint8(tvb
, *offset
);
6429 /* USHORTLEN_TYPE */
6430 case TDS_DATA_TYPE_BIGVARCHR
: /* VarChar */
6431 case TDS_DATA_TYPE_BIGVARBIN
: /* VarBinary */
6432 case TDS_DATA_TYPE_NVARCHAR
: /* NVarChar */
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)
6440 case TDS_DATA_TYPE_BIGBINARY
: /* Binary */
6441 case TDS_DATA_TYPE_BIGCHAR
: /* Char */
6442 case TDS_DATA_TYPE_NCHAR
: /* NChar */
6444 varlen
= tvb_get_letohs(tvb
, *offset
);
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) */
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) */
6456 varlen
= tvb_get_letohl(tvb
, *offset
);
6459 expert_add_info(pinfo
, data_type_item
, &ei_tds_type_info_type
);
6461 data_type
= TDS_DATA_TYPE_INVALID
;
6465 item1
= proto_tree_add_uint(sub_tree
, hf_tds_type_info_varlen
, tvb
, *offset
, varlen_len
, varlen
);
6467 proto_item_append_text(item1
, " (PLP - Partially Length-Prefixed data type)");
6468 *offset
+= varlen_len
;
6470 /* Optional data dependent on 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
);
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
);
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
);
6509 proto_item_set_end(item
, tvb
, *offset
);
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
;
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) {
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
);
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
);
6548 if (len
== 0xFFFF) {
6549 proto_tree_add_item(tree
, hf_tds_rpc_proc_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
6552 else if (len
!= 0) {
6554 proto_tree_add_item(tree
, hf_tds_rpc_name
, tvb
, offset
, len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6566 /* dissect parameters */
6567 while(tvb_reported_length_remaining(tvb
, offset
) > 0) {
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
);
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
);
6583 proto_tree_add_item(sub_tree
, hf_tds_rpc_parameter_name
, tvb
, offset
, len
, ENC_UTF_16
|ENC_LITTLE_ENDIAN
);
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
);
6591 data_type
= dissect_tds_type_info(tvb
, &offset
, pinfo
, sub_tree
, &plp
, false);
6592 if (data_type
== TDS_DATA_TYPE_INVALID
)
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
);
6602 dissect_tds_featureextack_token(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
)
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
);
6621 if(featureid
== 0xff)
6624 proto_tree_add_item(feature_tree
, hf_tds_featureextack_featureackdatalen
, tvb
, cur
, 4, ENC_LITTLE_ENDIAN
);
6627 proto_tree_add_item(feature_tree
, hf_tds_featureextack_featureackdata
, tvb
, cur
, featureackdatalen
, ENC_NA
);
6628 cur
+= featureackdatalen
;
6631 return cur
- offset
;
6635 dissect_tds_sessionstate_token(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
)
6638 unsigned cur
= offset
, len
;
6640 proto_tree_add_item_ret_uint(tree
, hf_tds_sessionstate_length
, tvb
, cur
, 4, ENC_LITTLE_ENDIAN
, &len
);
6643 proto_tree_add_item(tree
, hf_tds_sessionstate_seqno
, tvb
, cur
, 4, ENC_LITTLE_ENDIAN
);
6646 proto_tree_add_item(tree
, hf_tds_sessionstate_status
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
6649 while((cur
- offset
- 3) < len
)
6651 proto_tree_add_item(tree
, hf_tds_sessionstate_stateid
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
6654 if(tvb_get_uint8(tvb
, cur
) == 0xFF)
6657 statelen
= tvb_get_ntohs(tvb
, cur
+ 2);
6658 proto_tree_add_item(tree
, hf_tds_sessionstate_statelen
, tvb
, cur
, 2, ENC_LITTLE_ENDIAN
);
6661 statelen
= tvb_get_uint8(tvb
, cur
);
6662 proto_tree_add_item(tree
, hf_tds_sessionstate_statelen
, tvb
, cur
, 1, ENC_LITTLE_ENDIAN
);
6666 proto_tree_add_item(tree
, hf_tds_sessionstate_statevalue
, tvb
, cur
, statelen
, ENC_NA
);
6670 return cur
- offset
;
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.
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
;
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;
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)
6737 * Until we reach the end of the packet, read tokens.
6739 while (tvb_reported_length_remaining(tvb
, pos
) > 0) {
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
);
6752 case TDS_CAPABILITY_TOKEN
:
6753 token_sz
= dissect_tds5_capability_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
6755 case TDS_CURINFO_TOKEN
:
6756 token_sz
= dissect_tds5_curinfo_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
6758 case TDS_DONE_TOKEN
:
6759 token_sz
= dissect_tds_done_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6761 case TDS_DONEPROC_TOKEN
:
6762 token_sz
= dissect_tds_doneproc_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6764 case TDS_DONEINPROC_TOKEN
:
6765 token_sz
= dissect_tds_doneinproc_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6767 case TDS5_EED_TOKEN
:
6768 token_sz
= dissect_tds_eed_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6770 case TDS_ENVCHG_TOKEN
:
6771 token_sz
= dissect_tds_envchg_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6773 case TDS_COL_NAME_TOKEN
:
6774 token_sz
= dissect_tds_col_name_token(token_tree
, tvb
, pos
+ 1, tds_info
, &nl_data
) + 1;
6776 case TDS_COLFMT_TOKEN
:
6777 token_sz
= dissect_tds_colfmt_token(token_tree
, tvb
, pos
+ 1, tds_info
, &nl_data
) + 1;
6779 case TDS_CONTROL_TOKEN
:
6780 token_sz
= dissect_tds_control_token(token_tree
, tvb
, pos
+ 1, tds_info
, &nl_data
) + 1;
6783 token_sz
= dissect_tds_error_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6785 case TDS_INFO_TOKEN
:
6786 token_sz
= dissect_tds_info_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6788 case TDS_LOGIN_ACK_TOKEN
:
6789 token_sz
= dissect_tds_login_ack_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
6791 case TDS5_MSG_TOKEN
:
6792 token_sz
= dissect_tds5_msg_token(token_tree
, tvb
, pos
+ 1, tds_info
) + 1;
6794 case TDS_ORDER_TOKEN
:
6795 token_sz
= dissect_tds_order_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6797 case TDS5_PARAMFMT_TOKEN
:
6798 token_sz
= dissect_tds_paramfmt_token(token_tree
, tvb
, pos
+ 1, tds_info
, &nl_data
) + 1;
6800 case TDS5_PARAMFMT2_TOKEN
:
6801 token_sz
= dissect_tds_paramfmt2_token(token_tree
, tvb
, pos
+ 1, tds_info
, &nl_data
) + 1;
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;
6807 case TDS_PROCID_TOKEN
:
6808 token_sz
= dissect_tds_procid_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6810 case TDS_RET_STAT_TOKEN
:
6811 token_sz
= dissect_tds_returnstatus_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6814 token_sz
= dissect_tds_row_token(tvb
, pinfo
, &nl_data
, pos
+ 1, token_tree
, tds_info
) + 1;
6816 case TDS5_ROWFMT_TOKEN
:
6817 token_sz
= dissect_tds_rowfmt_token(token_tree
, tvb
, pinfo
, pos
+ 1, tds_info
, &nl_data
) + 1;
6819 case TDS5_ROWFMT2_TOKEN
:
6820 token_sz
= dissect_tds_rowfmt2_token(token_tree
, tvb
, pinfo
, pos
+ 1, tds_info
, &nl_data
) + 1;
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
);
6832 proto_item_set_len(token_item
, token_sz
);
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) */
6845 case TDS7_COL_METADATA_TOKEN
:
6846 token_sz
= dissect_tds7_colmetadata_token(tvb
, &nl_data
, pos
+ 1, token_tree
, tds_info
) + 1;
6848 case TDS_DONE_TOKEN
:
6849 token_sz
= dissect_tds_done_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6851 case TDS_DONEPROC_TOKEN
:
6852 token_sz
= dissect_tds_doneproc_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6854 case TDS_DONEINPROC_TOKEN
:
6855 token_sz
= dissect_tds_doneinproc_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6857 case TDS_ENVCHG_TOKEN
:
6858 token_sz
= dissect_tds_envchg_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6861 token_sz
= dissect_tds_error_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6863 case TDS_INFO_TOKEN
:
6864 token_sz
= dissect_tds_info_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6866 case TDS_FEATUREEXTACK_TOKEN
:
6867 token_sz
= dissect_tds_featureextack_token(tvb
, pos
+ 1, token_tree
) + 1;
6869 case TDS_LOGIN_ACK_TOKEN
:
6870 token_sz
= dissect_tds_login_ack_token(tvb
, pinfo
, pos
+ 1, token_tree
, tds_info
) + 1;
6872 case TDS_NBCROW_TOKEN
:
6873 token_sz
= dissect_tds_nbc_row_token(tvb
, pinfo
, &nl_data
, pos
+ 1, token_tree
, tds_info
) + 1;
6875 case TDS_OFFSET_TOKEN
:
6876 token_sz
= dissect_tds_offset_token(tvb
, pos
+ 1, token_tree
) + 1;
6878 case TDS_ORDER_TOKEN
:
6879 token_sz
= dissect_tds_order_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6881 case TDS_RET_STAT_TOKEN
:
6882 token_sz
= dissect_tds_returnstatus_token(tvb
, pos
+ 1, token_tree
, tds_info
) + 1;
6885 token_sz
= dissect_tds_row_token(tvb
, pinfo
, &nl_data
, pos
+ 1, token_tree
, tds_info
) + 1;
6887 case TDS_SESSIONSTATE_TOKEN
:
6888 token_sz
= dissect_tds_sessionstate_token(tvb
, pos
+ 1, token_tree
) + 1;
6890 case TDS_SSPI_TOKEN
:
6891 token_sz
= dissect_tds_sspi_token(tvb
, pos
+ 1, pinfo
, token_tree
) + 1;
6898 /* Move on if nothing identifiable found */
6902 proto_item_set_len(token_item
, token_sz
);
6904 /* and step to the end of the token, rinse, lather, repeat */
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
;
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
;
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
:
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
;
6948 dissect_netlib_buffer(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
6951 proto_item
*tds_item
;
6952 proto_tree
*tds_tree
;
6956 uint8_t packet_number
;
6957 bool save_fragmented
, last_buffer
;
6959 fragment_head
*fd_head
;
6961 conversation_t
*conv
;
6962 tds_conv_info_t
*tds_info
;
6964 static int * const status_flags
[] = {
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
,
6975 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
6976 call_dissector(tls_handle
, next_tvb
, pinfo
, tree
);
6980 conv
= find_or_create_conversation(pinfo
);
6981 tds_info
= (tds_conv_info_t
*)conversation_get_proto_data(conv
, proto_tds
);
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) &&
7024 tds_info
->tds_packets_in_order
) {
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
7031 * When a more modern stream has a large number of fragments and the packet
7032 * number wraps back to zero.
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
,
7049 next_tvb
= process_reassembled_data(tvb
, offset
, pinfo
,
7050 "Reassembled TDS", fd_head
, &tds_frag_items
, NULL
,
7053 else if (packet_number
> 1 || !(status
& STATUS_LAST_BUFFER
)) {
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))
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
,
7107 /* We're defragmenting, but this isn't a fragment. */
7108 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
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
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))
7131 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
7135 if (next_tvb
!= NULL
) {
7140 dissect_tds_rpc(next_tvb
, pinfo
, tds_tree
, tds_info
);
7143 dissect_tds_resp(next_tvb
, pinfo
, tds_tree
, tds_info
);
7146 dissect_tds45_login(next_tvb
, pinfo
, tds_tree
, tds_info
);
7148 case TDS_LOGIN7_PKT
:
7149 dissect_tds7_login(next_tvb
, pinfo
, tds_tree
, tds_info
);
7152 dissect_tds_query_packet(next_tvb
, pinfo
, tds_tree
, tds_info
);
7154 case TDS5_QUERY_PKT
:
7155 dissect_tds5_tokenized_request_packet(next_tvb
, pinfo
, tds_tree
,
7159 dissect_tds_nt(next_tvb
, pinfo
, tds_tree
, offset
- 8);
7161 case TDS_TRANS_MGR_PKT
:
7162 dissect_tds_transmgr_packet(next_tvb
, pinfo
, tds_tree
);
7164 case TDS_ATTENTION_PKT
:
7166 case TDS_PRELOGIN_PKT
:
7167 dissect_tds7_prelogin_packet(next_tvb
, pinfo
, tds_tree
, tds_info
, false);
7171 proto_tree_add_item(tds_tree
, hf_tds_unknown_tds_packet
, next_tvb
, 0, -1, ENC_NA
);
7175 next_tvb
= tvb_new_subset_remaining (tvb
, offset
);
7176 call_data_dissector(next_tvb
, pinfo
, tds_tree
);
7178 pinfo
->fragmented
= save_fragmented
;
7182 dissect_tds_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
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
);
7206 get_tds_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
7211 type
= tvb_get_uint8(tvb
, offset
);
7216 /* Special case for SMP dissector */
7217 plen
= tvb_get_letohl(tvb
, offset
+ 4);
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;
7224 plen
= tvb_get_ntohs(tvb
, offset
+ 2);
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
);
7239 dissect_tds_tcp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
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)
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
))
7266 * Check the status field
7268 status
= tvb_get_uint8(tvb
, offset
+ 1);
7269 if (!is_valid_tds_status(status
))
7273 * Get the length of the PDU.
7275 plen
= tvb_get_ntohs(tvb
, offset
+ 2);
7278 * The length is less than the header length.
7284 if (!netlib_check_login_pkt(tvb
, offset
, pinfo
, type
))
7288 * Now dissect it as TDS.
7290 dissect_tds(tvb
, pinfo
, tree
, data
);
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
7302 snprintf( result
, ITEM_LABEL_LENGTH
, "%d.%d.%d",
7303 (hexver
>> 24) & 0xFF, (hexver
>> 16) & 0xFF, (hexver
& 0xFFFF));
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.
7318 proto_register_tds(void)
7320 static hf_register_info hf
[] = {
7322 /************************ Token definitions ************************/
7324 /* ALTMETADATA token */
7328 /* CAPABILITY token */
7329 { &hf_tds_capability
,
7330 { "Token - Capability", "tds.capability",
7331 FT_NONE
, BASE_NONE
, NULL
, 0x0,
7334 { &hf_tds_capability_length
,
7335 { "Token length", "tds.capability.length",
7336 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7339 { &hf_tds_capability_captype
,
7340 { "Capability type", "tds.capability.captype",
7341 FT_UINT8
, BASE_DEC
, VALS(tds_capability_type
), 0x0,
7344 { &hf_tds_capability_caplen
,
7345 { "Capability len", "tds.capability.caplen",
7346 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7349 { &hf_tds_capability_req_lang
,
7350 { "Language requests", "tds.capability.req.lang",
7351 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), 0x02,
7354 { &hf_tds_capability_req_rpc
,
7355 { "RPC requests", "tds.capability.req.rpc",
7356 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), 0x04,
7359 { &hf_tds_capability_req_evt
,
7360 { "RPC event notifications", "tds.capability.req.evt",
7361 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), 0x08,
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,
7369 { &hf_tds_capability_req_bcp
,
7370 { "Bulk copy requests", "tds.capability.req.bcp",
7371 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), 0x20,
7374 { &hf_tds_capability_req_cursor
,
7375 { "Cursor command requests", "tds.capability.req.cursor",
7376 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), 0x40,
7379 { &hf_tds_capability_req_dynf
,
7380 { "Dynamic SQL requests", "tds.capability.req.dynf",
7381 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), 0x80,
7384 { &hf_tds_capability_req_msg
,
7385 { "TDS_MSG requests", "tds.capability.req.msg",
7386 FT_BOOLEAN
, 8, TFS(&tfs_allowed_not_allowed
), 0x01,
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,
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,
7399 { &hf_tds_capability_data_int2
,
7400 { "Support 2-byte ints", "tds.capability.data.int2",
7401 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7404 { &hf_tds_capability_data_int4
,
7405 { "Support 4-byte ints", "tds.capability.data.int4",
7406 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
7409 { &hf_tds_capability_data_bit
,
7410 { "Support bits", "tds.capability.data.bit",
7411 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
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,
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,
7424 { &hf_tds_capability_data_bin
,
7425 { "Support fixed-length binary", "tds.capability.data.bin",
7426 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
7429 { &hf_tds_capability_data_vbin
,
7430 { "Support variable-length binary", "tds.capability.data.vbin",
7431 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
7434 { &hf_tds_capability_data_mny8
,
7435 { "Support 8-byte money", "tds.capability.data.mny8",
7436 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7439 { &hf_tds_capability_data_mny4
,
7440 { "Support 4-byte money", "tds.capability.data.mny4",
7441 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7444 { &hf_tds_capability_data_date8
,
7445 { "Support 8-byte datetime", "tds.capability.data.date8",
7446 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
7449 { &hf_tds_capability_data_date4
,
7450 { "Support 4-byte datetime", "tds.capability.data.date4",
7451 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
7454 { &hf_tds_capability_data_flt4
,
7455 { "Support 4-byte float", "tds.capability.data.flt4",
7456 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
7459 { &hf_tds_capability_data_flt8
,
7460 { "Support 8-byte float", "tds.capability.data.flt8",
7461 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
7464 { &hf_tds_capability_data_num
,
7465 { "Support numeric", "tds.capability.data.num",
7466 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
7469 { &hf_tds_capability_data_text
,
7470 { "Support text data", "tds.capability.data.text",
7471 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
7474 { &hf_tds_capability_data_image
,
7475 { "Support image data", "tds.capability.data.image",
7476 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7479 { &hf_tds_capability_data_dec
,
7480 { "Support decimal", "tds.capability.data.dec",
7481 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
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,
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,
7494 { &hf_tds_capability_data_intn
,
7495 { "Support nullable ints", "tds.capability.data.intn",
7496 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
7499 { &hf_tds_capability_data_datetimen
,
7500 { "Support nullable datetime", "tds.capability.data.datetimen",
7501 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
7504 { &hf_tds_capability_data_moneyn
,
7505 { "Support nullable money", "tds.capability.data.moneyn",
7506 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
7509 { &hf_tds_capability_csr_prev
,
7510 { "Support fetch previous cursor", "tds.capability.csr.prev",
7511 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
7514 { &hf_tds_capability_csr_first
,
7515 { "Support fetch first cursor", "tds.capability.csr.first",
7516 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7519 { &hf_tds_capability_csr_last
,
7520 { "Support fetch last cursor", "tds.capability.csr.last",
7521 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7524 { &hf_tds_capability_csr_abs
,
7525 { "Support fetch absolute cursor", "tds.capability.csr.abs",
7526 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
7529 { &hf_tds_capability_csr_rel
,
7530 { "Support fetch relative cursor", "tds.capability.csr.rel",
7531 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
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,
7539 { &hf_tds_capability_con_oob
,
7540 { "Support expedited attention", "tds.capability.con.oob",
7541 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
7544 { &hf_tds_capability_con_inband
,
7545 { "Support non-expedited attention", "tds.capability.con.inband",
7546 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
7549 { &hf_tds_capability_con_logical
,
7550 { "Support logical logout", "tds.capability.con.logout",
7551 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
7554 { &hf_tds_capability_proto_text
,
7555 { "Support tokenized text/image", "tds.capability.proto.text",
7556 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7559 { &hf_tds_capability_proto_bulk
,
7560 { "Support tokenized bcp", "tds.capability.proto.bulk",
7561 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7564 { &hf_tds_capability_req_urgevt
,
7565 { "Use new event notification", "tds.capability.req.urgevt",
7566 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
7569 { &hf_tds_capability_data_sensitivity
,
7570 { "Support sensitivity data", "tds.capability.data.sensitivity",
7571 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
7574 { &hf_tds_capability_data_boundary
,
7575 { "Support boundary data", "tds.capability.data.boundary",
7576 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
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,
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,
7589 { &hf_tds_capability_data_fltn
,
7590 { "Support nullable floats", "tds.capability.data.fltn",
7591 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
7594 { &hf_tds_capability_data_bitn
,
7595 { "Support nullable bits", "tds.capability.data.bitn",
7596 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7599 { &hf_tds_capability_data_int8
,
7600 { "Support 8-byte ints", "tds.capability.data.int8",
7601 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7604 { &hf_tds_capability_data_void
,
7605 { "Undocumented TDS_DATA_VOID", "tds.capability.data.void",
7606 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
7609 { &hf_tds_capability_dol_bulk
,
7610 { "Undocumented TDS_DOL_VOID", "tds.capability.dol.bulk",
7611 FT_BOOLEAN
, 8, NULL
, 0x20,
7614 { &hf_tds_capability_object_java1
,
7615 { "Support serialized java objects", "tds.capability.object.java1",
7616 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
7619 { &hf_tds_capability_object_char
,
7620 { "Support streaming char data", "tds.capability.object.char",
7621 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
7624 { &hf_tds_capability_object_binary
,
7625 { "Support streaming binary data", "tds.capability.object.binary",
7626 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
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,
7634 { &hf_tds_capability_widetable
,
7635 { "Allow wide-table tokens", "tds.capability.widetable",
7636 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
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,
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,
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,
7654 { &hf_tds_capability_data_uintn
,
7655 { "Support nullable unsigned ints", "tds.capability.data.uintn",
7656 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
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,
7664 { &hf_tds_capability_data_nlbin
,
7665 { "Support UTF-16 LONGBINARY", "tds.capability.data.nlbin",
7666 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7669 { &hf_tds_capability_image_nchar
,
7670 { "Support UTF-16 IMAGE", "tds.capability.image.nchar",
7671 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
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,
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,
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,
7689 { &hf_tds_capability_data_date
,
7690 { "Support DATE", "tds.capability.data.date",
7691 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
7694 { &hf_tds_capability_data_time
,
7695 { "Support TIME", "tds.capability.data.time",
7696 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
7699 { &hf_tds_capability_data_interval
,
7700 { "Support INTERVAL", "tds.capability.data.interval",
7701 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
7704 { &hf_tds_capability_csr_scroll
,
7705 { "Support scrollable cursor", "tds.capability.csr.scroll",
7706 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7709 { &hf_tds_capability_csr_sensitive
,
7710 { "Support sens. scr csr", "tds.capability.csr.sensitive",
7711 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7714 { &hf_tds_capability_csr_insensitive
,
7715 { "Support insens. scr csr", "tds.capability.csr.insensitive",
7716 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
7719 { &hf_tds_capability_csr_semisensitive
,
7720 { "Support semisens. scr csr", "tds.capability.csr.semisensitive",
7721 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
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,
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,
7734 { &hf_tds_capability_data_unitext
,
7735 { "Support UTF-16 text", "tds.capability.data.unitext",
7736 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
7739 { &hf_tds_capability_cap_clusterfailover
,
7740 { "Support cluster failover", "tds.capability.cap.clusterfailover",
7741 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
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,
7749 { &hf_tds_capability_req_largeident
,
7750 { "Support large identifiers", "tds.capability.req.largeident",
7751 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
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,
7759 { &hf_tds_capability_data_xml
,
7760 { "Support XML type", "tds.capability.data.xml",
7761 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
7764 { &hf_tds_capability_req_curinfo3
,
7765 { "Support TDS_CURINFO3 token", "tds.capability.req.curinfo3",
7766 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
7769 { &hf_tds_capability_req_dbrpc2
,
7770 { "Support TDS_DBRPC2 token", "tds.capability.req.dbrpc2",
7771 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
7859 { &hf_tds_capability_data_nonum
,
7860 { "No sup. for NUMERIC", "tds.capability.data.nonum",
7861 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
7864 { &hf_tds_capability_data_notext
,
7865 { "No sup. for TEXT", "tds.capability.data.notext",
7866 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7869 { &hf_tds_capability_data_noimage
,
7870 { "No sup. for IMAGE", "tds.capability.data.noimage",
7871 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
7874 { &hf_tds_capability_data_nodec
,
7875 { "No sup. for DECIMAL", "tds.capability.data.nodec",
7876 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
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,
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,
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,
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,
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,
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,
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,
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,
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,
7924 { &hf_tds_capability_data_nosensitivity
,
7925 { "No sup. for sensitivity", "tds.capability.data.nosensitivity",
7926 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
7929 { &hf_tds_capability_data_noboundary
,
7930 { "No sup. for BOUNDARY", "tds.capability.data.noboundary",
7931 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
8019 { &hf_tds_capability_data_nodate
,
8020 { "No sup. for DATE", "tds.capability.data.nodate",
8021 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
8024 { &hf_tds_capability_data_notime
,
8025 { "No sup. for TIME", "tds.capability.data.notime",
8026 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
8029 { &hf_tds_capability_data_nointerval
,
8030 { "No sup. for INTERVAL", "tds.capability.data.nointerval",
8031 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
8090 /* COLINFO token (TDS_COLFMT_TOKEN) */
8092 { "Token - ColFormat", "tds.colfmt",
8093 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8096 { &hf_tds_colfmt_length
,
8097 { "Token length - ColFormat", "tds.colfmt.length",
8098 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8101 { &hf_tds_colfmt_column
,
8102 { "Column", "tds.colfmt.column",
8103 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8106 { &hf_tds_colfmt_utype
,
8107 { "ColFormat - Column Usertype", "tds.colfmt.utype",
8108 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8111 { &hf_tds_colfmt_ctype
,
8112 { "ColFormat - Column Datatype", "tds.colfmt.ctype",
8113 FT_UINT8
, BASE_DEC
, &tds_data_type_names
, 0x0,
8116 { &hf_tds_colfmt_csize
,
8117 { "ColFormat - Column size", "tds.colfmt.csize",
8118 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8121 { &hf_tds_colfmt_csize_long
,
8122 { "ColFormat - Column size - long", "tds.colfmt.csize_long",
8123 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8126 { &hf_tds_colfmt_text_tablename
,
8127 { "ColFormat - Text Tablename", "tds.colfmt.text_tablename",
8128 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8132 /* COLNAME token (TDS_COL_NAME_TOKEN) */
8134 { "Token - ColName", "tds.colname",
8135 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8138 { &hf_tds_colname_length
,
8139 { "Token length - ColName", "tds.colname.length",
8140 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8143 { &hf_tds_colname_column
,
8144 { "Column", "tds.colname.column",
8145 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8148 { &hf_tds_colname_name
,
8149 { "Column name", "tds.colname.name",
8150 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8154 /* COLMETADATA token (TDS7_COL_METADATA_TOKEN) */
8155 { &hf_tds_colmetadata
,
8156 { "Token - ColumnMetaData", "tds.colmetadata",
8157 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8160 { &hf_tds_colmetadata_columns
,
8161 { "Columns", "tds.colmetadata.columns",
8162 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8165 { &hf_tds_colmetadata_usertype32
,
8166 { "Usertype", "tds.colmetadata.usertype",
8167 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8170 { &hf_tds_colmetadata_usertype16
,
8171 { "Usertype", "tds.colmetadata.usertype",
8172 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8175 { &hf_tds_colmetadata_results_token_flags
,
8176 { "Flags", "tds.colmetadata.results_token_flags",
8177 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8180 { &hf_tds_colmetadata_results_token_type
,
8181 { "Type", "tds.colmetadata.results_token_type",
8182 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8185 { &hf_tds_colmetadata_csize
,
8186 { "Type size", "tds.colmetadata.type_size",
8187 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8190 { &hf_tds_colmetadata_large2_type_size
,
8191 { "Large type size", "tds.colmetadata.large_type_size",
8192 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8195 { &hf_tds_colmetadata_large4_type_size
,
8196 { "Large type size", "tds.colmetadata.large_type_size",
8197 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8200 { &hf_tds_colmetadata_collate_codepage
,
8201 { "Collate codepage", "tds.colmetadata.collate_codepage",
8202 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8205 { &hf_tds_colmetadata_collate_flags
,
8206 { "Collate flags", "tds.colmetadata.collate_flags",
8207 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8210 { &hf_tds_colmetadata_collate_charset_id
,
8211 { "Collate charset ID", "tds.colmetadata.collate_charset_id",
8212 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8215 { &hf_tds_colmetadata_precision
,
8216 { "Precision", "tds.colmetadata.precision",
8217 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8220 { &hf_tds_colmetadata_scale
,
8221 { "Scale", "tds.colmetadata.scale",
8222 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8225 { &hf_tds_colmetadata_colname_length
,
8226 { "Column name length", "tds.colmetadata.colname_length",
8227 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8230 { &hf_tds_colmetadata_colname
,
8231 { "Column Name", "tds.colmetadata.colname",
8232 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8235 { &hf_tds_colmetadata_table_name_parts
,
8236 { "Table name parts", "tds.colmetadata.table_name_parts",
8237 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8240 { &hf_tds_colmetadata_table_name
,
8241 { "Table name", "tds.colmetadata.table_name",
8242 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8245 { &hf_tds_colmetadata_table_name_length
,
8246 { "Table name length", "tds.colmetadata.table_name_length",
8247 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8250 { &hf_tds_colmetadata_field
,
8251 { "Field", "tds.colmetadata.field",
8252 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8255 { &hf_tds_colmetadata_flags_nullable
,
8256 { "Nullable", "tds.colmetadata.flags.nullable",
8257 FT_BOOLEAN
, 16, NULL
, 0x8000,
8260 { &hf_tds_colmetadata_flags_casesen
,
8261 { "Case sensitive", "tds.colmetadata.flags.casesen",
8262 FT_BOOLEAN
, 16, NULL
, 0x4000,
8265 { &hf_tds_colmetadata_flags_updateable
,
8266 { "Updateable", "tds.colmetadata.flags.updateable",
8267 FT_BOOLEAN
, 16, NULL
, 0x3000,
8270 { &hf_tds_colmetadata_flags_identity
,
8271 { "Identity", "tds.colmetadata.flags.identity",
8272 FT_BOOLEAN
, 16, NULL
, 0x0800,
8275 { &hf_tds_colmetadata_flags_computed
,
8276 { "Computed", "tds.colmetadata.flags.computed",
8277 FT_BOOLEAN
, 16, NULL
, 0x0400,
8280 { &hf_tds_colmetadata_flags_reservedodbc
,
8281 { "Reserved ODBC", "tds.colmetadata.flags.reservedodbc",
8282 FT_BOOLEAN
, 16, NULL
, 0x0300,
8285 { &hf_tds_colmetadata_flags_fixedlenclrtype
,
8286 { "Fixed length CLR type", "tds.colmetadata.flags.fixedlenclrtype",
8287 FT_BOOLEAN
, 16, NULL
, 0x0080,
8290 { &hf_tds_colmetadata_flags_sparsecolumnset
,
8291 { "Sparse column set", "tds.colmetadata.flags.sparsecolumnset",
8292 FT_BOOLEAN
, 16, NULL
, 0x0020,
8295 { &hf_tds_colmetadata_flags_encrypted
,
8296 { "Encrypted", "tds.colmetadata.flags.encrypted",
8297 FT_BOOLEAN
, 16, NULL
, 0x0010,
8300 { &hf_tds_colmetadata_flags_hidden
,
8301 { "Hidden", "tds.colmetadata.flags.hidden",
8302 FT_BOOLEAN
, 16, NULL
, 0x0004,
8305 { &hf_tds_colmetadata_flags_key
,
8306 { "Flags", "tds.colmetadata.flags.key",
8307 FT_BOOLEAN
, 16, NULL
, 0x0002,
8310 { &hf_tds_colmetadata_flags_nullableunknown
,
8311 { "Nullable unknown", "tds.colmetadata.flags.nullableunknown",
8312 FT_BOOLEAN
, 16, NULL
, 0x0001,
8315 { &hf_tds_colmetadata_maxbytesize
,
8316 { "Max byte size", "tds.colmetadata.maxbytesize",
8317 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8320 { &hf_tds_colmetadata_dbname_length
,
8321 { "Database name length", "tds.colmetadata.dbname_length",
8322 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8325 { &hf_tds_colmetadata_dbname
,
8326 { "Database name length", "tds.colmetadata.dbname",
8327 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8330 { &hf_tds_colmetadata_schemaname_length
,
8331 { "Schema name length", "tds.colmetadata.schemaname_length",
8332 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8335 { &hf_tds_colmetadata_schemaname
,
8336 { "Schema name", "tds.colmetadata.schemaname",
8337 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8340 { &hf_tds_colmetadata_typename_length
,
8341 { "Type name length", "tds.colmetadata.typename_length",
8342 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8345 { &hf_tds_colmetadata_typename
,
8346 { "Type name", "tds.colmetadata.typename",
8347 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8350 { &hf_tds_colmetadata_assemblyqualifiedname_length
,
8351 { "Assembly qualified name length", "tds.colmetadata.assemblyqualifiedname_length",
8352 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8355 { &hf_tds_colmetadata_assemblyqualifiedname
,
8356 { "Assembly qualified name", "tds.colmetadata.assemblyqualifiedname",
8357 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8360 { &hf_tds_colmetadata_owningschema_length
,
8361 { "Owning schema name length", "tds.colmetadata.owningschema_length",
8362 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8365 { &hf_tds_colmetadata_owningschema
,
8366 { "Owning schema name", "tds.colmetadata.owningschema",
8367 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8370 { &hf_tds_colmetadata_xmlschemacollection_length
,
8371 { "XML schema collection length", "tds.colmetadata.xmlschemacollection_length",
8372 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8375 { &hf_tds_colmetadata_xmlschemacollection
,
8376 { "XML schema collection", "tds.colmetadata.xmlschemacollection",
8377 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8381 /* CONTROL token (TDS_CONTROL_TOKEN) */
8383 { "Token - Control", "tds.control",
8384 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8387 { &hf_tds_control_length
,
8388 { "Token Length - Control", "tds.control.length",
8389 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8392 { &hf_tds_control_fmt
,
8393 { "Control - Fmt", "tds.control.fmt",
8394 FT_UINT_BYTES
, BASE_NONE
|BASE_ALLOW_ZERO
, NULL
, 0x0,
8398 /* CURCLOSE token (TDS_CURCLOSE_TOKEN) */
8400 { "Token - CurClose", "tds.curclose",
8401 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8404 { &hf_tds_curclose_length
,
8405 { "Token Length - CurClose", "tds.curclose.length",
8406 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8409 { &hf_tds_curclose_cursorid
,
8410 { "CursorId", "tds.curclose.cursorid",
8411 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
8414 { &hf_tds_curclose_cursor_name
,
8415 { "Cursorname", "tds.curclose.cursor.name_len",
8416 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8419 { &hf_tds_curclose_option_deallocate
,
8420 { "Deallocate", "tds.curclose.option.deallocate",
8421 FT_BOOLEAN
, 8, NULL
, 0x01,
8425 /* CURDECLARE token (TDS_CURDECLARE_TOKEN) */
8426 { &hf_tds_curdeclare
,
8427 { "Token - CurDeclare", "tds.curdeclare",
8428 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8431 { &hf_tds_curdeclare_length
,
8432 { "Token Length - CurDeclare", "tds.curdeclare.length",
8433 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8436 { &hf_tds_curdeclare_cursor_name
,
8437 { "Cursorname", "tds.curdeclare.cursor.name_len",
8438 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8441 { &hf_tds_curdeclare_options
,
8442 { "Options", "tds.curdeclare.options",
8443 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8446 { &hf_tds_curdeclare_options_rdonly
,
8447 { "Read Only", "tds.curdeclare.options.rdonly",
8448 FT_BOOLEAN
, 8, NULL
, 0x01,
8451 { &hf_tds_curdeclare_options_updatable
,
8452 { "Updatable", "tds.curdeclare.options.updatable",
8453 FT_BOOLEAN
, 8, NULL
, 0x02,
8456 { &hf_tds_curdeclare_options_sensitive
,
8457 { "Sensitive", "tds.curdeclare.options.sensitive",
8458 FT_BOOLEAN
, 8, NULL
, 0x04,
8461 { &hf_tds_curdeclare_options_dynamic
,
8462 { "Dynamic", "tds.curdeclare.options.dynamic",
8463 FT_BOOLEAN
, 8, NULL
, 0x08,
8466 { &hf_tds_curdeclare_options_implicit
,
8467 { "Implicit", "tds.curdeclare.options.implicit",
8468 FT_BOOLEAN
, 8, NULL
, 0x10,
8471 { &hf_tds_curdeclare_status_parameterized
,
8472 { "Status Parameterized", "tds.curdeclare.status.parameterized",
8473 FT_BOOLEAN
, 8, NULL
, 0x01,
8476 { &hf_tds_curdeclare_statement
,
8477 { "Statement", "tds.curdeclare.statement",
8478 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8481 { &hf_tds_curdeclare_update_columns_num
,
8482 { "Number of updatable columns", "tds.curdeclare.update_columns_num",
8483 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8486 { &hf_tds_curdeclare_update_columns_name
,
8487 { "Updatable Column Name", "tds.curdeclare.update_columns_name",
8488 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8492 /* CURFETCH token (TDS_CURFETCH_TOKEN) */
8494 { "Token - CurFetch", "tds.curfetch",
8495 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8498 { &hf_tds_curfetch_length
,
8499 { "Token Length - CurFetch", "tds.curfetch.length",
8500 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8503 { &hf_tds_curfetch_cursorid
,
8504 { "CursorId", "tds.curfetch.cursorid",
8505 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
8508 { &hf_tds_curfetch_cursor_name
,
8509 { "CurFetch - Cursorname", "tds.curfetch.cursor.name_len",
8510 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8513 { &hf_tds_curfetch_type
,
8514 { "CurFetch - Type", "tds.curinfo.type",
8515 FT_UINT8
, BASE_DEC
, VALS(tds_curfetch_types
), 0x0,
8518 { &hf_tds_curfetch_rowcnt
,
8519 { "CurFetch - Rowcnt", "tds.curfetch.rowcnt",
8520 FT_INT32
, BASE_DEC
, NULL
, 0x0,
8524 /* CURINFO token (TDS_CURINFO_TOKEN) */
8526 { "Token - CurInfo", "tds.curinfo",
8527 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8530 { &hf_tds_curinfo_length
,
8531 { "Token Length - Curinfo", "tds.curinfo.length",
8532 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8535 { &hf_tds_curinfo_cursorid
,
8536 { "CursorId", "tds.curinfo.cursorid",
8537 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
8540 { &hf_tds_curinfo_cursor_name
,
8541 { "Cursorname", "tds.curinfo.cursor.name_len",
8542 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8545 { &hf_tds_curinfo_cursor_command
,
8546 { "Cursor Command", "tds.curinfo.cursor.command",
8547 FT_UINT8
, BASE_DEC
, VALS(tds_curinfo_commands
), 0x0,
8550 { &hf_tds_curinfo_cursor_status
,
8551 { "Cursor Status", "tds.curinfo.cursor.status",
8552 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8555 { &hf_tds_curinfo_cursor_status_declared
,
8556 { "Declared", "tds.curinfo.cursor.status.declared",
8557 FT_BOOLEAN
, 16, NULL
, 0x0001,
8560 { &hf_tds_curinfo_cursor_status_open
,
8561 { "Open", "tds.curinfo.cursor.status.open",
8562 FT_BOOLEAN
, 16, NULL
, 0x0002,
8565 { &hf_tds_curinfo_cursor_status_closed
,
8566 { "Closed", "tds.curinfo.cursor.status.closed",
8567 FT_BOOLEAN
, 16, NULL
, 0x0004,
8570 { &hf_tds_curinfo_cursor_status_rdonly
,
8571 { "Read only", "tds.curinfo.cursor.status.rdonly",
8572 FT_BOOLEAN
, 16, NULL
, 0x0008,
8575 { &hf_tds_curinfo_cursor_status_updatable
,
8576 { "Updatable", "tds.curinfo.cursor.status.updatable",
8577 FT_BOOLEAN
, 16, NULL
, 0x0010,
8580 { &hf_tds_curinfo_cursor_status_rowcnt
,
8581 { "Rowcount valid", "tds.curinfo.cursor.status.rowcnt",
8582 FT_BOOLEAN
, 16, NULL
, 0x0020,
8585 { &hf_tds_curinfo_cursor_status_dealloc
,
8586 { "Deallocated", "tds.curinfo.cursor.status.dealloc",
8587 FT_BOOLEAN
, 16, NULL
, 0x0040,
8590 { &hf_tds_curinfo_cursor_rowcnt
,
8591 { "Cursor Rowcnt", "tds.curinfo.cursor.rowcnt",
8592 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8596 /* CUROPEN token (TDS_CUROPEN_TOKEN) */
8598 { "Token - CurOpen", "tds.curopen",
8599 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8602 { &hf_tds_curopen_length
,
8603 { "Token Length - CurOpen", "tds.curopen.length",
8604 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8607 { &hf_tds_curopen_cursorid
,
8608 { "CursorId", "tds.curopen.cursorid",
8609 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0,
8612 { &hf_tds_curopen_cursor_name
,
8613 { "Cursorname", "tds.curopen.cursor.name_len",
8614 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8617 { &hf_tds_curopen_status_parameterized
,
8618 { "Status Parameterized", "tds.curopen.status.parameterized",
8619 FT_BOOLEAN
, 8, NULL
, 0x01,
8623 /* DBRPC token (TDS5_DBRPC_TOKEN) */
8625 { "Token - DBRPC", "tds.dbrpc",
8626 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8629 { &hf_tds_dbrpc_length
,
8630 { "Token Length - DBRPC", "tds.dbrpc.length",
8631 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8634 { &hf_tds_dbrpc_rpcname_len
,
8635 { "DBRPC - RPC Name Length", "tds.dbrpc.rpcname_len",
8636 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8639 { &hf_tds_dbrpc_rpcname
,
8640 { "DBRPC - RPC Name", "tds.dbrpc.rpcname",
8641 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8644 { &hf_tds_dbrpc_options
,
8645 { "DBRPC - Options", "tds.dbrpc.options",
8646 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8649 { &hf_tds_dbrpc_options_recompile
,
8650 { "Recompile", "tds.dbrpc.options.recompile",
8651 FT_BOOLEAN
, 16, NULL
, 0x0001,
8654 { &hf_tds_dbrpc_options_params
,
8655 { "Has parameters", "tds.dbrpc.options.params",
8656 FT_BOOLEAN
, 16, NULL
, 0x0002,
8660 /* DONE token (TDS_DONE_TOKEN) */
8662 { "Token - Done", "tds.done",
8663 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8666 { &hf_tds_done_donerowcount_64
,
8667 { "Row count", "tds.done.donerowcount64",
8668 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
8671 { &hf_tds_done_donerowcount_32
,
8672 { "Row count", "tds.done.donerowcount",
8673 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8676 { &hf_tds_done_status
,
8677 { "Status flags", "tds.done.status",
8678 FT_UINT16
, BASE_HEX
, NULL
, 0x017f,
8681 { &hf_tds_done_status_more
,
8682 { "More", "tds.done.status.more",
8683 FT_BOOLEAN
, 16, TFS(&tds_tfs_more_final
), 0x0001,
8686 { &hf_tds_done_status_error
,
8687 { "Error", "tds.done.status.error",
8688 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0002,
8691 { &hf_tds_done_status_inxact
,
8692 { "In Transaction", "tds.done.status.inxact",
8693 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0004,
8696 { &hf_tds_done_status_proc
,
8697 { "Procedure", "tds.done.status.proc",
8698 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0008,
8701 { &hf_tds_done_status_count
,
8702 { "Row count valid", "tds.done.status.count",
8703 FT_BOOLEAN
, 16, TFS(&tfs_valid_invalid
), 0x0010,
8706 { &hf_tds_done_status_attn
,
8707 { "Acknowledge ATTN", "tds.done.status.attn",
8708 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0020,
8711 { &hf_tds_done_status_event
,
8712 { "Event", "tds.done.status.event",
8713 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0040,
8716 { &hf_tds_done_status_rpcinbatch
,
8717 { "RPC in batch", "tds.done.status.rpcinbatch",
8718 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0080,
8721 { &hf_tds_done_status_srverror
,
8722 { "Server Error", "tds.done.status.srverror",
8723 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0100,
8726 { &hf_tds_done_curcmd
,
8727 { "Operation", "tds.done.curcmd",
8728 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8732 /* DONEPROC token (TDS_DONEPROC_TOKEN - implemented the same as TDS_DONE_TOKEN) */
8734 { "Token - DoneProc", "tds.doneproc",
8735 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8738 { &hf_tds_doneproc_donerowcount_64
,
8739 { "Row count", "tds.doneproc.donerowcount64",
8740 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
8743 { &hf_tds_doneproc_donerowcount_32
,
8744 { "Row count", "tds.doneproc.donerowcount",
8745 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8748 { &hf_tds_doneproc_status
,
8749 { "Status flags", "tds.doneproc.status",
8750 FT_UINT16
, BASE_HEX
, NULL
, 0x01ff,
8753 { &hf_tds_doneproc_curcmd
,
8754 { "Operation", "tds.doneproc.curcmd",
8755 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
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,
8765 { &hf_tds_doneinproc_donerowcount_64
,
8766 { "Row count", "tds.doneinproc.donerowcount64",
8767 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
8770 { &hf_tds_doneinproc_donerowcount_32
,
8771 { "Row count", "tds.doneinproc.donerowcount",
8772 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8775 { &hf_tds_doneinproc_status
,
8776 { "Status flags", "tds.doneinproc.status",
8777 FT_UINT16
, BASE_HEX
, NULL
, 0x01ff,
8780 { &hf_tds_doneinproc_curcmd
,
8781 { "Operation", "tds.doneinproc.curcmd",
8782 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8786 /* EED token (TDS5_EED_TOKEN) */
8788 { "Token - ExtendedErrorDiagnostic", "tds.eed",
8789 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8792 { &hf_tds_eed_length
,
8793 { "Token length", "tds.eed.length",
8794 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8797 { &hf_tds_eed_number
,
8798 { "SQL Error Number", "tds.eed.number",
8799 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8802 { &hf_tds_eed_state
,
8803 { "State", "tds.eed.state",
8804 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8807 { &hf_tds_eed_class
,
8808 { "Class (Severity)", "tds.eed.class",
8809 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8812 { &hf_tds_eed_sql_state
,
8813 { "SQL State", "tds.eed.sql_state",
8814 FT_UINT_BYTES
, BASE_NONE
|BASE_ALLOW_ZERO
, NULL
, 0x0,
8817 { &hf_tds_eed_status
,
8818 { "EED Following", "tds.eed.status",
8819 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
8822 { &hf_tds_eed_transtate
,
8823 { "Transaction state", "tds.eed.transtate",
8824 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8827 { &hf_tds_eed_msgtext
,
8828 { "Error message", "tds.eed.msgtext",
8829 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8832 { &hf_tds_eed_servername
,
8833 { "Server name", "tds.eed.servername",
8834 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8837 { &hf_tds_eed_procname
,
8838 { "Procedure name", "tds.eed.procname",
8839 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
8842 { &hf_tds_eed_linenumber
,
8843 { "Line number", "tds.eed.linenumber",
8844 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8848 /* ENVCHANGE token (TDS_ENVCHG_TOKEN) */
8850 { "Token - EnvChange", "tds.envchange",
8851 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8854 { &hf_tds_envchg_length
,
8855 { "Token length", "tds.envchange.length",
8856 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8859 { &hf_tds_envchg_type
,
8860 { "Type", "tds.envchange.type",
8861 FT_UINT8
, BASE_DEC
, VALS(envchg_names
), 0x0,
8864 { &hf_tds_envchg_newvalue_length
,
8865 { "New Value Length", "tds.envchange.newvalue_length",
8866 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8869 { &hf_tds_envchg_newvalue_string
,
8870 { "New Value", "tds.envchange.newvalue_string",
8871 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8874 { &hf_tds_envchg_newvalue_bytes
,
8875 { "New Value", "tds.envchange.newvalue",
8876 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8879 { &hf_tds_envchg_oldvalue_length
,
8880 { "Old Value Length", "tds.envchange.oldvalue_length",
8881 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8884 { &hf_tds_envchg_oldvalue_string
,
8885 { "Old Value", "tds.envchange.oldvalue_string",
8886 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8889 { &hf_tds_envchg_oldvalue_bytes
,
8890 { "Old Value", "tds.envchange.oldvalue",
8891 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8894 { &hf_tds_envchg_collate_codepage
,
8895 { "Collate codepage", "tds.envchange.collate_codepage",
8896 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8899 { &hf_tds_envchg_collate_flags
,
8900 { "Collate flags", "tds.envchange.collate_flags",
8901 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8904 { &hf_tds_envchg_collate_charset_id
,
8905 { "Collate charset ID", "tds.envchange.collate_charset_id",
8906 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8910 /* ERROR token (TDS_ERR_TOKEN) */
8912 { "Token - Error", "tds.error",
8913 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8916 { &hf_tds_error_length
,
8917 { "Token length", "tds.error.length",
8918 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8921 { &hf_tds_error_number
,
8922 { "SQL Error Number", "tds.error.number",
8923 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8926 { &hf_tds_error_state
,
8927 { "State", "tds.error.state",
8928 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8931 { &hf_tds_error_class
,
8932 { "Class (Severity)", "tds.error.class",
8933 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
8941 { &hf_tds_error_msgtext
,
8942 { "Error message", "tds.error.msgtext",
8943 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
8951 { &hf_tds_error_servername
,
8952 { "Server name", "tds.error.servername",
8953 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
8961 { &hf_tds_error_procname
,
8962 { "Process name", "tds.error.procname",
8963 FT_STRING
, BASE_NONE
, NULL
, 0x0,
8966 { &hf_tds_error_linenumber_16
,
8967 { "Line number", "tds.error.linenumber",
8968 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8971 { &hf_tds_error_linenumber_32
,
8972 { "Line number", "tds.error.linenumber",
8973 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8977 /* FEATUREEXTACK token (TDS_FEATUREEXTACK_TOKEN) */
8978 { &hf_tds_featureextack
,
8979 { "Token - FeatureExtAct", "tds.featureextack",
8980 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8983 { &hf_tds_featureextack_feature
,
8984 { "Feature", "tds.featureextack.feature",
8985 FT_NONE
, BASE_NONE
, NULL
, 0x0,
8988 { &hf_tds_featureextack_featureid
,
8989 { "Feature ID", "tds.featureextack.featureid",
8990 FT_UINT8
, BASE_DEC
, VALS(featureextack_feature_names
), 0x0,
8993 { &hf_tds_featureextack_featureackdatalen
,
8994 { "Feature length", "tds.featureextack.featureackdatalen",
8995 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8998 { &hf_tds_featureextack_featureackdata
,
8999 { "Feature data", "tds.featureextack.featureackdata",
9000 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
9004 /* FEDAUTHINFO token */
9008 { "Token - Info", "tds.info",
9009 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9012 { &hf_tds_info_length
,
9013 { "Token length", "tds.info.length",
9014 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9017 { &hf_tds_info_number
,
9018 { "SQL Error Number", "tds.info.number",
9019 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9022 { &hf_tds_info_state
,
9023 { "State", "tds.info.state",
9024 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9027 { &hf_tds_info_class
,
9028 { "Class (Severity)", "tds.info.class",
9029 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
9037 { &hf_tds_info_msgtext
,
9038 { "Error message", "tds.info.msgtext",
9039 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
9047 { &hf_tds_info_servername
,
9048 { "Server name", "tds.info.servername",
9049 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
9057 { &hf_tds_info_procname
,
9058 { "Process name", "tds.info.procname",
9059 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9062 { &hf_tds_info_linenumber_16
,
9063 { "Line number", "tds.info.linenumber",
9064 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9067 { &hf_tds_info_linenumber_32
,
9068 { "Line number", "tds.info.linenumber",
9069 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9073 /* LOGINACK token (TDS_LOGIN_ACK_TOKEN) */
9075 { "Token - LoginAck", "tds.loginack",
9076 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9079 { &hf_tds_loginack_length
,
9080 { "Token length", "tds.loginack.length",
9081 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9084 { &hf_tds_loginack_interface
,
9085 { "Interface", "tds.loginack.interface",
9086 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9089 { &hf_tds_loginack_tdsversion
,
9090 { "TDS version", "tds.loginack.tdsversion",
9091 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
9094 { &hf_tds_loginack_progversion
,
9095 { "Server Version", "tds.loginack.progversion",
9096 FT_UINT32
, BASE_CUSTOM
, CF_FUNC(version_convert
), 0x0,
9099 { &hf_tds_loginack_progname
,
9100 { "Server name", "tds.loginack.progname",
9101 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9105 /* LOGOUT token (TDS5_LOGOUT_TOKEN) */
9107 { "Token - Logout", "tds.logout",
9108 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9111 { &hf_tds_logout_options
,
9112 { "Logout Options", "tds.logout.options",
9113 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9117 /* MSG token (TDS5_MSG_TOKEN) */
9119 { "Token - Msg", "tds.msg",
9120 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9123 { &hf_tds_msg_length
,
9124 { "Token length - Msg", "tds.msg.length",
9125 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9128 { &hf_tds_msg_status
,
9129 { "Status", "tds.msg.status",
9130 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9133 { &hf_tds_msg_msgid
,
9134 { "Message Id", "tds.msg.msgid",
9135 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9139 /* NBCROW token (TDS_NBCROW_TOKEN) */
9141 { "Token - NBCRow", "tds.nbcrow",
9142 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9148 { "Token - Offset", "tds.offset",
9149 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9152 { &hf_tds_offset_id
,
9153 { "Offset ID", "tds.offset.id",
9154 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9157 { &hf_tds_offset_len
,
9158 { "Offset length", "tds.offset.len",
9159 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9163 /* ORDER token (TDS_ORDER_TOKEN) */
9165 { "Token - Order", "tds.order",
9166 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9169 { &hf_tds_order_length
,
9170 { "Token length", "tds.order.length",
9171 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9174 { &hf_tds_order_colnum
,
9175 { "Order column", "tds.order.colnum",
9176 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9180 /* PARAMFMT token (TDS5_PARAMFMT_TOKEN) */
9182 { "Token - Paramfmt", "tds.paramfmt",
9183 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9186 { &hf_tds_paramfmt_length
,
9187 { "Token length - Paramfmt", "tds.paramfmt.length",
9188 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9191 { &hf_tds_paramfmt_numparams
,
9192 { "Number of Parameters", "tds.paramfmt.numparams",
9193 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9196 { &hf_tds_paramfmt_colname
,
9197 { "Parameter name", "tds.paramfmt.colname",
9198 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9201 { &hf_tds_paramfmt_status
,
9202 { "Column Status", "tds.paramfmt.status",
9203 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9206 { &hf_tds_paramfmt_utype
,
9207 { "Parameter Usertype", "tds.paramfmt.utype",
9208 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9211 { &hf_tds_paramfmt_ctype
,
9212 { "Parameter Datatype", "tds.paramfmt.ctype",
9213 FT_UINT8
, BASE_DEC
, &tds_data_type_names
, 0x0,
9216 { &hf_tds_paramfmt_csize
,
9217 { "Parameter size", "tds.paramfmt.csize",
9218 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9221 { &hf_tds_paramfmt_locale_info
,
9222 { "Locale info", "tds.paramfmt.locale_info",
9223 FT_UINT_BYTES
, BASE_NONE
|BASE_ALLOW_ZERO
, NULL
, 0x0,
9227 /* PARAMFMT2 token (TDS5_PARAMFMT2_TOKEN) */
9228 { &hf_tds_paramfmt2
,
9229 { "Token - Paramfmt2", "tds.paramfmt2",
9230 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9233 { &hf_tds_paramfmt2_length
,
9234 { "Token length - Paramfmt2", "tds.paramfmt2.length",
9235 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9238 { &hf_tds_paramfmt2_numparams
,
9239 { "Number of Parameters", "tds.paramfmt2.numparams",
9240 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9243 { &hf_tds_paramfmt2_colname
,
9244 { "Parameter name", "tds.paramfmt2.paramname",
9245 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9248 { &hf_tds_paramfmt2_status
,
9249 { "Parameter Status", "tds.paramfmt2.status",
9250 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
9253 { &hf_tds_paramfmt2_utype
,
9254 { "Parameter Usertype", "tds.paramfmt2.utype",
9255 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9258 { &hf_tds_paramfmt2_ctype
,
9259 { "Parameter Datatype", "tds.paramfmt2.ctype",
9260 FT_UINT8
, BASE_DEC
, &tds_data_type_names
, 0x0,
9263 { &hf_tds_paramfmt2_csize
,
9264 { "Parameter size", "tds.paramfmt2.csize",
9265 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9268 { &hf_tds_paramfmt2_locale_info
,
9269 { "Locale info", "tds.paramfmt2.locale_info",
9270 FT_UINT_BYTES
, BASE_NONE
|BASE_ALLOW_ZERO
, NULL
, 0x0,
9274 /* PARAMS token (TDS5_PARAMS_TOKEN) */
9276 { "Token - Params", "tds.params",
9277 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9280 { &hf_tds_params_field
,
9281 { "Parameter", "tds.params.parameter",
9282 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9286 /* PROCID token (TDS_PROCID_TOKEN) */
9288 { "Token - Procid", "tds.procid",
9289 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9292 { &hf_tds_procid_value
,
9293 { "Procid Value", "tds.procid.value",
9294 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
9298 /* RETURNSTATUS token (TDS_RET_STAT_TOKEN) */
9299 { &hf_tds_returnstatus
,
9300 { "Token - ReturnStatus", "tds.returnstatus",
9301 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9304 { &hf_tds_returnstatus_value
,
9305 { "Value", "tds.returnstatus.value",
9306 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9310 /* RETURNVALUE token (TDS_RETURNVAL_TOKEN) */
9312 /* ROW token (TDS_ROW_TOKEN) */
9314 { "Token - Row", "tds.row",
9315 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9318 { &hf_tds_row_field
,
9319 { "Field", "tds.row.field",
9320 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9324 /* ROWFMT token (TDS5_ROWFMT_TOKEN) */
9326 { "Token - Rowfmt", "tds.rowfmt",
9327 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9330 { &hf_tds_rowfmt_length
,
9331 { "Token length - Rowfmt", "tds.rowfmt.length",
9332 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9335 { &hf_tds_rowfmt_numcols
,
9336 { "Number of Columns", "tds.rowfmt.numcols",
9337 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9340 { &hf_tds_rowfmt_colname
,
9341 { "Column name", "tds.rowfmt.colname",
9342 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9345 { &hf_tds_rowfmt_status
,
9346 { "Column Status", "tds.rowfmt.status",
9347 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9350 { &hf_tds_rowfmt_utype
,
9351 { "Column Usertype", "tds.rowfmt.utype",
9352 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9355 { &hf_tds_rowfmt_ctype
,
9356 { "Column Datatype", "tds.rowfmt.ctype",
9357 FT_UINT8
, BASE_DEC
, &tds_data_type_names
, 0x0,
9360 { &hf_tds_rowfmt_csize
,
9361 { "Column size", "tds.rowfmt.csize",
9362 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9365 { &hf_tds_rowfmt_text_tablename
,
9366 { "Text Tablename", "tds.rowfmt.text_tablename",
9367 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9370 { &hf_tds_rowfmt_precision
,
9371 { "Precision", "tds.rowfmt.precision",
9372 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9375 { &hf_tds_rowfmt_scale
,
9376 { "Scale", "tds.rowfmt.scale",
9377 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9380 { &hf_tds_rowfmt_locale_info
,
9381 { "Locale info", "tds.rowfmt.locale_info",
9382 FT_UINT_BYTES
, BASE_NONE
|BASE_ALLOW_ZERO
, NULL
, 0x0,
9386 /* ROWFMT2 token (TDS5_ROWFMT2_TOKEN) */
9388 { "Token - Rowfmt2", "tds.rowfmt2",
9389 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9392 { &hf_tds_rowfmt2_length
,
9393 { "Token length - Rowfmt2", "tds.rowfmt2.length",
9394 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9397 { &hf_tds_rowfmt2_numcols
,
9398 { "Number of Columns", "tds.rowfmt2.numcols",
9399 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9402 { &hf_tds_rowfmt2_labelname
,
9403 { "Label name", "tds.rowfmt2.labelname",
9404 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9407 { &hf_tds_rowfmt2_catalogname
,
9408 { "Catalog name", "tds.rowfmt2.catalogname",
9409 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9412 { &hf_tds_rowfmt2_schemaname
,
9413 { "Schema name", "tds.rowfmt2.schemaname",
9414 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9417 { &hf_tds_rowfmt2_tablename
,
9418 { "Table name", "tds.rowfmt2.tablename",
9419 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9422 { &hf_tds_rowfmt2_colname
,
9423 { "Column name", "tds.rowfmt2.colname",
9424 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9427 { &hf_tds_rowfmt2_status
,
9428 { "Column Status", "tds.rowfmt2.status",
9429 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
9432 { &hf_tds_rowfmt2_utype
,
9433 { "Column Usertype", "tds.rowfmt2.utype",
9434 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9437 { &hf_tds_rowfmt2_ctype
,
9438 { "Column Datatype", "tds.rowfmt2.ctype",
9439 FT_UINT8
, BASE_DEC
, &tds_data_type_names
, 0x0,
9442 { &hf_tds_rowfmt2_csize
,
9443 { "Column size", "tds.rowfmt2.csize",
9444 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9447 { &hf_tds_rowfmt2_text_tablename
,
9448 { "Text Tablename", "tds.rowfmt2.text_tablename",
9449 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
9452 { &hf_tds_rowfmt2_precision
,
9453 { "Precision", "tds.rowfmt2.precision",
9454 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9457 { &hf_tds_rowfmt2_scale
,
9458 { "Scale", "tds.rowfmt2.scale",
9459 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9462 { &hf_tds_rowfmt2_locale_info
,
9463 { "Locale info", "tds.rowfmt2.locale_info",
9464 FT_UINT_BYTES
, BASE_NONE
|BASE_ALLOW_ZERO
, NULL
, 0x0,
9468 /* SESSIONSTATE token (TDS_SESSIONSTATE_TOKEN) */
9469 { &hf_tds_sessionstate
,
9470 { "Token - Session state", "tds.sessionstate",
9471 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9474 { &hf_tds_sessionstate_length
,
9475 { "Token length", "tds.sessionstate.length",
9476 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9479 { &hf_tds_sessionstate_seqno
,
9480 { "Sequence number", "tds.sessionstate.seqno",
9481 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9484 { &hf_tds_sessionstate_status
,
9485 { "Status", "tds.sessionstate.status",
9486 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9489 { &hf_tds_sessionstate_stateid
,
9490 { "State ID", "tds.sessionstate.stateid",
9491 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9494 { &hf_tds_sessionstate_statelen
,
9495 { "State Length", "tds.sessionstate.statelen",
9496 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9499 { &hf_tds_sessionstate_statevalue
,
9500 { "State Value", "tds.sessionstate.statevalue",
9501 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
9507 { "Token - SSPI", "tds.sspi",
9508 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9511 { &hf_tds_sspi_buffer
,
9512 { "State Value", "tds.sspi.buffer",
9513 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
9521 /* TDS5 Lang Token */
9522 { &hf_tds_lang_length
,
9523 { "Token Length - Language", "tds.lang.length",
9524 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9527 { &hf_tds_lang_token_status
,
9528 { "Status", "tds.lang.token_status",
9529 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9532 { &hf_tds_lang_status_parameterized
,
9533 { "Parameters follow", "tds.lang.token_status.parameterized",
9534 FT_BOOLEAN
, 8, NULL
, 0x01,
9537 { &hf_tds_lang_language_text
,
9538 { "Language text", "tds.lang.language_text",
9539 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9543 /* Unknown token type */
9544 { &hf_tds_unknown_tds_token
,
9545 { "Token - Unknown", "tds.unknown_tds_token",
9546 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9550 /************************ Message definitions ***********************/
9552 /* Bulk Load BCP stream */
9554 /* Bulk Load Update Text/Write Text */
9556 /* Federated Authentication Token */
9560 { "Hostname length", "tds.login",
9561 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9564 { &hf_tdslogin_hostname_length
,
9565 { "Hostname length", "tds.login.hostname_length",
9566 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9569 { &hf_tdslogin_hostname
,
9570 { "Hostname", "tds.login.hostname",
9571 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9574 { &hf_tdslogin_username_length
,
9575 { "Username length", "tds.login.username_length",
9576 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9579 { &hf_tdslogin_username
,
9580 { "Username", "tds.login.username",
9581 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9584 { &hf_tdslogin_password_length
,
9585 { "Password length", "tds.login.password_length",
9586 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9589 { &hf_tdslogin_password
,
9590 { "Password", "tds.login.password",
9591 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9594 { &hf_tdslogin_hostprocess_length
,
9595 { "Host Process Id length", "tds.login.hostprocess_length",
9596 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9599 { &hf_tdslogin_hostprocess
,
9600 { "Host Process Id", "tds.login.pid",
9601 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9604 { &hf_tdslogin_option_int2
,
9605 { "Short (2-byte) integer format", "tds.login.option.int2",
9606 FT_UINT8
, BASE_DEC
, VALS(login_options
), 0x0,
9609 { &hf_tdslogin_option_int4
,
9610 { "Long (4-byte) integer format", "tds.login.option.int4",
9611 FT_UINT8
, BASE_DEC
, VALS(login_options
), 0x0,
9614 { &hf_tdslogin_option_char
,
9615 { "Character set", "tds.login.option.char",
9616 FT_UINT8
, BASE_DEC
, VALS(login_options
), 0x0,
9619 { &hf_tdslogin_option_float
,
9620 { "Double (8 byte) float format", "tds.login.option.float",
9621 FT_UINT8
, BASE_DEC
, VALS(login_options
), 0x0,
9624 { &hf_tdslogin_option_date8
,
9625 { "Long (8 byte) date format", "tds.login.option.date",
9626 FT_UINT8
, BASE_DEC
, VALS(login_options
), 0x0,
9629 { &hf_tdslogin_option_usedb
,
9630 { "Use DB", "tds.login.option.usedb",
9631 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_no_yes
), 0x0,
9634 { &hf_tdslogin_option_bulk
,
9635 { "Bulk Copy", "tds.login.option.bulk",
9636 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_no_yes
), 0x0,
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,
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,
9649 { &hf_tdslogin_option_conversation_type
,
9650 { "Conversation type", "tds.login.option.type",
9651 FT_UINT8
, BASE_DEC
, VALS(login_conversation_type
), 0x0,
9654 { &hf_tdslogin_appname_length
,
9655 { "Application name length", "tds.login.appname_length",
9656 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9659 { &hf_tdslogin_appname
,
9660 { "Application name", "tds.login.appname",
9661 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9664 { &hf_tdslogin_servername_length
,
9665 { "Server name length", "tds.login.servername_length",
9666 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9669 { &hf_tdslogin_servername
,
9670 { "Server name", "tds.login.servname",
9671 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9674 { &hf_tdslogin_remotepassword_length
,
9675 { "Remote password length", "tds.login.rempw_length",
9676 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9679 { &hf_tdslogin_rempw_servername_length
,
9680 { "Remote password servername length", "tds.login.rempw_servername_length",
9681 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9684 { &hf_tdslogin_rempw_servername
,
9685 { "Remote password server name", "tds.login.rempw_servername",
9686 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9689 { &hf_tdslogin_rempw_password_length
,
9690 { "Remote password password length", "tds.login.rempw_password_length",
9691 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9694 { &hf_tdslogin_rempw_password
,
9695 { "Remote password password", "tds.login.rempw_password",
9696 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9699 { &hf_tdslogin_proto_version
,
9700 { "Protocol version", "tds.login.protoversion",
9701 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
9704 { &hf_tdslogin_progname_length
,
9705 { "Program name length", "tds.login.progname_length",
9706 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9709 { &hf_tdslogin_progname
,
9710 { "Program name", "tds.login.progname",
9711 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9714 { &hf_tdslogin_progvers
,
9715 { "Program version", "tds.login.progversion",
9716 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
9719 { &hf_tdslogin_option2_noshort
,
9720 { "Convert shorts to longs", "tds.login.option.noshort",
9721 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
9724 { &hf_tdslogin_option2_flt4
,
9725 { "Single (4 byte) float format", "tds.login.option.flt4",
9726 FT_UINT8
, BASE_DEC
, VALS(login_options
), 0x0,
9729 { &hf_tdslogin_option2_date4
,
9730 { "Short (4 byte) date format", "tds.login.option.date4",
9731 FT_UINT8
, BASE_DEC
, VALS(login_options
), 0x0,
9734 { &hf_tdslogin_language
,
9735 { "Language", "tds.login.language",
9736 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9739 { &hf_tdslogin_language_length
,
9740 { "Language name length", "tds.login.language_length",
9741 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9744 { &hf_tdslogin_setlang
,
9745 { "Notify client of language changes", "tds.login.setlang",
9746 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
9749 { &hf_tdslogin_seclogin
,
9750 { "Secure login", "tds.login.seclogin",
9751 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
9754 { &hf_tdslogin_secbulk
,
9755 { "Secure bulk copy", "tds.login.secbulk",
9756 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
9759 { &hf_tdslogin_halogin
,
9760 { "High Availability login", "tds.login.halogin",
9761 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
9764 { &hf_tdslogin_hasessionid
,
9765 { "High Availability session id", "tds.login.hasessionid",
9766 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
9769 { &hf_tdslogin_charset
,
9770 { "Character set", "tds.login.charset",
9771 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9774 { &hf_tdslogin_charset_length
,
9775 { "Character set name length", "tds.login.charset_length",
9776 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9779 { &hf_tdslogin_setcharset
,
9780 { "Notify client of character set changes", "tds.login.setcharset",
9781 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
9784 { &hf_tdslogin_packetsize
,
9785 { "Packet size", "tds.login.packetsize",
9786 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9789 { &hf_tdslogin_packetsize_length
,
9790 { "Packet size length", "tds.login.packetsize_length",
9791 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
9806 { &hf_tds7login_packet_size
,
9807 { "Packet Size", "tds.7login.packet_size",
9808 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9811 { &hf_tds7login_client_version
,
9812 { "Client version", "tds.7login.client_version",
9813 FT_UINT32
, BASE_CUSTOM
, CF_FUNC(version_convert
), 0x0,
9816 { &hf_tds7login_client_pid
,
9817 { "Client PID", "tds.7login.client_pid",
9818 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9821 { &hf_tds7login_connection_id
,
9822 { "Connection ID", "tds.7login.connection_id",
9823 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9826 { &hf_tds7login_option_flags1
,
9827 { "Option Flags 1", "tds.7login.option_flags1",
9828 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9831 { &hf_tds7login_option_flags2
,
9832 { "Option Flags 2", "tds.7login.option_flags2",
9833 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9836 { &hf_tds7login_sql_type_flags
,
9837 { "SQL Type Flags", "tds.7login.sql_type_flags",
9838 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9841 { &hf_tds7login_reserved_flags
,
9842 { "Reserved Flags", "tds.7login.reserved_flags",
9843 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
9846 { &hf_tds7login_time_zone
,
9847 { "Time Zone", "tds.7login.time_zone",
9848 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
9851 { &hf_tds7login_collation
,
9852 { "Collation", "tds.7login.collation",
9853 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
9856 { &hf_tds7login_offset
,
9857 { "Offset", "tds.7login.offset",
9858 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
9861 { &hf_tds7login_length
,
9862 { "Length", "tds.7login.length",
9863 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
9866 { &hf_tds7login_password
,
9867 { "Password", "tds.7login.password",
9868 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9871 { &hf_tds7login_clientname
,
9872 { "Client name", "tds.7login.clientname",
9873 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9876 { &hf_tds7login_username
,
9877 { "Username", "tds.7login.username",
9878 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9881 { &hf_tds7login_appname
,
9882 { "App name", "tds.7login.appname",
9883 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9886 { &hf_tds7login_servername
,
9887 { "Server name", "tds.7login.servername",
9888 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9891 { &hf_tds7login_libraryname
,
9892 { "Library name", "tds.7login.libraryname",
9893 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9896 { &hf_tds7login_locale
,
9897 { "Locale", "tds.7login.locale",
9898 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9901 { &hf_tds7login_databasename
,
9902 { "Database name", "tds.7login.databasename",
9903 FT_STRING
, BASE_NONE
, NULL
, 0x0,
9907 /* PRELOGIN stream */
9910 { "Pre-Login Message", "tds.prelogin",
9911 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9914 { &hf_tds_prelogin_option_token
,
9915 { "Option Token", "tds.prelogin.option.token",
9916 FT_UINT8
, BASE_DEC
, VALS(prelogin_token_names
), 0x0,
9919 { &hf_tds_prelogin_option_offset
,
9920 { "Option offset", "tds.prelogin.option.offset",
9921 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9924 { &hf_tds_prelogin_option_length
,
9925 { "Option length", "tds.prelogin.option.length",
9926 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9929 { &hf_tds_prelogin_option_version
,
9930 { "Version", "tds.prelogin.option.version",
9931 FT_UINT32
, BASE_CUSTOM
, CF_FUNC(version_convert
), 0x0,
9934 { &hf_tds_prelogin_option_subbuild
,
9935 { "Sub-build", "tds.prelogin.option.subbuild",
9936 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9939 { &hf_tds_prelogin_option_encryption
,
9940 { "Encryption", "tds.prelogin.option.encryption",
9941 FT_UINT8
, BASE_DEC
, VALS(prelogin_encryption_options
), 0x0,
9944 { &hf_tds_prelogin_option_instopt
,
9945 { "InstOpt", "tds.prelogin.option.instopt",
9946 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
9949 { &hf_tds_prelogin_option_threadid
,
9950 { "ThreadID", "tds.prelogin.option.threadid",
9951 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
9954 { &hf_tds_prelogin_option_mars
,
9955 { "MARS", "tds.prelogin.option.mars",
9956 FT_UINT8
, BASE_DEC
, VALS(tds_mars_type
), 0x0,
9959 { &hf_tds_prelogin_option_traceid
,
9960 { "TraceID", "tds.prelogin.option.traceid",
9961 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
9964 { &hf_tds_prelogin_option_fedauthrequired
,
9965 { "FedAuthRequired", "tds.prelogin.option.fedauthrequired",
9966 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9969 { &hf_tds_prelogin_option_nonceopt
,
9970 { "NonceOpt", "tds.prelogin.option.nonceopt",
9971 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
9975 /* RPC Request Stream */
9978 { "Remote Procedure Call", "tds.rpc",
9979 FT_NONE
, BASE_NONE
, NULL
, 0x0,
9982 { &hf_tds_rpc_name_length8
,
9983 { "Procedure name length", "tds.rpc.name_length",
9984 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
9987 { &hf_tds_rpc_name_length
,
9988 { "Procedure name length", "tds.rpc.name_length",
9989 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
9993 { "Procedure name", "tds.rpc.name",
9994 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
10027 { &hf_tds_rpc_parameter
,
10028 { "Parameter", "tds.rpc.parameter",
10029 FT_NONE
, BASE_NONE
, NULL
, 0x0,
10032 { &hf_tds_rpc_parameter_name_length
,
10033 { "Name length", "tds.rpc.parameter.name_length",
10034 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
10037 { &hf_tds_rpc_parameter_name
,
10038 { "Name", "tds.rpc.parameter.name",
10039 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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
,
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
,
10057 { &hf_tds_rpc_parameter_value
,
10058 { "Value", "tds.rpc.parameter.value",
10059 FT_NONE
, BASE_NONE
, NULL
, 0x0,
10063 /* SQLBatch Stream */
10065 { "Query", "tds.query",
10066 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
10078 { &hf_tds_transmgr_payload
,
10079 { "Payload", "tds.transmgr.payload",
10080 FT_NONE
, BASE_NONE
, NULL
, 0x0,
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,
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,
10106 { &hf_tds_type_info_scale
,
10107 { "Scale", "tds.type_info.scale",
10108 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
10126 { &hf_tds_type_info_collation_ign_accent
,
10127 { "Ignore accent", "tds.type_info.collation.ignore_accent",
10128 FT_BOOLEAN
, 32, NULL
, 0x00200000,
10131 { &hf_tds_type_info_collation_ign_kana
,
10132 { "Ignore kana", "tds.type_info.collation.ignore_kana",
10133 FT_BOOLEAN
, 32, NULL
, 0x00400000,
10136 { &hf_tds_type_info_collation_ign_width
,
10137 { "Ignore width", "tds.type_info.collation.ignore_width",
10138 FT_BOOLEAN
, 32, NULL
, 0x00800000,
10141 { &hf_tds_type_info_collation_binary
,
10142 { "Binary", "tds.type_info.collation.binary",
10143 FT_BOOLEAN
, 32, NULL
, 0x01000000,
10146 { &hf_tds_type_info_collation_version
,
10147 { "Version", "tds.type_info.collation.version",
10148 FT_UINT32
, BASE_DEC
, NULL
, 0xF0000000,
10151 { &hf_tds_type_info_collation_sortid
,
10152 { "SortId", "tds.type_info.collation.sortid",
10153 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
10156 { &hf_tds_type_varbyte_length
,
10157 { "Length", "tds.type_varbyte.length",
10158 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
10161 { &hf_tds_type_varbyte_data_null
,
10162 { "Data: NULL", "tds.type_varbyte.data.null",
10163 FT_NONE
, BASE_NONE
, NULL
, 0x0,
10166 { &hf_tds_type_varbyte_data_boolean
,
10167 { "Data", "tds.type_varbyte.data.bool",
10168 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
10171 { &hf_tds_type_varbyte_data_int1
,
10172 { "Data", "tds.type_varbyte.data.int",
10173 FT_INT8
, BASE_DEC
, NULL
, 0x0,
10176 { &hf_tds_type_varbyte_data_int2
,
10177 { "Data", "tds.type_varbyte.data.int",
10178 FT_INT16
, BASE_DEC
, NULL
, 0x0,
10181 { &hf_tds_type_varbyte_data_int4
,
10182 { "Data", "tds.type_varbyte.data.int",
10183 FT_INT32
, BASE_DEC
, NULL
, 0x0,
10186 { &hf_tds_type_varbyte_data_int8
,
10187 { "Data", "tds.type_varbyte.data.int64",
10188 FT_INT64
, BASE_DEC
, NULL
, 0x0,
10191 { &hf_tds_type_varbyte_data_float
,
10192 { "Data", "tds.type_varbyte.data.float",
10193 FT_FLOAT
, BASE_NONE
, NULL
, 0x0,
10196 { &hf_tds_type_varbyte_data_double
,
10197 { "Data", "tds.type_varbyte.data.float",
10198 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
10201 { &hf_tds_type_varbyte_data_bytes
,
10202 { "Data", "tds.type_varbyte.data.bytes",
10203 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
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,
10211 { &hf_tds_type_varbyte_data_guid
,
10212 { "Data", "tds.type_varbyte.data.guid",
10213 FT_GUID
, BASE_NONE
, NULL
, 0x0,
10216 { &hf_tds_type_varbyte_data_string
,
10217 { "Data", "tds.type_varbyte.data.string",
10218 FT_STRING
, BASE_NONE
, NULL
, 0x0,
10221 { &hf_tds_type_varbyte_data_uint_string
,
10222 { "Data", "tds.type_varbyte.data.uint_string",
10223 FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
10226 { &hf_tds_type_varbyte_data_absdatetime
,
10227 { "Data", "tds.type_varbyte.data.datetime",
10228 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0x0,
10231 { &hf_tds_type_varbyte_data_reltime
,
10232 { "Time", "tds.type_varbyte.data.time",
10233 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
10236 { &hf_tds_type_varbyte_data_sign
,
10237 { "Sign", "tds.type_varbyte.data.sign",
10238 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
10241 { &hf_tds_type_varbyte_data_textptr_len
,
10242 { "Data Textptr Len", "tds.type_varbyte.textptr_len",
10243 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
10246 { &hf_tds_type_varbyte_data_textptr
,
10247 { "Data Textptr", "tds.type_varbyte.data.textptr",
10248 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
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,
10256 { &hf_tds_type_varbyte_plp_len
,
10257 { "PLP length", "tds.type_varbyte.plp_len",
10258 FT_INT64
, BASE_DEC
, NULL
, 0x0,
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,
10266 { &hf_tds_type_varbyte_plp_chunk
,
10267 { "PLP chunk", "tds.type_varbyte.plp_chunk",
10268 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
10271 { &hf_tds_type_varbyte_column_name
,
10272 { "Column name", "tds.type_varbyte.column.name",
10273 FT_STRING
, BASE_NONE
, NULL
, 0x0,
10277 /***************************** Top level TDS *******************************/
10280 { "Type", "tds.type",
10281 FT_UINT8
, BASE_DEC
, VALS(packet_type_names
), 0x0,
10282 "Packet type", HFILL
}
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
,
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
}
10315 { "Length", "tds.length",
10316 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
10317 "Packet length", HFILL
}
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,
10330 { "Window", "tds.window",
10331 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
10364 { &hf_tds_fragment
,
10365 { "TDS Fragment", "tds.fragment",
10366 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
10369 { &hf_tds_fragments
,
10370 { "TDS Fragments", "tds.fragments",
10371 FT_NONE
, BASE_NONE
, NULL
, 0x0,
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,
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,
10421 static int *ett
[] = {
10424 &ett_tds_fragments
,
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
,
10432 &ett_tds_rpc_options
,
10433 &ett_tds_rpc_parameter
,
10434 &ett_tds_rpc_parameter_status
,
10435 &ett_tds_prelogin_option
,
10437 &ett_tds_capability_req
,
10438 &ett_tds_capability_resp
,
10439 &ett_tds_done_status
,
10441 &ett_tds7_prelogin
,
10443 &ett_tds_login_options
,
10444 &ett_tds_login_options2
,
10445 &ett_tds_login_rempw
,
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
}},
10461 { &ei_tds_type_info_type_undecoded
, { "tds.type_info.type.undecoded", PI_UNDECODED
, PI_ERROR
, "Data type not supported yet", EXPFILL
}},
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
}},
10467 { &ei_tds_token_stats
, { "tds.token.stats", PI_PROTOCOL
, PI_NOTE
, "Token stats", EXPFILL
}},
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.",
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",
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",
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
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.
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
);
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
));
10544 * c-basic-offset: 4
10546 * indent-tabs-mode: nil
10549 * ex: set shiftwidth=4 tabstop=8 expandtab:
10550 * :indentSize=4:tabSize=8:noTabs=true: