2 * Routines for Web Cache C* Protocol dissection
3 * Jerry Talkington <jtalkington@users.sourceforge.net>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/to_str.h>
16 #include <epan/ipproto.h>
17 #include <epan/expert.h>
19 #include <wsutil/array.h>
20 #include "packet-wccp.h"
22 void proto_register_wccp(void);
23 void proto_reg_handoff_wccp(void);
25 static dissector_handle_t wccp_handle
;
27 static int proto_wccp
;
28 static int hf_wccp_message_type
; /* the message type */
29 static int hf_wccp_version
; /* protocol version */
31 static int hf_bucket_bit
;
32 static int hf_message_header_version
;
33 static int hf_hash_revision
; /* the version of the hash */
34 static int hf_change_num
; /* change number */
35 static int hf_hash_flag
;
36 static int hf_hash_flag_u
;
37 static int hf_recvd_id
;
39 static int hf_wc_view_wc_num
;
40 static int hf_cache_ip
;
41 static int hf_message_header_length
;
42 static int hf_item_type
;
43 static int hf_item_length
;
44 static int hf_item_data
;
45 static int hf_security_info_option
;
46 static int hf_security_info_md5_checksum
;
47 static int hf_command_element_type
;
48 static int hf_command_element_length
;
49 static int hf_command_length
;
50 static int hf_command_element_shutdown_ip_index
;
51 static int hf_command_element_shutdown_ipv4
;
52 static int hf_command_element_shutdown_ipv6
;
53 static int hf_command_unknown
;
54 static int hf_service_info_type
;
55 static int hf_service_info_id_standard
;
56 static int hf_service_info_id_dynamic
;
57 static int hf_service_info_priority
;
58 static int hf_service_info_protocol
;
59 static int hf_service_info_flags
;
60 static int hf_service_info_flags_src_ip_hash
;
61 static int hf_service_info_flags_dest_ip_hash
;
62 static int hf_service_info_flags_src_port_hash
;
63 static int hf_service_info_flags_dest_port_hash
;
64 static int hf_service_info_flags_ports_defined
;
65 static int hf_service_info_flags_ports_source
;
66 static int hf_service_info_flags_redirect_only_protocol_0
;
67 static int hf_service_info_flags_src_ip_alt_hash
;
68 static int hf_service_info_flags_dest_ip_alt_hash
;
69 static int hf_service_info_flags_src_port_alt_hash
;
70 static int hf_service_info_flags_dest_port_alt_hash
;
71 static int hf_service_info_flags_reserved
;
72 static int hf_service_info_source_port
;
73 static int hf_service_info_destination_port
;
74 static int hf_router_identity_ip_index
;
75 static int hf_router_identity_ipv4
;
76 static int hf_router_identity_ipv6
;
77 static int hf_router_identity_receive_id
;
78 static int hf_router_identity_send_to_ip_index
;
79 static int hf_router_identity_send_to_ipv4
;
80 static int hf_router_identity_send_to_ipv6
;
81 static int hf_router_identity_received_from_num
;
82 static int hf_web_cache_identity_index
;
83 static int hf_web_cache_identity_ipv4
;
84 static int hf_web_cache_identity_ipv6
;
85 static int hf_web_cache_identity_hash_rev
;
86 static int hf_web_cache_identity_flags
;
87 static int hf_web_cache_identity_flag_hash_info
;
88 static int hf_web_cache_identity_flag_assign_type
;
89 static int hf_web_cache_identity_flag_version_request
;
90 static int hf_web_cache_identity_flag_reserved
;
91 static int hf_mask_value_set_element_value_element_num
;
92 static int hf_assignment_weight
;
93 static int hf_assignment_status
;
94 static int hf_assignment_key_ip_index
;
95 static int hf_assignment_key_ipv4
;
96 static int hf_assignment_key_ipv6
;
97 static int hf_assignment_key_change_num
;
98 static int hf_assignment_no_data
;
99 static int hf_router_view_member_change_num
;
100 static int hf_router_router_num
;
101 static int hf_router_identity_router_ip_index
;
102 static int hf_router_identity_router_ipv4
;
103 static int hf_router_identity_router_ipv6
;
104 static int hf_wc_view_info_change_num
;
105 static int hf_wc_view_info_router_ip_index
;
106 static int hf_wc_view_info_router_ipv4
;
107 static int hf_wc_view_info_router_ipv6
;
108 static int hf_wc_view_info_wc_ip_index
;
109 static int hf_wc_view_info_wc_ipv4
;
110 static int hf_wc_view_info_wc_ipv6
;
111 static int hf_wc_view_router_num
;
112 static int hf_wc_identity_ip_address_index
;
113 static int hf_wc_identity_ip_address_ipv4
;
114 static int hf_wc_identity_ip_address_ipv6
;
115 static int hf_router_identity_received_from_ip_index
;
116 static int hf_router_identity_received_from_ipv4
;
117 static int hf_router_identity_received_from_ipv6
;
118 static int hf_router_assignment_element_change_num
;
119 static int hf_assignment_info_router_num
;
120 static int hf_hash_buckets_assignment_wc_num
;
121 static int hf_hash_buckets_assignment_wc_ip_index
;
122 static int hf_hash_buckets_assignment_wc_ipv4
;
123 static int hf_hash_buckets_assignment_wc_ipv6
;
124 static int hf_assignment_info_router_ip_index
;
125 static int hf_assignment_info_router_ipv4
;
126 static int hf_assignment_info_router_ipv6
;
127 static int hf_router_view_ip_index
;
128 static int hf_router_view_ipv4
;
129 static int hf_router_view_ipv6
;
130 static int hf_router_query_info_ip_index
;
131 static int hf_router_query_info_ipv4
;
132 static int hf_router_query_info_ipv6
;
133 static int hf_router_query_info_send_to_ip_index
;
134 static int hf_router_query_info_send_to_ipv4
;
135 static int hf_router_query_info_send_to_ipv6
;
136 static int hf_router_query_info_target_ip_index
;
137 static int hf_router_query_info_target_ipv4
;
138 static int hf_router_query_info_target_ipv6
;
139 static int hf_capability_element_type
;
140 static int hf_capability_element_length
;
141 static int hf_capability_info_value
;
142 static int hf_capability_forwarding_method_flag_gre
;
143 static int hf_capability_forwarding_method_flag_l2
;
144 static int hf_capability_assignment_method_flag_hash
;
145 static int hf_capability_assignment_method_flag_mask
;
146 static int hf_capability_return_method_flag_gre
;
147 static int hf_capability_return_method_flag_l2
;
148 static int hf_capability_transmit_t
;
149 static int hf_capability_transmit_t_upper_limit
;
150 static int hf_capability_transmit_t_lower_limit
;
151 static int hf_capability_timer_scale_timeout_scale
;
152 static int hf_capability_timer_scale_ra_timer_scale
;
153 static int hf_capability_timer_scale_timeout_scale_upper_limit
;
154 static int hf_capability_timer_scale_timeout_scale_lower_limit
;
155 static int hf_capability_timer_scale_ra_scale_upper_limit
;
156 static int hf_capability_timer_scale_ra_scale_lower_limit
;
157 static int hf_capability_value
;
158 static int hf_reserved_zero
;
159 static int hf_value_element_src_ip_index
;
160 static int hf_value_element_src_ipv4
;
161 static int hf_value_element_src_ipv6
;
162 static int hf_value_element_dest_ip_index
;
163 static int hf_value_element_dest_ipv4
;
164 static int hf_value_element_dest_ipv6
;
165 static int hf_value_element_src_port
;
166 static int hf_value_element_dest_port
;
167 static int hf_value_element_web_cache_ip_index
;
168 static int hf_value_element_web_cache_ipv4
;
169 static int hf_value_element_web_cache_ipv6
;
170 static int hf_mask_value_set_list_num_elements
;
171 static int hf_mask_element_src_ip
;
172 static int hf_mask_element_dest_ip
;
173 static int hf_mask_element_src_port
;
174 static int hf_mask_element_dest_port
;
175 static int hf_alt_assignment_info_assignment_type
;
176 static int hf_extended_assignment_data_type
;
177 static int hf_alt_assignment_info_assignment_length
;
178 static int hf_alt_assignment_map_assignment_type
;
179 static int hf_alt_assignment_map_assignment_length
;
180 static int hf_extended_assignment_data_length
;
181 static int hf_alt_assignment_info_num_routers
;
182 static int hf_alt_assignment_mask_value_set_element_num_wc_value_elements
;
183 static int hf_web_cache_value_element_wc_address_index
;
184 static int hf_web_cache_value_element_wc_address_ipv4
;
185 static int hf_web_cache_value_element_wc_address_ipv6
;
186 static int hf_web_cache_value_element_num_values
;
187 static int hf_web_cache_value_seq_num
;
188 static int hf_alt_assignment_mask_value_set_list_num_elements
;
189 static int hf_address_table_family
;
190 static int hf_address_table_address_length
;
191 static int hf_address_table_length
;
192 static int hf_address_table_element
;
195 static int ett_buckets
;
196 static int ett_hash_assignment_buckets
;
197 static int ett_mask_assignment_data_element
;
198 static int ett_alternate_mask_assignment_data_element
;
199 static int ett_extended_assigment_data_element
;
200 static int ett_table_element
;
201 static int ett_hash_flags
;
202 static int ett_wc_identity_flags
;
203 static int ett_cache_info
;
204 static int ett_security_info
;
205 static int ett_service_info
;
206 static int ett_service_flags
;
207 static int ett_service_info_ports
;
208 static int ett_wc_view_info_router_element
;
209 static int ett_router_identity_info
;
210 static int ett_wc_identity_element
;
211 static int ett_wc_identity_info
;
212 static int ett_router_view_info
;
213 static int ett_wc_view_info
;
214 static int ett_router_assignment_element
;
215 static int ett_hash_buckets_assignment_wc_element
;
216 static int ett_hash_buckets_assignment_buckets
;
217 static int ett_router_alt_assignment_element
;
218 static int ett_router_assignment_info
;
219 static int ett_query_info
;
220 static int ett_capabilities_info
;
221 static int ett_capability_element
;
222 static int ett_capability_forwarding_method
;
223 static int ett_capability_assignment_method
;
224 static int ett_capability_return_method
;
225 static int ett_capability_transmit_t
;
226 static int ett_capability_timer_scale
;
227 static int ett_alt_assignment_info
;
228 static int ett_alt_assignment_map
;
229 static int ett_address_table
;
230 static int ett_assignment_map
;
231 static int ett_command_extension
;
232 static int ett_alternate_mask_value_set
;
233 static int ett_alternate_mask_value_set_element
;
234 static int ett_mv_set_list
;
235 static int ett_mv_set_element
;
236 static int ett_mv_set_value_list
;
237 static int ett_alternate_mv_set_element_list
;
238 static int ett_web_cache_value_element_list
;
239 static int ett_alternate_mv_set_element
;
240 static int ett_value_element
;
241 static int ett_unknown_info
;
243 static expert_field ei_wccp_missing_security_info
;
244 static expert_field ei_wccp_missing_service_info
;
245 static expert_field ei_wccp_missing_wc_id_info
;
246 static expert_field ei_wccp_missing_router_id_info
;
247 static expert_field ei_wccp_missing_query_info
;
248 static expert_field ei_wccp_missing_wc_view_info
;
249 static expert_field ei_wccp_missing_rtr_view_info
;
250 static expert_field ei_wccp_contains_redirect_assignment
;
251 static expert_field ei_wccp_contains_router_id_info
;
252 static expert_field ei_wccp_contains_rtr_view_info
;
253 static expert_field ei_wccp_contains_query_info
;
254 static expert_field ei_wccp_contains_alt_assignment
;
255 static expert_field ei_wccp_contains_assign_map
;
256 static expert_field ei_wccp_contains_alt_assignment_map
;
257 static expert_field ei_wccp_contains_wc_id_info
;
258 static expert_field ei_wccp_contains_wc_view_info
;
259 static expert_field ei_wccp_contains_capabilities_info
;
260 static expert_field ei_wccp_contains_command_extension
;
261 static expert_field ei_wccp_missing_assignment
;
262 static expert_field ei_wccp_assignment_length_bad
;
263 static expert_field ei_wccp_length_bad
;
264 static expert_field ei_wccp_service_info_priority_nonzero
;
265 static expert_field ei_wccp_service_info_protocol_nonzero
;
266 static expert_field ei_wccp_router_identity_receive_id_zero
;
267 static expert_field ei_wccp_web_cache_identity_hash_rev_zero
;
268 static expert_field ei_wccp_address_table_family_unknown
;
269 static expert_field ei_wccp_capability_element_length
;
270 static expert_field ei_wccp_port_fields_not_used
;
271 static expert_field ei_wccp_a_zero_not_c
;
272 /* static expert_field ei_wccp_c_zero_not_a; */
277 * https://datatracker.ietf.org/doc/html/draft-forster-wrec-wccp-v1-00
279 * is the now-expired Internet-Draft for WCCP 1.0 (Web Cache Coordination
284 * https://datatracker.ietf.org/doc/html/draft-wilson-wrec-wccp-v2-01
286 * is the now-expired Internet-Draft for WCCP 2.0 (Web Cache Communication
289 * https://datatracker.ietf.org/doc/html/draft-param-wccp-v2rev1-01
291 * is the now-expired Internet-Draft for WCCP 2.01 (Web Cache Communication
292 * Protocol V2, Revision 1).
295 /* This is NOT IANA assigned */
296 #define UDP_PORT_WCCP 2048
299 #define WCCPv2 0x0200
300 #define WCCPv2r1 0x0201
301 #define WCCP_HERE_I_AM 7
302 #define WCCP_I_SEE_YOU 8
303 #define WCCP_ASSIGN_BUCKET 9
304 #define WCCP2_HERE_I_AM 10
305 #define WCCP2_I_SEE_YOU 11
306 #define WCCP2_REDIRECT_ASSIGN 12
307 #define WCCP2_REMOVAL_QUERY 13
309 static const value_string wccp_type_vals
[] = {
310 { WCCP_HERE_I_AM
, "1.0 Here I am" },
311 { WCCP_I_SEE_YOU
, "1.0 I see you" },
312 { WCCP_ASSIGN_BUCKET
, "1.0 Assign bucket" },
313 { WCCP2_HERE_I_AM
, "2.0 Here I am" },
314 { WCCP2_I_SEE_YOU
, "2.0 I see you" },
315 { WCCP2_REDIRECT_ASSIGN
, "2.0 Redirect assign" },
316 { WCCP2_REMOVAL_QUERY
, "2.0 Removal query" },
320 static const value_string wccp_version_val
[] = {
327 static const true_false_string tfs_src_dest_port
= { "Source port", "Destination port" };
328 static const true_false_string tfs_redirect_protocol0
= { "Redirect only protocol 0 (IP)", "Redirect all traffic" };
329 static const true_false_string tfs_historical_current
= { "Historical", "Current" };
330 static const true_false_string tfs_version_min_max
= {"WCCP version set is maximum supported by CE", "WCCP version set is minimum supported by CE"};
332 static const value_string wccp_address_family_val
[] = {
340 #define WCCP2_HASH_ASSIGNMENT_TYPE 0
341 #define WCCP2_MASK_ASSIGNMENT_TYPE 1
342 #define WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE 2
343 #define WCCP2r1_ASSIGNMENT_WEIGHT_STATUS 3
345 static const value_string assignment_type_vals
[] = {
346 { WCCP2_HASH_ASSIGNMENT_TYPE
, "Hash" },
347 { WCCP2_MASK_ASSIGNMENT_TYPE
, "Mask" },
348 { WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
, "WCCP2r1 Alternate Mask"},
349 { WCCP2r1_ASSIGNMENT_WEIGHT_STATUS
, "WCCP2r1 Assignment Weight Status"},
353 #define HASH_INFO_SIZE (4*(1+8+1))
355 #define WCCP2_SECURITY_INFO 0
356 #define WCCP2_SERVICE_INFO 1
357 #define WCCP2_ROUTER_ID_INFO 2
358 #define WCCP2_WC_ID_INFO 3
359 #define WCCP2_RTR_VIEW_INFO 4
360 #define WCCP2_WC_VIEW_INFO 5
361 #define WCCP2_REDIRECT_ASSIGNMENT 6
362 #define WCCP2_QUERY_INFO 7
363 #define WCCP2_CAPABILITIES_INFO 8
364 #define WCCP2_ALT_ASSIGNMENT 13
365 #define WCCP2_ASSIGN_MAP 14
366 #define WCCP2_COMMAND_EXTENSION 15
367 /* WCCP 2 r1 additions: */
368 #define WCCP2r1_ALT_ASSIGNMENT_MAP 16
369 #define WCCP2r1_ADDRESS_TABLE 17
371 static const value_string info_type_vals
[] = {
372 { WCCP2_SECURITY_INFO
, "Security Info" },
373 { WCCP2_SERVICE_INFO
, "Service Info" },
374 { WCCP2_ROUTER_ID_INFO
, "Router Identity Info" },
375 { WCCP2_WC_ID_INFO
, "Web-Cache Identity Info" },
376 { WCCP2_RTR_VIEW_INFO
, "Router View Info" },
377 { WCCP2_WC_VIEW_INFO
, "Web-Cache View Info" },
378 { WCCP2_REDIRECT_ASSIGNMENT
, "Assignment Info" },
379 { WCCP2_QUERY_INFO
, "Router Query Info" },
380 { WCCP2_CAPABILITIES_INFO
, "Capabilities Info" },
381 { WCCP2_ALT_ASSIGNMENT
, "Alternate Assignment" },
382 { WCCP2_ASSIGN_MAP
, "Assignment Map" },
383 { WCCP2_COMMAND_EXTENSION
, "Command Extension" },
384 { WCCP2r1_ALT_ASSIGNMENT_MAP
, "Alternative Assignment Map" },
385 { WCCP2r1_ADDRESS_TABLE
, "Address Table" },
389 const value_string service_id_vals
[] = {
394 typedef struct capability_flag
{
396 const char *short_name
;
403 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_HASH 0
404 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_MASK 1
405 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_NOT_PRESENT 2
406 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_EXTENDED 3
408 static const value_string wccp_web_cache_assignment_data_type_val
[] = {
409 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_HASH
, "Hash Assignment Data Element"},
410 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_MASK
, "Mask Assignment Data Element"},
411 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_NOT_PRESENT
, "Assignment Data Element Not Present"},
412 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_EXTENDED
, "Extended Assignment Data Element"},
416 #define WCCP2_FORWARDING_METHOD 0x01
417 #define WCCP2_ASSIGNMENT_METHOD 0x02
418 #define WCCP2_PACKET_RETURN_METHOD 0x03
419 #define WCCP2_TRANSMIT_T 0x04
420 #define WCCP2_TIMER_SCALE 0x05
422 static const value_string capability_type_vals
[] = {
423 { WCCP2_FORWARDING_METHOD
, "Forwarding Method" },
424 { WCCP2_ASSIGNMENT_METHOD
, "Assignment Method" },
425 { WCCP2_PACKET_RETURN_METHOD
, "Packet Return Method" },
426 { WCCP2_TRANSMIT_T
, "Transmit_t Message interval values"},
427 { WCCP2_TIMER_SCALE
, "Timer_scale Timeout scale values"},
432 /* with version 2.01 we now have a address table which is possibly present */
434 typedef struct wccp_address_table
{
438 uint16_t table_length
;
439 ws_in4_addr
*table_ipv4
;
440 ws_in6_addr
*table_ipv6
;
441 } wccp_address_table
;
443 static int wccp_bucket_info(uint8_t bucket_info
, proto_tree
*bucket_tree
,
444 uint32_t start
, tvbuff_t
*tvb
, int offset
);
446 /* The V2 dissectors will return the remaining length of the packet
447 and a negative number if there are missing bytes to finish the
449 static int dissect_wccp2_mask_assignment_data_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
450 proto_tree
*info_tree
, wccp_address_table
* addr_table
);
451 static int dissect_wccp2_hash_buckets_assignment_element(tvbuff_t
*tvb
, int offset
, int length
,
452 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
);
453 static int dissect_wccp2r1_address_table_info(tvbuff_t
*tvb
, int offset
,
454 int length
, packet_info
*pinfo
, proto_tree
*info_tree
,
455 wccp_address_table
* wccp_wccp_address_table
);
456 static int dissect_wccp2_hash_assignment_data_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
457 proto_tree
*info_tree
);
458 static int dissect_wccp2_assignment_weight_and_status_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
459 proto_tree
*info_tree
);
460 static int dissect_wccp2_extended_assignment_data_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
461 proto_tree
*info_tree
, wccp_address_table
* addr_table
);
462 static int dissect_wccp2_capability_element(tvbuff_t
*tvb
, int offset
, int length
,
463 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
464 static int dissect_wccp2_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
465 int length
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
);
467 /* Utility functions */
468 static int dissect_wccp2_mask_value_set_element(tvbuff_t
*tvb
, int offset
,
469 int length
, int idx
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
);
470 static int dissect_wccp2_alternate_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
471 int length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
, wccp_address_table
* addr_table
);
472 static int dissect_wccp2_alternate_mask_value_set_element(tvbuff_t
*tvb
, int offset
, int length
, unsigned el_index
, packet_info
*pinfo
,
473 proto_tree
*info_tree
, wccp_address_table
* addr_table
);
474 static int dissect_wccp2_web_cache_value_element(tvbuff_t
*tvb
, int offset
,
475 int length
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
);
476 static void dissect_32_bit_capability_flags(tvbuff_t
*tvb
, int curr_offset
,
477 uint16_t capability_val_len
, int ett
, const capability_flag
*flags
,
478 proto_tree
*element_tree
, proto_item
*header
,
479 proto_item
*length_item
, packet_info
*pinfo
);
480 static void dissect_transmit_t_capability(tvbuff_t
*tvb
, proto_item
*te
, int curr_offset
,
481 uint16_t capability_val_len
, int ett
, proto_tree
*element_tree
,
482 proto_item
*length_item
, packet_info
*pinfo
);
483 static void dissect_timer_scale_capability(tvbuff_t
*tvb
, int curr_offset
,
484 uint16_t capability_val_len
, int ett
, proto_tree
*element_tree
,
485 proto_item
*length_item
, packet_info
*pinfo
);
491 * In WCCP 2.01 addresses are encoded to support IPv6 with 32 bit fields
493 * handle the decoding
497 find_wccp_address_table(tvbuff_t
*tvb
, int offset
,
498 packet_info
*pinfo
, proto_tree
*wccp_tree _U_
, wccp_address_table
* wccp_wccp_address_table
)
501 uint16_t item_length
;
504 if (4 > tvb_reported_length_remaining(tvb
, offset
)) {
505 /* We've run out of packet data without finding an address table,
506 so there's no address table in the packet. */
509 type
= tvb_get_ntohs(tvb
, offset
);
510 item_length
= tvb_get_ntohs(tvb
, offset
+2);
512 if ((item_length
+ 4) > tvb_reported_length_remaining(tvb
, offset
)) {
513 /* We've run out of packet data without finding an address table,
514 so there's no address table in the packet. */
518 if (type
== WCCP2r1_ADDRESS_TABLE
)
520 dissect_wccp2r1_address_table_info(tvb
, offset
+4, item_length
, pinfo
, NULL
, wccp_wccp_address_table
);
521 /* no need to decode the rest */
525 offset
= offset
+ (item_length
+ 4);
530 /* This function prints the IP or the encoded IP if the table exists */
532 /* at most an IPv6 IP: see
533 http://stackoverflow.com/questions/166132/maximum-length-of-the-textual-representation-of-an-ipv6-address
535 39 = 8 groups of 4 digits with 7 : characters
539 45 = IPv4 tunnel features: 0000:0000:0000:0000:0000:0000:192.168.0.1
542 /* problem here is that the IP is in network byte order for IPv4
546 static const char * decode_wccp_encoded_address(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
,
547 proto_tree
*info_tree _U_
, wccp_address_table
* addr_table
)
552 /* are we using an address table? */
553 if (!addr_table
->in_use
)
555 /* no; return the IPv4 IP */
556 host_addr
= tvb_get_ipv4(tvb
,offset
);
557 buffer
= (char *) wmem_alloc(wmem_packet_scope(), WS_INET_ADDRSTRLEN
);
558 ip_addr_to_str_buf(&host_addr
, buffer
, WS_INET_ADDRSTRLEN
);
562 /* yes; we need to decode the encoded address */
566 host_addr
= tvb_get_ntohl(tvb
,offset
);
567 reserv
= (host_addr
& 0xFFFF0000) >> 16;
568 addr_index
= (host_addr
& 0x0000FFFF);
571 buffer
= wmem_strdup(wmem_packet_scope(), "INVALID: reserved part non zero");
574 /* now check if it's IPv4 or IPv6 we need to print */
575 switch (addr_table
->family
) {
579 /* special case: index 0 -> undefined IP */
580 if (addr_index
== 0) {
581 buffer
= wmem_strdup(wmem_packet_scope(), "0.0.0.0");
584 /* are we be beyond the end of the table? */
585 if (addr_index
> addr_table
->table_length
) {
586 buffer
= wmem_strdup_printf(wmem_packet_scope(), "INVALID IPv4 index: %d > %d",
587 addr_index
, addr_table
->table_length
);
592 if (addr_table
->table_ipv4
!= NULL
) {
593 buffer
= (char *) wmem_alloc(wmem_packet_scope(), WS_INET_ADDRSTRLEN
);
594 ip_addr_to_str_buf(&addr_table
->table_ipv4
[addr_index
-1], buffer
, WS_INET_ADDRSTRLEN
);
597 buffer
= wmem_strdup(wmem_packet_scope(), "INVALID IPv4 table empty!");
602 /* special case: index 0 -> undefined IP */
603 if (addr_index
== 0) {
604 buffer
= wmem_strdup(wmem_packet_scope(), "::");
608 /* are we be beyond the end of the table? */
609 if (addr_index
> addr_table
->table_length
) {
610 buffer
= wmem_strdup_printf(wmem_packet_scope(), "INVALID IPv6 index: %d > %d",
611 addr_index
, addr_table
->table_length
);
616 if (addr_table
->table_ipv6
!= NULL
) {
617 buffer
= (char *) wmem_alloc(wmem_packet_scope(), WS_INET6_ADDRSTRLEN
);
618 ip6_to_str_buf(&(addr_table
->table_ipv6
[addr_index
-1]), buffer
, WS_INET6_ADDRSTRLEN
);
621 buffer
= wmem_strdup(wmem_packet_scope(), "INVALID IPv6 table empty!");
625 buffer
= wmem_strdup(wmem_packet_scope(), "INVALID IP family");
634 static proto_item
* wccp_add_ipaddress_item(proto_tree
* tree
, int hf_index
, int hf_ipv4
, int hf_ipv6
, tvbuff_t
*tvb
,
635 int offset
, int length
, wccp_address_table
* addr_table
)
638 ws_in6_addr ipv6_zero
;
639 uint16_t reserv
, addr_index
;
641 /* are we using an address table? */
642 if (! addr_table
->in_use
)
643 return proto_tree_add_item(tree
, hf_ipv4
, tvb
, offset
, length
, ENC_BIG_ENDIAN
);
645 host_addr
= tvb_get_ntohl(tvb
, offset
);
647 /* we need to decode the encoded address: */
648 reserv
= (host_addr
& 0xFFFF0000) >> 16;
649 addr_index
= (host_addr
& 0x0000FFFF);
651 memset(&ipv6_zero
, 0, sizeof(ipv6_zero
));
654 return proto_tree_add_uint_format_value(tree
, hf_index
, tvb
, offset
, length
, host_addr
, "INVALID: reserved part non zero");
656 /* now check if it's IPv4 or IPv6 we need to print */
657 switch (addr_table
->family
) {
661 /* special case: index 0 -> undefined IP */
662 if (addr_index
== 0) {
663 return proto_tree_add_item(tree
, hf_ipv4
, tvb
, offset
, length
, ENC_LITTLE_ENDIAN
);
665 /* are we be beyond the end of the table? */
666 if (addr_index
> addr_table
->table_length
) {
667 return proto_tree_add_uint_format_value(tree
, hf_index
, tvb
, offset
, length
, host_addr
,
668 "INVALID IPv4 index: %d > %d", addr_index
, addr_table
->table_length
);
672 if (addr_table
->table_ipv4
!= NULL
) {
673 return proto_tree_add_ipv4(tree
, hf_ipv4
, tvb
, offset
, length
, addr_table
->table_ipv4
[addr_index
-1]);
676 return proto_tree_add_uint_format_value(tree
, hf_index
, tvb
, offset
, length
, host_addr
, "INVALID: IPv4 table empty!");
680 /* special case: index 0 -> undefined IP */
681 if (addr_index
== 0) {
682 return proto_tree_add_ipv6(tree
, hf_ipv6
, tvb
, offset
, length
, &ipv6_zero
);
685 /* are we be beyond the end of the table? */
686 if (addr_index
> addr_table
->table_length
) {
687 return proto_tree_add_uint_format_value(tree
, hf_index
, tvb
, offset
, length
, host_addr
,
688 "INVALID IPv6 index: %d > %d", addr_index
, addr_table
->table_length
);
692 if (addr_table
->table_ipv6
!= NULL
) {
693 return proto_tree_add_ipv6(tree
, hf_ipv6
, tvb
, offset
, length
, &(addr_table
->table_ipv6
[addr_index
-1]));
696 return proto_tree_add_uint_format_value(tree
, hf_index
, tvb
, offset
, length
, host_addr
,
697 "INVALID IPv6 table empty!");
700 return proto_tree_add_ipv4_format(tree
, hf_index
, tvb
, offset
, length
, host_addr
, "INVALID IP family");
703 #define WCCP_IP_MAX_LENGTH (WS_INET_ADDRSTRLEN > 46 ? WS_INET_ADDRSTRLEN : 46)
707 dissect_hash_data(tvbuff_t
*tvb
, int offset
, proto_tree
*wccp_tree
)
709 proto_tree
*bucket_tree
;
711 proto_tree
*field_tree
;
716 proto_tree_add_item(wccp_tree
, hf_hash_revision
, tvb
, offset
, 4,
720 bucket_tree
= proto_tree_add_subtree(wccp_tree
, tvb
, offset
, 32,
721 ett_buckets
, NULL
, "Hash information");
723 for (i
= 0, n
= 0; i
< 32; i
++) {
724 bucket_info
= tvb_get_uint8(tvb
, offset
);
725 n
= wccp_bucket_info(bucket_info
, bucket_tree
, n
, tvb
, offset
);
728 tf
= proto_tree_add_item(wccp_tree
, hf_hash_flag
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
729 field_tree
= proto_item_add_subtree(tf
, ett_hash_flags
);
730 proto_tree_add_item(field_tree
, hf_hash_flag_u
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
736 dissect_web_cache_list_entry(tvbuff_t
*tvb
, int offset
, int idx
,
737 proto_tree
*wccp_tree
)
739 proto_tree
*list_entry_tree
;
741 list_entry_tree
= proto_tree_add_subtree_format(wccp_tree
, tvb
, offset
, 4 + HASH_INFO_SIZE
,
742 ett_cache_info
, NULL
, "Web-Cache List Entry(%d)", idx
);
743 proto_tree_add_item(list_entry_tree
, hf_cache_ip
, tvb
, offset
, 4,
746 offset
= dissect_hash_data(tvb
, offset
, list_entry_tree
);
752 * takes an integer representing a "Hash Information" bitmap, and spits out
753 * the corresponding proto_tree entries, returning the next bucket number.
756 wccp_bucket_info(uint8_t bucket_info
, proto_tree
*bucket_tree
, uint32_t start
,
757 tvbuff_t
*tvb
, int offset
)
761 for(i
= 0; i
< 8; i
++) {
762 proto_tree_add_uint_format(bucket_tree
, hf_bucket_bit
, tvb
, offset
, 1, bucket_info
& 1<<i
,
763 "Bucket %3d: %s", start
, (bucket_info
& 1<<i
? "Assigned" : "Not Assigned") );
770 /* the following functions all need to check the length and the offset
771 so we have a few macros to use
774 #define EAT(x) {length -= x; offset += x;}
776 #define EAT_AND_CHECK(x,next) {length -= x; offset += x; if (length < next) return length - next;}
778 #define CHECK_LENGTH_ADVANCE_OFFSET(new_length) { \
779 int old_offset = offset; \
780 if (new_length<0) return new_length; \
781 offset += length-new_length; \
782 if (old_offset >= offset) return offset - old_offset; \
783 length = new_length; \
787 /* 5.1.1 Security Info Component */
789 /* Security options */
791 #define WCCP2_NO_SECURITY 0
792 #define WCCP2_MD5_SECURITY 1
794 #define SECURITY_INFO_LEN 4
796 static const value_string security_option_vals
[] = {
797 { WCCP2_NO_SECURITY
, "None" },
798 { WCCP2_MD5_SECURITY
, "MD5" },
804 dissect_wccp2_security_info(tvbuff_t
*tvb
, int offset
, int length
,
805 packet_info
*pinfo _U_
, proto_tree
*info_tree
, wccp_address_table
* addr_table _U_
)
807 uint32_t security_option
;
809 if (length
< SECURITY_INFO_LEN
)
810 return (length
-SECURITY_INFO_LEN
);
812 security_option
= tvb_get_ntohl(tvb
, offset
);
813 proto_tree_add_item(info_tree
, hf_security_info_option
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
815 if (security_option
== WCCP2_MD5_SECURITY
) {
818 proto_tree_add_item(info_tree
, hf_security_info_md5_checksum
, tvb
, offset
, length
-4, ENC_NA
);
826 /* 5.1.2 Service Info Component */
828 #define SERVICE_INFO_LEN (4+4+8*2)
830 #define WCCP2_SERVICE_STANDARD 0
831 #define WCCP2_SERVICE_DYNAMIC 1
833 static const value_string service_type_vals
[] = {
834 { WCCP2_SERVICE_STANDARD
, "Standard predefined service"},
835 { WCCP2_SERVICE_DYNAMIC
, "Dynamic CE defined service" },
842 #define WCCP2_SI_SRC_IP_HASH 0x00000001
843 #define WCCP2_SI_DST_IP_HASH 0x00000002
844 #define WCCP2_SI_SRC_PORT_HASH 0x00000004
845 #define WCCP2_SI_DST_PORT_HASH 0x00000008
846 #define WCCP2_SI_PORTS_DEFINED 0x00000010
847 #define WCCP2_SI_PORTS_SOURCE 0x00000020
848 #define WCCP2r1_SI_REDIRECT_ONLY_PROTOCOL_0 0x00000040
849 #define WCCP2_SI_SRC_IP_ALT_HASH 0x00000100
850 #define WCCP2_SI_DST_IP_ALT_HASH 0x00000200
851 #define WCCP2_SI_SRC_PORT_ALT_HASH 0x00000400
852 #define WCCP2_SI_DST_PORT_ALT_HASH 0x00000800
856 dissect_wccp2_service_info(tvbuff_t
*tvb
, int offset
, int length
,
857 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table _U_
)
859 uint8_t service_type
;
862 proto_tree
*ports_tree
;
864 int max_offset
= offset
+length
;
866 static int * const flag_fields
[] = {
867 &hf_service_info_flags_src_ip_hash
,
868 &hf_service_info_flags_dest_ip_hash
,
869 &hf_service_info_flags_src_port_hash
,
870 &hf_service_info_flags_dest_port_hash
,
871 &hf_service_info_flags_ports_defined
,
872 &hf_service_info_flags_ports_source
,
873 &hf_service_info_flags_redirect_only_protocol_0
,
874 &hf_service_info_flags_src_ip_alt_hash
,
875 &hf_service_info_flags_dest_ip_alt_hash
,
876 &hf_service_info_flags_src_port_alt_hash
,
877 &hf_service_info_flags_dest_port_alt_hash
,
878 &hf_service_info_flags_reserved
,
882 if (length
!= SERVICE_INFO_LEN
)
883 return length
- SERVICE_INFO_LEN
;
885 service_type
= tvb_get_uint8(tvb
, offset
);
886 proto_tree_add_item(info_tree
, hf_service_info_type
, tvb
,
887 offset
, 1, ENC_BIG_ENDIAN
);
889 switch (service_type
) {
891 case WCCP2_SERVICE_STANDARD
:
892 proto_tree_add_item(info_tree
, hf_service_info_id_standard
, tvb
,
893 offset
+1 , 1, ENC_BIG_ENDIAN
);
895 tf
= proto_tree_add_item(info_tree
, hf_service_info_priority
, tvb
, offset
+2, 1, ENC_BIG_ENDIAN
);
896 if (tvb_get_uint8(tvb
, offset
+2) != 0)
897 expert_add_info(pinfo
, tf
, &ei_wccp_service_info_priority_nonzero
);
899 tf
= proto_tree_add_item(info_tree
, hf_service_info_protocol
, tvb
,
900 offset
+3, 1, ENC_BIG_ENDIAN
);
902 if (tvb_get_uint8(tvb
, offset
+3) != 0)
903 expert_add_info(pinfo
, tf
, &ei_wccp_service_info_protocol_nonzero
);
906 case WCCP2_SERVICE_DYNAMIC
:
907 proto_tree_add_item(info_tree
, hf_service_info_id_dynamic
, tvb
,
908 offset
+1 , 1, ENC_BIG_ENDIAN
);
909 proto_tree_add_item(info_tree
, hf_service_info_priority
, tvb
,
910 offset
+2, 1, ENC_BIG_ENDIAN
);
911 proto_tree_add_item(info_tree
, hf_service_info_protocol
, tvb
,
912 offset
+3, 1, ENC_BIG_ENDIAN
);
917 flags
= tvb_get_ntohl(tvb
, offset
);
918 proto_tree_add_bitmask(info_tree
, tvb
, offset
, hf_service_info_flags
, ett_service_flags
, flag_fields
, ENC_BIG_ENDIAN
);
922 if (flags
& WCCP2_SI_PORTS_DEFINED
) {
923 ports_tree
= proto_tree_add_subtree(info_tree
, tvb
, offset
, 2*8,
924 ett_service_info_ports
, &tf
, "Ports list: ");
926 for (i
= 0; i
< 8; i
++) {
927 uint16_t port
= tvb_get_ntohs(tvb
, offset
);
930 if (flags
& WCCP2_SI_SRC_PORT_HASH
)
931 proto_tree_add_item(ports_tree
, hf_service_info_source_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
933 proto_tree_add_item(ports_tree
, hf_service_info_destination_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
934 proto_item_append_text(tf
, " %d", port
);
937 DISSECTOR_ASSERT(offset
<= max_offset
);
941 /* just use up the space if there is */
942 if (offset
+ 8 * 2 <= max_offset
) {
943 proto_tree_add_expert(info_tree
, pinfo
, &ei_wccp_port_fields_not_used
, tvb
, offset
, 8*2);
948 return length
- SERVICE_INFO_LEN
;
951 /* 6.1 Router Identity Element */
953 dissect_wccp2_router_identity_element(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
954 proto_tree
*tree
, wccp_address_table
* addr_table
)
959 wccp_add_ipaddress_item(tree
, hf_router_identity_ip_index
, hf_router_identity_ipv4
, hf_router_identity_ipv6
, tvb
, offset
, 4, addr_table
);
960 tf
= proto_tree_add_item(tree
, hf_router_identity_receive_id
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
962 if (tvb_get_ntohl(tvb
, offset
+ 4) == 0)
963 expert_add_info(pinfo
, tf
, &ei_wccp_router_identity_receive_id_zero
);
966 #define ROUTER_ID_INFO_MIN_LEN (8+4+4)
968 /* 5.3.1 Router Identity Info Component */
970 dissect_wccp2_router_identity_info(tvbuff_t
*tvb
, int offset
, int length
,
971 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
973 uint32_t n_received_from
;
976 proto_tree
*element_tree
;
979 return length
- ROUTER_ID_INFO_MIN_LEN
;
982 te
= wccp_add_ipaddress_item(info_tree
, hf_router_identity_router_ip_index
, hf_router_identity_router_ipv4
, hf_router_identity_router_ipv6
, tvb
, offset
, 4, addr_table
);
984 element_tree
= proto_item_add_subtree(te
,ett_wc_view_info_router_element
);
986 dissect_wccp2_router_identity_element(tvb
,offset
,pinfo
,element_tree
, addr_table
);
989 wccp_add_ipaddress_item(info_tree
, hf_router_identity_send_to_ip_index
, hf_router_identity_send_to_ipv4
, hf_router_identity_send_to_ipv6
, tvb
, offset
, 4, addr_table
);
992 n_received_from
= tvb_get_ntohl(tvb
, offset
);
993 proto_tree_add_item(info_tree
, hf_router_identity_received_from_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
996 for (i
= 0; i
< n_received_from
; i
++) {
998 return length
-4*(i
-n_received_from
);
1001 wccp_add_ipaddress_item(info_tree
, hf_router_identity_received_from_ip_index
, hf_router_identity_received_from_ipv4
, hf_router_identity_received_from_ipv6
, tvb
, offset
, 4, addr_table
);
1008 #define ROUTER_WC_ID_ELEMENT_MIN_LEN (4+2+2)
1010 /* 6.4 Web-Cache Identity Element */
1012 dissect_wccp2_web_cache_identity_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
1013 proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1017 unsigned data_element_type
;
1019 static int * const flag_fields
[] = {
1020 &hf_web_cache_identity_flag_hash_info
,
1021 &hf_web_cache_identity_flag_assign_type
,
1022 &hf_web_cache_identity_flag_version_request
,
1023 &hf_web_cache_identity_flag_reserved
,
1027 if (length
< ROUTER_WC_ID_ELEMENT_MIN_LEN
)
1028 return length
- ROUTER_WC_ID_ELEMENT_MIN_LEN
;
1030 wccp_add_ipaddress_item(info_tree
, hf_web_cache_identity_index
, hf_web_cache_identity_ipv4
, hf_web_cache_identity_ipv6
, tvb
, offset
, 4, addr_table
);
1033 tf
= proto_tree_add_item(info_tree
, hf_web_cache_identity_hash_rev
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1034 if (tvb_get_ntohs(tvb
, offset
) != 0)
1035 expert_add_info(pinfo
, tf
, &ei_wccp_web_cache_identity_hash_rev_zero
);
1039 flags
= tvb_get_ntohs(tvb
, offset
);
1040 data_element_type
= (flags
& 0x6) >> 1;
1041 proto_tree_add_bitmask(info_tree
, tvb
, offset
, hf_web_cache_identity_flags
, ett_wc_identity_flags
, flag_fields
, ENC_BIG_ENDIAN
);
1045 switch (data_element_type
) {
1046 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_HASH
:
1047 return dissect_wccp2_hash_assignment_data_element(tvb
,offset
,length
,pinfo
,info_tree
);
1048 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_MASK
:
1049 return dissect_wccp2_mask_assignment_data_element(tvb
,offset
,length
,pinfo
,info_tree
, addr_table
);
1051 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_NOT_PRESENT
:
1052 proto_tree_add_item(info_tree
, hf_assignment_no_data
, tvb
, offset
, 2, ENC_NA
);
1054 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_EXTENDED
:
1055 return dissect_wccp2_extended_assignment_data_element(tvb
,offset
,length
,pinfo
,info_tree
, addr_table
);
1060 /* 5.2.1 Web-Cache Identity Info Component */
1062 dissect_wccp2_wc_identity_info(tvbuff_t
*tvb
, int offset
, int length
,
1063 packet_info
*pinfo _U_
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1066 proto_tree
*element_tree
;
1068 te
= wccp_add_ipaddress_item(info_tree
, hf_wc_identity_ip_address_index
, hf_wc_identity_ip_address_ipv4
, hf_wc_identity_ip_address_ipv6
,
1069 tvb
, offset
, 4, addr_table
);
1071 element_tree
= proto_item_add_subtree(te
, ett_wc_identity_element
);
1072 return dissect_wccp2_web_cache_identity_element(tvb
, offset
,length
, pinfo
,
1073 element_tree
, addr_table
);
1076 /* 6.3 Assignment Key Element */
1078 dissect_wccp2_assignment_key_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo _U_
,
1079 proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1085 wccp_add_ipaddress_item(info_tree
, hf_assignment_key_ip_index
, hf_assignment_key_ipv4
, hf_assignment_key_ipv6
, tvb
, offset
, 4, addr_table
);
1088 proto_tree_add_item(info_tree
, hf_assignment_key_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1095 #define ROUTER_VIEW_INFO_MIN_LEN (4+8+4+4)
1097 /* 5.3.2 Router View Info Component */
1099 dissect_wccp2_router_view_info(tvbuff_t
*tvb
, int offset
, int length
,
1100 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1103 uint32_t n_web_caches
;
1106 proto_tree
*element_tree
;
1109 if (length
< ROUTER_VIEW_INFO_MIN_LEN
)
1110 return length
- ROUTER_VIEW_INFO_MIN_LEN
;
1112 proto_tree_add_item(info_tree
, hf_router_view_member_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1115 new_length
=dissect_wccp2_assignment_key_element(tvb
, offset
, length
, pinfo
, info_tree
, addr_table
);
1116 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1118 n_routers
= tvb_get_ntohl(tvb
, offset
);
1119 proto_tree_add_uint(info_tree
, hf_router_router_num
, tvb
, offset
, 4, n_routers
);
1122 for (i
= 0; i
< n_routers
; i
++) {
1124 return length
- (n_routers
-i
)*4 - 4;
1126 wccp_add_ipaddress_item(info_tree
, hf_router_view_ip_index
, hf_router_view_ipv4
, hf_router_view_ipv6
, tvb
, offset
, 4, addr_table
);
1133 n_web_caches
= tvb_get_ntohl(tvb
, offset
);
1134 proto_tree_add_uint(info_tree
, hf_wc_view_wc_num
, tvb
, offset
, 4, n_web_caches
);
1137 for (i
= 0; i
< n_web_caches
; i
++) {
1139 old_length
= length
;
1142 return length
- 4*(n_web_caches
-i
);
1144 te
= wccp_add_ipaddress_item(info_tree
, hf_router_query_info_ip_index
, hf_router_query_info_ipv4
, hf_router_query_info_ipv6
, tvb
, offset
, 4, addr_table
);
1146 element_tree
= proto_item_add_subtree(te
, ett_wc_identity_element
);
1147 length
= dissect_wccp2_web_cache_identity_element(tvb
,
1148 offset
, length
, pinfo
,
1149 element_tree
, addr_table
);
1153 offset
+= old_length
- length
;
1158 #define WC_VIEW_INFO_MIN_LEN (4+4+4)
1160 /* 5.2.2 Web Cache View Info Component */
1163 dissect_wccp2_web_cache_view_info(tvbuff_t
*tvb
, int offset
, int length
,
1164 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1167 uint32_t n_web_caches
;
1170 proto_tree
*element_tree
;
1173 if (length
< WC_VIEW_INFO_MIN_LEN
)
1174 return length
- WC_VIEW_INFO_MIN_LEN
;
1177 proto_tree_add_item(info_tree
, hf_wc_view_info_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1180 n_routers
= tvb_get_ntohl(tvb
, offset
);
1181 proto_tree_add_uint(info_tree
, hf_wc_view_router_num
, tvb
, offset
, 4, n_routers
);
1184 for (i
= 0; i
< n_routers
; i
++) {
1186 return length
-8 * (n_routers
-i
) - 4;
1188 te
= wccp_add_ipaddress_item(info_tree
, hf_wc_view_info_router_ip_index
, hf_wc_view_info_router_ipv4
, hf_wc_view_info_router_ipv6
, tvb
, offset
, 4, addr_table
);
1189 /* also include the receive id in the object */
1190 proto_item_set_len(te
, 8);
1192 element_tree
= proto_item_add_subtree(te
,ett_wc_view_info_router_element
);
1193 dissect_wccp2_router_identity_element(tvb
, offset
, pinfo
, element_tree
, addr_table
);
1200 n_web_caches
= tvb_get_ntohl(tvb
, offset
);
1201 proto_tree_add_uint(info_tree
, hf_wc_view_wc_num
, tvb
, offset
, 4, n_web_caches
);
1204 for (i
= 0; i
< n_web_caches
; i
++) {
1206 return length
- 4*(n_web_caches
-i
);
1208 wccp_add_ipaddress_item(info_tree
, hf_wc_view_info_wc_ip_index
, hf_wc_view_info_wc_ipv4
, hf_wc_view_info_wc_ipv6
, tvb
, offset
, 4, addr_table
);
1214 /* 6.2 Router Assignment Element */
1216 dissect_wccp2_router_assignment_element(tvbuff_t
*tvb
, int offset
,
1217 int length _U_
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1219 dissect_wccp2_router_identity_element(tvb
,offset
,pinfo
,info_tree
, addr_table
);
1221 proto_tree_add_item(info_tree
, hf_router_assignment_element_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1226 assignment_bucket_name(uint8_t bucket
)
1230 if (bucket
== 0xff) {
1233 cur
=wmem_strdup_printf(wmem_packet_scope(), "%u%s", bucket
& 0x7F,
1234 (bucket
& 0x80) ? " (Alt)" : "");
1239 #define ASSIGNMENT_INFO_MIN_LEN (8+4+4)
1241 /* 5.4.1 Assignment Info Component */
1243 dissect_wccp2_assignment_info(tvbuff_t
*tvb
, int offset
, int length
,
1244 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1249 proto_tree
*element_tree
;
1252 if (length
< ASSIGNMENT_INFO_MIN_LEN
)
1253 return length
- ASSIGNMENT_INFO_MIN_LEN
;
1256 new_length
=dissect_wccp2_assignment_key_element(tvb
, offset
, length
, pinfo
, info_tree
, addr_table
);
1257 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1259 n_routers
= tvb_get_ntohl(tvb
, offset
);
1260 proto_tree_add_uint(info_tree
, hf_assignment_info_router_num
, tvb
, offset
, 4, n_routers
);
1263 for (i
= 0; i
< n_routers
; i
++) {
1265 return length
- 12*(n_routers
-i
)-4-256;
1267 te
= wccp_add_ipaddress_item(info_tree
, hf_assignment_info_router_ip_index
, hf_assignment_info_router_ipv4
, hf_assignment_info_router_ipv6
, tvb
, offset
, 4, addr_table
);
1269 element_tree
= proto_item_add_subtree(te
, ett_router_assignment_element
);
1270 dissect_wccp2_router_assignment_element(tvb
, offset
, length
, pinfo
,
1271 element_tree
, addr_table
);
1275 new_length
= dissect_wccp2_hash_buckets_assignment_element(tvb
, offset
, length
, pinfo
, info_tree
, addr_table
);
1276 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1281 #define QUERY_INFO_LEN (4+4+4+4)
1283 /* 5.5.1 Router Query Info Component */
1285 dissect_wccp2_router_query_info(tvbuff_t
*tvb
, int offset
, int length
,
1286 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1288 if (length
< QUERY_INFO_LEN
)
1289 return length
- QUERY_INFO_LEN
;
1291 dissect_wccp2_router_identity_element(tvb
,offset
,pinfo
,info_tree
, addr_table
);
1294 wccp_add_ipaddress_item(info_tree
, hf_router_query_info_send_to_ip_index
, hf_router_query_info_send_to_ipv4
, hf_router_query_info_send_to_ipv6
, tvb
, offset
, 4, addr_table
);
1296 wccp_add_ipaddress_item(info_tree
, hf_router_query_info_target_ip_index
, hf_router_query_info_target_ipv4
, hf_router_query_info_target_ipv6
, tvb
, offset
, 4, addr_table
);
1302 /* 6.5 Hash Buckets Assignment Element */
1303 static int dissect_wccp2_hash_buckets_assignment_element(tvbuff_t
*tvb
, int offset
, int length
,
1304 packet_info
*pinfo _U_
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1306 uint32_t i
,n_web_caches
;
1308 proto_tree
*element_tree
;
1314 te
= proto_tree_add_item_ret_uint(info_tree
, hf_hash_buckets_assignment_wc_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &n_web_caches
);
1317 element_tree
= proto_item_add_subtree(te
,ett_hash_buckets_assignment_wc_element
);
1318 for (i
= 0; i
< n_web_caches
; i
++) {
1322 return length
- 4*(n_web_caches
-i
)-256;
1324 l_te
= wccp_add_ipaddress_item(element_tree
, hf_hash_buckets_assignment_wc_ip_index
, hf_hash_buckets_assignment_wc_ipv4
, hf_hash_buckets_assignment_wc_ipv6
, tvb
, offset
, 4, addr_table
);
1326 proto_item_append_text(l_te
, " id: %d", i
);
1330 element_tree
= proto_tree_add_subtree(info_tree
,tvb
, offset
, 256, ett_hash_buckets_assignment_buckets
, NULL
, "Buckets");
1332 for (i
= 0; i
< 256; i
++, offset
++, length
--) {
1334 return length
- (256-i
);
1335 bucket
= tvb_get_uint8(tvb
, offset
);
1336 proto_tree_add_uint_format(element_tree
, hf_bucket
, tvb
, offset
, 1,
1337 bucket
, "Bucket %3d: %10s",
1338 i
, assignment_bucket_name(bucket
));
1343 #define WCCP2_FORWARDING_METHOD_GRE 0x00000001
1344 #define WCCP2_FORWARDING_METHOD_L2 0x00000002
1346 static const capability_flag forwarding_method_flags
[] = {
1347 { WCCP2_FORWARDING_METHOD_GRE
, "IP-GRE", &hf_capability_forwarding_method_flag_gre
},
1348 { WCCP2_FORWARDING_METHOD_L2
, "L2", &hf_capability_forwarding_method_flag_l2
},
1352 #define WCCP2_ASSIGNMENT_METHOD_HASH 0x00000001
1353 #define WCCP2_ASSIGNMENT_METHOD_MASK 0x00000002
1355 static const capability_flag assignment_method_flags
[] = {
1356 { WCCP2_ASSIGNMENT_METHOD_HASH
, "Hash", &hf_capability_assignment_method_flag_hash
},
1357 { WCCP2_ASSIGNMENT_METHOD_MASK
, "Mask", &hf_capability_assignment_method_flag_mask
},
1362 #define WCCP2_PACKET_RETURN_METHOD_GRE 0x00000001
1363 #define WCCP2_PACKET_RETURN_METHOD_L2 0x00000002
1365 static const capability_flag packet_return_method_flags
[] = {
1366 { WCCP2_PACKET_RETURN_METHOD_GRE
, "IP-GRE", &hf_capability_return_method_flag_gre
},
1367 { WCCP2_PACKET_RETURN_METHOD_L2
, "L2", &hf_capability_return_method_flag_l2
},
1371 #define WCCP2_COMMAND_TYPE_SHUTDOWN 1
1372 #define WCCP2_COMMAND_TYPE_SHUTDOWN_RESPONSE 2
1374 static const value_string wccp_command_type_vals
[] = {
1375 { WCCP2_COMMAND_TYPE_SHUTDOWN
, "CE shutting down" },
1376 { WCCP2_COMMAND_TYPE_SHUTDOWN_RESPONSE
, "Router Acknowledge CE shutdown"},
1382 /* 5.1.3 Capabilities Info Component */
1385 dissect_wccp2_capability_info(tvbuff_t
*tvb
, int offset
, int length
,
1386 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table _U_
)
1388 int capability_length
;
1390 while (length
>= 8) {
1391 capability_length
= dissect_wccp2_capability_element(tvb
,offset
,length
,pinfo
,info_tree
);
1393 CHECK_LENGTH_ADVANCE_OFFSET(capability_length
);
1399 #define ALT_COMMAND_EXTENSION_MIN_LEN (4)
1401 /* 5.1.4 && 6.12 Command Extension Component */
1404 dissect_wccp2_command_extension(tvbuff_t
*tvb
, int offset
,
1405 int length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1407 uint16_t command_type
;
1408 uint32_t command_length
;
1414 if (length
< ALT_COMMAND_EXTENSION_MIN_LEN
)
1415 return length
- ALT_COMMAND_EXTENSION_MIN_LEN
;
1417 command_type
= tvb_get_ntohs(tvb
, offset
);
1418 proto_tree_add_item(info_tree
, hf_command_element_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1421 proto_tree_add_item_ret_uint(info_tree
, hf_command_element_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &command_length
);
1422 proto_tree_add_item(info_tree
, hf_command_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1425 if (((command_type
== WCCP2_COMMAND_TYPE_SHUTDOWN
) ||
1426 (command_type
== WCCP2_COMMAND_TYPE_SHUTDOWN_RESPONSE
)) &&
1427 (command_length
== 4)) {
1431 wccp_add_ipaddress_item(info_tree
, hf_command_element_shutdown_ip_index
, hf_command_element_shutdown_ipv4
, hf_command_element_shutdown_ipv6
, tvb
, offset
, 4, addr_table
);
1433 if (length
< (int)command_length
)
1434 return length
- command_length
;
1436 proto_tree_add_item(info_tree
, hf_command_unknown
, tvb
, offset
, command_length
, ENC_NA
);
1438 EAT(command_length
);
1443 /* 5.1.5 Address Table Component */
1444 /* this function is special as it can be invoked twice during a packet decode:
1445 once to get the tables, once to display them
1448 dissect_wccp2r1_address_table_info(tvbuff_t
*tvb
, int offset
, int length
,
1449 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* wccp_wccp_address_table
)
1451 uint16_t address_length
;
1454 uint16_t table_length
;
1455 proto_tree
*element_tree
;
1459 return length
- 2*4;
1461 family
= tvb_get_ntohs(tvb
, offset
);
1462 proto_tree_add_item(info_tree
, hf_address_table_family
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1465 address_length
= tvb_get_ntohs(tvb
, offset
);
1466 proto_tree_add_item(info_tree
, hf_address_table_address_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1469 table_length
= tvb_get_ntohl(tvb
, offset
);
1470 tf
= proto_tree_add_item(info_tree
, hf_address_table_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1471 element_tree
= proto_item_add_subtree(tf
, ett_table_element
);
1474 if (wccp_wccp_address_table
->in_use
== false) {
1475 wccp_wccp_address_table
->family
= family
;
1476 wccp_wccp_address_table
->table_length
= table_length
;
1478 /* check if the length is valid and allocate the tables if needed */
1479 switch (wccp_wccp_address_table
->family
) {
1481 if (wccp_wccp_address_table
->table_ipv4
== NULL
)
1482 wccp_wccp_address_table
->table_ipv4
= (uint32_t *)
1483 wmem_alloc0(pinfo
->pool
, wccp_wccp_address_table
->table_length
* 4);
1484 if (address_length
!= 4) {
1485 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
1486 "The Address length must be 4, but I found %d for IPv4 addresses. Correcting this.",
1492 if (wccp_wccp_address_table
->table_ipv6
== NULL
)
1493 wccp_wccp_address_table
->table_ipv6
= (ws_in6_addr
*)
1494 wmem_alloc0(pinfo
->pool
, wccp_wccp_address_table
->table_length
* sizeof(ws_in6_addr
));
1495 if (address_length
!= 16) {
1496 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
1497 "The Address length must be 16, but I found %d for IPv6 addresses. Correcting this.",
1499 address_length
= 16;
1503 expert_add_info_format(pinfo
, tf
, &ei_wccp_address_table_family_unknown
,
1504 "Unknown address family: %d", wccp_wccp_address_table
->family
);
1508 /* now read the addresses and print/store them */
1510 for(i
=0; i
<table_length
; i
++) {
1516 addr
= tvb_ip_to_str(pinfo
->pool
, tvb
, offset
);
1517 if ((wccp_wccp_address_table
->in_use
== false) &&
1518 (wccp_wccp_address_table
->table_ipv4
!= NULL
) &&
1519 (i
< wccp_wccp_address_table
->table_length
))
1520 wccp_wccp_address_table
->table_ipv4
[i
] = tvb_get_ipv4(tvb
, offset
);
1524 addr
= tvb_ip6_to_str(pinfo
->pool
, tvb
, offset
);
1525 if ((wccp_wccp_address_table
->in_use
== false) &&
1526 (wccp_wccp_address_table
->table_ipv6
!= NULL
) &&
1527 (i
< wccp_wccp_address_table
->table_length
))
1528 tvb_get_ipv6(tvb
, offset
, &(wccp_wccp_address_table
->table_ipv6
[i
]));
1531 addr
= wmem_strdup_printf(wmem_packet_scope(), "unknown family %d", wccp_wccp_address_table
->family
);
1537 pi
= proto_tree_add_string_format_value(element_tree
, hf_address_table_element
, tvb
,
1538 offset
, address_length
, addr
,
1539 "%d: %s", i
+1, addr
);
1540 if (i
> wccp_wccp_address_table
->table_length
)
1541 expert_add_info_format(pinfo
, pi
, &ei_wccp_length_bad
, "Ran out of space to store address");
1543 EAT(address_length
);
1546 wccp_wccp_address_table
->in_use
= true;
1554 #define HASH_ASSIGNMENT_INFO_MIN_LEN (4+256)
1556 /* part of 5.6.11 Alternate Assignment Component */
1558 dissect_wccp2_hash_assignment_info(tvbuff_t
*tvb
, int offset
, int length
,
1559 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1561 uint32_t n_web_caches
, host_addr
;
1565 if (length
< HASH_ASSIGNMENT_INFO_MIN_LEN
)
1566 return length
- ASSIGNMENT_INFO_MIN_LEN
;
1568 proto_tree_add_item_ret_uint(info_tree
, hf_wc_view_wc_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &n_web_caches
);
1571 for (i
= 0; i
< n_web_caches
; i
++) {
1573 return length
- 4*(n_web_caches
-i
)-256;
1575 host_addr
= tvb_get_ntohl(tvb
,offset
);
1576 if (! addr_table
->in_use
){
1577 proto_tree_add_ipv4_format(info_tree
, hf_cache_ip
, tvb
, offset
, 4, host_addr
, "Web-Cache %d: IP address %s", i
,
1578 decode_wccp_encoded_address(tvb
, offset
, pinfo
, info_tree
, addr_table
));
1580 proto_tree_add_uint_format(info_tree
, hf_web_cache_identity_index
, tvb
, offset
, 4, host_addr
, "Web-Cache %d: IP address %s", i
,
1581 decode_wccp_encoded_address(tvb
, offset
, pinfo
, info_tree
, addr_table
));
1587 for (i
= 0; i
< 256; i
++, offset
++, length
--) {
1589 return length
- (256-i
);
1590 bucket
= tvb_get_uint8(tvb
, offset
);
1591 proto_tree_add_uint_format(info_tree
, hf_bucket
, tvb
, offset
, 1,
1592 bucket
, "Bucket %3d: %10s",
1593 i
, assignment_bucket_name(bucket
));
1598 /* 5.3.3 Assignment Map Component */
1599 static int dissect_wccp2_assignment_map(tvbuff_t
*tvb
, int offset
,
1600 int length
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1604 new_length
=dissect_wccp2_mask_value_set_list(tvb
, offset
, length
, pinfo
, info_tree
, addr_table
);
1606 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1613 #define ALT_ASSIGNMENT_MAP_MIN_LEN (4)
1615 /* 5.3.4 Alternate Assignment Map Component */
1617 dissect_wccp2r1_alt_assignment_map_info(tvbuff_t
*tvb
, int offset
,
1618 int length
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1620 uint16_t assignment_type
;
1621 uint16_t assignment_length
;
1622 proto_item
*tf
=NULL
;
1624 if (length
< ALT_ASSIGNMENT_MAP_MIN_LEN
)
1625 return length
- ALT_ASSIGNMENT_MAP_MIN_LEN
;
1628 assignment_type
= tvb_get_ntohs(tvb
, offset
);
1629 proto_tree_add_item(info_tree
, hf_alt_assignment_map_assignment_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1632 assignment_length
= tvb_get_ntohs(tvb
, offset
);
1633 tf
=proto_tree_add_item(info_tree
, hf_alt_assignment_map_assignment_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1636 if (length
< assignment_length
)
1637 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
1638 "Assignment length is %d but only %d remain in the packet. Ignoring this for now",
1639 assignment_length
, length
);
1641 if (length
> assignment_length
) {
1642 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
1643 "Assignment length is %d but %d remain in the packet. Assuming that the assignment length is wrong and setting it to %d.",
1644 assignment_length
, length
, length
);
1645 assignment_length
= length
;
1648 switch (assignment_type
) {
1649 case WCCP2_HASH_ASSIGNMENT_TYPE
:
1650 return dissect_wccp2_assignment_info(tvb
, offset
, assignment_length
,
1651 pinfo
, info_tree
, addr_table
);
1652 case WCCP2_MASK_ASSIGNMENT_TYPE
:
1653 return dissect_wccp2_mask_value_set_list(tvb
, offset
, assignment_length
,
1654 pinfo
, info_tree
, addr_table
);
1655 case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
:
1656 return dissect_wccp2_alternate_mask_value_set_list(tvb
, offset
, assignment_length
,
1657 pinfo
, info_tree
, addr_table
);
1667 /* 6.6 Hash Assignment Data Element */
1669 dissect_wccp2_hash_assignment_data_element(tvbuff_t
*tvb
, int offset
, int length
,
1670 packet_info
*pinfo _U_
,
1671 proto_tree
*info_tree
)
1674 proto_tree
*bucket_tree
;
1676 uint8_t bucket_info
;
1680 bucket_tree
= proto_tree_add_subtree(info_tree
, tvb
, offset
, 8*4,
1681 ett_hash_assignment_buckets
, NULL
, "Hash Assignment Data");
1683 for (i
= 0, n
= 0; i
< 32; i
++) {
1688 bucket_info
= tvb_get_uint8(tvb
, offset
);
1689 n
= wccp_bucket_info(bucket_info
, bucket_tree
, n
, tvb
, offset
);
1697 return dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, length
, pinfo
, info_tree
);
1700 /* 6.7 Mask Assignment Data Element */
1702 dissect_wccp2_mask_assignment_data_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
1703 proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1706 proto_item
*mask_item
;
1707 proto_tree
*mask_tree
;
1708 int new_length
,start
;
1711 mask_tree
= proto_tree_add_subtree(info_tree
, tvb
, offset
, 4,
1712 ett_mask_assignment_data_element
, &mask_item
, "Mask Assignment Data");
1715 new_length
=dissect_wccp2_mask_value_set_list(tvb
, offset
, length
, pinfo
, mask_tree
, addr_table
);
1717 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1722 new_length
= dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, length
, pinfo
, info_tree
);
1723 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1725 proto_item_set_len(mask_item
, offset
-start
);
1730 /* 5.7.5 Alternate Mask Assignment Data Element */
1732 dissect_wccp2_alternate_mask_assignment_data_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
1733 proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1735 proto_tree
*mask_tree
;
1737 mask_tree
= proto_tree_add_subtree(info_tree
, tvb
, offset
, length
,
1738 ett_alternate_mask_assignment_data_element
, NULL
, "Alternate Mask Assignment Data");
1748 new_length
=dissect_wccp2_alternate_mask_value_set_list(tvb
, offset
, length
, pinfo
, mask_tree
, addr_table
);
1750 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1756 return dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, length
, pinfo
, info_tree
);
1760 /* 6.9 Assignment Weight and Status Data Element */
1762 dissect_wccp2_assignment_weight_and_status_element(tvbuff_t
*tvb
, int offset
, int length
,
1763 packet_info
*pinfo _U_
,
1764 proto_tree
*info_tree
)
1771 proto_tree_add_item(info_tree
, hf_assignment_weight
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1773 proto_tree_add_item(info_tree
, hf_assignment_status
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1779 /* 6.10 Extended Assignment Data Element */
1781 dissect_wccp2_extended_assignment_data_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo
,
1782 proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1784 proto_item
*element_item
, *header
;
1785 proto_tree
*item_tree
;
1787 unsigned type_of_assignment
;
1789 int assignment_length
;
1795 item_tree
= proto_tree_add_subtree(info_tree
, tvb
, offset
, length
,
1796 ett_extended_assigment_data_element
, &header
, "Extended Assignment Data Element");
1798 type_of_assignment
= tvb_get_ntohs(tvb
, offset
);
1799 proto_tree_add_item(item_tree
, hf_extended_assignment_data_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1802 assignment_length
= tvb_get_ntohs(tvb
,offset
);
1803 element_item
= proto_tree_add_item(item_tree
, hf_extended_assignment_data_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1806 if (length
< assignment_length
)
1807 expert_add_info_format(pinfo
, element_item
, &ei_wccp_assignment_length_bad
,
1808 "Assignment length is %d but only %d remain in the packet. Ignoring this for now",
1809 assignment_length
, length
);
1811 /* Now a common bug seems to be to set the assignment_length to the length -4
1813 if ((length
> assignment_length
) &&
1814 (length
== (assignment_length
+ 4)))
1816 expert_add_info_format(pinfo
, element_item
, &ei_wccp_assignment_length_bad
,
1817 "Assignment length is %d but %d remain in the packet. Assuming that this is wrong as this is only 4 bytes too small, proceeding with the assumption it is %d",
1818 assignment_length
, length
, length
);
1819 assignment_length
= length
;
1823 proto_item_set_len(header
, assignment_length
+4);
1825 switch (type_of_assignment
)
1827 case WCCP2_HASH_ASSIGNMENT_TYPE
:
1828 dissect_wccp2_hash_assignment_data_element(tvb
, offset
, assignment_length
,
1830 return length
- assignment_length
;
1831 case WCCP2_MASK_ASSIGNMENT_TYPE
:
1832 dissect_wccp2_mask_assignment_data_element(tvb
, offset
, assignment_length
,
1833 pinfo
, item_tree
, addr_table
);
1834 return length
- assignment_length
;
1835 case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
:
1836 dissect_wccp2_alternate_mask_assignment_data_element(tvb
, offset
, assignment_length
,
1837 pinfo
, item_tree
, addr_table
);
1838 return length
- assignment_length
;
1839 case WCCP2r1_ASSIGNMENT_WEIGHT_STATUS
:
1840 dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, assignment_length
,
1842 return length
- assignment_length
;
1852 /* 6.11 Capability Element */
1854 dissect_wccp2_capability_element(tvbuff_t
*tvb
, int offset
, int length
,
1855 packet_info
*pinfo
, proto_tree
*info_tree
)
1857 uint16_t capability_type
;
1858 uint16_t capability_val_len
;
1859 proto_item
*te
, *header
, *tf
;
1860 proto_tree
*element_tree
;
1865 capability_type
= tvb_get_ntohs(tvb
, offset
);
1866 element_tree
= proto_tree_add_subtree_format(info_tree
, tvb
, offset
, -1, ett_capability_element
, &te
,
1868 val_to_str(capability_type
,
1869 capability_type_vals
,
1870 "Unknown (0x%08X)"));
1873 proto_tree_add_item(element_tree
, hf_capability_element_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1875 capability_val_len
= tvb_get_ntohs(tvb
, offset
+2);
1876 tf
= proto_tree_add_uint(element_tree
, hf_capability_element_length
, tvb
, offset
+2, 2, capability_val_len
);
1877 proto_item_set_len(te
, capability_val_len
+ 4);
1879 if (length
< (4+capability_val_len
))
1880 return length
- (4 + capability_val_len
);
1882 switch (capability_type
) {
1883 case WCCP2_FORWARDING_METHOD
:
1884 dissect_32_bit_capability_flags(tvb
, offset
,
1886 ett_capability_forwarding_method
,
1887 forwarding_method_flags
, element_tree
,
1891 case WCCP2_ASSIGNMENT_METHOD
:
1892 dissect_32_bit_capability_flags(tvb
, offset
,
1894 ett_capability_assignment_method
,
1895 assignment_method_flags
, element_tree
,
1899 case WCCP2_PACKET_RETURN_METHOD
:
1900 dissect_32_bit_capability_flags(tvb
, offset
,
1902 ett_capability_return_method
,
1903 packet_return_method_flags
, element_tree
,
1907 case WCCP2_TRANSMIT_T
:
1908 dissect_transmit_t_capability(tvb
, te
, offset
,
1910 ett_capability_transmit_t
, element_tree
,
1914 case WCCP2_TIMER_SCALE
:
1915 dissect_timer_scale_capability(tvb
, offset
,
1917 ett_capability_timer_scale
, element_tree
,
1921 proto_tree_add_item(element_tree
, hf_capability_value
, tvb
, offset
, capability_val_len
, ENC_NA
);
1924 return length
- 4 - capability_val_len
;
1928 /* 6.13 Mask/Value Set List */
1930 dissect_wccp2_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
1931 int length
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1933 unsigned num_of_elem
;
1936 proto_tree
*element_tree
;
1943 element_tree
= proto_tree_add_subtree(info_tree
, tvb
, offset
, 4, ett_mv_set_list
, &te
, "Mask/Value Set List");
1947 num_of_elem
= tvb_get_ntohl(tvb
, offset
);
1948 proto_tree_add_item(element_tree
, hf_mask_value_set_list_num_elements
,
1949 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1950 /* proto_tree_add_uint(element_tree, , tvb, offset, 4, num_of_elem); */
1953 for (i
= 0; i
< num_of_elem
; i
++)
1957 new_length
=dissect_wccp2_mask_value_set_element(tvb
, offset
, length
, i
, pinfo
, element_tree
, addr_table
);
1959 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
1962 proto_item_set_len(te
, offset
-start
);
1970 /* 6.15 Mask Element */
1972 dissect_wccp2_mask_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
)
1977 proto_tree_add_item(info_tree
, hf_mask_element_src_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1979 proto_tree_add_item(info_tree
, hf_mask_element_dest_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1982 proto_tree_add_item(info_tree
, hf_mask_element_src_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1984 proto_tree_add_item(info_tree
, hf_mask_element_dest_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1995 /* 6.17 Alternate Mask/Value Set List */
1996 static int dissect_wccp2_alternate_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
1997 int length
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
1999 proto_tree
*list_tree
;
2000 unsigned num_of_val_elements
;
2006 list_tree
= proto_tree_add_subtree(info_tree
, tvb
, offset
, length
,
2007 ett_alternate_mask_value_set
, NULL
, "Alternate Mask/Value Set List");
2009 num_of_val_elements
= tvb_get_ntohl(tvb
, offset
);
2010 proto_tree_add_uint(list_tree
, hf_alt_assignment_mask_value_set_list_num_elements
, tvb
, offset
, 4, num_of_val_elements
);
2013 for(i
=0;i
<num_of_val_elements
;i
++) {
2016 new_length
=dissect_wccp2_alternate_mask_value_set_element(tvb
, offset
, length
, i
, pinfo
, list_tree
, addr_table
);
2018 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
2024 /* 6.18 Alternate Mask/Value Set Element */
2026 dissect_wccp2_alternate_mask_value_set_element(tvbuff_t
*tvb
, int offset
, int length
, unsigned el_index
, packet_info
*pinfo
,
2027 proto_tree
*info_tree
, wccp_address_table
* addr_table
)
2029 proto_item
*tl
, *header
;
2030 proto_tree
*element_tree
, *value_tree
;
2031 unsigned number_of_elements
;
2032 int new_length
, total_length
;
2035 element_tree
= proto_tree_add_subtree_format(info_tree
, tvb
, offset
, 0,
2036 ett_alternate_mask_value_set_element
, &header
,
2037 "Alternate Mask/Value Set Element(%d)", el_index
);
2041 new_length
=dissect_wccp2_mask_element(tvb
,offset
,length
,pinfo
,element_tree
);
2042 total_length
+= length
- new_length
;
2043 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
2048 number_of_elements
= tvb_get_ntohl(tvb
, offset
);
2049 tl
= proto_tree_add_uint(element_tree
, hf_alt_assignment_mask_value_set_element_num_wc_value_elements
, tvb
, offset
, 4, number_of_elements
);
2050 value_tree
= proto_item_add_subtree(tl
, ett_alternate_mv_set_element_list
);
2054 /* XXX Add a bounds check for number_of_elements? */
2055 for (i
=0; i
< number_of_elements
; i
++) {
2056 new_length
=dissect_wccp2_web_cache_value_element(tvb
, offset
, length
, pinfo
, value_tree
, addr_table
);
2057 total_length
+= length
- new_length
;
2058 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
2060 proto_item_set_len(header
, total_length
);
2065 /* 6.19 Web-Cache Value Element */
2067 dissect_wccp2_web_cache_value_element(tvbuff_t
*tvb
, int offset
, int length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
2069 unsigned number_of_elements
, seq_num
;
2071 proto_tree
*element_tree
;
2077 tl
= wccp_add_ipaddress_item(info_tree
, hf_web_cache_value_element_wc_address_index
, hf_web_cache_value_element_wc_address_ipv4
, hf_web_cache_value_element_wc_address_ipv6
, tvb
, offset
, 4, addr_table
);
2079 element_tree
= proto_item_add_subtree(tl
, ett_web_cache_value_element_list
);
2082 number_of_elements
= tvb_get_ntohl(tvb
, offset
);
2083 proto_tree_add_uint(element_tree
, hf_web_cache_value_element_num_values
, tvb
, offset
, 4, number_of_elements
);
2086 for (i
=0; i
< number_of_elements
; i
++) {
2088 return length
- 4*(number_of_elements
-i
);
2090 seq_num
= tvb_get_ntohl(tvb
, offset
);
2091 proto_tree_add_uint_format(element_tree
, hf_web_cache_value_seq_num
, tvb
, offset
, 4,
2092 seq_num
, "Value Sequence Number %d: %x", i
+1, seq_num
);
2100 /* End of standard functions */
2104 dissect_32_bit_capability_flags(tvbuff_t
*tvb
, int curr_offset
,
2105 uint16_t capability_val_len
, int ett
, const capability_flag
*flags
,
2106 proto_tree
*element_tree
, proto_item
*header
,
2107 proto_item
*length_item
, packet_info
*pinfo
)
2109 uint32_t capability_val
;
2111 proto_tree
*method_tree
;
2115 if (capability_val_len
!= 4) {
2116 expert_add_info_format(pinfo
, length_item
, &ei_wccp_capability_element_length
,
2117 "Value Length: %u (illegal, must be == 4)", capability_val_len
);
2121 capability_val
= tvb_get_ntohl(tvb
, curr_offset
+ 4);
2122 tm
= proto_tree_add_uint(element_tree
, hf_capability_info_value
, tvb
, curr_offset
+ 4, 4, capability_val
);
2124 for (i
= 0; flags
[i
].short_name
!= NULL
; i
++) {
2125 if (capability_val
& flags
[i
].value
) {
2127 proto_item_append_text( tm
, " (%s", flags
[i
].short_name
);
2128 proto_item_append_text( header
, " (%s", flags
[i
].short_name
);
2131 proto_item_append_text( tm
, ", %s", flags
[i
].short_name
);
2132 proto_item_append_text( header
, " (%s", flags
[i
].short_name
);
2137 if (first
== false) {
2138 proto_item_append_text( tm
, ")");
2139 proto_item_append_text( header
, ")");
2142 method_tree
= proto_item_add_subtree(tm
, ett
);
2143 for (i
= 0; flags
[i
].phf
!= NULL
; i
++)
2144 proto_tree_add_item(method_tree
, *(flags
[i
].phf
), tvb
, curr_offset
+4, 4, ENC_BIG_ENDIAN
);
2149 /* 6.11.4 Capability Type WCCP2_TRANSMIT_T */
2151 dissect_transmit_t_capability(tvbuff_t
*tvb
, proto_item
*te
, int curr_offset
,
2152 uint16_t capability_val_len
, int ett
, proto_tree
*element_tree
,
2153 proto_item
*length_item
, packet_info
*pinfo
)
2155 uint16_t upper_limit
, lower_limit
;
2156 proto_tree
*method_tree
;
2158 if (capability_val_len
!= 4) {
2159 expert_add_info_format(pinfo
, length_item
, &ei_wccp_capability_element_length
,
2160 "Value Length: %u (illegal, must be == 4)", capability_val_len
);
2164 upper_limit
= tvb_get_ntohs(tvb
, curr_offset
);
2165 lower_limit
= tvb_get_ntohs(tvb
, curr_offset
+ 2);
2167 if ( upper_limit
== 0) {
2168 method_tree
= proto_tree_add_subtree(element_tree
, tvb
, curr_offset
, 2,
2169 ett
, NULL
, "Only accepting one value");
2170 proto_tree_add_uint(method_tree
, hf_reserved_zero
, tvb
, curr_offset
, 2, upper_limit
);
2172 proto_tree_add_item(method_tree
, hf_capability_transmit_t
, tvb
, curr_offset
+2, 2, ENC_BIG_ENDIAN
);
2173 proto_item_append_text(te
, " %d ms", lower_limit
);
2175 method_tree
= proto_tree_add_subtree(element_tree
, tvb
, curr_offset
, 2,
2176 ett
, NULL
, "Accepting a range");
2177 proto_tree_add_item(method_tree
, hf_capability_transmit_t_upper_limit
,
2178 tvb
, curr_offset
, 2, ENC_BIG_ENDIAN
);
2180 proto_tree_add_item(method_tree
, hf_capability_transmit_t_lower_limit
,
2181 tvb
, curr_offset
+2, 2, ENC_BIG_ENDIAN
);
2182 proto_item_append_text(te
, " < %d ms > %d ms", lower_limit
, upper_limit
);
2188 dissect_timer_scale_capability(tvbuff_t
*tvb
, int curr_offset
,
2189 uint16_t capability_val_len
, int ett
, proto_tree
*element_tree
,
2190 proto_item
*length_item
, packet_info
*pinfo
)
2193 proto_tree
*method_tree
;
2195 if (capability_val_len
!= 4) {
2196 expert_add_info_format(pinfo
, length_item
, &ei_wccp_capability_element_length
,
2197 "Value Length: %u (illegal, must be == 4)", capability_val_len
);
2201 a
= tvb_get_uint8(tvb
, curr_offset
);
2202 c
= tvb_get_uint8(tvb
, curr_offset
+2);
2206 method_tree
= proto_tree_add_subtree(element_tree
, tvb
, curr_offset
, 2,
2207 ett
, NULL
, "Only accepting one value");
2209 proto_tree_add_uint(method_tree
, hf_reserved_zero
, tvb
, curr_offset
, 1, a
);
2211 proto_tree_add_item(method_tree
, hf_capability_timer_scale_timeout_scale
,
2212 tvb
, curr_offset
+1, 1, ENC_BIG_ENDIAN
);
2213 proto_tree_add_uint(method_tree
, hf_reserved_zero
, tvb
, curr_offset
+2, 1, c
);
2214 proto_tree_add_item(method_tree
, hf_capability_timer_scale_ra_timer_scale
,
2215 tvb
, curr_offset
+3, 1, ENC_BIG_ENDIAN
);
2217 proto_tree_add_expert(element_tree
, pinfo
, &ei_wccp_a_zero_not_c
, tvb
, curr_offset
, 1);
2221 proto_tree_add_expert(element_tree
, pinfo
, &ei_wccp_a_zero_not_c
, tvb
, curr_offset
, 1);
2223 method_tree
= proto_tree_add_subtree(element_tree
, tvb
, curr_offset
, 2,
2224 ett
, NULL
, "Accepting a range");
2225 proto_tree_add_item(method_tree
, hf_capability_timer_scale_timeout_scale_upper_limit
,
2226 tvb
, curr_offset
, 1, ENC_BIG_ENDIAN
);
2228 proto_tree_add_item(method_tree
, hf_capability_timer_scale_timeout_scale_lower_limit
,
2229 tvb
, curr_offset
+1, 1, ENC_BIG_ENDIAN
);
2230 proto_tree_add_item(method_tree
, hf_capability_timer_scale_ra_scale_upper_limit
,
2231 tvb
, curr_offset
+2, 1, ENC_BIG_ENDIAN
);
2232 proto_tree_add_item(method_tree
, hf_capability_timer_scale_ra_scale_lower_limit
,
2233 tvb
, curr_offset
+3, 1, ENC_BIG_ENDIAN
);
2239 /* 6.16 Value Element */
2241 dissect_wccp2_value_element(tvbuff_t
*tvb
, int offset
, int length
, int idx
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
2243 proto_tree
*element_tree
;
2248 element_tree
= proto_tree_add_subtree_format(info_tree
, tvb
, offset
, 16, ett_value_element
, NULL
, "Value Element(%u) %s",
2249 idx
,decode_wccp_encoded_address(tvb
, offset
+4+4+2+2, pinfo
, info_tree
, addr_table
));
2252 wccp_add_ipaddress_item(info_tree
, hf_value_element_src_ip_index
, hf_value_element_src_ipv4
, hf_value_element_src_ipv6
, tvb
, offset
, 4, addr_table
);
2254 wccp_add_ipaddress_item(info_tree
, hf_value_element_dest_ip_index
, hf_value_element_dest_ipv4
, hf_value_element_dest_ipv6
, tvb
, offset
, 4, addr_table
);
2257 proto_tree_add_item(element_tree
, hf_value_element_src_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2259 proto_tree_add_item(element_tree
, hf_value_element_dest_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2262 wccp_add_ipaddress_item(info_tree
, hf_value_element_web_cache_ip_index
, hf_value_element_web_cache_ipv4
, hf_value_element_web_cache_ipv6
, tvb
, offset
, 4, addr_table
);
2269 /* 6.14 Mask/Value Set Element */
2271 dissect_wccp2_mask_value_set_element(tvbuff_t
*tvb
, int offset
, int length
, int idx
, packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
2273 proto_item
*tl
, *te
;
2274 proto_tree
*element_tree
, *value_tree
;
2275 unsigned num_of_val_elements
;
2279 element_tree
= proto_tree_add_subtree_format(info_tree
, tvb
, offset
, 0,
2280 ett_mv_set_element
, &tl
, "Mask/Value Set Element(%d)", idx
);
2282 new_length
= dissect_wccp2_mask_element(tvb
,offset
,length
,pinfo
,element_tree
);
2283 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
2288 num_of_val_elements
= tvb_get_ntohl(tvb
, offset
);
2289 te
= proto_tree_add_uint(element_tree
, hf_mask_value_set_element_value_element_num
, tvb
, offset
, 4, num_of_val_elements
);
2291 value_tree
= proto_item_add_subtree(te
, ett_mv_set_value_list
);
2294 for (i
= 0; i
< num_of_val_elements
; i
++)
2296 new_length
=dissect_wccp2_value_element(tvb
, offset
, length
, i
, pinfo
, value_tree
, addr_table
);
2298 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
2301 proto_item_set_len(tl
, 16+num_of_val_elements
*16);
2306 #define ALT_ASSIGNMENT_INFO_MIN_LEN (4+4)
2308 /* 5.4.2 Alternate Assignment Component */
2310 dissect_wccp2_alternate_assignment_info(tvbuff_t
*tvb
, int offset
, int length
,
2311 packet_info
*pinfo
, proto_tree
*info_tree
, wccp_address_table
* addr_table
)
2313 uint16_t assignment_type
;
2314 uint16_t assignment_length
;
2315 proto_item
*tf
=NULL
;
2319 proto_tree
*element_tree
;
2323 if (length
< ALT_ASSIGNMENT_INFO_MIN_LEN
)
2324 return length
- ALT_ASSIGNMENT_INFO_MIN_LEN
;
2327 assignment_type
= tvb_get_ntohs(tvb
, offset
);
2328 proto_tree_add_item(info_tree
, hf_alt_assignment_info_assignment_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2331 assignment_length
= tvb_get_ntohs(tvb
, offset
);
2332 tf
=proto_tree_add_item(info_tree
, hf_alt_assignment_info_assignment_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2335 if (length
< assignment_length
)
2336 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
2337 "Assignment length is %d but only %d remain in the packet. Ignoring this for now",
2338 assignment_length
, length
);
2340 if (length
> assignment_length
) {
2341 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
2342 "Assignment length is %d but %d remain in the packet. Assuming that the assignment length is wrong and setting it to %d.",
2343 assignment_length
, length
, length
);
2346 new_length
=dissect_wccp2_assignment_key_element(tvb
, offset
, length
, pinfo
, info_tree
, addr_table
);
2347 CHECK_LENGTH_ADVANCE_OFFSET(new_length
);
2349 n_routers
= tvb_get_ntohl(tvb
, offset
);
2350 proto_tree_add_uint(info_tree
, hf_alt_assignment_info_num_routers
, tvb
, offset
, 4, n_routers
);
2353 for (i
= 0; i
< n_routers
; i
++) {
2355 return length
- 12*(n_routers
-i
);
2357 element_tree
= proto_tree_add_subtree_format(info_tree
, tvb
, offset
, 12,
2358 ett_router_alt_assignment_element
, NULL
,
2359 "Router %d Assignment Element: IP address %s", i
,
2360 decode_wccp_encoded_address(tvb
, offset
, pinfo
, info_tree
, addr_table
));
2362 dissect_wccp2_router_assignment_element(tvb
, offset
, length
, pinfo
, element_tree
, addr_table
);
2366 switch (assignment_type
) {
2367 case WCCP2_HASH_ASSIGNMENT_TYPE
:
2368 return dissect_wccp2_hash_assignment_info(tvb
, offset
, length
,
2369 pinfo
, info_tree
, addr_table
);
2370 case WCCP2_MASK_ASSIGNMENT_TYPE
:
2371 return dissect_wccp2_mask_value_set_list(tvb
, offset
, length
,
2372 pinfo
, info_tree
, addr_table
);
2373 case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
:
2374 return dissect_wccp2_alternate_mask_value_set_list(tvb
, offset
, length
,
2375 pinfo
, info_tree
, addr_table
);
2382 dissect_wccp2_info(tvbuff_t
*tvb
, int offset
,
2383 packet_info
*pinfo
, proto_tree
*wccp_tree
,
2384 uint32_t message_type
)
2387 uint16_t item_length
;
2389 proto_tree
*info_tree
;
2391 int (*dissector
)(tvbuff_t
*, int, int, packet_info
*, proto_tree
*, wccp_address_table
*);
2393 /* check if all required fields are there */
2394 bool wccp2_security_info
;
2395 bool wccp2_service_info
;
2396 bool wccp2_router_id_info
;
2397 bool wccp2_wc_id_info
;
2398 bool wccp2_rtr_view_info
;
2399 bool wccp2_wc_view_info
;
2400 bool wccp2_redirect_assignment
;
2401 bool wccp2_query_info
;
2402 bool wccp2_capabilities_info
;
2403 bool wccp2_alt_assignment
;
2404 bool wccp2_assign_map
;
2405 bool wccp2_command_extension
;
2406 bool wccp2r1_alt_assignment_map
;
2407 wccp_address_table wccp_wccp_address_table
= {false, -1, -1, 0, NULL
, NULL
};
2409 wccp2_security_info
=false;
2410 wccp2_service_info
=false;
2411 wccp2_router_id_info
=false;
2412 wccp2_wc_id_info
=false;
2413 wccp2_rtr_view_info
=false;
2414 wccp2_wc_view_info
=false;
2415 wccp2_redirect_assignment
=false;
2416 wccp2_query_info
=false;
2417 wccp2_capabilities_info
=false;
2418 wccp2_alt_assignment
=false;
2419 wccp2_assign_map
=false;
2420 wccp2_command_extension
=false;
2421 wccp2r1_alt_assignment_map
=false;
2423 /* ugly hack: we first need to check for the address table
2424 component, otherwise we cannot print the IP's.
2426 find_wccp_address_table(tvb
,offset
,pinfo
,wccp_tree
, &wccp_wccp_address_table
);
2428 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2429 type
= tvb_get_ntohs(tvb
, offset
);
2432 case WCCP2_SECURITY_INFO
:
2433 wccp2_security_info
=true;
2434 ett
= ett_security_info
;
2435 dissector
= dissect_wccp2_security_info
;
2438 case WCCP2_SERVICE_INFO
:
2439 wccp2_service_info
=true;
2440 ett
= ett_service_info
;
2441 dissector
= dissect_wccp2_service_info
;
2444 case WCCP2_ROUTER_ID_INFO
:
2445 wccp2_router_id_info
=true;
2446 ett
= ett_router_identity_info
;
2447 dissector
= dissect_wccp2_router_identity_info
;
2450 case WCCP2_WC_ID_INFO
:
2451 wccp2_wc_id_info
=true;
2452 ett
= ett_wc_identity_info
;
2453 dissector
= dissect_wccp2_wc_identity_info
;
2456 case WCCP2_RTR_VIEW_INFO
:
2457 wccp2_rtr_view_info
=true;
2458 ett
= ett_router_view_info
;
2459 dissector
= dissect_wccp2_router_view_info
;
2462 case WCCP2_WC_VIEW_INFO
:
2463 wccp2_wc_view_info
=true;
2464 ett
= ett_wc_view_info
;
2465 dissector
= dissect_wccp2_web_cache_view_info
;
2468 case WCCP2_REDIRECT_ASSIGNMENT
:
2469 wccp2_redirect_assignment
=true;
2470 ett
= ett_router_assignment_info
;
2471 dissector
= dissect_wccp2_assignment_info
;
2474 case WCCP2_QUERY_INFO
:
2475 wccp2_query_info
=true;
2476 ett
= ett_query_info
;
2477 dissector
= dissect_wccp2_router_query_info
;
2480 case WCCP2_CAPABILITIES_INFO
:
2481 wccp2_capabilities_info
=true;
2482 ett
= ett_capabilities_info
;
2483 dissector
= dissect_wccp2_capability_info
;
2486 case WCCP2_ALT_ASSIGNMENT
:
2487 wccp2_alt_assignment
=true;
2488 ett
= ett_alt_assignment_info
;
2489 dissector
= dissect_wccp2_alternate_assignment_info
;
2492 case WCCP2r1_ALT_ASSIGNMENT_MAP
:
2493 wccp2r1_alt_assignment_map
=true;
2494 ett
= ett_alt_assignment_map
;
2495 dissector
= dissect_wccp2r1_alt_assignment_map_info
;
2498 case WCCP2r1_ADDRESS_TABLE
:
2499 ett
= ett_address_table
;
2500 dissector
= dissect_wccp2r1_address_table_info
;
2503 case WCCP2_ASSIGN_MAP
:
2504 wccp2_assign_map
=true;
2505 ett
= ett_assignment_map
;
2506 dissector
= dissect_wccp2_assignment_map
;
2508 case WCCP2_COMMAND_EXTENSION
:
2509 wccp2_command_extension
=true;
2510 ett
= ett_command_extension
;
2511 dissector
= dissect_wccp2_command_extension
;
2515 ett
= ett_unknown_info
;
2520 info_tree
= proto_tree_add_subtree(wccp_tree
, tvb
, offset
, -1, ett
, &tf
,
2521 val_to_str(type
, info_type_vals
, "Unknown info type (%u)"));
2523 proto_tree_add_item(info_tree
, hf_item_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2525 item_length
= tvb_get_ntohs(tvb
, offset
+2);
2526 proto_tree_add_item(info_tree
, hf_item_length
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
2530 if (dissector
!= NULL
) {
2531 int remaining_item_length
= (*dissector
)(tvb
, offset
, item_length
, pinfo
, info_tree
, &wccp_wccp_address_table
);
2533 /* warn if we left bytes */
2534 if (remaining_item_length
> 0)
2535 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
2536 "The item is %d bytes too long",
2537 remaining_item_length
);
2539 /* error if we needed more bytes */
2540 if (remaining_item_length
< 0)
2541 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
2542 "The item is %d bytes too short",
2543 -remaining_item_length
);
2545 /* we assume that the item length is correct and jump forward */
2547 proto_tree_add_item(info_tree
, hf_item_data
, tvb
, offset
, item_length
, ENC_NA
);
2550 offset
+= item_length
;
2551 proto_item_set_end(tf
, tvb
, offset
);
2555 /* we're done. Check if we got all the required components */
2557 switch (message_type
) {
2558 case WCCP2_HERE_I_AM
:
2559 if (!wccp2_security_info
)
2560 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
2561 if (!wccp2_service_info
)
2562 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
2563 if (wccp2_router_id_info
)
2564 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_router_id_info
);
2565 if (!wccp2_wc_id_info
)
2566 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_wc_id_info
);
2567 if (wccp2_rtr_view_info
)
2568 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_rtr_view_info
);
2569 if (!wccp2_wc_view_info
)
2570 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_wc_view_info
);
2571 if (wccp2_redirect_assignment
)
2572 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_redirect_assignment
);
2573 if (wccp2_query_info
)
2574 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_query_info
);
2575 if (wccp2_alt_assignment
)
2576 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment
);
2577 if (wccp2_assign_map
)
2578 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_assign_map
);
2579 if (wccp2r1_alt_assignment_map
)
2580 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment_map
);
2582 case WCCP2_I_SEE_YOU
:
2583 if (!wccp2_security_info
)
2584 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
2585 if (!wccp2_service_info
)
2586 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
2587 if (!wccp2_router_id_info
)
2588 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_router_id_info
);
2589 if (wccp2_wc_id_info
)
2590 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_id_info
);
2591 if (!wccp2_rtr_view_info
)
2592 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_rtr_view_info
);
2593 if (wccp2_wc_view_info
)
2594 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_view_info
);
2595 if (wccp2_redirect_assignment
)
2596 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_redirect_assignment
);
2597 if (wccp2_query_info
)
2598 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_query_info
);
2599 if (wccp2r1_alt_assignment_map
)
2600 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment_map
);
2603 case WCCP2_REMOVAL_QUERY
:
2604 if (!wccp2_security_info
)
2605 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
2606 if (!wccp2_service_info
)
2607 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
2608 if (wccp2_router_id_info
)
2609 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_router_id_info
);
2610 if (wccp2_wc_id_info
)
2611 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_id_info
);
2612 if (wccp2_rtr_view_info
)
2613 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_rtr_view_info
);
2614 if (wccp2_wc_view_info
)
2615 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_view_info
);
2616 if (wccp2_redirect_assignment
)
2617 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_redirect_assignment
);
2618 if (!wccp2_query_info
)
2619 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_query_info
);
2620 if (wccp2_capabilities_info
)
2621 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_capabilities_info
);
2622 if (wccp2_alt_assignment
)
2623 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment
);
2624 if (wccp2_assign_map
)
2625 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_assign_map
);
2626 if (wccp2_command_extension
)
2627 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_command_extension
);
2628 if (wccp2r1_alt_assignment_map
)
2629 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment_map
);
2632 case WCCP2_REDIRECT_ASSIGN
:
2633 if (!wccp2_security_info
)
2634 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
2635 if (!wccp2_service_info
)
2636 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
2637 if (wccp2_router_id_info
)
2638 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_router_id_info
);
2639 if (wccp2_wc_id_info
)
2640 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_id_info
);
2641 if (wccp2_rtr_view_info
)
2642 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_rtr_view_info
);
2643 if (wccp2_wc_view_info
)
2644 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_view_info
);
2645 if (wccp2_query_info
)
2646 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_query_info
);
2647 if (wccp2_capabilities_info
)
2648 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_capabilities_info
);
2649 if (! (wccp2_assign_map
|| wccp2r1_alt_assignment_map
|| wccp2_alt_assignment
|| wccp2_redirect_assignment
))
2650 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_assignment
);
2651 if (wccp2_command_extension
)
2652 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_command_extension
);
2658 dissect_wccp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
2661 proto_tree
*wccp_tree
= NULL
;
2662 proto_item
*wccp_tree_item
;
2663 uint32_t wccp_message_type
;
2666 proto_item
*length_item
;
2667 uint32_t cache_count
;
2672 wccp_message_type
= tvb_get_ntohl(tvb
, offset
);
2674 /* Check if this is really a WCCP message */
2675 if (try_val_to_str(wccp_message_type
, wccp_type_vals
) == NULL
)
2678 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "WCCP");
2680 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(wccp_message_type
,
2681 wccp_type_vals
, "Unknown WCCP message (%u)"));
2683 wccp_tree_item
= proto_tree_add_item(tree
, proto_wccp
, tvb
, offset
, -1, ENC_NA
);
2684 wccp_tree
= proto_item_add_subtree(wccp_tree_item
, ett_wccp
);
2686 proto_tree_add_uint(wccp_tree
, hf_wccp_message_type
, tvb
, offset
, 4, wccp_message_type
);
2689 switch (wccp_message_type
) {
2691 case WCCP_HERE_I_AM
:
2692 proto_tree_add_item(wccp_tree
, hf_wccp_version
, tvb
,
2693 offset
, 4, ENC_BIG_ENDIAN
);
2695 offset
= dissect_hash_data(tvb
, offset
, wccp_tree
);
2696 proto_tree_add_item(wccp_tree
, hf_recvd_id
, tvb
, offset
,
2701 case WCCP_I_SEE_YOU
:
2702 proto_tree_add_item(wccp_tree
, hf_wccp_version
, tvb
,
2703 offset
, 4, ENC_BIG_ENDIAN
);
2705 proto_tree_add_item(wccp_tree
, hf_change_num
, tvb
, offset
,
2708 proto_tree_add_item(wccp_tree
, hf_recvd_id
, tvb
, offset
,
2711 cache_count
= tvb_get_ntohl(tvb
, offset
);
2712 proto_tree_add_uint(wccp_tree
, hf_wc_num
, tvb
, offset
, 4, cache_count
);
2714 for (i
= 0; i
< cache_count
; i
++) {
2715 offset
= dissect_web_cache_list_entry(tvb
, offset
, i
,
2720 case WCCP_ASSIGN_BUCKET
:
2722 * This hasn't been tested, since I don't have any
2723 * traces with this in it.
2725 * The V1 spec claims that this does, indeed,
2726 * have a Received ID field after the type,
2727 * rather than a Version field.
2729 proto_tree_add_item(wccp_tree
, hf_recvd_id
, tvb
, offset
,
2732 cache_count
= tvb_get_ntohl(tvb
, offset
);
2733 proto_tree_add_uint(wccp_tree
, hf_wc_num
, tvb
, offset
, 4, cache_count
);
2735 for (i
= 0; i
< cache_count
; i
++) {
2736 ipaddr
= tvb_get_ipv4(tvb
, offset
);
2737 proto_tree_add_ipv4_format(wccp_tree
,
2738 hf_cache_ip
, tvb
, offset
, 4,
2740 "Web Cache %d IP Address: %s", i
,
2741 tvb_ip_to_str(pinfo
->pool
, tvb
, offset
));
2745 for (i
= 0; i
< 256; i
++) {
2746 bucket
= tvb_get_uint8(tvb
, offset
);
2747 if (bucket
== 0xff) {
2748 proto_tree_add_uint_format(wccp_tree
, hf_bucket
, tvb
, offset
, 1,
2749 bucket
, "Bucket %d: Unassigned", i
);
2751 proto_tree_add_uint_format(wccp_tree
, hf_bucket
, tvb
, offset
, 1,
2752 bucket
, "Bucket %d: %d", i
, bucket
);
2758 case WCCP2_HERE_I_AM
:
2759 case WCCP2_I_SEE_YOU
:
2760 case WCCP2_REMOVAL_QUERY
:
2761 case WCCP2_REDIRECT_ASSIGN
:
2762 default: /* assume unknown packets are v2 */
2763 /* 5.5 WCCP Message Header */
2765 proto_tree_add_item(wccp_tree
, hf_message_header_version
, tvb
, offset
, 2,
2769 length
= tvb_get_ntohs(tvb
, offset
);
2770 length_item
= proto_tree_add_uint(wccp_tree
, hf_message_header_length
, tvb
, offset
, 2, length
);
2773 /* Is the length plus the length of the data preceding it longer than
2774 the length of our packet? */
2775 wccp2_length
= tvb_reported_length_remaining(tvb
, offset
);
2776 if (length
> (unsigned)wccp2_length
) {
2777 expert_add_info_format(pinfo
, length_item
, &ei_wccp_length_bad
,
2778 "The length as specified by the length field is bigger than the length of the packet");
2779 length
= wccp2_length
- offset
;
2781 /* Truncate the packet to the specified length. */
2782 tvb_set_reported_length(tvb
, offset
+ length
);
2784 proto_item_set_len(wccp_tree_item
, offset
+ length
);
2785 dissect_wccp2_info(tvb
, offset
, pinfo
, wccp_tree
, wccp_message_type
);
2789 return tvb_captured_length(tvb
);
2794 /* End of utility functions */
2797 proto_register_wccp(void)
2799 static hf_register_info hf
[] = {
2800 { &hf_wccp_message_type
,
2801 { "WCCP Message Type", "wccp.message", FT_UINT32
, BASE_DEC
, VALS(wccp_type_vals
), 0x0,
2802 "The WCCP message that was sent", HFILL
}
2805 { "WCCP Version", "wccp.version", FT_UINT32
, BASE_HEX
, VALS(wccp_version_val
), 0x0,
2806 "The WCCP version", HFILL
}
2809 { "Bucket", "wccp.bucket", FT_UINT8
, BASE_DEC
, 0x0, 0x0,
2813 { "Bucket", "wccp.bucket_bit", FT_UINT8
, BASE_DEC
, 0x0, 0x0,
2816 { &hf_message_header_version
,
2817 { "WCCP Version (>=2)", "wccp.message_header_version", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2818 "The WCCP version for version 2 and above", HFILL
}
2820 { &hf_hash_revision
,
2821 { "Hash Revision", "wccp.hash_revision", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2822 "The cache hash revision", HFILL
}
2825 { "Change Number", "wccp.change_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2826 "The Web-Cache list entry change number", HFILL
}
2829 { "Flags", "wccp.hash_flag", FT_UINT32
, BASE_HEX
, 0x0, 0x0,
2833 { "Hash information", "wccp.hash_flag.u", FT_BOOLEAN
, 32, TFS(&tfs_historical_current
), 0x00010000,
2837 { "Received ID", "wccp.recvd_id", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2838 "The number of I_SEE_YOU's that have been sent", HFILL
}
2841 { "Web Cache IP address", "wccp.cache_ip", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2842 "The IP address of a Web cache", HFILL
}
2845 { "Number of Web Caches", "wccp.wc_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2848 { &hf_message_header_length
,
2849 { "Length", "wccp.message_header_length", FT_UINT16
, BASE_DEC
, 0x0, 0x0,
2853 { "Length", "wccp.item_length", FT_UINT16
, BASE_DEC
, 0x0, 0x0,
2854 "The Length of the WCCPv2 item", HFILL
}
2857 { "Type", "wccp.item_type", FT_UINT16
, BASE_DEC
, VALS(info_type_vals
), 0x0,
2858 "The type of the WCCPv2 item", HFILL
}
2861 { "Data", "wccp.item_data", FT_BYTES
, BASE_NONE
, 0x0, 0x0,
2862 "The data for an unknown item type", HFILL
}
2864 { &hf_security_info_option
,
2865 { "Security Option", "wccp.security_info_option", FT_UINT32
, BASE_DEC
, VALS(security_option_vals
), 0x0,
2868 { &hf_security_info_md5_checksum
,
2869 { "MD5 checksum (not checked)", "wccp.security_md5_checksum", FT_BYTES
, BASE_NONE
, 0x0, 0x0,
2872 { &hf_command_element_type
,
2873 {"Command Extension Type", "wccp.command_element_type", FT_UINT16
, BASE_DEC
, VALS(wccp_command_type_vals
), 0x0,
2876 { &hf_command_element_length
,
2877 {"Command Extension Length", "wccp.command_element_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2880 { &hf_command_length
,
2881 {"Command Length", "wccp.command_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2884 { &hf_command_element_shutdown_ip_index
,
2885 {"Command Element Shutdown IP", "wccp.command_element_shutdown_ip_Address.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2888 { &hf_command_element_shutdown_ipv4
,
2889 {"Command Element Shutdown IP", "wccp.command_element_shutdown_ip_address.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2892 { &hf_command_element_shutdown_ipv6
,
2893 {"Command Element Shutdown IP", "wccp.command_element_shutdown_ip_address.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2896 { &hf_command_unknown
,
2897 {"Unknown Command", "wccp.command_unknown", FT_NONE
, BASE_NONE
, NULL
, 0x0,
2900 { &hf_service_info_type
,
2901 { "Service Type", "wccp.service_info_type", FT_UINT8
, BASE_DEC
, VALS(service_type_vals
), 0x0,
2904 { &hf_service_info_id_standard
,
2905 { "WCCP Service ID (Standard)", "wccp.service_info_std_id", FT_UINT8
, BASE_DEC
, VALS(service_id_vals
) , 0x0,
2906 "The WCCP Service id (Standard)", HFILL
}
2908 { &hf_service_info_id_dynamic
,
2909 { "WCCP Service ID ( Dynamic)", "wccp.service_info_dyn_id", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2910 "The WCCP Service id (Dynamic)", HFILL
}
2912 { &hf_service_info_priority
,
2913 { "Priority (highest is 255)", "wccp.service_info_priority", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2916 { &hf_service_info_protocol
,
2917 { "Protocol", "wccp.service_info_protocol", FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &ipproto_val_ext
, 0x0,
2920 { &hf_service_info_flags
,
2921 { "Flags", "wccp.service_info_flags", FT_UINT32
, BASE_HEX
, 0x0, 0x0,
2924 { &hf_service_info_flags_src_ip_hash
,
2925 { "Source IP address in primary hash", "wccp.service_info_flag.src_ip_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_SRC_IP_HASH
,
2928 { &hf_service_info_flags_dest_ip_hash
,
2929 { "Destination IP address in primary hash", "wccp.service_info_flag.dest_ip_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_DST_IP_HASH
,
2932 { &hf_service_info_flags_src_port_hash
,
2933 { "Source port in primary hash", "wccp.service_info_flag.src_port_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_SRC_PORT_HASH
,
2936 { &hf_service_info_flags_dest_port_hash
,
2937 { "Destination port in primary hash", "wccp.service_info_flag.dest_port_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_DST_PORT_HASH
,
2940 { &hf_service_info_flags_ports_defined
,
2941 { "Ports", "wccp.service_info_flag.ports_defined", FT_BOOLEAN
, 32, TFS(&tfs_defined_not_defined
), WCCP2_SI_PORTS_DEFINED
,
2944 { &hf_service_info_flags_ports_source
,
2945 { "Ports refer to", "wccp.service_info_flag.ports_source", FT_BOOLEAN
, 32, TFS(&tfs_src_dest_port
), WCCP2_SI_PORTS_SOURCE
,
2948 { &hf_service_info_flags_redirect_only_protocol_0
,
2949 { "Redirect only protocol 0", "wccp.service_info_flag.redirect_only_protocol_0", FT_BOOLEAN
, 32, TFS(&tfs_redirect_protocol0
), WCCP2r1_SI_REDIRECT_ONLY_PROTOCOL_0
,
2952 { &hf_service_info_flags_src_ip_alt_hash
,
2953 { "Source IP address in secondary hash", "wccp.service_info_flag.src_ip_alt_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_SRC_IP_ALT_HASH
,
2956 { &hf_service_info_flags_dest_ip_alt_hash
,
2957 { "Destination IP address in secondary hash", "wccp.service_info_flag.dest_ip_alt_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_DST_IP_ALT_HASH
,
2960 { &hf_service_info_flags_src_port_alt_hash
,
2961 { "Source port in secondary hash", "wccp.service_info_flag.src_port_alt_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_SRC_PORT_ALT_HASH
,
2964 { &hf_service_info_flags_dest_port_alt_hash
,
2965 { "Destination port in secondary hash", "wccp.service_info_flag.dest_port_alt_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_DST_PORT_ALT_HASH
,
2968 { &hf_service_info_flags_reserved
,
2969 { "Reserved, should be 0", "wccp.service_info_flag.reserved", FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFF000,
2972 { &hf_service_info_source_port
,
2973 { "Source Port", "wccp.service_info_source_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2976 { &hf_service_info_destination_port
,
2977 { "Destination Port", "wccp.service_info_destination_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2980 { &hf_router_identity_ip_index
,
2981 { "IP Address", "wccp.router_identity.ip_address.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2984 { &hf_router_identity_ipv4
,
2985 { "IP Address", "wccp.router_identity.ip_address.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2988 { &hf_router_identity_ipv6
,
2989 { "IP Address", "wccp.router_identity.ip_address.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
2992 { &hf_router_identity_receive_id
,
2993 { "Received ID", "wccp.router_identity.receive_id", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2996 { &hf_router_identity_send_to_ip_index
,
2997 { "Sent To IP Address", "wccp.router_identity.send_to_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3000 { &hf_router_identity_send_to_ipv4
,
3001 { "Sent To IP Address", "wccp.router_identity.send_to_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3004 { &hf_router_identity_send_to_ipv6
,
3005 { "Sent To IP Address", "wccp.router_identity.send_to_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3008 { &hf_router_identity_received_from_num
,
3009 { "Number of Received From IP addresses (Webcache to which the message is directed)", "wccp.router.num_recv_ip", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
3012 { &hf_web_cache_identity_index
,
3013 { "Web-Cache IP Address", "wccp.web_cache_identity.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3016 { &hf_web_cache_identity_ipv4
,
3017 { "Web-Cache IP Address", "wccp.web_cache_identity.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3020 { &hf_web_cache_identity_ipv6
,
3021 { "Web-Cache IP Address", "wccp.web_cache_identity.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3024 { &hf_web_cache_identity_hash_rev
,
3025 { "Hash Revision", "wccp.web_cache_identity.hash_rev", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3028 { &hf_web_cache_identity_flags
,
3029 { "Flags", "wccp.web_cache_identity.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3032 { &hf_web_cache_identity_flag_hash_info
,
3033 { "Hash information", "wccp.web_cache_identity.flags.hash_info", FT_BOOLEAN
, 16,
3034 TFS(&tfs_historical_current
), 0x1,
3037 { &hf_web_cache_identity_flag_assign_type
,
3038 { "Assignment Type", "wccp.web_cache_identity.flags.assign_type", FT_UINT16
, BASE_HEX
,
3039 VALS(wccp_web_cache_assignment_data_type_val
), 0x6,
3042 { &hf_web_cache_identity_flag_version_request
,
3043 { "Version Request", "wccp.web_cache_identity.flags.version_request", FT_BOOLEAN
, 16,
3044 TFS(&tfs_version_min_max
), 0x8,
3047 { &hf_web_cache_identity_flag_reserved
,
3048 { "Reserved, should be 0", "wccp.web_cache_identity.flags.reserved", FT_UINT16
, BASE_HEX
,
3052 { &hf_mask_value_set_element_value_element_num
,
3053 { "Number of Value Elements", "wccp.mask_value_set_element.value_element_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
3056 { &hf_assignment_weight
,
3057 { "Assignment Weight", "wccp.assignment_weight", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3060 { &hf_assignment_status
,
3061 { "Status", "wccp.assignment_status", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3064 { &hf_assignment_key_ip_index
,
3065 { "Assignment Key IP Address", "wccp.assignment_key.ip_index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3068 { &hf_assignment_key_ipv4
,
3069 { "Assignment Key IP Address", "wccp.assignment_key.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3072 { &hf_assignment_key_ipv6
,
3073 { "Assignment Key IP Address", "wccp.assignment_key.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3076 { &hf_assignment_key_change_num
,
3077 { "Assignment Key Change Number", "wccp.assignment_key.change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3080 { &hf_assignment_no_data
,
3081 { "No Assignment Data Present", "wccp.assignment_no_data", FT_NONE
, BASE_NONE
, NULL
, 0x0,
3084 { &hf_router_view_member_change_num
,
3085 { "Member Change Number", "wccp.router_view.member_change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3088 { &hf_router_router_num
,
3089 { "Number of Routers", "wccp.router_view.router_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3092 { &hf_router_identity_router_ip_index
,
3093 { "Router IP Address", "wccp.router_identity.router_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3096 { &hf_router_identity_router_ipv4
,
3097 { "Router IP Address", "wccp.router_identity.router_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3100 { &hf_router_identity_router_ipv6
,
3101 { "Router IP Address", "wccp.router_identity.router_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3104 { &hf_router_identity_received_from_ip_index
,
3105 { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3108 { &hf_router_identity_received_from_ipv4
,
3109 { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3112 { &hf_router_identity_received_from_ipv6
,
3113 { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3116 { &hf_wc_view_info_change_num
,
3117 { "Change Number", "wccp.wc_view_info.change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3120 { &hf_wc_view_info_router_ip_index
,
3121 { "Router IP", "wccp.wc_view_info.router_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3124 { &hf_wc_view_info_router_ipv4
,
3125 { "Router IP", "wccp.wc_view_info.router_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3128 { &hf_wc_view_info_router_ipv6
,
3129 { "Router IP", "wccp.wc_view_info.router_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3132 { &hf_wc_view_info_wc_ip_index
,
3133 { "Web Cache IP", "wccp.wc_view_info.wc_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3136 { &hf_wc_view_info_wc_ipv4
,
3137 { "Web Cache IP", "wccp.wc_view_info.wc_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3140 { &hf_wc_view_info_wc_ipv6
,
3141 { "Web Cache IP", "wccp.wc_view_info.wc_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3144 { &hf_wc_view_router_num
,
3145 { "Number of Routers", "wccp.wc_view_info.router_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3148 { &hf_wc_view_wc_num
,
3149 { "Number of Web Caches", "wccp.wc_view_info.wc_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
3152 { &hf_wc_identity_ip_address_index
,
3153 { "Web Cache Identity", "wccp.wc_identity_ip_address.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3154 "The IP identifying the Web Cache", HFILL
}
3156 { &hf_wc_identity_ip_address_ipv4
,
3157 { "Web Cache Identity", "wccp.wc_identity_ip_address.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3158 "The IP identifying the Web Cache", HFILL
}
3160 { &hf_wc_identity_ip_address_ipv6
,
3161 { "Web Cache Identity", "wccp.wc_identity_ip_address.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3162 "The IP identifying the Web Cache", HFILL
}
3164 { &hf_router_assignment_element_change_num
,
3165 { "Change Number", "wccp.router_assignment_element.change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3168 { &hf_assignment_info_router_num
,
3169 { "Number of Routers", "wccp.assignment_info.router_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3172 { &hf_assignment_info_router_ip_index
,
3173 { "Router IP", "wccp.assignment_info.router_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3176 { &hf_assignment_info_router_ipv4
,
3177 { "Router IP", "wccp.assignment_info.router_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3180 { &hf_assignment_info_router_ipv6
,
3181 { "Router IP", "wccp.assignment_info.router_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3184 { &hf_hash_buckets_assignment_wc_num
,
3185 { "Number of WC", "wccp.hash_buckets_assignment.wc_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3188 { &hf_hash_buckets_assignment_wc_ip_index
,
3189 { "WC IP", "wccp.hash_buckets_assignment.wc_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3192 { &hf_hash_buckets_assignment_wc_ipv4
,
3193 { "WC IP", "wccp.hash_buckets_assignment.wc_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3196 { &hf_hash_buckets_assignment_wc_ipv6
,
3197 { "WC IP", "wccp.hash_buckets_assignment.wc_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3200 { &hf_router_view_ip_index
,
3201 { "Router IP Address", "wccp.router_view.ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3204 { &hf_router_view_ipv4
,
3205 { "Router IP Address", "wccp.router_view.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3208 { &hf_router_view_ipv6
,
3209 { "Router IP Address", "wccp.router_view.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3212 { &hf_router_query_info_ip_index
,
3213 { "Web-Cache Identity Element IP address", "wccp.router_query_info.ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3216 { &hf_router_query_info_ipv4
,
3217 { "Web-Cache Identity Element IP address", "wccp.router_query_info.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3220 { &hf_router_query_info_ipv6
,
3221 { "Web-Cache Identity Element IP address", "wccp.router_query_info.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3224 { &hf_router_query_info_send_to_ip_index
,
3225 { "Sent To IP Address", "wccp.router_query_info.send_to_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3228 { &hf_router_query_info_send_to_ipv4
,
3229 { "Sent To IP Address", "wccp.router_query_info.send_to_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3232 { &hf_router_query_info_send_to_ipv6
,
3233 { "Sent To IP Address", "wccp.router_query_info.send_to_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3236 { &hf_router_query_info_target_ip_index
,
3237 { "Target IP Address", "wccp.router_query_info.target_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3240 { &hf_router_query_info_target_ipv4
,
3241 { "Target IP Address", "wccp.router_query_info.target_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3244 { &hf_router_query_info_target_ipv6
,
3245 { "Target IP Address", "wccp.router_query_info.target_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3248 { &hf_capability_element_type
,
3249 { "Type", "wccp.capability_element.type", FT_UINT16
, BASE_DEC
, VALS(capability_type_vals
), 0x0,
3252 { &hf_capability_element_length
,
3253 { "Value Length", "wccp.capability_element.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3256 { &hf_capability_info_value
,
3257 { "Value", "wccp.capability_info.value", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3260 { &hf_capability_forwarding_method_flag_gre
,
3261 { "GRE-encapsulated", "wccp.capability_info.forwarding_method_flag.gre", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_FORWARDING_METHOD_GRE
,
3264 { &hf_capability_forwarding_method_flag_l2
,
3265 { "L2 rewrite", "wccp.capability_info.forwarding_method_flag.l2", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_FORWARDING_METHOD_L2
,
3268 { &hf_capability_assignment_method_flag_hash
,
3269 { "Hash", "wccp.capability_info.assignment_method_flag.hash", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_ASSIGNMENT_METHOD_HASH
,
3272 { &hf_capability_assignment_method_flag_mask
,
3273 { "Mask", "wccp.capability_info.assignment_method_flag.mask", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_ASSIGNMENT_METHOD_MASK
,
3276 { &hf_capability_return_method_flag_gre
,
3277 { "GRE-encapsulated", "wccp.capability_info.return_method_flag.gre", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_PACKET_RETURN_METHOD_GRE
,
3280 { &hf_capability_return_method_flag_l2
,
3281 { "L2 rewrite", "wccp.capability_info.return_method_flag.l2", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_PACKET_RETURN_METHOD_L2
,
3284 { &hf_capability_transmit_t
,
3285 { "Message interval in milliseconds", "wccp.capability.transmit_t", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3288 { &hf_capability_transmit_t_upper_limit
,
3289 { "Message interval upper limit in milliseconds", "wccp.capability.transmit_t.upper_limit", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3292 { &hf_capability_transmit_t_lower_limit
,
3293 { "Message interval lower limit in milliseconds", "wccp.capability.transmit_t.lower_limit", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3296 { &hf_capability_timer_scale_timeout_scale
,
3297 { "Timer scale", "wccp.capability.timer_scale.timeout_scale", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3300 { &hf_capability_timer_scale_timeout_scale_upper_limit
,
3301 { "Timer scale upper limit", "wccp.capability.timer_scale.timeout_scale.upper_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3304 { &hf_capability_timer_scale_timeout_scale_lower_limit
,
3305 { "Timer scale lower limit", "wccp.capability.timer_scale.timeout_scale.lower_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3308 { &hf_capability_timer_scale_ra_timer_scale
,
3309 { "RA Timer scale", "wccp.capability.timer_scale.ra_timer_scale", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3312 { &hf_capability_timer_scale_ra_scale_upper_limit
,
3313 { "RA Timer scale upper limit", "wccp.capability.timer_scale.ra_timer_scale.upper_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3316 { &hf_capability_timer_scale_ra_scale_lower_limit
,
3317 { "RA Timer scale lower limit", "wccp.capability.timer_scale.ra_timer_scale.lower_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3320 { &hf_capability_value
,
3321 { "Value", "wccp.capability.value", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3324 { &hf_reserved_zero
,
3325 { "Reserved, must be 0", "wccp.reserved_zero", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3328 { &hf_value_element_src_ip_index
,
3329 { "Source Address", "wccp.value_element.src_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3332 { &hf_value_element_src_ipv4
,
3333 { "Source Address", "wccp.value_element.src_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3336 { &hf_value_element_src_ipv6
,
3337 { "Source Address", "wccp.value_element.src_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3340 { &hf_value_element_dest_ip_index
,
3341 { "Destination Address", "wccp.value_element.dest_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3344 { &hf_value_element_dest_ipv4
,
3345 { "Destination Address", "wccp.value_element.dest_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3348 { &hf_value_element_dest_ipv6
,
3349 { "Destination Address", "wccp.value_element.dest_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3352 { &hf_value_element_src_port
,
3353 { "Source Port", "wccp.value_element.src_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3356 { &hf_value_element_dest_port
,
3357 { "Destination Port", "wccp.value_element.dest_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3360 { &hf_value_element_web_cache_ip_index
,
3361 { "Web Cache Address", "wccp.value_element.web_cache_ip.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3364 { &hf_value_element_web_cache_ipv4
,
3365 { "Web Cache Address", "wccp.value_element.web_cache_ip.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3368 { &hf_value_element_web_cache_ipv6
,
3369 { "Web Cache Address", "wccp.value_element.web_cache_ip.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3372 { &hf_mask_value_set_list_num_elements
,
3373 { "Number of elements", "wccp.mask_value_set_list.num_elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3376 { &hf_mask_element_src_ip
,
3377 { "Source Address Mask", "wccp.mask_element.src_ip", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3380 { &hf_mask_element_dest_ip
,
3381 { "Destination Address Mask", "wccp.mask_element.dest_ip", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3384 { &hf_mask_element_src_port
,
3385 { "Source Port Mask", "wccp.mask_element.src_port", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3388 { &hf_mask_element_dest_port
,
3389 { "Destination Port Mask", "wccp.mask_element.dest_port", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3392 { &hf_alt_assignment_info_assignment_type
,
3393 { "Assignment type", "wccp.alt_assignment_info.assignment_type", FT_UINT16
, BASE_DEC
, VALS(assignment_type_vals
), 0x0,
3396 { &hf_extended_assignment_data_type
,
3397 { "Assignment type", "wccp.extended_assignment_data.type", FT_UINT16
, BASE_DEC
, VALS(assignment_type_vals
), 0x0,
3400 { &hf_alt_assignment_map_assignment_type
,
3401 { "Assignment type", "wccp.alt_assignment_map.assignment_type", FT_UINT16
, BASE_DEC
, VALS(assignment_type_vals
), 0x0,
3404 { &hf_alt_assignment_map_assignment_length
,
3405 { "Assignment length", "wccp.alt_assignment_map.assignment_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3408 { &hf_alt_assignment_info_assignment_length
,
3409 { "Assignment length", "wccp.alt_assignment_info.assignment_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3412 { &hf_extended_assignment_data_length
,
3413 { "Assignment length", "wccp.extended_assignment_data.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3416 { &hf_alt_assignment_info_num_routers
,
3417 { "Number of routers", "wccp.alt_assignment_info.num_routers", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3420 { &hf_alt_assignment_mask_value_set_element_num_wc_value_elements
,
3421 { "Number of Web-Cache Value Elements", "wccp.alt_assignment_mask_value_set_element.num_wc_value_elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3424 { &hf_web_cache_value_element_wc_address_index
,
3425 { "Web-Cache Address", "wccp.web_cache_value_element.wc_address.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3428 { &hf_web_cache_value_element_wc_address_ipv4
,
3429 { "Web-Cache Address", "wccp.web_cache_value_element.wc_address.ipv4", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
3432 { &hf_web_cache_value_element_wc_address_ipv6
,
3433 { "Web-Cache Address", "wccp.web_cache_value_element.wc_address.ipv6", FT_IPv6
, BASE_NONE
, NULL
, 0x0,
3436 { &hf_web_cache_value_element_num_values
,
3437 { "Number of Value Sequence Numbers", "wccp.web_cache_value_element.num_values", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3440 { &hf_web_cache_value_seq_num
,
3441 { "Value Sequence Number", "wccp.web_cache_value_element.value_seq_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3444 { &hf_alt_assignment_mask_value_set_list_num_elements
,
3445 { "Number of Alternate Mask/Value Set Elements", "wccp.alt_assignment_mask_value_list.num_elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3448 { &hf_address_table_family
,
3449 { "Family Type", "wccp.address_table.family_type", FT_UINT16
, BASE_DEC
, VALS(wccp_address_family_val
), 0x0,
3450 "The WCCP Address Table Family type", HFILL
}
3452 { &hf_address_table_address_length
,
3453 { "Address Length", "wccp.address_table.address_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3454 "The WCCP Address Table Address Length", HFILL
}
3456 { &hf_address_table_length
,
3457 { "Length", "wccp.address_table.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3458 "The WCCP Address Table Length", HFILL
}
3460 { &hf_address_table_element
,
3461 { "Address", "wccp.address_table.element", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3466 static int *ett
[] = {
3469 &ett_hash_assignment_buckets
,
3470 &ett_mask_assignment_data_element
,
3471 &ett_alternate_mask_assignment_data_element
,
3472 &ett_extended_assigment_data_element
,
3475 &ett_wc_identity_flags
,
3480 &ett_service_info_ports
,
3481 &ett_wc_view_info_router_element
,
3482 &ett_router_identity_info
,
3483 &ett_wc_identity_element
,
3484 &ett_wc_identity_info
,
3485 &ett_router_view_info
,
3487 &ett_router_assignment_element
,
3488 &ett_hash_buckets_assignment_wc_element
,
3489 &ett_hash_buckets_assignment_buckets
,
3490 &ett_router_alt_assignment_element
,
3491 &ett_router_assignment_info
,
3493 &ett_capabilities_info
,
3494 &ett_capability_element
,
3495 &ett_capability_forwarding_method
,
3496 &ett_capability_assignment_method
,
3497 &ett_capability_return_method
,
3498 &ett_capability_transmit_t
,
3499 &ett_capability_timer_scale
,
3500 &ett_alt_assignment_info
,
3501 &ett_alt_assignment_map
,
3503 &ett_assignment_map
,
3504 &ett_command_extension
,
3505 &ett_alternate_mask_value_set
,
3506 &ett_alternate_mask_value_set_element
,
3508 &ett_mv_set_element
,
3509 &ett_mv_set_value_list
,
3510 &ett_alternate_mv_set_element_list
,
3511 &ett_web_cache_value_element_list
,
3512 &ett_alternate_mv_set_element
,
3517 static ei_register_info ei
[] = {
3518 { &ei_wccp_missing_security_info
, { "wccp.missing.security_info", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Security Info component, but it is missing", EXPFILL
}},
3519 { &ei_wccp_missing_service_info
, { "wccp.missing.service_info", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Service Info component, but it is missing", EXPFILL
}},
3520 { &ei_wccp_missing_wc_id_info
, { "wccp.missing.wc_id_info", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Web-Cache Identity Info component, but it is missing", EXPFILL
}},
3521 { &ei_wccp_missing_router_id_info
, { "wccp.missing.router_id_info", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Router Identity Info component, but it is missing", EXPFILL
}},
3522 { &ei_wccp_missing_query_info
, { "wccp.missing.query_info", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Query Info component, but it is missing", EXPFILL
}},
3523 { &ei_wccp_missing_wc_view_info
, { "wccp.missing.wc_view_info", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Web-Cache View Info component, but it is missing", EXPFILL
}},
3524 { &ei_wccp_missing_rtr_view_info
, { "wccp.missing.rtr_view_info", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Router View Info component, but it is missing", EXPFILL
}},
3525 { &ei_wccp_missing_assignment
, { "wccp.missing.assignment", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Alternate Assignment, Assignment Map, Assignment Info or "
3526 "Alternative Assignment Map component, but it is missing", EXPFILL
}},
3527 { &ei_wccp_contains_redirect_assignment
, { "wccp.contains.redirect_assignment", PI_PROTOCOL
, PI_ERROR
, "This message contains a Assignment Info component, but it should not", EXPFILL
}},
3528 { &ei_wccp_contains_router_id_info
, { "wccp.contains.router_id_info", PI_PROTOCOL
, PI_ERROR
, "This message contains a Router Identity Info component, but it should not", EXPFILL
}},
3529 { &ei_wccp_contains_rtr_view_info
, { "wccp.contains.rtr_view_info", PI_PROTOCOL
, PI_ERROR
, "This message contains a Router View Info component, but it should not", EXPFILL
}},
3530 { &ei_wccp_contains_query_info
, { "wccp.contains.query_info", PI_PROTOCOL
, PI_ERROR
, "This message contains a Query Info component, but it should not", EXPFILL
}},
3531 { &ei_wccp_contains_alt_assignment
, { "wccp.contains.alt_assignment", PI_PROTOCOL
, PI_ERROR
, "This message contains a Alternate Assignment component, but it should not", EXPFILL
}},
3532 { &ei_wccp_contains_assign_map
, { "wccp.contains.assign_map", PI_PROTOCOL
, PI_ERROR
, "This message contains a Assignment Map component, but it should not", EXPFILL
}},
3533 { &ei_wccp_contains_alt_assignment_map
, { "wccp.contains.alt_assignment_map", PI_PROTOCOL
, PI_ERROR
, "This message contains a Alternative Assignment Map component, but it should not", EXPFILL
}},
3534 { &ei_wccp_contains_wc_id_info
, { "wccp.contains.wc_id_info", PI_PROTOCOL
, PI_ERROR
, "This message contains a Web-Cache Identity Info component, but it should not", EXPFILL
}},
3535 { &ei_wccp_contains_wc_view_info
, { "wccp.contains.wc_view_info", PI_PROTOCOL
, PI_ERROR
, "This message contains a Web-Cache View Info component, but it should not", EXPFILL
}},
3536 { &ei_wccp_contains_capabilities_info
, { "wccp.contains.capabilities_info", PI_PROTOCOL
, PI_ERROR
, "This message contains a Capabilities Info component, but it should not", EXPFILL
}},
3537 { &ei_wccp_contains_command_extension
, { "wccp.contains.command_extension", PI_PROTOCOL
, PI_ERROR
, "This message contains a Command Extension component, but it should not", EXPFILL
}},
3538 { &ei_wccp_assignment_length_bad
, { "wccp.assignment_length_bad", PI_PROTOCOL
, PI_ERROR
, "Assignment length bad", EXPFILL
}},
3539 { &ei_wccp_length_bad
, { "wccp.length_bad", PI_PROTOCOL
, PI_ERROR
, "Length bad", EXPFILL
}},
3540 { &ei_wccp_service_info_priority_nonzero
, { "wccp.service_info_priority.nonzero", PI_PROTOCOL
, PI_WARN
, "The priority must be zero for well-known services.", EXPFILL
}},
3541 { &ei_wccp_service_info_protocol_nonzero
, { "wccp.service_info_protocol.nonzero", PI_PROTOCOL
, PI_WARN
, "The protocol must be zero for well-known services.", EXPFILL
}},
3542 { &ei_wccp_router_identity_receive_id_zero
, { "wccp.router_identity.receive_id.zero", PI_PROTOCOL
, PI_WARN
, "Receive ID shouldn't be 0", EXPFILL
}},
3543 { &ei_wccp_web_cache_identity_hash_rev_zero
, { "wccp.web_cache_identity.hash_rev.zero", PI_PROTOCOL
, PI_WARN
, "Should be 0 (6.4)", EXPFILL
}},
3544 { &ei_wccp_address_table_family_unknown
, { "wccp.address_table.family_type.unknown", PI_PROTOCOL
, PI_ERROR
, "Unknown address family", EXPFILL
}},
3545 { &ei_wccp_capability_element_length
, { "wccp.capability_element.length.invalid", PI_PROTOCOL
, PI_WARN
, "Value Length invalid", EXPFILL
}},
3546 { &ei_wccp_port_fields_not_used
, { "wccp.port_fields_not_used", PI_PROTOCOL
, PI_NOTE
, "Ports fields not used", EXPFILL
}},
3547 { &ei_wccp_a_zero_not_c
, { "wccp.a_zero_not_c", PI_PROTOCOL
, PI_WARN
, "Error A is 0, but C is not", EXPFILL
}},
3549 { &ei_wccp_c_zero_not_a
, { "wccp.c_zero_not_a", PI_PROTOCOL
, PI_WARN
, "Error C is 0, but A is not", EXPFILL
}},
3553 expert_module_t
* expert_wccp
;
3555 proto_wccp
= proto_register_protocol("Web Cache Communication Protocol",
3557 proto_register_field_array(proto_wccp
, hf
, array_length(hf
));
3558 proto_register_subtree_array(ett
, array_length(ett
));
3559 expert_wccp
= expert_register_protocol(proto_wccp
);
3560 expert_register_field_array(expert_wccp
, ei
, array_length(ei
));
3561 wccp_handle
= register_dissector("wccp", dissect_wccp
, proto_wccp
);
3565 proto_reg_handoff_wccp(void)
3567 dissector_add_uint_with_preference("udp.port", UDP_PORT_WCCP
, wccp_handle
);
3571 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3576 * indent-tabs-mode: nil
3579 * vi: set shiftwidth=2 tabstop=8 expandtab:
3580 * :indentSize=2:tabSize=8:noTabs=true: