* Routines for Web Cache Coordination Protocol dissection
* Jerry Talkington <jerryt@netapp.com>
*
- * $Id: packet-wccp.c,v 1.23 2001/11/27 00:50:45 guy Exp $
+ * $Id: packet-wccp.c,v 1.33 2002/08/28 21:00:37 jmayer Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# include "config.h"
#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
#include <string.h>
#include <glib.h>
-#include "packet.h"
-#include "strutil.h"
+#include <epan/packet.h>
+#include <epan/strutil.h>
#include "packet-wccp.h"
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
+
static int proto_wccp = -1;
static int hf_wccp_message_type = -1; /* the message type */
static int hf_wccp_version = -1; /* protocol version */
static int hf_hash_revision = -1; /* the version of the hash */
static int hf_change_num = -1; /* change number */
-static int hf_recvd_id = -1;
+static int hf_recvd_id = -1;
static int hf_cache_ip = -1;
static gint ett_wccp = -1;
static gboolean dissect_wccp2_capability_info(tvbuff_t *tvb, int offset,
int length, proto_tree *info_tree);
static void dissect_32_bit_capability_flags(tvbuff_t *tvb, int curr_offset,
- guint16 capability_len, gint ett, const capability_flag *flags,
+ guint16 capability_val_len, gint ett, const capability_flag *flags,
proto_tree *element_tree);
-static void
+static void
dissect_wccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset = 0;
guint32 wccp_message_type;
guint16 length;
guint32 cache_count;
+ guint32 ipaddr;
guint i;
- if(check_col(pinfo->fd, COL_PROTOCOL)) {
- col_set_str(pinfo->fd, COL_PROTOCOL, "WCCP");
+ if(check_col(pinfo->cinfo, COL_PROTOCOL)) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WCCP");
}
- if(check_col(pinfo->fd, COL_INFO)) {
- col_clear(pinfo->fd, COL_INFO);
+ if(check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo, COL_INFO);
}
wccp_message_type = tvb_get_ntohl(tvb, offset);
- if(check_col(pinfo->fd, COL_INFO)) {
- col_add_str(pinfo->fd, COL_INFO, val_to_str(wccp_message_type,
+ if(check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(wccp_message_type,
wccp_type_vals, "Unknown WCCP message (%u)"));
}
if(tree != NULL) {
wccp_tree_item = proto_tree_add_item(tree, proto_wccp, tvb, offset,
- tvb_length(tvb), FALSE);
+ -1, FALSE);
wccp_tree = proto_item_add_subtree(wccp_tree_item, ett_wccp);
proto_tree_add_uint(wccp_tree, hf_wccp_message_type, tvb, offset,
"Number of Web Caches: %u", cache_count);
offset += 4;
for (i = 0; i < cache_count; i++) {
+ tvb_memcpy(tvb, (guint8 *)&ipaddr, offset, 4);
proto_tree_add_ipv4_format(wccp_tree,
hf_cache_ip, tvb, offset, 4,
- tvb_get_ntohl(tvb, offset),
+ ipaddr,
"Web Cache %d IP Address: %s", i,
- ip_to_str(tvb_get_ptr(tvb, offset, 4)));
+ ip_to_str((guint8 *)&ipaddr));
offset += 4;
}
for (i = 0; i < 256; i += 4) {
"Service Type: Well-known service");
proto_tree_add_text(info_tree, tvb, offset+1, 1,
"Service ID: %s",
- val_to_str(tvb_get_guint8(tvb, offset+1), service_id_vals,
+ val_to_str(tvb_get_guint8(tvb, offset+1), service_id_vals,
"Unknown (0x%02X)"));
break;
"Service Type: Dynamic service");
proto_tree_add_text(info_tree, tvb, offset+1, 1,
"Service ID: %s",
- val_to_str(tvb_get_guint8(tvb, offset+1), service_id_vals,
+ val_to_str(tvb_get_guint8(tvb, offset+1), service_id_vals,
"Unknown (0x%02X)"));
proto_tree_add_text(info_tree, tvb, offset+2, 1,
"Priority: %u", tvb_get_guint8(tvb, offset+2));
ip_to_str(tvb_get_ptr(tvb, offset, 4)));
offset += 4;
}
-
+
return TRUE;
}
"IP-GRE", "GRE-encapsulated" },
{ WCCP2_FORWARDING_METHOD_L2,
"L2", "L2 rewrite" },
- { 0,
+ { 0,
NULL, NULL }
};
"IP-GRE", "GRE-encapsulated" },
{ WCCP2_PACKET_RETURN_METHOD_L2,
"L2", "L2 rewrite" },
- { 0,
+ { 0,
NULL, NULL }
};
proto_tree *info_tree)
{
guint16 capability_type;
- guint16 capability_len;
+ guint16 capability_val_len;
int curr_offset;
proto_item *te;
proto_tree *element_tree;
for (curr_offset = offset; curr_offset < (length + offset);
- curr_offset += capability_len + 4) {
+ curr_offset += (capability_val_len + 4)) {
capability_type = tvb_get_ntohs(tvb, curr_offset);
- capability_len = tvb_get_ntohs(tvb, curr_offset + 2);
+ capability_val_len = tvb_get_ntohs(tvb, curr_offset + 2);
te = proto_tree_add_text(info_tree, tvb, curr_offset,
- capability_len, "%s",
+ capability_val_len + 4, "%s",
val_to_str(capability_type,
capability_type_vals, "Unknown Capability Element (0x%08X)"));
element_tree = proto_item_add_subtree(te,
val_to_str(capability_type,
capability_type_vals, "Unknown (0x%08X)"));
- if (capability_len < 4) {
+ if (capability_val_len < 4) {
proto_tree_add_text(element_tree, tvb, curr_offset+2, 2,
- "Length: %u (illegal, must be >= 4)",
- capability_len);
+ "Value Length: %u (illegal, must be >= 4)",
+ capability_val_len);
break;
}
proto_tree_add_text(element_tree, tvb, curr_offset+2, 2,
- "Length: %u", capability_len);
+ "Value Length: %u", capability_val_len);
switch (capability_type) {
case WCCP2_FORWARDING_METHOD:
dissect_32_bit_capability_flags(tvb, curr_offset,
- capability_len, ett_capability_forwarding_method,
+ capability_val_len,
+ ett_capability_forwarding_method,
forwarding_method_flags, element_tree);
break;
case WCCP2_ASSIGNMENT_METHOD:
dissect_32_bit_capability_flags(tvb, curr_offset,
- capability_len, ett_capability_assignment_method,
+ capability_val_len,
+ ett_capability_assignment_method,
assignment_method_flags, element_tree);
break;
case WCCP2_PACKET_RETURN_METHOD:
dissect_32_bit_capability_flags(tvb, curr_offset,
- capability_len, ett_capability_return_method,
+ capability_val_len,
+ ett_capability_return_method,
packet_return_method_flags, element_tree);
break;
default:
proto_tree_add_text(element_tree, tvb,
- curr_offset+4, capability_len-4,
+ curr_offset+4, capability_val_len,
"Value: %s",
- tvb_bytes_to_str(tvb, curr_offset+4, capability_len-4));
+ tvb_bytes_to_str(tvb, curr_offset+4,
+ capability_val_len));
break;
}
static void
dissect_32_bit_capability_flags(tvbuff_t *tvb, int curr_offset,
- guint16 capability_len, gint ett, const capability_flag *flags,
+ guint16 capability_val_len, gint ett, const capability_flag *flags,
proto_tree *element_tree)
{
guint32 capability_val;
int space_left;
char buf[1025];
- if (capability_len != 4) {
+ if (capability_val_len != 4) {
proto_tree_add_text(element_tree, tvb,
- curr_offset+4, capability_len-4,
+ curr_offset+4, capability_val_len,
"Illegal length (must be 4)");
return;
}
{ "WCCP Message Type", "wccp.message", FT_UINT32, BASE_DEC, VALS(wccp_type_vals), 0x0,
"The WCCP message that was sent", HFILL }
},
- { &hf_wccp_version,
+ { &hf_wccp_version,
{ "WCCP Version", "wccp.version", FT_UINT32, BASE_HEX, VALS(wccp_version_val), 0x0,
"The WCCP version", HFILL }
},
void
proto_reg_handoff_wccp(void)
{
- dissector_add("udp.port", UDP_PORT_WCCP, dissect_wccp, proto_wccp);
+ dissector_handle_t wccp_handle;
+
+ wccp_handle = create_dissector_handle(dissect_wccp, proto_wccp);
+ dissector_add("udp.port", UDP_PORT_WCCP, wccp_handle);
}