2 * Routines for Zabbix protocol dissection
3 * Copyright 2023, Markku Leiniƶ <markku.leinio@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * Zabbix protocol specifications can be found in Zabbix documentation:
14 * https://www.zabbix.com/documentation/current/en/manual/appendix/protocols
19 #include <epan/conversation.h>
20 #include <epan/expert.h>
21 #include <epan/packet.h>
22 #include <epan/prefs.h>
24 #include <wsutil/array.h>
25 #include <wsutil/inet_addr.h>
26 #include <wsutil/nstime.h>
27 #include <wsutil/wsjson.h>
28 #include "packet-tcp.h"
30 void proto_register_zabbix(void);
31 void proto_reg_handoff_zabbix(void);
33 static dissector_handle_t zabbix_handle
;
35 /* Desegmentation of Zabbix protocol over TCP */
36 static bool zabbix_desegment
= true;
38 /* The protocol and registered fields */
39 static int proto_zabbix
;
40 static int hf_zabbix_header
;
41 static int hf_zabbix_flags
;
42 static int hf_zabbix_flag_zabbix_communications
;
43 static int hf_zabbix_flag_compressed
;
44 static int hf_zabbix_flag_largepacket
;
45 static int hf_zabbix_flag_reserved
;
46 static int hf_zabbix_length
;
47 static int hf_zabbix_reserved
;
48 static int hf_zabbix_uncompressed_length
;
49 static int hf_zabbix_large_length
;
50 static int hf_zabbix_large_reserved
;
51 static int hf_zabbix_large_uncompressed_length
;
52 static int hf_zabbix_data
;
53 static int hf_zabbix_error
;
54 static int hf_zabbix_time
;
55 static int hf_zabbix_agent
;
56 static int hf_zabbix_agent_commands
;
57 static int hf_zabbix_agent_config
;
58 static int hf_zabbix_agent_data
;
59 static int hf_zabbix_agent_redirection
;
60 static int hf_zabbix_agent_passive
;
61 static int hf_zabbix_agent_name
;
62 static int hf_zabbix_agent_hb
;
63 static int hf_zabbix_agent_hb_freq
;
64 static int hf_zabbix_agent_hostmetadata
;
65 static int hf_zabbix_agent_hostinterface
;
66 static int hf_zabbix_agent_listenipv4
;
67 static int hf_zabbix_agent_listenipv6
;
68 static int hf_zabbix_agent_listenport
;
69 static int hf_zabbix_agent_variant
;
70 static int hf_zabbix_proxy
;
71 static int hf_zabbix_proxy_hb
;
72 static int hf_zabbix_proxy_name
;
73 static int hf_zabbix_proxy_data
;
74 static int hf_zabbix_proxy_config
;
75 static int hf_zabbix_proxy_fullsync
;
76 static int hf_zabbix_proxy_incr_config
;
77 static int hf_zabbix_proxy_no_config_change
;
78 static int hf_zabbix_proxy_tasks
;
79 static int hf_zabbix_sender
;
80 static int hf_zabbix_sender_name
;
81 static int hf_zabbix_frontend
;
82 static int hf_zabbix_frontend_sysinfo
;
83 static int hf_zabbix_frontend_queueinfo
;
84 static int hf_zabbix_frontend_historypush
;
85 static int hf_zabbix_frontend_itemtest
;
86 static int hf_zabbix_frontend_mediatest
;
87 static int hf_zabbix_frontend_reporttest
;
88 static int hf_zabbix_frontend_expressioneval
;
89 static int hf_zabbix_frontend_scriptexec
;
90 static int hf_zabbix_metrics
;
91 static int hf_zabbix_request
;
92 static int hf_zabbix_response
;
93 static int hf_zabbix_success
;
94 static int hf_zabbix_failed
;
95 static int hf_zabbix_config_revision
;
96 static int hf_zabbix_hostmap_revision
;
97 static int hf_zabbix_session
;
98 static int hf_zabbix_version
;
100 /* Subtree pointers */
101 static int ett_zabbix
;
102 static int ett_zabbix_flags
;
105 static expert_field ei_zabbix_packet_too_large
;
106 static expert_field ei_zabbix_json_error
;
108 /* Other dissector-specifics */
109 static range_t
*zabbix_port_range
;
111 static const char ZABBIX_HDR_SIGNATURE
[] = "ZBXD";
112 static const char ZABBIX_UNKNOWN
[] = "<unknown>";
113 static const char ZABBIX_ZBX_NOTSUPPORTED
[] = "ZBX_NOTSUPPORTED";
115 typedef struct _zabbix_conv_info_t
{
116 uint32_t req_framenum
;
117 nstime_t req_timestamp
;
118 uint32_t oper_flags
; /* ZABBIX_T_XXX macros below */
119 const char *host_name
;
120 } zabbix_conv_info_t
;
122 #define ZABBIX_HDR_MIN_LEN 13 /* When not large packet */
123 #define ZABBIX_HDR_MAX_LEN 21 /* When large packet */
124 #define ZABBIX_MAX_LENGTH_ALLOWED 1024*1024*1024 /* 1 GB */
125 #define ZABBIX_TCP_PORTS "10050,10051" /* IANA registered ports */
127 #define ZABBIX_FLAG_ZABBIX_COMMUNICATIONS 0x01
128 #define ZABBIX_FLAG_COMPRESSED 0x02
129 #define ZABBIX_FLAG_LARGEPACKET 0x04
130 #define ZABBIX_FLAG_RESERVED 0xf8
132 /* Response flags are not saved in the conversations */
133 #define ZABBIX_RESPONSE_SUCCESS 0x01
134 #define ZABBIX_RESPONSE_FAILED 0x02
135 #define ZABBIX_RESPONSE_FULLSYNC 0x04
136 #define ZABBIX_RESPONSE_INCREMENTAL 0x08
137 #define ZABBIX_RESPONSE_NOCHANGE 0x10
139 /* Flags for saving and comparing operation types,
140 * max 32 bits as defined in zabbix_conv_info_t above */
141 #define ZABBIX_T_REQUEST 0x00000001
142 #define ZABBIX_T_RESPONSE 0x00000002
143 #define ZABBIX_T_ACTIVE 0x00000004
144 #define ZABBIX_T_PASSIVE 0x00000008
145 #define ZABBIX_T_AGENT 0x00000010
146 #define ZABBIX_T_PROXY 0x00000020
147 #define ZABBIX_T_SENDER 0x00000040
148 #define ZABBIX_T_CONFIG 0x00000080
149 #define ZABBIX_T_DATA 0x00000100
150 #define ZABBIX_T_TASKS 0x00000200
151 #define ZABBIX_T_HEARTBEAT 0x00000400
152 #define ZABBIX_T_LEGACY 0x00000800 /* pre-7.0 non-JSON protocol */
153 #define ZABBIX_T_FRONTEND 0x00001000
154 #define ZABBIX_T_SYSINFO 0x00002000
155 #define ZABBIX_T_QUEUEINFO 0x00004000
156 #define ZABBIX_T_HISTORYPUSH 0x00008000
157 #define ZABBIX_T_ITEMTEST 0x00010000
158 #define ZABBIX_T_MEDIATEST 0x00020000
159 #define ZABBIX_T_REPORTTEST 0x00040000
160 #define ZABBIX_T_METRICS 0x00080000
161 #define ZABBIX_T_EXPRESSIONEVAL 0x00100000
162 #define ZABBIX_T_SCRIPTEXEC 0x00200000
164 #define ADD_ZABBIX_T_FLAGS(flags) (zabbix_info->oper_flags |= (flags))
165 #define CLEAR_ZABBIX_T_FLAGS(flags) (zabbix_info->oper_flags &= (0xffffffff-(flags)))
166 #define IS_ZABBIX_T_FLAGS(flags) ((zabbix_info->oper_flags & (flags)) == (flags))
168 #define CONV_IS_ZABBIX_REQUEST(zabbix_info,pinfo) ((zabbix_info)->req_framenum == (pinfo)->fd->num)
169 #define CONV_IS_ZABBIX_RESPONSE(zabbix_info,pinfo) ((zabbix_info)->req_framenum != (pinfo)->fd->num)
171 #define ZABBIX_NAME_OR_UNKNOWN(name) ((name) ? (name) : ZABBIX_UNKNOWN)
174 static zabbix_conv_info_t
*
175 zabbix_find_conversation_and_get_conv_data(packet_info
*pinfo
)
177 conversation_t
*conversation
;
178 zabbix_conv_info_t
*zabbix_info
= NULL
;
180 conversation
= find_conversation_pinfo(pinfo
, 0);
182 zabbix_info
= (zabbix_conv_info_t
*)conversation_get_proto_data(conversation
, proto_zabbix
);
184 conversation
= conversation_new(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
,
185 conversation_pt_to_conversation_type(pinfo
->ptype
),
186 pinfo
->srcport
, pinfo
->destport
, 0);
189 /* New conversation, or there was no Zabbix data yet in the existing conv */
190 zabbix_info
= wmem_alloc(wmem_file_scope(), sizeof(zabbix_conv_info_t
));
191 if (value_is_in_range(zabbix_port_range
, pinfo
->destport
)) {
192 /* Let's assume this is the first Zabbix packet (request) */
193 zabbix_info
->req_framenum
= pinfo
->fd
->num
;
194 zabbix_info
->req_timestamp
= pinfo
->abs_ts
;
197 /* For any reason we didn't have Zabbix data yet but this is not
198 * the first packet for the connection, so don't save it as a request
200 zabbix_info
->req_framenum
= 0;
201 nstime_set_unset(&zabbix_info
->req_timestamp
);
202 /* For some reason this produces "syntax error: '{'" when compiling:
203 zabbix_info->req_timestamp = NSTIME_INIT_UNSET;
206 zabbix_info
->oper_flags
= 0;
207 zabbix_info
->host_name
= NULL
;
208 conversation_add_proto_data(conversation
, proto_zabbix
, (void *)zabbix_info
);
214 zabbix_add_expert_info_if_too_large(packet_info
*pinfo
, proto_tree
*tree_item
,
215 uint64_t length
, bool *is_too_large
)
217 if (length
> ZABBIX_MAX_LENGTH_ALLOWED
) {
218 expert_add_info(pinfo
, tree_item
, &ei_zabbix_packet_too_large
);
219 *is_too_large
= true;
225 dissect_zabbix_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
228 int agent_hb_freq
= 0;
229 unsigned oper_response
= 0;
233 proto_tree
*zabbix_tree
= NULL
;
235 uint16_t agent_listenport
= 0;
237 uint64_t uncompressed_length
;
239 int64_t agent_variant
= 0;
240 int64_t config_revision
= -1;
241 int64_t hostmap_revision
= -1;
243 bool is_large_packet
;
244 bool is_too_large
= false;
245 bool is_redirection
= false;
247 char *passive_agent_data_str
= NULL
;
248 jsmntok_t
*commands_array
= NULL
;
249 jsmntok_t
*data_array
= NULL
;
250 jsmntok_t
*data_object
= NULL
;
251 const char *agent_name
= NULL
;
252 const char *agent_hostmetadata
= NULL
;
253 const char *agent_hostinterface
= NULL
;
254 const char *agent_listenip
= NULL
;
255 const char *proxy_name
= NULL
;
256 const char *sender_name
= NULL
;
257 const char *session
= NULL
;
258 const char *request_type
= NULL
;
259 const char *response_status
= NULL
;
260 const char *version
= NULL
;
263 zabbix_conv_info_t
*zabbix_info
;
264 static int* const flagbits
[] = {
265 &hf_zabbix_flag_reserved
,
266 &hf_zabbix_flag_largepacket
,
267 &hf_zabbix_flag_compressed
,
268 &hf_zabbix_flag_zabbix_communications
,
272 /* Make entries in Protocol column and Info column on summary display */
273 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Zabbix");
274 col_clear(pinfo
->cinfo
, COL_INFO
);
276 if ((tvb_reported_length(tvb
) < ZABBIX_HDR_MIN_LEN
) ||
277 (tvb_memeql(tvb
, offset
, ZABBIX_HDR_SIGNATURE
, 4) == -1)) {
278 /* Encrypted or not Zabbix at all */
281 flags
= tvb_get_uint8(tvb
, offset
+4);
282 if (!(flags
& ZABBIX_FLAG_ZABBIX_COMMUNICATIONS
)) {
286 zabbix_info
= zabbix_find_conversation_and_get_conv_data(pinfo
);
288 is_compressed
= (flags
& ZABBIX_FLAG_COMPRESSED
) > 0;
289 is_large_packet
= (flags
& ZABBIX_FLAG_LARGEPACKET
) > 0;
291 /* create display subtree for the protocol */
292 ti
= proto_tree_add_item(tree
, proto_zabbix
, tvb
, 0, -1, ENC_NA
);
293 zabbix_tree
= proto_item_add_subtree(ti
, ett_zabbix
);
294 proto_tree_add_item(zabbix_tree
, hf_zabbix_header
, tvb
, offset
, 4, ENC_UTF_8
);
296 proto_tree_add_bitmask(zabbix_tree
, tvb
, offset
, hf_zabbix_flags
, ett_zabbix_flags
, flagbits
, ENC_BIG_ENDIAN
);
298 if (is_large_packet
) {
300 temp_ti
= proto_tree_add_item_ret_uint64(zabbix_tree
,
301 hf_zabbix_large_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
, &length
);
302 zabbix_add_expert_info_if_too_large(pinfo
, temp_ti
, length
, &is_too_large
);
305 temp_ti
= proto_tree_add_item_ret_uint64(zabbix_tree
,
306 hf_zabbix_large_uncompressed_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
, &uncompressed_length
);
307 zabbix_add_expert_info_if_too_large(pinfo
, temp_ti
, uncompressed_length
, &is_too_large
);
309 proto_tree_add_item(zabbix_tree
, hf_zabbix_large_reserved
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
314 uint32_t temp_uint32
;
315 temp_ti
= proto_tree_add_item_ret_uint(zabbix_tree
,
316 hf_zabbix_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &temp_uint32
);
317 length
= (uint64_t)temp_uint32
;
318 zabbix_add_expert_info_if_too_large(pinfo
, temp_ti
, length
, &is_too_large
);
321 temp_ti
= proto_tree_add_item_ret_uint(zabbix_tree
,
322 hf_zabbix_uncompressed_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &temp_uint32
);
323 uncompressed_length
= (uint64_t)temp_uint32
;
324 zabbix_add_expert_info_if_too_large(pinfo
, temp_ti
, uncompressed_length
, &is_too_large
);
326 proto_tree_add_item(zabbix_tree
, hf_zabbix_reserved
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
331 /* Set next_tvb for response time calculation to work later */
332 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
333 /* ... but don't do any content-based inspection, just skip to the end */
335 } else if (is_compressed
) {
336 next_tvb
= tvb_uncompress_zlib(tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
));
338 tvb_set_child_real_data_tvbuff(tvb
, next_tvb
);
339 add_new_data_source(pinfo
, next_tvb
, "Uncompressed data");
340 datalen
= uncompressed_length
;
342 /* Handle uncompressed */
343 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
347 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
351 /* Use only next_tvb and datalen for data extraction from here on! */
354 /* Rewrite the default texts in the protocol tree and initialize request/response flags */
355 if (CONV_IS_ZABBIX_REQUEST(zabbix_info
, pinfo
)) {
356 proto_item_set_text(ti
, "Zabbix Protocol request");
357 ADD_ZABBIX_T_FLAGS(ZABBIX_T_REQUEST
);
358 CLEAR_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE
);
360 else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info
, pinfo
)) {
361 proto_item_set_text(ti
, "Zabbix Protocol response");
362 ADD_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE
);
363 CLEAR_ZABBIX_T_FLAGS(ZABBIX_T_REQUEST
);
367 * Note that json_str is modified when using json_get_xxx() functions below!
368 * So don't use it to anything else (make a wmem_strdup() if needed, see below)
370 json_str
= tvb_get_string_enc(pinfo
->pool
, next_tvb
, offset
, (int)datalen
, ENC_UTF_8
);
371 /* First check if this is a pre-7.0 passive agent.
372 * Note that even pre-7.0 passive agent *responses* can be JSON, so don't just check
373 * for JSON validation but check the conversation data!
376 !json_validate(json_str
, datalen
) ||
378 CONV_IS_ZABBIX_RESPONSE(zabbix_info
, pinfo
) &&
379 IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_PASSIVE
| ZABBIX_T_LEGACY
)
382 /* The only non-JSON Zabbix request/response is passive agent before Zabbix 7.0,
383 * ensure the conversation data is set, then set the texts
385 ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_PASSIVE
| ZABBIX_T_LEGACY
);
386 if (CONV_IS_ZABBIX_REQUEST(zabbix_info
, pinfo
)) {
387 proto_item_set_text(ti
, "Zabbix Server/proxy request for passive agent checks");
388 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Server/proxy request for passive agent checks");
389 } else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info
, pinfo
)) {
390 proto_item_set_text(ti
, "Zabbix Agent response for passive checks");
391 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Agent response for passive checks");
393 /* Make a copy of the data string for later error message lookup use */
394 passive_agent_data_str
= wmem_strndup(pinfo
->pool
, json_str
, (size_t)datalen
);
395 /* Don't do content-based searches for pre-7.0 passive agents */
396 goto show_agent_outputs
;
398 /* Parse JSON, first get the token count */
399 int token_count
= json_parse(json_str
, NULL
, 0);
400 if (token_count
<= 0) {
401 temp_ti
= proto_tree_add_item(zabbix_tree
, hf_zabbix_data
, next_tvb
, 0, (int)datalen
, ENC_UTF_8
);
402 expert_add_info_format(pinfo
, temp_ti
, &ei_zabbix_json_error
, "Error in initial JSON parse");
405 jsmntok_t
*tokens
= wmem_alloc_array(pinfo
->pool
, jsmntok_t
, token_count
);
406 int ret
= json_parse(json_str
, tokens
, token_count
);
408 temp_ti
= proto_tree_add_item(zabbix_tree
, hf_zabbix_data
, next_tvb
, 0, (int)datalen
, ENC_UTF_8
);
409 expert_add_info_format(pinfo
, temp_ti
, &ei_zabbix_json_error
, "Error parsing JSON tokens");
414 * Now we have JSON tokens analyzed, let's do all the logic to populate the fields.
415 * Also set Zabbix tree item and Info column texts, Len= and ports will be added later below.
418 /* First populate common fields */
419 version
= json_get_string(json_str
, tokens
, "version");
420 if (json_get_double(json_str
, tokens
, "variant", &temp_double
)) {
421 agent_variant
= (int64_t)temp_double
;
423 session
= json_get_string(json_str
, tokens
, "session");
424 if (json_get_double(json_str
, tokens
, "config_revision", &temp_double
)) {
425 config_revision
= (int64_t)temp_double
;
427 if (json_get_double(json_str
, tokens
, "hostmap_revision", &temp_double
)) {
428 hostmap_revision
= (int64_t)temp_double
;
430 jsmntok_t
*proxy_group_object
= json_get_object(json_str
, tokens
, "proxy_group");
431 if (proxy_group_object
) {
432 if (json_get_double(json_str
, proxy_group_object
, "hostmap_revision", &temp_double
)) {
433 hostmap_revision
= (int64_t)temp_double
;
437 request_type
= json_get_string(json_str
, tokens
, "request");
438 response_status
= json_get_string(json_str
, tokens
, "response");
439 commands_array
= json_get_array(json_str
, tokens
, "commands");
440 data_array
= json_get_array(json_str
, tokens
, "data");
441 data_object
= json_get_object(json_str
, tokens
, "data");
442 /* Find the packet type primarily based on "request" field */
444 if (strcmp(request_type
, "active checks") == 0) {
445 /* Active agent requesting configs */
446 ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_CONFIG
| ZABBIX_T_ACTIVE
);
447 agent_name
= json_get_string(json_str
, tokens
, "host");
448 if (agent_name
&& !PINFO_FD_VISITED(pinfo
)) {
449 zabbix_info
->host_name
= wmem_strdup(wmem_file_scope(), agent_name
);
451 proto_item_set_text(ti
,
452 "Zabbix Agent request for active checks for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
453 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
454 "Zabbix Agent request for active checks for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
455 agent_hostmetadata
= json_get_string(json_str
, tokens
, "host_metadata");
456 agent_hostinterface
= json_get_string(json_str
, tokens
, "interface");
457 agent_listenip
= json_get_string(json_str
, tokens
, "ip");
458 if (json_get_double(json_str
, tokens
, "port", &temp_double
)) {
459 agent_listenport
= (uint16_t)temp_double
;
462 else if (strcmp(request_type
, "agent data") == 0) {
463 /* Active agent sending data */
464 ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_DATA
| ZABBIX_T_ACTIVE
);
465 /* Zabbix Agent 2 has Host in the top level */
466 agent_name
= json_get_string(json_str
, tokens
, "host");
468 /* For Zabbix Agent try parsing agent name inside data array */
469 jsmntok_t
*tok
= json_get_array(json_str
, tokens
, "data");
470 if (tok
&& json_get_array_len(tok
) > 0) {
471 jsmntok_t
*datatok
= json_get_array_index(tok
, 0);
472 agent_name
= json_get_string(json_str
, datatok
, "host");
475 if (agent_name
&& !PINFO_FD_VISITED(pinfo
)) {
476 zabbix_info
->host_name
= wmem_strdup(wmem_file_scope(), agent_name
);
478 proto_item_set_text(ti
,
479 "Zabbix Agent data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
480 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
481 "Zabbix Agent data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
483 else if (strcmp(request_type
, "active check heartbeat") == 0) {
484 /* Active agent sending heartbeat */
485 ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_HEARTBEAT
| ZABBIX_T_ACTIVE
);
486 agent_name
= json_get_string(json_str
, tokens
, "host");
487 if (agent_name
&& !PINFO_FD_VISITED(pinfo
)) {
488 zabbix_info
->host_name
= wmem_strdup(wmem_file_scope(), agent_name
);
490 if (json_get_double(json_str
, tokens
, "heartbeat_freq", &temp_double
)) {
491 agent_hb_freq
= (int)temp_double
;
493 proto_item_set_text(ti
,
494 "Zabbix Agent heartbeat from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
495 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
496 "Zabbix Agent heartbeat from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
498 else if (strcmp(request_type
, "passive checks") == 0) {
499 /* Passive agent checks since Zabbix 7.0 */
500 ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_PASSIVE
);
501 proto_item_set_text(ti
, "Zabbix Server/proxy request for passive agent checks");
502 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Server/proxy request for passive agent checks");
504 else if (strcmp(request_type
, "zabbix.stats") == 0) {
505 /* Agent requesting server/proxy internal metrics, since Zabbix 4.0.5 */
506 ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_METRICS
);
507 proto_item_set_text(ti
, "Zabbix Server/proxy internal metrics request");
508 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Server/proxy internal metrics request");
510 else if (strcmp(request_type
, "sender data") == 0) {
512 ADD_ZABBIX_T_FLAGS(ZABBIX_T_SENDER
);
513 /* Try to get the sender name from the first data array item */
514 jsmntok_t
*tok
= json_get_array(json_str
, tokens
, "data");
515 if (tok
&& json_get_array_len(tok
) > 0) {
516 jsmntok_t
*datatok
= json_get_array_index(tok
, 0);
517 sender_name
= json_get_string(json_str
, datatok
, "host");
518 if (sender_name
&& !PINFO_FD_VISITED(pinfo
)) {
519 zabbix_info
->host_name
= wmem_strdup(wmem_file_scope(), sender_name
);
522 proto_item_set_text(ti
,
523 "Zabbix Sender data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(sender_name
));
524 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
525 "Zabbix Sender data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(sender_name
));
527 else if ((strcmp(request_type
, "proxy data") == 0) ||
528 (strcmp(request_type
, "host availability") == 0) ||
529 (strcmp(request_type
, "history data") == 0) ||
530 (strcmp(request_type
, "discovery data") == 0) ||
531 (strcmp(request_type
, "auto registration") == 0)) {
532 /* Either active or passive proxy; "proxy data" = Zabbix 3.4+,
533 * others = Zabbix 3.2 or older */
534 proxy_name
= json_get_string(json_str
, tokens
, "host");
535 if (token_count
== 3) { /* Only '{"request":"xxx"}' */
536 /* This is Zabbix server connecting to passive proxy */
537 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_DATA
| ZABBIX_T_PASSIVE
);
538 proto_item_set_text(ti
, "Zabbix Proxy data request to passive proxy");
539 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Proxy data request to passive proxy");
541 else if (proxy_name
) {
542 /* This is an active proxy connecting to server */
543 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_DATA
| ZABBIX_T_ACTIVE
);
544 if (proxy_name
&& !PINFO_FD_VISITED(pinfo
)) {
545 zabbix_info
->host_name
= wmem_strdup(wmem_file_scope(), proxy_name
);
547 proto_item_set_text(ti
, "Zabbix Proxy data from \"%s\"", proxy_name
);
548 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Zabbix Proxy data from \"%s\"", proxy_name
);
551 else if (strcmp(request_type
, "proxy config") == 0) {
552 /* Either active or passive proxy */
553 proxy_name
= json_get_string(json_str
, tokens
, "host");
554 if (token_count
== 3) { /* Only '{"request":"proxy config"}' */
555 /* This is Zabbix 6.4+ server connecting to passive proxy */
556 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_CONFIG
| ZABBIX_T_PASSIVE
);
557 proto_item_set_text(ti
, "Zabbix Proxy config request to passive proxy");
558 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Proxy config request to passive proxy");
560 else if (proxy_name
) {
561 /* This is an active proxy connecting to server */
562 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_CONFIG
| ZABBIX_T_ACTIVE
);
563 if (proxy_name
&& !PINFO_FD_VISITED(pinfo
)) {
564 zabbix_info
->host_name
= wmem_strdup(wmem_file_scope(), proxy_name
);
566 proto_item_set_text(ti
, "Zabbix Request proxy config for \"%s\"", proxy_name
);
567 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Zabbix Request proxy config for \"%s\"", proxy_name
);
570 else if (strcmp(request_type
, "proxy tasks") == 0) {
571 /* Zabbix server connecting to passive proxy, only '{"request":"proxy tasks"}' */
572 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_TASKS
| ZABBIX_T_PASSIVE
);
573 proto_item_set_text(ti
, "Zabbix Proxy tasks request to passive proxy");
574 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Proxy tasks request to passive proxy");
576 else if (strcmp(request_type
, "proxy heartbeat") == 0) {
577 /* Heartbeat from active proxy, not used in Zabbix 6.4+ */
578 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_HEARTBEAT
| ZABBIX_T_ACTIVE
);
579 proxy_name
= json_get_string(json_str
, tokens
, "host");
580 if (proxy_name
&& !PINFO_FD_VISITED(pinfo
)) {
581 zabbix_info
->host_name
= wmem_strdup(wmem_file_scope(), proxy_name
);
583 proto_item_set_text(ti
, "Zabbix Proxy heartbeat from \"%s\"", proxy_name
);
584 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Zabbix Proxy heartbeat from \"%s\"", proxy_name
);
586 /* UI/API-specific requests */
587 else if (strcmp(request_type
, "status.get") == 0) {
588 /* System information report */
589 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_SYSINFO
);
590 proto_item_set_text(ti
, "Zabbix System information request");
591 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix System information request");
593 else if (strcmp(request_type
, "queue.get") == 0) {
594 /* Queue information request */
595 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_QUEUEINFO
);
596 proto_item_set_text(ti
, "Zabbix Queue information request");
597 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Queue information request");
599 else if (strcmp(request_type
, "history.push") == 0) {
600 /* history.push API call, since Zabbix 7.0 */
601 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_HISTORYPUSH
);
602 proto_item_set_text(ti
, "Zabbix History push request");
603 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix History push request");
605 else if (strcmp(request_type
, "item.test") == 0) {
606 /* Item test in the frontend */
607 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_ITEMTEST
);
608 proto_item_set_text(ti
, "Zabbix Item test request");
609 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Item test request");
611 else if (strcmp(request_type
, "alert.send") == 0) {
612 /* Media test in the frontend */
613 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_MEDIATEST
);
614 proto_item_set_text(ti
, "Zabbix Media test request");
615 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Media test request");
617 else if (strcmp(request_type
, "report.test") == 0) {
618 /* Report test in the frontend */
619 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_REPORTTEST
);
620 proto_item_set_text(ti
, "Zabbix Report test request");
621 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Report test request");
623 else if (strcmp(request_type
, "expressions.evaluate") == 0) {
624 /* Trigger expression evaluation test in the frontend */
625 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_EXPRESSIONEVAL
);
626 proto_item_set_text(ti
, "Zabbix Expression evaluation request");
627 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Expression evaluation request");
629 else if (strcmp(request_type
, "command") == 0) {
630 /* Script execution from the frontend */
631 ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
| ZABBIX_T_SCRIPTEXEC
);
632 proto_item_set_text(ti
, "Zabbix Script execution request");
633 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Script execution request");
636 /* There was no "request" field match, continue with other ways to recognize the packet */
637 else if (json_get_object(json_str
, tokens
, "globalmacro")) {
638 /* This is Zabbix server before 6.4 sending configurations to active proxy */
639 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_CONFIG
| ZABBIX_T_ACTIVE
);
640 proxy_name
= zabbix_info
->host_name
;
641 proto_item_set_text(ti
,
642 "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name
));
643 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
644 "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name
));
646 else if (json_get_double(json_str
, tokens
, "full_sync", &temp_double
)) {
647 /* This is Zabbix 6.4+ server sending proxy config to active or passive proxy */
648 /* Only present when value is 1 */
649 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_CONFIG
);
650 oper_response
|= ZABBIX_RESPONSE_FULLSYNC
;
651 /* Active/passive flag was set in the earlier packet */
652 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PASSIVE
)) {
653 /* There is no proxy name anywhere to use */
654 proto_item_set_text(ti
, "Zabbix Passive proxy config");
655 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Passive proxy config");
659 proxy_name
= zabbix_info
->host_name
;
660 proto_item_set_text(ti
,
661 "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name
));
662 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
663 "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name
));
666 else if (response_status
) {
667 if (strcmp(response_status
, "success") == 0) {
668 oper_response
|= ZABBIX_RESPONSE_SUCCESS
;
670 else if (strcmp(response_status
, "failed") == 0) {
671 oper_response
|= ZABBIX_RESPONSE_FAILED
;
673 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
)) {
674 agent_name
= zabbix_info
->host_name
;
675 if (json_get_object(json_str
, tokens
, "redirect")) {
676 /* Agent redirection response from a Zabbix 7.0+ proxy in load balancing configuration.
677 * Not added in the conversation flags to prevent it from showing in the request packet,
678 * just set a local variable for later usage.
680 is_redirection
= true;
681 proto_item_set_text(ti
,
682 "Zabbix Agent redirection for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
683 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
684 "Zabbix Agent redirection for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name
));
686 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG
| ZABBIX_T_ACTIVE
)) {
687 proto_item_set_text(ti
,
688 "Zabbix Server/proxy response for active checks for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name
), response_status
);
689 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
690 "Zabbix Server/proxy response for active checks for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name
), response_status
);
692 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA
| ZABBIX_T_ACTIVE
)) {
693 proto_item_set_text(ti
,
694 "Zabbix Server/proxy response for agent data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name
), response_status
);
695 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
696 "Zabbix Server/proxy response for agent data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name
), response_status
);
698 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_METRICS
)) {
699 proto_item_set_text(ti
, "Zabbix Server/proxy internal metrics response");
700 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Server/proxy internal metrics response");
703 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
)) {
704 proxy_name
= zabbix_info
->host_name
;
705 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG
| ZABBIX_T_ACTIVE
)) {
706 proto_item_set_text(ti
,
707 "Zabbix Response for active proxy config request for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name
), response_status
);
708 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
709 "Zabbix Response for active proxy config request for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name
), response_status
);
711 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA
| ZABBIX_T_ACTIVE
)) {
712 proto_item_set_text(ti
,
713 "Zabbix Server response for active proxy data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name
), response_status
);
714 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
715 "Zabbix Server response for active proxy data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name
), response_status
);
717 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG
| ZABBIX_T_PASSIVE
)) {
718 proto_item_set_text(ti
,
719 "Zabbix Proxy response for passive proxy config (%s)", response_status
);
720 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
721 "Zabbix Proxy response for passive proxy config (%s)", response_status
);
723 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA
| ZABBIX_T_PASSIVE
)) {
724 proto_item_set_text(ti
,
725 "Zabbix Server response for passive proxy data (%s)", response_status
);
726 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
727 "Zabbix Server response for passive proxy data (%s)", response_status
);
729 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_TASKS
| ZABBIX_T_PASSIVE
)) {
730 proto_item_set_text(ti
,
731 "Zabbix Server response for passive proxy tasks (%s)", response_status
);
732 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
733 "Zabbix Server response for passive proxy tasks (%s)", response_status
);
735 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HEARTBEAT
| ZABBIX_T_ACTIVE
)) {
736 proto_item_set_text(ti
,
737 "Zabbix Server response for active proxy heartbeat for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name
), response_status
);
738 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
739 "Zabbix Server response for active proxy heartbeat for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name
), response_status
);
742 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SENDER
)) {
743 sender_name
= zabbix_info
->host_name
;
744 proto_item_set_text(ti
,
745 "Zabbix Server/proxy response for sender data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(sender_name
), response_status
);
746 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
747 "Zabbix Server/proxy response for sender data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(sender_name
), response_status
);
749 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
)) {
750 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SYSINFO
)) {
751 proto_item_set_text(ti
, "Zabbix System information response");
752 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix System information response");
754 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_QUEUEINFO
)) {
755 proto_item_set_text(ti
, "Zabbix Queue information response");
756 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Queue information response");
758 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HISTORYPUSH
)) {
759 proto_item_set_text(ti
, "Zabbix History push response");
760 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix History push response");
762 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_ITEMTEST
)) {
763 proto_item_set_text(ti
, "Zabbix Item test response");
764 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Item test response");
766 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_MEDIATEST
)) {
767 proto_item_set_text(ti
, "Zabbix Media test response");
768 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Media test response");
770 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_REPORTTEST
)) {
771 proto_item_set_text(ti
, "Zabbix Report test response");
772 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Report test response");
774 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_EXPRESSIONEVAL
)) {
775 proto_item_set_text(ti
, "Zabbix Expression evaluation response");
776 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Expression evaluation response");
778 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SCRIPTEXEC
)) {
779 proto_item_set_text(ti
, "Zabbix Script execution response");
780 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Script execution response");
784 else if (version
&& data_array
) {
785 /* This looks like passive agent response in Zabbix 7.0+ */
786 ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
| ZABBIX_T_PASSIVE
);
787 proto_item_set_text(ti
, "Zabbix Agent response for passive checks");
788 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Agent response for passive checks");
790 else if (data_object
|| data_array
|| tokens
->size
== 0) {
791 /* No other match above, let's assume this is server sending incremental
792 * configuration to a proxy
794 ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_CONFIG
);
795 if ((data_object
&& (data_object
->size
== 0)) || tokens
->size
== 0) {
796 /* Empty data object or the whole JSON is empty */
797 oper_response
|= ZABBIX_RESPONSE_NOCHANGE
;
799 else if (data_array
) {
800 /* This was not a "full_sync" but data array exists */
801 oper_response
|= ZABBIX_RESPONSE_INCREMENTAL
;
803 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PASSIVE
)) {
804 /* There is no proxy name anywhere to use */
805 proto_item_set_text(ti
, "Zabbix Passive proxy config");
806 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Passive proxy config");
809 proxy_name
= zabbix_info
->host_name
;
810 proto_item_set_text(ti
,
811 "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name
));
812 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
813 "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name
));
816 /* Final guesses to provide customized packet information */
817 else if (session
&& version
) {
818 /* Config or data responses from passive proxy */
819 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_CONFIG
| ZABBIX_T_PASSIVE
)) {
820 proto_item_set_text(ti
, "Zabbix Passive proxy response for config push");
821 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Passive proxy response for config push");
823 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_DATA
| ZABBIX_T_PASSIVE
)) {
824 proto_item_set_text(ti
, "Zabbix Passive proxy data response");
825 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Passive proxy data response");
829 /* Tasks response from passive proxy */
830 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
| ZABBIX_T_TASKS
| ZABBIX_T_PASSIVE
)) {
831 proto_item_set_text(ti
, "Zabbix Passive proxy response for tasks request");
832 col_set_str(pinfo
->cinfo
, COL_INFO
, "Zabbix Passive proxy response for tasks request");
837 /* Add all relevant fields to the tree */
840 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
)) {
841 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_agent
, NULL
, 0, 0, true);
842 proto_item_set_text(temp_ti
, "This is an agent connection");
843 proto_item_set_generated(temp_ti
);
844 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA
)) {
845 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_agent_data
, NULL
, 0, 0, true);
846 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE
)) {
847 /* Set as generated, not seen in data */
848 proto_item_set_generated(temp_ti
);
851 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG
)) {
852 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_agent_config
, NULL
, 0, 0, true);
853 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE
)) {
854 /* Set as generated, not seen in data */
855 proto_item_set_generated(temp_ti
);
858 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HEARTBEAT
)) {
859 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_agent_hb
, NULL
, 0, 0, true);
861 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PASSIVE
)) {
862 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_agent_passive
, NULL
, 0, 0, true);
863 proto_item_set_text(temp_ti
, "Agent is in passive mode");
864 proto_item_set_generated(temp_ti
);
866 if (is_redirection
) {
867 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_agent_redirection
, NULL
, 0, 0, true);
870 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
)) {
871 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy
, NULL
, 0, 0, true);
872 proto_item_set_text(temp_ti
, "This is a proxy connection");
873 proto_item_set_generated(temp_ti
);
875 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SENDER
)) {
876 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_sender
, NULL
, 0, 0, true);
877 proto_item_set_text(temp_ti
, "This is a sender connection");
878 proto_item_set_generated(temp_ti
);
880 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
)) {
881 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend
, NULL
, 0, 0, true);
882 proto_item_set_text(temp_ti
, "This is a frontend connection");
883 proto_item_set_generated(temp_ti
);
885 if (oper_response
& ZABBIX_RESPONSE_SUCCESS
) {
886 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_success
, NULL
, 0, 0, true);
888 else if (oper_response
& ZABBIX_RESPONSE_FAILED
) {
889 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_failed
, NULL
, 0, 0, true);
891 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT
)) {
893 temp_ti
= proto_tree_add_string(zabbix_tree
, hf_zabbix_agent_name
, NULL
, 0, 0, agent_name
);
894 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE
)) {
895 /* agent_name was populated from the conversation */
896 proto_item_set_generated(temp_ti
);
897 proto_item_append_text(temp_ti
, " (from the request)");
901 proto_tree_add_int64(zabbix_tree
, hf_zabbix_agent_variant
, NULL
, 0, 0, agent_variant
);
904 proto_tree_add_int(zabbix_tree
, hf_zabbix_agent_hb_freq
, NULL
, 0, 0, agent_hb_freq
);
906 if (agent_hostmetadata
) {
907 proto_tree_add_string(zabbix_tree
, hf_zabbix_agent_hostmetadata
, NULL
, 0, 0, agent_hostmetadata
);
909 if (agent_hostinterface
) {
910 proto_tree_add_string(zabbix_tree
, hf_zabbix_agent_hostinterface
, NULL
, 0, 0, agent_hostinterface
);
912 if (agent_listenip
) {
913 if (strstr(agent_listenip
, ":") != NULL
) {
915 if (ws_inet_pton6(agent_listenip
, &addr6
)) {
916 proto_tree_add_ipv6(zabbix_tree
, hf_zabbix_agent_listenipv6
, NULL
, 0, 0, &addr6
);
921 if (ws_inet_pton4(agent_listenip
, &addr4
)) {
922 proto_tree_add_ipv4(zabbix_tree
, hf_zabbix_agent_listenipv4
, NULL
, 0, 0, addr4
);
926 if (agent_listenport
) {
927 proto_tree_add_uint(zabbix_tree
, hf_zabbix_agent_listenport
, NULL
, 0, 0, agent_listenport
);
929 if (commands_array
) {
930 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_agent_commands
, NULL
, 0, 0, true);
932 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_METRICS
)) {
933 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_metrics
, NULL
, 0, 0, true);
936 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY
)) {
938 temp_ti
= proto_tree_add_string(zabbix_tree
, hf_zabbix_proxy_name
, NULL
, 0, 0, proxy_name
);
939 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE
)) {
940 /* proxy_name was populated from the conversation */
941 proto_item_set_generated(temp_ti
);
942 proto_item_append_text(temp_ti
, " (from the request)");
945 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA
)) {
946 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy_data
, NULL
, 0, 0, true);
948 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG
)) {
949 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy_config
, NULL
, 0, 0, true);
950 if (oper_response
& ZABBIX_RESPONSE_FULLSYNC
) {
951 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy_fullsync
, NULL
, 0, 0, true);
953 else if (oper_response
& ZABBIX_RESPONSE_INCREMENTAL
) {
954 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy_incr_config
, NULL
, 0, 0, true);
956 else if (oper_response
& ZABBIX_RESPONSE_NOCHANGE
) {
957 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy_no_config_change
, NULL
, 0, 0, true);
960 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_TASKS
)) {
961 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy_tasks
, NULL
, 0, 0, true);
963 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HEARTBEAT
)) {
964 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_proxy_hb
, NULL
, 0, 0, true);
967 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND
)) {
968 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SYSINFO
)) {
969 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_sysinfo
, NULL
, 0, 0, true);
971 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_QUEUEINFO
)) {
972 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_queueinfo
, NULL
, 0, 0, true);
974 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HISTORYPUSH
)) {
975 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_historypush
, NULL
, 0, 0, true);
977 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_ITEMTEST
)) {
978 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_itemtest
, NULL
, 0, 0, true);
980 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_MEDIATEST
)) {
981 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_mediatest
, NULL
, 0, 0, true);
983 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_REPORTTEST
)) {
984 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_reporttest
, NULL
, 0, 0, true);
986 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_EXPRESSIONEVAL
)) {
987 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_expressioneval
, NULL
, 0, 0, true);
989 else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SCRIPTEXEC
)) {
990 proto_tree_add_boolean(zabbix_tree
, hf_zabbix_frontend_scriptexec
, NULL
, 0, 0, true);
993 else if (sender_name
) {
994 temp_ti
= proto_tree_add_string(zabbix_tree
, hf_zabbix_sender_name
, NULL
, 0, 0, sender_name
);
995 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE
)) {
996 /* sender_name was populated from the conversation */
997 proto_item_set_generated(temp_ti
);
998 proto_item_append_text(temp_ti
, " (from the request)");
1002 proto_tree_add_string(zabbix_tree
, hf_zabbix_version
, NULL
, 0, 0, version
);
1004 if (config_revision
> -1) {
1005 proto_tree_add_int64(zabbix_tree
, hf_zabbix_config_revision
, NULL
, 0, 0, config_revision
);
1007 if (hostmap_revision
> -1) {
1008 proto_tree_add_int64(zabbix_tree
, hf_zabbix_hostmap_revision
, NULL
, 0, 0, hostmap_revision
);
1011 proto_tree_add_string(zabbix_tree
, hf_zabbix_session
, NULL
, 0, 0, session
);
1013 /* Show also the full JSON, or pre-7.0 passive agent request/response (or error message).
1014 * Note that ZABBIX_ZBX_NOTSUPPORTED does not include the \0 that is in the
1015 * protocol specification! Therefore +1/-1's are present
1017 if (passive_agent_data_str
&&
1018 strlen(passive_agent_data_str
) >= strlen(ZABBIX_ZBX_NOTSUPPORTED
) &&
1019 strncmp(passive_agent_data_str
, ZABBIX_ZBX_NOTSUPPORTED
, strlen(ZABBIX_ZBX_NOTSUPPORTED
)) == 0) {
1020 /* Pre-7.0 passive agent error, first ZBX_NOTSUPPORTED\0 and then the error message */
1021 proto_tree_add_item(zabbix_tree
, hf_zabbix_data
,
1022 next_tvb
, 0, (int)strlen(ZABBIX_ZBX_NOTSUPPORTED
)+1, ENC_UTF_8
);
1023 proto_tree_add_item(zabbix_tree
, hf_zabbix_error
,
1024 next_tvb
, (int)strlen(ZABBIX_ZBX_NOTSUPPORTED
)+1, (int)datalen
-(int)strlen(ZABBIX_ZBX_NOTSUPPORTED
)-1, ENC_UTF_8
);
1026 /* JSON or pre-7.0 passive agent without error */
1027 proto_tree_add_item(zabbix_tree
, hf_zabbix_data
, next_tvb
, 0, (int)datalen
, ENC_UTF_8
);
1032 /* These are common for all cases, too large or not */
1034 /* Check the ZABBIX_T_REQUEST flag (and not CONV_IS_ZABBIX_REQUEST macro) because
1035 * heartbeats are not marked as requests */
1036 if (IS_ZABBIX_T_FLAGS(ZABBIX_T_REQUEST
)) {
1037 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_request
, NULL
, 0, 0, true);
1038 proto_item_set_text(temp_ti
, "This is Zabbix request");
1039 } else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info
, pinfo
)) {
1040 temp_ti
= proto_tree_add_boolean(zabbix_tree
, hf_zabbix_response
, NULL
, 0, 0, true);
1041 proto_item_set_text(temp_ti
, "This is Zabbix response");
1042 if (!nstime_is_unset(&zabbix_info
->req_timestamp
)) {
1044 nstime_delta(&delta
, &pinfo
->abs_ts
, &zabbix_info
->req_timestamp
);
1045 pi
= proto_tree_add_time(zabbix_tree
, hf_zabbix_time
, next_tvb
, 0, 0, &delta
);
1046 proto_item_set_generated(pi
);
1050 /* Add length to the Zabbix tree text */
1051 proto_item_append_text(ti
, ", Len=%u", (unsigned)length
);
1052 /* Add/set Info column texts */
1053 const char *info_text
= col_get_text(pinfo
->cinfo
, COL_INFO
);
1054 if (!info_text
|| !strlen(info_text
)) {
1055 /* Info column is still empty, set the default text */
1056 if (CONV_IS_ZABBIX_REQUEST(zabbix_info
, pinfo
)) {
1057 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Zabbix Protocol request, Flags=0x%02x", flags
);
1058 } else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info
, pinfo
)) {
1059 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Zabbix Protocol response, Flags=0x%02x", flags
);
1061 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Zabbix Protocol, Flags=0x%02x", flags
);
1064 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Len=%u (", (unsigned)length
);
1065 col_append_ports(pinfo
->cinfo
, COL_INFO
, PT_TCP
, pinfo
->srcport
, pinfo
->destport
);
1066 col_append_str(pinfo
->cinfo
, COL_INFO
, ")");
1068 return tvb_reported_length(tvb
);
1071 /* Determine PDU length of Zabbix protocol */
1073 get_zabbix_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
1078 flags
= tvb_get_uint8(tvb
, offset
+4);
1079 if (flags
& ZABBIX_FLAG_LARGEPACKET
) {
1080 /* 8-byte length field
1081 * Note that ZABBIX_HDR_MIN_LEN check (in dissect_zabbix()) is still enough
1082 * due to the header structure (there are reserved bytes)
1084 length
= tvb_get_uint64(tvb
, offset
+5, ENC_LITTLE_ENDIAN
) + ZABBIX_HDR_MAX_LEN
;
1087 length
= tvb_get_uint32(tvb
, offset
+5, ENC_LITTLE_ENDIAN
) + ZABBIX_HDR_MIN_LEN
;
1089 return (unsigned)length
;
1092 /* The main dissecting routine */
1094 dissect_zabbix(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1098 if (tvb_captured_length(tvb
) < ZABBIX_HDR_MIN_LEN
) {
1099 /* Not enough data */
1102 if (tvb_memeql(tvb
, 0, ZABBIX_HDR_SIGNATURE
, 4)) {
1103 /* Encrypted or not Zabbix at all */
1106 flags
= tvb_get_uint8(tvb
, 4);
1107 if (!(flags
& ZABBIX_FLAG_ZABBIX_COMMUNICATIONS
)) {
1110 /* This is unencrypted Zabbix protocol, continue with dissecting it */
1111 tcp_dissect_pdus(tvb
, pinfo
, tree
, zabbix_desegment
, ZABBIX_HDR_MIN_LEN
,
1112 get_zabbix_pdu_len
, dissect_zabbix_pdu
, data
);
1113 return tvb_reported_length(tvb
);
1116 /* Register the protocol with Wireshark */
1119 proto_register_zabbix(void)
1121 static hf_register_info hf
[] = {
1122 { &hf_zabbix_header
,
1123 { "Header", "zabbix.header",
1124 FT_STRING
, BASE_NONE
, NULL
, 0,
1128 { "Flags", "zabbix.flags",
1129 FT_UINT8
, BASE_HEX
, NULL
, 0,
1132 { &hf_zabbix_flag_zabbix_communications
,
1133 { "Zabbix communications protocol", "zabbix.flags.zabbix",
1134 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), ZABBIX_FLAG_ZABBIX_COMMUNICATIONS
,
1137 { &hf_zabbix_flag_compressed
,
1138 { "Compressed", "zabbix.flags.compressed",
1139 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), ZABBIX_FLAG_COMPRESSED
,
1142 { &hf_zabbix_flag_largepacket
,
1143 { "Large packet", "zabbix.flags.large_packet",
1144 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), ZABBIX_FLAG_LARGEPACKET
,
1147 { &hf_zabbix_flag_reserved
,
1148 { "Reserved bits", "zabbix.flags.reserved",
1149 FT_UINT8
, BASE_DEC
, NULL
, ZABBIX_FLAG_RESERVED
,
1152 { &hf_zabbix_length
,
1153 { "Length", "zabbix.len",
1154 FT_UINT32
, BASE_DEC
, NULL
, 0,
1157 { &hf_zabbix_reserved
,
1158 { "Reserved", "zabbix.reserved",
1159 FT_UINT32
, BASE_DEC
, NULL
, 0,
1162 { &hf_zabbix_uncompressed_length
,
1163 { "Uncompressed length", "zabbix.uncompressed_len",
1164 FT_UINT32
, BASE_DEC
, NULL
, 0,
1167 { &hf_zabbix_large_length
,
1168 { "Large length", "zabbix.large.len",
1169 FT_UINT64
, BASE_DEC
, NULL
, 0,
1172 { &hf_zabbix_large_reserved
,
1173 { "Large reserved", "zabbix.large.reserved",
1174 FT_UINT64
, BASE_DEC
, NULL
, 0,
1177 { &hf_zabbix_large_uncompressed_length
,
1178 { "Large uncompressed length", "zabbix.large.uncompressed_len",
1179 FT_UINT64
, BASE_DEC
, NULL
, 0,
1183 { "Data", "zabbix.data",
1184 FT_STRING
, BASE_NONE
, NULL
, 0,
1188 { "Error message", "zabbix.error",
1189 FT_STRING
, BASE_NONE
, NULL
, 0,
1193 { "Response time", "zabbix.time",
1194 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0,
1197 { &hf_zabbix_request
,
1198 { "Zabbix protocol request", "zabbix.request",
1199 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1202 { &hf_zabbix_response
,
1203 { "Zabbix protocol response", "zabbix.response",
1204 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1207 { &hf_zabbix_success
,
1208 { "Success", "zabbix.success",
1209 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1212 { &hf_zabbix_failed
,
1213 { "Failed", "zabbix.failed",
1214 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1218 { "Zabbix agent connection", "zabbix.agent",
1219 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1222 { &hf_zabbix_agent_commands
,
1223 { "Zabbix agent commands", "zabbix.agent.commands",
1224 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1227 { &hf_zabbix_agent_config
,
1228 { "Zabbix agent config", "zabbix.agent.config",
1229 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1232 { &hf_zabbix_agent_data
,
1233 { "Zabbix agent data", "zabbix.agent.data",
1234 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1237 { &hf_zabbix_agent_redirection
,
1238 { "Agent redirection", "zabbix.agent.redirection",
1239 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1242 { &hf_zabbix_agent_passive
,
1243 { "Passive agent", "zabbix.agent.passive",
1244 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1247 { &hf_zabbix_agent_name
,
1248 { "Agent name", "zabbix.agent.name",
1249 FT_STRING
, BASE_NONE
, NULL
, 0,
1252 { &hf_zabbix_agent_hb
,
1253 { "Agent heartbeat", "zabbix.agent.heartbeat",
1254 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1257 { &hf_zabbix_agent_hb_freq
,
1258 { "Agent heartbeat frequency", "zabbix.agent.heartbeat_freq",
1259 FT_INT32
, BASE_DEC
, NULL
, 0,
1262 { &hf_zabbix_agent_hostmetadata
,
1263 { "Agent host metadata", "zabbix.agent.host_metadata",
1264 FT_STRING
, BASE_NONE
, NULL
, 0,
1267 { &hf_zabbix_agent_hostinterface
,
1268 { "Agent host interface", "zabbix.agent.host_interface",
1269 FT_STRING
, BASE_NONE
, NULL
, 0,
1272 { &hf_zabbix_agent_listenipv4
,
1273 { "Agent listen IPv4", "zabbix.agent.listen_ipv4",
1274 FT_IPv4
, BASE_NONE
, NULL
, 0,
1277 { &hf_zabbix_agent_listenipv6
,
1278 { "Agent listen IPv6", "zabbix.agent.listen_ipv6",
1279 FT_IPv6
, BASE_NONE
, NULL
, 0,
1282 { &hf_zabbix_agent_listenport
,
1283 { "Agent listen port", "zabbix.agent.listen_port",
1284 FT_UINT16
, BASE_DEC
, NULL
, 0,
1287 { &hf_zabbix_agent_variant
,
1288 { "Agent variant", "zabbix.agent.variant",
1289 FT_INT64
, BASE_DEC
, NULL
, 0,
1293 { "Proxy connection", "zabbix.proxy",
1294 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1297 { &hf_zabbix_proxy_name
,
1298 { "Proxy name", "zabbix.proxy.name",
1299 FT_STRING
, BASE_NONE
, NULL
, 0,
1302 { &hf_zabbix_proxy_hb
,
1303 { "Proxy heartbeat", "zabbix.proxy.heartbeat",
1304 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1307 { &hf_zabbix_proxy_data
,
1308 { "Proxy data", "zabbix.proxy.data",
1309 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1312 { &hf_zabbix_proxy_config
,
1313 { "Proxy config", "zabbix.proxy.config",
1314 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1317 { &hf_zabbix_proxy_fullsync
,
1318 { "Proxy config full sync", "zabbix.proxy.full_sync",
1319 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1322 { &hf_zabbix_proxy_incr_config
,
1323 { "Proxy incremental config", "zabbix.proxy.incremental_config",
1324 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1327 { &hf_zabbix_proxy_no_config_change
,
1328 { "Proxy no config changes", "zabbix.proxy.no_config_changes",
1329 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1332 { &hf_zabbix_proxy_tasks
,
1333 { "Proxy tasks", "zabbix.proxy.tasks",
1334 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1337 { &hf_zabbix_sender
,
1338 { "Sender connection", "zabbix.sender",
1339 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1342 { &hf_zabbix_sender_name
,
1343 { "Sender name", "zabbix.sender.name",
1344 FT_STRING
, BASE_NONE
, NULL
, 0,
1347 { &hf_zabbix_version
,
1348 { "Version", "zabbix.version",
1349 FT_STRING
, BASE_NONE
, NULL
, 0,
1352 { &hf_zabbix_session
,
1353 { "Session", "zabbix.session",
1354 FT_STRING
, BASE_NONE
, NULL
, 0,
1357 { &hf_zabbix_config_revision
,
1358 { "Config revision", "zabbix.config_revision",
1359 FT_INT64
, BASE_DEC
, NULL
, 0,
1362 { &hf_zabbix_hostmap_revision
,
1363 { "Hostmap revision", "zabbix.hostmap_revision",
1364 FT_INT64
, BASE_DEC
, NULL
, 0,
1367 { &hf_zabbix_metrics
,
1368 { "Server/proxy internal metrics", "zabbix.stats",
1369 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1372 { &hf_zabbix_frontend
,
1373 { "Zabbix frontend", "zabbix.frontend",
1374 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1377 { &hf_zabbix_frontend_sysinfo
,
1378 { "System information", "zabbix.frontend.sysinfo",
1379 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1382 { &hf_zabbix_frontend_queueinfo
,
1383 { "Queue information", "zabbix.frontend.queueinfo",
1384 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1387 { &hf_zabbix_frontend_historypush
,
1388 { "History push", "zabbix.frontend.historypush",
1389 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1392 { &hf_zabbix_frontend_itemtest
,
1393 { "Item test", "zabbix.frontend.itemtest",
1394 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1397 { &hf_zabbix_frontend_mediatest
,
1398 { "Media test", "zabbix.frontend.mediatest",
1399 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1402 { &hf_zabbix_frontend_reporttest
,
1403 { "Report test", "zabbix.frontend.reporttest",
1404 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1407 { &hf_zabbix_frontend_expressioneval
,
1408 { "Expression evaluation", "zabbix.frontend.expressioneval",
1409 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1412 { &hf_zabbix_frontend_scriptexec
,
1413 { "Script execution", "zabbix.frontend.scriptexec",
1414 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0,
1419 static ei_register_info ei
[] = {
1421 &ei_zabbix_packet_too_large
,
1422 { "zabbix.packet_too_large", PI_UNDECODED
, PI_WARN
,
1423 "Packet is too large for detailed dissection", EXPFILL
}
1426 &ei_zabbix_json_error
,
1427 { "zabbix.json_error", PI_PROTOCOL
, PI_ERROR
,
1428 "Cannot parse JSON", EXPFILL
}
1432 /* Setup protocol subtree array */
1433 static int *ett
[] = {
1438 module_t
*zabbix_module
;
1439 expert_module_t
*expert_zabbix
;
1441 /* Register the protocol name and description */
1442 proto_zabbix
= proto_register_protocol("Zabbix Protocol", "Zabbix", "zabbix");
1444 /* Required function calls to register the header fields and subtrees used */
1445 proto_register_field_array(proto_zabbix
, hf
, array_length(hf
));
1446 proto_register_subtree_array(ett
, array_length(ett
));
1448 zabbix_module
= prefs_register_protocol(proto_zabbix
, NULL
);
1450 prefs_register_bool_preference(zabbix_module
, "desegment",
1451 "Reassemble Zabbix messages spanning multiple TCP segments",
1452 "Whether the Zabbix protocol dissector should reassemble messages spanning multiple TCP segments."
1453 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1456 zabbix_handle
= register_dissector("zabbix", dissect_zabbix
, proto_zabbix
);
1458 expert_zabbix
= expert_register_protocol(proto_zabbix
);
1459 expert_register_field_array(expert_zabbix
, ei
, array_length(ei
));
1463 proto_reg_handoff_zabbix(void)
1465 dissector_add_uint_range_with_preference("tcp.port", ZABBIX_TCP_PORTS
, zabbix_handle
);
1466 zabbix_port_range
= prefs_get_range_value("Zabbix", "tcp.port");
1467 dissector_add_uint_range("tls.port", zabbix_port_range
, zabbix_handle
);