Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ctdb.c
blob5aa9ba26dd23a3e423866e9c93abb8bce8a4cb51
1 /* packet-ctdb.c
2 * Routines for CTDB (Cluster TDB) dissection
3 * Copyright 2007, Ronnie Sahlberg
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
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/tfs.h>
16 #include <epan/expert.h>
17 void proto_register_ctdb(void);
18 void proto_reg_handoff_ctdb(void);
20 static dissector_handle_t ctdb_handle;
22 /* Initialize the protocol and registered fields */
23 static int proto_ctdb;
24 static int hf_ctdb_length;
25 static int hf_ctdb_opcode;
26 static int hf_ctdb_magic;
27 static int hf_ctdb_version;
28 static int hf_ctdb_dst;
29 static int hf_ctdb_src;
30 static int hf_ctdb_id;
31 static int hf_ctdb_flags_immediate;
32 static int hf_ctdb_dbid;
33 static int hf_ctdb_callid;
34 static int hf_ctdb_status;
35 static int hf_ctdb_keylen;
36 static int hf_ctdb_datalen;
37 static int hf_ctdb_errorlen;
38 static int hf_ctdb_key;
39 static int hf_ctdb_keyhash;
40 static int hf_ctdb_data;
41 static int hf_ctdb_error;
42 static int hf_ctdb_dmaster;
43 static int hf_ctdb_request_in;
44 static int hf_ctdb_response_in;
45 static int hf_ctdb_time;
46 static int hf_ctdb_generation;
47 static int hf_ctdb_hopcount;
48 static int hf_ctdb_rsn;
49 static int hf_ctdb_ctrl_opcode;
50 static int hf_ctdb_srvid;
51 static int hf_ctdb_clientid;
52 static int hf_ctdb_ctrl_flags;
53 static int hf_ctdb_recmaster;
54 static int hf_ctdb_recmode;
55 static int hf_ctdb_num_nodes;
56 static int hf_ctdb_vnn;
57 static int hf_ctdb_node_flags;
58 static int hf_ctdb_node_ip;
59 static int hf_ctdb_pid;
60 static int hf_ctdb_process_exists;
62 /* Initialize the subtree pointers */
63 static int ett_ctdb;
64 static int ett_ctdb_key;
66 static expert_field ei_ctdb_too_many_nodes;
68 /* this tree keeps track of caller/reqid for ctdb transactions */
69 static wmem_tree_t *ctdb_transactions;
70 typedef struct _ctdb_trans_t {
71 uint32_t key_hash;
72 uint32_t request_in;
73 uint32_t response_in;
74 nstime_t req_time;
75 } ctdb_trans_t;
77 /* this tree keeps track of CONTROL request/responses */
78 static wmem_tree_t *ctdb_controls;
79 typedef struct _ctdb_control_t {
80 uint32_t opcode;
81 uint32_t request_in;
82 uint32_t response_in;
83 nstime_t req_time;
84 } ctdb_control_t;
86 #define CTDB_REQ_CALL 0
87 #define CTDB_REPLY_CALL 1
88 #define CTDB_REQ_DMASTER 2
89 #define CTDB_REPLY_DMASTER 3
90 #define CTDB_REPLY_ERROR 4
91 #define CTDB_REQ_MESSAGE 5
92 #define CTDB_REQ_CONTROL 7
93 #define CTDB_REPLY_CONTROL 8
94 #define CTDB_REQ_KEEPALIVE 9
95 static const value_string ctdb_opcodes[] = {
96 {CTDB_REQ_CALL, "REQ_CALL"},
97 {CTDB_REPLY_CALL, "REPLY_CALL"},
98 {CTDB_REQ_DMASTER, "REQ_DMASTER"},
99 {CTDB_REPLY_DMASTER, "REPLY_DMASTER"},
100 {CTDB_REPLY_ERROR, "REPLY_ERROR"},
101 {CTDB_REQ_MESSAGE, "REQ_MESSAGE"},
102 {CTDB_REQ_CONTROL, "REQ_CONTROL"},
103 {CTDB_REPLY_CONTROL, "REPLY_CONTROL"},
104 {CTDB_REQ_KEEPALIVE, "REQ_KEEPALIVE"},
105 {0,NULL}
109 #define CTDB_CONTROL_PROCESS_EXISTS 0
110 #define CTDB_CONTROL_STATISTICS 1
111 /* note: #2 removed upstream */
112 #define CTDB_CONTROL_CONFIG 2
113 #define CTDB_CONTROL_PING 3
114 #define CTDB_CONTROL_GETDBPATH 4
115 #define CTDB_CONTROL_GETVNNMAP 5
116 #define CTDB_CONTROL_SETVNNMAP 6
117 #define CTDB_CONTROL_GET_DEBUG 7
118 #define CTDB_CONTROL_SET_DEBUG 8
119 #define CTDB_CONTROL_GET_DBMAP 9
120 #define CTDB_CONTROL_GET_NODEMAPv4 10 /* obsolete */
121 #define CTDB_CONTROL_SET_DMASTER 11 /* obsolete */
122 /* note: #12 removed upstream */
123 #define CTDB_CONTROL_CLEAR_DB 12
124 #define CTDB_CONTROL_PULL_DB 13
125 #define CTDB_CONTROL_PUSH_DB 14
126 #define CTDB_CONTROL_GET_RECMODE 15
127 #define CTDB_CONTROL_SET_RECMODE 16
128 #define CTDB_CONTROL_STATISTICS_RESET 17
129 #define CTDB_CONTROL_DB_ATTACH 18
130 #define CTDB_CONTROL_SET_CALL 19 /* obsolete */
131 #define CTDB_CONTROL_TRAVERSE_START 20
132 #define CTDB_CONTROL_TRAVERSE_ALL 21
133 #define CTDB_CONTROL_TRAVERSE_DATA 22
134 #define CTDB_CONTROL_REGISTER_SRVID 23
135 #define CTDB_CONTROL_DEREGISTER_SRVID 24
136 #define CTDB_CONTROL_GET_DBNAME 25
137 #define CTDB_CONTROL_ENABLE_SEQNUM 26
138 #define CTDB_CONTROL_UPDATE_SEQNUM 27
139 /* note: #28 removed upstream */
140 #define CTDB_CONTROL_SET_SEQNUM_FREQUENCY 28
141 #define CTDB_CONTROL_DUMP_MEMORY 29
142 #define CTDB_CONTROL_GET_PID 30
143 #define CTDB_CONTROL_GET_RECMASTER 31
144 #define CTDB_CONTROL_SET_RECMASTER 32
145 #define CTDB_CONTROL_FREEZE 33
146 #define CTDB_CONTROL_THAW 34 /* obsolete */
147 #define CTDB_CONTROL_GET_PNN 35
148 #define CTDB_CONTROL_SHUTDOWN 36
149 #define CTDB_CONTROL_GET_MONMODE 37
150 /* note: #38, #39, #40 and #41 removed upstream */
151 #define CTDB_CONTROL_SET_MONMODE 38
152 #define CTDB_CONTROL_MAX_RSN 39
153 #define CTDB_CONTROL_SET_RSN_NONEMPTY 40
154 #define CTDB_CONTROL_DELETE_LOW_RSN 41
155 #define CTDB_CONTROL_TAKEOVER_IPv4 42 /* obsolete */
156 #define CTDB_CONTROL_RELEASE_IPv4 43 /* obsolete */
157 #define CTDB_CONTROL_TCP_CLIENT 44
158 #define CTDB_CONTROL_TCP_ADD 45
159 #define CTDB_CONTROL_TCP_REMOVE 46
160 #define CTDB_CONTROL_STARTUP 47
161 #define CTDB_CONTROL_SET_TUNABLE 48
162 #define CTDB_CONTROL_GET_TUNABLE 49
163 #define CTDB_CONTROL_LIST_TUNABLES 50
164 #define CTDB_CONTROL_GET_PUBLIC_IPSv4 51 /* obsolete */
165 #define CTDB_CONTROL_MODIFY_FLAGS 52
166 #define CTDB_CONTROL_GET_ALL_TUNABLES 53
167 #define CTDB_CONTROL_KILL_TCP 54 /* obsolete */
168 #define CTDB_CONTROL_GET_TCP_TICKLE_LIST 55
169 #define CTDB_CONTROL_SET_TCP_TICKLE_LIST 56
170 #define CTDB_CONTROL_REGISTER_SERVER_ID 57 /* obsolete */
171 #define CTDB_CONTROL_UNREGISTER_SERVER_ID 58 /* obsolete */
172 #define CTDB_CONTROL_CHECK_SERVER_ID 59 /* obsolete */
173 #define CTDB_CONTROL_GET_SERVER_ID_LIST 60 /* obsolete */
174 #define CTDB_CONTROL_DB_ATTACH_PERSISTENT 61
175 #define CTDB_CONTROL_PERSISTENT_STORE 62 /* obsolete */
176 #define CTDB_CONTROL_UPDATE_RECORD 63
177 #define CTDB_CONTROL_SEND_GRATUITOUS_ARP 64
178 #define CTDB_CONTROL_TRANSACTION_START 65 /* obsolete */
179 #define CTDB_CONTROL_TRANSACTION_COMMIT 66 /* obsolete */
180 #define CTDB_CONTROL_WIPE_DATABASE 67
181 /* #68 removed */
182 #define CTDB_CONTROL_UPTIME 69
183 #define CTDB_CONTROL_START_RECOVERY 70
184 #define CTDB_CONTROL_END_RECOVERY 71
185 #define CTDB_CONTROL_RELOAD_NODES_FILE 72
186 /* #73 removed */
187 #define CTDB_CONTROL_TRY_DELETE_RECORDS 74
188 #define CTDB_CONTROL_ENABLE_MONITOR 75
189 #define CTDB_CONTROL_DISABLE_MONITOR 76
190 #define CTDB_CONTROL_ADD_PUBLIC_IP 77
191 #define CTDB_CONTROL_DEL_PUBLIC_IP 78
192 #define CTDB_CONTROL_RUN_EVENTSCRIPTS 79 /* obsolete */
193 #define CTDB_CONTROL_GET_CAPABILITIES 80
194 #define CTDB_CONTROL_START_PERSISTENT_UPDATE 81 /* obsolete */
195 #define CTDB_CONTROL_CANCEL_PERSISTENT_UPDATE 82 /* obsolete */
196 #define CTDB_CONTROL_TRANS2_COMMIT 83 /* obsolete */
197 #define CTDB_CONTROL_TRANS2_FINISHED 84 /* obsolete */
198 #define CTDB_CONTROL_TRANS2_ERROR 85 /* obsolete */
199 #define CTDB_CONTROL_TRANS2_COMMIT_RETRY 86 /* obsolete */
200 #define CTDB_CONTROL_RECD_PING 87
201 #define CTDB_CONTROL_RELEASE_IP 88
202 #define CTDB_CONTROL_TAKEOVER_IP 89
203 #define CTDB_CONTROL_GET_PUBLIC_IPS 90
204 #define CTDB_CONTROL_GET_NODEMAP 91
205 /* missing */
206 #define CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS 96 /* obsolete */
207 #define CTDB_CONTROL_TRAVERSE_KILL 97
208 #define CTDB_CONTROL_RECD_RECLOCK_LATENCY 98
209 #define CTDB_CONTROL_GET_RECLOCK_FILE 99
210 #define CTDB_CONTROL_SET_RECLOCK_FILE 100 /* obsolete */
211 #define CTDB_CONTROL_STOP_NODE 101
212 #define CTDB_CONTROL_CONTINUE_NODE 102
213 #define CTDB_CONTROL_SET_NATGWSTATE 103 /* obsolete */
214 #define CTDB_CONTROL_SET_LMASTERROLE 104
215 #define CTDB_CONTROL_SET_RECMASTERROLE 105
216 #define CTDB_CONTROL_ENABLE_SCRIPT 107 /* obsolete */
217 #define CTDB_CONTROL_DISABLE_SCRIPT 108 /* obsolete */
218 #define CTDB_CONTROL_SET_BAN_STATE 109
219 #define CTDB_CONTROL_GET_BAN_STATE 110
220 #define CTDB_CONTROL_SET_DB_PRIORITY 111 /* obsolete */
221 #define CTDB_CONTROL_GET_DB_PRIORITY 112 /* obsolete */
222 #define CTDB_CONTROL_TRANSACTION_CANCEL 113 /* obsolete */
223 #define CTDB_CONTROL_REGISTER_NOTIFY 114
224 #define CTDB_CONTROL_DEREGISTER_NOTIFY 115
225 #define CTDB_CONTROL_TRANS2_ACTIVE 116 /* obsolete */
226 #define CTDB_CONTROL_GET_LOG 117 /* obsolete */
227 #define CTDB_CONTROL_CLEAR_LOG 118 /* obsolete */
228 #define CTDB_CONTROL_TRANS3_COMMIT 119
229 #define CTDB_CONTROL_GET_DB_SEQNUM 120
230 #define CTDB_CONTROL_DB_SET_HEALTHY 121
231 #define CTDB_CONTROL_DB_GET_HEALTH 122
232 #define CTDB_CONTROL_GET_PUBLIC_IP_INFO 123
233 #define CTDB_CONTROL_GET_IFACES 124
234 #define CTDB_CONTROL_SET_IFACE_LINK_STATE 125
235 #define CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE 126
236 #define CTDB_CONTROL_GET_STAT_HISTORY 127
237 #define CTDB_CONTROL_SCHEDULE_FOR_DELETION 128
238 #define CTDB_CONTROL_SET_DB_READONLY 129
239 #define CTDB_CONTROL_CHECK_SRVIDS 130
240 #define CTDB_CONTROL_TRAVERSE_START_EXT 131
241 #define CTDB_CONTROL_GET_DB_STATISTICS 132
242 #define CTDB_CONTROL_SET_DB_STICKY 133
243 #define CTDB_CONTROL_RELOAD_PUBLIC_IPS 134
244 #define CTDB_CONTROL_TRAVERSE_ALL_EXT 135
245 #define CTDB_CONTROL_RECEIVE_RECORDS 136
246 #define CTDB_CONTROL_IPREALLOCATED 137
247 #define CTDB_CONTROL_GET_RUNSTATE 138
248 #define CTDB_CONTROL_DB_DETACH 139
249 #define CTDB_CONTROL_GET_NODES_FILE 140
250 #define CTDB_CONTROL_DB_FREEZE 141
251 #define CTDB_CONTROL_DB_THAW 142
252 #define CTDB_CONTROL_DB_TRANSACTION_START 143
253 #define CTDB_CONTROL_DB_TRANSACTION_COMMIT 144
254 #define CTDB_CONTROL_DB_TRANSACTION_CANCEL 145
255 #define CTDB_CONTROL_DB_PULL 146
256 #define CTDB_CONTROL_DB_PUSH_START 147
257 #define CTDB_CONTROL_DB_PUSH_CONFIRM 148
260 static const value_string ctrl_opcode_vals[] = {
261 {CTDB_CONTROL_PROCESS_EXISTS, "PROCESS_EXISTS"},
262 {CTDB_CONTROL_STATISTICS, "STATISTICS"},
263 {CTDB_CONTROL_CONFIG, "CONFIG"},
264 {CTDB_CONTROL_PING, "PING"},
265 {CTDB_CONTROL_GETDBPATH, "GETDBPATH"},
266 {CTDB_CONTROL_GETVNNMAP, "GETVNNMAP"},
267 {CTDB_CONTROL_SETVNNMAP, "SETVNNMAP"},
268 {CTDB_CONTROL_GET_DEBUG, "GET_DEBUG"},
269 {CTDB_CONTROL_SET_DEBUG, "SET_DEBUG"},
270 {CTDB_CONTROL_GET_DBMAP, "GET_DBMAP"},
271 {CTDB_CONTROL_GET_NODEMAPv4, "GET_NODEMAPv4"},
272 {CTDB_CONTROL_SET_DMASTER, "SET_DMASTER"},
273 {CTDB_CONTROL_CLEAR_DB, "CLEAR_DB"},
274 {CTDB_CONTROL_PULL_DB, "PULL_DB"},
275 {CTDB_CONTROL_PUSH_DB, "PUSH_DB"},
276 {CTDB_CONTROL_GET_RECMODE, "GET_RECMODE"},
277 {CTDB_CONTROL_SET_RECMODE, "SET_RECMODE"},
278 {CTDB_CONTROL_STATISTICS_RESET, "STATISTICS_RESET"},
279 {CTDB_CONTROL_DB_ATTACH, "DB_ATTACH"},
280 {CTDB_CONTROL_SET_CALL, "SET_CALL"},
281 {CTDB_CONTROL_TRAVERSE_START, "TRAVERSE_START"},
282 {CTDB_CONTROL_TRAVERSE_ALL, "TRAVERSE_ALL"},
283 {CTDB_CONTROL_TRAVERSE_DATA, "TRAVERSE_DATA"},
284 {CTDB_CONTROL_REGISTER_SRVID, "REGISTER_SRVID"},
285 {CTDB_CONTROL_DEREGISTER_SRVID, "DEREGISTER_SRVID"},
286 {CTDB_CONTROL_GET_DBNAME, "GET_DBNAME"},
287 {CTDB_CONTROL_ENABLE_SEQNUM, "ENABLE_SEQNUM"},
288 {CTDB_CONTROL_UPDATE_SEQNUM, "UPDATE_SEQNUM"},
289 {CTDB_CONTROL_SET_SEQNUM_FREQUENCY, "SET_SEQNUM_FREQUENCY"},
290 {CTDB_CONTROL_DUMP_MEMORY, "DUMP_MEMORY"},
291 {CTDB_CONTROL_GET_PID, "GET_PID"},
292 {CTDB_CONTROL_GET_RECMASTER, "GET_RECMASTER"},
293 {CTDB_CONTROL_SET_RECMASTER, "SET_RECMASTER"},
294 {CTDB_CONTROL_FREEZE, "FREEZE"},
295 {CTDB_CONTROL_THAW, "THAW"},
296 {CTDB_CONTROL_GET_PNN, "GET_PNN"},
297 {CTDB_CONTROL_SHUTDOWN, "SHUTDOWN"},
298 {CTDB_CONTROL_GET_MONMODE, "GET_MONMODE"},
299 {CTDB_CONTROL_SET_MONMODE, "SET_MONMODE"},
300 {CTDB_CONTROL_MAX_RSN, "MAX_RSN"},
301 {CTDB_CONTROL_SET_RSN_NONEMPTY, "SET_RSN_NONEMPTY"},
302 {CTDB_CONTROL_DELETE_LOW_RSN, "DELETE_LOW_RSN"},
303 {CTDB_CONTROL_TAKEOVER_IPv4, "TAKEOVER_IPv4"},
304 {CTDB_CONTROL_RELEASE_IPv4, "RELEASE_IPv4"},
305 {CTDB_CONTROL_TCP_CLIENT, "TCP_CLIENT"},
306 {CTDB_CONTROL_TCP_ADD, "TCP_ADD"},
307 {CTDB_CONTROL_TCP_REMOVE, "TCP_REMOVE"},
308 {CTDB_CONTROL_STARTUP, "STARTUP"},
309 {CTDB_CONTROL_SET_TUNABLE, "SET_TUNABLE"},
310 {CTDB_CONTROL_GET_TUNABLE, "GET_TUNABLE"},
311 {CTDB_CONTROL_LIST_TUNABLES, "LIST_TUNABLES"},
312 {CTDB_CONTROL_GET_PUBLIC_IPSv4, "GET_PUBLIC_IPSv4"},
313 {CTDB_CONTROL_MODIFY_FLAGS, "MODIFY_FLAGS"},
314 {CTDB_CONTROL_GET_ALL_TUNABLES, "GET_ALL_TUNABLES"},
315 {CTDB_CONTROL_KILL_TCP, "KILL_TCP"},
316 {CTDB_CONTROL_GET_TCP_TICKLE_LIST, "GET_TCP_TICKLE_LIST"},
317 {CTDB_CONTROL_SET_TCP_TICKLE_LIST, "SET_TCP_TICKLE_LIST"},
318 {CTDB_CONTROL_REGISTER_SERVER_ID, "REGISTER_SERVER_ID"},
319 {CTDB_CONTROL_UNREGISTER_SERVER_ID, "UNREGISTER_SERVER_ID"},
320 {CTDB_CONTROL_CHECK_SERVER_ID, "CHECK_SERVER_ID"},
321 {CTDB_CONTROL_GET_SERVER_ID_LIST, "GET_SERVER_ID_LIST"},
322 {CTDB_CONTROL_DB_ATTACH_PERSISTENT, "DB_ATTACH_PERSISTENT"},
323 {CTDB_CONTROL_PERSISTENT_STORE, "PERSISTENT_STORE"},
324 {CTDB_CONTROL_UPDATE_RECORD, "UPDATE_RECORD"},
325 {CTDB_CONTROL_SEND_GRATUITOUS_ARP, "SEND_GRATUITOUS_ARP"},
326 {CTDB_CONTROL_TRANSACTION_START, "TRANSACTION_START"},
327 {CTDB_CONTROL_TRANSACTION_COMMIT, "TRANSACTION_COMMIT"},
328 {CTDB_CONTROL_WIPE_DATABASE, "WIPE_DATABASE"},
329 {CTDB_CONTROL_UPTIME, "UPTIME"},
330 {CTDB_CONTROL_START_RECOVERY, "START_RECOVERY"},
331 {CTDB_CONTROL_END_RECOVERY, "END_RECOVERY"},
332 {CTDB_CONTROL_RELOAD_NODES_FILE, "RELOAD_NODES_FILE"},
333 {CTDB_CONTROL_TRY_DELETE_RECORDS, "TRY_DELETE_RECORDS"},
334 {CTDB_CONTROL_ENABLE_MONITOR, "ENABLE_MONITOR"},
335 {CTDB_CONTROL_DISABLE_MONITOR, "DISABLE_MONITOR"},
336 {CTDB_CONTROL_ADD_PUBLIC_IP, "ADD_PUBLIC_IP"},
337 {CTDB_CONTROL_DEL_PUBLIC_IP, "DEL_PUBLIC_IP"},
338 {CTDB_CONTROL_RUN_EVENTSCRIPTS, "RUN_EVENTSCRIPTS"},
339 {CTDB_CONTROL_GET_CAPABILITIES, "GET_CAPABILITIES"},
340 {CTDB_CONTROL_START_PERSISTENT_UPDATE, "START_PERSISTENT_UPDATE"},
341 {CTDB_CONTROL_CANCEL_PERSISTENT_UPDATE, "CANCEL_PERSISTENT_UPDATE"},
342 {CTDB_CONTROL_TRANS2_COMMIT, "TRANS2_COMMIT"},
343 {CTDB_CONTROL_TRANS2_FINISHED, "TRANS2_FINISHED"},
344 {CTDB_CONTROL_TRANS2_ERROR, "TRANS2_ERROR"},
345 {CTDB_CONTROL_TRANS2_COMMIT_RETRY, "TRANS2_COMMIT_RETRY"},
346 {CTDB_CONTROL_RECD_PING, "RECD_PING"},
347 {CTDB_CONTROL_RELEASE_IP, "RELEASE_IP"},
348 {CTDB_CONTROL_TAKEOVER_IP, "TAKEOVER_IP"},
349 {CTDB_CONTROL_GET_PUBLIC_IPS, "GET_PUBLIC_IPS"},
350 {CTDB_CONTROL_GET_NODEMAP, "GET_NODEMAP"},
351 {CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, "GET_EVENT_SCRIPT_STATUS"},
352 {CTDB_CONTROL_TRAVERSE_KILL, "TRAVERSE_KILL"},
353 {CTDB_CONTROL_RECD_RECLOCK_LATENCY, "RECD_RECLOCK_LATENCY"},
354 {CTDB_CONTROL_GET_RECLOCK_FILE, "GET_RECLOCK_FILE"},
355 {CTDB_CONTROL_SET_RECLOCK_FILE, "SET_RECLOCK_FILE"},
356 {CTDB_CONTROL_STOP_NODE, "STOP_NODE"},
357 {CTDB_CONTROL_CONTINUE_NODE, "CONTINUE_NODE"},
358 {CTDB_CONTROL_SET_NATGWSTATE, "SET_NATGWSTATE"},
359 {CTDB_CONTROL_SET_LMASTERROLE, "SET_LMASTERROLE"},
360 {CTDB_CONTROL_SET_RECMASTERROLE, "SET_RECMASTERROLE"},
361 {CTDB_CONTROL_ENABLE_SCRIPT, "ENABLE_SCRIPT"},
362 {CTDB_CONTROL_DISABLE_SCRIPT, "DISABLE_SCRIPT"},
363 {CTDB_CONTROL_SET_BAN_STATE, "SET_BAN_STATE"},
364 {CTDB_CONTROL_GET_BAN_STATE, "GET_BAN_STATE"},
365 {CTDB_CONTROL_SET_DB_PRIORITY, "SET_DB_PRIORITY"},
366 {CTDB_CONTROL_GET_DB_PRIORITY, "GET_DB_PRIORITY"},
367 {CTDB_CONTROL_TRANSACTION_CANCEL, "TRANSACTION_CANCEL"},
368 {CTDB_CONTROL_REGISTER_NOTIFY, "REGISTER_NOTIFY"},
369 {CTDB_CONTROL_DEREGISTER_NOTIFY, "DEREGISTER_NOTIFY"},
370 {CTDB_CONTROL_TRANS2_ACTIVE, "TRANS2_ACTIVE"},
371 {CTDB_CONTROL_GET_LOG, "GET_LOG"},
372 {CTDB_CONTROL_CLEAR_LOG, "CLEAR_LOG"},
373 {CTDB_CONTROL_TRANS3_COMMIT, "TRANS3_COMMIT"},
374 {CTDB_CONTROL_GET_DB_SEQNUM, "GET_DB_SEQNUM"},
375 {CTDB_CONTROL_DB_SET_HEALTHY, "DB_SET_HEALTHY"},
376 {CTDB_CONTROL_DB_GET_HEALTH, "DB_GET_HEALTH"},
377 {CTDB_CONTROL_GET_PUBLIC_IP_INFO, "GET_PUBLIC_IP_INFO"},
378 {CTDB_CONTROL_GET_IFACES, "GET_IFACES"},
379 {CTDB_CONTROL_SET_IFACE_LINK_STATE, "SET_IFACE_LINK_STATE"},
380 {CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE, "TCP_ADD_DELAYED_UPDATE"},
381 {CTDB_CONTROL_GET_STAT_HISTORY, "GET_STAT_HISTORY"},
382 {CTDB_CONTROL_SCHEDULE_FOR_DELETION, "SCHEDULE_FOR_DELETION"},
383 {CTDB_CONTROL_SET_DB_READONLY, "SET_DB_READONLY"},
384 {CTDB_CONTROL_CHECK_SRVIDS, "CHECK_SRVIDS"},
385 {CTDB_CONTROL_TRAVERSE_START_EXT, "TRAVERSE_START_EXT"},
386 {CTDB_CONTROL_GET_DB_STATISTICS, "GET_DB_STATISTICS"},
387 {CTDB_CONTROL_SET_DB_STICKY, "SET_DB_STICKY"},
388 {CTDB_CONTROL_RELOAD_PUBLIC_IPS, "RELOAD_PUBLIC_IPS"},
389 {CTDB_CONTROL_TRAVERSE_ALL_EXT, "TRAVERSE_ALL_EXT"},
390 {CTDB_CONTROL_RECEIVE_RECORDS, "RECEIVE_RECORDS"},
391 {CTDB_CONTROL_IPREALLOCATED, "IPREALLOCATED"},
392 {CTDB_CONTROL_GET_RUNSTATE, "GET_RUNSTATE"},
393 {CTDB_CONTROL_DB_DETACH, "DB_DETACH"},
394 {CTDB_CONTROL_GET_NODES_FILE, "GET_NODES_FILE"},
395 {CTDB_CONTROL_DB_FREEZE, "DB_FREEZE"},
396 {CTDB_CONTROL_DB_THAW, "DB_THAW"},
397 {CTDB_CONTROL_DB_TRANSACTION_START, "DB_TRANSACTION_START"},
398 {CTDB_CONTROL_DB_TRANSACTION_COMMIT, "DB_TRANSACTION_COMMIT"},
399 {CTDB_CONTROL_DB_TRANSACTION_CANCEL, "DB_TRANSACTION_CANCEL"},
400 {CTDB_CONTROL_DB_PULL, "DB_PULL"},
401 {CTDB_CONTROL_DB_PUSH_START, "DB_PUSH_START"},
402 {CTDB_CONTROL_DB_PUSH_CONFIRM, "DB_PUSH_CONFIRM"},
403 {0, NULL}
408 static int dissect_control_get_recmaster_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t status, int endianess _U_)
410 proto_tree_add_uint(tree, hf_ctdb_recmaster, tvb, 0, 0, status);
412 col_append_fstr(pinfo->cinfo, COL_INFO, " RecMaster:%d", status);
414 return offset;
417 static const value_string recmode_vals[] = {
418 {0, "NORMAL"},
419 {1, "RECOVERY ACTIVE"},
420 {0, NULL}
423 static int dissect_control_get_recmode_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t status, int endianess _U_)
425 proto_tree_add_uint(tree, hf_ctdb_recmode, tvb, 0, 0, status);
427 col_append_fstr(pinfo->cinfo, COL_INFO, " RecMode:%s",
428 val_to_str(status, recmode_vals, "Unknown:%d"));
430 return offset;
433 #define CTDB_MAX_NODES 500 /* Arbitrary. */
434 static int dissect_control_get_nodemap_reply(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t status _U_, int endianess)
436 uint32_t num_nodes;
437 proto_item *item;
439 /* num nodes */
440 item = proto_tree_add_item(tree, hf_ctdb_num_nodes, tvb, offset, 4, endianess);
441 if(endianess){
442 num_nodes=tvb_get_letohl(tvb, offset);
443 } else {
444 num_nodes=tvb_get_ntohl(tvb, offset);
446 offset+=4;
448 if (num_nodes > CTDB_MAX_NODES) {
449 expert_add_info_format(pinfo, item, &ei_ctdb_too_many_nodes, "Too many nodes (%u). Stopping dissection.", num_nodes);
450 return offset;
453 while(num_nodes--){
454 /* vnn */
455 proto_tree_add_item(tree, hf_ctdb_vnn, tvb, offset, 4, endianess);
456 offset+=4;
458 /* node flags */
459 proto_tree_add_item(tree, hf_ctdb_node_flags, tvb, offset, 4, endianess);
460 offset+=4;
462 /* here comes a sockaddr_in but we only store ipv4 addresses in it */
463 proto_tree_add_item(tree, hf_ctdb_node_ip, tvb, offset+4, 4, ENC_BIG_ENDIAN);
464 offset+=16;
467 return offset;
470 static int dissect_control_process_exist_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t status _U_, int endianess)
472 uint32_t pid;
474 /* pid */
475 proto_tree_add_item(tree, hf_ctdb_pid, tvb, offset, 4, endianess);
476 if(endianess){
477 pid=tvb_get_letohl(tvb, offset);
478 } else {
479 pid=tvb_get_ntohl(tvb, offset);
481 offset+=4;
483 col_append_fstr(pinfo->cinfo, COL_INFO, " pid:%d", pid);
485 return offset;
488 static const true_false_string process_exists_tfs = {
489 "Process does NOT exist",
490 "Process Exists"
493 static int dissect_control_process_exist_reply(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t status, int endianess _U_)
495 proto_tree_add_boolean(tree, hf_ctdb_process_exists, tvb, offset, 4, status);
496 return offset;
499 /* This defines the array of dissectors for request/reply controls */
500 typedef int (*control_dissector)(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t status, int endianess);
502 typedef struct _control_dissector_array_t {
503 uint32_t opcode;
504 control_dissector request_dissector;
505 control_dissector reply_dissector;
506 } control_dissector_array_t;
508 static control_dissector_array_t control_dissectors[] = {
509 {CTDB_CONTROL_GET_RECMASTER,
510 NULL,
511 dissect_control_get_recmaster_reply},
512 {CTDB_CONTROL_GET_RECMODE,
513 NULL,
514 dissect_control_get_recmode_reply},
515 {CTDB_CONTROL_GET_NODEMAP,
516 NULL,
517 dissect_control_get_nodemap_reply},
518 {CTDB_CONTROL_FREEZE,
519 NULL,
520 NULL},
521 {CTDB_CONTROL_THAW,
522 NULL,
523 NULL},
524 {CTDB_CONTROL_PROCESS_EXISTS,
525 dissect_control_process_exist_request,
526 dissect_control_process_exist_reply},
528 /*CTDB_CONTROL_STATISTICS*/
529 /*CTDB_CONTROL_CONFIG*/
530 /*CTDB_CONTROL_PING*/
531 /*CTDB_CONTROL_GETDBPATH*/
532 /*CTDB_CONTROL_GETVNNMAP*/
533 /*CTDB_CONTROL_SETVNNMAP*/
534 /*CTDB_CONTROL_GET_DEBUG*/
535 /*CTDB_CONTROL_SET_DEBUG*/
536 /*CTDB_CONTROL_GET_DBMAP*/
537 /*CTDB_CONTROL_SET_DMASTER*/
538 /*CTDB_CONTROL_CLEAR_DB*/
539 /*CTDB_CONTROL_PULL_DB*/
540 /*CTDB_CONTROL_PUSH_DB*/
541 /*CTDB_CONTROL_SET_RECMODE*/
542 /*CTDB_CONTROL_STATISTICS_RESET*/
543 /*CTDB_CONTROL_DB_ATTACH*/
544 /*CTDB_CONTROL_SET_CALL*/
545 /*CTDB_CONTROL_TRAVERSE_START*/
546 /*CTDB_CONTROL_TRAVERSE_ALL*/
547 /*CTDB_CONTROL_TRAVERSE_DATA*/
548 /*CTDB_CONTROL_REGISTER_SRVID*/
549 /*CTDB_CONTROL_DEREGISTER_SRVID*/
550 /*CTDB_CONTROL_GET_DBNAME*/
551 /*CTDB_CONTROL_ENABLE_SEQNUM*/
552 /*CTDB_CONTROL_UPDATE_SEQNUM*/
553 /*CTDB_CONTROL_SET_SEQNUM_FREQUENCY*/
554 /*CTDB_CONTROL_DUMP_MEMORY*/
555 /*CTDB_CONTROL_GET_PID*/
556 /*CTDB_CONTROL_SET_RECMASTER*/
557 /*CTDB_CONTROL_GET_VNN*/
558 /*CTDB_CONTROL_SHUTDOWN*/
559 /*CTDB_CONTROL_GET_MONMODE*/
560 /*CTDB_CONTROL_SET_MONMODE*/
561 /*CTDB_CONTROL_MAX_RSN*/
562 /*CTDB_CONTROL_SET_RSN_NONEMPTY*/
563 /*CTDB_CONTROL_DELETE_LOW_RSN*/
564 /*CTDB_CONTROL_TAKEOVER_IP*/
565 /*CTDB_CONTROL_RELEASE_IP*/
566 /*CTDB_CONTROL_TCP_CLIENT*/
567 /*CTDB_CONTROL_TCP_ADD*/
568 /*CTDB_CONTROL_TCP_REMOVE*/
569 /*CTDB_CONTROL_STARTUP*/
570 /*CTDB_CONTROL_SET_TUNABLE*/
571 /*CTDB_CONTROL_GET_TUNABLE*/
572 /*CTDB_CONTROL_LIST_TUNABLES*/
573 /*CTDB_CONTROL_GET_PUBLIC_IPS*/
574 /*CTDB_CONTROL_MODIFY_FLAGS*/
575 /*CTDB_CONTROL_GET_ALL_TUNABLES*/
576 /*CTDB_CONTROL_KILL_TCP*/
577 /*CTDB_CONTROL_GET_TCP_TICKLE_LIST*/
578 /*CTDB_CONTROL_SET_TCP_TICKLE_LIST*/
579 {0, NULL, NULL}
582 static control_dissector find_control_dissector(uint32_t opcode, bool is_request)
584 control_dissector_array_t *cd=control_dissectors;
586 while(cd){
587 if((!cd->opcode)&&(!cd->request_dissector)&&(!cd->reply_dissector)){
588 break;
590 if(opcode==cd->opcode){
591 if(is_request){
592 return cd->request_dissector;
593 } else {
594 return cd->reply_dissector;
597 cd++;
599 return NULL;
602 static const value_string ctdb_dbid_vals[] = {
603 {0x435d3410, "notify.tdb"},
604 {0x42fe72c5, "locking.tdb"},
605 {0x1421fb78, "brlock.tdb"},
606 {0x17055d90, "connections.tdb"},
607 {0xc0bdde6a, "sessionid.tdb"},
608 {0, NULL}
611 static void
612 ctdb_display_trans(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, ctdb_trans_t *ctdb_trans)
614 proto_item *item;
616 if(ctdb_trans->request_in!=pinfo->num){
617 item=proto_tree_add_uint(tree, hf_ctdb_request_in, tvb, 0, 0, ctdb_trans->request_in);
618 proto_item_set_generated(item);
621 if( (ctdb_trans->response_in!=0)
622 &&(ctdb_trans->response_in!=pinfo->num) ){
623 item=proto_tree_add_uint(tree, hf_ctdb_response_in, tvb, 0, 0, ctdb_trans->response_in);
624 proto_item_set_generated(item);
627 if(pinfo->num==ctdb_trans->response_in){
628 nstime_t ns;
630 nstime_delta(&ns, &pinfo->abs_ts, &ctdb_trans->req_time);
631 item=proto_tree_add_time(tree, hf_ctdb_time, tvb, 0, 0, &ns);
632 proto_item_set_generated(item);
636 static void
637 ctdb_display_control(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, ctdb_control_t *ctdb_control)
639 proto_item *item;
641 if(ctdb_control->request_in!=pinfo->num){
642 item=proto_tree_add_uint(tree, hf_ctdb_request_in, tvb, 0, 0, ctdb_control->request_in);
643 proto_item_set_generated(item);
646 if( (ctdb_control->response_in!=0)
647 &&(ctdb_control->response_in!=pinfo->num) ){
648 item=proto_tree_add_uint(tree, hf_ctdb_response_in, tvb, 0, 0, ctdb_control->response_in);
649 proto_item_set_generated(item);
652 if(pinfo->num==ctdb_control->response_in){
653 nstime_t ns;
655 nstime_delta(&ns, &pinfo->abs_ts, &ctdb_control->req_time);
656 item=proto_tree_add_time(tree, hf_ctdb_time, tvb, 0, 0, &ns);
657 proto_item_set_generated(item);
661 static uint32_t
662 ctdb_hash(tvbuff_t *tvb, int offset, uint32_t len)
664 uint32_t value;
665 uint32_t i;
667 for(value=0x238F13AF*len, i=0; i < len; i++)
668 value=(value+(tvb_get_uint8(tvb, offset+i) << (i*5 % 24)));
670 return (1103515243 * value + 12345);
673 static int
674 dissect_ctdb_key(proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t keylen, uint32_t *key_hash, int endianess)
676 uint32_t keyhash;
677 proto_item *key_item=NULL;
678 proto_item *key_tree=NULL;
680 if(tree){
681 key_item=proto_tree_add_item(tree, hf_ctdb_key, tvb, offset, keylen, endianess);
682 key_tree=proto_item_add_subtree(key_item, ett_ctdb_key);
686 keyhash=ctdb_hash(tvb, offset, keylen);
687 proto_item_append_text(key_item, " (Hash:0x%08x)", keyhash);
688 key_item=proto_tree_add_uint(key_tree, hf_ctdb_keyhash, tvb, 0, 0, keyhash);
689 proto_item_set_generated(key_item);
691 offset+=keylen;
693 if(key_hash){
694 *key_hash=keyhash;
697 return offset;
700 static int
701 dissect_ctdb_reply_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int endianess)
703 uint32_t datalen;
705 /* status */
706 proto_tree_add_item(tree, hf_ctdb_status, tvb, offset, 4, endianess);
707 offset+=4;
709 /* datalen */
710 proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
711 if(endianess){
712 datalen=tvb_get_letohl(tvb, offset);
713 } else {
714 datalen=tvb_get_ntohl(tvb, offset);
716 offset+=4;
718 /* data */
719 proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
720 offset+=datalen;
723 return offset;
726 static int
727 dissect_ctdb_reply_dmaster(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, uint32_t reqid, uint32_t dst, int endianess)
729 uint32_t datalen, keylen;
730 wmem_tree_key_t tkey[3];
731 ctdb_trans_t *ctdb_trans;
733 /* dbid */
734 proto_tree_add_item(tree, hf_ctdb_dbid, tvb, offset, 4, endianess);
735 offset+=4;
738 /* rsn */
739 offset=(offset+7)&0xfffff8; /* fixup alignment*/
740 proto_tree_add_item(tree, hf_ctdb_rsn, tvb, offset, 8, endianess);
741 offset+=8;
743 /* keylen */
744 proto_tree_add_item(tree, hf_ctdb_keylen, tvb, offset, 4, endianess);
745 if(endianess){
746 keylen=tvb_get_letohl(tvb, offset);
747 } else {
748 keylen=tvb_get_ntohl(tvb, offset);
750 offset+=4;
752 /* datalen */
753 proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
754 if(endianess){
755 datalen=tvb_get_letohl(tvb, offset);
756 } else {
757 datalen=tvb_get_ntohl(tvb, offset);
759 offset+=4;
761 /* key */
762 offset=dissect_ctdb_key(tree, tvb, offset, keylen, NULL, endianess);
764 /* data */
765 proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
766 offset+=datalen;
768 tkey[0].length=1;
769 tkey[0].key=&reqid;
770 tkey[1].length=1;
771 tkey[1].key=&dst;
772 tkey[2].length=0;
773 ctdb_trans=(ctdb_trans_t *)wmem_tree_lookup32_array(ctdb_transactions, &tkey[0]);
775 if(ctdb_trans){
776 ctdb_trans->response_in=pinfo->num;
777 ctdb_display_trans(pinfo, tree, tvb, ctdb_trans);
780 return offset;
783 static int
784 dissect_ctdb_req_dmaster(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, uint32_t reqid, int endianess)
786 uint32_t keylen, datalen, dmaster;
787 wmem_tree_key_t tkey[3];
788 ctdb_trans_t *ctdb_trans;
790 /* dbid */
791 proto_tree_add_item(tree, hf_ctdb_dbid, tvb, offset, 4, endianess);
792 offset+=4;
794 /* rsn */
795 offset=(offset+7)&0xfffff8; /* fixup alignment*/
796 proto_tree_add_item(tree, hf_ctdb_rsn, tvb, offset, 8, endianess);
797 offset+=8;
799 /* dmaster */
800 proto_tree_add_item(tree, hf_ctdb_dmaster, tvb, offset, 4, endianess);
801 if(endianess){
802 dmaster=tvb_get_letohl(tvb, offset);
803 } else {
804 dmaster=tvb_get_ntohl(tvb, offset);
806 offset += 4;
808 /* keylen */
809 proto_tree_add_item(tree, hf_ctdb_keylen, tvb, offset, 4, endianess);
810 if(endianess){
811 keylen=tvb_get_letohl(tvb, offset);
812 } else {
813 keylen=tvb_get_ntohl(tvb, offset);
815 offset+=4;
817 /* datalen */
818 proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
819 if(endianess){
820 datalen=tvb_get_letohl(tvb, offset);
821 } else {
822 datalen=tvb_get_ntohl(tvb, offset);
824 offset+=4;
826 /* key */
827 offset=dissect_ctdb_key(tree, tvb, offset, keylen, NULL, endianess);
829 /* data */
830 proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
831 offset+=datalen;
834 tkey[0].length=1;
835 tkey[0].key=&reqid;
836 tkey[1].length=1;
837 tkey[1].key=&dmaster;
838 tkey[2].length=0;
839 ctdb_trans=(ctdb_trans_t *)wmem_tree_lookup32_array(ctdb_transactions, &tkey[0]);
841 if(ctdb_trans){
842 ctdb_display_trans(pinfo, tree, tvb, ctdb_trans);
845 return offset;
850 static int
851 dissect_ctdb_req_control(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, uint32_t reqid, uint32_t src, uint32_t dst, int endianess)
853 uint32_t datalen;
854 uint32_t opcode;
855 ctdb_control_t *ctdb_control;
856 control_dissector cd;
857 int data_offset;
859 /* ctrl opcode */
860 proto_tree_add_item(tree, hf_ctdb_ctrl_opcode, tvb, offset, 4, endianess);
861 if(endianess){
862 opcode=tvb_get_letohl(tvb, offset);
863 } else {
864 opcode=tvb_get_ntohl(tvb, offset);
866 offset+=4;
868 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request %d->%d",
869 val_to_str(opcode, ctrl_opcode_vals, "Unknown:%d"),
870 src, dst);
872 /* srvid */
873 offset=(offset+7)&0xfffff8; /* fixup alignment*/
874 proto_tree_add_item(tree, hf_ctdb_srvid, tvb, offset, 8, endianess);
875 offset+=8;
877 /* client id */
878 proto_tree_add_item(tree, hf_ctdb_clientid, tvb, offset, 4, endianess);
879 offset+=4;
881 /* ctrl flags */
882 proto_tree_add_item(tree, hf_ctdb_ctrl_flags, tvb, offset, 4, endianess);
883 offset+=4;
885 /* datalen */
886 proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
887 if(endianess){
888 datalen=tvb_get_letohl(tvb, offset);
889 } else {
890 datalen=tvb_get_ntohl(tvb, offset);
892 offset+=4;
894 /* data */
895 data_offset=offset;
896 if (datalen) {
897 proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
898 offset+=datalen;
901 /* setup request/response matching */
902 if(!pinfo->fd->visited){
903 wmem_tree_key_t tkey[4];
905 ctdb_control=wmem_new(wmem_file_scope(), ctdb_control_t);
906 ctdb_control->opcode=opcode;
907 ctdb_control->request_in=pinfo->num;
908 ctdb_control->response_in=0;
909 ctdb_control->req_time=pinfo->abs_ts;
910 tkey[0].length=1;
911 tkey[0].key=&reqid;
912 tkey[1].length=1;
913 tkey[1].key=&src;
914 tkey[2].length=1;
915 tkey[2].key=&dst;
916 tkey[3].length=0;
918 wmem_tree_insert32_array(ctdb_controls, &tkey[0], ctdb_control);
919 } else {
920 wmem_tree_key_t tkey[4];
922 tkey[0].length=1;
923 tkey[0].key=&reqid;
924 tkey[1].length=1;
925 tkey[1].key=&src;
926 tkey[2].length=1;
927 tkey[2].key=&dst;
928 tkey[3].length=0;
929 ctdb_control=(ctdb_control_t *)wmem_tree_lookup32_array(ctdb_controls, &tkey[0]);
932 if (ctdb_control) {
933 cd=find_control_dissector(ctdb_control->opcode, true);
934 if (cd) {
935 cd(pinfo, tree, tvb, data_offset, 0, endianess);
937 ctdb_display_control(pinfo, tree, tvb, ctdb_control);
940 return offset;
943 static int
944 dissect_ctdb_reply_control(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, uint32_t reqid, uint32_t src, uint32_t dst, int endianess)
946 ctdb_control_t *ctdb_control;
947 wmem_tree_key_t tkey[4];
948 proto_item *item;
949 uint32_t datalen, errorlen, status;
950 int data_offset;
951 control_dissector cd;
953 tkey[0].length=1;
954 tkey[0].key=&reqid;
955 tkey[1].length=1;
956 tkey[1].key=&dst;
957 tkey[2].length=1;
958 tkey[2].key=&src;
959 tkey[3].length=0;
960 ctdb_control=(ctdb_control_t *)wmem_tree_lookup32_array(ctdb_controls, &tkey[0]);
962 if(!ctdb_control){
963 return offset;
966 if(!pinfo->fd->visited){
967 ctdb_control->response_in = pinfo->num;
970 /* ctrl opcode */
971 item=proto_tree_add_uint(tree, hf_ctdb_ctrl_opcode, tvb, 0, 0, ctdb_control->opcode);
972 proto_item_set_generated(item);
974 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Reply %d->%d",
975 val_to_str(ctdb_control->opcode, ctrl_opcode_vals, "Unknown:%d"),
976 src, dst);
979 /* status */
980 proto_tree_add_item(tree, hf_ctdb_status, tvb, offset, 4, endianess);
981 if(endianess){
982 status=tvb_get_letohl(tvb, offset);
983 } else {
984 status=tvb_get_ntohl(tvb, offset);
986 offset+=4;
988 /* datalen */
989 proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
990 if(endianess){
991 datalen=tvb_get_letohl(tvb, offset);
992 } else {
993 datalen=tvb_get_ntohl(tvb, offset);
995 offset+=4;
997 /* errorlen */
998 proto_tree_add_item(tree, hf_ctdb_errorlen, tvb, offset, 4, endianess);
999 if(endianess){
1000 errorlen=tvb_get_letohl(tvb, offset);
1001 } else {
1002 errorlen=tvb_get_ntohl(tvb, offset);
1004 offset+=4;
1006 /* data */
1007 data_offset=offset;
1008 if (datalen) {
1009 proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
1010 offset+=datalen;
1014 /* error */
1015 if (errorlen) {
1016 proto_tree_add_item(tree, hf_ctdb_error, tvb, offset, errorlen, endianess);
1017 offset+=errorlen;
1021 cd=find_control_dissector(ctdb_control->opcode, false);
1022 if (cd) {
1023 cd(pinfo, tree, tvb, data_offset, status, endianess);
1026 ctdb_display_control(pinfo, tree, tvb, ctdb_control);
1027 return offset;
1030 static const true_false_string flags_immediate_tfs={
1031 "DMASTER for the record must IMMEDIATELY be migrated to the caller",
1032 "Dmaster migration is not required"
1035 static int
1036 dissect_ctdb_req_call(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, uint32_t reqid, uint32_t caller, int endianess)
1038 uint32_t flags, keyhash;
1039 uint32_t keylen, datalen;
1040 ctdb_trans_t *ctdb_trans=NULL;
1042 /* flags */
1043 proto_tree_add_item(tree, hf_ctdb_flags_immediate, tvb, offset, 4, endianess);
1044 if(endianess){
1045 flags=tvb_get_letohl(tvb, offset);
1046 } else {
1047 flags=tvb_get_ntohl(tvb, offset);
1049 if(flags&0x00000001){
1050 col_append_str(pinfo->cinfo, COL_INFO, " IMMEDIATE");
1052 offset+=4;
1054 /* dbid */
1055 proto_tree_add_item(tree, hf_ctdb_dbid, tvb, offset, 4, endianess);
1056 offset+=4;
1058 /* callid */
1059 proto_tree_add_item(tree, hf_ctdb_callid, tvb, offset, 4, endianess);
1060 offset+=4;
1062 /* hopcount */
1063 proto_tree_add_item(tree, hf_ctdb_hopcount, tvb, offset, 4, endianess);
1064 offset+=4;
1066 /* keylen */
1067 proto_tree_add_item(tree, hf_ctdb_keylen, tvb, offset, 4, endianess);
1068 if(endianess){
1069 keylen=tvb_get_letohl(tvb, offset);
1070 } else {
1071 keylen=tvb_get_ntohl(tvb, offset);
1073 offset+=4;
1075 /* datalen */
1076 proto_tree_add_item(tree, hf_ctdb_datalen, tvb, offset, 4, endianess);
1077 if(endianess){
1078 datalen=tvb_get_letohl(tvb, offset);
1079 } else {
1080 datalen=tvb_get_ntohl(tvb, offset);
1082 offset+=4;
1084 /* key */
1085 offset=dissect_ctdb_key(tree, tvb, offset, keylen, &keyhash, endianess);
1087 /* data */
1088 proto_tree_add_item(tree, hf_ctdb_data, tvb, offset, datalen, endianess);
1089 offset+=datalen;
1091 /* setup request/response matching */
1092 if(!pinfo->fd->visited){
1093 wmem_tree_key_t tkey[3];
1095 ctdb_trans=wmem_new(wmem_file_scope(), ctdb_trans_t);
1096 ctdb_trans->key_hash=keyhash;
1097 ctdb_trans->request_in=pinfo->num;
1098 ctdb_trans->response_in=0;
1099 ctdb_trans->req_time=pinfo->abs_ts;
1100 tkey[0].length=1;
1101 tkey[0].key=&reqid;
1102 tkey[1].length=1;
1103 tkey[1].key=&caller;
1104 tkey[2].length=0;
1106 wmem_tree_insert32_array(ctdb_transactions, &tkey[0], ctdb_trans);
1107 } else {
1108 wmem_tree_key_t tkey[3];
1110 tkey[0].length=1;
1111 tkey[0].key=&reqid;
1112 tkey[1].length=1;
1113 tkey[1].key=&caller;
1114 tkey[2].length=0;
1115 ctdb_trans=(ctdb_trans_t *)wmem_tree_lookup32_array(ctdb_transactions, &tkey[0]);
1118 if(ctdb_trans){
1119 ctdb_display_trans(pinfo, tree, tvb, ctdb_trans);
1122 return offset;
1125 static gboolean
1126 dissect_ctdb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
1128 proto_tree *tree=NULL;
1129 proto_item *item=NULL;
1130 int offset=0;
1131 uint32_t opcode, src, dst, reqid;
1132 int endianess;
1134 /* does this look like CTDB? */
1135 if(tvb_captured_length(tvb)<8){
1136 return FALSE;
1138 switch(tvb_get_letohl(tvb, offset+4)){
1139 case 0x42445443:
1140 endianess=false;
1141 break;
1142 case 0x43544442:
1143 endianess=true;
1144 break;
1145 default:
1146 return FALSE;
1150 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CTDB");
1151 col_clear(pinfo->cinfo, COL_INFO);
1153 if(parent_tree){
1154 item=proto_tree_add_item(parent_tree, proto_ctdb, tvb, offset,
1155 -1, endianess);
1156 tree=proto_item_add_subtree(item, ett_ctdb);
1159 /* header*/
1160 /* length */
1161 proto_tree_add_item(tree, hf_ctdb_length, tvb, offset, 4, endianess);
1162 offset+=4;
1164 /* magic */
1165 proto_tree_add_item(tree, hf_ctdb_magic, tvb, offset, 4, endianess);
1166 offset+=4;
1168 /* version */
1169 proto_tree_add_item(tree, hf_ctdb_version, tvb, offset, 4, endianess);
1170 offset+=4;
1172 /* generation */
1173 proto_tree_add_item(tree, hf_ctdb_generation, tvb, offset, 4, endianess);
1174 offset+=4;
1176 /* opcode */
1177 proto_tree_add_item(tree, hf_ctdb_opcode, tvb, offset, 4, endianess);
1178 if(endianess){
1179 opcode=tvb_get_letohl(tvb, offset);
1180 } else {
1181 opcode=tvb_get_ntohl(tvb, offset);
1183 offset+=4;
1185 /* dst */
1186 proto_tree_add_item(tree, hf_ctdb_dst, tvb, offset, 4, endianess);
1187 if(endianess){
1188 dst=tvb_get_letohl(tvb, offset);
1189 } else {
1190 dst=tvb_get_ntohl(tvb, offset);
1192 offset+=4;
1194 /* src */
1195 proto_tree_add_item(tree, hf_ctdb_src, tvb, offset, 4, endianess);
1196 if(endianess){
1197 src=tvb_get_letohl(tvb, offset);
1198 } else {
1199 src=tvb_get_ntohl(tvb, offset);
1201 offset+=4;
1203 /* id */
1204 proto_tree_add_item(tree, hf_ctdb_id, tvb, offset, 4, endianess);
1205 if(endianess){
1206 reqid=tvb_get_letohl(tvb, offset);
1207 } else {
1208 reqid=tvb_get_ntohl(tvb, offset);
1210 offset+=4;
1212 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %d->%d",
1213 val_to_str(opcode, ctdb_opcodes, "Unknown:%d"),
1214 src, dst);
1216 switch(opcode){
1217 case CTDB_REQ_CALL:
1218 dissect_ctdb_req_call(tvb, offset, pinfo, tree, reqid, src, endianess);
1219 break;
1220 case CTDB_REPLY_CALL:
1221 dissect_ctdb_reply_call(tvb, offset, pinfo, tree, endianess);
1222 break;
1223 case CTDB_REPLY_DMASTER:
1224 dissect_ctdb_reply_dmaster(tvb, offset, pinfo, tree, reqid, dst, endianess);
1225 break;
1226 case CTDB_REQ_DMASTER:
1227 dissect_ctdb_req_dmaster(tvb, offset, pinfo, tree, reqid, endianess);
1228 break;
1229 case CTDB_REPLY_ERROR:
1230 break;
1231 case CTDB_REQ_MESSAGE:
1232 break;
1233 case CTDB_REQ_CONTROL:
1234 dissect_ctdb_req_control(tvb, offset, pinfo, tree, reqid, src, dst, endianess);
1235 break;
1236 case CTDB_REPLY_CONTROL:
1237 dissect_ctdb_reply_control(tvb, offset, pinfo, tree, reqid, src, dst, endianess);
1238 break;
1241 return TRUE;
1244 static bool
1245 dissect_ctdb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1247 return (bool)dissect_ctdb(tvb, pinfo, tree, data);
1251 * Register the protocol with Wireshark
1253 void
1254 proto_register_ctdb(void)
1256 static hf_register_info hf[] = {
1257 { &hf_ctdb_length, {
1258 "Length", "ctdb.len", FT_UINT32, BASE_DEC,
1259 NULL, 0x0, "Size of CTDB PDU", HFILL }},
1260 { &hf_ctdb_dst, {
1261 "Destination", "ctdb.dst", FT_UINT32, BASE_DEC,
1262 NULL, 0x0, NULL, HFILL }},
1263 { &hf_ctdb_src, {
1264 "Source", "ctdb.src", FT_UINT32, BASE_DEC,
1265 NULL, 0x0, NULL, HFILL }},
1266 { &hf_ctdb_id, {
1267 "Id", "ctdb.id", FT_UINT32, BASE_DEC,
1268 NULL, 0x0, "Transaction ID", HFILL }},
1269 { &hf_ctdb_opcode, {
1270 "Opcode", "ctdb.opcode", FT_UINT32, BASE_DEC,
1271 VALS(ctdb_opcodes), 0x0, "CTDB command opcode", HFILL }},
1272 { &hf_ctdb_flags_immediate, {
1273 "Immediate", "ctdb.immediate", FT_BOOLEAN, 32,
1274 TFS(&flags_immediate_tfs), 0x00000001, "Force migration of DMASTER?", HFILL }},
1275 { &hf_ctdb_dbid, {
1276 "DB Id", "ctdb.dbid", FT_UINT32, BASE_HEX,
1277 VALS(ctdb_dbid_vals), 0x0, "Database ID", HFILL }},
1278 { &hf_ctdb_callid, {
1279 "Call Id", "ctdb.callid", FT_UINT32, BASE_DEC,
1280 NULL, 0x0, NULL, HFILL }},
1281 { &hf_ctdb_status, {
1282 "Status", "ctdb.status", FT_UINT32, BASE_DEC,
1283 NULL, 0x0, NULL, HFILL }},
1284 { &hf_ctdb_datalen, {
1285 "Data Length", "ctdb.datalen", FT_UINT32, BASE_DEC,
1286 NULL, 0x0, NULL, HFILL }},
1287 { &hf_ctdb_errorlen, {
1288 "Error Length", "ctdb.errorlen", FT_UINT32, BASE_DEC,
1289 NULL, 0x0, NULL, HFILL }},
1290 { &hf_ctdb_keylen, {
1291 "Key Length", "ctdb.keylen", FT_UINT32, BASE_DEC,
1292 NULL, 0x0, NULL, HFILL }},
1293 { &hf_ctdb_magic, {
1294 "Magic", "ctdb.magic", FT_UINT32, BASE_HEX,
1295 NULL, 0x0, NULL, HFILL }},
1296 { &hf_ctdb_version, {
1297 "Version", "ctdb.version", FT_UINT32, BASE_DEC,
1298 NULL, 0x0, NULL, HFILL }},
1299 { &hf_ctdb_dmaster, {
1300 "Dmaster", "ctdb.dmaster", FT_UINT32, BASE_DEC,
1301 NULL, 0x0, NULL, HFILL }},
1302 { &hf_ctdb_generation, {
1303 "Generation", "ctdb.generation", FT_UINT32, BASE_DEC,
1304 NULL, 0x0, NULL, HFILL }},
1305 { &hf_ctdb_key, {
1306 "Key", "ctdb.key", FT_BYTES, BASE_NONE,
1307 NULL, 0x0, NULL, HFILL }},
1308 { &hf_ctdb_keyhash, {
1309 "KeyHash", "ctdb.keyhash", FT_UINT32, BASE_HEX,
1310 NULL, 0x0, NULL, HFILL }},
1311 { &hf_ctdb_data, {
1312 "Data", "ctdb.data", FT_BYTES, BASE_NONE,
1313 NULL, 0x0, NULL, HFILL }},
1314 { &hf_ctdb_error, {
1315 "Error", "ctdb.error", FT_BYTES, BASE_NONE,
1316 NULL, 0x0, NULL, HFILL }},
1317 { &hf_ctdb_request_in, {
1318 "Request In", "ctdb.request_in", FT_FRAMENUM, BASE_NONE,
1319 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0, NULL, HFILL }},
1320 { &hf_ctdb_response_in, {
1321 "Response In", "ctdb.response_in", FT_FRAMENUM, BASE_NONE,
1322 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0, NULL, HFILL }},
1323 { &hf_ctdb_time, {
1324 "Time since request", "ctdb.time", FT_RELATIVE_TIME, BASE_NONE,
1325 NULL, 0x0, NULL, HFILL }},
1326 { &hf_ctdb_hopcount, {
1327 "Hopcount", "ctdb.hopcount", FT_UINT32, BASE_DEC,
1328 NULL, 0x0, NULL, HFILL }},
1329 { &hf_ctdb_rsn, {
1330 "RSN", "ctdb.rsn", FT_UINT64, BASE_HEX,
1331 NULL, 0x0, NULL, HFILL }},
1332 { &hf_ctdb_ctrl_opcode, {
1333 "CTRL Opcode", "ctdb.ctrl_opcode", FT_UINT32, BASE_DEC,
1334 VALS(ctrl_opcode_vals), 0x0, NULL, HFILL }},
1335 { &hf_ctdb_srvid, {
1336 "SrvId", "ctdb.srvid", FT_UINT64, BASE_HEX,
1337 NULL, 0x0, NULL, HFILL }},
1338 { &hf_ctdb_clientid, {
1339 "ClientId", "ctdb.clientid", FT_UINT32, BASE_HEX,
1340 NULL, 0x0, NULL, HFILL }},
1341 { &hf_ctdb_ctrl_flags, {
1342 "CTRL Flags", "ctdb.ctrl_flags", FT_UINT32, BASE_HEX,
1343 NULL, 0x0, NULL, HFILL }},
1344 { &hf_ctdb_recmaster, {
1345 "Recovery Master", "ctdb.recmaster", FT_UINT32, BASE_DEC,
1346 NULL, 0x0, NULL, HFILL }},
1347 { &hf_ctdb_recmode, {
1348 "Recovery Mode", "ctdb.recmode", FT_UINT32, BASE_DEC,
1349 VALS(recmode_vals), 0x0, NULL, HFILL }},
1350 { &hf_ctdb_num_nodes, {
1351 "Num Nodes", "ctdb.num_nodes", FT_UINT32, BASE_DEC,
1352 NULL, 0x0, NULL, HFILL }},
1353 { &hf_ctdb_vnn, {
1354 "VNN", "ctdb.vnn", FT_UINT32, BASE_DEC,
1355 NULL, 0x0, NULL, HFILL }},
1356 { &hf_ctdb_node_flags, {
1357 "Node Flags", "ctdb.node_flags", FT_UINT32, BASE_HEX,
1358 NULL, 0x0, NULL, HFILL }},
1359 { &hf_ctdb_node_ip, {
1360 "Node IP", "ctdb.node_ip", FT_IPv4, BASE_NONE,
1361 NULL, 0x0, NULL, HFILL }},
1362 { &hf_ctdb_pid, {
1363 "PID", "ctdb.pid", FT_UINT32, BASE_DEC,
1364 NULL, 0x0, NULL, HFILL }},
1365 { &hf_ctdb_process_exists, {
1366 "Process Exists", "ctdb.process_exists", FT_BOOLEAN, 32,
1367 TFS(&process_exists_tfs), 0x00000001, NULL, HFILL }},
1370 /* Setup protocol subtree array */
1371 static int *ett[] = {
1372 &ett_ctdb,
1373 &ett_ctdb_key,
1376 static ei_register_info ei[] = {
1377 { &ei_ctdb_too_many_nodes, { "ctdb.too_many_nodes", PI_UNDECODED, PI_WARN, "Too many nodes", EXPFILL }},
1380 expert_module_t* expert_ctdb;
1383 /* Register the protocol name and description */
1384 proto_ctdb = proto_register_protocol("Cluster TDB", "CTDB", "ctdb");
1386 /* Required function calls to register the header fields and subtrees used */
1387 proto_register_field_array(proto_ctdb, hf, array_length(hf));
1388 proto_register_subtree_array(ett, array_length(ett));
1389 expert_ctdb = expert_register_protocol(proto_ctdb);
1390 expert_register_field_array(expert_ctdb, ei, array_length(ei));
1392 /* Register the dissector */
1393 ctdb_handle = register_dissector("ctdb", dissect_ctdb, proto_ctdb);
1395 ctdb_transactions = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1396 ctdb_controls = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1400 void
1401 proto_reg_handoff_ctdb(void)
1403 dissector_add_for_decode_as_with_preference("tcp.port", ctdb_handle);
1405 heur_dissector_add("tcp", dissect_ctdb_heur, "Cluster TDB over TCP", "ctdb_tcp", proto_ctdb, HEURISTIC_ENABLE);
1409 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1411 * Local variables:
1412 * c-basic-offset: 8
1413 * tab-width: 8
1414 * indent-tabs-mode: t
1415 * End:
1417 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1418 * :indentSize=8:tabSize=8:noTabs=false: