/src/wireshark/epan/dissectors/packet-enrp.c
Line | Count | Source |
1 | | /* packet-enrp.c |
2 | | * Routines for Endpoint Handlespace Redundancy Protocol (ENRP) |
3 | | * It is hopefully (needs testing) compliant to |
4 | | * RFC 5353 |
5 | | * RFC 5354 |
6 | | * RFC 5356 |
7 | | * https://tools.ietf.org/html/draft-dreibholz-rserpool-enrp-takeover-21 |
8 | | * |
9 | | * Copyright 2008-2021 Thomas Dreibholz <dreibh [AT] iem.uni-due.de> |
10 | | * Copyright 2004-2007 Michael Tüxen <tuexen [AT] fh-muenster.de> |
11 | | * |
12 | | * Wireshark - Network traffic analyzer |
13 | | * By Gerald Combs <gerald@wireshark.org> |
14 | | * Copyright 1998 Gerald Combs |
15 | | * |
16 | | * Copied from README.developer |
17 | | * |
18 | | * SPDX-License-Identifier: GPL-2.0-or-later |
19 | | */ |
20 | | |
21 | | #include "config.h" |
22 | | |
23 | | #include <epan/packet.h> |
24 | | #include <epan/to_str.h> |
25 | | #include <epan/stat_tap_ui.h> |
26 | | #include <epan/expert.h> |
27 | | #include <epan/proto_data.h> |
28 | | #include <epan/tfs.h> |
29 | | #include <epan/unit_strings.h> |
30 | | |
31 | | #include <wsutil/str_util.h> |
32 | | #include <wsutil/ws_roundup.h> |
33 | | #include <wsutil/array.h> |
34 | | |
35 | | #include "packet-asap+enrp-common.h" |
36 | | #include "packet-sctp.h" |
37 | | |
38 | | void proto_register_enrp(void); |
39 | | void proto_reg_handoff_enrp(void); |
40 | | |
41 | | static dissector_handle_t enrp_handle; |
42 | | |
43 | | /* Initialize the protocol and registered fields */ |
44 | | static int enrp_tap; |
45 | | static int proto_enrp; |
46 | | static int hf_cause_code; |
47 | | static int hf_cause_length; |
48 | | static int hf_cause_info; |
49 | | static int hf_cause_padding; |
50 | | static int hf_message_type; |
51 | | static int hf_message_flags; |
52 | | static int hf_message_length; |
53 | | static int hf_message_value; |
54 | | static int hf_parameter_type; |
55 | | static int hf_parameter_length; |
56 | | static int hf_parameter_value; |
57 | | static int hf_parameter_padding; |
58 | | static int hf_parameter_ipv4_address; |
59 | | static int hf_parameter_ipv6_address; |
60 | | static int hf_dccp_port; |
61 | | static int hf_dccp_reserved; |
62 | | static int hf_dccp_service_code; |
63 | | static int hf_sctp_port; |
64 | | static int hf_transport_use; |
65 | | static int hf_tcp_port; |
66 | | static int hf_udp_port; |
67 | | static int hf_udp_reserved; |
68 | | static int hf_udp_lite_port; |
69 | | static int hf_udp_lite_reserved; |
70 | | static int hf_policy_type; |
71 | | static int hf_policy_value; |
72 | | static int hf_policy_weight; |
73 | | static int hf_policy_priority; |
74 | | static int hf_policy_load; |
75 | | static int hf_policy_degradation; |
76 | | static int hf_policy_loaddpf; |
77 | | static int hf_policy_weightdpf; |
78 | | static int hf_policy_distance; |
79 | | static int hf_pool_handle; |
80 | | static int hf_pe_pe_identifier; |
81 | | static int hf_home_enrp_id; |
82 | | static int hf_reg_life; |
83 | | static int hf_server_identifier; |
84 | | static int hf_cookie; |
85 | | static int hf_pe_identifier; |
86 | | static int hf_pe_checksum; |
87 | | static int hf_sender_servers_id; |
88 | | static int hf_receiver_servers_id; |
89 | | static int hf_target_servers_id; |
90 | | static int hf_update_action; |
91 | | static int hf_pmu_reserved; |
92 | | static int hf_reply_required_bit; |
93 | | static int hf_own_children_only_bit; |
94 | | static int hf_more_to_send_bit; |
95 | | static int hf_reject_bit; |
96 | | static int hf_tos_bit; |
97 | | |
98 | | /* Initialize the subtree pointers */ |
99 | | static int ett_enrp; |
100 | | static int ett_enrp_parameter; |
101 | | static int ett_enrp_cause; |
102 | | static int ett_enrp_flags; |
103 | | |
104 | | static uint64_t enrp_total_msgs; |
105 | | static uint64_t enrp_total_bytes; |
106 | | |
107 | | static expert_field ei_enrp_max_recursion_depth_reached; |
108 | | static expert_field ei_enrp_invalid_length; |
109 | | |
110 | | static void |
111 | | dissect_parameters(tvbuff_t *, packet_info *, proto_tree *); |
112 | | static void |
113 | | dissect_parameter(tvbuff_t *, packet_info *, proto_tree *); |
114 | | static void |
115 | | dissect_enrp_main(tvbuff_t *, packet_info *, proto_tree *); |
116 | | static int |
117 | | dissect_enrp(tvbuff_t *, packet_info *, proto_tree *, void*); |
118 | | |
119 | 14 | #define ENRP_UDP_PORT 9901 |
120 | 14 | #define ENRP_SCTP_PORT 9901 |
121 | 58 | #define ENRP_MAX_RECURSION_DEPTH 10 |
122 | | |
123 | | typedef struct _enrp_tap_rec_t { |
124 | | uint8_t type; |
125 | | uint16_t size; |
126 | | const char* type_string; |
127 | | } enrp_tap_rec_t; |
128 | | |
129 | | /* Dissectors for error causes. This is common for ASAP and ENRP. */ |
130 | | |
131 | | static void |
132 | | dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item) |
133 | 7 | { |
134 | 7 | uint16_t code, length, cause_info_length; |
135 | | |
136 | 7 | code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET); |
137 | 7 | length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET); |
138 | 7 | cause_info_length = length - CAUSE_HEADER_LENGTH; |
139 | 7 | if (cause_info_length > 0) |
140 | 7 | proto_tree_add_item(cause_tree, hf_cause_info, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, ENC_NA); |
141 | 7 | proto_item_append_text(cause_item, " (code %u and %u byte%s information)", code, cause_info_length, plurality(cause_info_length, "", "s")); |
142 | 7 | } |
143 | | |
144 | | static void |
145 | | // NOLINTNEXTLINE(misc-no-recursion) |
146 | | dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
147 | 11 | { |
148 | 11 | uint16_t code, length, padding_length; |
149 | 11 | proto_item *cause_item; |
150 | 11 | proto_tree *cause_tree; |
151 | 11 | tvbuff_t *parameter_tvb, *message_tvb; |
152 | | |
153 | 11 | code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET); |
154 | 11 | length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET); |
155 | 11 | padding_length = tvb_captured_length(cause_tvb) - length; |
156 | | |
157 | 11 | cause_tree = proto_tree_add_subtree(parameter_tree, cause_tvb, CAUSE_HEADER_OFFSET, -1, |
158 | 11 | ett_enrp_cause, &cause_item, val_to_str_const(code, cause_code_values, "Unknown error cause")); |
159 | | |
160 | 11 | proto_tree_add_item(cause_tree, hf_cause_code, cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH, ENC_BIG_ENDIAN); |
161 | 11 | proto_tree_add_item(cause_tree, hf_cause_length, cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH, ENC_BIG_ENDIAN); |
162 | | |
163 | 11 | switch(code) { |
164 | 0 | case UNRECOGNIZED_PARAMETER_CAUSE_CODE: |
165 | 0 | parameter_tvb = tvb_new_subset_remaining(cause_tvb, CAUSE_INFO_OFFSET); |
166 | 0 | dissect_parameter(parameter_tvb, pinfo, cause_tree); |
167 | 0 | break; |
168 | 2 | case UNRECONGNIZED_MESSAGE_CAUSE_CODE: |
169 | 2 | message_tvb = tvb_new_subset_remaining(cause_tvb, CAUSE_INFO_OFFSET); |
170 | 2 | dissect_enrp_main(message_tvb, pinfo, cause_tree); |
171 | 2 | break; |
172 | 1 | case INVALID_VALUES: |
173 | 1 | parameter_tvb = tvb_new_subset_remaining(cause_tvb, CAUSE_INFO_OFFSET); |
174 | 1 | dissect_parameter(parameter_tvb, pinfo, cause_tree); |
175 | 1 | break; |
176 | 0 | case NON_UNIQUE_PE_IDENTIFIER: |
177 | 0 | break; |
178 | 0 | case POOLING_POLICY_INCONSISTENT_CAUSE_CODE: |
179 | 0 | parameter_tvb = tvb_new_subset_remaining(cause_tvb, CAUSE_INFO_OFFSET); |
180 | 0 | dissect_parameter(parameter_tvb, pinfo, cause_tree); |
181 | 0 | break; |
182 | 1 | case LACK_OF_RESOURCES_CAUSE_CODE: |
183 | 1 | break; |
184 | 0 | case INCONSISTENT_TRANSPORT_TYPE_CAUSE_CODE: |
185 | 0 | parameter_tvb = tvb_new_subset_remaining(cause_tvb, CAUSE_INFO_OFFSET); |
186 | 0 | dissect_parameter(parameter_tvb, pinfo, cause_tree); |
187 | 0 | break; |
188 | 0 | case INCONSISTENT_DATA_CONTROL_CONFIGURATION_CAUSE_CODE: |
189 | 0 | break; |
190 | 0 | case UNKNOWN_POOL_HANDLE: |
191 | 0 | break; |
192 | 0 | case REJECTION_DUE_TO_SECURITY_CAUSE_CODE: |
193 | 0 | break; |
194 | 7 | default: |
195 | 7 | dissect_unknown_cause(cause_tvb, cause_tree, cause_item); |
196 | 7 | break; |
197 | 11 | } |
198 | 7 | if (padding_length > 0) |
199 | 7 | proto_tree_add_item(cause_tree, hf_cause_padding, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length, ENC_NA); |
200 | 7 | } |
201 | | |
202 | | static void |
203 | | // NOLINTNEXTLINE(misc-no-recursion) |
204 | | dissect_error_causes(tvbuff_t *error_causes_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
205 | 6 | { |
206 | 6 | uint16_t length, total_length; |
207 | 6 | int offset; |
208 | 6 | tvbuff_t *error_cause_tvb; |
209 | | |
210 | 6 | offset = 0; |
211 | 17 | while(tvb_reported_length_remaining(error_causes_tvb, offset) > 0) { |
212 | 12 | length = tvb_get_ntohs(error_causes_tvb, offset + CAUSE_LENGTH_OFFSET); |
213 | 12 | if (length < 4) { |
214 | 1 | proto_tree_add_expert_format(parameter_tree, pinfo, &ei_enrp_invalid_length, |
215 | 1 | error_causes_tvb, offset + CAUSE_LENGTH_OFFSET, 2, |
216 | 1 | "Error cause length must be at least 4 bytes"); |
217 | 1 | return; |
218 | 1 | } |
219 | 11 | total_length = WS_ROUNDUP_4(length); |
220 | 11 | error_cause_tvb = tvb_new_subset_length(error_causes_tvb, offset, total_length); |
221 | 11 | dissect_error_cause(error_cause_tvb, pinfo, parameter_tree); |
222 | 11 | offset += total_length; |
223 | 11 | } |
224 | 6 | } |
225 | | |
226 | | /* Dissectors for parameters. This is common for ASAP and ENRP. */ |
227 | | |
228 | | static void |
229 | | dissect_ipv4_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item) |
230 | 1 | { |
231 | 1 | proto_tree_add_item(parameter_tree, hf_parameter_ipv4_address, parameter_tvb, IPV4_ADDRESS_OFFSET, IPV4_ADDRESS_LENGTH, ENC_BIG_ENDIAN); |
232 | 1 | proto_item_append_text(parameter_item, " (%s)", tvb_ip_to_str(pinfo->pool, parameter_tvb, IPV4_ADDRESS_OFFSET)); |
233 | 1 | } |
234 | | |
235 | | static void |
236 | | dissect_ipv6_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item) |
237 | 2 | { |
238 | 2 | proto_tree_add_item(parameter_tree, hf_parameter_ipv6_address, parameter_tvb, IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH, ENC_NA); |
239 | 2 | proto_item_append_text(parameter_item, " (%s)", tvb_ip6_to_str(pinfo->pool, parameter_tvb, IPV6_ADDRESS_OFFSET)); |
240 | 2 | } |
241 | | |
242 | | static void |
243 | | // NOLINTNEXTLINE(misc-no-recursion) |
244 | | dissect_dccp_transport_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
245 | 0 | { |
246 | 0 | tvbuff_t *parameters_tvb; |
247 | |
|
248 | 0 | proto_tree_add_item(parameter_tree, hf_dccp_port, parameter_tvb, DCCP_PORT_OFFSET, DCCP_PORT_LENGTH, ENC_BIG_ENDIAN); |
249 | 0 | proto_tree_add_item(parameter_tree, hf_dccp_reserved, parameter_tvb, DCCP_RESERVED_OFFSET, DCCP_RESERVED_LENGTH, ENC_BIG_ENDIAN); |
250 | 0 | proto_tree_add_item(parameter_tree, hf_dccp_service_code, parameter_tvb, DCCP_SERVICE_CODE_OFFSET, DCCP_SERVICE_CODE_LENGTH, ENC_BIG_ENDIAN); |
251 | |
|
252 | 0 | parameters_tvb = tvb_new_subset_remaining(parameter_tvb, DCCP_ADDRESS_OFFSET); |
253 | 0 | dissect_parameters(parameters_tvb, pinfo, parameter_tree); |
254 | 0 | } |
255 | | |
256 | | static void |
257 | | // NOLINTNEXTLINE(misc-no-recursion) |
258 | | dissect_sctp_transport_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
259 | 0 | { |
260 | 0 | tvbuff_t *parameters_tvb; |
261 | |
|
262 | 0 | proto_tree_add_item(parameter_tree, hf_sctp_port, parameter_tvb, SCTP_PORT_OFFSET, SCTP_PORT_LENGTH, ENC_BIG_ENDIAN); |
263 | 0 | proto_tree_add_item(parameter_tree, hf_transport_use, parameter_tvb, SCTP_TRANSPORT_USE_OFFSET, SCTP_TRANSPORT_USE_LENGTH, ENC_BIG_ENDIAN); |
264 | |
|
265 | 0 | parameters_tvb = tvb_new_subset_remaining(parameter_tvb, SCTP_ADDRESS_OFFSET); |
266 | 0 | dissect_parameters(parameters_tvb, pinfo, parameter_tree); |
267 | 0 | } |
268 | | |
269 | | static void |
270 | | // NOLINTNEXTLINE(misc-no-recursion) |
271 | | dissect_tcp_transport_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
272 | 0 | { |
273 | 0 | tvbuff_t *parameters_tvb; |
274 | |
|
275 | 0 | proto_tree_add_item(parameter_tree, hf_tcp_port, parameter_tvb, TCP_PORT_OFFSET, TCP_PORT_LENGTH, ENC_BIG_ENDIAN); |
276 | 0 | proto_tree_add_item(parameter_tree, hf_transport_use, parameter_tvb, TCP_TRANSPORT_USE_OFFSET, TCP_TRANSPORT_USE_LENGTH, ENC_BIG_ENDIAN); |
277 | |
|
278 | 0 | parameters_tvb = tvb_new_subset_remaining(parameter_tvb, TCP_ADDRESS_OFFSET); |
279 | 0 | dissect_parameters(parameters_tvb, pinfo, parameter_tree); |
280 | 0 | } |
281 | | |
282 | | static void |
283 | | // NOLINTNEXTLINE(misc-no-recursion) |
284 | | dissect_udp_transport_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
285 | 7 | { |
286 | 7 | tvbuff_t *parameters_tvb; |
287 | | |
288 | 7 | proto_tree_add_item(parameter_tree, hf_udp_port, parameter_tvb, UDP_PORT_OFFSET, UDP_PORT_LENGTH, ENC_BIG_ENDIAN); |
289 | 7 | proto_tree_add_item(parameter_tree, hf_udp_reserved, parameter_tvb, UDP_RESERVED_OFFSET, UDP_RESERVED_LENGTH, ENC_BIG_ENDIAN); |
290 | | |
291 | 7 | parameters_tvb = tvb_new_subset_remaining(parameter_tvb, UDP_ADDRESS_OFFSET); |
292 | 7 | dissect_parameters(parameters_tvb, pinfo, parameter_tree); |
293 | 7 | } |
294 | | |
295 | | static void |
296 | | // NOLINTNEXTLINE(misc-no-recursion) |
297 | | dissect_udp_lite_transport_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
298 | 0 | { |
299 | 0 | tvbuff_t *parameters_tvb; |
300 | |
|
301 | 0 | proto_tree_add_item(parameter_tree, hf_udp_lite_port, parameter_tvb, UDP_LITE_PORT_OFFSET, UDP_LITE_PORT_LENGTH, ENC_BIG_ENDIAN); |
302 | 0 | proto_tree_add_item(parameter_tree, hf_udp_lite_reserved, parameter_tvb, UDP_LITE_RESERVED_OFFSET, UDP_LITE_RESERVED_LENGTH, ENC_BIG_ENDIAN); |
303 | |
|
304 | 0 | parameters_tvb = tvb_new_subset_remaining(parameter_tvb, UDP_LITE_ADDRESS_OFFSET); |
305 | 0 | dissect_parameters(parameters_tvb, pinfo, parameter_tree); |
306 | 0 | } |
307 | | |
308 | | static void |
309 | | dissect_pool_member_selection_policy_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree) |
310 | 0 | { |
311 | 0 | uint32_t type; |
312 | 0 | unsigned length; |
313 | |
|
314 | 0 | proto_tree_add_item(parameter_tree, hf_policy_type, parameter_tvb, POLICY_TYPE_OFFSET, POLICY_TYPE_LENGTH, ENC_BIG_ENDIAN); |
315 | 0 | type = tvb_get_ntohl(parameter_tvb, POLICY_TYPE_OFFSET); |
316 | 0 | switch (type) { |
317 | 0 | case RANDOM_POLICY: |
318 | 0 | case ROUND_ROBIN_POLICY: |
319 | 0 | break; |
320 | 0 | case WEIGHTED_RANDOM_POLICY: |
321 | 0 | case WEIGHTED_ROUND_ROBIN_POLICY: |
322 | 0 | proto_tree_add_item(parameter_tree, hf_policy_weight, parameter_tvb, POLICY_WEIGHT_OFFSET, POLICY_WEIGHT_LENGTH, ENC_BIG_ENDIAN); |
323 | 0 | break; |
324 | 0 | case PRIORITY_POLICY: |
325 | 0 | proto_tree_add_item(parameter_tree, hf_policy_priority, parameter_tvb, POLICY_PRIORITY_OFFSET, POLICY_PRIORITY_LENGTH, ENC_BIG_ENDIAN); |
326 | 0 | break; |
327 | 0 | case LEAST_USED_POLICY: |
328 | 0 | case RANDOMIZED_LEAST_USED_POLICY: |
329 | 0 | proto_tree_add_double_format_value(parameter_tree, hf_policy_load, parameter_tvb, POLICY_LOAD_OFFSET, POLICY_LOAD_LENGTH, |
330 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_LOAD_OFFSET) / (double)0xffffffff, "%1.2f%%", |
331 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_LOAD_OFFSET) / (double)0xffffffff); |
332 | 0 | break; |
333 | 0 | case LEAST_USED_WITH_DEG_POLICY: |
334 | 0 | case PRIORITY_LEAST_USED_POLICY: |
335 | 0 | proto_tree_add_double_format_value(parameter_tree, hf_policy_load, parameter_tvb, POLICY_LOAD_OFFSET, POLICY_LOAD_LENGTH, |
336 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_LOAD_OFFSET) / (double)0xffffffff, "%1.2f%%", |
337 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_LOAD_OFFSET) / (double)0xffffffff); |
338 | 0 | proto_tree_add_double_format_value(parameter_tree, hf_policy_degradation, parameter_tvb, POLICY_DEGRADATION_OFFSET, POLICY_DEGRADATION_LENGTH, |
339 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_DEGRADATION_OFFSET) / (double)0xffffffff, "%1.2f%%", |
340 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_DEGRADATION_OFFSET) / (double)0xffffffff); |
341 | 0 | break; |
342 | 0 | case LEAST_USED_DPF_POLICY: |
343 | 0 | proto_tree_add_double_format_value(parameter_tree, hf_policy_load, parameter_tvb, POLICY_LOAD_OFFSET, POLICY_LOAD_LENGTH, |
344 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_LOAD_OFFSET) / (double)0xffffffff, "%1.2f%%", |
345 | 0 | 100.0 * tvb_get_ntohl(parameter_tvb, POLICY_LOAD_OFFSET) / (double)0xffffffff); |
346 | 0 | proto_tree_add_double_format_value(parameter_tree, hf_policy_loaddpf, parameter_tvb, POLICY_LUDPF_LOADDPF_OFFSET, POLICY_LUDPF_LOADDPF_LENGTH, |
347 | 0 | tvb_get_ntohl(parameter_tvb, POLICY_LUDPF_LOADDPF_OFFSET) / (double)0xffffffff, "%1.5f", |
348 | 0 | tvb_get_ntohl(parameter_tvb, POLICY_LUDPF_LOADDPF_OFFSET) / (double)0xffffffff); |
349 | 0 | proto_tree_add_item(parameter_tree, hf_policy_distance, parameter_tvb, POLICY_LUDPF_DISTANCE_OFFSET, POLICY_LUDPF_DISTANCE_LENGTH, ENC_BIG_ENDIAN); |
350 | 0 | break; |
351 | 0 | case WEIGHTED_RANDOM_DPF_POLICY: |
352 | 0 | proto_tree_add_item(parameter_tree, hf_policy_weight, parameter_tvb, POLICY_WEIGHT_OFFSET, POLICY_WEIGHT_LENGTH, ENC_BIG_ENDIAN); |
353 | 0 | proto_tree_add_double_format_value(parameter_tree, hf_policy_weightdpf, parameter_tvb, POLICY_WRANDDPF_WEIGHTDPF_OFFSET, POLICY_WRANDDPF_WEIGHTDPF_LENGTH, |
354 | 0 | tvb_get_ntohl(parameter_tvb, POLICY_WRANDDPF_WEIGHTDPF_OFFSET) / (double)0xffffffff, "%1.5f", |
355 | 0 | tvb_get_ntohl(parameter_tvb, POLICY_WRANDDPF_WEIGHTDPF_OFFSET) / (double)0xffffffff); |
356 | 0 | proto_tree_add_item(parameter_tree, hf_policy_distance, parameter_tvb, POLICY_WRANDDPF_DISTANCE_OFFSET, POLICY_WRANDDPF_DISTANCE_LENGTH, ENC_BIG_ENDIAN); |
357 | 0 | break; |
358 | 0 | default: |
359 | 0 | length = tvb_reported_length(parameter_tvb) - POLICY_VALUE_OFFSET; |
360 | 0 | if (length > 0) { |
361 | 0 | proto_tree_add_item(parameter_tree, hf_policy_value, parameter_tvb, POLICY_VALUE_OFFSET, length, ENC_NA); |
362 | 0 | } |
363 | 0 | break; |
364 | 0 | } |
365 | 0 | } |
366 | | |
367 | | static void |
368 | | dissect_pool_handle_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
369 | 0 | { |
370 | 0 | uint16_t handle_length; |
371 | 0 | proto_item* pi; |
372 | |
|
373 | 0 | handle_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH; |
374 | 0 | pi = proto_tree_add_item(parameter_tree, hf_pool_handle, parameter_tvb, POOL_HANDLE_OFFSET, handle_length, ENC_NA); |
375 | |
|
376 | 0 | proto_item_append_text(pi, " (%s)", |
377 | 0 | tvb_format_text(pinfo->pool, parameter_tvb, POOL_HANDLE_OFFSET, handle_length) ); |
378 | 0 | } |
379 | | |
380 | | static void |
381 | | // NOLINTNEXTLINE(misc-no-recursion) |
382 | | dissect_pool_element_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
383 | 0 | { |
384 | 0 | tvbuff_t* parameters_tvb; |
385 | |
|
386 | 0 | proto_tree_add_item(parameter_tree, hf_pe_pe_identifier, parameter_tvb, PE_PE_IDENTIFIER_OFFSET, PE_PE_IDENTIFIER_LENGTH, ENC_BIG_ENDIAN); |
387 | 0 | proto_tree_add_item(parameter_tree, hf_home_enrp_id, parameter_tvb, HOME_ENRP_INDENTIFIER_OFFSET, HOME_ENRP_INDENTIFIER_LENGTH, ENC_BIG_ENDIAN); |
388 | 0 | proto_tree_add_item(parameter_tree, hf_reg_life, parameter_tvb, REGISTRATION_LIFE_OFFSET, REGISTRATION_LIFE_LENGTH, ENC_BIG_ENDIAN); |
389 | |
|
390 | 0 | parameters_tvb = tvb_new_subset_remaining(parameter_tvb, USER_TRANSPORT_PARAMETER_OFFSET); |
391 | 0 | dissect_parameters(parameters_tvb, pinfo, parameter_tree); |
392 | 0 | } |
393 | | |
394 | | static void |
395 | | // NOLINTNEXTLINE(misc-no-recursion) |
396 | | dissect_server_information_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
397 | 0 | { |
398 | 0 | tvbuff_t *parameters_tvb; |
399 | |
|
400 | 0 | proto_tree_add_item(parameter_tree, hf_server_identifier, parameter_tvb, SERVER_ID_OFFSET, SERVER_ID_LENGTH, ENC_BIG_ENDIAN); |
401 | |
|
402 | 0 | parameters_tvb = tvb_new_subset_remaining(parameter_tvb, SERVER_TRANSPORT_OFFSET); |
403 | 0 | dissect_parameters(parameters_tvb, pinfo, parameter_tree); |
404 | 0 | } |
405 | | |
406 | | static void |
407 | | // NOLINTNEXTLINE(misc-no-recursion) |
408 | | dissect_operation_error_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree) |
409 | 6 | { |
410 | 6 | tvbuff_t *error_causes_tvb; |
411 | | |
412 | 6 | error_causes_tvb = tvb_new_subset_remaining(parameter_tvb, ERROR_CAUSES_OFFSET); |
413 | 6 | dissect_error_causes(error_causes_tvb, pinfo, parameter_tree); |
414 | 6 | } |
415 | | |
416 | | static void |
417 | | dissect_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item) |
418 | 0 | { |
419 | 0 | uint16_t cookie_length; |
420 | |
|
421 | 0 | cookie_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH; |
422 | 0 | if (cookie_length > 0) |
423 | 0 | proto_tree_add_item(parameter_tree, hf_cookie, parameter_tvb, COOKIE_OFFSET, cookie_length, ENC_NA); |
424 | 0 | proto_item_append_text(parameter_item, " (%u byte%s)", cookie_length, plurality(cookie_length, "", "s")); |
425 | 0 | } |
426 | | |
427 | | static void |
428 | | dissect_pe_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item) |
429 | 0 | { |
430 | 0 | proto_tree_add_item(parameter_tree, hf_pe_identifier, parameter_tvb, PE_IDENTIFIER_OFFSET, PE_IDENTIFIER_LENGTH, ENC_BIG_ENDIAN); |
431 | 0 | proto_item_append_text(parameter_item, " (0x%x)", tvb_get_ntohl(parameter_tvb, PE_IDENTIFIER_OFFSET)); |
432 | 0 | } |
433 | | |
434 | | static void |
435 | | dissect_pe_checksum_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item) |
436 | 0 | { |
437 | 0 | proto_tree_add_item(parameter_tree, hf_pe_checksum, parameter_tvb, PE_CHECKSUM_OFFSET, PE_CHECKSUM_LENGTH, ENC_BIG_ENDIAN); |
438 | 0 | proto_item_append_text(parameter_item, " (0x%x)", tvb_get_ntohs(parameter_tvb, PE_CHECKSUM_OFFSET)); |
439 | 0 | } |
440 | | |
441 | | static void |
442 | | dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item) |
443 | 13 | { |
444 | 13 | uint16_t type, parameter_value_length; |
445 | | |
446 | 13 | type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET); |
447 | 13 | parameter_value_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH; |
448 | | |
449 | 13 | if (parameter_value_length > 0) |
450 | 11 | proto_tree_add_item(parameter_tree, hf_parameter_value, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, ENC_NA); |
451 | | |
452 | 13 | proto_item_append_text(parameter_item, " (type %u and %u byte%s value)", type, parameter_value_length, plurality(parameter_value_length, "", "s")); |
453 | 13 | } |
454 | | |
455 | | static void |
456 | | // NOLINTNEXTLINE(misc-no-recursion) |
457 | | dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *enrp_tree) |
458 | 29 | { |
459 | 29 | uint16_t type, length, padding_length; |
460 | 29 | proto_tree *parameter_item; |
461 | 29 | proto_tree *parameter_tree; |
462 | | |
463 | 29 | unsigned recursion_depth = p_get_proto_depth(pinfo, proto_enrp); |
464 | | |
465 | 29 | if (recursion_depth > ENRP_MAX_RECURSION_DEPTH) { |
466 | 0 | proto_tree_add_expert(enrp_tree, pinfo, &ei_enrp_max_recursion_depth_reached, |
467 | 0 | parameter_tvb, 0, 0); |
468 | 0 | return; |
469 | 0 | } |
470 | 29 | p_set_proto_depth(pinfo, proto_enrp, recursion_depth + 1); |
471 | | |
472 | | /* extract tag and length from the parameter */ |
473 | 29 | type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET); |
474 | 29 | length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET); |
475 | 29 | padding_length = tvb_captured_length(parameter_tvb) - length; |
476 | | |
477 | | /* create proto_tree stuff */ |
478 | 29 | parameter_tree = proto_tree_add_subtree(enrp_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, -1, |
479 | 29 | ett_enrp_parameter, ¶meter_item, val_to_str_const(type, parameter_type_values, "Unknown Parameter")); |
480 | | |
481 | | /* add tag and length to the enrp tree */ |
482 | 29 | proto_tree_add_item(parameter_tree, hf_parameter_type, parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH, ENC_BIG_ENDIAN); |
483 | 29 | proto_tree_add_item(parameter_tree, hf_parameter_length, parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH, ENC_BIG_ENDIAN); |
484 | | |
485 | 29 | switch(type) { |
486 | 1 | case IPV4_ADDRESS_PARAMETER_TYPE: |
487 | 1 | dissect_ipv4_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item); |
488 | 1 | break; |
489 | 2 | case IPV6_ADDRESS_PARAMETER_TYPE: |
490 | 2 | dissect_ipv6_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item); |
491 | 2 | break; |
492 | 0 | case DCCP_TRANSPORT_PARAMETER_TYPE: |
493 | 0 | dissect_dccp_transport_parameter(parameter_tvb, pinfo, parameter_tree); |
494 | 0 | break; |
495 | 0 | case SCTP_TRANSPORT_PARAMETER_TYPE: |
496 | 0 | dissect_sctp_transport_parameter(parameter_tvb, pinfo, parameter_tree); |
497 | 0 | break; |
498 | 0 | case TCP_TRANSPORT_PARAMETER_TYPE: |
499 | 0 | dissect_tcp_transport_parameter(parameter_tvb, pinfo, parameter_tree); |
500 | 0 | break; |
501 | 7 | case UDP_TRANSPORT_PARAMETER_TYPE: |
502 | 7 | dissect_udp_transport_parameter(parameter_tvb, pinfo, parameter_tree); |
503 | 7 | break; |
504 | 0 | case UDP_LITE_TRANSPORT_PARAMETER_TYPE: |
505 | 0 | dissect_udp_lite_transport_parameter(parameter_tvb, pinfo, parameter_tree); |
506 | 0 | break; |
507 | 0 | case POOL_MEMBER_SELECTION_POLICY_PARAMETER_TYPE: |
508 | 0 | dissect_pool_member_selection_policy_parameter(parameter_tvb, parameter_tree); |
509 | 0 | break; |
510 | 0 | case POOL_HANDLE_PARAMETER_TYPE: |
511 | 0 | dissect_pool_handle_parameter(parameter_tvb, pinfo, parameter_tree); |
512 | 0 | break; |
513 | 0 | case POOL_ELEMENT_PARAMETER_TYPE: |
514 | 0 | dissect_pool_element_parameter(parameter_tvb, pinfo, parameter_tree); |
515 | 0 | break; |
516 | 0 | case SERVER_INFORMATION_PARAMETER_TYPE: |
517 | 0 | dissect_server_information_parameter(parameter_tvb, pinfo, parameter_tree); |
518 | 0 | break; |
519 | 6 | case OPERATION_ERROR_PARAMETER_TYPE: |
520 | 6 | dissect_operation_error_parameter(parameter_tvb, pinfo, parameter_tree); |
521 | 6 | break; |
522 | 0 | case COOKIE_PARAMETER_TYPE: |
523 | 0 | dissect_cookie_parameter(parameter_tvb, parameter_tree, parameter_item); |
524 | 0 | break; |
525 | 0 | case PE_IDENTIFIER_PARAMETER_TYPE: |
526 | 0 | dissect_pe_identifier_parameter(parameter_tvb, parameter_tree, parameter_item); |
527 | 0 | break; |
528 | 0 | case PE_CHECKSUM_PARAMETER_TYPE: |
529 | 0 | dissect_pe_checksum_parameter(parameter_tvb, parameter_tree, parameter_item); |
530 | 0 | break; |
531 | 13 | default: |
532 | 13 | dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item); |
533 | 13 | break; |
534 | 29 | }; |
535 | | |
536 | 10 | if (padding_length > 0) |
537 | 6 | proto_tree_add_item(parameter_tree, hf_parameter_padding, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length, ENC_NA); |
538 | | |
539 | 10 | p_set_proto_depth(pinfo, proto_enrp, recursion_depth); |
540 | 10 | } |
541 | | |
542 | | static void |
543 | | // NOLINTNEXTLINE(misc-no-recursion) |
544 | | dissect_parameters(tvbuff_t *parameters_tvb, packet_info *pinfo, proto_tree *tree) |
545 | 28 | { |
546 | 28 | int offset, length, total_length, remaining_length; |
547 | 28 | tvbuff_t *parameter_tvb; |
548 | | |
549 | 28 | offset = 0; |
550 | 57 | while((remaining_length = tvb_reported_length_remaining(parameters_tvb, offset)) > 0) { |
551 | 33 | length = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_LENGTH_OFFSET); |
552 | 33 | if (length < 4) { |
553 | 4 | proto_tree_add_expert(tree, pinfo, &ei_enrp_invalid_length, |
554 | 4 | parameters_tvb, offset + PARAMETER_LENGTH_OFFSET, 2); |
555 | 4 | return; |
556 | 4 | } |
557 | 29 | total_length = WS_ROUNDUP_4(length); |
558 | 29 | if (remaining_length >= length) |
559 | 11 | total_length = MIN(total_length, remaining_length); |
560 | | /* create a tvb for the parameter including the padding bytes */ |
561 | 29 | parameter_tvb = tvb_new_subset_length(parameters_tvb, offset, total_length); |
562 | 29 | dissect_parameter(parameter_tvb, pinfo, tree); |
563 | | /* get rid of the handled parameter */ |
564 | 29 | offset += total_length; |
565 | 29 | } |
566 | 28 | } |
567 | | |
568 | | /* Dissectors for messages. This is specific to ENRP */ |
569 | | |
570 | 84 | #define SENDER_SERVERS_ID_LENGTH 4 |
571 | 57 | #define RECEIVER_SERVERS_ID_LENGTH 4 |
572 | | |
573 | 78 | #define SENDER_SERVERS_ID_OFFSET MESSAGE_VALUE_OFFSET |
574 | 51 | #define RECEIVER_SERVERS_ID_OFFSET (SENDER_SERVERS_ID_OFFSET + SENDER_SERVERS_ID_LENGTH) |
575 | 22 | #define MESSAGE_PARAMETERS_OFFSET (RECEIVER_SERVERS_ID_OFFSET + RECEIVER_SERVERS_ID_LENGTH) |
576 | | |
577 | 14 | #define REPLY_REQUIRED_BIT_MASK 0x01 |
578 | | |
579 | | static const true_false_string reply_required_bit_value = { |
580 | | "Reply required", |
581 | | "Reply not required" |
582 | | }; |
583 | | |
584 | | static void |
585 | | // NOLINTNEXTLINE(misc-no-recursion) |
586 | | dissect_enrp_presence_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *message_tree, proto_tree *flags_tree) |
587 | 4 | { |
588 | 4 | tvbuff_t *parameters_tvb; |
589 | | |
590 | 4 | proto_tree_add_item(flags_tree, hf_reply_required_bit, message_tvb, MESSAGE_FLAGS_OFFSET, MESSAGE_FLAGS_LENGTH, ENC_BIG_ENDIAN); |
591 | 4 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
592 | 4 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
593 | 4 | parameters_tvb = tvb_new_subset_remaining(message_tvb, MESSAGE_PARAMETERS_OFFSET); |
594 | 4 | dissect_parameters(parameters_tvb, pinfo, message_tree); |
595 | 4 | } |
596 | | |
597 | 14 | #define OWN_CHILDREN_ONLY_BIT_MASK 0x01 |
598 | | |
599 | | static const true_false_string own_children_only_bit_value = { |
600 | | "Only information for own PEs", |
601 | | "Information for all PEs" |
602 | | }; |
603 | | |
604 | | |
605 | | static void |
606 | | dissect_enrp_handle_table_request_message(tvbuff_t *message_tvb, proto_tree *message_tree, proto_tree *flags_tree) |
607 | 1 | { |
608 | | /* FIXME: ensure that the length is 12 bytes. */ |
609 | 1 | proto_tree_add_item(flags_tree, hf_own_children_only_bit, message_tvb, MESSAGE_FLAGS_OFFSET, MESSAGE_FLAGS_LENGTH, ENC_BIG_ENDIAN); |
610 | 1 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
611 | 1 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
612 | 1 | } |
613 | | |
614 | 14 | #define REJECT_BIT_MASK 0x01 |
615 | 14 | #define MORE_TO_SEND_BIT_MASK 0x02 |
616 | | |
617 | | static const true_false_string reject_bit_value = { |
618 | | "Rejected", |
619 | | "Accepted" |
620 | | }; |
621 | | |
622 | | static const true_false_string more_to_send_bit_value = { |
623 | | "More information available", |
624 | | "All information included" |
625 | | }; |
626 | | |
627 | | static void |
628 | | // NOLINTNEXTLINE(misc-no-recursion) |
629 | | dissect_enrp_handle_table_response_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *message_tree, proto_tree *flags_tree) |
630 | 0 | { |
631 | 0 | tvbuff_t *parameters_tvb; |
632 | |
|
633 | 0 | proto_tree_add_item(flags_tree, hf_more_to_send_bit, message_tvb, MESSAGE_FLAGS_OFFSET, MESSAGE_FLAGS_LENGTH, ENC_BIG_ENDIAN); |
634 | 0 | proto_tree_add_item(flags_tree, hf_reject_bit, message_tvb, MESSAGE_FLAGS_OFFSET, MESSAGE_FLAGS_LENGTH, ENC_BIG_ENDIAN); |
635 | 0 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
636 | 0 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
637 | 0 | parameters_tvb = tvb_new_subset_remaining(message_tvb, MESSAGE_PARAMETERS_OFFSET); |
638 | 0 | dissect_parameters(parameters_tvb, pinfo, message_tree); |
639 | 0 | } |
640 | | |
641 | 6 | #define UPDATE_ACTION_LENGTH 2 |
642 | 4 | #define PNU_RESERVED_LENGTH 2 |
643 | | |
644 | 6 | #define UPDATE_ACTION_OFFSET (MESSAGE_VALUE_OFFSET + SENDER_SERVERS_ID_LENGTH + RECEIVER_SERVERS_ID_LENGTH) |
645 | 4 | #define PNU_RESERVED_OFFSET (UPDATE_ACTION_OFFSET + UPDATE_ACTION_LENGTH) |
646 | 2 | #define PNU_MESSAGE_PARAMETERS_OFFSET (PNU_RESERVED_OFFSET + PNU_RESERVED_LENGTH) |
647 | | |
648 | | static const value_string update_action_values[] = { |
649 | | { 0, "Add pool element" }, |
650 | | { 1, "Delete pool element" }, |
651 | | { 0, NULL } }; |
652 | | |
653 | 14 | #define TOS_BIT_MASK 0x01 |
654 | | |
655 | | static const true_false_string tos_bit_value = { |
656 | | "Takeover suggested", |
657 | | "Takeover not suggested" |
658 | | }; |
659 | | |
660 | | static void |
661 | | // NOLINTNEXTLINE(misc-no-recursion) |
662 | | dissect_enrp_handle_update_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *message_tree, proto_tree *flags_tree) |
663 | 2 | { |
664 | 2 | tvbuff_t *parameters_tvb; |
665 | | |
666 | 2 | proto_tree_add_item(flags_tree, hf_tos_bit, message_tvb, MESSAGE_FLAGS_OFFSET, MESSAGE_FLAGS_LENGTH, ENC_BIG_ENDIAN); |
667 | 2 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
668 | 2 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
669 | 2 | proto_tree_add_item(message_tree, hf_update_action, message_tvb, UPDATE_ACTION_OFFSET, UPDATE_ACTION_LENGTH, ENC_BIG_ENDIAN); |
670 | 2 | proto_tree_add_item(message_tree, hf_pmu_reserved, message_tvb, PNU_RESERVED_OFFSET, PNU_RESERVED_LENGTH, ENC_BIG_ENDIAN); |
671 | 2 | parameters_tvb = tvb_new_subset_remaining(message_tvb, PNU_MESSAGE_PARAMETERS_OFFSET); |
672 | 2 | dissect_parameters(parameters_tvb, pinfo, message_tree); |
673 | 2 | } |
674 | | |
675 | | static void |
676 | | dissect_enrp_list_request_message(tvbuff_t *message_tvb, packet_info *pinfo _U_, proto_tree *message_tree, proto_tree *flags_tree _U_) |
677 | 0 | { |
678 | | /* FIXME: ensure that the length is 12 bytes. */ |
679 | 0 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
680 | 0 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
681 | 0 | } |
682 | | |
683 | | static void |
684 | | // NOLINTNEXTLINE(misc-no-recursion) |
685 | | dissect_enrp_list_response_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *message_tree, proto_tree *flags_tree) |
686 | 8 | { |
687 | 8 | tvbuff_t *parameters_tvb; |
688 | | |
689 | 8 | proto_tree_add_item(flags_tree, hf_reject_bit, message_tvb, MESSAGE_FLAGS_OFFSET, MESSAGE_FLAGS_LENGTH, ENC_BIG_ENDIAN); |
690 | 8 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
691 | 8 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
692 | 8 | parameters_tvb = tvb_new_subset_remaining(message_tvb, MESSAGE_PARAMETERS_OFFSET); |
693 | 8 | dissect_parameters(parameters_tvb, pinfo, message_tree); |
694 | 8 | } |
695 | | |
696 | 2 | #define TARGET_SERVERS_ID_LENGTH 4 |
697 | 2 | #define TARGET_SERVERS_ID_OFFSET (RECEIVER_SERVERS_ID_OFFSET + RECEIVER_SERVERS_ID_LENGTH) |
698 | | |
699 | | static void |
700 | | dissect_enrp_init_takeover_message(tvbuff_t *message_tvb, packet_info *pinfo _U_, proto_tree *message_tree, proto_tree *flags_tree _U_) |
701 | 1 | { |
702 | | /* FIXME: ensure that the length is 16 bytes. */ |
703 | 1 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
704 | 1 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
705 | 1 | proto_tree_add_item(message_tree, hf_target_servers_id, message_tvb, TARGET_SERVERS_ID_OFFSET, TARGET_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
706 | 1 | } |
707 | | |
708 | | static void |
709 | | dissect_enrp_init_takeover_ack_message(tvbuff_t *message_tvb, packet_info *pinfo _U_, proto_tree *message_tree, proto_tree *flags_tree _U_) |
710 | 1 | { |
711 | | /* FIXME: ensure that the length is 16 bytes. */ |
712 | 1 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
713 | 1 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
714 | 1 | proto_tree_add_item(message_tree, hf_target_servers_id, message_tvb, TARGET_SERVERS_ID_OFFSET, TARGET_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
715 | 1 | } |
716 | | |
717 | | static void |
718 | | dissect_enrp_init_takeover_server_message(tvbuff_t *message_tvb, packet_info *pinfo _U_, proto_tree *message_tree, proto_tree *flags_tree _U_) |
719 | 0 | { |
720 | | /* FIXME: ensure that the length is 16 bytes. */ |
721 | 0 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
722 | 0 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
723 | 0 | proto_tree_add_item(message_tree, hf_target_servers_id, message_tvb, TARGET_SERVERS_ID_OFFSET, TARGET_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
724 | 0 | } |
725 | | |
726 | | static void |
727 | | // NOLINTNEXTLINE(misc-no-recursion) |
728 | | dissect_enrp_error_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *message_tree, proto_tree *flags_tree _U_) |
729 | 10 | { |
730 | 10 | tvbuff_t *parameters_tvb; |
731 | | |
732 | 10 | proto_tree_add_item(message_tree, hf_sender_servers_id, message_tvb, SENDER_SERVERS_ID_OFFSET, SENDER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
733 | 10 | proto_tree_add_item(message_tree, hf_receiver_servers_id, message_tvb, RECEIVER_SERVERS_ID_OFFSET, RECEIVER_SERVERS_ID_LENGTH, ENC_BIG_ENDIAN); |
734 | 10 | parameters_tvb = tvb_new_subset_remaining(message_tvb, MESSAGE_PARAMETERS_OFFSET); |
735 | 10 | dissect_parameters(parameters_tvb, pinfo, message_tree); |
736 | 10 | } |
737 | | |
738 | | static void |
739 | | dissect_unknown_message(tvbuff_t *message_tvb, packet_info *pinfo _U_, proto_tree *message_tree, proto_tree *flags_tree _U_) |
740 | 2 | { |
741 | 2 | proto_tree_add_item(message_tree, hf_message_value, message_tvb, MESSAGE_VALUE_OFFSET, tvb_captured_length(message_tvb) - MESSAGE_HEADER_LENGTH, ENC_NA); |
742 | 2 | } |
743 | | |
744 | 4 | #define ENRP_PRESENCE_MESSAGE_TYPE 0x01 |
745 | 1 | #define ENRP_HANDLE_TABLE_REQUEST_MESSAGE_TYPE 0x02 |
746 | 0 | #define ENRP_HANDLE_TABLE_RESPONSE_MESSAGE_TYPE 0x03 |
747 | 2 | #define ENRP_HANDLE_UPDATE_MESSAGE_TYPE 0x04 |
748 | 0 | #define ENRP_LIST_REQUEST_MESSAGE_TYPE 0x05 |
749 | 8 | #define ENRP_LIST_RESPONSE_MESSAGE_TYPE 0x06 |
750 | 1 | #define ENRP_INIT_TAKEOVER_MESSAGE_TYPE 0x07 |
751 | 1 | #define ENRP_INIT_TAKEOVER_ACK_MESSAGE_TYPE 0x08 |
752 | 0 | #define ENRP_TAKEOVER_SERVER_MESSAGE_TYPE 0x09 |
753 | 10 | #define ENRP_ERROR_MESSAGE_TYPE 0x0a |
754 | | |
755 | | static const value_string message_type_values[] = { |
756 | | { ENRP_PRESENCE_MESSAGE_TYPE, "ENRP Presence" }, |
757 | | { ENRP_HANDLE_TABLE_REQUEST_MESSAGE_TYPE, "ENRP Handle Table Request" }, |
758 | | { ENRP_HANDLE_TABLE_RESPONSE_MESSAGE_TYPE, "ENRP Handle Table Response" }, |
759 | | { ENRP_HANDLE_UPDATE_MESSAGE_TYPE, "ENRP Handle Update" }, |
760 | | { ENRP_LIST_REQUEST_MESSAGE_TYPE, "ENRP List Request" }, |
761 | | { ENRP_LIST_RESPONSE_MESSAGE_TYPE, "ENRP List Response" }, |
762 | | { ENRP_INIT_TAKEOVER_MESSAGE_TYPE, "ENRP Init Takeover" }, |
763 | | { ENRP_INIT_TAKEOVER_ACK_MESSAGE_TYPE, "ENRP Init Takeover Ack" }, |
764 | | { ENRP_TAKEOVER_SERVER_MESSAGE_TYPE, "ENRP Takeover Server" }, |
765 | | { ENRP_ERROR_MESSAGE_TYPE, "ENRP Error" }, |
766 | | { 0, NULL } }; |
767 | | |
768 | | static void |
769 | | // NOLINTNEXTLINE(misc-no-recursion) |
770 | | dissect_enrp_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *enrp_tree) |
771 | 29 | { |
772 | 29 | enrp_tap_rec_t *tap_rec; |
773 | 29 | proto_item *flags_item; |
774 | 29 | proto_tree *flags_tree; |
775 | 29 | uint8_t type; |
776 | | |
777 | 29 | type = tvb_get_uint8(message_tvb, MESSAGE_TYPE_OFFSET); |
778 | 29 | if (p_get_proto_depth(pinfo, proto_enrp) == 1) { |
779 | 27 | tap_rec = wmem_new0(pinfo->pool, enrp_tap_rec_t); |
780 | 27 | tap_rec->type = type; |
781 | 27 | tap_rec->size = tvb_get_ntohs(message_tvb, MESSAGE_LENGTH_OFFSET); |
782 | 27 | tap_rec->type_string = val_to_str_const(tap_rec->type, message_type_values, "Unknown ENRP type"); |
783 | 27 | tap_queue_packet(enrp_tap, pinfo, tap_rec); |
784 | | |
785 | 27 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(type, message_type_values, "Unknown ENRP Type")); |
786 | 27 | } |
787 | | |
788 | 29 | if (enrp_tree) { |
789 | 29 | proto_tree_add_item(enrp_tree, hf_message_type, message_tvb, MESSAGE_TYPE_OFFSET, MESSAGE_TYPE_LENGTH, ENC_BIG_ENDIAN); |
790 | 29 | flags_item = proto_tree_add_item(enrp_tree, hf_message_flags, message_tvb, MESSAGE_FLAGS_OFFSET, MESSAGE_FLAGS_LENGTH, ENC_BIG_ENDIAN); |
791 | 29 | flags_tree = proto_item_add_subtree(flags_item, ett_enrp_flags); |
792 | 29 | proto_tree_add_item(enrp_tree, hf_message_length, message_tvb, MESSAGE_LENGTH_OFFSET, MESSAGE_LENGTH_LENGTH, ENC_BIG_ENDIAN); |
793 | 29 | switch (type) { |
794 | 4 | case ENRP_PRESENCE_MESSAGE_TYPE: |
795 | 4 | dissect_enrp_presence_message(message_tvb, pinfo, enrp_tree, flags_tree); |
796 | 4 | break; |
797 | 1 | case ENRP_HANDLE_TABLE_REQUEST_MESSAGE_TYPE: |
798 | 1 | dissect_enrp_handle_table_request_message(message_tvb, enrp_tree, flags_tree); |
799 | 1 | break; |
800 | 0 | case ENRP_HANDLE_TABLE_RESPONSE_MESSAGE_TYPE: |
801 | 0 | dissect_enrp_handle_table_response_message(message_tvb, pinfo, enrp_tree, flags_tree); |
802 | 0 | break; |
803 | 2 | case ENRP_HANDLE_UPDATE_MESSAGE_TYPE: |
804 | 2 | dissect_enrp_handle_update_message(message_tvb, pinfo, enrp_tree, flags_tree); |
805 | 2 | break; |
806 | 0 | case ENRP_LIST_REQUEST_MESSAGE_TYPE: |
807 | 0 | dissect_enrp_list_request_message(message_tvb, pinfo, enrp_tree, flags_tree); |
808 | 0 | break; |
809 | 8 | case ENRP_LIST_RESPONSE_MESSAGE_TYPE: |
810 | 8 | dissect_enrp_list_response_message(message_tvb, pinfo, enrp_tree, flags_tree); |
811 | 8 | break; |
812 | 1 | case ENRP_INIT_TAKEOVER_MESSAGE_TYPE: |
813 | 1 | dissect_enrp_init_takeover_message(message_tvb, pinfo, enrp_tree, flags_tree); |
814 | 1 | break; |
815 | 1 | case ENRP_INIT_TAKEOVER_ACK_MESSAGE_TYPE: |
816 | 1 | dissect_enrp_init_takeover_ack_message(message_tvb, pinfo, enrp_tree, flags_tree); |
817 | 1 | break; |
818 | 0 | case ENRP_TAKEOVER_SERVER_MESSAGE_TYPE: |
819 | 0 | dissect_enrp_init_takeover_server_message(message_tvb, pinfo, enrp_tree, flags_tree); |
820 | 0 | break; |
821 | 10 | case ENRP_ERROR_MESSAGE_TYPE: |
822 | 10 | dissect_enrp_error_message(message_tvb, pinfo, enrp_tree, flags_tree); |
823 | 10 | break; |
824 | 2 | default: |
825 | 2 | dissect_unknown_message(message_tvb, pinfo, enrp_tree, flags_tree); |
826 | 2 | break; |
827 | 29 | } |
828 | 29 | } |
829 | 29 | } |
830 | | |
831 | | static void |
832 | | // NOLINTNEXTLINE(misc-no-recursion) |
833 | | dissect_enrp_main(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree) |
834 | 29 | { |
835 | 29 | proto_item *enrp_item; |
836 | 29 | proto_tree *enrp_tree; |
837 | 29 | unsigned recursion_depth = p_get_proto_depth(pinfo, proto_enrp); |
838 | | |
839 | 29 | if (recursion_depth > ENRP_MAX_RECURSION_DEPTH) { |
840 | 0 | proto_tree_add_expert(tree, pinfo, &ei_enrp_max_recursion_depth_reached, |
841 | 0 | message_tvb, 0, 0); |
842 | 0 | return; |
843 | 0 | } |
844 | 29 | p_set_proto_depth(pinfo, proto_enrp, recursion_depth + 1); |
845 | | |
846 | | /* create the enrp protocol tree */ |
847 | 29 | enrp_item = proto_tree_add_item(tree, proto_enrp, message_tvb, 0, -1, ENC_NA); |
848 | 29 | enrp_tree = proto_item_add_subtree(enrp_item, ett_enrp); |
849 | | |
850 | | /* dissect the message */ |
851 | 29 | dissect_enrp_message(message_tvb, pinfo, enrp_tree); |
852 | 29 | } |
853 | | |
854 | | static int |
855 | | dissect_enrp(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
856 | 27 | { |
857 | 27 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ENRP"); |
858 | | |
859 | 27 | dissect_enrp_main(message_tvb, pinfo, tree); |
860 | 27 | return tvb_captured_length(message_tvb); |
861 | 27 | } |
862 | | |
863 | | /* TAP STAT INFO */ |
864 | | typedef enum |
865 | | { |
866 | | MESSAGE_TYPE_COLUMN = 0, |
867 | | MESSAGES_COLUMN, |
868 | | MESSAGES_SHARE_COLUMN, |
869 | | BYTES_COLUMN, |
870 | | BYTES_SHARE_COLUMN, |
871 | | FIRST_SEEN_COLUMN, |
872 | | LAST_SEEN_COLUMN, |
873 | | INTERVAL_COLUMN, |
874 | | MESSAGE_RATE_COLUMN, |
875 | | BYTE_RATE_COLUMN |
876 | | } enrp_stat_columns; |
877 | | |
878 | | static stat_tap_table_item enrp_stat_fields[] = { |
879 | | { TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "NetPerfMeter Message Type", "%-25s" }, |
880 | | { TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Messages ", "%u" }, |
881 | | { TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Messages Share (%)" , "%1.3f %%" }, |
882 | | { TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Bytes (B)", "%u" }, |
883 | | { TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Bytes Share (%) ", "%1.3f %%" }, |
884 | | { TABLE_ITEM_FLOAT, TAP_ALIGN_LEFT, "First Seen (s)", "%1.6f" }, |
885 | | { TABLE_ITEM_FLOAT, TAP_ALIGN_LEFT, "Last Seen (s)", "%1.6f" }, |
886 | | { TABLE_ITEM_FLOAT, TAP_ALIGN_LEFT, "Interval (s)", "%1.6f" }, |
887 | | { TABLE_ITEM_FLOAT, TAP_ALIGN_LEFT, "Message Rate (Msg/s)", "%1.2f" }, |
888 | | { TABLE_ITEM_FLOAT, TAP_ALIGN_LEFT, "Byte Rate (B/s)", "%1.2f" } |
889 | | }; |
890 | | |
891 | | static void enrp_stat_init(stat_tap_table_ui* new_stat) |
892 | 0 | { |
893 | 0 | const char *table_name = "NetPerfMeter Statistics"; |
894 | 0 | int num_fields = array_length(enrp_stat_fields); |
895 | 0 | stat_tap_table *table; |
896 | 0 | int i = 0; |
897 | 0 | stat_tap_table_item_type items[array_length(enrp_stat_fields)]; |
898 | |
|
899 | 0 | table = stat_tap_find_table(new_stat, table_name); |
900 | 0 | if (table) { |
901 | 0 | if (new_stat->stat_tap_reset_table_cb) { |
902 | 0 | new_stat->stat_tap_reset_table_cb(table); |
903 | 0 | } |
904 | 0 | return; |
905 | 0 | } |
906 | | |
907 | 0 | table = stat_tap_init_table(table_name, num_fields, 0, NULL); |
908 | 0 | stat_tap_add_table(new_stat, table); |
909 | |
|
910 | 0 | memset(items, 0x0, sizeof(items)); |
911 | | /* Add a row for each value type */ |
912 | 0 | while (message_type_values[i].strptr) { |
913 | 0 | items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING; |
914 | 0 | items[MESSAGE_TYPE_COLUMN].value.string_value = message_type_values[i].strptr; |
915 | 0 | items[MESSAGES_COLUMN].type = TABLE_ITEM_UINT; |
916 | 0 | items[MESSAGES_COLUMN].value.uint_value = 0; |
917 | 0 | items[MESSAGES_SHARE_COLUMN].type = TABLE_ITEM_NONE; |
918 | 0 | items[MESSAGES_SHARE_COLUMN].value.float_value = -1.0; |
919 | 0 | items[BYTES_COLUMN].type = TABLE_ITEM_UINT; |
920 | 0 | items[BYTES_COLUMN].value.uint_value = 0; |
921 | 0 | items[BYTES_SHARE_COLUMN].type = TABLE_ITEM_NONE; |
922 | 0 | items[BYTES_SHARE_COLUMN].value.float_value = -1.0; |
923 | 0 | items[FIRST_SEEN_COLUMN].type = TABLE_ITEM_NONE; |
924 | 0 | items[FIRST_SEEN_COLUMN].value.float_value = DBL_MAX; |
925 | 0 | items[LAST_SEEN_COLUMN].type = TABLE_ITEM_NONE; |
926 | 0 | items[LAST_SEEN_COLUMN].value.float_value = DBL_MIN; |
927 | 0 | items[INTERVAL_COLUMN].type = TABLE_ITEM_NONE; |
928 | 0 | items[INTERVAL_COLUMN].value.float_value = -1.0; |
929 | 0 | items[MESSAGE_RATE_COLUMN].type = TABLE_ITEM_NONE; |
930 | 0 | items[MESSAGE_RATE_COLUMN].value.float_value = -1.0; |
931 | 0 | items[BYTE_RATE_COLUMN].type = TABLE_ITEM_NONE; |
932 | 0 | items[BYTE_RATE_COLUMN].value.float_value = -1.0; |
933 | 0 | stat_tap_init_table_row(table, i, num_fields, items); |
934 | 0 | i++; |
935 | 0 | } |
936 | 0 | } |
937 | | |
938 | | static tap_packet_status |
939 | | enrp_stat_packet(void* tapdata, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* data, tap_flags_t flags _U_) |
940 | 0 | { |
941 | 0 | stat_data_t* stat_data = (stat_data_t*)tapdata; |
942 | 0 | const enrp_tap_rec_t* tap_rec = (const enrp_tap_rec_t*)data; |
943 | 0 | stat_tap_table* table; |
944 | 0 | stat_tap_table_item_type* msg_data; |
945 | 0 | int idx; |
946 | 0 | uint64_t messages; |
947 | 0 | uint64_t bytes; |
948 | 0 | int i = 0; |
949 | 0 | double firstSeen = -1.0; |
950 | 0 | double lastSeen = -1.0; |
951 | |
|
952 | 0 | idx = str_to_val_idx(tap_rec->type_string, message_type_values); |
953 | 0 | if (idx < 0) |
954 | 0 | return TAP_PACKET_DONT_REDRAW; |
955 | | |
956 | 0 | table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 0); |
957 | | |
958 | | /* Update packets counter */ |
959 | 0 | enrp_total_msgs++; |
960 | 0 | msg_data = stat_tap_get_field_data(table, idx, MESSAGES_COLUMN); |
961 | 0 | msg_data->value.uint_value++; |
962 | 0 | messages = msg_data->value.uint_value; |
963 | 0 | stat_tap_set_field_data(table, idx, MESSAGES_COLUMN, msg_data); |
964 | | |
965 | | /* Update bytes counter */ |
966 | 0 | enrp_total_bytes += tap_rec->size; |
967 | 0 | msg_data = stat_tap_get_field_data(table, idx, BYTES_COLUMN); |
968 | 0 | msg_data->value.uint_value += tap_rec->size; |
969 | 0 | bytes = msg_data->value.uint_value; |
970 | 0 | stat_tap_set_field_data(table, idx, BYTES_COLUMN, msg_data); |
971 | | |
972 | | /* Update messages and bytes share */ |
973 | 0 | while (message_type_values[i].strptr) { |
974 | 0 | msg_data = stat_tap_get_field_data(table, i, MESSAGES_COLUMN); |
975 | 0 | const unsigned m = msg_data->value.uint_value; |
976 | 0 | msg_data = stat_tap_get_field_data(table, i, BYTES_COLUMN); |
977 | 0 | const unsigned b = msg_data->value.uint_value; |
978 | |
|
979 | 0 | msg_data = stat_tap_get_field_data(table, i, MESSAGES_SHARE_COLUMN); |
980 | 0 | msg_data->type = TABLE_ITEM_FLOAT; |
981 | 0 | msg_data->value.float_value = 100.0 * m / (double)enrp_total_msgs; |
982 | 0 | stat_tap_set_field_data(table, i, MESSAGES_SHARE_COLUMN, msg_data); |
983 | |
|
984 | 0 | msg_data = stat_tap_get_field_data(table, i, BYTES_SHARE_COLUMN); |
985 | 0 | msg_data->type = TABLE_ITEM_FLOAT; |
986 | 0 | msg_data->value.float_value = 100.0 * b / (double)enrp_total_bytes; |
987 | 0 | stat_tap_set_field_data(table, i, BYTES_SHARE_COLUMN, msg_data); |
988 | 0 | i++; |
989 | 0 | } |
990 | | |
991 | | /* Update first seen time */ |
992 | 0 | if (pinfo->presence_flags & PINFO_HAS_TS) { |
993 | 0 | msg_data = stat_tap_get_field_data(table, idx, FIRST_SEEN_COLUMN); |
994 | 0 | msg_data->type = TABLE_ITEM_FLOAT; |
995 | 0 | msg_data->value.float_value = MIN(msg_data->value.float_value, nstime_to_sec(&pinfo->rel_ts)); |
996 | 0 | firstSeen = msg_data->value.float_value; |
997 | 0 | stat_tap_set_field_data(table, idx, FIRST_SEEN_COLUMN, msg_data); |
998 | 0 | } |
999 | | |
1000 | | /* Update last seen time */ |
1001 | 0 | if (pinfo->presence_flags & PINFO_HAS_TS) { |
1002 | 0 | msg_data = stat_tap_get_field_data(table, idx, LAST_SEEN_COLUMN); |
1003 | 0 | msg_data->type = TABLE_ITEM_FLOAT; |
1004 | 0 | msg_data->value.float_value = MAX(msg_data->value.float_value, nstime_to_sec(&pinfo->rel_ts)); |
1005 | 0 | lastSeen = msg_data->value.float_value; |
1006 | 0 | stat_tap_set_field_data(table, idx, LAST_SEEN_COLUMN, msg_data); |
1007 | 0 | } |
1008 | |
|
1009 | 0 | if ((lastSeen - firstSeen) > 0.0) { |
1010 | | /* Update interval */ |
1011 | 0 | msg_data = stat_tap_get_field_data(table, idx, INTERVAL_COLUMN); |
1012 | 0 | msg_data->type = TABLE_ITEM_FLOAT; |
1013 | 0 | msg_data->value.float_value = lastSeen - firstSeen; |
1014 | 0 | stat_tap_set_field_data(table, idx, INTERVAL_COLUMN, msg_data); |
1015 | | |
1016 | | /* Update message rate */ |
1017 | 0 | msg_data = stat_tap_get_field_data(table, idx, MESSAGE_RATE_COLUMN); |
1018 | 0 | msg_data->type = TABLE_ITEM_FLOAT; |
1019 | 0 | msg_data->value.float_value = messages / (lastSeen - firstSeen); |
1020 | 0 | stat_tap_set_field_data(table, idx, MESSAGE_RATE_COLUMN, msg_data); |
1021 | | |
1022 | | /* Update byte rate */ |
1023 | 0 | msg_data = stat_tap_get_field_data(table, idx, BYTE_RATE_COLUMN); |
1024 | 0 | msg_data->type = TABLE_ITEM_FLOAT; |
1025 | 0 | msg_data->value.float_value = bytes / (lastSeen - firstSeen); |
1026 | 0 | stat_tap_set_field_data(table, idx, BYTE_RATE_COLUMN, msg_data); |
1027 | 0 | } |
1028 | |
|
1029 | 0 | return TAP_PACKET_REDRAW; |
1030 | 0 | } |
1031 | | |
1032 | | static void |
1033 | | enrp_stat_reset(stat_tap_table* table) |
1034 | 0 | { |
1035 | 0 | unsigned element; |
1036 | 0 | stat_tap_table_item_type* item_data; |
1037 | |
|
1038 | 0 | for (element = 0; element < table->num_elements; element++) { |
1039 | 0 | item_data = stat_tap_get_field_data(table, element, MESSAGES_COLUMN); |
1040 | 0 | item_data->value.uint_value = 0; |
1041 | 0 | stat_tap_set_field_data(table, element, MESSAGES_COLUMN, item_data); |
1042 | |
|
1043 | 0 | item_data = stat_tap_get_field_data(table, element, MESSAGES_SHARE_COLUMN); |
1044 | 0 | item_data->type = TABLE_ITEM_NONE; |
1045 | 0 | item_data->value.float_value = -1.0; |
1046 | 0 | stat_tap_set_field_data(table, element, MESSAGES_SHARE_COLUMN, item_data); |
1047 | |
|
1048 | 0 | item_data = stat_tap_get_field_data(table, element, BYTES_COLUMN); |
1049 | 0 | item_data->value.uint_value = 0; |
1050 | 0 | stat_tap_set_field_data(table, element, BYTES_COLUMN, item_data); |
1051 | |
|
1052 | 0 | item_data = stat_tap_get_field_data(table, element, BYTES_SHARE_COLUMN); |
1053 | 0 | item_data->type = TABLE_ITEM_NONE; |
1054 | 0 | item_data->value.float_value = -1.0; |
1055 | 0 | stat_tap_set_field_data(table, element, BYTES_SHARE_COLUMN, item_data); |
1056 | |
|
1057 | 0 | item_data = stat_tap_get_field_data(table, element, FIRST_SEEN_COLUMN); |
1058 | 0 | item_data->type = TABLE_ITEM_NONE; |
1059 | 0 | item_data->value.float_value = DBL_MAX; |
1060 | 0 | stat_tap_set_field_data(table, element, FIRST_SEEN_COLUMN, item_data); |
1061 | |
|
1062 | 0 | item_data = stat_tap_get_field_data(table, element, LAST_SEEN_COLUMN); |
1063 | 0 | item_data->type = TABLE_ITEM_NONE; |
1064 | 0 | item_data->value.float_value = DBL_MIN; |
1065 | 0 | stat_tap_set_field_data(table, element, LAST_SEEN_COLUMN, item_data); |
1066 | |
|
1067 | 0 | item_data = stat_tap_get_field_data(table, element, INTERVAL_COLUMN); |
1068 | 0 | item_data->type = TABLE_ITEM_NONE; |
1069 | 0 | item_data->value.float_value = -1.0; |
1070 | 0 | stat_tap_set_field_data(table, element, INTERVAL_COLUMN, item_data); |
1071 | |
|
1072 | 0 | item_data = stat_tap_get_field_data(table, element, MESSAGE_RATE_COLUMN); |
1073 | 0 | item_data->type = TABLE_ITEM_NONE; |
1074 | 0 | item_data->value.float_value = -1.0; |
1075 | 0 | stat_tap_set_field_data(table, element, MESSAGE_RATE_COLUMN, item_data); |
1076 | |
|
1077 | 0 | item_data = stat_tap_get_field_data(table, element, BYTE_RATE_COLUMN); |
1078 | 0 | item_data->type = TABLE_ITEM_NONE; |
1079 | 0 | item_data->value.float_value = -1.0; |
1080 | 0 | stat_tap_set_field_data(table, element, BYTE_RATE_COLUMN, item_data); |
1081 | 0 | } |
1082 | 0 | enrp_total_msgs = 0; |
1083 | 0 | enrp_total_bytes = 0; |
1084 | 0 | } |
1085 | | |
1086 | | /* Register the protocol with Wireshark */ |
1087 | | void |
1088 | | proto_register_enrp(void) |
1089 | 14 | { |
1090 | | |
1091 | | /* Setup list of header fields */ |
1092 | 14 | static hf_register_info hf[] = { |
1093 | 14 | { &hf_message_type, { "Type", "enrp.message_type", FT_UINT8, BASE_DEC, VALS(message_type_values), 0x0, NULL, HFILL } }, |
1094 | 14 | { &hf_message_flags, { "Flags", "enrp.message_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1095 | 14 | { &hf_message_length, { "Length", "enrp.message_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1096 | 14 | { &hf_message_value, { "Value", "enrp.message_value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1097 | 14 | { &hf_cause_code, { "Cause Code", "enrp.cause_code", FT_UINT16, BASE_HEX, VALS(cause_code_values), 0x0, NULL, HFILL } }, |
1098 | 14 | { &hf_cause_length, { "Cause Length", "enrp.cause_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1099 | 14 | { &hf_cause_info, { "Cause Info", "enrp.cause_info", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1100 | 14 | { &hf_cause_padding, { "Padding", "enrp.cause_padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1101 | 14 | { &hf_parameter_type, { "Parameter Type", "enrp.parameter_type", FT_UINT16, BASE_HEX, VALS(parameter_type_values), 0x0, NULL, HFILL } }, |
1102 | 14 | { &hf_parameter_length, { "Parameter Length", "enrp.parameter_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1103 | 14 | { &hf_parameter_value, { "Parameter Value", "enrp.parameter_value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1104 | 14 | { &hf_parameter_padding, { "Padding", "enrp.parameter_padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1105 | 14 | { &hf_parameter_ipv4_address, { "IP Version 4 Address", "enrp.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1106 | 14 | { &hf_parameter_ipv6_address, { "IP Version 6 Address", "enrp.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1107 | 14 | { &hf_dccp_port, { "Port", "enrp.dccp_transport_port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1108 | 14 | { &hf_dccp_reserved, { "Reserved", "enrp.dccp_transport_reserved", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1109 | 14 | { &hf_dccp_service_code, { "Service Code", "enrp.dccp_transport_service_code", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1110 | 14 | { &hf_sctp_port, { "Port", "enrp.sctp_transport_port", FT_UINT16, BASE_PT_SCTP, NULL, 0x0, NULL, HFILL } }, |
1111 | 14 | { &hf_transport_use, { "Transport Use", "enrp.transport_use", FT_UINT16, BASE_DEC, VALS(transport_use_values), 0x0, NULL, HFILL } }, |
1112 | 14 | { &hf_tcp_port, { "Port", "enrp.tcp_transport_port", FT_UINT16, BASE_PT_TCP, NULL, 0x0, NULL, HFILL } }, |
1113 | 14 | { &hf_udp_port, { "Port", "enrp.udp_transport_port", FT_UINT16, BASE_PT_UDP, NULL, 0x0, NULL, HFILL } }, |
1114 | 14 | { &hf_udp_reserved, { "Reserved", "enrp.udp_transport_reserved", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1115 | 14 | { &hf_udp_lite_port, { "Port", "enrp.udp_lite_transport_port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1116 | 14 | { &hf_udp_lite_reserved, { "Reserved", "enrp.udp_lite_transport_reserved", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1117 | 14 | { &hf_policy_type, { "Policy Type", "enrp.pool_member_selection_policy_type", FT_UINT32, BASE_HEX, VALS(policy_type_values), 0x0, NULL, HFILL } }, |
1118 | 14 | { &hf_policy_weight, { "Policy Weight", "enrp.pool_member_selection_policy_weight", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1119 | 14 | { &hf_policy_priority, { "Policy Priority", "enrp.pool_member_selection_policy_priority", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1120 | 14 | { &hf_policy_load, { "Policy Load", "enrp.pool_member_selection_policy_load", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1121 | 14 | { &hf_policy_degradation, { "Policy Degradation", "enrp.pool_member_selection_policy_degradation", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1122 | 14 | { &hf_policy_loaddpf, { "Policy Load DPF", "enrp.pool_member_selection_policy_load_dpf", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1123 | 14 | { &hf_policy_weightdpf, { "Policy Weight DPF", "enrp.pool_member_selection_policy_weight_dpf", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1124 | 14 | { &hf_policy_distance, { "Policy Distance", "enrp.pool_member_selection_policy_distance", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1125 | 14 | { &hf_policy_value, { "Policy Value", "enrp.pool_member_selection_policy_value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1126 | 14 | { &hf_pool_handle, { "Pool Handle", "enrp.pool_handle_pool_handle", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1127 | 14 | { &hf_pe_pe_identifier, { "PE Identifier", "enrp.pool_element_pe_identifier", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1128 | 14 | { &hf_home_enrp_id, { "Home ENRP Server Identifier", "enrp.pool_element_home_enrp_server_identifier", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1129 | 14 | { &hf_reg_life, { "Registration Life", "enrp.pool_element_registration_life", FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL } }, |
1130 | 14 | { &hf_server_identifier, { "Server Identifier", "enrp.server_information_server_identifier", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1131 | 14 | { &hf_cookie, { "Cookie", "enrp.cookie", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1132 | 14 | { &hf_pe_identifier, { "PE Identifier", "enrp.pe_identifier", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1133 | 14 | { &hf_pe_checksum, { "PE Checksum", "enrp.pe_checksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1134 | 14 | { &hf_sender_servers_id, { "Sender Server's ID", "enrp.sender_servers_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1135 | 14 | { &hf_receiver_servers_id, { "Receiver Server's ID", "enrp.receiver_servers_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1136 | 14 | { &hf_target_servers_id, { "Target Server's ID", "enrp.target_servers_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1137 | 14 | { &hf_update_action, { "Update Action", "enrp.update_action", FT_UINT16, BASE_DEC, VALS(update_action_values), 0x0, NULL, HFILL } }, |
1138 | 14 | { &hf_pmu_reserved, { "Reserved", "enrp.reserved", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1139 | 14 | { &hf_reply_required_bit, { "R Bit", "enrp.r_bit", FT_BOOLEAN, 8, TFS(&reply_required_bit_value), REPLY_REQUIRED_BIT_MASK, NULL, HFILL } }, |
1140 | 14 | { &hf_own_children_only_bit, { "W Bit", "enrp.w_bit", FT_BOOLEAN, 8, TFS(&own_children_only_bit_value), OWN_CHILDREN_ONLY_BIT_MASK, NULL, HFILL } }, |
1141 | 14 | { &hf_more_to_send_bit, { "M Bit", "enrp.m_bit", FT_BOOLEAN, 8, TFS(&more_to_send_bit_value), MORE_TO_SEND_BIT_MASK, NULL, HFILL } }, |
1142 | 14 | { &hf_reject_bit, { "R Bit", "enrp.r_bit", FT_BOOLEAN, 8, TFS(&reject_bit_value), REJECT_BIT_MASK, NULL, HFILL } }, |
1143 | 14 | { &hf_tos_bit, { "T Bit", "enrp.t_bit", FT_BOOLEAN, 8, TFS(&tos_bit_value), TOS_BIT_MASK, NULL, HFILL } }, |
1144 | 14 | }; |
1145 | | |
1146 | | /* Setup protocol subtree array */ |
1147 | 14 | static int *ett[] = { |
1148 | 14 | &ett_enrp, |
1149 | 14 | &ett_enrp_parameter, |
1150 | 14 | &ett_enrp_cause, |
1151 | 14 | &ett_enrp_flags, |
1152 | 14 | }; |
1153 | | |
1154 | 14 | expert_module_t *expert_enrp; |
1155 | | |
1156 | 14 | static ei_register_info ei[] = { |
1157 | 14 | { &ei_enrp_max_recursion_depth_reached, { "enrp.max_recursion_depth_reached", |
1158 | 14 | PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached - stop decoding", EXPFILL }}, |
1159 | 14 | { &ei_enrp_invalid_length, { "enrp.invalid_length", |
1160 | 14 | PI_MALFORMED, PI_ERROR, "Parameter length must be at least 4 bytes", EXPFILL }} |
1161 | 14 | }; |
1162 | | |
1163 | 14 | static tap_param enrp_stat_params[] = { |
1164 | 14 | { PARAM_FILTER, "filter", "Filter", NULL, true } |
1165 | 14 | }; |
1166 | | |
1167 | 14 | static stat_tap_table_ui enrp_stat_table = { |
1168 | 14 | REGISTER_STAT_GROUP_RSERPOOL, |
1169 | 14 | "ENRP Statistics", |
1170 | 14 | "enrp", |
1171 | 14 | "enrp,stat", |
1172 | 14 | enrp_stat_init, |
1173 | 14 | enrp_stat_packet, |
1174 | 14 | enrp_stat_reset, |
1175 | 14 | NULL, |
1176 | 14 | NULL, |
1177 | 14 | array_length(enrp_stat_fields), enrp_stat_fields, |
1178 | 14 | array_length(enrp_stat_params), enrp_stat_params, |
1179 | 14 | NULL, |
1180 | 14 | 0 |
1181 | 14 | }; |
1182 | | |
1183 | | /* Register the protocol name and description */ |
1184 | 14 | proto_enrp = proto_register_protocol("Endpoint Handlespace Redundancy Protocol", "ENRP", "enrp"); |
1185 | | |
1186 | 14 | expert_enrp = expert_register_protocol(proto_enrp); |
1187 | 14 | expert_register_field_array(expert_enrp, ei, array_length(ei)); |
1188 | | |
1189 | | /* Required function calls to register the header fields and subtrees used */ |
1190 | 14 | proto_register_field_array(proto_enrp, hf, array_length(hf)); |
1191 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
1192 | 14 | enrp_tap = register_tap("enrp"); |
1193 | | |
1194 | 14 | enrp_handle = register_dissector("enrp", dissect_enrp, proto_enrp); |
1195 | 14 | register_stat_tap_table_ui(&enrp_stat_table); |
1196 | 14 | } |
1197 | | |
1198 | | void |
1199 | | proto_reg_handoff_enrp(void) |
1200 | 14 | { |
1201 | 14 | dissector_add_uint("sctp.ppi", ENRP_PAYLOAD_PROTOCOL_ID, enrp_handle); |
1202 | 14 | dissector_add_uint("sctp.port", ENRP_SCTP_PORT, enrp_handle); |
1203 | 14 | dissector_add_uint_with_preference("udp.port", ENRP_UDP_PORT, enrp_handle); |
1204 | 14 | } |
1205 | | |
1206 | | /* |
1207 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1208 | | * |
1209 | | * Local Variables: |
1210 | | * c-basic-offset: 2 |
1211 | | * tab-width: 8 |
1212 | | * indent-tabs-mode: nil |
1213 | | * End: |
1214 | | * |
1215 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
1216 | | * :indentSize=2:tabSize=8:noTabs=true: |
1217 | | */ |