]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/wccp2.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / wccp2.cc
index bb34d448044a84b70406faa1484802392883fe10..bb10f1bdc35e1d8fe4b30a73d9cbf62181d1acab 100644 (file)
  */
 
 #include "squid.h"
+
+#if USE_WCCPv2
+
 #include "comm.h"
+#include "comm/Connection.h"
+#include "comm/Loops.h"
+#include "compat/strsep.h"
 #include "event.h"
+#include "ip/Address.h"
+#include "md5.h"
 #include "Parsing.h"
+#include "protos.h"
 #include "Store.h"
 #include "SwapDir.h"
-#include "ip/IpAddress.h"
 
-#if USE_WCCPv2
 #if HAVE_NETDB_H
 #include <netdb.h>
 #endif
@@ -55,99 +62,81 @@ static EVH wccp2HereIam;
 static EVH wccp2AssignBuckets;
 
 /* KDW WCCP V2 */
-#define WCCP2_HERE_I_AM                10
-#define WCCP2_I_SEE_YOU                11
-#define WCCP2_REDIRECT_ASSIGN          12
-#define WCCP2_REMOVAL_QUERY            13
 
-#define WCCP2_VERSION                  0x200
+#define WCCP2_HASH_ASSIGNMENT          0x00
+#define WCCP2_MASK_ASSIGNMENT          0x01
 
-#define WCCP2_SECURITY_INFO            0
-#define WCCP2_NO_SECURITY              0
-#define WCCP2_MD5_SECURITY             1
+#define        WCCP2_NONE_SECURITY_LEN 0
+#define        WCCP2_MD5_SECURITY_LEN  16
 
-#define WCCP2_SERVICE_INFO             1
-#define WCCP2_SERVICE_STANDARD         0
-#define WCCP2_SERVICE_DYNAMIC          1
-#define WCCP2_SERVICE_ID_HTTP          0x00
+/* Useful defines */
+#define        WCCP2_NUMPORTS  8
+#define        WCCP2_PASSWORD_LEN      8
 
-#define WCCP2_SERVICE_SRC_IP_HASH      0x1
-#define WCCP2_SERVICE_DST_IP_HASH      0x2
-#define WCCP2_SERVICE_SRC_PORT_HASH    0x4
-#define WCCP2_SERVICE_DST_PORT_HASH    0x8
-#define WCCP2_SERVICE_PORTS_DEFINED    0x10
-#define WCCP2_SERVICE_PORTS_SOURCE     0x20
-#define WCCP2_SERVICE_SRC_IP_ALT_HASH  0x100
-#define WCCP2_SERVICE_DST_IP_ALT_HASH  0x200
-#define WCCP2_SERVICE_SRC_PORT_ALT_HASH        0x400
-#define WCCP2_SERVICE_DST_PORT_ALT_HASH        0x800
+/* WCCPv2 Pakcet format structures */
+/* Defined in draft-wilson-wccp-v2-12-oct-2001.txt */
 
-#define WCCP2_ROUTER_ID_INFO           2
+/** \interface WCCPv2_Protocol
+ * Generic header struct
+ */
+struct wccp2_item_header_t {
+    uint16_t type;
+    uint16_t length;
+};
 
+/* item type values */
+#define WCCP2_SECURITY_INFO            0
+#define WCCP2_SERVICE_INFO             1
+#define WCCP2_ROUTER_ID_INFO           2
 #define WCCP2_WC_ID_INFO               3
-
 #define WCCP2_RTR_VIEW_INFO            4
-
 #define WCCP2_WC_VIEW_INFO             5
-
 #define WCCP2_REDIRECT_ASSIGNMENT      6
-
 #define WCCP2_QUERY_INFO               7
-
 #define WCCP2_CAPABILITY_INFO          8
-
 #define WCCP2_ALT_ASSIGNMENT           13
-
 #define WCCP2_ASSIGN_MAP               14
-
 #define WCCP2_COMMAND_EXTENSION                15
 
