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