2 * Routines for Scylla RPC dissection
3 * Copyright 2020 ScyllaDB, Piotr Sarna <sarna@scylladb.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 * ScyllaDB RPC protocol is used for inter-node communication
14 * in the ScyllaDB database - reading/sending data, exchanging
15 * cluster information through gossip, updating schemas, etc.
17 * Protocol references:
18 * https://github.com/scylladb/seastar/blob/master/doc/rpc.md
19 * https://github.com/scylladb/scylla/blob/master/message/messaging_service.hh
25 #include <epan/expert.h>
26 #include <epan/packet.h>
27 #include <epan/prefs.h>
28 #include "packet-tcp.h"
30 void proto_reg_handoff_scylla(void);
31 void proto_register_scylla(void);
33 static dissector_handle_t scylla_handle
;
35 #define SCYLLA_PORT 0 /* Not IANA registered, 7000 is the expected value */
37 #define SCYLLA_HEADER_SIZE 28
38 #define SCYLLA_HEADER_VERB_OFFSET 8
39 #define SCYLLA_HEADER_MSG_ID_OFFSET 16
40 #define SCYLLA_HEADER_LEN_OFFSET 24
42 #define SCYLLA_RESPONSE_SIZE 12
43 #define SCYLLA_RESPONSE_MSG_ID_OFFSET 0
44 #define SCYLLA_RESPONSE_LEN_OFFSET 8
46 #define SCYLLA_NEGOTIATION_SIZE 12
47 #define SCYLLA_NEGOTIATION_LEN_OFFSET 8
49 static int proto_scylla
;
51 static int hf_scylla_request
;
52 static int hf_scylla_request_response_frame
;
53 static int hf_scylla_timeout
;
54 static int hf_scylla_verb
;
55 static int hf_scylla_msg_id
;
56 static int hf_scylla_len
;
57 static int hf_scylla_response
;
58 static int hf_scylla_response_size
;
59 static int hf_scylla_response_request_frame
;
60 static int hf_scylla_negotiation_magic
;
61 static int hf_scylla_negotiation_size
;
62 static int hf_scylla_payload
; // TODO: dissect everything, so that generic "payload" is not needed
65 static int hf_scylla_mut_size1
;
66 static int hf_scylla_mut_size2
;
67 static int hf_scylla_mut_table_id
;
68 static int hf_scylla_mut_schema_id
;
69 static int hf_scylla_mut_len_pkeys
;
70 static int hf_scylla_mut_num_pkeys
;
71 static int hf_scylla_mut_len_pkey
;
72 static int hf_scylla_mut_pkey
;
75 static int hf_scylla_read_data_timeout
;
76 static int hf_scylla_read_data_table_id
;
77 static int hf_scylla_read_data_schema_version
;
79 static int ett_scylla
;
80 static int ett_scylla_header
;
81 static int ett_scylla_response
;
82 static int ett_scylla_negotiation
;
83 static int ett_scylla_mut
;
84 static int ett_scylla_mut_pkey
;
85 static int ett_scylla_read_data
;
87 static bool scylla_desegment
= true;
89 static expert_field ei_scylla_response_missing
;
96 READ_MUTATION_DATA
= 4,
99 GOSSIP_DIGEST_SYN
= 6,
100 GOSSIP_DIGEST_ACK
= 7,
101 GOSSIP_DIGEST_ACK2
= 8,
103 GOSSIP_SHUTDOWN
= 10,
104 // end of gossip verb
105 DEFINITIONS_UPDATE
= 11,
107 REPLICATION_FINISHED
= 13,
108 MIGRATION_REQUEST
= 14,
110 PREPARE_MESSAGE
= 15,
111 PREPARE_DONE_MESSAGE
= 16,
112 STREAM_MUTATION
= 17,
113 STREAM_MUTATION_DONE
= 18,
114 COMPLETE_MESSAGE
= 19,
115 // end of streaming verbs
116 REPAIR_CHECKSUM_RANGE
= 20,
117 GET_SCHEMA_VERSION
= 21,
119 COUNTER_MUTATION
= 23,
120 MUTATION_FAILED
= 24,
121 STREAM_MUTATION_FRAGMENTS
= 25,
122 REPAIR_ROW_LEVEL_START
= 26,
123 REPAIR_ROW_LEVEL_STOP
= 27,
124 REPAIR_GET_FULL_ROW_HASHES
= 28,
125 REPAIR_GET_COMBINED_ROW_HASH
= 29,
126 REPAIR_GET_SYNC_BOUNDARY
= 30,
127 REPAIR_GET_ROW_DIFF
= 31,
128 REPAIR_PUT_ROW_DIFF
= 32,
129 REPAIR_GET_ESTIMATED_PARTITIONS
= 33,
130 REPAIR_SET_ESTIMATED_PARTITIONS
= 34,
131 REPAIR_GET_DIFF_ALGORITHMS
= 35,
132 REPAIR_GET_ROW_DIFF_WITH_RPC_STREAM
= 36,
133 REPAIR_PUT_ROW_DIFF_WITH_RPC_STREAM
= 37,
134 REPAIR_GET_FULL_ROW_HASHES_WITH_RPC_STREAM
= 38,
143 static const val64_string packettypenames
[] = {
144 {CLIENT_ID
, "CLIENT_ID"},
145 {MUTATION
, "MUTATION"},
146 {MUTATION_DONE
, "MUTATION_DONE"},
147 {READ_DATA
, "READ_DATA"},
148 {READ_MUTATION_DATA
, "READ_MUTATION_DATA"},
149 {READ_DIGEST
, "READ_DIGEST"},
150 {GOSSIP_DIGEST_SYN
, "GOSSIP_DIGEST_SYN"},
151 {GOSSIP_DIGEST_ACK
, "GOSSIP_DIGEST_ACK"},
152 {GOSSIP_DIGEST_ACK2
, "GOSSIP_DIGEST_ACK2"},
153 {GOSSIP_ECHO
, "GOSSIP_ECHO"},
154 {GOSSIP_SHUTDOWN
, "GOSSIP_SHUTDOWN"},
155 {DEFINITIONS_UPDATE
, "DEFINITIONS_UPDATE"},
156 {TRUNCATE
, "TRUNCATE"},
157 {REPLICATION_FINISHED
, "REPLICATION_FINISHED"},
158 {MIGRATION_REQUEST
, "MIGRATION_REQUEST"},
159 {PREPARE_MESSAGE
, "PREPARE_MESSAGE"},
160 {PREPARE_DONE_MESSAGE
, "PREPARE_DONE_MESSAGE"},
161 {STREAM_MUTATION
, "STREAM_MUTATION"},
162 {STREAM_MUTATION_DONE
, "STREAM_MUTATION_DONE"},
163 {COMPLETE_MESSAGE
, "COMPLETE_MESSAGE"},
164 {REPAIR_CHECKSUM_RANGE
, "REPAIR_CHECKSUM_RANGE"},
165 {GET_SCHEMA_VERSION
, "GET_SCHEMA_VERSION"},
166 {SCHEMA_CHECK
, "SCHEMA_CHECK"},
167 {COUNTER_MUTATION
, "COUNTER_MUTATION"},
168 {MUTATION_FAILED
, "MUTATION_FAILED"},
169 {STREAM_MUTATION_FRAGMENTS
, "STREAM_MUTATION_FRAGMENTS"},
170 {REPAIR_ROW_LEVEL_START
, "REPAIR_ROW_LEVEL_START"},
171 {REPAIR_ROW_LEVEL_STOP
, "REPAIR_ROW_LEVEL_STOP"},
172 {REPAIR_GET_FULL_ROW_HASHES
, "REPAIR_GET_FULL_ROW_HASHES"},
173 {REPAIR_GET_COMBINED_ROW_HASH
, "REPAIR_GET_COMBINED_ROW_HASH"},
174 {REPAIR_GET_SYNC_BOUNDARY
, "REPAIR_GET_SYNC_BOUNDARY"},
175 {REPAIR_GET_ROW_DIFF
, "REPAIR_GET_ROW_DIFF"},
176 {REPAIR_PUT_ROW_DIFF
, "REPAIR_PUT_ROW_DIFF"},
177 {REPAIR_GET_ESTIMATED_PARTITIONS
, "REPAIR_GET_ESTIMATED_PARTITIONS"},
178 {REPAIR_SET_ESTIMATED_PARTITIONS
, "REPAIR_SET_ESTIMATED_PARTITIONS"},
179 {REPAIR_GET_DIFF_ALGORITHMS
, "REPAIR_GET_DIFF_ALGORITHMS"},
180 {REPAIR_GET_ROW_DIFF_WITH_RPC_STREAM
, "REPAIR_GET_ROW_DIFF_WITH_RPC_STREAM"},
181 {REPAIR_PUT_ROW_DIFF_WITH_RPC_STREAM
, "REPAIR_PUT_ROW_DIFF_WITH_RPC_STREAM"},
182 {REPAIR_GET_FULL_ROW_HASHES_WITH_RPC_STREAM
, "REPAIR_GET_FULL_ROW_HASHES_WITH_RPC_STREAM"},
183 {PAXOS_PREPARE
, "PAXOS_PREPARE"},
184 {PAXOS_ACCEPT
, "PAXOS_ACCEPT"},
185 {PAXOS_LEARN
, "PAXOS_LEARN"},
186 {HINT_MUTATION
, "HINT_MUTATION"},
187 {PAXOS_PRUNE
, "PAXOS_PRUNE"},
192 looks_like_rpc_negotiation(tvbuff_t
*tvb
, const int offset
) {
193 return tvb_memeql(tvb
, offset
, (const uint8_t *)"SSTARRPC", 8) == 0;
197 looks_like_response(uint64_t verb_type
, uint32_t len
) {
198 return verb_type
>= LAST
|| len
> 64*1024*1024;
203 uint32_t request_frame_num
;
204 uint32_t response_frame_num
;
205 } request_response_t
;
208 get_scylla_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
210 uint64_t verb_type
= LAST
;
212 if (looks_like_rpc_negotiation(tvb
, offset
)) {
213 return tvb_get_letohl(tvb
, offset
+ SCYLLA_NEGOTIATION_LEN_OFFSET
) + SCYLLA_NEGOTIATION_SIZE
;
215 if (tvb_reported_length(tvb
) >= SCYLLA_HEADER_SIZE
) {
216 plen
= tvb_get_letohl(tvb
, offset
+ SCYLLA_HEADER_LEN_OFFSET
);
217 verb_type
= tvb_get_letoh64(tvb
, offset
+ SCYLLA_HEADER_VERB_OFFSET
);
220 if (looks_like_response(verb_type
, plen
)) {
221 return tvb_get_letohl(tvb
, offset
+ SCYLLA_RESPONSE_LEN_OFFSET
) + SCYLLA_RESPONSE_SIZE
;
223 return plen
+ SCYLLA_HEADER_SIZE
;
227 dissect_scylla_negotiation_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*scylla_tree
)
230 uint32_t len
= tvb_get_letohl(tvb
, offset
+ SCYLLA_NEGOTIATION_LEN_OFFSET
) + SCYLLA_NEGOTIATION_SIZE
;
232 proto_tree
*scylla_negotiation_tree
= proto_tree_add_subtree(scylla_tree
, tvb
, offset
,
233 len
, ett_scylla_negotiation
, NULL
, "Protocol negotiation");
234 proto_tree_add_item(scylla_negotiation_tree
, hf_scylla_negotiation_magic
, tvb
, offset
, 8, ENC_ASCII
);
235 int negotiation_offset
= 8;
236 proto_tree_add_item(scylla_negotiation_tree
, hf_scylla_negotiation_size
, tvb
, offset
+ negotiation_offset
, 4, ENC_LITTLE_ENDIAN
);
237 negotiation_offset
+= 4;
238 proto_tree_add_item(scylla_negotiation_tree
, hf_scylla_payload
, tvb
, offset
+ negotiation_offset
, len
- negotiation_offset
, ENC_NA
);
240 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Scylla");
241 col_set_str(pinfo
->cinfo
, COL_INFO
, "Protocol negotiation");
242 return tvb_reported_length(tvb
);
246 dissect_scylla_response_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*scylla_tree
, request_response_t
*req_resp
)
249 uint32_t len
= tvb_get_letohl(tvb
, offset
+ SCYLLA_RESPONSE_LEN_OFFSET
) + SCYLLA_RESPONSE_SIZE
;
251 /* Add response subtree */
252 proto_item
*response_ti
= proto_tree_add_string_format(scylla_tree
, hf_scylla_response
,
253 tvb
, offset
, len
, "", "Response");
254 proto_tree
*scylla_response_tree
= proto_item_add_subtree(response_ti
, ett_scylla_response
);
259 proto_tree_add_item_ret_uint64(scylla_response_tree
, hf_scylla_msg_id
, tvb
, offset
+ resp_offset
, 8, ENC_LITTLE_ENDIAN
, &msg_id
);
261 proto_tree_add_item(scylla_response_tree
, hf_scylla_response_size
, tvb
, offset
+ resp_offset
, 4, ENC_LITTLE_ENDIAN
);
263 proto_tree_add_item(scylla_response_tree
, hf_scylla_payload
, tvb
, offset
+ resp_offset
, len
- resp_offset
, ENC_NA
);
265 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Scylla");
267 /* Fill in the response frame */
268 req_resp
->response_frame_num
= pinfo
->num
;
270 proto_item
*verb_item
= proto_tree_add_uint64(scylla_response_tree
, hf_scylla_verb
, tvb
, offset
+ len
, 8, req_resp
->verb_type
);
271 proto_item_set_generated(verb_item
);
272 proto_item
*req
= proto_tree_add_uint(scylla_tree
, hf_scylla_response_request_frame
, tvb
, 0, 0, req_resp
->request_frame_num
);
273 proto_item_set_generated(req
);
275 proto_item_append_text(response_ti
, " (msg_id=%" PRIu64
", %s)",
276 msg_id
, val64_to_str(req_resp
->verb_type
, packettypenames
, "Unknown (0x%02x)"));
278 col_clear(pinfo
->cinfo
, COL_INFO
);
279 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Response for %s",
280 val64_to_str(req_resp
->verb_type
, packettypenames
, "Unknown (0x%02x)"));
282 col_set_str(pinfo
->cinfo
, COL_INFO
, "Response for unknown packet");
284 return tvb_reported_length(tvb
);
288 dissect_scylla_msg_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*scylla_tree
, proto_item
*ti
, uint64_t verb_type
, uint32_t len
, request_response_t
*req_resp
)
292 /* Add request subtree */
293 proto_item
*request_ti
= proto_tree_add_string_format(scylla_tree
, hf_scylla_request
,
294 tvb
, offset
, SCYLLA_HEADER_SIZE
,
296 val64_to_str(verb_type
, packettypenames
, "Unknown (0x%02x)"));
297 proto_tree
*scylla_header_tree
= proto_item_add_subtree(request_ti
, ett_scylla_response
);
299 proto_tree_add_item(scylla_header_tree
, hf_scylla_timeout
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
301 proto_item_append_text(ti
, ", Type %s", val64_to_str(verb_type
, packettypenames
, "Unknown (0x%02x)"));
302 proto_tree_add_item(scylla_header_tree
, hf_scylla_verb
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
305 proto_tree_add_item_ret_uint64(scylla_header_tree
, hf_scylla_msg_id
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
, &msg_id
);
307 proto_tree_add_item(scylla_header_tree
, hf_scylla_len
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
310 proto_item_append_text(request_ti
, " (msg_id=%" PRIu64
")", msg_id
);
314 proto_tree
* scylla_mut_tree
= proto_tree_add_subtree(scylla_tree
, tvb
, offset
,
315 len
, ett_scylla_mut
, NULL
, "Mutation");
319 proto_tree_add_item(scylla_mut_tree
, hf_scylla_mut_size1
, tvb
, offset
+ mut_offset
, 4, ENC_LITTLE_ENDIAN
);
321 proto_tree_add_item(scylla_mut_tree
, hf_scylla_mut_size2
, tvb
, offset
+ mut_offset
, 4, ENC_LITTLE_ENDIAN
);
323 proto_tree_add_item(scylla_mut_tree
, hf_scylla_mut_table_id
, tvb
, offset
+ mut_offset
, 16, ENC_NA
);
325 proto_tree_add_item(scylla_mut_tree
, hf_scylla_mut_schema_id
, tvb
, offset
+ mut_offset
, 16, ENC_NA
);
327 proto_tree_add_item_ret_uint(scylla_mut_tree
, hf_scylla_mut_len_pkeys
, tvb
, offset
+ mut_offset
, 4, ENC_LITTLE_ENDIAN
, &len_keys
);
329 proto_tree
* scylla_mut_pkey_tree
= proto_tree_add_subtree(scylla_mut_tree
, tvb
, offset
+ mut_offset
,
330 len
- mut_offset
, ett_scylla_mut_pkey
, NULL
, "Partition key");
331 proto_tree_add_item_ret_uint(scylla_mut_pkey_tree
, hf_scylla_mut_num_pkeys
, tvb
, offset
+ mut_offset
, 4, ENC_LITTLE_ENDIAN
, &num_keys
);
334 for (i
= 0; i
< num_keys
; ++i
) {
335 uint32_t len_pkey
= tvb_get_letohl(tvb
, offset
+ mut_offset
);
336 proto_tree_add_item(scylla_mut_pkey_tree
, hf_scylla_mut_len_pkey
, tvb
, offset
+ mut_offset
, 4, ENC_LITTLE_ENDIAN
);
338 proto_tree_add_item(scylla_mut_pkey_tree
, hf_scylla_mut_pkey
, tvb
, offset
+ mut_offset
, len_pkey
, ENC_NA
);
339 mut_offset
+= len_pkey
;
341 // TODO: dissect further
342 proto_tree_add_item(scylla_mut_tree
, hf_scylla_payload
, tvb
, offset
+ mut_offset
, len
- mut_offset
, ENC_NA
);
346 proto_tree
* scylla_read_tree
= proto_tree_add_subtree(scylla_tree
, tvb
, offset
,
347 len
, ett_scylla_read_data
, NULL
, "Read data");
350 proto_tree_add_item(scylla_read_tree
, hf_scylla_read_data_timeout
, tvb
, offset
+ rd_offset
, 4, ENC_LITTLE_ENDIAN
);
352 proto_tree_add_item(scylla_read_tree
, hf_scylla_read_data_table_id
, tvb
, offset
+ rd_offset
, 16, ENC_NA
);
354 proto_tree_add_item(scylla_read_tree
, hf_scylla_read_data_schema_version
, tvb
, offset
+ rd_offset
, 16, ENC_NA
);
356 //TODO: dissect further
357 proto_tree_add_item(scylla_read_tree
, hf_scylla_payload
, tvb
, offset
+ rd_offset
, len
- rd_offset
, ENC_NA
);
361 // Generic payload. TODO: dissect
362 proto_tree_add_item(scylla_tree
, hf_scylla_payload
, tvb
, offset
, len
, ENC_NA
);
366 /* req_resp will only be set if fd was already visited (PINFO_FD_VISITED(pinfo)) */
368 if (req_resp
->response_frame_num
> 0) {
369 proto_item
*rep
= proto_tree_add_uint(scylla_tree
, hf_scylla_request_response_frame
, tvb
, 0, 0, req_resp
->response_frame_num
);
370 proto_item_set_generated(rep
);
372 expert_add_info(pinfo
, request_ti
, &ei_scylla_response_missing
);
376 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Scylla");
377 col_clear(pinfo
->cinfo
, COL_INFO
);
378 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Request %s",
379 val64_to_str(verb_type
, packettypenames
, "Unknown (0x%02x)"));
380 return tvb_reported_length(tvb
);
384 response_expected(uint64_t verb_type
)
387 case GOSSIP_DIGEST_SYN
:
388 case GOSSIP_DIGEST_ACK
:
389 case GOSSIP_DIGEST_ACK2
:
390 case GOSSIP_SHUTDOWN
:
391 case DEFINITIONS_UPDATE
:
394 case MUTATION_FAILED
:
406 dissect_scylla_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
409 conversation_t
*conversation
;
410 wmem_map_t
*conv_map
;
412 proto_item
*ti
= proto_tree_add_item(tree
, proto_scylla
, tvb
, 0, -1, ENC_NA
);
413 proto_tree
*scylla_tree
= proto_item_add_subtree(ti
, ett_scylla
);
415 uint64_t verb_type
= LAST
;
418 if (looks_like_rpc_negotiation(tvb
, offset
)) {
419 return dissect_scylla_negotiation_pdu(tvb
, pinfo
, scylla_tree
);
422 if (tvb_reported_length(tvb
) >= SCYLLA_HEADER_SIZE
) {
423 verb_type
= tvb_get_letoh64(tvb
, offset
+ SCYLLA_HEADER_VERB_OFFSET
);
424 len
= tvb_get_letohl(tvb
, offset
+ SCYLLA_HEADER_LEN_OFFSET
);
427 conversation
= find_or_create_conversation(pinfo
);
428 conv_map
= (wmem_map_t
*)conversation_get_proto_data(conversation
, proto_scylla
);
429 if (conv_map
== NULL
) {
430 conv_map
= wmem_map_new(wmem_file_scope(), wmem_int64_hash
, g_int64_equal
);
431 conversation_add_proto_data(conversation
, proto_scylla
, conv_map
);
434 if (looks_like_response(verb_type
, len
)) {
437 msg_id
= tvb_get_letoh64(tvb
, offset
+ SCYLLA_RESPONSE_MSG_ID_OFFSET
);
438 req_resp
= wmem_map_lookup(conv_map
, &msg_id
);
439 return dissect_scylla_response_pdu(tvb
, pinfo
, scylla_tree
, (request_response_t
*)req_resp
);
442 uint64_t msg_id
= tvb_get_letoh64(tvb
, offset
+ SCYLLA_HEADER_MSG_ID_OFFSET
);
443 void *req_resp
= NULL
;
445 if (response_expected(verb_type
)) {
446 if (!PINFO_FD_VISITED(pinfo
)) {
447 uint64_t *key
= wmem_new(wmem_file_scope(), uint64_t);
448 request_response_t
*val
= wmem_new(wmem_file_scope(), request_response_t
);
450 val
->verb_type
= verb_type
;
451 val
->request_frame_num
= pinfo
->num
;
452 wmem_map_insert(conv_map
, key
, val
);
454 req_resp
= wmem_map_lookup(conv_map
, &msg_id
);
458 return dissect_scylla_msg_pdu(tvb
, pinfo
, scylla_tree
, ti
, verb_type
, len
, (request_response_t
*)req_resp
);
462 dissect_scylla(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
464 tcp_dissect_pdus(tvb
, pinfo
, tree
, scylla_desegment
, SCYLLA_NEGOTIATION_SIZE
,
465 get_scylla_pdu_len
, dissect_scylla_pdu
, data
);
466 return tvb_reported_length(tvb
);
470 proto_register_scylla(void)
472 static hf_register_info hf
[] = {
474 { &hf_scylla_request
, { "request", "scylla.request", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
475 { &hf_scylla_request_response_frame
, { "Response frame", "scylla.request.response", FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x0, NULL
, HFILL
} },
476 { &hf_scylla_timeout
, { "RPC timeout", "scylla.timeout", FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
477 { &hf_scylla_verb
, { "verb", "scylla.verb", FT_UINT64
, BASE_DEC
|BASE_VAL64_STRING
, VALS64(packettypenames
), 0x0, NULL
, HFILL
} },
478 { &hf_scylla_msg_id
, { "msg id", "scylla.msg_id", FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
479 { &hf_scylla_len
, { "packet length", "scylla.len", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
480 { &hf_scylla_payload
, { "payload", "scylla.payload", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
481 { &hf_scylla_response
, { "response", "scylla.response", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
482 { &hf_scylla_response_size
, { "response size", "scylla.response.size", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
483 { &hf_scylla_response_request_frame
, { "Request frame", "scylla.response.request", FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x0, NULL
, HFILL
} },
484 { &hf_scylla_negotiation_magic
, { "negotiation magic sequence", "scylla.negotiation.magic", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
485 { &hf_scylla_negotiation_size
, { "negotiation size", "scylla.negotiation.size", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
487 { &hf_scylla_mut_size1
, { "mutation size 1", "scylla.mut.size1", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
488 { &hf_scylla_mut_size2
, { "mutation size 2", "scylla.mut.size2", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
489 { &hf_scylla_mut_table_id
, { "mutation table id", "scylla.mut.table_id", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
490 { &hf_scylla_mut_schema_id
, { "mutation schema id", "scylla.mut.schema_id", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
491 { &hf_scylla_mut_len_pkeys
, { "size of partition keys payload", "scylla.mut.len_pkeys", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
492 { &hf_scylla_mut_num_pkeys
, { "number of partition keys", "scylla.mut.num_pkeys", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
493 { &hf_scylla_mut_len_pkey
, { "length of a partition key", "scylla.mut.len_pkey", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
494 { &hf_scylla_mut_pkey
, { "partition key", "scylla.mut.pkey", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
496 { &hf_scylla_read_data_timeout
, { "timeout", "scylla.read_data.timeout", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
497 { &hf_scylla_read_data_table_id
, { "table ID", "scylla.read_data.table_id", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
498 { &hf_scylla_read_data_schema_version
, { "Schema version", "scylla.read_data.schema_version", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
502 static ei_register_info ei
[] = {
503 { &ei_scylla_response_missing
,
504 { "scylla.ei_scylla_response_missing",
505 PI_COMMENTS_GROUP
, PI_NOTE
, "Response has not arrived yet", EXPFILL
}},
508 /* Setup protocol subtree array */
509 static int *ett
[] = {
512 &ett_scylla_response
,
513 &ett_scylla_negotiation
,
515 &ett_scylla_mut_pkey
,
516 &ett_scylla_read_data
,
519 expert_module_t
* expert_scylla
;
521 proto_scylla
= proto_register_protocol("Scylla RPC protocol", "Scylla", "scylla");
522 module_t
* scylla_module
= prefs_register_protocol(proto_scylla
, NULL
);
523 prefs_register_bool_preference(scylla_module
, "desegment",
524 "Desegment all Scylla messages spanning multiple TCP segments",
525 "Whether Scylla dissector should desegment all messages spanning multiple TCP segments",
528 proto_register_field_array(proto_scylla
, hf
, array_length(hf
));
529 proto_register_subtree_array(ett
, array_length(ett
));
530 expert_scylla
= expert_register_protocol(proto_scylla
);
531 expert_register_field_array(expert_scylla
, ei
, array_length(ei
));
533 scylla_handle
= register_dissector("scylla", dissect_scylla
, proto_scylla
);
537 proto_reg_handoff_scylla(void)
539 dissector_add_uint_with_preference("tcp.port", SCYLLA_PORT
, scylla_handle
);
543 * Editor modelines - https://www.wireshark.org/tools/modelines.html
548 * indent-tabs-mode: nil
551 * vi: set shiftwidth=4 tabstop=8 expandtab:
552 * :indentSize=4:tabSize=8:noTabs=true: