From 38c05061ba1c27472f45678e2f4782d3194b25b8 Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Wed, 15 Jul 2015 16:02:51 -0400 Subject: WCCP - remove global variable used to store address information for computation later. Change-Id: I06841ec77cf9f34914b9dfe10b8cd35824b32b71 Reviewed-on: https://code.wireshark.org/review/9647 Petri-Dish: Michael Mann Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- epan/dissectors/packet-wccp.c | 1669 +++++++++++++++++++++++------------------ 1 file changed, 934 insertions(+), 735 deletions(-) (limited to 'epan/dissectors/packet-wccp.c') diff --git a/epan/dissectors/packet-wccp.c b/epan/dissectors/packet-wccp.c index e69d9ba04e..acd4dc5aaa 100644 --- a/epan/dissectors/packet-wccp.c +++ b/epan/dissectors/packet-wccp.c @@ -28,7 +28,6 @@ #include #include #include "packet-wccp.h" - #include void proto_register_wccp(void); void proto_reg_handoff_wccp(void); @@ -56,7 +55,9 @@ static int hf_security_info_md5_checksum = -1; static int hf_command_element_type = -1; static int hf_command_element_length = -1; static int hf_command_length = -1; -static int hf_command_element_shutdown_ip = -1; +static int hf_command_element_shutdown_ip_index = -1; +static int hf_command_element_shutdown_ipv4 = -1; +static int hf_command_element_shutdown_ipv6 = -1; static int hf_command_unknown = -1; static int hf_service_info_type = -1; static int hf_service_info_id_standard = -1; @@ -78,11 +79,17 @@ static int hf_service_info_flags_dest_port_alt_hash = -1; static int hf_service_info_flags_reserved = -1; static int hf_service_info_source_port = -1; static int hf_service_info_destination_port = -1; -static int hf_router_identity_ip = -1; +static int hf_router_identity_ip_index = -1; +static int hf_router_identity_ipv4 = -1; +static int hf_router_identity_ipv6 = -1; static int hf_router_identity_receive_id = -1; -static int hf_router_identity_send_to_ip = -1; +static int hf_router_identity_send_to_ip_index = -1; +static int hf_router_identity_send_to_ipv4 = -1; +static int hf_router_identity_send_to_ipv6 = -1; static int hf_router_identity_received_from_num = -1; -static int hf_web_cache_identity_ip = -1; +static int hf_web_cache_identity_index = -1; +static int hf_web_cache_identity_ipv4 = -1; +static int hf_web_cache_identity_ipv6 = -1; static int hf_web_cache_identity_hash_rev = -1; static int hf_web_cache_identity_flags = -1; static int hf_web_cache_identity_flag_hash_info = -1; @@ -92,27 +99,51 @@ static int hf_web_cache_identity_flag_reserved = -1; static int hf_mask_value_set_element_value_element_num = -1; static int hf_assignment_weight = -1; static int hf_assignment_status = -1; -static int hf_assignment_key_ip = -1; +static int hf_assignment_key_ip_index = -1; +static int hf_assignment_key_ipv4 = -1; +static int hf_assignment_key_ipv6 = -1; static int hf_assignment_key_change_num = -1; static int hf_assignment_no_data = -1; static int hf_router_view_member_change_num = -1; static int hf_router_router_num = -1; -static int hf_router_identity_router_ip = -1; +static int hf_router_identity_router_ip_index = -1; +static int hf_router_identity_router_ipv4 = -1; +static int hf_router_identity_router_ipv6 = -1; static int hf_wc_view_info_change_num = -1; -static int hf_wc_view_info_router_ip = -1; -static int hf_wc_view_info_wc_ip = -1; +static int hf_wc_view_info_router_ip_index = -1; +static int hf_wc_view_info_router_ipv4 = -1; +static int hf_wc_view_info_router_ipv6 = -1; +static int hf_wc_view_info_wc_ip_index = -1; +static int hf_wc_view_info_wc_ipv4 = -1; +static int hf_wc_view_info_wc_ipv6 = -1; static int hf_wc_view_router_num = -1; -static int hf_wc_identity_ip_address = -1; -static int hf_router_identity_received_from_ip = -1; +static int hf_wc_identity_ip_address_index = -1; +static int hf_wc_identity_ip_address_ipv4 = -1; +static int hf_wc_identity_ip_address_ipv6 = -1; +static int hf_router_identity_received_from_ip_index = -1; +static int hf_router_identity_received_from_ipv4 = -1; +static int hf_router_identity_received_from_ipv6 = -1; static int hf_router_assignment_element_change_num = -1; static int hf_assignment_info_router_num = -1; static int hf_hash_buckets_assignment_wc_num = -1; -static int hf_hash_buckets_assignment_wc_ip = -1; -static int hf_assignment_info_router_ip = -1; -static int hf_router_view_ip = -1; -static int hf_router_query_info_ip = -1; -static int hf_router_query_info_send_to_ip = -1; -static int hf_router_query_info_target_ip = -1; +static int hf_hash_buckets_assignment_wc_ip_index = -1; +static int hf_hash_buckets_assignment_wc_ipv4 = -1; +static int hf_hash_buckets_assignment_wc_ipv6 = -1; +static int hf_assignment_info_router_ip_index = -1; +static int hf_assignment_info_router_ipv4 = -1; +static int hf_assignment_info_router_ipv6 = -1; +static int hf_router_view_ip_index = -1; +static int hf_router_view_ipv4 = -1; +static int hf_router_view_ipv6 = -1; +static int hf_router_query_info_ip_index = -1; +static int hf_router_query_info_ipv4 = -1; +static int hf_router_query_info_ipv6 = -1; +static int hf_router_query_info_send_to_ip_index = -1; +static int hf_router_query_info_send_to_ipv4 = -1; +static int hf_router_query_info_send_to_ipv6 = -1; +static int hf_router_query_info_target_ip_index = -1; +static int hf_router_query_info_target_ipv4 = -1; +static int hf_router_query_info_target_ipv6 = -1; static int hf_capability_element_type = -1; static int hf_capability_element_length = -1; static int hf_capability_info_value = -1; @@ -133,11 +164,17 @@ static int hf_capability_timer_scale_ra_scale_upper_limit = -1; static int hf_capability_timer_scale_ra_scale_lower_limit = -1; static int hf_capability_value = -1; static int hf_reserved_zero = -1; -static int hf_value_element_src_ip = -1; -static int hf_value_element_dest_ip = -1; +static int hf_value_element_src_ip_index = -1; +static int hf_value_element_src_ipv4 = -1; +static int hf_value_element_src_ipv6 = -1; +static int hf_value_element_dest_ip_index = -1; +static int hf_value_element_dest_ipv4 = -1; +static int hf_value_element_dest_ipv6 = -1; static int hf_value_element_src_port = -1; static int hf_value_element_dest_port = -1; -static int hf_value_element_web_cache_ip = -1; +static int hf_value_element_web_cache_ip_index = -1; +static int hf_value_element_web_cache_ipv4 = -1; +static int hf_value_element_web_cache_ipv6 = -1; static int hf_mask_value_set_list_num_elements = -1; static int hf_mask_element_src_ip = -1; static int hf_mask_element_dest_ip = -1; @@ -151,7 +188,9 @@ static int hf_alt_assignment_map_assignment_length = -1; static int hf_extended_assignment_data_length = -1; static int hf_alt_assignment_info_num_routers = -1; static int hf_alt_assignment_mask_value_set_element_num_wc_value_elements = -1; -static int hf_web_cache_value_element_wc_address = -1; +static int hf_web_cache_value_element_wc_address_index = -1; +static int hf_web_cache_value_element_wc_address_ipv4 = -1; +static int hf_web_cache_value_element_wc_address_ipv6 = -1; static int hf_web_cache_value_element_num_values = -1; static int hf_web_cache_value_seq_num = -1; static int hf_alt_assignment_mask_value_set_list_num_elements = -1; @@ -407,91 +446,39 @@ typedef struct wccp_address_table { struct e_in6_addr *table_ipv6; } wccp_address_table; - -wccp_address_table wccp_wccp_address_table; - -static guint dissect_hash_data(tvbuff_t *tvb, int offset, - proto_tree *wccp_tree); -static guint dissect_web_cache_list_entry(tvbuff_t *tvb, int offset, - int idx, proto_tree *wccp_tree); static int wccp_bucket_info(guint8 bucket_info, proto_tree *bucket_tree, guint32 start, tvbuff_t *tvb, int offset); -static void dissect_wccp2_info(tvbuff_t *tvb, int offset, - packet_info *pinfo, proto_tree *wccp_tree, guint32 wccp_message_type); -/* WCCP 2r1 IPv6 utlility functions */ -static void find_wccp_address_table(tvbuff_t *tvb, int offset, - packet_info *pinfo _U_, proto_tree *wccp_tree _U_); /* The V2 dissectors will return the remaining length of the packet and a negative number if there are missing bytes to finish the dissection */ -static gint dissect_wccp2_security_info(tvbuff_t *tvb, int offset, gint lengreth, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_service_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree); -static gint dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo, proto_tree *info_tree); -static gint dissect_wccp2_router_identity_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_wc_identity_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_router_view_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_web_cache_view_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_assignment_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); +static gint dissect_wccp2_mask_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, + proto_tree *info_tree, wccp_address_table* addr_table); static gint dissect_wccp2_hash_buckets_assignment_element(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree); -static gboolean dissect_wccp2_router_query_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_capability_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_alternate_assignment_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree); -static gint dissect_wccp2_hash_assignment_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2_assignment_map(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo _U_, proto_tree *info_tree); -static gint dissect_wccp2r1_alt_assignment_map_info(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo, proto_tree *info_tree); -static gint dissect_wccp2_command_extension(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo _U_, proto_tree *info_tree); -static void dissect_wccp2_router_identity_element(tvbuff_t *tvb, int offset, packet_info *pinfo, - proto_tree *tree); -static gint dissect_wccp2_web_cache_identity_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree); + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table); +static gint dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, + int length, packet_info *pinfo, proto_tree *info_tree, + wccp_address_table* wccp_wccp_address_table); static gint dissect_wccp2_hash_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, proto_tree *info_tree); -static gint dissect_wccp2_mask_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree) ; -static gint dissect_wccp2_alternate_mask_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree); static gint dissect_wccp2_assignment_weight_and_status_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, proto_tree *info_tree); static gint dissect_wccp2_extended_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree); -static gint dissect_wccp2_assignment_key_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree); -static void dissect_wccp2_router_assignment_element(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) ; + proto_tree *info_tree, wccp_address_table* addr_table); static gint dissect_wccp2_capability_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo _U_, proto_tree *info_tree); static gint dissect_wccp2_mask_value_set_list(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo, proto_tree *info_tree); + int length, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table); /* Utility functions */ static gint dissect_wccp2_mask_value_set_element(tvbuff_t *tvb, int offset, - gint length, int idx, packet_info *pinfo, proto_tree *info_tree); -static gint dissect_wccp2_mask_element(tvbuff_t *tvb, int offset, - gint length, packet_info *pinfo, proto_tree *info_tree); -static gint dissect_wccp2_value_element(tvbuff_t *tvb, int offset, - gint length, int idx, packet_info *pinfo, proto_tree *info_tree); + gint length, int idx, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table); static gint dissect_wccp2_alternate_mask_value_set_list(tvbuff_t *tvb, int offset, - gint length, packet_info *pinfo _U_, proto_tree *info_tree); -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); + gint length, packet_info *pinfo _U_, proto_tree *info_tree, wccp_address_table* addr_table); +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, wccp_address_table* addr_table); static gint dissect_wccp2_web_cache_value_element(tvbuff_t *tvb, int offset, - gint length, packet_info *pinfo, proto_tree *info_tree); + gint length, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table); static void dissect_32_bit_capability_flags(tvbuff_t *tvb, int curr_offset, guint16 capability_val_len, gint ett, const capability_flag *flags, proto_tree *element_tree, proto_item *header, @@ -514,31 +501,17 @@ static void dissect_timer_scale_capability(tvbuff_t *tvb, int curr_offset, static void find_wccp_address_table(tvbuff_t *tvb, int offset, - packet_info *pinfo, proto_tree *wccp_tree _U_) + packet_info *pinfo, proto_tree *wccp_tree _U_, wccp_address_table* wccp_wccp_address_table) { guint16 type; guint16 item_length; - /* first clean up: */ - wccp_wccp_address_table.in_use = FALSE; - wccp_wccp_address_table.family = -1; - wccp_wccp_address_table.version = -1; - wccp_wccp_address_table.table_length = 0; - wccp_wccp_address_table.table_ipv4 = (guint32 *) NULL; - wccp_wccp_address_table.table_ipv6 = (struct e_in6_addr *)NULL; - for (;;) { if (4 > tvb_reported_length_remaining(tvb, offset)) { /* We've run out of packet data without finding an address table, so there's no address table in the packet. */ return; } - if (4 > tvb_captured_length_remaining(tvb, offset)) { - /* We've run out of captured date without finding an address table, - so we've no way of determining whether there's an address table - or not. */ - return; - } type = tvb_get_ntohs(tvb, offset); item_length = tvb_get_ntohs(tvb, offset+2); @@ -547,16 +520,10 @@ find_wccp_address_table(tvbuff_t *tvb, int offset, so there's no address table in the packet. */ return; } - if ((item_length + 4) > tvb_captured_length_remaining(tvb, offset)) { - /* We've run out of captured date without finding an address table, - so we've no way of determining whether there's an address table - or not. */ - return; - } if (type == WCCP2r1_ADDRESS_TABLE) { - dissect_wccp2r1_address_table_info(tvb, offset+4, item_length, pinfo, NULL); + dissect_wccp2r1_address_table_info(tvb, offset+4, item_length, pinfo, NULL, wccp_wccp_address_table); /* no need to decode the rest */ return; } @@ -582,10 +549,10 @@ find_wccp_address_table(tvbuff_t *tvb, int offset, we need to fix that */ -static void wccp_fmt_ipadddress(gchar *buffer, guint32 host_addr) +static void wccp_fmt_ipaddress(gchar *buffer, guint32 host_addr, wccp_address_table* addr_table) { /* are we using an address table? */ - if (! wccp_wccp_address_table.in_use) + if (!addr_table->in_use) { /* no return the IPv4 IP */ /* first fix the byte order */ @@ -606,7 +573,7 @@ static void wccp_fmt_ipadddress(gchar *buffer, guint32 host_addr) } /* now check if it's IPv4 or IPv6 we need to print */ - switch (wccp_wccp_address_table.family) { + switch (addr_table->family) { case 1: /* IPv4 */ @@ -616,15 +583,15 @@ static void wccp_fmt_ipadddress(gchar *buffer, guint32 host_addr) return; } /* are we be beyond the end of the table? */ - if (addr_index > wccp_wccp_address_table.table_length) { + if (addr_index > addr_table->table_length) { g_snprintf(buffer, ITEM_LABEL_LENGTH, "INVALID IPv4 index: %d > %d", - addr_index, wccp_wccp_address_table.table_length); + addr_index, addr_table->table_length); return; } /* ok get the IP */ - if (wccp_wccp_address_table.table_ipv4 != NULL) { - ip_to_str_buf( (guint8 *) &(wccp_wccp_address_table.table_ipv4[addr_index-1]), buffer, ITEM_LABEL_LENGTH); + if (addr_table->table_ipv4 != NULL) { + ip_to_str_buf( (guint8 *) &(addr_table->table_ipv4[addr_index-1]), buffer, ITEM_LABEL_LENGTH); return; } else { @@ -641,15 +608,15 @@ static void wccp_fmt_ipadddress(gchar *buffer, guint32 host_addr) } /* are we be beyond the end of the table? */ - if (addr_index > wccp_wccp_address_table.table_length) { + if (addr_index > addr_table->table_length) { g_snprintf(buffer, ITEM_LABEL_LENGTH, "INVALID IPv6 index: %d > %d", - addr_index, wccp_wccp_address_table.table_length); + addr_index, addr_table->table_length); return; } /* ok get the IP */ - if (wccp_wccp_address_table.table_ipv6 != NULL) { - ip6_to_str_buf(&(wccp_wccp_address_table.table_ipv6[addr_index-1]), buffer); + if (addr_table->table_ipv6 != NULL) { + ip6_to_str_buf(&(addr_table->table_ipv6[addr_index-1]), buffer); return; } else { @@ -664,155 +631,89 @@ static void wccp_fmt_ipadddress(gchar *buffer, guint32 host_addr) } } - -#define WCCP_IP_MAX_LENGTH (MAX_IP_STR_LEN > 46 ? MAX_IP_STR_LEN : 46) - - -static const gchar * decode_wccp_encoded_address(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *info_tree _U_) +static proto_item* wccp_add_ipaddress_item(proto_tree* tree, int hf_index, int hf_ipv4, int hf_ipv6, tvbuff_t *tvb, + int offset, gint length, wccp_address_table* addr_table) { - gchar *buffer; - guint32 host_addr; + guint32 host_addr; + struct e_in6_addr ipv6_zero; + guint16 reserv, addr_index; - buffer= (char *) wmem_alloc(wmem_packet_scope(), WCCP_IP_MAX_LENGTH+1); - host_addr = tvb_get_ntohl(tvb,offset); + /* are we using an address table? */ + if (! addr_table->in_use) + return proto_tree_add_item(tree, hf_ipv4, tvb, offset, length, ENC_BIG_ENDIAN); - wccp_fmt_ipadddress(buffer, host_addr); - return buffer; -} + host_addr = tvb_get_ntohl(tvb, offset); -static int -dissect_wccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) -{ - int offset = 0; - proto_tree *wccp_tree = NULL; - proto_item *wccp_tree_item; - guint32 wccp_message_type; - guint16 length; - gint wccp2_length; - proto_item *length_item; - guint32 cache_count; - guint32 ipaddr; - guint i; - guint8 bucket; + /* we need to decode the encoded address: */ + reserv = (host_addr & 0xFF00) >> 16; + addr_index = (host_addr & 0x00FF); - wccp_message_type = tvb_get_ntohl(tvb, offset); + memset(&ipv6_zero, 0, sizeof(ipv6_zero)); - /* Check if this is really a WCCP message */ - if (try_val_to_str(wccp_message_type, wccp_type_vals) == NULL) - return 0; + if (reserv != 0) + return proto_tree_add_uint_format_value(tree, hf_index, tvb, offset, length, host_addr, "INVALID: reserved part non zero"); - col_set_str(pinfo->cinfo, COL_PROTOCOL, "WCCP"); + /* now check if it's IPv4 or IPv6 we need to print */ + switch (addr_table->family) { + case 1: + /* IPv4 */ - col_add_str(pinfo->cinfo, COL_INFO, val_to_str(wccp_message_type, - wccp_type_vals, "Unknown WCCP message (%u)")); + /* special case: index 0 -> undefined IP */ + if (addr_index == 0) { + return proto_tree_add_item(tree, hf_ipv4, tvb, offset, length, ENC_LITTLE_ENDIAN); + } + /* are we be beyond the end of the table? */ + if (addr_index > addr_table->table_length) { + return proto_tree_add_uint_format_value(tree, hf_index, tvb, offset, length, host_addr, + "INVALID IPv4 index: %d > %d", addr_index, addr_table->table_length); + } - wccp_tree_item = proto_tree_add_item(tree, proto_wccp, tvb, offset, -1, ENC_NA); - wccp_tree = proto_item_add_subtree(wccp_tree_item, ett_wccp); + /* ok get the IP */ + if (addr_table->table_ipv4 != NULL) { + return proto_tree_add_ipv4(tree, hf_ipv4, tvb, offset, length, addr_table->table_ipv4[addr_index-1]); + } - proto_tree_add_uint(wccp_tree, hf_wccp_message_type, tvb, offset, 4, wccp_message_type); - offset += 4; + return proto_tree_add_uint_format_value(tree, hf_index, tvb, offset, length, host_addr, "INVALID: IPv4 table empty!"); - switch (wccp_message_type) { + case 2: + /* IPv6 */ + /* special case: index 0 -> undefined IP */ + if (addr_index == 0) { + return proto_tree_add_ipv6(tree, hf_ipv6, tvb, offset, length, ipv6_zero.bytes); + } - case WCCP_HERE_I_AM: - proto_tree_add_item(wccp_tree, hf_wccp_version, tvb, - offset, 4, ENC_BIG_ENDIAN); - offset += 4; - offset = dissect_hash_data(tvb, offset, wccp_tree); - proto_tree_add_item(wccp_tree, hf_recvd_id, tvb, offset, - 4, ENC_BIG_ENDIAN); - /*offset += 4;*/ - break; + /* are we be beyond the end of the table? */ + if (addr_index > addr_table->table_length) { + return proto_tree_add_uint_format_value(tree, hf_index, tvb, offset, length, host_addr, + "INVALID IPv6 index: %d > %d", addr_index, addr_table->table_length); + } - case WCCP_I_SEE_YOU: - proto_tree_add_item(wccp_tree, hf_wccp_version, tvb, - offset, 4, ENC_BIG_ENDIAN); - offset += 4; - proto_tree_add_item(wccp_tree, hf_change_num, tvb, offset, - 4, ENC_BIG_ENDIAN); - offset += 4; - proto_tree_add_item(wccp_tree, hf_recvd_id, tvb, offset, - 4, ENC_BIG_ENDIAN); - offset += 4; - cache_count = tvb_get_ntohl(tvb, offset); - proto_tree_add_uint(wccp_tree, hf_wc_num, tvb, offset, 4, cache_count); - offset += 4; - for (i = 0; i < cache_count; i++) { - offset = dissect_web_cache_list_entry(tvb, offset, i, - wccp_tree); - } - break; + /* ok get the IP */ + if (addr_table->table_ipv6 != NULL) { + return proto_tree_add_ipv6(tree, hf_ipv6, tvb, offset, length, addr_table->table_ipv6[addr_index-1].bytes); + } - case WCCP_ASSIGN_BUCKET: - /* - * This hasn't been tested, since I don't have any - * traces with this in it. - * - * The V1 spec claims that this does, indeed, - * have a Received ID field after the type, - * rather than a Version field. - */ - proto_tree_add_item(wccp_tree, hf_recvd_id, tvb, offset, - 4, ENC_BIG_ENDIAN); - offset += 4; - cache_count = tvb_get_ntohl(tvb, offset); - proto_tree_add_uint(wccp_tree, hf_wc_num, tvb, offset, 4, cache_count); - offset += 4; - for (i = 0; i < cache_count; i++) { - ipaddr = tvb_get_ipv4(tvb, offset); - proto_tree_add_ipv4_format(wccp_tree, - hf_cache_ip, tvb, offset, 4, - ipaddr, - "Web Cache %d IP Address: %s", i, - tvb_ip_to_str(tvb, offset)); - offset += 4; - } + return proto_tree_add_uint_format_value(tree, hf_index, tvb, offset, length, host_addr, + "INVALID IPv6 table empty!"); + } - for (i = 0; i < 256; i++) { - bucket = tvb_get_guint8(tvb, offset); - if (bucket == 0xff) { - proto_tree_add_uint_format(wccp_tree, hf_bucket, tvb, offset, 1, - bucket, "Bucket %d: Unassigned", i); - } else { - proto_tree_add_uint_format(wccp_tree, hf_bucket, tvb, offset, 1, - bucket, "Bucket %d: %d", i, bucket); - } - offset++; - } - break; + return proto_tree_add_ipv4_format(tree, hf_index, tvb, offset, length, host_addr, "INVALID IP family"); +} - case WCCP2_HERE_I_AM: - case WCCP2_I_SEE_YOU: - case WCCP2_REMOVAL_QUERY: - case WCCP2_REDIRECT_ASSIGN: - default: /* assume unknown packets are v2 */ - /* 5.5 WCCP Message Header */ +#define WCCP_IP_MAX_LENGTH (MAX_IP_STR_LEN > 46 ? MAX_IP_STR_LEN : 46) - proto_tree_add_item(wccp_tree, hf_message_header_version, tvb, offset, 2, - ENC_BIG_ENDIAN); - offset += 2; - length = tvb_get_ntohs(tvb, offset); - length_item = proto_tree_add_uint(wccp_tree, hf_message_header_length, tvb, offset, 2, length); - offset += 2; +static const gchar * decode_wccp_encoded_address(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, + proto_tree *info_tree _U_, wccp_address_table* addr_table) +{ + gchar *buffer; + guint32 host_addr; - /* Is the length plus the length of the data preceding it longer than - the length of our packet? */ - wccp2_length = tvb_reported_length_remaining(tvb, offset); - if (length > (guint)wccp2_length) { - expert_add_info_format(pinfo, length_item, &ei_wccp_length_bad, - "The length as specified by the length field is bigger than the length of the packet"); - length = wccp2_length - offset; - } else { - /* Truncate the packet to the specified length. */ - tvb_set_reported_length(tvb, offset + length); - } - proto_item_set_len(wccp_tree_item, offset + length); - dissect_wccp2_info(tvb, offset, pinfo, wccp_tree, wccp_message_type); - break; - } + buffer= (char *) wmem_alloc(wmem_packet_scope(), WCCP_IP_MAX_LENGTH+1); + host_addr = tvb_get_ntohl(tvb,offset); - return tvb_captured_length(tvb); + wccp_fmt_ipaddress(buffer, host_addr, addr_table); + return buffer; } static guint @@ -878,312 +779,37 @@ wccp_bucket_info(guint8 bucket_info, proto_tree *bucket_tree, guint32 start, return(start); } -static void -dissect_wccp2_info(tvbuff_t *tvb, int offset, - packet_info *pinfo, proto_tree *wccp_tree, - guint32 message_type) -{ - int length_remaining; - guint16 type; - guint16 item_length; - proto_item *tf; - proto_tree *info_tree; - gint ett; - gint (*dissector)(tvbuff_t *, int, int, packet_info *, proto_tree *); - /* check if all required fields are there */ - gboolean wccp2_security_info; - gboolean wccp2_service_info; - gboolean wccp2_router_id_info; - gboolean wccp2_wc_id_info; - gboolean wccp2_rtr_view_info; - gboolean wccp2_wc_view_info; - gboolean wccp2_redirect_assignment; - gboolean wccp2_query_info; - gboolean wccp2_capabilities_info; - gboolean wccp2_alt_assignment; - gboolean wccp2_assign_map; - gboolean wccp2_command_extension; - gboolean wccp2r1_alt_assignment_map; +/* the following functions all need to check the length and the offset + so we have a few macros to use +*/ - wccp2_security_info=FALSE; - wccp2_service_info=FALSE; - wccp2_router_id_info=FALSE; - wccp2_wc_id_info=FALSE; - wccp2_rtr_view_info=FALSE; - wccp2_wc_view_info=FALSE; - wccp2_redirect_assignment=FALSE; - wccp2_query_info=FALSE; - wccp2_capabilities_info=FALSE; - wccp2_alt_assignment=FALSE; - wccp2_assign_map=FALSE; - wccp2_command_extension=FALSE; - wccp2r1_alt_assignment_map=FALSE; +#define EAT(x) {length -= x; offset += x;} - /* ugly hack: we first need to check for the address table - compnent, otherwise we cannot print the IP's. - */ - find_wccp_address_table(tvb,offset,pinfo,wccp_tree); +#define EAT_AND_CHECK(x,next) {length -= x; offset += x; if (length < next) return length - next;} - while ((length_remaining = tvb_reported_length_remaining(tvb, offset)) > 0) { - type = tvb_get_ntohs(tvb, offset); - switch (type) { +#define NOTE_EATEN_LENGTH(new_length) {if (new_length<0) return new_length; offset += length-new_length; length = new_length; } - case WCCP2_SECURITY_INFO: - wccp2_security_info=TRUE; - ett = ett_security_info; - dissector = dissect_wccp2_security_info; - break; - case WCCP2_SERVICE_INFO: - wccp2_service_info=TRUE; - ett = ett_service_info; - dissector = dissect_wccp2_service_info; - break; +/* 5.1.1 Security Info Component */ - case WCCP2_ROUTER_ID_INFO: - wccp2_router_id_info=TRUE; - ett = ett_router_identity_info; - dissector = dissect_wccp2_router_identity_info; - break; +/* Security options */ - case WCCP2_WC_ID_INFO: - wccp2_wc_id_info=TRUE; - ett = ett_wc_identity_info; - dissector = dissect_wccp2_wc_identity_info; - break; +#define WCCP2_NO_SECURITY 0 +#define WCCP2_MD5_SECURITY 1 - case WCCP2_RTR_VIEW_INFO: - wccp2_rtr_view_info=TRUE; - ett = ett_router_view_info; - dissector = dissect_wccp2_router_view_info; - break; +#define SECURITY_INFO_LEN 4 - case WCCP2_WC_VIEW_INFO: - wccp2_wc_view_info=TRUE; - ett = ett_wc_view_info; - dissector = dissect_wccp2_web_cache_view_info; - break; - - case WCCP2_REDIRECT_ASSIGNMENT: - wccp2_redirect_assignment=TRUE; - ett = ett_router_assignment_info; - dissector = dissect_wccp2_assignment_info; - break; - - case WCCP2_QUERY_INFO: - wccp2_query_info=TRUE; - ett = ett_query_info; - dissector = dissect_wccp2_router_query_info; - break; - - case WCCP2_CAPABILITIES_INFO: - wccp2_capabilities_info=TRUE; - ett = ett_capabilities_info; - dissector = dissect_wccp2_capability_info; - break; - - case WCCP2_ALT_ASSIGNMENT: - wccp2_alt_assignment=TRUE; - ett = ett_alt_assignment_info; - dissector = dissect_wccp2_alternate_assignment_info; - break; - - case WCCP2r1_ALT_ASSIGNMENT_MAP: - wccp2r1_alt_assignment_map=TRUE; - ett = ett_alt_assignment_map; - dissector = dissect_wccp2r1_alt_assignment_map_info; - break; - - case WCCP2r1_ADDRESS_TABLE: - ett = ett_address_table; - dissector = dissect_wccp2r1_address_table_info; - break; - - case WCCP2_ASSIGN_MAP: - wccp2_assign_map=TRUE; - ett = ett_assignment_map; - dissector = dissect_wccp2_assignment_map; - break; - case WCCP2_COMMAND_EXTENSION: - wccp2_command_extension=TRUE; - ett = ett_command_extension; - dissector = dissect_wccp2_command_extension; - break; - - default: - ett = ett_unknown_info; - dissector = NULL; - break; - } - - info_tree = proto_tree_add_subtree(wccp_tree, tvb, offset, -1, ett, &tf, - val_to_str(type, info_type_vals, "Unknown info type (%u)")); - - proto_tree_add_item(info_tree, hf_item_type, tvb, offset, 2, ENC_BIG_ENDIAN); - - item_length = tvb_get_ntohs(tvb, offset+2); - proto_tree_add_item(info_tree, hf_item_length, tvb, offset+2, 2, ENC_BIG_ENDIAN); - - offset += 4; - - if (dissector != NULL) { - gint remaining_item_length = (*dissector)(tvb, offset, item_length, pinfo, info_tree); - - /* warn if we left bytes */ - if (remaining_item_length > 0) - expert_add_info_format(pinfo, tf, &ei_wccp_length_bad, - "The item is %d bytes too long", - remaining_item_length); - - /* error if we needed more bytes */ - if (remaining_item_length < 0) - expert_add_info_format(pinfo, tf, &ei_wccp_length_bad, - "The item is %d bytes too short", - -remaining_item_length); - - /* we assume that the item length is correct and jump forward */ - } else { - proto_tree_add_item(info_tree, hf_item_data, tvb, offset, item_length, ENC_NA); - } - - offset += item_length; - proto_item_set_end(tf, tvb, offset); - } - - - /* we're done. Check if we got all the required components */ - - switch (message_type) { - case WCCP2_HERE_I_AM: - if (!wccp2_security_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); - if (!wccp2_service_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); - if (wccp2_router_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_router_id_info); - if (!wccp2_wc_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_wc_id_info); - if (wccp2_rtr_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_rtr_view_info); - if (!wccp2_wc_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_wc_view_info); - if (wccp2_redirect_assignment) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_redirect_assignment); - if (wccp2_query_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_query_info); - if (wccp2_alt_assignment) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment); - if (wccp2_assign_map) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_assign_map); - if (wccp2r1_alt_assignment_map) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment_map); - break; - case WCCP2_I_SEE_YOU: - if (!wccp2_security_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); - if (!wccp2_service_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); - if (!wccp2_router_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_router_id_info); - if (wccp2_wc_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_id_info); - if (!wccp2_rtr_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_rtr_view_info); - if (wccp2_wc_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_view_info); - if (wccp2_redirect_assignment) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_redirect_assignment); - if (wccp2_query_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_query_info); - if (wccp2r1_alt_assignment_map) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment_map); - break; - - case WCCP2_REMOVAL_QUERY: - if (!wccp2_security_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); - if (!wccp2_service_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); - if (wccp2_router_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_router_id_info); - if (wccp2_wc_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_id_info); - if (wccp2_rtr_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_rtr_view_info); - if (wccp2_wc_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_view_info); - if (wccp2_redirect_assignment) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_redirect_assignment); - if (!wccp2_query_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_query_info); - if (wccp2_capabilities_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_capabilities_info); - if (wccp2_alt_assignment) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment); - if (wccp2_assign_map) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_assign_map); - if (wccp2_command_extension) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_command_extension); - if (wccp2r1_alt_assignment_map) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment_map); - break; - - case WCCP2_REDIRECT_ASSIGN: - if (!wccp2_security_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); - if (!wccp2_service_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); - if (wccp2_router_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_router_id_info); - if (wccp2_wc_id_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_id_info); - if (wccp2_rtr_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_rtr_view_info); - if (wccp2_wc_view_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_view_info); - if (wccp2_query_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_query_info); - if (wccp2_capabilities_info) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_capabilities_info); - if (! (wccp2_assign_map || wccp2r1_alt_assignment_map || wccp2_alt_assignment || wccp2_redirect_assignment)) - expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_assignment); - if (wccp2_command_extension) - expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_command_extension); - break; - } -} - -/* the following functions all need to check the length and the offset - so we have a few macros to use -*/ - -#define EAT(x) {length -= x; offset += x;} - -#define EAT_AND_CHECK(x,next) {length -= x; offset += x; if (length < next) return length - next;} - -#define NOTE_EATEN_LENGTH(new_length) {if (new_length<0) return new_length; offset += length-new_length; length = new_length; } - - -/* 5.1.1 Security Info Component */ - -/* Security options */ - -#define WCCP2_NO_SECURITY 0 -#define WCCP2_MD5_SECURITY 1 - -#define SECURITY_INFO_LEN 4 - -const value_string security_option_vals[] = { - { WCCP2_NO_SECURITY, "None" }, - { WCCP2_MD5_SECURITY, "MD5" }, - { 0, NULL } -}; +const value_string security_option_vals[] = { + { WCCP2_NO_SECURITY, "None" }, + { WCCP2_MD5_SECURITY, "MD5" }, + { 0, NULL } +}; static gint dissect_wccp2_security_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree) + packet_info *pinfo _U_, proto_tree *info_tree, wccp_address_table* addr_table _U_) { guint32 security_option; @@ -1235,7 +861,7 @@ const value_string service_type_vals[] = { static gint dissect_wccp2_service_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table _U_) { guint8 service_type; guint32 flags; @@ -1332,12 +958,12 @@ dissect_wccp2_service_info(tvbuff_t *tvb, int offset, gint length, /* 6.1 Router Identity Element */ static void dissect_wccp2_router_identity_element(tvbuff_t *tvb, int offset, packet_info *pinfo, - proto_tree *tree) + proto_tree *tree, wccp_address_table* addr_table) { proto_item *tf; - proto_tree_add_item(tree, hf_router_identity_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(tree, hf_router_identity_ip_index, hf_router_identity_ipv4, hf_router_identity_ipv6, tvb, offset, 4, addr_table); tf = proto_tree_add_item(tree, hf_router_identity_receive_id, tvb, offset+4, 4, ENC_BIG_ENDIAN); if (tvb_get_ntohl(tvb, offset + 4) == 0) @@ -1349,7 +975,7 @@ dissect_wccp2_router_identity_element(tvbuff_t *tvb, int offset, packet_info *pi /* 5.3.1 Router Identity Info Component */ static gint dissect_wccp2_router_identity_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { guint32 n_received_from; guint i; @@ -1360,15 +986,14 @@ dissect_wccp2_router_identity_info(tvbuff_t *tvb, int offset, gint length, return length - ROUTER_ID_INFO_MIN_LEN; - te = proto_tree_add_item(info_tree, hf_router_identity_router_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + te = wccp_add_ipaddress_item(info_tree, hf_router_identity_router_ip_index, hf_router_identity_router_ipv4, hf_router_identity_router_ipv6, tvb, offset, 4, addr_table); element_tree = proto_item_add_subtree(te,ett_wc_view_info_router_element); - dissect_wccp2_router_identity_element(tvb,offset,pinfo,element_tree); + dissect_wccp2_router_identity_element(tvb,offset,pinfo,element_tree, addr_table); EAT_AND_CHECK(8,4); - - proto_tree_add_item(info_tree, hf_router_identity_send_to_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_router_identity_send_to_ip_index, hf_router_identity_send_to_ipv4, hf_router_identity_send_to_ipv6, tvb, offset, 4, addr_table); EAT_AND_CHECK(4,4); n_received_from = tvb_get_ntohl(tvb, offset); @@ -1380,7 +1005,7 @@ dissect_wccp2_router_identity_info(tvbuff_t *tvb, int offset, gint length, return length-4*(i-n_received_from); - proto_tree_add_item(info_tree, hf_router_identity_received_from_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_router_identity_received_from_ip_index, hf_router_identity_received_from_ipv4, hf_router_identity_received_from_ipv6, tvb, offset, 4, addr_table); EAT(4); } @@ -1392,7 +1017,7 @@ dissect_wccp2_router_identity_info(tvbuff_t *tvb, int offset, gint length, /* 6.4 Web-Cache Identity Element */ static gint dissect_wccp2_web_cache_identity_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree) + proto_tree *info_tree, wccp_address_table* addr_table) { proto_item *tf; guint16 flags; @@ -1409,7 +1034,7 @@ dissect_wccp2_web_cache_identity_element(tvbuff_t *tvb, int offset, gint length, if (length < ROUTER_WC_ID_ELEMENT_MIN_LEN) return length - ROUTER_WC_ID_ELEMENT_MIN_LEN; - proto_tree_add_item(info_tree, hf_web_cache_identity_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_web_cache_identity_index, hf_web_cache_identity_ipv4, hf_web_cache_identity_ipv6, tvb, offset, 4, addr_table); EAT_AND_CHECK(4,2); tf = proto_tree_add_item(info_tree, hf_web_cache_identity_hash_rev, tvb, offset, 2, ENC_BIG_ENDIAN); @@ -1428,14 +1053,14 @@ dissect_wccp2_web_cache_identity_element(tvbuff_t *tvb, int offset, gint length, case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_HASH: return dissect_wccp2_hash_assignment_data_element(tvb,offset,length,pinfo,info_tree); case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_MASK: - return dissect_wccp2_mask_assignment_data_element(tvb,offset,length,pinfo,info_tree); + return dissect_wccp2_mask_assignment_data_element(tvb,offset,length,pinfo,info_tree, addr_table); case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_NOT_PRESENT: proto_tree_add_item(info_tree, hf_assignment_no_data, tvb, offset, 2, ENC_NA); return length; break; case WCCP2_WEB_CACHE_ASSIGNMENT_DATA_TYPE_EXTENDED: - return dissect_wccp2_extended_assignment_data_element(tvb,offset,length,pinfo,info_tree); + return dissect_wccp2_extended_assignment_data_element(tvb,offset,length,pinfo,info_tree, addr_table); } return length; } @@ -1443,29 +1068,29 @@ dissect_wccp2_web_cache_identity_element(tvbuff_t *tvb, int offset, gint length, /* 5.2.1 Web-Cache Identity Info Component */ static gint dissect_wccp2_wc_identity_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree) + packet_info *pinfo _U_, proto_tree *info_tree, wccp_address_table* addr_table) { proto_item *te; proto_tree *element_tree; - - te = proto_tree_add_item(info_tree, hf_wc_identity_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN); + te = wccp_add_ipaddress_item(info_tree, hf_wc_identity_ip_address_index, hf_wc_identity_ip_address_ipv4, hf_wc_identity_ip_address_ipv6, + tvb, offset, 4, addr_table); element_tree = proto_item_add_subtree(te, ett_wc_identity_element); return dissect_wccp2_web_cache_identity_element(tvb, offset,length, pinfo, - element_tree); + element_tree, addr_table); } /* 6.3 Assignment Key Element */ static gint dissect_wccp2_assignment_key_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo _U_, - proto_tree *info_tree) + proto_tree *info_tree, wccp_address_table* addr_table) { if (length < 8) return length -8; - proto_tree_add_item(info_tree, hf_assignment_key_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_assignment_key_ip_index, hf_assignment_key_ipv4, hf_assignment_key_ipv6, tvb, offset, 4, addr_table); EAT_AND_CHECK(4,4); proto_tree_add_item(info_tree, hf_assignment_key_change_num, tvb, offset, 4, ENC_BIG_ENDIAN); @@ -1480,7 +1105,7 @@ dissect_wccp2_assignment_key_element(tvbuff_t *tvb, int offset, gint length, pac /* 5.3.2 Router View Info Component */ static gint dissect_wccp2_router_view_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { guint32 n_routers; guint32 n_web_caches; @@ -1495,7 +1120,7 @@ dissect_wccp2_router_view_info(tvbuff_t *tvb, int offset, gint length, proto_tree_add_item(info_tree, hf_router_view_member_change_num, tvb, offset, 4, ENC_BIG_ENDIAN); EAT(4); - new_length=dissect_wccp2_assignment_key_element(tvb, offset, length, pinfo, info_tree); + new_length=dissect_wccp2_assignment_key_element(tvb, offset, length, pinfo, info_tree, addr_table); NOTE_EATEN_LENGTH(new_length); n_routers = tvb_get_ntohl(tvb, offset); @@ -1506,7 +1131,7 @@ dissect_wccp2_router_view_info(tvbuff_t *tvb, int offset, gint length, if (length < 4) return length - (n_routers-i)*4 - 4; - proto_tree_add_item(info_tree, hf_router_view_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_router_view_ip_index, hf_router_view_ipv4, hf_router_view_ipv6, tvb, offset, 4, addr_table); EAT(4); } @@ -1524,12 +1149,12 @@ dissect_wccp2_router_view_info(tvbuff_t *tvb, int offset, gint length, if (length < 4) return length - 4*(n_web_caches-i); - te = proto_tree_add_item(info_tree, hf_router_query_info_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + te = wccp_add_ipaddress_item(info_tree, hf_router_query_info_ip_index, hf_router_query_info_ipv4, hf_router_query_info_ipv6, tvb, offset, 4, addr_table); element_tree = proto_item_add_subtree(te, ett_wc_identity_element); length = dissect_wccp2_web_cache_identity_element(tvb, offset, length, pinfo, - element_tree); + element_tree, addr_table); if (length < 0) return length; @@ -1544,7 +1169,7 @@ dissect_wccp2_router_view_info(tvbuff_t *tvb, int offset, gint length, static gint dissect_wccp2_web_cache_view_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { guint32 n_routers; guint32 n_web_caches; @@ -1568,12 +1193,12 @@ dissect_wccp2_web_cache_view_info(tvbuff_t *tvb, int offset, gint length, if (length < 8) return length -8 * (n_routers-i) - 4; - te = proto_tree_add_item(info_tree, hf_wc_view_info_router_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + te = wccp_add_ipaddress_item(info_tree, hf_wc_view_info_router_ip_index, hf_wc_view_info_router_ipv4, hf_wc_view_info_router_ipv6, tvb, offset, 4, addr_table); /* also include the receive id in the object */ proto_item_set_len(te, 8); element_tree = proto_item_add_subtree(te,ett_wc_view_info_router_element); - dissect_wccp2_router_identity_element(tvb, offset, pinfo, element_tree); + dissect_wccp2_router_identity_element(tvb, offset, pinfo, element_tree, addr_table); EAT(8); } @@ -1588,7 +1213,7 @@ dissect_wccp2_web_cache_view_info(tvbuff_t *tvb, int offset, gint length, if (length < 4) return length - 4*(n_web_caches-i); - proto_tree_add_item(info_tree, hf_wc_view_info_wc_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_wc_view_info_wc_ip_index, hf_wc_view_info_wc_ipv4, hf_wc_view_info_wc_ipv6, tvb, offset, 4, addr_table); EAT(4); } return length; @@ -1597,9 +1222,9 @@ dissect_wccp2_web_cache_view_info(tvbuff_t *tvb, int offset, gint length, /* 6.2 Router Assignment Element */ static void dissect_wccp2_router_assignment_element(tvbuff_t *tvb, int offset, - gint length, packet_info *pinfo, proto_tree *info_tree) + gint length, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { - dissect_wccp2_router_identity_element(tvb,offset,pinfo,info_tree); + dissect_wccp2_router_identity_element(tvb,offset,pinfo,info_tree, addr_table); EAT(8); proto_tree_add_item(info_tree, hf_router_assignment_element_change_num, tvb, offset, 4, ENC_BIG_ENDIAN); EAT(4); @@ -1624,7 +1249,7 @@ assignment_bucket_name(guint8 bucket) /* 5.4.1 Assignment Info Component */ static gint dissect_wccp2_assignment_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { guint32 n_routers; guint i; @@ -1636,7 +1261,7 @@ dissect_wccp2_assignment_info(tvbuff_t *tvb, int offset, gint length, return length - ASSIGNMENT_INFO_MIN_LEN; - new_length=dissect_wccp2_assignment_key_element(tvb, offset, length, pinfo, info_tree); + new_length=dissect_wccp2_assignment_key_element(tvb, offset, length, pinfo, info_tree, addr_table); NOTE_EATEN_LENGTH(new_length); n_routers = tvb_get_ntohl(tvb, offset); @@ -1647,15 +1272,15 @@ dissect_wccp2_assignment_info(tvbuff_t *tvb, int offset, gint length, if (length < 12) return length - 12*(n_routers-i)-4-256; - te = proto_tree_add_item(info_tree, hf_assignment_info_router_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + te = wccp_add_ipaddress_item(info_tree, hf_assignment_info_router_ip_index, hf_assignment_info_router_ipv4, hf_assignment_info_router_ipv6, tvb, offset, 4, addr_table); element_tree = proto_item_add_subtree(te, ett_router_assignment_element); dissect_wccp2_router_assignment_element(tvb, offset, length , pinfo, - element_tree); + element_tree, addr_table); EAT(12); } - new_length = dissect_wccp2_hash_buckets_assignment_element(tvb, offset, length, pinfo, info_tree); + new_length = dissect_wccp2_hash_buckets_assignment_element(tvb, offset, length, pinfo, info_tree, addr_table); NOTE_EATEN_LENGTH(new_length); return length; } @@ -1666,17 +1291,17 @@ dissect_wccp2_assignment_info(tvbuff_t *tvb, int offset, gint length, /* 5.5.1 Router Query Info Component */ static gboolean dissect_wccp2_router_query_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { if (length < QUERY_INFO_LEN) return length - QUERY_INFO_LEN; - dissect_wccp2_router_identity_element(tvb,offset,pinfo,info_tree); + dissect_wccp2_router_identity_element(tvb,offset,pinfo,info_tree, addr_table); EAT_AND_CHECK(8,4); - proto_tree_add_item(info_tree, hf_router_query_info_send_to_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_router_query_info_send_to_ip_index, hf_router_query_info_send_to_ipv4, hf_router_query_info_send_to_ipv6, tvb, offset, 4, addr_table); EAT_AND_CHECK(4,4); - proto_tree_add_item(info_tree, hf_router_query_info_target_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + wccp_add_ipaddress_item(info_tree, hf_router_query_info_target_ip_index, hf_router_query_info_target_ipv4, hf_router_query_info_target_ipv6, tvb, offset, 4, addr_table); EAT(4); return length; @@ -1684,7 +1309,7 @@ dissect_wccp2_router_query_info(tvbuff_t *tvb, int offset, gint length, /* 6.5 Hash Buckets Assignment Element */ static gint dissect_wccp2_hash_buckets_assignment_element(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo _U_, proto_tree *info_tree) + packet_info *pinfo _U_, proto_tree *info_tree, wccp_address_table* addr_table) { guint32 i,n_web_caches; proto_item *te; @@ -1704,7 +1329,7 @@ static gint dissect_wccp2_hash_buckets_assignment_element(tvbuff_t *tvb, int off if (length < 4) return length - 4*(n_web_caches-i)-256; - l_te = proto_tree_add_item(element_tree, hf_hash_buckets_assignment_wc_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + l_te = wccp_add_ipaddress_item(info_tree, hf_hash_buckets_assignment_wc_ip_index, hf_hash_buckets_assignment_wc_ipv4, hf_hash_buckets_assignment_wc_ipv6, tvb, offset, 4, addr_table); proto_item_append_text(l_te, " id: %d", i); EAT(4); @@ -1766,7 +1391,7 @@ static const value_string wccp_command_type_vals[] = { static gint dissect_wccp2_capability_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table _U_) { gint capability_length; @@ -1785,7 +1410,7 @@ dissect_wccp2_capability_info(tvbuff_t *tvb, int offset, gint length, static gint dissect_wccp2_command_extension(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo _U_, proto_tree *info_tree) + int length, packet_info *pinfo _U_, proto_tree *info_tree, wccp_address_table* addr_table) { guint16 command_type; guint32 command_length; @@ -1810,7 +1435,8 @@ dissect_wccp2_command_extension(tvbuff_t *tvb, int offset, (command_length == 4)) { if (length < 4) return length - 4; - proto_tree_add_item(info_tree, hf_command_element_shutdown_ip, tvb, offset, 4, ENC_BIG_ENDIAN); + + wccp_add_ipaddress_item(info_tree, hf_command_element_shutdown_ip_index, hf_command_element_shutdown_ipv4, hf_command_element_shutdown_ipv6, tvb, offset, 4, addr_table); } else { if (length < (int)command_length) return length - command_length; @@ -1828,7 +1454,7 @@ dissect_wccp2_command_extension(tvbuff_t *tvb, int offset, */ static gint dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, int length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* wccp_wccp_address_table) { guint16 address_length; guint32 i; @@ -1853,16 +1479,16 @@ dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, int length, element_tree = proto_item_add_subtree(tf, ett_table_element); EAT(4); - if (wccp_wccp_address_table.in_use == FALSE) { - wccp_wccp_address_table.family = family; - wccp_wccp_address_table.table_length = table_length; + if (wccp_wccp_address_table->in_use == FALSE) { + wccp_wccp_address_table->family = family; + wccp_wccp_address_table->table_length = table_length; /* check if the length is valid and allocate the tables if needed */ - switch (wccp_wccp_address_table.family) { + switch (wccp_wccp_address_table->family) { case 1: - if (wccp_wccp_address_table.table_ipv4 == NULL) - wccp_wccp_address_table.table_ipv4 = (guint32 *) - wmem_alloc0(pinfo->pool, wccp_wccp_address_table.table_length * 4); + if (wccp_wccp_address_table->table_ipv4 == NULL) + wccp_wccp_address_table->table_ipv4 = (guint32 *) + wmem_alloc0(pinfo->pool, wccp_wccp_address_table->table_length * 4); if (address_length != 4) { expert_add_info_format(pinfo, tf, &ei_wccp_length_bad, "The Address length must be 4, but I found %d for IPv4 addresses. Correcting this.", @@ -1871,9 +1497,9 @@ dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, int length, } break; case 2: - if (wccp_wccp_address_table.table_ipv6 == NULL) - wccp_wccp_address_table.table_ipv6 = (struct e_in6_addr *) - wmem_alloc0(pinfo->pool, wccp_wccp_address_table.table_length * sizeof(struct e_in6_addr)); + if (wccp_wccp_address_table->table_ipv6 == NULL) + wccp_wccp_address_table->table_ipv6 = (struct e_in6_addr *) + wmem_alloc0(pinfo->pool, wccp_wccp_address_table->table_length * sizeof(struct e_in6_addr)); if (address_length != 16) { expert_add_info_format(pinfo, tf, &ei_wccp_length_bad, "The Address length must be 16, but I found %d for IPv6 addresses. Correcting this.", @@ -1883,7 +1509,7 @@ dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, int length, break; default: expert_add_info_format(pinfo, tf, &ei_wccp_address_table_family_unknown, - "Unknown address family: %d", wccp_wccp_address_table.family); + "Unknown address family: %d", wccp_wccp_address_table->family); }; } @@ -1896,21 +1522,21 @@ dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, int length, case 1: /* IPv4 */ addr = tvb_ip_to_str(tvb, offset); - if ((wccp_wccp_address_table.in_use == FALSE) && - (wccp_wccp_address_table.table_ipv4 != NULL) && - ((address_length * i) < wccp_wccp_address_table.table_length)) - wccp_wccp_address_table.table_ipv4[i] = tvb_get_ntohl(tvb, offset); + if ((wccp_wccp_address_table->in_use == FALSE) && + (wccp_wccp_address_table->table_ipv4 != NULL) && + (i < wccp_wccp_address_table->table_length)) + wccp_wccp_address_table->table_ipv4[i] = tvb_get_ntohl(tvb, offset); break; case 2: /* IPv6 */ addr = tvb_ip6_to_str(tvb, offset); - if ((wccp_wccp_address_table.in_use == FALSE) && - (wccp_wccp_address_table.table_ipv6 != NULL) && - (i < wccp_wccp_address_table.table_length)) - tvb_get_ipv6(tvb, offset, &(wccp_wccp_address_table.table_ipv6[i])); + if ((wccp_wccp_address_table->in_use == FALSE) && + (wccp_wccp_address_table->table_ipv6 != NULL) && + (i < wccp_wccp_address_table->table_length)) + tvb_get_ipv6(tvb, offset, &(wccp_wccp_address_table->table_ipv6[i])); break; default: - addr = wmem_strdup_printf(wmem_packet_scope(), "unknown family %d", wccp_wccp_address_table.family); + addr = wmem_strdup_printf(wmem_packet_scope(), "unknown family %d", wccp_wccp_address_table->family); }; if (element_tree) { @@ -1919,13 +1545,13 @@ dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, int length, pi = proto_tree_add_string_format_value(element_tree, hf_address_table_element, tvb, offset, address_length, addr, "%d: %s", i+1, addr); - if (i > wccp_wccp_address_table.table_length) + if (i > wccp_wccp_address_table->table_length) expert_add_info_format(pinfo, pi, &ei_wccp_length_bad, "Ran out of space to store address"); } EAT(address_length); } - wccp_wccp_address_table.in_use = TRUE; + wccp_wccp_address_table->in_use = TRUE; return length; } @@ -1938,7 +1564,7 @@ dissect_wccp2r1_address_table_info(tvbuff_t *tvb, int offset, int length, /* part of 5.6.11 Alternate Assignment Component */ static gint dissect_wccp2_hash_assignment_info(tvbuff_t *tvb, int offset, gint length, - packet_info *pinfo, proto_tree *info_tree) + packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { guint32 n_web_caches, host_addr; guint i; @@ -1956,7 +1582,7 @@ dissect_wccp2_hash_assignment_info(tvbuff_t *tvb, int offset, gint length, host_addr = tvb_get_ntohl(tvb,offset); proto_tree_add_uint_format(info_tree, hf_cache_ip, tvb, offset, 4, host_addr, "Web-Cache %d: IP address %s", i, - decode_wccp_encoded_address(tvb, offset, pinfo, info_tree)); + decode_wccp_encoded_address(tvb, offset, pinfo, info_tree, addr_table)); EAT(4); } @@ -1974,11 +1600,11 @@ dissect_wccp2_hash_assignment_info(tvbuff_t *tvb, int offset, gint length, /* 5.3.3 Assignment Map Component */ static gint dissect_wccp2_assignment_map(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo, proto_tree *info_tree) + int length, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { gint new_length; - new_length=dissect_wccp2_mask_value_set_list(tvb, offset, length, pinfo, info_tree); + new_length=dissect_wccp2_mask_value_set_list(tvb, offset, length, pinfo, info_tree, addr_table); NOTE_EATEN_LENGTH(new_length); @@ -1992,7 +1618,7 @@ static gint dissect_wccp2_assignment_map(tvbuff_t *tvb, int offset, /* 5.3.4 Alternate Assignment Map Component */ static gint dissect_wccp2r1_alt_assignment_map_info(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo, proto_tree *info_tree) + int length, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { guint16 assignment_type; guint16 assignment_length; @@ -2025,13 +1651,13 @@ dissect_wccp2r1_alt_assignment_map_info(tvbuff_t *tvb, int offset, switch (assignment_type) { case WCCP2_HASH_ASSIGNMENT_TYPE: return dissect_wccp2_assignment_info(tvb, offset, assignment_length, - pinfo, info_tree); + pinfo, info_tree, addr_table); case WCCP2_MASK_ASSIGNMENT_TYPE: return dissect_wccp2_mask_value_set_list(tvb, offset, assignment_length, - pinfo, info_tree); + pinfo, info_tree, addr_table); case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE: return dissect_wccp2_alternate_mask_value_set_list(tvb, offset, assignment_length, - pinfo, info_tree); + pinfo, info_tree, addr_table); default: return length; } @@ -2077,7 +1703,7 @@ dissect_wccp2_hash_assignment_data_element(tvbuff_t *tvb, int offset, gint lengt /* 6.7 Mask Assignment Data Element */ static gint dissect_wccp2_mask_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree) + proto_tree *info_tree, wccp_address_table* addr_table) { proto_item *mask_item; @@ -2089,7 +1715,7 @@ dissect_wccp2_mask_assignment_data_element(tvbuff_t *tvb, int offset, gint lengt ett_mask_assignment_data_element, &mask_item, "Mask Assignment Data"); start = offset; - new_length=dissect_wccp2_mask_value_set_list(tvb, offset, length, pinfo, mask_tree); + new_length=dissect_wccp2_mask_value_set_list(tvb, offset, length, pinfo, mask_tree, addr_table); NOTE_EATEN_LENGTH(new_length); @@ -2107,7 +1733,7 @@ dissect_wccp2_mask_assignment_data_element(tvbuff_t *tvb, int offset, gint lengt /* 5.7.5 Alternate Mask Assignment Data Element */ static gint dissect_wccp2_alternate_mask_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree) + proto_tree *info_tree, wccp_address_table* addr_table) { proto_tree *mask_tree; @@ -2122,7 +1748,7 @@ dissect_wccp2_alternate_mask_assignment_data_element(tvbuff_t *tvb, int offset, { gint new_length; - new_length=dissect_wccp2_alternate_mask_value_set_list(tvb, offset, length, pinfo, mask_tree); + new_length=dissect_wccp2_alternate_mask_value_set_list(tvb, offset, length, pinfo, mask_tree, addr_table); NOTE_EATEN_LENGTH(new_length); } @@ -2156,7 +1782,7 @@ dissect_wccp2_assignment_weight_and_status_element(tvbuff_t *tvb, int offset, gi /* 6.10 Extended Assignment Data Element */ static gint dissect_wccp2_extended_assignment_data_element(tvbuff_t *tvb, int offset, gint length, packet_info *pinfo, - proto_tree *info_tree) + proto_tree *info_tree, wccp_address_table* addr_table) { proto_item *element_item, *header; proto_tree *item_tree; @@ -2207,11 +1833,11 @@ dissect_wccp2_extended_assignment_data_element(tvbuff_t *tvb, int offset, gint l return length - assignment_length; case WCCP2_MASK_ASSIGNMENT_TYPE: dissect_wccp2_mask_assignment_data_element(tvb, offset, assignment_length, - pinfo, item_tree); + pinfo, item_tree, addr_table); return length - assignment_length; case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE: dissect_wccp2_alternate_mask_assignment_data_element(tvb, offset, assignment_length, - pinfo, item_tree); + pinfo, item_tree, addr_table); return length - assignment_length; case WCCP2r1_ASSIGNMENT_WEIGHT_STATUS: dissect_wccp2_assignment_weight_and_status_element(tvb, offset, assignment_length, @@ -2305,7 +1931,7 @@ dissect_wccp2_capability_element(tvbuff_t *tvb, int offset, gint length, /* 6.13 Mask/Value Set List */ static gint dissect_wccp2_mask_value_set_list(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo, proto_tree *info_tree) + int length, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { guint num_of_elem; guint i; @@ -2331,7 +1957,7 @@ dissect_wccp2_mask_value_set_list(tvbuff_t *tvb, int offset, { gint new_length; - new_length=dissect_wccp2_mask_value_set_element(tvb, offset, length, i, pinfo, element_tree); + new_length=dissect_wccp2_mask_value_set_element(tvb, offset, length, i, pinfo, element_tree, addr_table); NOTE_EATEN_LENGTH(new_length); } @@ -2371,7 +1997,7 @@ dissect_wccp2_mask_element(tvbuff_t *tvb, int offset, gint length, packet_info * /* 6.17 Alternate Mask/Value Set List */ static gint dissect_wccp2_alternate_mask_value_set_list(tvbuff_t *tvb, int offset, - int length, packet_info *pinfo, proto_tree *info_tree) + int length, packet_info *pinfo, proto_tree *info_tree, wccp_address_table* addr_table) { proto_tree *list_tree; guint num_of_val_elements; @@ -2390,7 +2016,7 @@ static gint dissect_wccp2_alternate_mask_value_set_list(tvbuff_t *tvb, int offse for(i=0;i assignment_length) { + expert_add_info_format(pinfo, tf, &ei_wccp_assignment_length_bad, + "Assignment length is %d but %d remain in the packet. Assuming that the assignment length is wrong and setting it to %d.", + assignment_length, length, length); + } + + new_length=dissect_wccp2_assignment_key_element(tvb, offset, length, pinfo, info_tree, addr_table); + NOTE_EATEN_LENGTH(new_length); + + n_routers = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(info_tree, hf_alt_assignment_info_num_routers, tvb, offset, 4, n_routers); + EAT(4); + + for (i = 0; i < n_routers; i++) { + if (length < 12) + return length - 12*(n_routers-i); + + element_tree = proto_tree_add_subtree_format(info_tree, tvb, offset, 12, + ett_router_alt_assignment_element, NULL, + "Router %d Assignment Element: IP address %s", i, + decode_wccp_encoded_address(tvb, offset, pinfo, info_tree, addr_table)); + + dissect_wccp2_router_assignment_element(tvb, offset, length , pinfo, element_tree, addr_table); + EAT(12); + } + + switch (assignment_type) { + case WCCP2_HASH_ASSIGNMENT_TYPE: + return dissect_wccp2_hash_assignment_info(tvb, offset, length, + pinfo, info_tree, addr_table); + case WCCP2_MASK_ASSIGNMENT_TYPE: + return dissect_wccp2_mask_value_set_list(tvb, offset, length, + pinfo, info_tree, addr_table); + case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE: + return dissect_wccp2_alternate_mask_value_set_list(tvb, offset, length, + pinfo, info_tree, addr_table); + default: + return length; + } +} + +static void +dissect_wccp2_info(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *wccp_tree, + guint32 message_type) +{ + int length_remaining; + guint16 type; + guint16 item_length; + proto_item *tf; + proto_tree *info_tree; + gint ett; + gint (*dissector)(tvbuff_t *, int, int, packet_info *, proto_tree *, wccp_address_table*); + + /* check if all required fields are there */ + gboolean wccp2_security_info; + gboolean wccp2_service_info; + gboolean wccp2_router_id_info; + gboolean wccp2_wc_id_info; + gboolean wccp2_rtr_view_info; + gboolean wccp2_wc_view_info; + gboolean wccp2_redirect_assignment; + gboolean wccp2_query_info; + gboolean wccp2_capabilities_info; + gboolean wccp2_alt_assignment; + gboolean wccp2_assign_map; + gboolean wccp2_command_extension; + gboolean wccp2r1_alt_assignment_map; + wccp_address_table wccp_wccp_address_table = {FALSE, -1, -1, 0, NULL, NULL}; + + wccp2_security_info=FALSE; + wccp2_service_info=FALSE; + wccp2_router_id_info=FALSE; + wccp2_wc_id_info=FALSE; + wccp2_rtr_view_info=FALSE; + wccp2_wc_view_info=FALSE; + wccp2_redirect_assignment=FALSE; + wccp2_query_info=FALSE; + wccp2_capabilities_info=FALSE; + wccp2_alt_assignment=FALSE; + wccp2_assign_map=FALSE; + wccp2_command_extension=FALSE; + wccp2r1_alt_assignment_map=FALSE; + + /* ugly hack: we first need to check for the address table + compnent, otherwise we cannot print the IP's. + */ + find_wccp_address_table(tvb,offset,pinfo,wccp_tree, &wccp_wccp_address_table); + + while ((length_remaining = tvb_reported_length_remaining(tvb, offset)) > 0) { + type = tvb_get_ntohs(tvb, offset); + switch (type) { + + case WCCP2_SECURITY_INFO: + wccp2_security_info=TRUE; + ett = ett_security_info; + dissector = dissect_wccp2_security_info; + break; + + case WCCP2_SERVICE_INFO: + wccp2_service_info=TRUE; + ett = ett_service_info; + dissector = dissect_wccp2_service_info; + break; + + case WCCP2_ROUTER_ID_INFO: + wccp2_router_id_info=TRUE; + ett = ett_router_identity_info; + dissector = dissect_wccp2_router_identity_info; + break; + + case WCCP2_WC_ID_INFO: + wccp2_wc_id_info=TRUE; + ett = ett_wc_identity_info; + dissector = dissect_wccp2_wc_identity_info; + break; + + case WCCP2_RTR_VIEW_INFO: + wccp2_rtr_view_info=TRUE; + ett = ett_router_view_info; + dissector = dissect_wccp2_router_view_info; + break; + + case WCCP2_WC_VIEW_INFO: + wccp2_wc_view_info=TRUE; + ett = ett_wc_view_info; + dissector = dissect_wccp2_web_cache_view_info; + break; + + case WCCP2_REDIRECT_ASSIGNMENT: + wccp2_redirect_assignment=TRUE; + ett = ett_router_assignment_info; + dissector = dissect_wccp2_assignment_info; + break; + + case WCCP2_QUERY_INFO: + wccp2_query_info=TRUE; + ett = ett_query_info; + dissector = dissect_wccp2_router_query_info; + break; + + case WCCP2_CAPABILITIES_INFO: + wccp2_capabilities_info=TRUE; + ett = ett_capabilities_info; + dissector = dissect_wccp2_capability_info; + break; + + case WCCP2_ALT_ASSIGNMENT: + wccp2_alt_assignment=TRUE; + ett = ett_alt_assignment_info; + dissector = dissect_wccp2_alternate_assignment_info; + break; + + case WCCP2r1_ALT_ASSIGNMENT_MAP: + wccp2r1_alt_assignment_map=TRUE; + ett = ett_alt_assignment_map; + dissector = dissect_wccp2r1_alt_assignment_map_info; + break; + + case WCCP2r1_ADDRESS_TABLE: + ett = ett_address_table; + dissector = dissect_wccp2r1_address_table_info; + break; + + case WCCP2_ASSIGN_MAP: + wccp2_assign_map=TRUE; + ett = ett_assignment_map; + dissector = dissect_wccp2_assignment_map; + break; + case WCCP2_COMMAND_EXTENSION: + wccp2_command_extension=TRUE; + ett = ett_command_extension; + dissector = dissect_wccp2_command_extension; + break; + + default: + ett = ett_unknown_info; + dissector = NULL; + break; + } + + info_tree = proto_tree_add_subtree(wccp_tree, tvb, offset, -1, ett, &tf, + val_to_str(type, info_type_vals, "Unknown info type (%u)")); + + proto_tree_add_item(info_tree, hf_item_type, tvb, offset, 2, ENC_BIG_ENDIAN); + + item_length = tvb_get_ntohs(tvb, offset+2); + proto_tree_add_item(info_tree, hf_item_length, tvb, offset+2, 2, ENC_BIG_ENDIAN); + + offset += 4; + + if (dissector != NULL) { + gint remaining_item_length = (*dissector)(tvb, offset, item_length, pinfo, info_tree, &wccp_wccp_address_table); + + /* warn if we left bytes */ + if (remaining_item_length > 0) + expert_add_info_format(pinfo, tf, &ei_wccp_length_bad, + "The item is %d bytes too long", + remaining_item_length); + + /* error if we needed more bytes */ + if (remaining_item_length < 0) + expert_add_info_format(pinfo, tf, &ei_wccp_length_bad, + "The item is %d bytes too short", + -remaining_item_length); + + /* we assume that the item length is correct and jump forward */ + } else { + proto_tree_add_item(info_tree, hf_item_data, tvb, offset, item_length, ENC_NA); + } + + offset += item_length; + proto_item_set_end(tf, tvb, offset); + } + + + /* we're done. Check if we got all the required components */ + + switch (message_type) { + case WCCP2_HERE_I_AM: + if (!wccp2_security_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); + if (!wccp2_service_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); + if (wccp2_router_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_router_id_info); + if (!wccp2_wc_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_wc_id_info); + if (wccp2_rtr_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_rtr_view_info); + if (!wccp2_wc_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_wc_view_info); + if (wccp2_redirect_assignment) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_redirect_assignment); + if (wccp2_query_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_query_info); + if (wccp2_alt_assignment) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment); + if (wccp2_assign_map) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_assign_map); + if (wccp2r1_alt_assignment_map) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment_map); + break; + case WCCP2_I_SEE_YOU: + if (!wccp2_security_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); + if (!wccp2_service_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); + if (!wccp2_router_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_router_id_info); + if (wccp2_wc_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_id_info); + if (!wccp2_rtr_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_rtr_view_info); + if (wccp2_wc_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_view_info); + if (wccp2_redirect_assignment) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_redirect_assignment); + if (wccp2_query_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_query_info); + if (wccp2r1_alt_assignment_map) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment_map); + break; + + case WCCP2_REMOVAL_QUERY: + if (!wccp2_security_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); + if (!wccp2_service_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); + if (wccp2_router_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_router_id_info); + if (wccp2_wc_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_id_info); + if (wccp2_rtr_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_rtr_view_info); + if (wccp2_wc_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_view_info); + if (wccp2_redirect_assignment) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_redirect_assignment); + if (!wccp2_query_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_query_info); + if (wccp2_capabilities_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_capabilities_info); + if (wccp2_alt_assignment) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment); + if (wccp2_assign_map) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_assign_map); + if (wccp2_command_extension) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_command_extension); + if (wccp2r1_alt_assignment_map) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_alt_assignment_map); + break; + + case WCCP2_REDIRECT_ASSIGN: + if (!wccp2_security_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_security_info); + if (!wccp2_service_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_service_info); + if (wccp2_router_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_router_id_info); + if (wccp2_wc_id_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_id_info); + if (wccp2_rtr_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_rtr_view_info); + if (wccp2_wc_view_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_wc_view_info); + if (wccp2_query_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_query_info); + if (wccp2_capabilities_info) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_capabilities_info); + if (! (wccp2_assign_map || wccp2r1_alt_assignment_map || wccp2_alt_assignment || wccp2_redirect_assignment)) + expert_add_info(pinfo, wccp_tree, &ei_wccp_missing_assignment); + if (wccp2_command_extension) + expert_add_info(pinfo, wccp_tree, &ei_wccp_contains_command_extension); + break; + } +} + +static int +dissect_wccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - guint16 assignment_type; - guint16 assignment_length; - proto_item *tf=NULL; - - guint32 n_routers; + int offset = 0; + proto_tree *wccp_tree = NULL; + proto_item *wccp_tree_item; + guint32 wccp_message_type; + guint16 length; + gint wccp2_length; + proto_item *length_item; + guint32 cache_count; + guint32 ipaddr; guint i; - proto_tree *element_tree; - gint new_length; + guint8 bucket; + wccp_message_type = tvb_get_ntohl(tvb, offset); - if (length < ALT_ASSIGNMENT_INFO_MIN_LEN) - return length - ALT_ASSIGNMENT_INFO_MIN_LEN; + /* Check if this is really a WCCP message */ + if (try_val_to_str(wccp_message_type, wccp_type_vals) == NULL) + return 0; + col_set_str(pinfo->cinfo, COL_PROTOCOL, "WCCP"); - assignment_type = tvb_get_ntohs(tvb, offset); - proto_tree_add_item(info_tree, hf_alt_assignment_info_assignment_type, tvb, offset, 2, ENC_BIG_ENDIAN); - EAT_AND_CHECK(2,2); + col_add_str(pinfo->cinfo, COL_INFO, val_to_str(wccp_message_type, + wccp_type_vals, "Unknown WCCP message (%u)")); - assignment_length = tvb_get_ntohs(tvb, offset); - tf=proto_tree_add_item(info_tree, hf_alt_assignment_info_assignment_length, tvb, offset, 2, ENC_BIG_ENDIAN); - EAT(2); + wccp_tree_item = proto_tree_add_item(tree, proto_wccp, tvb, offset, -1, ENC_NA); + wccp_tree = proto_item_add_subtree(wccp_tree_item, ett_wccp); - if (length < assignment_length) - expert_add_info_format(pinfo, tf, &ei_wccp_assignment_length_bad, - "Assignment length is %d but only %d remain in the packet. Ignoring this for now", - assignment_length, length); + proto_tree_add_uint(wccp_tree, hf_wccp_message_type, tvb, offset, 4, wccp_message_type); + offset += 4; - if (length > assignment_length) { - expert_add_info_format(pinfo, tf, &ei_wccp_assignment_length_bad, - "Assignment length is %d but %d remain in the packet. Assuming that the assignment length is wrong and setting it to %d.", - assignment_length, length, length); - } + switch (wccp_message_type) { - new_length=dissect_wccp2_assignment_key_element(tvb, offset, length, pinfo, info_tree); - NOTE_EATEN_LENGTH(new_length); + case WCCP_HERE_I_AM: + proto_tree_add_item(wccp_tree, hf_wccp_version, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset += 4; + offset = dissect_hash_data(tvb, offset, wccp_tree); + proto_tree_add_item(wccp_tree, hf_recvd_id, tvb, offset, + 4, ENC_BIG_ENDIAN); + /*offset += 4;*/ + break; - n_routers = tvb_get_ntohl(tvb, offset); - proto_tree_add_uint(info_tree, hf_alt_assignment_info_num_routers, tvb, offset, 4, n_routers); - EAT(4); + case WCCP_I_SEE_YOU: + proto_tree_add_item(wccp_tree, hf_wccp_version, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(wccp_tree, hf_change_num, tvb, offset, + 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(wccp_tree, hf_recvd_id, tvb, offset, + 4, ENC_BIG_ENDIAN); + offset += 4; + cache_count = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(wccp_tree, hf_wc_num, tvb, offset, 4, cache_count); + offset += 4; + for (i = 0; i < cache_count; i++) { + offset = dissect_web_cache_list_entry(tvb, offset, i, + wccp_tree); + } + break; - for (i = 0; i < n_routers; i++) { - if (length < 12) - return length - 12*(n_routers-i); + case WCCP_ASSIGN_BUCKET: + /* + * This hasn't been tested, since I don't have any + * traces with this in it. + * + * The V1 spec claims that this does, indeed, + * have a Received ID field after the type, + * rather than a Version field. + */ + proto_tree_add_item(wccp_tree, hf_recvd_id, tvb, offset, + 4, ENC_BIG_ENDIAN); + offset += 4; + cache_count = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint(wccp_tree, hf_wc_num, tvb, offset, 4, cache_count); + offset += 4; + for (i = 0; i < cache_count; i++) { + ipaddr = tvb_get_ipv4(tvb, offset); + proto_tree_add_ipv4_format(wccp_tree, + hf_cache_ip, tvb, offset, 4, + ipaddr, + "Web Cache %d IP Address: %s", i, + tvb_ip_to_str(tvb, offset)); + offset += 4; + } - element_tree = proto_tree_add_subtree_format(info_tree, tvb, offset, 12, - ett_router_alt_assignment_element, NULL, - "Router %d Assignment Element: IP address %s", i, - decode_wccp_encoded_address(tvb, offset, pinfo, info_tree)); + for (i = 0; i < 256; i++) { + bucket = tvb_get_guint8(tvb, offset); + if (bucket == 0xff) { + proto_tree_add_uint_format(wccp_tree, hf_bucket, tvb, offset, 1, + bucket, "Bucket %d: Unassigned", i); + } else { + proto_tree_add_uint_format(wccp_tree, hf_bucket, tvb, offset, 1, + bucket, "Bucket %d: %d", i, bucket); + } + offset++; + } + break; - dissect_wccp2_router_assignment_element(tvb, offset, length , pinfo, element_tree); - EAT(12); - } + case WCCP2_HERE_I_AM: + case WCCP2_I_SEE_YOU: + case WCCP2_REMOVAL_QUERY: + case WCCP2_REDIRECT_ASSIGN: + default: /* assume unknown packets are v2 */ + /* 5.5 WCCP Message Header */ - switch (assignment_type) { - case WCCP2_HASH_ASSIGNMENT_TYPE: - return dissect_wccp2_hash_assignment_info(tvb, offset, length, - pinfo, info_tree); - case WCCP2_MASK_ASSIGNMENT_TYPE: - return dissect_wccp2_mask_value_set_list(tvb, offset, length, - pinfo, info_tree); - case WCCP2r1_ALT_MASK_ASSIGNMENT_TYPE: - return dissect_wccp2_alternate_mask_value_set_list(tvb, offset, length, - pinfo, info_tree); - default: - return length; + proto_tree_add_item(wccp_tree, hf_message_header_version, tvb, offset, 2, + ENC_BIG_ENDIAN); + offset += 2; + + length = tvb_get_ntohs(tvb, offset); + length_item = proto_tree_add_uint(wccp_tree, hf_message_header_length, tvb, offset, 2, length); + offset += 2; + + /* Is the length plus the length of the data preceding it longer than + the length of our packet? */ + wccp2_length = tvb_reported_length_remaining(tvb, offset); + if (length > (guint)wccp2_length) { + expert_add_info_format(pinfo, length_item, &ei_wccp_length_bad, + "The length as specified by the length field is bigger than the length of the packet"); + length = wccp2_length - offset; + } else { + /* Truncate the packet to the specified length. */ + tvb_set_reported_length(tvb, offset + length); + } + proto_item_set_len(wccp_tree_item, offset + length); + dissect_wccp2_info(tvb, offset, pinfo, wccp_tree, wccp_message_type); + break; } -} + return tvb_captured_length(tvb); +} @@ -2845,8 +2884,16 @@ proto_register_wccp(void) {"Command Length", "wccp.command_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_command_element_shutdown_ip, - {"Command Extension Length", "wccp.command_element_shudown_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_command_element_shutdown_ip_index, + {"Command Element Shutdown IP", "wccp.command_element_shudown_ip_Address.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_command_element_shutdown_ipv4, + {"Command Element Shutdown IP", "wccp.command_element_shudown_ip_address.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_command_element_shutdown_ipv6, + {"Command Element Shutdown IP", "wccp.command_element_shudown_ip_address.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_command_unknown, @@ -2933,24 +2980,48 @@ proto_register_wccp(void) { "Destination Port", "wccp.service_info_destination_port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_router_identity_ip, - { "IP Address", "wccp.router_identity.ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_identity_ip_index, + { "IP Address", "wccp.router_identity.ip_address.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_ipv4, + { "IP Address", "wccp.router_identity.ip_address.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_ipv6, + { "IP Address", "wccp.router_identity.ip_address.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_router_identity_receive_id, { "Received ID", "wccp.router_identity.receive_id", FT_UINT32, BASE_DEC, 0x0, 0x0, NULL, HFILL } }, - { &hf_router_identity_send_to_ip, - { "Sent To IP Address", "wccp.router_identity.send_to_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_identity_send_to_ip_index, + { "Sent To IP Address", "wccp.router_identity.send_to_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_send_to_ipv4, + { "Sent To IP Address", "wccp.router_identity.send_to_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_send_to_ipv6, + { "Sent To IP Address", "wccp.router_identity.send_to_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_router_identity_received_from_num, { "Number of Received From IP addresses (Webcache to which the message is directed)", "wccp.router.num_recv_ip", FT_UINT32, BASE_DEC, 0x0, 0x0, NULL, HFILL } }, - { &hf_web_cache_identity_ip, - { "Web-Cache IP Address", "wccp.web_cache_identity.ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_web_cache_identity_index, + { "Web-Cache IP Address", "wccp.web_cache_identity.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_web_cache_identity_ipv4, + { "Web-Cache IP Address", "wccp.web_cache_identity.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_web_cache_identity_ipv6, + { "Web-Cache IP Address", "wccp.web_cache_identity.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_web_cache_identity_hash_rev, @@ -2993,8 +3064,16 @@ proto_register_wccp(void) { "Status", "wccp.assignment_status", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, - { &hf_assignment_key_ip, - { "Assignment Key IP Address", "wccp.assignment_key.ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_assignment_key_ip_index, + { "Assignment Key IP Address", "wccp.assignment_key.ip_index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_assignment_key_ipv4, + { "Assignment Key IP Address", "wccp.assignment_key.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_assignment_key_ipv6, + { "Assignment Key IP Address", "wccp.assignment_key.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_assignment_key_change_num, @@ -3013,24 +3092,56 @@ proto_register_wccp(void) { "Number of Routers", "wccp.router_view.router_num", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_router_identity_router_ip, - { "Router IP Address", "wccp.router_identity.router_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_identity_router_ip_index, + { "Router IP Address", "wccp.router_identity.router_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_router_ipv4, + { "Router IP Address", "wccp.router_identity.router_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_router_ipv6, + { "Router IP Address", "wccp.router_identity.router_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_router_identity_received_from_ip, - { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_identity_received_from_ip_index, + { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_received_from_ipv4, + { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_identity_received_from_ipv6, + { "Received From IP Address/Target Web Cache IP", "wccp.router_identity.received_from_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_wc_view_info_change_num, { "Change Number", "wccp.wc_view_info.change_num", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_wc_view_info_router_ip, - { "Router IP", "wccp.wc_view_info.router_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_wc_view_info_router_ip_index, + { "Router IP", "wccp.wc_view_info.router_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_wc_view_info_router_ipv4, + { "Router IP", "wccp.wc_view_info.router_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_wc_view_info_router_ipv6, + { "Router IP", "wccp.wc_view_info.router_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_wc_view_info_wc_ip, - { "Web Cache IP", "wccp.wc_view_info.wc_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_wc_view_info_wc_ip_index, + { "Web Cache IP", "wccp.wc_view_info.wc_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_wc_view_info_wc_ipv4, + { "Web Cache IP", "wccp.wc_view_info.wc_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_wc_view_info_wc_ipv6, + { "Web Cache IP", "wccp.wc_view_info.wc_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_wc_view_router_num, @@ -3041,8 +3152,16 @@ proto_register_wccp(void) { "Number of Web Caches", "wccp.wc_view_info.wc_num", FT_UINT32, BASE_DEC, 0x0, 0x0, NULL, HFILL } }, - { &hf_wc_identity_ip_address, - { "Web Cache Identity", "wccp.hf_wc_identity_ip_address", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_wc_identity_ip_address_index, + { "Web Cache Identity", "wccp.wc_identity_ip_address.index", FT_UINT32, BASE_HEX, NULL, 0x0, + "The IP identifying the Web Cache", HFILL } + }, + { &hf_wc_identity_ip_address_ipv4, + { "Web Cache Identity", "wccp.wc_identity_ip_address.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + "The IP identifying the Web Cache", HFILL } + }, + { &hf_wc_identity_ip_address_ipv6, + { "Web Cache Identity", "wccp.wc_identity_ip_address.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, "The IP identifying the Web Cache", HFILL } }, { &hf_router_assignment_element_change_num, @@ -3053,32 +3172,80 @@ proto_register_wccp(void) { "Number of Routers", "wccp.assignment_info.router_num", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_assignment_info_router_ip, - { "Router IP", "wccp.assignment_info.router_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_assignment_info_router_ip_index, + { "Router IP", "wccp.assignment_info.router_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_assignment_info_router_ipv4, + { "Router IP", "wccp.assignment_info.router_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_assignment_info_router_ipv6, + { "Router IP", "wccp.assignment_info.router_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_hash_buckets_assignment_wc_num, { "Number of WC", "wccp.hash_buckets_assignment.wc_num", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_hash_buckets_assignment_wc_ip, - { "WC IP", "wccp.hash_buckets_assignment.wc_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_hash_buckets_assignment_wc_ip_index, + { "WC IP", "wccp.hash_buckets_assignment.wc_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_hash_buckets_assignment_wc_ipv4, + { "WC IP", "wccp.hash_buckets_assignment.wc_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_hash_buckets_assignment_wc_ipv6, + { "WC IP", "wccp.hash_buckets_assignment.wc_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_router_view_ip, - { "Router IP Address", "wccp.router_view.ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_view_ip_index, + { "Router IP Address", "wccp.router_view.ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, - { &hf_router_query_info_ip, - { "Web-Cache Identity Element IP address", "wccp.router_query_info.ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_view_ipv4, + { "Router IP Address", "wccp.router_view.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_router_query_info_send_to_ip, - { "Sent To IP Address", "wccp.router_query_info.send_to_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_view_ipv6, + { "Router IP Address", "wccp.router_view.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_router_query_info_target_ip, - { "Target IP Address", "wccp.router_query_info.target_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_router_query_info_ip_index, + { "Web-Cache Identity Element IP address", "wccp.router_query_info.ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_ipv4, + { "Web-Cache Identity Element IP address", "wccp.router_query_info.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_ipv6, + { "Web-Cache Identity Element IP address", "wccp.router_query_info.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_send_to_ip_index, + { "Sent To IP Address", "wccp.router_query_info.send_to_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_send_to_ipv4, + { "Sent To IP Address", "wccp.router_query_info.send_to_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_send_to_ipv6, + { "Sent To IP Address", "wccp.router_query_info.send_to_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_target_ip_index, + { "Target IP Address", "wccp.router_query_info.target_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_target_ipv4, + { "Target IP Address", "wccp.router_query_info.target_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_router_query_info_target_ipv6, + { "Target IP Address", "wccp.router_query_info.target_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_capability_element_type, @@ -3161,12 +3328,28 @@ proto_register_wccp(void) { "Reserved, must be 0", "wccp.reserved_zero", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_value_element_src_ip, - { "Source Address", "wccp.value_element.src_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_value_element_src_ip_index, + { "Source Address", "wccp.value_element.src_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, - { &hf_value_element_dest_ip, - { "Destination Address", "wccp.value_element.dest_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_value_element_src_ipv4, + { "Source Address", "wccp.value_element.src_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_value_element_src_ipv6, + { "Source Address", "wccp.value_element.src_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_value_element_dest_ip_index, + { "Destination Address", "wccp.value_element.dest_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_value_element_dest_ipv4, + { "Destination Address", "wccp.value_element.dest_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_value_element_dest_ipv6, + { "Destination Address", "wccp.value_element.dest_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_value_element_src_port, @@ -3177,8 +3360,16 @@ proto_register_wccp(void) { "Destination Port", "wccp.value_element.dest_port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_value_element_web_cache_ip, - { "Web Cache Address", "wccp.value_element.web_cache_ip", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_value_element_web_cache_ip_index, + { "Web Cache Address", "wccp.value_element.web_cache_ip.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_value_element_web_cache_ipv4, + { "Web Cache Address", "wccp.value_element.web_cache_ip.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_value_element_web_cache_ipv6, + { "Web Cache Address", "wccp.value_element.web_cache_ip.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_mask_value_set_list_num_elements, @@ -3233,8 +3424,16 @@ proto_register_wccp(void) { "Number of Web-Cache Value Elements", "wccp.alt_assignment_mask_value_set_element.num_wc_value_elements", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_web_cache_value_element_wc_address, - { "Web-Cache Address", "wccp.web_cache_value_element.wc_address", FT_UINT32, BASE_CUSTOM, CF_FUNC(wccp_fmt_ipadddress), 0x0, + { &hf_web_cache_value_element_wc_address_index, + { "Web-Cache Address", "wccp.web_cache_value_element.wc_address.index", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_web_cache_value_element_wc_address_ipv4, + { "Web-Cache Address", "wccp.web_cache_value_element.wc_address.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_web_cache_value_element_wc_address_ipv6, + { "Web-Cache Address", "wccp.web_cache_value_element.wc_address.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_web_cache_value_element_num_values, -- cgit v1.2.3