2 * Routines for CTDB (Cluster TDB) dissection
3 * Copyright 2007, Ronnie Sahlberg
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <epan/packet.h>
31 #include <epan/exceptions.h>
32 #include <epan/expert.h>
33 #include <epan/wmem/wmem.h>
35 void proto_register_ctdb(void);
36 void proto_reg_handoff_ctdb(void);
38 /* Initialize the protocol and registered fields */
39 static int proto_ctdb
= -1;
40 static int hf_ctdb_length
= -1;
41 static int hf_ctdb_opcode
= -1;
42 static int hf_ctdb_magic
= -1;
43 static int hf_ctdb_version
= -1;
44 static int hf_ctdb_dst
= -1;
45 static int hf_ctdb_src
= -1;
46 static int hf_ctdb_id
= -1;
47 static int hf_ctdb_flags_immediate
= -1;
48 static int hf_ctdb_dbid
= -1;
49 static int hf_ctdb_callid
= -1;
50 static int hf_ctdb_status
= -1;
51 static int hf_ctdb_keylen
= -1;
52 static int hf_ctdb_datalen
= -1;
53 static int hf_ctdb_errorlen
= -1;
54 static int hf_ctdb_key
= -1;
55 static int hf_ctdb_keyhash
= -1;
56 static int hf_ctdb_data
= -1;
57 static int hf_ctdb_error
= -1;
58 static int hf_ctdb_dmaster
= -1;
59 static int hf_ctdb_request_in
= -1;
60 static int hf_ctdb_response_in
= -1;
61 static int hf_ctdb_time
= -1;
62 static int hf_ctdb_generation
= -1;
63 static int hf_ctdb_hopcount
= -1;
64 static int hf_ctdb_rsn
= -1;
65 static int hf_ctdb_ctrl_opcode
= -1;
66 static int hf_ctdb_srvid
= -1;
67 static int hf_ctdb_clientid
= -1;
68 static int hf_ctdb_ctrl_flags
= -1;
69 static int hf_ctdb_recmaster
= -1;
70 static int hf_ctdb_recmode
= -1;
71 static int hf_ctdb_num_nodes
= -1;
72 static int hf_ctdb_vnn
= -1;
73 static int hf_ctdb_node_flags
= -1;
74 static int hf_ctdb_node_ip
= -1;
75 static int hf_ctdb_pid
= -1;
76 static int hf_ctdb_process_exists
= -1;
78 /* Initialize the subtree pointers */
79 static gint ett_ctdb
= -1;
80 static gint ett_ctdb_key
= -1;
82 static expert_field ei_ctdb_too_many_nodes
= EI_INIT
;
84 /* this tree keeps track of caller/reqid for ctdb transactions */
85 static wmem_tree_t
*ctdb_transactions
=NULL
;
86 typedef struct _ctdb_trans_t
{
93 /* this tree keeps track of CONTROL request/responses */
94 static wmem_tree_t
*ctdb_controls
=NULL
;
95 typedef struct _ctdb_control_t
{
102 #define CTDB_REQ_CALL 0
103 #define CTDB_REPLY_CALL 1
104 #define CTDB_REQ_DMASTER 2
105 #define CTDB_REPLY_DMASTER 3
106 #define CTDB_REPLY_ERROR 4
107 #define CTDB_REQ_MESSAGE 5
108 #define CTDB_REQ_CONTROL 7
109 #define CTDB_REPLY_CONTROL 8
110 #define CTDB_REQ_KEEPALIVE 9
111 static const value_string ctdb_opcodes
[] = {
112 {CTDB_REQ_CALL
, "REQ_CALL"},
113 {CTDB_REPLY_CALL
, "REPLY_CALL"},
114 {CTDB_REQ_DMASTER
, "REQ_DMASTER"},
115 {CTDB_REPLY_DMASTER
, "REPLY_DMASTER"},
116 {CTDB_REPLY_ERROR
, "REPLY_ERROR"},
117 {CTDB_REQ_MESSAGE
, "REQ_MESSAGE"},
118 {CTDB_REQ_CONTROL
, "REQ_CONTROL"},
119 {CTDB_REPLY_CONTROL
, "REPLY_CONTROL"},
120 {CTDB_REQ_KEEPALIVE
, "REQ_KEEPALIVE"},
125 #define CTDB_CONTROL_PROCESS_EXISTS 0
126 #define CTDB_CONTROL_STATISTICS 1
127 #define CTDB_CONTROL_CONFIG 2
128 #define CTDB_CONTROL_PING 3
129 #define CTDB_CONTROL_GETDBPATH 4
130 #define CTDB_CONTROL_GETVNNMAP 5
131 #define CTDB_CONTROL_SETVNNMAP 6
132 #define CTDB_CONTROL_GET_DEBUG 7
133 #define CTDB_CONTROL_SET_DEBUG 8
134 #define CTDB_CONTROL_GET_DBMAP 9
135 #define CTDB_CONTROL_GET_NODEMAP 10
136 #define CTDB_CONTROL_SET_DMASTER 11
137 #define CTDB_CONTROL_CLEAR_DB 12
138 #define CTDB_CONTROL_PULL_DB 13
139 #define CTDB_CONTROL_PUSH_DB 14
140 #define CTDB_CONTROL_GET_RECMODE 15
141 #define CTDB_CONTROL_SET_RECMODE 16
142 #define CTDB_CONTROL_STATISTICS_RESET 17
143 #define CTDB_CONTROL_DB_ATTACH 18
144 #define CTDB_CONTROL_SET_CALL 19
145 #define CTDB_CONTROL_TRAVERSE_START 20
146 #define CTDB_CONTROL_TRAVERSE_ALL 21
147 #define CTDB_CONTROL_TRAVERSE_DATA 22
148 #define CTDB_CONTROL_REGISTER_SRVID 23
149 #define CTDB_CONTROL_DEREGISTER_SRVID 24
150 #define CTDB_CONTROL_GET_DBNAME 25
151 #define CTDB_CONTROL_ENABLE_SEQNUM 26
152 #define CTDB_CONTROL_UPDATE_SEQNUM 27
153 #define CTDB_CONTROL_SET_SEQNUM_FREQUENCY 28
154 #define CTDB_CONTROL_DUMP_MEMORY 29
155 #define CTDB_CONTROL_GET_PID 30
156 #define CTDB_CONTROL_GET_RECMASTER 31
157 #define CTDB_CONTROL_SET_RECMASTER 32
158 #define CTDB_CONTROL_FREEZE 33
159 #define CTDB_CONTROL_THAW 34
160 #define CTDB_CONTROL_GET_VNN 35
161 #define CTDB_CONTROL_SHUTDOWN 36
162 #define CTDB_CONTROL_GET_MONMODE 37
163 #define CTDB_CONTROL_SET_MONMODE 38
164 #define CTDB_CONTROL_MAX_RSN 39
165 #define CTDB_CONTROL_SET_RSN_NONEMPTY 40
166 #define CTDB_CONTROL_DELETE_LOW_RSN 41
167 #define CTDB_CONTROL_TAKEOVER_IP 42
168 #define CTDB_CONTROL_RELEASE_IP 43
169 #define CTDB_CONTROL_TCP_CLIENT 44
170 #define CTDB_CONTROL_TCP_ADD 45
171 #define CTDB_CONTROL_TCP_REMOVE 46
172 #define CTDB_CONTROL_STARTUP 47
173 #define CTDB_CONTROL_SET_TUNABLE 48
174 #define CTDB_CONTROL_GET_TUNABLE 49
175 #define CTDB_CONTROL_LIST_TUNABLES 50
176 #define CTDB_CONTROL_GET_PUBLIC_IPS 51
177 #define CTDB_CONTROL_MODIFY_FLAGS 52
178 #define CTDB_CONTROL_GET_ALL_TUNABLES 53
179 #define CTDB_CONTROL_KILL_TCP 54
180 #define CTDB_CONTROL_GET_TCP_TICKLE_LIST 55
181 #define CTDB_CONTROL_SET_TCP_TICKLE_LIST 56
182 #define CTDB_CONTROL_REGISTER_SERVER_ID 57
183 #define CTDB_CONTROL_UNREGISTER_SERVER_ID 58
184 #define CTDB_CONTROL_CHECK_SERVER_ID 59
185 #define CTDB_CONTROL_GET_SERVER_ID_LIST 60
186 #define CTDB_CONTROL_DB_ATTACH_PERSISTENT 61
187 #define CTDB_CONTROL_PERSISTENT_STORE 62
188 #define CTDB_CONTROL_UPDATE_RECORD 63
190 static const value_string ctrl_opcode_vals
[] = {
191 {CTDB_CONTROL_PROCESS_EXISTS
, "PROCESS_EXISTS"},
192 {CTDB_CONTROL_STATISTICS
, "STATISTICS"},
193 {CTDB_CONTROL_CONFIG
, "CONFIG"},
194 {CTDB_CONTROL_PING
, "PING"},
195 {CTDB_CONTROL_GETDBPATH
, "GETDBPATH"},
196 {CTDB_CONTROL_GETVNNMAP
, "GETVNNMAP"},
197 {CTDB_CONTROL_SETVNNMAP
, "SETVNNMAP"},
198 {CTDB_CONTROL_GET_DEBUG
, "GET_DEBUG"},
199 {CTDB_CONTROL_SET_DEBUG
, "SET_DEBUG"},
200 {CTDB_CONTROL_GET_DBMAP
, "GET_DBMAP"},
201 {CTDB_CONTROL_GET_NODEMAP
, "GET_NODEMAP"},
202 {CTDB_CONTROL_SET_DMASTER
, "SET_DMASTER"},
203 {CTDB_CONTROL_CLEAR_DB
, "CLEAR_DB"},
204 {CTDB_CONTROL_PULL_DB
, "PULL_DB"},
205 {CTDB_CONTROL_PUSH_DB
, "PUSH_DB"},
206 {CTDB_CONTROL_GET_RECMODE
, "GET_RECMODE"},
207 {CTDB_CONTROL_SET_RECMODE
, "SET_RECMODE"},
208 {CTDB_CONTROL_STATISTICS_RESET
, "STATISTICS_RESET"},
209 {CTDB_CONTROL_DB_ATTACH
, "DB_ATTACH"},
210 {CTDB_CONTROL_SET_CALL
, "SET_CALL"},
211 {CTDB_CONTROL_TRAVERSE_START
, "TRAVERSE_START"},
212 {CTDB_CONTROL_TRAVERSE_ALL
, "TRAVERSE_ALL"},
213 {CTDB_CONTROL_TRAVERSE_DATA
, "TRAVERSE_DATA"},
214 {CTDB_CONTROL_REGISTER_SRVID
, "REGISTER_SRVID"},
215 {CTDB_CONTROL_DEREGISTER_SRVID
, "DEREGISTER_SRVID"},
216 {CTDB_CONTROL_GET_DBNAME
, "GET_DBNAME"},
217 {CTDB_CONTROL_ENABLE_SEQNUM
, "ENABLE_SEQNUM"},
218 {CTDB_CONTROL_UPDATE_SEQNUM
, "UPDATE_SEQNUM"},
219 {CTDB_CONTROL_SET_SEQNUM_FREQUENCY
, "SET_SEQNUM_FREQUENCY"},
220 {CTDB_CONTROL_DUMP_MEMORY
, "DUMP_MEMORY"},
221 {CTDB_CONTROL_GET_PID
, "GET_PID"},
222 {CTDB_CONTROL_GET_RECMASTER
, "GET_RECMASTER"},
223 {CTDB_CONTROL_SET_RECMASTER
, "SET_RECMASTER"},
224 {CTDB_CONTROL_FREEZE
, "FREEZE"},
225 {CTDB_CONTROL_THAW
, "THAW"},
226 {CTDB_CONTROL_GET_VNN
, "GET_VNN"},
227 {CTDB_CONTROL_SHUTDOWN
, "SHUTDOWN"},
228 {CTDB_CONTROL_GET_MONMODE
, "GET_MONMODE"},
229 {CTDB_CONTROL_SET_MONMODE
, "SET_MONMODE"},
230 {CTDB_CONTROL_MAX_RSN
, "MAX_RSN"},
231 {CTDB_CONTROL_SET_RSN_NONEMPTY
, "SET_RSN_NONEMPTY"},
232 {CTDB_CONTROL_DELETE_LOW_RSN
, "DELETE_LOW_RSN"},
233 {CTDB_CONTROL_TAKEOVER_IP
, "TAKEOVER_IP"},
234 {CTDB_CONTROL_RELEASE_IP
, "RELEASE_IP"},
235 {CTDB_CONTROL_TCP_CLIENT
, "TCP_CLIENT"},
236 {CTDB_CONTROL_TCP_ADD
, "TCP_ADD"},
237 {CTDB_CONTROL_TCP_REMOVE
, "TCP_REMOVE"},
238 {CTDB_CONTROL_STARTUP
, "STARTUP"},
239 {CTDB_CONTROL_SET_TUNABLE
, "SET_TUNABLE"},
240 {CTDB_CONTROL_GET_TUNABLE
, "GET_TUNABLE"},
241 {CTDB_CONTROL_LIST_TUNABLES
, "LIST_TUNABLES"},
242 {CTDB_CONTROL_GET_PUBLIC_IPS
, "GET_PUBLIC_IPS"},
243 {CTDB_CONTROL_MODIFY_FLAGS
, "MODIFY_FLAGS"},
244 {CTDB_CONTROL_GET_ALL_TUNABLES
, "GET_ALL_TUNABLES"},
245 {CTDB_CONTROL_KILL_TCP
, "KILL_TCP"},
246 {CTDB_CONTROL_GET_TCP_TICKLE_LIST
, "GET_TCP_TICKLE_LIST"},
247 {CTDB_CONTROL_SET_TCP_TICKLE_LIST
, "SET_TCP_TICKLE_LIST"},
248 {CTDB_CONTROL_REGISTER_SERVER_ID
, "REGISTER_SERVER_ID"},
249 {CTDB_CONTROL_UNREGISTER_SERVER_ID
, "UNREGISTER_SERVER_ID"},
250 {CTDB_CONTROL_CHECK_SERVER_ID
, "CHECK_SERVER_ID"},
251 {CTDB_CONTROL_GET_SERVER_ID_LIST
, "GET_SERVER_ID_LIST"},
252 {CTDB_CONTROL_DB_ATTACH_PERSISTENT
, "DB_ATTACH_PERSISTENT"},
253 {CTDB_CONTROL_PERSISTENT_STORE
, "PERSISTENT_STORE"},
254 {CTDB_CONTROL_UPDATE_RECORD
, "UPDATE_RECORD"},
260 static int dissect_control_get_recmaster_reply(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint32 status
, int endianess _U_
)
262 proto_tree_add_uint(tree
, hf_ctdb_recmaster
, tvb
, 0, 0, status
);
264 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " RecMaster:%d", status
);
269 static const value_string recmode_vals
[] = {
271 {1,"RECOVERY ACTIVE"},
275 static int dissect_control_get_recmode_reply(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint32 status
, int endianess _U_
)
277 proto_tree_add_uint(tree
, hf_ctdb_recmode
, tvb
, 0, 0, status
);
279 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " RecMode:%s",
280 val_to_str(status
, recmode_vals
, "Unknown:%d"));
285 #define CTDB_MAX_NODES 500 /* Arbitrary. */
286 static int dissect_control_get_nodemap_reply(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint32 status _U_
, int endianess
)
292 item
= proto_tree_add_item(tree
, hf_ctdb_num_nodes
, tvb
, offset
, 4, endianess
);
294 num_nodes
=tvb_get_letohl(tvb
, offset
);
296 num_nodes
=tvb_get_ntohl(tvb
, offset
);
300 if (num_nodes
> CTDB_MAX_NODES
) {
301 expert_add_info_format(pinfo
, item
, &ei_ctdb_too_many_nodes
, "Too many nodes (%u). Stopping dissection.", num_nodes
);
302 THROW(ReportedBoundsError
);
307 proto_tree_add_item(tree
, hf_ctdb_vnn
, tvb
, offset
, 4, endianess
);
311 proto_tree_add_item(tree
, hf_ctdb_node_flags
, tvb
, offset
, 4, endianess
);
314 /* here comes a sockaddr_in but we only store ipv4 addresses in it */
315 proto_tree_add_item(tree
, hf_ctdb_node_ip
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
322 static int dissect_control_process_exist_request(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint32 status _U_
, int endianess
)
327 proto_tree_add_item(tree
, hf_ctdb_pid
, tvb
, offset
, 4, endianess
);
329 pid
=tvb_get_letohl(tvb
, offset
);
331 pid
=tvb_get_ntohl(tvb
, offset
);
335 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " pid:%d", pid
);
340 static const true_false_string process_exists_tfs
= {
341 "Process does NOT exist",
345 static int dissect_control_process_exist_reply(packet_info
*pinfo _U_
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint32 status
, int endianess _U_
)
347 proto_tree_add_boolean(tree
, hf_ctdb_process_exists
, tvb
, offset
, 4, status
);
351 /* This defines the array of dissectors for request/reply controls */
352 typedef int (*control_dissector
)(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint32 status
, int endianess
);
354 typedef struct _control_dissector_array_t
{
356 control_dissector request_dissector
;
357 control_dissector reply_dissector
;
358 } control_dissector_array_t
;
360 static control_dissector_array_t control_dissectors
[] = {
361 {CTDB_CONTROL_GET_RECMASTER
,
363 dissect_control_get_recmaster_reply
},
364 {CTDB_CONTROL_GET_RECMODE
,
366 dissect_control_get_recmode_reply
},
367 {CTDB_CONTROL_GET_NODEMAP
,
369 dissect_control_get_nodemap_reply
},
370 {CTDB_CONTROL_FREEZE
,
376 {CTDB_CONTROL_PROCESS_EXISTS
,
377 dissect_control_process_exist_request
,
378 dissect_control_process_exist_reply
},
380 /*CTDB_CONTROL_STATISTICS*/
381 /*CTDB_CONTROL_CONFIG*/
382 /*CTDB_CONTROL_PING*/
383 /*CTDB_CONTROL_GETDBPATH*/
384 /*CTDB_CONTROL_GETVNNMAP*/
385 /*CTDB_CONTROL_SETVNNMAP*/
386 /*CTDB_CONTROL_GET_DEBUG*/
387 /*CTDB_CONTROL_SET_DEBUG*/
388 /*CTDB_CONTROL_GET_DBMAP*/
389 /*CTDB_CONTROL_SET_DMASTER*/
390 /*CTDB_CONTROL_CLEAR_DB*/
391 /*CTDB_CONTROL_PULL_DB*/
392 /*CTDB_CONTROL_PUSH_DB*/
393 /*CTDB_CONTROL_SET_RECMODE*/
394 /*CTDB_CONTROL_STATISTICS_RESET*/
395 /*CTDB_CONTROL_DB_ATTACH*/
396 /*CTDB_CONTROL_SET_CALL*/
397 /*CTDB_CONTROL_TRAVERSE_START*/
398 /*CTDB_CONTROL_TRAVERSE_ALL*/
399 /*CTDB_CONTROL_TRAVERSE_DATA*/
400 /*CTDB_CONTROL_REGISTER_SRVID*/
401 /*CTDB_CONTROL_DEREGISTER_SRVID*/
402 /*CTDB_CONTROL_GET_DBNAME*/
403 /*CTDB_CONTROL_ENABLE_SEQNUM*/
404 /*CTDB_CONTROL_UPDATE_SEQNUM*/
405 /*CTDB_CONTROL_SET_SEQNUM_FREQUENCY*/
406 /*CTDB_CONTROL_DUMP_MEMORY*/
407 /*CTDB_CONTROL_GET_PID*/
408 /*CTDB_CONTROL_SET_RECMASTER*/
409 /*CTDB_CONTROL_GET_VNN*/
410 /*CTDB_CONTROL_SHUTDOWN*/
411 /*CTDB_CONTROL_GET_MONMODE*/
412 /*CTDB_CONTROL_SET_MONMODE*/
413 /*CTDB_CONTROL_MAX_RSN*/
414 /*CTDB_CONTROL_SET_RSN_NONEMPTY*/
415 /*CTDB_CONTROL_DELETE_LOW_RSN*/
416 /*CTDB_CONTROL_TAKEOVER_IP*/
417 /*CTDB_CONTROL_RELEASE_IP*/
418 /*CTDB_CONTROL_TCP_CLIENT*/
419 /*CTDB_CONTROL_TCP_ADD*/
420 /*CTDB_CONTROL_TCP_REMOVE*/
421 /*CTDB_CONTROL_STARTUP*/
422 /*CTDB_CONTROL_SET_TUNABLE*/
423 /*CTDB_CONTROL_GET_TUNABLE*/
424 /*CTDB_CONTROL_LIST_TUNABLES*/
425 /*CTDB_CONTROL_GET_PUBLIC_IPS*/
426 /*CTDB_CONTROL_MODIFY_FLAGS*/
427 /*CTDB_CONTROL_GET_ALL_TUNABLES*/
428 /*CTDB_CONTROL_KILL_TCP*/
429 /*CTDB_CONTROL_GET_TCP_TICKLE_LIST*/
430 /*CTDB_CONTROL_SET_TCP_TICKLE_LIST*/
434 static control_dissector
find_control_dissector(guint32 opcode
, gboolean is_request
)
436 control_dissector_array_t
*cd
=control_dissectors
;
439 if((!cd
->opcode
)&&(!cd
->request_dissector
)&&(!cd
->reply_dissector
)){
442 if(opcode
==cd
->opcode
){
444 return cd
->request_dissector
;
446 return cd
->reply_dissector
;
454 static const value_string ctdb_dbid_vals
[] = {
455 {0x435d3410, "notify.tdb"},
456 {0x42fe72c5, "locking.tdb"},
457 {0x1421fb78, "brlock.tdb"},
458 {0x17055d90, "connections.tdb"},
459 {0xc0bdde6a, "sessionid.tdb"},
464 ctdb_display_trans(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, ctdb_trans_t
*ctdb_trans
)
468 if(ctdb_trans
->request_in
!=pinfo
->fd
->num
){
469 item
=proto_tree_add_uint(tree
, hf_ctdb_request_in
, tvb
, 0, 0, ctdb_trans
->request_in
);
470 PROTO_ITEM_SET_GENERATED(item
);
473 if( (ctdb_trans
->response_in
!=0)
474 &&(ctdb_trans
->response_in
!=pinfo
->fd
->num
) ){
475 item
=proto_tree_add_uint(tree
, hf_ctdb_response_in
, tvb
, 0, 0, ctdb_trans
->response_in
);
476 PROTO_ITEM_SET_GENERATED(item
);
479 if(pinfo
->fd
->num
==ctdb_trans
->response_in
){
482 nstime_delta(&ns
, &pinfo
->fd
->abs_ts
, &ctdb_trans
->req_time
);
483 item
=proto_tree_add_time(tree
, hf_ctdb_time
, tvb
, 0, 0, &ns
);
484 PROTO_ITEM_SET_GENERATED(item
);
489 ctdb_display_control(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, ctdb_control_t
*ctdb_control
)
493 if(ctdb_control
->request_in
!=pinfo
->fd
->num
){
494 item
=proto_tree_add_uint(tree
, hf_ctdb_request_in
, tvb
, 0, 0, ctdb_control
->request_in
);
495 PROTO_ITEM_SET_GENERATED(item
);
498 if( (ctdb_control
->response_in
!=0)
499 &&(ctdb_control
->response_in
!=pinfo
->fd
->num
) ){
500 item
=proto_tree_add_uint(tree
, hf_ctdb_response_in
, tvb
, 0, 0, ctdb_control
->response_in
);
501 PROTO_ITEM_SET_GENERATED(item
);
504 if(pinfo
->fd
->num
==ctdb_control
->response_in
){
507 nstime_delta(&ns
, &pinfo
->fd
->abs_ts
, &ctdb_control
->req_time
);
508 item
=proto_tree_add_time(tree
, hf_ctdb_time
, tvb
, 0, 0, &ns
);
509 PROTO_ITEM_SET_GENERATED(item
);
514 ctdb_hash(tvbuff_t
*tvb
, int offset
, guint32 len
)
519 for(value
=0x238F13AF*len
, i
=0; i
< len
; i
++)
520 value
=(value
+(tvb_get_guint8(tvb
, offset
+i
) << (i
*5 % 24)));
522 return (1103515243 * value
+ 12345);
526 dissect_ctdb_key(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint32 keylen
, guint32
*key_hash
, int endianess
)
529 proto_item
*key_item
=NULL
;
530 proto_item
*key_tree
=NULL
;
533 key_item
=proto_tree_add_item(tree
, hf_ctdb_key
, tvb
, offset
, keylen
, endianess
);
534 key_tree
=proto_item_add_subtree(key_item
, ett_ctdb_key
);
538 keyhash
=ctdb_hash(tvb
, offset
, keylen
);
539 proto_item_append_text(key_item
, " (Hash:0x%08x)", keyhash
);
540 key_item
=proto_tree_add_uint(key_tree
, hf_ctdb_keyhash
, tvb
, 0, 0, keyhash
);
541 PROTO_ITEM_SET_GENERATED(key_item
);
553 dissect_ctdb_reply_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, int endianess
)
558 proto_tree_add_item(tree
, hf_ctdb_status
, tvb
, offset
, 4, endianess
);
562 proto_tree_add_item(tree
, hf_ctdb_datalen
, tvb
, offset
, 4, endianess
);
564 datalen
=tvb_get_letohl(tvb
, offset
);
566 datalen
=tvb_get_ntohl(tvb
, offset
);
571 proto_tree_add_item(tree
, hf_ctdb_data
, tvb
, offset
, datalen
, endianess
);
579 dissect_ctdb_reply_dmaster(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint32 reqid
, guint32 dst
, int endianess
)
581 guint32 datalen
, keylen
;
582 wmem_tree_key_t tkey
[3];
583 ctdb_trans_t
*ctdb_trans
;
586 proto_tree_add_item(tree
, hf_ctdb_dbid
, tvb
, offset
, 4, endianess
);
591 offset
=(offset
+7)&0xfffff8; /* fixup alignment*/
592 proto_tree_add_item(tree
, hf_ctdb_rsn
, tvb
, offset
, 8, endianess
);
596 proto_tree_add_item(tree
, hf_ctdb_keylen
, tvb
, offset
, 4, endianess
);
598 keylen
=tvb_get_letohl(tvb
, offset
);
600 keylen
=tvb_get_ntohl(tvb
, offset
);
605 proto_tree_add_item(tree
, hf_ctdb_datalen
, tvb
, offset
, 4, endianess
);
607 datalen
=tvb_get_letohl(tvb
, offset
);
609 datalen
=tvb_get_ntohl(tvb
, offset
);
614 offset
=dissect_ctdb_key(tree
, tvb
, offset
, keylen
, NULL
, endianess
);
617 proto_tree_add_item(tree
, hf_ctdb_data
, tvb
, offset
, datalen
, endianess
);
625 ctdb_trans
=(ctdb_trans_t
*)wmem_tree_lookup32_array(ctdb_transactions
, &tkey
[0]);
628 ctdb_trans
->response_in
=pinfo
->fd
->num
;
629 ctdb_display_trans(pinfo
, tree
, tvb
, ctdb_trans
);
636 dissect_ctdb_req_dmaster(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint32 reqid
, int endianess
)
638 guint32 keylen
, datalen
, dmaster
;
639 wmem_tree_key_t tkey
[3];
640 ctdb_trans_t
*ctdb_trans
;
643 proto_tree_add_item(tree
, hf_ctdb_dbid
, tvb
, offset
, 4, endianess
);
647 offset
=(offset
+7)&0xfffff8; /* fixup alignment*/
648 proto_tree_add_item(tree
, hf_ctdb_rsn
, tvb
, offset
, 8, endianess
);
652 proto_tree_add_item(tree
, hf_ctdb_dmaster
, tvb
, offset
, 4, endianess
);
654 dmaster
=tvb_get_letohl(tvb
, offset
);
656 dmaster
=tvb_get_ntohl(tvb
, offset
);
661 proto_tree_add_item(tree
, hf_ctdb_keylen
, tvb
, offset
, 4, endianess
);
663 keylen
=tvb_get_letohl(tvb
, offset
);
665 keylen
=tvb_get_ntohl(tvb
, offset
);
670 proto_tree_add_item(tree
, hf_ctdb_datalen
, tvb
, offset
, 4, endianess
);
672 datalen
=tvb_get_letohl(tvb
, offset
);
674 datalen
=tvb_get_ntohl(tvb
, offset
);
679 offset
=dissect_ctdb_key(tree
, tvb
, offset
, keylen
, NULL
, endianess
);
682 proto_tree_add_item(tree
, hf_ctdb_data
, tvb
, offset
, datalen
, endianess
);
689 tkey
[1].key
=&dmaster
;
691 ctdb_trans
=(ctdb_trans_t
*)wmem_tree_lookup32_array(ctdb_transactions
, &tkey
[0]);
694 ctdb_display_trans(pinfo
, tree
, tvb
, ctdb_trans
);
703 dissect_ctdb_req_control(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint32 reqid
, guint32 src
, guint32 dst
, int endianess
)
707 ctdb_control_t
*ctdb_control
;
708 control_dissector cd
;
712 proto_tree_add_item(tree
, hf_ctdb_ctrl_opcode
, tvb
, offset
, 4, endianess
);
714 opcode
=tvb_get_letohl(tvb
, offset
);
716 opcode
=tvb_get_ntohl(tvb
, offset
);
720 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s Request %d->%d",
721 val_to_str(opcode
, ctrl_opcode_vals
, "Unknown:%d"),
725 offset
=(offset
+7)&0xfffff8; /* fixup alignment*/
726 proto_tree_add_item(tree
, hf_ctdb_srvid
, tvb
, offset
, 8, endianess
);
730 proto_tree_add_item(tree
, hf_ctdb_clientid
, tvb
, offset
, 4, endianess
);
734 proto_tree_add_item(tree
, hf_ctdb_ctrl_flags
, tvb
, offset
, 4, endianess
);
738 proto_tree_add_item(tree
, hf_ctdb_datalen
, tvb
, offset
, 4, endianess
);
740 datalen
=tvb_get_letohl(tvb
, offset
);
742 datalen
=tvb_get_ntohl(tvb
, offset
);
749 proto_tree_add_item(tree
, hf_ctdb_data
, tvb
, offset
, datalen
, endianess
);
753 /* setup request/response matching */
754 if(!pinfo
->fd
->flags
.visited
){
755 wmem_tree_key_t tkey
[4];
757 ctdb_control
=wmem_new(wmem_file_scope(), ctdb_control_t
);
758 ctdb_control
->opcode
=opcode
;
759 ctdb_control
->request_in
=pinfo
->fd
->num
;
760 ctdb_control
->response_in
=0;
761 ctdb_control
->req_time
=pinfo
->fd
->abs_ts
;
770 wmem_tree_insert32_array(ctdb_controls
, &tkey
[0], ctdb_control
);
772 wmem_tree_key_t tkey
[4];
781 ctdb_control
=(ctdb_control_t
*)wmem_tree_lookup32_array(ctdb_controls
, &tkey
[0]);
785 cd
=find_control_dissector(ctdb_control
->opcode
, TRUE
);
787 cd(pinfo
, tree
, tvb
, data_offset
, 0, endianess
);
790 ctdb_display_control(pinfo
, tree
, tvb
, ctdb_control
);
796 dissect_ctdb_reply_control(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint32 reqid
, guint32 src
, guint32 dst
, int endianess
)
798 ctdb_control_t
*ctdb_control
;
799 wmem_tree_key_t tkey
[4];
801 guint32 datalen
, errorlen
, status
;
803 control_dissector cd
;
812 ctdb_control
=(ctdb_control_t
*)wmem_tree_lookup32_array(ctdb_controls
, &tkey
[0]);
818 if(!pinfo
->fd
->flags
.visited
){
819 ctdb_control
->response_in
= pinfo
->fd
->num
;
823 item
=proto_tree_add_uint(tree
, hf_ctdb_ctrl_opcode
, tvb
, 0, 0, ctdb_control
->opcode
);
824 PROTO_ITEM_SET_GENERATED(item
);
826 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s Reply %d->%d",
827 val_to_str(ctdb_control
->opcode
, ctrl_opcode_vals
, "Unknown:%d"),
832 proto_tree_add_item(tree
, hf_ctdb_status
, tvb
, offset
, 4, endianess
);
834 status
=tvb_get_letohl(tvb
, offset
);
836 status
=tvb_get_ntohl(tvb
, offset
);
841 proto_tree_add_item(tree
, hf_ctdb_datalen
, tvb
, offset
, 4, endianess
);
843 datalen
=tvb_get_letohl(tvb
, offset
);
845 datalen
=tvb_get_ntohl(tvb
, offset
);
850 proto_tree_add_item(tree
, hf_ctdb_errorlen
, tvb
, offset
, 4, endianess
);
852 errorlen
=tvb_get_letohl(tvb
, offset
);
854 errorlen
=tvb_get_ntohl(tvb
, offset
);
861 proto_tree_add_item(tree
, hf_ctdb_data
, tvb
, offset
, datalen
, endianess
);
868 proto_tree_add_item(tree
, hf_ctdb_error
, tvb
, offset
, errorlen
, endianess
);
873 cd
=find_control_dissector(ctdb_control
->opcode
, FALSE
);
875 cd(pinfo
, tree
, tvb
, data_offset
, status
, endianess
);
878 ctdb_display_control(pinfo
, tree
, tvb
, ctdb_control
);
882 static const true_false_string flags_immediate_tfs
={
883 "DMASTER for the record must IMMEDIATELY be migrated to the caller",
884 "Dmaster migration is not required"
888 dissect_ctdb_req_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, guint32 reqid
, guint32 caller
, int endianess
)
890 guint32 flags
, keyhash
;
891 guint32 keylen
, datalen
;
892 ctdb_trans_t
*ctdb_trans
=NULL
;
895 proto_tree_add_item(tree
, hf_ctdb_flags_immediate
, tvb
, offset
, 4, endianess
);
897 flags
=tvb_get_letohl(tvb
, offset
);
899 flags
=tvb_get_ntohl(tvb
, offset
);
901 if(flags
&0x00000001){
902 col_append_str(pinfo
->cinfo
, COL_INFO
, " IMMEDIATE");
907 proto_tree_add_item(tree
, hf_ctdb_dbid
, tvb
, offset
, 4, endianess
);
911 proto_tree_add_item(tree
, hf_ctdb_callid
, tvb
, offset
, 4, endianess
);
915 proto_tree_add_item(tree
, hf_ctdb_hopcount
, tvb
, offset
, 4, endianess
);
919 proto_tree_add_item(tree
, hf_ctdb_keylen
, tvb
, offset
, 4, endianess
);
921 keylen
=tvb_get_letohl(tvb
, offset
);
923 keylen
=tvb_get_ntohl(tvb
, offset
);
928 proto_tree_add_item(tree
, hf_ctdb_datalen
, tvb
, offset
, 4, endianess
);
930 datalen
=tvb_get_letohl(tvb
, offset
);
932 datalen
=tvb_get_ntohl(tvb
, offset
);
937 offset
=dissect_ctdb_key(tree
, tvb
, offset
, keylen
, &keyhash
, endianess
);
940 proto_tree_add_item(tree
, hf_ctdb_data
, tvb
, offset
, datalen
, endianess
);
943 /* setup request/response matching */
944 if(!pinfo
->fd
->flags
.visited
){
945 wmem_tree_key_t tkey
[3];
947 ctdb_trans
=wmem_new(wmem_file_scope(), ctdb_trans_t
);
948 ctdb_trans
->key_hash
=keyhash
;
949 ctdb_trans
->request_in
=pinfo
->fd
->num
;
950 ctdb_trans
->response_in
=0;
951 ctdb_trans
->req_time
=pinfo
->fd
->abs_ts
;
958 wmem_tree_insert32_array(ctdb_transactions
, &tkey
[0], ctdb_trans
);
960 wmem_tree_key_t tkey
[3];
967 ctdb_trans
=(ctdb_trans_t
*)wmem_tree_lookup32_array(ctdb_transactions
, &tkey
[0]);
971 ctdb_display_trans(pinfo
, tree
, tvb
, ctdb_trans
);
978 dissect_ctdb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void *data _U_
)
980 proto_tree
*tree
=NULL
;
981 proto_item
*item
=NULL
;
983 guint32 opcode
, src
, dst
, reqid
;
986 /* does this look like CTDB? */
987 if(tvb_length_remaining(tvb
, offset
)<8){
990 switch(tvb_get_letohl(tvb
, offset
+4)){
1002 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CTDB");
1003 col_clear(pinfo
->cinfo
, COL_INFO
);
1006 item
=proto_tree_add_item(parent_tree
, proto_ctdb
, tvb
, offset
,
1008 tree
=proto_item_add_subtree(item
, ett_ctdb
);
1013 proto_tree_add_item(tree
, hf_ctdb_length
, tvb
, offset
, 4, endianess
);
1017 proto_tree_add_item(tree
, hf_ctdb_magic
, tvb
, offset
, 4, endianess
);
1021 proto_tree_add_item(tree
, hf_ctdb_version
, tvb
, offset
, 4, endianess
);
1025 proto_tree_add_item(tree
, hf_ctdb_generation
, tvb
, offset
, 4, endianess
);
1029 proto_tree_add_item(tree
, hf_ctdb_opcode
, tvb
, offset
, 4, endianess
);
1031 opcode
=tvb_get_letohl(tvb
, offset
);
1033 opcode
=tvb_get_ntohl(tvb
, offset
);
1038 proto_tree_add_item(tree
, hf_ctdb_dst
, tvb
, offset
, 4, endianess
);
1040 dst
=tvb_get_letohl(tvb
, offset
);
1042 dst
=tvb_get_ntohl(tvb
, offset
);
1047 proto_tree_add_item(tree
, hf_ctdb_src
, tvb
, offset
, 4, endianess
);
1049 src
=tvb_get_letohl(tvb
, offset
);
1051 src
=tvb_get_ntohl(tvb
, offset
);
1056 proto_tree_add_item(tree
, hf_ctdb_id
, tvb
, offset
, 4, endianess
);
1058 reqid
=tvb_get_letohl(tvb
, offset
);
1060 reqid
=tvb_get_ntohl(tvb
, offset
);
1064 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s %d->%d",
1065 val_to_str(opcode
, ctdb_opcodes
, "Unknown:%d"),
1070 dissect_ctdb_req_call(tvb
, offset
, pinfo
, tree
, reqid
, src
, endianess
);
1072 case CTDB_REPLY_CALL
:
1073 dissect_ctdb_reply_call(tvb
, offset
, pinfo
, tree
, endianess
);
1075 case CTDB_REPLY_DMASTER
:
1076 dissect_ctdb_reply_dmaster(tvb
, offset
, pinfo
, tree
, reqid
, dst
, endianess
);
1078 case CTDB_REQ_DMASTER
:
1079 dissect_ctdb_req_dmaster(tvb
, offset
, pinfo
, tree
, reqid
, endianess
);
1081 case CTDB_REPLY_ERROR
:
1083 case CTDB_REQ_MESSAGE
:
1085 case CTDB_REQ_CONTROL
:
1086 dissect_ctdb_req_control(tvb
, offset
, pinfo
, tree
, reqid
, src
, dst
, endianess
);
1088 case CTDB_REPLY_CONTROL
:
1089 dissect_ctdb_reply_control(tvb
, offset
, pinfo
, tree
, reqid
, src
, dst
, endianess
);
1098 * Register the protocol with Wireshark
1101 proto_register_ctdb(void)
1103 static hf_register_info hf
[] = {
1104 { &hf_ctdb_length
, {
1105 "Length", "ctdb.len", FT_UINT32
, BASE_DEC
,
1106 NULL
, 0x0, "Size of CTDB PDU", HFILL
}},
1108 "Destination", "ctdb.dst", FT_UINT32
, BASE_DEC
,
1109 NULL
, 0x0, NULL
, HFILL
}},
1111 "Source", "ctdb.src", FT_UINT32
, BASE_DEC
,
1112 NULL
, 0x0, NULL
, HFILL
}},
1114 "Id", "ctdb.id", FT_UINT32
, BASE_DEC
,
1115 NULL
, 0x0, "Transaction ID", HFILL
}},
1116 { &hf_ctdb_opcode
, {
1117 "Opcode", "ctdb.opcode", FT_UINT32
, BASE_DEC
,
1118 VALS(ctdb_opcodes
), 0x0, "CTDB command opcode", HFILL
}},
1119 { &hf_ctdb_flags_immediate
, {
1120 "Immediate", "ctdb.immediate", FT_BOOLEAN
, 32,
1121 TFS(&flags_immediate_tfs
), 0x00000001, "Force migration of DMASTER?", HFILL
}},
1123 "DB Id", "ctdb.dbid", FT_UINT32
, BASE_HEX
,
1124 VALS(ctdb_dbid_vals
), 0x0, "Database ID", HFILL
}},
1125 { &hf_ctdb_callid
, {
1126 "Call Id", "ctdb.callid", FT_UINT32
, BASE_DEC
,
1127 NULL
, 0x0, NULL
, HFILL
}},
1128 { &hf_ctdb_status
, {
1129 "Status", "ctdb.status", FT_UINT32
, BASE_DEC
,
1130 NULL
, 0x0, NULL
, HFILL
}},
1131 { &hf_ctdb_datalen
, {
1132 "Data Length", "ctdb.datalen", FT_UINT32
, BASE_DEC
,
1133 NULL
, 0x0, NULL
, HFILL
}},
1134 { &hf_ctdb_errorlen
, {
1135 "Error Length", "ctdb.errorlen", FT_UINT32
, BASE_DEC
,
1136 NULL
, 0x0, NULL
, HFILL
}},
1137 { &hf_ctdb_keylen
, {
1138 "Key Length", "ctdb.keylen", FT_UINT32
, BASE_DEC
,
1139 NULL
, 0x0, NULL
, HFILL
}},
1141 "Magic", "ctdb.magic", FT_UINT32
, BASE_HEX
,
1142 NULL
, 0x0, NULL
, HFILL
}},
1143 { &hf_ctdb_version
, {
1144 "Version", "ctdb.version", FT_UINT32
, BASE_DEC
,
1145 NULL
, 0x0, NULL
, HFILL
}},
1146 { &hf_ctdb_dmaster
, {
1147 "Dmaster", "ctdb.dmaster", FT_UINT32
, BASE_DEC
,
1148 NULL
, 0x0, NULL
, HFILL
}},
1149 { &hf_ctdb_generation
, {
1150 "Generation", "ctdb.generation", FT_UINT32
, BASE_DEC
,
1151 NULL
, 0x0, NULL
, HFILL
}},
1153 "Key", "ctdb.key", FT_BYTES
, BASE_NONE
,
1154 NULL
, 0x0, NULL
, HFILL
}},
1155 { &hf_ctdb_keyhash
, {
1156 "KeyHash", "ctdb.keyhash", FT_UINT32
, BASE_HEX
,
1157 NULL
, 0x0, NULL
, HFILL
}},
1159 "Data", "ctdb.data", FT_BYTES
, BASE_NONE
,
1160 NULL
, 0x0, NULL
, HFILL
}},
1162 "Error", "ctdb.error", FT_BYTES
, BASE_NONE
,
1163 NULL
, 0x0, NULL
, HFILL
}},
1164 { &hf_ctdb_request_in
, {
1165 "Request In", "ctdb.request_in", FT_FRAMENUM
, BASE_NONE
,
1166 NULL
, 0x0, NULL
, HFILL
}},
1167 { &hf_ctdb_response_in
, {
1168 "Response In", "ctdb.response_in", FT_FRAMENUM
, BASE_NONE
,
1169 NULL
, 0x0, NULL
, HFILL
}},
1171 "Time since request", "ctdb.time", FT_RELATIVE_TIME
, BASE_NONE
,
1172 NULL
, 0x0, NULL
, HFILL
}},
1173 { &hf_ctdb_hopcount
, {
1174 "Hopcount", "ctdb.hopcount", FT_UINT32
, BASE_DEC
,
1175 NULL
, 0x0, NULL
, HFILL
}},
1177 "RSN", "ctdb.rsn", FT_UINT64
, BASE_HEX
,
1178 NULL
, 0x0, NULL
, HFILL
}},
1179 { &hf_ctdb_ctrl_opcode
, {
1180 "CTRL Opcode", "ctdb.ctrl_opcode", FT_UINT32
, BASE_DEC
,
1181 VALS(ctrl_opcode_vals
), 0x0, NULL
, HFILL
}},
1183 "SrvId", "ctdb.srvid", FT_UINT64
, BASE_HEX
,
1184 NULL
, 0x0, NULL
, HFILL
}},
1185 { &hf_ctdb_clientid
, {
1186 "ClientId", "ctdb.clientid", FT_UINT32
, BASE_HEX
,
1187 NULL
, 0x0, NULL
, HFILL
}},
1188 { &hf_ctdb_ctrl_flags
, {
1189 "CTRL Flags", "ctdb.ctrl_flags", FT_UINT32
, BASE_HEX
,
1190 NULL
, 0x0, NULL
, HFILL
}},
1191 { &hf_ctdb_recmaster
, {
1192 "Recovery Master", "ctdb.recmaster", FT_UINT32
, BASE_DEC
,
1193 NULL
, 0x0, NULL
, HFILL
}},
1194 { &hf_ctdb_recmode
, {
1195 "Recovery Mode", "ctdb.recmode", FT_UINT32
, BASE_DEC
,
1196 VALS(recmode_vals
), 0x0, NULL
, HFILL
}},
1197 { &hf_ctdb_num_nodes
, {
1198 "Num Nodes", "ctdb.num_nodes", FT_UINT32
, BASE_DEC
,
1199 NULL
, 0x0, NULL
, HFILL
}},
1201 "VNN", "ctdb.vnn", FT_UINT32
, BASE_DEC
,
1202 NULL
, 0x0, NULL
, HFILL
}},
1203 { &hf_ctdb_node_flags
, {
1204 "Node Flags", "ctdb.node_flags", FT_UINT32
, BASE_HEX
,
1205 NULL
, 0x0, NULL
, HFILL
}},
1206 { &hf_ctdb_node_ip
, {
1207 "Node IP", "ctdb.node_ip", FT_IPv4
, BASE_NONE
,
1208 NULL
, 0x0, NULL
, HFILL
}},
1210 "PID", "ctdb.pid", FT_UINT32
, BASE_DEC
,
1211 NULL
, 0x0, NULL
, HFILL
}},
1212 { &hf_ctdb_process_exists
, {
1213 "Process Exists", "ctdb.process_exists", FT_BOOLEAN
, 32,
1214 TFS(&process_exists_tfs
), 0x01, NULL
, HFILL
}},
1217 /* Setup protocol subtree array */
1218 static gint
*ett
[] = {
1223 static ei_register_info ei
[] = {
1224 { &ei_ctdb_too_many_nodes
, { "ctdb.too_many_nodes", PI_UNDECODED
, PI_WARN
, "Too many nodes", EXPFILL
}},
1227 expert_module_t
* expert_ctdb
;
1230 /* Register the protocol name and description */
1231 proto_ctdb
= proto_register_protocol("Cluster TDB", "CTDB", "ctdb");
1233 /* Required function calls to register the header fields and subtrees used */
1234 proto_register_field_array(proto_ctdb
, hf
, array_length(hf
));
1235 proto_register_subtree_array(ett
, array_length(ett
));
1236 expert_ctdb
= expert_register_protocol(proto_ctdb
);
1237 expert_register_field_array(expert_ctdb
, ei
, array_length(ei
));
1239 ctdb_transactions
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1240 ctdb_controls
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1245 proto_reg_handoff_ctdb(void)
1247 dissector_handle_t ctdb_handle
;
1249 ctdb_handle
= new_create_dissector_handle(dissect_ctdb
, proto_ctdb
);
1250 dissector_add_handle("tcp.port", ctdb_handle
);
1252 heur_dissector_add("tcp", dissect_ctdb
, proto_ctdb
);