aboutsummaryrefslogtreecommitdiffstats
path: root/packet-wccp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>1999-12-14 01:59:50 +0000
committerGuy Harris <guy@alum.mit.edu>1999-12-14 01:59:50 +0000
commitafe4437cf68002d2042183bfddc268bf33106580 (patch)
tree873a34b681d58f0287e95daa2183363d2529f7f2 /packet-wccp.c
parent2ad53e520e40e77469e4be0b1fa3cc66a810515a (diff)
Merge Jerry's version with a version I'd done.
svn path=/trunk/; revision=1319
Diffstat (limited to 'packet-wccp.c')
-rw-r--r--packet-wccp.c404
1 files changed, 214 insertions, 190 deletions
diff --git a/packet-wccp.c b/packet-wccp.c
index 3aaefde2eb..e3138465ed 100644
--- a/packet-wccp.c
+++ b/packet-wccp.c
@@ -2,10 +2,10 @@
* Routines for Web Cache Coordination Protocol dissection
* Jerry Talkington <jerryt@netapp.com>
*
- * $Id: packet-wccp.c,v 1.2 1999/12/12 03:10:14 guy Exp $
+ * $Id: packet-wccp.c,v 1.3 1999/12/14 01:59:50 guy Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@unicom.net>
+ * By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
*
@@ -39,6 +39,20 @@
#include <glib.h>
#include "packet.h"
+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_cache_ip = -1;
+
+static gint ett_wccp = -1;
+static gint ett_cache_count = -1;
+static gint ett_buckets = -1;
+static gint ett_flags = -1;
+static gint ett_cache_info = -1;
+
/*
* See
*
@@ -47,15 +61,15 @@
* if it hasn't expired yet.
*/
#define WCCPv1 0x0004
-#define WCCP_HERE_I_AM 0x0007
-#define WCCP_I_SEE_YOU 0x0008
-#define WCCP_ASSIGN_BUCKET 0x0009
-
-static const value_string wccp_types[] = {
- { WCCP_HERE_I_AM, "WCCP_HERE_I_AM" },
- { WCCP_I_SEE_YOU, "WCCP_I_SEE_YOU" },
- { WCCP_ASSIGN_BUCKET, "WCCP_ASSIGN_BUCKET" },
- { 0, NULL}
+#define WCCP_HERE_I_AM 7
+#define WCCP_I_SEE_YOU 8
+#define WCCP_ASSIGN_BUCKET 9
+
+static const value_string wccp_type_vals[] = {
+ { WCCP_HERE_I_AM, "Here I am" },
+ { WCCP_I_SEE_YOU, "I see you" },
+ { WCCP_ASSIGN_BUCKET, "Assign bucket" },
+ { 0, NULL }
};
static const value_string wccp_version_val[] = {
@@ -63,200 +77,190 @@ static const value_string wccp_version_val[] = {
{ 0, NULL}
};
-typedef struct _wccp_cache_info {
- guint32 ip_addr;
- guint32 hash_rev;
- guint32 hash_info[8];
- guint32 reserved;
-} wccp_cache_info;
-
-static guint32 proto_wccp = -1;
-static guint32 ett_wccp = -1;
-static guint32 ett_cache_count = -1;
-static guint32 ett_cache_info = -1;
-static guint32 ett_buckets = -1;
-static guint32 hf_wccp_message_type = -1; /* the message type */
-static guint32 hf_wccp_version = -1; /* protocol version */
-static guint32 hf_hash_version = -1; /* the version of the hash */
-static guint32 hf_change_num = -1; /* change number */
-static guint32 hf_recvd_id = -1;
-static guint32 hf_cache_ip = -1;
-
-int wccp_bucket_info(guint8 bucket_info, proto_tree *bucket_tree, guint32 start, int offset);
+#define HASH_INFO_SIZE (4*(1+8+1))
-void
+#define WCCP_U_FLAG 0x80000000
+
+static void dissect_hash_data(const u_char *pd, int offset,
+ proto_tree *wccp_tree);
+static void dissect_web_cache_list_entry(const u_char *pd, int offset,
+ int index, proto_tree *wccp_tree);
+static int wccp_bucket_info(guint8 bucket_info, proto_tree *bucket_tree,
+ guint32 start, int offset);
+static gchar *bucket_name(guint8 bucket);
+
+void
dissect_wccp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
{
- const u_char *data, *data_end;
proto_tree *wccp_tree = NULL;
- proto_item *wccp_tree_item = NULL;
- guint32 wccp_message_type = 0;
-
- data = &pd[offset];
- data_end = data + END_OF_FRAME;
+ proto_item *wccp_tree_item;
+ guint32 wccp_message_type;
+ guint32 wccp_version;
+ guint32 cache_count;
+ int i;
if(check_col(fd, COL_PROTOCOL)) {
col_add_str(fd, COL_PROTOCOL, "WCCP");
}
-
+
wccp_message_type = pntohl(&pd[offset]);
if(check_col(fd, COL_INFO)) {
- col_add_str(fd, COL_INFO, val_to_str(wccp_message_type, wccp_types, "Unknown WCCP message"));
+ col_add_str(fd, COL_INFO, val_to_str(wccp_message_type,
+ wccp_type_vals, "Unknown WCCP message (%u)"));
}
if(tree != NULL) {
- guint32 wccp_version = 0;
-
- wccp_tree_item = proto_tree_add_item_format(tree, proto_wccp, offset, (data_end - data),
- NULL, "Web Cache Coordination Protocol");
-
+ wccp_tree_item = proto_tree_add_item(tree, proto_wccp, offset,
+ END_OF_FRAME, NULL);
wccp_tree = proto_item_add_subtree(wccp_tree_item, ett_wccp);
- proto_tree_add_item(wccp_tree, hf_wccp_message_type , offset, sizeof(wccp_message_type), wccp_message_type);
- offset += sizeof(wccp_message_type);
- wccp_version = pntohl(&pd[offset]);
- proto_tree_add_item(wccp_tree, hf_wccp_version, offset, sizeof(wccp_version), wccp_version);
- offset += sizeof(wccp_version);
-
- if (wccp_message_type == WCCP_HERE_I_AM) {
- guint32 *rsvd;
- guint32 hash_version;
- guint32 recvd_id;
- guint32 i = 0;
- guint32 n = 0;
- guint8 bucket_info;
- proto_tree *bucket_tree = NULL;
- proto_item *bucket_item = NULL;
-
- hash_version = pntohl(&pd[offset]);
- proto_tree_add_item(wccp_tree, hf_hash_version, offset, sizeof(hash_version), hash_version);
- offset += sizeof(hash_version);
-
- bucket_item = proto_tree_add_text(wccp_tree, offset, 32, "Hash Information");
- bucket_tree = proto_item_add_subtree(bucket_item, ett_buckets);
- for(i = 0, n = 0; i < 32; i++) {
- bucket_info = (guint32)pd[offset];
- n = wccp_bucket_info(bucket_info, bucket_tree, n, offset);
- offset += sizeof(bucket_info);
- }
-
- /* we only care about the first bit, the rest is just pad */
- rsvd = (guint32 *)&pd[offset];
- proto_tree_add_text(wccp_tree, offset, sizeof(rsvd), ( (*rsvd & (1<<31) ) ? "U: Historical" : "U: Current" ) );
- offset += sizeof(rsvd);
-
- recvd_id = pntohl(&pd[offset]);
- proto_tree_add_item(wccp_tree, hf_recvd_id, offset, sizeof(recvd_id), recvd_id);
- offset += sizeof(recvd_id); /* copy and paste is fun */
-
- } else if (wccp_message_type == WCCP_I_SEE_YOU) {
- guint32 change_num = 0;
- guint32 recvd_id = 0;
- guint32 cache_count = 0;
- guint32 i = 0;
- guint32 n = 0;
- guint32 ccount = 0;
- guint8 bucket_info;
- wccp_cache_info *cache_info;
- proto_item *cache_count_item = NULL;
- proto_item *cache_info_item = NULL;
- proto_item *bucket_item = NULL;
- proto_tree *cache_count_tree = NULL;
- proto_tree *cache_info_tree = NULL;
- proto_tree *bucket_tree = NULL;
-
-
- change_num = pntohl(&pd[offset]);
- proto_tree_add_item(wccp_tree, hf_change_num, offset, sizeof(change_num), change_num);
- offset += sizeof(change_num);
-
- recvd_id = pntohl(&pd[offset]);
- proto_tree_add_item(wccp_tree, hf_recvd_id, offset, sizeof(recvd_id), recvd_id);
- offset += sizeof(recvd_id);
+ proto_tree_add_item(wccp_tree, hf_wccp_message_type, offset,
+ sizeof(wccp_message_type), wccp_message_type);
+ offset += sizeof(wccp_message_type);
+ switch (wccp_message_type) {
+
+ case WCCP_HERE_I_AM:
+ wccp_version = pntohl(&pd[offset]);
+ proto_tree_add_item(wccp_tree, hf_wccp_version,
+ offset, 4, wccp_version);
+ offset += 4;
+ dissect_hash_data(pd, offset, wccp_tree);
+ offset += HASH_INFO_SIZE;
+ proto_tree_add_item(wccp_tree, hf_recvd_id, offset,
+ 4, pntohl(&pd[offset]));
+ offset += 4;
+ break;
+
+ case WCCP_I_SEE_YOU:
+ wccp_version = pntohl(&pd[offset]);
+ proto_tree_add_item(wccp_tree, hf_wccp_version,
+ offset, 4, wccp_version);
+ offset += 4;
+ proto_tree_add_item(wccp_tree, hf_change_num, offset,
+ 4, pntohl(&pd[offset]));
+ offset += 4;
+ proto_tree_add_item(wccp_tree, hf_recvd_id, offset,
+ 4, pntohl(&pd[offset]));
+ offset += 4;
cache_count = pntohl(&pd[offset]);
- cache_count_item = proto_tree_add_text(wccp_tree, offset, sizeof(cache_count), "Number of caches: %i", cache_count);
- offset += sizeof(cache_count);
-
- cache_count_tree = proto_item_add_subtree(cache_count_item, ett_cache_count);
- for(ccount = 0; ccount < cache_count; ccount++) {
- cache_info = (wccp_cache_info *)&pd[offset];
- cache_info_item = proto_tree_add_item(cache_count_tree, hf_cache_ip, offset, sizeof(cache_info->ip_addr), cache_info->ip_addr);
- offset += sizeof(cache_info->ip_addr);
-
- cache_info_tree = proto_item_add_subtree(cache_info_item, ett_cache_info);
-
- proto_tree_add_text(cache_info_tree, offset, sizeof(cache_info->hash_rev), "Hash Revision: %i", cache_info->hash_rev);
- offset += sizeof(cache_info->hash_rev);
- bucket_item = proto_tree_add_text(cache_info_tree, offset, 32, "Hash Information");
- bucket_tree = proto_item_add_subtree(bucket_item, ett_buckets);
-
-
- for(i = 0, n = 0; i < 32; i++) {
- bucket_info = (guint32)pd[offset];
- n = wccp_bucket_info(bucket_info, bucket_tree, n, offset);
- offset += sizeof(bucket_info);
- }
- proto_tree_add_text(cache_info_tree, offset, sizeof(cache_info->reserved), ( (cache_info->reserved & (1<<31) ) ? "U: Historical" : "U: Current" ) );
- offset += sizeof(cache_info->reserved);
+ proto_tree_add_text(wccp_tree, offset, 4,
+ "Number of Web Caches: %u", cache_count);
+ offset += 4;
+ for (i = 0; i < cache_count; i++) {
+ dissect_web_cache_list_entry(pd, offset, i,
+ wccp_tree);
+ offset += 4 + HASH_INFO_SIZE;
}
-
-
- } else if (wccp_message_type == WCCP_ASSIGN_BUCKET) {
- /* this hasn't been tested, since I don't have any traces with this in it. */
- guint32 recvd_id = 0;
- guint32 wc_count = 0;
- guint32 ip_addr = 0;
- guint16 cache_index;
- guint8 i = 0;
- guint8 bucket_info;
- proto_item *ip_item;
- proto_item *bucket_item;
- proto_tree *ip_tree;
- proto_tree *bucket_tree;
-
- recvd_id = pd[offset];
- proto_tree_add_item(wccp_tree, hf_recvd_id, offset, sizeof(recvd_id), recvd_id);
- offset += sizeof(recvd_id);
-
- wc_count = pntohl(&pd[offset]);
- ip_item = proto_tree_add_text(wccp_tree, offset, sizeof(wc_count), "Number of caches: %i", wc_count);
- offset += sizeof(wc_count);
-
- ip_tree = proto_item_add_subtree(ip_item, ett_cache_count);
- for(i = 0; i < wc_count; i++) {
- ip_addr = pd[offset];
- proto_tree_add_item(ip_tree, hf_cache_ip, offset, sizeof(ip_addr), ip_addr);
- offset += sizeof(ip_addr);
+ break;
+
+ case WCCP_ASSIGN_BUCKET:
+ /*
+ * This hasn't been tested, since I don't have any
+ * traces with this in it.
+ */
+ proto_tree_add_item(wccp_tree, hf_recvd_id, offset,
+ 4, pntohl(&pd[offset]));
+ offset += 4;
+ cache_count = pntohl(&pd[offset]);
+ proto_tree_add_text(wccp_tree, offset, 4,
+ "Number of Web Caches: %u", cache_count);
+ offset += 4;
+ for (i = 0; i < cache_count; i++) {
+ proto_tree_add_item_format(wccp_tree,
+ hf_cache_ip, offset, 4,
+ pntohl(&pd[offset]),
+ "Web Cache %d IP Address: %s", i,
+ ip_to_str((guint8 *) &pd[offset]));
+ offset += 4;
}
-
- bucket_item = proto_tree_add_text(wccp_tree, offset, 32, "Bucket Assignments");
- bucket_tree = proto_item_add_subtree(bucket_item, ett_buckets);
-
- for(i = 0; i < 256; i++) {
- bucket_info = pd[offset];
- if(bucket_info != 0xff) {
- cache_index = g_ntohs((guint16)bucket_info);
- proto_tree_add_text(bucket_tree, offset, sizeof(bucket_info), "Bucket %i: Cache %i", i, bucket_info);
- } else {
- proto_tree_add_text(bucket_tree, offset, sizeof(bucket_info), "Bucket %i: Unassigned", i);
- }
- offset += sizeof(bucket_info);
+ for (i = 0; i < 256; i += 4) {
+ proto_tree_add_text(wccp_tree, offset, 4,
+ "Buckets %d - %d: %10s %10s %10s %10s",
+ i, i + 3,
+ bucket_name(pd[offset]),
+ bucket_name(pd[offset+1]),
+ bucket_name(pd[offset+2]),
+ bucket_name(pd[offset+3]));
+ offset += 4;
}
+ break;
+
+ default:
+ wccp_version = pntohl(&pd[offset]);
+ proto_tree_add_item(wccp_tree, hf_wccp_version,
+ offset, 4, wccp_version);
+ offset += 4;
+ dissect_data(pd, offset, fd, wccp_tree);
+ break;
}
-
-
}
}
+static void
+dissect_hash_data(const u_char *pd, int offset, proto_tree *wccp_tree)
+{
+ proto_item *bucket_item;
+ proto_tree *bucket_tree;
+ proto_item *tf;
+ proto_tree *field_tree;
+ int i;
+ guint8 bucket_info;
+ int n;
+ guint32 flags;
+
+ proto_tree_add_item(wccp_tree, hf_hash_revision, offset, 4,
+ pntohl(&pd[offset]));
+ offset += 4;
+
+ bucket_item = proto_tree_add_text(wccp_tree, offset, 8*4,
+ "Hash information");
+ bucket_tree = proto_item_add_subtree(bucket_item, ett_buckets);
+
+ for (i = 0, n = 0; i < 32; i++) {
+ bucket_info = pd[offset];
+ n = wccp_bucket_info(bucket_info, bucket_tree, n, offset);
+ offset += 1;
+ }
+ flags = pntohl(&pd[offset]);
+ tf = proto_tree_add_text(wccp_tree, offset, 4,
+ "Flags: 0x%08X (%s)", flags,
+ ((flags & WCCP_U_FLAG) ?
+ "Hash information is historical" :
+ "Hash information is current"));
+ field_tree = proto_item_add_subtree(tf, ett_flags);
+ proto_tree_add_text(field_tree, offset, 4, "%s",
+ decode_boolean_bitfield(flags, WCCP_U_FLAG,
+ sizeof (flags)*8,
+ "Hash information is historical",
+ "Hash information is current"));
+}
+
+static void
+dissect_web_cache_list_entry(const u_char *pd, int offset, int index,
+ proto_tree *wccp_tree)
+{
+ proto_item *tl;
+ proto_tree *list_entry_tree;
+
+ tl = proto_tree_add_text(wccp_tree, offset, 4 + HASH_INFO_SIZE,
+ "Web-Cache List Entry(%d)", index);
+ list_entry_tree = proto_item_add_subtree(tl,
+ ett_cache_info);
+ proto_tree_add_item(list_entry_tree, hf_cache_ip, offset, 4,
+ pntohl(&pd[offset]));
+ dissect_hash_data(pd, offset + 4, list_entry_tree);
+}
+
/*
* wccp_bucket_info()
* takes an integer representing a "Hash Information" bitmap, and spits out
* the corresponding proto_tree entries, returning the next bucket number.
*/
-int
-wccp_bucket_info(guint8 bucket_info, proto_tree *bucket_tree, guint32 start, int offset)
+static int
+wccp_bucket_info(guint8 bucket_info, proto_tree *bucket_tree, guint32 start,
+ int offset)
{
guint32 i;
@@ -267,26 +271,40 @@ wccp_bucket_info(guint8 bucket_info, proto_tree *bucket_tree, guint32 start, int
return(start);
}
-/* register */
+static gchar *
+bucket_name(guint8 bucket)
+{
+ static gchar str[4][10+1];
+ static gchar *cur;
+
+ if (cur == &str[0][0])
+ cur = &str[1][0];
+ else if (cur == &str[1][0])
+ cur = &str[2][0];
+ else if (cur == &str[2][0])
+ cur = &str[3][0];
+ else
+ cur = &str[0][0];
+ if (bucket == 0xff)
+ strcpy(cur, "Unassigned");
+ else
+ sprintf(cur, "%u", bucket);
+ return cur;
+}
+
void
proto_register_wccp(void)
{
- static gint *ett[] = {
- &ett_wccp,
- &ett_cache_count,
- &ett_cache_info,
- &ett_buckets,
- };
static hf_register_info hf[] = {
{ &hf_wccp_message_type,
- { "WCCP Message Type", "wccp.message", FT_UINT32, BASE_DEC, VALS(wccp_types), 0x0,
+ { "WCCP Message Type", "wccp.message", FT_UINT32, BASE_DEC, VALS(wccp_type_vals), 0x0,
"The WCCP message that was sent"}
},
{ &hf_wccp_version,
{ "WCCP Version", "wccp.version", FT_UINT32, BASE_DEC, VALS(wccp_version_val), 0x0,
"The WCCP version"}
},
- { &hf_hash_version,
+ { &hf_hash_revision,
{ "Hash Revision", "wccp.hash_revision", FT_UINT32, BASE_DEC, 0x0, 0x0,
"The cache hash revision"}
},
@@ -299,14 +317,20 @@ proto_register_wccp(void)
"The number of I_SEE_YOU's that have been sent"}
},
{ &hf_cache_ip,
- { "Cache IP address", "wccp.cache.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
- "The IP address of a cache"}
+ { "Web Cache IP address", "wccp.cache_ip", FT_IPv4, BASE_NONE, NULL, 0x0,
+ "The IP address of a Web cache"}
},
-
+ };
+ static gint *ett[] = {
+ &ett_wccp,
+ &ett_cache_count,
+ &ett_buckets,
+ &ett_flags,
+ &ett_cache_info,
};
-
- proto_wccp = proto_register_protocol("Web Cache Coordination Protocol", "wccp");
+ proto_wccp = proto_register_protocol("Web Cache Coordination Protocol",
+ "wccp");
proto_register_field_array(proto_wccp, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
+ proto_register_subtree_array(ett, array_length(ett));
}