Reassemble PLP chunks.
Display the data in a PLP chunk as just raw bytes, and reassembled all the chunks and extract the value from the reassembled data. Showing the chunks as strings doesn't necessarily work - if the string is an NVarChar string, a chunk might well have an odd number of octets, meaning you're splitting one of the 16-bit UTF-16LE items in half. Reassembling handles that, as well as just, in general, showing the actual value rather than pieces of the value. If the column is a string, append its value to the top-level item, just as we do for non-PLP strings. Also, if a length value was specified, report an error if it doesn't match the total length of the reassembled chunks. Change-Id: Iab80da052eb363ee08cd518afbe2556a5ab740b9 Reviewed-on: https://code.wireshark.org/review/33466 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
7cb77f5ca7
commit
7b12f11721
|
@ -1215,6 +1215,7 @@ static int hf_tds_type_varbyte_data_textptr = -1;
|
|||
static int hf_tds_type_varbyte_data_text_ts = -1;
|
||||
static int hf_tds_type_varbyte_plp_len = -1;
|
||||
static int hf_tds_type_varbyte_plp_chunk_len = -1;
|
||||
static int hf_tds_type_varbyte_plp_chunk = -1;
|
||||
static int hf_tds_type_varbyte_column_name = -1;
|
||||
|
||||
/****************************** Top level TDS ******************************/
|
||||
|
@ -1287,6 +1288,7 @@ static gint ett_tds5_curinfo_status = -1;
|
|||
/* static expert_field ei_tds_type_info_type_undecoded = EI_INIT; */
|
||||
static expert_field ei_tds_invalid_length = EI_INIT;
|
||||
static expert_field ei_tds_token_length_invalid = EI_INIT;
|
||||
static expert_field ei_tds_invalid_plp_length = EI_INIT;
|
||||
static expert_field ei_tds_type_info_type = EI_INIT;
|
||||
static expert_field ei_tds_all_headers_header_type = EI_INIT;
|
||||
/* static expert_field ei_tds_token_stats = EI_INIT; */
|
||||
|
@ -2103,40 +2105,117 @@ dissect_tds_type_varbyte(tvbuff_t *tvb, guint *offset, packet_info *pinfo, proto
|
|||
if(plp_length == TDS_PLP_NULL)
|
||||
proto_item_append_text(length_item, " (PLP_NULL)");
|
||||
else {
|
||||
if(plp_length == TDS_UNKNOWN_PLP_LEN)
|
||||
tvbuff_t *combined_chunks_tvb;
|
||||
guint combined_length;
|
||||
|
||||
if(plp_length == TDS_UNKNOWN_PLP_LEN) {
|
||||
proto_item_append_text(length_item, " (UNKNOWN_PLP_LEN)");
|
||||
}
|
||||
/*
|
||||
* XXX - composite tvbuffs with no compontents aren't supported,
|
||||
* so we create the tvbuff when the first non-terminator chunk
|
||||
* is found.
|
||||
*/
|
||||
combined_chunks_tvb = NULL;
|
||||
while(TRUE) {
|
||||
/*
|
||||
* XXX - this needs to reassemble the chunks, making sure
|
||||
* the total length of all the chunks isn't greater than
|
||||
* the item length. The result of the reassembly is the data
|
||||
* to dissect.
|
||||
*/
|
||||
length_item = proto_tree_add_item_ret_uint(sub_tree, hf_tds_type_varbyte_plp_chunk_len, tvb, *offset, 4, ENC_LITTLE_ENDIAN, &length);
|
||||
*offset += 4;
|
||||
if(length == TDS_PLP_TERMINATOR) {
|
||||
proto_item_append_text(length_item, " (PLP_TERMINATOR)");
|
||||
break;
|
||||
}
|
||||
|
||||
proto_tree_add_item(sub_tree, hf_tds_type_varbyte_plp_chunk, tvb, *offset, length, ENC_NA);
|
||||
if (combined_chunks_tvb == NULL)
|
||||
combined_chunks_tvb = tvb_new_composite();
|
||||
/* Add this chunk to the composite tvbuff */
|
||||
tvbuff_t *chunk_tvb = tvb_new_subset_length(tvb, *offset, length);
|
||||
tvb_composite_append(combined_chunks_tvb, chunk_tvb);
|
||||
*offset += length;
|
||||
}
|
||||
if (combined_chunks_tvb != NULL) {
|
||||
tvb_composite_finalize(combined_chunks_tvb);
|
||||
|
||||
/*
|
||||
* If a length was specified, report an error if it's not
|
||||
* the same as the reassembled length.
|
||||
*/
|
||||
combined_length = tvb_reported_length(combined_chunks_tvb);
|
||||
if(plp_length != TDS_UNKNOWN_PLP_LEN) {
|
||||
if(plp_length != combined_length) {
|
||||
expert_add_info(pinfo, length_item, &ei_tds_invalid_plp_length);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now dissect the reassembled data.
|
||||
*
|
||||
* XXX - can we make this item cover multiple ranges?
|
||||
* If so, do so.
|
||||
*/
|
||||
const guint8 *strval = NULL;
|
||||
switch(data_type) {
|
||||
case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
|
||||
proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
|
||||
proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, combined_chunks_tvb, 0, combined_length, ENC_NA);
|
||||
break;
|
||||
case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
|
||||
proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_ASCII|ENC_NA);
|
||||
proto_tree_add_item_ret_string(sub_tree,
|
||||
hf_tds_type_varbyte_data_string,
|
||||
combined_chunks_tvb, 0, combined_length, ENC_ASCII|ENC_NA,
|
||||
wmem_packet_scope(), &strval);
|
||||
if (strval) {
|
||||
proto_item_append_text(item, " (%s)", strval);
|
||||
}
|
||||
break;
|
||||
case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
|
||||
proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_string, tvb, *offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item_ret_string(sub_tree,
|
||||
hf_tds_type_varbyte_data_string,
|
||||
combined_chunks_tvb, 0, combined_length, ENC_UTF_16|ENC_LITTLE_ENDIAN,
|
||||
wmem_packet_scope(), &strval);
|
||||
if (strval) {
|
||||
proto_item_append_text(item, " (%s)", strval);
|
||||
}
|
||||
break;
|
||||
case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
|
||||
case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
|
||||
proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, tvb, *offset, length, ENC_NA);
|
||||
proto_tree_add_item(sub_tree, hf_tds_type_varbyte_data_bytes, combined_chunks_tvb, 0, combined_length, ENC_NA);
|
||||
break;
|
||||
default:
|
||||
/* no other data type sets plp = TRUE */
|
||||
expert_add_info_format(pinfo, length_item, &ei_tds_invalid_plp_type, "This type should not use PLP");
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If a length was specified, report an error if it's not
|
||||
* zero.
|
||||
*/
|
||||
if(plp_length != TDS_UNKNOWN_PLP_LEN) {
|
||||
if(plp_length != 0) {
|
||||
expert_add_info(pinfo, length_item, &ei_tds_invalid_plp_length);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The data is empty.
|
||||
*/
|
||||
switch(data_type) {
|
||||
case TDS_DATA_TYPE_BIGVARBIN: /* VarBinary */
|
||||
proto_tree_add_bytes(sub_tree, hf_tds_type_varbyte_data_bytes, NULL, 0, 0, NULL);
|
||||
break;
|
||||
case TDS_DATA_TYPE_BIGVARCHR: /* VarChar */
|
||||
proto_tree_add_string(sub_tree, hf_tds_type_varbyte_data_string, NULL, 0, 0, "");
|
||||
break;
|
||||
case TDS_DATA_TYPE_NVARCHAR: /* NVarChar */
|
||||
proto_tree_add_string(sub_tree, hf_tds_type_varbyte_data_string, NULL, 0, 0, "");
|
||||
break;
|
||||
case TDS_DATA_TYPE_XML: /* XML (introduced in TDS 7.2) */
|
||||
case TDS_DATA_TYPE_UDT: /* CLR-UDT (introduced in TDS 7.2) */
|
||||
proto_tree_add_bytes(sub_tree, hf_tds_type_varbyte_data_bytes, NULL, 0, 0, NULL);
|
||||
break;
|
||||
default:
|
||||
/* no other data type sets plp = TRUE */
|
||||
expert_add_info_format(pinfo, length_item, &ei_tds_invalid_plp_type, "This type should not use PLP");
|
||||
}
|
||||
*offset += length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9935,6 +10014,11 @@ proto_register_tds(void)
|
|||
FT_UINT32, BASE_DEC, NULL, 0x0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
{ &hf_tds_type_varbyte_plp_chunk,
|
||||
{ "PLP chunk", "tds.type_varbyte.plp_chunk",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
{ &hf_tds_type_varbyte_column_name,
|
||||
{ "Column name", "tds.type_varbyte.column.name",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0,
|
||||
|
@ -10129,6 +10213,7 @@ proto_register_tds(void)
|
|||
#endif
|
||||
{ &ei_tds_invalid_length, { "tds.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
|
||||
{ &ei_tds_token_length_invalid, { "tds.token.length.invalid", PI_PROTOCOL, PI_WARN, "Bogus token size", EXPFILL }},
|
||||
{ &ei_tds_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 }},
|
||||
#if 0
|
||||
{ &ei_tds_token_stats, { "tds.token.stats", PI_PROTOCOL, PI_NOTE, "Token stats", EXPFILL }},
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue