/src/wireshark/epan/dissectors/packet-zabbix.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-zabbix.c |
2 | | * Routines for Zabbix protocol dissection |
3 | | * Copyright 2023, Markku Leiniƶ <markku.leinio@gmail.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | /* |
13 | | * Zabbix protocol specifications can be found in Zabbix documentation: |
14 | | * https://www.zabbix.com/documentation/current/en/manual/appendix/protocols |
15 | | */ |
16 | | |
17 | | #include "config.h" |
18 | | |
19 | | #include <epan/conversation.h> |
20 | | #include <epan/expert.h> |
21 | | #include <epan/packet.h> |
22 | | #include <epan/prefs.h> |
23 | | #include <epan/tfs.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" |
29 | | |
30 | | void proto_register_zabbix(void); |
31 | | void proto_reg_handoff_zabbix(void); |
32 | | |
33 | | static dissector_handle_t zabbix_handle; |
34 | | |
35 | | /* Desegmentation of Zabbix protocol over TCP */ |
36 | | static bool zabbix_desegment = true; |
37 | | |
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; |
99 | | |
100 | | /* Subtree pointers */ |
101 | | static int ett_zabbix; |
102 | | static int ett_zabbix_flags; |
103 | | |
104 | | /* Expert fields */ |
105 | | static expert_field ei_zabbix_packet_too_large; |
106 | | static expert_field ei_zabbix_json_error; |
107 | | |
108 | | /* Other dissector-specifics */ |
109 | | static range_t *zabbix_port_range; |
110 | | |
111 | | static const char ZABBIX_HDR_SIGNATURE[] = "ZBXD"; |
112 | | static const char ZABBIX_UNKNOWN[] = "<unknown>"; |
113 | | static const char ZABBIX_ZBX_NOTSUPPORTED[] = "ZBX_NOTSUPPORTED"; |
114 | | |
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; |
121 | | |
122 | 6 | #define ZABBIX_HDR_MIN_LEN 13 /* When not large packet */ |
123 | 0 | #define ZABBIX_HDR_MAX_LEN 21 /* When large packet */ |
124 | 0 | #define ZABBIX_MAX_LENGTH_ALLOWED 1024*1024*1024 /* 1 GB */ |
125 | 14 | #define ZABBIX_TCP_PORTS "10050,10051" /* IANA registered ports */ |
126 | | |
127 | 14 | #define ZABBIX_FLAG_ZABBIX_COMMUNICATIONS 0x01 |
128 | 14 | #define ZABBIX_FLAG_COMPRESSED 0x02 |
129 | 14 | #define ZABBIX_FLAG_LARGEPACKET 0x04 |
130 | 14 | #define ZABBIX_FLAG_RESERVED 0xf8 |
131 | | |
132 | | /* Response flags are not saved in the conversations */ |
133 | 0 | #define ZABBIX_RESPONSE_SUCCESS 0x01 |
134 | 0 | #define ZABBIX_RESPONSE_FAILED 0x02 |
135 | 0 | #define ZABBIX_RESPONSE_FULLSYNC 0x04 |
136 | 0 | #define ZABBIX_RESPONSE_INCREMENTAL 0x08 |
137 | 0 | #define ZABBIX_RESPONSE_NOCHANGE 0x10 |
138 | | |
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 |
163 | | |
164 | 0 | #define ADD_ZABBIX_T_FLAGS(flags) (zabbix_info->oper_flags |= (flags)) |
165 | 0 | #define CLEAR_ZABBIX_T_FLAGS(flags) (zabbix_info->oper_flags &= (0xffffffff-(flags))) |
166 | 0 | #define IS_ZABBIX_T_FLAGS(flags) ((zabbix_info->oper_flags & (flags)) == (flags)) |
167 | | |
168 | 0 | #define CONV_IS_ZABBIX_REQUEST(zabbix_info,pinfo) ((zabbix_info)->req_framenum == (pinfo)->fd->num) |
169 | 0 | #define CONV_IS_ZABBIX_RESPONSE(zabbix_info,pinfo) ((zabbix_info)->req_framenum != (pinfo)->fd->num) |
170 | | |
171 | 0 | #define ZABBIX_NAME_OR_UNKNOWN(name) ((name) ? (name) : ZABBIX_UNKNOWN) |
172 | | |
173 | | |
174 | | static zabbix_conv_info_t* |
175 | | zabbix_find_conversation_and_get_conv_data(packet_info *pinfo) |
176 | 0 | { |
177 | 0 | conversation_t *conversation; |
178 | 0 | zabbix_conv_info_t *zabbix_info = NULL; |
179 | |
|
180 | 0 | conversation = find_conversation_pinfo(pinfo, 0); |
181 | 0 | if (conversation) { |
182 | 0 | zabbix_info = (zabbix_conv_info_t *)conversation_get_proto_data(conversation, proto_zabbix); |
183 | 0 | } else { |
184 | 0 | conversation = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst, |
185 | 0 | conversation_pt_to_conversation_type(pinfo->ptype), |
186 | 0 | pinfo->srcport, pinfo->destport, 0); |
187 | 0 | } |
188 | 0 | if (!zabbix_info) { |
189 | | /* New conversation, or there was no Zabbix data yet in the existing conv */ |
190 | 0 | zabbix_info = wmem_alloc(wmem_file_scope(), sizeof(zabbix_conv_info_t)); |
191 | 0 | if (value_is_in_range(zabbix_port_range, pinfo->destport)) { |
192 | | /* Let's assume this is the first Zabbix packet (request) */ |
193 | 0 | zabbix_info->req_framenum = pinfo->fd->num; |
194 | 0 | zabbix_info->req_timestamp = pinfo->abs_ts; |
195 | 0 | } |
196 | 0 | else { |
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 |
199 | | */ |
200 | 0 | zabbix_info->req_framenum = 0; |
201 | 0 | 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; |
204 | | */ |
205 | 0 | } |
206 | 0 | zabbix_info->oper_flags = 0; |
207 | 0 | zabbix_info->host_name = NULL; |
208 | 0 | conversation_add_proto_data(conversation, proto_zabbix, (void *)zabbix_info); |
209 | 0 | } |
210 | 0 | return zabbix_info; |
211 | 0 | } |
212 | | |
213 | | static void |
214 | | zabbix_add_expert_info_if_too_large(packet_info *pinfo, proto_tree *tree_item, |
215 | | uint64_t length, bool *is_too_large) |
216 | 0 | { |
217 | 0 | if (length > ZABBIX_MAX_LENGTH_ALLOWED) { |
218 | 0 | expert_add_info(pinfo, tree_item, &ei_zabbix_packet_too_large); |
219 | 0 | *is_too_large = true; |
220 | 0 | } |
221 | 0 | return; |
222 | 0 | } |
223 | | |
224 | | static int |
225 | | dissect_zabbix_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
226 | 0 | { |
227 | 0 | int offset = 0; |
228 | 0 | int agent_hb_freq = 0; |
229 | 0 | unsigned oper_response = 0; |
230 | 0 | proto_item *ti; |
231 | 0 | proto_item *pi; |
232 | 0 | proto_tree *temp_ti; |
233 | 0 | proto_tree *zabbix_tree = NULL; |
234 | 0 | uint8_t flags; |
235 | 0 | uint16_t agent_listenport = 0; |
236 | 0 | uint64_t length; |
237 | 0 | uint64_t uncompressed_length; |
238 | 0 | uint64_t datalen; |
239 | 0 | int64_t agent_variant = 0; |
240 | 0 | int64_t config_revision = -1; |
241 | 0 | int64_t hostmap_revision = -1; |
242 | 0 | bool is_compressed; |
243 | 0 | bool is_large_packet; |
244 | 0 | bool is_too_large = false; |
245 | 0 | bool is_redirection = false; |
246 | 0 | char *json_str; |
247 | 0 | char *passive_agent_data_str = NULL; |
248 | 0 | jsmntok_t *commands_array = NULL; |
249 | 0 | jsmntok_t *data_array = NULL; |
250 | 0 | jsmntok_t *data_object = NULL; |
251 | 0 | const char *agent_name = NULL; |
252 | 0 | const char *agent_hostmetadata = NULL; |
253 | 0 | const char *agent_hostinterface = NULL; |
254 | 0 | const char *agent_listenip = NULL; |
255 | 0 | const char *proxy_name = NULL; |
256 | 0 | const char *sender_name = NULL; |
257 | 0 | const char *session = NULL; |
258 | 0 | const char *request_type = NULL; |
259 | 0 | const char *response_status = NULL; |
260 | 0 | const char *version = NULL; |
261 | 0 | double temp_double; |
262 | 0 | tvbuff_t *next_tvb; |
263 | 0 | zabbix_conv_info_t *zabbix_info; |
264 | 0 | static int* const flagbits[] = { |
265 | 0 | &hf_zabbix_flag_reserved, |
266 | 0 | &hf_zabbix_flag_largepacket, |
267 | 0 | &hf_zabbix_flag_compressed, |
268 | 0 | &hf_zabbix_flag_zabbix_communications, |
269 | 0 | NULL |
270 | 0 | }; |
271 | | |
272 | | /* Make entries in Protocol column and Info column on summary display */ |
273 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Zabbix"); |
274 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
275 | |
|
276 | 0 | if ((tvb_reported_length(tvb) < ZABBIX_HDR_MIN_LEN) || |
277 | 0 | (tvb_memeql(tvb, offset, ZABBIX_HDR_SIGNATURE, 4) == -1)) { |
278 | | /* Encrypted or not Zabbix at all */ |
279 | 0 | return 0; |
280 | 0 | } |
281 | 0 | flags = tvb_get_uint8(tvb, offset+4); |
282 | 0 | if (!(flags & ZABBIX_FLAG_ZABBIX_COMMUNICATIONS)) { |
283 | 0 | return 0; |
284 | 0 | } |
285 | | |
286 | 0 | zabbix_info = zabbix_find_conversation_and_get_conv_data(pinfo); |
287 | |
|
288 | 0 | is_compressed = (flags & ZABBIX_FLAG_COMPRESSED) > 0; |
289 | 0 | is_large_packet = (flags & ZABBIX_FLAG_LARGEPACKET) > 0; |
290 | | |
291 | | /* create display subtree for the protocol */ |
292 | 0 | ti = proto_tree_add_item(tree, proto_zabbix, tvb, 0, -1, ENC_NA); |
293 | 0 | zabbix_tree = proto_item_add_subtree(ti, ett_zabbix); |
294 | 0 | proto_tree_add_item(zabbix_tree, hf_zabbix_header, tvb, offset, 4, ENC_UTF_8); |
295 | 0 | offset += 4; |
296 | 0 | proto_tree_add_bitmask(zabbix_tree, tvb, offset, hf_zabbix_flags, ett_zabbix_flags, flagbits, ENC_BIG_ENDIAN); |
297 | 0 | offset += 1; |
298 | 0 | if (is_large_packet) { |
299 | | /* 8-byte values */ |
300 | 0 | temp_ti = proto_tree_add_item_ret_uint64(zabbix_tree, |
301 | 0 | hf_zabbix_large_length, tvb, offset, 8, ENC_LITTLE_ENDIAN, &length); |
302 | 0 | zabbix_add_expert_info_if_too_large(pinfo, temp_ti, length, &is_too_large); |
303 | 0 | offset += 8; |
304 | 0 | if (is_compressed) { |
305 | 0 | temp_ti = proto_tree_add_item_ret_uint64(zabbix_tree, |
306 | 0 | hf_zabbix_large_uncompressed_length, tvb, offset, 8, ENC_LITTLE_ENDIAN, &uncompressed_length); |
307 | 0 | zabbix_add_expert_info_if_too_large(pinfo, temp_ti, uncompressed_length, &is_too_large); |
308 | 0 | } else { |
309 | 0 | proto_tree_add_item(zabbix_tree, hf_zabbix_large_reserved, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
310 | 0 | } |
311 | 0 | offset += 8; |
312 | 0 | } else { |
313 | | /* 4-byte values */ |
314 | 0 | uint32_t temp_uint32; |
315 | 0 | temp_ti = proto_tree_add_item_ret_uint(zabbix_tree, |
316 | 0 | hf_zabbix_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &temp_uint32); |
317 | 0 | length = (uint64_t)temp_uint32; |
318 | 0 | zabbix_add_expert_info_if_too_large(pinfo, temp_ti, length, &is_too_large); |
319 | 0 | offset += 4; |
320 | 0 | if (is_compressed) { |
321 | 0 | temp_ti = proto_tree_add_item_ret_uint(zabbix_tree, |
322 | 0 | hf_zabbix_uncompressed_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &temp_uint32); |
323 | 0 | uncompressed_length = (uint64_t)temp_uint32; |
324 | 0 | zabbix_add_expert_info_if_too_large(pinfo, temp_ti, uncompressed_length, &is_too_large); |
325 | 0 | } else { |
326 | 0 | proto_tree_add_item(zabbix_tree, hf_zabbix_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
327 | 0 | } |
328 | 0 | offset += 4; |
329 | 0 | } |
330 | 0 | if (is_too_large) { |
331 | | /* Set next_tvb for response time calculation to work later */ |
332 | 0 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
333 | | /* ... but don't do any content-based inspection, just skip to the end */ |
334 | 0 | goto final_outputs; |
335 | 0 | } else if (is_compressed) { |
336 | 0 | next_tvb = tvb_uncompress_zlib(tvb, offset, tvb_reported_length_remaining(tvb, offset)); |
337 | 0 | if (next_tvb) { |
338 | 0 | tvb_set_child_real_data_tvbuff(tvb, next_tvb); |
339 | 0 | add_new_data_source(pinfo, next_tvb, "Uncompressed data"); |
340 | 0 | datalen = uncompressed_length; |
341 | 0 | } else { |
342 | | /* Handle uncompressed */ |
343 | 0 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
344 | 0 | datalen = length; |
345 | 0 | } |
346 | 0 | } else { |
347 | 0 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
348 | 0 | datalen = length; |
349 | 0 | } |
350 | | |
351 | | /* Use only next_tvb and datalen for data extraction from here on! */ |
352 | 0 | offset = 0; |
353 | | |
354 | | /* Rewrite the default texts in the protocol tree and initialize request/response flags */ |
355 | 0 | if (CONV_IS_ZABBIX_REQUEST(zabbix_info, pinfo)) { |
356 | 0 | proto_item_set_text(ti, "Zabbix Protocol request"); |
357 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_REQUEST); |
358 | 0 | CLEAR_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE); |
359 | 0 | } |
360 | 0 | else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info, pinfo)) { |
361 | 0 | proto_item_set_text(ti, "Zabbix Protocol response"); |
362 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE); |
363 | 0 | CLEAR_ZABBIX_T_FLAGS(ZABBIX_T_REQUEST); |
364 | 0 | } |
365 | | |
366 | | /* |
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) |
369 | | */ |
370 | 0 | 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! |
374 | | */ |
375 | 0 | int token_count = json_parse(json_str, NULL, 0); |
376 | 0 | if ( |
377 | 0 | token_count < 0 || |
378 | 0 | ( |
379 | 0 | CONV_IS_ZABBIX_RESPONSE(zabbix_info, pinfo) && |
380 | 0 | IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_PASSIVE | ZABBIX_T_LEGACY) |
381 | 0 | ) |
382 | 0 | ) { |
383 | | /* The only non-JSON Zabbix request/response is passive agent before Zabbix 7.0, |
384 | | * ensure the conversation data is set, then set the texts |
385 | | */ |
386 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_PASSIVE | ZABBIX_T_LEGACY); |
387 | 0 | if (CONV_IS_ZABBIX_REQUEST(zabbix_info, pinfo)) { |
388 | 0 | proto_item_set_text(ti, "Zabbix Server/proxy request for passive agent checks"); |
389 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Server/proxy request for passive agent checks"); |
390 | 0 | } else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info, pinfo)) { |
391 | 0 | proto_item_set_text(ti, "Zabbix Agent response for passive checks"); |
392 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Agent response for passive checks"); |
393 | 0 | } |
394 | | /* Make a copy of the data string for later error message lookup use */ |
395 | 0 | passive_agent_data_str = wmem_strndup(pinfo->pool, json_str, (size_t)datalen); |
396 | | /* Don't do content-based searches for pre-7.0 passive agents */ |
397 | 0 | goto show_agent_outputs; |
398 | 0 | } |
399 | 0 | jsmntok_t *tokens = wmem_alloc_array(pinfo->pool, jsmntok_t, token_count); |
400 | 0 | int ret = json_parse(json_str, tokens, token_count); |
401 | 0 | if (ret <= 0) { |
402 | 0 | temp_ti = proto_tree_add_item(zabbix_tree, hf_zabbix_data, next_tvb, 0, (int)datalen, ENC_UTF_8); |
403 | 0 | expert_add_info_format(pinfo, temp_ti, &ei_zabbix_json_error, "Error parsing JSON tokens"); |
404 | 0 | goto final_outputs; |
405 | 0 | } |
406 | | |
407 | | /* |
408 | | * Now we have JSON tokens analyzed, let's do all the logic to populate the fields. |
409 | | * Also set Zabbix tree item and Info column texts, Len= and ports will be added later below. |
410 | | */ |
411 | | |
412 | | /* First populate common fields */ |
413 | 0 | version = json_get_string(json_str, tokens, "version"); |
414 | 0 | if (json_get_double(json_str, tokens, "variant", &temp_double)) { |
415 | 0 | agent_variant = (int64_t)temp_double; |
416 | 0 | } |
417 | 0 | session = json_get_string(json_str, tokens, "session"); |
418 | 0 | if (json_get_double(json_str, tokens, "config_revision", &temp_double)) { |
419 | 0 | config_revision = (int64_t)temp_double; |
420 | 0 | } |
421 | 0 | if (json_get_double(json_str, tokens, "hostmap_revision", &temp_double)) { |
422 | 0 | hostmap_revision = (int64_t)temp_double; |
423 | 0 | } else { |
424 | 0 | jsmntok_t *proxy_group_object = json_get_object(json_str, tokens, "proxy_group"); |
425 | 0 | if (proxy_group_object) { |
426 | 0 | if (json_get_double(json_str, proxy_group_object, "hostmap_revision", &temp_double)) { |
427 | 0 | hostmap_revision = (int64_t)temp_double; |
428 | 0 | } |
429 | 0 | } |
430 | 0 | } |
431 | 0 | request_type = json_get_string(json_str, tokens, "request"); |
432 | 0 | response_status = json_get_string(json_str, tokens, "response"); |
433 | 0 | commands_array = json_get_array(json_str, tokens, "commands"); |
434 | 0 | data_array = json_get_array(json_str, tokens, "data"); |
435 | 0 | data_object = json_get_object(json_str, tokens, "data"); |
436 | | /* Find the packet type primarily based on "request" field */ |
437 | 0 | if (request_type) { |
438 | 0 | if (strcmp(request_type, "active checks") == 0) { |
439 | | /* Active agent requesting configs */ |
440 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_CONFIG | ZABBIX_T_ACTIVE); |
441 | 0 | agent_name = json_get_string(json_str, tokens, "host"); |
442 | 0 | if (agent_name && !PINFO_FD_VISITED(pinfo)) { |
443 | 0 | zabbix_info->host_name = wmem_strdup(wmem_file_scope(), agent_name); |
444 | 0 | } |
445 | 0 | proto_item_set_text(ti, |
446 | 0 | "Zabbix Agent request for active checks for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
447 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
448 | 0 | "Zabbix Agent request for active checks for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
449 | 0 | agent_hostmetadata = json_get_string(json_str, tokens, "host_metadata"); |
450 | 0 | agent_hostinterface = json_get_string(json_str, tokens, "interface"); |
451 | 0 | agent_listenip = json_get_string(json_str, tokens, "ip"); |
452 | 0 | if (json_get_double(json_str, tokens, "port", &temp_double)) { |
453 | 0 | agent_listenport = (uint16_t)temp_double; |
454 | 0 | } |
455 | 0 | } |
456 | 0 | else if (strcmp(request_type, "agent data") == 0) { |
457 | | /* Active agent sending data */ |
458 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_DATA | ZABBIX_T_ACTIVE); |
459 | | /* Zabbix Agent 2 has Host in the top level */ |
460 | 0 | agent_name = json_get_string(json_str, tokens, "host"); |
461 | 0 | if (!agent_name) { |
462 | | /* For Zabbix Agent try parsing agent name inside data array */ |
463 | 0 | jsmntok_t *tok = json_get_array(json_str, tokens, "data"); |
464 | 0 | if (tok && json_get_array_len(tok) > 0) { |
465 | 0 | jsmntok_t *datatok = json_get_array_index(tok, 0); |
466 | 0 | agent_name = json_get_string(json_str, datatok, "host"); |
467 | 0 | } |
468 | 0 | } |
469 | 0 | if (agent_name && !PINFO_FD_VISITED(pinfo)) { |
470 | 0 | zabbix_info->host_name = wmem_strdup(wmem_file_scope(), agent_name); |
471 | 0 | } |
472 | 0 | proto_item_set_text(ti, |
473 | 0 | "Zabbix Agent data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
474 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
475 | 0 | "Zabbix Agent data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
476 | 0 | } |
477 | 0 | else if (strcmp(request_type, "active check heartbeat") == 0) { |
478 | | /* Active agent sending heartbeat */ |
479 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_HEARTBEAT | ZABBIX_T_ACTIVE); |
480 | 0 | agent_name = json_get_string(json_str, tokens, "host"); |
481 | 0 | if (agent_name && !PINFO_FD_VISITED(pinfo)) { |
482 | 0 | zabbix_info->host_name = wmem_strdup(wmem_file_scope(), agent_name); |
483 | 0 | } |
484 | 0 | if (json_get_double(json_str, tokens, "heartbeat_freq", &temp_double)) { |
485 | 0 | agent_hb_freq = (int)temp_double; |
486 | 0 | } |
487 | 0 | proto_item_set_text(ti, |
488 | 0 | "Zabbix Agent heartbeat from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
489 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
490 | 0 | "Zabbix Agent heartbeat from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
491 | 0 | } |
492 | 0 | else if (strcmp(request_type, "passive checks") == 0) { |
493 | | /* Passive agent checks since Zabbix 7.0 */ |
494 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_PASSIVE); |
495 | 0 | proto_item_set_text(ti, "Zabbix Server/proxy request for passive agent checks"); |
496 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Server/proxy request for passive agent checks"); |
497 | 0 | } |
498 | 0 | else if (strcmp(request_type, "zabbix.stats") == 0) { |
499 | | /* Agent requesting server/proxy internal metrics, since Zabbix 4.0.5 */ |
500 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_METRICS); |
501 | 0 | proto_item_set_text(ti, "Zabbix Server/proxy internal metrics request"); |
502 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Server/proxy internal metrics request"); |
503 | 0 | } |
504 | 0 | else if (strcmp(request_type, "sender data") == 0) { |
505 | | /* Sender/trapper */ |
506 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_SENDER); |
507 | | /* Try to get the sender name from the first data array item */ |
508 | 0 | jsmntok_t *tok = json_get_array(json_str, tokens, "data"); |
509 | 0 | if (tok && json_get_array_len(tok) > 0) { |
510 | 0 | jsmntok_t *datatok = json_get_array_index(tok, 0); |
511 | 0 | sender_name = json_get_string(json_str, datatok, "host"); |
512 | 0 | if (sender_name && !PINFO_FD_VISITED(pinfo)) { |
513 | 0 | zabbix_info->host_name = wmem_strdup(wmem_file_scope(), sender_name); |
514 | 0 | } |
515 | 0 | } |
516 | 0 | proto_item_set_text(ti, |
517 | 0 | "Zabbix Sender data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(sender_name)); |
518 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
519 | 0 | "Zabbix Sender data from \"%s\"", ZABBIX_NAME_OR_UNKNOWN(sender_name)); |
520 | 0 | } |
521 | 0 | else if ((strcmp(request_type, "proxy data") == 0) || |
522 | 0 | (strcmp(request_type, "host availability") == 0) || |
523 | 0 | (strcmp(request_type, "history data") == 0) || |
524 | 0 | (strcmp(request_type, "discovery data") == 0) || |
525 | 0 | (strcmp(request_type, "auto registration") == 0)) { |
526 | | /* Either active or passive proxy; "proxy data" = Zabbix 3.4+, |
527 | | * others = Zabbix 3.2 or older */ |
528 | 0 | proxy_name = json_get_string(json_str, tokens, "host"); |
529 | 0 | if (token_count == 3) { /* Only '{"request":"xxx"}' */ |
530 | | /* This is Zabbix server connecting to passive proxy */ |
531 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_DATA | ZABBIX_T_PASSIVE); |
532 | 0 | proto_item_set_text(ti, "Zabbix Proxy data request to passive proxy"); |
533 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Proxy data request to passive proxy"); |
534 | 0 | } |
535 | 0 | else if (proxy_name) { |
536 | | /* This is an active proxy connecting to server */ |
537 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_DATA | ZABBIX_T_ACTIVE); |
538 | 0 | if (proxy_name && !PINFO_FD_VISITED(pinfo)) { |
539 | 0 | zabbix_info->host_name = wmem_strdup(wmem_file_scope(), proxy_name); |
540 | 0 | } |
541 | 0 | proto_item_set_text(ti, "Zabbix Proxy data from \"%s\"", proxy_name); |
542 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Zabbix Proxy data from \"%s\"", proxy_name); |
543 | 0 | } |
544 | 0 | } |
545 | 0 | else if (strcmp(request_type, "proxy config") == 0) { |
546 | | /* Either active or passive proxy */ |
547 | 0 | proxy_name = json_get_string(json_str, tokens, "host"); |
548 | 0 | if (token_count == 3) { /* Only '{"request":"proxy config"}' */ |
549 | | /* This is Zabbix 6.4+ server connecting to passive proxy */ |
550 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_CONFIG | ZABBIX_T_PASSIVE); |
551 | 0 | proto_item_set_text(ti, "Zabbix Proxy config request to passive proxy"); |
552 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Proxy config request to passive proxy"); |
553 | 0 | } |
554 | 0 | else if (proxy_name) { |
555 | | /* This is an active proxy connecting to server */ |
556 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_CONFIG | ZABBIX_T_ACTIVE); |
557 | 0 | if (proxy_name && !PINFO_FD_VISITED(pinfo)) { |
558 | 0 | zabbix_info->host_name = wmem_strdup(wmem_file_scope(), proxy_name); |
559 | 0 | } |
560 | 0 | proto_item_set_text(ti, "Zabbix Request proxy config for \"%s\"", proxy_name); |
561 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Zabbix Request proxy config for \"%s\"", proxy_name); |
562 | 0 | } |
563 | 0 | } |
564 | 0 | else if (strcmp(request_type, "proxy tasks") == 0) { |
565 | | /* Zabbix server connecting to passive proxy, only '{"request":"proxy tasks"}' */ |
566 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_TASKS | ZABBIX_T_PASSIVE); |
567 | 0 | proto_item_set_text(ti, "Zabbix Proxy tasks request to passive proxy"); |
568 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Proxy tasks request to passive proxy"); |
569 | 0 | } |
570 | 0 | else if (strcmp(request_type, "proxy heartbeat") == 0) { |
571 | | /* Heartbeat from active proxy, not used in Zabbix 6.4+ */ |
572 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_HEARTBEAT | ZABBIX_T_ACTIVE); |
573 | 0 | proxy_name = json_get_string(json_str, tokens, "host"); |
574 | 0 | if (proxy_name && !PINFO_FD_VISITED(pinfo)) { |
575 | 0 | zabbix_info->host_name = wmem_strdup(wmem_file_scope(), proxy_name); |
576 | 0 | } |
577 | 0 | proto_item_set_text(ti, "Zabbix Proxy heartbeat from \"%s\"", proxy_name); |
578 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Zabbix Proxy heartbeat from \"%s\"", proxy_name); |
579 | 0 | } |
580 | | /* UI/API-specific requests */ |
581 | 0 | else if (strcmp(request_type, "status.get") == 0) { |
582 | | /* System information report */ |
583 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_SYSINFO); |
584 | 0 | proto_item_set_text(ti, "Zabbix System information request"); |
585 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix System information request"); |
586 | 0 | } |
587 | 0 | else if (strcmp(request_type, "queue.get") == 0) { |
588 | | /* Queue information request */ |
589 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_QUEUEINFO); |
590 | 0 | proto_item_set_text(ti, "Zabbix Queue information request"); |
591 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Queue information request"); |
592 | 0 | } |
593 | 0 | else if (strcmp(request_type, "history.push") == 0) { |
594 | | /* history.push API call, since Zabbix 7.0 */ |
595 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_HISTORYPUSH); |
596 | 0 | proto_item_set_text(ti, "Zabbix History push request"); |
597 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix History push request"); |
598 | 0 | } |
599 | 0 | else if (strcmp(request_type, "item.test") == 0) { |
600 | | /* Item test in the frontend */ |
601 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_ITEMTEST); |
602 | 0 | proto_item_set_text(ti, "Zabbix Item test request"); |
603 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Item test request"); |
604 | 0 | } |
605 | 0 | else if (strcmp(request_type, "alert.send") == 0) { |
606 | | /* Media test in the frontend */ |
607 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_MEDIATEST); |
608 | 0 | proto_item_set_text(ti, "Zabbix Media test request"); |
609 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Media test request"); |
610 | 0 | } |
611 | 0 | else if (strcmp(request_type, "report.test") == 0) { |
612 | | /* Report test in the frontend */ |
613 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_REPORTTEST); |
614 | 0 | proto_item_set_text(ti, "Zabbix Report test request"); |
615 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Report test request"); |
616 | 0 | } |
617 | 0 | else if (strcmp(request_type, "expressions.evaluate") == 0) { |
618 | | /* Trigger expression evaluation test in the frontend */ |
619 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_EXPRESSIONEVAL); |
620 | 0 | proto_item_set_text(ti, "Zabbix Expression evaluation request"); |
621 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Expression evaluation request"); |
622 | 0 | } |
623 | 0 | else if (strcmp(request_type, "command") == 0) { |
624 | | /* Script execution from the frontend */ |
625 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND | ZABBIX_T_SCRIPTEXEC); |
626 | 0 | proto_item_set_text(ti, "Zabbix Script execution request"); |
627 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Script execution request"); |
628 | 0 | } |
629 | 0 | } |
630 | | /* There was no "request" field match, continue with other ways to recognize the packet */ |
631 | 0 | else if (json_get_object(json_str, tokens, "globalmacro")) { |
632 | | /* This is Zabbix server before 6.4 sending configurations to active proxy */ |
633 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_CONFIG | ZABBIX_T_ACTIVE); |
634 | 0 | proxy_name = zabbix_info->host_name; |
635 | 0 | proto_item_set_text(ti, |
636 | 0 | "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name)); |
637 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
638 | 0 | "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name)); |
639 | 0 | } |
640 | 0 | else if (json_get_double(json_str, tokens, "full_sync", &temp_double)) { |
641 | | /* This is Zabbix 6.4+ server sending proxy config to active or passive proxy */ |
642 | | /* Only present when value is 1 */ |
643 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_CONFIG); |
644 | 0 | oper_response |= ZABBIX_RESPONSE_FULLSYNC; |
645 | | /* Active/passive flag was set in the earlier packet */ |
646 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PASSIVE)) { |
647 | | /* There is no proxy name anywhere to use */ |
648 | 0 | proto_item_set_text(ti, "Zabbix Passive proxy config"); |
649 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Passive proxy config"); |
650 | 0 | } |
651 | 0 | else { |
652 | | /* Active proxy */ |
653 | 0 | proxy_name = zabbix_info->host_name; |
654 | 0 | proto_item_set_text(ti, |
655 | 0 | "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name)); |
656 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
657 | 0 | "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name)); |
658 | 0 | } |
659 | 0 | } |
660 | 0 | else if (response_status) { |
661 | 0 | if (strcmp(response_status, "success") == 0) { |
662 | 0 | oper_response |= ZABBIX_RESPONSE_SUCCESS; |
663 | 0 | } |
664 | 0 | else if (strcmp(response_status, "failed") == 0) { |
665 | 0 | oper_response |= ZABBIX_RESPONSE_FAILED; |
666 | 0 | } |
667 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT)) { |
668 | 0 | agent_name = zabbix_info->host_name; |
669 | 0 | if (json_get_object(json_str, tokens, "redirect")) { |
670 | | /* Agent redirection response from a Zabbix 7.0+ proxy in load balancing configuration. |
671 | | * Not added in the conversation flags to prevent it from showing in the request packet, |
672 | | * just set a local variable for later usage. |
673 | | */ |
674 | 0 | is_redirection = true; |
675 | 0 | proto_item_set_text(ti, |
676 | 0 | "Zabbix Agent redirection for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
677 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
678 | 0 | "Zabbix Agent redirection for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(agent_name)); |
679 | 0 | } |
680 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG | ZABBIX_T_ACTIVE)) { |
681 | 0 | proto_item_set_text(ti, |
682 | 0 | "Zabbix Server/proxy response for active checks for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name), response_status); |
683 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
684 | 0 | "Zabbix Server/proxy response for active checks for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name), response_status); |
685 | 0 | } |
686 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA | ZABBIX_T_ACTIVE)) { |
687 | 0 | proto_item_set_text(ti, |
688 | 0 | "Zabbix Server/proxy response for agent data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name), response_status); |
689 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
690 | 0 | "Zabbix Server/proxy response for agent data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(agent_name), response_status); |
691 | 0 | } |
692 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_METRICS)) { |
693 | 0 | proto_item_set_text(ti, "Zabbix Server/proxy internal metrics response"); |
694 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Server/proxy internal metrics response"); |
695 | 0 | } |
696 | 0 | } |
697 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY)) { |
698 | 0 | proxy_name = zabbix_info->host_name; |
699 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG | ZABBIX_T_ACTIVE)) { |
700 | 0 | proto_item_set_text(ti, |
701 | 0 | "Zabbix Response for active proxy config request for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name), response_status); |
702 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
703 | 0 | "Zabbix Response for active proxy config request for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name), response_status); |
704 | 0 | } |
705 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA | ZABBIX_T_ACTIVE)) { |
706 | 0 | proto_item_set_text(ti, |
707 | 0 | "Zabbix Server response for active proxy data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name), response_status); |
708 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
709 | 0 | "Zabbix Server response for active proxy data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name), response_status); |
710 | 0 | } |
711 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG | ZABBIX_T_PASSIVE)) { |
712 | 0 | proto_item_set_text(ti, |
713 | 0 | "Zabbix Proxy response for passive proxy config (%s)", response_status); |
714 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
715 | 0 | "Zabbix Proxy response for passive proxy config (%s)", response_status); |
716 | 0 | } |
717 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA | ZABBIX_T_PASSIVE)) { |
718 | 0 | proto_item_set_text(ti, |
719 | 0 | "Zabbix Server response for passive proxy data (%s)", response_status); |
720 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
721 | 0 | "Zabbix Server response for passive proxy data (%s)", response_status); |
722 | 0 | } |
723 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_TASKS | ZABBIX_T_PASSIVE)) { |
724 | 0 | proto_item_set_text(ti, |
725 | 0 | "Zabbix Server response for passive proxy tasks (%s)", response_status); |
726 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
727 | 0 | "Zabbix Server response for passive proxy tasks (%s)", response_status); |
728 | 0 | } |
729 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HEARTBEAT | ZABBIX_T_ACTIVE)) { |
730 | 0 | proto_item_set_text(ti, |
731 | 0 | "Zabbix Server response for active proxy heartbeat for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name), response_status); |
732 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
733 | 0 | "Zabbix Server response for active proxy heartbeat for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(proxy_name), response_status); |
734 | 0 | } |
735 | 0 | } |
736 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SENDER)) { |
737 | 0 | sender_name = zabbix_info->host_name; |
738 | 0 | proto_item_set_text(ti, |
739 | 0 | "Zabbix Server/proxy response for sender data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(sender_name), response_status); |
740 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
741 | 0 | "Zabbix Server/proxy response for sender data for \"%s\" (%s)", ZABBIX_NAME_OR_UNKNOWN(sender_name), response_status); |
742 | 0 | } |
743 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND)) { |
744 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SYSINFO)) { |
745 | 0 | proto_item_set_text(ti, "Zabbix System information response"); |
746 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix System information response"); |
747 | 0 | } |
748 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_QUEUEINFO)) { |
749 | 0 | proto_item_set_text(ti, "Zabbix Queue information response"); |
750 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Queue information response"); |
751 | 0 | } |
752 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HISTORYPUSH)) { |
753 | 0 | proto_item_set_text(ti, "Zabbix History push response"); |
754 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix History push response"); |
755 | 0 | } |
756 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_ITEMTEST)) { |
757 | 0 | proto_item_set_text(ti, "Zabbix Item test response"); |
758 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Item test response"); |
759 | 0 | } |
760 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_MEDIATEST)) { |
761 | 0 | proto_item_set_text(ti, "Zabbix Media test response"); |
762 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Media test response"); |
763 | 0 | } |
764 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_REPORTTEST)) { |
765 | 0 | proto_item_set_text(ti, "Zabbix Report test response"); |
766 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Report test response"); |
767 | 0 | } |
768 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_EXPRESSIONEVAL)) { |
769 | 0 | proto_item_set_text(ti, "Zabbix Expression evaluation response"); |
770 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Expression evaluation response"); |
771 | 0 | } |
772 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SCRIPTEXEC)) { |
773 | 0 | proto_item_set_text(ti, "Zabbix Script execution response"); |
774 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Script execution response"); |
775 | 0 | } |
776 | 0 | } |
777 | 0 | } |
778 | 0 | else if (version && data_array) { |
779 | | /* This looks like passive agent response in Zabbix 7.0+ */ |
780 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_AGENT | ZABBIX_T_PASSIVE); |
781 | 0 | proto_item_set_text(ti, "Zabbix Agent response for passive checks"); |
782 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Agent response for passive checks"); |
783 | 0 | } |
784 | 0 | else if (data_object || data_array || tokens->size == 0) { |
785 | | /* No other match above, let's assume this is server sending incremental |
786 | | * configuration to a proxy |
787 | | */ |
788 | 0 | ADD_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_CONFIG); |
789 | 0 | if ((data_object && (data_object->size == 0)) || tokens->size == 0) { |
790 | | /* Empty data object or the whole JSON is empty */ |
791 | 0 | oper_response |= ZABBIX_RESPONSE_NOCHANGE; |
792 | 0 | } |
793 | 0 | else if (data_array) { |
794 | | /* This was not a "full_sync" but data array exists */ |
795 | 0 | oper_response |= ZABBIX_RESPONSE_INCREMENTAL; |
796 | 0 | } |
797 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PASSIVE)) { |
798 | | /* There is no proxy name anywhere to use */ |
799 | 0 | proto_item_set_text(ti, "Zabbix Passive proxy config"); |
800 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Passive proxy config"); |
801 | 0 | } |
802 | 0 | else { |
803 | 0 | proxy_name = zabbix_info->host_name; |
804 | 0 | proto_item_set_text(ti, |
805 | 0 | "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name)); |
806 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
807 | 0 | "Zabbix Server response for proxy config for \"%s\"", ZABBIX_NAME_OR_UNKNOWN(proxy_name)); |
808 | 0 | } |
809 | 0 | } |
810 | | /* Final guesses to provide customized packet information */ |
811 | 0 | else if (session && version) { |
812 | | /* Config or data responses from passive proxy */ |
813 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_CONFIG | ZABBIX_T_PASSIVE)) { |
814 | 0 | proto_item_set_text(ti, "Zabbix Passive proxy response for config push"); |
815 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Passive proxy response for config push"); |
816 | 0 | } |
817 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_DATA | ZABBIX_T_PASSIVE)) { |
818 | 0 | proto_item_set_text(ti, "Zabbix Passive proxy data response"); |
819 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Passive proxy data response"); |
820 | 0 | } |
821 | 0 | } |
822 | 0 | else if (version) { |
823 | | /* Tasks response from passive proxy */ |
824 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY | ZABBIX_T_TASKS | ZABBIX_T_PASSIVE)) { |
825 | 0 | proto_item_set_text(ti, "Zabbix Passive proxy response for tasks request"); |
826 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Zabbix Passive proxy response for tasks request"); |
827 | 0 | } |
828 | 0 | } |
829 | | |
830 | | |
831 | | /* Add all relevant fields to the tree */ |
832 | |
|
833 | 0 | show_agent_outputs: |
834 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT)) { |
835 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_agent, NULL, 0, 0, true); |
836 | 0 | proto_item_set_text(temp_ti, "This is an agent connection"); |
837 | 0 | proto_item_set_generated(temp_ti); |
838 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA)) { |
839 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_agent_data, NULL, 0, 0, true); |
840 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE)) { |
841 | | /* Set as generated, not seen in data */ |
842 | 0 | proto_item_set_generated(temp_ti); |
843 | 0 | } |
844 | 0 | } |
845 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG)) { |
846 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_agent_config, NULL, 0, 0, true); |
847 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE)) { |
848 | | /* Set as generated, not seen in data */ |
849 | 0 | proto_item_set_generated(temp_ti); |
850 | 0 | } |
851 | 0 | } |
852 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HEARTBEAT)) { |
853 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_agent_hb, NULL, 0, 0, true); |
854 | 0 | } |
855 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PASSIVE)) { |
856 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_agent_passive, NULL, 0, 0, true); |
857 | 0 | proto_item_set_text(temp_ti, "Agent is in passive mode"); |
858 | 0 | proto_item_set_generated(temp_ti); |
859 | 0 | } |
860 | 0 | if (is_redirection) { |
861 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_agent_redirection, NULL, 0, 0, true); |
862 | 0 | } |
863 | 0 | } |
864 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY)) { |
865 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy, NULL, 0, 0, true); |
866 | 0 | proto_item_set_text(temp_ti, "This is a proxy connection"); |
867 | 0 | proto_item_set_generated(temp_ti); |
868 | 0 | } |
869 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SENDER)) { |
870 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_sender, NULL, 0, 0, true); |
871 | 0 | proto_item_set_text(temp_ti, "This is a sender connection"); |
872 | 0 | proto_item_set_generated(temp_ti); |
873 | 0 | } |
874 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND)) { |
875 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend, NULL, 0, 0, true); |
876 | 0 | proto_item_set_text(temp_ti, "This is a frontend connection"); |
877 | 0 | proto_item_set_generated(temp_ti); |
878 | 0 | } |
879 | 0 | if (oper_response & ZABBIX_RESPONSE_SUCCESS) { |
880 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_success, NULL, 0, 0, true); |
881 | 0 | } |
882 | 0 | else if (oper_response & ZABBIX_RESPONSE_FAILED) { |
883 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_failed, NULL, 0, 0, true); |
884 | 0 | } |
885 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_AGENT)) { |
886 | 0 | if (agent_name) { |
887 | 0 | temp_ti = proto_tree_add_string(zabbix_tree, hf_zabbix_agent_name, NULL, 0, 0, agent_name); |
888 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE)) { |
889 | | /* agent_name was populated from the conversation */ |
890 | 0 | proto_item_set_generated(temp_ti); |
891 | 0 | proto_item_append_text(temp_ti, " (from the request)"); |
892 | 0 | } |
893 | 0 | } |
894 | 0 | if (agent_variant) { |
895 | 0 | proto_tree_add_int64(zabbix_tree, hf_zabbix_agent_variant, NULL, 0, 0, agent_variant); |
896 | 0 | } |
897 | 0 | if (agent_hb_freq) { |
898 | 0 | proto_tree_add_int(zabbix_tree, hf_zabbix_agent_hb_freq, NULL, 0, 0, agent_hb_freq); |
899 | 0 | } |
900 | 0 | if (agent_hostmetadata) { |
901 | 0 | proto_tree_add_string(zabbix_tree, hf_zabbix_agent_hostmetadata, NULL, 0, 0, agent_hostmetadata); |
902 | 0 | } |
903 | 0 | if (agent_hostinterface) { |
904 | 0 | proto_tree_add_string(zabbix_tree, hf_zabbix_agent_hostinterface, NULL, 0, 0, agent_hostinterface); |
905 | 0 | } |
906 | 0 | if (agent_listenip) { |
907 | 0 | if (strstr(agent_listenip, ":") != NULL) { |
908 | 0 | ws_in6_addr addr6; |
909 | 0 | if (ws_inet_pton6(agent_listenip, &addr6)) { |
910 | 0 | proto_tree_add_ipv6(zabbix_tree, hf_zabbix_agent_listenipv6, NULL, 0, 0, &addr6); |
911 | 0 | } |
912 | 0 | } |
913 | 0 | else { |
914 | 0 | ws_in4_addr addr4; |
915 | 0 | if (ws_inet_pton4(agent_listenip, &addr4)) { |
916 | 0 | proto_tree_add_ipv4(zabbix_tree, hf_zabbix_agent_listenipv4, NULL, 0, 0, addr4); |
917 | 0 | } |
918 | 0 | } |
919 | 0 | } |
920 | 0 | if (agent_listenport) { |
921 | 0 | proto_tree_add_uint(zabbix_tree, hf_zabbix_agent_listenport, NULL, 0, 0, agent_listenport); |
922 | 0 | } |
923 | 0 | if (commands_array) { |
924 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_agent_commands, NULL, 0, 0, true); |
925 | 0 | } |
926 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_METRICS)) { |
927 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_metrics, NULL, 0, 0, true); |
928 | 0 | } |
929 | 0 | } |
930 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_PROXY)) { |
931 | 0 | if (proxy_name) { |
932 | 0 | temp_ti = proto_tree_add_string(zabbix_tree, hf_zabbix_proxy_name, NULL, 0, 0, proxy_name); |
933 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE)) { |
934 | | /* proxy_name was populated from the conversation */ |
935 | 0 | proto_item_set_generated(temp_ti); |
936 | 0 | proto_item_append_text(temp_ti, " (from the request)"); |
937 | 0 | } |
938 | 0 | } |
939 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_DATA)) { |
940 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy_data, NULL, 0, 0, true); |
941 | 0 | } |
942 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_CONFIG)) { |
943 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy_config, NULL, 0, 0, true); |
944 | 0 | if (oper_response & ZABBIX_RESPONSE_FULLSYNC) { |
945 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy_fullsync, NULL, 0, 0, true); |
946 | 0 | } |
947 | 0 | else if (oper_response & ZABBIX_RESPONSE_INCREMENTAL) { |
948 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy_incr_config, NULL, 0, 0, true); |
949 | 0 | } |
950 | 0 | else if (oper_response & ZABBIX_RESPONSE_NOCHANGE) { |
951 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy_no_config_change, NULL, 0, 0, true); |
952 | 0 | } |
953 | 0 | } |
954 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_TASKS)) { |
955 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy_tasks, NULL, 0, 0, true); |
956 | 0 | } |
957 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HEARTBEAT)) { |
958 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_proxy_hb, NULL, 0, 0, true); |
959 | 0 | } |
960 | 0 | } |
961 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_FRONTEND)) { |
962 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SYSINFO)) { |
963 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_sysinfo, NULL, 0, 0, true); |
964 | 0 | } |
965 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_QUEUEINFO)) { |
966 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_queueinfo, NULL, 0, 0, true); |
967 | 0 | } |
968 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_HISTORYPUSH)) { |
969 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_historypush, NULL, 0, 0, true); |
970 | 0 | } |
971 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_ITEMTEST)) { |
972 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_itemtest, NULL, 0, 0, true); |
973 | 0 | } |
974 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_MEDIATEST)) { |
975 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_mediatest, NULL, 0, 0, true); |
976 | 0 | } |
977 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_REPORTTEST)) { |
978 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_reporttest, NULL, 0, 0, true); |
979 | 0 | } |
980 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_EXPRESSIONEVAL)) { |
981 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_expressioneval, NULL, 0, 0, true); |
982 | 0 | } |
983 | 0 | else if (IS_ZABBIX_T_FLAGS(ZABBIX_T_SCRIPTEXEC)) { |
984 | 0 | proto_tree_add_boolean(zabbix_tree, hf_zabbix_frontend_scriptexec, NULL, 0, 0, true); |
985 | 0 | } |
986 | 0 | } |
987 | 0 | else if (sender_name) { |
988 | 0 | temp_ti = proto_tree_add_string(zabbix_tree, hf_zabbix_sender_name, NULL, 0, 0, sender_name); |
989 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_RESPONSE)) { |
990 | | /* sender_name was populated from the conversation */ |
991 | 0 | proto_item_set_generated(temp_ti); |
992 | 0 | proto_item_append_text(temp_ti, " (from the request)"); |
993 | 0 | } |
994 | 0 | } |
995 | 0 | if (version) { |
996 | 0 | proto_tree_add_string(zabbix_tree, hf_zabbix_version, NULL, 0, 0, version); |
997 | 0 | } |
998 | 0 | if (config_revision > -1) { |
999 | 0 | proto_tree_add_int64(zabbix_tree, hf_zabbix_config_revision, NULL, 0, 0, config_revision); |
1000 | 0 | } |
1001 | 0 | if (hostmap_revision > -1) { |
1002 | 0 | proto_tree_add_int64(zabbix_tree, hf_zabbix_hostmap_revision, NULL, 0, 0, hostmap_revision); |
1003 | 0 | } |
1004 | 0 | if (session) { |
1005 | 0 | proto_tree_add_string(zabbix_tree, hf_zabbix_session, NULL, 0, 0, session); |
1006 | 0 | } |
1007 | | /* Show also the full JSON, or pre-7.0 passive agent request/response (or error message). |
1008 | | * Note that ZABBIX_ZBX_NOTSUPPORTED does not include the \0 that is in the |
1009 | | * protocol specification! Therefore +1/-1's are present |
1010 | | */ |
1011 | 0 | if (passive_agent_data_str && |
1012 | 0 | strlen(passive_agent_data_str) >= strlen(ZABBIX_ZBX_NOTSUPPORTED) && |
1013 | 0 | strncmp(passive_agent_data_str, ZABBIX_ZBX_NOTSUPPORTED, strlen(ZABBIX_ZBX_NOTSUPPORTED)) == 0) { |
1014 | | /* Pre-7.0 passive agent error, first ZBX_NOTSUPPORTED\0 and then the error message */ |
1015 | 0 | proto_tree_add_item(zabbix_tree, hf_zabbix_data, |
1016 | 0 | next_tvb, 0, (int)strlen(ZABBIX_ZBX_NOTSUPPORTED)+1, ENC_UTF_8); |
1017 | 0 | proto_tree_add_item(zabbix_tree, hf_zabbix_error, |
1018 | 0 | next_tvb, (int)strlen(ZABBIX_ZBX_NOTSUPPORTED)+1, (int)datalen-(int)strlen(ZABBIX_ZBX_NOTSUPPORTED)-1, ENC_UTF_8); |
1019 | 0 | } else { |
1020 | | /* JSON or pre-7.0 passive agent without error */ |
1021 | 0 | proto_tree_add_item(zabbix_tree, hf_zabbix_data, next_tvb, 0, (int)datalen, ENC_UTF_8); |
1022 | 0 | } |
1023 | |
|
1024 | 0 | final_outputs: |
1025 | | |
1026 | | /* These are common for all cases, too large or not */ |
1027 | | |
1028 | | /* Check the ZABBIX_T_REQUEST flag (and not CONV_IS_ZABBIX_REQUEST macro) because |
1029 | | * heartbeats are not marked as requests */ |
1030 | 0 | if (IS_ZABBIX_T_FLAGS(ZABBIX_T_REQUEST)) { |
1031 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_request, NULL, 0, 0, true); |
1032 | 0 | proto_item_set_text(temp_ti, "This is Zabbix request"); |
1033 | 0 | } else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info, pinfo)) { |
1034 | 0 | temp_ti = proto_tree_add_boolean(zabbix_tree, hf_zabbix_response, NULL, 0, 0, true); |
1035 | 0 | proto_item_set_text(temp_ti, "This is Zabbix response"); |
1036 | 0 | if (!nstime_is_unset(&zabbix_info->req_timestamp)) { |
1037 | 0 | nstime_t delta; |
1038 | 0 | nstime_delta(&delta, &pinfo->abs_ts, &zabbix_info->req_timestamp); |
1039 | 0 | pi = proto_tree_add_time(zabbix_tree, hf_zabbix_time, next_tvb, 0, 0, &delta); |
1040 | 0 | proto_item_set_generated(pi); |
1041 | 0 | } |
1042 | 0 | } |
1043 | | |
1044 | | /* Add length to the Zabbix tree text */ |
1045 | 0 | proto_item_append_text(ti, ", Len=%u", (unsigned)length); |
1046 | | /* Add/set Info column texts */ |
1047 | 0 | const char *info_text = col_get_text(pinfo->cinfo, COL_INFO); |
1048 | 0 | if (!info_text || !strlen(info_text)) { |
1049 | | /* Info column is still empty, set the default text */ |
1050 | 0 | if (CONV_IS_ZABBIX_REQUEST(zabbix_info, pinfo)) { |
1051 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Zabbix Protocol request, Flags=0x%02x", flags); |
1052 | 0 | } else if (CONV_IS_ZABBIX_RESPONSE(zabbix_info, pinfo)) { |
1053 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Zabbix Protocol response, Flags=0x%02x", flags); |
1054 | 0 | } else { |
1055 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Zabbix Protocol, Flags=0x%02x", flags); |
1056 | 0 | } |
1057 | 0 | } |
1058 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Len=%u (", (unsigned)length); |
1059 | 0 | col_append_ports(pinfo->cinfo, COL_INFO, PT_TCP, pinfo->srcport, pinfo->destport); |
1060 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ")"); |
1061 | |
|
1062 | 0 | return tvb_reported_length(tvb); |
1063 | 0 | } |
1064 | | |
1065 | | /* Determine PDU length of Zabbix protocol */ |
1066 | | static unsigned |
1067 | | get_zabbix_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
1068 | 0 | { |
1069 | 0 | uint8_t flags; |
1070 | 0 | uint64_t length; |
1071 | |
|
1072 | 0 | flags = tvb_get_uint8(tvb, offset+4); |
1073 | 0 | if (flags & ZABBIX_FLAG_LARGEPACKET) { |
1074 | | /* 8-byte length field |
1075 | | * Note that ZABBIX_HDR_MIN_LEN check (in dissect_zabbix()) is still enough |
1076 | | * due to the header structure (there are reserved bytes) |
1077 | | */ |
1078 | 0 | length = tvb_get_uint64(tvb, offset+5, ENC_LITTLE_ENDIAN) + ZABBIX_HDR_MAX_LEN; |
1079 | 0 | } else { |
1080 | | /* 4-byte length */ |
1081 | 0 | length = tvb_get_uint32(tvb, offset+5, ENC_LITTLE_ENDIAN) + ZABBIX_HDR_MIN_LEN; |
1082 | 0 | } |
1083 | 0 | return (unsigned)length; |
1084 | 0 | } |
1085 | | |
1086 | | /* The main dissecting routine */ |
1087 | | static int |
1088 | | dissect_zabbix(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
1089 | 6 | { |
1090 | 6 | uint8_t flags; |
1091 | | |
1092 | 6 | if (tvb_captured_length(tvb) < ZABBIX_HDR_MIN_LEN) { |
1093 | | /* Not enough data */ |
1094 | 4 | return 0; |
1095 | 4 | } |
1096 | 2 | if (tvb_memeql(tvb, 0, ZABBIX_HDR_SIGNATURE, 4)) { |
1097 | | /* Encrypted or not Zabbix at all */ |
1098 | 2 | return 0; |
1099 | 2 | } |
1100 | 0 | flags = tvb_get_uint8(tvb, 4); |
1101 | 0 | if (!(flags & ZABBIX_FLAG_ZABBIX_COMMUNICATIONS)) { |
1102 | 0 | return 0; |
1103 | 0 | } |
1104 | | /* This is unencrypted Zabbix protocol, continue with dissecting it */ |
1105 | 0 | tcp_dissect_pdus(tvb, pinfo, tree, zabbix_desegment, ZABBIX_HDR_MIN_LEN, |
1106 | 0 | get_zabbix_pdu_len, dissect_zabbix_pdu, data); |
1107 | 0 | return tvb_reported_length(tvb); |
1108 | 0 | } |
1109 | | |
1110 | | /* Register the protocol with Wireshark */ |
1111 | | |
1112 | | void |
1113 | | proto_register_zabbix(void) |
1114 | 14 | { |
1115 | 14 | static hf_register_info hf[] = { |
1116 | 14 | { &hf_zabbix_header, |
1117 | 14 | { "Header", "zabbix.header", |
1118 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1119 | 14 | NULL, HFILL } |
1120 | 14 | }, |
1121 | 14 | { &hf_zabbix_flags, |
1122 | 14 | { "Flags", "zabbix.flags", |
1123 | 14 | FT_UINT8, BASE_HEX, NULL, 0, |
1124 | 14 | NULL, HFILL } |
1125 | 14 | }, |
1126 | 14 | { &hf_zabbix_flag_zabbix_communications, |
1127 | 14 | { "Zabbix communications protocol", "zabbix.flags.zabbix", |
1128 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), ZABBIX_FLAG_ZABBIX_COMMUNICATIONS, |
1129 | 14 | NULL, HFILL } |
1130 | 14 | }, |
1131 | 14 | { &hf_zabbix_flag_compressed, |
1132 | 14 | { "Compressed", "zabbix.flags.compressed", |
1133 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), ZABBIX_FLAG_COMPRESSED, |
1134 | 14 | NULL, HFILL } |
1135 | 14 | }, |
1136 | 14 | { &hf_zabbix_flag_largepacket, |
1137 | 14 | { "Large packet", "zabbix.flags.large_packet", |
1138 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), ZABBIX_FLAG_LARGEPACKET, |
1139 | 14 | NULL, HFILL } |
1140 | 14 | }, |
1141 | 14 | { &hf_zabbix_flag_reserved, |
1142 | 14 | { "Reserved bits", "zabbix.flags.reserved", |
1143 | 14 | FT_UINT8, BASE_DEC, NULL, ZABBIX_FLAG_RESERVED, |
1144 | 14 | NULL, HFILL } |
1145 | 14 | }, |
1146 | 14 | { &hf_zabbix_length, |
1147 | 14 | { "Length", "zabbix.len", |
1148 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
1149 | 14 | NULL, HFILL } |
1150 | 14 | }, |
1151 | 14 | { &hf_zabbix_reserved, |
1152 | 14 | { "Reserved", "zabbix.reserved", |
1153 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
1154 | 14 | NULL, HFILL } |
1155 | 14 | }, |
1156 | 14 | { &hf_zabbix_uncompressed_length, |
1157 | 14 | { "Uncompressed length", "zabbix.uncompressed_len", |
1158 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
1159 | 14 | NULL, HFILL } |
1160 | 14 | }, |
1161 | 14 | { &hf_zabbix_large_length, |
1162 | 14 | { "Large length", "zabbix.large.len", |
1163 | 14 | FT_UINT64, BASE_DEC, NULL, 0, |
1164 | 14 | NULL, HFILL } |
1165 | 14 | }, |
1166 | 14 | { &hf_zabbix_large_reserved, |
1167 | 14 | { "Large reserved", "zabbix.large.reserved", |
1168 | 14 | FT_UINT64, BASE_DEC, NULL, 0, |
1169 | 14 | NULL, HFILL } |
1170 | 14 | }, |
1171 | 14 | { &hf_zabbix_large_uncompressed_length, |
1172 | 14 | { "Large uncompressed length", "zabbix.large.uncompressed_len", |
1173 | 14 | FT_UINT64, BASE_DEC, NULL, 0, |
1174 | 14 | NULL, HFILL } |
1175 | 14 | }, |
1176 | 14 | { &hf_zabbix_data, |
1177 | 14 | { "Data", "zabbix.data", |
1178 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1179 | 14 | NULL, HFILL } |
1180 | 14 | }, |
1181 | 14 | { &hf_zabbix_error, |
1182 | 14 | { "Error message", "zabbix.error", |
1183 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1184 | 14 | NULL, HFILL } |
1185 | 14 | }, |
1186 | 14 | { &hf_zabbix_time, |
1187 | 14 | { "Response time", "zabbix.time", |
1188 | 14 | FT_RELATIVE_TIME, BASE_NONE, NULL, 0, |
1189 | 14 | NULL, HFILL } |
1190 | 14 | }, |
1191 | 14 | { &hf_zabbix_request, |
1192 | 14 | { "Zabbix protocol request", "zabbix.request", |
1193 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
1194 | 14 | NULL, HFILL } |
1195 | 14 | }, |
1196 | 14 | { &hf_zabbix_response, |
1197 | 14 | { "Zabbix protocol response", "zabbix.response", |
1198 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
1199 | 14 | NULL, HFILL } |
1200 | 14 | }, |
1201 | 14 | { &hf_zabbix_success, |
1202 | 14 | { "Success", "zabbix.success", |
1203 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1204 | 14 | NULL, HFILL } |
1205 | 14 | }, |
1206 | 14 | { &hf_zabbix_failed, |
1207 | 14 | { "Failed", "zabbix.failed", |
1208 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1209 | 14 | NULL, HFILL } |
1210 | 14 | }, |
1211 | 14 | { &hf_zabbix_agent, |
1212 | 14 | { "Zabbix agent connection", "zabbix.agent", |
1213 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
1214 | 14 | NULL, HFILL } |
1215 | 14 | }, |
1216 | 14 | { &hf_zabbix_agent_commands, |
1217 | 14 | { "Zabbix agent commands", "zabbix.agent.commands", |
1218 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1219 | 14 | NULL, HFILL } |
1220 | 14 | }, |
1221 | 14 | { &hf_zabbix_agent_config, |
1222 | 14 | { "Zabbix agent config", "zabbix.agent.config", |
1223 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1224 | 14 | NULL, HFILL } |
1225 | 14 | }, |
1226 | 14 | { &hf_zabbix_agent_data, |
1227 | 14 | { "Zabbix agent data", "zabbix.agent.data", |
1228 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1229 | 14 | NULL, HFILL } |
1230 | 14 | }, |
1231 | 14 | { &hf_zabbix_agent_redirection, |
1232 | 14 | { "Agent redirection", "zabbix.agent.redirection", |
1233 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1234 | 14 | NULL, HFILL } |
1235 | 14 | }, |
1236 | 14 | { &hf_zabbix_agent_passive, |
1237 | 14 | { "Passive agent", "zabbix.agent.passive", |
1238 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1239 | 14 | NULL, HFILL } |
1240 | 14 | }, |
1241 | 14 | { &hf_zabbix_agent_name, |
1242 | 14 | { "Agent name", "zabbix.agent.name", |
1243 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1244 | 14 | NULL, HFILL } |
1245 | 14 | }, |
1246 | 14 | { &hf_zabbix_agent_hb, |
1247 | 14 | { "Agent heartbeat", "zabbix.agent.heartbeat", |
1248 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1249 | 14 | NULL, HFILL } |
1250 | 14 | }, |
1251 | 14 | { &hf_zabbix_agent_hb_freq, |
1252 | 14 | { "Agent heartbeat frequency", "zabbix.agent.heartbeat_freq", |
1253 | 14 | FT_INT32, BASE_DEC, NULL, 0, |
1254 | 14 | NULL, HFILL } |
1255 | 14 | }, |
1256 | 14 | { &hf_zabbix_agent_hostmetadata, |
1257 | 14 | { "Agent host metadata", "zabbix.agent.host_metadata", |
1258 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1259 | 14 | NULL, HFILL } |
1260 | 14 | }, |
1261 | 14 | { &hf_zabbix_agent_hostinterface, |
1262 | 14 | { "Agent host interface", "zabbix.agent.host_interface", |
1263 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1264 | 14 | NULL, HFILL } |
1265 | 14 | }, |
1266 | 14 | { &hf_zabbix_agent_listenipv4, |
1267 | 14 | { "Agent listen IPv4", "zabbix.agent.listen_ipv4", |
1268 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
1269 | 14 | NULL, HFILL } |
1270 | 14 | }, |
1271 | 14 | { &hf_zabbix_agent_listenipv6, |
1272 | 14 | { "Agent listen IPv6", "zabbix.agent.listen_ipv6", |
1273 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
1274 | 14 | NULL, HFILL } |
1275 | 14 | }, |
1276 | 14 | { &hf_zabbix_agent_listenport, |
1277 | 14 | { "Agent listen port", "zabbix.agent.listen_port", |
1278 | 14 | FT_UINT16, BASE_PT_TCP, NULL, 0, |
1279 | 14 | NULL, HFILL } |
1280 | 14 | }, |
1281 | 14 | { &hf_zabbix_agent_variant, |
1282 | 14 | { "Agent variant", "zabbix.agent.variant", |
1283 | 14 | FT_INT64, BASE_DEC, NULL, 0, |
1284 | 14 | NULL, HFILL } |
1285 | 14 | }, |
1286 | 14 | { &hf_zabbix_proxy, |
1287 | 14 | { "Proxy connection", "zabbix.proxy", |
1288 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1289 | 14 | NULL, HFILL } |
1290 | 14 | }, |
1291 | 14 | { &hf_zabbix_proxy_name, |
1292 | 14 | { "Proxy name", "zabbix.proxy.name", |
1293 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1294 | 14 | NULL, HFILL } |
1295 | 14 | }, |
1296 | 14 | { &hf_zabbix_proxy_hb, |
1297 | 14 | { "Proxy heartbeat", "zabbix.proxy.heartbeat", |
1298 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1299 | 14 | NULL, HFILL } |
1300 | 14 | }, |
1301 | 14 | { &hf_zabbix_proxy_data, |
1302 | 14 | { "Proxy data", "zabbix.proxy.data", |
1303 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1304 | 14 | NULL, HFILL } |
1305 | 14 | }, |
1306 | 14 | { &hf_zabbix_proxy_config, |
1307 | 14 | { "Proxy config", "zabbix.proxy.config", |
1308 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1309 | 14 | NULL, HFILL } |
1310 | 14 | }, |
1311 | 14 | { &hf_zabbix_proxy_fullsync, |
1312 | 14 | { "Proxy config full sync", "zabbix.proxy.full_sync", |
1313 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1314 | 14 | NULL, HFILL } |
1315 | 14 | }, |
1316 | 14 | { &hf_zabbix_proxy_incr_config, |
1317 | 14 | { "Proxy incremental config", "zabbix.proxy.incremental_config", |
1318 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1319 | 14 | NULL, HFILL } |
1320 | 14 | }, |
1321 | 14 | { &hf_zabbix_proxy_no_config_change, |
1322 | 14 | { "Proxy no config changes", "zabbix.proxy.no_config_changes", |
1323 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1324 | 14 | NULL, HFILL } |
1325 | 14 | }, |
1326 | 14 | { &hf_zabbix_proxy_tasks, |
1327 | 14 | { "Proxy tasks", "zabbix.proxy.tasks", |
1328 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1329 | 14 | NULL, HFILL } |
1330 | 14 | }, |
1331 | 14 | { &hf_zabbix_sender, |
1332 | 14 | { "Sender connection", "zabbix.sender", |
1333 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1334 | 14 | NULL, HFILL } |
1335 | 14 | }, |
1336 | 14 | { &hf_zabbix_sender_name, |
1337 | 14 | { "Sender name", "zabbix.sender.name", |
1338 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1339 | 14 | NULL, HFILL } |
1340 | 14 | }, |
1341 | 14 | { &hf_zabbix_version, |
1342 | 14 | { "Version", "zabbix.version", |
1343 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1344 | 14 | NULL, HFILL } |
1345 | 14 | }, |
1346 | 14 | { &hf_zabbix_session, |
1347 | 14 | { "Session", "zabbix.session", |
1348 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
1349 | 14 | NULL, HFILL } |
1350 | 14 | }, |
1351 | 14 | { &hf_zabbix_config_revision, |
1352 | 14 | { "Config revision", "zabbix.config_revision", |
1353 | 14 | FT_INT64, BASE_DEC, NULL, 0, |
1354 | 14 | NULL, HFILL } |
1355 | 14 | }, |
1356 | 14 | { &hf_zabbix_hostmap_revision, |
1357 | 14 | { "Hostmap revision", "zabbix.hostmap_revision", |
1358 | 14 | FT_INT64, BASE_DEC, NULL, 0, |
1359 | 14 | NULL, HFILL } |
1360 | 14 | }, |
1361 | 14 | { &hf_zabbix_metrics, |
1362 | 14 | { "Server/proxy internal metrics", "zabbix.stats", |
1363 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1364 | 14 | NULL, HFILL } |
1365 | 14 | }, |
1366 | 14 | { &hf_zabbix_frontend, |
1367 | 14 | { "Zabbix frontend", "zabbix.frontend", |
1368 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1369 | 14 | NULL, HFILL } |
1370 | 14 | }, |
1371 | 14 | { &hf_zabbix_frontend_sysinfo, |
1372 | 14 | { "System information", "zabbix.frontend.sysinfo", |
1373 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1374 | 14 | NULL, HFILL } |
1375 | 14 | }, |
1376 | 14 | { &hf_zabbix_frontend_queueinfo, |
1377 | 14 | { "Queue information", "zabbix.frontend.queueinfo", |
1378 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1379 | 14 | NULL, HFILL } |
1380 | 14 | }, |
1381 | 14 | { &hf_zabbix_frontend_historypush, |
1382 | 14 | { "History push", "zabbix.frontend.historypush", |
1383 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1384 | 14 | NULL, HFILL } |
1385 | 14 | }, |
1386 | 14 | { &hf_zabbix_frontend_itemtest, |
1387 | 14 | { "Item test", "zabbix.frontend.itemtest", |
1388 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1389 | 14 | NULL, HFILL } |
1390 | 14 | }, |
1391 | 14 | { &hf_zabbix_frontend_mediatest, |
1392 | 14 | { "Media test", "zabbix.frontend.mediatest", |
1393 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1394 | 14 | NULL, HFILL } |
1395 | 14 | }, |
1396 | 14 | { &hf_zabbix_frontend_reporttest, |
1397 | 14 | { "Report test", "zabbix.frontend.reporttest", |
1398 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1399 | 14 | NULL, HFILL } |
1400 | 14 | }, |
1401 | 14 | { &hf_zabbix_frontend_expressioneval, |
1402 | 14 | { "Expression evaluation", "zabbix.frontend.expressioneval", |
1403 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1404 | 14 | NULL, HFILL } |
1405 | 14 | }, |
1406 | 14 | { &hf_zabbix_frontend_scriptexec, |
1407 | 14 | { "Script execution", "zabbix.frontend.scriptexec", |
1408 | 14 | FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0, |
1409 | 14 | NULL, HFILL } |
1410 | 14 | }, |
1411 | 14 | }; |
1412 | | |
1413 | 14 | static ei_register_info ei[] = { |
1414 | 14 | { |
1415 | 14 | &ei_zabbix_packet_too_large, |
1416 | 14 | { "zabbix.packet_too_large", PI_UNDECODED, PI_WARN, |
1417 | 14 | "Packet is too large for detailed dissection", EXPFILL } |
1418 | 14 | }, |
1419 | 14 | { |
1420 | 14 | &ei_zabbix_json_error, |
1421 | 14 | { "zabbix.json_error", PI_PROTOCOL, PI_ERROR, |
1422 | 14 | "Cannot parse JSON", EXPFILL } |
1423 | 14 | }, |
1424 | 14 | }; |
1425 | | |
1426 | | /* Setup protocol subtree array */ |
1427 | 14 | static int *ett[] = { |
1428 | 14 | &ett_zabbix, |
1429 | 14 | &ett_zabbix_flags, |
1430 | 14 | }; |
1431 | | |
1432 | 14 | module_t *zabbix_module; |
1433 | 14 | expert_module_t *expert_zabbix; |
1434 | | |
1435 | | /* Register the protocol name and description */ |
1436 | 14 | proto_zabbix = proto_register_protocol("Zabbix Protocol", "Zabbix", "zabbix"); |
1437 | | |
1438 | | /* Required function calls to register the header fields and subtrees used */ |
1439 | 14 | proto_register_field_array(proto_zabbix, hf, array_length(hf)); |
1440 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
1441 | | |
1442 | 14 | zabbix_module = prefs_register_protocol(proto_zabbix, NULL); |
1443 | | |
1444 | 14 | prefs_register_bool_preference(zabbix_module, "desegment", |
1445 | 14 | "Reassemble Zabbix messages spanning multiple TCP segments", |
1446 | 14 | "Whether the Zabbix protocol dissector should reassemble messages spanning multiple TCP segments." |
1447 | 14 | " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", |
1448 | 14 | &zabbix_desegment); |
1449 | | |
1450 | 14 | zabbix_handle = register_dissector("zabbix", dissect_zabbix, proto_zabbix); |
1451 | | |
1452 | 14 | expert_zabbix = expert_register_protocol(proto_zabbix); |
1453 | 14 | expert_register_field_array(expert_zabbix, ei, array_length(ei)); |
1454 | 14 | } |
1455 | | |
1456 | | void |
1457 | | proto_reg_handoff_zabbix(void) |
1458 | 14 | { |
1459 | 14 | dissector_add_uint_range_with_preference("tcp.port", ZABBIX_TCP_PORTS, zabbix_handle); |
1460 | 14 | zabbix_port_range = prefs_get_range_value("Zabbix", "tcp.port"); |
1461 | 14 | dissector_add_uint_range("tls.port", zabbix_port_range, zabbix_handle); |
1462 | 14 | } |