1 /* packet-drbd.c 2 * Routines for DRBD dissection 3 * By Joel Colledge <joel.colledge@linbit.com> 4 * Copyright 2019, LINBIT Information Technologies GmbH 5 * 6 * Wireshark - Network traffic analyzer 7 * By Gerald Combs <gerald@wireshark.org> 8 * Copyright 1998 Gerald Combs 9 * 10 * SPDX-License-Identifier: GPL-2.0-or-later 11 */ 12 13 /* 14 * Wireshark dissector for DRBD - Distributed Replicated Block Device. 15 * The DRBD Linux kernel module sources can be found at https://github.com/LINBIT/drbd-9.0 16 * More information about Linbit and DRBD can be found at https://www.linbit.com/ 17 */ 18 19 #include <config.h> 20 21 #include <epan/packet.h> 22 #include <epan/prefs.h> 23 #include <epan/dissectors/packet-tcp.h> 24 25 #include <wsutil/str_util.h> 26 27 typedef struct value_payload_decoder { 28 int value; 29 void (*decoder_fn)(tvbuff_t *, proto_tree*); 30 } value_payload_decoder; 31 32 /* Known as SHARED_SECRET_MAX in the DRBD sources */ 33 #define DRBD_STRING_MAX 64 34 35 enum drbd_packet { 36 P_DATA = 0x00, 37 P_DATA_REPLY = 0x01, 38 P_RS_DATA_REPLY = 0x02, 39 P_BARRIER = 0x03, 40 P_BITMAP = 0x04, 41 P_BECOME_SYNC_TARGET = 0x05, 42 P_BECOME_SYNC_SOURCE = 0x06, 43 P_UNPLUG_REMOTE = 0x07, 44 P_DATA_REQUEST = 0x08, 45 P_RS_DATA_REQUEST = 0x09, 46 P_SYNC_PARAM = 0x0a, 47 P_PROTOCOL = 0x0b, 48 P_UUIDS = 0x0c, 49 P_SIZES = 0x0d, 50 P_STATE = 0x0e, 51 P_SYNC_UUID = 0x0f, 52 P_AUTH_CHALLENGE = 0x10, 53 P_AUTH_RESPONSE = 0x11, 54 P_STATE_CHG_REQ = 0x12, 55 56 P_PING = 0x13, 57 P_PING_ACK = 0x14, 58 P_RECV_ACK = 0x15, 59 P_WRITE_ACK = 0x16, 60 P_RS_WRITE_ACK = 0x17, 61 P_SUPERSEDED = 0x18, 62 P_NEG_ACK = 0x19, 63 P_NEG_DREPLY = 0x1a, 64 P_NEG_RS_DREPLY = 0x1b, 65 P_BARRIER_ACK = 0x1c, 66 P_STATE_CHG_REPLY = 0x1d, 67 68 P_OV_REQUEST = 0x1e, 69 P_OV_REPLY = 0x1f, 70 P_OV_RESULT = 0x20, 71 P_CSUM_RS_REQUEST = 0x21, 72 P_RS_IS_IN_SYNC = 0x22, 73 P_SYNC_PARAM89 = 0x23, 74 P_COMPRESSED_BITMAP = 0x24, 75 76 P_DELAY_PROBE = 0x27, 77 P_OUT_OF_SYNC = 0x28, 78 P_RS_CANCEL = 0x29, 79 P_CONN_ST_CHG_REQ = 0x2a, 80 P_CONN_ST_CHG_REPLY = 0x2b, 81 P_RETRY_WRITE = 0x2c, 82 P_PROTOCOL_UPDATE = 0x2d, 83 P_TWOPC_PREPARE = 0x2e, 84 P_TWOPC_ABORT = 0x2f, 85 86 P_DAGTAG = 0x30, dissect_dpnss_link(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)87 88 P_TRIM = 0x31, 89 90 P_RS_THIN_REQ = 0x32, 91 P_RS_DEALLOCATED = 0x33, 92 93 P_WSAME = 0x34, 94 P_TWOPC_PREP_RSZ = 0x35, 95 P_ZEROES = 0x36, 96 97 P_PEER_ACK = 0x40, 98 P_PEERS_IN_SYNC = 0x41, 99 100 P_UUIDS110 = 0x42, 101 P_PEER_DAGTAG = 0x43, 102 P_CURRENT_UUID = 0x44, 103 104 P_TWOPC_YES = 0x45, 105 P_TWOPC_NO = 0x46, 106 P_TWOPC_COMMIT = 0x47, 107 P_TWOPC_RETRY = 0x48, 108 109 P_CONFIRM_STABLE = 0x49, 110 111 P_INITIAL_META = 0xfff1, 112 P_INITIAL_DATA = 0xfff2, 113 114 P_CONNECTION_FEATURES = 0xfffe 115 }; 116 117 static const value_string packet_names[] = { 118 { P_DATA, "P_DATA" }, 119 { P_DATA_REPLY, "P_DATA_REPLY" }, 120 { P_RS_DATA_REPLY, "P_RS_DATA_REPLY" }, 121 { P_BARRIER, "P_BARRIER" }, 122 { P_BITMAP, "P_BITMAP" }, 123 { P_BECOME_SYNC_TARGET, "P_BECOME_SYNC_TARGET" }, 124 { P_BECOME_SYNC_SOURCE, "P_BECOME_SYNC_SOURCE" }, 125 { P_UNPLUG_REMOTE, "P_UNPLUG_REMOTE" }, 126 { P_DATA_REQUEST, "P_DATA_REQUEST" }, 127 { P_RS_DATA_REQUEST, "P_RS_DATA_REQUEST" }, 128 { P_SYNC_PARAM, "P_SYNC_PARAM" }, 129 { P_PROTOCOL, "P_PROTOCOL" }, 130 { P_UUIDS, "P_UUIDS" }, 131 { P_SIZES, "P_SIZES" }, 132 { P_STATE, "P_STATE" }, 133 { P_SYNC_UUID, "P_SYNC_UUID" }, 134 { P_AUTH_CHALLENGE, "P_AUTH_CHALLENGE" }, 135 { P_AUTH_RESPONSE, "P_AUTH_RESPONSE" }, 136 { P_STATE_CHG_REQ, "P_STATE_CHG_REQ" }, 137 138 { P_PING, "P_PING" }, 139 { P_PING_ACK, "P_PING_ACK" }, 140 { P_RECV_ACK, "P_RECV_ACK" }, 141 { P_WRITE_ACK, "P_WRITE_ACK" }, 142 { P_RS_WRITE_ACK, "P_RS_WRITE_ACK" }, 143 { P_SUPERSEDED, "P_SUPERSEDED" }, 144 { P_NEG_ACK, "P_NEG_ACK" }, 145 { P_NEG_DREPLY, "P_NEG_DREPLY" }, 146 { P_NEG_RS_DREPLY, "P_NEG_RS_DREPLY" }, 147 { P_BARRIER_ACK, "P_BARRIER_ACK" }, proto_register_dpnss_link(void)148 { P_STATE_CHG_REPLY, "P_STATE_CHG_REPLY" }, 149 150 { P_OV_REQUEST, "P_OV_REQUEST" }, 151 { P_OV_REPLY, "P_OV_REPLY" }, 152 { P_OV_RESULT, "P_OV_RESULT" }, 153 { P_CSUM_RS_REQUEST, "P_CSUM_RS_REQUEST" }, 154 { P_RS_IS_IN_SYNC, "P_RS_IS_IN_SYNC" }, 155 { P_SYNC_PARAM89, "P_SYNC_PARAM89" }, 156 { P_COMPRESSED_BITMAP, "P_COMPRESSED_BITMAP" }, 157 158 { P_DELAY_PROBE, "P_DELAY_PROBE" }, 159 { P_OUT_OF_SYNC, "P_OUT_OF_SYNC" }, 160 { P_RS_CANCEL, "P_RS_CANCEL" }, 161 { P_CONN_ST_CHG_REQ, "P_CONN_ST_CHG_REQ" }, 162 { P_CONN_ST_CHG_REPLY, "P_CONN_ST_CHG_REPLY" }, 163 { P_RETRY_WRITE, "P_RETRY_WRITE" }, 164 { P_PROTOCOL_UPDATE, "P_PROTOCOL_UPDATE" }, 165 { P_TWOPC_PREPARE, "P_TWOPC_PREPARE" }, 166 { P_TWOPC_ABORT, "P_TWOPC_ABORT" }, 167 168 { P_DAGTAG, "P_DAGTAG" }, 169 170 { P_TRIM, "P_TRIM" }, 171 172 { P_RS_THIN_REQ, "P_RS_THIN_REQ" }, 173 { P_RS_DEALLOCATED, "P_RS_DEALLOCATED" }, 174 175 { P_WSAME, "P_WSAME" }, 176 { P_TWOPC_PREP_RSZ, "P_TWOPC_PREP_RSZ" }, 177 { P_ZEROES, "P_ZEROES" }, 178 179 { P_PEER_ACK, "P_PEER_ACK" }, 180 { P_PEERS_IN_SYNC, "P_PEERS_IN_SYNC" }, 181 182 { P_UUIDS110, "P_UUIDS110" }, 183 { P_PEER_DAGTAG, "P_PEER_DAGTAG" }, 184 { P_CURRENT_UUID, "P_CURRENT_UUID" }, 185 186 { P_TWOPC_YES, "P_TWOPC_YES" }, 187 { P_TWOPC_NO, "P_TWOPC_NO" }, 188 { P_TWOPC_COMMIT, "P_TWOPC_COMMIT" }, 189 { P_TWOPC_RETRY, "P_TWOPC_RETRY" }, 190 191 { P_CONFIRM_STABLE, "P_CONFIRM_STABLE" }, 192 193 { P_INITIAL_META, "P_INITIAL_META" }, 194 { P_INITIAL_DATA, "P_INITIAL_DATA" }, 195 196 { P_CONNECTION_FEATURES, "P_CONNECTION_FEATURES" }, 197 { 0, NULL } 198 }; 199 200 #define DRBD_PROT_A 1 201 #define DRBD_PROT_B 2 202 #define DRBD_PROT_C 3 203 204 static const value_string protocol_names[] = { 205 { DRBD_PROT_A, "A" }, 206 { DRBD_PROT_B, "B" }, proto_reg_handoff_dpnss_link(void)207 { DRBD_PROT_C, "C" }, 208 { 0, NULL } 209 }; 210 211 #define DRBD_ROLE_UNKNOWN 0 212 #define DRBD_ROLE_PRIMARY 1 213 #define DRBD_ROLE_SECONDARY 2 214 215 static const value_string role_names[] = { 216 { DRBD_ROLE_UNKNOWN, "UNKNOWN" }, 217 { DRBD_ROLE_PRIMARY, "PRIMARY" }, 218 { DRBD_ROLE_SECONDARY, "SECONDARY" }, 219 { 0, NULL } 220 }; 221 222 #define DRBD_CONNECTION_STATE_C_STANDALONE 0 223 #define DRBD_CONNECTION_STATE_C_DISCONNECTING 1 224 #define DRBD_CONNECTION_STATE_C_UNCONNECTED 2 225 #define DRBD_CONNECTION_STATE_C_TIMEOUT 3 226 #define DRBD_CONNECTION_STATE_C_BROKEN_PIPE 4 227 #define DRBD_CONNECTION_STATE_C_NETWORK_FAILURE 5 228 #define DRBD_CONNECTION_STATE_C_PROTOCOL_ERROR 6 229 #define DRBD_CONNECTION_STATE_C_TEAR_DOWN 7 230 #define DRBD_CONNECTION_STATE_C_CONNECTING 8 231 #define DRBD_CONNECTION_STATE_C_CONNECTED 9 232 #define DRBD_CONNECTION_STATE_L_ESTABLISHED 10 233 #define DRBD_CONNECTION_STATE_L_STARTING_SYNC_S 11 234 #define DRBD_CONNECTION_STATE_L_STARTING_SYNC_T 12 235 #define DRBD_CONNECTION_STATE_L_WF_BITMAP_S 13 236 #define DRBD_CONNECTION_STATE_L_WF_BITMAP_T 14 237 #define DRBD_CONNECTION_STATE_L_WF_SYNC_UUID 15 238 #define DRBD_CONNECTION_STATE_L_SYNC_SOURCE 16 239 #define DRBD_CONNECTION_STATE_L_SYNC_TARGET 17 240 #define DRBD_CONNECTION_STATE_L_VERIFY_S 18 241 #define DRBD_CONNECTION_STATE_L_VERIFY_T 19 242 #define DRBD_CONNECTION_STATE_L_PAUSED_SYNC_S 20 243 #define DRBD_CONNECTION_STATE_L_PAUSED_SYNC_T 21 244 #define DRBD_CONNECTION_STATE_L_AHEAD 22 245 #define DRBD_CONNECTION_STATE_L_BEHIND 23 246 247 static const value_string connection_state_names[] = { 248 { DRBD_CONNECTION_STATE_C_STANDALONE, "C_STANDALONE" }, 249 { DRBD_CONNECTION_STATE_C_DISCONNECTING, "C_DISCONNECTING" }, 250 { DRBD_CONNECTION_STATE_C_UNCONNECTED, "C_UNCONNECTED" }, 251 { DRBD_CONNECTION_STATE_C_TIMEOUT, "C_TIMEOUT" }, 252 { DRBD_CONNECTION_STATE_C_BROKEN_PIPE, "C_BROKEN_PIPE" }, 253 { DRBD_CONNECTION_STATE_C_NETWORK_FAILURE, "C_NETWORK_FAILURE" }, 254 { DRBD_CONNECTION_STATE_C_PROTOCOL_ERROR, "C_PROTOCOL_ERROR" }, 255 { DRBD_CONNECTION_STATE_C_TEAR_DOWN, "C_TEAR_DOWN" }, 256 { DRBD_CONNECTION_STATE_C_CONNECTING, "C_CONNECTING" }, 257 { DRBD_CONNECTION_STATE_C_CONNECTED, "C_CONNECTED" }, 258 { DRBD_CONNECTION_STATE_L_ESTABLISHED, "L_ESTABLISHED" }, 259 { DRBD_CONNECTION_STATE_L_STARTING_SYNC_S, "L_STARTING_SYNC_S" }, 260 { DRBD_CONNECTION_STATE_L_STARTING_SYNC_T, "L_STARTING_SYNC_T" }, 261 { DRBD_CONNECTION_STATE_L_WF_BITMAP_S, "L_WF_BITMAP_S" }, 262 { DRBD_CONNECTION_STATE_L_WF_BITMAP_T, "L_WF_BITMAP_T" }, 263 { DRBD_CONNECTION_STATE_L_WF_SYNC_UUID, "L_WF_SYNC_UUID" }, 264 { DRBD_CONNECTION_STATE_L_SYNC_SOURCE, "L_SYNC_SOURCE" }, 265 { DRBD_CONNECTION_STATE_L_SYNC_TARGET, "L_SYNC_TARGET" }, 266 { DRBD_CONNECTION_STATE_L_VERIFY_S, "L_VERIFY_S" }, 267 { DRBD_CONNECTION_STATE_L_VERIFY_T, "L_VERIFY_T" }, 268 { DRBD_CONNECTION_STATE_L_PAUSED_SYNC_S, "L_PAUSED_SYNC_S" }, 269 { DRBD_CONNECTION_STATE_L_PAUSED_SYNC_T, "L_PAUSED_SYNC_T" }, 270 { DRBD_CONNECTION_STATE_L_AHEAD, "L_AHEAD" }, 271 { DRBD_CONNECTION_STATE_L_BEHIND, "L_BEHIND" }, 272 { 0, NULL } 273 }; 274 275 #define DRBD_DISK_STATE_DISKLESS 0 276 #define DRBD_DISK_STATE_ATTACHING 1 277 #define DRBD_DISK_STATE_DETACHING 2 278 #define DRBD_DISK_STATE_FAILED 3 279 #define DRBD_DISK_STATE_NEGOTIATING 4 280 #define DRBD_DISK_STATE_INCONSISTENT 5 281 #define DRBD_DISK_STATE_OUTDATED 6 282 #define DRBD_DISK_STATE_UNKNOWN 7 283 #define DRBD_DISK_STATE_CONSISTENT 8 284 #define DRBD_DISK_STATE_UP_TO_DATE 9 285 286 static const value_string disk_state_names[] = { 287 { DRBD_DISK_STATE_DISKLESS, "D_DISKLESS" }, 288 { DRBD_DISK_STATE_ATTACHING, "D_ATTACHING" }, 289 { DRBD_DISK_STATE_DETACHING, "D_DETACHING" }, 290 { DRBD_DISK_STATE_FAILED, "D_FAILED" }, 291 { DRBD_DISK_STATE_NEGOTIATING, "D_NEGOTIATING" }, 292 { DRBD_DISK_STATE_INCONSISTENT, "D_INCONSISTENT" }, 293 { DRBD_DISK_STATE_OUTDATED, "D_OUTDATED" }, 294 { DRBD_DISK_STATE_UNKNOWN, "D_UNKNOWN" }, 295 { DRBD_DISK_STATE_CONSISTENT, "D_CONSISTENT" }, 296 { DRBD_DISK_STATE_UP_TO_DATE, "D_UP_TO_DATE" }, 297 { 0, NULL } 298 }; 299 300 #define STATE_ROLE (0x3 << 0) /* 3/4 primary/secondary/unknown */ 301 #define STATE_PEER (0x3 << 2) /* 3/4 primary/secondary/unknown */ 302 #define STATE_CONN (0x1f << 4) /* 17/32 cstates */ 303 #define STATE_DISK (0xf << 9) /* 8/16 from D_DISKLESS to D_UP_TO_DATE */ 304 #define STATE_PDSK (0xf << 13) /* 8/16 from D_DISKLESS to D_UP_TO_DATE */ 305 #define STATE_SUSP (0x1 << 17) /* 2/2 IO suspended no/yes (by user) */ 306 #define STATE_AFTR_ISP (0x1 << 18) /* isp .. imposed sync pause */ 307 #define STATE_PEER_ISP (0x1 << 19) 308 #define STATE_USER_ISP (0x1 << 20) 309 #define STATE_SUSP_NOD (0x1 << 21) /* IO suspended because no data */ 310 #define STATE_SUSP_FEN (0x1 << 22) /* IO suspended because fence peer handler runs*/ 311 #define STATE_QUORUM (0x1 << 23) 312 313 #define UUID_FLAG_DISCARD_MY_DATA 1 314 #define UUID_FLAG_CRASHED_PRIMARY 2 315 #define UUID_FLAG_INCONSISTENT 4 316 #define UUID_FLAG_SKIP_INITIAL_SYNC 8 317 #define UUID_FLAG_NEW_DATAGEN 16 318 #define UUID_FLAG_STABLE 32 319 #define UUID_FLAG_GOT_STABLE 64 320 #define UUID_FLAG_RESYNC 128 321 #define UUID_FLAG_RECONNECT 256 322 #define UUID_FLAG_DISKLESS_PRIMARY 512 323 #define UUID_FLAG_PRIMARY_LOST_QUORUM 1024 324 325 #define DP_HARDBARRIER 1 326 #define DP_RW_SYNC 2 327 #define DP_MAY_SET_IN_SYNC 4 328 #define DP_UNPLUG 8 329 #define DP_FUA 16 330 #define DP_FLUSH 32 331 #define DP_DISCARD 64 332 #define DP_SEND_RECEIVE_ACK 128 333 #define DP_SEND_WRITE_ACK 256 334 #define DP_WSAME 512 335 #define DP_ZEROES 1024 336 337 static void dissect_drbd_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); 338 339 static void decode_payload_connection_features(tvbuff_t *tvb, proto_tree *tree); 340 static void decode_payload_auth_challenge(tvbuff_t *tvb, proto_tree *tree); 341 static void decode_payload_auth_response(tvbuff_t *tvb, proto_tree *tree); 342 static void decode_payload_data(tvbuff_t *tvb, proto_tree *tree); 343 static void decode_payload_data_reply(tvbuff_t *tvb, proto_tree *tree); 344 static void decode_payload_rs_data_reply(tvbuff_t *tvb, proto_tree *tree); 345 static void decode_payload_barrier(tvbuff_t *tvb, proto_tree *tree); 346 static void decode_payload_data_request(tvbuff_t *tvb, proto_tree *tree); 347 static void decode_payload_sync_param(tvbuff_t *tvb, proto_tree *tree); 348 static void decode_payload_protocol(tvbuff_t *tvb, proto_tree *tree); 349 static void decode_payload_uuids(tvbuff_t *tvb, proto_tree *tree); 350 static void decode_payload_sizes(tvbuff_t *tvb, proto_tree *tree); 351 static void decode_payload_state(tvbuff_t *tvb, proto_tree *tree); 352 static void decode_payload_req_state(tvbuff_t *tvb, proto_tree *tree); 353 static void decode_payload_sync_uuid(tvbuff_t *tvb, proto_tree *tree); 354 static void decode_payload_skip(tvbuff_t *tvb, proto_tree *tree); 355 static void decode_payload_out_of_sync(tvbuff_t *tvb, proto_tree *tree); 356 static void decode_payload_twopc(tvbuff_t *tvb, proto_tree *tree); 357 static void decode_payload_dagtag(tvbuff_t *tvb, proto_tree *tree); 358 static void decode_payload_uuids110(tvbuff_t *tvb, proto_tree *tree); 359 static void decode_payload_peer_dagtag(tvbuff_t *tvb, proto_tree *tree); 360 static void decode_payload_current_uuid(tvbuff_t *tvb, proto_tree *tree); 361 static void decode_payload_data_size(tvbuff_t *tvb, proto_tree *tree); 362 static void decode_payload_data_wsame(tvbuff_t *tvb, proto_tree *tree); 363 static void decode_payload_rs_deallocated(tvbuff_t *tvb, proto_tree *tree); 364 365 static void decode_payload_block_ack(tvbuff_t *tvb, proto_tree *tree); 366 static void decode_payload_barrier_ack(tvbuff_t *tvb, proto_tree *tree); 367 static void decode_payload_confirm_stable(tvbuff_t *tvb, proto_tree *tree); 368 static void decode_payload_rq_s_reply(tvbuff_t *tvb, proto_tree *tree); 369 static void decode_payload_peer_ack(tvbuff_t *tvb, proto_tree *tree); 370 static void decode_payload_peers_in_sync(tvbuff_t *tvb, proto_tree *tree); 371 static void decode_payload_twopc_reply(tvbuff_t *tvb, proto_tree *tree); 372 373 static const value_payload_decoder payload_decoders[] = { 374 { P_CONNECTION_FEATURES, decode_payload_connection_features }, 375 { P_AUTH_CHALLENGE, decode_payload_auth_challenge }, 376 { P_AUTH_RESPONSE, decode_payload_auth_response }, 377 { P_DATA, decode_payload_data }, 378 { P_DATA_REPLY, decode_payload_data_reply }, 379 { P_RS_DATA_REPLY, decode_payload_rs_data_reply }, 380 { P_BARRIER, decode_payload_barrier }, 381 { P_BITMAP, NULL }, /* TODO: decode additional data */ 382 { P_COMPRESSED_BITMAP, NULL }, /* TODO: decode additional data */ 383 { P_UNPLUG_REMOTE, NULL }, 384 { P_DATA_REQUEST, decode_payload_data_request }, 385 { P_RS_DATA_REQUEST, decode_payload_data_request }, 386 { P_SYNC_PARAM, decode_payload_sync_param }, 387 { P_SYNC_PARAM89, decode_payload_sync_param }, 388 { P_PROTOCOL, decode_payload_protocol }, 389 { P_UUIDS, decode_payload_uuids }, 390 { P_SIZES, decode_payload_sizes }, 391 { P_STATE, decode_payload_state }, 392 { P_STATE_CHG_REQ, decode_payload_req_state }, 393 { P_SYNC_UUID, decode_payload_sync_uuid }, 394 { P_OV_REQUEST, decode_payload_data_request }, 395 { P_OV_REPLY, decode_payload_data_request }, /* TODO: decode additional data */ 396 { P_CSUM_RS_REQUEST, decode_payload_data_request }, /* TODO: decode additional data */ 397 { P_RS_THIN_REQ, decode_payload_data_request }, 398 { P_DELAY_PROBE, decode_payload_skip }, 399 { P_OUT_OF_SYNC, decode_payload_out_of_sync }, 400 { P_CONN_ST_CHG_REQ, decode_payload_req_state }, 401 { P_PROTOCOL_UPDATE, decode_payload_protocol }, /* TODO: decode additional data */ 402 { P_TWOPC_PREPARE, decode_payload_twopc }, 403 { P_TWOPC_PREP_RSZ, decode_payload_twopc }, 404 { P_TWOPC_ABORT, decode_payload_twopc }, 405 { P_DAGTAG, decode_payload_dagtag }, 406 { P_UUIDS110, decode_payload_uuids110 }, 407 { P_PEER_DAGTAG, decode_payload_peer_dagtag }, 408 { P_CURRENT_UUID, decode_payload_current_uuid }, 409 { P_TWOPC_COMMIT, decode_payload_twopc }, 410 { P_TRIM, decode_payload_data_size }, 411 { P_ZEROES, decode_payload_data_size }, 412 { P_RS_DEALLOCATED, decode_payload_rs_deallocated }, 413 { P_WSAME, decode_payload_data_wsame }, 414 415 { P_PING, NULL }, 416 { P_PING_ACK, NULL }, 417 { P_RECV_ACK, decode_payload_block_ack }, 418 { P_WRITE_ACK, decode_payload_block_ack }, 419 { P_RS_WRITE_ACK, decode_payload_block_ack }, 420 { P_SUPERSEDED, decode_payload_block_ack }, 421 { P_NEG_ACK, decode_payload_block_ack }, 422 { P_NEG_DREPLY, decode_payload_block_ack }, 423 { P_NEG_RS_DREPLY, decode_payload_block_ack }, 424 { P_OV_RESULT, decode_payload_block_ack }, 425 { P_BARRIER_ACK, decode_payload_barrier_ack }, 426 { P_CONFIRM_STABLE, decode_payload_confirm_stable }, 427 { P_STATE_CHG_REPLY, decode_payload_rq_s_reply }, 428 { P_RS_IS_IN_SYNC, decode_payload_block_ack }, 429 { P_DELAY_PROBE, decode_payload_skip }, 430 { P_RS_CANCEL, decode_payload_block_ack }, 431 { P_CONN_ST_CHG_REPLY, decode_payload_rq_s_reply }, 432 { P_RETRY_WRITE, decode_payload_block_ack }, 433 { P_PEER_ACK, decode_payload_peer_ack }, 434 { P_PEERS_IN_SYNC, decode_payload_peers_in_sync }, 435 { P_TWOPC_YES, decode_payload_twopc_reply }, 436 { P_TWOPC_NO, decode_payload_twopc_reply }, 437 { P_TWOPC_RETRY, decode_payload_twopc_reply }, 438 }; 439 440 441 void proto_register_drbd(void); 442 void proto_reg_handoff_drbd(void); 443 444 static dissector_handle_t drbd_handle; 445 446 static int proto_drbd = -1; 447 448 static int hf_drbd_command = -1; 449 static int hf_drbd_length = -1; 450 static int hf_drbd_volume = -1; 451 static int hf_drbd_auth_challenge_nonce = -1; 452 static int hf_drbd_auth_response_hash = -1; 453 static int hf_drbd_sector = -1; 454 static int hf_drbd_block_id = -1; 455 static int hf_drbd_seq_num = -1; 456 static int hf_drbd_dp_flags = -1; 457 static int hf_drbd_data = -1; 458 static int hf_drbd_size = -1; 459 static int hf_drbd_blksize = -1; 460 static int hf_drbd_protocol_min = -1; 461 static int hf_drbd_feature_flags = -1; 462 static int hf_drbd_protocol_max = -1; 463 static int hf_drbd_sender_node_id = -1; 464 static int hf_drbd_receiver_node_id = -1; 465 static int hf_drbd_barrier = -1; 466 static int hf_drbd_set_size = -1; 467 static int hf_drbd_oldest_block_id = -1; 468 static int hf_drbd_youngest_block_id = -1; 469 static int hf_drbd_resync_rate = -1; 470 static int hf_drbd_verify_alg = -1; 471 static int hf_drbd_csums_alg = -1; 472 static int hf_drbd_c_plan_ahead = -1; 473 static int hf_drbd_c_delay_target = -1; 474 static int hf_drbd_c_fill_target = -1; 475 static int hf_drbd_c_max_rate = -1; 476 static int hf_drbd_protocol = -1; 477 static int hf_drbd_after_sb_0p = -1; 478 static int hf_drbd_after_sb_1p = -1; 479 static int hf_drbd_after_sb_2p = -1; 480 static int hf_drbd_conn_flags = -1; 481 static int hf_drbd_two_primaries = -1; 482 static int hf_drbd_integrity_alg = -1; 483 static int hf_drbd_current_uuid = -1; 484 static int hf_drbd_bitmap_uuid = -1; 485 static int hf_drbd_history_uuid_list = -1; 486 static int hf_drbd_history_uuid = -1; 487 static int hf_drbd_dirty_bits = -1; 488 static int hf_drbd_uuid_flags = -1; 489 static int hf_drbd_node_mask = -1; 490 static int hf_drbd_bitmap_uuids_mask = -1; 491 static int hf_drbd_uuid = -1; 492 static int hf_drbd_weak_nodes = -1; 493 static int hf_drbd_physical_block_size = -1; 494 static int hf_drbd_logical_block_size = -1; 495 static int hf_drbd_alignment_offset = -1; 496 static int hf_drbd_io_min = -1; 497 static int hf_drbd_io_opt = -1; 498 static int hf_drbd_discard_enabled = -1; 499 static int hf_drbd_discard_zeroes_data = -1; 500 static int hf_drbd_write_same_capable = -1; 501 static int hf_drbd_d_size = -1; 502 static int hf_drbd_u_size = -1; 503 static int hf_drbd_c_size = -1; 504 static int hf_drbd_max_bio_size = -1; 505 static int hf_drbd_queue_order_type = -1; 506 static int hf_drbd_dds_flags = -1; 507 static int hf_drbd_state = -1; 508 static int hf_drbd_mask = -1; 509 static int hf_drbd_val = -1; 510 static int hf_drbd_retcode = -1; 511 static int hf_drbd_tid = -1; 512 static int hf_drbd_initiator_node_id = -1; 513 static int hf_drbd_target_node_id = -1; 514 static int hf_drbd_nodes_to_reach = -1; 515 static int hf_drbd_reachable_nodes = -1; 516 static int hf_drbd_offset = -1; 517 static int hf_drbd_dagtag = -1; 518 static int hf_drbd_node_id = -1; 519 520 static int hf_drbd_state_role = -1; 521 static int hf_drbd_state_peer = -1; 522 static int hf_drbd_state_conn = -1; 523 static int hf_drbd_state_disk = -1; 524 static int hf_drbd_state_pdsk = -1; 525 static int hf_drbd_state_susp = -1; 526 static int hf_drbd_state_aftr_isp = -1; 527 static int hf_drbd_state_peer_isp = -1; 528 static int hf_drbd_state_user_isp = -1; 529 static int hf_drbd_state_susp_nod = -1; 530 static int hf_drbd_state_susp_fen = -1; 531 static int hf_drbd_state_quorum = -1; 532 533 static int hf_drbd_uuid_flag_discard_my_data = -1; 534 static int hf_drbd_uuid_flag_crashed_primary = -1; 535 static int hf_drbd_uuid_flag_inconsistent = -1; 536 static int hf_drbd_uuid_flag_skip_initial_sync = -1; 537 static int hf_drbd_uuid_flag_new_datagen = -1; 538 static int hf_drbd_uuid_flag_stable = -1; 539 static int hf_drbd_uuid_flag_got_stable = -1; 540 static int hf_drbd_uuid_flag_resync = -1; 541 static int hf_drbd_uuid_flag_reconnect = -1; 542 static int hf_drbd_uuid_flag_diskless_primary = -1; 543 static int hf_drbd_uuid_flag_primary_lost_quorum = -1; 544 545 static int hf_drbd_dp_hardbarrier = -1; 546 static int hf_drbd_dp_rw_sync = -1; 547 static int hf_drbd_dp_may_set_in_sync = -1; 548 static int hf_drbd_dp_unplug = -1; 549 static int hf_drbd_dp_fua = -1; 550 static int hf_drbd_dp_flush = -1; 551 static int hf_drbd_dp_discard = -1; 552 static int hf_drbd_dp_send_receive_ack = -1; 553 static int hf_drbd_dp_send_write_ack = -1; 554 static int hf_drbd_dp_wsame = -1; 555 static int hf_drbd_dp_zeroes = -1; 556 557 static gint ett_drbd = -1; 558 static gint ett_drbd_state = -1; 559 static gint ett_drbd_uuid_flags = -1; 560 static gint ett_drbd_history_uuids = -1; 561 static gint ett_drbd_data_flags = -1; 562 563 static int * const state_fields[] = { 564 &hf_drbd_state_role, 565 &hf_drbd_state_peer, 566 &hf_drbd_state_conn, 567 &hf_drbd_state_disk, 568 &hf_drbd_state_pdsk, 569 &hf_drbd_state_susp, 570 &hf_drbd_state_aftr_isp, 571 &hf_drbd_state_peer_isp, 572 &hf_drbd_state_user_isp, 573 &hf_drbd_state_susp_nod, 574 &hf_drbd_state_susp_fen, 575 &hf_drbd_state_quorum, 576 NULL 577 }; 578 579 static int * const uuid_flag_fields[] = { 580 &hf_drbd_uuid_flag_discard_my_data, 581 &hf_drbd_uuid_flag_crashed_primary, 582 &hf_drbd_uuid_flag_inconsistent, 583 &hf_drbd_uuid_flag_skip_initial_sync, 584 &hf_drbd_uuid_flag_new_datagen, 585 &hf_drbd_uuid_flag_stable, 586 &hf_drbd_uuid_flag_got_stable, 587 &hf_drbd_uuid_flag_resync, 588 &hf_drbd_uuid_flag_reconnect, 589 &hf_drbd_uuid_flag_diskless_primary, 590 &hf_drbd_uuid_flag_primary_lost_quorum, 591 NULL 592 }; 593 594 static int * const data_flag_fields[] = { 595 &hf_drbd_dp_hardbarrier, 596 &hf_drbd_dp_rw_sync, 597 &hf_drbd_dp_may_set_in_sync, 598 &hf_drbd_dp_unplug, 599 &hf_drbd_dp_fua, 600 &hf_drbd_dp_flush, 601 &hf_drbd_dp_discard, 602 &hf_drbd_dp_send_receive_ack, 603 &hf_drbd_dp_send_write_ack, 604 &hf_drbd_dp_wsame, 605 &hf_drbd_dp_zeroes, 606 NULL 607 }; 608 609 #define CHALLENGE_LEN 64 610 611 static gboolean is_bit_set_64(guint64 value, int bit) { 612 return !!(value & (G_GUINT64_CONSTANT(1) << bit)); 613 } 614 615 /* 616 * Length of the frame header. 617 */ 618 #define DRBD_FRAME_HEADER_80_LEN 8 619 #define DRBD_FRAME_HEADER_95_LEN 8 620 #define DRBD_FRAME_HEADER_100_LEN 16 621 622 #define DRBD_MAGIC 0x83740267 623 #define DRBD_MAGIC_BIG 0x835a 624 #define DRBD_MAGIC_100 0x8620ec20 625 626 static guint get_drbd_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) 627 { 628 guint32 magic32; 629 guint16 magic16; 630 631 magic32 = tvb_get_ntohl(tvb, offset); 632 633 if (magic32 == DRBD_MAGIC) 634 return DRBD_FRAME_HEADER_80_LEN + tvb_get_ntohs(tvb, offset + 6); 635 636 if (tvb_reported_length_remaining(tvb, offset) >= DRBD_FRAME_HEADER_100_LEN && magic32 == DRBD_MAGIC_100) 637 return DRBD_FRAME_HEADER_100_LEN + tvb_get_ntohl(tvb, offset + 8); 638 639 magic16 = tvb_get_ntohs(tvb, offset); 640 641 if (magic16 == DRBD_MAGIC_BIG) 642 return DRBD_FRAME_HEADER_95_LEN + tvb_get_ntohl(tvb, offset + 4); 643 644 return 0; 645 } 646 647 static int dissect_drbd_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data _U_) 648 { 649 dissect_drbd_message(tvb, pinfo, tree); 650 return tvb_reported_length(tvb); 651 } 652 653 static int dissect_drbd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) 654 { 655 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRBD"); 656 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, DRBD_FRAME_HEADER_80_LEN, 657 get_drbd_pdu_len, dissect_drbd_pdu, data); 658 return tvb_reported_length(tvb); 659 } 660 661 static gboolean test_drbd_protocol(tvbuff_t *tvb, packet_info *pinfo, 662 proto_tree *tree, void *data _U_) 663 { 664 guint reported_length = tvb_reported_length(tvb); 665 if (reported_length < DRBD_FRAME_HEADER_80_LEN || tvb_captured_length(tvb) < 4) { 666 return FALSE; 667 } 668 669 gboolean match = FALSE; 670 guint32 magic32 = tvb_get_ntohl(tvb, 0); 671 672 if (magic32 == DRBD_MAGIC) 673 match = TRUE; 674 else if (reported_length >= DRBD_FRAME_HEADER_100_LEN && magic32 == DRBD_MAGIC_100) 675 match = TRUE; 676 else { 677 guint16 magic16 = tvb_get_ntohs(tvb, 0); 678 if (magic16 == DRBD_MAGIC_BIG) 679 match = TRUE; 680 } 681 682 if (match) { 683 conversation_t *conversation = find_or_create_conversation(pinfo); 684 conversation_set_dissector(conversation, drbd_handle); 685 dissect_drbd(tvb, pinfo, tree, data); 686 } 687 688 return match; 689 } 690 691 /** 692 * Returns buffer containing the payload. 693 */ 694 static tvbuff_t *decode_header(tvbuff_t *tvb, proto_tree *pt, guint16 *command) 695 { 696 guint32 magic32; 697 guint16 magic16; 698 699 magic32 = tvb_get_ntohl(tvb, 0); 700 701 if (magic32 == DRBD_MAGIC) { 702 *command = tvb_get_ntohs(tvb, 4); 703 704 proto_tree_add_item(pt, hf_drbd_command, tvb, 4, 2, ENC_BIG_ENDIAN); 705 proto_tree_add_item(pt, hf_drbd_length, tvb, 6, 2, ENC_BIG_ENDIAN); 706 707 return tvb_new_subset_remaining(tvb, DRBD_FRAME_HEADER_80_LEN); 708 } 709 710 if (tvb_reported_length(tvb) >= DRBD_FRAME_HEADER_100_LEN && magic32 == DRBD_MAGIC_100) { 711 *command = tvb_get_ntohs(tvb, 6); 712 713 proto_tree_add_item(pt, hf_drbd_volume, tvb, 4, 2, ENC_BIG_ENDIAN); 714 proto_tree_add_item(pt, hf_drbd_command, tvb, 6, 2, ENC_BIG_ENDIAN); 715 proto_tree_add_item(pt, hf_drbd_length, tvb, 8, 4, ENC_BIG_ENDIAN); 716 717 return tvb_new_subset_remaining(tvb, DRBD_FRAME_HEADER_100_LEN); 718 } 719 720 magic16 = tvb_get_ntohs(tvb, 0); 721 722 if (magic16 == DRBD_MAGIC_BIG) { 723 *command = tvb_get_ntohs(tvb, 2); 724 725 proto_tree_add_item(pt, hf_drbd_command, tvb, 2, 2, ENC_BIG_ENDIAN); 726 proto_tree_add_item(pt, hf_drbd_length, tvb, 4, 4, ENC_BIG_ENDIAN); 727 728 return tvb_new_subset_remaining(tvb, DRBD_FRAME_HEADER_95_LEN); 729 } 730 731 return NULL; 732 } 733 734 static void dissect_drbd_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 735 { 736 proto_tree *drbd_tree; 737 proto_item *ti; 738 guint16 command = -1; 739 740 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRBD"); 741 col_clear(pinfo->cinfo, COL_INFO); 742 743 ti = proto_tree_add_item(tree, proto_drbd, tvb, 0, -1, ENC_NA); 744 drbd_tree = proto_item_add_subtree(ti, ett_drbd); 745 746 tvbuff_t *payload_tvb = decode_header(tvb, drbd_tree, &command); 747 748 if (!payload_tvb) 749 return; 750 751 /* 752 * Indicate what kind of message this is. 753 */ 754 const gchar *packet_name = val_to_str(command, packet_names, "Unknown (0x%02x)"); 755 const gchar *info_text = col_get_text(pinfo->cinfo, COL_INFO); 756 if (!info_text || !info_text[0]) { 757 col_append_ports(pinfo->cinfo, COL_INFO, PT_TCP, pinfo->srcport, pinfo->destport); 758 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", packet_name); 759 } else { 760 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "[%s]", packet_name); 761 } 762 col_set_fence(pinfo->cinfo, COL_INFO); 763 764 if (tree == NULL) 765 return; 766 767 proto_item_set_text(ti, "DRBD [%s]", packet_name); 768 769 const value_payload_decoder *payload_decoder = NULL; 770 for (unsigned int i = 0; i < array_length(payload_decoders); i++) { 771 if (payload_decoders[i].value == command) { 772 payload_decoder = &payload_decoders[i]; 773 break; 774 } 775 } 776 777 if (payload_decoder && payload_decoder->decoder_fn) 778 (*payload_decoder->decoder_fn) (payload_tvb, drbd_tree); 779 } 780 781 static void decode_payload_connection_features(tvbuff_t *tvb, proto_tree *tree) 782 { 783 proto_tree_add_item(tree, hf_drbd_protocol_min, tvb, 0, 4, ENC_BIG_ENDIAN); 784 proto_tree_add_item(tree, hf_drbd_feature_flags, tvb, 4, 4, ENC_BIG_ENDIAN); 785 proto_tree_add_item(tree, hf_drbd_protocol_max, tvb, 8, 4, ENC_BIG_ENDIAN); 786 proto_tree_add_item(tree, hf_drbd_sender_node_id, tvb, 12, 4, ENC_BIG_ENDIAN); 787 proto_tree_add_item(tree, hf_drbd_receiver_node_id, tvb, 16, 4, ENC_BIG_ENDIAN); 788 } 789 790 static void decode_payload_auth_challenge(tvbuff_t *tvb _U_, proto_tree *tree _U_) 791 { 792 proto_tree_add_bytes_format(tree, hf_drbd_auth_challenge_nonce, tvb, 0, CHALLENGE_LEN, NULL, "Nonce"); 793 } 794 795 static void decode_payload_auth_response(tvbuff_t *tvb _U_, proto_tree *tree _U_) 796 { 797 proto_tree_add_bytes_format(tree, hf_drbd_auth_response_hash, tvb, 0, -1, NULL, "Hash"); 798 } 799 800 static void decode_data_common(tvbuff_t *tvb, proto_tree *tree) 801 { 802 proto_tree_add_item(tree, hf_drbd_sector, tvb, 0, 8, ENC_BIG_ENDIAN); 803 proto_tree_add_item(tree, hf_drbd_block_id, tvb, 8, 8, ENC_BIG_ENDIAN); 804 proto_tree_add_item(tree, hf_drbd_seq_num, tvb, 16, 4, ENC_BIG_ENDIAN); 805 proto_tree_add_bitmask(tree, tvb, 20, hf_drbd_dp_flags, ett_drbd_data_flags, data_flag_fields, ENC_BIG_ENDIAN); 806 } 807 808 static void decode_data_remaining(tvbuff_t *tvb, proto_tree *tree, guint offset) 809 { 810 guint nbytes = tvb_reported_length_remaining(tvb, offset); 811 proto_tree_add_bytes_format(tree, hf_drbd_data, tvb, offset, 812 -1, NULL, "Data (%u byte%s)", nbytes, plurality(nbytes, "", "s")); 813 } 814 815 static void decode_payload_data(tvbuff_t *tvb, proto_tree *tree) 816 { 817 decode_data_common(tvb, tree); 818 decode_data_remaining(tvb, tree, 24); 819 } 820 821 static void decode_payload_data_reply(tvbuff_t *tvb, proto_tree *tree) 822 { 823 decode_data_common(tvb, tree); 824 decode_data_remaining(tvb, tree, 24); 825 } 826 827 static void decode_payload_rs_data_reply(tvbuff_t *tvb, proto_tree *tree) 828 { 829 decode_data_common(tvb, tree); 830 decode_data_remaining(tvb, tree, 24); 831 } 832 833 static void decode_payload_barrier(tvbuff_t *tvb, proto_tree *tree) 834 { 835 proto_tree_add_item(tree, hf_drbd_barrier, tvb, 0, 4, ENC_BIG_ENDIAN); 836 } 837 838 static void decode_payload_data_request(tvbuff_t *tvb, proto_tree *tree) 839 { 840 proto_tree_add_item(tree, hf_drbd_sector, tvb, 0, 8, ENC_BIG_ENDIAN); 841 proto_tree_add_item(tree, hf_drbd_block_id, tvb, 8, 8, ENC_BIG_ENDIAN); 842 proto_tree_add_item(tree, hf_drbd_blksize, tvb, 16, 4, ENC_BIG_ENDIAN); 843 } 844 845 static void decode_payload_sync_param(tvbuff_t *tvb, proto_tree *tree) 846 { 847 guint length = tvb_reported_length(tvb); 848 guint offset = 0; 849 850 proto_tree_add_item(tree, hf_drbd_resync_rate, tvb, offset, 4, ENC_BIG_ENDIAN); 851 offset += 4; 852 proto_tree_add_item(tree, hf_drbd_verify_alg, tvb, offset, DRBD_STRING_MAX, ENC_ASCII | ENC_NA); 853 offset += DRBD_STRING_MAX; 854 855 if (length >= offset + DRBD_STRING_MAX) { 856 proto_tree_add_item(tree, hf_drbd_csums_alg, tvb, offset, DRBD_STRING_MAX, ENC_ASCII | ENC_NA); 857 offset += DRBD_STRING_MAX; 858 } 859 860 if (length >= offset + 16) { 861 proto_tree_add_item(tree, hf_drbd_c_plan_ahead, tvb, offset, 4, ENC_BIG_ENDIAN); 862 proto_tree_add_item(tree, hf_drbd_c_delay_target, tvb, offset + 4, 4, ENC_BIG_ENDIAN); 863 proto_tree_add_item(tree, hf_drbd_c_fill_target, tvb, offset + 8, 4, ENC_BIG_ENDIAN); 864 proto_tree_add_item(tree, hf_drbd_c_max_rate, tvb, offset + 12, 4, ENC_BIG_ENDIAN); 865 } 866 } 867 868 static void decode_payload_protocol(tvbuff_t *tvb, proto_tree *tree) 869 { 870 proto_tree_add_item(tree, hf_drbd_protocol, tvb, 0, 4, ENC_BIG_ENDIAN); 871 proto_tree_add_item(tree, hf_drbd_after_sb_0p, tvb, 4, 4, ENC_BIG_ENDIAN); 872 proto_tree_add_item(tree, hf_drbd_after_sb_1p, tvb, 8, 4, ENC_BIG_ENDIAN); 873 proto_tree_add_item(tree, hf_drbd_after_sb_2p, tvb, 12, 4, ENC_BIG_ENDIAN); 874 proto_tree_add_item(tree, hf_drbd_conn_flags, tvb, 16, 4, ENC_BIG_ENDIAN); 875 proto_tree_add_item(tree, hf_drbd_two_primaries, tvb, 20, 4, ENC_BIG_ENDIAN); 876 proto_tree_add_item(tree, hf_drbd_integrity_alg, tvb, 24, -1, ENC_ASCII | ENC_NA); 877 } 878 879 static void decode_payload_uuids(tvbuff_t *tvb, proto_tree *tree) 880 { 881 proto_tree_add_item(tree, hf_drbd_current_uuid, tvb, 0, 8, ENC_BIG_ENDIAN); 882 proto_tree_add_item(tree, hf_drbd_bitmap_uuid, tvb, 8, 8, ENC_BIG_ENDIAN); 883 proto_tree_add_item(tree, hf_drbd_history_uuid, tvb, 16, 8, ENC_BIG_ENDIAN); 884 proto_tree_add_item(tree, hf_drbd_history_uuid, tvb, 24, 8, ENC_BIG_ENDIAN); 885 proto_tree_add_item(tree, hf_drbd_dirty_bits, tvb, 32, 8, ENC_BIG_ENDIAN); 886 proto_tree_add_bitmask(tree, tvb, 40, hf_drbd_uuid_flags, ett_drbd_uuid_flags, uuid_flag_fields, ENC_BIG_ENDIAN); 887 } 888 889 static void decode_payload_sizes(tvbuff_t *tvb, proto_tree *tree) 890 { 891 proto_tree_add_item(tree, hf_drbd_d_size, tvb, 0, 8, ENC_BIG_ENDIAN); 892 proto_tree_add_item(tree, hf_drbd_u_size, tvb, 8, 8, ENC_BIG_ENDIAN); 893 proto_tree_add_item(tree, hf_drbd_c_size, tvb, 16, 8, ENC_BIG_ENDIAN); 894 proto_tree_add_item(tree, hf_drbd_max_bio_size, tvb, 24, 4, ENC_BIG_ENDIAN); 895 proto_tree_add_item(tree, hf_drbd_queue_order_type, tvb, 28, 2, ENC_BIG_ENDIAN); 896 proto_tree_add_item(tree, hf_drbd_dds_flags, tvb, 30, 2, ENC_BIG_ENDIAN); 897 proto_tree_add_item(tree, hf_drbd_physical_block_size, tvb, 32, 4, ENC_BIG_ENDIAN); 898 proto_tree_add_item(tree, hf_drbd_logical_block_size, tvb, 36, 4, ENC_BIG_ENDIAN); 899 proto_tree_add_item(tree, hf_drbd_alignment_offset, tvb, 40, 4, ENC_BIG_ENDIAN); 900 proto_tree_add_item(tree, hf_drbd_io_min, tvb, 44, 4, ENC_BIG_ENDIAN); 901 proto_tree_add_item(tree, hf_drbd_io_opt, tvb, 48, 4, ENC_BIG_ENDIAN); 902 proto_tree_add_item(tree, hf_drbd_discard_enabled, tvb, 52, 1, ENC_BIG_ENDIAN); 903 proto_tree_add_item(tree, hf_drbd_discard_zeroes_data, tvb, 53, 1, ENC_BIG_ENDIAN); 904 proto_tree_add_item(tree, hf_drbd_write_same_capable, tvb, 54, 1, ENC_BIG_ENDIAN); 905 } 906 907 static void decode_payload_state(tvbuff_t *tvb, proto_tree *tree) 908 { 909 proto_tree_add_bitmask(tree, tvb, 0, hf_drbd_state, ett_drbd_state, state_fields, ENC_BIG_ENDIAN); 910 } 911 912 static void decode_payload_req_state(tvbuff_t *tvb, proto_tree *tree) 913 { 914 proto_tree_add_item(tree, hf_drbd_mask, tvb, 0, 4, ENC_BIG_ENDIAN); 915 proto_tree_add_item(tree, hf_drbd_val, tvb, 4, 4, ENC_BIG_ENDIAN); 916 } 917 918 static void decode_payload_sync_uuid(tvbuff_t *tvb, proto_tree *tree) 919 { 920 proto_tree_add_item(tree, hf_drbd_uuid, tvb, 0, 8, ENC_BIG_ENDIAN); 921 } 922 923 static void decode_payload_skip(tvbuff_t *tvb, proto_tree *tree) 924 { 925 proto_tree_add_item(tree, hf_drbd_seq_num, tvb, 0, 4, ENC_BIG_ENDIAN); 926 proto_tree_add_item(tree, hf_drbd_offset, tvb, 4, 4, ENC_BIG_ENDIAN); 927 } 928 929 static void decode_payload_out_of_sync(tvbuff_t *tvb, proto_tree *tree) 930 { 931 proto_tree_add_item(tree, hf_drbd_sector, tvb, 0, 8, ENC_BIG_ENDIAN); 932 proto_tree_add_item(tree, hf_drbd_blksize, tvb, 8, 4, ENC_BIG_ENDIAN); 933 } 934 935 static void decode_payload_twopc(tvbuff_t *tvb, proto_tree *tree) 936 { 937 proto_tree_add_item(tree, hf_drbd_tid, tvb, 0, 4, ENC_BIG_ENDIAN); 938 proto_tree_add_item(tree, hf_drbd_initiator_node_id, tvb, 4, 4, ENC_BIG_ENDIAN); 939 proto_tree_add_item(tree, hf_drbd_target_node_id, tvb, 8, 4, ENC_BIG_ENDIAN); 940 proto_tree_add_item(tree, hf_drbd_nodes_to_reach, tvb, 12, 8, ENC_BIG_ENDIAN); 941 /* TODO: Decode further fields based on type */ 942 } 943 944 static void decode_payload_dagtag(tvbuff_t *tvb, proto_tree *tree) 945 { 946 proto_tree_add_item(tree, hf_drbd_dagtag, tvb, 0, 8, ENC_BIG_ENDIAN); 947 } 948 949 static void decode_payload_uuids110(tvbuff_t *tvb, proto_tree *tree) 950 { 951 proto_tree_add_item(tree, hf_drbd_current_uuid, tvb, 0, 8, ENC_BIG_ENDIAN); 952 proto_tree_add_item(tree, hf_drbd_dirty_bits, tvb, 8, 8, ENC_BIG_ENDIAN); 953 proto_tree_add_bitmask(tree, tvb, 16, hf_drbd_uuid_flags, ett_drbd_uuid_flags, uuid_flag_fields, ENC_BIG_ENDIAN); 954 proto_tree_add_item(tree, hf_drbd_node_mask, tvb, 24, 8, ENC_BIG_ENDIAN); 955 956 guint64 bitmap_uuids_mask; 957 proto_tree_add_item_ret_uint64(tree, hf_drbd_bitmap_uuids_mask, tvb, 32, 8, ENC_BIG_ENDIAN, &bitmap_uuids_mask); 958 959 guint offset = 40; 960 for (int i = 0; i < 64; i++) { 961 if (is_bit_set_64(bitmap_uuids_mask, i)) { 962 guint64 bitmap_uuid = tvb_get_ntoh64(tvb, offset); 963 proto_tree_add_uint64_format(tree, hf_drbd_bitmap_uuid, tvb, offset, 8, bitmap_uuid, 964 "Bitmap UUID for node %d: 0x%016" G_GINT64_MODIFIER "x", i, bitmap_uuid); 965 offset += 8; 966 } 967 } 968 969 proto_item *history_uuids = proto_tree_add_item(tree, hf_drbd_history_uuid_list, tvb, offset, -1, ENC_NA); 970 proto_tree *history_tree = proto_item_add_subtree(history_uuids, ett_drbd_history_uuids); 971 guint total_length = tvb_reported_length(tvb); 972 while (offset < total_length) { 973 proto_tree_add_item(history_tree, hf_drbd_history_uuid, tvb, offset, 8, ENC_BIG_ENDIAN); 974 offset += 8; 975 } 976 } 977 978 static void decode_payload_peer_dagtag(tvbuff_t *tvb, proto_tree *tree) 979 { 980 proto_tree_add_item(tree, hf_drbd_dagtag, tvb, 0, 8, ENC_BIG_ENDIAN); 981 proto_tree_add_item(tree, hf_drbd_node_id, tvb, 8, 4, ENC_BIG_ENDIAN); 982 } 983 984 static void decode_payload_current_uuid(tvbuff_t *tvb, proto_tree *tree) 985 { 986 proto_tree_add_item(tree, hf_drbd_uuid, tvb, 0, 8, ENC_BIG_ENDIAN); 987 proto_tree_add_item(tree, hf_drbd_weak_nodes, tvb, 8, 8, ENC_BIG_ENDIAN); 988 } 989 990 static void decode_payload_data_size(tvbuff_t *tvb, proto_tree *tree) 991 { 992 decode_data_common(tvb, tree); 993 proto_tree_add_item(tree, hf_drbd_size, tvb, 24, 4, ENC_BIG_ENDIAN); 994 } 995 996 static void decode_payload_data_wsame(tvbuff_t *tvb, proto_tree *tree) 997 { 998 decode_data_common(tvb, tree); 999 proto_tree_add_item(tree, hf_drbd_size, tvb, 24, 4, ENC_BIG_ENDIAN); 1000 decode_data_remaining(tvb, tree, 28); 1001 } 1002 1003 static void decode_payload_rs_deallocated(tvbuff_t *tvb, proto_tree *tree) 1004 { 1005 proto_tree_add_item(tree, hf_drbd_sector, tvb, 0, 8, ENC_BIG_ENDIAN); 1006 proto_tree_add_item(tree, hf_drbd_blksize, tvb, 8, 4, ENC_BIG_ENDIAN); 1007 } 1008 1009 static void decode_payload_block_ack(tvbuff_t *tvb, proto_tree *tree) 1010 { 1011 proto_tree_add_item(tree, hf_drbd_sector, tvb, 0, 8, ENC_BIG_ENDIAN); 1012 proto_tree_add_item(tree, hf_drbd_block_id, tvb, 8, 8, ENC_BIG_ENDIAN); 1013 proto_tree_add_item(tree, hf_drbd_blksize, tvb, 16, 4, ENC_BIG_ENDIAN); 1014 proto_tree_add_item(tree, hf_drbd_seq_num, tvb, 20, 4, ENC_BIG_ENDIAN); 1015 } 1016 1017 static void decode_payload_barrier_ack(tvbuff_t *tvb, proto_tree *tree) 1018 { 1019 proto_tree_add_item(tree, hf_drbd_barrier, tvb, 0, 4, ENC_BIG_ENDIAN); 1020 proto_tree_add_item(tree, hf_drbd_set_size, tvb, 4, 4, ENC_BIG_ENDIAN); 1021 } 1022 1023 static void decode_payload_confirm_stable(tvbuff_t *tvb, proto_tree *tree) 1024 { 1025 proto_tree_add_item(tree, hf_drbd_oldest_block_id, tvb, 0, 8, ENC_BIG_ENDIAN); 1026 proto_tree_add_item(tree, hf_drbd_youngest_block_id, tvb, 8, 8, ENC_BIG_ENDIAN); 1027 proto_tree_add_item(tree, hf_drbd_set_size, tvb, 16, 4, ENC_BIG_ENDIAN); 1028 } 1029 1030 static void decode_payload_rq_s_reply(tvbuff_t *tvb, proto_tree *tree) 1031 { 1032 proto_tree_add_item(tree, hf_drbd_retcode, tvb, 0, 4, ENC_BIG_ENDIAN); 1033 } 1034 1035 static void decode_payload_peer_ack(tvbuff_t *tvb, proto_tree *tree) 1036 { 1037 proto_tree_add_item(tree, hf_drbd_node_mask, tvb, 0, 8, ENC_BIG_ENDIAN); 1038 proto_tree_add_item(tree, hf_drbd_dagtag, tvb, 8, 8, ENC_BIG_ENDIAN); 1039 } 1040 1041 static void decode_payload_peers_in_sync(tvbuff_t *tvb, proto_tree *tree) 1042 { 1043 proto_tree_add_item(tree, hf_drbd_sector, tvb, 0, 8, ENC_BIG_ENDIAN); 1044 proto_tree_add_item(tree, hf_drbd_node_mask, tvb, 8, 8, ENC_BIG_ENDIAN); 1045 proto_tree_add_item(tree, hf_drbd_size, tvb, 16, 4, ENC_BIG_ENDIAN); 1046 } 1047 1048 static void decode_payload_twopc_reply(tvbuff_t *tvb, proto_tree *tree) 1049 { 1050 proto_tree_add_item(tree, hf_drbd_tid, tvb, 0, 4, ENC_BIG_ENDIAN); 1051 proto_tree_add_item(tree, hf_drbd_initiator_node_id, tvb, 4, 4, ENC_BIG_ENDIAN); 1052 proto_tree_add_item(tree, hf_drbd_reachable_nodes, tvb, 8, 8, ENC_BIG_ENDIAN); 1053 /* TODO: Decode further fields based on type */ 1054 } 1055 1056 static void format_node_mask(gchar *s, guint64 value) 1057 { 1058 if (!value) { 1059 (void) g_strlcpy(s, "<none>", ITEM_LABEL_LENGTH); 1060 return; 1061 } 1062 1063 int written = 0; 1064 int run_start = -1; 1065 for (int i = 0; i < 64 && written < ITEM_LABEL_LENGTH; i++) { 1066 gboolean is_set = is_bit_set_64(value, i); 1067 1068 int run_end; 1069 if (!is_set) { 1070 run_end = i; 1071 } else if (i == 63) { 1072 if (run_start == -1) 1073 run_start = i; 1074 run_end = 64; 1075 } else { 1076 run_end = -1; 1077 } 1078 1079 if (run_start != -1 && run_end != -1) { 1080 int run_length = run_end - run_start; 1081 const char *sep = written ? ", " : ""; 1082 1083 if (run_length == 1) 1084 written += g_snprintf(s + written, ITEM_LABEL_LENGTH - written, "%s%d", sep, run_start); 1085 else if (run_length == 2) 1086 written += g_snprintf(s + written, ITEM_LABEL_LENGTH - written, "%s%d, %d", sep, run_start, run_start + 1); 1087 else 1088 written += g_snprintf(s + written, ITEM_LABEL_LENGTH - written, "%s%d - %d", sep, run_start, run_end - 1); 1089 } 1090 1091 if (!is_set) 1092 run_start = -1; 1093 else if (run_start == -1) 1094 run_start = i; 1095 } 1096 } 1097 1098 void proto_register_drbd(void) 1099 { 1100 static hf_register_info hf[] = { 1101 { &hf_drbd_command, { "Command", "drbd.command", FT_UINT16, BASE_HEX, VALS(packet_names), 0x0, NULL, HFILL }}, 1102 { &hf_drbd_length, { "Payload length", "drbd.length", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1103 { &hf_drbd_volume, { "Volume", "drbd.volume", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1104 { &hf_drbd_auth_challenge_nonce, { "Nonce", "drbd.auth_nonce", FT_BYTES, BASE_NO_DISPLAY_VALUE, NULL, 0x0, NULL, HFILL }}, 1105 { &hf_drbd_auth_response_hash, { "Hash", "drbd.auth_hash", FT_BYTES, BASE_NO_DISPLAY_VALUE, NULL, 0x0, NULL, HFILL }}, 1106 { &hf_drbd_sector, { "Sector", "drbd.sector", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1107 { &hf_drbd_block_id, { "Block ID", "drbd.block_id", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1108 { &hf_drbd_seq_num, { "Sequence number", "drbd.seq_num", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1109 { &hf_drbd_dp_flags, { "Data flags", "drbd.dp_flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1110 { &hf_drbd_data, { "Data", "drbd.data", FT_BYTES, BASE_NO_DISPLAY_VALUE, NULL, 0x0, NULL, HFILL }}, 1111 { &hf_drbd_size, { "size", "drbd.size", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1112 { &hf_drbd_blksize, { "blksize", "drbd.blksize", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }}, 1113 { &hf_drbd_protocol_min, { "protocol_min", "drbd.protocol_min", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1114 { &hf_drbd_feature_flags, { "feature_flags", "drbd.feature_flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1115 { &hf_drbd_protocol_max, { "protocol_max", "drbd.protocol_max", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1116 { &hf_drbd_sender_node_id, { "sender_node_id", "drbd.sender_node_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1117 { &hf_drbd_receiver_node_id, { "receiver_node_id", "drbd.receiver_node_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1118 { &hf_drbd_barrier, { "barrier", "drbd.barrier", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1119 { &hf_drbd_set_size, { "set_size", "drbd.set_size", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1120 { &hf_drbd_oldest_block_id, { "oldest_block_id", "drbd.oldest_block_id", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1121 { &hf_drbd_youngest_block_id, { "youngest_block_id", "drbd.youngest_block_id", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1122 { &hf_drbd_resync_rate, { "resync_rate", "drbd.resync_rate", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1123 { &hf_drbd_verify_alg, { "verify_alg", "drbd.verify_alg", FT_STRINGZ, STR_ASCII, NULL, 0x0, NULL, HFILL }}, 1124 { &hf_drbd_csums_alg, { "csums_alg", "drbd.csums_alg", FT_STRINGZ, STR_ASCII, NULL, 0x0, NULL, HFILL }}, 1125 { &hf_drbd_c_plan_ahead, { "c_plan_ahead", "drbd.c_plan_ahead", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1126 { &hf_drbd_c_delay_target, { "c_delay_target", "drbd.c_delay_target", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1127 { &hf_drbd_c_fill_target, { "c_fill_target", "drbd.c_fill_target", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1128 { &hf_drbd_c_max_rate, { "c_max_rate", "drbd.c_max_rate", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1129 { &hf_drbd_protocol, { "protocol", "drbd.protocol", FT_UINT32, BASE_HEX, VALS(protocol_names), 0x0, NULL, HFILL }}, 1130 { &hf_drbd_after_sb_0p, { "after_sb_0p", "drbd.after_sb_0p", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1131 { &hf_drbd_after_sb_1p, { "after_sb_1p", "drbd.after_sb_1p", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1132 { &hf_drbd_after_sb_2p, { "after_sb_2p", "drbd.after_sb_2p", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1133 { &hf_drbd_conn_flags, { "conn_flags", "drbd.conn_flags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1134 { &hf_drbd_two_primaries, { "two_primaries", "drbd.two_primaries", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1135 { &hf_drbd_integrity_alg, { "integrity_alg", "drbd.integrity_alg", FT_STRINGZ, STR_ASCII, NULL, 0x0, NULL, HFILL }}, 1136 { &hf_drbd_current_uuid, { "Current UUID", "drbd.current_uuid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1137 { &hf_drbd_bitmap_uuid, { "Bitmap UUID", "drbd.bitmap_uuid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1138 { &hf_drbd_history_uuid_list, { "History UUIDs", "drbd.history_uuids", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 1139 { &hf_drbd_history_uuid, { "History UUID", "drbd.history_uuid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1140 { &hf_drbd_dirty_bits, { "Dirty bits", "drbd.dirty_bits", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1141 { &hf_drbd_uuid_flags, { "UUID flags", "drbd.uuid_flags", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1142 { &hf_drbd_node_mask, { "Nodes", "drbd.node_mask", FT_UINT64, BASE_CUSTOM, format_node_mask, 0x0, NULL, HFILL }}, 1143 { &hf_drbd_bitmap_uuids_mask, { "Bitmap UUID nodes", "drbd.bitmap_uuids_mask", FT_UINT64, BASE_CUSTOM, format_node_mask, 0x0, NULL, HFILL }}, 1144 { &hf_drbd_uuid, { "uuid", "drbd.uuid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1145 { &hf_drbd_weak_nodes, { "weak_nodes", "drbd.weak_nodes", FT_UINT64, BASE_CUSTOM, format_node_mask, 0x0, NULL, HFILL }}, 1146 { &hf_drbd_physical_block_size, { "physical_block_size", "drbd.physical_block_size", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1147 { &hf_drbd_logical_block_size, { "logical_block_size", "drbd.logical_block_size", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1148 { &hf_drbd_alignment_offset, { "alignment_offset", "drbd.alignment_offset", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1149 { &hf_drbd_io_min, { "io_min", "drbd.io_min", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1150 { &hf_drbd_io_opt, { "io_opt", "drbd.io_opt", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1151 { &hf_drbd_discard_enabled, { "discard_enabled", "drbd.discard_enabled", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 1152 { &hf_drbd_discard_zeroes_data, { "discard_zeroes_data", "drbd.discard_zeroes_data", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 1153 { &hf_drbd_write_same_capable, { "write_same_capable", "drbd.write_same_capable", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }}, 1154 { &hf_drbd_d_size, { "d_size", "drbd.d_size", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1155 { &hf_drbd_u_size, { "u_size", "drbd.u_size", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1156 { &hf_drbd_c_size, { "c_size", "drbd.c_size", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1157 { &hf_drbd_max_bio_size, { "max_bio_size", "drbd.max_bio_size", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1158 { &hf_drbd_queue_order_type, { "queue_order_type", "drbd.queue_order_type", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1159 { &hf_drbd_dds_flags, { "dds_flags", "drbd.dds_flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1160 { &hf_drbd_state, { "state", "drbd.state", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1161 { &hf_drbd_mask, { "mask", "drbd.mask", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, 1162 { &hf_drbd_val, { "val", "drbd.val", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1163 { &hf_drbd_retcode, { "retcode", "drbd.retcode", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1164 { &hf_drbd_tid, { "tid", "drbd.tid", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }}, 1165 { &hf_drbd_initiator_node_id, { "initiator_node_id", "drbd.initiator_node_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1166 { &hf_drbd_target_node_id, { "target_node_id", "drbd.target_node_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1167 { &hf_drbd_nodes_to_reach, { "nodes_to_reach", "drbd.nodes_to_reach", FT_UINT64, BASE_CUSTOM, format_node_mask, 0x0, NULL, HFILL }}, 1168 { &hf_drbd_reachable_nodes, { "reachable_nodes", "drbd.reachable_nodes", FT_UINT64, BASE_CUSTOM, format_node_mask, 0x0, NULL, HFILL }}, 1169 { &hf_drbd_offset, { "offset", "drbd.offset", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1170 { &hf_drbd_dagtag, { "dagtag", "drbd.dagtag", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, 1171 { &hf_drbd_node_id, { "node_id", "drbd.node_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, 1172 1173 { &hf_drbd_state_role, { "role", "drbd.state.role", FT_UINT32, BASE_DEC, VALS(role_names), STATE_ROLE, NULL, HFILL }}, 1174 { &hf_drbd_state_peer, { "peer", "drbd.state.peer", FT_UINT32, BASE_DEC, VALS(role_names), STATE_PEER, NULL, HFILL }}, 1175 { &hf_drbd_state_conn, { "conn", "drbd.state.conn", FT_UINT32, BASE_DEC, VALS(connection_state_names), STATE_CONN, NULL, HFILL }}, 1176 { &hf_drbd_state_disk, { "disk", "drbd.state.disk", FT_UINT32, BASE_DEC, VALS(disk_state_names), STATE_DISK, NULL, HFILL }}, 1177 { &hf_drbd_state_pdsk, { "pdsk", "drbd.state.pdsk", FT_UINT32, BASE_DEC, VALS(disk_state_names), STATE_PDSK, NULL, HFILL }}, 1178 { &hf_drbd_state_susp, { "susp", "drbd.state.susp", FT_BOOLEAN, 32, NULL, STATE_SUSP, NULL, HFILL }}, 1179 { &hf_drbd_state_aftr_isp, { "aftr_isp", "drbd.state.aftr_isp", FT_BOOLEAN, 32, NULL, STATE_AFTR_ISP, NULL, HFILL }}, 1180 { &hf_drbd_state_peer_isp, { "peer_isp", "drbd.state.peer_isp", FT_BOOLEAN, 32, NULL, STATE_PEER_ISP, NULL, HFILL }}, 1181 { &hf_drbd_state_user_isp, { "user_isp", "drbd.state.user_isp", FT_BOOLEAN, 32, NULL, STATE_USER_ISP, NULL, HFILL }}, 1182 { &hf_drbd_state_susp_nod, { "susp_nod", "drbd.state.susp_nod", FT_BOOLEAN, 32, NULL, STATE_SUSP_NOD, NULL, HFILL }}, 1183 { &hf_drbd_state_susp_fen, { "susp_fen", "drbd.state.susp_fen", FT_BOOLEAN, 32, NULL, STATE_SUSP_FEN, NULL, HFILL }}, 1184 { &hf_drbd_state_quorum, { "quorum", "drbd.state.quorum", FT_BOOLEAN, 32, NULL, STATE_QUORUM, NULL, HFILL }}, 1185 1186 { &hf_drbd_uuid_flag_discard_my_data, { "discard_my_data", "drbd.uuid_flag.discard_my_data", FT_BOOLEAN, 64, NULL, UUID_FLAG_DISCARD_MY_DATA, NULL, HFILL }}, 1187 { &hf_drbd_uuid_flag_crashed_primary, { "crashed_primary", "drbd.uuid_flag.crashed_primary", FT_BOOLEAN, 64, NULL, UUID_FLAG_CRASHED_PRIMARY, NULL, HFILL }}, 1188 { &hf_drbd_uuid_flag_inconsistent, { "inconsistent", "drbd.uuid_flag.inconsistent", FT_BOOLEAN, 64, NULL, UUID_FLAG_INCONSISTENT, NULL, HFILL }}, 1189 { &hf_drbd_uuid_flag_skip_initial_sync, { "skip_initial_sync", "drbd.uuid_flag.skip_initial_sync", FT_BOOLEAN, 64, NULL, UUID_FLAG_SKIP_INITIAL_SYNC, NULL, HFILL }}, 1190 { &hf_drbd_uuid_flag_new_datagen, { "new_datagen", "drbd.uuid_flag.new_datagen", FT_BOOLEAN, 64, NULL, UUID_FLAG_NEW_DATAGEN, NULL, HFILL }}, 1191 { &hf_drbd_uuid_flag_stable, { "stable", "drbd.uuid_flag.stable", FT_BOOLEAN, 64, NULL, UUID_FLAG_STABLE, NULL, HFILL }}, 1192 { &hf_drbd_uuid_flag_got_stable, { "got_stable", "drbd.uuid_flag.got_stable", FT_BOOLEAN, 64, NULL, UUID_FLAG_GOT_STABLE, NULL, HFILL }}, 1193 { &hf_drbd_uuid_flag_resync, { "resync", "drbd.uuid_flag.resync", FT_BOOLEAN, 64, NULL, UUID_FLAG_RESYNC, NULL, HFILL }}, 1194 { &hf_drbd_uuid_flag_reconnect, { "reconnect", "drbd.uuid_flag.reconnect", FT_BOOLEAN, 64, NULL, UUID_FLAG_RECONNECT, NULL, HFILL }}, 1195 { &hf_drbd_uuid_flag_diskless_primary, { "diskless_primary", "drbd.uuid_flag.diskless_primary", FT_BOOLEAN, 64, NULL, UUID_FLAG_DISKLESS_PRIMARY, NULL, HFILL }}, 1196 { &hf_drbd_uuid_flag_primary_lost_quorum, { "primary_lost_quorum", "drbd.uuid_flag.primary_lost_quorum", FT_BOOLEAN, 64, NULL, UUID_FLAG_PRIMARY_LOST_QUORUM, NULL, HFILL }}, 1197 1198 { &hf_drbd_dp_hardbarrier, { "hardbarrier", "drbd.dp_flag.hardbarrier", FT_BOOLEAN, 32, NULL, DP_HARDBARRIER, NULL, HFILL }}, 1199 { &hf_drbd_dp_rw_sync, { "rw_sync", "drbd.dp_flag.rw_sync", FT_BOOLEAN, 32, NULL, DP_RW_SYNC, NULL, HFILL }}, 1200 { &hf_drbd_dp_may_set_in_sync, { "may_set_in_sync", "drbd.dp_flag.may_set_in_sync", FT_BOOLEAN, 32, NULL, DP_MAY_SET_IN_SYNC, NULL, HFILL }}, 1201 { &hf_drbd_dp_unplug, { "unplug", "drbd.dp_flag.unplug", FT_BOOLEAN, 32, NULL, DP_UNPLUG, NULL, HFILL }}, 1202 { &hf_drbd_dp_fua, { "fua", "drbd.dp_flag.fua", FT_BOOLEAN, 32, NULL, DP_FUA, NULL, HFILL }}, 1203 { &hf_drbd_dp_flush, { "flush", "drbd.dp_flag.flush", FT_BOOLEAN, 32, NULL, DP_FLUSH, NULL, HFILL }}, 1204 { &hf_drbd_dp_discard, { "discard", "drbd.dp_flag.discard", FT_BOOLEAN, 32, NULL, DP_DISCARD, NULL, HFILL }}, 1205 { &hf_drbd_dp_send_receive_ack, { "send_receive_ack", "drbd.dp_flag.send_receive_ack", FT_BOOLEAN, 32, NULL, DP_SEND_RECEIVE_ACK, NULL, HFILL }}, 1206 { &hf_drbd_dp_send_write_ack, { "send_write_ack", "drbd.dp_flag.send_write_ack", FT_BOOLEAN, 32, NULL, DP_SEND_WRITE_ACK, NULL, HFILL }}, 1207 { &hf_drbd_dp_wsame, { "wsame", "drbd.dp_flag.wsame", FT_BOOLEAN, 32, NULL, DP_WSAME, NULL, HFILL }}, 1208 { &hf_drbd_dp_zeroes, { "zeroes", "drbd.dp_flag.zeroes", FT_BOOLEAN, 32, NULL, DP_ZEROES, NULL, HFILL }}, 1209 }; 1210 1211 static gint *ett[] = { 1212 &ett_drbd, 1213 &ett_drbd_state, 1214 &ett_drbd_uuid_flags, 1215 &ett_drbd_history_uuids, 1216 &ett_drbd_data_flags, 1217 }; 1218 1219 proto_drbd = proto_register_protocol("DRBD Protocol", "DRBD", "drbd"); 1220 proto_register_field_array(proto_drbd, hf, array_length(hf)); 1221 proto_register_subtree_array(ett, array_length(ett)); 1222 } 1223 1224 void proto_reg_handoff_drbd(void) 1225 { 1226 drbd_handle = create_dissector_handle(dissect_drbd, proto_drbd); 1227 heur_dissector_add("tcp", test_drbd_protocol, "DRBD over TCP", "drbd_tcp", proto_drbd, HEURISTIC_DISABLE); 1228 } 1229 1230 /* 1231 * Editor modelines - https://www.wireshark.org/tools/modelines.html 1232 * 1233 * Local variables: 1234 * c-basic-offset: 4 1235 * tab-width: 8 1236 * indent-tabs-mode: nil 1237 * End: 1238 * 1239 * vi: set shiftwidth=4 tabstop=8 expandtab: 1240 * :indentSize=4:tabSize=8:noTabs=true: 1241 */ 1242