-#define WCCP2_CAPABILITY_FORWARDING_METHOD     0x01
-#define WCCP2_CAPABILITY_ASSIGNMENT_METHOD     0x02
-#define WCCP2_CAPABILITY_RETURN_METHOD         0x03
-
-#define WCCP2_METHOD_GRE               0x00000001
-#define WCCP2_METHOD_L2                        0x00000002
-
-#define WCCP2_FORWARDING_METHOD_GRE    WCCP2_METHOD_GRE
-#define WCCP2_FORWARDING_METHOD_L2     WCCP2_METHOD_L2
-
-#define WCCP2_ASSIGNMENT_METHOD_HASH   0x00000001
-#define WCCP2_ASSIGNMENT_METHOD_MASK   0x00000002
-
-#define WCCP2_PACKET_RETURN_METHOD_GRE WCCP2_METHOD_GRE
-#define WCCP2_PACKET_RETURN_METHOD_L2  WCCP2_METHOD_L2
-
-#define WCCP2_HASH_ASSIGNMENT          0x00
-#define WCCP2_MASK_ASSIGNMENT          0x01
-
-#define        WCCP2_NONE_SECURITY_LEN 0
-#define        WCCP2_MD5_SECURITY_LEN  16
-
-/* Useful defines */
-#define        WCCP2_NUMPORTS  8
-#define        WCCP2_PASSWORD_LEN      8
-
-/* WCCP v2 packet header */
-
-/// \interface WCCPv2_Protocol
-struct wccp2_here_i_am_header_t {
+/** \interface WCCPv2_Protocol
+ * Sect 5.5  WCCP Message Header
+ */
+struct wccp2_message_header_t {
     uint32_t type;
     uint16_t version;
+#define WCCP2_VERSION          0x200
+
     uint16_t length;
 };
+static struct wccp2_message_header_t wccp2_here_i_am_header;
 
-static struct wccp2_here_i_am_header_t wccp2_here_i_am_header;
-
-/* Security struct for the "no security" option */
+/* message types */
+#define WCCP2_HERE_I_AM           10
+#define WCCP2_I_SEE_YOU           11
+#define WCCP2_REDIRECT_ASSIGN     12
+#define WCCP2_REMOVAL_QUERY       13
 
+/** \interface WCCPv2_Protocol
+ * Sect 5.6.1 Security Info Component
+ *
+ * Basic security Header. Matches "no security" case exactly.
+ */
 struct wccp2_security_none_t {
     uint16_t security_type;
     uint16_t security_length;
     uint32_t security_option;
 };
 
-/// \interface WCCPv2_Protocol
+/* security options */
+#define WCCP2_NO_SECURITY              0
+#define WCCP2_MD5_SECURITY             1
+
+/** \interface WCCPv2_Protocol
+ * Sect 5.6.1 Security Info Component
+ *
+ * Extended security section. Matches "MD5 security" type exactly.
+ * Including the security header.
+ */
 struct wccp2_security_md5_t {
     uint16_t security_type;
     uint16_t security_length;
@@ -157,7 +146,9 @@ struct wccp2_security_md5_t {
 
 /* Service info struct */
 
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * Sect 5.6.2 Service Info Component
+ */
 struct wccp2_service_info_t {
     uint16_t service_type;
     uint16_t service_length;
@@ -175,20 +166,50 @@ struct wccp2_service_info_t {
     uint16_t port6;
     uint16_t port7;
 };
+/* services */
+#define WCCP2_SERVICE_STANDARD         0
+#define WCCP2_SERVICE_DYNAMIC          1
 
-/// \interface WCCPv2_Protocol
+/* service IDs */
+#define WCCP2_SERVICE_ID_HTTP          0x00
+
+/* service flags */
+#define WCCP2_SERVICE_SRC_IP_HASH      0x1
+#define WCCP2_SERVICE_DST_IP_HASH      0x2
+#define WCCP2_SERVICE_SRC_PORT_HASH    0x4
+#define WCCP2_SERVICE_DST_PORT_HASH    0x8
+#define WCCP2_SERVICE_PORTS_DEFINED    0x10
+#define WCCP2_SERVICE_PORTS_SOURCE     0x20
+#define WCCP2_SERVICE_SRC_IP_ALT_HASH  0x100
+#define WCCP2_SERVICE_DST_IP_ALT_HASH  0x200
+#define WCCP2_SERVICE_SRC_PORT_ALT_HASH        0x400
+#define WCCP2_SERVICE_DST_PORT_ALT_HASH        0x800
+
+/* TODO the following structures need to be re-defined for correct full operation.
+ wccp2_cache_identity_element needs to be merged as a sub-struct of
+ wccp2_identity_info_t (identity_type);  which frees up the identifty info
+ structures so mask_assigment_data_element can become variable length
+ and cope with multiple fail-over caches hanging off one router.
+ */
+
+/** \interface WCCPv2_Protocol
+ * Sect 5.7.2 Web-Cache Identity Element
+ */
 struct wccp2_cache_identity_info_t {
     struct in_addr addr;
     uint16_t hash_revision;
-    char bits[2];
-    char buckets[32];
+    uint16_t bits;
+//#define WCCP2_HASH_ASSIGNMENT_DATA  0x0
+
+    /* 5.7.2 Hash Assignment Data Element */
+    char buckets[32]; /* Draft indicates 8x 32-bit buckets but it's just a mask so doesn't matter how we define. */
     uint16_t weight;
     uint16_t status;
 };
 
-/* Web Cache identity info */
-
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * Sect 5.6.4 Web-Cache Identity Info Component
+ */
 struct wccp2_identity_info_t {
     uint16_t cache_identity_type;
     uint16_t cache_identity_length;
@@ -198,22 +219,45 @@ struct wccp2_identity_info_t {
 
 static struct wccp2_identity_info_t wccp2_identity_info;
 
-/// \interface WCCPv2_Protocol
-struct wccp2_cache_mask_identity_info_t {
-    struct in_addr addr;
-    uint32_t num1;
-    uint32_t num2;
+/** \interface WCCPv2_Protocol
+ * Sect 5.7.7 Mask Element
+ */
+struct wccp2_mask_element_t {
     uint32_t source_ip_mask;
     uint32_t dest_ip_mask;
     uint16_t source_port_mask;
     uint16_t dest_port_mask;
-    uint32_t num3;
-    uint32_t num4;
+    uint32_t number_values;
 };
 
-/* Web Cache identity info */
+/** \interface WCCPv2_Protocol
+ * Sect 5.7.2 Web-Cache Identity Element
+ */
+struct wccp2_cache_mask_identity_info_t {
+    struct in_addr addr;
+    uint16_t hash_revision;
+    uint16_t bits;
+#define WCCP2_MASK_ASSIGNMENT_DATA  (0x2)
 
-/// \interface WCCPv2_Protocol
+    /* Sect 5.7.2 Mask Assignment Data Element
+     *
+     * NP: draft specifies a variable-length set of keys here.
+     *     the following fields only matche the special case Squid sends outbound (single-cache).
+     */
+    uint32_t mask_element_count;
+
+    /* Sect 5.7.6 Mask/Value Set Element */
+    /* special case: single mask element. no values. */
+    struct wccp2_mask_element_t mask;
+
+    /* Sect 5.7.2 Mask Assignment Data Element */
+    uint16_t weight;
+    uint16_t status;
+};
+
+/** \interface WCCPv2_Protocol
+ * Sect 5.6.4 Web-Cache Identity Info Component
+ */
 struct wccp2_mask_identity_info_t {
     uint16_t cache_identity_type;
     uint16_t cache_identity_length;
@@ -223,9 +267,12 @@ struct wccp2_mask_identity_info_t {
 
 static struct wccp2_mask_identity_info_t wccp2_mask_identity_info;
 
-/* View header */
-
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * Sect 5.6.5 Router View Info Component
+ * Sect 5.6.6 Web Cache View Info Component
+ *
+ * first three fields. (shared by both view components)
+ */
 struct wccp2_cache_view_header_t {
     uint16_t cache_view_type;
     uint16_t cache_view_length;
@@ -234,9 +281,8 @@ struct wccp2_cache_view_header_t {
 
 static struct wccp2_cache_view_header_t wccp2_cache_view_header;
 
-/* View info */
-
 /// \interface WCCPv2_Protocol
+/* NP: special-case 5.6.5 or 5.6.6 * View Info when no routers or caches are advertised? */
 struct wccp2_cache_view_info_t {
     uint32_t num_routers;
     uint32_t num_caches;
@@ -244,9 +290,9 @@ struct wccp2_cache_view_info_t {
 
 static struct wccp2_cache_view_info_t wccp2_cache_view_info;
 
-/* Router ID element */
-
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * Sect 5.7.1 Router ID Element
+ */
 struct wccp2_router_id_element_t {
     struct in_addr router_address;
     uint32_t received_id;
@@ -254,49 +300,50 @@ struct wccp2_router_id_element_t {
 
 static struct wccp2_router_id_element_t wccp2_router_id_element;
 
-/* Capability info header */
-
-/// \interface WCCpv2_Protocol
+/** \interface WCCPv2_Protocol
+ * Sect 5.6.9 Capabilities Info Component
+ */
 struct wccp2_capability_info_header_t {
     uint16_t capability_info_type;
     uint16_t capability_info_length;
+    /* dynamic length capabilities list */
 };
 
 static struct wccp2_capability_info_header_t wccp2_capability_info_header;
 
-/* Capability element header */
-
-/// \interface WCCPv2_Protocol
-struct wccp2_capability_element_header_t {
-    uint16_t capability_type;
-    uint16_t capability_length;
-};
-
-/* Capability element */
-
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * 5.7.5 Capability Element
+ */
 struct wccp2_capability_element_t {
     uint16_t capability_type;
     uint16_t capability_length;
     uint32_t capability_value;
 };
-
 static struct wccp2_capability_element_t wccp2_capability_element;
 
-/* Mask Element */
-
-/// \interface WCCPv2_Protocol
-struct wccp2_mask_element_t {
-    uint32_t source_ip_mask;
-    uint32_t dest_ip_mask;
-    uint16_t source_port_mask;
-    uint16_t dest_port_mask;
-    uint32_t number_values;
-};
+/* capability types */
+#define WCCP2_CAPABILITY_FORWARDING_METHOD     0x01
+#define WCCP2_CAPABILITY_ASSIGNMENT_METHOD     0x02
+#define WCCP2_CAPABILITY_RETURN_METHOD         0x03
+// 0x04 ?? - advertised by a 4507 (ios v15.1) Cisco switch
+// 0x05 ?? - advertised by a 4507 (ios v15.1) Cisco switch
 
-/* Value Element */
+/* capability values */
+#define WCCP2_METHOD_GRE               0x00000001
+#define WCCP2_METHOD_L2                        0x00000002
+/* when type=WCCP2_CAPABILITY_FORWARDING_METHOD */
+#define WCCP2_FORWARDING_METHOD_GRE    WCCP2_METHOD_GRE
+#define WCCP2_FORWARDING_METHOD_L2     WCCP2_METHOD_L2
+/* when type=WCCP2_CAPABILITY_ASSIGNMENT_METHOD */
+#define WCCP2_ASSIGNMENT_METHOD_HASH   0x00000001
+#define WCCP2_ASSIGNMENT_METHOD_MASK   0x00000002
+/* when type=WCCP2_CAPABILITY_RETURN_METHOD */
+#define WCCP2_PACKET_RETURN_METHOD_GRE WCCP2_METHOD_GRE
+#define WCCP2_PACKET_RETURN_METHOD_L2  WCCP2_METHOD_L2
 
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * 5.7.8 Value Element
+ */
 struct wccp2_value_element_t {
     uint32_t source_ip_value;
     uint32_t dest_ip_value;
@@ -308,7 +355,9 @@ struct wccp2_value_element_t {
 
 /* RECEIVED PACKET STRUCTURE */
 
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * 5.2 'I See You' Message
+ */
 struct wccp2_i_see_you_t {
     uint32_t type;
     uint16_t version;
@@ -318,26 +367,20 @@ struct wccp2_i_see_you_t {
 
 static struct wccp2_i_see_you_t wccp2_i_see_you;
 
-/* Router ID element */
-
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * 5.7.4 Router Assignment Element
+ */
 struct wccp2_router_assign_element_t {
     struct in_addr router_address;
     uint32_t received_id;
     uint32_t change_number;
 };
 
-/* Generic header struct */
-
-/// \interface WCCPv2_Protocol
-struct wccp2_item_header_t {
-    uint16_t type;
-    uint16_t length;
-};
-
 /* Router identity struct */
 
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * 5.6.3 Router Identity Info Component (partial)
+ */
 struct router_identity_info_t {
 
     struct wccp2_item_header_t header;
@@ -346,11 +389,15 @@ struct router_identity_info_t {
 
     struct in_addr router_address;
     uint32_t number_caches;
+    /* dynamic list of cache IP addresses */
 };
 
 /* The received packet for a mask assignment is unusual */
 
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * Sect 5.7.7 Mask Element  ???
+ * see code below. apparently the supposed IP address at position num1 can be equal to 3.
+ */
 struct cache_mask_info_t {
     struct in_addr addr;
     uint32_t num1;
@@ -358,23 +405,22 @@ struct cache_mask_info_t {
     uint32_t num3;
 };
 
-/* assigment key */
-
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * 5.7.3 Assignment Key Element
+ */
 struct assignment_key_t {
     struct in_addr master_ip;
     uint32_t master_number;
 };
 
-/* Router view of WCCP */
-
-/// \interface WCCPv2_Protocol
+/** \interface WCCPv2_Protocol
+ * 5.6.5 Router View Info Component (first three fields)
+ */
 struct router_view_t {
-
     struct wccp2_item_header_t header;
     uint32_t change_number;
-
     struct assignment_key_t assignment_key;
+    /* dynamic lists of routers and caches elided */
 };
 
 /* Lists used to keep track of caches, routers and services */
@@ -434,7 +480,8 @@ static struct wccp2_service_list_t *wccp2_service_list_head = NULL;
 
 int empty_portlist[WCCP2_NUMPORTS] = {0, 0, 0, 0, 0, 0, 0, 0};
 
-/* END WCCP V2 */
+/* END WCCP V2 PROTOCL TYPES DEFINITION */
+
 void wccp2_add_service_list(int service, int service_id, int service_priority,
                             int service_proto, int service_flags, int ports[], int security_type, char *password);
 static void wccp2SortCacheList(struct wccp2_cache_list_t *head);
@@ -501,7 +548,7 @@ wccp2_add_service_list(int service, int service_id, int service_priority,
 }
 
 static struct wccp2_service_list_t *
-            wccp2_get_service_by_id(int service, int service_id) {
+wccp2_get_service_by_id(int service, int service_id) {
 
     struct wccp2_service_list_t *p;
 
@@ -526,7 +573,7 @@ static struct wccp2_service_list_t *
 static char
 wccp2_update_md5_security(char *password, char *ptr, char *packet, int len)
 {
-    u_int8_t md5_digest[16];
+    uint8_t md5_digest[16];
     char pwd[WCCP2_PASSWORD_LEN];
     SquidMD5_CTX M;
 
@@ -570,7 +617,6 @@ wccp2_update_md5_security(char *password, char *ptr, char *packet, int len)
     return 1;
 }
 
-
 /*
  * Check the given WCCP2 packet against the given password.
  */
@@ -580,14 +626,14 @@ wccp2_check_security(struct wccp2_service_list_t *srv, char *security, char *pac
 {
 
     struct wccp2_security_md5_t *ws = (struct wccp2_security_md5_t *) security;
-    u_int8_t md5_digest[16], md5_challenge[16];
+    uint8_t md5_digest[16], md5_challenge[16];
     char pwd[WCCP2_PASSWORD_LEN];
     SquidMD5_CTX M;
 
     /* Make sure the security type matches what we expect */
 
     if (ntohl(ws->security_option) != srv->wccp2_security_type) {
-        debugs(80, 1, "wccp2_check_security: received packet has the wrong security option");
+        debugs(80, DBG_IMPORTANT, "wccp2_check_security: received packet has the wrong security option");
         return 0;
     }
 
@@ -596,7 +642,7 @@ wccp2_check_security(struct wccp2_service_list_t *srv, char *security, char *pac
     }
 
     if (srv->wccp2_security_type != WCCP2_MD5_SECURITY) {
-        debugs(80, 1, "wccp2_check_security: invalid security option");
+        debugs(80, DBG_IMPORTANT, "wccp2_check_security: invalid security option");
         return 0;
     }
 
@@ -623,11 +669,10 @@ wccp2_check_security(struct wccp2_service_list_t *srv, char *security, char *pac
     return (memcmp(md5_digest, md5_challenge, 16) == 0);
 }
 
-
 void
 wccp2Init(void)
 {
-    IpAddress_list *s;
+    Ip::Address_list *s;
     char *ptr;
     uint32_t service_flags;
 
@@ -648,7 +693,7 @@ wccp2Init(void)
     for (s = Config.Wccp2.router; s; s = s->next) {
         if (!s->s.IsAnyAddr()) {
             /* Increment the counter */
-            wccp2_numrouters++;
+            ++wccp2_numrouters;
         }
     }
 
@@ -693,13 +738,11 @@ wccp2Init(void)
         service_list_ptr->security_info = (struct wccp2_security_md5_t *) ptr;
 
         if (service_list_ptr->wccp2_security_type == WCCP2_MD5_SECURITY) {
-
-            xmemcpy(ptr, &wccp2_security_md5, sizeof(struct wccp2_security_md5_t));
-
+            memcpy(ptr, &wccp2_security_md5, sizeof(struct wccp2_security_md5_t));
             ptr += sizeof(struct wccp2_security_md5_t);
         } else {
             /* assume NONE, and XXX I hate magic length numbers */
-            xmemcpy(ptr, &wccp2_security_md5, 8);
+            memcpy(ptr, &wccp2_security_md5, 8);
             ptr += 8;
         }
 
@@ -709,7 +752,7 @@ wccp2Init(void)
 
         assert(wccp2_here_i_am_header.length <= WCCP_RESPONSE_SIZE);
 
-        xmemcpy(ptr, &service_list_ptr->info, sizeof(struct wccp2_service_info_t));
+        memcpy(ptr, &service_list_ptr->info, sizeof(struct wccp2_service_info_t));
 
         service_list_ptr->service_info = (struct wccp2_service_info_t *) ptr;
 
@@ -732,7 +775,7 @@ wccp2Init(void)
             wccp2_identity_info.cache_identity.weight = htons(Config.Wccp2.weight);
             memset(&wccp2_identity_info.cache_identity.status, '\0', sizeof(wccp2_identity_info.cache_identity.status));
 
-            xmemcpy(ptr, &wccp2_identity_info, sizeof(struct wccp2_identity_info_t));
+            memcpy(ptr, &wccp2_identity_info, sizeof(struct wccp2_identity_info_t));
             service_list_ptr->wccp2_identity_info_ptr = ptr;
 
             ptr += sizeof(struct wccp2_identity_info_t);
@@ -745,38 +788,28 @@ wccp2Init(void)
             wccp2_mask_identity_info.cache_identity_type = htons(WCCP2_WC_ID_INFO);
             wccp2_mask_identity_info.cache_identity_length = htons(sizeof(wccp2_mask_identity_info.cache_identity));
             memset(&wccp2_mask_identity_info.cache_identity.addr, '\0', sizeof(struct in_addr));
-            wccp2_mask_identity_info.cache_identity.num1 = htonl(2);
-            wccp2_mask_identity_info.cache_identity.num2 = htonl(1);
+            wccp2_mask_identity_info.cache_identity.bits = htons(WCCP2_MASK_ASSIGNMENT_DATA);
+            wccp2_mask_identity_info.cache_identity.mask_element_count = htonl(1);
             service_flags = ntohl(service_list_ptr->service_info->service_flags);
 
+            memset(&wccp2_mask_identity_info.cache_identity.mask, 0, sizeof(struct wccp2_mask_element_t));
+
             if ((service_flags & WCCP2_SERVICE_SRC_IP_HASH) || (service_flags & WCCP2_SERVICE_SRC_IP_ALT_HASH)) {
-                wccp2_mask_identity_info.cache_identity.source_ip_mask = htonl(0x00001741);
-                wccp2_mask_identity_info.cache_identity.dest_ip_mask = 0;
-                wccp2_mask_identity_info.cache_identity.source_port_mask = 0;
-                wccp2_mask_identity_info.cache_identity.dest_port_mask = 0;
+                wccp2_mask_identity_info.cache_identity.mask.source_ip_mask = htonl(0x00001741);
             } else if ((service_list_ptr->info.service == WCCP2_SERVICE_STANDARD) || (service_flags & WCCP2_SERVICE_DST_IP_HASH) || (service_flags & WCCP2_SERVICE_DST_IP_ALT_HASH)) {
-                wccp2_mask_identity_info.cache_identity.source_ip_mask = 0;
-                wccp2_mask_identity_info.cache_identity.dest_ip_mask = htonl(0x00001741);
-                wccp2_mask_identity_info.cache_identity.source_port_mask = 0;
-                wccp2_mask_identity_info.cache_identity.dest_port_mask = 0;
+                wccp2_mask_identity_info.cache_identity.mask.dest_ip_mask = htonl(0x00001741);
             } else if ((service_flags & WCCP2_SERVICE_SRC_PORT_HASH) || (service_flags & WCCP2_SERVICE_SRC_PORT_ALT_HASH)) {
-                wccp2_mask_identity_info.cache_identity.source_ip_mask = 0;
-                wccp2_mask_identity_info.cache_identity.dest_ip_mask = 0;
-                wccp2_mask_identity_info.cache_identity.source_port_mask = htons(0x1741);
-                wccp2_mask_identity_info.cache_identity.dest_port_mask = 0;
+                wccp2_mask_identity_info.cache_identity.mask.source_port_mask = htons(0x1741);
             } else if ((service_flags & WCCP2_SERVICE_DST_PORT_HASH) || (service_flags & WCCP2_SERVICE_DST_PORT_ALT_HASH)) {
-                wccp2_mask_identity_info.cache_identity.source_ip_mask = 0;
-                wccp2_mask_identity_info.cache_identity.dest_ip_mask = 0;
-                wccp2_mask_identity_info.cache_identity.source_port_mask = 0;
-                wccp2_mask_identity_info.cache_identity.dest_port_mask = htons(0x1741);
+                wccp2_mask_identity_info.cache_identity.mask.dest_port_mask = htons(0x1741);
             } else {
                 fatalf("Unknown service hash method\n");
             }
 
-            wccp2_mask_identity_info.cache_identity.num3 = 0;
-            wccp2_mask_identity_info.cache_identity.num4 = 0;
+            wccp2_mask_identity_info.cache_identity.weight = 0;
+            wccp2_mask_identity_info.cache_identity.status = 0;
 
-            xmemcpy(ptr, &wccp2_mask_identity_info, sizeof(struct wccp2_mask_identity_info_t));
+            memcpy(ptr, &wccp2_mask_identity_info, sizeof(struct wccp2_mask_identity_info_t));
             service_list_ptr->wccp2_identity_info_ptr = ptr;
 
             ptr += sizeof(struct wccp2_mask_identity_info_t);
@@ -798,7 +831,7 @@ wccp2Init(void)
 
         wccp2_cache_view_header.cache_view_version = htonl(1);
 
-        xmemcpy(ptr, &wccp2_cache_view_header, sizeof(wccp2_cache_view_header));
+        memcpy(ptr, &wccp2_cache_view_header, sizeof(wccp2_cache_view_header));
 
         ptr += sizeof(wccp2_cache_view_header);
 
@@ -809,7 +842,7 @@ wccp2Init(void)
 
         service_list_ptr->num_routers = htonl(wccp2_numrouters);
 
-        xmemcpy(ptr, &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
+        memcpy(ptr, &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
 
         ptr += sizeof(service_list_ptr->num_routers);
 
@@ -849,7 +882,7 @@ wccp2Init(void)
 
         wccp2_cache_view_info.num_caches = htonl(0);
 
-        xmemcpy(ptr, &wccp2_cache_view_info.num_caches, sizeof(wccp2_cache_view_info.num_caches));
+        memcpy(ptr, &wccp2_cache_view_info.num_caches, sizeof(wccp2_cache_view_info.num_caches));
 
         ptr += sizeof(wccp2_cache_view_info.num_caches);
 
@@ -862,7 +895,7 @@ wccp2Init(void)
 
         wccp2_capability_info_header.capability_info_length = htons(3 * sizeof(wccp2_capability_element));
 
-        xmemcpy(ptr, &wccp2_capability_info_header, sizeof(wccp2_capability_info_header));
+        memcpy(ptr, &wccp2_capability_info_header, sizeof(wccp2_capability_info_header));
 
         ptr += sizeof(wccp2_capability_info_header);
 
@@ -877,7 +910,7 @@ wccp2Init(void)
 
         wccp2_capability_element.capability_value = htonl(Config.Wccp2.forwarding_method);
 
-        xmemcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
+        memcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
 
         ptr += sizeof(wccp2_capability_element);
 
@@ -892,7 +925,7 @@ wccp2Init(void)
 
         wccp2_capability_element.capability_value = htonl(Config.Wccp2.assignment_method);
 
-        xmemcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
+        memcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
 
         ptr += sizeof(wccp2_capability_element);
 
@@ -907,7 +940,7 @@ wccp2Init(void)
 
         wccp2_capability_element.capability_value = htonl(Config.Wccp2.return_method);
 
-        xmemcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
+        memcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
 
         ptr += sizeof(wccp2_capability_element);
 
@@ -923,8 +956,7 @@ wccp2Init(void)
         if (wccp2_numrouters) {
             if (!eventFind(wccp2HereIam, NULL)) {
                 eventAdd("wccp2HereIam", wccp2HereIam, NULL, 1, 1);
-            }
-            else
+            } else
                 debugs(80,3,"wccp2Init: skip duplicate 'HERE_I_AM'.");
         }
 
@@ -945,21 +977,21 @@ wccp2ConnectionOpen(void)
     debugs(80, 5, "wccp2ConnectionOpen: Called");
 
     if (wccp2_numrouters == 0 || !wccp2_service_list_head) {
-        debugs(80, 2, "WCCPv2 Disabled.");
+        debugs(80, 2, "WCCPv2 Disabled. No IPv4 Router(s) configured.");
         return;
     }
 
     if ( !Config.Wccp2.address.SetIPv4() ) {
-        debugs(80, 0, "WCCPv2 Disabled. " << Config.Wccp2.address << " is not an IPv4 address.");
+        debugs(80, DBG_CRITICAL, "WCCPv2 Disabled. Local address " << Config.Wccp2.address << " is not an IPv4 address.");
         return;
     }
 
     Config.Wccp2.address.SetPort(WCCP_PORT);
-    theWccp2Connection = comm_open(SOCK_DGRAM,
-                                   0,
-                                   Config.Wccp2.address,
-                                   COMM_NONBLOCKING,
-                                   "WCCPv2 Socket");
+    theWccp2Connection = comm_open_listener(SOCK_DGRAM,
+                                            0,
+                                            Config.Wccp2.address,
+                                            COMM_NONBLOCKING,
+                                            "WCCPv2 Socket");
 
     if (theWccp2Connection < 0)
         fatal("Cannot open WCCP Port");
@@ -971,14 +1003,10 @@ wccp2ConnectionOpen(void)
     }
 
 #endif
-    commSetSelect(theWccp2Connection,
-                  COMM_SELECT_READ,
-                  wccp2HandleUdp,
-                  NULL,
-                  0);
+    Comm::SetSelect(theWccp2Connection, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0);
 
-    debugs(80, 1, "Accepting WCCPv2 messages on port " << WCCP_PORT << ", FD " << theWccp2Connection << ".");
-    debugs(80, 1, "Initialising all WCCPv2 lists");
+    debugs(80, DBG_IMPORTANT, "Accepting WCCPv2 messages on port " << WCCP_PORT << ", FD " << theWccp2Connection << ".");
+    debugs(80, DBG_IMPORTANT, "Initialising all WCCPv2 lists");
 
     /* Initialise all routers on all services */
     memset(&null, 0, sizeof(null));
@@ -1041,7 +1069,7 @@ wccp2ConnectionClose(void)
     }
 
     if (theWccp2Connection > -1) {
-        debugs(80, 1, "FD " << theWccp2Connection << " Closing WCCPv2 socket");
+        debugs(80, DBG_IMPORTANT, "FD " << theWccp2Connection << " Closing WCCPv2 socket");
         comm_close(theWccp2Connection);
         theWccp2Connection = -1;
     }
@@ -1136,10 +1164,10 @@ wccp2HandleUdp(int sock, void *not_used)
 
     debugs(80, 6, "wccp2HandleUdp: Called.");
 
-    commSetSelect(sock, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0);
+    Comm::SetSelect(sock, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0);
 
     /* FIXME INET6 : drop conversion boundary */
-    IpAddress from_tmp;
+    Ip::Address from_tmp;
 
     len = comm_udp_recvfrom(sock,
                             &wccp2_i_see_you,
@@ -1166,21 +1194,23 @@ wccp2HandleUdp(int sock, void *not_used)
     offset = 0;
 
     if (data_length > len) {
-        debugs(80, 1, "ERROR: Malformed WCCPv2 packet claiming it's bigger than received data");
+        debugs(80, DBG_IMPORTANT, "ERROR: Malformed WCCPv2 packet claiming it's bigger than received data");
         return;
     }
 
     /* Go through the data structure */
     while (data_length > offset) {
 
-        header = (struct wccp2_item_header_t *) &wccp2_i_see_you.data[offset];
+        char *data = wccp2_i_see_you.data;
+
+        header = (struct wccp2_item_header_t *) &data[offset];
 
         switch (ntohs(header->type)) {
 
         case WCCP2_SECURITY_INFO:
 
             if (security_info != NULL) {
-                debugs(80, 1, "Duplicate security definition");
+                debugs(80, DBG_IMPORTANT, "Duplicate security definition");
                 return;
             }
 
@@ -1190,7 +1220,7 @@ wccp2HandleUdp(int sock, void *not_used)
         case WCCP2_SERVICE_INFO:
 
             if (service_info != NULL) {
-                debugs(80, 1, "Duplicate service_info definition");
+                debugs(80, DBG_IMPORTANT, "Duplicate service_info definition");
                 return;
             }
 
@@ -1200,7 +1230,7 @@ wccp2HandleUdp(int sock, void *not_used)
         case WCCP2_ROUTER_ID_INFO:
 
             if (router_identity_info != NULL) {
-                debugs(80, 1, "Duplicate router_identity_info definition");
+                debugs(80, DBG_IMPORTANT, "Duplicate router_identity_info definition");
                 return;
             }
 
@@ -1210,7 +1240,7 @@ wccp2HandleUdp(int sock, void *not_used)
         case WCCP2_RTR_VIEW_INFO:
 
             if (router_view_header != NULL) {
-                debugs(80, 1, "Duplicate router_view definition");
+                debugs(80, DBG_IMPORTANT, "Duplicate router_view definition");
                 return;
             }
 
@@ -1220,7 +1250,7 @@ wccp2HandleUdp(int sock, void *not_used)
         case WCCP2_CAPABILITY_INFO:
 
             if (router_capability_header != NULL) {
-                debugs(80, 1, "Duplicate router_capability definition");
+                debugs(80, DBG_IMPORTANT, "Duplicate router_capability definition");
                 return;
             }
 
@@ -1230,23 +1260,24 @@ wccp2HandleUdp(int sock, void *not_used)
             /* Nothing to do for the types below */
 
         case WCCP2_ASSIGN_MAP:
+        case WCCP2_REDIRECT_ASSIGNMENT:
             break;
 
         default:
-            debugs(80, 1, "Unknown record type in WCCPv2 Packet (" << ntohs(header->type) << ").");
+            debugs(80, DBG_IMPORTANT, "Unknown record type in WCCPv2 Packet (" << ntohs(header->type) << ").");
         }
 
         offset += sizeof(struct wccp2_item_header_t);
         offset += ntohs(header->length);
 
         if (offset > data_length) {
-            debugs(80, 1, "Error: WCCPv2 packet tried to tell us there is data beyond the end of the packet");
+            debugs(80, DBG_IMPORTANT, "Error: WCCPv2 packet tried to tell us there is data beyond the end of the packet");
             return;
         }
     }
 
     if ((security_info == NULL) || (service_info == NULL) || (router_identity_info == NULL) || (router_view_header == NULL)) {
-        debugs(80, 1, "Incomplete WCCPv2 Packet");
+        debugs(80, DBG_IMPORTANT, "Incomplete WCCPv2 Packet");
         return;
     }
 
@@ -1264,17 +1295,17 @@ wccp2HandleUdp(int sock, void *not_used)
     }
 
     if (service_list_ptr == NULL) {
-        debugs(80, 1, "WCCPv2 Unknown service received from router (" << service_info->service_id << ")");
+        debugs(80, DBG_IMPORTANT, "WCCPv2 Unknown service received from router (" << service_info->service_id << ")");
         return;
     }
 
     if (ntohl(security_info->security_option) != ntohl(service_list_ptr->security_info->security_option)) {
-        debugs(80, 1, "Invalid security option in WCCPv2 Packet (" << ntohl(security_info->security_option) << " vs " << ntohl(service_list_ptr->security_info->security_option) << ").");
+        debugs(80, DBG_IMPORTANT, "Invalid security option in WCCPv2 Packet (" << ntohl(security_info->security_option) << " vs " << ntohl(service_list_ptr->security_info->security_option) << ").");
         return;
     }
 
     if (!wccp2_check_security(service_list_ptr, (char *) security_info, (char *) &wccp2_i_see_you, len)) {
-        debugs(80, 1, "Received WCCPv2 Packet failed authentication");
+        debugs(80, DBG_IMPORTANT, "Received WCCPv2 Packet failed authentication");
         return;
     }
 
@@ -1285,7 +1316,7 @@ wccp2HandleUdp(int sock, void *not_used)
     }
 
     if (router_list_ptr->next == NULL) {
-        debugs(80, 1, "WCCPv2 Packet received from unknown router");
+        debugs(80, DBG_IMPORTANT, "WCCPv2 Packet received from unknown router");
         return;
     }
 
@@ -1301,7 +1332,7 @@ wccp2HandleUdp(int sock, void *not_used)
     /* TODO: check return/forwarding methods */
     if (router_capability_header == NULL) {
         if ((Config.Wccp2.return_method != WCCP2_PACKET_RETURN_METHOD_GRE) || (Config.Wccp2.forwarding_method != WCCP2_FORWARDING_METHOD_GRE)) {
-            debugs(80, 1, "wccp2HandleUdp: fatal error - A WCCP router does not support the forwarding method specified, only GRE supported");
+            debugs(80, DBG_IMPORTANT, "wccp2HandleUdp: fatal error - A WCCP router does not support the forwarding method specified, only GRE supported");
             wccp2ConnectionClose();
             return;
         }
@@ -1318,7 +1349,7 @@ wccp2HandleUdp(int sock, void *not_used)
             case WCCP2_CAPABILITY_FORWARDING_METHOD:
 
                 if (!(ntohl(router_capability_element->capability_value) & Config.Wccp2.forwarding_method)) {
-                    debugs(80, 1, "wccp2HandleUdp: fatal error - A WCCP router has specified a different forwarding method " << ntohl(router_capability_element->capability_value) << ", expected " << Config.Wccp2.forwarding_method);
+                    debugs(80, DBG_IMPORTANT, "wccp2HandleUdp: fatal error - A WCCP router has specified a different forwarding method " << ntohl(router_capability_element->capability_value) << ", expected " << Config.Wccp2.forwarding_method);
                     wccp2ConnectionClose();
                     return;
                 }
@@ -1328,7 +1359,7 @@ wccp2HandleUdp(int sock, void *not_used)
             case WCCP2_CAPABILITY_ASSIGNMENT_METHOD:
 
                 if (!(ntohl(router_capability_element->capability_value) & Config.Wccp2.assignment_method)) {
-                    debugs(80, 1, "wccp2HandleUdp: fatal error - A WCCP router has specified a different assignment method " << ntohl(router_capability_element->capability_value) << ", expected "<< Config.Wccp2.assignment_method);
+                    debugs(80, DBG_IMPORTANT, "wccp2HandleUdp: fatal error - A WCCP router has specified a different assignment method " << ntohl(router_capability_element->capability_value) << ", expected "<< Config.Wccp2.assignment_method);
                     wccp2ConnectionClose();
                     return;
                 }
@@ -1338,18 +1369,22 @@ wccp2HandleUdp(int sock, void *not_used)
             case WCCP2_CAPABILITY_RETURN_METHOD:
 
                 if (!(ntohl(router_capability_element->capability_value) & Config.Wccp2.return_method)) {
-                    debugs(80, 1, "wccp2HandleUdp: fatal error - A WCCP router has specified a different return method " << ntohl(router_capability_element->capability_value) << ", expected " << Config.Wccp2.return_method);
+                    debugs(80, DBG_IMPORTANT, "wccp2HandleUdp: fatal error - A WCCP router has specified a different return method " << ntohl(router_capability_element->capability_value) << ", expected " << Config.Wccp2.return_method);
                     wccp2ConnectionClose();
                     return;
                 }
 
                 break;
 
+            case 4:
+            case 5:
+                break; // ignore silently for now
+
             default:
-                debugs(80, 1, "Unknown capability type in WCCPv2 Packet (" << ntohs(router_capability_element->capability_type) << ").");
+                debugs(80, DBG_IMPORTANT, "Unknown capability type in WCCPv2 Packet (" << ntohs(router_capability_element->capability_type) << ").");
             }
 
-            router_capability_element = (struct wccp2_capability_element_t *) (((char *) router_capability_element) + sizeof(struct wccp2_capability_element_header_t) + ntohs(router_capability_element->capability_length));
+            router_capability_element = (struct wccp2_capability_element_t *) (((char *) router_capability_element) + sizeof(struct wccp2_item_header_t) + ntohs(router_capability_element->capability_length));
         }
     }
 
@@ -1390,8 +1425,9 @@ wccp2HandleUdp(int sock, void *not_used)
     if (ntohl(tmp) != 0) {
         /* search through the list of received-from ip addresses */
 
-        for (num_caches = 0; num_caches < (int) ntohl(tmp); num_caches++) {
+        for (num_caches = 0; num_caches < (int) ntohl(tmp); ++num_caches) {
             /* Get a copy of the ip */
+            memset(&cache_address, 0, sizeof(cache_address)); // Make GCC happy
 
             switch (Config.Wccp2.assignment_method) {
 
@@ -1500,12 +1536,12 @@ wccp2HereIam(void *voidnotused)
 
     struct wccp2_mask_identity_info_t *wccp2_mask_identity_info_ptr;
 
-    IpAddress router;
+    Ip::Address router;
 
     debugs(80, 6, "wccp2HereIam: Called");
 
     if (wccp2_connected == 0) {
-        debugs(80, 1, "wccp2HereIam: wccp2 socket closed.  Shutting down WCCP2");
+        debugs(80, DBG_IMPORTANT, "wccp2HereIam: wccp2 socket closed.  Shutting down WCCP2");
         return;
     }
 
@@ -1590,11 +1626,11 @@ wccp2AssignBuckets(void *voidnotused)
     int router_len;
     int bucket_counter;
     uint32_t service_flags;
-    u_short port = WCCP_PORT;
+    unsigned short port = WCCP_PORT;
 
     /* Packet segments */
 
-    struct wccp2_here_i_am_header_t *main_header;
+    struct wccp2_message_header_t *main_header;
 
     struct wccp2_security_md5_t *security = NULL;
     /* service from service struct */
@@ -1629,7 +1665,7 @@ wccp2AssignBuckets(void *voidnotused)
     /* Start main header - fill in length later */
     offset = 0;
 
-    main_header = (struct wccp2_here_i_am_header_t *) &wccp_packet[offset];
+    main_header = (struct wccp2_message_header_t *) &wccp_packet[offset];
     main_header->type = htonl(WCCP2_REDIRECT_ASSIGN);
     main_header->version = htons(WCCP2_VERSION);
 
@@ -1647,7 +1683,7 @@ wccp2AssignBuckets(void *voidnotused)
 
         /* reset the offset */
 
-        offset = sizeof(struct wccp2_here_i_am_header_t);
+        offset = sizeof(struct wccp2_message_header_t);
 
         /* build packet header from hereIam packet */
         /* Security info */
@@ -1723,7 +1759,7 @@ wccp2AssignBuckets(void *voidnotused)
         offset += sizeof(struct assignment_key_t);
 
         /* Number of routers */
-        xmemcpy(&wccp_packet[offset], &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
+        memcpy(&wccp_packet[offset], &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
 
         offset += sizeof(service_list_ptr->num_routers);
 
@@ -1752,18 +1788,18 @@ wccp2AssignBuckets(void *voidnotused)
 
             case WCCP2_ASSIGNMENT_METHOD_HASH:
                 /* Number of caches */
-                xmemcpy(&wccp_packet[offset], &router_list_ptr->num_caches, sizeof(router_list_ptr->num_caches));
+                memcpy(&wccp_packet[offset], &router_list_ptr->num_caches, sizeof(router_list_ptr->num_caches));
                 offset += sizeof(router_list_ptr->num_caches);
 
                 if (num_caches) {
                     int cache;
 
-                    for (cache = 0, cache_list_ptr = &router_list_ptr->cache_list_head; cache_list_ptr->next; cache_list_ptr = cache_list_ptr->next, cache++) {
+                    for (cache = 0, cache_list_ptr = &router_list_ptr->cache_list_head; cache_list_ptr->next; cache_list_ptr = cache_list_ptr->next, ++cache) {
                         /* add caches */
 
                         cache_address = (struct in_addr *) &wccp_packet[offset];
 
-                        xmemcpy(cache_address, &cache_list_ptr->cache_ip, sizeof(struct in_addr));
+                        memcpy(cache_address, &cache_list_ptr->cache_ip, sizeof(struct in_addr));
                         total_weight += cache_list_ptr->weight << 12;
                         weight[cache] = cache_list_ptr->weight << 12;
 
@@ -1778,7 +1814,7 @@ wccp2AssignBuckets(void *voidnotused)
 
                 if (num_caches != 0) {
                     if (total_weight == 0) {
-                        for (bucket_counter = 0; bucket_counter < WCCP_BUCKETS; bucket_counter++) {
+                        for (bucket_counter = 0; bucket_counter < WCCP_BUCKETS; ++bucket_counter) {
                             buckets[bucket_counter] = (char) (bucket_counter % num_caches);
                         }
                     } else {
@@ -1787,18 +1823,18 @@ wccp2AssignBuckets(void *voidnotused)
                         int cache = -1;
                         unsigned long per_bucket = total_weight / WCCP_BUCKETS;
 
-                        for (bucket_counter = 0; bucket_counter < WCCP_BUCKETS; bucket_counter++) {
+                        for (bucket_counter = 0; bucket_counter < WCCP_BUCKETS; ++bucket_counter) {
                             int n;
                             unsigned long step;
 
-                            for (n = num_caches; n; n--) {
-                                cache++;
+                            for (n = num_caches; n; --n) {
+                                ++cache;
 
                                 if (cache >= num_caches)
                                     cache = 0;
 
                                 if (!weight[cache]) {
-                                    n++;
+                                    ++n;
                                     continue;
                                 }
 
@@ -1822,7 +1858,7 @@ wccp2AssignBuckets(void *voidnotused)
 
             case WCCP2_ASSIGNMENT_METHOD_MASK:
                 num_maskval = htonl(1);
-                xmemcpy(&wccp_packet[offset], &num_maskval, sizeof(int));
+                memcpy(&wccp_packet[offset], &num_maskval, sizeof(int));
                 offset += sizeof(int);
 
                 mask_element = (struct wccp2_mask_element_t *) &wccp_packet[offset];
@@ -1859,13 +1895,13 @@ wccp2AssignBuckets(void *voidnotused)
                 cache_list_ptr = &router_list_ptr->cache_list_head;
                 value = 0;
 
-                for (valuecounter = 0; valuecounter < 64; valuecounter++) {
+                for (valuecounter = 0; valuecounter < 64; ++valuecounter) {
 
                     value_element = (struct wccp2_value_element_t *) &wccp_packet[offset];
 
                     /* Update the value according the the "correct" formula */
 
-                    for (; (value & 0x1741) != value; value++) {
+                    for (; (value & 0x1741) != value; ++value) {
                         assert(value <= 0x1741);
                     }
 
@@ -1896,7 +1932,7 @@ wccp2AssignBuckets(void *voidnotused)
                     value_element->cache_ip = cache_list_ptr->cache_ip;
 
                     offset += sizeof(struct wccp2_value_element_t);
-                    value++;
+                    ++value;
 
                     /* Assign the next value to the next cache */
 
@@ -1924,7 +1960,7 @@ wccp2AssignBuckets(void *voidnotused)
 
             /* finish length */
 
-            main_header->length = htons(offset - sizeof(struct wccp2_here_i_am_header_t));
+            main_header->length = htons(offset - sizeof(struct wccp2_message_header_t));
 
             /* set the destination address */
             router.sin_addr = router_list_ptr->router_sendto_address;
@@ -1940,7 +1976,7 @@ wccp2AssignBuckets(void *voidnotused)
 
                 if (wccp2_numrouters > 1) {
                     /* FIXME INET6 : drop temp conversion */
-                    IpAddress tmp_rtr(router);
+                    Ip::Address tmp_rtr(router);
                     comm_udp_sendto(theWccp2Connection,
                                     tmp_rtr,
                                     &wccp_packet,
@@ -1958,7 +1994,6 @@ wccp2AssignBuckets(void *voidnotused)
     }
 }
 
-
 /*
  * Configuration option parsing code
  */
@@ -2072,13 +2107,13 @@ parse_wccp2_service(void *v)
     char wccp_password[WCCP2_PASSWORD_LEN + 1];
 
     if (wccp2_connected == 1) {
-        debugs(80, 1, "WCCPv2: Somehow reparsing the configuration without having shut down WCCP! Try reloading squid again.");
+        debugs(80, DBG_IMPORTANT, "WCCPv2: Somehow reparsing the configuration without having shut down WCCP! Try reloading squid again.");
         return;
     }
 
     /* Snarf the type */
     if ((t = strtok(NULL, w_space)) == NULL) {
-        debugs(80, 0, "wccp2ParseServiceInfo: missing service info type (standard|dynamic)");
+        debugs(80, DBG_CRITICAL, "wccp2ParseServiceInfo: missing service info type (standard|dynamic)");
         self_destruct();
     }
 
@@ -2087,7 +2122,7 @@ parse_wccp2_service(void *v)
     } else if (strcmp(t, "dynamic") == 0) {
         service = WCCP2_SERVICE_DYNAMIC;
     } else {
-        debugs(80, 0, "wccp2ParseServiceInfo: bad service info type (expected standard|dynamic, got " << t << ")");
+        debugs(80, DBG_CRITICAL, "wccp2ParseServiceInfo: bad service info type (expected standard|dynamic, got " << t << ")");
         self_destruct();
     }
 
@@ -2095,7 +2130,7 @@ parse_wccp2_service(void *v)
     service_id = GetInteger();
 
     if (service_id < 0 || service_id > 255) {
-        debugs(80, 0, "wccp2ParseServiceInfo: service info id " << service_id << " is out of range (0..255)");
+        debugs(80, DBG_CRITICAL, "ERROR: invalid WCCP service id " << service_id << " (must be between 0 .. 255)");
         self_destruct();
     }
 
@@ -2232,11 +2267,11 @@ parse_wccp2_service_ports(char *options, int portlist[])
         }
 
         portlist[i] = p;
-        i++;
+        ++i;
         port = strsep(&tmp2, ",");
     }
 
-    if (i == 8) {
+    if (i == WCCP2_NUMPORTS && port) {
         fatalf("parse_wccp2_service_ports: too many ports (maximum: 8) in list '%s'\n", options);
     }
 
@@ -2256,7 +2291,7 @@ parse_wccp2_service_info(void *v)
     int priority = -1;
 
     if (wccp2_connected == 1) {
-        debugs(80, 1, "WCCPv2: Somehow reparsing the configuration without having shut down WCCP! Try reloading squid again.");
+        debugs(80, DBG_IMPORTANT, "WCCPv2: Somehow reparsing the configuration without having shut down WCCP! Try reloading squid again.");
         return;
     }
 
@@ -2266,7 +2301,7 @@ parse_wccp2_service_info(void *v)
     service_id = GetInteger();
 
     if (service_id < 0 || service_id > 255) {
-        debugs(80, 1, "parse_wccp2_service_info: invalid service id " << service_id << " (must be between 0 .. 255)");
+        debugs(80, DBG_CRITICAL, "ERROR: invalid WCCP service id " << service_id << " (must be between 0 .. 255)");
         self_destruct();
     }