Ethereal-dev: [Ethereal-dev] TDS dissector changes [packet-tds.c]
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: "Bill Meier" <wmeier@xxxxxxxxxxx>
Date: Sun, 21 Nov 2004 16:15:27 -0500
Below are:
1. An overview of changes I've made to packet-tds.c;
2. A diff of the changes. The diff is versus v 12115
I'm open to any and all feedback.
Note:
Almost all of the changes relate to decoding TDS4/TDS5 which I've tested extensively using
TDS4/TDS5 captures I have.
I've not been able to test these changes for TDS7/TDS8 capture files.
since I don't have any TDS7/TDS8 capures. In theory the changes I've made should not affect
decodes of TDS7/TDS8
If anyone can supply a TDS7/TDS capture (or a pointer to one) I'd be glad to test against same.
Thanks
Bill Meier
Overview of changes
===================
1. Do first-level dissection of:
TDS4 ascii query, rpc and response packets;
TDS5 query packets.
2. Handle big-endian TDS5 (and TDS4 if such exists).
3. Add preferences to allow 'hints' as to the TDS version and
'big-endian/little-endian' in the capture being decoded.
4. Register MS_SQL default ports as TDS ports. This also
enables TDS as a choice in 'decode as'.
In addition: Add a preference to specify 'ranges'
of TCP ports to be recognized as TDS ports by the
TDS heuristics function.
Details
-------
1. Add Preferences:
a. To allow specification of a hint as to TDS protocol being decoded
(Unspecified/TDS4/TDS5/TDS7/TDS8); Default: 'unspecified'
The 'hint' is used only when needed to do a correct decode.
If the protocol is unspecified, the decode is as previous.
b. To allow specification of 'ranges' of TCP ports to be treated as
'TDS tcp ports'; i.e. if the source or destination port of a tcp
connection matches a specified range, then the connection should be
considered to be TDS.
c. To allow specification of a hint as to whether TDS being decoded is
'little-endian' or 'big-endian'. Default: 'little-endian'.
A hint is just that; E.G. if TDS7+ packets are encountered the decode
is always 'little-endian'/
2, Register tcp MS SQL default ports (1433, 2433) as TDS ports
('dissector_add'). This also enables TDS as a choice for 'decode as'.
3. 'netlib_check_login_pkt' changed to check 'TDS tcp port' range(s) as
entered in preferences;
4. Change 'dissect_tds_query_packet' to handle TDS4 ascii in addition to
TDS7/8 UCS-16.
5. Change 'dissect_tds_rpc' to:
a. handle TDS4 ascii RPC in addition to TDS7/8 UCS-16 RPC;
b. handle Microsoft 'encoded' rpc_name;
c. fix memory leak (not freeing memory obtained using
'tvb_fake_unicode');
6. Change 'dissect_tds_response' to:
a. handle tds4 tokens 'tds_col_name' and 'tds_col_info';
b. dissect tokens 'tds_doneinproc' and tds 'doneproc' similarly to
'tds_done'
c. reclaim memory allocated for 'tds_col' structures when finished
processing response
(Additional memory was being allocated each time a
tokenized tds5 response was processed)
7. New function 'dissect_tds_col_info_token' (similar to
'read_results_tds5') associated with handling TDS4 responses.
8. New functions 'dissect_tds_query5_packet', 'dissect_tds5_lang_token'
9. Rework TDS token size calculation; Some TDS tokens have a length field
of other than 2 bytes. (e.g.: the length field
for TDS_LANG_TOKEN is 4 bytes)
10. Update token definitions and usages;
a. Update based upon info from current version of FreeTDS 'tds.h'
as well as info from Sybase TDS5 document;
example: TDS_124_TOKEN renamed to TDS_PROCID_TOKEN
b. TDS_124_TOKEN [TDS_PROCID] was incorrectly not considered
a 'fixed-size' token in function 'tds_is_fixed_token'
183a184
> /* TODO Update from current version of FreeTDS tds.h */
185,187c186,189
< #define TDS5_DYN_TOKEN 231 /* 0xE7 TDS 5.0 only */
< #define TDS5_DYNRES_TOKEN 236 /* 0xEC TDS 5.0 only */
< #define TDS5_DYN3_TOKEN 215 /* 0xD7 TDS 5.0 only */
---
> #define TDS5_PARAMS_TOKEN 215 /* 0xD7 TDS 5.0 only */
> #define TDS5_DYNAMIC_TOKEN 231 /* 0xE7 TDS 5.0 only */
> #define TDS5_PARAMFMT_TOKEN 236 /* 0xEC TDS 5.0 only */
> #define TDS5_PARAMFMT2_TOKEN 32 /* 0x20 TDS 5.0 only */
189c191,195
< #define TDS_CLOSE_TOKEN 113 /* 0x71 TDS 5.0 only? ct_close() */
---
> #define TDS5_ORDERBY2_TOKEN 34 /* 0x22 TDS 5.0 only */
> #define TDS5_CURDECLARE2_TOKEN 35 /* 0x23 TDS 5.0 only */
> #define TDS5_ROWFMT2_TOKEN 97 /* 0x61 TDS 5.0 only */
> #define TDS5_MSG_TOKEN 101 /* 0x65 TDS 5.0 only */
> #define TDS_LOGOUT_TOKEN 113 /* 0x71 TDS 5.0 only? ct_close() */
191c197
< #define TDS_124_TOKEN 124 /* 0x7C TDS 4.2 only - TDS_PROCID */
---
> #define TDS_PROCID_TOKEN 124 /* 0x7C TDS 4.2 only - TDS_PROCID */
194a201
> #define TDS5_DYNAMIC2_TOKEN 163 /* 0xA3 TDS 5.0 only */
197,198c204,205
< #define TDS_167_TOKEN 167 /* 0xA7 */
< #define TDS_168_TOKEN 168 /* 0xA8 */
---
> #define TDS_COMPUTE_NAMES_TOKEN 167 /* 0xA7 */
> #define TDS_COMPUTE_RESULT_TOKEN 168 /* 0xA8 */
204c211,212
< #define TDS_174_TOKEN 174 /* 0xAE TDS_CONTROL */
---
> #define TDS_CONTROL_TOKEN 174 /* 0xAE TDS_CONTROL */
> #define TDS_KEY_TOKEN 202 /* 0xCA */
215a224,243
> /* Microsoft internal stored procedure id's */
>
> #define TDS_SP_CURSOR 1
> #define TDS_SP_CURSOROPEN 2
> #define TDS_SP_CURSORPREPARE 3
> #define TDS_SP_CURSOREXECUTE 4
> #define TDS_SP_CURSORPREPEXEC 5
> #define TDS_SP_CURSORUNPREPARE 6
> #define TDS_SP_CURSORFETCH 7
> #define TDS_SP_CURSOROPTION 8
> #define TDS_SP_CURSORCLOSE 9
> #define TDS_SP_EXECUTESQL 10
> #define TDS_SP_PREPARE 11
> #define TDS_SP_EXECUTE 12
> #define TDS_SP_PREPEXEC 13
> #define TDS_SP_PREPEXECRPC 14
> #define TDS_SP_UNPREPARE 15
>
> /* Sybase Data Types */
>
330a359,407
> /* TDS protocol type preference */
> /* XXX: This preference is used as a 'hint' for cases where interpretation is ambiguous */
> /* Currently the hint is global */
> /* TODO: Consider storing protocol type with each conversation */
> /* (when type is determined and using the preference as a default) ?? */
>
> #define TDS_PROTOCOL_NOT_SPECIFIED 0
> #define TDS_PROTOCOL_4 4
> #define TDS_PROTOCOL_5 5
> #define TDS_PROTOCOL_7 7
> #define TDS_PROTOCOL_8 8
>
> static gint tds_protocol_type = TDS_PROTOCOL_NOT_SPECIFIED;
>
> const enum_val_t tds_protocol_type_options[] = {
> {"not_specified", "Not Specified", TDS_PROTOCOL_NOT_SPECIFIED},
> {"tds4", "TDS 4", TDS_PROTOCOL_4}, /* TDS 4.2 and TDS 4.6 */
> {"tds5", "TDS 5", TDS_PROTOCOL_5},
> {"tds7", "TDS 7", TDS_PROTOCOL_7},
> {"tds8", "TDS 8", TDS_PROTOCOL_8},
> {NULL, NULL, -1}
> };
>
> #define TDS_PROTO_PREF_NOT_SPECIFIED (tds_protocol_type == TDS_NOT_SPECIFIED)
> #define TDS_PROTO_PREF_TDS4 (tds_protocol_type == TDS_PROTOCOL_4)
> #define TDS_PROTO_PREF_TDS5 (tds_protocol_type == TDS_PROTOCOL_5)
> #define TDS_PROTO_PREF_TDS7 (tds_protocol_type == TDS_PROTOCOL_7)
> #define TDS_PROTO_PREF_TDS8 (tds_protocol_type == TDS_PROTOCOL_8)
> #define TDS_PROTO_PREF_TDS7_TDS8 ( TDS_PROTO_PREF_TDS7 || TDS_PROTO_PREF_TDS8 )
>
> /* TDS "endian type" */
> /* XXX: Assumption is that all TDS conversations being decoded in a particular capture */
> /* have the same endian type */
> /* TODO: consider storing endian type with each conversation */
> /* (using pref as the default) */
>
> static gint tds_little_endian = TRUE;
>
> const enum_val_t tds_endian_type_options[] = {
> {"little_endian", "Little Endian", TRUE},
> {"big_endian" , "Big Endian" , FALSE},
> {NULL, NULL, -1}
> };
>
>
> /* TCP port preferences for TDS decode */
>
> static range_t *tds_tcp_ports = NULL;
>
366,368c443,446
< {TDS5_DYN_TOKEN, "Dynamic SQL"},
< {TDS5_DYNRES_TOKEN, "Dynamic Results"},
< {TDS5_DYN3_TOKEN, "Dynamic (Unknown)"},
---
> {TDS5_DYNAMIC_TOKEN, "TDS5 Dynamic SQL"},
> {TDS5_PARAMFMT_TOKEN, "TDS5 Parameter Format"},
> {TDS5_PARAMFMT2_TOKEN, "TDS5 Parameter2 Format"},
> {TDS5_PARAMS_TOKEN, "TDS5 Parameters"},
370c448
< {TDS_CLOSE_TOKEN, "Close Connection"},
---
> {TDS_LOGOUT_TOKEN, "Logout"},
372c450
< {TDS_124_TOKEN, "Proc ID"},
---
> {TDS_PROCID_TOKEN, "Proc ID"},
376,377c454,455
< {TDS_167_TOKEN, "Unknown (167)"},
< {TDS_168_TOKEN, "Unknown (168)"},
---
> {TDS_COMPUTE_NAMES_TOKEN, "Compute Names"},
> {TDS_COMPUTE_RESULT_TOKEN, "Compute Results"},
383c461,462
< {TDS_174_TOKEN, "Unknown (174)"},
---
> {TDS_CONTROL_TOKEN, "TDS Control"},
> {TDS_KEY_TOKEN, "TDS Key"},
393a473,477
> {TDS5_DYNAMIC2_TOKEN, "TDS5 Dynamic2"},
> {TDS5_ORDERBY2_TOKEN, "TDS5 OrderBy2"},
> {TDS5_CURDECLARE2_TOKEN, "TDS5 CurDeclare2"},
> {TDS5_ROWFMT2_TOKEN, "TDS5 RowFmt2"},
> {TDS5_MSG_TOKEN, "TDS5 Msg"},
396a481,500
>
> static const value_string internal_stored_proc_id_names[] = {
> {TDS_SP_CURSOR, "sp_cursor" },
> {TDS_SP_CURSOROPEN, "sp_cursoropen" },
> {TDS_SP_CURSORPREPARE, "sp_cursorprepare" },
> {TDS_SP_CURSOREXECUTE, "sp_cursorexecute" },
> {TDS_SP_CURSORPREPEXEC, "sp_cursorprepexec" },
> {TDS_SP_CURSORUNPREPARE, "sp_cursorunprepare"},
> {TDS_SP_CURSORFETCH, "sp_cursorfetch" },
> {TDS_SP_CURSOROPTION, "sp_cursoroption" },
> {TDS_SP_CURSORCLOSE, "sp_cursorclose" },
> {TDS_SP_EXECUTESQL, "sp_executesql" },
> {TDS_SP_PREPARE, "sp_prepare" },
> {TDS_SP_EXECUTE, "sp_execute" },
> {TDS_SP_PREPEXEC, "sp_prepexec" },
> {TDS_SP_PREPEXECRPC, "sp_prepexecrpc" },
> {TDS_SP_UNPREPARE, "sp_unprepare" },
> {0, NULL },
> };
>
404c508
< {7, "Collation Info"},
---
> {7, "Collation Info"},
457c561
< #define tds_column_init_count 10
---
> #define tds_column_init_count 40
461a566
>
471a577,654
> /* */
>
> static guint16
> tds_tvb_get_xxtohs(tvbuff_t *tvb, gint offset, gint tds_little_endian) {
> if (tds_little_endian)
> return tvb_get_letohs(tvb, offset);
> else
> return tvb_get_ntohs(tvb, offset);
> }
>
> static guint32
> tds_tvb_get_xxtohl(tvbuff_t *tvb, gint offset, gint tds_little_endian) {
> if (tds_little_endian)
> return tvb_get_letohl(tvb, offset);
> else
> return tvb_get_ntohl(tvb, offset);
> }
>
>
> static int tds_token_is_fixed_size(guint8 token)
> {
> switch (token) {
> case TDS_DONE_TOKEN:
> case TDS_DONEPROC_TOKEN:
> case TDS_DONEINPROC_TOKEN:
> case TDS_RET_STAT_TOKEN:
> case TDS7_RESULT_TOKEN:
> case TDS_PROCID_TOKEN:
> case TDS_LOGOUT_TOKEN:
> return 1;
> default:
> return 0;
> }
> }
>
>
> static int tds_get_fixed_token_size(guint8 token)
> {
> switch(token) {
> case TDS_DONE_TOKEN:
> case TDS_DONEPROC_TOKEN:
> case TDS_DONEINPROC_TOKEN:
> case TDS_PROCID_TOKEN:
> return 8;
> case TDS_RET_STAT_TOKEN:
> return 4;
> case TDS_LOGOUT_TOKEN:
> return 1;
> case TDS7_RESULT_TOKEN:
> default:
> return 0;
> }
> }
>
> static guint tds_get_variable_token_size(tvbuff_t *tvb, gint offset, guint8 token, guint *len_field_size_p)
> {
> switch(token) {
> /* some tokens have a 4 byte length field */
> case TDS5_PARAMFMT2_TOKEN:
> case TDS_LANG_TOKEN:
> case TDS5_ORDERBY2_TOKEN:
> case TDS5_CURDECLARE2_TOKEN:
> case TDS5_ROWFMT2_TOKEN:
> case TDS5_DYNAMIC2_TOKEN:
> *len_field_size_p = 4;
> return tds_tvb_get_xxtohl(tvb, offset, tds_little_endian) + 5;
> /* some have a 1 byte length field */
> case TDS5_MSG_TOKEN:
> *len_field_size_p = 1;
> return tvb_get_guint8(tvb, offset) +2;
> /* and most have a 2 byte length field */
> default:
> *len_field_size_p = 2;
> return tds_tvb_get_xxtohs(tvb, offset, tds_little_endian) + 3;
> }
> }
>
>
486c669,671
< if((len < 2) || tvb_get_guint8(tvb, offset+1) !=0)
---
>
> if( TDS_PROTO_PREF_TDS4 ||
> !TDS_PROTO_PREF_TDS7_TDS8 && ((len < 2) || tvb_get_guint8(tvb, offset+1) !=0) )
489c674
< if (is_unicode) {
---
> if (is_unicode)
491,494c676,755
< proto_tree_add_text(query_tree, tvb, offset, len, "Query: %s", msg);
< g_free(msg);
< offset += len;
< }
---
> else
> msg = tvb_get_string(tvb, offset, len);
>
> proto_tree_add_text(query_tree, tvb, offset, len, "Query: %s", msg);
> g_free(msg);
> offset += len;
> }
>
>
> static void
> dissect_tds5_lang_token(tvbuff_t *tvb, guint offset, guint len, proto_tree *tree) {
> gboolean is_unicode = FALSE;
> char *msg;
>
> proto_tree_add_text(tree, tvb, offset, 1 , "Status: %u", tvb_get_guint8(tvb, offset));
> offset += 1;
> len -= 1;
>
> if (is_unicode)
> msg = tvb_fake_unicode(tvb, offset, (len)/2, TRUE);
> else
> msg = tvb_get_string(tvb, offset, len);
>
> proto_tree_add_text(tree, tvb, offset, len, "Language text: %s", msg);
> g_free(msg);
> }
>
> static void
> dissect_tds_query5_packet(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
> {
> guint offset;
> guint pos;
> guint token_len_field_size = 2;
> guint8 token;
> guint token_sz;
> proto_item *query_hdr;
> proto_tree *query_tree;
> proto_item *token_item;
> proto_tree *token_tree;
>
> offset = 0;
> query_hdr = proto_tree_add_text(tree, tvb, offset, -1, "TDS5 Query Packet");
> query_tree = proto_item_add_subtree(query_hdr, ett_tds7_query);
>
> /*
> * Until we reach the end of the packet, read tokens.
> */
> pos = offset;
> while (tvb_reported_length_remaining(tvb, pos) > 0) {
>
> /* our token */
> token = tvb_get_guint8(tvb, pos);
> if (tds_token_is_fixed_size(token))
> token_sz = tds_get_fixed_token_size(token) + 1;
> else
> token_sz = tds_get_variable_token_size(tvb, pos+1, token, &token_len_field_size);
>
> token_item = proto_tree_add_text(tree, tvb, pos, token_sz,
> "Token 0x%02x %s", token,
> val_to_str(token, token_names, "Unknown Token Type"));
> token_tree = proto_item_add_subtree(token_item, ett_tds_token);
>
> /*
> * If it's a variable token, put the length field in here
> * instead of replicating this for each token subdissector.
> */
> if (!tds_token_is_fixed_size(token))
> proto_tree_add_text(token_tree, tvb, pos+1, token_len_field_size, "Length: %u", token_sz);
>
> switch (token) {
> case TDS_LANG_TOKEN:
> dissect_tds5_lang_token(tvb, pos + 5, token_sz -5, token_tree);
> break;
> default:
> break;
> }
>
> pos += token_sz;
>
> } /* while */
496a758
>
523c785,786
< proto_tree_add_uint(header_tree, hf_tds7_login_total_size, tvb, offset, sizeof(td7hdr.total_packet_size), td7hdr.total_packet_size);
---
> proto_tree_add_uint(header_tree, hf_tds7_login_total_size, tvb, offset,
> sizeof(td7hdr.total_packet_size), td7hdr.total_packet_size);
632,660d894
< static int tds_is_fixed_token(int token)
< {
< switch (token) {
< case TDS_DONE_TOKEN:
< case TDS_DONEPROC_TOKEN:
< case TDS_DONEINPROC_TOKEN:
< case TDS_RET_STAT_TOKEN:
< case TDS7_RESULT_TOKEN:
< return 1;
< default:
< return 0;
< }
< }
< static int tds_get_token_size(int token)
< {
< switch(token) {
< case TDS_DONE_TOKEN:
< case TDS_DONEPROC_TOKEN:
< case TDS_DONEINPROC_TOKEN:
< return 8;
< case TDS_RET_STAT_TOKEN:
< return 4;
< case TDS_124_TOKEN:
< return 8;
< default:
< return 0;
< }
< }
<
716a951,1003
> * Process TDS 4 "COL_INFO" token and store relevant information in the
> * _netlib_data structure for later use (see tds_get_row_size)
> *
> * XXX Can TDS 4 be "big-endian" ? we'll assume yes.
> *
> */
> static gboolean
> dissect_tds_col_info_token(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset)
> {
> guint next, cur;
> guint col;
>
> next = offset + tds_tvb_get_xxtohs(tvb, offset+1, tds_little_endian) + 3;
> cur = offset + 3;
>
> col = 0;
> while (cur < next) {
>
> if (col >= MAX_COLUMNS) {
> nl_data->num_cols = 0;
> return FALSE;
> }
>
> nl_data->columns[col] = g_mem_chunk_alloc(tds_column);
>
> nl_data->columns[col]->name[0] ='\0';
>
> nl_data->columns[col]->utype = tds_tvb_get_xxtohs(tvb, cur, tds_little_endian);
> cur += 2;
>
> cur += 2; /* unknown */
>
> nl_data->columns[col]->ctype = tvb_get_guint8(tvb,cur);
> cur++;
>
> if (!is_fixed_coltype(nl_data->columns[col]->ctype)) {
> nl_data->columns[col]->csize = tvb_get_guint8(tvb,cur);
> cur ++;
> } else {
> nl_data->columns[col]->csize =
> get_size_by_coltype(nl_data->columns[col]->ctype);
> }
>
> col += 1;
>
> } /* while */
>
> nl_data->num_cols = col;
> return TRUE;
> }
>
>
> /*
718a1006,1007
> *
> * TODO: check we don't go past end of the token
721c1010
< read_results_tds5(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset)
---
> read_results_tds5(tvbuff_t *tvb, struct _netlib_data *nl_data, guint offset, guint len)
723c1012
< guint len, name_len;
---
> guint name_len;
727,728c1016
< len = tvb_get_letohs(tvb, offset+1);
< cur = offset + 3;
---
> cur = offset;
732a1021
> * XXX: We'll take a hint
734c1023
< nl_data->num_cols = tvb_get_letohs(tvb, cur);
---
> nl_data->num_cols = tds_tvb_get_xxtohs(tvb, cur, tds_little_endian);
750c1039
< nl_data->columns[i]->utype = tvb_get_letohs(tvb, cur);
---
> nl_data->columns[i]->utype = tds_tvb_get_xxtohs(tvb, cur, tds_little_endian);
810,815d1098
< /* check if it is MS SQL default port */
< } else if ((pinfo->srcport != 1433 &&
< pinfo->destport != 1433) && (pinfo->srcport != 2433 && pinfo->destport != 2433)) {
< /* otherwise, we can not ensure this is netlib */
< /* beyond a reasonable doubt. */
< return FALSE;
816a1100,1108
> /*
> * See if either tcp.destport or tcp.srcport is specified
> * in the preferences as being a TDS port.
> */
> else if (!value_is_in_range(tds_tcp_ports, pinfo->srcport) &&
> !value_is_in_range(tds_tcp_ports, pinfo->destport)) {
> return FALSE;
> }
>
903c1195
< proto_tree_add_text(tree, tvb, offset, 4, "SQL Error Number: %d", tvb_get_letohl(tvb, offset));
---
> proto_tree_add_text(tree, tvb, offset, 4, "SQL Error Number: %d", tds_tvb_get_xxtohl(tvb, offset, tds_little_endian));
910c1202
< msg_len = tvb_get_letohs(tvb, offset);
---
> msg_len = tds_tvb_get_xxtohs(tvb, offset, tds_little_endian);
959c1251
< proto_tree_add_text(tree, tvb, offset, 2, "line number: %d", tvb_get_letohs(tvb, offset));
---
> proto_tree_add_text(tree, tvb, offset, 2, "line number: %d", tds_tvb_get_xxtohs(tvb, offset, tds_little_endian));
1083c1375
< proto_tree_add_text(tree, tvb, offset, 4, "row count: %u", tvb_get_letohl(tvb, offset));
---
> proto_tree_add_text(tree, tvb, offset, 4, "row count: %u", tds_tvb_get_xxtohl(tvb, offset, tds_little_endian));
1092c1384,1385
< const char *val;
---
> guint16 sp_id;
> char *val;
1096d1388
< * XXX - how can we determine whether this is ASCII or Unicode?
1098,1109c1390,1423
< len = tvb_get_letohs(tvb, offset);
< proto_tree_add_text(tree, tvb, offset, 2, "RPC Name Length: %u", len);
< offset += 2;
< if (len != 0) {
< val = tvb_fake_unicode(tvb, offset, len, TRUE);
< len *= 2;
< proto_tree_add_text(tree, tvb, offset, len, "RPC Name: %s",
< val);
< offset += len;
< }
<
< proto_tree_add_text(tree, tvb, offset, -1, "Unknown data");
---
> switch(tds_protocol_type) {
> case TDS_PROTOCOL_4:
> len = tvb_get_guint8(tvb, offset);
> proto_tree_add_text(tree, tvb, offset, 1, "RPC Name Length: %u", len);
> offset += 1;
> val = tvb_get_string(tvb, offset, len);
> proto_tree_add_text(tree, tvb, offset, len, "RPC Name: %s", val);
> g_free(val);
> offset += len;
> break;
>
> case TDS_PROTOCOL_7:
> case TDS_PROTOCOL_8:
> default: /* unspecified: try as if TDS7/TDS8 */
> len = tvb_get_letohs(tvb, offset);
> proto_tree_add_text(tree, tvb, offset, 2, "RPC Name Length: %u", len);
> offset += 2;
> if (len == 0xFFFF) {
> sp_id = tvb_get_letohs(tvb, offset);
> proto_tree_add_text(tree, tvb, offset, 2, "RPC Stored Proc ID: %u (%s)",
> sp_id,
> val_to_str(sp_id, internal_stored_proc_id_names, "Unknown"));
> offset += 2;
> }
> else if (len != 0) {
> val = tvb_fake_unicode(tvb, offset, len, TRUE);
> len *= 2;
> proto_tree_add_text(tree, tvb, offset, len, "RPC Name: %s", val);
> g_free(val);
> offset += len;
> }
> break;
> }
> proto_tree_add_text(tree, tvb, offset, -1, "Params (not dissected)");
1118a1433
> guint token_len_field_size = 2;
1123c1438,1440
< memset(&nl_data, '\0', sizeof nl_data);
---
> g_mem_chunk_reset(tds_column); /* in case exception thrown the previous time thru this code */
>
> memset(&nl_data, '\0', sizeof nl_data);
1133,1134c1450,1452
< if (tds_is_fixed_token(token)) {
< token_sz = tds_get_token_size(token) + 1;
---
> /* TODO Handle TDS_PARAMFMT, TDS_PARAMS [similar to TDS_RESULTS, TDS_ROW] */
> if (tds_token_is_fixed_size(token)) {
> token_sz = tds_get_fixed_token_size(token) + 1;
1142c1460
< token_sz = tvb_get_letohs(tvb, pos + 1) + 3;
---
> token_sz = tds_get_variable_token_size(tvb, pos+1, token, &token_len_field_size);
1145,1146d1462
< if (token_sz > (guint)length_remaining)
< token_sz = (guint)length_remaining;
1157,1159c1473,1474
< if (!tds_is_fixed_token(token) && token != TDS_ROW_TOKEN) {
< proto_tree_add_text(token_tree, tvb, pos+1, 2,
< "Length: %u", tvb_get_letohs(tvb, pos+1));
---
> if (!tds_token_is_fixed_size(token) && token != TDS_ROW_TOKEN) {
> proto_tree_add_text(token_tree, tvb, pos+1, token_len_field_size, "Length: %u", token_sz);
1162c1477,1494
< switch (token) {
---
> if (token_sz > (guint)length_remaining)
> token_sz = (guint)length_remaining;
>
> switch (token) {
>
> case TDS_COL_NAME_TOKEN:
> /*
> * TDS 4.2
> * TODO dissect token to get "column names" to fill in _netlib_data
> */
> break;
>
> case TDS_COL_INFO_TOKEN:
> /*
> * TDS 4.2: get the column info
> */
> dissect_tds_col_info_token(tvb, &nl_data, pos);
> break;
1164c1496
< case TDS_RESULT_TOKEN:
---
> case TDS_RESULT_TOKEN:
1169c1501
< read_results_tds5(tvb, &nl_data, pos);
---
> read_results_tds5(tvb, &nl_data, pos + 3, token_sz - 3);
1173,1174c1505
< dissect_tds_env_chg(tvb, pos + 3, token_sz - 3,
< token_tree);
---
> dissect_tds_env_chg(tvb, pos + 3, token_sz - 3, token_tree);
1178,1179c1509
< dissect_tds_ntlmssp(tvb, pinfo, token_tree, pos + 3,
< token_sz - 3);
---
> dissect_tds_ntlmssp(tvb, pinfo, token_tree, pos + 3, token_sz - 3);
1184a1515
>
1186c1517,1519
< dissect_tds_done_token(tvb, pos + 1, token_tree);
---
> case TDS_DONEPROC_TOKEN:
> case TDS_DONEINPROC_TOKEN:
> dissect_tds_done_token(tvb, pos + 1, token_tree);
1198a1532,1534
> /* reset tds_column mem_chunk since finished processing response */
> /* (pointers to atoms in nl_data being discarded) */
> g_mem_chunk_reset(tds_column);
1254a1591,1594
> *
> * TODO: handle case where netlib headers 'packet-number'.is always 0
> * use fragment_add_seq_next in this case ?
> *
1293c1633,1635
< if (next_tvb != NULL) {
---
>
> if (next_tvb != NULL) {
>
1310c1652,1655
< case TDS_NTLMAUTH_PKT:
---
> case TDS_QUERY5_PKT:
> dissect_tds_query5_packet(next_tvb, pinfo, tds_tree);
> break;
> case TDS_NTLMAUTH_PKT:
1492c1837
< /*
---
> /*
1738c2083,2084
< static gint *ett[] = {
---
>
> static gint *ett[] = {
1756,1757d2101
< tds_tcp_handle = create_dissector_handle(dissect_tds_tcp, proto_tds);
<
1767a2112,2125
> prefs_register_enum_preference(tds_module, "protocol_type",
> "TDS Protocol Type",
> "Hint as to version of TDS protocol being decoded",
> &tds_protocol_type,
> tds_protocol_type_options, FALSE);
> prefs_register_enum_preference(tds_module, "endian_type",
> "TDS decode as ",
> "Hint as to whether to decode TDS protocol as little-endian or big-endian. (TDS7/8 always decoded as little-endian)",
> &tds_little_endian,
> tds_endian_type_options, FALSE);
> prefs_register_range_preference(tds_module, "tcp_ports",
> "TDS TCP ports",
> "Additional TCP ports to decode as TDS",
> &tds_tcp_ports, 0xFFFF);
1779,1781c2137,2143
< /* dissector_add("tcp.port", 1433, dissect_tds,
< proto_tds); */
< heur_dissector_add("tcp", dissect_tds_tcp_heur, proto_tds);
---
> tds_tcp_handle = create_dissector_handle(dissect_tds_tcp, proto_tds);
>
> /* Initial TDS ports: MS SQL default ports */
> dissector_add("tcp.port", 1433, tds_tcp_handle);
> dissector_add("tcp.port", 2433, tds_tcp_handle);
>
> heur_dissector_add("tcp", dissect_tds_tcp_heur, proto_tds);
- Prev by Date: Re: [Ethereal-dev] How can I submit a modified file?
- Next by Date: Re: [Ethereal-dev] packet-dns.c patch - GSSAPI in TKEY can also be NTLMSSP data
- Previous by thread: Re: [Ethereal-dev] Patch to packet-dns.c (2) - fixes a display error
- Next by thread: [Ethereal-dev] netxray 'Timeunit' issues: help requested
- Index(es):





