Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-kafka.c
blob2b6b179fb28d88b26de392566b3c4e6b058f992e
1 /* packet-kafka.c
2 * Routines for Apache Kafka Protocol dissection (version 0.8 - 2.5)
3 * Copyright 2013, Evan Huus <eapache@gmail.com>
4 * Update from Kafka 0.10.1.0 to 2.5 by Piotr Smolinski <piotr.smolinski@confluent.io>
6 * https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol
7 * https://kafka.apache.org/protocol.html
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/expert.h>
20 #include <epan/prefs.h>
22 #include <wsutil/array.h>
25 #ifdef HAVE_SNAPPY
26 #include <snappy-c.h>
27 #endif
28 #ifdef HAVE_LZ4FRAME_H
29 #include <lz4.h>
30 #include <lz4frame.h>
31 #endif
33 #include "packet-tcp.h"
34 #include "packet-tls.h"
36 void proto_register_kafka(void);
37 void proto_reg_handoff_kafka(void);
39 static int proto_kafka;
41 static int hf_kafka_len;
42 static int hf_kafka_api_key;
43 static int hf_kafka_api_version;
44 static int hf_kafka_request_api_key;
45 static int hf_kafka_response_api_key;
46 static int hf_kafka_request_api_version;
47 static int hf_kafka_response_api_version;
48 static int hf_kafka_correlation_id;
49 static int hf_kafka_client_id;
50 static int hf_kafka_client_host;
51 static int hf_kafka_required_acks;
52 static int hf_kafka_timeout;
53 static int hf_kafka_topic_name;
54 static int hf_kafka_topic_id;
55 static int hf_kafka_transactional_id;
56 static int hf_kafka_transaction_result;
57 static int hf_kafka_transaction_timeout;
58 static int hf_kafka_partition_id;
59 static int hf_kafka_replica;
60 static int hf_kafka_replication_factor;
61 static int hf_kafka_isr;
62 static int hf_kafka_offline;
63 static int hf_kafka_last_stable_offset;
64 static int hf_kafka_log_start_offset;
65 static int hf_kafka_first_offset;
66 static int hf_kafka_producer_id;
67 static int hf_kafka_producer_epoch;
68 static int hf_kafka_message_size;
69 static int hf_kafka_message_crc;
70 static int hf_kafka_message_magic;
71 static int hf_kafka_message_codec;
72 static int hf_kafka_message_timestamp_type;
73 static int hf_kafka_message_timestamp;
74 static int hf_kafka_batch_crc;
75 static int hf_kafka_batch_codec;
76 static int hf_kafka_batch_timestamp_type;
77 static int hf_kafka_batch_transactional;
78 static int hf_kafka_batch_control_batch;
79 static int hf_kafka_batch_last_offset_delta;
80 static int hf_kafka_batch_first_timestamp;
81 static int hf_kafka_batch_last_timestamp;
82 static int hf_kafka_batch_base_sequence;
83 static int hf_kafka_batch_size;
84 static int hf_kafka_batch_index;
85 static int hf_kafka_batch_index_error_message;
86 static int hf_kafka_message_key;
87 static int hf_kafka_message_value;
88 static int hf_kafka_message_compression_reduction;
89 static int hf_kafka_truncated_content;
90 static int hf_kafka_request_frame;
91 static int hf_kafka_response_frame;
92 static int hf_kafka_consumer_group;
93 static int hf_kafka_consumer_group_instance;
94 static int hf_kafka_coordinator_key;
95 static int hf_kafka_coordinator_type;
96 static int hf_kafka_group_state;
97 static int hf_kafka_offset;
98 static int hf_kafka_offset_time;
99 static int hf_kafka_max_offsets;
100 static int hf_kafka_metadata;
101 static int hf_kafka_error;
102 static int hf_kafka_error_message;
103 static int hf_kafka_broker_nodeid;
104 static int hf_kafka_broker_epoch;
105 static int hf_kafka_broker_host;
106 static int hf_kafka_listener_name;
107 static int hf_kafka_broker_port;
108 static int hf_kafka_rack;
109 static int hf_kafka_broker_security_protocol_type;
110 static int hf_kafka_cluster_id;
111 static int hf_kafka_controller_id;
112 static int hf_kafka_controller_epoch;
113 static int hf_kafka_delete_partitions;
114 static int hf_kafka_leader_id;
115 static int hf_kafka_group_leader_id;
116 static int hf_kafka_leader_epoch;
117 static int hf_kafka_current_leader_epoch;
118 static int hf_kafka_is_internal;
119 static int hf_kafka_isolation_level;
120 static int hf_kafka_min_bytes;
121 static int hf_kafka_max_bytes;
122 static int hf_kafka_max_wait_time;
123 static int hf_kafka_throttle_time;
124 static int hf_kafka_api_versions_api_key;
125 static int hf_kafka_api_versions_min_version;
126 static int hf_kafka_api_versions_max_version;
127 static int hf_kafka_session_timeout;
128 static int hf_kafka_rebalance_timeout;
129 static int hf_kafka_member_id;
130 static int hf_kafka_protocol_type;
131 static int hf_kafka_protocol_name;
132 static int hf_kafka_protocol_metadata;
133 static int hf_kafka_member_metadata;
134 static int hf_kafka_generation_id;
135 static int hf_kafka_member_assignment;
136 static int hf_kafka_sasl_mechanism;
137 static int hf_kafka_num_partitions;
138 static int hf_kafka_zk_version;
139 static int hf_kafka_is_new_replica;
140 static int hf_kafka_leader_recovery_state;
141 static int hf_kafka_config_key;
142 static int hf_kafka_config_value;
143 static int hf_kafka_commit_timestamp;
144 static int hf_kafka_retention_time;
145 static int hf_kafka_forgotten_topic_name;
146 static int hf_kafka_forgotten_topic_id;
147 static int hf_kafka_forgotten_topic_partition;
148 static int hf_kafka_fetch_session_id;
149 static int hf_kafka_fetch_session_epoch;
150 static int hf_kafka_require_stable_offset;
151 static int hf_kafka_record_header_key;
152 static int hf_kafka_record_header_value;
153 static int hf_kafka_record_attributes;
154 static int hf_kafka_allow_auto_topic_creation;
155 static int hf_kafka_validate_only;
156 static int hf_kafka_coordinator_epoch;
157 static int hf_kafka_sasl_auth_bytes;
158 static int hf_kafka_session_lifetime_ms;
159 static int hf_kafka_acl_resource_type;
160 static int hf_kafka_acl_resource_name;
161 static int hf_kafka_acl_resource_pattern_type;
162 static int hf_kafka_acl_principal;
163 static int hf_kafka_acl_host;
164 static int hf_kafka_acl_operation;
165 static int hf_kafka_acl_permission_type;
166 static int hf_kafka_config_resource_type;
167 static int hf_kafka_config_resource_name;
168 static int hf_kafka_config_include_synonyms;
169 static int hf_kafka_config_include_documentation;
170 static int hf_kafka_config_source;
171 static int hf_kafka_config_readonly;
172 static int hf_kafka_config_default;
173 static int hf_kafka_config_sensitive;
174 static int hf_kafka_config_data_type;
175 static int hf_kafka_config_documentation;
176 static int hf_kafka_config_operation;
177 static int hf_kafka_log_dir;
178 static int hf_kafka_segment_size;
179 static int hf_kafka_offset_lag;
180 static int hf_kafka_future;
181 static int hf_kafka_partition_count;
182 static int hf_kafka_token_max_life_time;
183 static int hf_kafka_token_renew_time;
184 static int hf_kafka_token_expiry_time;
185 static int hf_kafka_token_principal_type;
186 static int hf_kafka_token_principal_name;
187 static int hf_kafka_token_issue_timestamp;
188 static int hf_kafka_token_expiry_timestamp;
189 static int hf_kafka_token_max_timestamp;
190 static int hf_kafka_token_id;
191 static int hf_kafka_token_hmac;
192 static int hf_kafka_include_cluster_authorized_ops;
193 static int hf_kafka_include_topic_authorized_ops;
194 static int hf_kafka_include_group_authorized_ops;
195 static int hf_kafka_cluster_authorized_ops;
196 static int hf_kafka_topic_authorized_ops;
197 static int hf_kafka_group_authorized_ops;
198 static int hf_kafka_election_type;
199 static int hf_kafka_tagged_field_tag;
200 static int hf_kafka_tagged_field_data;
201 static int hf_kafka_client_software_name;
202 static int hf_kafka_client_software_version;
203 static int hf_kafka_is_kraft_controller;
204 static int hf_kafka_topic_inclusion_type;
205 static int hf_kafka_delete_partition;
206 static int hf_kafka_join_reason;
207 static int hf_kafka_leave_reason;
208 static int hf_kafka_skip_assignment;
209 static int hf_kafka_producer_id_start;
210 static int hf_kafka_producer_id_len;
211 static int hf_kafka_group_id;
212 static int hf_kafka_member_epoch;
213 static int hf_kafka_endpoint_type;
214 static int hf_kafka_last_fetched_epoch;
216 static int ett_kafka;
217 static int ett_kafka_batch;
218 static int ett_kafka_message;
219 static int ett_kafka_message_set;
220 static int ett_kafka_replicas;
221 static int ett_kafka_isrs;
222 static int ett_kafka_offline;
223 static int ett_kafka_broker;
224 static int ett_kafka_brokers;
225 static int ett_kafka_broker_end_point;
226 static int ett_kafka_markers;
227 static int ett_kafka_marker;
228 static int ett_kafka_topics;
229 static int ett_kafka_topic;
230 static int ett_kafka_partitions;
231 static int ett_kafka_partition;
232 static int ett_kafka_api_version;
233 static int ett_kafka_group_protocols;
234 static int ett_kafka_group_protocol;
235 static int ett_kafka_group_members;
236 static int ett_kafka_group_member;
237 static int ett_kafka_group_assignments;
238 static int ett_kafka_group_assignment;
239 static int ett_kafka_groups;
240 static int ett_kafka_group;
241 static int ett_kafka_sasl_enabled_mechanisms;
242 static int ett_kafka_replica_assignment;
243 static int ett_kafka_configs;
244 static int ett_kafka_config;
245 static int ett_kafka_request_forgotten_topic;
246 static int ett_kafka_record;
247 static int ett_kafka_record_headers;
248 static int ett_kafka_record_headers_header;
249 static int ett_kafka_aborted_transactions;
250 static int ett_kafka_aborted_transaction;
251 static int ett_kafka_resources;
252 static int ett_kafka_resource;
253 static int ett_kafka_acls;
254 static int ett_kafka_acl;
255 static int ett_kafka_acl_creations;
256 static int ett_kafka_acl_creation;
257 static int ett_kafka_acl_filters;
258 static int ett_kafka_acl_filter;
259 static int ett_kafka_acl_filter_matches;
260 static int ett_kafka_acl_filter_match;
261 static int ett_kafka_config_synonyms;
262 static int ett_kafka_config_synonym;
263 static int ett_kafka_config_entries;
264 static int ett_kafka_config_entry;
265 static int ett_kafka_log_dirs;
266 static int ett_kafka_log_dir;
267 static int ett_kafka_renewers;
268 static int ett_kafka_renewer;
269 static int ett_kafka_owners;
270 static int ett_kafka_owner;
271 static int ett_kafka_tokens;
272 static int ett_kafka_token;
273 /* in Kafka 2.5 these structures have been added, but not yet used */
274 static int ett_kafka_tagged_fields;
275 static int ett_kafka_tagged_field;
276 static int ett_kafka_record_errors;
277 static int ett_kafka_record_error;
279 static expert_field ei_kafka_request_missing;
280 static expert_field ei_kafka_unknown_api_key;
281 static expert_field ei_kafka_unsupported_api_version;
282 static expert_field ei_kafka_assumed_api_version;
283 static expert_field ei_kafka_bad_string_length;
284 static expert_field ei_kafka_bad_bytes_length;
285 static expert_field ei_kafka_bad_array_length;
286 static expert_field ei_kafka_bad_record_length;
287 static expert_field ei_kafka_bad_varint;
288 static expert_field ei_kafka_bad_message_set_length;
289 static expert_field ei_kafka_bad_decompression_length;
290 static expert_field ei_kafka_zero_decompression_length;
291 static expert_field ei_kafka_unknown_message_magic;
292 static expert_field ei_kafka_pdu_length_mismatch;
293 static expert_field ei_kafka_zero_field_length;
295 typedef int16_t kafka_api_key_t;
296 typedef int16_t kafka_api_version_t;
297 typedef int16_t kafka_error_t;
298 typedef int32_t kafka_partition_t;
299 typedef int64_t kafka_offset_t;
301 typedef struct _kafka_api_info_t {
302 kafka_api_key_t api_key;
303 const char *name;
304 /* If api key is not supported then set min_version and max_version to -1 */
305 kafka_api_version_t min_version;
306 kafka_api_version_t max_version;
307 /* Added in Kafka 2.4. Protocol messages are upgraded gradually. */
308 kafka_api_version_t flexible_since;
309 } kafka_api_info_t;
311 #define KAFKA_TCP_DEFAULT_RANGE "9092"
313 #define KAFKA_PRODUCE 0
314 #define KAFKA_FETCH 1
315 #define KAFKA_OFFSETS 2
316 #define KAFKA_METADATA 3
317 #define KAFKA_LEADER_AND_ISR 4
318 #define KAFKA_STOP_REPLICA 5
319 #define KAFKA_UPDATE_METADATA 6
320 #define KAFKA_CONTROLLED_SHUTDOWN 7
321 #define KAFKA_OFFSET_COMMIT 8
322 #define KAFKA_OFFSET_FETCH 9
323 #define KAFKA_FIND_COORDINATOR 10
324 #define KAFKA_JOIN_GROUP 11
325 #define KAFKA_HEARTBEAT 12
326 #define KAFKA_LEAVE_GROUP 13
327 #define KAFKA_SYNC_GROUP 14
328 #define KAFKA_DESCRIBE_GROUPS 15
329 #define KAFKA_LIST_GROUPS 16
330 #define KAFKA_SASL_HANDSHAKE 17
331 #define KAFKA_API_VERSIONS 18
332 #define KAFKA_CREATE_TOPICS 19
333 #define KAFKA_DELETE_TOPICS 20
334 #define KAFKA_DELETE_RECORDS 21
335 #define KAFKA_INIT_PRODUCER_ID 22
336 #define KAFKA_OFFSET_FOR_LEADER_EPOCH 23
337 #define KAFKA_ADD_PARTITIONS_TO_TXN 24
338 #define KAFKA_ADD_OFFSETS_TO_TXN 25
339 #define KAFKA_END_TXN 26
340 #define KAFKA_WRITE_TXN_MARKERS 27
341 #define KAFKA_TXN_OFFSET_COMMIT 28
342 #define KAFKA_DESCRIBE_ACLS 29
343 #define KAFKA_CREATE_ACLS 30
344 #define KAFKA_DELETE_ACLS 31
345 #define KAFKA_DESCRIBE_CONFIGS 32
346 #define KAFKA_ALTER_CONFIGS 33
347 #define KAFKA_ALTER_REPLICA_LOG_DIRS 34
348 #define KAFKA_DESCRIBE_LOG_DIRS 35
349 #define KAFKA_SASL_AUTHENTICATE 36
350 #define KAFKA_CREATE_PARTITIONS 37
351 #define KAFKA_CREATE_DELEGATION_TOKEN 38
352 #define KAFKA_RENEW_DELEGATION_TOKEN 39
353 #define KAFKA_EXPIRE_DELEGATION_TOKEN 40
354 #define KAFKA_DESCRIBE_DELEGATION_TOKEN 41
355 #define KAFKA_DELETE_GROUPS 42
356 #define KAFKA_ELECT_LEADERS 43
357 #define KAFKA_INC_ALTER_CONFIGS 44
358 #define KAFKA_ALTER_PARTITION_REASSIGNMENTS 45
359 #define KAFKA_LIST_PARTITION_REASSIGNMENTS 46
360 #define KAFKA_OFFSET_DELETE 47
361 #define KAFKA_DESCRIBE_CLIENT_QUOTAS 48
362 #define KAFKA_ALTER_CLIENT_QUOTAS 49
363 #define KAFKA_DESCRIBE_USER_SCRAM_CREDENTIALS 50
364 #define KAFKA_ALTER_USER_SCRAM_CREDENTIALS 51
365 #define KAFKA_DESCRIBE_QUORUM 55
366 #define KAFKA_ALTER_PARTITION 56
367 #define KAFKA_UPDATE_FEATURES 57
368 #define KAFKA_ENVELOPE 58
369 #define KAFKA_DESCRIBE_CLUSTER 60
370 #define KAFKA_DESCRIBE_PRODUCERS 61
371 #define KAFKA_UNREGISTER_BROKER 64
372 #define KAFKA_DESCRIBE_TRANSACTIONS 65
373 #define KAFKA_LIST_TRANSACTIONS 66
374 #define KAFKA_ALLOCATE_PRODUCER_IDS 67
375 #define KAFKA_CONSUMER_GROUP_HEARTBEAT 68
376 #define KAFKA_CONSUMER_GROUP_DESCRIBE 69
377 #define KAFKA_GET_TELEMETRY_SUBSCRIPTIONS 71
378 #define KAFKA_PUSH_TELEMETRY 72
379 #define KAFKA_LIST_CLIENT_METRICS_RESOURCES 74
382 * Check for message changes here:
383 * https://github.com/apache/kafka/tree/trunk/clients/src/main/resources/common/message
384 * The values are:
385 * - api key
386 * - min supported version
387 * - max supported version
388 * - flexible since (new in 2.4) - drives if string fields are prefixed by short or varint (unsigned)
389 * Flexible request header is 2 and response header id 1.
390 * Note that request header version is hardcoded to 0 for ControlledShutdown v.0 and
391 * response header version for ApiVersions is always 0.
393 static const kafka_api_info_t kafka_apis[] = {
394 { KAFKA_PRODUCE, "Produce",
395 0, 11, 9 },
396 { KAFKA_FETCH, "Fetch",
397 0, 16, 12 },
398 { KAFKA_OFFSETS, "Offsets",
399 0, 8, 6 },
400 { KAFKA_METADATA, "Metadata",
401 0, 12, 9 },
402 { KAFKA_LEADER_AND_ISR, "LeaderAndIsr",
403 0, 7, 4 },
404 { KAFKA_STOP_REPLICA, "StopReplica",
405 0, 4, 2 },
406 { KAFKA_UPDATE_METADATA, "UpdateMetadata",
407 0, 8, 6 },
408 { KAFKA_CONTROLLED_SHUTDOWN, "ControlledShutdown",
409 0, 3, 3 },
410 { KAFKA_OFFSET_COMMIT, "OffsetCommit",
411 0, 8, 8 },
412 { KAFKA_OFFSET_FETCH, "OffsetFetch",
413 0, 9, 6 },
414 { KAFKA_FIND_COORDINATOR, "FindCoordinator",
415 0, 5, 3 },
416 { KAFKA_JOIN_GROUP, "JoinGroup",
417 0, 9, 6 },
418 { KAFKA_HEARTBEAT, "Heartbeat",
419 0, 4, 4 },
420 { KAFKA_LEAVE_GROUP, "LeaveGroup",
421 0, 5, 4 },
422 { KAFKA_SYNC_GROUP, "SyncGroup",
423 0, 5, 4 },
424 { KAFKA_DESCRIBE_GROUPS, "DescribeGroups",
425 0, 5, 5 },
426 { KAFKA_LIST_GROUPS, "ListGroups",
427 0, 3, 3 },
428 { KAFKA_SASL_HANDSHAKE, "SaslHandshake",
429 0, 1, -1 },
430 { KAFKA_API_VERSIONS, "ApiVersions",
431 0, 3, 3 },
432 { KAFKA_CREATE_TOPICS, "CreateTopics",
433 0, 7, 5 },
434 { KAFKA_DELETE_TOPICS, "DeleteTopics",
435 0, 6, 4 },
436 { KAFKA_DELETE_RECORDS, "DeleteRecords",
437 0, 1, -1 },
438 { KAFKA_INIT_PRODUCER_ID, "InitProducerId",
439 0, 5, 2 },
440 { KAFKA_OFFSET_FOR_LEADER_EPOCH, "OffsetForLeaderEpoch",
441 0, 3, -1 },
442 { KAFKA_ADD_PARTITIONS_TO_TXN, "AddPartitionsToTxn",
443 0, 1, -1 },
444 { KAFKA_ADD_OFFSETS_TO_TXN, "AddOffsetsToTxn",
445 0, 1, -1 },
446 { KAFKA_END_TXN, "EndTxn",
447 0, 1, -1 },
448 { KAFKA_WRITE_TXN_MARKERS, "WriteTxnMarkers",
449 0, 0, -1 },
450 { KAFKA_TXN_OFFSET_COMMIT, "TxnOffsetCommit",
451 0, 3, 3 },
452 { KAFKA_DESCRIBE_ACLS, "DescribeAcls",
453 0, 2, 2 },
454 { KAFKA_CREATE_ACLS, "CreateAcls",
455 0, 2, 2 },
456 { KAFKA_DELETE_ACLS, "DeleteAcls",
457 0, 2, 2 },
458 { KAFKA_DESCRIBE_CONFIGS, "DescribeConfigs",
459 0, 4, 4 },
460 { KAFKA_ALTER_CONFIGS, "AlterConfigs",
461 0, 1, -1 },
462 { KAFKA_ALTER_REPLICA_LOG_DIRS, "AlterReplicaLogDirs",
463 0, 1, -1 },
464 { KAFKA_DESCRIBE_LOG_DIRS, "DescribeLogDirs",
465 0, 1, -1 },
466 { KAFKA_SASL_AUTHENTICATE, "SaslAuthenticate",
467 0, 2, 2 },
468 { KAFKA_CREATE_PARTITIONS, "CreatePartitions",
469 0, 2, 2 },
470 { KAFKA_CREATE_DELEGATION_TOKEN, "CreateDelegationToken",
471 0, 2, 2 },
472 { KAFKA_RENEW_DELEGATION_TOKEN, "RenewDelegationToken",
473 0, 2, 2 },
474 { KAFKA_EXPIRE_DELEGATION_TOKEN, "ExpireDelegationToken",
475 0, 2, 2 },
476 { KAFKA_DESCRIBE_DELEGATION_TOKEN, "DescribeDelegationToken",
477 0, 2, 2 },
478 { KAFKA_DELETE_GROUPS, "DeleteGroups",
479 0, 2, 2 },
480 { KAFKA_ELECT_LEADERS, "ElectLeaders",
481 0, 2, 2 },
482 { KAFKA_INC_ALTER_CONFIGS, "IncrementalAlterConfigs",
483 0, 1, 1 },
484 { KAFKA_ALTER_PARTITION_REASSIGNMENTS, "AlterPartitionReassignments",
485 0, 0, 0 },
486 { KAFKA_LIST_PARTITION_REASSIGNMENTS, "ListPartitionReassignments",
487 0, 0, 0 },
488 { KAFKA_OFFSET_DELETE, "OffsetDelete",
489 0, 0, -1 },
490 { KAFKA_DESCRIBE_CLUSTER, "DescribeCluster",
491 0, 1, 0 },
492 { KAFKA_ALLOCATE_PRODUCER_IDS, "AllocateProducerIds",
493 0, 0, 0 },
497 * Generated from kafka_apis. Add 1 to length for last dummy element.
499 static value_string kafka_api_names[array_length(kafka_apis) + 1];
502 * For the current list of error codes check here:
503 * https://github.com/apache/kafka/blob/trunk/clients/src/main/java/org/apache/kafka/common/protocol/Errors.java
505 static const value_string kafka_errors[] = {
506 { -1, "Unexpected Server Error" },
507 { 0, "No Error" },
508 { 1, "Offset Out Of Range" },
509 { 2, "Invalid Message" },
510 { 3, "Unknown Topic or Partition" },
511 { 4, "Invalid Message Size" },
512 { 5, "Leader Not Available" },
513 { 6, "Not Leader For Partition" },
514 { 7, "Request Timed Out" },
515 { 8, "Broker Not Available" },
516 { 10, "Message Size Too Large" },
517 { 11, "Stale Controller Epoch Code" },
518 { 12, "Offset Metadata Too Large" },
519 { 14, "Offsets Load In Progress" },
520 { 15, "The Coordinator is not Available" },
521 { 16, "Not Coordinator For Consumer" },
522 { 17, "Invalid topic" },
523 { 18, "Message batch larger than configured server segment size" },
524 { 19, "Not enough in-sync replicas" },
525 { 20, "Message(s) written to insufficient number of in-sync replicas" },
526 { 21, "Invalid required acks value" },
527 { 22, "Specified group generation id is not valid" },
528 { 23, "Inconsistent group protocol" },
529 { 24, "Invalid group.id" },
530 { 25, "Unknown member" },
531 { 26, "Invalid session timeout" },
532 { 27, "Group rebalance in progress" },
533 { 28, "Commit offset data size is not valid" },
534 { 29, "Topic authorization failed" },
535 { 30, "Group authorization failed" },
536 { 31, "Cluster authorization failed" },
537 { 32, "Invalid timestamp" },
538 { 33, "Unsupported SASL mechanism" },
539 { 34, "Illegal SASL state" },
540 { 35, "Unsupported version" },
541 { 36, "Topic already exists" },
542 { 37, "Invalid number of partitions" },
543 { 38, "Invalid replication-factor" },
544 { 39, "Invalid replica assignment" },
545 { 40, "Invalid configuration" },
546 { 41, "Not controller" },
547 { 42, "Invalid request" },
548 { 43, "Unsupported for Message Format" },
549 { 44, "Policy Violation" },
550 { 45, "Out of Order Sequence Number" },
551 { 46, "Duplicate Sequence Number" },
552 { 47, "Invalid Producer Epoch" },
553 { 48, "Invalid Transaction State" },
554 { 49, "Invalid Producer ID Mapping" },
555 { 50, "Invalid Transaction Timeout" },
556 { 51, "Concurrent Transactions" },
557 { 52, "Transaction Coordinator Fenced" },
558 { 53, "Transactional ID Authorization Failed" },
559 { 54, "Security Disabled" },
560 { 55, "Operation not Attempted" },
561 { 56, "Kafka Storage Error" },
562 { 57, "Log Directory not Found" },
563 { 58, "SASL Authentication failed" },
564 { 59, "Unknown Producer ID" },
565 { 60, "Partition Reassignment in Progress" },
566 { 61, "Delegation Token Auth Disabled" },
567 { 62, "Delegation Token not Found" },
568 { 63, "Delegation Token Owner Mismatch" },
569 { 64, "Delegation Token Request not Allowed" },
570 { 65, "Delegation Token Authorization Failed" },
571 { 66, "Delegation Token Expired" },
572 { 67, "Supplied Principal Type Unsupported" },
573 { 68, "Not Empty Group" },
574 { 69, "Group ID not Found" },
575 { 70, "Fetch Session ID not Found" },
576 { 71, "Invalid Fetch Session Epoch" },
577 { 72, "Listener not Found" },
578 { 73, "Topic Deletion Disabled" },
579 { 74, "Fenced Leader Epoch" },
580 { 75, "Unknown Leader Epoch" },
581 { 76, "Unsupported Compression Type" },
582 { 77, "Stale Broker Epoch" },
583 { 78, "Offset not Available" },
584 { 79, "Member ID Required" },
585 { 80, "Preferred Leader not Available" },
586 { 81, "Group Max Size Reached" },
587 { 82, "Fenced Instance ID" },
588 { 83, "Eligible topic partition leaders are not available" },
589 { 84, "Leader election not needed for topic partition" },
590 { 85, "No partition reassignment is in progress" },
591 { 86, "Deleting offsets of a topic is forbidden while the consumer group is actively subscribed to it" },
592 { 87, "This record has failed the validation on broker and hence will be rejected" },
593 { 88, "There are unstable offsets that need to be cleared" },
594 { 89, "The throttling quota has been exceeded." },
595 { 90, "There is a newer producer with the same transactionalId which fences the current one." },
596 { 91, "A request illegally referred to a resource that does not exist." },
597 { 92, "A request illegally referred to the same resource twice." },
598 { 93, "Requested credential would not meet criteria for acceptability." },
599 { 94, "Indicates that the either the sender or recipient of a voter-only request is not one of the expected voters." },
600 { 95, "The given update version was invalid." },
601 { 96, "Unable to update finalized features due to an unexpected server error." },
602 { 97, "Request principal deserialization failed during forwarding. This indicates an internal error on the broker cluster security setup." },
603 { 98, "Requested snapshot was not found." },
604 { 99, "Requested position is not greater than or equal to zero, and less than the size of the snapshot." },
605 { 100, "This server does not host this topic ID." },
606 { 101, "This broker ID is already in use." },
607 { 102, "The given broker ID was not registered." },
608 { 103, "The log's topic ID did not match the topic ID in the request." },
609 { 104, "The clusterId in the request does not match that found on the server." },
610 { 105, "The transactionalId could not be found." },
611 { 106, "The fetch session encountered inconsistent topic ID usage." },
612 { 107, "The new ISR contains at least one ineligible replica." },
613 { 108, "The AlterPartition request successfully updated the partition state but the leader has changed." },
614 { 109, "The requested offset is moved to tiered storage." },
615 { 110, "The member epoch is fenced by the group coordinator. The member must abandon all its partitions and rejoin." },
616 { 111, "The instance ID is still used by another member in the consumer group. That member must leave first." },
617 { 112, "The assignor or its version range is not supported by the consumer group." },
618 { 113, "The member epoch is stale. The member must retry after receiving its updated member epoch via the ConsumerGroupHeartbeat API." },
619 { 114, "The request was sent to an endpoint of the wrong type." },
620 { 115, "This endpoint type is not supported yet." },
621 { 116, "This controller ID is not known." },
622 { 117, "Client sent a push telemetry request with an invalid or outdated subscription ID." },
623 { 118, "Client sent a push telemetry request larger than the maximum size the broker will accept." },
624 { 119, "The controller has considered the broker registration to be invalid." },
625 { 120, "The server encountered an error with the transaction. The client can abort the transaction to continue using this transactional ID." },
626 { 0, NULL }
629 #define KAFKA_ACK_NOT_REQUIRED 0
630 #define KAFKA_ACK_LEADER 1
631 #define KAFKA_ACK_FULL_ISR -1
632 static const value_string kafka_acks[] = {
633 { KAFKA_ACK_NOT_REQUIRED, "Not Required" },
634 { KAFKA_ACK_LEADER, "Leader" },
635 { KAFKA_ACK_FULL_ISR, "Full ISR" },
636 { 0, NULL }
639 #define KAFKA_MESSAGE_CODEC_MASK 0x07
640 #define KAFKA_MESSAGE_CODEC_NONE 0
641 #define KAFKA_MESSAGE_CODEC_GZIP 1
642 #define KAFKA_MESSAGE_CODEC_SNAPPY 2
643 #define KAFKA_MESSAGE_CODEC_LZ4 3
644 #define KAFKA_MESSAGE_CODEC_ZSTD 4
645 static const value_string kafka_message_codecs[] = {
646 { KAFKA_MESSAGE_CODEC_NONE, "None" },
647 { KAFKA_MESSAGE_CODEC_GZIP, "Gzip" },
648 { KAFKA_MESSAGE_CODEC_SNAPPY, "Snappy" },
649 { KAFKA_MESSAGE_CODEC_LZ4, "LZ4" },
650 { KAFKA_MESSAGE_CODEC_ZSTD, "Zstd" },
651 { 0, NULL }
653 #ifdef HAVE_SNAPPY
654 static const uint8_t kafka_xerial_header[8] = {0x82, 0x53, 0x4e, 0x41, 0x50, 0x50, 0x59, 0x00};
655 #endif
657 #define KAFKA_MESSAGE_TIMESTAMP_MASK 0x08
658 static const value_string kafka_message_timestamp_types[] = {
659 { 0, "CreateTime" },
660 { 1, "LogAppendTime" },
661 { 0, NULL }
664 #define KAFKA_BATCH_TRANSACTIONAL_MASK 0x10
665 static const value_string kafka_batch_transactional_values[] = {
666 { 0, "Non-transactional" },
667 { 1, "Transactional" },
668 { 0, NULL }
671 #define KAFKA_BATCH_CONTROL_BATCH_MASK 0x20
672 static const value_string kafka_batch_control_batch_values[] = {
673 { 0, "Data batch" },
674 { 1, "Control batch" },
675 { 0, NULL }
678 static const value_string kafka_coordinator_types[] = {
679 { 0, "Group" },
680 { 1, "Transaction" },
681 { 0, NULL }
684 static const value_string kafka_security_protocol_types[] = {
685 { 0, "PLAINTEXT" },
686 { 1, "SSL" },
687 { 2, "SASL_PLAINTEXT" },
688 { 3, "SASL_SSL" },
689 { 0, NULL }
692 static const value_string kafka_isolation_levels[] = {
693 { 0, "Read Uncommitted" },
694 { 1, "Read Committed" },
695 { 0, NULL }
698 static const value_string kafka_transaction_results[] = {
699 { 0, "ABORT" },
700 { 1, "COMMIT" },
701 { 0, NULL }
704 static const value_string acl_resource_types[] = {
705 { 0, "Unknown" },
706 { 1, "Any" },
707 { 2, "Topic" },
708 { 3, "Group" },
709 { 4, "Cluster" },
710 { 5, "TransactionalId" },
711 { 6, "DelegationToken" },
712 { 0, NULL }
715 static const value_string acl_resource_pattern_types[] = {
716 { 0, "Unknown" },
717 { 1, "Any" },
718 { 2, "Match" },
719 { 3, "Literal" },
720 { 4, "Prefixed" },
721 { 0, NULL }
724 static const value_string acl_operations[] = {
725 { 0, "Unknown" },
726 { 1, "Any" },
727 { 2, "All" },
728 { 3, "Read" },
729 { 4, "Write" },
730 { 5, "Create" },
731 { 6, "Delete" },
732 { 7, "Alter" },
733 { 8, "Describe" },
734 { 9, "Cluster Action" },
735 { 10, "Describe Configs" },
736 { 11, "Alter Configs" },
737 { 12, "Idempotent Write" },
738 { 0, NULL }
741 static const value_string acl_permission_types[] = {
742 { 0, "Unknown" },
743 { 1, "Any" },
744 { 2, "Deny" },
745 { 3, "Allow" },
746 { 0, NULL }
749 static const value_string config_resource_types[] = {
750 { 0, "Unknown" },
751 { 2, "Topic" },
752 { 4, "Broker" },
753 { 0, NULL }
756 static const value_string config_sources[] = {
757 { 0, "Unknown" },
758 { 1, "Topic" },
759 { 2, "Broker (Dynamic)" },
760 { 3, "Broker (Dynamic/Default)" },
761 { 4, "Broker (Static)" },
762 { 5, "Default" },
763 { 0, NULL }
766 static const value_string config_operations[] = {
767 { 0, "Set" },
768 { 1, "Delete" },
769 { 2, "Append" },
770 { 3, "Subtract" },
771 { 0, NULL }
774 static const value_string election_types[] = {
775 { 0, "Preferred" },
776 { 1, "Unclean" },
777 { 0, NULL }
780 /* Whether to show the lengths of string and byte fields in the protocol tree.
781 * It can be useful to see these, but they do clutter up the display, so disable
782 * by default */
783 static bool kafka_show_string_bytes_lengths;
785 typedef struct _kafka_query_response_t {
786 kafka_api_key_t api_key;
787 kafka_api_version_t api_version;
788 uint32_t correlation_id;
789 uint32_t request_frame;
790 uint32_t response_frame;
791 bool response_found;
792 bool flexible_api;
793 } kafka_query_response_t;
796 /* Some values to temporarily remember during dissection */
797 typedef struct kafka_packet_values_t {
798 kafka_partition_t partition_id;
799 kafka_offset_t offset;
800 } kafka_packet_values_t;
802 /* Forward declaration (dissect_kafka_regular_message_set() and dissect_kafka_message() call each other...) */
803 static int
804 dissect_kafka_regular_message_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, unsigned len, uint8_t codec);
807 /* HELPERS */
809 #ifdef HAVE_LZ4FRAME_H
810 /* Local copy of XXH32() algorithm as found in https://github.com/lz4/lz4/blob/v1.7.5/lib/xxhash.c
811 as some packagers are not providing xxhash.h in liblz4 */
812 typedef struct {
813 uint32_t total_len_32;
814 uint32_t large_len;
815 uint32_t v1;
816 uint32_t v2;
817 uint32_t v3;
818 uint32_t v4;
819 uint32_t mem32[4]; /* buffer defined as U32 for alignment */
820 uint32_t memsize;
821 uint32_t reserved; /* never read nor write, will be removed in a future version */
822 } XXH32_state_t;
824 typedef enum {
825 XXH_bigEndian=0,
826 XXH_littleEndian=1
827 } XXH_endianess;
829 static const int g_one = 1;
830 #define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one))
832 static const uint32_t PRIME32_1 = 2654435761U;
833 static const uint32_t PRIME32_2 = 2246822519U;
834 static const uint32_t PRIME32_3 = 3266489917U;
835 static const uint32_t PRIME32_4 = 668265263U;
836 static const uint32_t PRIME32_5 = 374761393U;
838 #define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
840 static uint32_t XXH_read32(const void* memPtr)
842 uint32_t val;
843 memcpy(&val, memPtr, sizeof(val));
844 return val;
847 static uint32_t XXH_swap32(uint32_t x)
849 return ((x << 24) & 0xff000000 ) |
850 ((x << 8) & 0x00ff0000 ) |
851 ((x >> 8) & 0x0000ff00 ) |
852 ((x >> 24) & 0x000000ff );
855 #define XXH_readLE32(ptr, endian) (endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)))
857 static uint32_t XXH32_round(uint32_t seed, uint32_t input)
859 seed += input * PRIME32_2;
860 seed = XXH_rotl32(seed, 13);
861 seed *= PRIME32_1;
862 return seed;
865 static uint32_t XXH32_endian(const void* input, size_t len, uint32_t seed, XXH_endianess endian)
867 const int8_t* p = (const int8_t*)input;
868 const int8_t* bEnd = p + len;
869 uint32_t h32;
870 #define XXH_get32bits(p) XXH_readLE32(p, endian)
872 if (len>=16) {
873 const int8_t* const limit = bEnd - 16;
874 uint32_t v1 = seed + PRIME32_1 + PRIME32_2;
875 uint32_t v2 = seed + PRIME32_2;
876 uint32_t v3 = seed + 0;
877 uint32_t v4 = seed - PRIME32_1;
879 do {
880 v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
881 v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
882 v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
883 v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
884 } while (p<=limit);
886 h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
887 } else {
888 h32 = seed + PRIME32_5;
891 h32 += (uint32_t) len;
893 while (p+4<=bEnd) {
894 h32 += XXH_get32bits(p) * PRIME32_3;
895 h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
896 p+=4;
899 while (p<bEnd) {
900 h32 += (*p) * PRIME32_5;
901 h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
902 p++;
905 h32 ^= h32 >> 15;
906 h32 *= PRIME32_2;
907 h32 ^= h32 >> 13;
908 h32 *= PRIME32_3;
909 h32 ^= h32 >> 16;
911 return h32;
914 static unsigned XXH32(const void* input, size_t len, unsigned seed)
916 XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
917 if (endian_detected==XXH_littleEndian)
918 return XXH32_endian(input, len, seed, XXH_littleEndian);
919 else
920 return XXH32_endian(input, len, seed, XXH_bigEndian);
922 #endif /* HAVE_LZ4FRAME_H */
924 static const char *
925 kafka_error_to_str(kafka_error_t error)
927 return val_to_str(error, kafka_errors, "Unknown %d");
930 static const char *
931 kafka_api_key_to_str(kafka_api_key_t api_key)
933 return val_to_str(api_key, kafka_api_names, "Unknown %d");
936 static const kafka_api_info_t *
937 kafka_get_api_info(kafka_api_key_t api_key)
939 // short-circuit on obvious garbage - Kafka API keys are always positive
940 if (api_key < 0) {
941 return NULL;
944 // Kafka API keys are a sparse array (non-contiguous) so we have to walk the known API keys to see if this is
945 // one of them
946 for (uint32_t i = 0; i < array_length(kafka_apis); i++) {
947 if (kafka_apis[i].api_key == api_key) {
948 return &kafka_apis[i];
952 return NULL;
956 * Check if the API version uses flexible coding. Flexible coding was introduced in Kafka 2.4.
957 * The major changes in the flexible versions:
958 * - string length is stored as varint instead of int16
959 * - the header and message content may include additional flexible fields.
960 * The flexible version affects also the header. Normally the header version is 1.
961 * Flexible API headers are version 2. There are two hardcoded exceptions. ControlledShutdown
962 * request always uses header version 0. Same applies for ApiVersions response. These cases
963 * have to be covered in the message parsing.
965 static bool
966 kafka_is_api_version_flexible(kafka_api_key_t api_key, kafka_api_version_t api_version)
968 const kafka_api_info_t *api_info;
969 api_info = kafka_get_api_info(api_key);
970 return api_info != NULL && !(api_info->flexible_since == -1 || api_version < api_info->flexible_since);
973 static bool
974 kafka_is_api_version_supported(const kafka_api_info_t *api_info, kafka_api_version_t api_version)
976 DISSECTOR_ASSERT(api_info);
978 return !(api_info->min_version == -1 ||
979 api_version < api_info->min_version ||
980 api_version > api_info->max_version);
983 static void
984 kafka_check_supported_api_key(packet_info *pinfo, proto_item *ti, kafka_query_response_t *matcher)
986 if (kafka_get_api_info(matcher->api_key) == NULL) {
987 col_append_str(pinfo->cinfo, COL_INFO, " [Unknown API key]");
988 expert_add_info_format(pinfo, ti, &ei_kafka_unknown_api_key,
989 "%s API key", kafka_api_key_to_str(matcher->api_key));
993 static kafka_api_version_t
994 kafka_check_supported_api_version(packet_info *pinfo, proto_item *ti, kafka_query_response_t *matcher)
996 const kafka_api_info_t *api_info;
997 kafka_api_version_t dissect_version = matcher->api_version;
999 api_info = kafka_get_api_info(matcher->api_key);
1000 if (api_info != NULL && !kafka_is_api_version_supported(api_info, matcher->api_version)) {
1001 col_append_str(pinfo->cinfo, COL_INFO, " [Unsupported API version]");
1002 if (api_info->min_version == -1) {
1003 expert_add_info_format(pinfo, ti, &ei_kafka_unsupported_api_version,
1004 "Unsupported %s version.",
1005 kafka_api_key_to_str(matcher->api_key));
1006 dissect_version = api_info->min_version;
1008 else if (api_info->min_version == api_info->max_version) {
1009 expert_add_info_format(pinfo, ti, &ei_kafka_unsupported_api_version,
1010 "Unsupported %s version. Supports v%d.",
1011 kafka_api_key_to_str(matcher->api_key), api_info->min_version);
1012 dissect_version = api_info->min_version;
1013 expert_add_info_format(pinfo, ti, &ei_kafka_assumed_api_version,
1014 "Dissecting assuming v%d.",
1015 dissect_version);
1016 } else {
1017 expert_add_info_format(pinfo, ti, &ei_kafka_unsupported_api_version,
1018 "Unsupported %s version. Supports v%d-%d.",
1019 kafka_api_key_to_str(matcher->api_key),
1020 api_info->min_version, api_info->max_version);
1021 if (matcher->api_version < 0 || matcher->api_version > api_info->max_version) {
1022 dissect_version = api_info->max_version;
1023 } else {
1024 dissect_version = api_info->min_version;
1026 expert_add_info_format(pinfo, ti, &ei_kafka_assumed_api_version,
1027 "Dissecting assuming v%d.",
1028 dissect_version);
1032 return dissect_version;
1035 static int
1036 dissect_kafka_array_elements(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
1037 kafka_api_version_t api_version,
1038 int(*func)(tvbuff_t*, packet_info*, proto_tree*, int, kafka_api_version_t),
1039 int count)
1041 int i;
1042 int next_offset;
1044 // sanity check - we expect at least 1 byte per array item
1045 if (tvb_reported_length_remaining(tvb, offset) < count) {
1046 expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_kafka_bad_array_length);
1047 return offset;
1050 for (i=0; i<count; i++) {
1051 next_offset = func(tvb, pinfo, tree, offset, api_version);
1053 // sanity check - the offset should advance for each field we read
1054 if (next_offset == offset) {
1055 expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_kafka_zero_field_length);
1056 break;
1059 offset = next_offset;
1061 return offset;
1065 * In the pre KIP-482 the arrays had length saved in 32-bit signed integer. If the value was -1,
1066 * the array was considered to be null.
1068 static int
1069 dissect_kafka_regular_array(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
1070 kafka_api_version_t api_version,
1071 int(*func)(tvbuff_t*, packet_info*, proto_tree*, int, kafka_api_version_t),
1072 int *p_count)
1074 int32_t count;
1076 count = (int32_t) tvb_get_ntohl(tvb, offset);
1077 offset += 4;
1079 if (count < -1) { // -1 means null array
1080 expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_kafka_bad_array_length);
1081 return offset;
1084 offset = dissect_kafka_array_elements(tree, tvb, pinfo, offset, api_version, func, count);
1086 if (p_count != NULL) *p_count = count;
1088 return offset;
1092 * KIP-482 introduced concept of compact arrays. If API version for the given call is marked flexible,
1093 * all arrays are prefixed with unsigned varint. The value is the array length + 1. If the value is 0,
1094 * the array is null.
1096 static int
1097 dissect_kafka_compact_array(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
1098 kafka_api_version_t api_version,
1099 int(*func)(tvbuff_t*, packet_info*, proto_tree*, int, kafka_api_version_t),
1100 int *p_count)
1102 int64_t count;
1103 int32_t len;
1105 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &count, ENC_VARINT_PROTOBUF);
1106 if (len == 0) {
1107 expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_kafka_bad_varint);
1108 return tvb_captured_length(tvb);
1110 if(count > 0x7ffffffL) {
1111 expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_kafka_bad_array_length);
1112 return offset + len;
1114 offset += len;
1117 * Compact arrays store count+1
1118 * https://cwiki.apache.org/confluence/display/KAFKA/KIP-482%3A+The+Kafka+Protocol+should+Support+Optional+Tagged+Fields
1120 offset = dissect_kafka_array_elements(tree, tvb, pinfo, offset, api_version, func, (int)count - 1);
1122 if (p_count != NULL) *p_count = (int)count - 1;
1124 return offset;
1128 * Dissect array. Use 'flexible' flag to select which variant should be used.
1130 static int
1131 dissect_kafka_array(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int flexible,
1132 kafka_api_version_t api_version,
1133 int(*func)(tvbuff_t*, packet_info*, proto_tree*, int, kafka_api_version_t),
1134 int *p_count)
1136 if (flexible) {
1137 return dissect_kafka_compact_array(tree, tvb, pinfo, offset, api_version, func, p_count);
1138 } else {
1139 return dissect_kafka_regular_array(tree, tvb, pinfo, offset, api_version, func, p_count);
1144 /* kept for completeness */
1145 static int
1146 dissect_kafka_varint(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
1147 int64_t *p_value) _U_;
1148 static int
1149 dissect_kafka_varint(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
1150 int64_t *p_value)
1152 int64_t value;
1153 unsigned len;
1154 proto_item *pi;
1156 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &value, ENC_VARINT_ZIGZAG);
1157 pi = proto_tree_add_int64(tree, hf_item, tvb, offset, len, value);
1159 if (len == 0) {
1160 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1161 return tvb_captured_length(tvb);
1164 if (p_value != NULL) *p_value = value;
1166 return offset + len;
1169 static int
1170 dissect_kafka_varuint(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
1171 uint64_t *p_value)
1173 uint64_t value;
1174 unsigned len;
1175 proto_item *pi;
1177 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &value, ENC_VARINT_PROTOBUF);
1178 pi = proto_tree_add_uint64(tree, hf_item, tvb, offset, len, value);
1180 if (len == 0) {
1181 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1182 return tvb_captured_length(tvb);
1185 if (p_value != NULL) *p_value = value;
1187 return offset + len;
1192 * Retrieve null-terminated copy of string from a package.
1193 * The function wraps the tvb_get_string_enc that if given string is NULL, which is represented as negative length,
1194 * a substitute string is returned instead of failing.
1196 static int8_t*
1197 kafka_tvb_get_string(wmem_allocator_t *pool, tvbuff_t *tvb, int offset, int length)
1199 if (length>=0) {
1200 return tvb_get_string_enc(pool, tvb, offset, length, ENC_UTF_8);
1201 } else {
1202 return "[ Null ]";
1207 * Pre KIP-482 coding. The string is prefixed with 16-bit signed integer. Value -1 means null.
1209 static int
1210 dissect_kafka_regular_string(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
1211 int *p_offset, int *p_length)
1213 int16_t length;
1214 proto_item *pi;
1216 length = (int16_t) tvb_get_ntohs(tvb, offset);
1217 if (length < -1) {
1218 pi = proto_tree_add_item(tree, hf_item, tvb, offset, 0, ENC_NA);
1219 expert_add_info(pinfo, pi, &ei_kafka_bad_string_length);
1220 if (p_offset) {
1221 *p_offset = 2;
1223 if (p_length) {
1224 *p_length = 0;
1226 return offset + 2;
1229 if (length == -1) {
1230 proto_tree_add_string(tree, hf_item, tvb, offset, 2, NULL);
1231 } else {
1232 proto_tree_add_string(tree, hf_item, tvb, offset, length + 2,
1233 kafka_tvb_get_string(pinfo->pool, tvb, offset + 2, length));
1236 if (p_offset != NULL) *p_offset = offset + 2;
1237 if (p_length != NULL) *p_length = length;
1239 offset += 2;
1240 if (length != -1) offset += length;
1242 return offset;
1246 * Compact coding. The string is prefixed with unsigned varint containing number of octets + 1.
1248 static int
1249 dissect_kafka_compact_string(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
1250 int *p_offset, int *p_length)
1252 unsigned len;
1253 uint64_t length;
1254 proto_item *pi;
1256 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &length, ENC_VARINT_PROTOBUF);
1258 if (len == 0) {
1259 pi = proto_tree_add_item(tree, hf_item, tvb, offset, 0, ENC_NA);
1260 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1261 if (p_offset) {
1262 *p_offset = 0;
1264 if (p_length) {
1265 *p_length = 0;
1267 return tvb_captured_length(tvb);
1270 if (length == 0) {
1271 proto_tree_add_string(tree, hf_item, tvb, offset, len, NULL);
1272 } else {
1273 proto_tree_add_string(tree, hf_item, tvb, offset, len + (int)length - 1,
1274 kafka_tvb_get_string(pinfo->pool, tvb, offset + len, (int)length - 1));
1277 if (p_offset != NULL) *p_offset = offset + len;
1278 if (p_length != NULL) *p_length = (int)length - 1;
1280 offset += len;
1281 if (length > 0) {
1282 offset += (int)length - 1;
1285 return offset;
1289 * Dissect string. Depending on the 'flexible' flag use old style or compact coding.
1291 static int
1292 dissect_kafka_string(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset, int flexible,
1293 int *p_offset, int *p_length)
1295 if (flexible) {
1296 return dissect_kafka_compact_string(tree, hf_item, tvb, pinfo, offset, p_offset, p_length);
1297 } else {
1298 return dissect_kafka_regular_string(tree, hf_item, tvb, pinfo, offset, p_offset, p_length);
1303 * Pre KIP-482 coding. The string is prefixed with signed 32-bit integer containing number of octets.
1305 static int
1306 dissect_kafka_regular_bytes(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
1307 int *p_offset, int *p_length)
1309 int32_t length;
1310 proto_item *pi;
1312 length = (int32_t) tvb_get_ntohl(tvb, offset);
1313 if (length < -1) {
1314 pi = proto_tree_add_item(tree, hf_item, tvb, offset, 0, ENC_NA);
1315 expert_add_info(pinfo, pi, &ei_kafka_bad_string_length);
1316 if (p_offset) {
1317 *p_offset = 4;
1319 if (p_length) {
1320 *p_length = 0;
1322 return offset + 4;
1325 if (length == -1) {
1326 proto_tree_add_bytes_with_length(tree, hf_item, tvb, offset, 4, NULL, 0);
1327 } else {
1328 proto_tree_add_bytes_with_length(tree, hf_item, tvb, offset, length + 4,
1329 tvb_get_ptr(tvb, offset + 4, length), length);
1332 if (p_offset != NULL) *p_offset = offset + 4;
1333 if (p_length != NULL) *p_length = length;
1335 offset += 4;
1336 if (length != -1) offset += length;
1338 return offset;
1342 * Compact coding. The bytes are prefixed with unsigned varint containing number of octets + 1.
1344 static int
1345 dissect_kafka_compact_bytes(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
1346 int *p_offset, int *p_length)
1348 unsigned len;
1349 uint64_t length;
1350 proto_item *pi;
1352 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &length, ENC_VARINT_PROTOBUF);
1354 if (len == 0) {
1355 pi = proto_tree_add_item(tree, hf_item, tvb, offset, 0, ENC_NA);
1356 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1357 if (p_offset) {
1358 *p_offset = 0;
1360 if (p_length) {
1361 *p_length = 0;
1363 return tvb_captured_length(tvb);
1366 if (length == 0) {
1367 proto_tree_add_bytes_with_length(tree, hf_item, tvb, offset, len, NULL, 0);
1368 } else {
1369 proto_tree_add_bytes_with_length(tree, hf_item, tvb, offset, len + (int)length - 1,
1370 tvb_get_ptr(tvb, offset + len, (int)length - 1),
1371 (int)length - 1);
1374 if (p_offset != NULL) *p_offset = offset + len;
1375 if (p_length != NULL) *p_length = (int)length - 1;
1377 if (length == 0) {
1378 offset += len;
1379 } else {
1380 offset += len + (int)length - 1;
1383 return offset;
1387 * Dissect byte buffer. Depending on the 'flexible' flag use old style or compact coding.
1389 static int
1390 dissect_kafka_bytes(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset, int flexible,
1391 int *p_offset, int *p_length)
1393 if (flexible) {
1394 return dissect_kafka_compact_bytes(tree, hf_item, tvb, pinfo, offset, p_offset, p_length);
1395 } else {
1396 return dissect_kafka_regular_bytes(tree, hf_item, tvb, pinfo, offset, p_offset, p_length);
1400 static int
1401 dissect_kafka_timestamp_delta(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int hf_item, int offset, uint64_t first_timestamp)
1403 nstime_t nstime;
1404 uint64_t milliseconds;
1405 uint64_t val;
1406 unsigned len;
1407 proto_item *pi;
1409 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &val, ENC_VARINT_ZIGZAG);
1411 milliseconds = first_timestamp + val;
1412 nstime.secs = (time_t) (milliseconds / 1000);
1413 nstime.nsecs = (int) ((milliseconds % 1000) * 1000000);
1415 pi = proto_tree_add_time(tree, hf_item, tvb, offset, len, &nstime);
1416 if (len == 0) {
1417 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1418 return tvb_captured_length(tvb);
1421 return offset+len;
1424 static int
1425 dissect_kafka_offset_delta(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int hf_item, int offset, uint64_t base_offset)
1427 int64_t val;
1428 unsigned len;
1429 proto_item *pi;
1431 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &val, ENC_VARINT_ZIGZAG);
1433 pi = proto_tree_add_int64(tree, hf_item, tvb, offset, len, base_offset+val);
1434 if (len == 0) {
1435 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1436 return tvb_captured_length(tvb);
1439 return offset+len;
1442 static int
1443 dissect_kafka_int8(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int8_t *p_value)
1445 if (p_value != NULL) *p_value = tvb_get_int8(tvb, offset);
1446 proto_tree_add_item(tree, hf_item, tvb, offset, 1, ENC_NA);
1447 return offset+1;
1450 static int
1451 dissect_kafka_int16(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int16_t *p_value)
1453 if (p_value != NULL) *p_value = tvb_get_int16(tvb, offset, ENC_BIG_ENDIAN);
1454 proto_tree_add_item(tree, hf_item, tvb, offset, 2, ENC_BIG_ENDIAN);
1455 return offset+2;
1458 static int
1459 dissect_kafka_int32(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int32_t *p_value)
1461 if (p_value != NULL) *p_value = tvb_get_int32(tvb, offset, ENC_BIG_ENDIAN);
1462 proto_tree_add_item(tree, hf_item, tvb, offset, 4, ENC_BIG_ENDIAN);
1463 return offset+4;
1466 static int
1467 dissect_kafka_int64(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int64_t *p_value)
1469 if (p_value != NULL) *p_value = tvb_get_int64(tvb, offset, ENC_BIG_ENDIAN);
1470 proto_tree_add_item(tree, hf_item, tvb, offset, 8, ENC_BIG_ENDIAN);
1471 return offset+8;
1474 static int
1475 dissect_kafka_timestamp(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int64_t *p_value)
1477 if (p_value != NULL) *p_value = tvb_get_int64(tvb, offset, ENC_BIG_ENDIAN);
1478 proto_tree_add_item(tree, hf_item, tvb, offset, 8, ENC_TIME_MSECS | ENC_BIG_ENDIAN);
1479 return offset+8;
1482 static int
1483 dissect_kafka_uuid(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
1485 proto_tree_add_item(tree, hf_item, tvb, offset, 16, ENC_BIG_ENDIAN);
1486 return offset + 16;
1489 static int
1490 dissect_kafka_bool(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo _U_, int offset)
1492 proto_tree_add_item(tree, hf_item, tvb, offset, 1, ENC_BIG_ENDIAN);
1493 return offset + 1;
1497 * Function: dissect_kafka_string_new
1498 * ---------------------------------------------------
1499 * Decodes UTF-8 string using the new length encoding. This format is used
1500 * in the v2 message encoding, where the string length is encoded using
1501 * ProtoBuf's ZigZag integer format (inspired by Avro). The main advantage
1502 * of ZigZag is very compact representation for small numbers.
1504 * tvb: actual data buffer
1505 * pinfo: packet information
1506 * tree: protocol information tree to append the item
1507 * hf_item: protocol information item descriptor index
1508 * offset: offset in the buffer where the string length is to be found
1509 * p_display_string: pointer to a variable to store a pointer to the string value
1511 * returns: offset of the next field in the message. If supplied, p_display_string
1512 * is guaranteed to be set to a valid value.
1514 static int
1515 dissect_kafka_string_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int hf_item, int offset, char **p_display_string)
1517 int64_t val;
1518 unsigned len;
1519 proto_item *pi;
1521 if (p_display_string != NULL)
1522 *p_display_string = "<INVALID>";
1523 len = tvb_get_varint(tvb, offset, 5, &val, ENC_VARINT_ZIGZAG);
1525 if (len == 0) {
1526 pi = proto_tree_add_string_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<INVALID>");
1527 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1528 return tvb_captured_length(tvb);
1529 } else if (val > 0) {
1530 // there is payload available, possibly with 0 octets
1531 if (p_display_string != NULL)
1532 proto_tree_add_item_ret_display_string(tree, hf_item, tvb, offset+len, (int)val, ENC_UTF_8, pinfo->pool, p_display_string);
1533 else
1534 proto_tree_add_item(tree, hf_item, tvb, offset+len, (int)val, ENC_UTF_8);
1535 } else if (val == 0) {
1536 // there is empty payload (0 octets)
1537 proto_tree_add_string_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<EMPTY>");
1538 if (p_display_string != NULL)
1539 *p_display_string = "<EMPTY>";
1540 } else if (val == -1) {
1541 // there is no payload (null)
1542 proto_tree_add_string_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<NULL>");
1543 val = 0;
1544 } else {
1545 pi = proto_tree_add_string_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<INVALID>");
1546 expert_add_info(pinfo, pi, &ei_kafka_bad_string_length);
1547 val = 0;
1550 return offset+len+(int)val;
1554 * Function: dissect_kafka_bytes_new
1555 * ---------------------------------------------------
1556 * Decodes byte buffer using the new length encoding. This format is used
1557 * in the v2 message encoding, where the buffer length is encoded using
1558 * ProtoBuf's ZigZag integer format (inspired by Avro). The main advantage
1559 * of ZigZag is very compact representation for small numbers.
1561 * tvb: actual data buffer
1562 * pinfo: packet information (unused)
1563 * tree: protocol information tree to append the item
1564 * hf_item: protocol information item descriptor index
1565 * offset: offset in the buffer where the string length is to be found
1566 * p_bytes_offset: pointer to a variable to store the actual buffer begin
1567 * p_bytes_length: pointer to a variable to store the actual buffer length
1568 * p_invalid: pointer to a variable to store whether the length is valid
1570 * returns: pointer to the next field in the message
1572 static int
1573 dissect_kafka_bytes_new(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int hf_item, int offset, int *p_bytes_offset, int *p_bytes_length, bool *p_invalid)
1575 int64_t val;
1576 unsigned len;
1577 proto_item *pi;
1579 *p_invalid = false;
1581 len = tvb_get_varint(tvb, offset, 5, &val, ENC_VARINT_ZIGZAG);
1583 if (len == 0) {
1584 pi = proto_tree_add_bytes_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<INVALID>");
1585 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
1586 return tvb_captured_length(tvb);
1587 } else if (val > 0) {
1588 // there is payload available, possibly with 0 octets
1589 proto_tree_add_item(tree, hf_item, tvb, offset+len, (int)val, ENC_NA);
1590 } else if (val == 0) {
1591 // there is empty payload (0 octets)
1592 proto_tree_add_bytes_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<EMPTY>");
1593 } else if (val == -1) {
1594 // there is no payload (null)
1595 proto_tree_add_bytes_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<NULL>");
1596 val = 0;
1597 } else {
1598 pi = proto_tree_add_bytes_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<INVALID>");
1599 expert_add_info(pinfo, pi, &ei_kafka_bad_bytes_length);
1600 val = 0;
1601 *p_invalid = true;
1604 if (p_bytes_offset != NULL) {
1605 *p_bytes_offset = offset+len;
1607 if (p_bytes_length != NULL) {
1608 *p_bytes_length = (int)val;
1610 return offset+len+(int)val;
1613 /* Calculate and show the reduction in transmitted size due to compression */
1614 static void
1615 show_compression_reduction(tvbuff_t *tvb, proto_tree *tree, unsigned compressed_size, unsigned uncompressed_size)
1617 proto_item *ti;
1618 /* Not really expecting a message to compress down to nothing, but defend against dividing by 0 anyway */
1619 if (uncompressed_size != 0) {
1620 ti = proto_tree_add_float(tree, hf_kafka_message_compression_reduction, tvb, 0, 0,
1621 (float)compressed_size / (float)uncompressed_size);
1622 proto_item_set_generated(ti);
1626 static int
1627 dissect_kafka_record_headers_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, bool *p_invalid)
1629 proto_item *header_ti;
1630 proto_tree *subtree;
1631 char *key_display_string;
1633 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_record_headers_header, &header_ti, "Header");
1635 offset = dissect_kafka_string_new(tvb, pinfo, subtree, hf_kafka_record_header_key, offset, &key_display_string);
1636 offset = dissect_kafka_bytes_new(tvb, pinfo, subtree, hf_kafka_record_header_value, offset, NULL, NULL, p_invalid);
1638 proto_item_append_text(header_ti, " (Key: %s)", key_display_string);
1640 proto_item_set_end(header_ti, tvb, offset);
1642 return offset;
1645 static int
1646 dissect_kafka_record_headers(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1648 proto_item *record_headers_ti;
1649 proto_tree *subtree;
1650 int64_t count;
1651 unsigned len;
1652 int i;
1653 bool invalid = false;
1655 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_record_headers, &record_headers_ti, "Headers");
1657 len = tvb_get_varint(tvb, offset, 5, &count, ENC_VARINT_ZIGZAG);
1658 if (len == 0) {
1659 expert_add_info(pinfo, record_headers_ti, &ei_kafka_bad_varint);
1660 return tvb_captured_length(tvb);
1661 } else if (count < -1) { // -1 means null array
1662 expert_add_info(pinfo, record_headers_ti, &ei_kafka_bad_array_length);
1665 offset += len;
1666 for (i = 0; i < count && !invalid; i++) {
1667 offset = dissect_kafka_record_headers_header(tvb, pinfo, subtree, offset, &invalid);
1670 proto_item_set_end(record_headers_ti, tvb, offset);
1672 return offset;
1675 static int
1676 dissect_kafka_record(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int start_offset, uint64_t base_offset, uint64_t first_timestamp)
1678 proto_item *record_ti;
1679 proto_tree *subtree;
1681 int64_t size;
1682 unsigned len;
1684 int offset, end_offset;
1685 bool invalid;
1687 offset = start_offset;
1689 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_record, &record_ti, "Record");
1691 len = tvb_get_varint(tvb, offset, 5, &size, ENC_VARINT_ZIGZAG);
1692 if (len == 0) {
1693 expert_add_info(pinfo, record_ti, &ei_kafka_bad_varint);
1694 return tvb_captured_length(tvb);
1695 } else if (size < 6) {
1696 expert_add_info(pinfo, record_ti, &ei_kafka_bad_record_length);
1697 return offset + len;
1700 end_offset = offset + len + (int)size;
1701 offset += len;
1703 proto_tree_add_item(subtree, hf_kafka_record_attributes, tvb, offset, 1, ENC_BIG_ENDIAN);
1704 offset += 1;
1706 offset = dissect_kafka_timestamp_delta(tvb, pinfo, subtree, hf_kafka_message_timestamp, offset, first_timestamp);
1707 offset = dissect_kafka_offset_delta(tvb, pinfo, subtree, hf_kafka_offset, offset, base_offset);
1709 offset = dissect_kafka_bytes_new(tvb, pinfo, subtree, hf_kafka_message_key, offset, NULL, NULL, &invalid);
1710 if (invalid)
1711 return end_offset;
1712 offset = dissect_kafka_bytes_new(tvb, pinfo, subtree, hf_kafka_message_value, offset, NULL, NULL, &invalid);
1713 if (invalid)
1714 return end_offset;
1716 offset = dissect_kafka_record_headers(tvb, pinfo, subtree, offset);
1718 if (offset != end_offset) {
1719 expert_add_info(pinfo, record_ti, &ei_kafka_bad_record_length);
1722 proto_item_set_end(record_ti, tvb, end_offset);
1724 return end_offset;
1727 static bool
1728 decompress_none(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, uint32_t length _U_, tvbuff_t **decompressed_tvb, int *decompressed_offset)
1730 *decompressed_tvb = tvb;
1731 *decompressed_offset = offset;
1732 return true;
1735 static bool
1736 decompress_gzip(tvbuff_t *tvb, packet_info *pinfo, int offset, uint32_t length, tvbuff_t **decompressed_tvb, int *decompressed_offset)
1738 *decompressed_tvb = tvb_child_uncompress_zlib(tvb, tvb, offset, length);
1739 *decompressed_offset = 0;
1740 if (*decompressed_tvb) {
1741 return true;
1742 } else {
1743 col_append_str(pinfo->cinfo, COL_INFO, " [gzip decompression failed] ");
1744 return false;
1748 #define MAX_LOOP_ITERATIONS 100
1750 #ifdef HAVE_LZ4FRAME_H
1751 static bool
1752 decompress_lz4(tvbuff_t *tvb, packet_info *pinfo, int offset, uint32_t length, tvbuff_t **decompressed_tvb, int *decompressed_offset)
1754 LZ4F_decompressionContext_t lz4_ctxt = NULL;
1755 LZ4F_frameInfo_t lz4_info;
1756 LZ4F_errorCode_t rc = 0;
1757 size_t src_offset = 0, src_size = 0, dst_size = 0;
1758 unsigned char *decompressed_buffer = NULL;
1759 tvbuff_t *composite_tvb = NULL;
1761 bool ret = false;
1763 /* Prepare compressed data buffer */
1764 uint8_t *data = (uint8_t*)tvb_memdup(pinfo->pool, tvb, offset, length);
1765 /* Override header checksum to workaround buggy Kafka implementations */
1766 if (length > 7) {
1767 uint32_t hdr_end = 6;
1768 if (data[4] & 0x08) {
1769 hdr_end += 8;
1771 if (hdr_end < length) {
1772 data[hdr_end] = (XXH32(&data[4], hdr_end - 4, 0) >> 8) & 0xff;
1776 /* Allocate output buffer */
1777 rc = LZ4F_createDecompressionContext(&lz4_ctxt, LZ4F_VERSION);
1778 if (LZ4F_isError(rc)) {
1779 goto end;
1782 src_offset = length;
1783 rc = LZ4F_getFrameInfo(lz4_ctxt, &lz4_info, data, &src_offset);
1784 if (LZ4F_isError(rc)) {
1785 goto end;
1788 switch (lz4_info.blockSizeID) {
1789 case LZ4F_max64KB:
1790 dst_size = 1 << 16;
1791 break;
1792 case LZ4F_max256KB:
1793 dst_size = 1 << 18;
1794 break;
1795 case LZ4F_max1MB:
1796 dst_size = 1 << 20;
1797 break;
1798 case LZ4F_max4MB:
1799 dst_size = 1 << 22;
1800 break;
1801 default:
1802 goto end;
1805 if (lz4_info.contentSize && lz4_info.contentSize < dst_size) {
1806 dst_size = (size_t)lz4_info.contentSize;
1809 size_t out_size;
1810 int count = 0;
1812 do {
1813 src_size = length - src_offset; // set the number of available octets
1814 if (src_size == 0) {
1815 goto end;
1818 decompressed_buffer = wmem_alloc(pinfo->pool, dst_size);
1819 out_size = dst_size;
1820 rc = LZ4F_decompress(lz4_ctxt, decompressed_buffer, &out_size,
1821 &data[src_offset], &src_size, NULL);
1822 if (LZ4F_isError(rc)) {
1823 goto end;
1825 if (out_size != dst_size) {
1826 decompressed_buffer = (uint8_t *)wmem_realloc(pinfo->pool, decompressed_buffer, out_size);
1828 if (out_size == 0) {
1829 goto end;
1831 if (!composite_tvb) {
1832 composite_tvb = tvb_new_composite();
1834 tvb_composite_append(composite_tvb,
1835 tvb_new_child_real_data(tvb, (uint8_t*)decompressed_buffer, (unsigned)out_size, (int)out_size));
1836 src_offset += src_size; // bump up the offset for the next iteration
1837 DISSECTOR_ASSERT_HINT(count < MAX_LOOP_ITERATIONS, "MAX_LOOP_ITERATIONS exceeded");
1838 } while (rc > 0 && count++ < MAX_LOOP_ITERATIONS);
1840 ret = true;
1841 end:
1842 if (composite_tvb) {
1843 tvb_composite_finalize(composite_tvb);
1845 LZ4F_freeDecompressionContext(lz4_ctxt);
1846 if (ret == 1) {
1847 *decompressed_tvb = composite_tvb;
1848 *decompressed_offset = 0;
1850 else {
1851 col_append_str(pinfo->cinfo, COL_INFO, " [lz4 decompression failed]");
1853 return ret;
1855 #else
1856 static bool
1857 decompress_lz4(tvbuff_t *tvb _U_, packet_info *pinfo, int offset _U_, uint32_t length _U_, tvbuff_t **decompressed_tvb _U_, int *decompressed_offset _U_)
1859 col_append_str(pinfo->cinfo, COL_INFO, " [lz4 decompression unsupported]");
1860 return false;
1862 #endif /* HAVE_LZ4FRAME_H */
1864 #ifdef HAVE_SNAPPY
1865 static bool
1866 decompress_snappy(tvbuff_t *tvb, packet_info *pinfo, int offset, uint32_t length, tvbuff_t **decompressed_tvb, int *decompressed_offset)
1868 tvbuff_t *composite_tvb = NULL;
1869 bool ret = false;
1871 if (tvb_memeql(tvb, offset, kafka_xerial_header, sizeof(kafka_xerial_header)) == 0) {
1873 /* xerial framing format */
1874 uint32_t chunk_size, pos = 16;
1875 int count = 0;
1877 while (pos < length && count < MAX_LOOP_ITERATIONS) {
1878 tvbuff_t *decompressed_chunk_tvb;
1880 if (pos > length-4) {
1881 // XXX - this is presumably an error, as the chunk size
1882 // doesn't fully fit in the data, so an error should be
1883 // reported.
1884 goto end;
1886 chunk_size = tvb_get_ntohl(tvb, offset+pos);
1887 pos += 4;
1888 if (chunk_size > length) {
1889 // XXX - this is presumably an error, as the chunk to be
1890 // decompressed doesn't fully fit in the data, so an error
1891 // should be reported.
1892 goto end;
1894 if (pos > length-chunk_size) {
1895 // XXX - this is presumably an error, as the chunk to be
1896 // decompressed doesn't fully fit in the data, so an error
1897 // should be reported.
1898 goto end;
1900 decompressed_chunk_tvb = tvb_child_uncompress_snappy(tvb, tvb, offset+pos, chunk_size);
1901 if (decompressed_chunk_tvb == NULL) {
1902 goto end;
1904 if (!composite_tvb) {
1905 composite_tvb = tvb_new_composite();
1907 tvb_composite_append(composite_tvb, decompressed_chunk_tvb);
1908 pos += chunk_size;
1909 count++;
1910 DISSECTOR_ASSERT_HINT(count < MAX_LOOP_ITERATIONS, "MAX_LOOP_ITERATIONS exceeded");
1913 } else {
1915 /* unframed format */
1916 *decompressed_tvb = tvb_child_uncompress_snappy(tvb, tvb, offset, length);
1917 if (*decompressed_tvb == NULL) {
1918 goto end;
1920 *decompressed_offset = 0;
1923 ret = true;
1924 end:
1925 if (composite_tvb) {
1926 tvb_composite_finalize(composite_tvb);
1927 if (ret) {
1928 *decompressed_tvb = composite_tvb;
1929 *decompressed_offset = 0;
1932 if (!ret) {
1933 col_append_str(pinfo->cinfo, COL_INFO, " [snappy decompression failed]");
1935 return ret;
1937 #else
1938 static bool
1939 decompress_snappy(tvbuff_t *tvb _U_, packet_info *pinfo, int offset _U_, int length _U_, tvbuff_t **decompressed_tvb _U_, int *decompressed_offset _U_)
1941 col_append_str(pinfo->cinfo, COL_INFO, " [snappy decompression unsupported]");
1942 return false;
1944 #endif /* HAVE_SNAPPY */
1946 #ifdef HAVE_ZSTD
1947 static bool
1948 decompress_zstd(tvbuff_t *tvb, packet_info *pinfo, int offset, uint32_t length, tvbuff_t **decompressed_tvb, int *decompressed_offset)
1950 *decompressed_tvb = tvb_child_uncompress_zstd(tvb, tvb, offset, length);
1951 *decompressed_offset = 0;
1952 if (*decompressed_tvb) {
1953 return true;
1954 } else {
1955 col_append_str(pinfo->cinfo, COL_INFO, " [zstd decompression failed] ");
1956 return false;
1959 #else
1960 static bool
1961 decompress_zstd(tvbuff_t *tvb _U_, packet_info *pinfo, int offset _U_, uint32_t length _U_, tvbuff_t **decompressed_tvb _U_, int *decompressed_offset _U_)
1963 col_append_str(pinfo->cinfo, COL_INFO, " [zstd compression unsupported]");
1964 return false;
1966 #endif /* HAVE_ZSTD */
1968 // Max is currently 2^22 in
1969 // https://github.com/apache/kafka/blob/trunk/clients/src/main/java/org/apache/kafka/common/compress/KafkaLZ4BlockOutputStream.java
1970 #define MAX_DECOMPRESSION_SIZE (1 << 22)
1971 static bool
1972 decompress(tvbuff_t *tvb, packet_info *pinfo, int offset, uint32_t length, int codec, tvbuff_t **decompressed_tvb, int *decompressed_offset)
1974 if (length > MAX_DECOMPRESSION_SIZE) {
1975 expert_add_info(pinfo, NULL, &ei_kafka_bad_decompression_length);
1976 return false;
1978 if (length == 0) {
1979 expert_add_info(pinfo, NULL, &ei_kafka_zero_decompression_length);
1980 return false;
1982 switch (codec) {
1983 case KAFKA_MESSAGE_CODEC_SNAPPY:
1984 return decompress_snappy(tvb, pinfo, offset, length, decompressed_tvb, decompressed_offset);
1985 case KAFKA_MESSAGE_CODEC_LZ4:
1986 return decompress_lz4(tvb, pinfo, offset, length, decompressed_tvb, decompressed_offset);
1987 case KAFKA_MESSAGE_CODEC_ZSTD:
1988 return decompress_zstd(tvb, pinfo, offset, length, decompressed_tvb, decompressed_offset);
1989 case KAFKA_MESSAGE_CODEC_GZIP:
1990 return decompress_gzip(tvb, pinfo, offset, length, decompressed_tvb, decompressed_offset);
1991 case KAFKA_MESSAGE_CODEC_NONE:
1992 return decompress_none(tvb, pinfo, offset, length, decompressed_tvb, decompressed_offset);
1993 default:
1994 col_append_str(pinfo->cinfo, COL_INFO, " [unsupported compression type]");
1995 return false;
2000 * Function: dissect_kafka_message_old
2001 * ---------------------------------------------------
2002 * Handles decoding of pre-0.11 message format. In the old format
2003 * only the message payload was the subject of compression
2004 * and the batches were special kind of message payload.
2006 * https://kafka.apache.org/0100/documentation/#messageformat
2008 * tvb: actual data buffer
2009 * pinfo: packet information
2010 * tree: protocol information tree to append the item
2011 * hf_item: protocol information item descriptor index
2012 * offset: pointer to the message
2013 * end_offset: last possible offset in this batch
2015 * returns: pointer to the next message/batch
2017 static int
2018 // NOLINTNEXTLINE(misc-no-recursion)
2019 dissect_kafka_message_old(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int end_offset _U_)
2021 proto_item *message_ti;
2022 proto_tree *subtree;
2023 tvbuff_t *decompressed_tvb;
2024 int decompressed_offset;
2025 int start_offset = offset;
2026 int bytes_offset;
2027 int8_t magic_byte;
2028 uint8_t codec;
2029 uint32_t message_size;
2030 uint32_t length;
2032 message_size = tvb_get_uint32(tvb, start_offset + 8, ENC_BIG_ENDIAN);
2034 subtree = proto_tree_add_subtree(tree, tvb, start_offset, message_size + 12, ett_kafka_message, &message_ti, "Message");
2036 offset = dissect_kafka_int64(subtree, hf_kafka_offset, tvb, pinfo, offset, NULL);
2038 offset = dissect_kafka_int32(subtree, hf_kafka_message_size, tvb, pinfo, offset, NULL);
2040 offset = dissect_kafka_int32(subtree, hf_kafka_message_crc, tvb, pinfo, offset, NULL);
2042 offset = dissect_kafka_int8(subtree, hf_kafka_message_magic, tvb, pinfo, offset, &magic_byte);
2044 /* Don't advance "offset" here: The following message timestamp type field is in the same byte as the codec. */
2045 (void)dissect_kafka_int8(subtree, hf_kafka_message_codec, tvb, pinfo, offset, &codec);
2046 codec &= KAFKA_MESSAGE_CODEC_MASK;
2048 offset = dissect_kafka_int8(subtree, hf_kafka_message_timestamp_type, tvb, pinfo, offset, NULL);
2050 if (magic_byte > 0) {
2051 proto_tree_add_item(subtree, hf_kafka_message_timestamp, tvb, offset, 8, ENC_TIME_MSECS|ENC_BIG_ENDIAN);
2052 offset += 8;
2055 bytes_offset = dissect_kafka_regular_bytes(subtree, hf_kafka_message_key, tvb, pinfo, offset, NULL, NULL);
2056 if (bytes_offset > offset) {
2057 offset = bytes_offset;
2058 } else {
2059 expert_add_info(pinfo, message_ti, &ei_kafka_bad_bytes_length);
2060 return offset;
2064 * depending on the compression codec, the payload is the actual message payload (codes=none)
2065 * or compressed set of messages (otherwise). In the new format (since Kafka 1.0) there
2066 * is no such duality.
2068 if (codec == 0) {
2069 bytes_offset = dissect_kafka_regular_bytes(subtree, hf_kafka_message_value, tvb, pinfo, offset, NULL, &length);
2070 if (bytes_offset > offset) {
2071 offset = bytes_offset;
2072 } else {
2073 expert_add_info(pinfo, message_ti, &ei_kafka_bad_bytes_length);
2074 return offset;
2076 } else {
2077 length = tvb_get_ntohl(tvb, offset);
2078 offset += 4;
2079 if (decompress(tvb, pinfo, offset, length, codec, &decompressed_tvb, &decompressed_offset)==1) {
2080 add_new_data_source(pinfo, decompressed_tvb, "Decompressed content");
2081 show_compression_reduction(tvb, subtree, length, tvb_captured_length(decompressed_tvb));
2082 dissect_kafka_regular_message_set(decompressed_tvb, pinfo, subtree, decompressed_offset,
2083 tvb_reported_length_remaining(decompressed_tvb, decompressed_offset),
2084 codec);
2085 offset += length;
2086 } else {
2087 proto_item_append_text(subtree, " [Cannot decompress records]");
2091 proto_item_set_end(message_ti, tvb, offset);
2093 return offset;
2097 * Function: dissect_kafka_message_new
2098 * ---------------------------------------------------
2099 * Handles decoding of the new message format. In the new format
2100 * there is no difference between compressed and plain batch.
2102 * https://kafka.apache.org/documentation/#messageformat
2104 * tvb: actual data buffer
2105 * pinfo: packet information
2106 * tree: protocol information tree to append the item
2107 * hf_item: protocol information item descriptor index
2108 * offset: pointer to the message
2109 * end_offset: last possible offset in this batch
2111 * returns: pointer to the next message/batch
2113 static int
2114 // NOLINTNEXTLINE(misc-no-recursion)
2115 dissect_kafka_message_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int end_offset _U_)
2117 proto_item *batch_ti;
2118 proto_tree *subtree;
2119 int start_offset = offset;
2120 int8_t magic_byte;
2121 uint16_t codec;
2122 uint32_t message_size;
2123 uint32_t count, i, length;
2124 uint64_t base_offset, first_timestamp;
2126 tvbuff_t *decompressed_tvb;
2127 int decompressed_offset;
2129 message_size = tvb_get_uint32(tvb, start_offset + 8, ENC_BIG_ENDIAN);
2131 subtree = proto_tree_add_subtree(tree, tvb, start_offset, message_size + 12, ett_kafka_batch, &batch_ti, "Record Batch");
2133 offset = dissect_kafka_int64(subtree, hf_kafka_offset, tvb, pinfo, offset, &base_offset);
2135 offset = dissect_kafka_int32(subtree, hf_kafka_message_size, tvb, pinfo, offset, NULL);
2137 offset = dissect_kafka_int32(subtree, hf_kafka_leader_epoch, tvb, pinfo, offset, NULL);
2139 offset = dissect_kafka_int8(subtree, hf_kafka_message_magic, tvb, pinfo, offset, &magic_byte);
2141 if (magic_byte != 2) {
2142 proto_item_append_text(subtree, "[Unknown message magic]");
2143 expert_add_info_format(pinfo, batch_ti, &ei_kafka_unknown_message_magic,
2144 "message magic: %d", magic_byte);
2145 return start_offset + 8 /*base offset*/ + 4 /*message size*/ + message_size;
2148 offset = dissect_kafka_int32(subtree, hf_kafka_batch_crc, tvb, pinfo, offset, NULL);
2150 dissect_kafka_int16(subtree, hf_kafka_batch_codec, tvb, pinfo, offset, &codec);
2151 codec &= KAFKA_MESSAGE_CODEC_MASK;
2152 dissect_kafka_int16(subtree, hf_kafka_batch_timestamp_type, tvb, pinfo, offset, NULL);
2153 dissect_kafka_int16(subtree, hf_kafka_batch_transactional, tvb, pinfo, offset, NULL);
2154 dissect_kafka_int16(subtree, hf_kafka_batch_control_batch, tvb, pinfo, offset, NULL);
2155 // next octet is reserved
2156 offset += 2;
2158 offset = dissect_kafka_int32(subtree, hf_kafka_batch_last_offset_delta, tvb, pinfo, offset, NULL);
2160 offset = dissect_kafka_int64(subtree, hf_kafka_batch_first_timestamp, tvb, pinfo, offset, &first_timestamp);
2161 offset = dissect_kafka_int64(subtree, hf_kafka_batch_last_timestamp, tvb, pinfo, offset, NULL);
2163 offset = dissect_kafka_int64(subtree, hf_kafka_producer_id, tvb, pinfo, offset, NULL);
2164 offset = dissect_kafka_int16(subtree, hf_kafka_producer_epoch, tvb, pinfo, offset, NULL);
2166 offset = dissect_kafka_int32(subtree, hf_kafka_batch_base_sequence, tvb, pinfo, offset, NULL);
2168 offset = dissect_kafka_int32(subtree, hf_kafka_batch_size, tvb, pinfo, offset, &count);
2170 length = start_offset + 8 /*base offset*/ + 4 /*message size*/ + message_size - offset;
2172 if (decompress(tvb, pinfo, offset, length, codec, &decompressed_tvb, &decompressed_offset)==1) {
2173 if (codec != 0) {
2174 add_new_data_source(pinfo, decompressed_tvb, "Decompressed Records");
2175 show_compression_reduction(tvb, subtree, length, tvb_captured_length(decompressed_tvb));
2177 for (i=0;i<count;i++) {
2178 decompressed_offset = dissect_kafka_record(decompressed_tvb, pinfo, subtree, decompressed_offset, base_offset, first_timestamp);
2180 } else {
2181 proto_item_append_text(subtree, " [Cannot decompress records]");
2184 return start_offset + 8 /*base offset*/ + 4 /*message size*/ + message_size;
2187 static int
2188 // NOLINTNEXTLINE(misc-no-recursion)
2189 dissect_kafka_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int end_offset)
2191 int8_t magic_byte;
2192 uint32_t message_size;
2194 if (offset + 12 > end_offset) {
2195 // in this case we deal with truncated message, where the size part may be also truncated
2196 // actually we may add truncated info
2197 proto_tree_add_item(tree, hf_kafka_truncated_content, tvb, offset, end_offset-offset, ENC_NA);
2198 return end_offset;
2200 message_size = tvb_get_uint32(tvb, offset + 8, ENC_BIG_ENDIAN);
2201 if (offset + 12 + message_size > (uint32_t)end_offset) {
2202 // in this case we deal with truncated message, where the truncation point falls somewhere
2203 // in the message body
2204 proto_tree_add_item(tree, hf_kafka_truncated_content, tvb, offset, end_offset-offset, ENC_NA);
2205 return end_offset;
2208 magic_byte = tvb_get_uint8(tvb, offset + 16);
2209 int message_offset = 0;
2210 increment_dissection_depth(pinfo);
2211 if (magic_byte < 2) {
2212 message_offset = dissect_kafka_message_old(tvb, pinfo, tree, offset, end_offset);
2213 } else {
2214 message_offset = dissect_kafka_message_new(tvb, pinfo, tree, offset, end_offset);
2216 decrement_dissection_depth(pinfo);
2217 return message_offset;
2220 static int
2221 // NOLINTNEXTLINE(misc-no-recursion)
2222 dissect_kafka_regular_message_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, unsigned len, uint8_t codec)
2224 proto_item *ti;
2225 proto_tree *subtree;
2226 int end_offset = offset + len;
2228 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_message_set, &ti, "Message Set");
2229 /* If set came from a compressed message, make it obvious in tree root */
2230 if (codec != KAFKA_MESSAGE_CODEC_NONE) {
2231 proto_item_append_text(subtree, " [from compressed %s message]", val_to_str_const(codec, kafka_message_codecs, "Unknown"));
2234 while (offset < end_offset) {
2235 offset = dissect_kafka_message(tvb, pinfo, subtree, offset, end_offset);
2238 if (offset != end_offset) {
2239 expert_add_info(pinfo, ti, &ei_kafka_bad_message_set_length);
2242 proto_item_set_end(ti, tvb, offset);
2244 return offset;
2247 static int
2248 dissect_kafka_message_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, unsigned flexible, uint8_t codec)
2250 unsigned len;
2251 uint64_t length;
2252 proto_item *subti;
2254 if (flexible) {
2255 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &length, ENC_VARINT_PROTOBUF);
2257 if (len == 0) {
2258 // this message set is malformed
2259 proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_message_set, &subti, "Message Set");
2260 expert_add_info(pinfo, subti, &ei_kafka_bad_varint);
2261 proto_item_set_end(subti, tvb, offset);
2262 return tvb_captured_length(tvb);
2265 offset = offset + len;
2267 if (length > 0) {
2268 offset = dissect_kafka_regular_message_set(tvb, pinfo, tree, offset, (int)length - 1, codec);
2271 else {
2272 len = tvb_get_ntohl(tvb, offset);
2273 offset += 4;
2275 if (len > 0) {
2276 offset = dissect_kafka_regular_message_set(tvb, pinfo, tree, offset, len, codec);
2280 return offset;
2283 /* Tagged fields support (since Kafka 2.4) */
2286 * Other that in dissect_kafka_compacted_bytes the length is given as unsigned varint.
2288 static int
2289 dissect_kafka_tagged_field_data(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info *pinfo, int offset,
2290 int *p_offset, int *p_len)
2292 proto_item *pi;
2294 uint64_t length;
2295 int32_t len;
2297 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &length, ENC_VARINT_PROTOBUF);
2298 if (len == 0) length = 0;
2300 pi = proto_tree_add_item(tree, hf_item, tvb, offset+len, (int)length, ENC_NA);
2301 if (len == 0) {
2302 expert_add_info(pinfo, pi, &ei_kafka_bad_varint);
2303 if (p_offset) {
2304 *p_offset = 0;
2306 if (p_len) {
2307 *p_len = 0;
2309 return tvb_captured_length(tvb);
2312 offset = offset + len + (int)length;
2313 if (p_offset != NULL) *p_offset = offset + len;
2314 if (p_len != NULL) *p_len = (int)length;
2316 return offset;
2319 static int
2320 dissect_kafka_tagged_field(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2321 kafka_api_version_t api_version _U_)
2323 proto_item *subti;
2324 proto_tree *subtree;
2326 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
2327 ett_kafka_tagged_field,
2328 &subti, "Field");
2330 offset = dissect_kafka_varuint(subtree, hf_kafka_tagged_field_tag, tvb, pinfo, offset, NULL);
2332 offset = dissect_kafka_tagged_field_data(subtree, hf_kafka_tagged_field_data, tvb, pinfo, offset, NULL, NULL);
2334 proto_item_set_end(subti, tvb, offset);
2336 return offset;
2340 static int
2341 dissect_kafka_tagged_fields(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2342 kafka_api_version_t api_version _U_)
2344 int64_t count;
2345 unsigned len;
2346 proto_item *subti;
2347 proto_tree *subtree;
2349 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
2350 ett_kafka_tagged_fields,
2351 &subti, "Tagged fields");
2353 len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &count, ENC_VARINT_PROTOBUF);
2354 if (len == 0) {
2355 expert_add_info(pinfo, subtree, &ei_kafka_bad_varint);
2356 return tvb_captured_length(tvb);
2358 offset += len;
2361 * Contrary to compact arrays, tagged fields store just count
2362 * https://cwiki.apache.org/confluence/display/KAFKA/KIP-482%3A+The+Kafka+Protocol+should+Support+Optional+Tagged+Fields
2364 offset = dissect_kafka_array_elements(subtree, tvb, pinfo, offset, api_version, &dissect_kafka_tagged_field, (int32_t)count);
2366 proto_item_set_end(subti, tvb, offset);
2368 return offset;
2371 /* OFFSET FETCH REQUEST/RESPONSE */
2373 static int
2374 dissect_kafka_partition_id_ret(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
2375 kafka_partition_t *p_partition)
2377 proto_tree_add_item(tree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2378 if (p_partition != NULL) {
2379 *p_partition = tvb_get_ntohl(tvb, offset);
2381 offset += 4;
2383 return offset;
2386 static int
2387 dissect_kafka_partition_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2388 kafka_api_version_t api_version _U_)
2390 return dissect_kafka_partition_id_ret(tvb, pinfo, tree, offset, NULL);
2393 static int
2394 dissect_kafka_offset_ret(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
2395 kafka_offset_t *p_offset)
2397 proto_tree_add_item(tree, hf_kafka_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
2398 if (p_offset != NULL) {
2399 *p_offset = tvb_get_ntoh64(tvb, offset);
2401 offset += 8;
2403 return offset;
2406 static int
2407 dissect_kafka_offset(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2408 kafka_api_version_t api_version _U_)
2410 return dissect_kafka_offset_ret(tvb, pinfo, tree, offset, NULL);
2413 static int
2414 dissect_kafka_leader_epoch(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
2415 kafka_api_version_t api_version _U_)
2417 proto_tree_add_item(tree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
2418 offset += 4;
2420 return offset;
2423 static int
2424 dissect_kafka_offset_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
2425 kafka_api_version_t api_version _U_)
2427 proto_item *ti;
2428 int64_t message_offset_time;
2430 message_offset_time = tvb_get_ntoh64(tvb, offset);
2432 ti = proto_tree_add_item(tree, hf_kafka_offset_time, tvb, offset, 8, ENC_BIG_ENDIAN);
2433 offset += 8;
2435 // The query for offset at given time takes the time in milliseconds since epoch.
2436 // It has two additional special values:
2437 // * -1 - the latest offset (to consume new messages only)
2438 // * -2 - the oldest offset (to consume all available messages)
2439 if (message_offset_time == -1) {
2440 proto_item_append_text(ti, " (latest)");
2441 } else if (message_offset_time == -2) {
2442 proto_item_append_text(ti, " (earliest)");
2445 return offset;
2448 static int
2449 dissect_kafka_offset_fetch_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2450 kafka_api_version_t api_version)
2452 proto_tree *subtree, *subsubtree;
2453 proto_item *subti, *subsubti;
2454 int32_t count = 0;
2455 int topic_start, topic_len;
2457 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
2459 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 6, &topic_start, &topic_len);
2461 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_topic, &subsubti, "Partition IDs");
2462 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 6, api_version, &dissect_kafka_partition_id, &count);
2463 proto_item_set_end(subsubti, tvb, offset);
2465 if (api_version >= 6) {
2466 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2469 proto_item_set_end(subti, tvb, offset);
2470 proto_item_append_text(subti, " (Topic: %s, Partitions: %u)",
2471 tvb_get_string_enc(pinfo->pool, tvb, topic_start, topic_len, ENC_UTF_8),
2472 count);
2474 return offset;
2477 static int
2478 dissect_kafka_offset_fetch_request_topics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2479 kafka_api_version_t api_version)
2481 proto_item *ti;
2482 proto_tree *subtree;
2483 int32_t count = 0;
2485 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &ti, "Topics");
2486 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
2487 &dissect_kafka_offset_fetch_request_topic, &count);
2488 proto_item_set_end(ti, tvb, offset);
2490 if (count < 0) {
2491 proto_item_append_text(ti, " (all committed topics)");
2492 } else {
2493 proto_item_append_text(ti, " (%u topics)", count);
2496 return offset;
2499 static int
2500 dissect_kafka_offset_fetch_request_group(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2501 kafka_api_version_t api_version)
2503 proto_item *subti;
2504 proto_tree *subtree;
2506 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_protocols, &subti, "Group");
2508 /* group_id */
2509 if (api_version >= 8) {
2510 offset = dissect_kafka_string(subtree, hf_kafka_group_id, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
2513 /* member_id */
2514 if (api_version >= 9) {
2515 offset = dissect_kafka_string(subtree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
2518 /* member_epoch */
2519 if (api_version >= 9) {
2520 offset = dissect_kafka_int32(subtree, hf_kafka_member_epoch, tvb, pinfo, offset, NULL);
2523 /* [topics] */
2524 if (api_version >= 8) {
2525 offset = dissect_kafka_offset_fetch_request_topics(tvb, pinfo, subtree, offset, api_version);
2528 if (api_version >= 6) {
2529 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2532 proto_item_set_end(subti, tvb, offset);
2534 return offset;
2537 static int
2538 dissect_kafka_offset_fetch_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2539 kafka_api_version_t api_version)
2541 proto_item *subti;
2542 proto_tree *subtree;
2544 /* In versions 0-7, topic information is an array attached to the root message object.
2545 * In version 8, topic information is moved to a groups array attached to the root message object. Topic fields
2546 * haven't changed; topics have just been moved down a level in the object tree. */
2547 if (api_version >= 0 && api_version <= 7) {
2548 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >=6, NULL, NULL);
2550 offset = dissect_kafka_offset_fetch_request_topics(tvb, pinfo, tree, offset, api_version);
2553 if (api_version >= 8) {
2554 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_protocols, &subti, "Groups");
2555 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
2556 &dissect_kafka_offset_fetch_request_group, NULL);
2557 proto_item_set_end(subti, tvb, offset);
2560 if (api_version >= 7) {
2561 proto_tree_add_item(tree, hf_kafka_require_stable_offset, tvb, offset, 1, ENC_NA);
2562 offset += 1;
2565 if (api_version >= 6) {
2566 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
2569 return offset;
2572 static int
2573 dissect_kafka_error_ret(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2574 kafka_error_t *ret)
2576 kafka_error_t error = (kafka_error_t) tvb_get_ntohs(tvb, offset);
2577 proto_tree_add_item(tree, hf_kafka_error, tvb, offset, 2, ENC_BIG_ENDIAN);
2578 offset += 2;
2580 /* Show error in Info column */
2581 if (error != 0) {
2582 col_append_fstr(pinfo->cinfo, COL_INFO,
2583 " [%s] ", kafka_error_to_str(error));
2586 if (ret) {
2587 *ret = error;
2590 return offset;
2593 static int
2594 dissect_kafka_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
2596 return dissect_kafka_error_ret(tvb, pinfo, tree, offset, NULL);
2599 static int
2600 dissect_kafka_throttle_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
2602 proto_tree_add_item(tree, hf_kafka_throttle_time, tvb, offset, 4, ENC_BIG_ENDIAN);
2603 offset += 4;
2604 return offset;
2607 static int
2608 dissect_kafka_offset_fetch_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2609 int start_offset, kafka_api_version_t api_version)
2611 proto_item *ti;
2612 proto_tree *subtree;
2613 int offset = start_offset;
2614 kafka_packet_values_t packet_values;
2615 memset(&packet_values, 0, sizeof(packet_values));
2617 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &ti, "Partition");
2619 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &packet_values.partition_id);
2620 offset = dissect_kafka_offset_ret(tvb, pinfo, subtree, offset, &packet_values.offset);
2622 if (api_version >= 5) {
2623 offset = dissect_kafka_leader_epoch(tvb, pinfo, subtree, offset, api_version);
2626 offset = dissect_kafka_string(subtree, hf_kafka_metadata, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
2628 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
2630 if (packet_values.offset==-1) {
2631 proto_item_append_text(ti, " (ID=%u, Offset=None)",
2632 packet_values.partition_id);
2633 } else {
2634 proto_item_append_text(ti, " (ID=%u, Offset=%" PRIi64 ")",
2635 packet_values.partition_id, packet_values.offset);
2638 if (api_version >= 6) {
2639 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2642 proto_item_set_end(ti, tvb, offset);
2644 return offset;
2647 static int
2648 dissect_kafka_offset_fetch_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2649 kafka_api_version_t api_version)
2651 proto_item *subti, *subsubti;
2652 proto_tree *subtree, *subsubtree;
2653 int topic_start, topic_len;
2654 int count = 0;
2656 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
2658 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 6, &topic_start, &topic_len);
2660 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_topic, &subsubti, "Partition IDs");
2661 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 6, api_version,
2662 &dissect_kafka_offset_fetch_response_partition, &count);
2663 proto_item_set_end(subsubti, tvb, offset);
2665 if (api_version >= 6) {
2666 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2669 proto_item_set_end(subti, tvb, offset);
2670 proto_item_append_text(subti, " (Topic: %s, Partitions: %u)",
2671 tvb_get_string_enc(pinfo->pool, tvb, topic_start, topic_len, ENC_UTF_8),
2672 count);
2674 return offset;
2677 static int
2678 dissect_kafka_offset_fetch_response_group(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2679 kafka_api_version_t api_version)
2681 proto_item *subti, *subsubti;
2682 proto_tree *subtree, *subsubtree;
2684 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &subti, "Group");
2686 /* group_id */
2687 offset = dissect_kafka_string(subtree, hf_kafka_group_id, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
2689 /* [topics] */
2690 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_topics, &subsubti, "Topics");
2691 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 6, api_version,
2692 &dissect_kafka_offset_fetch_response_topic, NULL);
2693 proto_item_set_end(subsubti, tvb, offset);
2695 /* error_code */
2696 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
2698 if (api_version >= 6) {
2699 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2702 proto_item_set_end(subti, tvb, offset);
2704 return offset;
2707 static int
2708 dissect_kafka_offset_fetch_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2709 kafka_api_version_t api_version)
2711 proto_item *subti;
2712 proto_tree *subtree;
2713 int count = 0;
2715 if (api_version >= 3) {
2716 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
2719 /* In versions 0-7, topic information is an array attached to the root message object.
2720 * In version 8, topic information is moved to a groups array attached to the root message object. Topic fields
2721 * haven't changed; topics have just been moved down a level in the object tree. */
2722 if (api_version >= 0 && api_version <= 7) {
2723 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &subti, "Topics");
2724 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
2725 &dissect_kafka_offset_fetch_response_topic, &count);
2726 proto_item_set_end(subti, tvb, offset);
2727 proto_item_append_text(subti, " (%u topics)", count);
2730 if (api_version >= 2 && api_version <= 7) {
2731 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
2734 if (api_version >= 8) {
2735 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_protocols, &subti,
2736 "Groups");
2737 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
2738 &dissect_kafka_offset_fetch_response_group, NULL);
2739 proto_item_set_end(subti, tvb, offset);
2742 if (api_version >= 6) {
2743 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
2746 return offset;
2749 /* METADATA REQUEST/RESPONSE */
2751 static int
2752 dissect_kafka_metadata_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2753 kafka_api_version_t api_version _U_)
2755 proto_item *ti;
2756 proto_tree *subtree;
2758 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &ti, "Topic");
2760 if (api_version >= 10) {
2761 offset = dissect_kafka_uuid(tree, hf_kafka_topic_id, tvb, pinfo, offset);
2764 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 9, NULL, NULL);
2766 if (api_version >= 9) {
2767 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2770 proto_item_set_end(ti, tvb, offset);
2772 return offset;
2775 static int
2776 dissect_kafka_metadata_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2777 kafka_api_version_t api_version)
2779 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 9, api_version,
2780 &dissect_kafka_metadata_request_topic, NULL);
2782 if (api_version >= 4) {
2783 proto_tree_add_item(tree, hf_kafka_allow_auto_topic_creation, tvb, offset, 1, ENC_BIG_ENDIAN);
2784 offset += 1;
2787 if (api_version >= 8 && api_version <= 10) {
2788 proto_tree_add_item(tree, hf_kafka_include_cluster_authorized_ops, tvb, offset, 1, ENC_BIG_ENDIAN);
2789 offset += 1;
2792 if (api_version >= 8) {
2793 proto_tree_add_item(tree, hf_kafka_include_topic_authorized_ops, tvb, offset, 1, ENC_BIG_ENDIAN);
2794 offset += 1;
2797 if (api_version >= 9) {
2798 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
2801 return offset;
2804 static int
2805 dissect_kafka_metadata_broker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2806 kafka_api_version_t api_version)
2808 proto_item *ti;
2809 proto_tree *subtree;
2810 uint32_t nodeid;
2811 int host_start, host_len;
2812 uint32_t broker_port;
2814 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker, &ti, "Broker");
2816 nodeid = tvb_get_ntohl(tvb, offset);
2817 proto_tree_add_item(subtree, hf_kafka_broker_nodeid, tvb, offset, 4, ENC_BIG_ENDIAN);
2818 offset += 4;
2820 offset = dissect_kafka_string(subtree, hf_kafka_broker_host, tvb, pinfo, offset, api_version >= 9, &host_start, &host_len);
2822 broker_port = tvb_get_ntohl(tvb, offset);
2823 proto_tree_add_item(subtree, hf_kafka_broker_port, tvb, offset, 4, ENC_BIG_ENDIAN);
2824 offset += 4;
2826 if (api_version >= 1) {
2827 offset = dissect_kafka_string(subtree, hf_kafka_rack, tvb, pinfo, offset, api_version >= 9, NULL, NULL);
2830 if (api_version >= 9) {
2831 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2834 proto_item_append_text(ti, " (node %u: %s:%u)",
2835 nodeid,
2836 tvb_get_string_enc(pinfo->pool, tvb,
2837 host_start, host_len, ENC_UTF_8),
2838 broker_port);
2839 proto_item_set_end(ti, tvb, offset);
2841 return offset;
2844 static int
2845 dissect_kafka_metadata_replica(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
2846 kafka_api_version_t api_version _U_)
2848 proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
2849 return offset + 4;
2852 static int
2853 dissect_kafka_metadata_isr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
2854 kafka_api_version_t api_version _U_)
2856 proto_tree_add_item(tree, hf_kafka_isr, tvb, offset, 4, ENC_BIG_ENDIAN);
2857 return offset + 4;
2860 static int
2861 dissect_kafka_metadata_offline(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
2862 kafka_api_version_t api_version _U_)
2864 proto_tree_add_item(tree, hf_kafka_offline, tvb, offset, 4, ENC_BIG_ENDIAN);
2865 return offset + 4;
2868 static int
2869 dissect_kafka_metadata_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2870 kafka_api_version_t api_version)
2872 proto_item *ti, *subti;
2873 proto_tree *subtree, *subsubtree;
2874 kafka_partition_t partition;
2876 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &ti, "Partition");
2878 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
2880 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &partition);
2882 proto_tree_add_item(subtree, hf_kafka_leader_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2883 offset += 4;
2885 if (api_version >= 7) {
2886 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
2887 offset += 4;
2890 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_replicas, &subti, "Replicas");
2891 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 9, api_version, &dissect_kafka_metadata_replica, NULL);
2892 proto_item_set_end(subti, tvb, offset);
2894 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_isrs, &subti, "Caught-Up Replicas");
2895 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 9, api_version, &dissect_kafka_metadata_isr, NULL);
2896 proto_item_set_end(subti, tvb, offset);
2898 if (api_version >= 5) {
2899 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_offline, &subti, "Offline Replicas");
2900 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 9, api_version, &dissect_kafka_metadata_offline, NULL);
2901 proto_item_set_end(subti, tvb, offset);
2904 if (api_version >= 9) {
2905 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2908 proto_item_set_end(ti, tvb, offset);
2909 proto_item_append_text(ti, " (ID=%u)", partition);
2911 return offset;
2914 static int
2915 dissect_kafka_metadata_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2916 kafka_api_version_t api_version)
2918 proto_item *ti;
2919 proto_tree *subtree;
2920 int name_start, name_length;
2922 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &ti, "Topic");
2924 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
2926 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 9, &name_start, &name_length);
2928 proto_item_append_text(ti, " (%s)",
2929 tvb_get_string_enc(pinfo->pool, tvb,
2930 name_start, name_length, ENC_UTF_8));
2932 if (api_version >= 10) {
2933 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
2936 if (api_version >= 1) {
2937 proto_tree_add_item(subtree, hf_kafka_is_internal, tvb, offset, 1, ENC_NA);
2938 offset += 1;
2941 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 9, api_version, &dissect_kafka_metadata_partition, NULL);
2943 if (api_version >= 8) {
2944 proto_tree_add_item(subtree, hf_kafka_topic_authorized_ops, tvb, offset, 4, ENC_BIG_ENDIAN);
2945 offset += 4;
2948 if (api_version >= 9) {
2949 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
2952 proto_item_set_end(ti, tvb, offset);
2954 return offset;
2957 static int
2958 dissect_kafka_metadata_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2959 kafka_api_version_t api_version)
2961 proto_item *ti;
2962 proto_tree *subtree;
2964 if (api_version >= 3) {
2965 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
2968 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_brokers, &ti, "Broker Metadata");
2969 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 9, api_version, &dissect_kafka_metadata_broker, NULL);
2970 proto_item_set_end(ti, tvb, offset);
2972 if (api_version >= 2) {
2973 offset = dissect_kafka_string(tree, hf_kafka_cluster_id, tvb, pinfo, offset, api_version >= 9, NULL, NULL);
2976 if (api_version >= 1) {
2977 offset = dissect_kafka_int32(tree, hf_kafka_controller_id, tvb, pinfo, offset, NULL);
2980 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &ti, "Topic Metadata");
2981 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 9, api_version, &dissect_kafka_metadata_topic, NULL);
2982 proto_item_set_end(ti, tvb, offset);
2984 if (api_version >= 8 && api_version <= 10) {
2985 offset = dissect_kafka_int32(tree, hf_kafka_cluster_authorized_ops, tvb, pinfo, offset, NULL);
2988 if (api_version >= 9) {
2989 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
2992 return offset;
2995 /* LEADER_AND_ISR REQUEST/RESPONSE */
2997 static int
2998 dissect_kafka_leader_and_isr_request_isr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
2999 int offset, kafka_api_version_t api_version _U_)
3001 /* isr */
3002 proto_tree_add_item(tree, hf_kafka_isr, tvb, offset, 4, ENC_BIG_ENDIAN);
3003 offset += 4;
3005 return offset;
3008 static int
3009 dissect_kafka_leader_and_isr_request_replica(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3010 int offset, kafka_api_version_t api_version _U_)
3012 /* replica */
3013 proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
3014 offset += 4;
3016 return offset;
3020 static int
3021 dissect_kafka_leader_and_isr_request_partition_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3022 int offset, kafka_api_version_t api_version)
3024 proto_tree *subtree, *subsubtree;
3025 proto_item *subti, *subsubti;
3026 int topic_start, topic_len;
3027 kafka_partition_t partition;
3029 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3030 ett_kafka_partition,
3031 &subti, "Partition");
3033 /* topic */
3034 if (api_version < 2) {
3035 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0,
3036 &topic_start, &topic_len);
3039 /* partition */
3040 partition = (kafka_partition_t) tvb_get_ntohl(tvb, offset);
3041 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3042 offset += 4;
3044 /* controller_epoch */
3045 proto_tree_add_item(subtree, hf_kafka_controller_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
3046 offset += 4;
3048 /* leader */
3049 proto_tree_add_item(subtree, hf_kafka_leader_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3050 offset += 4;
3052 /* leader_epoch */
3053 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
3054 offset += 4;
3056 /* [isr] */
3057 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
3058 ett_kafka_isrs,
3059 &subsubti, "ISRs");
3060 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 4, api_version,
3061 &dissect_kafka_leader_and_isr_request_isr, NULL);
3062 proto_item_set_end(subsubti, tvb, offset);
3064 /* zk_version */
3065 proto_tree_add_item(subtree, hf_kafka_zk_version, tvb, offset, 4, ENC_BIG_ENDIAN);
3066 offset += 4;
3068 /* [replica] */
3069 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
3070 ett_kafka_replicas,
3071 &subsubti, "Current Replicas");
3072 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 4, api_version,
3073 &dissect_kafka_leader_and_isr_request_replica, NULL);
3074 proto_item_set_end(subsubti, tvb, offset);
3076 if (api_version >= 3) {
3077 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
3078 ett_kafka_replicas,
3079 &subsubti, "Adding Replicas");
3080 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 4, api_version,
3081 &dissect_kafka_leader_and_isr_request_replica, NULL);
3082 proto_item_set_end(subsubti, tvb, offset);
3085 if (api_version >= 3) {
3086 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
3087 ett_kafka_replicas,
3088 &subsubti, "Removing Replicas");
3089 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 4, api_version,
3090 &dissect_kafka_leader_and_isr_request_replica, NULL);
3091 proto_item_set_end(subsubti, tvb, offset);
3094 if (api_version >= 1) {
3095 proto_tree_add_item(subtree, hf_kafka_is_new_replica, tvb, offset, 1, ENC_BIG_ENDIAN);
3096 offset += 1;
3099 if (api_version >= 6) {
3100 offset = dissect_kafka_int8(subtree, hf_kafka_leader_recovery_state, tvb, pinfo, offset, NULL);
3103 if (api_version >= 4) {
3104 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3107 proto_item_set_end(subti, tvb, offset);
3109 if (api_version < 2) {
3110 proto_item_append_text(subti, " (Topic=%s, Partition-ID=%u)",
3111 tvb_get_string_enc(pinfo->pool, tvb,
3112 topic_start, topic_len, ENC_UTF_8),
3113 partition);
3114 } else {
3115 proto_item_append_text(subti, " (Partition-ID=%u)",
3116 partition);
3119 return offset;
3122 static int
3123 dissect_kafka_leader_and_isr_request_topic_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3124 int offset, kafka_api_version_t api_version)
3126 proto_tree *subtree;
3127 proto_item *subti;
3128 int topic_start, topic_len;
3130 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3131 ett_kafka_topic,
3132 &subti, "Topic");
3134 /* topic */
3135 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 4,
3136 &topic_start, &topic_len);
3138 /* topic_id */
3139 if (api_version >= 5) {
3140 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
3143 /* [partition_state] */
3144 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
3145 &dissect_kafka_leader_and_isr_request_partition_state, NULL);
3147 if (api_version >= 4) {
3148 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3151 proto_item_append_text(subti, " (Name=%s)",
3152 tvb_get_string_enc(pinfo->pool, tvb,
3153 topic_start, topic_len, ENC_UTF_8));
3155 return offset;
3158 static int
3159 dissect_kafka_leader_and_isr_request_live_leader(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3160 int offset, kafka_api_version_t api_version _U_)
3162 proto_item *subti;
3163 proto_tree *subtree;
3164 int32_t nodeid;
3165 int host_start, host_len;
3166 int32_t broker_port;
3168 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker, &subti, "Live Leader");
3170 /* id */
3171 nodeid = tvb_get_ntohl(tvb, offset);
3172 proto_tree_add_item(subtree, hf_kafka_broker_nodeid, tvb, offset, 4, ENC_BIG_ENDIAN);
3173 offset += 4;
3175 /* host */
3176 offset = dissect_kafka_string(subtree, hf_kafka_broker_host, tvb, pinfo, offset,api_version >= 4, &host_start, &host_len);
3178 /* port */
3179 broker_port = tvb_get_ntohl(tvb, offset);
3180 proto_tree_add_item(subtree, hf_kafka_broker_port, tvb, offset, 4, ENC_BIG_ENDIAN);
3181 offset += 4;
3183 if (api_version >= 4) {
3184 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3187 proto_item_set_end(subti, tvb, offset);
3188 proto_item_append_text(subti, " (node %u: %s:%u)",
3189 nodeid,
3190 tvb_get_string_enc(pinfo->pool, tvb, host_start, host_len, ENC_UTF_8),
3191 broker_port);
3193 return offset;
3196 static int
3197 dissect_kafka_leader_and_isr_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3198 kafka_api_version_t api_version)
3200 int32_t controller_id;
3202 /* controller_id */
3203 controller_id = (int32_t) tvb_get_ntohl(tvb, offset);
3204 proto_tree_add_item(tree, hf_kafka_controller_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3205 offset += 4;
3207 /* is_kraft_controller */
3208 if (api_version >= 7) {
3209 offset = dissect_kafka_bool(tree, hf_kafka_is_kraft_controller, tvb, pinfo, offset);
3212 /* controller_epoch */
3213 proto_tree_add_item(tree, hf_kafka_controller_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
3214 offset += 4;
3216 if (api_version >= 2) {
3217 /* broker_epoch */
3218 proto_tree_add_item(tree, hf_kafka_broker_epoch, tvb, offset, 8, ENC_BIG_ENDIAN);
3219 offset += 8;
3222 /* type */
3223 if (api_version >= 5) {
3224 offset = dissect_kafka_int8(tree, hf_kafka_topic_inclusion_type, tvb, pinfo, offset, NULL);
3227 if (api_version <= 1) {
3228 /* [partition_state] */
3229 offset = dissect_kafka_array(tree, tvb, pinfo, offset, 0, api_version,
3230 &dissect_kafka_leader_and_isr_request_partition_state, NULL);
3231 } else {
3232 /* [topic_state] */
3233 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 4, api_version,
3234 &dissect_kafka_leader_and_isr_request_topic_state, NULL);
3237 /* [live_leader] */
3238 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 4, api_version,
3239 &dissect_kafka_leader_and_isr_request_live_leader, NULL);
3241 if (api_version >= 4) {
3242 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
3245 col_append_fstr(pinfo->cinfo, COL_INFO, " (Controller-ID=%d)", controller_id);
3247 return offset;
3250 static int
3251 dissect_kafka_leader_and_isr_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3252 int offset, kafka_api_version_t api_version _U_)
3254 proto_item *subti;
3255 proto_tree *subtree;
3256 int topic_start, topic_len;
3257 kafka_partition_t partition;
3258 kafka_error_t error;
3260 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3261 ett_kafka_partition,
3262 &subti, "Partition");
3264 /* topic */
3265 if (api_version >= 0 && api_version <= 4) {
3266 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 4, &topic_start, &topic_len);
3269 /* partition */
3270 partition = (int32_t) tvb_get_ntohl(tvb, offset);
3271 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3272 offset += 4;
3274 /* error_code */
3275 offset = dissect_kafka_error_ret(tvb, pinfo, subtree, offset, &error);
3277 if (api_version >= 4) {
3278 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3281 proto_item_set_end(subti, tvb, offset);
3283 if (api_version >= 0 && api_version <= 4) {
3284 proto_item_append_text(subti, " (Topic=%s, Partition-ID=%u, Error=%s)",
3285 tvb_get_string_enc(pinfo->pool, tvb,
3286 topic_start, topic_len, ENC_UTF_8),
3287 partition,
3288 kafka_error_to_str(error));
3291 return offset;
3294 static int
3295 dissect_kafka_leader_and_isr_response_topic_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3296 int offset, kafka_api_version_t api_version)
3298 proto_tree *subtree;
3299 proto_item *subti;
3301 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3302 ett_kafka_topic,
3303 &subti, "Topic");
3305 /* topic_id */
3306 if (api_version >= 5) {
3307 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
3310 /* [partition_state] */
3311 if (api_version >= 5) {
3312 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
3313 &dissect_kafka_leader_and_isr_response_partition, NULL);
3316 if (api_version >= 4) {
3317 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3320 proto_item_set_end(subti, tvb, offset);
3322 return offset;
3325 static int
3326 dissect_kafka_leader_and_isr_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3327 kafka_api_version_t api_version)
3329 /* error_code */
3330 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
3332 /* [partition] */
3333 if (api_version >= 0 && api_version <= 4) {
3334 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 4, api_version,
3335 &dissect_kafka_leader_and_isr_response_partition, NULL);
3337 /* [topic] */
3338 else {
3339 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 4, api_version,
3340 &dissect_kafka_leader_and_isr_response_topic_state, NULL);
3343 if (api_version >= 4) {
3344 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
3347 return offset;
3350 /* STOP_REPLICA REQUEST/RESPONSE */
3352 static int
3353 dissect_kafka_stop_replicate_request_partition_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3354 int offset, kafka_api_version_t api_version)
3356 if (api_version >= 3) {
3357 /* partition_id */
3358 offset = dissect_kafka_int32(tree, hf_kafka_partition_id, tvb, pinfo, offset, NULL);
3360 /* leader_epoch */
3361 offset = dissect_kafka_int32(tree, hf_kafka_leader_epoch, tvb, pinfo, offset, NULL);
3363 /* delete_partition */
3364 offset = dissect_kafka_bool(tree, hf_kafka_delete_partition, tvb, pinfo, offset);
3367 return offset;
3370 static int
3371 dissect_kafka_stop_replica_request_topic_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3372 int offset, kafka_api_version_t api_version)
3374 proto_item *subti, *subsubti;
3375 proto_tree *subtree, *subsubtree;
3376 int topic_start, topic_len;
3378 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3379 ett_kafka_topic,
3380 &subti, "Topic");
3382 if (api_version >= 3) {
3383 /* topic */
3384 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 2, &topic_start, &topic_len);
3386 /* [partition_states] */
3387 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
3388 ett_kafka_partitions,
3389 &subsubti, "Partitions");
3390 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
3391 &dissect_kafka_stop_replicate_request_partition_state, NULL);
3393 if (api_version >= 2) {
3394 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3397 proto_item_set_end(subsubti, tvb, offset);
3400 proto_item_set_end(subti, tvb, offset);
3402 if (api_version >= 3) {
3403 proto_item_append_text(subti, " (Topic=%s)",
3404 tvb_get_string_enc(pinfo->pool, tvb,
3405 topic_start, topic_len, ENC_UTF_8));
3408 return offset;
3411 static int
3412 dissect_kafka_stop_replica_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3413 int offset, kafka_api_version_t api_version)
3415 proto_item *subti, *subsubti;
3416 proto_tree *subtree, *subsubtree;
3417 int topic_start, topic_len;
3419 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3420 ett_kafka_topic,
3421 &subti, "Topic");
3423 if (api_version >= 1 && api_version <= 2) {
3424 /* topic */
3425 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 2, &topic_start, &topic_len);
3427 /* [partitions] */
3428 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
3429 ett_kafka_partitions,
3430 &subsubti, "Partitions");
3431 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
3432 &dissect_kafka_partition_id, NULL);
3433 proto_item_set_end(subsubti, tvb, offset);
3436 if (api_version >= 2) {
3437 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3440 proto_item_set_end(subti, tvb, offset);
3442 if (api_version >= 1 && api_version <= 2) {
3443 proto_item_append_text(subti, " (Topic=%s)",
3444 tvb_get_string_enc(pinfo->pool, tvb,
3445 topic_start, topic_len, ENC_UTF_8));
3448 return offset;
3451 static int
3452 dissect_kafka_stop_replica_request_ungrouped_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3453 int offset, kafka_api_version_t api_version _U_)
3455 proto_item *subti;
3456 proto_tree *subtree;
3457 int topic_start, topic_len;
3458 kafka_partition_t partition;
3460 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3461 ett_kafka_topic,
3462 &subti, "Partition");
3464 /* topic */
3465 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
3467 /* partition */
3468 partition = (int32_t) tvb_get_ntohl(tvb, offset);
3469 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3470 offset += 4;
3472 proto_item_set_end(subti, tvb, offset);
3473 proto_item_append_text(subti, " (Topic=%s, Partition-ID=%u)",
3474 tvb_get_string_enc(pinfo->pool, tvb,
3475 topic_start, topic_len, ENC_UTF_8),
3476 partition);
3478 return offset;
3481 static int
3482 dissect_kafka_stop_replica_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3483 kafka_api_version_t api_version)
3485 proto_item *subti;
3486 proto_tree *subtree;
3487 int32_t controller_id;
3489 /* controller_id */
3490 controller_id = (int32_t) tvb_get_ntohl(tvb, offset);
3491 proto_tree_add_item(tree, hf_kafka_controller_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3492 offset += 4;
3494 /* is_kraft_controller */
3495 if (api_version >= 4) {
3496 offset = dissect_kafka_bool(tree, hf_kafka_is_kraft_controller, tvb, pinfo, offset);
3499 /* controller_epoch */
3500 proto_tree_add_item(tree, hf_kafka_controller_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
3501 offset += 4;
3503 /* broker_epoch */
3504 if (api_version >= 1) {
3505 proto_tree_add_item(tree, hf_kafka_broker_epoch, tvb, offset, 8, ENC_BIG_ENDIAN);
3506 offset += 8;
3509 /* delete_partitions */
3510 if (api_version >= 0 && api_version <= 2) {
3511 proto_tree_add_item(tree, hf_kafka_delete_partitions, tvb, offset, 1, ENC_BIG_ENDIAN);
3512 offset += 1;
3515 /* in V1 list of topic/partition was changed to list of topics with their partitions */
3516 /* in V3 this was changed again to list of topics with partition states */
3517 if (api_version == 0) {
3518 /* [ungrouped_partitions] */
3519 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3520 ett_kafka_partitions,
3521 &subti, "Ungrouped Partitions");
3522 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
3523 &dissect_kafka_stop_replica_request_ungrouped_partition, NULL);
3524 proto_item_set_end(subti, tvb, offset);
3525 } else if (api_version >= 1 && api_version <= 2) {
3526 /* [topics] */
3527 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3528 ett_kafka_topics,
3529 &subti, "Topics");
3530 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
3531 &dissect_kafka_stop_replica_request_topic, NULL);
3532 proto_item_set_end(subti, tvb, offset);
3533 } else {
3534 /* [topics] */
3535 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3536 ett_kafka_topics,
3537 &subti, "Topics");
3538 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
3539 &dissect_kafka_stop_replica_request_topic_state, NULL);
3541 if (api_version >= 2) {
3542 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3545 proto_item_set_end(subti, tvb, offset);
3548 if (api_version >= 2) {
3549 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
3552 col_append_fstr(pinfo->cinfo, COL_INFO, " (Controller-ID=%d)", controller_id);
3554 return offset;
3557 static int
3558 dissect_kafka_stop_replica_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3559 int offset, kafka_api_version_t api_version)
3561 proto_item *subti;
3562 proto_tree *subtree;
3563 int topic_start, topic_len;
3564 kafka_error_t error;
3565 kafka_partition_t partition;
3567 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
3568 ett_kafka_partition,
3569 &subti, "Partition");
3571 /* topic */
3572 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 2, &topic_start, &topic_len);
3574 /* partition */
3575 partition = (int32_t) tvb_get_ntohl(tvb, offset);
3576 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3577 offset += 4;
3579 /* error_code */
3580 offset = dissect_kafka_error_ret(tvb, pinfo, subtree, offset, &error);
3582 if (api_version >= 2) {
3583 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3586 proto_item_set_end(subti, tvb, offset);
3587 proto_item_append_text(subti, " (Topic=%s, Partition-ID=%u, Error=%s)",
3588 tvb_get_string_enc(pinfo->pool, tvb,
3589 topic_start, topic_len, ENC_UTF_8),
3590 partition,
3591 kafka_error_to_str(error));
3593 return offset;
3596 static int
3597 dissect_kafka_stop_replica_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3598 kafka_api_version_t api_version)
3600 /* error_code */
3601 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
3603 /* [partition] */
3604 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 2, api_version,
3605 &dissect_kafka_stop_replica_response_partition, NULL);
3607 if (api_version >= 2) {
3608 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
3611 return offset;
3614 /* FETCH REQUEST/RESPONSE */
3616 static int
3617 dissect_kafka_fetch_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3618 kafka_api_version_t api_version)
3620 proto_item *ti;
3621 proto_tree *subtree;
3622 kafka_packet_values_t packet_values;
3623 memset(&packet_values, 0, sizeof(packet_values));
3625 subtree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_kafka_partition, &ti, "Partition");
3627 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &packet_values.partition_id);
3629 if (api_version >= 9) {
3630 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
3631 offset += 4;
3634 offset = dissect_kafka_offset_ret(tvb, pinfo, subtree, offset, &packet_values.offset);
3636 if (api_version >= 12) {
3637 offset = dissect_kafka_int32(subtree, hf_kafka_last_fetched_epoch, tvb, pinfo, offset, NULL);
3640 if (api_version >= 5) {
3641 proto_tree_add_item(subtree, hf_kafka_log_start_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
3642 offset += 8;
3645 proto_tree_add_item(subtree, hf_kafka_max_bytes, tvb, offset, 4, ENC_BIG_ENDIAN);
3646 offset += 4;
3648 if (api_version >= 12) {
3649 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3652 proto_item_append_text(ti, " (ID=%u, Offset=%" PRIi64 ")",
3653 packet_values.partition_id, packet_values.offset);
3655 return offset;
3658 static int
3659 dissect_kafka_fetch_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3660 kafka_api_version_t api_version)
3662 proto_item *subti, *subsubti;
3663 proto_tree *subtree, *subsubtree;
3664 uint32_t count = 0;
3665 int name_start, name_length;
3667 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
3669 if (api_version >= 0 && api_version <= 12) {
3670 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 12, &name_start, &name_length);
3673 if (api_version >= 13) {
3674 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
3677 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_topic, &subsubti, "Partitions");
3678 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 12, api_version,
3679 &dissect_kafka_fetch_request_partition, &count);
3680 proto_item_set_end(subsubti, tvb, offset);
3682 if (api_version >= 12) {
3683 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3686 proto_item_set_end(subti, tvb, offset);
3687 proto_item_append_text(subti, " (%u partitions)", count);
3689 return offset;
3692 static int
3693 dissect_kafka_fetch_request_forgottent_topic_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
3694 kafka_api_version_t api_version _U_)
3696 proto_tree_add_item(tree, hf_kafka_forgotten_topic_partition, tvb, offset, 4, ENC_BIG_ENDIAN);
3697 offset += 4;
3698 return offset;
3701 static int
3702 dissect_kafka_fetch_request_forgotten_topics_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3703 kafka_api_version_t api_version)
3705 proto_item *ti;
3706 proto_tree *subtree;
3707 uint32_t count = 0;
3708 int name_start, name_length;
3710 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_request_forgotten_topic, &ti, "Fetch Request Forgotten Topic Data");
3712 if (api_version >= 0 && api_version <= 12) {
3713 offset = dissect_kafka_string(subtree, hf_kafka_forgotten_topic_name, tvb, pinfo, offset,
3714 api_version >= 12, &name_start, &name_length);
3717 if (api_version >= 13) {
3718 offset = dissect_kafka_uuid(subtree, hf_kafka_forgotten_topic_id, tvb, pinfo, offset);
3721 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 12, api_version,
3722 &dissect_kafka_fetch_request_forgottent_topic_partition, &count);
3724 if (api_version >= 12) {
3725 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3728 proto_item_set_end(ti, tvb, offset);
3729 proto_item_append_text(ti, " (%u partitions)", count);
3731 return offset;
3734 static int
3735 dissect_kafka_fetch_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3736 kafka_api_version_t api_version)
3738 proto_item *subti;
3739 proto_tree *subtree;
3741 if (api_version >= 0 && api_version <= 14) {
3742 proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
3743 offset += 4;
3746 proto_tree_add_item(tree, hf_kafka_max_wait_time, tvb, offset, 4, ENC_BIG_ENDIAN);
3747 offset += 4;
3749 proto_tree_add_item(tree, hf_kafka_min_bytes, tvb, offset, 4, ENC_BIG_ENDIAN);
3750 offset += 4;
3752 if (api_version >= 3) {
3753 proto_tree_add_item(tree, hf_kafka_max_bytes, tvb, offset, 4, ENC_BIG_ENDIAN);
3754 offset += 4;
3757 if (api_version >= 4) {
3758 proto_tree_add_item(tree, hf_kafka_isolation_level, tvb, offset, 1, ENC_BIG_ENDIAN);
3759 offset += 1;
3762 if (api_version >= 7) {
3763 proto_tree_add_item(tree, hf_kafka_fetch_session_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3764 offset += 4;
3766 proto_tree_add_item(tree, hf_kafka_fetch_session_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
3767 offset += 4;
3770 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_request_forgotten_topic, &subti, "Topics");
3771 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 12, api_version, &dissect_kafka_fetch_request_topic, NULL);
3772 proto_item_set_end(subti, tvb, offset);
3774 if (api_version >= 7) {
3775 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_request_forgotten_topic, &subti, "Forgotten Topics");
3776 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 12, api_version,
3777 &dissect_kafka_fetch_request_forgotten_topics_data, NULL);
3778 proto_item_set_end(subti, tvb, offset);
3781 if (api_version >= 11) {
3782 offset = dissect_kafka_string(tree, hf_kafka_rack, tvb, pinfo, offset, api_version >= 12, NULL, NULL);
3785 if (api_version >= 12) {
3786 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
3789 return offset;
3792 static int
3793 dissect_kafka_aborted_transaction(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3794 int offset, kafka_api_version_t api_version _U_)
3796 proto_item *ti;
3797 proto_tree *subtree;
3799 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_aborted_transaction, &ti, "Transaction");
3801 proto_tree_add_item(subtree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
3802 offset += 8;
3804 proto_tree_add_item(subtree, hf_kafka_first_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
3805 offset += 8;
3807 if (api_version >= 12) {
3808 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3811 proto_item_set_end(ti, tvb, offset);
3813 return offset;
3816 static int
3817 dissect_kafka_aborted_transactions(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3818 int offset, kafka_api_version_t api_version)
3820 proto_item *ti;
3821 proto_tree *subtree;
3823 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_aborted_transactions, &ti, "Aborted Transactions");
3825 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 12, api_version, &dissect_kafka_aborted_transaction, NULL);
3827 proto_item_set_end(ti, tvb, offset);
3829 return offset;
3832 static int
3833 dissect_kafka_fetch_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3834 kafka_api_version_t api_version)
3836 proto_item *ti;
3837 proto_tree *subtree;
3838 kafka_packet_values_t packet_values;
3839 memset(&packet_values, 0, sizeof(packet_values));
3841 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &ti, "Partition");
3843 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &packet_values.partition_id);
3845 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
3847 offset = dissect_kafka_offset_ret(tvb, pinfo, subtree, offset, &packet_values.offset);
3849 if (api_version >= 4) {
3850 proto_tree_add_item(subtree, hf_kafka_last_stable_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
3851 offset += 8;
3854 if (api_version >= 5) {
3855 proto_tree_add_item(subtree, hf_kafka_log_start_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
3856 offset += 8;
3859 if (api_version >= 4) {
3860 offset = dissect_kafka_aborted_transactions(tvb, pinfo, subtree, offset, api_version);
3863 if (api_version >= 11) {
3864 proto_tree_add_item(subtree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
3865 offset += 4;
3868 offset = dissect_kafka_message_set(tvb, pinfo, subtree, offset, api_version >= 12, KAFKA_MESSAGE_CODEC_NONE);
3870 if (api_version >= 12) {
3871 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3874 proto_item_set_end(ti, tvb, offset);
3876 proto_item_append_text(ti, " (ID=%u, Offset=%" PRIi64 ")",
3877 packet_values.partition_id, packet_values.offset);
3879 return offset;
3882 static int
3883 dissect_kafka_fetch_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3884 kafka_api_version_t api_version)
3886 proto_item *subti, *subsubti;
3887 proto_tree *subtree, *subsubtree;
3888 uint32_t count = 0;
3890 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
3892 if (api_version >= 0 && api_version <= 12) {
3893 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 12, NULL, NULL);
3896 if (api_version >= 13) {
3897 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
3900 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_topic, &subsubti, "Partitions");
3901 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 12, api_version,
3902 &dissect_kafka_fetch_response_partition, &count);
3903 proto_item_set_end(subsubti, tvb, offset);
3905 if (api_version >= 12) {
3906 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3909 proto_item_set_end(subti, tvb, offset);
3910 proto_item_append_text(subti, " (%u partitions)", count);
3912 return offset;
3915 static int
3916 dissect_kafka_fetch_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3917 kafka_api_version_t api_version)
3919 proto_item *subti;
3920 proto_tree *subtree;
3922 if (api_version >= 1) {
3923 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
3926 if (api_version >= 7) {
3927 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
3929 proto_tree_add_item(tree, hf_kafka_fetch_session_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3930 offset += 4;
3933 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topics");
3934 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 12, api_version, &dissect_kafka_fetch_response_topic, NULL);
3935 proto_item_set_end(subti, tvb, offset);
3937 if (api_version >= 12) {
3938 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
3941 return offset;
3944 /* PRODUCE REQUEST/RESPONSE */
3946 static int
3947 dissect_kafka_produce_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3948 kafka_api_version_t api_version _U_)
3950 proto_item *ti;
3951 proto_tree *subtree;
3952 kafka_packet_values_t packet_values;
3953 memset(&packet_values, 0, sizeof(packet_values));
3955 subtree = proto_tree_add_subtree(tree, tvb, offset, 14, ett_kafka_partition, &ti, "Partition");
3957 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &packet_values.partition_id);
3959 offset = dissect_kafka_message_set(tvb, pinfo, subtree, offset, api_version >= 9, KAFKA_MESSAGE_CODEC_NONE);
3961 if (api_version >= 9) {
3962 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3965 proto_item_append_text(ti, " (ID=%u)", packet_values.partition_id);
3966 proto_item_set_end(ti, tvb, offset);
3968 return offset;
3971 static int
3972 dissect_kafka_produce_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int start_offset,
3973 kafka_api_version_t api_version)
3975 proto_item *ti;
3976 proto_tree *subtree;
3977 int offset = start_offset;
3978 int topic_off, topic_len;
3980 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &ti, "Topic");
3982 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 9, &topic_off, &topic_len);
3983 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 9, api_version,
3984 &dissect_kafka_produce_request_partition, NULL);
3986 if (api_version >= 9) {
3987 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
3990 proto_item_append_text(ti, " (Name=%s)",
3991 tvb_get_string_enc(pinfo->pool, tvb, topic_off, topic_len, ENC_UTF_8));
3992 proto_item_set_end(ti, tvb, offset);
3994 return offset;
3997 static int
3998 dissect_kafka_produce_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3999 kafka_api_version_t api_version)
4001 if (api_version >= 3) {
4002 offset = dissect_kafka_string(tree, hf_kafka_transactional_id, tvb, pinfo, offset, api_version >= 9, NULL, NULL);
4005 proto_tree_add_item(tree, hf_kafka_required_acks, tvb, offset, 2, ENC_BIG_ENDIAN);
4006 offset += 2;
4008 proto_tree_add_item(tree, hf_kafka_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
4009 offset += 4;
4011 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 9, api_version,
4012 &dissect_kafka_produce_request_topic, NULL);
4014 if (api_version >= 9) {
4015 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4018 return offset;
4021 static int
4022 dissect_kafka_produce_response_partition_record_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4023 kafka_api_version_t api_version _U_) {
4024 proto_item *ti;
4025 proto_tree *subtree;
4027 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_record_error, &ti, "Record Error");
4029 proto_tree_add_item(subtree, hf_kafka_batch_index, tvb, offset, 4, ENC_BIG_ENDIAN);
4030 offset += 4;
4032 offset = dissect_kafka_string(subtree, hf_kafka_batch_index_error_message, tvb, pinfo, offset, api_version >= 9, NULL, NULL);
4034 if (api_version >= 9) {
4035 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4038 proto_item_set_end(ti, tvb, offset);
4040 return offset;
4043 static int
4044 dissect_kafka_produce_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4045 kafka_api_version_t api_version) {
4046 proto_item *ti, *subti;
4047 proto_tree *subtree, *subsubtree;
4048 kafka_packet_values_t packet_values;
4049 memset(&packet_values, 0, sizeof(packet_values));
4051 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &ti, "Partition");
4053 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &packet_values.partition_id);
4055 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
4057 offset = dissect_kafka_offset_ret(tvb, pinfo, subtree, offset, &packet_values.offset);
4059 if (api_version >= 2) {
4060 offset = dissect_kafka_offset_time(tvb, pinfo, subtree, offset, api_version);
4063 if (api_version >= 5) {
4064 proto_tree_add_item(subtree, hf_kafka_log_start_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
4065 offset += 8;
4068 if (api_version >= 8) {
4069 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_record_errors, &subti, "Record Errors");
4070 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 9, api_version,
4071 &dissect_kafka_produce_response_partition_record_error, NULL);
4072 proto_item_set_end(subti, tvb, offset);
4075 if (api_version >= 8) {
4076 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 9, NULL, NULL);
4079 if (api_version >= 9) {
4080 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4083 proto_item_set_end(ti, tvb, offset);
4085 proto_item_append_text(ti, " (ID=%u, Offset=%" PRIi64 ")",
4086 packet_values.partition_id, packet_values.offset);
4088 return offset;
4091 static int
4092 dissect_kafka_produce_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4093 kafka_api_version_t api_version)
4095 proto_item *subti, *subsubti;
4096 proto_tree *subtree, *subsubtree;
4098 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
4100 /* name */
4101 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 9, NULL, NULL);
4103 /* [partitions] */
4104 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_topic, &subsubti, "Partitions");
4105 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 9, api_version,
4106 &dissect_kafka_produce_response_partition, NULL);
4107 proto_item_set_end(subsubti, tvb, offset);
4109 if (api_version >= 9) {
4110 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4113 proto_item_set_end(subti, tvb, offset);
4115 return offset;
4118 static int
4119 dissect_kafka_produce_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4120 kafka_api_version_t api_version)
4122 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 9, api_version, &dissect_kafka_produce_response_topic, NULL);
4124 if (api_version >= 1) {
4125 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
4128 if (api_version >= 9) {
4129 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4132 return offset;
4135 /* OFFSETS REQUEST/RESPONSE */
4137 static int
4138 dissect_kafka_offsets_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4139 int offset, kafka_api_version_t api_version)
4141 proto_item *ti;
4142 proto_tree *subtree;
4143 kafka_partition_t partition = 0;
4145 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &ti, "Partition");
4147 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &partition);
4149 if (api_version >= 4) {
4150 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
4151 offset += 4;
4154 offset = dissect_kafka_offset_time(tvb, pinfo, subtree, offset, api_version);
4156 if (api_version == 0) {
4157 proto_tree_add_item(subtree, hf_kafka_max_offsets, tvb, offset, 4, ENC_BIG_ENDIAN);
4158 offset += 4;
4161 if (api_version >= 6) {
4162 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4165 proto_item_set_end(ti, tvb, offset);
4166 proto_item_append_text(ti, " (ID=%u)", partition);
4168 return offset;
4171 static int
4172 dissect_kafka_offsets_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4173 kafka_api_version_t api_version)
4175 proto_item *ti;
4176 proto_tree *subtree;
4178 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &ti, "Topic");
4180 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
4181 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
4182 &dissect_kafka_offsets_request_partition, NULL);
4184 if (api_version >= 6) {
4185 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4188 proto_item_set_end(ti, tvb, offset);
4190 return offset;
4193 static int
4194 dissect_kafka_offsets_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4195 kafka_api_version_t api_version)
4197 proto_item *subti;
4198 proto_tree *subtree;
4200 proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
4201 offset += 4;
4203 if (api_version >= 2) {
4204 proto_tree_add_item(tree, hf_kafka_isolation_level, tvb, offset, 1, ENC_BIG_ENDIAN);
4205 offset += 1;
4208 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker, &subti, "Topics");
4210 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
4211 &dissect_kafka_offsets_request_topic, NULL);
4213 proto_item_set_end(subti, tvb, offset);
4215 if (api_version >= 6) {
4216 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4219 return offset;
4222 static int
4223 dissect_kafka_offsets_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4224 int offset, kafka_api_version_t api_version)
4226 proto_item *ti;
4227 proto_tree *subtree;
4228 kafka_partition_t partition = 0;
4230 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &ti, "Partition");
4232 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &partition);
4234 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
4236 if (api_version == 0) {
4237 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version, &dissect_kafka_offset, NULL);
4239 else if (api_version >= 1) {
4240 offset = dissect_kafka_offset_time(tvb, pinfo, subtree, offset, api_version);
4242 offset = dissect_kafka_offset_ret(tvb, pinfo, subtree, offset, NULL);
4245 if (api_version >= 4) {
4246 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
4247 offset += 4;
4250 if (api_version >= 6) {
4251 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4254 proto_item_set_end(ti, tvb, offset);
4255 proto_item_append_text(ti, " (ID=%u)", partition);
4257 return offset;
4260 static int
4261 dissect_kafka_offsets_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4262 kafka_api_version_t api_version)
4264 proto_item *ti;
4265 proto_tree *subtree;
4267 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &ti, "Topic");
4269 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
4270 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
4271 &dissect_kafka_offsets_response_partition, NULL);
4273 if (api_version >= 6) {
4274 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4277 proto_item_set_end(ti, tvb, offset);
4279 return offset;
4282 static int
4283 dissect_kafka_offsets_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int start_offset,
4284 kafka_api_version_t api_version)
4286 proto_item *subti;
4287 proto_tree *subtree;
4288 int offset = start_offset;
4290 if (api_version >= 2) {
4291 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
4294 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker, &subti, "Topics");
4296 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
4297 &dissect_kafka_offsets_response_topic, NULL);
4299 proto_item_set_end(subti, tvb, offset);
4301 if (api_version >= 6) {
4302 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4305 return offset;
4308 /* API_VERSIONS REQUEST/RESPONSE */
4310 static int
4311 dissect_kafka_api_versions_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4312 int offset, kafka_api_version_t api_version)
4314 if (api_version >= 3) {
4315 offset = dissect_kafka_compact_string(tree, hf_kafka_client_software_name, tvb, pinfo, offset, NULL, NULL);
4316 offset = dissect_kafka_compact_string(tree, hf_kafka_client_software_version, tvb, pinfo, offset, NULL, NULL);
4317 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4320 return offset;
4323 static int
4324 dissect_kafka_api_versions_response_api_version(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4325 int offset, kafka_api_version_t api_version _U_)
4327 proto_item *ti;
4328 proto_tree *subtree;
4329 kafka_api_key_t api_key;
4330 kafka_api_version_t min_version, max_version;
4331 const kafka_api_info_t *api_info;
4333 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_api_version, &ti,
4334 "API Version");
4336 api_key = tvb_get_ntohs(tvb, offset);
4337 proto_tree_add_item(subtree, hf_kafka_api_versions_api_key, tvb, offset, 2, ENC_BIG_ENDIAN);
4338 offset += 2;
4340 min_version = tvb_get_ntohs(tvb, offset);
4341 proto_tree_add_item(subtree, hf_kafka_api_versions_min_version, tvb, offset, 2, ENC_BIG_ENDIAN);
4342 offset += 2;
4344 max_version = tvb_get_ntohs(tvb, offset);
4345 proto_tree_add_item(subtree, hf_kafka_api_versions_max_version, tvb, offset, 2, ENC_BIG_ENDIAN);
4346 offset += 2;
4348 proto_item_set_end(ti, tvb, offset);
4349 if (max_version != min_version) {
4350 /* Range of versions supported. */
4351 proto_item_append_text(subtree, " %s (v%d-%d)",
4352 kafka_api_key_to_str(api_key),
4353 min_version, max_version);
4355 else {
4356 /* Only one version. */
4357 proto_item_append_text(subtree, " %s (v%d)",
4358 kafka_api_key_to_str(api_key),
4359 min_version);
4362 api_info = kafka_get_api_info(api_key);
4363 if (api_info == NULL) {
4364 proto_item_append_text(subtree, " [Unknown API key]");
4365 expert_add_info_format(pinfo, ti, &ei_kafka_unknown_api_key,
4366 "%s API key", kafka_api_key_to_str(api_key));
4368 else if (!kafka_is_api_version_supported(api_info, min_version) ||
4369 !kafka_is_api_version_supported(api_info, max_version)) {
4370 if (api_info->min_version == -1) {
4371 proto_item_append_text(subtree, " [Unsupported API version]");
4372 expert_add_info_format(pinfo, ti, &ei_kafka_unsupported_api_version,
4373 "Unsupported %s version.",
4374 kafka_api_key_to_str(api_key));
4376 else if (api_info->min_version == api_info->max_version) {
4377 proto_item_append_text(subtree, " [Unsupported API version. Supports v%d]",
4378 api_info->min_version);
4379 expert_add_info_format(pinfo, ti, &ei_kafka_unsupported_api_version,
4380 "Unsupported %s version. Supports v%d.",
4381 kafka_api_key_to_str(api_key), api_info->min_version);
4382 } else {
4383 proto_item_append_text(subtree, " [Unsupported API version. Supports v%d-%d]",
4384 api_info->min_version, api_info->max_version);
4385 expert_add_info_format(pinfo, ti, &ei_kafka_unsupported_api_version,
4386 "Unsupported %s version. Supports v%d-%d.",
4387 kafka_api_key_to_str(api_key),
4388 api_info->min_version, api_info->max_version);
4392 if (api_version >= 3) {
4393 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4396 return offset;
4399 static int
4400 dissect_kafka_api_versions_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4401 kafka_api_version_t api_version)
4403 /* error_code */
4404 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
4406 /* [api_version] */
4407 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 3, api_version,
4408 &dissect_kafka_api_versions_response_api_version, NULL);
4410 if (api_version >= 1) {
4411 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
4414 if (api_version >= 3) {
4415 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4418 return offset;
4421 /* UPDATE_METADATA REQUEST/RESPONSE */
4423 static int
4424 dissect_kafka_update_metadata_request_replica(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4425 int offset, kafka_api_version_t api_version _U_)
4427 return dissect_kafka_int32(tree, hf_kafka_replica, tvb, pinfo, offset, NULL);
4430 static int
4431 dissect_kafka_update_metadata_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4432 int offset, kafka_api_version_t api_version)
4434 proto_tree *subtree, *subsubtree;
4435 proto_item *subti, *subsubti;
4436 int topic_start, topic_len;
4437 kafka_partition_t partition;
4439 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
4440 ett_kafka_partition,
4441 &subti, "Partition");
4443 /* topic */
4444 if (api_version < 5) {
4445 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0,
4446 &topic_start, &topic_len);
4449 /* partition */
4450 offset = dissect_kafka_int32(subtree, hf_kafka_partition_id, tvb, pinfo, offset, &partition);
4452 /* controller_epoch */
4453 offset = dissect_kafka_int32(subtree, hf_kafka_controller_epoch, tvb, pinfo, offset, NULL);
4455 /* leader */
4456 offset = dissect_kafka_int32(subtree, hf_kafka_leader_id, tvb, pinfo, offset, NULL);
4458 /* leader_epoch */
4459 offset = dissect_kafka_int32(subtree, hf_kafka_leader_epoch, tvb, pinfo, offset, NULL);
4461 /* [isr] */
4462 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
4463 ett_kafka_isrs,
4464 &subsubti, "Insync Replicas");
4465 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 6, api_version,
4466 &dissect_kafka_update_metadata_request_replica, NULL);
4467 proto_item_set_end(subsubti, tvb, offset);
4469 /* zk_version */
4470 offset = dissect_kafka_int32(subtree, hf_kafka_zk_version, tvb, pinfo, offset, NULL);
4472 /* [replica] */
4473 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
4474 ett_kafka_replicas,
4475 &subsubti, "Replicas");
4476 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 6, api_version,
4477 &dissect_kafka_update_metadata_request_replica, NULL);
4478 proto_item_set_end(subsubti, tvb, offset);
4480 /* [offline_replica] */
4481 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
4482 ett_kafka_replicas,
4483 &subsubti, "Offline Replicas");
4484 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 6, api_version,
4485 &dissect_kafka_update_metadata_request_replica, NULL);
4486 proto_item_set_end(subsubti, tvb, offset);
4488 if (api_version >= 6) {
4489 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4492 proto_item_set_end(subti, tvb, offset);
4494 if (api_version >= 5) {
4495 proto_item_append_text(subti, " (Partition-ID=%u)",
4496 partition);
4497 } else {
4498 proto_item_append_text(subti, " (Topic=%s, Partition-ID=%u)",
4499 tvb_get_string_enc(pinfo->pool, tvb,
4500 topic_start, topic_len, ENC_UTF_8),
4501 partition);
4503 return offset;
4506 static int
4507 dissect_kafka_update_metadata_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4508 int offset, kafka_api_version_t api_version)
4510 proto_tree *subtree;
4511 proto_item *subti;
4512 int topic_start, topic_len;
4514 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
4515 ett_kafka_topic,
4516 &subti, "Topic");
4517 /* topic */
4518 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 6,
4519 &topic_start, &topic_len);
4521 /* topic_id */
4522 if (api_version >= 7) {
4523 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
4526 /* partitions */
4527 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
4528 &dissect_kafka_update_metadata_request_partition, NULL);
4530 if (api_version >= 6) {
4531 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4534 proto_item_set_end(subti, tvb, offset);
4535 proto_item_append_text(subti, " (Topic=%s)",
4536 tvb_get_string_enc(pinfo->pool, tvb,
4537 topic_start, topic_len, ENC_UTF_8));
4539 return offset;
4542 static int
4543 dissect_kafka_update_metadata_request_endpoint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4544 int offset, kafka_api_version_t api_version _U_)
4546 proto_item *subti;
4547 proto_tree *subtree;
4548 int host_start, host_len;
4549 int32_t broker_port;
4550 int16_t security_protocol_type;
4552 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker_end_point,
4553 &subti, "End Point");
4555 /* port */
4556 offset = dissect_kafka_int32(subtree, hf_kafka_broker_port, tvb, pinfo, offset, &broker_port);
4558 /* host */
4559 offset = dissect_kafka_string(subtree, hf_kafka_broker_host, tvb, pinfo, offset, api_version >= 6, &host_start, &host_len);
4561 /* listener_name */
4562 if (api_version >= 3) {
4563 offset = dissect_kafka_string(subtree, hf_kafka_listener_name, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
4566 /* security_protocol_type */
4567 offset = dissect_kafka_int16(subtree, hf_kafka_broker_security_protocol_type, tvb, pinfo, offset, &security_protocol_type);
4569 if (api_version >= 6) {
4570 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4573 proto_item_set_end(subti, tvb, offset);
4574 proto_item_append_text(subti, " (%s://%s:%d)",
4575 val_to_str_const(security_protocol_type,
4576 kafka_security_protocol_types, "UNKNOWN"),
4577 tvb_get_string_enc(pinfo->pool, tvb, host_start, host_len,
4578 ENC_UTF_8),
4579 broker_port);
4581 return offset;
4584 static int
4585 dissect_kafka_update_metadata_request_broker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4586 int offset, kafka_api_version_t api_version)
4588 proto_item *subti;
4589 proto_tree *subtree;
4590 int32_t nodeid;
4592 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker,
4593 &subti, "Live Leader");
4595 /* id */
4596 offset = dissect_kafka_int32(subtree, hf_kafka_broker_nodeid, tvb, pinfo, offset, &nodeid);
4598 if (api_version == 0) {
4599 int host_start, host_len;
4600 int32_t broker_port;
4602 /* host */
4603 offset = dissect_kafka_string(subtree, hf_kafka_broker_host, tvb, pinfo, offset, 0, &host_start, &host_len);
4605 /* port */
4606 offset = dissect_kafka_int32(tree, hf_kafka_broker_port, tvb, pinfo, offset, &broker_port);
4608 proto_item_append_text(subti, " (node %u: %s:%u)",
4609 nodeid,
4610 tvb_get_string_enc(pinfo->pool, tvb, host_start, host_len,
4611 ENC_UTF_8),
4612 broker_port);
4613 } else if (api_version >= 1) {
4614 /* [end_point] */
4615 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
4616 &dissect_kafka_update_metadata_request_endpoint, NULL);
4618 if (api_version >= 2) {
4619 /* rack */
4620 offset = dissect_kafka_string(subtree, hf_kafka_rack, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
4623 proto_item_append_text(subti, " (node %d)",
4624 nodeid);
4627 if (api_version >= 6) {
4628 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4631 proto_item_set_end(subti, tvb, offset);
4633 return offset;
4636 static int
4637 dissect_kafka_update_metadata_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4638 kafka_api_version_t api_version)
4640 int32_t controller_id;
4642 /* controller_id */
4643 offset = dissect_kafka_int32(tree, hf_kafka_controller_id, tvb, pinfo, offset, &controller_id);
4645 /* is_kraft_controller */
4646 if (api_version >= 8) {
4647 offset = dissect_kafka_bool(tree, hf_kafka_is_kraft_controller, tvb, pinfo, offset);
4650 /* controller_epoch */
4651 offset = dissect_kafka_int32(tree, hf_kafka_controller_epoch, tvb, pinfo, offset, NULL);
4653 /* broker_epoch */
4654 if (api_version >= 5) {
4655 offset = dissect_kafka_int64(tree, hf_kafka_broker_epoch, tvb, pinfo, offset, NULL);
4658 if (api_version >= 5) {
4659 /* [topic_state] */
4660 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 6, api_version,
4661 &dissect_kafka_update_metadata_request_topic, NULL);
4662 } else {
4663 /* [partition_state] */
4664 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 6, api_version,
4665 &dissect_kafka_update_metadata_request_partition, NULL);
4668 /* [live_leader] */
4669 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 6, api_version,
4670 &dissect_kafka_update_metadata_request_broker, NULL);
4672 if (api_version >= 6) {
4673 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4676 return offset;
4679 static int
4680 dissect_kafka_update_metadata_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4681 kafka_api_version_t api_version)
4683 /* error_code */
4684 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
4686 if (api_version >= 6) {
4687 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4690 return offset;
4693 /* CONTROLLED_SHUTDOWN REQUEST/RESPONSE */
4695 static int
4696 dissect_kafka_controlled_shutdown_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4697 kafka_api_version_t api_version _U_)
4699 int32_t broker_id;
4701 /* broker_id */
4702 broker_id = (int32_t) tvb_get_ntohl(tvb, offset);
4703 proto_tree_add_item(tree, hf_kafka_broker_nodeid, tvb, offset, 4, ENC_BIG_ENDIAN);
4704 offset += 4;
4706 if (api_version >= 2) {
4707 proto_tree_add_item(tree, hf_kafka_broker_epoch, tvb, offset, 8, ENC_BIG_ENDIAN);
4708 offset += 8;
4711 if (api_version >= 3) {
4712 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4715 col_append_fstr(pinfo->cinfo, COL_INFO, " (Broker-ID=%d)", broker_id);
4717 return offset;
4720 static int
4721 dissect_kafka_controlled_shutdown_response_partition_remaining(tvbuff_t *tvb, packet_info *pinfo,
4722 proto_tree *tree, int offset,
4723 kafka_api_version_t api_version)
4725 proto_item *subti;
4726 proto_tree *subtree;
4727 int topic_start, topic_len;
4728 kafka_partition_t partition;
4730 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti,
4731 "Partition Remaining");
4733 /* topic */
4734 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 3,
4735 &topic_start, &topic_len);
4737 /* partition */
4738 partition = (int32_t) tvb_get_ntohl(tvb, offset);
4739 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
4740 offset += 4;
4742 if (api_version >= 3) {
4743 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4746 proto_item_set_end(subti, tvb, offset);
4747 proto_item_append_text(subti, " (Topic=%s, Partition-ID=%d)",
4748 tvb_get_string_enc(pinfo->pool, tvb,
4749 topic_start, topic_len, ENC_UTF_8),
4750 partition);
4752 return offset;
4755 static int
4756 dissect_kafka_controlled_shutdown_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4757 kafka_api_version_t api_version)
4759 /* error_code */
4760 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
4762 /* [partition_remaining] */
4763 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 3, api_version,
4764 &dissect_kafka_controlled_shutdown_response_partition_remaining, NULL);
4766 if (api_version >= 3) {
4767 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4770 return offset;
4773 /* OFFSET_COMMIT REQUEST/RESPONSE */
4775 static int
4776 dissect_kafka_offset_commit_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4777 int offset, kafka_api_version_t api_version _U_)
4779 proto_item *subti;
4780 proto_tree *subtree;
4781 kafka_partition_t partition_id;
4782 kafka_offset_t partition_offset;
4784 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti,
4785 "Partition");
4787 /* partition */
4788 partition_id = (int32_t) tvb_get_ntohl(tvb, offset);
4789 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
4790 offset += 4;
4792 /* offset */
4793 partition_offset = (int64_t) tvb_get_ntoh64(tvb, offset);
4794 proto_tree_add_item(subtree, hf_kafka_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
4795 offset += 8;
4797 if (api_version >= 6) {
4798 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
4799 offset += 4;
4802 if (api_version == 1) {
4803 /* timestamp */
4804 proto_tree_add_item(subtree, hf_kafka_commit_timestamp, tvb, offset, 8, ENC_TIME_MSECS|ENC_BIG_ENDIAN);
4805 offset += 8;
4808 /* metadata */
4809 offset = dissect_kafka_string(subtree, hf_kafka_metadata, tvb, pinfo, offset, api_version >= 8, NULL, NULL);
4811 if (api_version >= 8) {
4812 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4815 proto_item_set_end(subti, tvb, offset);
4816 proto_item_append_text(subti, " (ID=%u, Offset=%" PRIi64 ")",
4817 partition_id, partition_offset);
4819 return offset;
4822 static int
4823 dissect_kafka_offset_commit_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4824 int offset, kafka_api_version_t api_version)
4826 proto_item *subti;
4827 proto_tree *subtree;
4828 int topic_start, topic_len;
4830 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
4832 /* topic */
4833 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 8,
4834 &topic_start, &topic_len);
4835 /* [partition] */
4836 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 8, api_version,
4837 &dissect_kafka_offset_commit_request_partition, NULL);
4839 if (api_version >= 8) {
4840 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4843 proto_item_set_end(subti, tvb, offset);
4844 proto_item_append_text(subti, " (Topic=%s)",
4845 tvb_get_string_enc(pinfo->pool, tvb,
4846 topic_start, topic_len, ENC_UTF_8));
4848 return offset;
4851 static int
4852 dissect_kafka_offset_commit_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4853 kafka_api_version_t api_version)
4855 int group_start = 0, group_len;
4857 /* group_id */
4858 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 8,
4859 &group_start, &group_len);
4861 if (api_version >= 1) {
4862 /* group_generation_id */
4863 proto_tree_add_item(tree, hf_kafka_generation_id, tvb, offset, 4, ENC_BIG_ENDIAN);
4864 offset += 4;
4867 /* member_id */
4868 if (api_version >= 1) {
4869 offset = dissect_kafka_string(tree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 8, NULL, NULL);
4872 /* instance_id */
4873 if (api_version >= 7) {
4874 offset = dissect_kafka_string(tree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 8, NULL, NULL);
4877 /* retention_time */
4878 if (api_version >= 2 && api_version < 5) {
4879 proto_tree_add_item(tree, hf_kafka_retention_time, tvb, offset, 8, ENC_BIG_ENDIAN);
4880 offset += 8;
4883 /* [topic] */
4884 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 8, api_version,
4885 &dissect_kafka_offset_commit_request_topic, NULL);
4887 if (api_version >= 8) {
4888 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4891 col_append_fstr(pinfo->cinfo, COL_INFO,
4892 " (Group=%s)",
4893 tvb_get_string_enc(pinfo->pool, tvb,
4894 group_start, group_len, ENC_UTF_8));
4896 return offset;
4899 static int
4900 dissect_kafka_offset_commit_response_partition_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4901 int offset, kafka_api_version_t api_version _U_)
4903 proto_item *subti;
4904 proto_tree *subtree;
4905 kafka_partition_t partition;
4906 kafka_error_t error;
4908 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti,
4909 "Partition");
4911 /* partition */
4912 partition = (int32_t) tvb_get_ntohl(tvb, offset);
4913 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
4914 offset += 4;
4916 /* error_code */
4917 offset = dissect_kafka_error_ret(tvb, pinfo, subtree, offset, &error);
4919 if (api_version >= 8) {
4920 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4923 proto_item_set_end(subti, tvb, offset);
4924 proto_item_append_text(subti, " (Partition-ID=%d, Error=%s)",
4925 partition, kafka_error_to_str(error));
4927 return offset;
4930 static int
4931 dissect_kafka_offset_commit_response_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4932 int offset, kafka_api_version_t api_version)
4934 proto_item *subti;
4935 proto_tree *subtree;
4936 int topic_start, topic_len;
4938 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
4940 /* topic */
4941 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 8,
4942 &topic_start, &topic_len);
4944 /* [partition_response] */
4945 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 8, api_version,
4946 &dissect_kafka_offset_commit_response_partition_response, NULL);
4948 if (api_version >= 8) {
4949 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
4952 proto_item_set_end(subti, tvb, offset);
4953 proto_item_append_text(subti, " (Name=%s)",
4954 tvb_get_string_enc(pinfo->pool, tvb,
4955 topic_start, topic_len, ENC_UTF_8));
4957 return offset;
4960 static int
4961 dissect_kafka_offset_commit_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4962 kafka_api_version_t api_version)
4964 if (api_version >= 3) {
4965 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
4968 /* [responses] */
4969 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 8, api_version,
4970 &dissect_kafka_offset_commit_response_response, NULL);
4972 if (api_version >= 8) {
4973 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
4976 return offset;
4979 /* GROUP_COORDINATOR REQUEST/RESPONSE */
4981 static int
4982 dissect_kafka_find_coordinator_request_coordinator_keys(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4983 kafka_api_version_t api_version)
4985 if (api_version >= 4) {
4986 offset = dissect_kafka_string(tree, hf_kafka_coordinator_key, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
4989 return offset;
4992 static int
4993 dissect_kafka_find_coordinator_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4994 kafka_api_version_t api_version _U_)
4996 proto_item *subti;
4997 proto_tree *subtree;
4998 int group_start, group_len;
5000 if (api_version == 0) {
5001 /* group_id */
5002 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, 0,
5003 &group_start, &group_len);
5005 col_append_fstr(pinfo->cinfo, COL_INFO,
5006 " (Group=%s)",
5007 tvb_get_string_enc(pinfo->pool, tvb,
5008 group_start, group_len, ENC_UTF_8));
5011 if (api_version >= 0 && api_version <= 3) {
5012 offset = dissect_kafka_string(tree, hf_kafka_coordinator_key, tvb, pinfo, offset, api_version >= 3,
5013 NULL, NULL);
5016 if (api_version >= 1) {
5017 proto_tree_add_item(tree, hf_kafka_coordinator_type, tvb, offset, 1, ENC_NA);
5018 offset += 1;
5021 if (api_version >= 4) {
5022 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Coordinator Keys");
5024 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 3, api_version,
5025 &dissect_kafka_find_coordinator_request_coordinator_keys, NULL);
5027 proto_item_set_end(subti, tvb, offset);
5030 if (api_version >= 3) {
5031 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5034 return offset;
5037 static int
5038 dissect_kafka_find_coordinator_response_coordinator_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5039 int offset, kafka_api_version_t api_version)
5041 proto_item *subti;
5042 proto_tree *subtree;
5043 int32_t node_id;
5044 int host_start, host_len;
5045 int32_t port;
5047 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker, &subti, "Coordinator");
5049 /* node_id */
5050 node_id = (int32_t) tvb_get_ntohl(tvb, offset);
5051 proto_tree_add_item(subtree, hf_kafka_broker_nodeid, tvb, offset, 4, ENC_BIG_ENDIAN);
5052 offset += 4;
5054 /* host */
5055 offset = dissect_kafka_string(subtree, hf_kafka_broker_host, tvb, pinfo, offset, api_version >= 3,
5056 &host_start, &host_len);
5058 /* port */
5059 port = (int32_t) tvb_get_ntohl(tvb, offset);
5060 proto_tree_add_item(subtree, hf_kafka_broker_port, tvb, offset, 4, ENC_BIG_ENDIAN);
5061 offset += 4;
5063 proto_item_set_end(subti, tvb, offset);
5065 if (node_id >= 0) {
5066 proto_item_append_text(subti, " (node %d: %s:%d)",
5067 node_id,
5068 tvb_get_string_enc(pinfo->pool, tvb,
5069 host_start, host_len, ENC_UTF_8),
5070 port);
5071 } else {
5072 proto_item_append_text(subti, " (none)");
5075 return offset;
5078 static int
5079 dissect_kafka_find_coordinator_response_coordinator_v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5080 int offset, kafka_api_version_t api_version)
5082 proto_item *subti;
5083 proto_tree *subtree;
5084 int32_t node_id;
5085 int host_start, host_len;
5086 int32_t port;
5088 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker, &subti, "Coordinator");
5090 /* key */
5091 offset = dissect_kafka_string(subtree, hf_kafka_coordinator_key, tvb, pinfo, offset, api_version >= 3, NULL, NULL);
5093 /* node_id */
5094 node_id = (int32_t) tvb_get_ntohl(tvb, offset);
5095 proto_tree_add_item(subtree, hf_kafka_broker_nodeid, tvb, offset, 4, ENC_BIG_ENDIAN);
5096 offset += 4;
5098 /* host */
5099 offset = dissect_kafka_string(subtree, hf_kafka_broker_host, tvb, pinfo, offset, api_version >= 3,
5100 &host_start, &host_len);
5102 /* port */
5103 port = (int32_t) tvb_get_ntohl(tvb, offset);
5104 proto_tree_add_item(subtree, hf_kafka_broker_port, tvb, offset, 4, ENC_BIG_ENDIAN);
5105 offset += 4;
5107 /* error_code */
5108 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
5110 /* error_message */
5111 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 3,
5112 NULL, NULL);
5114 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5116 proto_item_set_end(subti, tvb, offset);
5118 if (node_id >= 0) {
5119 proto_item_append_text(subti, " (node %d: %s:%d)",
5120 node_id,
5121 tvb_get_string_enc(pinfo->pool, tvb,
5122 host_start, host_len, ENC_UTF_8),
5123 port);
5124 } else {
5125 proto_item_append_text(subti, " (none)");
5128 return offset;
5131 static int
5132 dissect_kafka_find_coordinator_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5133 kafka_api_version_t api_version)
5135 proto_item *subti;
5136 proto_tree *subtree;
5138 if (api_version >= 1) {
5139 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
5142 /* error_code */
5143 if (api_version >= 0 && api_version <= 3) {
5144 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
5147 /* error_message */
5148 if (api_version >= 1 && api_version <= 3) {
5149 offset = dissect_kafka_string(tree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 3,
5150 NULL, NULL);
5153 /* In versions 0-3, coordinator fields exist once on the message (one single coordinator) in a flat layout.
5154 * In version 3+, this has been changed to an array of coordinators, each with some extra fields compared to the
5155 * original single coordinator. */
5156 if (api_version >= 0 && api_version <= 3) {
5157 /* coordinator */
5158 offset = dissect_kafka_find_coordinator_response_coordinator_v1(tvb, pinfo, tree, offset, api_version);
5160 else if (api_version >= 4) {
5161 /* [coordinators] */
5162 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_broker, &subti, "Coordinators");
5164 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 3, api_version,
5165 &dissect_kafka_find_coordinator_response_coordinator_v2, NULL);
5167 proto_item_set_end(subti, tvb, offset);
5170 if (api_version >= 3) {
5171 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5174 return offset;
5177 /* JOIN_GROUP REQUEST/RESPONSE */
5179 static int
5180 dissect_kafka_join_group_request_group_protocols(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5181 int offset, kafka_api_version_t api_version _U_)
5183 proto_item *subti;
5184 proto_tree *subtree;
5185 int protocol_start, protocol_len;
5187 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_protocol, &subti,
5188 "Group Protocol");
5190 /* protocol_name */
5191 offset = dissect_kafka_string(subtree, hf_kafka_protocol_name, tvb, pinfo, offset, api_version >= 6,
5192 &protocol_start, &protocol_len);
5194 /* protocol_metadata */
5195 offset = dissect_kafka_bytes(subtree, hf_kafka_protocol_metadata, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
5197 if (api_version >= 6) {
5198 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5201 proto_item_set_end(subti, tvb, offset);
5202 proto_item_append_text(subti, " (Group-ID=%s)",
5203 tvb_get_string_enc(pinfo->pool, tvb,
5204 protocol_start, protocol_len, ENC_UTF_8));
5206 return offset;
5209 static int
5210 dissect_kafka_join_group_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5211 kafka_api_version_t api_version)
5213 proto_item *subti;
5214 proto_tree *subtree;
5215 int group_start, group_len;
5216 int member_start, member_len;
5218 /* group_id */
5219 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 6,
5220 &group_start, &group_len);
5222 /* session_timeout */
5223 proto_tree_add_item(tree, hf_kafka_session_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
5224 offset += 4;
5226 if (api_version > 0) {
5227 /* rebalance_timeout */
5228 proto_tree_add_item(tree, hf_kafka_rebalance_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
5229 offset += 4;
5232 /* member_id */
5233 offset = dissect_kafka_string(tree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 6,
5234 &member_start, &member_len);
5236 /* instance id */
5237 if (api_version >= 5) {
5238 offset = dissect_kafka_string(tree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 6,
5239 NULL, NULL);
5242 /* protocol_type */
5243 offset = dissect_kafka_string(tree, hf_kafka_protocol_type, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
5245 /* [group_protocols] */
5246 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_protocols, &subti,
5247 "Group Protocols");
5248 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
5249 &dissect_kafka_join_group_request_group_protocols, NULL);
5250 proto_item_set_end(subti, tvb, offset);
5252 /* join_reason */
5253 if (api_version >= 8) {
5254 offset = dissect_kafka_string(tree, hf_kafka_join_reason, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
5257 col_append_fstr(pinfo->cinfo, COL_INFO,
5258 " (Group=%s, Member=%s)",
5259 kafka_tvb_get_string(pinfo->pool, tvb, group_start, group_len),
5260 kafka_tvb_get_string(pinfo->pool, tvb, member_start, member_len));
5262 if (api_version >= 6) {
5263 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5266 return offset;
5269 static int
5270 dissect_kafka_join_group_response_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5271 int offset, kafka_api_version_t api_version)
5273 proto_item *subti;
5274 proto_tree *subtree;
5275 int member_start, member_len;
5277 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_member, &subti, "Member");
5279 /* member_id */
5280 offset = dissect_kafka_string(subtree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 6,
5281 &member_start, &member_len);
5283 /* instance id */
5284 if (api_version >= 5) {
5285 offset = dissect_kafka_string(subtree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 6,
5286 NULL, NULL);
5289 /* member_metadata */
5290 offset = dissect_kafka_bytes(subtree, hf_kafka_member_metadata, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
5292 if (api_version >= 6) {
5293 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5296 proto_item_set_end(subti, tvb, offset);
5297 proto_item_append_text(subti, " (Member=%s)",
5298 tvb_get_string_enc(pinfo->pool, tvb,
5299 member_start, member_len, ENC_UTF_8));
5301 return offset;
5304 static int
5305 dissect_kafka_join_group_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5306 kafka_api_version_t api_version)
5308 proto_item *subti;
5309 proto_tree *subtree;
5310 int member_start = 0, member_len;
5312 if (api_version >= 2) {
5313 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
5316 /* error_code */
5317 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
5319 /* generation_id */
5320 proto_tree_add_item(tree, hf_kafka_generation_id, tvb, offset, 4, ENC_BIG_ENDIAN);
5321 offset += 4;
5323 /* group_protocol_type */
5324 if (api_version >= 7) {
5325 offset = dissect_kafka_string(tree, hf_kafka_protocol_type, tvb, pinfo, offset, 1,NULL, NULL);
5328 /* group_protocol */
5329 offset = dissect_kafka_string(tree, hf_kafka_protocol_name, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
5331 /* leader_id */
5332 offset = dissect_kafka_string(tree, hf_kafka_group_leader_id, tvb, pinfo, offset, api_version >= 6, NULL, NULL);
5334 /* skip_assignment */
5335 if (api_version >= 9) {
5336 offset = dissect_kafka_bool(tree, hf_kafka_skip_assignment, tvb, pinfo, offset);
5339 /* member_id */
5340 offset = dissect_kafka_string(tree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 6, &member_start, &member_len);
5342 /* [member] */
5343 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_members, &subti, "Members");
5344 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 6, api_version,
5345 &dissect_kafka_join_group_response_member, NULL);
5346 proto_item_set_end(subti, tvb, offset);
5348 col_append_fstr(pinfo->cinfo, COL_INFO,
5349 " (Member=%s)",
5350 tvb_get_string_enc(pinfo->pool, tvb,
5351 member_start, member_len, ENC_UTF_8));
5353 if (api_version >= 6) {
5354 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5357 return offset;
5360 /* HEARTBEAT REQUEST/RESPONSE */
5362 static int
5363 dissect_kafka_heartbeat_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5364 kafka_api_version_t api_version _U_)
5366 int group_start, group_len;
5367 int member_start, member_len;
5369 /* group_id */
5370 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 4,
5371 &group_start, &group_len);
5373 /* group_generation_id */
5374 proto_tree_add_item(tree, hf_kafka_generation_id, tvb, offset, 4, ENC_BIG_ENDIAN);
5375 offset += 4;
5377 /* member_id */
5378 offset = dissect_kafka_string(tree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 4,
5379 &member_start, &member_len);
5381 /* instance_id */
5382 if (api_version >= 3) {
5383 offset = dissect_kafka_string(tree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 4,
5384 NULL, NULL);
5387 col_append_fstr(pinfo->cinfo, COL_INFO,
5388 " (Group=%s, Member=%s)",
5389 tvb_get_string_enc(pinfo->pool, tvb,
5390 group_start, group_len, ENC_UTF_8),
5391 tvb_get_string_enc(pinfo->pool, tvb,
5392 member_start, member_len, ENC_UTF_8));
5394 if (api_version >= 4) {
5395 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5398 return offset;
5401 static int
5402 dissect_kafka_heartbeat_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5403 kafka_api_version_t api_version _U_)
5405 if (api_version >= 1) {
5406 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
5409 /* error_code */
5410 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
5412 if (api_version >= 4) {
5413 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5416 return offset;
5419 /* LEAVE_GROUP REQUEST/RESPONSE */
5421 static int
5422 dissect_kafka_leave_group_request_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5423 kafka_api_version_t api_version)
5425 proto_item *subti;
5426 proto_tree *subtree;
5427 int member_start, member_len;
5428 int instance_start, instance_len;
5430 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_member, &subti, "Member");
5432 /* member_id */
5433 offset = dissect_kafka_string(subtree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 4,
5434 &member_start, &member_len);
5436 /* instance_id */
5437 offset = dissect_kafka_string(subtree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 4,
5438 &instance_start, &instance_len);
5440 /* leave_reason */
5441 if (api_version >= 5) {
5442 offset = dissect_kafka_string(subtree, hf_kafka_leave_reason, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
5445 if (api_version >= 4) {
5446 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5449 proto_item_set_end(subti, tvb, offset);
5451 if (instance_len >= 0) {
5452 proto_item_append_text(subti, " (Member=%s, Group-Instance=%s)",
5453 tvb_get_string_enc(pinfo->pool, tvb,
5454 member_start, member_len, ENC_UTF_8),
5455 tvb_get_string_enc(pinfo->pool, tvb,
5456 instance_start, instance_len, ENC_UTF_8)
5458 } else {
5459 proto_item_append_text(subti, " (Member=%s)",
5460 tvb_get_string_enc(pinfo->pool, tvb,
5461 member_start, member_len, ENC_UTF_8)
5465 return offset;
5468 static int
5469 dissect_kafka_leave_group_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5470 kafka_api_version_t api_version)
5472 int group_start, group_len;
5473 int member_start, member_len;
5474 proto_item *subti;
5475 proto_tree *subtree;
5477 /* group_id */
5478 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 4,
5479 &group_start, &group_len);
5481 if (api_version >= 0 && api_version <= 2) {
5483 /* member_id */
5484 offset = dissect_kafka_string(tree, hf_kafka_member_id, tvb, pinfo, offset, 0,
5485 &member_start, &member_len);
5487 col_append_fstr(pinfo->cinfo, COL_INFO,
5488 " (Group=%s, Member=%s)",
5489 tvb_get_string_enc(pinfo->pool, tvb,
5490 group_start, group_len, ENC_UTF_8),
5491 tvb_get_string_enc(pinfo->pool, tvb,
5492 member_start, member_len, ENC_UTF_8));
5494 } else if (api_version >= 3) {
5496 // KIP-345
5497 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_members, &subti, "Members");
5498 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
5499 &dissect_kafka_leave_group_request_member, NULL);
5500 proto_item_set_end(subti, tvb, offset);
5502 col_append_fstr(pinfo->cinfo, COL_INFO,
5503 " (Group=%s)",
5504 tvb_get_string_enc(pinfo->pool, tvb,
5505 group_start, group_len, ENC_UTF_8));
5509 if (api_version >= 4) {
5510 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5513 return offset;
5516 static int
5517 dissect_kafka_leave_group_response_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5518 kafka_api_version_t api_version)
5520 proto_item *subti;
5521 proto_tree *subtree;
5522 int member_start, member_len;
5523 int instance_start, instance_len;
5525 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_member, &subti, "Member");
5527 /* member_id */
5528 offset = dissect_kafka_string(subtree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 4,
5529 &member_start, &member_len);
5531 /* instance_id */
5532 offset = dissect_kafka_string(subtree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 4,
5533 &instance_start, &instance_len);
5535 /* error_code */
5536 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
5538 if (api_version >= 4) {
5539 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5542 proto_item_set_end(subti, tvb, offset);
5544 if (instance_len >= 0) {
5545 proto_item_append_text(subti, " (Member=%s, Group-Instance=%s)",
5546 tvb_get_string_enc(pinfo->pool, tvb,
5547 member_start, member_len, ENC_UTF_8),
5548 tvb_get_string_enc(pinfo->pool, tvb,
5549 instance_start, instance_len, ENC_UTF_8)
5551 } else {
5552 proto_item_append_text(subti, " (Member=%s)",
5553 tvb_get_string_enc(pinfo->pool, tvb,
5554 member_start, member_len, ENC_UTF_8)
5558 return offset;
5561 static int
5562 dissect_kafka_leave_group_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5563 kafka_api_version_t api_version _U_)
5565 proto_item *subti;
5566 proto_tree *subtree;
5568 if (api_version >= 1) {
5569 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
5572 /* error_code */
5573 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
5575 if (api_version >= 3) {
5577 // KIP-345
5578 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_members, &subti, "Members");
5579 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
5580 &dissect_kafka_leave_group_response_member, NULL);
5581 proto_item_set_end(subti, tvb, offset);
5585 if (api_version >= 4) {
5586 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5589 return offset;
5592 /* SYNC_GROUP REQUEST/RESPONSE */
5594 static int
5595 dissect_kafka_sync_group_request_group_assignment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5596 int offset, kafka_api_version_t api_version _U_)
5598 proto_item *subti;
5599 proto_tree *subtree;
5600 int member_start, member_len;
5602 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_assignment, &subti,
5603 "Group Assignment");
5605 /* member_id */
5606 offset = dissect_kafka_string(subtree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 4,
5607 &member_start, &member_len);
5609 /* member_assignment */
5610 offset = dissect_kafka_bytes(subtree, hf_kafka_member_assignment, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
5612 if (api_version >= 4) {
5613 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5616 proto_item_set_end(subti, tvb, offset);
5617 proto_item_append_text(subti, " (Member=%s)",
5618 tvb_get_string_enc(pinfo->pool, tvb,
5619 member_start, member_len, ENC_UTF_8));
5621 return offset;
5624 static int
5625 dissect_kafka_sync_group_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5626 kafka_api_version_t api_version)
5628 proto_item *subti;
5629 proto_tree *subtree;
5630 int group_start, group_len;
5631 int member_start, member_len;
5633 /* group_id */
5634 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 4,
5635 &group_start, &group_len);
5637 /* generation_id */
5638 proto_tree_add_item(tree, hf_kafka_generation_id, tvb, offset, 4, ENC_BIG_ENDIAN);
5639 offset += 4;
5641 /* member_id */
5642 offset = dissect_kafka_string(tree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 4,
5643 &member_start, &member_len);
5645 /* instance_id */
5646 if (api_version >= 3) {
5647 offset = dissect_kafka_string(tree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 4,
5648 NULL, NULL);
5651 /* protocol_type */
5652 if (api_version >= 5) {
5653 offset = dissect_kafka_string(tree, hf_kafka_protocol_type, tvb, pinfo, offset, 1,
5654 NULL, NULL);
5657 /* protocol_name */
5658 if (api_version >= 5) {
5659 offset = dissect_kafka_string(tree, hf_kafka_protocol_name, tvb, pinfo, offset, 1,
5660 NULL, NULL);
5663 /* [group_assignment] */
5664 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_assignments, &subti,
5665 "Group Assignments");
5666 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
5667 &dissect_kafka_sync_group_request_group_assignment, NULL);
5669 if (api_version >= 4) {
5670 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5673 proto_item_set_end(subti, tvb, offset);
5675 col_append_fstr(pinfo->cinfo, COL_INFO,
5676 " (Group=%s, Member=%s)",
5677 tvb_get_string_enc(pinfo->pool, tvb,
5678 group_start, group_len, ENC_UTF_8),
5679 tvb_get_string_enc(pinfo->pool, tvb,
5680 member_start, member_len, ENC_UTF_8));
5682 return offset;
5685 static int
5686 dissect_kafka_sync_group_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5687 kafka_api_version_t api_version _U_)
5689 if (api_version >= 1) {
5690 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
5693 /* error_code */
5694 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
5696 /* protocol_type */
5697 if (api_version >= 5) {
5698 offset = dissect_kafka_compact_string(tree, hf_kafka_protocol_type, tvb, pinfo, offset,
5699 NULL, NULL);
5702 /* protocol_name */
5703 if (api_version >= 5) {
5704 offset = dissect_kafka_compact_string(tree, hf_kafka_protocol_name, tvb, pinfo, offset,
5705 NULL, NULL);
5708 /* member_assignment */
5709 offset = dissect_kafka_bytes(tree, hf_kafka_member_assignment, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
5711 if (api_version >= 4) {
5712 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5715 return offset;
5718 /* DESCRIBE_GROUPS REQUEST/RESPONSE */
5720 static int
5721 dissect_kafka_describe_groups_request_group_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5722 int offset, kafka_api_version_t api_version _U_)
5724 /* group_id */
5725 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5727 return offset;
5730 static int
5731 dissect_kafka_describe_groups_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5732 kafka_api_version_t api_version)
5734 /* [group_id] */
5735 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 5, api_version,
5736 &dissect_kafka_describe_groups_request_group_id, NULL);
5738 if (api_version >= 3) {
5739 proto_tree_add_item(tree, hf_kafka_include_group_authorized_ops, tvb, offset, 1, ENC_BIG_ENDIAN);
5740 offset += 1;
5743 if (api_version >= 5) {
5744 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5747 return offset;
5750 static int
5751 dissect_kafka_describe_groups_response_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5752 kafka_api_version_t api_version _U_)
5754 proto_item *subti;
5755 proto_tree *subtree;
5756 int member_start, member_len = -1;
5757 int instance_start, instance_len = -1;
5759 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group_member, &subti, "Member");
5761 /* member_id */
5762 offset = dissect_kafka_string(subtree, hf_kafka_member_id, tvb, pinfo, offset, api_version >= 5,
5763 &member_start, &member_len);
5765 /* instance_id */
5766 if (api_version >= 4) {
5767 offset = dissect_kafka_string(subtree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, api_version >= 5,
5768 &instance_start, &instance_len);
5771 /* client_id */
5772 offset = dissect_kafka_string(subtree, hf_kafka_client_id, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5774 /* client_host */
5775 offset = dissect_kafka_string(subtree, hf_kafka_client_host, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5777 /* member_metadata */
5778 offset = dissect_kafka_bytes(subtree, hf_kafka_member_metadata, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5780 /* member_assignment */
5781 offset = dissect_kafka_bytes(subtree, hf_kafka_member_assignment, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5783 if (api_version >= 5) {
5784 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5787 proto_item_set_end(subti, tvb, offset);
5789 if (api_version < 4) {
5790 proto_item_append_text(subti, " (Member=%s)",
5791 kafka_tvb_get_string(pinfo->pool, tvb, member_start, member_len));
5793 } else {
5794 proto_item_append_text(subti, " (Member=%s, Instance=%s)",
5795 kafka_tvb_get_string(pinfo->pool, tvb, member_start, member_len),
5796 kafka_tvb_get_string(pinfo->pool, tvb, instance_start, instance_len));
5799 return offset;
5802 static int
5803 dissect_kafka_describe_groups_response_group(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5804 kafka_api_version_t api_version)
5806 proto_item *subti, *subsubti;
5807 proto_tree *subtree, *subsubtree;
5808 int group_start, group_len;
5810 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group, &subti, "Group");
5812 /* error_code */
5813 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
5815 /* group_id */
5816 offset = dissect_kafka_string(subtree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 5,
5817 &group_start, &group_len);
5819 /* state */
5820 offset = dissect_kafka_string(subtree, hf_kafka_group_state, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5822 /* protocol_type */
5823 offset = dissect_kafka_string(subtree, hf_kafka_protocol_type, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5825 /* protocol */
5826 offset = dissect_kafka_string(subtree, hf_kafka_protocol_name, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
5828 /* [member] */
5829 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_group_members,
5830 &subsubti, "Members");
5831 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 5, api_version,
5832 &dissect_kafka_describe_groups_response_member, NULL);
5833 proto_item_set_end(subsubti, tvb, offset);
5835 if (api_version >= 3) {
5836 offset = dissect_kafka_int32(subtree, hf_kafka_group_authorized_ops, tvb, pinfo, offset, NULL);
5839 if (api_version >= 5) {
5840 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5843 proto_item_set_end(subti, tvb, offset);
5844 proto_item_append_text(subti, " (Group=%s)",
5845 kafka_tvb_get_string(pinfo->pool, tvb, group_start, group_len));
5847 return offset;
5850 static int
5851 dissect_kafka_describe_groups_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5852 kafka_api_version_t api_version)
5854 if (api_version >= 1) {
5855 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
5858 /* [group] */
5859 offset = dissect_kafka_array(tree, tvb, pinfo, offset, api_version >= 5, api_version,
5860 &dissect_kafka_describe_groups_response_group, NULL);
5862 if (api_version >= 5) {
5863 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5866 return offset;
5869 /* LIST_GROUPS REQUEST/RESPONSE */
5871 static int
5872 dissect_kafka_list_groups_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5873 kafka_api_version_t api_version)
5876 if (api_version >= 3) {
5877 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5880 return offset;
5883 static int
5884 dissect_kafka_list_groups_response_group(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5885 kafka_api_version_t api_version _U_)
5887 proto_item *subti;
5888 proto_tree *subtree;
5889 int group_start, group_len;
5890 int protocol_type_start, protocol_type_len;
5892 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group, &subti, "Group");
5894 /* group_id */
5895 offset = dissect_kafka_string(subtree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 3,
5896 &group_start, &group_len);
5898 /* protocol_type */
5899 offset = dissect_kafka_string(subtree, hf_kafka_protocol_type, tvb, pinfo, offset, api_version >= 3,
5900 &protocol_type_start, &protocol_type_len);
5902 if (api_version >= 3) {
5903 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
5906 proto_item_set_end(subti, tvb, offset);
5907 proto_item_append_text(subti, " (Group-ID=%s, Protocol-Type=%s)",
5908 tvb_get_string_enc(pinfo->pool, tvb,
5909 group_start, group_len, ENC_UTF_8),
5910 tvb_get_string_enc(pinfo->pool, tvb,
5911 protocol_type_start, protocol_type_len, ENC_UTF_8));
5913 return offset;
5916 static int
5917 dissect_kafka_list_groups_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5918 kafka_api_version_t api_version)
5920 proto_item *subti;
5921 proto_tree *subtree;
5923 if (api_version >= 1) {
5924 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
5927 /* error_code */
5928 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
5930 /* [group] */
5931 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_groups, &subti, "Groups");
5932 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 3, api_version,
5933 &dissect_kafka_list_groups_response_group, NULL);
5934 proto_item_set_end(subti, tvb, offset);
5936 if (api_version >= 3) {
5937 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
5940 return offset;
5943 /* SASL_HANDSHAKE REQUEST/RESPONSE */
5945 static int
5946 dissect_kafka_sasl_handshake_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5947 kafka_api_version_t api_version _U_)
5949 /* mechanism */
5950 offset = dissect_kafka_string(tree, hf_kafka_sasl_mechanism, tvb, pinfo, offset, 0, NULL, NULL);
5952 return offset;
5955 static int
5956 dissect_kafka_sasl_handshake_response_enabled_mechanism(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5957 int offset, kafka_api_version_t api_version _U_)
5959 /* mechanism */
5960 offset = dissect_kafka_string(tree, hf_kafka_sasl_mechanism, tvb, pinfo, offset, 0, NULL, NULL);
5962 return offset;
5965 static int
5966 dissect_kafka_sasl_handshake_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
5967 kafka_api_version_t api_version)
5969 proto_item *subti;
5970 proto_tree *subtree;
5972 /* error_code */
5973 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
5975 /* [enabled_mechanism] */
5976 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
5977 ett_kafka_sasl_enabled_mechanisms,
5978 &subti, "Enabled SASL Mechanisms");
5979 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
5980 &dissect_kafka_sasl_handshake_response_enabled_mechanism, NULL);
5981 proto_item_set_end(subti, tvb, offset);
5983 return offset;
5986 /* CREATE_TOPICS REQUEST/RESPONSE */
5988 static int
5989 dissect_kafka_create_topics_request_replica(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5990 int offset, kafka_api_version_t api_version _U_)
5992 /* replica */
5993 proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
5994 offset += 4;
5996 return offset;
5999 static int
6000 dissect_kafka_create_topics_request_replica_assignment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6001 int offset, kafka_api_version_t api_version)
6003 proto_item *subti;
6004 proto_tree *subtree;
6005 kafka_partition_t partition;
6007 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6008 ett_kafka_replica_assignment,
6009 &subti, "Replica Assignment");
6011 /* partition_id */
6012 dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &partition);
6014 /* [replica] */
6015 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 5, api_version,
6016 &dissect_kafka_create_topics_request_replica, NULL);
6018 if (api_version >= 5) {
6019 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6022 proto_item_set_end(subti, tvb, offset);
6023 proto_item_append_text(subti, " (Partition-ID=%d)",
6024 partition);
6026 return offset;
6029 static int
6030 dissect_kafka_create_topics_request_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6031 int offset, kafka_api_version_t api_version)
6033 proto_item *subti;
6034 proto_tree *subtree;
6035 int key_start, key_len;
6036 int val_start, val_len;
6038 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6039 ett_kafka_config,
6040 &subti, "Config");
6042 /* key */
6043 offset = dissect_kafka_string(subtree, hf_kafka_config_key, tvb, pinfo, offset, api_version >= 5, &key_start, &key_len);
6045 /* value */
6046 offset = dissect_kafka_string(subtree, hf_kafka_config_value, tvb, pinfo, offset, api_version >= 5, &val_start, &val_len);
6048 if (api_version >= 5) {
6049 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
6052 proto_item_set_end(subti, tvb, offset);
6053 proto_item_append_text(subti, " (Key=%s, Value=%s)",
6054 tvb_get_string_enc(pinfo->pool, tvb,
6055 key_start, key_len, ENC_UTF_8),
6056 tvb_get_string_enc(pinfo->pool, tvb,
6057 val_start, val_len, ENC_UTF_8));
6059 return offset;
6062 static int
6063 dissect_kafka_create_topics_request_create_topic_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6064 int offset, kafka_api_version_t api_version)
6066 proto_item *subti, *subsubti;
6067 proto_tree *subtree, *subsubtree;
6068 int topic_start, topic_len;
6070 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6071 ett_kafka_topic,
6072 &subti, "Create Topic Request");
6074 /* topic */
6075 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 5, &topic_start, &topic_len);
6077 /* num_partitions */
6078 proto_tree_add_item(subtree, hf_kafka_num_partitions, tvb, offset, 4, ENC_BIG_ENDIAN);
6079 offset += 4;
6081 /* replication_factor */
6082 proto_tree_add_item(subtree, hf_kafka_replication_factor, tvb, offset, 2, ENC_BIG_ENDIAN);
6083 offset += 2;
6085 /* [replica_assignment] */
6086 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
6087 ett_kafka_replica_assignment,
6088 &subsubti, "Replica Assignments");
6089 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 5, api_version,
6090 &dissect_kafka_create_topics_request_replica_assignment, NULL);
6091 proto_item_set_end(subsubti, tvb, offset);
6093 /* [config] */
6094 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
6095 ett_kafka_config,
6096 &subsubti, "Configs");
6097 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 5, api_version,
6098 &dissect_kafka_create_topics_request_config, NULL);
6099 proto_item_set_end(subsubti, tvb, offset);
6101 if (api_version >= 5) {
6102 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6105 proto_item_set_end(subti, tvb, offset);
6106 proto_item_append_text(subti, " (Topic=%s)",
6107 tvb_get_string_enc(pinfo->pool, tvb,
6108 topic_start, topic_len, ENC_UTF_8));
6110 return offset;
6113 static int
6114 dissect_kafka_create_topics_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6115 kafka_api_version_t api_version)
6117 proto_item *subti;
6118 proto_tree *subtree;
6120 /* [topic] */
6121 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6122 ett_kafka_topics,
6123 &subti, "Create Topic Requests");
6124 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 5, api_version,
6125 &dissect_kafka_create_topics_request_create_topic_request, NULL);
6126 proto_item_set_end(subti, tvb, offset);
6128 /* timeout */
6129 proto_tree_add_item(tree, hf_kafka_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
6130 offset += 4;
6132 if (api_version >= 1) {
6133 /* validate */
6134 proto_tree_add_item(tree, hf_kafka_validate_only, tvb, offset, 1, ENC_NA);
6135 offset += 1;
6138 if (api_version >= 5) {
6139 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6142 return offset;
6145 static int
6146 dissect_kafka_create_topics_response_topic_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6147 int offset, kafka_api_version_t api_version)
6149 proto_item *subti;
6150 proto_tree *subtree;
6152 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6153 ett_kafka_config_entry,
6154 &subti, "Config Entry");
6156 offset = dissect_kafka_string(subtree, hf_kafka_config_key, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
6158 offset = dissect_kafka_string(subtree, hf_kafka_config_value, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
6160 offset = dissect_kafka_int8(subtree, hf_kafka_config_readonly, tvb, pinfo, offset, NULL);
6162 offset = dissect_kafka_int8(subtree, hf_kafka_config_source, tvb, pinfo, offset, NULL);
6164 offset = dissect_kafka_int8(subtree, hf_kafka_config_sensitive, tvb, pinfo, offset, NULL);
6166 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
6168 proto_item_set_end(subti, tvb, offset);
6170 return offset;
6174 static int
6175 dissect_kafka_create_topics_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6176 int offset, kafka_api_version_t api_version)
6178 proto_item *subti, *subsubti;
6179 proto_tree *subtree, *subsubtree;
6180 int topic_start, topic_len;
6181 kafka_error_t error;
6183 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6184 ett_kafka_topic,
6185 &subti, "Topic");
6187 /* topic */
6188 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 5, &topic_start, &topic_len);
6190 /* topic_id */
6191 if (api_version >= 7) {
6192 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
6195 /* error_code */
6196 offset = dissect_kafka_error_ret(tvb, pinfo, subtree, offset, &error);
6198 if (api_version >= 1) {
6199 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 5, NULL, NULL);
6202 if (api_version >= 5) {
6203 offset = dissect_kafka_int32(subtree, hf_kafka_num_partitions, tvb, pinfo, offset, NULL);
6206 if (api_version >= 5) {
6207 offset = dissect_kafka_int16(subtree, hf_kafka_replication_factor, tvb, pinfo, offset, NULL);
6210 if (api_version >= 5) {
6211 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
6212 ett_kafka_config,
6213 &subsubti, "Config");
6214 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 5, api_version,
6215 &dissect_kafka_create_topics_response_topic_config, NULL);
6216 proto_item_set_end(subsubti, tvb, offset);
6219 if (api_version >= 5) {
6220 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6223 proto_item_set_end(subti, tvb, offset);
6224 proto_item_append_text(subti, " (Topic=%s, Error=%s)",
6225 kafka_tvb_get_string(pinfo->pool, tvb, topic_start, topic_len),
6226 kafka_error_to_str(error));
6228 return offset;
6231 static int
6232 dissect_kafka_create_topics_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6233 kafka_api_version_t api_version)
6235 proto_item *subti;
6236 proto_tree *subtree;
6238 if (api_version >= 2) {
6239 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6242 /* [topic_error_code] */
6243 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6244 ett_kafka_topics,
6245 &subti, "Topics");
6246 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 5, api_version,
6247 &dissect_kafka_create_topics_response_topic, NULL);
6248 proto_item_set_end(subti, tvb, offset);
6250 if (api_version >= 5) {
6251 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6254 return offset;
6257 /* DELETE_TOPICS REQUEST/RESPONSE */
6259 static int
6260 dissect_kafka_delete_topics_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6261 int offset, kafka_api_version_t api_version)
6263 proto_item *subti;
6264 proto_tree *subtree;
6266 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6267 ett_kafka_topics,
6268 &subti, "Topic");
6270 if (api_version >= 6) {
6271 /* topic_name */
6272 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
6274 /* topic_id */
6275 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
6278 proto_item_set_end(subti, tvb, offset);
6280 return offset;
6283 static int
6284 dissect_kafka_delete_topics_request_topic_name(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6285 int offset, kafka_api_version_t api_version)
6287 /* topic */
6288 offset = dissect_kafka_string(tree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
6290 return offset;
6293 static int
6294 dissect_kafka_delete_topics_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6295 kafka_api_version_t api_version)
6297 proto_item *subti;
6298 proto_tree *subtree;
6300 /* [topic] */
6301 if (api_version >= 6) {
6302 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6303 ett_kafka_topics,
6304 &subti, "Topics");
6306 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
6307 &dissect_kafka_delete_topics_request_topic, NULL);
6309 if (api_version >= 4) {
6310 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
6313 proto_item_set_end(subti, tvb, offset);
6316 /* [topic_names] */
6317 if (api_version >= 0 && api_version <= 5) {
6318 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6319 ett_kafka_topics,
6320 &subti, "Topics");
6322 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
6323 &dissect_kafka_delete_topics_request_topic_name, NULL);
6325 proto_item_set_end(subti, tvb, offset);
6328 /* timeout */
6329 proto_tree_add_item(tree, hf_kafka_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
6330 offset += 4;
6332 if (api_version >= 4) {
6333 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6336 return offset;
6339 static int
6340 dissect_kafka_delete_topics_response_topic_error_code(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6341 int offset, kafka_api_version_t api_version)
6343 proto_item *subti;
6344 proto_tree *subtree;
6345 int topic_start, topic_len;
6346 kafka_error_t error;
6348 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6349 ett_kafka_topic,
6350 &subti, "Topic Error Code");
6352 /* topic */
6353 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 4, &topic_start, &topic_len);
6355 /* topic_id */
6356 if (api_version >= 6) {
6357 offset = dissect_kafka_uuid(subtree, hf_kafka_topic_id, tvb, pinfo, offset);
6360 /* error_code */
6361 offset = dissect_kafka_error_ret(tvb, pinfo, subtree, offset, &error);
6363 /* error_message */
6364 if (api_version >= 5) {
6365 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
6368 if (api_version >= 4) {
6369 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
6372 proto_item_set_end(subti, tvb, offset);
6373 proto_item_append_text(subti, " (Topic=%s, Error=%s)",
6374 tvb_get_string_enc(pinfo->pool, tvb,
6375 topic_start, topic_len, ENC_UTF_8),
6376 kafka_error_to_str(error));
6378 return offset;
6381 static int
6382 dissect_kafka_delete_topics_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6383 kafka_api_version_t api_version)
6385 proto_item *subti;
6386 proto_tree *subtree;
6388 if (api_version >= 3) {
6389 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6392 /* [topic_error_code] */
6393 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6394 ett_kafka_topics,
6395 &subti, "Topic Error Codes");
6396 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
6397 &dissect_kafka_delete_topics_response_topic_error_code, NULL);
6398 proto_item_set_end(subti, tvb, offset);
6400 if (api_version >= 4) {
6401 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6404 return offset;
6407 /* DELETE_RECORDS REQUEST/RESPONSE */
6409 static int
6410 dissect_kafka_delete_records_request_topic_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
6411 int offset, kafka_api_version_t api_version _U_)
6413 uint32_t partition_id;
6414 int64_t partition_offset;
6415 proto_item *subti;
6416 proto_tree *subtree;
6418 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
6420 partition_id = tvb_get_ntohl(tvb, offset);
6421 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
6422 offset += 4;
6424 partition_offset = tvb_get_ntohi64(tvb, offset);
6425 proto_tree_add_item(subtree, hf_kafka_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
6426 offset += 8;
6428 proto_item_set_end(subti, tvb, offset);
6430 if (partition_offset == -1) {
6431 proto_item_append_text(subti, " (ID=%u, Offset=HWM)", partition_id);
6432 } else {
6433 proto_item_append_text(subti, " (ID=%u, Offset=%" PRIi64 ")", partition_id, partition_offset);
6436 return offset;
6439 static int
6440 dissect_kafka_delete_records_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6441 int offset, kafka_api_version_t api_version _U_)
6443 int topic_start, topic_len;
6444 proto_item *subti, *subsubti;
6445 proto_tree *subtree, *subsubtree;
6447 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
6449 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
6451 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
6452 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
6453 &dissect_kafka_delete_records_request_topic_partition, NULL);
6454 proto_item_set_end(subsubti, tvb, offset);
6456 proto_item_set_end(subti, tvb, offset);
6457 proto_item_append_text(subti, " (Topic=%s)",
6458 tvb_get_string_enc(pinfo->pool, tvb,
6459 topic_start, topic_len, ENC_UTF_8));
6461 return offset;
6464 static int
6465 dissect_kafka_delete_records_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6466 kafka_api_version_t api_version)
6468 proto_item *subti;
6469 proto_tree *subtree;
6471 /* [topic] */
6472 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6473 ett_kafka_topics,
6474 &subti, "Topics");
6475 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
6476 &dissect_kafka_delete_records_request_topic, NULL);
6477 proto_item_set_end(subti, tvb, offset);
6479 /* timeout */
6480 proto_tree_add_item(tree, hf_kafka_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
6481 offset += 4;
6483 return offset;
6486 static int
6487 dissect_kafka_delete_records_response_topic_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
6488 int offset, kafka_api_version_t api_version _U_)
6490 uint32_t partition_id;
6491 int64_t partition_offset; // low watermark
6492 kafka_error_t partition_error_code;
6494 proto_item *subti;
6495 proto_tree *subtree;
6497 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
6499 partition_id = tvb_get_ntohl(tvb, offset);
6500 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
6501 offset += 4;
6503 partition_offset = tvb_get_ntohi64(tvb, offset);
6504 proto_tree_add_item(subtree, hf_kafka_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
6505 offset += 8;
6507 partition_error_code = (kafka_error_t) tvb_get_ntohs(tvb, offset);
6508 proto_tree_add_item(subtree, hf_kafka_error, tvb, offset, 2, ENC_BIG_ENDIAN);
6509 offset += 2;
6511 proto_item_set_end(subti, tvb, offset);
6513 if (partition_error_code == 0) {
6514 proto_item_append_text(subti, " (ID=%u, Offset=%" PRIi64 ")", partition_id, partition_offset);
6515 } else {
6516 proto_item_append_text(subti, " (ID=%u, Error=%s)", partition_id, kafka_error_to_str(partition_error_code));
6519 return offset;
6522 static int
6523 dissect_kafka_delete_records_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6524 int offset, kafka_api_version_t api_version _U_)
6526 int topic_start, topic_len;
6527 proto_item *subti, *subsubti;
6528 proto_tree *subtree, *subsubtree;
6530 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
6532 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
6534 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
6535 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
6536 &dissect_kafka_delete_records_response_topic_partition, NULL);
6537 proto_item_set_end(subsubti, tvb, offset);
6539 proto_item_set_end(subti, tvb, offset);
6540 proto_item_append_text(subti, " (Topic=%s)",
6541 tvb_get_string_enc(pinfo->pool, tvb,
6542 topic_start, topic_len, ENC_UTF_8));
6544 return offset;
6548 static int
6549 dissect_kafka_delete_records_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6550 kafka_api_version_t api_version)
6552 proto_item *subti;
6553 proto_tree *subtree;
6555 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6557 /* [topic_error_code] */
6558 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6559 ett_kafka_topics,
6560 &subti, "Topics");
6561 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
6562 &dissect_kafka_delete_records_response_topic, NULL);
6564 proto_item_set_end(subti, tvb, offset);
6566 return offset;
6569 /* INIT_PRODUCER_ID REQUEST/RESPONSE */
6571 static int
6572 dissect_kafka_init_producer_id_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6573 kafka_api_version_t api_version)
6576 offset = dissect_kafka_string(tree, hf_kafka_transactional_id, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
6578 proto_tree_add_item(tree, hf_kafka_transaction_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
6579 offset += 4;
6581 if (api_version >= 3) {
6582 proto_tree_add_item(tree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
6583 offset += 8;
6586 if (api_version >= 3) {
6587 proto_tree_add_item(tree, hf_kafka_producer_epoch, tvb, offset, 2, ENC_BIG_ENDIAN);
6588 offset += 2;
6591 if (api_version >= 2) {
6592 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6595 return offset;
6599 static int
6600 dissect_kafka_init_producer_id_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6601 kafka_api_version_t api_version)
6603 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6605 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
6607 proto_tree_add_item(tree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
6608 offset += 8;
6610 proto_tree_add_item(tree, hf_kafka_producer_epoch, tvb, offset, 2, ENC_BIG_ENDIAN);
6611 offset += 2;
6613 if (api_version >= 2) {
6614 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
6617 return offset;
6620 /* OFFSET_FOR_LEADER_EPOCH REQUEST/RESPONSE */
6622 static int
6623 dissect_kafka_offset_for_leader_epoch_request_topic_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
6624 int offset, kafka_api_version_t api_version)
6626 uint32_t partition_id;
6627 proto_item *subti;
6628 proto_tree *subtree;
6630 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
6632 partition_id = tvb_get_ntohl(tvb, offset);
6633 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
6634 offset += 4;
6636 if (api_version >= 2) {
6637 proto_tree_add_item(subtree, hf_kafka_current_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
6638 offset += 4;
6641 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
6642 offset += 4;
6644 proto_item_set_end(subti, tvb, offset);
6646 proto_item_append_text(subti, " (ID=%u)", partition_id);
6648 return offset;
6651 static int
6652 dissect_kafka_offset_for_leader_epoch_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6653 int offset, kafka_api_version_t api_version _U_)
6655 int topic_start, topic_len;
6656 proto_item *subti, *subsubti;
6657 proto_tree *subtree, *subsubtree;
6659 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
6661 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
6663 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
6664 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
6665 &dissect_kafka_offset_for_leader_epoch_request_topic_partition, NULL);
6666 proto_item_set_end(subsubti, tvb, offset);
6668 proto_item_set_end(subti, tvb, offset);
6669 proto_item_append_text(subti, " (Name=%s)",
6670 tvb_get_string_enc(pinfo->pool, tvb,
6671 topic_start, topic_len, ENC_UTF_8));
6673 return offset;
6676 static int
6677 dissect_kafka_offset_for_leader_epoch_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6678 kafka_api_version_t api_version)
6680 proto_item *subti;
6681 proto_tree *subtree;
6682 int32_t replica_id;
6684 if (api_version >= 3) {
6685 replica_id = tvb_get_ntohl(tvb, offset);
6686 subti = proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
6687 if (replica_id==-2) {
6688 proto_item_append_text(subti, " (debug)");
6689 } else if (replica_id==-1) {
6690 proto_item_append_text(subti, " (consumer)");
6692 offset += 4;
6695 /* [topic] */
6696 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6697 ett_kafka_topics,
6698 &subti, "Topics");
6699 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
6700 &dissect_kafka_offset_for_leader_epoch_request_topic, NULL);
6701 proto_item_set_end(subti, tvb, offset);
6703 return offset;
6706 static int
6707 dissect_kafka_offset_for_leader_epoch_response_topic_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
6708 int offset, kafka_api_version_t api_version _U_)
6710 uint32_t partition_id;
6711 kafka_error_t partition_error_code;
6713 proto_item *subti;
6714 proto_tree *subtree;
6716 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
6718 partition_error_code = (kafka_error_t) tvb_get_ntohs(tvb, offset);
6719 proto_tree_add_item(subtree, hf_kafka_error, tvb, offset, 2, ENC_BIG_ENDIAN);
6720 offset += 2;
6722 partition_id = tvb_get_ntohl(tvb, offset);
6723 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
6724 offset += 4;
6726 if (api_version >= 1) {
6727 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
6728 offset += 4;
6731 proto_tree_add_item(subtree, hf_kafka_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
6732 offset += 8;
6734 proto_item_set_end(subti, tvb, offset);
6736 if (partition_error_code == 0) {
6737 proto_item_append_text(subti, " (ID=%u)", partition_id);
6738 } else {
6739 proto_item_append_text(subti, " (ID=%u, Error=%s)", partition_id, kafka_error_to_str(partition_error_code));
6742 return offset;
6745 static int
6746 dissect_kafka_offset_for_leader_epoch_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6747 int offset, kafka_api_version_t api_version _U_)
6749 int topic_start, topic_len;
6750 proto_item *subti, *subsubti;
6751 proto_tree *subtree, *subsubtree;
6753 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
6755 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
6757 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
6758 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
6759 &dissect_kafka_offset_for_leader_epoch_response_topic_partition, NULL);
6760 proto_item_set_end(subsubti, tvb, offset);
6762 proto_item_set_end(subti, tvb, offset);
6763 proto_item_append_text(subti, " (Name=%s)",
6764 tvb_get_string_enc(pinfo->pool, tvb,
6765 topic_start, topic_len, ENC_UTF_8));
6767 return offset;
6771 static int
6772 dissect_kafka_offset_for_leader_epoch_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6773 kafka_api_version_t api_version)
6775 proto_item *subti;
6776 proto_tree *subtree;
6778 if (api_version >= 2) {
6779 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6782 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6783 ett_kafka_topics,
6784 &subti, "Topics");
6785 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
6786 &dissect_kafka_offset_for_leader_epoch_response_topic, NULL);
6788 proto_item_set_end(subti, tvb, offset);
6790 return offset;
6793 /* ADD_PARTITIONS_TO_TXN REQUEST/RESPONSE */
6795 static int
6796 dissect_kafka_add_partitions_to_txn_request_topic_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
6797 int offset, kafka_api_version_t api_version _U_)
6799 proto_tree_add_item(tree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
6801 return offset+4;
6804 static int
6805 dissect_kafka_add_partitions_to_txn_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6806 int offset, kafka_api_version_t api_version _U_)
6808 int topic_start, topic_len;
6809 proto_item *subti, *subsubti;
6810 proto_tree *subtree, *subsubtree;
6812 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
6814 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
6816 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
6817 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
6818 &dissect_kafka_add_partitions_to_txn_request_topic_partition, NULL);
6819 proto_item_set_end(subsubti, tvb, offset);
6821 proto_item_set_end(subti, tvb, offset);
6822 proto_item_append_text(subti, " (Topic=%s)",
6823 tvb_get_string_enc(pinfo->pool, tvb,
6824 topic_start, topic_len, ENC_UTF_8));
6826 return offset;
6829 static int
6830 dissect_kafka_add_partitions_to_txn_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6831 kafka_api_version_t api_version)
6833 proto_item *subti;
6834 proto_tree *subtree;
6836 offset = dissect_kafka_string(tree, hf_kafka_transactional_id, tvb, pinfo, offset, 0, NULL, NULL);
6838 proto_tree_add_item(tree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
6839 offset += 8;
6841 proto_tree_add_item(tree, hf_kafka_producer_epoch, tvb, offset, 2, ENC_BIG_ENDIAN);
6842 offset += 2;
6844 /* [topic] */
6845 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6846 ett_kafka_topics,
6847 &subti, "Topics");
6848 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
6849 &dissect_kafka_add_partitions_to_txn_request_topic, NULL);
6850 proto_item_set_end(subti, tvb, offset);
6852 return offset;
6855 static int
6856 dissect_kafka_add_partitions_to_txn_response_topic_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
6857 int offset, kafka_api_version_t api_version _U_)
6859 uint32_t partition_id;
6860 kafka_error_t partition_error_code;
6862 proto_item *subti;
6863 proto_tree *subtree;
6865 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
6867 partition_id = tvb_get_ntohl(tvb, offset);
6868 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
6869 offset += 4;
6871 partition_error_code = (kafka_error_t) tvb_get_ntohs(tvb, offset);
6872 proto_tree_add_item(subtree, hf_kafka_error, tvb, offset, 2, ENC_BIG_ENDIAN);
6873 offset += 2;
6875 proto_item_set_end(subti, tvb, offset);
6877 if (partition_error_code == 0) {
6878 proto_item_append_text(subti, " (ID=%u)", partition_id);
6879 } else {
6880 proto_item_append_text(subti, " (ID=%u, Error=%s)", partition_id, kafka_error_to_str(partition_error_code));
6883 return offset;
6886 static int
6887 dissect_kafka_add_partitions_to_txn_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6888 int offset, kafka_api_version_t api_version _U_)
6890 int topic_start, topic_len;
6891 proto_item *subti, *subsubti;
6892 proto_tree *subtree, *subsubtree;
6894 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
6896 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
6898 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
6899 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
6900 &dissect_kafka_add_partitions_to_txn_response_topic_partition, NULL);
6901 proto_item_set_end(subsubti, tvb, offset);
6903 proto_item_set_end(subti, tvb, offset);
6904 proto_item_append_text(subti, " (Topic=%s)",
6905 tvb_get_string_enc(pinfo->pool, tvb,
6906 topic_start, topic_len, ENC_UTF_8));
6908 return offset;
6912 static int
6913 dissect_kafka_add_partitions_to_txn_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6914 kafka_api_version_t api_version)
6916 proto_item *subti;
6917 proto_tree *subtree;
6919 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6921 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
6922 ett_kafka_topics,
6923 &subti, "Topics");
6924 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
6925 &dissect_kafka_add_partitions_to_txn_response_topic, NULL);
6927 proto_item_set_end(subti, tvb, offset);
6929 return offset;
6932 /* ADD_OFFSETS_TO_TXN REQUEST/RESPONSE */
6934 static int
6935 dissect_kafka_add_offsets_to_txn_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6936 kafka_api_version_t api_version _U_)
6938 offset = dissect_kafka_string(tree, hf_kafka_transactional_id, tvb, pinfo, offset, 0, NULL, NULL);
6940 proto_tree_add_item(tree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
6941 offset += 8;
6943 proto_tree_add_item(tree, hf_kafka_producer_epoch, tvb, offset, 2, ENC_BIG_ENDIAN);
6944 offset += 2;
6946 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, 0, NULL, NULL);
6948 return offset;
6952 static int
6953 dissect_kafka_add_offsets_to_txn_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6954 kafka_api_version_t api_version _U_)
6956 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6958 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
6960 return offset;
6963 /* END_TXN REQUEST/RESPONSE */
6965 static int
6966 dissect_kafka_end_txn_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6967 kafka_api_version_t api_version _U_)
6969 offset = dissect_kafka_string(tree, hf_kafka_transactional_id, tvb, pinfo, offset, 0, NULL, NULL);
6971 proto_tree_add_item(tree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
6972 offset += 8;
6974 proto_tree_add_item(tree, hf_kafka_producer_epoch, tvb, offset, 2, ENC_BIG_ENDIAN);
6975 offset += 2;
6977 proto_tree_add_item(tree, hf_kafka_transaction_result, tvb, offset, 1, ENC_BIG_ENDIAN);
6978 offset += 1;
6980 return offset;
6984 static int
6985 dissect_kafka_end_txn_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
6986 kafka_api_version_t api_version _U_)
6988 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
6990 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
6992 return offset;
6995 /* WRITE_TXN_MARKERS REQUEST/RESPONSE */
6997 static int
6998 dissect_kafka_write_txn_markers_request_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
6999 int offset, kafka_api_version_t api_version _U_)
7001 proto_tree_add_item(tree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
7002 offset += 4;
7004 return offset;
7007 static int
7008 dissect_kafka_write_txn_markers_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7009 int offset, kafka_api_version_t api_version)
7011 int topic_start, topic_len;
7012 proto_item *subti, *subsubti;
7013 proto_tree *subtree, *subsubtree;
7015 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
7017 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
7019 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
7020 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
7021 &dissect_kafka_write_txn_markers_request_partition, NULL);
7022 proto_item_set_end(subsubti, tvb, offset);
7024 proto_item_set_end(subti, tvb, offset);
7025 proto_item_append_text(subti, " (Topic=%s)",
7026 tvb_get_string_enc(pinfo->pool, tvb,
7027 topic_start, topic_len, ENC_UTF_8));
7029 return offset;
7032 static int
7033 dissect_kafka_write_txn_markers_request_marker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7034 kafka_api_version_t api_version)
7036 uint64_t producer_id;
7037 proto_item *subti, *subsubti;
7038 proto_tree *subtree, *subsubtree;
7040 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7041 ett_kafka_marker,
7042 &subti, "Marker");
7044 producer_id = tvb_get_ntoh64(tvb, offset);
7045 proto_tree_add_item(subtree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
7046 offset += 8;
7048 proto_tree_add_item(subtree, hf_kafka_producer_epoch, tvb, offset, 2, ENC_BIG_ENDIAN);
7049 offset += 2;
7051 proto_tree_add_item(subtree, hf_kafka_transaction_result, tvb, offset, 1, ENC_BIG_ENDIAN);
7052 offset += 1;
7054 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
7055 ett_kafka_topics,
7056 &subsubti, "Topics");
7057 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
7058 &dissect_kafka_write_txn_markers_request_topic, NULL);
7060 proto_tree_add_item(subsubtree, hf_kafka_coordinator_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
7061 offset += 4;
7063 proto_item_set_end(subsubti, tvb, offset);
7064 proto_item_set_end(subti, tvb, offset);
7065 proto_item_append_text(subti, " (Producer=%" PRIu64 ")", producer_id);
7067 return offset;
7070 static int
7071 dissect_kafka_write_txn_markers_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7072 kafka_api_version_t api_version)
7074 proto_item *subti;
7075 proto_tree *subtree;
7077 /* [topic] */
7078 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7079 ett_kafka_markers,
7080 &subti, "Markers");
7081 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
7082 &dissect_kafka_write_txn_markers_request_marker, NULL);
7083 proto_item_set_end(subti, tvb, offset);
7085 return offset;
7088 static int
7089 dissect_kafka_write_txn_markers_response_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7090 int offset, kafka_api_version_t api_version _U_)
7092 uint32_t partition_id;
7093 kafka_error_t partition_error_code;
7095 proto_item *subti;
7096 proto_tree *subtree;
7098 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
7100 partition_id = tvb_get_ntohl(tvb, offset);
7101 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
7102 offset += 4;
7104 partition_error_code = (kafka_error_t) tvb_get_ntohs(tvb, offset);
7105 proto_tree_add_item(subtree, hf_kafka_error, tvb, offset, 2, ENC_BIG_ENDIAN);
7106 offset += 2;
7108 proto_item_set_end(subti, tvb, offset);
7110 if (partition_error_code == 0) {
7111 proto_item_append_text(subti, " (ID=%u", partition_id);
7112 } else {
7113 proto_item_append_text(subti, " (ID=%u, Error=%s)", partition_id, kafka_error_to_str(partition_error_code));
7116 return offset;
7119 static int
7120 dissect_kafka_write_txn_markers_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7121 int offset, kafka_api_version_t api_version _U_)
7123 int topic_start, topic_len;
7124 proto_item *subti, *subsubti;
7125 proto_tree *subtree, *subsubtree;
7127 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
7129 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
7131 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
7132 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
7133 &dissect_kafka_write_txn_markers_response_partition, NULL);
7134 proto_item_set_end(subsubti, tvb, offset);
7136 proto_item_set_end(subti, tvb, offset);
7137 proto_item_append_text(subti, " (Topic=%s)",
7138 tvb_get_string_enc(pinfo->pool, tvb,
7139 topic_start, topic_len, ENC_UTF_8));
7141 return offset;
7144 static int
7145 dissect_kafka_write_txn_markers_response_marker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7146 int offset, kafka_api_version_t api_version _U_)
7148 uint64_t producer_id;
7149 proto_item *subti, *subsubti;
7150 proto_tree *subtree, *subsubtree;
7152 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_marker, &subti, "Marker");
7154 producer_id = tvb_get_ntoh64(tvb, offset);
7155 proto_tree_add_item(subtree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
7156 offset += 8;
7158 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Topics");
7159 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
7160 &dissect_kafka_write_txn_markers_response_topic, NULL);
7161 proto_item_set_end(subsubti, tvb, offset);
7163 proto_item_set_end(subti, tvb, offset);
7164 proto_item_append_text(subti, " (Producer=%" PRIu64 ")", producer_id);
7166 return offset;
7169 static int
7170 dissect_kafka_write_txn_markers_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7171 kafka_api_version_t api_version)
7173 proto_item *subti;
7174 proto_tree *subtree;
7176 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
7178 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7179 ett_kafka_markers,
7180 &subti, "Markers");
7181 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
7182 &dissect_kafka_write_txn_markers_response_marker, NULL);
7184 proto_item_set_end(subti, tvb, offset);
7186 return offset;
7189 /* TXN_OFFSET_COMMIT REQUEST/RESPONSE */
7191 static int
7192 dissect_kafka_txn_offset_commit_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7193 int offset, kafka_api_version_t api_version)
7195 uint32_t partition_id;
7196 int64_t partition_offset;
7197 proto_item *subti;
7198 proto_tree *subtree;
7200 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
7202 partition_id = tvb_get_ntohl(tvb, offset);
7203 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
7204 offset += 4;
7206 partition_offset = tvb_get_ntohi64(tvb, offset);
7207 proto_tree_add_item(subtree, hf_kafka_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
7208 offset += 8;
7210 if (api_version >= 2) {
7211 proto_tree_add_item(subtree, hf_kafka_leader_epoch, tvb, offset, 4, ENC_BIG_ENDIAN);
7212 offset += 4;
7215 offset = dissect_kafka_string(subtree, hf_kafka_metadata, tvb, pinfo, offset, api_version >= 3, NULL, NULL);
7217 if (api_version >= 3) {
7218 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7221 proto_item_set_end(subti, tvb, offset);
7223 proto_item_append_text(subti, " (ID=%u, Offset=%" PRIi64 ")", partition_id, partition_offset);
7225 return offset;
7228 static int
7229 dissect_kafka_txn_offset_commit_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7230 int offset, kafka_api_version_t api_version)
7232 int topic_start, topic_len;
7233 proto_item *subti, *subsubti;
7234 proto_tree *subtree, *subsubtree;
7236 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
7238 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 3, &topic_start, &topic_len);
7240 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
7241 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 3, api_version,
7242 &dissect_kafka_txn_offset_commit_request_partition, NULL);
7243 proto_item_set_end(subsubti, tvb, offset);
7246 if (api_version >= 3) {
7247 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7250 proto_item_set_end(subti, tvb, offset);
7251 proto_item_append_text(subti, " (Topic=%s)",
7252 tvb_get_string_enc(pinfo->pool, tvb,
7253 topic_start, topic_len, ENC_UTF_8));
7255 return offset;
7258 static int
7259 dissect_kafka_txn_offset_commit_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7260 kafka_api_version_t api_version)
7262 proto_item *subti;
7263 proto_tree *subtree;
7265 offset = dissect_kafka_string(tree, hf_kafka_transactional_id, tvb, pinfo, offset, api_version >= 3, NULL, NULL);
7267 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 3, NULL, NULL);
7269 proto_tree_add_item(tree, hf_kafka_producer_id, tvb, offset, 8, ENC_BIG_ENDIAN);
7270 offset += 8;
7272 proto_tree_add_item(tree, hf_kafka_producer_epoch, tvb, offset, 2, ENC_BIG_ENDIAN);
7273 offset += 2;
7275 if (api_version >= 3) {
7276 proto_tree_add_item(tree, hf_kafka_generation_id, tvb, offset, 4, ENC_BIG_ENDIAN);
7277 offset += 4;
7280 if (api_version >= 3) {
7281 offset = dissect_kafka_string(tree, hf_kafka_member_id, tvb, pinfo, offset, 1,NULL, NULL);
7284 if (api_version >= 3) {
7285 offset = dissect_kafka_string(tree, hf_kafka_consumer_group_instance, tvb, pinfo, offset, 1,NULL, NULL);
7288 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7289 ett_kafka_topics,
7290 &subti, "Topics");
7291 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 3, api_version,
7292 &dissect_kafka_txn_offset_commit_request_topic, NULL);
7293 proto_item_set_end(subti, tvb, offset);
7295 if (api_version >= 3) {
7296 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7299 return offset;
7302 static int
7303 dissect_kafka_txn_offset_commit_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7304 int offset, kafka_api_version_t api_version)
7306 uint32_t partition_id;
7307 kafka_error_t partition_error_code;
7309 proto_item *subti;
7310 proto_tree *subtree;
7312 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
7314 partition_id = tvb_get_ntohl(tvb, offset);
7315 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
7316 offset += 4;
7318 partition_error_code = (kafka_error_t) tvb_get_ntohs(tvb, offset);
7319 proto_tree_add_item(subtree, hf_kafka_error, tvb, offset, 2, ENC_BIG_ENDIAN);
7320 offset += 2;
7322 if (api_version >= 3) {
7323 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7326 proto_item_set_end(subti, tvb, offset);
7328 if (partition_error_code == 0) {
7329 proto_item_append_text(subti, " (ID=%u)", partition_id);
7330 } else {
7331 proto_item_append_text(subti, " (ID=%u, Error=%s)", partition_id, kafka_error_to_str(partition_error_code));
7334 return offset;
7337 static int
7338 dissect_kafka_txn_offset_commit_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7339 int offset, kafka_api_version_t api_version)
7341 int topic_start, topic_len;
7342 proto_item *subti, *subsubti;
7343 proto_tree *subtree, *subsubtree;
7345 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
7347 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 3, &topic_start, &topic_len);
7349 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
7350 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 3, api_version,
7351 &dissect_kafka_txn_offset_commit_response_partition, NULL);
7352 proto_item_set_end(subsubti, tvb, offset);
7354 if (api_version >= 3) {
7355 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7358 proto_item_set_end(subti, tvb, offset);
7359 proto_item_append_text(subti, " (Topic=%s)",
7360 tvb_get_string_enc(pinfo->pool, tvb,
7361 topic_start, topic_len, ENC_UTF_8));
7363 return offset;
7367 static int
7368 dissect_kafka_txn_offset_commit_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7369 kafka_api_version_t api_version)
7371 proto_item *subti;
7372 proto_tree *subtree;
7374 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
7376 /* [topic_error_code] */
7377 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7378 ett_kafka_topics,
7379 &subti, "Topics");
7380 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 3, api_version,
7381 &dissect_kafka_txn_offset_commit_response_topic, NULL);
7382 proto_item_set_end(subti, tvb, offset);
7384 if (api_version >= 3) {
7385 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7388 return offset;
7391 /* DESCRIBE_ACLS REQUEST/RESPONSE */
7393 static int
7394 dissect_kafka_describe_acls_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7395 kafka_api_version_t api_version)
7398 offset = dissect_kafka_int8(tree, hf_kafka_acl_resource_type, tvb, pinfo, offset, NULL);
7400 offset = dissect_kafka_string(tree, hf_kafka_acl_resource_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7402 if (api_version >= 1) {
7403 offset = dissect_kafka_int8(tree, hf_kafka_acl_resource_pattern_type, tvb, pinfo, offset, NULL);
7406 offset = dissect_kafka_string(tree, hf_kafka_acl_principal, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7408 offset = dissect_kafka_string(tree, hf_kafka_acl_host, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7410 offset = dissect_kafka_int8(tree, hf_kafka_acl_operation, tvb, pinfo, offset, NULL);
7412 offset = dissect_kafka_int8(tree, hf_kafka_acl_permission_type, tvb, pinfo, offset, NULL);
7414 if (api_version >= 2) {
7415 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7418 return offset;
7421 static int
7422 dissect_kafka_describe_acls_response_resource_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7423 int offset, kafka_api_version_t api_version)
7425 proto_item *subti;
7426 proto_tree *subtree;
7428 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_acl, &subti, "ACL");
7430 offset = dissect_kafka_string(subtree, hf_kafka_acl_principal, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7432 offset = dissect_kafka_string(subtree, hf_kafka_acl_host, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7434 offset = dissect_kafka_int8(subtree, hf_kafka_acl_operation, tvb, pinfo, offset, NULL);
7436 offset = dissect_kafka_int8(subtree, hf_kafka_acl_permission_type, tvb, pinfo, offset, NULL);
7438 if (api_version >= 2) {
7439 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7442 return offset;
7445 static int
7446 dissect_kafka_describe_acls_response_resource(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7447 int offset, kafka_api_version_t api_version)
7449 proto_item *subti, *subsubti;
7450 proto_tree *subtree, *subsubtree;
7452 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Resource");
7454 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_type, tvb, pinfo, offset, NULL);
7456 offset = dissect_kafka_string(subtree, hf_kafka_acl_resource_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7458 if (api_version >= 1) {
7459 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_pattern_type, tvb, pinfo, offset, NULL);
7462 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_acls, &subsubti, "ACLs");
7463 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
7464 &dissect_kafka_describe_acls_response_resource_acl, NULL);
7465 proto_item_set_end(subsubti, tvb, offset);
7467 if (api_version >= 2) {
7468 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7471 proto_item_set_end(subti, tvb, offset);
7473 return offset;
7477 static int
7478 dissect_kafka_describe_acls_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7479 kafka_api_version_t api_version)
7481 proto_item *subti;
7482 proto_tree *subtree;
7484 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
7486 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
7488 offset = dissect_kafka_string(tree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7490 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7491 ett_kafka_resources,
7492 &subti, "Resources");
7493 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
7494 &dissect_kafka_describe_acls_response_resource, NULL);
7496 if (api_version >= 2) {
7497 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7500 proto_item_set_end(subti, tvb, offset);
7502 return offset;
7505 /* CREATE_ACLS REQUEST/RESPONSE */
7507 static int
7508 dissect_kafka_create_acls_request_creation(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7509 int offset, kafka_api_version_t api_version _U_)
7511 proto_item *subti;
7512 proto_tree *subtree;
7514 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_acl_creation, &subti, "Creation");
7516 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_type, tvb, pinfo, offset, NULL);
7518 offset = dissect_kafka_string(subtree, hf_kafka_acl_resource_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7520 if (api_version >= 1) {
7521 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_pattern_type, tvb, pinfo, offset, NULL);
7524 offset = dissect_kafka_string(subtree, hf_kafka_acl_principal, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7526 offset = dissect_kafka_string(subtree, hf_kafka_acl_host, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7528 offset = dissect_kafka_int8(subtree, hf_kafka_acl_operation, tvb, pinfo, offset, NULL);
7530 offset = dissect_kafka_int8(subtree, hf_kafka_acl_permission_type, tvb, pinfo, offset, NULL);
7532 if (api_version >= 2) {
7533 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7536 proto_item_set_end(subti, tvb, offset);
7538 return offset;
7541 static int
7542 dissect_kafka_create_acls_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7543 kafka_api_version_t api_version)
7545 proto_item *subti;
7546 proto_tree *subtree;
7548 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7549 ett_kafka_acl_creations,
7550 &subti, "Creations");
7551 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2 , api_version,
7552 &dissect_kafka_create_acls_request_creation, NULL);
7553 proto_item_set_end(subti, tvb, offset);
7555 if (api_version >= 2) {
7556 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7559 return offset;
7562 static int
7563 dissect_kafka_create_acls_response_creation(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7564 int offset, kafka_api_version_t api_version _U_)
7566 proto_item *subti;
7567 proto_tree *subtree;
7569 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_acl_creation, &subti, "Creation");
7571 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
7573 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7575 if (api_version >= 2) {
7576 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7579 proto_item_set_end(subti, tvb, offset);
7581 return offset;
7584 static int
7585 dissect_kafka_create_acls_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7586 kafka_api_version_t api_version)
7588 proto_item *subti;
7589 proto_tree *subtree;
7591 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
7593 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7594 ett_kafka_acl_creations,
7595 &subti, "Creations");
7596 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
7597 &dissect_kafka_create_acls_response_creation, NULL);
7598 proto_item_set_end(subti, tvb, offset);
7600 if (api_version >= 2) {
7601 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7604 return offset;
7607 /* DELETE_ACLS REQUEST/RESPONSE */
7609 static int
7610 dissect_kafka_delete_acls_request_filter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7611 int offset, kafka_api_version_t api_version _U_)
7613 proto_item *subti;
7614 proto_tree *subtree;
7616 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_acl_filter, &subti, "Filter");
7618 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_type, tvb, pinfo, offset, NULL);
7620 offset = dissect_kafka_string(subtree, hf_kafka_acl_resource_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7622 if (api_version >= 1) {
7623 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_pattern_type, tvb, pinfo, offset, NULL);
7626 offset = dissect_kafka_string(subtree, hf_kafka_acl_principal, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7628 offset = dissect_kafka_string(subtree, hf_kafka_acl_host, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7630 offset = dissect_kafka_int8(subtree, hf_kafka_acl_operation, tvb, pinfo, offset, NULL);
7632 offset = dissect_kafka_int8(subtree, hf_kafka_acl_permission_type, tvb, pinfo, offset, NULL);
7634 if (api_version >= 2) {
7635 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7638 proto_item_set_end(subti, tvb, offset);
7640 return offset;
7643 static int
7644 dissect_kafka_delete_acls_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7645 kafka_api_version_t api_version)
7647 proto_item *subti;
7648 proto_tree *subtree;
7650 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7651 ett_kafka_acl_filter,
7652 &subti, "Filters");
7653 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
7654 &dissect_kafka_delete_acls_request_filter, NULL);
7655 proto_item_set_end(subti, tvb, offset);
7657 if (api_version >= 2) {
7658 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7661 return offset;
7664 static int
7665 dissect_kafka_delete_acls_response_match(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7666 int offset, kafka_api_version_t api_version _U_)
7668 proto_item *subti;
7669 proto_tree *subtree;
7671 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_acl_filter_match, &subti, "Match");
7673 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
7675 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7677 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_type, tvb, pinfo, offset, NULL);
7679 offset = dissect_kafka_string(subtree, hf_kafka_acl_resource_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7681 if (api_version >= 1) {
7682 offset = dissect_kafka_int8(subtree, hf_kafka_acl_resource_pattern_type, tvb, pinfo, offset, NULL);
7685 offset = dissect_kafka_string(subtree, hf_kafka_acl_principal, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7687 offset = dissect_kafka_string(subtree, hf_kafka_acl_host, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7689 offset = dissect_kafka_int8(subtree, hf_kafka_acl_operation, tvb, pinfo, offset, NULL);
7691 offset = dissect_kafka_int8(subtree, hf_kafka_acl_permission_type, tvb, pinfo, offset, NULL);
7693 if (api_version >= 2) {
7694 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7697 proto_item_set_end(subti, tvb, offset);
7699 return offset;
7702 static int
7703 dissect_kafka_delete_acls_response_filter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7704 int offset, kafka_api_version_t api_version _U_)
7706 proto_item *subti, *subsubti;
7707 proto_tree *subtree, *subsubtree;
7709 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_acl_creation, &subti, "Filter");
7711 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
7713 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
7715 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
7716 ett_kafka_acl_filter_matches,
7717 &subsubti, "Matches");
7718 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
7719 &dissect_kafka_delete_acls_response_match, NULL);
7721 proto_item_set_end(subsubti, tvb, offset);
7723 if (api_version >= 2) {
7724 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7727 proto_item_set_end(subti, tvb, offset);
7729 return offset;
7732 static int
7733 dissect_kafka_delete_acls_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7734 kafka_api_version_t api_version)
7736 proto_item *subti;
7737 proto_tree *subtree;
7739 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
7741 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7742 ett_kafka_acl_creations,
7743 &subti, "Filters");
7744 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 0, api_version,
7745 &dissect_kafka_delete_acls_response_filter, NULL);
7746 proto_item_set_end(subti, tvb, offset);
7748 if (api_version >= 2) {
7749 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7752 return offset;
7755 /* DESCRIBE_CONFIGS REQUEST/RESPONSE */
7757 static int
7758 dissect_kafka_describe_config_request_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7759 int offset, kafka_api_version_t api_version _U_)
7761 offset = dissect_kafka_string(tree, hf_kafka_config_key, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
7763 return offset;
7766 static int
7767 dissect_kafka_describe_config_request_resource(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7768 int offset, kafka_api_version_t api_version)
7770 proto_item *subti, *subsubti;
7771 proto_tree *subtree, *subsubtree;
7773 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Resource");
7775 proto_tree_add_item(subtree, hf_kafka_config_resource_type, tvb, offset, 1, ENC_BIG_ENDIAN);
7776 offset += 1;
7778 offset = dissect_kafka_string(subtree, hf_kafka_config_resource_name, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
7780 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_config_entries, &subsubti, "Entries");
7782 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 4, api_version,
7783 &dissect_kafka_describe_config_request_entry, NULL);
7785 if (api_version >= 4) {
7786 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7789 proto_item_set_end(subti, tvb, offset);
7791 return offset;
7794 static int
7795 dissect_kafka_describe_configs_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7796 kafka_api_version_t api_version)
7798 proto_item *subti;
7799 proto_tree *subtree;
7801 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7802 ett_kafka_resources,
7803 &subti, "Resources");
7804 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
7805 &dissect_kafka_describe_config_request_resource, NULL);
7807 proto_item_set_end(subti, tvb, offset);
7809 if (api_version >= 1) {
7810 proto_tree_add_item(tree, hf_kafka_config_include_synonyms, tvb, offset, 1, ENC_BIG_ENDIAN);
7811 offset += 1;
7814 if (api_version >= 3) {
7815 offset = dissect_kafka_bool(tree, hf_kafka_config_include_documentation, tvb, pinfo, offset);
7818 if (api_version >= 4) {
7819 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7822 return offset;
7825 static int
7826 dissect_kafka_describe_configs_response_synonym(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7827 int offset, kafka_api_version_t api_version _U_)
7829 proto_item *subti;
7830 proto_tree *subtree;
7831 int key_start, key_len;
7833 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_config_synonym, &subti, "Synonym");
7835 offset = dissect_kafka_string(subtree, hf_kafka_config_key, tvb, pinfo, offset, 0, &key_start, &key_len);
7836 offset = dissect_kafka_string(subtree, hf_kafka_config_value, tvb, pinfo, offset, 0, NULL, NULL);
7838 proto_tree_add_item(subtree, hf_kafka_config_source, tvb, offset, 1, ENC_BIG_ENDIAN);
7839 offset += 1;
7841 if (api_version >= 4) {
7842 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7845 proto_item_set_end(subti, tvb, offset);
7846 proto_item_append_text(subti, " (Key=%s)",
7847 tvb_get_string_enc(pinfo->pool, tvb,
7848 key_start, key_len, ENC_UTF_8));
7850 return offset;
7853 static int
7854 dissect_kafka_describe_configs_response_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7855 int offset, kafka_api_version_t api_version _U_)
7857 proto_item *subti, *subsubti;
7858 proto_tree *subtree, *subsubtree;
7859 int key_start, key_len;
7861 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_config_entry, &subti, "Entry");
7863 offset = dissect_kafka_string(subtree, hf_kafka_config_key, tvb, pinfo, offset, api_version >= 4, &key_start, &key_len);
7864 offset = dissect_kafka_string(subtree, hf_kafka_config_value, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
7866 proto_tree_add_item(subtree, hf_kafka_config_readonly, tvb, offset, 1, ENC_BIG_ENDIAN);
7867 offset += 1;
7869 if (api_version == 0) {
7870 proto_tree_add_item(subtree, hf_kafka_config_default, tvb, offset, 1, ENC_BIG_ENDIAN);
7871 offset += 1;
7872 } else {
7873 proto_tree_add_item(subtree, hf_kafka_config_source, tvb, offset, 1, ENC_BIG_ENDIAN);
7874 offset += 1;
7877 proto_tree_add_item(subtree, hf_kafka_config_sensitive, tvb, offset, 1, ENC_BIG_ENDIAN);
7878 offset += 1;
7880 if (api_version >= 1) {
7881 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
7882 ett_kafka_config_synonyms,
7883 &subsubti, "Synonyms");
7884 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 4, api_version,
7885 &dissect_kafka_describe_configs_response_synonym, NULL);
7887 proto_item_set_end(subsubti, tvb, offset);
7890 if (api_version >= 3) {
7891 offset = dissect_kafka_int8(subtree, hf_kafka_config_data_type, tvb, pinfo, offset, NULL);
7893 offset = dissect_kafka_string(subtree, hf_kafka_config_documentation, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
7896 if (api_version >= 4) {
7897 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7900 proto_item_set_end(subti, tvb, offset);
7901 proto_item_append_text(subti, " (Key=%s)",
7902 tvb_get_string_enc(pinfo->pool, tvb,
7903 key_start, key_len, ENC_UTF_8));
7905 return offset;
7908 static int
7909 dissect_kafka_describe_configs_response_resource(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7910 int offset, kafka_api_version_t api_version _U_)
7912 proto_item *subti, *subsubti;
7913 proto_tree *subtree, *subsubtree;
7915 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Resource");
7917 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
7919 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
7921 proto_tree_add_item(subtree, hf_kafka_config_resource_type, tvb, offset, 1, ENC_BIG_ENDIAN);
7922 offset += 1;
7924 offset = dissect_kafka_string(subtree, hf_kafka_config_resource_name, tvb, pinfo, offset, api_version >= 4, NULL, NULL);
7926 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
7927 ett_kafka_config_entries,
7928 &subsubti, "Entries");
7929 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 4, api_version,
7930 &dissect_kafka_describe_configs_response_entry, NULL);
7932 proto_item_set_end(subsubti, tvb, offset);
7934 if (api_version >= 4) {
7935 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
7938 proto_item_set_end(subti, tvb, offset);
7940 return offset;
7943 static int
7944 dissect_kafka_describe_configs_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
7945 kafka_api_version_t api_version)
7947 proto_item *subti;
7948 proto_tree *subtree;
7950 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
7952 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
7953 ett_kafka_resources,
7954 &subti, "Resources");
7955 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 4, api_version,
7956 &dissect_kafka_describe_configs_response_resource, NULL);
7958 proto_item_set_end(subti, tvb, offset);
7960 if (api_version >= 4) {
7961 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
7964 return offset;
7967 /* ALTER_CONFIGS REQUEST/RESPONSE */
7969 static int
7970 dissect_kafka_alter_config_request_entry(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7971 int offset, kafka_api_version_t api_version _U_)
7973 proto_item *subti;
7974 proto_tree *subtree;
7976 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_config_entry, &subti, "Entry");
7978 offset = dissect_kafka_string(subtree, hf_kafka_config_key, tvb, pinfo, offset, 0, NULL, NULL);
7979 offset = dissect_kafka_string(subtree, hf_kafka_config_value, tvb, pinfo, offset, 0, NULL, NULL);
7981 proto_item_set_end(subti, tvb, offset);
7983 return offset;
7986 static int
7987 dissect_kafka_alter_config_request_resource(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
7988 int offset, kafka_api_version_t api_version _U_)
7990 proto_item *subti, *subsubti;
7991 proto_tree *subtree, *subsubtree;
7993 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Resource");
7995 proto_tree_add_item(subtree, hf_kafka_config_resource_type, tvb, offset, 1, ENC_BIG_ENDIAN);
7996 offset += 1;
7998 offset = dissect_kafka_string(subtree, hf_kafka_config_resource_name, tvb, pinfo, offset, 0, NULL, NULL);
8000 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_config_entries, &subsubti, "Entries");
8002 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
8003 &dissect_kafka_alter_config_request_entry, NULL);
8005 proto_item_set_end(subti, tvb, offset);
8007 return offset;
8010 static int
8011 dissect_kafka_alter_configs_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8012 kafka_api_version_t api_version)
8014 proto_item *subti;
8015 proto_tree *subtree;
8017 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8018 ett_kafka_resources,
8019 &subti, "Resources");
8020 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
8021 &dissect_kafka_alter_config_request_resource, NULL);
8023 proto_tree_add_item(subtree, hf_kafka_validate_only, tvb, offset, 1, ENC_BIG_ENDIAN);
8024 offset += 1;
8026 proto_item_set_end(subti, tvb, offset);
8028 return offset;
8031 static int
8032 dissect_kafka_alter_configs_response_resource(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
8033 int offset, kafka_api_version_t api_version _U_)
8035 proto_item *subti;
8036 proto_tree *subtree;
8038 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Resource");
8040 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
8042 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, 0, NULL, NULL);
8044 proto_tree_add_item(subtree, hf_kafka_config_resource_type, tvb, offset, 1, ENC_BIG_ENDIAN);
8045 offset += 1;
8047 offset = dissect_kafka_string(subtree, hf_kafka_config_resource_name, tvb, pinfo, offset, 0, NULL, NULL);
8049 proto_item_set_end(subti, tvb, offset);
8051 return offset;
8054 static int
8055 dissect_kafka_alter_configs_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8056 kafka_api_version_t api_version)
8058 proto_item *subti;
8059 proto_tree *subtree;
8061 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8063 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8064 ett_kafka_resources,
8065 &subti, "Resources");
8066 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
8067 &dissect_kafka_alter_configs_response_resource, NULL);
8069 proto_item_set_end(subti, tvb, offset);
8071 return offset;
8074 /* ALTER_REPLICA_LOG_DIRS REQUEST/RESPONSE */
8076 static int
8077 dissect_kafka_alter_replica_log_dirs_request_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
8078 int offset, kafka_api_version_t api_version _U_)
8080 proto_tree_add_item(tree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
8081 offset += 4;
8083 return offset;
8086 static int
8087 dissect_kafka_alter_replica_log_dirs_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8088 int offset, kafka_api_version_t api_version _U_)
8090 proto_item *subti, *subsubti;
8091 proto_tree *subtree, *subsubtree;
8092 int topic_start, topic_len;
8094 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Topic");
8096 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
8098 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &subsubti, "Partitions");
8100 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
8101 &dissect_kafka_alter_replica_log_dirs_request_partition, NULL);
8103 proto_item_set_end(subti, tvb, offset);
8104 proto_item_append_text(subti, " (Name=%s)",
8105 tvb_get_string_enc(pinfo->pool, tvb,
8106 topic_start, topic_len, ENC_UTF_8));
8108 return offset;
8111 static int
8112 dissect_kafka_alter_replica_log_dirs_request_log_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8113 int offset, kafka_api_version_t api_version)
8115 proto_item *subti, *subsubti;
8116 proto_tree *subtree, *subsubtree;
8118 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_log_dir, &subti, "Log Directory");
8120 offset = dissect_kafka_string(subtree, hf_kafka_log_dir, tvb, pinfo, offset, 0, NULL, NULL);
8122 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &subsubti, "Topics");
8124 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
8125 &dissect_kafka_alter_replica_log_dirs_request_topic, NULL);
8127 proto_item_set_end(subti, tvb, offset);
8129 return offset;
8132 static int
8133 dissect_kafka_alter_replica_log_dirs_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8134 kafka_api_version_t api_version)
8136 proto_item *subti;
8137 proto_tree *subtree;
8139 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8140 ett_kafka_log_dirs,
8141 &subti, "Log Directories");
8142 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
8143 &dissect_kafka_alter_replica_log_dirs_request_log_dir, NULL);
8145 proto_item_set_end(subti, tvb, offset);
8147 return offset;
8150 static int
8151 dissect_kafka_alter_replica_log_dirs_response_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
8152 int offset, kafka_api_version_t api_version _U_)
8154 proto_item *subti;
8155 proto_tree *subtree;
8156 int partition_id;
8158 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
8160 partition_id = tvb_get_ntohl(tvb, offset);
8161 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
8162 offset += 4;
8164 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
8166 proto_item_append_text(subti, " (ID=%u)", partition_id);
8168 proto_item_set_end(subti, tvb, offset);
8170 return offset;
8173 static int
8174 dissect_kafka_alter_replica_log_dirs_response_topic(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
8175 int offset, kafka_api_version_t api_version)
8177 proto_item *subti, *subsubti;
8178 proto_tree *subtree, *subsubtree;
8179 int topic_start, topic_len;
8181 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
8183 offset = dissect_kafka_string(subtree, hf_kafka_log_dir, tvb, pinfo, offset, 0, &topic_start, &topic_len);
8185 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partition");
8187 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
8188 &dissect_kafka_alter_replica_log_dirs_response_partition, NULL);
8190 proto_item_set_end(subti, tvb, offset);
8191 proto_item_append_text(subti, " (Name=%s)",
8192 tvb_get_string_enc(pinfo->pool, tvb,
8193 topic_start, topic_len, ENC_UTF_8));
8195 return offset;
8198 static int
8199 dissect_kafka_alter_replica_log_dirs_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8200 kafka_api_version_t api_version)
8202 proto_item *subti;
8203 proto_tree *subtree;
8205 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8207 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8208 ett_kafka_topics,
8209 &subti, "Topics");
8210 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
8211 &dissect_kafka_alter_replica_log_dirs_response_topic, NULL);
8213 proto_item_set_end(subti, tvb, offset);
8215 return offset;
8218 /* DESCRIBE_LOG_DIRS REQUEST/RESPONSE */
8220 static int
8221 dissect_kafka_describe_log_dirs_request_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
8222 int offset, kafka_api_version_t api_version _U_)
8224 proto_tree_add_item(tree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
8225 offset += 4;
8227 return offset;
8230 static int
8231 dissect_kafka_describe_log_dirs_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8232 int offset, kafka_api_version_t api_version _U_)
8234 proto_item *subti, *subsubti;
8235 proto_tree *subtree, *subsubtree;
8236 int topic_start, topic_len;
8238 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Topic");
8240 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
8242 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
8244 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
8245 &dissect_kafka_describe_log_dirs_request_partition, NULL);
8247 proto_item_set_end(subti, tvb, offset);
8248 proto_item_append_text(subti, " (Name=%s)",
8249 tvb_get_string_enc(pinfo->pool, tvb,
8250 topic_start, topic_len, ENC_UTF_8));
8252 return offset;
8255 static int
8256 dissect_kafka_describe_log_dirs_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8257 kafka_api_version_t api_version)
8259 proto_item *subti;
8260 proto_tree *subtree;
8262 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8263 ett_kafka_topics,
8264 &subti, "Topics");
8265 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
8266 &dissect_kafka_describe_log_dirs_request_topic, NULL);
8268 proto_item_set_end(subti, tvb, offset);
8270 return offset;
8273 static int
8274 dissect_kafka_describe_log_dirs_response_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
8275 int offset, kafka_api_version_t api_version _U_)
8277 proto_item *subti;
8278 proto_tree *subtree;
8280 int partition_id;
8282 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
8284 partition_id = tvb_get_ntohl(tvb, offset);
8285 proto_tree_add_item(subtree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
8286 offset += 4;
8288 proto_tree_add_item(subtree, hf_kafka_segment_size, tvb, offset, 8, ENC_BIG_ENDIAN);
8289 offset += 8;
8291 proto_tree_add_item(subtree, hf_kafka_offset_lag, tvb, offset, 8, ENC_BIG_ENDIAN);
8292 offset += 8;
8294 proto_tree_add_item(subtree, hf_kafka_future, tvb, offset, 1, ENC_BIG_ENDIAN);
8295 offset += 1;
8297 proto_item_set_end(subti, tvb, offset);
8298 proto_item_append_text(subti, " (ID=%u)", partition_id);
8300 return offset;
8303 static int
8304 dissect_kafka_describe_log_dirs_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8305 int offset, kafka_api_version_t api_version)
8307 proto_item *subti, *subsubti;
8308 proto_tree *subtree, *subsubtree;
8309 int topic_start, topic_len;
8311 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
8313 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, &topic_start, &topic_len);
8315 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
8317 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
8318 &dissect_kafka_describe_log_dirs_response_partition, NULL);
8320 proto_item_set_end(subti, tvb, offset);
8321 proto_item_append_text(subti, " (Name=%s)",
8322 tvb_get_string_enc(pinfo->pool, tvb,
8323 topic_start, topic_len, ENC_UTF_8));
8325 return offset;
8328 static int
8329 dissect_kafka_describe_log_dirs_response_log_dir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8330 int offset, kafka_api_version_t api_version)
8332 proto_item *subti, *subsubti;
8333 proto_tree *subtree, *subsubtree;
8334 int dir_start, dir_len;
8336 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_log_dir, &subti, "Log Directory");
8338 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
8340 offset = dissect_kafka_string(subtree, hf_kafka_log_dir, tvb, pinfo, offset, 0, &dir_start, &dir_len);
8342 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_topics, &subsubti, "Topics");
8344 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
8345 &dissect_kafka_describe_log_dirs_response_topic, NULL);
8347 proto_item_set_end(subti, tvb, offset);
8348 proto_item_append_text(subti, " (Dir=%s)",
8349 tvb_get_string_enc(pinfo->pool, tvb,
8350 dir_start, dir_len, ENC_UTF_8));
8352 return offset;
8355 static int
8356 dissect_kafka_describe_log_dirs_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8357 kafka_api_version_t api_version)
8359 proto_item *subti;
8360 proto_tree *subtree;
8362 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8364 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8365 ett_kafka_log_dirs,
8366 &subti, "Log Directories");
8367 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
8368 &dissect_kafka_describe_log_dirs_response_log_dir, NULL);
8370 proto_item_set_end(subti, tvb, offset);
8372 return offset;
8375 /* CREATE_PARTITIONS REQUEST/RESPONSE */
8377 static int
8378 dissect_kafka_create_partitions_request_broker(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
8379 int offset, kafka_api_version_t api_version _U_)
8381 proto_tree_add_item(tree, hf_kafka_broker_nodeid, tvb, offset, 4, ENC_BIG_ENDIAN);
8382 offset += 4;
8384 return offset;
8387 static int
8388 dissect_kafka_create_partitions_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8389 int offset, kafka_api_version_t api_version)
8391 proto_item *subti, *subsubti;
8392 proto_tree *subtree, *subsubtree;
8393 int topic_start, topic_len;
8395 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Topic");
8397 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 2, &topic_start, &topic_len);
8399 proto_tree_add_item(subtree, hf_kafka_partition_count, tvb, offset, 4, ENC_BIG_ENDIAN);
8400 offset += 4;
8402 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_brokers, &subsubti, "Brokers");
8403 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
8404 &dissect_kafka_create_partitions_request_broker, NULL);
8405 proto_item_set_end(subsubti, tvb, offset);
8407 if (api_version >= 2) {
8408 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8411 proto_item_set_end(subti, tvb, offset);
8412 proto_item_append_text(subti, " (Name=%s)",
8413 tvb_get_string_enc(pinfo->pool, tvb,
8414 topic_start, topic_len, ENC_UTF_8));
8416 return offset;
8419 static int
8420 dissect_kafka_create_partitions_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8421 kafka_api_version_t api_version)
8423 proto_item *subti;
8424 proto_tree *subtree;
8426 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8427 ett_kafka_topics,
8428 &subti, "Topics");
8429 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8430 &dissect_kafka_create_partitions_request_topic, NULL);
8431 proto_item_set_end(subti, tvb, offset);
8433 proto_tree_add_item(tree, hf_kafka_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
8434 offset += 4;
8436 proto_tree_add_item(tree, hf_kafka_validate_only, tvb, offset, 1, ENC_BIG_ENDIAN);
8437 offset += 1;
8439 if (api_version >= 2) {
8440 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8443 return offset;
8446 static int
8447 dissect_kafka_create_partitions_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8448 int offset, kafka_api_version_t api_version)
8450 proto_item *subti;
8451 proto_tree *subtree;
8452 int topic_start, topic_len;
8454 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
8456 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 2, &topic_start, &topic_len);
8458 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
8460 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8462 if (api_version >= 2) {
8463 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8466 proto_item_set_end(subti, tvb, offset);
8467 proto_item_append_text(subti, " (Name=%s)",
8468 tvb_get_string_enc(pinfo->pool, tvb,
8469 topic_start, topic_len, ENC_UTF_8));
8471 return offset;
8474 static int
8475 dissect_kafka_create_partitions_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8476 kafka_api_version_t api_version)
8478 proto_item *subti;
8479 proto_tree *subtree;
8481 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8483 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8484 ett_kafka_topics,
8485 &subti, "Topics");
8486 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8487 &dissect_kafka_create_partitions_response_topic, NULL);
8488 proto_item_set_end(subti, tvb, offset);
8490 if (api_version >= 2) {
8491 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8494 return offset;
8497 /* SASL_AUTHENTICATE REQUEST/RESPONSE */
8499 static int
8500 dissect_kafka_sasl_authenticate_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8501 kafka_api_version_t api_version)
8503 offset = dissect_kafka_bytes(tree, hf_kafka_sasl_auth_bytes, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8505 if (api_version >= 2) {
8506 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8509 return offset;
8513 static int
8514 dissect_kafka_sasl_authenticate_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8515 kafka_api_version_t api_version _U_)
8517 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
8519 offset = dissect_kafka_string(tree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8521 offset = dissect_kafka_bytes(tree, hf_kafka_sasl_auth_bytes, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8523 if (api_version >= 1) {
8524 offset = dissect_kafka_int64(tree, hf_kafka_session_lifetime_ms, tvb, pinfo, offset, NULL);
8527 if (api_version >= 2) {
8528 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8531 return offset;
8534 /* CREATE_DELEGATION_TOKEN REQUEST/RESPONSE */
8536 static int
8537 dissect_kafka_create_delegation_token_request_renewer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8538 int offset, kafka_api_version_t api_version)
8540 proto_item *subti;
8541 proto_tree *subtree;
8543 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_renewer, &subti, "Renewer");
8545 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_type, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8547 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8549 if (api_version >= 2) {
8550 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8553 proto_item_set_end(subti, tvb, offset);
8555 return offset;
8558 static int
8559 dissect_kafka_create_delegation_token_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8560 kafka_api_version_t api_version)
8562 proto_item *subti;
8563 proto_tree *subtree;
8565 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8566 ett_kafka_renewers,
8567 &subti, "Renewers");
8569 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8570 &dissect_kafka_create_delegation_token_request_renewer, NULL);
8572 proto_item_set_end(subti, tvb, offset);
8574 offset = dissect_kafka_int64(tree, hf_kafka_token_max_life_time, tvb, pinfo, offset, NULL);
8576 if (api_version >= 2) {
8577 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8580 return offset;
8583 static int
8584 dissect_kafka_create_delegation_token_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8585 kafka_api_version_t api_version)
8587 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
8589 offset = dissect_kafka_string(tree, hf_kafka_token_principal_type, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8591 offset = dissect_kafka_string(tree, hf_kafka_token_principal_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8593 offset = dissect_kafka_timestamp(tree, hf_kafka_token_issue_timestamp, tvb, pinfo, offset, NULL);
8595 offset = dissect_kafka_timestamp(tree, hf_kafka_token_expiry_timestamp, tvb, pinfo, offset, NULL);
8597 offset = dissect_kafka_timestamp(tree, hf_kafka_token_max_timestamp, tvb, pinfo, offset, NULL);
8599 offset = dissect_kafka_string(tree, hf_kafka_token_id, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8601 offset = dissect_kafka_bytes(tree, hf_kafka_token_hmac, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8603 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8605 if (api_version >= 2) {
8606 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8609 return offset;
8612 /* RENEW_DELEGATION_TOKEN REQUEST/RESPONSE */
8614 static int
8615 dissect_kafka_renew_delegation_token_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8616 kafka_api_version_t api_version)
8618 offset = dissect_kafka_bytes(tree, hf_kafka_token_hmac, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8620 offset = dissect_kafka_int64(tree, hf_kafka_token_renew_time, tvb, pinfo, offset, NULL);
8622 if (api_version >= 2) {
8623 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8626 return offset;
8629 static int
8630 dissect_kafka_renew_delegation_token_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8631 kafka_api_version_t api_version)
8633 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
8635 offset = dissect_kafka_timestamp(tree, hf_kafka_token_expiry_timestamp, tvb, pinfo, offset, NULL);
8637 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8639 if (api_version >= 2) {
8640 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8643 return offset;
8646 /* EXPIRE_DELEGATION_TOKEN REQUEST/RESPONSE */
8648 static int
8649 dissect_kafka_expire_delegation_token_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8650 kafka_api_version_t api_version)
8652 offset = dissect_kafka_bytes(tree, hf_kafka_token_hmac, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8654 offset = dissect_kafka_int64(tree, hf_kafka_token_expiry_time, tvb, pinfo, offset, NULL);
8656 if (api_version >= 2) {
8657 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8660 return offset;
8663 static int
8664 dissect_kafka_expire_delegation_token_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8665 kafka_api_version_t api_version _U_)
8667 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
8669 offset = dissect_kafka_timestamp(tree, hf_kafka_token_expiry_timestamp, tvb, pinfo, offset, NULL);
8671 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8673 if (api_version >= 2) {
8674 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8677 return offset;
8680 /* DESCRIBE_DELEGATION_TOKEN REQUEST/RESPONSE */
8682 static int
8683 dissect_kafka_describe_delegation_token_request_owner(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8684 int offset, kafka_api_version_t api_version)
8686 proto_item *subti;
8687 proto_tree *subtree;
8689 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_owner, &subti, "Owner");
8691 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_type, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8693 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8695 if (api_version >= 2) {
8696 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8699 proto_item_set_end(subti, tvb, offset);
8701 return offset;
8704 static int
8705 dissect_kafka_describe_delegation_token_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8706 kafka_api_version_t api_version)
8708 proto_item *subti;
8709 proto_tree *subtree;
8711 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8712 ett_kafka_owners,
8713 &subti, "Owners");
8714 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8715 &dissect_kafka_describe_delegation_token_request_owner, NULL);
8716 proto_item_set_end(subti, tvb, offset);
8718 if (api_version >= 2) {
8719 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8722 return offset;
8725 static int
8726 dissect_kafka_describe_delegation_token_response_renewer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8727 int offset, kafka_api_version_t api_version)
8729 proto_item *subti;
8730 proto_tree *subtree;
8732 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_renewer, &subti, "Renewer");
8734 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_type, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8735 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8737 if (api_version >= 2) {
8738 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8741 proto_item_set_end(subti, tvb, offset);
8743 return offset;
8746 static int
8747 dissect_kafka_describe_delegation_token_response_token(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8748 int offset, kafka_api_version_t api_version)
8750 proto_item *subti, *subsubti;
8751 proto_tree *subtree, *subsubtree;
8753 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_token, &subti, "Token");
8755 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_type, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8756 offset = dissect_kafka_string(subtree, hf_kafka_token_principal_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8758 offset = dissect_kafka_timestamp(subtree, hf_kafka_token_issue_timestamp, tvb, pinfo, offset, NULL);
8760 offset = dissect_kafka_timestamp(subtree, hf_kafka_token_expiry_timestamp, tvb, pinfo, offset, NULL);
8762 offset = dissect_kafka_timestamp(subtree, hf_kafka_token_max_timestamp, tvb, pinfo, offset, NULL);
8764 offset = dissect_kafka_string(subtree, hf_kafka_token_id, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8765 offset = dissect_kafka_bytes(subtree, hf_kafka_token_hmac, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8767 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
8768 ett_kafka_renewers,
8769 &subsubti, "Renewers");
8770 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
8771 &dissect_kafka_describe_delegation_token_response_renewer, NULL);
8772 proto_item_set_end(subsubti, tvb, offset);
8774 if (api_version >= 2) {
8775 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8778 proto_item_set_end(subti, tvb, offset);
8780 return offset;
8783 static int
8784 dissect_kafka_describe_delegation_token_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8785 kafka_api_version_t api_version)
8787 proto_item *subti;
8788 proto_tree *subtree;
8790 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
8792 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8793 ett_kafka_tokens,
8794 &subti, "Tokens");
8795 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8796 &dissect_kafka_describe_delegation_token_response_token, NULL);
8797 proto_item_set_end(subti, tvb, offset);
8799 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8801 if (api_version >= 2) {
8802 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8805 return offset;
8808 /* DELETE_GROUPS REQUEST/RESPONSE */
8810 static int
8811 dissect_kafka_delete_groups_request_group(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8812 int offset, kafka_api_version_t api_version)
8814 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8815 return offset;
8818 static int
8819 dissect_kafka_delete_groups_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8820 kafka_api_version_t api_version _U_)
8822 proto_item *subti;
8823 proto_tree *subtree;
8825 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8826 ett_kafka_groups,
8827 &subti, "Groups");
8829 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8830 &dissect_kafka_delete_groups_request_group, NULL);
8832 if (api_version >= 2) {
8833 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8836 proto_item_set_end(subti, tvb, offset);
8838 return offset;
8841 static int
8842 dissect_kafka_delete_groups_response_group(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8843 int offset, kafka_api_version_t api_version _U_)
8845 proto_item *subti;
8846 proto_tree *subtree;
8848 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_group, &subti, "Group");
8850 offset = dissect_kafka_string(subtree, hf_kafka_consumer_group, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8852 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
8854 if (api_version >= 2) {
8855 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8858 proto_item_set_end(subti, tvb, offset);
8860 return offset;
8863 static int
8864 dissect_kafka_delete_groups_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8865 kafka_api_version_t api_version _U_)
8867 proto_item *subti;
8868 proto_tree *subtree;
8870 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
8872 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8873 ett_kafka_groups,
8874 &subti, "Groups");
8876 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8877 &dissect_kafka_delete_groups_response_group, NULL);
8879 if (api_version >= 2) {
8880 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8883 proto_item_set_end(subti, tvb, offset);
8885 return offset;
8888 /* ELECT_LEADERS REQUEST/RESPONSE */
8890 static int
8891 dissect_kafka_elect_leaders_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8892 int offset, kafka_api_version_t api_version _U_)
8894 return dissect_kafka_int32(tree, hf_kafka_partition_id, tvb, pinfo, offset, NULL);
8897 static int
8898 dissect_kafka_elect_leaders_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8899 kafka_api_version_t api_version)
8901 proto_item *subti, *subsubti;
8902 proto_tree *subtree, *subsubtree;
8904 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8905 ett_kafka_topic,
8906 &subti, "Topic");
8908 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
8909 ett_kafka_partitions,
8910 &subsubti, "Partitions");
8911 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
8912 &dissect_kafka_elect_leaders_request_partition, NULL);
8913 proto_item_set_end(subsubti, tvb, offset);
8915 if (api_version >= 2) {
8916 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8919 proto_item_set_end(subti, tvb, offset);
8921 return offset;
8924 static int
8925 dissect_kafka_elect_leaders_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8926 kafka_api_version_t api_version)
8928 proto_item *subti;
8929 proto_tree *subtree;
8931 if (api_version >= 1) {
8932 offset = dissect_kafka_int8(tree, hf_kafka_election_type, tvb, pinfo, offset, NULL);
8935 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8936 ett_kafka_topics,
8937 &subti, "Topics");
8938 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
8939 &dissect_kafka_elect_leaders_request_topic, NULL);
8940 proto_item_set_end(subti, tvb, offset);
8942 offset = dissect_kafka_int32(tree, hf_kafka_timeout, tvb, pinfo, offset, NULL);
8944 if (api_version >= 2) {
8945 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
8948 return offset;
8952 static int
8953 dissect_kafka_elect_leaders_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8954 int offset, kafka_api_version_t api_version)
8957 proto_item *subti;
8958 proto_tree *subtree;
8960 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8961 ett_kafka_partition,
8962 &subti, "Partition");
8964 offset = dissect_kafka_int32(subtree, hf_kafka_partition_id, tvb, pinfo, offset, NULL);
8966 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
8968 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8970 if (api_version >= 2) {
8971 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
8974 proto_item_set_end(subti, tvb, offset);
8976 return offset;
8979 static int
8980 dissect_kafka_elect_leaders_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
8981 kafka_api_version_t api_version)
8983 proto_item *subti, *subsubti;
8984 proto_tree *subtree, *subsubtree;
8986 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
8987 ett_kafka_topic,
8988 &subti, "Topic");
8990 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 2, NULL, NULL);
8992 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
8993 ett_kafka_partitions,
8994 &subsubti, "Partitions");
8995 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 2, api_version,
8996 &dissect_kafka_elect_leaders_response_partition, NULL);
8997 proto_item_set_end(subsubti, tvb, offset);
8999 if (api_version >= 2) {
9000 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9003 proto_item_set_end(subti, tvb, offset);
9005 return offset;
9008 static int
9009 dissect_kafka_elect_leaders_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9010 kafka_api_version_t api_version)
9012 proto_item *subti;
9013 proto_tree *subtree;
9015 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
9017 if (api_version >= 1) {
9018 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
9021 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9022 ett_kafka_topics,
9023 &subti, "Topics");
9025 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 2, api_version,
9026 &dissect_kafka_elect_leaders_response_topic, NULL);
9028 proto_item_set_end(subti, tvb, offset);
9030 if (api_version >= 2) {
9031 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9034 return offset;
9037 /* INCREMENTAL_ALTER_CONFIGS REQUEST/RESPONSE */
9039 static int
9040 dissect_kafka_inc_alter_config_request_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9041 int offset, kafka_api_version_t api_version)
9043 proto_item *subti;
9044 proto_tree *subtree;
9046 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_config_entry, &subti, "Entry");
9048 offset = dissect_kafka_string(subtree, hf_kafka_config_key, tvb, pinfo, offset, api_version >= 1, NULL, NULL);
9050 proto_tree_add_item(subtree, hf_kafka_config_operation, tvb, offset, 1, ENC_BIG_ENDIAN);
9051 offset += 1;
9053 offset = dissect_kafka_string(subtree, hf_kafka_config_value, tvb, pinfo, offset, api_version >= 1, NULL, NULL);
9055 if (api_version >= 1) {
9056 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9059 proto_item_set_end(subti, tvb, offset);
9061 return offset;
9064 static int
9065 dissect_kafka_inc_alter_config_request_resource(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9066 int offset, kafka_api_version_t api_version)
9068 proto_item *subti, *subsubti;
9069 proto_tree *subtree, *subsubtree;
9071 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Resource");
9073 proto_tree_add_item(subtree, hf_kafka_config_resource_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9074 offset += 1;
9076 offset = dissect_kafka_string(subtree, hf_kafka_config_resource_name, tvb, pinfo, offset, api_version >= 1, NULL, NULL);
9078 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_config_entries, &subsubti, "Entries");
9079 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 1, api_version,
9080 &dissect_kafka_inc_alter_config_request_entry, NULL);
9081 proto_item_set_end(subsubti, tvb, offset);
9083 if (api_version >= 1) {
9084 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9087 proto_item_set_end(subti, tvb, offset);
9089 return offset;
9092 static int
9093 dissect_kafka_inc_alter_configs_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9094 kafka_api_version_t api_version)
9096 proto_item *subti;
9097 proto_tree *subtree;
9099 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9100 ett_kafka_resources,
9101 &subti, "Resources");
9103 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 1, api_version,
9104 &dissect_kafka_inc_alter_config_request_resource, NULL);
9106 proto_item_set_end(subti, tvb, offset);
9108 proto_tree_add_item(tree, hf_kafka_validate_only, tvb, offset, 1, ENC_BIG_ENDIAN);
9109 offset += 1;
9111 if (api_version >= 1) {
9112 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9115 return offset;
9118 static int
9119 dissect_kafka_inc_alter_configs_response_resource(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9120 int offset, kafka_api_version_t api_version)
9122 proto_item *subti;
9123 proto_tree *subtree;
9125 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_resource, &subti, "Resource");
9127 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
9129 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 1, NULL, NULL);
9131 proto_tree_add_item(subtree, hf_kafka_config_resource_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9132 offset += 1;
9134 offset = dissect_kafka_string(subtree, hf_kafka_config_resource_name, tvb, pinfo, offset, api_version >= 1, NULL, NULL);
9136 if (api_version >= 1) {
9137 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9140 proto_item_set_end(subti, tvb, offset);
9142 return offset;
9145 static int
9146 dissect_kafka_inc_alter_configs_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9147 kafka_api_version_t api_version)
9149 proto_item *subti;
9150 proto_tree *subtree;
9152 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
9154 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9155 ett_kafka_resources,
9156 &subti, "Resources");
9157 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 1, api_version,
9158 &dissect_kafka_inc_alter_configs_response_resource, NULL);
9159 proto_item_set_end(subti, tvb, offset);
9161 if (api_version >= 1) {
9162 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9165 return offset;
9168 /* ALTER_PARTITION_REASSIGNMENTS REQUEST/RESPONSE */
9170 static int
9171 dissect_kafka_alter_partition_reassignments_request_replica(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
9172 int offset, kafka_api_version_t api_version _U_)
9174 proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
9175 offset += 4;
9176 return offset;
9179 static int
9180 dissect_kafka_alter_partition_reassignments_request_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9181 int offset, kafka_api_version_t api_version)
9183 proto_item *subti, *subsubti;
9184 proto_tree *subtree, *subsubtree;
9185 kafka_partition_t partition;
9187 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
9189 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &partition);
9191 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Replicas");
9193 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
9194 &dissect_kafka_alter_partition_reassignments_request_replica, NULL);
9196 proto_item_set_end(subti, tvb, offset);
9198 return offset;
9201 static int
9202 dissect_kafka_alter_partition_reassignments_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9203 int offset, kafka_api_version_t api_version)
9205 proto_item *subti, *subsubti;
9206 proto_tree *subtree, *subsubtree;
9208 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
9210 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, NULL, NULL);
9212 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
9214 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
9215 &dissect_kafka_alter_partition_reassignments_request_partition, NULL);
9217 proto_item_set_end(subti, tvb, offset);
9219 return offset;
9222 static int
9223 dissect_kafka_alter_partition_reassignments_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9224 kafka_api_version_t api_version)
9226 proto_item *subti;
9227 proto_tree *subtree;
9229 proto_tree_add_item(tree, hf_kafka_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
9230 offset += 4;
9232 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9233 ett_kafka_topics,
9234 &subti, "Topics");
9235 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
9236 &dissect_kafka_alter_partition_reassignments_request_topic, NULL);
9238 proto_item_set_end(subti, tvb, offset);
9240 return offset;
9243 static int
9244 dissect_kafka_alter_partition_reassignments_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9245 int offset, kafka_api_version_t api_version _U_)
9247 proto_item *subti;
9248 proto_tree *subtree;
9249 kafka_partition_t partition;
9251 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
9253 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &partition);
9255 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
9257 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, 0, NULL, NULL);
9259 proto_item_set_end(subti, tvb, offset);
9261 return offset;
9264 static int
9265 dissect_kafka_alter_partition_reassignments_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9266 int offset, kafka_api_version_t api_version)
9268 proto_item *subti, *subsubti;
9269 proto_tree *subtree, *subsubtree;
9271 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
9273 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, NULL, NULL);
9275 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
9277 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
9278 &dissect_kafka_alter_partition_reassignments_response_partition, NULL);
9280 proto_item_set_end(subti, tvb, offset);
9282 return offset;
9285 static int
9286 dissect_kafka_alter_partition_reassignments_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9287 kafka_api_version_t api_version)
9289 proto_item *subti;
9290 proto_tree *subtree;
9292 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
9294 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
9296 offset = dissect_kafka_string(tree, hf_kafka_error_message, tvb, pinfo, offset, 0, NULL, NULL);
9298 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9299 ett_kafka_topics,
9300 &subti, "Topics");
9301 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
9302 &dissect_kafka_alter_partition_reassignments_response_topic, NULL);
9304 proto_item_set_end(subti, tvb, offset);
9306 return offset;
9309 /* LIST_PARTITION_REASSIGNMENTS REQUEST/RESPONSE */
9311 static int
9312 dissect_kafka_list_partition_reassignments_request_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
9313 int offset, kafka_api_version_t api_version _U_)
9315 proto_tree_add_item(tree, hf_kafka_partition_id, tvb, offset, 4, ENC_BIG_ENDIAN);
9316 offset += 4;
9318 return offset;
9321 static int
9322 dissect_kafka_list_partition_reassignments_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9323 int offset, kafka_api_version_t api_version)
9325 proto_item *subti, *subsubti;
9326 proto_tree *subtree, *subsubtree;
9328 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
9330 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9332 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
9334 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 0, api_version,
9335 &dissect_kafka_list_partition_reassignments_request_partition, NULL);
9337 proto_item_set_end(subti, tvb, offset);
9339 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9341 return offset;
9344 static int
9345 dissect_kafka_list_partition_reassignments_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9346 kafka_api_version_t api_version)
9348 proto_item *subti;
9349 proto_tree *subtree;
9351 proto_tree_add_item(tree, hf_kafka_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
9352 offset += 4;
9354 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9355 ett_kafka_topics,
9356 &subti, "Topics");
9357 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 0, api_version,
9358 &dissect_kafka_list_partition_reassignments_request_topic, NULL);
9360 proto_item_set_end(subti, tvb, offset);
9362 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9364 return offset;
9367 static int
9368 dissect_kafka_list_partition_reassignments_response_replica(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
9369 int offset, kafka_api_version_t api_version _U_)
9371 proto_tree_add_item(tree, hf_kafka_replica, tvb, offset, 4, ENC_BIG_ENDIAN);
9372 offset += 4;
9374 return offset;
9377 static int
9378 dissect_kafka_list_partition_reassignments_response_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9379 int offset, kafka_api_version_t api_version)
9381 proto_item *subti, *subsubti;
9382 proto_tree *subtree, *subsubtree;
9383 kafka_partition_t partition;
9385 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partition, &subti, "Partition");
9387 offset = dissect_kafka_partition_id_ret(tvb, pinfo, subtree, offset, &partition);
9389 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
9391 offset = dissect_kafka_string(subtree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9393 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
9394 ett_kafka_replicas,
9395 &subsubti, "Current Replicas");
9396 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 0, api_version,
9397 &dissect_kafka_list_partition_reassignments_response_replica, NULL);
9398 proto_item_set_end(subsubti, tvb, offset);
9400 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
9401 ett_kafka_replicas,
9402 &subsubti, "Adding Replicas");
9403 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 0, api_version,
9404 &dissect_kafka_list_partition_reassignments_response_replica, NULL);
9405 proto_item_set_end(subsubti, tvb, offset);
9407 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
9408 ett_kafka_replicas,
9409 &subsubti, "Removing Replicas");
9410 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 0, api_version,
9411 &dissect_kafka_list_partition_reassignments_response_replica, NULL);
9412 proto_item_set_end(subsubti, tvb, offset);
9414 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9416 proto_item_set_end(subti, tvb, offset);
9418 return offset;
9421 static int
9422 dissect_kafka_list_partition_reassignments_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9423 int offset, kafka_api_version_t api_version)
9425 proto_item *subti, *subsubti;
9426 proto_tree *subtree, *subsubtree;
9428 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topic, &subti, "Topic");
9430 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9432 subsubtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_partitions, &subsubti, "Partitions");
9434 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, api_version >= 0, api_version,
9435 &dissect_kafka_list_partition_reassignments_response_partition, NULL);
9437 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9439 proto_item_set_end(subti, tvb, offset);
9441 return offset;
9444 static int
9445 dissect_kafka_list_partition_reassignments_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9446 kafka_api_version_t api_version)
9448 proto_item *subti;
9449 proto_tree *subtree;
9451 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
9453 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
9455 offset = dissect_kafka_string(tree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9457 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9458 ett_kafka_topics,
9459 &subti, "Topics");
9460 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 0, api_version,
9461 &dissect_kafka_list_partition_reassignments_response_topic, NULL);
9463 proto_item_set_end(subti, tvb, offset);
9465 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9467 return offset;
9470 /* OFFSET_DELETE REQUEST/RESPONSE */
9472 static int
9473 dissect_kafka_offset_delete_request_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9474 kafka_api_version_t api_version)
9476 proto_item *subti, *subsubti;
9477 proto_tree *subtree, *subsubtree;
9479 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9480 ett_kafka_topic,
9481 &subti, "Topic");
9483 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, NULL, NULL);
9485 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
9486 ett_kafka_partitions,
9487 &subsubti, "Partitions");
9489 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
9490 &dissect_kafka_partition_id, NULL);
9492 proto_item_set_end(subti, tvb, offset);
9494 proto_item_set_end(subsubti, tvb, offset);
9496 return offset;
9499 static int
9500 dissect_kafka_offset_delete_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9501 kafka_api_version_t api_version)
9503 proto_item *subti;
9504 proto_tree *subtree;
9506 offset = dissect_kafka_string(tree, hf_kafka_consumer_group, tvb, pinfo, offset, 0, NULL, NULL);
9508 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9509 ett_kafka_topics,
9510 &subti, "Topics");
9512 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
9513 &dissect_kafka_offset_delete_request_topic, NULL);
9515 proto_item_set_end(subti, tvb, offset);
9517 return offset;
9520 static int
9521 dissect_kafka_offset_delete_response_topic_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9522 kafka_api_version_t api_version)
9524 proto_item *subti;
9525 proto_tree *subtree;
9527 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9528 ett_kafka_partition,
9529 &subti, "Partition");
9531 offset = dissect_kafka_partition_id(tvb, pinfo, subtree, offset, api_version);
9533 offset = dissect_kafka_error(tvb, pinfo, subtree, offset);
9535 proto_item_set_end(subti, tvb, offset);
9537 return offset;
9540 static int
9541 dissect_kafka_offset_delete_response_topic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9542 kafka_api_version_t api_version)
9544 proto_item *subti, *subsubti;
9545 proto_tree *subtree, *subsubtree;
9547 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9548 ett_kafka_topic,
9549 &subti, "Topic");
9551 offset = dissect_kafka_string(subtree, hf_kafka_topic_name, tvb, pinfo, offset, 0, NULL, NULL);
9553 subsubtree = proto_tree_add_subtree(subtree, tvb, offset, -1,
9554 ett_kafka_partitions,
9555 &subsubti, "Partitions");
9557 offset = dissect_kafka_array(subsubtree, tvb, pinfo, offset, 0, api_version,
9558 &dissect_kafka_offset_delete_response_topic_partition, NULL);
9560 proto_item_set_end(subsubti, tvb, offset);
9562 proto_item_set_end(subti, tvb, offset);
9564 return offset;
9567 static int
9568 dissect_kafka_offset_delete_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9569 kafka_api_version_t api_version)
9571 proto_item *subti;
9572 proto_tree *subtree;
9574 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
9576 offset = dissect_kafka_throttle_time(tvb, pinfo, tree, offset);
9578 subtree = proto_tree_add_subtree(tree, tvb, offset, -1,
9579 ett_kafka_topics,
9580 &subti, "Topics");
9582 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, 0, api_version,
9583 &dissect_kafka_offset_delete_response_topic, NULL);
9585 proto_item_set_end(subti, tvb, offset);
9587 return offset;
9590 /* DESCRIBE_CLUSTER REQUEST/RESPONSE */
9591 static int
9592 dissect_kafka_describe_cluster_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9593 kafka_api_version_t api_version)
9595 /* include_cluster_authorized_operations */
9596 offset = dissect_kafka_bool(tree, hf_kafka_include_cluster_authorized_ops, tvb, pinfo, offset);
9598 /* endpoint_type */
9599 if (api_version >= 1) {
9600 offset = dissect_kafka_int8(tree, hf_kafka_endpoint_type, tvb, pinfo, offset, NULL);
9603 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9605 return offset;
9608 static int
9609 dissect_kafka_describe_cluster_response_broker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9610 kafka_api_version_t api_version)
9612 proto_item *subti;
9613 proto_tree *subtree;
9615 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &subti, "Broker");
9617 /* broker_id */
9618 offset = dissect_kafka_int32(subtree, hf_kafka_broker_nodeid, tvb, pinfo, offset, NULL);
9620 /* host */
9621 offset = dissect_kafka_string(subtree, hf_kafka_broker_host, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9623 /* port */
9624 offset = dissect_kafka_int32(subtree, hf_kafka_broker_port, tvb, pinfo, offset, NULL);
9626 /* rack */
9627 offset = dissect_kafka_string(subtree, hf_kafka_rack, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9629 offset = dissect_kafka_tagged_fields(tvb, pinfo, subtree, offset, 0);
9631 proto_item_set_end(subti, tvb, offset);
9633 return offset;
9636 static int
9637 dissect_kafka_describe_cluster_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9638 kafka_api_version_t api_version)
9640 proto_item *subti;
9641 proto_tree *subtree;
9643 /* throttle_time */
9644 offset = dissect_kafka_int32(tree, hf_kafka_throttle_time, tvb, pinfo, offset, NULL);
9646 /* error */
9647 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
9649 /* error_message */
9650 offset = dissect_kafka_string(tree, hf_kafka_error_message, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9652 /* endpoint_type */
9653 if (api_version >= 1) {
9654 offset = dissect_kafka_int8(tree, hf_kafka_endpoint_type, tvb, pinfo, offset, NULL);
9657 /* cluster_id */
9658 offset = dissect_kafka_string(tree, hf_kafka_cluster_id, tvb, pinfo, offset, api_version >= 0, NULL, NULL);
9660 /* controller_id */
9661 offset = dissect_kafka_int32(tree, hf_kafka_controller_id, tvb, pinfo, offset, NULL);
9663 /* [brokers] */
9664 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_kafka_topics, &subti, "Brokers");
9665 offset = dissect_kafka_array(subtree, tvb, pinfo, offset, api_version >= 0, api_version,
9666 &dissect_kafka_describe_cluster_response_broker, NULL);
9667 proto_item_set_end(subti, tvb, offset);
9669 /* cluster_authorized_operations */
9670 offset = dissect_kafka_int32(tree, hf_kafka_cluster_authorized_ops, tvb, pinfo, offset, NULL);
9672 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9674 return offset;
9677 /* ALLOCATE_PRODUCER_IDS REQUEST/RESPONSE */
9679 static int
9680 dissect_kafka_allocate_producer_ids_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9681 kafka_api_version_t api_version _U_)
9683 /* broker_id */
9684 offset = dissect_kafka_int32(tree, hf_kafka_broker_nodeid, tvb, pinfo, offset, NULL);
9686 /* broker_epoch */
9687 offset = dissect_kafka_int64(tree, hf_kafka_broker_epoch, tvb, pinfo, offset, NULL);
9689 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9691 return offset;
9694 static int
9695 dissect_kafka_allocate_producer_ids_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
9696 kafka_api_version_t api_version _U_)
9698 /* throttle_time */
9699 offset = dissect_kafka_int32(tree, hf_kafka_throttle_time, tvb, pinfo, offset, NULL);
9701 /* error */
9702 offset = dissect_kafka_error(tvb, pinfo, tree, offset);
9704 /* producer_id_start */
9705 offset = dissect_kafka_int64(tree, hf_kafka_producer_id_start, tvb, pinfo, offset, NULL);
9707 /* producer_id_len */
9708 offset = dissect_kafka_int32(tree, hf_kafka_producer_id_len, tvb, pinfo, offset, NULL);
9710 offset = dissect_kafka_tagged_fields(tvb, pinfo, tree, offset, 0);
9712 return offset;
9715 /* MAIN */
9717 static wmem_multimap_t *
9718 dissect_kafka_get_match_map(packet_info *pinfo)
9720 conversation_t *conversation;
9721 wmem_multimap_t *match_map;
9722 conversation = find_or_create_conversation(pinfo);
9723 match_map = (wmem_multimap_t *) conversation_get_proto_data(conversation, proto_kafka);
9724 if (match_map == NULL) {
9725 match_map = wmem_multimap_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
9726 conversation_add_proto_data(conversation, proto_kafka, match_map);
9729 return match_map;
9732 static bool
9733 dissect_kafka_insert_match(packet_info *pinfo, uint32_t correlation_id, kafka_query_response_t *match)
9735 if (wmem_multimap_lookup32(dissect_kafka_get_match_map(pinfo), GUINT_TO_POINTER(correlation_id), pinfo->num)) {
9736 return 0;
9738 wmem_multimap_insert32(dissect_kafka_get_match_map(pinfo), GUINT_TO_POINTER(correlation_id), pinfo->num, match);
9739 return 1;
9742 static kafka_query_response_t *
9743 dissect_kafka_lookup_match(packet_info *pinfo, uint32_t correlation_id)
9745 kafka_query_response_t *match = (kafka_query_response_t*)wmem_multimap_lookup32_le(dissect_kafka_get_match_map(pinfo), GUINT_TO_POINTER(correlation_id), pinfo->num);
9746 return match;
9750 static int
9751 dissect_kafka(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
9753 proto_item *root_ti, *ti;
9754 proto_tree *kafka_tree;
9755 int offset = 0;
9756 uint32_t pdu_length;
9757 uint32_t pdu_correlation_id;
9758 kafka_query_response_t *matcher;
9759 kafka_api_version_t dissect_api_version;
9760 bool has_response = 1;
9762 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Kafka");
9763 col_clear(pinfo->cinfo, COL_INFO);
9765 root_ti = proto_tree_add_item(tree, proto_kafka, tvb, 0, -1, ENC_NA);
9767 kafka_tree = proto_item_add_subtree(root_ti, ett_kafka);
9769 pdu_length = tvb_get_ntohl(tvb, offset);
9770 proto_tree_add_item(kafka_tree, hf_kafka_len, tvb, offset, 4, ENC_BIG_ENDIAN);
9771 offset += 4;
9773 if (pinfo->destport == pinfo->match_uint) {
9775 /* Request (as directed towards server port) */
9777 /* in the request PDU the correlation id comes after api_key and api_version */
9778 pdu_correlation_id = tvb_get_ntohl(tvb, offset+4);
9780 matcher = wmem_new(wmem_file_scope(), kafka_query_response_t);
9782 matcher->api_key = tvb_get_ntohs(tvb, offset);
9783 matcher->api_version = tvb_get_ntohs(tvb, offset+2);
9784 matcher->correlation_id = pdu_correlation_id;
9785 matcher->request_frame = pinfo->num;
9786 matcher->response_found = false;
9787 matcher->flexible_api = kafka_is_api_version_flexible(matcher->api_key, matcher->api_version);
9789 col_add_fstr(pinfo->cinfo, COL_INFO, "Kafka %s v%d Request",
9790 kafka_api_key_to_str(matcher->api_key),
9791 matcher->api_version);
9793 /* Also add to protocol root */
9794 proto_item_append_text(root_ti, " (%s v%d Request)",
9795 kafka_api_key_to_str(matcher->api_key),
9796 matcher->api_version);
9798 /* for the header implementation check RequestHeaderData class */
9800 ti = proto_tree_add_item(kafka_tree, hf_kafka_request_api_key, tvb, offset, 2, ENC_BIG_ENDIAN);
9801 proto_item_set_hidden(ti);
9803 ti = proto_tree_add_item(kafka_tree, hf_kafka_api_key, tvb, offset, 2, ENC_BIG_ENDIAN);
9804 offset += 2;
9805 kafka_check_supported_api_key(pinfo, ti, matcher);
9807 ti = proto_tree_add_item(kafka_tree, hf_kafka_request_api_version, tvb, offset, 2, ENC_BIG_ENDIAN);
9808 proto_item_set_hidden(ti);
9810 ti = proto_tree_add_item(kafka_tree, hf_kafka_api_version, tvb, offset, 2, ENC_BIG_ENDIAN);
9811 offset += 2;
9812 dissect_api_version = kafka_check_supported_api_version(pinfo, ti, matcher);
9814 proto_tree_add_item(kafka_tree, hf_kafka_correlation_id, tvb, offset, 4, ENC_BIG_ENDIAN);
9815 offset += 4;
9817 if (matcher->api_key == KAFKA_CONTROLLED_SHUTDOWN && matcher->api_version == 0) {
9819 * Special case for ControlledShutdownRequest.
9820 * https://github.com/apache/kafka/blob/2.5.0/generator/src/main/java/org/apache/kafka/message/ApiMessageTypeGenerator.java#L268-L277
9821 * The code is materialized in ApiMessageTypes class.
9823 } else {
9824 /* even if flexible API is used, clientId is still using int16_t string length prefix */
9825 offset = dissect_kafka_string(kafka_tree, hf_kafka_client_id, tvb, pinfo, offset, 0, NULL, NULL);
9828 if (matcher->flexible_api) {
9829 /* version 2 request header (flexible API) contains list of tagged fields, last param is ignored */
9830 offset = dissect_kafka_tagged_fields(tvb, pinfo, kafka_tree, offset, 0);
9833 switch (matcher->api_key) {
9834 case KAFKA_PRODUCE:
9835 /* The kafka server always responds, except in the case of a produce
9836 * request whose RequiredAcks field is 0. This field is at a dynamic
9837 * offset into the request, so to avoid too much prefetch logic we
9838 * simply don't queue produce requests here. If it is a produce
9839 * request with a non-zero RequiredAcks field it gets queued later.
9841 if (tvb_get_ntohs(tvb, offset) == KAFKA_ACK_NOT_REQUIRED) {
9842 has_response = 0;
9844 offset = dissect_kafka_produce_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9845 break;
9846 case KAFKA_FETCH:
9847 offset = dissect_kafka_fetch_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9848 break;
9849 case KAFKA_OFFSETS:
9850 offset = dissect_kafka_offsets_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9851 break;
9852 case KAFKA_METADATA:
9853 offset = dissect_kafka_metadata_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9854 break;
9855 case KAFKA_LEADER_AND_ISR:
9856 offset = dissect_kafka_leader_and_isr_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9857 break;
9858 case KAFKA_STOP_REPLICA:
9859 offset = dissect_kafka_stop_replica_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9860 break;
9861 case KAFKA_UPDATE_METADATA:
9862 offset = dissect_kafka_update_metadata_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9863 break;
9864 case KAFKA_CONTROLLED_SHUTDOWN:
9865 offset = dissect_kafka_controlled_shutdown_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9866 break;
9867 case KAFKA_OFFSET_COMMIT:
9868 offset = dissect_kafka_offset_commit_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9869 break;
9870 case KAFKA_OFFSET_FETCH:
9871 offset = dissect_kafka_offset_fetch_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9872 break;
9873 case KAFKA_FIND_COORDINATOR:
9874 offset = dissect_kafka_find_coordinator_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9875 break;
9876 case KAFKA_JOIN_GROUP:
9877 offset = dissect_kafka_join_group_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9878 break;
9879 case KAFKA_HEARTBEAT:
9880 offset = dissect_kafka_heartbeat_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9881 break;
9882 case KAFKA_LEAVE_GROUP:
9883 offset = dissect_kafka_leave_group_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9884 break;
9885 case KAFKA_SYNC_GROUP:
9886 offset = dissect_kafka_sync_group_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9887 break;
9888 case KAFKA_DESCRIBE_GROUPS:
9889 offset = dissect_kafka_describe_groups_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9890 break;
9891 case KAFKA_LIST_GROUPS:
9892 offset = dissect_kafka_list_groups_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9893 break;
9894 case KAFKA_SASL_HANDSHAKE:
9895 offset = dissect_kafka_sasl_handshake_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9896 break;
9897 case KAFKA_API_VERSIONS:
9898 offset = dissect_kafka_api_versions_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9899 break;
9900 case KAFKA_CREATE_TOPICS:
9901 offset = dissect_kafka_create_topics_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9902 break;
9903 case KAFKA_DELETE_TOPICS:
9904 offset = dissect_kafka_delete_topics_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9905 break;
9906 case KAFKA_DELETE_RECORDS:
9907 offset = dissect_kafka_delete_records_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9908 break;
9909 case KAFKA_INIT_PRODUCER_ID:
9910 offset = dissect_kafka_init_producer_id_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9911 break;
9912 case KAFKA_OFFSET_FOR_LEADER_EPOCH:
9913 offset = dissect_kafka_offset_for_leader_epoch_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9914 break;
9915 case KAFKA_ADD_PARTITIONS_TO_TXN:
9916 offset = dissect_kafka_add_partitions_to_txn_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9917 break;
9918 case KAFKA_ADD_OFFSETS_TO_TXN:
9919 offset = dissect_kafka_add_offsets_to_txn_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9920 break;
9921 case KAFKA_END_TXN:
9922 offset = dissect_kafka_end_txn_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9923 break;
9924 case KAFKA_WRITE_TXN_MARKERS:
9925 offset = dissect_kafka_write_txn_markers_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9926 break;
9927 case KAFKA_TXN_OFFSET_COMMIT:
9928 offset = dissect_kafka_txn_offset_commit_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9929 break;
9930 case KAFKA_DESCRIBE_ACLS:
9931 offset = dissect_kafka_describe_acls_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9932 break;
9933 case KAFKA_CREATE_ACLS:
9934 offset = dissect_kafka_create_acls_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9935 break;
9936 case KAFKA_DELETE_ACLS:
9937 offset = dissect_kafka_delete_acls_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9938 break;
9939 case KAFKA_DESCRIBE_CONFIGS:
9940 offset = dissect_kafka_describe_configs_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9941 break;
9942 case KAFKA_ALTER_CONFIGS:
9943 offset = dissect_kafka_alter_configs_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9944 break;
9945 case KAFKA_ALTER_REPLICA_LOG_DIRS:
9946 offset = dissect_kafka_alter_replica_log_dirs_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9947 break;
9948 case KAFKA_DESCRIBE_LOG_DIRS:
9949 offset = dissect_kafka_describe_log_dirs_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9950 break;
9951 case KAFKA_CREATE_PARTITIONS:
9952 offset = dissect_kafka_create_partitions_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9953 break;
9954 case KAFKA_SASL_AUTHENTICATE:
9955 offset = dissect_kafka_sasl_authenticate_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9956 break;
9957 case KAFKA_CREATE_DELEGATION_TOKEN:
9958 offset = dissect_kafka_create_delegation_token_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9959 break;
9960 case KAFKA_RENEW_DELEGATION_TOKEN:
9961 offset = dissect_kafka_renew_delegation_token_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9962 break;
9963 case KAFKA_EXPIRE_DELEGATION_TOKEN:
9964 offset = dissect_kafka_expire_delegation_token_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9965 break;
9966 case KAFKA_DESCRIBE_DELEGATION_TOKEN:
9967 offset = dissect_kafka_describe_delegation_token_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9968 break;
9969 case KAFKA_DELETE_GROUPS:
9970 offset = dissect_kafka_delete_groups_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9971 break;
9972 case KAFKA_ELECT_LEADERS:
9973 offset = dissect_kafka_elect_leaders_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9974 break;
9975 case KAFKA_INC_ALTER_CONFIGS:
9976 offset = dissect_kafka_inc_alter_configs_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9977 break;
9978 case KAFKA_ALTER_PARTITION_REASSIGNMENTS:
9979 offset = dissect_kafka_alter_partition_reassignments_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9980 break;
9981 case KAFKA_LIST_PARTITION_REASSIGNMENTS:
9982 offset = dissect_kafka_list_partition_reassignments_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9983 break;
9984 case KAFKA_OFFSET_DELETE:
9985 offset = dissect_kafka_offset_delete_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9986 break;
9987 case KAFKA_DESCRIBE_CLUSTER:
9988 offset = dissect_kafka_describe_cluster_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9989 break;
9990 case KAFKA_ALLOCATE_PRODUCER_IDS:
9991 offset = dissect_kafka_allocate_producer_ids_request(tvb, pinfo, kafka_tree, offset, dissect_api_version);
9992 break;
9995 if (!(has_response && dissect_kafka_insert_match(pinfo, pdu_correlation_id, matcher))) {
9996 wmem_free(wmem_file_scope(), matcher);
10000 else {
10001 /* Response */
10003 /* in the response PDU the correlation id comes directly after frame length */
10004 pdu_correlation_id = tvb_get_ntohl(tvb, offset);
10005 proto_tree_add_item(kafka_tree, hf_kafka_correlation_id, tvb, offset, 4, ENC_BIG_ENDIAN);
10006 offset += 4;
10008 matcher = dissect_kafka_lookup_match(pinfo, pdu_correlation_id);
10010 if (matcher == NULL) {
10011 col_set_str(pinfo->cinfo, COL_INFO, "Kafka Response (Undecoded, Request Missing)");
10012 expert_add_info(pinfo, root_ti, &ei_kafka_request_missing);
10013 return tvb_captured_length(tvb);
10016 col_add_fstr(pinfo->cinfo, COL_INFO, "Kafka %s v%d Response",
10017 kafka_api_key_to_str(matcher->api_key),
10018 matcher->api_version);
10019 /* Also add to protocol root */
10020 proto_item_append_text(root_ti, " (%s v%d Response)",
10021 kafka_api_key_to_str(matcher->api_key),
10022 matcher->api_version);
10025 /* Show request frame */
10026 ti = proto_tree_add_uint(kafka_tree, hf_kafka_request_frame, tvb,
10027 0, 0, matcher->request_frame);
10028 proto_item_set_generated(ti);
10030 /* Show api key (message type) */
10031 ti = proto_tree_add_int(kafka_tree, hf_kafka_response_api_key, tvb,
10032 0, 0, matcher->api_key);
10033 proto_item_set_generated(ti);
10034 proto_item_set_hidden(ti);
10035 ti = proto_tree_add_int(kafka_tree, hf_kafka_api_key, tvb,
10036 0, 0, matcher->api_key);
10037 proto_item_set_generated(ti);
10038 kafka_check_supported_api_key(pinfo, ti, matcher);
10040 /* Also show api version from request */
10041 ti = proto_tree_add_int(kafka_tree, hf_kafka_response_api_version, tvb,
10042 0, 0, matcher->api_version);
10043 proto_item_set_generated(ti);
10044 dissect_api_version = kafka_check_supported_api_version(pinfo, ti, matcher);
10046 if (matcher->api_key == KAFKA_API_VERSIONS) {
10048 * Special case for ApiVersions.
10049 * https://cwiki.apache.org/confluence/display/KAFKA/KIP-511%3A+Collect+and+Expose+Client%27s+Name+and+Version+in+the+Brokers
10050 * https://github.com/apache/kafka/blob/2.5.0/generator/src/main/java/org/apache/kafka/message/ApiMessageTypeGenerator.java#L261-L267
10051 * The code is materialized in ApiMessageTypes class.
10053 } else if (matcher->flexible_api) {
10054 /* version 1 response header (flexible API) contains list of tagged fields, last param is ignored */
10055 offset = dissect_kafka_tagged_fields(tvb, pinfo, kafka_tree, offset, 0);
10058 switch (matcher->api_key) {
10059 case KAFKA_PRODUCE:
10060 offset = dissect_kafka_produce_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10061 break;
10062 case KAFKA_FETCH:
10063 offset = dissect_kafka_fetch_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10064 break;
10065 case KAFKA_OFFSETS:
10066 offset = dissect_kafka_offsets_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10067 break;
10068 case KAFKA_METADATA:
10069 offset = dissect_kafka_metadata_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10070 break;
10071 case KAFKA_LEADER_AND_ISR:
10072 offset = dissect_kafka_leader_and_isr_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10073 break;
10074 case KAFKA_STOP_REPLICA:
10075 offset = dissect_kafka_stop_replica_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10076 break;
10077 case KAFKA_UPDATE_METADATA:
10078 offset = dissect_kafka_update_metadata_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10079 break;
10080 case KAFKA_CONTROLLED_SHUTDOWN:
10081 offset = dissect_kafka_controlled_shutdown_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10082 break;
10083 case KAFKA_OFFSET_COMMIT:
10084 offset = dissect_kafka_offset_commit_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10085 break;
10086 case KAFKA_OFFSET_FETCH:
10087 offset = dissect_kafka_offset_fetch_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10088 break;
10089 case KAFKA_FIND_COORDINATOR:
10090 offset = dissect_kafka_find_coordinator_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10091 break;
10092 case KAFKA_JOIN_GROUP:
10093 offset = dissect_kafka_join_group_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10094 break;
10095 case KAFKA_HEARTBEAT:
10096 offset = dissect_kafka_heartbeat_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10097 break;
10098 case KAFKA_LEAVE_GROUP:
10099 offset = dissect_kafka_leave_group_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10100 break;
10101 case KAFKA_SYNC_GROUP:
10102 offset = dissect_kafka_sync_group_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10103 break;
10104 case KAFKA_DESCRIBE_GROUPS:
10105 offset = dissect_kafka_describe_groups_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10106 break;
10107 case KAFKA_LIST_GROUPS:
10108 offset = dissect_kafka_list_groups_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10109 break;
10110 case KAFKA_SASL_HANDSHAKE:
10111 offset = dissect_kafka_sasl_handshake_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10112 break;
10113 case KAFKA_API_VERSIONS:
10114 offset = dissect_kafka_api_versions_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10115 break;
10116 case KAFKA_CREATE_TOPICS:
10117 offset = dissect_kafka_create_topics_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10118 break;
10119 case KAFKA_DELETE_TOPICS:
10120 offset = dissect_kafka_delete_topics_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10121 break;
10122 case KAFKA_DELETE_RECORDS:
10123 offset = dissect_kafka_delete_records_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10124 break;
10125 case KAFKA_INIT_PRODUCER_ID:
10126 offset = dissect_kafka_init_producer_id_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10127 break;
10128 case KAFKA_OFFSET_FOR_LEADER_EPOCH:
10129 offset = dissect_kafka_offset_for_leader_epoch_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10130 break;
10131 case KAFKA_ADD_PARTITIONS_TO_TXN:
10132 offset = dissect_kafka_add_partitions_to_txn_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10133 break;
10134 case KAFKA_ADD_OFFSETS_TO_TXN:
10135 offset = dissect_kafka_add_offsets_to_txn_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10136 break;
10137 case KAFKA_END_TXN:
10138 offset = dissect_kafka_end_txn_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10139 break;
10140 case KAFKA_WRITE_TXN_MARKERS:
10141 offset = dissect_kafka_write_txn_markers_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10142 break;
10143 case KAFKA_TXN_OFFSET_COMMIT:
10144 offset = dissect_kafka_txn_offset_commit_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10145 break;
10146 case KAFKA_DESCRIBE_ACLS:
10147 offset = dissect_kafka_describe_acls_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10148 break;
10149 case KAFKA_CREATE_ACLS:
10150 offset = dissect_kafka_create_acls_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10151 break;
10152 case KAFKA_DELETE_ACLS:
10153 offset = dissect_kafka_delete_acls_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10154 break;
10155 case KAFKA_DESCRIBE_CONFIGS:
10156 offset = dissect_kafka_describe_configs_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10157 break;
10158 case KAFKA_ALTER_CONFIGS:
10159 offset = dissect_kafka_alter_configs_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10160 break;
10161 case KAFKA_ALTER_REPLICA_LOG_DIRS:
10162 offset = dissect_kafka_alter_replica_log_dirs_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10163 break;
10164 case KAFKA_DESCRIBE_LOG_DIRS:
10165 offset = dissect_kafka_describe_log_dirs_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10166 break;
10167 case KAFKA_CREATE_PARTITIONS:
10168 offset = dissect_kafka_create_partitions_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10169 break;
10170 case KAFKA_SASL_AUTHENTICATE:
10171 offset = dissect_kafka_sasl_authenticate_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10172 break;
10173 case KAFKA_CREATE_DELEGATION_TOKEN:
10174 offset = dissect_kafka_create_delegation_token_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10175 break;
10176 case KAFKA_RENEW_DELEGATION_TOKEN:
10177 offset = dissect_kafka_renew_delegation_token_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10178 break;
10179 case KAFKA_EXPIRE_DELEGATION_TOKEN:
10180 offset = dissect_kafka_expire_delegation_token_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10181 break;
10182 case KAFKA_DESCRIBE_DELEGATION_TOKEN:
10183 offset = dissect_kafka_describe_delegation_token_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10184 break;
10185 case KAFKA_DELETE_GROUPS:
10186 offset = dissect_kafka_delete_groups_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10187 break;
10188 case KAFKA_ELECT_LEADERS:
10189 offset = dissect_kafka_elect_leaders_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10190 break;
10191 case KAFKA_INC_ALTER_CONFIGS:
10192 offset = dissect_kafka_inc_alter_configs_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10193 break;
10194 case KAFKA_ALTER_PARTITION_REASSIGNMENTS:
10195 offset = dissect_kafka_alter_partition_reassignments_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10196 break;
10197 case KAFKA_LIST_PARTITION_REASSIGNMENTS:
10198 offset = dissect_kafka_list_partition_reassignments_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10199 break;
10200 case KAFKA_OFFSET_DELETE:
10201 offset = dissect_kafka_offset_delete_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10202 break;
10203 case KAFKA_DESCRIBE_CLUSTER:
10204 offset = dissect_kafka_describe_cluster_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10205 break;
10206 case KAFKA_ALLOCATE_PRODUCER_IDS:
10207 offset = dissect_kafka_allocate_producer_ids_response(tvb, pinfo, kafka_tree, offset, dissect_api_version);
10208 break;
10213 if (offset != (int)pdu_length + 4) {
10214 expert_add_info(pinfo, root_ti, &ei_kafka_pdu_length_mismatch);
10217 return offset;
10221 * Compute the length of a Kafka protocol frame (PDU) from the minimal fragment.
10222 * The datastream in TCP (and TLS) is and abstraction of continuous stream of octets.
10223 * On the network level these are transported in chunks (packets). On the application
10224 * protocol level we do also deal with discrete chunks (PDUs). Ideally these should
10225 * match. In the real life the boundaries are different. In Kafka case a PDU may span
10226 * multiple network packets. A PDU starts with 32 bit unsigned integer that specifies
10227 * remaining protocol frame length. Fortunatelly protocol implementations execute
10228 * flush between subsequent PDUs, therefore we should not expect PDU starting in the middle
10229 * of TCP data packet or TLS data frame.
10231 static unsigned
10232 get_kafka_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
10234 return 4 + tvb_get_ntohl(tvb, offset);
10238 * Attempt to dissect Kafka protocol frames.
10240 static int
10241 dissect_kafka_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
10243 tcp_dissect_pdus(tvb, pinfo, tree, true, 4,
10244 get_kafka_pdu_len, dissect_kafka, data);
10245 return tvb_captured_length(tvb);
10248 static void
10249 compute_kafka_api_names(void)
10251 unsigned i;
10252 unsigned len = array_length(kafka_apis);
10254 for (i = 0; i < len; ++i) {
10255 kafka_api_names[i].value = kafka_apis[i].api_key;
10256 kafka_api_names[i].strptr = kafka_apis[i].name;
10259 kafka_api_names[len].value = 0;
10260 kafka_api_names[len].strptr = NULL;
10263 static void
10264 proto_register_kafka_protocol_fields(int protocol)
10266 static hf_register_info hf[] = {
10267 { &hf_kafka_len,
10268 { "Length", "kafka.len",
10269 FT_INT32, BASE_DEC, 0, 0,
10270 "The length of this Kafka packet.", HFILL }
10272 { &hf_kafka_offset,
10273 { "Offset", "kafka.offset",
10274 FT_INT64, BASE_DEC, 0, 0,
10275 NULL, HFILL }
10277 { &hf_kafka_offset_time,
10278 { "Time", "kafka.offset_time",
10279 FT_INT64, BASE_DEC, 0, 0,
10280 NULL, HFILL }
10282 { &hf_kafka_log_start_offset,
10283 { "Log Start Offset", "kafka.log_start_offset",
10284 FT_INT64, BASE_DEC, 0, 0,
10285 NULL, HFILL }
10287 { &hf_kafka_last_stable_offset,
10288 { "Last Stable Offset", "kafka.last_stable_offset",
10289 FT_INT64, BASE_DEC, 0, 0,
10290 NULL, HFILL }
10292 { &hf_kafka_first_offset,
10293 { "First Offset", "kafka.first_offset",
10294 FT_INT64, BASE_DEC, 0, 0,
10295 NULL, HFILL }
10297 { &hf_kafka_max_offsets,
10298 { "Max Offsets", "kafka.max_offsets",
10299 FT_INT32, BASE_DEC, 0, 0,
10300 NULL, HFILL }
10302 { &hf_kafka_metadata,
10303 { "Metadata", "kafka.metadata",
10304 FT_STRING, BASE_NONE, 0, 0,
10305 NULL, HFILL }
10307 { &hf_kafka_error,
10308 { "Error", "kafka.error",
10309 FT_INT16, BASE_DEC, VALS(kafka_errors), 0,
10310 NULL, HFILL }
10312 { &hf_kafka_error_message,
10313 { "Error Message", "kafka.error_message",
10314 FT_STRING, BASE_NONE, 0, 0,
10315 NULL, HFILL }
10317 { &hf_kafka_api_key,
10318 { "API Key", "kafka.api_key",
10319 FT_INT16, BASE_DEC, VALS(kafka_api_names), 0,
10320 "Request API Key.", HFILL }
10322 { &hf_kafka_api_version,
10323 { "API Version", "kafka.api_version",
10324 FT_INT16, BASE_DEC, 0, 0,
10325 "Request API Version.", HFILL }
10327 // these should be deprecated
10328 // --- begin ---
10329 { &hf_kafka_request_api_key,
10330 { "API Key", "kafka.request_key",
10331 FT_INT16, BASE_DEC, VALS(kafka_api_names), 0,
10332 "Request API.", HFILL }
10334 { &hf_kafka_response_api_key,
10335 { "API Key", "kafka.response_key",
10336 FT_INT16, BASE_DEC, VALS(kafka_api_names), 0,
10337 "Response API.", HFILL }
10339 { &hf_kafka_request_api_version,
10340 { "API Version", "kafka.request.version",
10341 FT_INT16, BASE_DEC, 0, 0,
10342 "Request API Version.", HFILL }
10344 { &hf_kafka_response_api_version,
10345 { "API Version", "kafka.response.version",
10346 FT_INT16, BASE_DEC, 0, 0,
10347 "Response API Version.", HFILL }
10349 // --- end ---
10350 { &hf_kafka_correlation_id,
10351 { "Correlation ID", "kafka.correlation_id",
10352 FT_INT32, BASE_DEC, 0, 0,
10353 NULL, HFILL }
10355 { &hf_kafka_client_id,
10356 { "Client ID", "kafka.client_id",
10357 FT_STRING, BASE_NONE, 0, 0,
10358 "The ID of the sending client.", HFILL }
10360 { &hf_kafka_client_host,
10361 { "Client Host", "kafka.client_host",
10362 FT_STRING, BASE_NONE, 0, 0,
10363 NULL, HFILL }
10365 { &hf_kafka_transactional_id,
10366 { "Transactional ID", "kafka.transactional_id",
10367 FT_STRING, BASE_NONE, 0, 0,
10368 NULL, HFILL }
10370 { &hf_kafka_transaction_result,
10371 { "Transaction Result", "kafka.transaction_result",
10372 FT_INT8, BASE_DEC, VALS(kafka_transaction_results), 0,
10373 NULL, HFILL }
10375 { &hf_kafka_transaction_timeout,
10376 { "Transaction Timeout", "kafka.transaction_timeout",
10377 FT_INT32, BASE_DEC, 0, 0,
10378 NULL, HFILL }
10380 { &hf_kafka_required_acks,
10381 { "Required Acks", "kafka.required_acks",
10382 FT_INT16, BASE_DEC, VALS(kafka_acks), 0,
10383 NULL, HFILL }
10385 { &hf_kafka_timeout,
10386 { "Timeout", "kafka.timeout",
10387 FT_INT32, BASE_DEC, 0, 0,
10388 NULL, HFILL }
10390 { &hf_kafka_topic_id,
10391 { "Topic ID", "kafka.topic_id",
10392 FT_GUID, BASE_NONE, 0, 0,
10393 NULL, HFILL }
10395 { &hf_kafka_topic_name,
10396 { "Topic Name", "kafka.topic_name",
10397 FT_STRING, BASE_NONE, 0, 0,
10398 NULL, HFILL }
10400 { &hf_kafka_producer_id,
10401 { "Producer ID", "kafka.producer_id",
10402 FT_INT64, BASE_DEC, 0, 0,
10403 NULL, HFILL }
10405 { &hf_kafka_producer_epoch,
10406 { "Producer Epoch", "kafka.producer_epoch",
10407 FT_INT16, BASE_DEC, 0, 0,
10408 NULL, HFILL }
10410 { &hf_kafka_partition_id,
10411 { "Partition ID", "kafka.partition_id",
10412 FT_INT32, BASE_DEC, 0, 0,
10413 NULL, HFILL }
10415 { &hf_kafka_replica,
10416 { "Replica ID", "kafka.replica_id",
10417 FT_INT32, BASE_DEC, 0, 0,
10418 NULL, HFILL }
10420 { &hf_kafka_replication_factor,
10421 { "Replication Factor", "kafka.replication_factor",
10422 FT_INT16, BASE_DEC, 0, 0,
10423 NULL, HFILL }
10425 { &hf_kafka_isr,
10426 { "Caught-Up Replica ID", "kafka.isr_id",
10427 FT_INT32, BASE_DEC, 0, 0,
10428 NULL, HFILL }
10430 { &hf_kafka_offline,
10431 { "Offline Replica ID", "kafka.offline_id",
10432 FT_INT32, BASE_DEC, 0, 0,
10433 NULL, HFILL }
10435 { &hf_kafka_message_size,
10436 { "Message Size", "kafka.message_size",
10437 FT_INT32, BASE_DEC, 0, 0,
10438 NULL, HFILL }
10440 { &hf_kafka_message_crc,
10441 { "CRC32", "kafka.message_crc",
10442 FT_UINT32, BASE_HEX, 0, 0,
10443 NULL, HFILL }
10445 { &hf_kafka_message_magic,
10446 { "Magic Byte", "kafka.message_magic",
10447 FT_INT8, BASE_DEC, 0, 0,
10448 NULL, HFILL }
10450 { &hf_kafka_message_codec,
10451 { "Compression Codec", "kafka.message_codec",
10452 FT_UINT8, BASE_DEC, VALS(kafka_message_codecs), KAFKA_MESSAGE_CODEC_MASK,
10453 NULL, HFILL }
10455 { &hf_kafka_message_timestamp_type,
10456 { "Timestamp Type", "kafka.message_timestamp_type",
10457 FT_UINT8, BASE_DEC, VALS(kafka_message_timestamp_types), KAFKA_MESSAGE_TIMESTAMP_MASK,
10458 NULL, HFILL }
10460 { &hf_kafka_batch_crc,
10461 { "CRC32", "kafka.batch_crc",
10462 FT_UINT32, BASE_HEX, 0, 0,
10463 NULL, HFILL }
10465 { &hf_kafka_batch_codec,
10466 { "Compression Codec", "kafka.batch_codec",
10467 FT_UINT16, BASE_DEC, VALS(kafka_message_codecs), KAFKA_MESSAGE_CODEC_MASK,
10468 NULL, HFILL }
10470 { &hf_kafka_batch_timestamp_type,
10471 { "Timestamp Type", "kafka.batch_timestamp_type",
10472 FT_UINT16, BASE_DEC, VALS(kafka_message_timestamp_types), KAFKA_MESSAGE_TIMESTAMP_MASK,
10473 NULL, HFILL }
10475 { &hf_kafka_batch_transactional,
10476 { "Transactional", "kafka.batch_transactional",
10477 FT_UINT16, BASE_DEC, VALS(kafka_batch_transactional_values), KAFKA_BATCH_TRANSACTIONAL_MASK,
10478 NULL, HFILL }
10480 { &hf_kafka_batch_control_batch,
10481 { "Control Batch", "kafka.batch_control_batch",
10482 FT_UINT16, BASE_DEC, VALS(kafka_batch_control_batch_values), KAFKA_BATCH_CONTROL_BATCH_MASK,
10483 NULL, HFILL }
10485 { &hf_kafka_batch_last_offset_delta,
10486 { "Last Offset Delta", "kafka.batch_last_offset_delta",
10487 FT_UINT32, BASE_DEC, 0, 0,
10488 NULL, HFILL }
10490 { &hf_kafka_batch_first_timestamp,
10491 { "First Timestamp", "kafka.batch_first_timestamp",
10492 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
10493 NULL, HFILL }
10495 { &hf_kafka_batch_last_timestamp,
10496 { "Last Timestamp", "kafka.batch_last_timestamp",
10497 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
10498 NULL, HFILL }
10500 { &hf_kafka_batch_base_sequence,
10501 { "Base Sequence", "kafka.batch_base_sequence",
10502 FT_INT32, BASE_DEC, 0, 0,
10503 NULL, HFILL }
10505 { &hf_kafka_batch_size,
10506 { "Size", "kafka.batch_size",
10507 FT_UINT32, BASE_DEC, 0, 0,
10508 NULL, HFILL }
10510 { &hf_kafka_batch_index,
10511 { "Batch Index", "kafka.batch_index",
10512 FT_UINT32, BASE_DEC, 0, 0,
10513 NULL, HFILL }
10515 { &hf_kafka_batch_index_error_message,
10516 { "Batch Index Error Message", "kafka.batch_index_error_message",
10517 FT_STRING, BASE_NONE, 0, 0,
10518 NULL, HFILL }
10520 { &hf_kafka_message_timestamp,
10521 { "Timestamp", "kafka.message_timestamp",
10522 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
10523 NULL, HFILL }
10525 { &hf_kafka_message_key,
10526 { "Key", "kafka.message_key",
10527 FT_BYTES, BASE_SHOW_ASCII_PRINTABLE, 0, 0,
10528 NULL, HFILL }
10530 { &hf_kafka_message_value,
10531 { "Value", "kafka.message_value",
10532 FT_BYTES, BASE_SHOW_ASCII_PRINTABLE, 0, 0,
10533 NULL, HFILL }
10535 { &hf_kafka_message_compression_reduction,
10536 { "Compression Reduction (compressed/uncompressed)", "kafka.message_compression_reduction",
10537 FT_FLOAT, BASE_NONE, 0, 0,
10538 NULL, HFILL }
10540 { &hf_kafka_truncated_content,
10541 { "Truncated Content", "kafka.truncated_content",
10542 FT_BYTES, BASE_NONE, 0, 0,
10543 NULL, HFILL }
10545 { &hf_kafka_consumer_group,
10546 { "Consumer Group", "kafka.consumer_group",
10547 FT_STRING, BASE_NONE, 0, 0,
10548 NULL, HFILL }
10550 { &hf_kafka_consumer_group_instance,
10551 { "Consumer Group Instance", "kafka.consumer_group_instance",
10552 FT_STRING, BASE_NONE, 0, 0,
10553 NULL, HFILL }
10555 { &hf_kafka_coordinator_key,
10556 { "Coordinator Key", "kafka.coordinator_key",
10557 FT_STRING, BASE_NONE, 0, 0,
10558 NULL, HFILL }
10560 { &hf_kafka_coordinator_type,
10561 { "Coordinator Type", "kafka.coordinator_type",
10562 FT_INT8, BASE_DEC, VALS(kafka_coordinator_types), 0,
10563 NULL, HFILL }
10565 { &hf_kafka_request_frame,
10566 { "Request Frame", "kafka.request_frame",
10567 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0,
10568 NULL, HFILL }
10570 { &hf_kafka_broker_nodeid,
10571 { "Node ID", "kafka.node_id",
10572 FT_INT32, BASE_DEC, 0, 0,
10573 NULL, HFILL }
10575 { &hf_kafka_broker_epoch,
10576 { "Broker Epoch", "kafka.broker_epoch",
10577 FT_INT64, BASE_DEC, 0, 0,
10578 NULL, HFILL }
10580 { &hf_kafka_broker_host,
10581 { "Host", "kafka.host",
10582 FT_STRING, BASE_NONE, 0, 0,
10583 NULL, HFILL }
10585 { &hf_kafka_listener_name,
10586 { "Listener", "kafka.listener_name",
10587 FT_STRING, BASE_NONE, 0, 0,
10588 NULL, HFILL }
10590 { &hf_kafka_broker_port,
10591 { "Port", "kafka.port",
10592 FT_INT32, BASE_DEC, 0, 0,
10593 NULL, HFILL }
10595 { &hf_kafka_rack,
10596 { "Rack", "kafka.rack",
10597 FT_STRING, BASE_NONE, 0, 0,
10598 NULL, HFILL }
10600 { &hf_kafka_broker_security_protocol_type,
10601 { "Security Protocol Type", "kafka.broker_security_protocol_type",
10602 FT_INT16, BASE_DEC, VALS(kafka_security_protocol_types), 0,
10603 NULL, HFILL }
10605 { &hf_kafka_cluster_id,
10606 { "Cluster ID", "kafka.cluster_id",
10607 FT_STRING, BASE_NONE, 0, 0,
10608 NULL, HFILL }
10610 { &hf_kafka_controller_id,
10611 { "Controller ID", "kafka.node_id",
10612 FT_INT32, BASE_DEC, 0, 0,
10613 NULL, HFILL }
10615 { &hf_kafka_controller_epoch,
10616 { "Controller Epoch", "kafka.controller_epoch",
10617 FT_INT32, BASE_DEC, 0, 0,
10618 NULL, HFILL }
10620 { &hf_kafka_delete_partitions,
10621 { "Delete Partitions", "kafka.delete_partitions",
10622 FT_BOOLEAN, BASE_NONE, 0, 0,
10623 NULL, HFILL }
10625 { &hf_kafka_group_leader_id,
10626 { "Leader ID", "kafka.group_leader_id",
10627 FT_STRING, BASE_NONE, 0, 0,
10628 NULL, HFILL }
10630 { &hf_kafka_leader_id,
10631 { "Leader ID", "kafka.leader_id",
10632 FT_INT32, BASE_DEC, 0, 0,
10633 NULL, HFILL }
10635 { &hf_kafka_leader_epoch,
10636 { "Leader Epoch", "kafka.leader_epoch",
10637 FT_INT32, BASE_DEC, 0, 0,
10638 NULL, HFILL }
10640 { &hf_kafka_current_leader_epoch,
10641 { "Leader Epoch", "kafka.current_leader_epoch",
10642 FT_INT32, BASE_DEC, 0, 0,
10643 NULL, HFILL }
10645 { &hf_kafka_is_internal,
10646 { "Is Internal", "kafka.is_internal",
10647 FT_BOOLEAN, BASE_NONE, 0, 0,
10648 NULL, HFILL }
10650 { &hf_kafka_min_bytes,
10651 { "Min Bytes", "kafka.min_bytes",
10652 FT_INT32, BASE_DEC, 0, 0,
10653 "The minimum number of bytes of messages that must be available"
10654 " to give a response.",
10655 HFILL }
10657 { &hf_kafka_max_bytes,
10658 { "Max Bytes", "kafka.max_bytes",
10659 FT_INT32, BASE_DEC, 0, 0,
10660 "The maximum bytes to include in the message set for this"
10661 " partition. This helps bound the size of the response.",
10662 HFILL }
10664 { &hf_kafka_isolation_level,
10665 { "Isolation Level", "kafka.isolation_level",
10666 FT_INT8, BASE_DEC, VALS(kafka_isolation_levels), 0,
10667 NULL, HFILL }
10669 { &hf_kafka_max_wait_time,
10670 { "Max Wait Time", "kafka.max_wait_time",
10671 FT_INT32, BASE_DEC, 0, 0,
10672 "The maximum amount of time in milliseconds to block waiting if"
10673 " insufficient data is available at the time the request is"
10674 " issued.",
10675 HFILL }
10677 { &hf_kafka_throttle_time,
10678 { "Throttle time", "kafka.throttle_time",
10679 FT_INT32, BASE_DEC, 0, 0,
10680 "Duration in milliseconds for which the request was throttled"
10681 " due to quota violation."
10682 " (Zero if the request did not violate any quota.)",
10683 HFILL }
10685 { &hf_kafka_response_frame,
10686 { "Response Frame", "kafka.response_frame",
10687 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0,
10688 NULL, HFILL }
10690 { &hf_kafka_api_versions_api_key,
10691 { "API Key", "kafka.api_versions.api_key",
10692 FT_INT16, BASE_DEC, VALS(kafka_api_names), 0,
10693 "API Key.", HFILL }
10695 { &hf_kafka_api_versions_min_version,
10696 { "Min Version", "kafka.api_versions.min_version",
10697 FT_INT16, BASE_DEC, 0, 0,
10698 "Minimal version which supports api key.", HFILL }
10700 { &hf_kafka_api_versions_max_version,
10701 { "Max Version", "kafka.api_versions.max_version",
10702 FT_INT16, BASE_DEC, 0, 0,
10703 "Maximal version which supports api key.", HFILL }
10705 { &hf_kafka_session_timeout,
10706 { "Session Timeout", "kafka.session_timeout",
10707 FT_INT32, BASE_DEC, 0, 0,
10708 NULL, HFILL }
10710 { &hf_kafka_rebalance_timeout,
10711 { "Rebalance Timeout", "kafka.rebalance_timeout",
10712 FT_INT32, BASE_DEC, 0, 0,
10713 NULL, HFILL }
10715 { &hf_kafka_group_state,
10716 { "State", "kafka.group_state",
10717 FT_STRING, BASE_NONE, 0, 0,
10718 NULL, HFILL }
10720 { &hf_kafka_member_id,
10721 { "Consumer Group Member ID", "kafka.member_id",
10722 FT_STRING, BASE_NONE, 0, 0,
10723 NULL, HFILL }
10725 { &hf_kafka_protocol_type,
10726 { "Protocol Type", "kafka.protocol_type",
10727 FT_STRING, BASE_NONE, 0, 0,
10728 NULL, HFILL }
10730 { &hf_kafka_protocol_name,
10731 { "Protocol Name", "kafka.protocol_name",
10732 FT_STRING, BASE_NONE, 0, 0,
10733 NULL, HFILL }
10735 { &hf_kafka_protocol_metadata,
10736 { "Protocol Metadata", "kafka.protocol_metadata",
10737 FT_BYTES, BASE_NONE, 0, 0,
10738 NULL, HFILL }
10740 { &hf_kafka_member_metadata,
10741 { "Member Metadata", "kafka.member_metadata",
10742 FT_BYTES, BASE_NONE, 0, 0,
10743 NULL, HFILL }
10745 { &hf_kafka_generation_id,
10746 { "Generation ID", "kafka.generation_id",
10747 FT_INT32, BASE_DEC, 0, 0,
10748 NULL, HFILL }
10750 { &hf_kafka_member_assignment,
10751 { "Member Assignment", "kafka.member_assignment",
10752 FT_BYTES, BASE_NONE, 0, 0,
10753 NULL, HFILL }
10755 { &hf_kafka_sasl_mechanism,
10756 { "SASL Mechanism", "kafka.sasl_mechanism",
10757 FT_STRING, BASE_NONE, 0, 0,
10758 NULL, HFILL }
10760 { &hf_kafka_num_partitions,
10761 { "Number of Partitions", "kafka.num_partitions",
10762 FT_INT32, BASE_DEC, 0, 0,
10763 NULL, HFILL }
10765 { &hf_kafka_zk_version,
10766 { "Zookeeper Version", "kafka.zk_version",
10767 FT_INT32, BASE_DEC, 0, 0,
10768 NULL, HFILL }
10770 { &hf_kafka_is_new_replica,
10771 { "New Replica", "kafka.is_new_replica",
10772 FT_BOOLEAN, BASE_NONE, 0, 0,
10773 NULL, HFILL }
10775 { &hf_kafka_leader_recovery_state,
10776 { "Leader Recovery State", "kafka.leader_recovery_state",
10777 FT_INT8, BASE_DEC, 0, 0,
10778 NULL, HFILL }
10780 { &hf_kafka_config_key,
10781 { "Key", "kafka.config_key",
10782 FT_STRING, BASE_NONE, 0, 0,
10783 NULL, HFILL }
10785 { &hf_kafka_config_value,
10786 { "Value", "kafka.config_value",
10787 FT_STRING, BASE_NONE, 0, 0,
10788 NULL, HFILL }
10790 { &hf_kafka_config_operation,
10791 { "Operation", "kafka.config_operation",
10792 FT_INT8, BASE_DEC, VALS(config_operations), 0,
10793 NULL, HFILL }
10795 { &hf_kafka_commit_timestamp,
10796 { "Timestamp", "kafka.commit_timestamp",
10797 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
10798 NULL, HFILL }
10800 { &hf_kafka_retention_time,
10801 { "Retention Time", "kafka.retention_time",
10802 FT_INT64, BASE_DEC, 0, 0,
10803 NULL, HFILL }
10805 { &hf_kafka_forgotten_topic_name,
10806 { "Forgotten Topic Name", "kafka.forgotten_topic_name",
10807 FT_STRING, BASE_NONE, 0, 0,
10808 NULL, HFILL }
10810 { &hf_kafka_forgotten_topic_id,
10811 { "Forgotten Topic ID", "kafka.forgotten_topic_id",
10812 FT_GUID, BASE_NONE, 0, 0,
10813 NULL, HFILL }
10815 { &hf_kafka_forgotten_topic_partition,
10816 { "Forgotten Topic Partition", "kafka.forgotten_topic_partition",
10817 FT_INT64, BASE_DEC, 0, 0,
10818 NULL, HFILL }
10820 { &hf_kafka_fetch_session_id,
10821 { "Fetch Session ID", "kafka.fetch_session_id",
10822 FT_INT64, BASE_DEC, 0, 0,
10823 NULL, HFILL }
10825 { &hf_kafka_fetch_session_epoch,
10826 { "Fetch Session Epoch", "kafka.fetch_session_epoch",
10827 FT_INT64, BASE_DEC, 0, 0,
10828 NULL, HFILL }
10830 { &hf_kafka_require_stable_offset,
10831 { "Require Stable Offset", "kafka.require_stable_offset",
10832 FT_BOOLEAN, BASE_NONE, 0, 0,
10833 NULL, HFILL }
10835 { &hf_kafka_record_header_key,
10836 { "Header Key", "kafka.header_key",
10837 FT_STRING, BASE_NONE, 0, 0,
10838 NULL, HFILL }
10840 { &hf_kafka_record_header_value,
10841 { "Header Value", "kafka.header_value",
10842 FT_BYTES, BASE_SHOW_ASCII_PRINTABLE, 0, 0,
10843 NULL, HFILL }
10845 { &hf_kafka_record_attributes,
10846 { "Record Attributes (reserved)", "kafka.record_attributes",
10847 FT_INT8, BASE_DEC, 0, 0,
10848 NULL, HFILL }
10850 { &hf_kafka_allow_auto_topic_creation,
10851 { "Allow Auto Topic Creation", "kafka.allow_auto_topic_creation",
10852 FT_BOOLEAN, BASE_NONE, 0, 0,
10853 NULL, HFILL }
10855 { &hf_kafka_validate_only,
10856 { "Only Validate the Request", "kafka.validate_only",
10857 FT_BOOLEAN, BASE_NONE, 0, 0,
10858 NULL, HFILL }
10860 { &hf_kafka_coordinator_epoch,
10861 { "Coordinator Epoch", "kafka.coordinator_epoch",
10862 FT_INT32, BASE_DEC, 0, 0,
10863 NULL, HFILL }
10865 { &hf_kafka_sasl_auth_bytes,
10866 { "SASL Authentication Bytes", "kafka.sasl_authentication",
10867 FT_BYTES, BASE_NONE, 0, 0,
10868 NULL, HFILL }
10870 { &hf_kafka_session_lifetime_ms,
10871 { "Session Lifetime (ms)", "kafka.session_lifetime_ms",
10872 FT_INT64, BASE_DEC, 0, 0,
10873 NULL, HFILL }
10875 { &hf_kafka_acl_resource_type,
10876 { "Resource Type", "kafka.acl_resource_type",
10877 FT_INT8, BASE_DEC, VALS(acl_resource_types), 0,
10878 NULL, HFILL }
10880 { &hf_kafka_acl_resource_name,
10881 { "Resource Name", "kafka.acl_resource_name",
10882 FT_STRING, BASE_NONE, 0, 0,
10883 NULL, HFILL }
10885 { &hf_kafka_acl_resource_pattern_type,
10886 { "Resource Pattern Type", "kafka.acl_resource_pattern_type",
10887 FT_INT8, BASE_DEC, VALS(acl_resource_pattern_types), 0,
10888 NULL, HFILL }
10890 { &hf_kafka_acl_principal,
10891 { "Principal", "kafka.acl_principal",
10892 FT_STRING, BASE_NONE, 0, 0,
10893 NULL, HFILL }
10895 { &hf_kafka_acl_host,
10896 { "Host", "kafka.acl_host",
10897 FT_STRING, BASE_NONE, 0, 0,
10898 NULL, HFILL }
10900 { &hf_kafka_acl_operation,
10901 { "Operation", "kafka.acl_operation",
10902 FT_INT8, BASE_DEC, VALS(acl_operations), 0,
10903 NULL, HFILL }
10905 { &hf_kafka_acl_permission_type,
10906 { "Permission Type", "kafka.acl_permission_type",
10907 FT_INT8, BASE_DEC, VALS(acl_permission_types), 0,
10908 NULL, HFILL }
10910 { &hf_kafka_config_resource_type,
10911 { "Resource Type", "kafka.config_resource_type",
10912 FT_INT8, BASE_DEC, VALS(config_resource_types), 0,
10913 NULL, HFILL }
10915 { &hf_kafka_config_resource_name,
10916 { "Resource Name", "kafka.config_resource_name",
10917 FT_STRING, BASE_NONE, 0, 0,
10918 NULL, HFILL }
10920 { &hf_kafka_config_include_synonyms,
10921 { "Include Synonyms", "kafka.config_include_synonyms",
10922 FT_BOOLEAN, BASE_NONE, 0, 0,
10923 NULL, HFILL }
10925 { &hf_kafka_config_include_documentation,
10926 { "Include Documentation", "kafka.config_include_documentation",
10927 FT_BOOLEAN, BASE_NONE, 0, 0,
10928 NULL, HFILL }
10930 { &hf_kafka_config_default,
10931 { "Default", "kafka.config_default",
10932 FT_BOOLEAN, BASE_NONE, 0, 0,
10933 NULL, HFILL }
10935 { &hf_kafka_config_readonly,
10936 { "Readonly", "kafka.config_readonly",
10937 FT_BOOLEAN, BASE_NONE, 0, 0,
10938 NULL, HFILL }
10940 { &hf_kafka_config_sensitive,
10941 { "Sensitive", "kafka.config_sensitive",
10942 FT_BOOLEAN, BASE_NONE, 0, 0,
10943 NULL, HFILL }
10945 { &hf_kafka_config_data_type,
10946 { "Data Type", "kafka.config_data_type",
10947 FT_INT8, BASE_DEC, 0, 0,
10948 NULL, HFILL }
10950 { &hf_kafka_config_documentation,
10951 { "Documentation", "kafka.config_documentation",
10952 FT_STRING, BASE_NONE, 0, 0,
10953 NULL, HFILL }
10955 { &hf_kafka_config_source,
10956 { "Source", "kafka.config_source",
10957 FT_INT8, BASE_DEC, VALS(config_sources), 0,
10958 NULL, HFILL }
10960 { &hf_kafka_log_dir,
10961 { "Log Directory", "kafka.log_dir",
10962 FT_STRING, BASE_NONE, 0, 0,
10963 NULL, HFILL }
10965 { &hf_kafka_segment_size,
10966 { "Segment Size", "kafka.segment_size",
10967 FT_UINT64, BASE_DEC, 0, 0,
10968 NULL, HFILL }
10970 { &hf_kafka_offset_lag,
10971 { "Offset Lag", "kafka.offset_lag",
10972 FT_UINT64, BASE_DEC, 0, 0,
10973 NULL, HFILL }
10975 { &hf_kafka_future,
10976 { "Future", "kafka.future",
10977 FT_BOOLEAN, BASE_NONE, 0, 0,
10978 NULL, HFILL }
10980 { &hf_kafka_partition_count,
10981 { "Partition Count", "kafka.partition_count",
10982 FT_UINT32, BASE_DEC, 0, 0,
10983 NULL, HFILL }
10985 { &hf_kafka_token_max_life_time,
10986 { "Max Life Time", "kafka.token_max_life_time",
10987 FT_INT64, BASE_DEC, 0, 0,
10988 NULL, HFILL }
10990 { &hf_kafka_token_renew_time,
10991 { "Renew Time", "kafka.renew_time",
10992 FT_INT64, BASE_DEC, 0, 0,
10993 NULL, HFILL }
10995 { &hf_kafka_token_expiry_time,
10996 { "Expiry Time", "kafka.expiry_time",
10997 FT_INT64, BASE_DEC, 0, 0,
10998 NULL, HFILL }
11000 { &hf_kafka_token_principal_type,
11001 { "Principal Type", "kafka.principal_type",
11002 FT_STRING, BASE_NONE, 0, 0,
11003 NULL, HFILL }
11005 { &hf_kafka_token_principal_name,
11006 { "Principal Name", "kafka.principal_name",
11007 FT_STRING, BASE_NONE, 0, 0,
11008 NULL, HFILL }
11010 { &hf_kafka_token_issue_timestamp,
11011 { "Issue Timestamp", "kafka.token_issue_timestamp",
11012 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
11013 NULL, HFILL }
11015 { &hf_kafka_token_expiry_timestamp,
11016 { "Expiry Timestamp", "kafka.token_expiry_timestamp",
11017 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
11018 NULL, HFILL }
11020 { &hf_kafka_token_max_timestamp,
11021 { "Max Timestamp", "kafka.token_max_timestamp",
11022 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
11023 NULL, HFILL }
11025 { &hf_kafka_token_id,
11026 { "ID", "kafka.token_id",
11027 FT_STRING, BASE_NONE, 0, 0,
11028 NULL, HFILL }
11030 { &hf_kafka_token_hmac,
11031 { "HMAC", "kafka.token_hmac",
11032 FT_BYTES, BASE_NONE, 0, 0,
11033 NULL, HFILL }
11035 { &hf_kafka_include_cluster_authorized_ops,
11036 { "Include Cluster Authorized Operations", "kafka.include_cluster_authorized_ops",
11037 FT_BOOLEAN, BASE_NONE, 0, 0,
11038 NULL, HFILL }
11040 { &hf_kafka_include_topic_authorized_ops,
11041 { "Include Topic Authorized Operations", "kafka.include_topic_authorized_ops",
11042 FT_BOOLEAN, BASE_NONE, 0, 0,
11043 NULL, HFILL }
11045 { &hf_kafka_cluster_authorized_ops,
11046 { "Cluster Authorized Operations", "kafka.cluster_authorized_ops",
11047 FT_UINT32, BASE_HEX, 0, 0,
11048 NULL, HFILL }
11050 { &hf_kafka_topic_authorized_ops,
11051 { "Topic Authorized Operations", "kafka.topic_authorized_ops",
11052 FT_UINT32, BASE_HEX, 0, 0,
11053 NULL, HFILL }
11055 { &hf_kafka_include_group_authorized_ops,
11056 { "Include Group Authorized Operations", "kafka.include_group_authorized_ops",
11057 FT_BOOLEAN, BASE_NONE, 0, 0,
11058 NULL, HFILL }
11060 { &hf_kafka_group_authorized_ops,
11061 { "Group Authorized Operations", "kafka.group_authorized_ops",
11062 FT_UINT32, BASE_HEX, 0, 0,
11063 NULL, HFILL }
11065 { &hf_kafka_election_type,
11066 { "Election Type", "kafka.election_type",
11067 FT_INT8, BASE_DEC, VALS(election_types), 0,
11068 NULL, HFILL }
11070 { &hf_kafka_tagged_field_tag,
11071 { "Tag Value", "kafka.tagged_field_tag",
11072 FT_UINT64, BASE_HEX, 0, 0,
11073 NULL, HFILL }
11075 { &hf_kafka_tagged_field_data,
11076 { "Tag Data", "kafka.tagged_field_data",
11077 FT_BYTES, BASE_SHOW_ASCII_PRINTABLE, 0, 0,
11078 NULL, HFILL }
11080 { &hf_kafka_client_software_name,
11081 { "Client Software Name", "kafka.client_software_name",
11082 FT_STRING, BASE_NONE, 0, 0,
11083 NULL, HFILL }
11085 { &hf_kafka_client_software_version,
11086 { "Client Software Version", "kafka.client_software_version",
11087 FT_STRING, BASE_NONE, 0, 0,
11088 NULL, HFILL }
11090 { &hf_kafka_is_kraft_controller,
11091 { "Is KRaft Controller", "kafka.is_kraft_controller",
11092 FT_BOOLEAN, BASE_NONE, 0, 0,
11093 NULL, HFILL }
11095 { &hf_kafka_topic_inclusion_type,
11096 { "Topic Inclusion Type", "kafka.topic_inclusion_type",
11097 FT_INT8, BASE_DEC, 0, 0,
11098 NULL, HFILL }
11100 { &hf_kafka_delete_partition,
11101 { "Delete Partition", "kafka.delete_partition",
11102 FT_BOOLEAN, BASE_NONE, 0, 0,
11103 NULL, HFILL }
11105 { &hf_kafka_join_reason,
11106 { "(Re)Join Reason", "kafka.join_reason",
11107 FT_STRING, BASE_NONE, 0, 0,
11108 NULL, HFILL }
11110 { &hf_kafka_leave_reason,
11111 { "Leave Reason", "kafka.leave_reason",
11112 FT_STRING, BASE_NONE, 0, 0,
11113 NULL, HFILL }
11115 { &hf_kafka_skip_assignment,
11116 { "Skip Assignment", "kafka.skip_assignment",
11117 FT_BOOLEAN, BASE_NONE, 0, 0,
11118 NULL, HFILL }
11120 { &hf_kafka_producer_id_start,
11121 { "First Producer ID", "kafka.producer_id_start",
11122 FT_INT64, BASE_DEC, 0, 0,
11123 NULL, HFILL }
11125 { &hf_kafka_producer_id_len,
11126 { "Number of Producers", "kafka.producer_len",
11127 FT_INT32, BASE_DEC, 0, 0,
11128 NULL, HFILL }
11130 { &hf_kafka_group_id,
11131 { "Group ID", "kafka.group_id",
11132 FT_STRING, BASE_NONE, 0, 0,
11133 NULL, HFILL }
11135 { &hf_kafka_member_epoch,
11136 { "Member Epoch", "kafka.member_epoch",
11137 FT_INT32, BASE_DEC, 0, 0,
11138 NULL, HFILL }
11140 { &hf_kafka_endpoint_type,
11141 { "Endpoint Type", "kafka.endpoint_type",
11142 FT_INT8, BASE_DEC, 0, 0,
11143 NULL, HFILL }
11145 { &hf_kafka_last_fetched_epoch,
11146 { "Last Fetched Epoch", "kafka.last_fetched_epoch",
11147 FT_INT32, BASE_DEC, 0, 0,
11148 NULL, HFILL }
11152 proto_register_field_array(protocol, hf, array_length(hf));
11156 static void
11157 proto_register_kafka_protocol_subtrees(const int proto _U_)
11159 static int *ett[] = {
11160 &ett_kafka,
11161 &ett_kafka_batch,
11162 &ett_kafka_message,
11163 &ett_kafka_message_set,
11164 &ett_kafka_offline,
11165 &ett_kafka_isrs,
11166 &ett_kafka_replicas,
11167 &ett_kafka_broker,
11168 &ett_kafka_brokers,
11169 &ett_kafka_broker_end_point,
11170 &ett_kafka_markers,
11171 &ett_kafka_marker,
11172 &ett_kafka_topics,
11173 &ett_kafka_topic,
11174 &ett_kafka_partitions,
11175 &ett_kafka_partition,
11176 &ett_kafka_api_version,
11177 &ett_kafka_group_protocols,
11178 &ett_kafka_group_protocol,
11179 &ett_kafka_group_members,
11180 &ett_kafka_group_member,
11181 &ett_kafka_group_assignments,
11182 &ett_kafka_group_assignment,
11183 &ett_kafka_groups,
11184 &ett_kafka_group,
11185 &ett_kafka_sasl_enabled_mechanisms,
11186 &ett_kafka_replica_assignment,
11187 &ett_kafka_configs,
11188 &ett_kafka_config,
11189 &ett_kafka_request_forgotten_topic,
11190 &ett_kafka_record,
11191 &ett_kafka_record_headers,
11192 &ett_kafka_record_headers_header,
11193 &ett_kafka_aborted_transactions,
11194 &ett_kafka_aborted_transaction,
11195 &ett_kafka_resources,
11196 &ett_kafka_resource,
11197 &ett_kafka_acls,
11198 &ett_kafka_acl,
11199 &ett_kafka_acl_creations,
11200 &ett_kafka_acl_creation,
11201 &ett_kafka_acl_filters,
11202 &ett_kafka_acl_filter,
11203 &ett_kafka_acl_filter_matches,
11204 &ett_kafka_acl_filter_match,
11205 &ett_kafka_config_synonyms,
11206 &ett_kafka_config_synonym,
11207 &ett_kafka_config_entries,
11208 &ett_kafka_config_entry,
11209 &ett_kafka_log_dirs,
11210 &ett_kafka_log_dir,
11211 &ett_kafka_renewers,
11212 &ett_kafka_renewer,
11213 &ett_kafka_owners,
11214 &ett_kafka_owner,
11215 &ett_kafka_tokens,
11216 &ett_kafka_token,
11217 &ett_kafka_tagged_fields,
11218 &ett_kafka_tagged_field,
11219 &ett_kafka_record_errors,
11220 &ett_kafka_record_error,
11222 proto_register_subtree_array(ett, array_length(ett));
11225 static void
11226 proto_register_kafka_expert_module(const int proto) {
11227 expert_module_t* expert_kafka;
11228 static ei_register_info ei[] = {
11229 { &ei_kafka_request_missing,
11230 { "kafka.request_missing", PI_UNDECODED, PI_WARN, "Request missing", EXPFILL }},
11231 { &ei_kafka_unknown_api_key,
11232 { "kafka.unknown_api_key", PI_UNDECODED, PI_WARN, "Unknown API key", EXPFILL }},
11233 { &ei_kafka_unsupported_api_version,
11234 { "kafka.unsupported_api_version", PI_UNDECODED, PI_WARN, "Unsupported API version", EXPFILL }},
11235 { &ei_kafka_assumed_api_version,
11236 { "kafka.assumed_api_version", PI_ASSUMPTION, PI_WARN, "Assumed API version", EXPFILL }},
11237 { &ei_kafka_bad_string_length,
11238 { "kafka.bad_string_length", PI_MALFORMED, PI_WARN, "Invalid string length field", EXPFILL }},
11239 { &ei_kafka_bad_bytes_length,
11240 { "kafka.bad_bytes_length", PI_MALFORMED, PI_WARN, "Invalid byte length field", EXPFILL }},
11241 { &ei_kafka_bad_array_length,
11242 { "kafka.bad_array_length", PI_MALFORMED, PI_WARN, "Invalid array length field", EXPFILL }},
11243 { &ei_kafka_bad_record_length,
11244 { "kafka.bad_record_length", PI_MALFORMED, PI_WARN, "Invalid record length field", EXPFILL }},
11245 { &ei_kafka_bad_varint,
11246 { "kafka.bad_varint", PI_MALFORMED, PI_WARN, "Invalid varint bytes", EXPFILL }},
11247 { &ei_kafka_bad_message_set_length,
11248 { "kafka.ei_kafka_bad_message_set_length", PI_MALFORMED, PI_WARN, "Message set size does not match content", EXPFILL }},
11249 { &ei_kafka_bad_decompression_length,
11250 { "kafka.ei_kafka_bad_decompression_length", PI_MALFORMED, PI_WARN, "Decompression size too large", EXPFILL }},
11251 { &ei_kafka_zero_decompression_length,
11252 { "kafka.ei_kafka_zero_decompression_length", PI_PROTOCOL, PI_NOTE, "Decompression size zero", EXPFILL }},
11253 { &ei_kafka_unknown_message_magic,
11254 { "kafka.unknown_message_magic", PI_MALFORMED, PI_WARN, "Invalid message magic field", EXPFILL }},
11255 { &ei_kafka_pdu_length_mismatch,
11256 { "kafka.pdu_length_mismatch", PI_MALFORMED, PI_WARN, "Dissected message does not end at the pdu length offset", EXPFILL }},
11257 { &ei_kafka_zero_field_length,
11258 { "kafka.zero_field_length", PI_MALFORMED, PI_WARN, "Zero length field", EXPFILL }},
11260 expert_kafka = expert_register_protocol(proto);
11261 expert_register_field_array(expert_kafka, ei, array_length(ei));
11264 static void
11265 proto_register_kafka_preferences(const int proto)
11267 module_t *kafka_module;
11268 kafka_module = prefs_register_protocol(proto, NULL);
11269 /* unused; kept for backward compatibility */
11270 prefs_register_bool_preference(kafka_module, "show_string_bytes_lengths",
11271 "Show length for string and bytes fields in the protocol tree",
11273 &kafka_show_string_bytes_lengths);
11278 * Dissector entry points, contract for dissection plugin.
11281 void
11282 proto_register_kafka(void)
11285 int protocol_handle;
11287 compute_kafka_api_names();
11289 protocol_handle = proto_register_protocol("Kafka", "Kafka", "kafka");
11290 proto_register_kafka_protocol_fields(protocol_handle);
11291 proto_register_kafka_protocol_subtrees(protocol_handle);
11292 proto_register_kafka_expert_module(protocol_handle);
11293 proto_register_kafka_preferences(protocol_handle);
11295 proto_kafka = protocol_handle;
11299 void
11300 proto_reg_handoff_kafka(void)
11303 static dissector_handle_t kafka_handle;
11305 kafka_handle = register_dissector("kafka", dissect_kafka_tcp, proto_kafka);
11307 dissector_add_uint_range_with_preference("tcp.port", KAFKA_TCP_DEFAULT_RANGE, kafka_handle);
11308 ssl_dissector_add(0, kafka_handle);
11313 * Editor modelines - https://www.wireshark.org/tools/modelines.html
11315 * Local variables:
11316 * c-basic-offset: 4
11317 * tab-width: 8
11318 * indent-tabs-mode: nil
11319 * End:
11321 * vi: set shiftwidth=4 tabstop=8 expandtab:
11322 * :indentSize=4:tabSize=8:noTabs=true: