2 * Routines for Apache Cassandra CQL dissection
3 * Copyright 2015, Aaron Ten Clay <aarontc@aarontc.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * CQL V3 reference: https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v3.spec
14 * CQL V4 reference: https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v4.spec
17 #include <epan/conversation.h>
18 #include <epan/packet.h>
19 #include "packet-tcp.h"
20 #include <epan/wmem_scopes.h>
21 #include <epan/expert.h>
22 #include <epan/to_str.h>
23 #include <epan/addr_resolv.h>
31 #define CQL_DEFAULT_PORT 9042 /* Not IANA registered */
33 /* the code can reasonably attempt to decompress buffer up to 10MB */
34 #define MAX_UNCOMPRESSED_SIZE (10 * 1024 * 1024)
36 void proto_reg_handoff_cql(void);
37 void proto_register_cql(void);
40 /* CQL header frame fields */
41 static int hf_cql_version
;
42 static int hf_cql_protocol_version
;
43 static int hf_cql_direction
;
44 /* CQL header frame fields */
45 static int hf_cql_flags_bitmap
;
46 static int hf_cql_flag_compression
;
47 static int hf_cql_flag_tracing
;
48 static int hf_cql_flag_reserved3
;
49 static int hf_cql_flag_custom_payload
;
50 static int hf_cql_flag_warning
;
51 static int hf_cql_flag_reserved4
;
52 static int hf_cql_stream
;
53 static int hf_cql_opcode
;
54 static int hf_cql_length
;
57 static int hf_cql_int;
58 static int hf_cql_long;
59 static int hf_cql_uuid;
60 static int hf_cql_bytes;
61 static int hf_cql_inet;
65 static int hf_cql_batch_flag_serial_consistency
;
66 static int hf_cql_batch_flag_default_timestamp
;
67 static int hf_cql_batch_flag_with_name_for_values
;
68 static int hf_cql_batch_flags_bitmap
;
69 static int ett_cql_batch_flags_bitmap
;
71 static int hf_cql_consistency
;
72 static int hf_cql_string_length
;
73 static int hf_cql_string_map_size
;
74 static int hf_cql_string
;
75 static int hf_cql_auth_token
;
76 static int hf_cql_value_count
;
77 static int hf_cql_short_bytes_length
;
78 static int hf_cql_bytes_length
;
79 static int hf_cql_bytes
;
80 static int hf_cql_bigint
;
81 static int hf_cql_scale
;
82 static int hf_cql_boolean
;
83 static int hf_cql_ascii
;
84 static int hf_cql_double
;
85 static int hf_cql_float
;
86 static int hf_cql_custom
;
87 static int hf_cql_null_value
;
88 static int hf_cql_int
;
89 static int hf_cql_uuid
;
90 static int hf_cql_tracing_uuid
;
91 static int hf_cql_port
;
92 static int hf_cql_timeuuid
;
93 static int hf_cql_varchar
;
94 static int hf_cql_varint_count8
;
95 static int hf_cql_varint_count16
;
96 static int hf_cql_varint_count32
;
97 static int hf_cql_varint_count64
;
98 static int hf_cql_raw_compressed_bytes
;
99 static int hf_cql_paging_state
;
100 static int hf_cql_page_size
;
101 static int hf_cql_timestamp
;
102 static int hf_cql_query_id
;
103 static int hf_cql_event_type
;
104 static int hf_cql_event_schema_change_type
;
105 static int hf_cql_event_schema_change_type_target
;
106 static int hf_cql_event_schema_change_keyspace
;
107 static int hf_cql_event_schema_change_object
;
108 static int hf_cql_result_timestamp
;
109 static int hf_cql_string_list_size
;
110 static int hf_cql_batch_type
;
111 static int hf_cql_batch_query_type
;
112 static int hf_cql_batch_query_size
;
113 static int hf_cql_error_code
;
114 static int hf_cql_result_kind
;
115 static int hf_cql_result_rows_data_type
;
117 static int hf_cql_query_flags_bitmap
;
118 static int hf_cql_query_flags_values
;
119 static int hf_cql_query_flags_skip_metadata
;
120 static int hf_cql_query_flags_page_size
;
121 static int hf_cql_query_flags_paging_state
;
122 static int hf_cql_query_flags_serial_consistency
;
123 static int hf_cql_query_flags_default_timestamp
;
124 static int hf_cql_query_flags_names_for_values
;
125 static int hf_cql_query_flags_reserved3
;
127 static int hf_cql_result_rows_flags_values
;
128 static int hf_cql_result_prepared_flags_values
;
129 static int hf_cql_result_rows_flag_global_tables_spec
;
130 static int hf_cql_result_rows_flag_has_more_pages
;
131 static int hf_cql_result_rows_flag_no_metadata
;
132 static int hf_cql_result_rows_column_count
;
133 static int hf_cql_result_rows_tuple_size
;
135 static int hf_cql_result_prepared_pk_count
;
137 static int hf_cql_string_result_rows_global_table_spec_ksname
;
138 static int hf_cql_string_result_rows_global_table_spec_table_name
;
139 static int hf_cql_string_result_rows_table_name
;
140 static int hf_cql_string_result_rows_keyspace_name
;
141 static int hf_cql_string_result_rows_column_name
;
142 static int hf_cql_result_rows_row_count
;
143 static int hf_cql_string_result_rows_udt_name
;
144 static int hf_cql_string_result_rows_udt_size
;
145 static int hf_cql_string_result_rows_udt_field_name
;
146 static int hf_cql_string_result_rows_list_size
;
147 static int hf_cql_string_result_rows_map_size
;
148 static int hf_cql_string_result_rows_set_size
;
149 static int hf_cql_bytesmap_string
;
151 static int ett_cql_protocol
;
152 static int ett_cql_version
;
153 static int ett_cql_message
;
154 static int ett_cql_result_columns
;
155 static int ett_cql_results_no_metadata
;
156 static int ett_cql_result_map
;
157 static int ett_cql_result_set
;
158 static int ett_cql_result_metadata
;
159 static int ett_cql_result_rows
;
160 static int ett_cql_result_metadata_colspec
;
161 static int ett_cql_header_flags_bitmap
;
162 static int ett_cql_query_flags_bitmap
;
163 static int ett_cql_custom_payload
;
165 static int hf_cql_response_in
;
166 static int hf_cql_response_to
;
167 static int hf_cql_response_time
;
169 static int hf_cql_ipv4
;
170 static int hf_cql_ipv6
;
172 /* desegmentation of CQL */
173 static bool cql_desegment
= true;
175 static expert_field ei_cql_data_not_dissected_yet
;
176 static expert_field ei_cql_unexpected_negative_value
;
179 typedef struct _cql_transaction_type
{
183 } cql_transaction_type
;
185 typedef struct _cql_conversation_info_type
{
187 } cql_conversation_type
;
189 static const value_string cql_direction_names
[] = {
196 CQL_BATCH_FLAG_SERIAL_CONSISTENCY
= 0x10,
197 CQL_BATCH_FLAG_DEFAULT_TIMESTAMP
= 0x20,
198 CQL_BATCH_FLAG_WITH_NAME_FOR_VALUES
= 0x40
202 CQL_OPCODE_ERROR
= 0x00,
203 CQL_OPCODE_STARTUP
= 0x01,
204 CQL_OPCODE_READY
= 0x02,
205 CQL_OPCODE_AUTHENTICATE
= 0x03,
206 /* Opcode 0x04 not used in CQL */
207 CQL_OPCODE_OPTIONS
= 0x05,
208 CQL_OPCODE_SUPPORTED
= 0x06,
209 CQL_OPCODE_QUERY
= 0x07,
210 CQL_OPCODE_RESULT
= 0x08,
211 CQL_OPCODE_PREPARE
= 0x09,
212 CQL_OPCODE_EXECUTE
= 0x0A,
213 CQL_OPCODE_REGISTER
= 0x0B,
214 CQL_OPCODE_EVENT
= 0x0C,
215 CQL_OPCODE_BATCH
= 0x0D,
216 CQL_OPCODE_AUTH_CHALLENGE
= 0x0E,
217 CQL_OPCODE_AUTH_RESPONSE
= 0x0F,
218 CQL_OPCODE_AUTH_SUCCESS
= 0x10
221 static const value_string cql_opcode_names
[] = {
222 { CQL_OPCODE_ERROR
, "ERROR" },
223 { CQL_OPCODE_STARTUP
, "STARTUP" },
224 { CQL_OPCODE_READY
, "READY" },
225 { CQL_OPCODE_AUTHENTICATE
, "AUTHENTICATE" },
226 { CQL_OPCODE_OPTIONS
, "OPTIONS" },
227 { CQL_OPCODE_SUPPORTED
, "SUPPORTED" },
228 { CQL_OPCODE_QUERY
, "QUERY" },
229 { CQL_OPCODE_RESULT
, "RESULT" },
230 { CQL_OPCODE_PREPARE
, "PREPARE" },
231 { CQL_OPCODE_EXECUTE
, "EXECUTE" },
232 { CQL_OPCODE_REGISTER
, "REGISTER" },
233 { CQL_OPCODE_EVENT
, "EVENT" },
234 { CQL_OPCODE_BATCH
, "BATCH" },
235 { CQL_OPCODE_AUTH_CHALLENGE
, "AUTH_CHALLENGE" },
236 { CQL_OPCODE_AUTH_RESPONSE
, "AUTH_RESPONSE" },
237 { CQL_OPCODE_AUTH_SUCCESS
, "AUTH_SUCCESS" },
243 CQL_HEADER_FLAG_COMPRESSION
= 0x01,
244 CQL_HEADER_FLAG_TRACING
= 0x02,
245 CQL_HEADER_FLAG_V3_RESERVED
= 0xFC,
246 CQL_HEADER_FLAG_CUSTOM_PAYLOAD
= 0x04,
247 CQL_HEADER_FLAG_WARNING
= 0x08,
248 CQL_HEADER_FLAG_V4_RESERVED
= 0xF0
252 CQL_QUERY_FLAG_VALUES
= 0x01,
253 CQL_QUERY_FLAG_SKIP_METADATA
= 0x02,
254 CQL_QUERY_FLAG_PAGE_SIZE
= 0x04,
255 CQL_QUERY_FLAG_PAGING_STATE
= 0x08,
256 CQL_QUERY_FLAG_SERIAL_CONSISTENCY
= 0x10,
257 CQL_QUERY_FLAG_DEFAULT_TIMESTAMP
= 0x20,
258 CQL_QUERY_FLAG_VALUE_NAMES
= 0x40,
259 CQL_QUERY_FLAG_V3_RESERVED
= 0x80
264 CQL_RESULT_ROWS_FLAG_GLOBAL_TABLES_SPEC
= 0x00000001,
265 CQL_RESULT_ROWS_FLAG_HAS_MORE_PAGES
= 0x00000002,
266 CQL_RESULT_ROWS_FLAG_NO_METADATA
= 0x00000004
267 } cql_result_rows_flags
;
270 CQL_CONSISTENCY_ANY
= 0x0000,
271 CQL_CONSISTENCY_ONE
= 0x0001,
272 CQL_CONSISTENCY_TWO
= 0x0002,
273 CQL_CONSISTENCY_THREE
= 0x003,
274 CQL_CONSISTENCY_QUORUM
= 0x0004,
275 CQL_CONSISTENCY_ALL
= 0x0005,
276 CQL_CONSISTENCY_LOCAL_QUORUM
= 0x0006,
277 CQL_CONSISTENCY_EACH_QUORUM
= 0x0007,
278 CQL_CONSISTENCY_SERIAL
= 0x0008,
279 CQL_CONSISTENCY_LOCAL_SERIAL
= 0x0009,
280 CQL_CONSISTENCY_LOCAL_ONE
= 0x000A
283 static const value_string cql_consistency_names
[] = {
284 { CQL_CONSISTENCY_ANY
, "ANY" },
285 { CQL_CONSISTENCY_ONE
, "ONE" },
286 { CQL_CONSISTENCY_TWO
, "TWO" },
287 { CQL_CONSISTENCY_THREE
, "THREE" },
288 { CQL_CONSISTENCY_QUORUM
, "QUORUM" },
289 { CQL_CONSISTENCY_ALL
, "ALL" },
290 { CQL_CONSISTENCY_LOCAL_QUORUM
, "LOCAL_QUORUM" },
291 { CQL_CONSISTENCY_EACH_QUORUM
, "EACH_QUORUM" },
292 { CQL_CONSISTENCY_SERIAL
, "SERIAL" },
293 { CQL_CONSISTENCY_LOCAL_SERIAL
, "LOCAL_SERIAL" },
294 { CQL_CONSISTENCY_LOCAL_ONE
, "LOCAL_ONE" },
300 CQL_BATCH_TYPE_LOGGED
= 0,
301 CQL_BATCH_TYPE_UNLOGGED
= 1,
302 CQL_BATCH_TYPE_COUNTER
= 2
305 static const value_string cql_batch_type_names
[] = {
306 { CQL_BATCH_TYPE_LOGGED
, "LOGGED" },
307 { CQL_BATCH_TYPE_UNLOGGED
, "UNLOGGED" },
308 { CQL_BATCH_TYPE_COUNTER
, "COUNTER" },
313 CQL_BATCH_QUERY_TYPE_QUERY
= 0,
314 CQL_BATCH_QUERY_TYPE_PREPARED
= 1
315 } cql_batch_query_types
;
317 static const value_string cql_batch_query_type_names
[] = {
318 { CQL_BATCH_QUERY_TYPE_QUERY
, "QUERY" },
319 { CQL_BATCH_QUERY_TYPE_PREPARED
, "PREPARED" },
324 CQL_RESULT_KIND_VOID
= 0x0001,
325 CQL_RESULT_KIND_ROWS
= 0x0002,
326 CQL_RESULT_KIND_SET_KEYSPACE
= 0x0003,
327 CQL_RESULT_KIND_PREPARED
= 0x0004,
328 CQL_RESULT_KIND_SCHEMA_CHANGE
= 0x0005
331 static const value_string cql_result_kind_names
[] = {
332 { CQL_RESULT_KIND_VOID
, "VOID" },
333 { CQL_RESULT_KIND_ROWS
, "Rows" },
334 { CQL_RESULT_KIND_SET_KEYSPACE
, "Set Keyspace" },
335 { CQL_RESULT_KIND_PREPARED
, "Prepared" },
336 { CQL_RESULT_KIND_SCHEMA_CHANGE
, "Schema Change" },
343 CQL_RESULT_ROW_TYPE_CUSTOM
= 0x0000,
344 CQL_RESULT_ROW_TYPE_ASCII
= 0x0001,
345 CQL_RESULT_ROW_TYPE_BIGINT
= 0x0002,
346 CQL_RESULT_ROW_TYPE_BLOB
= 0x0003,
347 CQL_RESULT_ROW_TYPE_BOOLEAN
= 0x0004,
348 CQL_RESULT_ROW_TYPE_COUNTER
= 0x0005,
349 CQL_RESULT_ROW_TYPE_DECIMAL
= 0x0006,
350 CQL_RESULT_ROW_TYPE_DOUBLE
= 0x0007,
351 CQL_RESULT_ROW_TYPE_FLOAT
= 0x0008,
352 CQL_RESULT_ROW_TYPE_INT
= 0x0009,
353 CQL_RESULT_ROW_TYPE_TIMESTAMP
= 0x000B,
354 CQL_RESULT_ROW_TYPE_UUID
= 0x000C,
355 CQL_RESULT_ROW_TYPE_VARCHAR
= 0x000D,
356 CQL_RESULT_ROW_TYPE_VARINT
= 0x000E,
357 CQL_RESULT_ROW_TYPE_TIMEUUID
= 0x000F,
358 CQL_RESULT_ROW_TYPE_INET
= 0x0010,
359 CQL_RESULT_ROW_TYPE_DATE
= 0x0011,
360 CQL_RESULT_ROW_TYPE_TIME
= 0x0012,
361 CQL_RESULT_ROW_TYPE_SMALLINT
= 0x0013,
362 CQL_RESULT_ROW_TYPE_TINYINT
= 0x0014,
363 CQL_RESULT_ROW_TYPE_LIST
= 0x0020,
364 CQL_RESULT_ROW_TYPE_MAP
= 0x0021,
365 CQL_RESULT_ROW_TYPE_SET
= 0x0022,
366 CQL_RESULT_ROW_TYPE_UDT
= 0x0030,
367 CQL_RESULT_ROW_TYPE_TUPLE
= 0x0031
368 } cql_result_row_data_types
;
370 static const value_string cql_result_row_type_names
[] = {
371 { CQL_RESULT_ROW_TYPE_CUSTOM
, "CUSTOM" },
372 { CQL_RESULT_ROW_TYPE_ASCII
, "ASCII" },
373 { CQL_RESULT_ROW_TYPE_BIGINT
, "BIGINT" },
374 { CQL_RESULT_ROW_TYPE_BLOB
, "BLOB" },
375 { CQL_RESULT_ROW_TYPE_BOOLEAN
, "BOOLEAN" },
376 { CQL_RESULT_ROW_TYPE_COUNTER
, "COUNTER" },
377 { CQL_RESULT_ROW_TYPE_DECIMAL
, "DECIMAL" },
378 { CQL_RESULT_ROW_TYPE_DOUBLE
, "DOUBLE" },
379 { CQL_RESULT_ROW_TYPE_FLOAT
, "FLOAT" },
380 { CQL_RESULT_ROW_TYPE_INT
, "INT" },
381 { CQL_RESULT_ROW_TYPE_TIMESTAMP
, "TIMESTAMP" },
382 { CQL_RESULT_ROW_TYPE_UUID
, "UUID" },
383 { CQL_RESULT_ROW_TYPE_VARCHAR
, "VARCHAR" },
384 { CQL_RESULT_ROW_TYPE_VARINT
, "VARINT" },
385 { CQL_RESULT_ROW_TYPE_TIMEUUID
, "TIMEUUID" },
386 { CQL_RESULT_ROW_TYPE_INET
, "INET" },
387 { CQL_RESULT_ROW_TYPE_DATE
, "DATE" },
388 { CQL_RESULT_ROW_TYPE_TIME
, "TIME" },
389 { CQL_RESULT_ROW_TYPE_SMALLINT
, "SMALLINT" },
390 { CQL_RESULT_ROW_TYPE_TINYINT
, "TINYINT" },
391 { CQL_RESULT_ROW_TYPE_LIST
, "LIST" },
392 { CQL_RESULT_ROW_TYPE_MAP
, "MAP" },
393 { CQL_RESULT_ROW_TYPE_SET
, "SET" },
394 { CQL_RESULT_ROW_TYPE_UDT
, "UDT" },
395 { CQL_RESULT_ROW_TYPE_TUPLE
, "TUPLE" },
399 /* From https://github.com/apache/cassandra/blob/cbf4dcb3345c7e2f42f6a897c66b6460b7acc2ca/doc/native_protocol_v4.spec#L1046 */
401 CQL_ERROR_SERVER
= 0x0000,
402 CQL_ERROR_PROTOCOL
= 0x000A,
403 CQL_ERROR_AUTH
= 0x0100,
404 CQL_ERROR_UNAVAILABLE
= 0x1000,
405 CQL_ERROR_OVERLOADED
= 0x1001,
406 CQL_ERROR_BOOTSTRAPPING
= 0x1002,
407 CQL_ERROR_TRUNCATE
= 0x1003,
408 CQL_ERROR_WRITE_TIMEOUT
= 0x1100,
409 CQL_ERROR_READ_TIMEOUT
= 0x1200,
410 CQL_ERROR_READ_FAILURE
= 0x1300,
411 CQL_ERROR_FUNCTION_FAILURE
= 0x1400,
412 CQL_ERROR_WRITE_FAILURE
= 0x1500,
413 CQL_ERROR_SYNTAX
= 0x2000,
414 CQL_ERROR_UNAUTHORIEZED
= 0x2100,
415 CQL_ERROR_INVALID
= 0x2200,
416 CQL_ERROR_CONFIG
= 0x2300,
417 CQL_ERROR_ALREADY_EXISTS
= 0x2400,
418 CQL_ERROR_UNPREPARED
= 0x2500
421 static const value_string cql_error_names
[] = {
422 { CQL_ERROR_SERVER
, "Server error" },
423 { CQL_ERROR_PROTOCOL
, "Protocol error" },
424 { CQL_ERROR_AUTH
, "Authentication error" },
425 { CQL_ERROR_UNAVAILABLE
, "Unavailable exception" },
426 { CQL_ERROR_OVERLOADED
, "Overloaded" },
427 { CQL_ERROR_BOOTSTRAPPING
, "Is_bootstrapping" },
428 { CQL_ERROR_TRUNCATE
, "Truncate_error" },
429 { CQL_ERROR_WRITE_TIMEOUT
, "Write_timeout" },
430 { CQL_ERROR_READ_TIMEOUT
, "Read_timeout" },
431 { CQL_ERROR_READ_FAILURE
, "Read_failure" },
432 { CQL_ERROR_FUNCTION_FAILURE
, "Function_failure" },
433 { CQL_ERROR_WRITE_FAILURE
, "Write_failure" },
434 { CQL_ERROR_SYNTAX
, "Syntax_error" },
435 { CQL_ERROR_UNAUTHORIEZED
, "Unauthorized" },
436 { CQL_ERROR_INVALID
, "Invalid" },
437 {CQL_ERROR_CONFIG
, "Config_error" },
438 { CQL_ERROR_ALREADY_EXISTS
, "Already_exists" },
439 { CQL_ERROR_UNPREPARED
, "Unprepared" },
444 dissect_cql_query_parameters(proto_tree
* cql_subtree
, tvbuff_t
* tvb
, int offset
, int execute
)
446 int32_t bytes_length
= 0;
449 uint32_t string_length
= 0;
450 uint32_t value_count
= 0;
452 static int * const cql_query_bitmaps
[] = {
453 &hf_cql_query_flags_values
,
454 &hf_cql_query_flags_skip_metadata
,
455 &hf_cql_query_flags_page_size
,
456 &hf_cql_query_flags_paging_state
,
457 &hf_cql_query_flags_serial_consistency
,
458 &hf_cql_query_flags_default_timestamp
,
459 &hf_cql_query_flags_names_for_values
,
460 &hf_cql_query_flags_reserved3
,
465 proto_tree_add_item(cql_subtree
, hf_cql_consistency
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
469 proto_tree_add_bitmask(cql_subtree
, tvb
, offset
, hf_cql_query_flags_bitmap
, ett_cql_query_flags_bitmap
, cql_query_bitmaps
, ENC_BIG_ENDIAN
);
470 flags
= tvb_get_uint8(tvb
, offset
);
473 if(flags
& CQL_QUERY_FLAG_VALUES
) {
474 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_value_count
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &value_count
);
476 for (i
= 0; i
< value_count
; ++i
) {
477 if (!execute
&& flags
& CQL_QUERY_FLAG_VALUE_NAMES
) {
478 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
480 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
481 offset
+= string_length
;
483 proto_tree_add_item_ret_int(cql_subtree
, hf_cql_bytes_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &bytes_length
);
485 if (bytes_length
> 0) {
486 proto_tree_add_item(cql_subtree
, hf_cql_bytes
, tvb
, offset
, bytes_length
, ENC_NA
);
487 offset
+= bytes_length
;
492 if (flags
& CQL_QUERY_FLAG_PAGE_SIZE
) {
493 proto_tree_add_item(cql_subtree
, hf_cql_page_size
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
497 if (flags
& CQL_QUERY_FLAG_PAGING_STATE
) {
498 proto_tree_add_item_ret_int(cql_subtree
, hf_cql_bytes_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &bytes_length
);
500 if (bytes_length
> 0) {
501 proto_tree_add_item(cql_subtree
, hf_cql_bytes
, tvb
, offset
, bytes_length
, ENC_NA
);
502 offset
+= bytes_length
;
506 if (flags
& CQL_QUERY_FLAG_SERIAL_CONSISTENCY
) {
507 proto_tree_add_item(cql_subtree
, hf_cql_consistency
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
511 if (flags
& CQL_QUERY_FLAG_DEFAULT_TIMESTAMP
) {
512 proto_tree_add_item(cql_subtree
, hf_cql_timestamp
, tvb
, offset
, 8, ENC_TIME_USECS
|ENC_BIG_ENDIAN
);
520 get_cql_pdu_len(packet_info
* pinfo _U_
, tvbuff_t
* tvb
, int offset
, void* data _U_
)
522 /* CQL has 32-bit length at 5th byte in frame. */
523 uint32_t length
= tvb_get_ntohl(tvb
, offset
+ 5);
525 /* Include length of frame header. */
529 static cql_transaction_type
*
530 cql_transaction_add_request(cql_conversation_type
* conv
,
535 cql_transaction_type
* trans
;
538 list
= (wmem_list_t
*)wmem_map_lookup(conv
->streams
, GINT_TO_POINTER(stream
));
540 list
= wmem_list_new(wmem_file_scope());
542 wmem_map_remove(conv
->streams
, GINT_TO_POINTER(stream
));
545 trans
= wmem_new(wmem_file_scope(), cql_transaction_type
);
547 trans
->req_frame
= 0;
549 trans
->req_frame
= pinfo
->fd
->num
;
551 trans
->rep_frame
= 0;
552 trans
->req_time
= pinfo
->abs_ts
;
554 wmem_list_append(list
, (void *)trans
);
555 wmem_map_insert(conv
->streams
, GINT_TO_POINTER(stream
), (void*)list
);
560 static cql_transaction_type
*
561 cql_enrich_transaction_with_response(cql_conversation_type
* conv
,
565 cql_transaction_type
* trans
;
566 wmem_list_frame_t
* frame
;
569 list
= (wmem_list_t
*)wmem_map_lookup(conv
->streams
, GINT_TO_POINTER(stream
));
574 frame
= wmem_list_tail(list
);
579 trans
= (cql_transaction_type
*)wmem_list_frame_data(frame
);
584 trans
->rep_frame
= pinfo
->fd
->num
;
589 static cql_transaction_type
*
590 cql_transaction_lookup(cql_conversation_type
* conv
,
594 wmem_list_frame_t
* frame
;
597 list
= (wmem_list_t
*)wmem_map_lookup(conv
->streams
, GINT_TO_POINTER(stream
));
602 frame
= wmem_list_head(list
);
608 cql_transaction_type
* trans
= NULL
;
609 trans
= (cql_transaction_type
*)wmem_list_frame_data(frame
);
610 if (trans
->req_frame
== pinfo
->fd
->num
|| trans
->rep_frame
== pinfo
->fd
->num
) {
613 } while ((frame
= wmem_list_frame_next(frame
)));
619 CQL_COMPRESSION_NONE
= 0,
620 CQL_COMPRESSION_LZ4
= 1,
621 CQL_COMPRESSION_SNAPPY
= 2,
622 CQL_DECOMPRESSION_ATTEMPTED
= 3,
623 } cql_compression_level
;
626 // NOLINTNEXTLINE(misc-no-recursion)
627 static int parse_option(proto_tree
* metadata_subtree
, packet_info
*pinfo
, tvbuff_t
* tvb
, int offset
)
629 uint32_t data_type
= 0;
630 uint32_t string_length
= 0;
631 uint32_t tuple_size
= 0;
632 uint32_t udt_size
= 0;
635 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_result_rows_data_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &data_type
);
637 increment_dissection_depth(pinfo
);
639 case CQL_RESULT_ROW_TYPE_LIST
:
640 offset
= parse_option(metadata_subtree
, pinfo
, tvb
, offset
);
642 case CQL_RESULT_ROW_TYPE_MAP
:
643 offset
= parse_option(metadata_subtree
, pinfo
, tvb
, offset
);
644 offset
= parse_option(metadata_subtree
, pinfo
, tvb
, offset
);
646 case CQL_RESULT_ROW_TYPE_SET
:
647 offset
= parse_option(metadata_subtree
, pinfo
, tvb
, offset
);
649 case CQL_RESULT_ROW_TYPE_UDT
:
651 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
653 proto_tree_add_item(metadata_subtree
, hf_cql_string_result_rows_keyspace_name
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
654 offset
+= string_length
;
657 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
659 proto_tree_add_item(metadata_subtree
, hf_cql_string_result_rows_udt_name
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
660 offset
+= string_length
;
663 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_string_result_rows_udt_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &udt_size
);
666 for (i
= 0; i
< udt_size
; i
++) {
668 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
670 proto_tree_add_item(metadata_subtree
, hf_cql_string_result_rows_udt_field_name
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
671 offset
+= string_length
;
673 /* UDT field option */
674 offset
= parse_option(metadata_subtree
, pinfo
, tvb
, offset
);
677 case CQL_RESULT_ROW_TYPE_TUPLE
:
678 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_result_rows_tuple_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &tuple_size
);
680 for (i
= 0; i
< tuple_size
; i
++) {
681 offset
= parse_option(metadata_subtree
, pinfo
, tvb
, offset
);
687 decrement_dissection_depth(pinfo
);
692 static void add_varint_item(proto_tree
*tree
, tvbuff_t
*tvb
, const int offset
, int length
)
697 proto_tree_add_item(tree
, hf_cql_varint_count8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
700 proto_tree_add_item(tree
, hf_cql_varint_count16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
703 proto_tree_add_item(tree
, hf_cql_varint_count32
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
706 proto_tree_add_item(tree
, hf_cql_varint_count32
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
709 proto_tree_add_item(tree
, hf_cql_varint_count64
, tvb
, offset
, 5, ENC_BIG_ENDIAN
);
712 proto_tree_add_item(tree
, hf_cql_varint_count64
, tvb
, offset
, 6, ENC_BIG_ENDIAN
);
715 proto_tree_add_item(tree
, hf_cql_varint_count64
, tvb
, offset
, 7, ENC_BIG_ENDIAN
);
718 proto_tree_add_item(tree
, hf_cql_varint_count64
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
723 static void add_cql_uuid(proto_tree
* tree
, int hf_uuid
, tvbuff_t
* tvb
, int offset
)
728 guid
.data1
= tvb_get_letohl(tvb
, offset
+12);
729 guid
.data2
= tvb_get_letohl(tvb
, offset
+10);
730 guid
.data3
= tvb_get_letohl(tvb
, offset
+8);
732 for (i
= 0; i
< 8; i
++)
734 guid
.data4
[i
] = tvb_get_uint8(tvb
, offset
+(7-i
));
737 proto_tree_add_guid(tree
, hf_uuid
, tvb
, offset
, 16, &guid
);
741 // NOLINTNEXTLINE(misc-no-recursion)
742 static int parse_value(proto_tree
* columns_subtree
, packet_info
*pinfo
, tvbuff_t
* tvb
, int* offset_metadata
, int offset
)
744 uint32_t data_type
= 0;
745 uint32_t string_length
= 0;
746 int32_t bytes_length
= 0;
747 uint32_t tuple_size
= 0;
748 int32_t list_size
= 0;
749 int32_t map_size
= 0;
750 int32_t set_size
= 0;
751 uint32_t udt_size
= 0;
753 proto_item
*sub_item
;
756 int offset_metadata_backup
= 0;
759 uint32_t port_number
;
760 proto_tree
* map_subtree
;
761 proto_tree
* set_subtree
;
763 proto_tree_add_item_ret_int(columns_subtree
, hf_cql_bytes_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &bytes_length
);
766 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_result_rows_data_type
, tvb
, *offset_metadata
, 2, ENC_BIG_ENDIAN
, &data_type
);
767 proto_item_set_hidden(item
);
768 *offset_metadata
+= 2;
770 if (bytes_length
== -1) { // value is NULL, but need to skip metadata offsets
771 proto_tree_add_item(columns_subtree
, hf_cql_null_value
, tvb
, offset
, 0, ENC_NA
);
772 if (data_type
== CQL_RESULT_ROW_TYPE_MAP
) {
773 *offset_metadata
+= 4; /* skip the type fields of *both* key and value in the map in the metadata */
774 } else if (data_type
== CQL_RESULT_ROW_TYPE_SET
) {
775 *offset_metadata
+= 2; /* skip the type field of the elements in the set in the metadata */
780 increment_dissection_depth(pinfo
);
782 case CQL_RESULT_ROW_TYPE_CUSTOM
:
783 proto_tree_add_item(columns_subtree
, hf_cql_custom
, tvb
, offset
, bytes_length
, ENC_UTF_8
| ENC_NA
);
784 offset
+= bytes_length
;
786 case CQL_RESULT_ROW_TYPE_ASCII
:
787 proto_tree_add_item(columns_subtree
, hf_cql_ascii
, tvb
, offset
, bytes_length
, ENC_ASCII
| ENC_NA
);
788 offset
+= bytes_length
;
790 case CQL_RESULT_ROW_TYPE_BIGINT
:
791 proto_tree_add_item(columns_subtree
, hf_cql_bigint
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
794 case CQL_RESULT_ROW_TYPE_BLOB
:
795 proto_tree_add_item(columns_subtree
, hf_cql_bytes
, tvb
, offset
, bytes_length
, ENC_NA
);
796 offset
+= bytes_length
;
798 case CQL_RESULT_ROW_TYPE_BOOLEAN
:
799 proto_tree_add_boolean(columns_subtree
, hf_cql_boolean
, tvb
, offset
, 1, true);
802 case CQL_RESULT_ROW_TYPE_COUNTER
:
804 case CQL_RESULT_ROW_TYPE_DECIMAL
:
805 proto_tree_add_item(columns_subtree
, hf_cql_scale
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
807 add_varint_item(columns_subtree
, tvb
, offset
, bytes_length
- 4);
808 offset
+= bytes_length
- 4;
810 case CQL_RESULT_ROW_TYPE_DOUBLE
:
811 proto_tree_add_item(columns_subtree
, hf_cql_double
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
814 case CQL_RESULT_ROW_TYPE_FLOAT
:
815 proto_tree_add_item(columns_subtree
, hf_cql_float
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
818 case CQL_RESULT_ROW_TYPE_INT
:
819 proto_tree_add_item(columns_subtree
, hf_cql_int
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
822 case CQL_RESULT_ROW_TYPE_TIMESTAMP
:
823 proto_tree_add_item(columns_subtree
, hf_cql_result_timestamp
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
826 case CQL_RESULT_ROW_TYPE_UUID
:
827 add_cql_uuid(columns_subtree
, hf_cql_uuid
, tvb
, offset
);
830 case CQL_RESULT_ROW_TYPE_VARCHAR
:
831 proto_tree_add_item(columns_subtree
, hf_cql_varchar
, tvb
, offset
, bytes_length
, ENC_ASCII
);
832 offset
+= bytes_length
;
834 case CQL_RESULT_ROW_TYPE_VARINT
:
835 add_varint_item(columns_subtree
, tvb
, offset
, bytes_length
);
836 offset
+= bytes_length
;
838 case CQL_RESULT_ROW_TYPE_TIMEUUID
:
839 add_cql_uuid(columns_subtree
, hf_cql_timeuuid
, tvb
, offset
);
842 case CQL_RESULT_ROW_TYPE_INET
:
843 switch (bytes_length
) {
846 addr4
= tvb_get_ipv4(tvb
, offset
);
847 proto_tree_add_ipv4_format_value(columns_subtree
, hf_cql_ipv4
, tvb
, offset
, 4, addr4
, "%s", get_hostname(addr4
));
852 tvb_get_ipv6(tvb
, offset
, &addr6
);
853 proto_tree_add_ipv6_format_value(columns_subtree
, hf_cql_ipv6
, tvb
, offset
, 16, &addr6
, "%s", get_hostname6(&addr6
));
859 /* port number is optional */
860 if (bytes_length
== 16 || bytes_length
== 20) {
861 sub_item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_port
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &port_number
);
862 proto_item_append_text(sub_item
, " (%u)", port_number
);
866 case CQL_RESULT_ROW_TYPE_DATE
:
868 case CQL_RESULT_ROW_TYPE_TIME
:
870 case CQL_RESULT_ROW_TYPE_SMALLINT
:
872 case CQL_RESULT_ROW_TYPE_TINYINT
:
874 case CQL_RESULT_ROW_TYPE_LIST
:
875 item
= proto_tree_add_item_ret_int(columns_subtree
, hf_cql_string_result_rows_list_size
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &list_size
);
877 expert_add_info(pinfo
, item
, &ei_cql_unexpected_negative_value
);
878 decrement_dissection_depth(pinfo
);
879 return tvb_reported_length(tvb
);
882 offset_metadata_backup
= *offset_metadata
;
883 for (j
= 0; j
< list_size
; j
++) {
884 *offset_metadata
= offset_metadata_backup
;
885 offset
= parse_value(columns_subtree
, pinfo
, tvb
, offset_metadata
, offset
);
888 case CQL_RESULT_ROW_TYPE_MAP
:
889 map_subtree
= proto_tree_add_subtree(columns_subtree
, tvb
, offset
, 0, ett_cql_result_map
, NULL
, "Map");
890 item
= proto_tree_add_item_ret_int(map_subtree
, hf_cql_string_result_rows_map_size
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &map_size
);
892 proto_item_append_text(map_subtree
, " with %" PRId32
" element(s)", map_size
);
894 expert_add_info(pinfo
, item
, &ei_cql_unexpected_negative_value
);
895 decrement_dissection_depth(pinfo
);
896 return tvb_reported_length(tvb
);
897 } else if (map_size
== 0) {
898 *offset_metadata
+= 4; /* skip the type fields of *both* key and value in the map in the metadata */
900 offset_metadata_backup
= *offset_metadata
;
901 for (j
= 0; j
< map_size
; j
++) {
902 *offset_metadata
= offset_metadata_backup
;
903 offset
= parse_value(map_subtree
, pinfo
, tvb
, offset_metadata
, offset
);
904 offset
= parse_value(map_subtree
, pinfo
, tvb
, offset_metadata
, offset
);
908 case CQL_RESULT_ROW_TYPE_SET
:
909 set_subtree
= proto_tree_add_subtree(columns_subtree
, tvb
, offset
, 0, ett_cql_result_set
, NULL
, "Set");
910 item
= proto_tree_add_item_ret_int(set_subtree
, hf_cql_string_result_rows_set_size
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &set_size
);
913 expert_add_info(pinfo
, item
, &ei_cql_unexpected_negative_value
);
914 decrement_dissection_depth(pinfo
);
915 return tvb_reported_length(tvb
);
916 } else if (set_size
== 0) {
917 *offset_metadata
+= 2; /* skip the type field of the elements in the set in the metadata */
919 offset_metadata_backup
= *offset_metadata
;
920 for (j
= 0; j
< set_size
; j
++) {
921 *offset_metadata
= offset_metadata_backup
;
922 offset
= parse_value(set_subtree
, pinfo
, tvb
, offset_metadata
, offset
);
926 case CQL_RESULT_ROW_TYPE_UDT
:
928 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_string_length
, tvb
, *offset_metadata
, 2, ENC_BIG_ENDIAN
, &string_length
);
929 proto_item_set_hidden(item
);
930 *offset_metadata
+= 2;
931 item
= proto_tree_add_item(columns_subtree
, hf_cql_string_result_rows_keyspace_name
, tvb
, *offset_metadata
, string_length
, ENC_UTF_8
| ENC_NA
);
932 proto_item_set_hidden(item
);
933 *offset_metadata
+= string_length
;
936 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_string_length
, tvb
, *offset_metadata
, 2, ENC_BIG_ENDIAN
, &string_length
);
937 proto_item_set_hidden(item
);
938 *offset_metadata
+= 2;
939 item
= proto_tree_add_item(columns_subtree
, hf_cql_string_result_rows_udt_name
, tvb
, *offset_metadata
, string_length
, ENC_UTF_8
| ENC_NA
);
940 proto_item_set_hidden(item
);
941 *offset_metadata
+= string_length
;
944 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_string_result_rows_udt_size
, tvb
, *offset_metadata
, 2, ENC_BIG_ENDIAN
, &udt_size
);
945 proto_item_set_hidden(item
);
946 *offset_metadata
+= 2;
948 for (i
= 0; i
< udt_size
; i
++) {
950 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_string_length
, tvb
, *offset_metadata
, 2, ENC_BIG_ENDIAN
, &string_length
);
951 proto_item_set_hidden(item
);
952 *offset_metadata
+= 2;
953 item
= proto_tree_add_item(columns_subtree
, hf_cql_string_result_rows_udt_field_name
, tvb
, *offset_metadata
, string_length
, ENC_UTF_8
| ENC_NA
);
954 proto_item_set_hidden(item
);
955 *offset_metadata
+= string_length
;
957 /* UDT field option */
958 offset
= parse_value(columns_subtree
, pinfo
, tvb
, offset_metadata
, offset
);
961 case CQL_RESULT_ROW_TYPE_TUPLE
:
962 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_result_rows_tuple_size
, tvb
, *offset_metadata
, 2, ENC_BIG_ENDIAN
, &tuple_size
);
963 proto_item_set_hidden(item
);
964 *offset_metadata
+= 2;
965 for (i
= 0; i
< tuple_size
; i
++) {
966 offset
= parse_value(columns_subtree
, pinfo
, tvb
, offset_metadata
, offset
);
972 decrement_dissection_depth(pinfo
);
977 static int parse_result_metadata_more_pages(proto_tree
* tree
, tvbuff_t
* tvb
, int offset
, int flags
)
979 int32_t bytes_length
= 0;
981 if (flags
& CQL_RESULT_ROWS_FLAG_HAS_MORE_PAGES
) {
982 /* show paging state */
983 proto_tree_add_item_ret_int(tree
, hf_cql_bytes_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &bytes_length
);
985 if (bytes_length
> 0) {
986 proto_tree_add_item(tree
, hf_cql_paging_state
, tvb
, offset
, bytes_length
, ENC_NA
);
987 offset
+= bytes_length
;
994 static int parse_result_metadata(proto_tree
* tree
, packet_info
*pinfo
, tvbuff_t
* tvb
,
995 int offset
, int flags
, int result_rows_columns_count
)
997 proto_tree
* col_spec_subtree
= NULL
;
998 uint32_t string_length
= 0;
1001 if (flags
& CQL_RESULT_ROWS_FLAG_NO_METADATA
) {
1002 /* There will be no col_spec elements. */
1006 if ((flags
& (CQL_RESULT_ROWS_FLAG_GLOBAL_TABLES_SPEC
| CQL_RESULT_ROWS_FLAG_NO_METADATA
)) == CQL_RESULT_ROWS_FLAG_GLOBAL_TABLES_SPEC
) {
1007 proto_tree_add_item_ret_uint(tree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1009 proto_tree_add_item(tree
, hf_cql_string_result_rows_global_table_spec_ksname
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1010 offset
+= string_length
;
1012 proto_tree_add_item_ret_uint(tree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1014 proto_tree_add_item(tree
, hf_cql_string_result_rows_global_table_spec_table_name
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1015 offset
+= string_length
;
1018 for (j
= 0; j
< result_rows_columns_count
; ++j
) {
1019 col_spec_subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0, ett_cql_result_metadata_colspec
, NULL
, "Column");
1020 proto_item_append_text(col_spec_subtree
, " # %" PRId32
" specification", j
+ 1);
1021 if (!(flags
& CQL_RESULT_ROWS_FLAG_GLOBAL_TABLES_SPEC
)) {
1022 /* ksname and tablename */
1023 proto_tree_add_item_ret_uint(col_spec_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1025 proto_tree_add_item(col_spec_subtree
, hf_cql_string_result_rows_keyspace_name
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1026 offset
+= string_length
;
1027 proto_tree_add_item_ret_uint(col_spec_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1029 proto_tree_add_item(col_spec_subtree
, hf_cql_string_result_rows_table_name
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1030 offset
+= string_length
;
1034 proto_tree_add_item_ret_uint(col_spec_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1036 proto_tree_add_item(col_spec_subtree
, hf_cql_string_result_rows_column_name
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1037 offset
+= string_length
;
1040 offset
= parse_option(col_spec_subtree
, pinfo
, tvb
, offset
);
1047 static int parse_result_schema_change(proto_tree
* subtree
, packet_info
*pinfo
, tvbuff_t
* tvb
,
1050 uint32_t short_bytes_length
= 0;
1051 const uint8_t* string_event_type_target
= NULL
;
1053 proto_tree_add_item_ret_uint(subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &short_bytes_length
);
1055 proto_tree_add_item(subtree
, hf_cql_event_schema_change_type
, tvb
, offset
, short_bytes_length
, ENC_UTF_8
| ENC_NA
);
1056 offset
+= short_bytes_length
;
1057 proto_tree_add_item_ret_uint(subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &short_bytes_length
);
1059 proto_tree_add_item_ret_string(subtree
, hf_cql_event_schema_change_type_target
, tvb
, offset
, short_bytes_length
, ENC_UTF_8
, pinfo
->pool
, &string_event_type_target
);
1060 offset
+= short_bytes_length
;
1061 /* all targets have the keyspace as the first parameter*/
1062 proto_tree_add_item_ret_uint(subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &short_bytes_length
);
1064 proto_tree_add_item(subtree
, hf_cql_event_schema_change_keyspace
, tvb
, offset
, short_bytes_length
, ENC_UTF_8
| ENC_NA
);
1065 offset
+= short_bytes_length
;
1066 if ((strcmp(string_event_type_target
, "TABLE") == 0) || (strcmp(string_event_type_target
, "TYPE") == 0)) {
1067 proto_tree_add_item_ret_uint(subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &short_bytes_length
);
1069 proto_tree_add_item(subtree
, hf_cql_event_schema_change_object
, tvb
, offset
, short_bytes_length
, ENC_UTF_8
| ENC_NA
);
1071 /* TODO: handle "FUNCTION" or "AGGREGATE" targets:
1072 - [string] the function/aggregate name
1073 - [string list] one string for each argument type (as CQL type)
1081 static int parse_row(proto_tree
* columns_subtree
, packet_info
*pinfo
, tvbuff_t
* tvb
,
1082 int offset_metadata
, int offset
, int result_rows_columns_count
)
1084 int32_t result_rows_flags
= 0;
1090 shadow_offset
= offset_metadata
;
1091 for (j
= 0; j
< result_rows_columns_count
; ++j
) {
1092 if (!(result_rows_flags
& CQL_RESULT_ROWS_FLAG_GLOBAL_TABLES_SPEC
)) {
1093 /* ksname and tablename */
1094 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_string_length
, tvb
, shadow_offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1095 proto_item_set_hidden(item
);
1097 item
= proto_tree_add_item(columns_subtree
, hf_cql_string_result_rows_keyspace_name
, tvb
, shadow_offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1098 proto_item_set_hidden(item
);
1099 shadow_offset
+= string_length
;
1100 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_string_length
, tvb
, shadow_offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1101 proto_item_set_hidden(item
);
1103 item
= proto_tree_add_item(columns_subtree
, hf_cql_string_result_rows_table_name
, tvb
, shadow_offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1104 proto_item_set_hidden(item
);
1105 shadow_offset
+= string_length
;
1109 item
= proto_tree_add_item_ret_uint(columns_subtree
, hf_cql_string_length
, tvb
, shadow_offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1110 proto_item_set_hidden(item
);
1112 item
= proto_tree_add_item(columns_subtree
, hf_cql_string_result_rows_column_name
, tvb
, shadow_offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1113 proto_item_set_hidden(item
);
1114 shadow_offset
+= string_length
;
1116 offset
= parse_value(columns_subtree
, pinfo
, tvb
, &shadow_offset
, offset
);
1123 dissect_cql_tcp_pdu(tvbuff_t
* raw_tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
)
1126 tvbuff_t
* tvb
= NULL
;
1127 proto_tree
* cql_tree
;
1128 proto_tree
* version_tree
;
1129 proto_tree
* cql_subtree
= NULL
;
1130 proto_tree
* cust_payload_tree
= NULL
;
1131 proto_tree
* rows_subtree
= NULL
;
1132 proto_tree
* columns_subtree
= NULL
;
1133 proto_tree
* single_column_subtree
= NULL
;
1134 proto_tree
* metadata_subtree
= NULL
;
1135 proto_tree
* prepared_metadata_subtree
= NULL
;
1138 int offset_row_metadata
= 0;
1140 uint8_t first_byte
= 0;
1141 uint8_t cql_version
= 0;
1142 uint8_t server_to_client
= 0;
1144 uint32_t message_length
= 0;
1145 uint32_t map_size
= 0;
1147 uint32_t string_length
= 0;
1149 uint32_t batch_size
= 0;
1150 uint32_t batch_query_type
= 0;
1151 uint32_t result_kind
= 0;
1152 int32_t result_rows_flags
= 0;
1153 int32_t result_rows_columns_count
= 0;
1154 int32_t result_prepared_flags
= 0;
1155 int32_t result_prepared_pk_count
= 0;
1158 uint32_t short_bytes_length
= 0;
1159 int32_t bytes_length
= 0;
1160 int32_t result_rows_row_count
= 0;
1162 conversation_t
* conversation
;
1163 cql_conversation_type
* cql_conv
;
1164 cql_transaction_type
* cql_trans
= NULL
;
1165 cql_compression_level compression_level
= CQL_COMPRESSION_NONE
;
1167 static int * const cql_batch_flags_bitmaps
[] = {
1168 &hf_cql_batch_flag_serial_consistency
,
1169 &hf_cql_batch_flag_default_timestamp
,
1170 &hf_cql_batch_flag_with_name_for_values
,
1174 static int * const cql_header_bitmaps_v3
[] = {
1175 &hf_cql_flag_compression
,
1176 &hf_cql_flag_tracing
,
1177 &hf_cql_flag_reserved3
,
1181 static int * const cql_header_bitmaps_v4
[] = {
1182 &hf_cql_flag_compression
,
1183 &hf_cql_flag_tracing
,
1184 &hf_cql_flag_custom_payload
,
1185 &hf_cql_flag_warning
,
1186 &hf_cql_flag_reserved4
,
1190 const uint8_t* string_event_type
= NULL
;
1192 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CQL");
1193 col_clear(pinfo
->cinfo
, COL_INFO
);
1195 first_byte
= tvb_get_uint8(raw_tvb
, 0);
1196 cql_version
= first_byte
& (uint8_t)0x7F;
1197 server_to_client
= first_byte
& (uint8_t)0x80;
1198 opcode
= tvb_get_uint8(raw_tvb
, 4);
1200 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "v%d %s Type %s",
1202 server_to_client
== 0 ? "C->S" : "S->C",
1203 val_to_str(opcode
, cql_opcode_names
, "Unknown (0x%02x)")
1206 conversation
= find_or_create_conversation(pinfo
);
1207 cql_conv
= (cql_conversation_type
*) conversation_get_proto_data(conversation
, proto_cql
);
1209 cql_conv
= wmem_new(wmem_file_scope(), cql_conversation_type
);
1210 cql_conv
->streams
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
1211 conversation_add_proto_data(conversation
, proto_cql
, cql_conv
);
1214 ti
= proto_tree_add_item(tree
, proto_cql
, raw_tvb
, 0, -1, ENC_NA
);
1215 cql_tree
= proto_item_add_subtree(ti
, ett_cql_protocol
);
1217 ti
= proto_tree_add_item(cql_tree
, hf_cql_version
, raw_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1218 version_tree
= proto_item_add_subtree(ti
, ett_cql_version
);
1219 proto_tree_add_item(version_tree
, hf_cql_protocol_version
, raw_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1220 proto_tree_add_item(version_tree
, hf_cql_direction
, raw_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1222 switch(cql_version
){
1224 proto_tree_add_bitmask(cql_tree
, raw_tvb
, offset
, hf_cql_flags_bitmap
, ett_cql_header_flags_bitmap
, cql_header_bitmaps_v3
, ENC_BIG_ENDIAN
);
1227 proto_tree_add_bitmask(cql_tree
, raw_tvb
, offset
, hf_cql_flags_bitmap
, ett_cql_header_flags_bitmap
, cql_header_bitmaps_v4
, ENC_BIG_ENDIAN
);
1230 proto_tree_add_item(cql_tree
, hf_cql_flags_bitmap
, raw_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1233 flags
= tvb_get_uint8(raw_tvb
, offset
);
1235 proto_tree_add_item_ret_int(cql_tree
, hf_cql_stream
, raw_tvb
, offset
, 2, ENC_BIG_ENDIAN
, &stream
);
1237 proto_tree_add_item(cql_tree
, hf_cql_opcode
, raw_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1239 proto_tree_add_item_ret_uint(cql_tree
, hf_cql_length
, raw_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &message_length
);
1242 /* Track the request/response. */
1243 if (!pinfo
->fd
->visited
) {
1244 if (server_to_client
== 0) {
1245 /* This is a request, add it to this stream tracking */
1246 cql_trans
= cql_transaction_add_request(cql_conv
, pinfo
, stream
, 0);
1248 /* This is a response, bind the response with the latest request */
1249 cql_trans
= cql_enrich_transaction_with_response(cql_conv
, pinfo
, stream
);
1252 /* Search for any packet having this packed id as request or response */
1253 cql_trans
= cql_transaction_lookup(cql_conv
, pinfo
, stream
);
1257 /* Add a fake request to this stream tracking */
1258 cql_trans
= cql_transaction_add_request(cql_conv
, pinfo
, stream
, 1);
1261 /* Add state tracking to tree */
1262 if (server_to_client
== 0 && cql_trans
->rep_frame
) {
1264 ti
= proto_tree_add_uint(cql_tree
, hf_cql_response_in
, raw_tvb
, 0, 0, cql_trans
->rep_frame
);
1265 proto_item_set_generated(ti
);
1267 if (server_to_client
&& cql_trans
->req_frame
) {
1271 ti
= proto_tree_add_uint(cql_tree
, hf_cql_response_to
, raw_tvb
, 0, 0, cql_trans
->req_frame
);
1272 proto_item_set_generated(ti
);
1273 nstime_delta(&ns
, &pinfo
->abs_ts
, &cql_trans
->req_time
);
1274 ti
= proto_tree_add_time(cql_tree
, hf_cql_response_time
, raw_tvb
, 0, 0, &ns
);
1275 proto_item_set_generated(ti
);
1278 /* We cannot rely on compression negotiation in the STARTUP message because the
1279 * capture can be done at a random time hence missing the negotiation.
1280 * So we will first try to decompress LZ4 then snappy
1282 if (flags
& CQL_HEADER_FLAG_COMPRESSION
) {
1283 compression_level
= CQL_DECOMPRESSION_ATTEMPTED
;
1285 if (tvb_captured_length_remaining(raw_tvb
, offset
) > 4) {
1286 /* Set ret == 0 to make it fail in case decompression is skipped
1287 * due to orig_size being too big
1289 uint32_t ret
= 0, orig_size
= tvb_get_ntohl(raw_tvb
, offset
);
1290 unsigned char *decompressed_buffer
= NULL
;
1293 /* if the decompressed size is reasonably small try to decompress data */
1294 if (orig_size
<= MAX_UNCOMPRESSED_SIZE
) {
1295 decompressed_buffer
= (unsigned char*)wmem_alloc(pinfo
->pool
, orig_size
);
1296 ret
= LZ4_decompress_safe(tvb_get_ptr(raw_tvb
, offset
, -1),
1297 decompressed_buffer
,
1298 tvb_captured_length_remaining(raw_tvb
, offset
),
1301 /* Decompression attempt failed: rewind offset */
1302 if (ret
!= orig_size
) {
1303 wmem_free(pinfo
->pool
, decompressed_buffer
);
1306 /* Now re-setup the tvb buffer to have the new data */
1307 tvb
= tvb_new_child_real_data(raw_tvb
, decompressed_buffer
, orig_size
, orig_size
);
1308 add_new_data_source(pinfo
, tvb
, "LZ4 Decompressed Data");
1309 /* mark the decompression as successful */
1310 compression_level
= CQL_COMPRESSION_LZ4
;
1311 message_length
= orig_size
;
1316 if (compression_level
== CQL_DECOMPRESSION_ATTEMPTED
) {
1317 unsigned char *decompressed_buffer
= NULL
;
1318 size_t orig_size
= 0;
1321 /* get the raw data length */
1322 ret
= snappy_uncompressed_length(tvb_get_ptr(raw_tvb
, offset
, -1),
1323 tvb_captured_length_remaining(raw_tvb
, offset
),
1325 /* if we get the length and it's reasonably short to allocate a buffer for it
1326 * proceed to try decompressing the data
1328 if (ret
== SNAPPY_OK
&& orig_size
<= MAX_UNCOMPRESSED_SIZE
) {
1329 decompressed_buffer
= (unsigned char*)wmem_alloc(pinfo
->pool
, orig_size
);
1331 ret
= snappy_uncompress(tvb_get_ptr(raw_tvb
, offset
, -1),
1332 tvb_captured_length_remaining(raw_tvb
, offset
),
1333 decompressed_buffer
,
1336 /* else mark the input as invalid in order to skip the rest of the
1339 ret
= SNAPPY_INVALID_INPUT
;
1341 /* if the decompression succeeded build the new tvb */
1342 if (ret
== SNAPPY_OK
) {
1343 tvb
= tvb_new_child_real_data(raw_tvb
, decompressed_buffer
, (uint32_t)orig_size
, (uint32_t)orig_size
);
1344 add_new_data_source(pinfo
, tvb
, "Snappy Decompressed Data");
1345 compression_level
= CQL_COMPRESSION_SNAPPY
;
1346 message_length
= (uint32_t)orig_size
;
1348 wmem_free(pinfo
->pool
, decompressed_buffer
);
1353 if (compression_level
== CQL_COMPRESSION_NONE
) {
1354 /* In case of decompression failure or uncompressed packet */
1355 tvb
= tvb_new_subset_remaining(raw_tvb
, offset
);
1356 } else if (compression_level
== CQL_DECOMPRESSION_ATTEMPTED
) {
1357 proto_tree_add_item(cql_tree
, hf_cql_raw_compressed_bytes
, raw_tvb
, offset
,
1358 tvb_captured_length_remaining(raw_tvb
, offset
), ENC_NA
);
1359 return tvb_captured_length(raw_tvb
);
1364 /* Dissect the operation. */
1365 if (server_to_client
== 0) {
1367 case CQL_OPCODE_STARTUP
:
1368 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message STARTUP");
1369 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_map_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &map_size
);
1371 for(i
= 0; i
< map_size
; ++i
) {
1372 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1374 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1375 offset
+= string_length
;
1377 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1379 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1380 offset
+= string_length
;
1384 case CQL_OPCODE_AUTH_RESPONSE
:
1385 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message AUTH_RESPONSE");
1387 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &string_length
);
1389 if (string_length
> 0) {
1390 proto_tree_add_item(cql_subtree
, hf_cql_auth_token
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1394 case CQL_OPCODE_OPTIONS
:
1395 /* body should be empty */
1398 case CQL_OPCODE_QUERY
:
1399 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Query");
1402 const uint8_t *query_string
;
1403 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &string_length
);
1405 proto_tree_add_item_ret_string(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
, pinfo
->pool
, &query_string
);
1406 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s", query_string
);
1407 offset
+= string_length
;
1409 /* Query parameters */
1410 dissect_cql_query_parameters(cql_subtree
, tvb
, offset
, 0);
1415 case CQL_OPCODE_PREPARE
:
1416 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message PREPARE");
1418 /* TODO: Link for later use by EXECUTE? */
1419 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &string_length
);
1421 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1425 case CQL_OPCODE_EXECUTE
:
1426 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message EXECUTE");
1428 /* TODO: link to original PREPARE? */
1431 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &short_bytes_length
);
1433 proto_tree_add_item(cql_subtree
, hf_cql_query_id
, tvb
, offset
, short_bytes_length
, ENC_NA
);
1434 offset
+= short_bytes_length
;
1436 /* Query parameters */
1437 dissect_cql_query_parameters(cql_subtree
, tvb
, offset
, 1);
1441 case CQL_OPCODE_BATCH
:
1443 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message BATCH");
1445 proto_tree_add_item(cql_subtree
, hf_cql_batch_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1448 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_batch_query_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &batch_size
);
1451 for (i
= 0; i
< batch_size
; ++i
) {
1452 uint32_t value_count
= 0;
1454 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_batch_query_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &batch_query_type
);
1455 batch_query_type
= tvb_get_uint8(tvb
, offset
);
1457 if (batch_query_type
== 0) {
1459 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &string_length
);
1461 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1462 offset
+= string_length
;
1463 } else if (batch_query_type
== 1) {
1464 uint32_t query_id_bytes_length
;
1467 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &query_id_bytes_length
);
1469 proto_tree_add_item(cql_subtree
, hf_cql_query_id
, tvb
, offset
, query_id_bytes_length
, ENC_NA
);
1470 offset
+= query_id_bytes_length
;
1473 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_value_count
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &value_count
);
1475 for (k
= 0; k
< value_count
; ++k
) {
1476 int32_t batch_bytes_length
= 0;
1477 proto_tree_add_item_ret_int(cql_subtree
, hf_cql_bytes_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &batch_bytes_length
);
1479 if (batch_bytes_length
> 0) {
1480 proto_tree_add_item(cql_subtree
, hf_cql_bytes
, tvb
, offset
, batch_bytes_length
, ENC_NA
);
1481 offset
+= batch_bytes_length
;
1483 /* TODO - handle both -1 and -2 batch_bytes_length values:
1484 -1 no byte should follow and the value represented is `null`.
1485 -2 no byte should follow and the value represented is `not set` not resulting in any change to the existing value.
1486 < -2 is an invalid value and results in an error. */
1490 proto_tree_add_item(cql_subtree
, hf_cql_consistency
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1492 proto_tree_add_bitmask(cql_subtree
, tvb
, offset
, hf_cql_batch_flags_bitmap
, ett_cql_batch_flags_bitmap
, cql_batch_flags_bitmaps
, ENC_BIG_ENDIAN
);
1495 case CQL_OPCODE_REGISTER
:
1496 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message REGISTER");
1499 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_list_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &map_size
);
1501 for(i
= 0; i
< map_size
; ++i
) {
1502 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1504 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1505 offset
+= string_length
;
1511 proto_tree_add_expert(cql_tree
, pinfo
, &ei_cql_data_not_dissected_yet
, tvb
, 0, message_length
);
1515 if (flags
& CQL_HEADER_FLAG_TRACING
) {
1516 add_cql_uuid(cql_tree
, hf_cql_tracing_uuid
, tvb
, offset
);
1520 case CQL_OPCODE_ERROR
:
1521 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message ERROR");
1522 uint32_t error_code
;
1523 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_error_code
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &error_code
);
1524 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s (0x%x)", val_to_str_const(error_code
, cql_error_names
, "Unknown error code"), error_code
);
1528 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1530 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1534 case CQL_OPCODE_AUTHENTICATE
:
1535 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message AUTHENTICATE");
1537 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1539 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1543 case CQL_OPCODE_SUPPORTED
:
1544 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message SUPPORTED");
1545 uint32_t multimap_count
, value_count
;
1547 /* string multimap */
1548 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_value_count
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &multimap_count
);
1550 for (k
= 0; k
< multimap_count
; ++k
) {
1552 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1554 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1555 offset
+= string_length
;
1557 /* value - string list */
1558 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_list_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &value_count
);
1560 for(i
= 0; i
< value_count
; ++i
) {
1561 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1563 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1564 offset
+= string_length
;
1570 case CQL_OPCODE_RESULT
:
1571 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message RESULT");
1573 if (flags
& CQL_HEADER_FLAG_CUSTOM_PAYLOAD
) {
1574 uint32_t bytesmap_count
;
1575 cust_payload_tree
= proto_tree_add_subtree(cql_subtree
, tvb
, offset
, 0, ett_cql_custom_payload
, NULL
, "Custom Payload");
1576 proto_tree_add_item_ret_uint(cust_payload_tree
, hf_cql_value_count
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &bytesmap_count
);
1578 for(k
= 0; k
< bytesmap_count
; ++k
) {
1579 proto_tree_add_item_ret_uint(cust_payload_tree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1581 proto_tree_add_item(cust_payload_tree
, hf_cql_bytesmap_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1582 offset
+= string_length
;
1583 if (bytes_length
> 0) {
1584 proto_tree_add_item(cust_payload_tree
, hf_cql_bytes
, tvb
, offset
, bytes_length
, ENC_NA
);
1585 offset
+= bytes_length
;
1591 proto_tree_add_item_ret_int(cql_subtree
, hf_cql_result_kind
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_kind
);
1592 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s", val_to_str_const(result_kind
, cql_result_kind_names
, "Unknown kind"));
1595 switch (result_kind
) {
1596 case CQL_RESULT_KIND_VOID
:
1600 case CQL_RESULT_KIND_ROWS
:
1601 metadata_subtree
= proto_tree_add_subtree(cql_subtree
, tvb
, offset
, 0, ett_cql_result_metadata
, &ti
, "Rows Result Metadata");
1602 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_result_rows_flags_values
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_rows_flags
);
1603 proto_tree_add_item(metadata_subtree
, hf_cql_result_rows_flag_global_tables_spec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1604 proto_tree_add_item(metadata_subtree
, hf_cql_result_rows_flag_has_more_pages
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1605 proto_tree_add_item(metadata_subtree
, hf_cql_result_rows_flag_no_metadata
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1608 ti
= proto_tree_add_item_ret_int(metadata_subtree
, hf_cql_result_rows_column_count
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_rows_columns_count
);
1609 if (result_rows_columns_count
< 0) {
1610 expert_add_info(pinfo
, ti
, &ei_cql_unexpected_negative_value
);
1611 return tvb_reported_length(tvb
);
1615 offset
= parse_result_metadata_more_pages(metadata_subtree
, tvb
, offset
, result_rows_flags
);
1617 offset_row_metadata
= offset
;
1618 offset
= parse_result_metadata(metadata_subtree
, pinfo
, tvb
, offset
, result_rows_flags
, result_rows_columns_count
);
1619 if (offset
== offset_row_metadata
) {
1620 /* there was no col spec, no row metadata available */
1621 offset_row_metadata
= 0;
1624 rows_subtree
= proto_tree_add_subtree(cql_subtree
, tvb
, offset
, 0, ett_cql_result_rows
, &ti
, "Rows");
1625 ti
= proto_tree_add_item_ret_int(rows_subtree
, hf_cql_result_rows_row_count
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_rows_row_count
);
1626 if (result_rows_row_count
< 0) {
1627 expert_add_info(pinfo
, ti
, &ei_cql_unexpected_negative_value
);
1628 return tvb_reported_length(tvb
);
1630 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (%d rows)", result_rows_row_count
);
1633 if (result_rows_columns_count
) {
1634 for (j
= 0; j
< result_rows_row_count
; ++j
) {
1635 columns_subtree
= proto_tree_add_subtree(rows_subtree
, tvb
, offset
, 0, ett_cql_result_columns
, &ti
, "Data (columns)");
1636 proto_item_append_text(columns_subtree
, " for row # %" PRId64
, j
+ 1);
1638 if (offset_row_metadata
) {
1639 offset
= parse_row(columns_subtree
, pinfo
, tvb
, offset_row_metadata
, offset
, result_rows_columns_count
);
1641 for (k
= 0; k
< result_rows_columns_count
; ++k
) {
1642 proto_tree_add_item_ret_int(columns_subtree
, hf_cql_bytes_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &bytes_length
);
1644 single_column_subtree
= proto_tree_add_subtree(columns_subtree
, tvb
, offset
, bytes_length
> 0 ? bytes_length
: 0, ett_cql_results_no_metadata
, &ti
, "Column data");
1645 if (bytes_length
> 0) {
1646 proto_item_append_text(single_column_subtree
, " for column # %" PRId64
, k
+ 1);
1647 proto_tree_add_item(single_column_subtree
, hf_cql_bytes
, tvb
, offset
, bytes_length
, ENC_NA
);
1648 offset
+= bytes_length
;
1649 } else if (bytes_length
== -1) {
1650 proto_item_append_text(single_column_subtree
, " is NULL for column # %" PRId64
, k
+ 1);
1651 } else if (bytes_length
== -2) {
1652 proto_item_append_text(single_column_subtree
, " is not set for column # %" PRId64
, k
+ 1);
1654 expert_add_info(pinfo
, ti
, &ei_cql_unexpected_negative_value
);
1655 return tvb_reported_length(tvb
);
1664 case CQL_RESULT_KIND_SET_KEYSPACE
:
1665 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &string_length
);
1667 proto_tree_add_item(cql_subtree
, hf_cql_string
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1671 case CQL_RESULT_KIND_PREPARED
:
1672 /* <id><metadata><result_metadata> */
1675 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &short_bytes_length
);
1677 proto_tree_add_item(cql_subtree
, hf_cql_query_id
, tvb
, offset
, short_bytes_length
, ENC_NA
);
1678 offset
+= short_bytes_length
;
1680 /* metadata: <flags><columns_count><pk_count>[<pk_index_1>...<pk_index_n>][<global_table_spec>?<col_spec_1>...<col_spec_n>] */
1681 prepared_metadata_subtree
= proto_tree_add_subtree(cql_subtree
, tvb
, offset
, 0, ett_cql_result_metadata
, &ti
, "Prepared Metadata");
1682 proto_tree_add_item_ret_uint(prepared_metadata_subtree
, hf_cql_result_prepared_flags_values
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_prepared_flags
);
1683 proto_tree_add_item(prepared_metadata_subtree
, hf_cql_result_rows_flag_global_tables_spec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1685 proto_tree_add_item_ret_int(prepared_metadata_subtree
, hf_cql_result_rows_column_count
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_rows_columns_count
);
1686 if (result_rows_columns_count
< 0) {
1687 expert_add_info(pinfo
, ti
, &ei_cql_unexpected_negative_value
);
1688 return tvb_reported_length(tvb
);
1692 proto_tree_add_item_ret_int(prepared_metadata_subtree
, hf_cql_result_prepared_pk_count
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_prepared_pk_count
);
1693 if (result_prepared_pk_count
< 0) {
1694 expert_add_info(pinfo
, ti
, &ei_cql_unexpected_negative_value
);
1695 return tvb_reported_length(tvb
);
1699 /* TODO: skipping all pk_index elements for now*/
1700 offset
+= (2 * result_prepared_pk_count
);
1702 offset
= parse_result_metadata(prepared_metadata_subtree
, pinfo
, tvb
, offset
, result_prepared_flags
, result_rows_columns_count
);
1704 /* <result_metadata> is identical to rows result metadata */
1705 metadata_subtree
= proto_tree_add_subtree(cql_subtree
, tvb
, offset
, 0, ett_cql_result_metadata
, &ti
, "Prepared Result Metadata");
1706 proto_tree_add_item_ret_uint(metadata_subtree
, hf_cql_result_rows_flags_values
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_rows_flags
);
1707 proto_tree_add_item(metadata_subtree
, hf_cql_result_rows_flag_global_tables_spec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1708 proto_tree_add_item(metadata_subtree
, hf_cql_result_rows_flag_has_more_pages
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1709 proto_tree_add_item(metadata_subtree
, hf_cql_result_rows_flag_no_metadata
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1712 ti
= proto_tree_add_item_ret_int(metadata_subtree
, hf_cql_result_rows_column_count
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &result_rows_columns_count
);
1713 if (result_rows_columns_count
< 0) {
1714 expert_add_info(pinfo
, ti
, &ei_cql_unexpected_negative_value
);
1715 return tvb_reported_length(tvb
);
1719 offset
= parse_result_metadata_more_pages(metadata_subtree
, tvb
, offset
, result_rows_flags
);
1721 parse_result_metadata(metadata_subtree
, pinfo
, tvb
, offset
, result_rows_flags
, result_rows_columns_count
);
1724 case CQL_RESULT_KIND_SCHEMA_CHANGE
:
1725 /*offset = */parse_result_schema_change(cql_subtree
, pinfo
, tvb
, offset
);
1729 proto_tree_add_expert(cql_subtree
, pinfo
, &ei_cql_data_not_dissected_yet
, tvb
, 0, message_length
);
1736 case CQL_OPCODE_EVENT
:
1737 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message EVENT");
1739 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_short_bytes_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &short_bytes_length
);
1742 proto_tree_add_item_ret_string(cql_subtree
, hf_cql_event_type
, tvb
, offset
, short_bytes_length
, ENC_UTF_8
, pinfo
->pool
, &string_event_type
);
1743 offset
+= short_bytes_length
;
1744 proto_item_append_text(cql_subtree
, " (type: %s)", string_event_type
);
1746 if (strcmp(string_event_type
, "SCHEMA_CHANGE") == 0) {
1747 /*offset = */parse_result_schema_change(cql_subtree
, pinfo
, tvb
, offset
);
1749 /* TODO: handle "TOPOLOGY_CHANGE" and "STATUS_CHANGE" event types as well*/
1754 case CQL_OPCODE_AUTH_CHALLENGE
:
1755 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message AUTH_CHALLENGE");
1757 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &string_length
);
1759 proto_tree_add_item(cql_subtree
, hf_cql_auth_token
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1763 case CQL_OPCODE_AUTH_SUCCESS
:
1764 cql_subtree
= proto_tree_add_subtree(cql_tree
, tvb
, offset
, message_length
, ett_cql_message
, &ti
, "Message AUTH_SUCCESS");
1766 proto_tree_add_item_ret_uint(cql_subtree
, hf_cql_string_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &string_length
);
1768 if (string_length
> 0) {
1769 proto_tree_add_item(cql_subtree
, hf_cql_auth_token
, tvb
, offset
, string_length
, ENC_UTF_8
| ENC_NA
);
1774 proto_tree_add_expert(cql_subtree
, pinfo
, &ei_cql_data_not_dissected_yet
, tvb
, 0, message_length
);
1779 return tvb_reported_length(tvb
);
1783 dissect_cql_tcp(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
)
1786 /* This dissector version only understands CQL protocol v3 and v4. */
1787 if (tvb_reported_length(tvb
) < 1)
1790 version
= tvb_get_uint8(tvb
, 0) & 0x7F;
1791 if ((version
!= 3 && version
!= 4))
1794 tcp_dissect_pdus(tvb
, pinfo
, tree
, cql_desegment
, 9 /* bytes to determine length of PDU */, get_cql_pdu_len
, dissect_cql_tcp_pdu
, data
);
1795 return tvb_reported_length(tvb
);
1799 proto_reg_handoff_cql(void)
1801 dissector_add_uint_with_preference("tcp.port", CQL_DEFAULT_PORT
, find_dissector("cql"));
1806 proto_register_cql(void)
1808 expert_module_t
* expert_cql
;
1809 static hf_register_info hf
[] = {
1811 &hf_cql_batch_flag_serial_consistency
,
1813 "Serial Consistency", "cql.batch.flags.serial_consistency",
1815 NULL
, CQL_BATCH_FLAG_SERIAL_CONSISTENCY
,
1820 &hf_cql_batch_flag_default_timestamp
,
1822 "Default Timestamp", "cql.batch.flags.default_timestamp",
1824 NULL
, CQL_BATCH_FLAG_DEFAULT_TIMESTAMP
,
1829 &hf_cql_batch_flag_with_name_for_values
,
1831 "With Name For Value", "cql.batch.flags.with_name_for_values",
1833 NULL
, CQL_BATCH_FLAG_WITH_NAME_FOR_VALUES
,
1838 &hf_cql_batch_flags_bitmap
,
1840 "Flags", "cql.batch.flags",
1849 "Version", "cql.version",
1852 "CQL protocol version (not language version)", HFILL
1856 &hf_cql_protocol_version
,
1858 "Protocol version", "cql.protocol_version",
1867 "Direction", "cql.direction",
1869 VALS(cql_direction_names
), 0xF0,
1874 &hf_cql_flags_bitmap
,
1876 "Flags", "cql.flags",
1883 &hf_cql_result_rows_flags_values
,
1885 "Rows Result Flags", "cql.result.rows.flags",
1886 FT_UINT32
, BASE_DEC
,
1892 &hf_cql_result_prepared_flags_values
,
1894 "Prepared Result Flags", "cql.result.prepared.flags",
1895 FT_UINT32
, BASE_DEC
,
1901 &hf_cql_result_rows_flag_global_tables_spec
,
1903 "Global tables spec.", "cql.result.rows.flags.global_tables",
1905 NULL
, CQL_RESULT_ROWS_FLAG_GLOBAL_TABLES_SPEC
,
1910 &hf_cql_result_rows_flag_has_more_pages
,
1912 "Has More Pages", "cql.result.rows.flags.has_more_pages",
1914 NULL
, CQL_RESULT_ROWS_FLAG_HAS_MORE_PAGES
,
1919 &hf_cql_result_rows_flag_no_metadata
,
1921 "No Metadata", "cql.result.rows.flags.no_metadata",
1923 NULL
, CQL_RESULT_ROWS_FLAG_NO_METADATA
,
1928 &hf_cql_flag_compression
,
1930 "Compression", "cql.flags.compression",
1932 NULL
, CQL_HEADER_FLAG_COMPRESSION
,
1937 &hf_cql_flag_tracing
,
1939 "Tracing", "cql.flags.tracing",
1941 NULL
, CQL_HEADER_FLAG_TRACING
,
1946 &hf_cql_flag_custom_payload
,
1948 "Custom Payload", "cql.flags.custom_payload",
1950 NULL
, CQL_HEADER_FLAG_CUSTOM_PAYLOAD
,
1955 &hf_cql_flag_warning
,
1957 "Warning", "cql.flags.warning",
1959 NULL
, CQL_HEADER_FLAG_WARNING
,
1964 &hf_cql_flag_reserved3
,
1966 "Reserved", "cql.flags.reserved",
1968 NULL
, CQL_HEADER_FLAG_V3_RESERVED
,
1973 &hf_cql_flag_reserved4
,
1975 "Reserved", "cql.flags.reserved",
1977 NULL
, CQL_HEADER_FLAG_V4_RESERVED
,
1982 &hf_cql_query_flags_bitmap
,
1984 "Flags", "cql.query.flags",
1991 &hf_cql_query_flags_page_size
,
1993 "Page Size", "cql.query.flags.page_size",
1995 NULL
, CQL_QUERY_FLAG_PAGE_SIZE
,
2000 &hf_cql_query_flags_skip_metadata
,
2002 "Skip Metadata", "cql.query.flags.skip_metadata",
2004 NULL
, CQL_QUERY_FLAG_SKIP_METADATA
,
2009 &hf_cql_query_flags_values
,
2011 "Values", "cql.query.flags.values",
2013 NULL
, CQL_QUERY_FLAG_VALUES
,
2018 &hf_cql_query_flags_default_timestamp
,
2020 "Default Timestamp", "cql.query.flags.default_timestamp",
2022 NULL
, CQL_QUERY_FLAG_DEFAULT_TIMESTAMP
,
2027 &hf_cql_query_flags_names_for_values
,
2029 "Names for Values", "cql.query.flags.value_names",
2031 NULL
, CQL_QUERY_FLAG_VALUE_NAMES
,
2036 &hf_cql_query_flags_paging_state
,
2038 "Paging State", "cql.query.flags.paging_state",
2040 NULL
, CQL_QUERY_FLAG_PAGING_STATE
,
2045 &hf_cql_query_flags_serial_consistency
,
2047 "Serial Consistency", "cql.query.flags.serial_consistency",
2049 NULL
, CQL_QUERY_FLAG_SERIAL_CONSISTENCY
,
2054 &hf_cql_query_flags_reserved3
,
2056 "Reserved", "cql.query_flags.reserved",
2058 NULL
, CQL_QUERY_FLAG_V3_RESERVED
,
2065 "Stream Identifier", "cql.stream",
2068 "Stream identifier this packet belongs to", HFILL
2074 "Opcode", "cql.opcode",
2076 VALS(cql_opcode_names
), 0x7F, /* Mask the highest-order bit because it indicates message direction, not opcode. */
2077 "CQL operation this packet describes", HFILL
2083 "Batch type", "cql.batch_type",
2085 VALS(cql_batch_type_names
), 0x0,
2090 &hf_cql_batch_query_type
,
2092 "Batch query type", "cql.batch_query_type",
2094 VALS(cql_batch_query_type_names
), 0x00,
2101 "Message Length", "cql.message_length",
2102 FT_UINT32
, BASE_DEC
,
2108 &hf_cql_string_map_size
,
2110 "String Map Size", "cql.string_map_size",
2111 FT_UINT16
, BASE_DEC
,
2113 "Number of strings in the map", HFILL
2117 &hf_cql_string_list_size
,
2119 "String List Size", "cql.string_list_size",
2120 FT_UINT16
, BASE_DEC
,
2122 "Number of strings in the list", HFILL
2128 "String", "cql.string",
2129 FT_STRING
, BASE_NONE
,
2131 "UTF-8 string value", HFILL
2137 "Auth Token", "cql.auth_token",
2138 FT_BYTES
, BASE_NONE
,
2140 "[bytes] auth token", HFILL
2144 &hf_cql_string_result_rows_global_table_spec_ksname
,
2146 "Global Spec Keyspace Name", "cql.result.rows.keyspace_name",
2147 FT_STRING
, BASE_NONE
,
2153 &hf_cql_string_result_rows_global_table_spec_table_name
,
2155 "Global Spec Table Name", "cql.result.rows.table_name",
2156 FT_STRING
, BASE_NONE
,
2162 &hf_cql_string_result_rows_table_name
,
2164 "Table Name", "cql.result.rows.table_name",
2165 FT_STRING
, BASE_NONE
,
2171 &hf_cql_string_result_rows_udt_name
,
2173 "User Defined Type Name", "cql.result.rows.udt_name",
2174 FT_STRING
, BASE_NONE
,
2180 &hf_cql_string_result_rows_udt_field_name
,
2182 "User Defined Type field Name", "cql.result.rows.udt_field_name",
2183 FT_STRING
, BASE_NONE
,
2189 &hf_cql_string_result_rows_udt_size
,
2191 "User Defined Type Size", "cql.result.rows.udt_size",
2192 FT_UINT16
, BASE_DEC
,
2198 &hf_cql_string_result_rows_list_size
,
2200 "List Size", "cql.result.rows.list_size",
2207 &hf_cql_string_result_rows_map_size
,
2209 "No. of key/value pairs in map", "cql.result.rows.map_size",
2216 &hf_cql_string_result_rows_set_size
,
2218 "Set Size", "cql.result.rows.set_size",
2225 &hf_cql_string_result_rows_keyspace_name
,
2227 "Keyspace Name", "cql.result.rows.keyspace_name",
2228 FT_STRING
, BASE_NONE
,
2234 &hf_cql_bytesmap_string
,
2236 "Key", "cql.bytesmap.key",
2237 FT_STRING
, BASE_NONE
,
2243 &hf_cql_string_result_rows_column_name
,
2245 "Column Name", "cql.result.rows.column_name",
2246 FT_STRING
, BASE_NONE
,
2252 &hf_cql_string_length
,
2254 "String Length", "cql.string_length",
2255 FT_UINT32
, BASE_DEC
,
2257 "Length of the subsequent string value", HFILL
2261 &hf_cql_consistency
,
2263 "Consistency", "cql.consistency",
2264 FT_UINT16
, BASE_HEX
,
2265 VALS(cql_consistency_names
), 0x0,
2266 "CQL consistency level specification", HFILL
2270 &hf_cql_value_count
,
2272 "Value count", "cql.value_count",
2273 FT_UINT16
, BASE_DEC
,
2275 "Number of subsequent values", HFILL
2279 &hf_cql_bytes_length
,
2281 "Bytes length", "cql.bytes_length.int",
2284 "Number of subsequent bytes", HFILL
2288 &hf_cql_short_bytes_length
,
2290 "Bytes length", "cql.bytes_length.short",
2291 FT_UINT16
, BASE_DEC
,
2293 "Number of subsequent bytes", HFILL
2298 "Bytes", "cql.bytes",
2299 FT_BYTES
, BASE_NONE
,
2301 "Raw byte array", HFILL
2307 "Bigint", "cql.bigint",
2316 "Scale", "cql.scale",
2325 "Ascii", "cql.ascii",
2326 FT_STRING
, BASE_NONE
,
2328 "An Ascii string", HFILL
2334 "Double float", "cql.double",
2335 FT_DOUBLE
, BASE_NONE
,
2343 "Float", "cql.float",
2344 FT_FLOAT
, BASE_NONE
,
2359 &hf_cql_varint_count8
,
2361 "Varint", "cql.varint",
2368 &hf_cql_varint_count16
,
2370 "Varint", "cql.varint",
2371 FT_UINT16
, BASE_DEC
,
2377 &hf_cql_varint_count32
,
2379 "Varint", "cql.varint",
2380 FT_UINT32
, BASE_DEC
,
2386 &hf_cql_varint_count64
,
2388 "Varint", "cql.varint64",
2389 FT_UINT64
, BASE_DEC
,
2397 "Varchar", "cql.varchar",
2398 FT_STRING
, BASE_NONE
,
2406 "Time Uuid", "cql.timeuuid",
2415 "Custom", "cql.custom",
2416 FT_STRING
, BASE_NONE
,
2418 "A custom field", HFILL
2424 "NULL value", "cql.null_value",
2427 "A NULL value", HFILL
2431 &hf_cql_raw_compressed_bytes
,
2433 "Raw compressed bytes", "cql.raw_compressed_bytes",
2434 FT_BYTES
, BASE_NONE
,
2436 "Raw byte that failed to be decompressed", HFILL
2441 &hf_cql_paging_state
,
2443 "Paging State", "cql.paging_state",
2444 FT_BYTES
, BASE_NONE
,
2446 "Paging state byte array", HFILL
2452 "Page size", "cql.page_size",
2455 "Desired page size of result (in CQL3 rows)", HFILL
2459 &hf_cql_response_in
,
2461 "Response in", "cql.response_in",
2462 FT_FRAMENUM
, BASE_NONE
,
2463 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x0,
2464 "The response to this CQL request is in this frame", HFILL
2468 &hf_cql_response_to
,
2470 "Request in", "cql.response_to",
2471 FT_FRAMENUM
, BASE_NONE
,
2472 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x0,
2473 "This is a response to the CQL request in this fame", HFILL
2477 &hf_cql_response_time
,
2479 "Response time", "cql.response_time",
2480 FT_RELATIVE_TIME
, BASE_NONE
,
2482 "The time between the request and the response", HFILL
2488 "Timestamp", "cql.timestamp",
2489 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
2497 "Query ID", "cql.query_id",
2498 FT_BYTES
, BASE_NONE
,
2500 "CQL query id resulting from a PREPARE statement", HFILL
2506 "Event Type", "cql.event_type",
2507 FT_STRING
, BASE_NONE
,
2509 "CQL Event Type", HFILL
2513 &hf_cql_event_schema_change_type
,
2515 "Schema change type", "cql.schema_change_type",
2516 FT_STRING
, BASE_NONE
,
2518 "CQL Schema Change Type", HFILL
2522 &hf_cql_event_schema_change_type_target
,
2524 "Schema change target", "cql.schema_change_target",
2525 FT_STRING
, BASE_NONE
,
2527 "CQL Schema Change target object", HFILL
2531 &hf_cql_event_schema_change_object
,
2533 "Schema change event object name", "cql.schema_change_object_name",
2534 FT_STRING
, BASE_NONE
,
2536 "CQL Schema Change object name", HFILL
2540 &hf_cql_event_schema_change_keyspace
,
2542 "Schema change event keyspace name", "cql.schema_change_keyspace",
2543 FT_STRING
, BASE_NONE
,
2545 "CQL Schema Change keyspace name", HFILL
2549 &hf_cql_batch_query_size
,
2551 "Batch Query Size", "cql.batch_query_size",
2552 FT_UINT16
, BASE_DEC
,
2554 "Number of statements in CQL batch", HFILL
2560 "Error Code", "cql.error_code",
2561 FT_UINT32
, BASE_HEX
,
2562 VALS(cql_error_names
), 0x0,
2563 "Error code from CQL server", HFILL
2567 &hf_cql_result_kind
,
2569 "Result Kind", "cql.result.kind",
2571 VALS(cql_result_kind_names
), 0x0,
2572 "Kind of result from CQL server", HFILL
2576 &hf_cql_result_rows_column_count
,
2578 "Column Count", "cql.result.rows.column_count",
2581 "Count of columns in a rows result from CQL server", HFILL
2585 &hf_cql_result_prepared_pk_count
,
2587 "PK Count", "cql.result.prepared.pk_count",
2590 "Count of Partition Key columns in a Prepared result from CQL server", HFILL
2594 &hf_cql_result_rows_tuple_size
,
2596 "Tuple Size", "cql.result.rows.tuple_size",
2597 FT_UINT16
, BASE_DEC
,
2599 "Size of a tuple rows result from CQL server", HFILL
2603 &hf_cql_result_timestamp
,
2605 "Timestamp (Epoch Time)", "cql.result.timestamp",
2608 "Timestamp result", HFILL
2612 &hf_cql_result_rows_data_type
,
2614 "CQL Data Type", "cql.data_type",
2615 FT_UINT16
, BASE_DEC
,
2616 VALS(cql_result_row_type_names
), 0x0,
2621 &hf_cql_result_rows_row_count
,
2623 "CQL Result Rows Count", "cql.result.rows.row_count",
2626 "Number of rows returned in CQL result", HFILL
2639 &hf_cql_tracing_uuid
,
2641 "Tracing UUID", "cql.tracing_uuid",
2651 FT_UINT32
, BASE_DEC
,
2659 "Boolean", "cql.boolean",
2660 FT_BOOLEAN
, BASE_NONE
,
2685 static ei_register_info ei
[] = {
2686 { &ei_cql_data_not_dissected_yet
,
2687 { "cql.ie_data_not_dissected_yet",
2688 PI_UNDECODED
, PI_WARN
, "IE data not dissected yet", EXPFILL
}},
2689 { &ei_cql_unexpected_negative_value
,
2690 { "cql.unexpected_negative_value",
2691 PI_UNDECODED
, PI_ERROR
, "Unexpected negative value", EXPFILL
}},
2694 static int* ett
[] = {
2698 &ett_cql_result_columns
,
2699 &ett_cql_results_no_metadata
,
2700 &ett_cql_result_map
,
2701 &ett_cql_result_set
,
2702 &ett_cql_result_metadata
,
2703 &ett_cql_result_metadata_colspec
,
2704 &ett_cql_result_rows
,
2705 &ett_cql_header_flags_bitmap
,
2706 &ett_cql_query_flags_bitmap
,
2707 &ett_cql_batch_flags_bitmap
,
2708 &ett_cql_custom_payload
2711 proto_cql
= proto_register_protocol("Cassandra CQL Protocol", "CQL", "cql" );
2712 register_dissector("cql", dissect_cql_tcp
, proto_cql
);
2714 proto_register_field_array(proto_cql
, hf
, array_length(hf
));
2715 proto_register_subtree_array(ett
, array_length(ett
));
2717 expert_cql
= expert_register_protocol(proto_cql
);
2718 expert_register_field_array(expert_cql
, ei
, array_length(ei
));
2722 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2727 * indent-tabs-mode: t
2730 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2731 * :indentSize=8:tabSize=8:noTabs=false: