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