2 * Routines for Web Cache Communication Protocol dissection
3 * Jerry Talkington <jtalkington@users.sourceforge.net>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/packet.h>
30 #include <epan/to_str.h>
31 #include <epan/wmem/wmem.h>
32 #include <epan/ipproto.h>
33 #include <epan/expert.h>
34 #include <epan/ipv6-utils.h>
35 #include <epan/ipv4.h>
36 #include "packet-wccp.h"
38 static int proto_wccp
= -1;
39 static int hf_wccp_message_type
= -1; /* the message type */
40 static int hf_wccp_version
= -1; /* protocol version */
41 static int hf_message_header_version
= -1;
42 static int hf_hash_revision
= -1; /* the version of the hash */
43 static int hf_change_num
= -1; /* change number */
44 static int hf_hash_flag
= -1;
45 static int hf_hash_flag_u
= -1;
46 static int hf_recvd_id
= -1;
47 static int hf_wc_num
= -1;
48 static int hf_wc_view_wc_num
= -1;
49 static int hf_cache_ip
= -1;
50 static int hf_message_header_length
= -1;
51 static int hf_item_type
= -1;
52 static int hf_item_length
= -1;
53 static int hf_item_data
= -1;
54 static int hf_security_info_option
= -1;
55 static int hf_security_info_md5_checksum
= -1;
56 static int hf_command_element_type
= -1;
57 static int hf_command_element_length
= -1;
58 static int hf_command_element_shutdown_ip
= -1;
59 static int hf_service_info_type
= -1;
60 static int hf_service_info_id_standard
= -1;
61 static int hf_service_info_id_dynamic
= -1;
62 static int hf_service_info_priority
= -1;
63 static int hf_service_info_protocol
= -1;
64 static int hf_service_info_flags
= -1;
65 static int hf_service_info_flags_src_ip_hash
= -1;
66 static int hf_service_info_flags_dest_ip_hash
= -1;
67 static int hf_service_info_flags_src_port_hash
= -1;
68 static int hf_service_info_flags_dest_port_hash
= -1;
69 static int hf_service_info_flags_ports_defined
= -1;
70 static int hf_service_info_flags_ports_source
= -1;
71 static int hf_service_info_flags_redirect_only_protocol_0
= -1;
72 static int hf_service_info_flags_src_ip_alt_hash
= -1;
73 static int hf_service_info_flags_dest_ip_alt_hash
= -1;
74 static int hf_service_info_flags_src_port_alt_hash
= -1;
75 static int hf_service_info_flags_dest_port_alt_hash
= -1;
76 static int hf_service_info_source_port
= -1;
77 static int hf_service_info_destination_port
= -1;
78 static int hf_router_identity_ip
= -1;
79 static int hf_router_identity_receive_id
= -1;
80 static int hf_router_identity_send_to_ip
= -1;
81 static int hf_router_identity_received_from_num
= -1;
82 static int hf_web_cache_identity_ip
= -1;
83 static int hf_web_cache_identity_hash_rev
= -1;
84 static int hf_web_cache_identity_flags
= -1;
85 static int hf_web_cache_identity_flag_hash_info
= -1;
86 static int hf_web_cache_identity_flag_assign_type
= -1;
87 static int hf_web_cache_identity_flag_version_request
= -1;
88 static int hf_mask_value_set_element_value_element_num
= -1;
89 static int hf_assignment_weight
= -1;
90 static int hf_assignment_status
= -1;
91 static int hf_assignment_key_ip
= -1;
92 static int hf_assignment_key_change_num
= -1;
93 static int hf_router_view_member_change_num
= -1;
94 static int hf_router_router_num
= -1;
95 static int hf_router_identity_router_ip
= -1;
96 static int hf_wc_view_info_change_num
= -1;
97 static int hf_wc_view_info_router_ip
= -1;
98 static int hf_wc_view_info_wc_ip
= -1;
99 static int hf_wc_view_router_num
= -1;
100 static int hf_wc_identity_ip_address
= -1;
101 static int hf_router_identity_received_from_ip
= -1;
102 static int hf_router_assignment_element_change_num
= -1;
103 static int hf_assignment_info_router_num
= -1;
104 static int hf_hash_buckets_assignment_wc_num
= -1;
105 static int hf_hash_buckets_assignment_wc_ip
= -1;
106 static int hf_assignment_info_router_ip
= -1;
107 static int hf_router_view_ip
= -1;
108 static int hf_router_query_info_ip
= -1;
109 static int hf_router_query_info_send_to_ip
= -1;
110 static int hf_router_query_info_target_ip
= -1;
111 static int hf_capability_element_type
= -1;
112 static int hf_capability_element_length
= -1;
113 static int hf_capability_info_value
= -1;
114 static int hf_capability_forwarding_method_flag_gre
= -1;
115 static int hf_capability_forwarding_method_flag_l2
= -1;
116 static int hf_capability_assignment_method_flag_hash
= -1;
117 static int hf_capability_assignment_method_flag_mask
= -1;
118 static int hf_capability_return_method_flag_gre
= -1;
119 static int hf_capability_return_method_flag_l2
= -1;
120 static int hf_capability_transmit_t
= -1;
121 static int hf_capability_transmit_t_upper_limit
= -1;
122 static int hf_capability_transmit_t_lower_limit
= -1;
123 static int hf_capability_timer_scale_timeout_scale
= -1;
124 static int hf_capability_timer_scale_ra_timer_scale
= -1;
125 static int hf_capability_timer_scale_timeout_scale_upper_limit
= -1;
126 static int hf_capability_timer_scale_timeout_scale_lower_limit
= -1;
127 static int hf_capability_timer_scale_ra_scale_upper_limit
= -1;
128 static int hf_capability_timer_scale_ra_scale_lower_limit
= -1;
129 static int hf_value_element_src_ip
= -1;
130 static int hf_value_element_dest_ip
= -1;
131 static int hf_value_element_src_port
= -1;
132 static int hf_value_element_dest_port
= -1;
133 static int hf_value_element_web_cache_ip
= -1;
134 static int hf_mask_value_set_list_num_elements
= -1;
135 static int hf_mask_element_src_ip
= -1;
136 static int hf_mask_element_dest_ip
= -1;
137 static int hf_mask_element_src_port
= -1;
138 static int hf_mask_element_dest_port
= -1;
139 static int hf_alt_assignment_info_assignment_type
= -1;
140 static int hf_extended_assignment_data_type
= -1;
141 static int hf_alt_assignment_info_assignment_length
= -1;
142 static int hf_alt_assignment_map_assignment_type
= -1;
143 static int hf_alt_assignment_map_assignment_length
= -1;
144 static int hf_extended_assignment_data_length
= -1;
145 static int hf_alt_assignment_info_num_routers
= -1;
146 static int hf_alt_assignment_mask_value_set_element_num_wc_value_elements
= -1;
147 static int hf_web_cache_value_element_wc_address
= -1;
148 static int hf_web_cache_value_element_num_values
= -1;
149 static int hf_alt_assignment_mask_value_set_list_num_elements
= -1;
150 static int hf_address_table_family
= -1;
151 static int hf_address_table_address_length
= -1;
152 static int hf_address_table_length
= -1;
153 static int hf_address_table_element
= -1;
155 static gint ett_wccp
= -1;
156 static gint ett_buckets
= -1;
157 static gint ett_hash_assignment_buckets
= -1;
158 static gint ett_mask_assignment_data_element
= -1;
159 static gint ett_alternate_mask_assignment_data_element
= -1;
160 static gint ett_extended_assigment_data_element
= -1;
161 static gint ett_table_element
= -1;
162 static gint ett_hash_flags
= -1;
163 static gint ett_wc_identity_flags
= -1;
164 static gint ett_cache_info
= -1;
165 static gint ett_security_info
= -1;
166 static gint ett_service_info
= -1;
167 static gint ett_service_flags
= -1;
168 static gint ett_service_info_ports
= -1;
169 static gint ett_wc_view_info_router_element
= -1;
170 static gint ett_router_identity_info
= -1;
171 static gint ett_wc_identity_element
= -1;
172 static gint ett_wc_identity_info
= -1;
173 static gint ett_router_view_info
= -1;
174 static gint ett_wc_view_info
= -1;
175 static gint ett_router_assignment_element
= -1;
176 static gint ett_hash_buckets_assignment_wc_element
=-1;
177 static gint ett_hash_buckets_assignment_buckets
=-1;
178 static gint ett_router_alt_assignment_element
= -1;
179 static gint ett_router_assignment_info
= -1;
180 static gint ett_query_info
= -1;
181 static gint ett_capabilities_info
= -1;
182 static gint ett_capability_element
= -1;
183 static gint ett_capability_forwarding_method
= -1;
184 static gint ett_capability_assignment_method
= -1;
185 static gint ett_capability_return_method
= -1;
186 static gint ett_capability_transmit_t
= -1;
187 static gint ett_capability_timer_scale
= -1;
188 static gint ett_alt_assignment_info
= -1;
189 static gint ett_alt_assignment_map
= -1;
190 static gint ett_address_table
= -1;
191 static gint ett_assignment_map
= -1;
192 static gint ett_command_extension
= -1;
193 static gint ett_alternate_mask_value_set
=-1;
194 static gint ett_alternate_mask_value_set_element
=-1;
195 static gint ett_mv_set_list
= -1;
196 static gint ett_mv_set_element
= -1;
197 static gint ett_mv_set_value_list
= -1;
198 static gint ett_alternate_mv_set_element_list
= -1;
199 static gint ett_web_cache_value_element_list
= -1;
200 static gint ett_alternate_mv_set_element
= -1;
201 static gint ett_value_element
= -1;
202 static gint ett_unknown_info
= -1;
204 static expert_field ei_wccp_missing_security_info
= EI_INIT
;
205 static expert_field ei_wccp_missing_service_info
= EI_INIT
;
206 static expert_field ei_wccp_missing_wc_id_info
= EI_INIT
;
207 static expert_field ei_wccp_missing_router_id_info
= EI_INIT
;
208 static expert_field ei_wccp_missing_query_info
= EI_INIT
;
209 static expert_field ei_wccp_missing_wc_view_info
= EI_INIT
;
210 static expert_field ei_wccp_missing_rtr_view_info
= EI_INIT
;
211 static expert_field ei_wccp_contains_redirect_assignment
= EI_INIT
;
212 static expert_field ei_wccp_contains_router_id_info
= EI_INIT
;
213 static expert_field ei_wccp_contains_rtr_view_info
= EI_INIT
;
214 static expert_field ei_wccp_contains_query_info
= EI_INIT
;
215 static expert_field ei_wccp_contains_alt_assignment
= EI_INIT
;
216 static expert_field ei_wccp_contains_assign_map
= EI_INIT
;
217 static expert_field ei_wccp_contains_alt_assignment_map
= EI_INIT
;
218 static expert_field ei_wccp_contains_wc_id_info
= EI_INIT
;
219 static expert_field ei_wccp_contains_wc_view_info
= EI_INIT
;
220 static expert_field ei_wccp_contains_capabilities_info
= EI_INIT
;
221 static expert_field ei_wccp_contains_command_extension
= EI_INIT
;
222 static expert_field ei_wccp_missing_assignment
= EI_INIT
;
223 static expert_field ei_wccp_assignment_length_bad
= EI_INIT
;
224 static expert_field ei_wccp_length_bad
= EI_INIT
;
225 static expert_field ei_wccp_service_info_priority_nonzero
= EI_INIT
;
226 static expert_field ei_wccp_service_info_protocol_nonzero
= EI_INIT
;
227 static expert_field ei_wccp_router_identity_receive_id_zero
= EI_INIT
;
228 static expert_field ei_wccp_web_cache_identity_hash_rev_zero
= EI_INIT
;
229 static expert_field ei_wccp_address_table_family_unknown
= EI_INIT
;
230 static expert_field ei_wccp_capability_element_length
= EI_INIT
;
235 * http://tools.ietf.org/html/draft-forster-wrec-wccp-v1-00
237 * is a copy of the now-expired Internet-Draft for WCCP 1.0.
241 * http://tools.ietf.org/id/draft-wilson-wrec-wccp-v2-01.txt
243 * is an Internet-Draft for WCCP 2.0.
245 * http://tools.ietf.org/html/draft-mclaggan-wccp-v2rev1
247 * is the current draft for WCCP 2.01
251 /* This is NOT IANA assigned */
252 #define UDP_PORT_WCCP 2048
255 #define WCCPv2 0x0200
256 #define WCCPv2r1 0x0201
257 #define WCCP_HERE_I_AM 7
258 #define WCCP_I_SEE_YOU 8
259 #define WCCP_ASSIGN_BUCKET 9
260 #define WCCP2_HERE_I_AM 10
261 #define WCCP2_I_SEE_YOU 11
262 #define WCCP2_REDIRECT_ASSIGN 12
263 #define WCCP2_REMOVAL_QUERY 13
265 static const value_string wccp_type_vals
[] = {
266 { WCCP_HERE_I_AM
, "1.0 Here I am" },
267 { WCCP_I_SEE_YOU
, "1.0 I see you" },
268 { WCCP_ASSIGN_BUCKET
, "1.0 Assign bucket" },
269 { WCCP2_HERE_I_AM
, "2.0 Here I am" },
270 { WCCP2_I_SEE_YOU
, "2.0 I see you" },
271 { WCCP2_REDIRECT_ASSIGN
, "2.0 Redirect assign" },
272 { WCCP2_REMOVAL_QUERY
, "2.0 Removal query" },
276 static const value_string wccp_version_val
[] = {
283 const true_false_string tfs_defined_not_defined
= { "Defined", "Not defined" };
284 const true_false_string tfs_src_dest_port
= { "Source port", "Destination port" };
285 const true_false_string tfs_redirect_protocol0
= { "Redirect only protocol 0 (IP)", "Redirect all traffic" };
286 const true_false_string tfs_historical_current
= { "Historical", "Current" };
287 const true_false_string tfs_version_min_max
= {"WCCP version set is maximum supported by CE", "WCCP version set is minimum supported by CE"};
289 static const value_string wccp_address_family_val
[] = {
297 #define WCCP2_HASH_ASSIGNMENT_TYPE 0
298 #define WCCP2_MASK_ASSIGNMENT_TYPE 1
299 #define WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE 2
300 #define WCCP2r1_ASSIGNMENT_WEIGHT_STATUS 3
302 static const value_string assignment_type_vals
[] = {
303 { WCCP2_HASH_ASSIGNMENT_TYPE
, "Hash" },
304 { WCCP2_MASK_ASSIGNMENT_TYPE
, "Mask" },
305 { WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
, "WCCP2r1 Alternate Mask"},
306 { WCCP2r1_ASSIGNMENT_WEIGHT_STATUS
, "WCCP2r1 Assignment Weight Status"},
310 #define HASH_INFO_SIZE (4*(1+8+1))
312 #define WCCP2_SECURITY_INFO 0
313 #define WCCP2_SERVICE_INFO 1
314 #define WCCP2_ROUTER_ID_INFO 2
315 #define WCCP2_WC_ID_INFO 3
316 #define WCCP2_RTR_VIEW_INFO 4
317 #define WCCP2_WC_VIEW_INFO 5
318 #define WCCP2_REDIRECT_ASSIGNMENT 6
319 #define WCCP2_QUERY_INFO 7
320 #define WCCP2_CAPABILITIES_INFO 8
321 #define WCCP2_ALT_ASSIGNMENT 13
322 #define WCCP2_ASSIGN_MAP 14
323 #define WCCP2_COMMAND_EXTENSION 15
324 /* WCCP 2 r1 additions: */
325 #define WCCP2r1_ALT_ASSIGNMENT_MAP 16
326 #define WCCP2r1_ADDRESS_TABLE 17
328 static const value_string info_type_vals
[] = {
329 { WCCP2_SECURITY_INFO
, "Security Info" },
330 { WCCP2_SERVICE_INFO
, "Service Info" },
331 { WCCP2_ROUTER_ID_INFO
, "Router Identity Info" },
332 { WCCP2_WC_ID_INFO
, "Web-Cache Identity Info" },
333 { WCCP2_RTR_VIEW_INFO
, "Router View Info" },
334 { WCCP2_WC_VIEW_INFO
, "Web-Cache View Info" },
335 { WCCP2_REDIRECT_ASSIGNMENT
, "Assignment Info" },
336 { WCCP2_QUERY_INFO
, "Router Query Info" },
337 { WCCP2_CAPABILITIES_INFO
, "Capabilities Info" },
338 { WCCP2_ALT_ASSIGNMENT
, "Alternate Assignment" },
339 { WCCP2_ASSIGN_MAP
, "Assignment Map" },
340 { WCCP2_COMMAND_EXTENSION
, "Command Extension" },
341 { WCCP2r1_ALT_ASSIGNMENT_MAP
, "Alternative Assignment Map" },
342 { WCCP2r1_ADDRESS_TABLE
, "Address Table" },
346 const value_string service_id_vals
[] = {
351 typedef struct capability_flag
{
353 const char *short_name
;
360 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_HASH 0
361 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_MASK 1
362 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_NOT_PRESENT 2
363 #define WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_EXTENDED 3
365 static const value_string wccp_web_cache_assignment_data_type_val
[] = {
366 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_HASH
, "Hash Assignment Data Element"},
367 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_MASK
, "Mask Assignment Data Element"},
368 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_NOT_PRESENT
, "Assignment Data Element Not Present"},
369 { WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_EXTENDED
, "Extended Assignment Data Element"},
373 #define WCCP2_FORWARDING_METHOD 0x01
374 #define WCCP2_ASSIGNMENT_METHOD 0x02
375 #define WCCP2_PACKET_RETURN_METHOD 0x03
376 #define WCCP2_TRANSMIT_T 0x04
377 #define WCCP2_TIMER_SCALE 0x05
379 static const value_string capability_type_vals
[] = {
380 { WCCP2_FORWARDING_METHOD
, "Forwarding Method" },
381 { WCCP2_ASSIGNMENT_METHOD
, "Assignment Method" },
382 { WCCP2_PACKET_RETURN_METHOD
, "Packet Return Method" },
383 { WCCP2_TRANSMIT_T
, "Transmit_t Message interval values"},
384 { WCCP2_TIMER_SCALE
, "Timer_scale Timeout scale values"},
389 /* with version 2.01 we now have a address table which is possibly present */
391 typedef struct wccp_address_table
{
395 guint16 table_length
;
397 struct e_in6_addr
*table_ipv6
;
398 } wccp_address_table
;
401 wccp_address_table wccp_wccp_address_table
;
403 static guint
dissect_hash_data(tvbuff_t
*tvb
, int offset
,
404 proto_tree
*wccp_tree
);
405 static guint
dissect_web_cache_list_entry(tvbuff_t
*tvb
, int offset
,
406 int idx
, proto_tree
*wccp_tree
);
407 static int wccp_bucket_info(guint8 bucket_info
, proto_tree
*bucket_tree
,
408 guint32 start
, tvbuff_t
*tvb
, int offset
);
409 static gchar
*bucket_name(guint8 bucket
);
410 static guint16
dissect_wccp2_header(tvbuff_t
*tvb
, int offset
,
411 proto_tree
*wccp_tree
);
412 static void dissect_wccp2_info(tvbuff_t
*tvb
, int offset
, guint16 length
,
413 packet_info
*pinfo
, proto_tree
*wccp_tree
, guint32 wccp_message_type
);
415 /* WCCP 2r1 IPv6 utlility functions */
416 static void find_wccp_address_table(tvbuff_t
*tvb
, int offset
, guint16 length
,
417 packet_info
*pinfo _U_
, proto_tree
*wccp_tree _U_
);
418 /* The V2 dissectors will return the remaining length of the packet
419 and a negative number if there are missing bytes to finish the
421 static gint
dissect_wccp2_security_info(tvbuff_t
*tvb
, int offset
, gint lengreth
,
422 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
423 static gint
dissect_wccp2_service_info(tvbuff_t
*tvb
, int offset
, gint length
,
424 packet_info
*pinfo
, proto_tree
*info_tree
);
425 static gint
dissect_wccp2r1_address_table_info(tvbuff_t
*tvb
, int offset
,
426 int length
, packet_info
*pinfo
, proto_tree
*info_tree
);
427 static gint
dissect_wccp2_router_identity_info(tvbuff_t
*tvb
, int offset
, gint length
,
428 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
429 static gint
dissect_wccp2_wc_identity_info(tvbuff_t
*tvb
, int offset
, gint length
,
430 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
431 static gint
dissect_wccp2_router_view_info(tvbuff_t
*tvb
, int offset
, gint length
,
432 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
433 static gint
dissect_wccp2_web_cache_view_info(tvbuff_t
*tvb
, int offset
, gint length
,
434 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
435 static gint
dissect_wccp2_assignment_info(tvbuff_t
*tvb
, int offset
, gint length
,
436 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
437 static gint
dissect_wccp2_hash_buckets_assignment_element(tvbuff_t
*tvb
, int offset
, gint length
,
438 packet_info
*pinfo
, proto_tree
*info_tree
);
439 static gboolean
dissect_wccp2_router_query_info(tvbuff_t
*tvb
, int offset
, gint length
,
440 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
441 static gint
dissect_wccp2_capability_info(tvbuff_t
*tvb
, int offset
, gint length
,
442 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
443 static gint
dissect_wccp2_alternate_assignment_info(tvbuff_t
*tvb
, int offset
, gint length
,
444 packet_info
*pinfo
, proto_tree
*info_tree
);
445 static gint
dissect_wccp2_hash_assignment_info(tvbuff_t
*tvb
, int offset
, gint length
,
446 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
447 static gint
dissect_wccp2_assignment_map(tvbuff_t
*tvb
, int offset
,
448 int length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
);
449 static gint
dissect_wccp2r1_alt_assignment_map_info(tvbuff_t
*tvb
, int offset
,
450 int length
, packet_info
*pinfo
, proto_tree
*info_tree
);
451 static gint
dissect_wccp2_command_extension(tvbuff_t
*tvb
, int offset
,
452 int length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
);
453 static void dissect_wccp2_router_identity_element(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
455 static gint
dissect_wccp2_web_cache_identity_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
456 proto_tree
*info_tree
);
457 static gint
dissect_wccp2_hash_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
458 proto_tree
*info_tree
);
459 static gint
dissect_wccp2_mask_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
460 proto_tree
*info_tree
) ;
461 static gint
dissect_wccp2_alternate_mask_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
462 proto_tree
*info_tree
);
463 static gint
dissect_wccp2_assignment_weight_and_status_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
464 proto_tree
*info_tree
);
465 static gint
dissect_wccp2_extended_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
466 proto_tree
*info_tree
);
467 static gint
dissect_wccp2_assignment_key_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
468 proto_tree
*info_tree
);
469 static void dissect_wccp2_router_assignment_element(tvbuff_t
*tvb
, int offset
, gint length
,
470 packet_info
*pinfo
, proto_tree
*info_tree
) ;
471 static gint
dissect_wccp2_capability_element(tvbuff_t
*tvb
, int offset
, gint length
,
472 packet_info
*pinfo _U_
, proto_tree
*info_tree
);
473 static gint
dissect_wccp2_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
474 int length
, packet_info
*pinfo
, proto_tree
*info_tree
);
476 /* Utility functions */
477 static gint
dissect_wccp2_mask_value_set_element(tvbuff_t
*tvb
, int offset
,
478 gint length
, int idx
, packet_info
*pinfo
, proto_tree
*info_tree
);
479 static gint
dissect_wccp2_mask_element(tvbuff_t
*tvb
, int offset
,
480 gint length
, packet_info
*pinfo
, proto_tree
*info_tree
);
481 static gint
dissect_wccp2_value_element(tvbuff_t
*tvb
, int offset
,
482 gint length
, int idx
, packet_info
*pinfo
, proto_tree
*info_tree
);
483 static gint
dissect_wccp2_alternate_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
484 gint length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
);
485 static gint
dissect_wccp2_alternate_mask_value_set_element(tvbuff_t
*tvb
, int offset
, gint length
, guint el_index
, packet_info
*pinfo
, proto_tree
*info_tree
);
486 static gint
dissect_wccp2_web_cache_value_element(tvbuff_t
*tvb
, int offset
,
487 gint length
, packet_info
*pinfo
, proto_tree
*info_tree
);
488 static gchar
*assignment_bucket_name(guint8 bucket
);
489 static void dissect_32_bit_capability_flags(tvbuff_t
*tvb
, int curr_offset
,
490 guint16 capability_val_len
, gint ett
, const capability_flag
*flags
,
491 proto_tree
*element_tree
, proto_item
*header
);
492 static void dissect_transmit_t_capability(tvbuff_t
*tvb
, proto_item
*te
, int curr_offset
,
493 guint16 capability_val_len
, gint ett
, proto_tree
*element_tree
);
494 static void dissect_timer_scale_capability(tvbuff_t
*tvb
, int curr_offset
,
495 guint16 capability_val_len
, gint ett
, proto_tree
*element_tree
);
501 * In WCCP 2.01 addresses are encoded to support IPv6 with 32 bit fields
503 * handle the decoding
507 find_wccp_address_table(tvbuff_t
*tvb
, int offset
, guint16 length
,
508 packet_info
*pinfo _U_
, proto_tree
*wccp_tree _U_
)
513 /* first clean up: */
514 wccp_wccp_address_table
.in_use
= FALSE
;
515 wccp_wccp_address_table
.family
= -1;
516 wccp_wccp_address_table
.version
= -1;
517 wccp_wccp_address_table
.table_length
= 0;
518 wccp_wccp_address_table
.table_ipv4
= (guint32
*) NULL
;
519 wccp_wccp_address_table
.table_ipv6
= (struct e_in6_addr
*)NULL
;
521 while (length
>= 4) {
522 type
= tvb_get_ntohs(tvb
, offset
);
523 item_length
= tvb_get_ntohs(tvb
, offset
+2);
525 if (item_length
> tvb_length_remaining(tvb
, offset
))
528 if (type
== WCCP2r1_ADDRESS_TABLE
)
530 dissect_wccp2r1_address_table_info(tvb
, offset
+4, item_length
, NULL
, NULL
);
531 /* no need to decode the rest */
535 /* check if we _can_ advance */
536 if (length
< (item_length
+4))
539 offset
= offset
+ item_length
+ 4;
540 length
= length
- item_length
- 4;
545 /* This function prints the IP or the encoded IP if the table exists */
547 /* at most an IPv6 IP: see
548 http://stackoverflow.com/questions/166132/maximum-length-of-the-textual-representation-of-an-ipv6-address
550 39 = 8 groups of 4 digits with 7 : characters
554 45 = IPv4 tunnel features: 0000:0000:0000:0000:0000:0000:192.168.0.1
557 /* problem here is that the IP is in network byte order for IPv4
561 static void wccp_fmt_ipadddress(gchar
*buffer
, guint32 host_addr
)
563 /* are we using an address table? */
564 if (! wccp_wccp_address_table
.in_use
)
566 /* no return the IPv4 IP */
567 /* first fix the byte order */
568 guint addr
= GUINT32_SWAP_LE_BE(host_addr
);
570 ip_to_str_buf( (guint8
*) &addr
, buffer
, ITEM_LABEL_LENGTH
);
575 /* we need to decode the encoded address: */
576 guint16 reserv
= (host_addr
& 0xFF00) >> 16;
577 guint16 addr_index
= (host_addr
& 0x00FF);
580 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "INVALID: reserved part non zero");
584 /* now check if it's IPv4 or IPv6 we need to print */
585 switch (wccp_wccp_address_table
.family
) {
589 /* special case: index 0 -> undefined IP */
590 if (addr_index
== 0) {
591 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "0.0.0.0");
594 /* are we be beyond the end of the table? */
595 if (addr_index
> wccp_wccp_address_table
.table_length
) {
596 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "INVALID IPv4 index: %d > %d",
597 addr_index
, wccp_wccp_address_table
.table_length
);
602 if (wccp_wccp_address_table
.table_ipv4
!= NULL
) {
603 ip_to_str_buf( (guint8
*) &(wccp_wccp_address_table
.table_ipv4
[addr_index
-1]), buffer
, ITEM_LABEL_LENGTH
);
607 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "INVALID IPv4 table empty!");
613 /* special case: index 0 -> undefined IP */
614 if (addr_index
== 0) {
615 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "::");
619 /* are we be beyond the end of the table? */
620 if (addr_index
> wccp_wccp_address_table
.table_length
) {
621 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "INVALID IPv6 index: %d > %d",
622 addr_index
, wccp_wccp_address_table
.table_length
);
627 if (wccp_wccp_address_table
.table_ipv6
!= NULL
) {
628 ip6_to_str_buf(&(wccp_wccp_address_table
.table_ipv6
[addr_index
-1]), buffer
);
632 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "INVALID IPv6 table empty!");
637 g_snprintf(buffer
, ITEM_LABEL_LENGTH
, "INVALID IP family");
644 #define WCCP_IP_MAX_LENGTH (MAX_IP_STR_LEN > 46 ? MAX_IP_STR_LEN : 46)
647 static const gchar
* decode_wccp_encoded_address(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*info_tree _U_
)
652 buffer
= (char *) wmem_alloc(wmem_packet_scope(), WCCP_IP_MAX_LENGTH
+1);
653 host_addr
= tvb_get_ntohl(tvb
,offset
);
655 wccp_fmt_ipadddress(buffer
, host_addr
);
660 dissect_wccp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
663 proto_tree
*wccp_tree
= NULL
;
664 proto_item
*wccp_tree_item
;
665 guint32 wccp_message_type
;
671 wccp_message_type
= tvb_get_ntohl(tvb
, offset
);
673 /* Check if this is really a WCCP message */
674 if (try_val_to_str(wccp_message_type
, wccp_type_vals
) == NULL
)
677 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "WCCP");
679 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(wccp_message_type
,
680 wccp_type_vals
, "Unknown WCCP message (%u)"));
682 wccp_tree_item
= proto_tree_add_item(tree
, proto_wccp
, tvb
, offset
, -1, ENC_NA
);
683 wccp_tree
= proto_item_add_subtree(wccp_tree_item
, ett_wccp
);
685 proto_tree_add_uint(wccp_tree
, hf_wccp_message_type
, tvb
, offset
, 4, wccp_message_type
);
688 switch (wccp_message_type
) {
691 proto_tree_add_item(wccp_tree
, hf_wccp_version
, tvb
,
692 offset
, 4, ENC_BIG_ENDIAN
);
694 offset
= dissect_hash_data(tvb
, offset
, wccp_tree
);
695 proto_tree_add_item(wccp_tree
, hf_recvd_id
, tvb
, offset
,
701 proto_tree_add_item(wccp_tree
, hf_wccp_version
, tvb
,
702 offset
, 4, ENC_BIG_ENDIAN
);
704 proto_tree_add_item(wccp_tree
, hf_change_num
, tvb
, offset
,
707 proto_tree_add_item(wccp_tree
, hf_recvd_id
, tvb
, offset
,
710 cache_count
= tvb_get_ntohl(tvb
, offset
);
711 proto_tree_add_uint(wccp_tree
, hf_wc_num
, tvb
, offset
, 4, cache_count
);
713 for (i
= 0; i
< cache_count
; i
++) {
714 offset
= dissect_web_cache_list_entry(tvb
, offset
, i
,
719 case WCCP_ASSIGN_BUCKET
:
721 * This hasn't been tested, since I don't have any
722 * traces with this in it.
724 * The V1 spec claims that this does, indeed,
725 * have a Received ID field after the type,
726 * rather than a Version field.
728 proto_tree_add_item(wccp_tree
, hf_recvd_id
, tvb
, offset
,
731 cache_count
= tvb_get_ntohl(tvb
, offset
);
732 proto_tree_add_uint(wccp_tree
, hf_wc_num
, tvb
, offset
, 4, cache_count
);
734 for (i
= 0; i
< cache_count
; i
++) {
735 ipaddr
= tvb_get_ipv4(tvb
, offset
);
736 proto_tree_add_ipv4_format(wccp_tree
,
737 hf_cache_ip
, tvb
, offset
, 4,
739 "Web Cache %d IP Address: %s", i
,
740 ip_to_str((guint8
*)&ipaddr
));
743 for (i
= 0; i
< 256; i
+= 4) {
744 proto_tree_add_text(wccp_tree
, tvb
, offset
, 4,
745 "Buckets %d - %d: %10s %10s %10s %10s",
747 bucket_name(tvb_get_guint8(tvb
, offset
)),
748 bucket_name(tvb_get_guint8(tvb
, offset
+1)),
749 bucket_name(tvb_get_guint8(tvb
, offset
+2)),
750 bucket_name(tvb_get_guint8(tvb
, offset
+3)));
755 case WCCP2_HERE_I_AM
:
756 case WCCP2_I_SEE_YOU
:
757 case WCCP2_REMOVAL_QUERY
:
758 case WCCP2_REDIRECT_ASSIGN
:
759 default: /* assume unknown packets are v2 */
760 length
= dissect_wccp2_header(tvb
, offset
, wccp_tree
);
762 dissect_wccp2_info(tvb
, offset
, length
, pinfo
, wccp_tree
, wccp_message_type
);
766 return tvb_length(tvb
);
770 dissect_hash_data(tvbuff_t
*tvb
, int offset
, proto_tree
*wccp_tree
)
772 proto_item
*bucket_item
;
773 proto_tree
*bucket_tree
;
775 proto_tree
*field_tree
;
780 proto_tree_add_item(wccp_tree
, hf_hash_revision
, tvb
, offset
, 4,
784 bucket_item
= proto_tree_add_text(wccp_tree
, tvb
, offset
, 32,
786 bucket_tree
= proto_item_add_subtree(bucket_item
, ett_buckets
);
788 for (i
= 0, n
= 0; i
< 32; i
++) {
789 bucket_info
= tvb_get_guint8(tvb
, offset
);
790 n
= wccp_bucket_info(bucket_info
, bucket_tree
, n
, tvb
, offset
);
793 tf
= proto_tree_add_item(wccp_tree
, hf_hash_flag
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
794 field_tree
= proto_item_add_subtree(tf
, ett_hash_flags
);
795 proto_tree_add_item(field_tree
, hf_hash_flag_u
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
801 dissect_web_cache_list_entry(tvbuff_t
*tvb
, int offset
, int idx
,
802 proto_tree
*wccp_tree
)
805 proto_tree
*list_entry_tree
;
807 tl
= proto_tree_add_text(wccp_tree
, tvb
, offset
, 4 + HASH_INFO_SIZE
,
808 "Web-Cache List Entry(%d)", idx
);
809 list_entry_tree
= proto_item_add_subtree(tl
, ett_cache_info
);
810 proto_tree_add_item(list_entry_tree
, hf_cache_ip
, tvb
, offset
, 4,
813 offset
= dissect_hash_data(tvb
, offset
, list_entry_tree
);
819 * takes an integer representing a "Hash Information" bitmap, and spits out
820 * the corresponding proto_tree entries, returning the next bucket number.
823 wccp_bucket_info(guint8 bucket_info
, proto_tree
*bucket_tree
, guint32 start
,
824 tvbuff_t
*tvb
, int offset
)
828 for(i
= 0; i
< 8; i
++) {
829 proto_tree_add_text(bucket_tree
, tvb
, offset
, sizeof(bucket_info
), "Bucket %3d: %s", start
, (bucket_info
& 1<<i
? "Assigned" : "Not Assigned") );
836 bucket_name(guint8 bucket
)
838 if (bucket
== 0xff) {
839 return (gchar
*) "Unassigned";
841 return wmem_strdup_printf(wmem_packet_scope(), "%u", bucket
);
846 /* 5.5 WCCP Message Header */
848 dissect_wccp2_header(tvbuff_t
*tvb
, int offset
, proto_tree
*wccp_tree
)
852 proto_tree_add_item(wccp_tree
, hf_message_header_version
, tvb
, offset
, 2,
855 length
= tvb_get_ntohs(tvb
, offset
);
856 proto_tree_add_uint(wccp_tree
, hf_message_header_length
, tvb
, offset
, 2, length
);
862 dissect_wccp2_info(tvbuff_t
*tvb
, int offset
, guint16 length
,
863 packet_info
*pinfo
, proto_tree
*wccp_tree
,
864 guint32 message_type
)
869 proto_tree
*info_tree
;
871 gint (*dissector
)(tvbuff_t
*, int, int, packet_info
*, proto_tree
*);
873 /* check if all required fields are there */
874 gboolean wccp2_security_info
;
875 gboolean wccp2_service_info
;
876 gboolean wccp2_router_id_info
;
877 gboolean wccp2_wc_id_info
;
878 gboolean wccp2_rtr_view_info
;
879 gboolean wccp2_wc_view_info
;
880 gboolean wccp2_redirect_assignment
;
881 gboolean wccp2_query_info
;
882 gboolean wccp2_capabilities_info
;
883 gboolean wccp2_alt_assignment
;
884 gboolean wccp2_assign_map
;
885 gboolean wccp2_command_extension
;
886 gboolean wccp2r1_alt_assignment_map
;
888 wccp2_security_info
=FALSE
;
889 wccp2_service_info
=FALSE
;
890 wccp2_router_id_info
=FALSE
;
891 wccp2_wc_id_info
=FALSE
;
892 wccp2_rtr_view_info
=FALSE
;
893 wccp2_wc_view_info
=FALSE
;
894 wccp2_redirect_assignment
=FALSE
;
895 wccp2_query_info
=FALSE
;
896 wccp2_capabilities_info
=FALSE
;
897 wccp2_alt_assignment
=FALSE
;
898 wccp2_assign_map
=FALSE
;
899 wccp2_command_extension
=FALSE
;
900 wccp2r1_alt_assignment_map
=FALSE
;
902 /* ugly hack: we first need to check for the address table
903 compnent, otherwise we cannot print the IP's.
905 find_wccp_address_table(tvb
,offset
,length
,pinfo
,wccp_tree
);
907 while (length
!= 0) {
910 tf
= proto_tree_add_text(wccp_tree
, tvb
, offset
, length
,
911 "Invalid WCCP Type/Length values");
913 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
914 "The packet only has %d bytes left. That is not enough for a WCCP item type and length.",
919 type
= tvb_get_ntohs(tvb
, offset
);
920 item_length
= tvb_get_ntohs(tvb
, offset
+2);
923 if (item_length
> tvb_length_remaining(tvb
, offset
)) {
924 tf
= proto_tree_add_text(wccp_tree
, tvb
, offset
, length
,
925 "Excessive WCCP Length values");
926 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
927 "The length of the item is %d but there are only %d bytes remaining in the packet, I counted %d remaining",
928 item_length
, tvb_length_remaining(tvb
, offset
), length
);
933 case WCCP2_SECURITY_INFO
:
934 wccp2_security_info
=TRUE
;
935 ett
= ett_security_info
;
936 dissector
= dissect_wccp2_security_info
;
939 case WCCP2_SERVICE_INFO
:
940 wccp2_service_info
=TRUE
;
941 ett
= ett_service_info
;
942 dissector
= dissect_wccp2_service_info
;
945 case WCCP2_ROUTER_ID_INFO
:
946 wccp2_router_id_info
=TRUE
;
947 ett
= ett_router_identity_info
;
948 dissector
= dissect_wccp2_router_identity_info
;
951 case WCCP2_WC_ID_INFO
:
952 wccp2_wc_id_info
=TRUE
;
953 ett
= ett_wc_identity_info
;
954 dissector
= dissect_wccp2_wc_identity_info
;
957 case WCCP2_RTR_VIEW_INFO
:
958 wccp2_rtr_view_info
=TRUE
;
959 ett
= ett_router_view_info
;
960 dissector
= dissect_wccp2_router_view_info
;
963 case WCCP2_WC_VIEW_INFO
:
964 wccp2_wc_view_info
=TRUE
;
965 ett
= ett_wc_view_info
;
966 dissector
= dissect_wccp2_web_cache_view_info
;
969 case WCCP2_REDIRECT_ASSIGNMENT
:
970 wccp2_redirect_assignment
=TRUE
;
971 ett
= ett_router_assignment_info
;
972 dissector
= dissect_wccp2_assignment_info
;
975 case WCCP2_QUERY_INFO
:
976 wccp2_query_info
=TRUE
;
977 ett
= ett_query_info
;
978 dissector
= dissect_wccp2_router_query_info
;
981 case WCCP2_CAPABILITIES_INFO
:
982 wccp2_capabilities_info
=TRUE
;
983 ett
= ett_capabilities_info
;
984 dissector
= dissect_wccp2_capability_info
;
987 case WCCP2_ALT_ASSIGNMENT
:
988 wccp2_alt_assignment
=TRUE
;
989 ett
= ett_alt_assignment_info
;
990 dissector
= dissect_wccp2_alternate_assignment_info
;
993 case WCCP2r1_ALT_ASSIGNMENT_MAP
:
994 wccp2r1_alt_assignment_map
=TRUE
;
995 ett
= ett_alt_assignment_map
;
996 dissector
= dissect_wccp2r1_alt_assignment_map_info
;
999 case WCCP2r1_ADDRESS_TABLE
:
1000 ett
= ett_address_table
;
1001 dissector
= dissect_wccp2r1_address_table_info
;
1004 case WCCP2_ASSIGN_MAP
:
1005 wccp2_assign_map
=TRUE
;
1006 ett
= ett_assignment_map
;
1007 dissector
= dissect_wccp2_assignment_map
;
1009 case WCCP2_COMMAND_EXTENSION
:
1010 wccp2_command_extension
=TRUE
;
1011 ett
= ett_command_extension
;
1012 dissector
= dissect_wccp2_command_extension
;
1016 ett
= ett_unknown_info
;
1021 tf
= proto_tree_add_text(wccp_tree
, tvb
, offset
, item_length
+ 4, "%s",
1022 val_to_str(type
, info_type_vals
, "Unknown info type (%u)"));
1023 info_tree
= proto_item_add_subtree(tf
, ett
);
1024 proto_tree_add_item(info_tree
, hf_item_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1025 proto_tree_add_item(info_tree
, hf_item_length
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
1030 if (length
< item_length
) {
1031 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
1032 "The item has length %d but the remaining WCCP data is only %d long",
1037 if (dissector
!= NULL
) {
1038 gint remaining_item_length
= (*dissector
)(tvb
, offset
, item_length
, pinfo
, info_tree
);
1040 /* warn if we left bytes */
1041 if (remaining_item_length
> 0)
1042 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
1043 "The dissector left %d bytes undecoded",
1044 remaining_item_length
);
1046 /* error if we needed more bytes */
1047 if (remaining_item_length
< 0)
1048 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
1049 "The dissector needed %d more bytes to decode the packet, but the item is not that long",
1050 remaining_item_length
);
1052 /* we assume that the item length is correct and jump forward */
1054 proto_tree_add_item(info_tree
, hf_item_data
, tvb
, offset
, item_length
, ENC_NA
);
1056 /* avoid looping forever */
1057 if (length
< item_length
)
1060 offset
+= item_length
;
1062 /* should no happen....*/
1063 DISSECTOR_ASSERT( ( (signed int) length
- item_length
) >= 0);
1064 length
-= item_length
;
1068 /* we're done. Check if we got all the required components */
1070 switch (message_type
) {
1071 case WCCP2_HERE_I_AM
:
1072 if (!wccp2_security_info
)
1073 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
1074 if (!wccp2_service_info
)
1075 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
1076 if (wccp2_router_id_info
)
1077 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_router_id_info
);
1078 if (!wccp2_wc_id_info
)
1079 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_wc_id_info
);
1080 if (wccp2_rtr_view_info
)
1081 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_rtr_view_info
);
1082 if (!wccp2_wc_view_info
)
1083 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_wc_view_info
);
1084 if (wccp2_redirect_assignment
)
1085 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_redirect_assignment
);
1086 if (wccp2_query_info
)
1087 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_query_info
);
1088 if (wccp2_alt_assignment
)
1089 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment
);
1090 if (wccp2_assign_map
)
1091 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_assign_map
);
1092 if (wccp2r1_alt_assignment_map
)
1093 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment_map
);
1095 case WCCP2_I_SEE_YOU
:
1096 if (!wccp2_security_info
)
1097 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
1098 if (!wccp2_service_info
)
1099 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
1100 if (!wccp2_router_id_info
)
1101 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_router_id_info
);
1102 if (wccp2_wc_id_info
)
1103 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_id_info
);
1104 if (!wccp2_rtr_view_info
)
1105 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_rtr_view_info
);
1106 if (wccp2_wc_view_info
)
1107 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_view_info
);
1108 if (wccp2_redirect_assignment
)
1109 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_redirect_assignment
);
1110 if (wccp2_query_info
)
1111 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_query_info
);
1112 if (wccp2r1_alt_assignment_map
)
1113 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment_map
);
1116 case WCCP2_REMOVAL_QUERY
:
1117 if (!wccp2_security_info
)
1118 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
1119 if (!wccp2_service_info
)
1120 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
1121 if (wccp2_router_id_info
)
1122 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_router_id_info
);
1123 if (wccp2_wc_id_info
)
1124 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_id_info
);
1125 if (wccp2_rtr_view_info
)
1126 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_rtr_view_info
);
1127 if (wccp2_wc_view_info
)
1128 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_view_info
);
1129 if (wccp2_redirect_assignment
)
1130 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_redirect_assignment
);
1131 if (!wccp2_query_info
)
1132 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_query_info
);
1133 if (wccp2_capabilities_info
)
1134 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_capabilities_info
);
1135 if (wccp2_alt_assignment
)
1136 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment
);
1137 if (wccp2_assign_map
)
1138 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_assign_map
);
1139 if (wccp2_command_extension
)
1140 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_command_extension
);
1141 if (wccp2r1_alt_assignment_map
)
1142 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_alt_assignment_map
);
1145 case WCCP2_REDIRECT_ASSIGN
:
1146 if (!wccp2_security_info
)
1147 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_security_info
);
1148 if (!wccp2_service_info
)
1149 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_service_info
);
1150 if (wccp2_router_id_info
)
1151 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_router_id_info
);
1152 if (wccp2_wc_id_info
)
1153 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_id_info
);
1154 if (wccp2_rtr_view_info
)
1155 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_rtr_view_info
);
1156 if (wccp2_wc_view_info
)
1157 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_wc_view_info
);
1158 if (wccp2_query_info
)
1159 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_query_info
);
1160 if (wccp2_capabilities_info
)
1161 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_capabilities_info
);
1162 if (! (wccp2_assign_map
|| wccp2r1_alt_assignment_map
|| wccp2_alt_assignment
|| wccp2_redirect_assignment
))
1163 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_missing_assignment
);
1164 if (wccp2_command_extension
)
1165 expert_add_info(pinfo
, wccp_tree
, &ei_wccp_contains_command_extension
);
1170 /* the following functions all need to check the length and the offset
1171 so we have a few macros to use
1174 #define EAT(x) {length -= x; offset += x;}
1176 #define EAT_AND_CHECK(x,next) {length -= x; offset += x; if (length < next) return length - next;}
1178 #define NOTE_EATEN_LENGTH(new_length) {if (new_length<0) return new_length; offset += length-new_length; length = new_length; }
1181 /* 5.1.1 Security Info Component */
1183 /* Security options */
1185 #define WCCP2_NO_SECURITY 0
1186 #define WCCP2_MD5_SECURITY 1
1188 #define SECURITY_INFO_LEN 4
1190 const value_string security_option_vals
[] = {
1191 { WCCP2_NO_SECURITY
, "None" },
1192 { WCCP2_MD5_SECURITY
, "MD5" },
1198 dissect_wccp2_security_info(tvbuff_t
*tvb
, int offset
, gint length
,
1199 packet_info
*pinfo _U_
, proto_tree
*info_tree
)
1201 guint32 security_option
;
1203 if (length
< SECURITY_INFO_LEN
)
1204 return (length
-SECURITY_INFO_LEN
);
1206 security_option
= tvb_get_ntohl(tvb
, offset
);
1207 proto_tree_add_item(info_tree
, hf_security_info_option
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1209 if (security_option
== WCCP2_MD5_SECURITY
) {
1212 proto_tree_add_item(info_tree
, hf_security_info_md5_checksum
, tvb
, offset
, length
-4, ENC_NA
);
1220 /* 5.1.2 Service Info Component */
1222 #define SERVICE_INFO_LEN (4+4+8*2)
1224 #define WCCP2_SERVICE_STANDARD 0
1225 #define WCCP2_SERVICE_DYNAMIC 1
1227 const value_string service_type_vals
[] = {
1228 { WCCP2_SERVICE_STANDARD
, "Standard predefined service"},
1229 { WCCP2_SERVICE_DYNAMIC
, "Dynamic CE defined service" },
1236 #define WCCP2_SI_SRC_IP_HASH 0x0001
1237 #define WCCP2_SI_DST_IP_HASH 0x0002
1238 #define WCCP2_SI_SRC_PORT_HASH 0x0004
1239 #define WCCP2_SI_DST_PORT_HASH 0x0008
1240 #define WCCP2_SI_PORTS_DEFINED 0x0010
1241 #define WCCP2_SI_PORTS_SOURCE 0x0020
1242 #define WCCP2r1_SI_REDIRECT_ONLY_PROTOCOL_0 0x0040
1243 #define WCCP2_SI_SRC_IP_ALT_HASH 0x0100
1244 #define WCCP2_SI_DST_IP_ALT_HASH 0x0200
1245 #define WCCP2_SI_SRC_PORT_ALT_HASH 0x0400
1246 #define WCCP2_SI_DST_PORT_ALT_HASH 0x0800
1250 dissect_wccp2_service_info(tvbuff_t
*tvb
, int offset
, gint length
,
1251 packet_info
*pinfo
, proto_tree
*info_tree
)
1253 guint8 service_type
;
1256 proto_tree
*field_tree
, *ports_tree
;
1259 int max_offset
= offset
+length
;
1261 if (length
!= SERVICE_INFO_LEN
)
1262 return length
- SERVICE_INFO_LEN
;
1264 service_type
= tvb_get_guint8(tvb
, offset
);
1265 proto_tree_add_item(info_tree
, hf_service_info_type
, tvb
,
1266 offset
, 1, ENC_BIG_ENDIAN
);
1268 switch (service_type
) {
1270 case WCCP2_SERVICE_STANDARD
:
1271 proto_tree_add_item(info_tree
, hf_service_info_id_standard
, tvb
,
1272 offset
+1 , 1, ENC_BIG_ENDIAN
);
1274 tf
= proto_tree_add_item(info_tree
, hf_service_info_priority
, tvb
, offset
+2, 1, ENC_BIG_ENDIAN
);
1275 if (tvb_get_guint8(tvb
, offset
+2) != 0)
1276 expert_add_info(pinfo
, tf
, &ei_wccp_service_info_priority_nonzero
);
1278 tf
= proto_tree_add_item(info_tree
, hf_service_info_protocol
, tvb
,
1279 offset
+3, 1, ENC_BIG_ENDIAN
);
1281 if (tvb_get_guint8(tvb
, offset
+3) != 0)
1282 expert_add_info(pinfo
, tf
, &ei_wccp_service_info_protocol_nonzero
);
1285 case WCCP2_SERVICE_DYNAMIC
:
1286 proto_tree_add_item(info_tree
, hf_service_info_id_dynamic
, tvb
,
1287 offset
+1 , 1, ENC_BIG_ENDIAN
);
1288 proto_tree_add_item(info_tree
, hf_service_info_priority
, tvb
,
1289 offset
+2, 1, ENC_BIG_ENDIAN
);
1290 proto_tree_add_item(info_tree
, hf_service_info_protocol
, tvb
,
1291 offset
+3, 1, ENC_BIG_ENDIAN
);
1296 flags
= tvb_get_ntohl(tvb
, offset
);
1297 tf
= proto_tree_add_item(info_tree
, hf_service_info_flags
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1299 field_tree
= proto_item_add_subtree(tf
, ett_service_flags
);
1300 proto_tree_add_item(field_tree
, hf_service_info_flags_src_ip_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1301 proto_tree_add_item(field_tree
, hf_service_info_flags_dest_ip_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1302 proto_tree_add_item(field_tree
, hf_service_info_flags_src_port_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1303 proto_tree_add_item(field_tree
, hf_service_info_flags_dest_port_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1304 proto_tree_add_item(field_tree
, hf_service_info_flags_ports_defined
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1305 /* if they are defined which ? */
1306 if (flags
& WCCP2_SI_PORTS_DEFINED
)
1307 proto_tree_add_item(field_tree
, hf_service_info_flags_ports_source
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1309 proto_tree_add_item(field_tree
, hf_service_info_flags_redirect_only_protocol_0
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1310 proto_tree_add_item(field_tree
, hf_service_info_flags_src_ip_alt_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1311 proto_tree_add_item(field_tree
, hf_service_info_flags_dest_ip_alt_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1312 proto_tree_add_item(field_tree
, hf_service_info_flags_src_port_alt_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1313 proto_tree_add_item(field_tree
, hf_service_info_flags_dest_port_alt_hash
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1315 buf
= (char *) wmem_alloc(wmem_packet_scope(), 128);
1316 decode_bitfield_value(buf
, flags
,
1317 0xFFFFFFFF ^ (WCCP2_SI_SRC_IP_HASH
1318 | WCCP2_SI_DST_IP_HASH
1319 | WCCP2_SI_SRC_PORT_HASH
1320 | WCCP2_SI_DST_PORT_HASH
1321 | WCCP2_SI_PORTS_DEFINED
1322 | WCCP2_SI_PORTS_SOURCE
1323 | WCCP2r1_SI_REDIRECT_ONLY_PROTOCOL_0
1324 | WCCP2_SI_SRC_IP_ALT_HASH
1325 | WCCP2_SI_DST_IP_ALT_HASH
1326 | WCCP2_SI_SRC_PORT_ALT_HASH
1327 | WCCP2_SI_DST_PORT_ALT_HASH
),
1329 proto_tree_add_text(field_tree
, tvb
, offset
, 2,
1331 buf
, "reserved, should be 0");
1335 if (flags
& WCCP2_SI_PORTS_DEFINED
) {
1336 tf
= proto_tree_add_text(info_tree
, tvb
, offset
, 2*8,
1338 ports_tree
= proto_item_add_subtree(tf
, ett_service_info_ports
);
1340 for (i
= 0; i
< 8; i
++) {
1341 guint16 port
= tvb_get_ntohs(tvb
, offset
);
1344 if (flags
& WCCP2_SI_SRC_PORT_HASH
)
1345 proto_tree_add_item(ports_tree
, hf_service_info_source_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1347 proto_tree_add_item(ports_tree
, hf_service_info_destination_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1348 proto_item_append_text(tf
, " %d", port
);
1351 DISSECTOR_ASSERT(offset
<= max_offset
);
1355 /* just use up the space if there is */
1356 if (offset
+ 8 * 2 <= max_offset
) {
1357 proto_tree_add_text(info_tree
, tvb
, offset
, 8*2,
1358 "Ports fields not used");
1363 return length
- SERVICE_INFO_LEN
;
1366 /* 6.1 Router Identity Element */
1368 dissect_wccp2_router_identity_element(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1374 proto_tree_add_item(tree
, hf_router_identity_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1375 tf
= proto_tree_add_item(tree
, hf_router_identity_receive_id
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
1377 if (tvb_get_ntohl(tvb
, offset
+ 4) == 0)
1378 expert_add_info(pinfo
, tf
, &ei_wccp_router_identity_receive_id_zero
);
1381 #define ROUTER_ID_INFO_MIN_LEN (8+4+4)
1383 /* 5.3.1 Router Identity Info Component */
1385 dissect_wccp2_router_identity_info(tvbuff_t
*tvb
, int offset
, gint length
,
1386 packet_info
*pinfo
, proto_tree
*info_tree
)
1388 guint32 n_received_from
;
1391 proto_tree
*element_tree
;
1394 return length
- ROUTER_ID_INFO_MIN_LEN
;
1397 te
= proto_tree_add_item(info_tree
, hf_router_identity_router_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1399 element_tree
= proto_item_add_subtree(te
,ett_wc_view_info_router_element
);
1401 dissect_wccp2_router_identity_element(tvb
,offset
,pinfo
,element_tree
);
1405 proto_tree_add_item(info_tree
, hf_router_identity_send_to_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1408 n_received_from
= tvb_get_ntohl(tvb
, offset
);
1409 proto_tree_add_item(info_tree
, hf_router_identity_received_from_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1412 for (i
= 0; i
< n_received_from
; i
++) {
1414 return length
-4*(i
-n_received_from
);
1417 proto_tree_add_item(info_tree
, hf_router_identity_received_from_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1424 #define ROUTER_WC_ID_ELEMENT_MIN_LEN (4+2+2)
1426 /* 6.4 Web-Cache Identity Element */
1428 dissect_wccp2_web_cache_identity_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
1429 proto_tree
*info_tree
)
1432 proto_tree
*field_tree
;
1434 guint data_element_type
;
1437 if (length
< ROUTER_WC_ID_ELEMENT_MIN_LEN
)
1438 return length
- ROUTER_WC_ID_ELEMENT_MIN_LEN
;
1440 proto_tree_add_item(info_tree
, hf_web_cache_identity_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1443 tf
= proto_tree_add_item(info_tree
, hf_web_cache_identity_hash_rev
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1444 if (tvb_get_ntohs(tvb
, offset
) != 0)
1445 expert_add_info(pinfo
, tf
, &ei_wccp_web_cache_identity_hash_rev_zero
);
1449 flags
= tvb_get_ntohs(tvb
, offset
);
1450 tf
= proto_tree_add_uint(info_tree
, hf_web_cache_identity_flags
, tvb
, offset
, 2, flags
);
1451 data_element_type
= (flags
& 0x6) >> 1;
1453 field_tree
= proto_item_add_subtree(tf
, ett_wc_identity_flags
);
1454 proto_tree_add_item(field_tree
, hf_web_cache_identity_flag_hash_info
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1455 proto_tree_add_item(field_tree
, hf_web_cache_identity_flag_assign_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1456 proto_tree_add_item(field_tree
, hf_web_cache_identity_flag_version_request
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1457 buf
=(char *) wmem_alloc(wmem_packet_scope(), 128);
1458 decode_bitfield_value(buf
, flags
, 0xFFF0, 16);
1459 proto_tree_add_text(field_tree
, tvb
, offset
, 2,
1461 buf
, "reserved, should be 0");
1464 switch (data_element_type
) {
1465 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_HASH
:
1466 return dissect_wccp2_hash_assignment_data_element(tvb
,offset
,length
,pinfo
,info_tree
);
1467 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_MASK
:
1468 return dissect_wccp2_mask_assignment_data_element(tvb
,offset
,length
,pinfo
,info_tree
);
1470 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_NOT_PRESENT
:
1471 proto_tree_add_text(info_tree
, tvb
, offset
, 2,
1472 "No Assignment Data Present");
1475 case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_EXTENDED
:
1476 return dissect_wccp2_extended_assignment_data_element(tvb
,offset
,length
,pinfo
,info_tree
);
1481 /* 5.2.1 Web-Cache Identity Info Component */
1483 dissect_wccp2_wc_identity_info(tvbuff_t
*tvb
, int offset
, gint length
,
1484 packet_info
*pinfo _U_
, proto_tree
*info_tree
)
1487 proto_tree
*element_tree
;
1490 te
= proto_tree_add_item(info_tree
, hf_wc_identity_ip_address
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1492 element_tree
= proto_item_add_subtree(te
, ett_wc_identity_element
);
1493 return dissect_wccp2_web_cache_identity_element(tvb
, offset
,length
, pinfo
,
1497 /* 6.3 Assignment Key Element */
1499 dissect_wccp2_assignment_key_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo _U_
,
1500 proto_tree
*info_tree
)
1506 proto_tree_add_item(info_tree
, hf_assignment_key_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1509 proto_tree_add_item(info_tree
, hf_assignment_key_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1516 #define ROUTER_VIEW_INFO_MIN_LEN (4+8+4+4)
1518 /* 5.3.2 Router View Info Component */
1520 dissect_wccp2_router_view_info(tvbuff_t
*tvb
, int offset
, gint length
,
1521 packet_info
*pinfo
, proto_tree
*info_tree
)
1524 guint32 n_web_caches
;
1527 proto_tree
*element_tree
;
1530 if (length
< ROUTER_VIEW_INFO_MIN_LEN
)
1531 return length
- ROUTER_VIEW_INFO_MIN_LEN
;
1533 proto_tree_add_item(info_tree
, hf_router_view_member_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1536 new_length
=dissect_wccp2_assignment_key_element(tvb
, offset
, length
, pinfo
, info_tree
);
1537 NOTE_EATEN_LENGTH(new_length
);
1539 n_routers
= tvb_get_ntohl(tvb
, offset
);
1540 proto_tree_add_uint(info_tree
, hf_router_router_num
, tvb
, offset
, 4, n_routers
);
1543 for (i
= 0; i
< n_routers
; i
++) {
1545 return length
- (n_routers
-i
)*4 - 4;
1547 proto_tree_add_item(info_tree
, hf_router_view_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1554 n_web_caches
= tvb_get_ntohl(tvb
, offset
);
1555 proto_tree_add_uint(info_tree
, hf_wc_view_wc_num
, tvb
, offset
, 4, n_web_caches
);
1558 for (i
= 0; i
< n_web_caches
; i
++) {
1560 old_length
= length
;
1563 return length
- 4*(n_web_caches
-i
);
1565 te
= proto_tree_add_item(info_tree
, hf_router_query_info_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1567 element_tree
= proto_item_add_subtree(te
, ett_wc_identity_element
);
1568 length
= dissect_wccp2_web_cache_identity_element(tvb
,
1569 offset
, length
, pinfo
,
1574 offset
+= old_length
- length
;
1579 #define WC_VIEW_INFO_MIN_LEN (4+4+4)
1581 /* 5.2.2 Web Cache View Info Component */
1584 dissect_wccp2_web_cache_view_info(tvbuff_t
*tvb
, int offset
, gint length
,
1585 packet_info
*pinfo
, proto_tree
*info_tree
)
1588 guint32 n_web_caches
;
1591 proto_tree
*element_tree
;
1594 if (length
< WC_VIEW_INFO_MIN_LEN
)
1595 return length
- WC_VIEW_INFO_MIN_LEN
;
1598 proto_tree_add_item(info_tree
, hf_wc_view_info_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1601 n_routers
= tvb_get_ntohl(tvb
, offset
);
1602 proto_tree_add_uint(info_tree
, hf_wc_view_router_num
, tvb
, offset
, 4, n_routers
);
1605 for (i
= 0; i
< n_routers
; i
++) {
1607 return length
-8 * (n_routers
-i
) - 4;
1609 te
= proto_tree_add_item(info_tree
, hf_wc_view_info_router_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1610 /* also include the receive id in the object */
1611 proto_item_set_len(te
, 8);
1613 element_tree
= proto_item_add_subtree(te
,ett_wc_view_info_router_element
);
1614 dissect_wccp2_router_identity_element(tvb
, offset
, pinfo
, element_tree
);
1621 n_web_caches
= tvb_get_ntohl(tvb
, offset
);
1622 proto_tree_add_uint(info_tree
, hf_wc_view_wc_num
, tvb
, offset
, 4, n_web_caches
);
1625 for (i
= 0; i
< n_web_caches
; i
++) {
1627 return length
- 4*(n_web_caches
-i
);
1629 proto_tree_add_item(info_tree
, hf_wc_view_info_wc_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1635 /* 6.2 Router Assignment Element */
1637 dissect_wccp2_router_assignment_element(tvbuff_t
*tvb
, int offset
,
1638 gint length
, packet_info
*pinfo
, proto_tree
*info_tree
)
1640 dissect_wccp2_router_identity_element(tvb
,offset
,pinfo
,info_tree
);
1642 proto_tree_add_item(info_tree
, hf_router_assignment_element_change_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1647 assignment_bucket_name(guint8 bucket
)
1651 if (bucket
== 0xff) {
1652 cur
= (gchar
*) "Unassigned";
1654 cur
=wmem_strdup_printf(wmem_packet_scope(), "%u%s", bucket
& 0x7F,
1655 (bucket
& 0x80) ? " (Alt)" : "");
1660 #define ASSIGNMENT_INFO_MIN_LEN (8+4+4)
1662 /* 5.4.1 Assignment Info Component */
1664 dissect_wccp2_assignment_info(tvbuff_t
*tvb
, int offset
, gint length
,
1665 packet_info
*pinfo
, proto_tree
*info_tree
)
1670 proto_tree
*element_tree
;
1673 if (length
< ASSIGNMENT_INFO_MIN_LEN
)
1674 return length
- ASSIGNMENT_INFO_MIN_LEN
;
1677 new_length
=dissect_wccp2_assignment_key_element(tvb
, offset
, length
, pinfo
, info_tree
);
1678 NOTE_EATEN_LENGTH(new_length
);
1680 n_routers
= tvb_get_ntohl(tvb
, offset
);
1681 proto_tree_add_uint(info_tree
, hf_assignment_info_router_num
, tvb
, offset
, 4, n_routers
);
1684 for (i
= 0; i
< n_routers
; i
++) {
1686 return length
- 12*(n_routers
-i
)-4-256;
1688 te
= proto_tree_add_item(info_tree
, hf_assignment_info_router_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1690 element_tree
= proto_item_add_subtree(te
, ett_router_assignment_element
);
1691 dissect_wccp2_router_assignment_element(tvb
, offset
, length
, pinfo
,
1696 new_length
= dissect_wccp2_hash_buckets_assignment_element(tvb
, offset
, length
, pinfo
, info_tree
);
1697 NOTE_EATEN_LENGTH(new_length
);
1702 #define QUERY_INFO_LEN (4+4+4+4)
1704 /* 5.5.1 Router Query Info Component */
1706 dissect_wccp2_router_query_info(tvbuff_t
*tvb
, int offset
, gint length
,
1707 packet_info
*pinfo
, proto_tree
*info_tree
)
1709 if (length
< QUERY_INFO_LEN
)
1710 return length
- QUERY_INFO_LEN
;
1712 dissect_wccp2_router_identity_element(tvb
,offset
,pinfo
,info_tree
);
1715 proto_tree_add_item(info_tree
, hf_router_query_info_send_to_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1717 proto_tree_add_item(info_tree
, hf_router_query_info_target_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1723 /* 6.5 Hash Buckets Assignment Element */
1724 static gint
dissect_wccp2_hash_buckets_assignment_element(tvbuff_t
*tvb
, int offset
, gint length
,
1725 packet_info
*pinfo _U_
, proto_tree
*info_tree
)
1727 guint32 i
,n_web_caches
;
1729 proto_tree
*element_tree
;
1734 n_web_caches
= tvb_get_ntohl(tvb
, offset
);
1735 te
= proto_tree_add_uint(info_tree
, hf_hash_buckets_assignment_wc_num
, tvb
, offset
, 4, n_web_caches
);
1738 element_tree
= proto_item_add_subtree(te
,ett_hash_buckets_assignment_wc_element
);
1739 for (i
= 0; i
< n_web_caches
; i
++) {
1743 return length
- 4*(n_web_caches
-i
)-256;
1745 l_te
= proto_tree_add_item(element_tree
, hf_hash_buckets_assignment_wc_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1747 proto_item_append_text(l_te
, " id: %d", i
);
1751 te
= proto_tree_add_text(info_tree
,tvb
, offset
,256, "Buckets");
1752 element_tree
= proto_item_add_subtree(te
,ett_hash_buckets_assignment_buckets
);
1754 for (i
= 0; i
< 256; i
+= 4) {
1756 return length
- (256-i
);
1758 proto_tree_add_text(element_tree
, tvb
, offset
, 4,
1759 "Buckets %3d - %3d: %10s %10s %10s %10s",
1761 assignment_bucket_name(tvb_get_guint8(tvb
, offset
)),
1762 assignment_bucket_name(tvb_get_guint8(tvb
, offset
+1)),
1763 assignment_bucket_name(tvb_get_guint8(tvb
, offset
+2)),
1764 assignment_bucket_name(tvb_get_guint8(tvb
, offset
+3)));
1770 #define WCCP2_FORWARDING_METHOD_GRE 0x00000001
1771 #define WCCP2_FORWARDING_METHOD_L2 0x00000002
1773 static const capability_flag forwarding_method_flags
[] = {
1774 { WCCP2_FORWARDING_METHOD_GRE
, "IP-GRE", &hf_capability_forwarding_method_flag_gre
},
1775 { WCCP2_FORWARDING_METHOD_L2
, "L2", &hf_capability_forwarding_method_flag_l2
},
1779 #define WCCP2_ASSIGNMENT_METHOD_HASH 0x00000001
1780 #define WCCP2_ASSIGNMENT_METHOD_MASK 0x00000002
1782 static const capability_flag assignment_method_flags
[] = {
1783 { WCCP2_ASSIGNMENT_METHOD_HASH
, "Hash", &hf_capability_assignment_method_flag_hash
},
1784 { WCCP2_ASSIGNMENT_METHOD_MASK
, "Mask", &hf_capability_assignment_method_flag_mask
},
1789 #define WCCP2_PACKET_RETURN_METHOD_GRE 0x00000001
1790 #define WCCP2_PACKET_RETURN_METHOD_L2 0x00000002
1792 static const capability_flag packet_return_method_flags
[] = {
1793 { WCCP2_PACKET_RETURN_METHOD_GRE
, "IP-GRE", &hf_capability_return_method_flag_gre
},
1794 { WCCP2_PACKET_RETURN_METHOD_L2
, "L2", &hf_capability_return_method_flag_l2
},
1798 #define WCCP2_COMMAND_TYPE_SHUTDOWN 1
1799 #define WCCP2_COMMAND_TYPE_SHUTDOWN_RESPONSE 2
1801 static const value_string wccp_command_type_vals
[] = {
1802 { WCCP2_COMMAND_TYPE_SHUTDOWN
, "CE shutting down" },
1803 { WCCP2_COMMAND_TYPE_SHUTDOWN_RESPONSE
, "Router Acknowledge CE shutdown"},
1809 /* 5.1.3 Capabilities Info Component */
1812 dissect_wccp2_capability_info(tvbuff_t
*tvb
, int offset
, gint length
,
1813 packet_info
*pinfo
, proto_tree
*info_tree
)
1815 gint capability_length
;
1817 while (length
>= 8) {
1818 capability_length
= dissect_wccp2_capability_element(tvb
,offset
,length
,pinfo
,info_tree
);
1820 NOTE_EATEN_LENGTH(capability_length
);
1826 #define ALT_COMMAND_EXTENSION_MIN_LEN (4)
1828 /* 5.1.4 && 6.12 Command Extension Component */
1831 dissect_wccp2_command_extension(tvbuff_t
*tvb
, int offset
,
1832 int length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
)
1834 guint16 command_type
;
1835 guint16 command_length
;
1841 if (length
< ALT_COMMAND_EXTENSION_MIN_LEN
)
1842 return length
- ALT_COMMAND_EXTENSION_MIN_LEN
;
1844 command_type
= tvb_get_ntohs(tvb
, offset
);
1845 proto_tree_add_item(info_tree
, hf_command_element_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1849 command_length
= tvb_get_ntohs(tvb
, offset
);
1850 proto_tree_add_item(info_tree
, hf_command_element_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1851 proto_tree_add_text(info_tree
, tvb
, offset
, 2,
1852 "Command length: %u", command_length
);
1855 if (((command_type
== WCCP2_COMMAND_TYPE_SHUTDOWN
) ||
1856 (command_type
== WCCP2_COMMAND_TYPE_SHUTDOWN_RESPONSE
)) &&
1857 (command_length
== 4)) {
1860 proto_tree_add_item(info_tree
, hf_command_element_shutdown_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1862 if (length
< command_length
)
1863 return length
- command_length
;
1865 proto_tree_add_text(info_tree
, tvb
, offset
, command_length
,
1868 EAT(command_length
);
1873 /* 5.1.5 Address Table Component */
1874 /* this function is special as it can be invoked twice during a packet decode:
1875 once to get the tables, once to display them
1878 dissect_wccp2r1_address_table_info(tvbuff_t
*tvb
, int offset
,
1879 int length
, packet_info
*pinfo
, proto_tree
*info_tree
)
1881 guint16 address_length
;
1883 proto_tree
*element_tree
=NULL
;
1884 proto_item
*tf
=NULL
;
1886 wccp_wccp_address_table
.in_use
= TRUE
;
1889 tf
= proto_tree_get_parent(info_tree
);
1892 return length
- 2*4;
1895 wccp_wccp_address_table
.family
= tvb_get_ntohs(tvb
,offset
);
1896 if (pinfo
&& info_tree
)
1897 proto_tree_add_item(info_tree
, hf_address_table_family
, tvb
,
1898 offset
, 2, ENC_BIG_ENDIAN
);
1901 address_length
= tvb_get_ntohs(tvb
,offset
);
1903 proto_tree_add_item(info_tree
, hf_address_table_address_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1906 wccp_wccp_address_table
.table_length
= tvb_get_ntohl(tvb
,offset
);
1907 if (pinfo
&& info_tree
) {
1908 tf
= proto_tree_add_item(info_tree
, hf_address_table_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1909 element_tree
= proto_item_add_subtree(tf
, ett_table_element
);
1913 /* check if the length is valid and allocate the tables if needed*/
1914 switch (wccp_wccp_address_table
.family
) {
1916 if (wccp_wccp_address_table
.table_ipv4
== NULL
)
1917 wccp_wccp_address_table
.table_ipv4
= (guint32
*)
1918 wmem_alloc(wmem_packet_scope(), wccp_wccp_address_table
.table_length
* 4);
1919 if ((address_length
!= 4) && (pinfo
&& info_tree
)) {
1920 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
1921 "The Address length must be 4, but I found %d for IPv4 addresses. Correcting this.",
1927 if (wccp_wccp_address_table
.table_ipv6
== NULL
)
1928 wccp_wccp_address_table
.table_ipv6
= (struct e_in6_addr
*)
1929 wmem_alloc(wmem_packet_scope(), wccp_wccp_address_table
.table_length
* sizeof(struct e_in6_addr
));
1930 if ((address_length
!= 16) && (pinfo
&& info_tree
)) {
1931 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
,
1932 "The Address length must be 16, but I found %d for IPv6 addresses. Correcting this",
1938 if (pinfo
&& info_tree
) {
1939 expert_add_info_format(pinfo
, tf
, &ei_wccp_address_table_family_unknown
,
1940 "Unknown address family: %d", wccp_wccp_address_table
.family
);
1944 /* now read the addresses and print/store them */
1946 for(i
=0; i
<wccp_wccp_address_table
.table_length
; i
++) {
1949 /* do we have space? */
1950 if (length
< address_length
) {
1952 expert_add_info_format(pinfo
, tf
, &ei_wccp_length_bad
, "Ran out of space to decode");
1954 /* first clean up: */
1955 wccp_wccp_address_table
.in_use
= FALSE
;
1956 wccp_wccp_address_table
.family
= -1;
1957 wccp_wccp_address_table
.version
= -1;
1958 wccp_wccp_address_table
.table_length
= 0;
1959 wccp_wccp_address_table
.table_ipv4
= (guint32
*) NULL
;
1960 wccp_wccp_address_table
.table_ipv6
= (struct e_in6_addr
*)NULL
;
1962 /* ABORT The decode */
1963 return length
- address_length
;
1966 switch (wccp_wccp_address_table
.family
) {
1969 addr
= tvb_ip_to_str(tvb
, offset
);
1970 if (wccp_wccp_address_table
.table_ipv4
!= NULL
)
1971 wccp_wccp_address_table
.table_ipv4
[i
] = tvb_get_ntohl(tvb
,offset
);
1975 addr
= tvb_ip6_to_str(tvb
,offset
);
1976 if (wccp_wccp_address_table
.table_ipv6
!= NULL
)
1977 tvb_get_ipv6(tvb
, offset
, &(wccp_wccp_address_table
.table_ipv6
[i
]));
1980 addr
= wmem_strdup_printf(wmem_packet_scope(), "unknown family");
1984 proto_tree_add_string_format_value(element_tree
, hf_address_table_element
, tvb
,
1985 offset
, address_length
, addr
,
1986 "%d: %s", i
+1, addr
);
1988 EAT(address_length
);
1997 #define HASH_ASSIGNMENT_INFO_MIN_LEN (4+256)
1999 /* part of 5.6.11 Alternate Assignment Component */
2001 dissect_wccp2_hash_assignment_info(tvbuff_t
*tvb
, int offset
, gint length
,
2002 packet_info
*pinfo
, proto_tree
*info_tree
)
2004 guint32 n_web_caches
;
2007 if (length
< HASH_ASSIGNMENT_INFO_MIN_LEN
)
2008 return length
- ASSIGNMENT_INFO_MIN_LEN
;
2010 n_web_caches
= tvb_get_ntohl(tvb
, offset
);
2011 proto_tree_add_uint(info_tree
, hf_wc_view_wc_num
, tvb
, offset
, 4, n_web_caches
);
2014 for (i
= 0; i
< n_web_caches
; i
++) {
2016 return length
- 4*(n_web_caches
-i
)-256;
2018 proto_tree_add_text(info_tree
, tvb
, offset
, 4,
2019 "Web-Cache %d: IP address %s", i
,
2020 decode_wccp_encoded_address(tvb
, offset
, pinfo
, info_tree
));
2024 for (i
= 0; i
< 256; i
+= 4) {
2026 return length
- (256-i
);
2028 proto_tree_add_text(info_tree
, tvb
, offset
, 4,
2029 "Buckets %d - %d: %10s %10s %10s %10s",
2031 assignment_bucket_name(tvb_get_guint8(tvb
, offset
)),
2032 assignment_bucket_name(tvb_get_guint8(tvb
, offset
+1)),
2033 assignment_bucket_name(tvb_get_guint8(tvb
, offset
+2)),
2034 assignment_bucket_name(tvb_get_guint8(tvb
, offset
+3)));
2040 /* 5.3.3 Assignment Map Component */
2041 static gint
dissect_wccp2_assignment_map(tvbuff_t
*tvb
, int offset
,
2042 int length
, packet_info
*pinfo
, proto_tree
*info_tree
)
2046 new_length
=dissect_wccp2_mask_value_set_list(tvb
, offset
, length
, pinfo
, info_tree
);
2048 NOTE_EATEN_LENGTH(new_length
);
2055 #define ALT_ASSIGNMENT_MAP_MIN_LEN (4)
2057 /* 5.3.4 Alternate Assignment Map Component */
2059 dissect_wccp2r1_alt_assignment_map_info(tvbuff_t
*tvb
, int offset
,
2060 int length
, packet_info
*pinfo
, proto_tree
*info_tree
)
2062 guint16 assignment_type
;
2063 guint16 assignment_length
;
2064 proto_item
*tf
=NULL
;
2066 if (length
< ALT_ASSIGNMENT_MAP_MIN_LEN
)
2067 return length
- ALT_ASSIGNMENT_MAP_MIN_LEN
;
2070 assignment_type
= tvb_get_ntohs(tvb
, offset
);
2071 proto_tree_add_item(info_tree
, hf_alt_assignment_map_assignment_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2074 assignment_length
= tvb_get_ntohs(tvb
, offset
);
2075 tf
=proto_tree_add_item(info_tree
, hf_alt_assignment_map_assignment_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2078 if (length
< assignment_length
)
2079 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
2080 "Assignment length is %d but only %d remain in the packet. Ignoring this for now",
2081 assignment_length
, length
);
2083 if (length
> assignment_length
) {
2084 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
2085 "Assignment length is %d but %d remain in the packet. Assuming that the assignment length is wrong and setting it to %d.",
2086 assignment_length
, length
, length
);
2087 assignment_length
= length
;
2090 switch (assignment_type
) {
2091 case WCCP2_HASH_ASSIGNMENT_TYPE
:
2092 return dissect_wccp2_assignment_info(tvb
, offset
, assignment_length
,
2094 case WCCP2_MASK_ASSIGNMENT_TYPE
:
2095 return dissect_wccp2_mask_value_set_list(tvb
, offset
, assignment_length
,
2097 case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
:
2098 return dissect_wccp2_alternate_mask_value_set_list(tvb
, offset
, assignment_length
,
2109 /* 6.6 Hash Assignment Data Element */
2111 dissect_wccp2_hash_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
,
2112 packet_info
*pinfo _U_
,
2113 proto_tree
*info_tree
)
2116 proto_item
*bucket_item
;
2117 proto_tree
*bucket_tree
;
2123 bucket_item
= proto_tree_add_text(info_tree
, tvb
, offset
, 8*4,
2124 "Hash Assignment Data");
2125 bucket_tree
= proto_item_add_subtree(bucket_item
, ett_hash_assignment_buckets
);
2127 for (i
= 0, n
= 0; i
< 32; i
++) {
2132 bucket_info
= tvb_get_guint8(tvb
, offset
);
2133 n
= wccp_bucket_info(bucket_info
, bucket_tree
, n
, tvb
, offset
);
2141 return dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, length
, pinfo
, info_tree
);
2144 /* 6.7 Mask Assignment Data Element */
2146 dissect_wccp2_mask_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
2147 proto_tree
*info_tree
)
2150 proto_item
*mask_item
;
2151 proto_tree
*mask_tree
;
2152 gint new_length
,start
;
2155 mask_item
= proto_tree_add_text(info_tree
, tvb
, offset
, 4,
2156 "Mask Assignment Data");
2157 mask_tree
= proto_item_add_subtree(mask_item
, ett_mask_assignment_data_element
);
2160 new_length
=dissect_wccp2_mask_value_set_list(tvb
, offset
, length
, pinfo
, mask_tree
);
2162 NOTE_EATEN_LENGTH(new_length
);
2167 new_length
= dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, length
, pinfo
, info_tree
);
2168 NOTE_EATEN_LENGTH(new_length
);
2170 proto_item_set_len(mask_item
, offset
-start
);
2175 /* 5.7.5 Alternate Mask Assignment Data Element */
2177 dissect_wccp2_alternate_mask_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
2178 proto_tree
*info_tree
)
2180 proto_item
*mask_item
;
2181 proto_tree
*mask_tree
;
2183 mask_item
= proto_tree_add_text(info_tree
, tvb
, offset
, length
,
2184 "Alternate Mask Assignment Data");
2185 mask_tree
= proto_item_add_subtree(mask_item
, ett_alternate_mask_assignment_data_element
);
2195 new_length
=dissect_wccp2_alternate_mask_value_set_list(tvb
, offset
, length
, pinfo
, mask_tree
);
2197 NOTE_EATEN_LENGTH(new_length
);
2203 return dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, length
, pinfo
, info_tree
);
2207 /* 6.9 Assignment Weight and Status Data Element */
2209 dissect_wccp2_assignment_weight_and_status_element(tvbuff_t
*tvb
, int offset
, gint length
,
2210 packet_info
*pinfo _U_
,
2211 proto_tree
*info_tree
)
2218 proto_tree_add_item(info_tree
, hf_assignment_weight
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2220 proto_tree_add_item(info_tree
, hf_assignment_status
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2226 /* 6.10 Extended Assignment Data Element */
2228 dissect_wccp2_extended_assignment_data_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo
,
2229 proto_tree
*info_tree
)
2231 proto_item
*element_item
, *header
;
2232 proto_tree
*item_tree
;
2234 guint type_of_assignment
;
2236 gint assignment_length
;
2242 header
= proto_tree_add_text(info_tree
, tvb
, offset
, length
,
2243 "Extended Assignment Data Element");
2245 item_tree
= proto_item_add_subtree(header
, ett_extended_assigment_data_element
);
2247 type_of_assignment
= tvb_get_ntohs(tvb
, offset
);
2248 proto_tree_add_item(item_tree
, hf_extended_assignment_data_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2251 assignment_length
= tvb_get_ntohs(tvb
,offset
);
2252 element_item
= proto_tree_add_item(item_tree
, hf_extended_assignment_data_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2255 if (length
< assignment_length
)
2256 expert_add_info_format(pinfo
, element_item
, &ei_wccp_assignment_length_bad
,
2257 "Assignment length is %d but only %d remain in the packet. Ignoring this for now",
2258 assignment_length
, length
);
2260 /* Now a common bug seems to be to set the assignment_length to the length -4
2262 if ((length
> assignment_length
) &&
2263 (length
== (assignment_length
+ 4)))
2265 expert_add_info_format(pinfo
, element_item
, &ei_wccp_assignment_length_bad
,
2266 "Assignment length is %d but %d remain in the packet. Assuming that this is wrong as this is only 4 bytes to small, proceding with the assumption it is %d",
2267 assignment_length
, length
, length
);
2268 assignment_length
= length
;
2272 proto_item_set_len(header
, assignment_length
+4);
2274 switch (type_of_assignment
)
2276 case WCCP2_HASH_ASSIGNMENT_TYPE
:
2277 return dissect_wccp2_hash_assignment_data_element(tvb
, offset
, assignment_length
,
2279 case WCCP2_MASK_ASSIGNMENT_TYPE
:
2280 return dissect_wccp2_mask_assignment_data_element(tvb
, offset
, assignment_length
,
2282 case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
:
2283 return dissect_wccp2_alternate_mask_assignment_data_element(tvb
, offset
, assignment_length
,
2285 case WCCP2r1_ASSIGNMENT_WEIGHT_STATUS
:
2286 return dissect_wccp2_assignment_weight_and_status_element(tvb
, offset
, assignment_length
,
2297 /* 6.11 Capability Element */
2299 dissect_wccp2_capability_element(tvbuff_t
*tvb
, int offset
, gint length
,
2300 packet_info
*pinfo
, proto_tree
*info_tree
)
2302 guint16 capability_type
;
2303 guint16 capability_val_len
;
2304 proto_item
*te
, *header
, *tf
;
2305 proto_tree
*element_tree
;
2311 capability_type
= tvb_get_ntohs(tvb
, offset
);
2312 capability_val_len
= tvb_get_ntohs(tvb
, offset
+ 2);
2313 header
= te
= proto_tree_add_item(info_tree
, hf_capability_element_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2315 proto_item_set_len(te
, capability_val_len
+ 4);
2316 element_tree
= proto_item_add_subtree(te
, ett_capability_element
);
2318 tf
= proto_tree_add_uint(element_tree
, hf_capability_element_length
, tvb
, offset
+2, 2, capability_val_len
);
2320 proto_tree_add_text(element_tree
, tvb
, offset
, 2,
2322 val_to_str(capability_type
,
2323 capability_type_vals
, "Unknown (0x%08X)"));
2324 if (capability_val_len
< 4) {
2325 expert_add_info_format(pinfo
, tf
, &ei_wccp_capability_element_length
,
2326 "Value Length: %u (illegal, must be >= 4)", capability_val_len
);
2330 if (length
< (4+capability_val_len
))
2331 return length
- 4 - capability_val_len
;
2333 switch (capability_type
) {
2334 case WCCP2_FORWARDING_METHOD
:
2335 dissect_32_bit_capability_flags(tvb
, offset
,
2337 ett_capability_forwarding_method
,
2338 forwarding_method_flags
, element_tree
, header
);
2341 case WCCP2_ASSIGNMENT_METHOD
:
2342 dissect_32_bit_capability_flags(tvb
, offset
,
2344 ett_capability_assignment_method
,
2345 assignment_method_flags
, element_tree
, header
);
2348 case WCCP2_PACKET_RETURN_METHOD
:
2349 dissect_32_bit_capability_flags(tvb
, offset
,
2351 ett_capability_return_method
,
2352 packet_return_method_flags
, element_tree
, header
);
2355 case WCCP2_TRANSMIT_T
:
2356 dissect_transmit_t_capability(tvb
, te
, offset
,
2358 ett_capability_transmit_t
,element_tree
);
2361 case WCCP2_TIMER_SCALE
:
2362 dissect_timer_scale_capability(tvb
, offset
,
2364 ett_capability_timer_scale
, element_tree
);
2367 proto_tree_add_text(element_tree
, tvb
,
2368 offset
, capability_val_len
,
2370 tvb_bytes_to_str(tvb
, offset
,
2371 capability_val_len
));
2374 return length
- 4 - capability_val_len
;
2378 /* 6.13 Mask/Value Set List */
2380 dissect_wccp2_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
2381 int length
, packet_info
*pinfo
, proto_tree
*info_tree
)
2386 proto_tree
*element_tree
;
2393 te
= proto_tree_add_text(info_tree
, tvb
, offset
, 4, "Mask/Value Set List");
2394 element_tree
= proto_item_add_subtree(te
, ett_mv_set_list
);
2398 num_of_elem
= tvb_get_ntohl(tvb
, offset
);
2399 proto_tree_add_item(element_tree
, hf_mask_value_set_list_num_elements
,
2400 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2401 /* proto_tree_add_uint(element_tree, , tvb, offset, 4, num_of_elem); */
2404 for (i
= 0; i
< num_of_elem
; i
++)
2408 new_length
=dissect_wccp2_mask_value_set_element(tvb
, offset
, length
, i
, pinfo
, element_tree
);
2410 NOTE_EATEN_LENGTH(new_length
);
2413 proto_item_set_len(te
, offset
-start
);
2421 /* 6.15 Mask Element */
2423 dissect_wccp2_mask_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
)
2428 proto_tree_add_item(info_tree
, hf_mask_element_src_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2430 proto_tree_add_item(info_tree
, hf_mask_element_dest_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2433 proto_tree_add_item(info_tree
, hf_mask_element_src_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2435 proto_tree_add_item(info_tree
, hf_mask_element_dest_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2446 /* 6.17 Alternate Mask/Value Set List */
2447 static gint
dissect_wccp2_alternate_mask_value_set_list(tvbuff_t
*tvb
, int offset
,
2448 int length
, packet_info
*pinfo
, proto_tree
*info_tree
)
2451 proto_tree
*list_tree
;
2452 guint num_of_val_elements
;
2458 header
= proto_tree_add_text(info_tree
, tvb
, offset
, length
,
2459 "Alternate Mask/Value Set List");
2460 list_tree
= proto_item_add_subtree(header
, ett_alternate_mask_value_set
);
2462 num_of_val_elements
= tvb_get_ntohl(tvb
, offset
);
2463 proto_tree_add_uint(list_tree
, hf_alt_assignment_mask_value_set_list_num_elements
, tvb
, offset
, 4, num_of_val_elements
);
2466 for(i
=0;i
<num_of_val_elements
;i
++) {
2469 new_length
=dissect_wccp2_alternate_mask_value_set_element(tvb
, offset
, length
, i
, pinfo
, list_tree
);
2471 NOTE_EATEN_LENGTH(new_length
);
2477 /* 6.18 Alternate Mask/Value Set Element */
2479 dissect_wccp2_alternate_mask_value_set_element(tvbuff_t
*tvb
, int offset
, gint length
, guint el_index
, packet_info
*pinfo
, proto_tree
*info_tree
)
2481 proto_item
*tl
, *header
;
2482 proto_tree
*element_tree
, *value_tree
;
2483 guint number_of_elements
;
2484 gint new_length
, total_length
;
2487 header
= proto_tree_add_text(info_tree
, tvb
, offset
, 0,
2488 "Alternate Mask/Value Set Element(%d)", el_index
);
2489 element_tree
= proto_item_add_subtree(header
, ett_alternate_mask_value_set_element
);
2493 new_length
=dissect_wccp2_mask_element(tvb
,offset
,length
,pinfo
,element_tree
);
2494 total_length
+= length
- new_length
;
2495 NOTE_EATEN_LENGTH(new_length
);
2500 number_of_elements
= tvb_get_ntohl(tvb
, offset
);
2501 tl
= proto_tree_add_uint(element_tree
, hf_alt_assignment_mask_value_set_element_num_wc_value_elements
, tvb
, offset
, 4, number_of_elements
);
2502 value_tree
= proto_item_add_subtree(tl
, ett_alternate_mv_set_element_list
);
2506 for (i
=0; i
< number_of_elements
; i
++) {
2507 new_length
=dissect_wccp2_web_cache_value_element(tvb
, offset
, length
, pinfo
, value_tree
);
2508 total_length
+= length
- new_length
;
2509 NOTE_EATEN_LENGTH(new_length
);
2511 proto_item_set_len(header
, total_length
);
2516 /* 6.19 Web-Cache Value Element */
2518 dissect_wccp2_web_cache_value_element(tvbuff_t
*tvb
, int offset
, gint length
, packet_info
*pinfo _U_
, proto_tree
*info_tree
)
2520 guint number_of_elements
;
2522 proto_tree
*element_tree
;
2528 tl
= proto_tree_add_item(info_tree
, hf_web_cache_value_element_wc_address
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2530 element_tree
= proto_item_add_subtree(tl
, ett_web_cache_value_element_list
);
2533 number_of_elements
= tvb_get_ntohl(tvb
, offset
);
2534 proto_tree_add_uint(element_tree
, hf_web_cache_value_element_num_values
, tvb
, offset
, 4, number_of_elements
);
2537 for (i
=0; i
< number_of_elements
; i
++) {
2539 return length
- 4*(number_of_elements
-i
);
2541 proto_tree_add_text(element_tree
, tvb
, offset
, 4,
2542 "Value Sequence Number %d: %x",
2544 tvb_get_ntohl(tvb
, offset
));
2552 /* End of standard functions */
2556 dissect_32_bit_capability_flags(tvbuff_t
*tvb
, int curr_offset
,
2557 guint16 capability_val_len
, gint ett
, const capability_flag
*flags
,
2558 proto_tree
*element_tree
, proto_item
*header
)
2560 guint32 capability_val
;
2562 proto_tree
*method_tree
;
2564 gboolean first
= TRUE
;
2566 capability_val
= tvb_get_ntohl(tvb
, curr_offset
+ 4);
2567 tm
= proto_tree_add_uint(element_tree
, hf_capability_info_value
, tvb
, curr_offset
+ 4, 4, capability_val
);
2569 DISSECTOR_ASSERT(capability_val_len
== 4);
2571 for (i
= 0; flags
[i
].short_name
!= NULL
; i
++) {
2572 if (capability_val
& flags
[i
].value
) {
2574 proto_item_append_text( tm
, " (%s", flags
[i
].short_name
);
2575 proto_item_append_text( header
, " (%s", flags
[i
].short_name
);
2578 proto_item_append_text( tm
, ", %s", flags
[i
].short_name
);
2579 proto_item_append_text( header
, " (%s", flags
[i
].short_name
);
2584 if (first
== FALSE
) {
2585 proto_item_append_text( tm
, ")");
2586 proto_item_append_text( header
, ")");
2589 method_tree
= proto_item_add_subtree(tm
, ett
);
2590 for (i
= 0; flags
[i
].phf
!= NULL
; i
++)
2591 proto_tree_add_item(method_tree
, *(flags
[i
].phf
), tvb
, curr_offset
+4, 4, ENC_BIG_ENDIAN
);
2596 /* 6.11.4 Capability Type WCCP2_TRANSMIT_T */
2598 dissect_transmit_t_capability(tvbuff_t
*tvb
, proto_item
*te
, int curr_offset
,
2599 guint16 capability_val_len
, gint ett
, proto_tree
*element_tree
)
2601 guint16 upper_limit
, lower_limit
;
2603 proto_tree
*method_tree
;
2605 DISSECTOR_ASSERT(capability_val_len
== 4);
2607 upper_limit
= tvb_get_ntohs(tvb
, curr_offset
);
2608 lower_limit
= tvb_get_ntohs(tvb
, curr_offset
+ 2);
2610 if ( upper_limit
== 0) {
2611 tm
= proto_tree_add_text(element_tree
, tvb
, curr_offset
, 2,
2612 "Only accepting one value");
2613 method_tree
= proto_item_add_subtree(tm
, ett
);
2614 proto_tree_add_text(method_tree
, tvb
, curr_offset
, 2,
2615 "Reserved, must be 0: %d", upper_limit
);
2617 proto_tree_add_item(method_tree
, hf_capability_transmit_t
, tvb
, curr_offset
+2, 2, ENC_BIG_ENDIAN
);
2618 proto_item_append_text(te
, " %d ms", lower_limit
);
2620 tm
= proto_tree_add_text(element_tree
, tvb
, curr_offset
, 2,
2621 "Accepting a range");
2622 method_tree
= proto_item_add_subtree(tm
, ett
);
2623 proto_tree_add_item(method_tree
, hf_capability_transmit_t_upper_limit
,
2624 tvb
, curr_offset
, 2, ENC_BIG_ENDIAN
);
2626 proto_tree_add_item(method_tree
, hf_capability_transmit_t_lower_limit
,
2627 tvb
, curr_offset
+2, 2, ENC_BIG_ENDIAN
);
2628 proto_item_append_text(te
, " < %d ms > %d ms", lower_limit
, upper_limit
);
2634 dissect_timer_scale_capability(tvbuff_t
*tvb
, int curr_offset
,
2635 guint16 capability_val_len
, gint ett
, proto_tree
*element_tree
)
2639 proto_tree
*method_tree
;
2641 DISSECTOR_ASSERT(capability_val_len
== 4);
2643 a
= tvb_get_guint8(tvb
, curr_offset
);
2644 c
= tvb_get_guint8(tvb
, curr_offset
+2);
2648 tm
= proto_tree_add_text(element_tree
, tvb
, curr_offset
, 2,
2649 "Only accepting one value");
2651 method_tree
= proto_item_add_subtree(tm
, ett
);
2652 proto_tree_add_text(method_tree
, tvb
, curr_offset
, 1,
2653 "Reserved, must be 0: %d", a
);
2655 proto_tree_add_item(method_tree
, hf_capability_timer_scale_timeout_scale
,
2656 tvb
, curr_offset
+1, 1, ENC_BIG_ENDIAN
);
2657 proto_tree_add_text(method_tree
, tvb
, curr_offset
+2, 1,
2658 "Reserved, must be 0: %d", c
);
2659 proto_tree_add_item(method_tree
, hf_capability_timer_scale_ra_timer_scale
,
2660 tvb
, curr_offset
+3, 1, ENC_BIG_ENDIAN
);
2662 proto_tree_add_text(element_tree
, tvb
, curr_offset
, 1,
2663 "Error A is 0, but C is not");
2667 proto_tree_add_text(element_tree
, tvb
, curr_offset
, 1,
2668 "Error C is 0, but A is not");
2670 tm
= proto_tree_add_text(element_tree
, tvb
, curr_offset
, 2,
2671 "Accepting a range");
2672 method_tree
= proto_item_add_subtree(tm
, ett
);
2673 proto_tree_add_item(method_tree
, hf_capability_timer_scale_timeout_scale_upper_limit
,
2674 tvb
, curr_offset
, 1, ENC_BIG_ENDIAN
);
2676 proto_tree_add_item(method_tree
, hf_capability_timer_scale_timeout_scale_lower_limit
,
2677 tvb
, curr_offset
+1, 1, ENC_BIG_ENDIAN
);
2678 proto_tree_add_item(method_tree
, hf_capability_timer_scale_ra_scale_upper_limit
,
2679 tvb
, curr_offset
+2, 1, ENC_BIG_ENDIAN
);
2680 proto_tree_add_item(method_tree
, hf_capability_timer_scale_ra_scale_lower_limit
,
2681 tvb
, curr_offset
+3, 1, ENC_BIG_ENDIAN
);
2687 /* 6.16 Value Element */
2689 dissect_wccp2_value_element(tvbuff_t
*tvb
, int offset
, gint length
, int idx
, packet_info
*pinfo
, proto_tree
*info_tree
)
2692 proto_tree
*element_tree
;
2697 tl
= proto_tree_add_text(info_tree
, tvb
, offset
, 16, "Value Element(%u) %s",
2698 idx
,decode_wccp_encoded_address(tvb
, offset
+4+4+2+2, pinfo
, info_tree
));
2699 element_tree
= proto_item_add_subtree(tl
, ett_value_element
);
2701 proto_tree_add_item(element_tree
, hf_value_element_src_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2703 proto_tree_add_item(element_tree
, hf_value_element_dest_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2706 proto_tree_add_item(element_tree
, hf_value_element_src_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2708 proto_tree_add_item(element_tree
, hf_value_element_dest_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2711 proto_tree_add_item(element_tree
, hf_value_element_web_cache_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2718 /* 6.14 Mask/Value Set Element */
2720 dissect_wccp2_mask_value_set_element(tvbuff_t
*tvb
, int offset
, gint length
, int idx
, packet_info
*pinfo
, proto_tree
*info_tree
)
2722 proto_item
*tl
, *te
;
2723 proto_tree
*element_tree
, *value_tree
;
2724 guint num_of_val_elements
;
2728 tl
= proto_tree_add_text(info_tree
, tvb
, offset
, 0,
2729 "Mask/Value Set Element(%d)", idx
);
2730 element_tree
= proto_item_add_subtree(tl
, ett_mv_set_element
);
2732 new_length
= dissect_wccp2_mask_element(tvb
,offset
,length
,pinfo
,element_tree
);
2733 NOTE_EATEN_LENGTH(new_length
);
2738 num_of_val_elements
= tvb_get_ntohl(tvb
, offset
);
2739 te
= proto_tree_add_uint(element_tree
, hf_mask_value_set_element_value_element_num
, tvb
, offset
, 4, num_of_val_elements
);
2741 value_tree
= proto_item_add_subtree(te
, ett_mv_set_value_list
);
2744 for (i
= 0; i
< num_of_val_elements
; i
++)
2746 new_length
=dissect_wccp2_value_element(tvb
, offset
, length
, i
, pinfo
, value_tree
);
2748 NOTE_EATEN_LENGTH(new_length
);
2751 proto_item_set_len(tl
, 16+num_of_val_elements
*16);
2756 #define ALT_ASSIGNMENT_INFO_MIN_LEN (4+4)
2758 /* 5.4.2 Alternate Assignment Component */
2760 dissect_wccp2_alternate_assignment_info(tvbuff_t
*tvb
, int offset
, gint length
,
2761 packet_info
*pinfo
, proto_tree
*info_tree
)
2763 guint16 assignment_type
;
2764 guint16 assignment_length
;
2765 proto_item
*tf
=NULL
;
2770 proto_tree
*element_tree
;
2774 if (length
< ALT_ASSIGNMENT_INFO_MIN_LEN
)
2775 return length
- ALT_ASSIGNMENT_INFO_MIN_LEN
;
2778 assignment_type
= tvb_get_ntohs(tvb
, offset
);
2779 proto_tree_add_item(info_tree
, hf_alt_assignment_info_assignment_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2782 assignment_length
= tvb_get_ntohs(tvb
, offset
);
2783 tf
=proto_tree_add_item(info_tree
, hf_alt_assignment_info_assignment_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2786 if (length
< assignment_length
)
2787 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
2788 "Assignment length is %d but only %d remain in the packet. Ignoring this for now",
2789 assignment_length
, length
);
2791 if (length
> assignment_length
) {
2792 expert_add_info_format(pinfo
, tf
, &ei_wccp_assignment_length_bad
,
2793 "Assignment length is %d but %d remain in the packet. Assuming that the assignment length is wrong and setting it to %d.",
2794 assignment_length
, length
, length
);
2797 new_length
=dissect_wccp2_assignment_key_element(tvb
, offset
, length
, pinfo
, info_tree
);
2798 NOTE_EATEN_LENGTH(new_length
);
2800 n_routers
= tvb_get_ntohl(tvb
, offset
);
2801 proto_tree_add_uint(info_tree
, hf_alt_assignment_info_num_routers
, tvb
, offset
, 4, n_routers
);
2804 for (i
= 0; i
< n_routers
; i
++) {
2806 return length
- 12*(n_routers
-i
);
2808 te
= proto_tree_add_text(info_tree
, tvb
, offset
, 12,
2809 "Router %d Assignment Element: IP address %s", i
,
2810 decode_wccp_encoded_address(tvb
, offset
, pinfo
, info_tree
));
2812 element_tree
= proto_item_add_subtree(te
, ett_router_alt_assignment_element
);
2813 dissect_wccp2_router_assignment_element(tvb
, offset
, length
, pinfo
, element_tree
);
2817 switch (assignment_type
) {
2818 case WCCP2_HASH_ASSIGNMENT_TYPE
:
2819 return dissect_wccp2_hash_assignment_info(tvb
, offset
, length
,
2821 case WCCP2_MASK_ASSIGNMENT_TYPE
:
2822 return dissect_wccp2_mask_value_set_list(tvb
, offset
, length
,
2824 case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE
:
2825 return dissect_wccp2_alternate_mask_value_set_list(tvb
, offset
, length
,
2835 /* End of utility functions */
2838 proto_register_wccp(void)
2840 static hf_register_info hf
[] = {
2841 { &hf_wccp_message_type
,
2842 { "WCCP Message Type", "wccp.message", FT_UINT32
, BASE_DEC
, VALS(wccp_type_vals
), 0x0,
2843 "The WCCP message that was sent", HFILL
}
2846 { "WCCP Version", "wccp.version", FT_UINT32
, BASE_HEX
, VALS(wccp_version_val
), 0x0,
2847 "The WCCP version", HFILL
}
2849 { &hf_message_header_version
,
2850 { "WCCP Version (>=2)", "wccp.message_header_version", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2851 "The WCCP version for version 2 and above", HFILL
}
2853 { &hf_hash_revision
,
2854 { "Hash Revision", "wccp.hash_revision", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2855 "The cache hash revision", HFILL
}
2858 { "Change Number", "wccp.change_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2859 "The Web-Cache list entry change number", HFILL
}
2862 { "Flags", "wccp.hash_flag", FT_UINT32
, BASE_HEX
, 0x0, 0x0,
2866 { "Hash information", "wccp.hash_flag.u", FT_BOOLEAN
, 32, TFS(&tfs_historical_current
), 0x10000,
2870 { "Received ID", "wccp.recvd_id", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2871 "The number of I_SEE_YOU's that have been sent", HFILL
}
2874 { "Web Cache IP address", "wccp.cache_ip", FT_IPv4
, BASE_NONE
, NULL
, 0x0,
2875 "The IP address of a Web cache", HFILL
}
2878 { "Number of Web Caches", "wccp.wc_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
2881 { &hf_message_header_length
,
2882 { "Length", "wccp.message_header_length", FT_UINT16
, BASE_DEC
, 0x0, 0x0,
2886 { "Length", "wccp.item_length", FT_UINT16
, BASE_DEC
, 0x0, 0x0,
2887 "The Length ofthe WCCPv2 item", HFILL
}
2890 { "Type", "wccp.item_type", FT_UINT16
, BASE_DEC
, VALS(info_type_vals
), 0x0,
2891 "The type of the WCCPv2 item", HFILL
}
2894 { "Data", "wccp.item_data", FT_BYTES
, BASE_NONE
, 0x0, 0x0,
2895 "The data for an unknown item type", HFILL
}
2897 { &hf_security_info_option
,
2898 { "Security Option", "wccp.security_info_option", FT_UINT16
, BASE_DEC
, VALS(security_option_vals
), 0x0,
2901 { &hf_security_info_md5_checksum
,
2902 { "MD5 checksum (not checked)", "wccp.security_md5_checksum", FT_BYTES
, BASE_NONE
, 0x0, 0x0,
2905 { &hf_command_element_type
,
2906 {"Command Extension Type", "wccp.command_element_type", FT_UINT16
, BASE_DEC
, VALS(wccp_command_type_vals
), 0x0,
2909 { &hf_command_element_length
,
2910 {"Command Extension Length", "wccp.command_element_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2913 { &hf_command_element_shutdown_ip
,
2914 {"Command Extension Length", "wccp.command_element_shudown_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
2917 { &hf_service_info_type
,
2918 { "Service Type", "wccp.service_info_type", FT_UINT8
, BASE_DEC
, VALS(service_type_vals
), 0x0,
2921 { &hf_service_info_id_standard
,
2922 { "WCCP Service ID (Standard)", "wccp.service_info_std_id", FT_UINT8
, BASE_DEC
, VALS(service_id_vals
) , 0x0,
2923 "The WCCP Service id (Standard)", HFILL
}
2925 { &hf_service_info_id_dynamic
,
2926 { "WCCP Service ID ( Dynamic)", "wccp.service_info_dyn_id", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2927 "The WCCP Service id (Dynamic)", HFILL
}
2929 { &hf_service_info_priority
,
2930 { "Priority (highest is 255)", "wccp.service_info_priority", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2933 { &hf_service_info_protocol
,
2934 { "Protocol", "wccp.service_info_protocol", FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &ipproto_val_ext
, 0x0,
2937 { &hf_service_info_flags
,
2938 { "Flags", "wccp.service_info_flags", FT_UINT32
, BASE_HEX
, 0x0, 0x0,
2941 { &hf_service_info_flags_src_ip_hash
,
2942 { "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
,
2945 { &hf_service_info_flags_dest_ip_hash
,
2946 { "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
,
2949 { &hf_service_info_flags_src_port_hash
,
2950 { "Source port in primary hash", "wccp.service_info_flag.src_port_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_SRC_PORT_HASH
,
2953 { &hf_service_info_flags_dest_port_hash
,
2954 { "Destination port in primary hash", "wccp.service_info_flag.dest_port_hash", FT_BOOLEAN
, 32, TFS(&tfs_used_notused
), WCCP2_SI_DST_PORT_HASH
,
2957 { &hf_service_info_flags_ports_defined
,
2958 { "Ports", "wccp.service_info_flag.ports_defined", FT_BOOLEAN
, 32, TFS(&tfs_defined_not_defined
), WCCP2_SI_PORTS_DEFINED
,
2961 { &hf_service_info_flags_ports_source
,
2962 { "Ports refer to", "wccp.service_info_flag.ports_source", FT_BOOLEAN
, 32, TFS(&tfs_src_dest_port
), WCCP2_SI_PORTS_SOURCE
,
2965 { &hf_service_info_flags_redirect_only_protocol_0
,
2966 { "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
,
2969 { &hf_service_info_flags_src_ip_alt_hash
,
2970 { "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
,
2973 { &hf_service_info_flags_dest_ip_alt_hash
,
2974 { "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
,
2977 { &hf_service_info_flags_src_port_alt_hash
,
2978 { "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
,
2981 { &hf_service_info_flags_dest_port_alt_hash
,
2982 { "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
,
2985 { &hf_service_info_source_port
,
2986 { "Source Port", "wccp.service_info_source_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2989 { &hf_service_info_destination_port
,
2990 { "Destination Port", "wccp.service_info_destination_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2993 { &hf_router_identity_ip
,
2994 { "IP Address", "wccp.router_identity.ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
2997 { &hf_router_identity_receive_id
,
2998 { "Received ID", "wccp.router_identity.receive_id", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
3001 { &hf_router_identity_send_to_ip
,
3002 { "Sent To IP Address", "wccp.router_identity.send_to_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3005 { &hf_router_identity_received_from_num
,
3006 { "Number of Received From IP addresses (Webcache to which the message is directed)", "wccp.router.num_recv_ip", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
3009 { &hf_web_cache_identity_ip
,
3010 { "Web-Cache IP Address", "wccp.web_cache_identity.ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3013 { &hf_web_cache_identity_hash_rev
,
3014 { "Hash Revision", "wccp.web_cache_identity.hash_rev", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3017 { &hf_web_cache_identity_flags
,
3018 { "Flags", "wccp.web_cache_identity.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3021 { &hf_web_cache_identity_flag_hash_info
,
3022 { "Hash information", "wccp.web_cache_identity.flags.hash_info", FT_BOOLEAN
, 16,
3023 TFS(&tfs_historical_current
), 0x1,
3026 { &hf_web_cache_identity_flag_assign_type
,
3027 { "Assignment Type", "wccp.web_cache_identity.flags.assign_type", FT_UINT16
, BASE_HEX
,
3028 VALS(&wccp_web_cache_assignment_data_type_val
), 0x6,
3031 { &hf_web_cache_identity_flag_version_request
,
3032 { "Version Request", "wccp.web_cache_identity.flags.version_request", FT_BOOLEAN
, 16,
3033 TFS(&tfs_version_min_max
), 0x8,
3036 { &hf_mask_value_set_element_value_element_num
,
3037 { "Number of Value Elements", "wccp.mask_value_set_selement.value_element_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
3040 { &hf_assignment_weight
,
3041 { "Assignment Weight", "wccp.assignment_weight", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3044 { &hf_assignment_status
,
3045 { "Status", "wccp.assignment_status", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3048 { &hf_assignment_key_ip
,
3049 { "Assignment Key IP Address", "wccp.assignment_key.ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3052 { &hf_assignment_key_change_num
,
3053 { "Assignment Key Change Number", "wccp.assignment_key.change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3056 { &hf_router_view_member_change_num
,
3057 { "Member Change Number", "wccp.router_view.member_change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3060 { &hf_router_router_num
,
3061 { "Number of Routers", "wccp.router_view.router_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3064 { &hf_router_identity_router_ip
,
3065 { "Router IP Address", "wccp.router_identity.router_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3068 { &hf_router_identity_received_from_ip
,
3069 { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3072 { &hf_wc_view_info_change_num
,
3073 { "Change Number", "wccp.wc_view_info.change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3076 { &hf_wc_view_info_router_ip
,
3077 { "Router IP", "wccp.wc_view_info.router_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3080 { &hf_wc_view_info_wc_ip
,
3081 { "Web Cache IP", "wccp.wc_view_info.wc_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3084 { &hf_wc_view_router_num
,
3085 { "Number of Routers", "wccp.wc_view_info.router_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3088 { &hf_wc_view_wc_num
,
3089 { "Number of Web Caches", "wccp.wc_view_info.wc_num", FT_UINT32
, BASE_DEC
, 0x0, 0x0,
3092 { &hf_wc_identity_ip_address
,
3093 { "Web Cache Identity", "wccp.hf_wc_identity_ip_address", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3094 "The IP identifying the Web Cache", HFILL
}
3096 { &hf_router_assignment_element_change_num
,
3097 { "Change Number", "wccp.router_assignment_element.change_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3100 { &hf_assignment_info_router_num
,
3101 { "Number of Routers", "wccp.assignment_info.router_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3104 { &hf_assignment_info_router_ip
,
3105 { "Router IP", "wccp.assignment_info.router_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3108 { &hf_hash_buckets_assignment_wc_num
,
3109 { "Number of WC", "wccp.hash_buckets_assignment.wc_num", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3112 { &hf_hash_buckets_assignment_wc_ip
,
3113 { "WC IP", "wccp.hash_buckets_assignment.wc_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3116 { &hf_router_view_ip
,
3117 { "Router IP Address", "wccp.router_view.ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3120 { &hf_router_query_info_ip
,
3121 { "Web-Cache Identity Element IP address", "wccp.router_query_info.ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3124 { &hf_router_query_info_send_to_ip
,
3125 { "Sent To IP Address", "wccp.router_query_info.send_to_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3128 { &hf_router_query_info_target_ip
,
3129 { "Target IP Address", "wccp.router_query_info.target_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3132 { &hf_capability_element_type
,
3133 { "Type", "wccp.capability_element.type", FT_UINT16
, BASE_DEC
, VALS(capability_type_vals
), 0x0,
3136 { &hf_capability_element_length
,
3137 { "Value Length", "wccp.capability_element.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3140 { &hf_capability_info_value
,
3141 { "Value", "wccp.capability_info.value", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3144 { &hf_capability_forwarding_method_flag_gre
,
3145 { "GRE-encapsulated", "wccp.capability_info.forwarding_method_flag.gre", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_FORWARDING_METHOD_GRE
,
3148 { &hf_capability_forwarding_method_flag_l2
,
3149 { "L2 rewrite", "wccp.capability_info.forwarding_method_flag.l2", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_FORWARDING_METHOD_L2
,
3152 { &hf_capability_assignment_method_flag_hash
,
3153 { "Hash", "wccp.capability_info.assignment_method_flag.hash", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_ASSIGNMENT_METHOD_HASH
,
3156 { &hf_capability_assignment_method_flag_mask
,
3157 { "Mask", "wccp.capability_info.assignment_method_flag.mask", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_ASSIGNMENT_METHOD_MASK
,
3160 { &hf_capability_return_method_flag_gre
,
3161 { "GRE-encapsulated", "wccp.capability_info.return_method_flag.gre", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_PACKET_RETURN_METHOD_GRE
,
3164 { &hf_capability_return_method_flag_l2
,
3165 { "L2 rewrite", "wccp.capability_info.return_method_flag.l2", FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), WCCP2_PACKET_RETURN_METHOD_L2
,
3168 { &hf_capability_transmit_t
,
3169 { "Message interval in milliseconds", "wccp.capability.transmit_t", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3172 { &hf_capability_transmit_t_upper_limit
,
3173 { "Message interval upper limit in milliseconds", "wccp.capability.transmit_t.upper_limit", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3176 { &hf_capability_transmit_t_lower_limit
,
3177 { "Message interval lower limit in milliseconds", "wccp.capability.transmit_t.upper_limit", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3180 { &hf_capability_timer_scale_timeout_scale
,
3181 { "Timer scale", "wccp.capability.timer_scale.timeout_scale", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3184 { &hf_capability_timer_scale_timeout_scale_upper_limit
,
3185 { "Timer scale upper limit", "wccp.capability.timer_scale.timeout_scale.upper_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3188 { &hf_capability_timer_scale_timeout_scale_lower_limit
,
3189 { "Timer scale lower limit", "wccp.capability.timer_scale.timeout_scale.lower_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3192 { &hf_capability_timer_scale_ra_timer_scale
,
3193 { "RA Timer scale", "wccp.capability.timer_scale.ra_timer_scale", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3196 { &hf_capability_timer_scale_ra_scale_upper_limit
,
3197 { "RA Timer scale upper limit", "wccp.capability.timer_scale.ra_timer_scale.upper_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3200 { &hf_capability_timer_scale_ra_scale_lower_limit
,
3201 { "RA Timer scale lower limit", "wccp.capability.timer_scale.ra_timer_scale.lower_limit", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3204 { &hf_value_element_src_ip
,
3205 { "Source Address", "wccp.value_element.src_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3208 { &hf_value_element_dest_ip
,
3209 { "Destination Address", "wccp.value_element.dest_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3212 { &hf_value_element_src_port
,
3213 { "Source Port", "wccp.value_element.src_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3216 { &hf_value_element_dest_port
,
3217 { "Destination Port", "wccp.value_element.dest_port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3220 { &hf_value_element_web_cache_ip
,
3221 { "Web Cache Address", "wccp.value_element.web_cache_ip", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3224 { &hf_mask_value_set_list_num_elements
,
3225 { "Number of elements", "wccp.mask_value_set_list.num_elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3228 { &hf_mask_element_src_ip
,
3229 { "Source Address Mask", "wccp.mask_element.src_ip", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3232 { &hf_mask_element_dest_ip
,
3233 { "Destination Address Mask", "wccp.mask_element.dest_ip", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3236 { &hf_mask_element_src_port
,
3237 { "Source Port Mask", "wccp.mask_element.src_port", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3240 { &hf_mask_element_dest_port
,
3241 { "Destination Port Mask", "wccp.mask_element.dest_port", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3244 { &hf_alt_assignment_info_assignment_type
,
3245 { "Assignment type", "wccp.alt_assignment_info.assignment_type", FT_UINT16
, BASE_DEC
, VALS(assignment_type_vals
), 0x0,
3248 { &hf_extended_assignment_data_type
,
3249 { "Assignment type", "wccp.extended_assignment_data.type", FT_UINT16
, BASE_DEC
, VALS(assignment_type_vals
), 0x0,
3252 { &hf_alt_assignment_map_assignment_type
,
3253 { "Assignment type", "wccp.alt_assignment_map.assignment_type", FT_UINT16
, BASE_DEC
, VALS(assignment_type_vals
), 0x0,
3256 { &hf_alt_assignment_map_assignment_length
,
3257 { "Assignment length", "wccp.alt_assignment_map.assignment_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3260 { &hf_alt_assignment_info_assignment_length
,
3261 { "Assignment length", "wccp.alt_assignment_info.assignment_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3264 { &hf_extended_assignment_data_length
,
3265 { "Assignment length", "wccp.extended_assignment_data.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3268 { &hf_alt_assignment_info_num_routers
,
3269 { "Number of routers", "wccp.alt_assignment_info.num_routers", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3272 { &hf_alt_assignment_mask_value_set_element_num_wc_value_elements
,
3273 { "Number of Web-Cache Value Elements", "wccp.alt_assignment_mask_value_set_element.num_wc_value_elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3276 { &hf_web_cache_value_element_wc_address
,
3277 { "Web-Cache Address", "wccp.web_cache_value_element.wc_address", FT_UINT32
, BASE_CUSTOM
, wccp_fmt_ipadddress
, 0x0,
3280 { &hf_web_cache_value_element_num_values
,
3281 { "Number of Valye Sequence Numbers", "wccp.web_cache_value_element.num_values", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3284 { &hf_alt_assignment_mask_value_set_list_num_elements
,
3285 { "Number of Alternate Mask/Value Set Elements", "wccp.alt_assignment_mask_value_list.num_elements", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3288 { &hf_address_table_family
,
3289 { "Family Type", "wccp.address_table.family_type", FT_UINT16
, BASE_DEC
, VALS(wccp_address_family_val
), 0x0,
3290 "The WCCP Address Table Family type", HFILL
}
3292 { &hf_address_table_address_length
,
3293 { "Address Length", "wccp.address_table.address_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3294 "The WCCP Address Table Address Length", HFILL
}
3296 { &hf_address_table_length
,
3297 { "Length", "wccp.address_table.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3298 "The WCCP Address Table Length", HFILL
}
3300 { &hf_address_table_element
,
3301 { "Address", "wccp.address_table.element", FT_STRING
, BASE_NONE
, NULL
, 0x0,
3306 static gint
*ett
[] = {
3309 &ett_hash_assignment_buckets
,
3310 &ett_mask_assignment_data_element
,
3311 &ett_alternate_mask_assignment_data_element
,
3312 &ett_extended_assigment_data_element
,
3315 &ett_wc_identity_flags
,
3320 &ett_service_info_ports
,
3321 &ett_wc_view_info_router_element
,
3322 &ett_router_identity_info
,
3323 &ett_wc_identity_element
,
3324 &ett_wc_identity_info
,
3325 &ett_router_view_info
,
3328 &ett_router_assignment_element
,
3329 &ett_hash_buckets_assignment_wc_element
,
3330 &ett_hash_buckets_assignment_buckets
,
3331 &ett_router_alt_assignment_element
,
3332 &ett_router_assignment_info
,
3333 &ett_capabilities_info
,
3334 &ett_capability_element
,
3335 &ett_capability_forwarding_method
,
3336 &ett_capability_assignment_method
,
3337 &ett_capability_return_method
,
3338 &ett_capability_transmit_t
,
3339 &ett_capability_timer_scale
,
3341 &ett_mv_set_element
,
3342 &ett_mv_set_value_list
,
3343 &ett_alternate_mv_set_element_list
,
3344 &ett_web_cache_value_element_list
,
3345 &ett_alternate_mv_set_element
,
3347 &ett_alt_assignment_info
,
3348 &ett_alt_assignment_map
,
3349 &ett_assignment_map
,
3352 &ett_alternate_mask_value_set
,
3353 &ett_alternate_mask_value_set_element
,
3354 &ett_command_extension
,
3357 static ei_register_info ei
[] = {
3358 { &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
}},
3359 { &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
}},
3360 { &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
}},
3361 { &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
}},
3362 { &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
}},
3363 { &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
}},
3364 { &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
}},
3365 { &ei_wccp_missing_assignment
, { "wccp.missing.assignment", PI_PROTOCOL
, PI_ERROR
, "This message should contain a Alternate Assignment, Assignment Map, Assignment Info or "
3366 "Alternative Assignment Map component, but it is missing", EXPFILL
}},
3367 { &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
}},
3368 { &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
}},
3369 { &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
}},
3370 { &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
}},
3371 { &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
}},
3372 { &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
}},
3373 { &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
}},
3374 { &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
}},
3375 { &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
}},
3376 { &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
}},
3377 { &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
}},
3378 { &ei_wccp_assignment_length_bad
, { "wccp.assignment_length_bad", PI_PROTOCOL
, PI_ERROR
, "Assignment length bad", EXPFILL
}},
3379 { &ei_wccp_length_bad
, { "wccp.length_bad", PI_PROTOCOL
, PI_ERROR
, "Length bad", EXPFILL
}},
3380 { &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
}},
3381 { &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
}},
3382 { &ei_wccp_router_identity_receive_id_zero
, { "wccp.router_identity.receive_id.zero", PI_PROTOCOL
, PI_WARN
, "Receive ID shouldn't be 0", EXPFILL
}},
3383 { &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
}},
3384 { &ei_wccp_address_table_family_unknown
, { "wccp.address_table.family_type.unknown", PI_PROTOCOL
, PI_ERROR
, "Unknown address family", EXPFILL
}},
3385 { &ei_wccp_capability_element_length
, { "wccp.capability_element.length.invalid", PI_PROTOCOL
, PI_WARN
, "Value Length invalid", EXPFILL
}},
3388 expert_module_t
* expert_wccp
;
3390 proto_wccp
= proto_register_protocol("Web Cache Communication Protocol",
3392 proto_register_field_array(proto_wccp
, hf
, array_length(hf
));
3393 proto_register_subtree_array(ett
, array_length(ett
));
3394 expert_wccp
= expert_register_protocol(proto_wccp
);
3395 expert_register_field_array(expert_wccp
, ei
, array_length(ei
));
3399 proto_reg_handoff_wccp(void)
3401 dissector_handle_t wccp_handle
;
3403 wccp_handle
= new_create_dissector_handle(dissect_wccp
, proto_wccp
);
3404 dissector_add_uint("udp.port", UDP_PORT_WCCP
, wccp_handle
);
3408 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3413 * indent-tabs-mode: nil
3416 * vi: set shiftwidth=2 tabstop=8 expandtab:
3417 * :indentSize=2:tabSize=8:noTabs=true: