---------------------
PatchSet 2086 
Date: 2001/04/25 12:28:59
Author: rbcollins
Branch: generic_modules
Tag: (none) 
Log:
ACL_ARP turned into module

Members: 
	acconfig.h:1.4.18.1->1.4.18.2 
	configure.in:1.17.4.3->1.17.4.4 
	include/squid_parser.h:1.1.2.1->1.1.2.2 
	src/MemPool.c:1.5->1.5.8.1 
	src/acl.c:1.21.4.11->1.21.4.12 
	src/acl.h:1.1.2.1->1.1.2.2 
	src/asn.c:1.9.4.2->1.9.4.3 
	src/cache_cf.c:1.18.4.25->1.18.4.26 
	src/enums.h:1.14.4.5->1.14.4.6 
	src/structs.h:1.24.4.18->1.24.4.19 

Index: squid/acconfig.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/Attic/acconfig.h,v
retrieving revision 1.4.18.1
retrieving revision 1.4.18.2
diff -u -r1.4.18.1 -r1.4.18.2
--- squid/acconfig.h	31 Mar 2001 09:52:18 -0000	1.4.18.1
+++ squid/acconfig.h	25 Apr 2001 12:28:59 -0000	1.4.18.2
@@ -23,7 +23,7 @@
 #ifndef __CONFIGURE_H__
 #define __CONFIGURE_H__
 @TOP@
-/* $Id: acconfig.h,v 1.4.18.1 2001/03/31 09:52:18 rbcollins Exp $ */
+/* $Id: acconfig.h,v 1.4.18.2 2001/04/25 12:28:59 rbcollins Exp $ */
 
 /*********************************
  * START OF CONFIGURABLE OPTIONS *
@@ -110,13 +110,6 @@
 #undef ALARM_UPDATES_TIME
 
 /*
- * Define this to include code which lets you specify access control
- * elements based on ethernet hardware addresses.  This code uses
- * functions found in 4.4 BSD derviations (e.g. FreeBSD, ?).
- */
-#undef USE_ARP_ACL
-
-/*
  * Define this to include code for the Hypertext Cache Protocol (HTCP)
  */
 #undef USE_HTCP
Index: squid/configure.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/configure.in,v
retrieving revision 1.17.4.3
retrieving revision 1.17.4.4
diff -u -r1.17.4.3 -r1.17.4.4
--- squid/configure.in	31 Mar 2001 09:52:18 -0000	1.17.4.3
+++ squid/configure.in	25 Apr 2001 12:28:59 -0000	1.17.4.4
@@ -3,13 +3,13 @@
 dnl
 dnl  Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
 dnl
-dnl  $Id: configure.in,v 1.17.4.3 2001/03/31 09:52:18 rbcollins Exp $
+dnl  $Id: configure.in,v 1.17.4.4 2001/04/25 12:28:59 rbcollins Exp $
 dnl
 dnl
 dnl
 AC_INIT(src/main.c)
 AC_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.17.4.3 $)dnl
+AC_REVISION($Revision: 1.17.4.4 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AC_CONFIG_AUX_DIR(cfgaux)
 
@@ -487,7 +487,7 @@
 	    sleep 10
 	    ;;
      esac
-     AC_DEFINE(USE_ARP_ACL)
+     CONF_MODULES="$CONF_MODULES acl_arp"
    fi
 ])
 
@@ -831,7 +831,7 @@
   no)
     ;;
   *)
-    CONF_MODULES="`echo $enableval|sed -e 's/,/ /g;s/  */ /g'`"
+    CONF_MODULES="$CONF_MODULES `echo $enableval|sed -e 's/,/ /g;s/  */ /g'`"
   esac
 ])
 if test -n "$CONF_MODULES"; then
Index: squid/include/squid_parser.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/Attic/squid_parser.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- squid/include/squid_parser.h	23 Apr 2001 22:28:33 -0000	1.1.2.1
+++ squid/include/squid_parser.h	25 Apr 2001 12:28:59 -0000	1.1.2.2
@@ -134,7 +134,7 @@
 extern void parserAddDocumentOption(const char *option);
 extern int parserDoDocument(const char *file_name);
 extern int parserReconfigure(const char *file_name);
-extern void intlistDestroy(intlist **);
+extern PARSER_FREE free_intlist;
 extern int intlistFind(intlist * list, int i);
 extern const char *wordlistAdd(wordlist **, const char *);
 extern void wordlistAddWl(wordlist **, wordlist *);
@@ -153,6 +153,7 @@
 extern PARSER_PARSE parse_eol;
 extern PARSER_PARSE parse_wordlist;
 extern PARSER_FREE  free_wordlist;
+extern PARSER_DUMP  dump_wordlist;
 extern void requirePathnameExists(const char *name, const char *path);
 extern PARSER_PARSE parse_time_t;
 
Index: squid/src/MemPool.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/MemPool.c,v
retrieving revision 1.5
retrieving revision 1.5.8.1
diff -u -r1.5 -r1.5.8.1
--- squid/src/MemPool.c	12 Jan 2001 08:20:32 -0000	1.5
+++ squid/src/MemPool.c	25 Apr 2001 12:28:59 -0000	1.5.8.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: MemPool.c,v 1.5 2001/01/12 08:20:32 hno Exp $
+ * $Id: MemPool.c,v 1.5.8.1 2001/04/25 12:28:59 rbcollins Exp $
  *
  * DEBUG: section 63    Low Level Memory Pool Management
  * AUTHOR: Alex Rousskov
@@ -118,13 +118,14 @@
     int dirty_count = 0;
     for (i = 0; i < Pools.count; i++) {
 	MemPool *pool = Pools.items[i];
-	if (memPoolInUseCount(pool)) {
-	    memPoolDescribe(pool);
-	    dirty_count++;
-	} else {
-	    memPoolDestroy(pool);
-	    Pools.items[i] = NULL;
-	}
+        if (pool)
+	    if (memPoolInUseCount(pool)) {
+		memPoolDescribe(pool);
+		dirty_count++;
+	    } else {
+		memPoolDestroy(pool);
+		Pools.items[i] = NULL;
+	    }
     }
     if (dirty_count)
 	debug(63, 2) ("memCleanModule: %d pools are left dirty\n", dirty_count);
@@ -221,9 +222,13 @@
 void
 memPoolDestroy(MemPool * pool)
 {
+    int i;
     assert(pool);
     stackClean(&pool->pstack);
     xfree(pool);
+    for (i = 0; i < Pools.count; i++) 
+	if (Pools.items[i]==pool)
+	    Pools.items[i]=NULL;
 }
 
 void *
Index: squid/src/acl.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/acl.c,v
retrieving revision 1.21.4.11
retrieving revision 1.21.4.12
diff -u -r1.21.4.11 -r1.21.4.12
--- squid/src/acl.c	25 Apr 2001 00:22:28 -0000	1.21.4.11
+++ squid/src/acl.c	25 Apr 2001 12:28:59 -0000	1.21.4.12
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.c,v 1.21.4.11 2001/04/25 00:22:28 rbcollins Exp $
+ * $Id: acl.c,v 1.21.4.12 2001/04/25 12:28:59 rbcollins Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -38,8 +38,6 @@
 #include "squid_parser.h"
 #include "acl.h"
 
-typedef int ACLMATCH(void * * , aclCheck_t *);
-
 struct _aclName {
     dlink_node node;
     char * namestr;
@@ -58,23 +56,23 @@
 MemPool * acl_pool = NULL;
 
 static PARSER_PARSE aclParseDomainList;
-static void aclParseUserList(void **current);
+static PARSER_PARSE aclParseUserList;
 static PARSER_PARSE aclParseIpList;
 static PARSER_PARSE aclParseRegexList;
 #if UNUSED_CODE
 static void aclParseIntlist(void *curlist);
 #endif
 #if SQUID_SNMP
-static void aclParseWordList(void *curlist);
+static PARSER_PARSE aclParseWordList;
 #endif
-static void aclParseProtoList(void *curlist);
-static void aclParseMethodList(void *curlist);
+static PARSER_PARSE aclParseProtoList;
+static PARSER_PARSE aclParseMethodList;
 static PARSER_PARSE aclParseTimeSpec;
-static void aclParseIntRange(void *curlist);
+static PARSER_PARSE aclParseIntRange;
 static char *strtokFile(void);
 static void aclDestroyAclList(acl_list * list);
 static PARSER_FREE aclDestroyTimeSpecList;
-static void aclDestroyIntRange(intrange *);
+static PARSER_FREE aclDestroyIntRange;
 static void aclLookupProxyAuthStart(aclCheck_t * checklist);
 static void aclLookupProxyAuthDone(void *data, char *result);
 static struct _acl *aclFindByName(const char *name);
@@ -84,7 +82,6 @@
 static int aclMatchUser(void *proxyauth_acl, char *user);
 static int aclMatchIp(void *, struct in_addr);
 static int aclMatchDomainList(void *dataptr, const char *);
-static int aclMatchIntegerRange(intrange * data, int i);
 #if SQUID_SNMP
 static int aclMatchWordList(wordlist *, const char *);
 #endif
@@ -114,14 +111,6 @@
 static SPLAYWALKEE aclDumpDomainListWalkee;
 static SPLAYFREE aclFreeIpData;
 
-#if USE_ARP_ACL
-static void aclParseArpList(void *curlist);
-static int decode_eth(const char *asc, char *eth);
-static int aclMatchArp(void *dataptr, struct in_addr c);
-static wordlist *aclDumpArpList(void *);
-static SPLAYCMP aclArpCompare;
-static SPLAYWALKEE aclDumpArpListWalkee;
-#endif
 static int aclCacheMatchAcl(dlink_list * cache, squid_acl acltype, void *data, char *MatchParam);
 
 
@@ -138,7 +127,7 @@
 }
 
 
-/* FIXME: this should be merged into cache_cf */
+/* FIXME: should this be merged into cache_cf */
 aclName *
 aclNameByName(const char *name)
 {
@@ -154,7 +143,7 @@
         return NULL;
 }
 
-static aclName * 
+aclName * 
 aclRegisterAclName(const char *namestr, parserTypeNode *parserType, ACLMATCH *Match) {
     aclName *Name;
     if ((Name=aclNameByName(namestr))==NULL) {
@@ -178,11 +167,6 @@
     }
 }
 
-
-
-
-
-
 static char *
 strtokFile(void)
 {
@@ -234,14 +218,13 @@
 static squid_acl
 aclStrToType(const char *s)
 {
+#if 0
     if (!strcmp(s, "src"))
 	return ACL_DYNAMIC; //ACL_SRC_IP;
     if (!strcmp(s, "dst"))
         return ACL_DYNAMIC; //	return ACL_DST_IP;
-//        fatal ("bad acl code\n");
     if (!strcmp(s, "myip"))
         return ACL_DYNAMIC; //	return ACL_MY_IP;
-//        fatal ("bad acl code\n");
     if (!strcmp(s, "domain"))
         return ACL_DYNAMIC; // 	return ACL_DST_DOMAIN;
     if (!strcmp(s, "dstdomain"))
@@ -261,16 +244,16 @@
     if (!strcmp(s, "url_regex"))
         return ACL_DYNAMIC; //	return ACL_URL_REGEX;
     if (!strcmp(s, "port"))
-	return ACL_URL_PORT;
+        return ACL_DYNAMIC; //	return ACL_URL_PORT;
     if (!strcmp(s, "myport"))
-	return ACL_MY_PORT;
+        return ACL_DYNAMIC; //	return ACL_MY_PORT;
     if (!strcmp(s, "maxconn"))
-	return ACL_MAXCONN;
+        return ACL_DYNAMIC; //	return ACL_MAXCONN;
 #if USE_IDENT
     if (!strcmp(s, "ident"))
 	return ACL_IDENT;
     if (!strcmp(s, "ident_regex"))
-	return ACL_IDENT_REGEX;
+        return ACL_DYNAMIC; //	return ACL_IDENT_REGEX;
 #endif
     if (!strncmp(s, "proto", 5))
 	return ACL_PROTO;
@@ -281,7 +264,7 @@
     if (!strcmp(s, "proxy_auth"))
 	return ACL_PROXY_AUTH;
     if (!strcmp(s, "proxy_auth_regex"))
-	return ACL_PROXY_AUTH_REGEX;
+        return ACL_DYNAMIC; //	return ACL_PROXY_AUTH_REGEX;
     if (!strcmp(s, "src_as"))
 	return ACL_SRC_ASN;
     if (!strcmp(s, "dst_as"))
@@ -294,14 +277,7 @@
     if (!strcmp(s, "src_rtt"))
 	return ACL_NETDB_SRC_RTT;
 #endif
-#if USE_ARP_ACL
-    if (!strcmp(s, "arp"))
-	return ACL_SRC_ARP;
 #endif
-    if (!strcmp(s, "req_mime_type"))
-        return ACL_DYNAMIC; //	return ACL_REQ_MIME_TYPE;
-    if (!strcmp(s, "rep_mime_type"))
-        return ACL_DYNAMIC; //	return ACL_REP_MIME_TYPE;
     return ACL_NONE;
 }
 
@@ -310,6 +286,7 @@
 {
     if (type == ACL_DYNAMIC)
 	fatal("dynamic acl encountered\n");
+#if 0
     if (type == ACL_SRC_IP)
 	return "src???";
     if (type == ACL_DST_IP)
@@ -331,16 +308,16 @@
     if (type == ACL_URL_REGEX)
 	return "url_regex??";
     if (type == ACL_URL_PORT)
-	return "port";
+	return "port??";
     if (type == ACL_MY_PORT)
-	return "myport";
+	return "myport??";
     if (type == ACL_MAXCONN)
-	return "maxconn";
+	return "maxconn???";
 #if USE_IDENT
     if (type == ACL_IDENT)
-	return "ident";
+	return "ident???";
     if (type == ACL_IDENT_REGEX)
-	return "ident_regex";
+	return "ident_regex???";
 #endif
     if (type == ACL_PROTO)
 	return "proto";
@@ -351,7 +328,7 @@
     if (type == ACL_PROXY_AUTH)
 	return "proxy_auth";
     if (type == ACL_PROXY_AUTH_REGEX)
-	return "proxy_auth_regex";
+	return "proxy_auth_regex????";
     if (type == ACL_SRC_ASN)
 	return "src_as";
     if (type == ACL_DST_ASN)
@@ -364,14 +341,7 @@
     if (type == ACL_NETDB_SRC_RTT)
 	return "src_rtt";
 #endif
-#if USE_ARP_ACL
-    if (type == ACL_SRC_ARP)
-	return "arp";
 #endif
-    if (type == ACL_REQ_MIME_TYPE)
-	return "req_mime_type???";
-    if (type == ACL_REP_MIME_TYPE)
-	return "rep_mime_type???";
     return "ERROR";
 }
 
@@ -410,7 +380,7 @@
 #endif
 
 static void
-aclParseIntRange(void *curlist)
+aclParseIntRange(parserNameNode *parserName, void *curlist)
 {
     intrange **Tail;
     intrange *q = NULL;
@@ -430,7 +400,7 @@
 }
 
 static void
-aclParseProtoList(void *curlist)
+aclParseProtoList(parserNameNode *parserName, void *curlist)
 {
     intlist **Tail;
     intlist *q = NULL;
@@ -445,7 +415,7 @@
 }
 
 static void
-aclParseMethodList(void *curlist)
+aclParseMethodList(parserNameNode *parserName, void *curlist)
 {
     intlist **Tail;
     intlist *q = NULL;
@@ -732,8 +702,9 @@
 }
 
 #if SQUID_SNMP
+// TODO: Move strtokFile into cache_cf, then this function can go away.
 static void
-aclParseWordList(void *curlist)
+aclParseWordList(parserNameNode *parserName, void *curlist)
 {
     char *t = NULL;
     while ((t = strtokFile()))
@@ -742,8 +713,9 @@
 #endif
 
 static void
-aclParseUserList(void **current)
+aclParseUserList(parserNameNode *parserName, void *curlist)
 {
+    void **current= curlist;
     char *t = NULL;
     acl_user_data *data;
     splayNode *Top = NULL;
@@ -803,6 +775,7 @@
 aclParseAclLine(parserNameNode *parserName, void *data)
 {
     acl ** head=(acl **)data;
+    aclName *aclname;
 
     /* we're already using strtok() to grok the line */
     char *token = NULL;
@@ -831,7 +804,14 @@
 	return;
     }
 
-    if ((acltype = aclStrToType(token)) == ACL_NONE) {
+    /* is there a aclname for this? */
+    debug (28,0) ("acl name string %s\n",token);
+    aclname = aclNameByName(token);
+    if (aclname) {
+        acltype = ACL_DYNAMIC;
+        parserType=aclname->type;
+        debug (28,0) ("found parserType %s\n",parserType->typestr);
+    } else if ((acltype = aclStrToType(token)) == ACL_NONE) {
 	debug(28, 0) ("%s line %d: %s\n",
 	    cfg_filename, config_lineno, config_input_line);
 	debug(28, 0) ("aclParseAclLine: Invalid ACL type '%s'\n", token);
@@ -867,16 +847,8 @@
 	A->type = acltype;
 	A->cfgline = xstrdup(config_input_line);
 	new_acl = 1;
-
-if (acltype == ACL_DYNAMIC) {
-    debug (28,0) ("acl name string %s\n",token);
-    A->aclname = aclNameByName(token);
-    assert (A->aclname);
-
-    parserType=A->aclname->type;
-    debug (28,0) ("found parserType %s\n",parserType->typestr);
-}
-
+	if (acltype == ACL_DYNAMIC) 
+	    A->aclname=aclname; 
     } else {
 	if (acltype != A->type) {
 	    debug(28, 0) ("aclParseAclLine: ACL '%s' already exists with different type, skipping.\n", A->name);
@@ -916,31 +888,28 @@
     case ACL_DST_DOM_REGEX:
     case ACL_URL_REGEX:
     case ACL_URLPATH_REGEX:
-    case ACL_BROWSER:
     case ACL_REQ_MIME_TYPE:
     case ACL_REP_MIME_TYPE:
+#if USE_IDENT
+    case ACL_IDENT:
+    case ACL_IDENT_REGEX:
+#endif
+    case ACL_PROXY_AUTH:
+    case ACL_PROXY_AUTH_REGEX:
     case ACL_TIME:
-        fatal("You hurt my feelings \n");
-	break;
+    case ACL_METHOD:
     case ACL_SRC_ASN:
-    case ACL_MAXCONN:
     case ACL_DST_ASN:
 #if SRC_RTT_NOT_YET_FINISHED
     case ACL_NETDB_SRC_RTT:
-	aclParseIntlist(&A->data);
-	break;
 #endif
-    case ACL_URL_PORT:
-    case ACL_MY_PORT:
-	aclParseIntRange(&A->data);
+        fatal("You hurt my feelings \n");
 	break;
+#if 0
 #if USE_IDENT
     case ACL_IDENT:
 	aclParseUserList(&A->data);
 	break;
-    case ACL_IDENT_REGEX:
-	aclParseRegexList(parserName, &A->data);
-	break;
 #endif
     case ACL_PROTO:
 	aclParseProtoList(&A->data);
@@ -948,6 +917,7 @@
     case ACL_METHOD:
 	aclParseMethodList(&A->data);
 	break;
+// FIXME: Move the check code below into a post-parse check.
     case ACL_PROXY_AUTH:
 	if (authenticateSchemeCount() == 0) {
 	    debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL '%s' \
@@ -956,9 +926,10 @@
 	    debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL '%s' \
 because no authentication schemes are fully configured.\n", A->cfgline);
 	} else {
-	    aclParseUserList(&A->data);
+	    aclParseUserList(parserName, &A->data);
 	}
 	break;
+// FIXME: Move the check code below into a post-parse check.
     case ACL_PROXY_AUTH_REGEX:
 	if (authenticateSchemeCount() == 0) {
 	    debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL '%s' \
@@ -970,15 +941,6 @@
 	    aclParseRegexList(parserName, &A->data);
 	}
 	break;
-#if SQUID_SNMP
-    case ACL_SNMP_COMMUNITY:
-	aclParseWordList(&A->data);
-	break;
-#endif
-#if USE_ARP_ACL
-    case ACL_SRC_ARP:
-	aclParseArpList(&A->data);
-	break;
 #endif
     case ACL_NONE:
     case ACL_ENUM_MAX:
@@ -1395,6 +1357,149 @@
     return aclMatchRegex(*dataptr, header);
 }
 
+static int
+aclMatchIdent(void * *dataptr, aclCheck_t * checklist)
+{
+    if (checklist->rfc931[0]) {
+        return aclMatchUser(*dataptr, checklist->rfc931);
+    } else {
+        checklist->state[ACL_IDENT] = ACL_LOOKUP_NEEDED;
+        return 0;
+    }
+}
+
+static int
+aclMatchIdentRegex(void * *dataptr, aclCheck_t * checklist)
+{
+    if (checklist->rfc931[0]) {
+        return aclMatchRegex(*dataptr, checklist->rfc931);
+    } else {
+        checklist->state[ACL_IDENT] = ACL_LOOKUP_NEEDED;
+        return 0;
+    }
+}
+
+static int
+aclMatchProxyAuth(void *data, http_hdr_type headertype,
+    auth_user_request_t * auth_user_request, aclCheck_t * checklist,
+    squid_acl acltype);
+
+static int
+aclMatchProxyAuthModule(void * *dataptr, aclCheck_t * checklist)
+{
+    request_t *r = checklist->request;
+    http_hdr_type headertype;
+    if (NULL == r) {
+        return -1;
+    } else if (!r->flags.accelerated) {
+        /* Proxy authorization on proxy requests */
+        headertype = HDR_PROXY_AUTHORIZATION;
+    } else if (r->flags.internal) {
+        /* WWW authorization on accelerated internal requests */
+        headertype = HDR_AUTHORIZATION;
+    } else {
+#if AUTH_ON_ACCELERATION
+        /* WWW authorization on accelerated requests */
+        headertype = HDR_AUTHORIZATION;
+#else
+//FIXME
+        debug(28, 1) ("aclMatchAcl: proxy_auth acls not applicable on accelerated requests.\n");
+        return -1;
+#endif
+    }
+    /* Check the credentials */
+    switch (aclMatchProxyAuth(*dataptr, headertype,
+            checklist->auth_user_request, checklist, ACL_PROXY_AUTH_REGEX)) {
+    case 0:
+        debug(28, 4) ("aclMatchAcl: returning  0 user authenticated but not authorised.\n");
+        /* Authenticated but not Authorised for this ACL */
+        return 0;
+    case 1:
+        debug(28, 4) ("aclMatchAcl: returning  1 user authenticated and authorised.\n");
+        /* Authenticated and Authorised for this ACL */
+        return 1;
+    case -2:
+        debug(28, 4) ("aclMatchAcl: returning 0 sending authentication challenge.\n");
+        /* Authentication credentials invalid or missing. */
+        /* Or partway through NTLM handshake. A proxy_Authenticate header
+         * gets sent to the client. */
+        checklist->state[ACL_PROXY_AUTH] = ACL_PROXY_AUTH_NEEDED;
+        return 0;
+    case -1:
+        debug(28, 4) ("aclMatchAcl: returning 0 sending credentials to helper.\n");
+        /*
+         * we need to validate the password
+         */
+        checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_NEEDED;
+        return 0;
+    default:
+	return 0;
+    }
+}
+
+// FIXME this function and the above one should be merged - the parsernode should be passed through.
+static int
+aclMatchProxyAuthModuleB(void * *dataptr, aclCheck_t * checklist)
+{
+    request_t *r = checklist->request;
+    http_hdr_type headertype;
+    if (NULL == r) {
+        return -1;
+    } else if (!r->flags.accelerated) {
+        /* Proxy authorization on proxy requests */
+        headertype = HDR_PROXY_AUTHORIZATION;
+    } else if (r->flags.internal) {
+        /* WWW authorization on accelerated internal requests */
+        headertype = HDR_AUTHORIZATION;
+    } else {
+#if AUTH_ON_ACCELERATION
+        /* WWW authorization on accelerated requests */
+        headertype = HDR_AUTHORIZATION;
+#else
+//FIXME
+        debug(28, 1) ("aclMatchAcl: proxy_auth acls not applicable on accelerated requests.\n");
+        return -1;
+#endif
+    }
+    /* Check the credentials */
+    switch (aclMatchProxyAuth(*dataptr, headertype,
+            checklist->auth_user_request, checklist, ACL_PROXY_AUTH)) {
+    case 0:
+        debug(28, 4) ("aclMatchAcl: returning  0 user authenticated but not authorised.\n");
+        /* Authenticated but not Authorised for this ACL */
+        return 0;
+    case 1:
+        debug(28, 4) ("aclMatchAcl: returning  1 user authenticated and authorised.\n");
+        /* Authenticated and Authorised for this ACL */
+        return 1;
+    case -2:
+        debug(28, 4) ("aclMatchAcl: returning 0 sending authentication challenge.\n");
+        /* Authentication credentials invalid or missing. */
+        /* Or partway through NTLM handshake. A proxy_Authenticate header
+         * gets sent to the client. */
+        checklist->state[ACL_PROXY_AUTH] = ACL_PROXY_AUTH_NEEDED;
+        return 0;
+    case -1:
+        debug(28, 4) ("aclMatchAcl: returning 0 sending credentials to helper.\n");
+        /*
+         * we need to validate the password
+         */
+        checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_NEEDED;
+        return 0;
+    default:
+        return 0;
+    }
+}
+
+static int
+aclMatchMaxConn(void * *dataptr, aclCheck_t * checklist)
+{
+    int k;
+    k = clientdbEstablished(checklist->src_addr, 0);
+    // FIXME we should drop the connection this request was made on or all other
+    // Requests will fail until the link times out.
+    return ((k > *(int *) dataptr) ? 1 : 0);
+}
 
 static int
 aclMatchUser(void *proxyauth_acl, char *user)
@@ -1465,6 +1570,7 @@
 	break;
     case ACL_PROXY_AUTH_REGEX:
 	matchrv = aclMatchRegex(data, MatchParam);
+	break;
     default:
 	/* This is a fatal to ensure that aclCacheMatchAcl calls are _only_
 	 * made for supported acl types */
@@ -1742,6 +1848,24 @@
     return aclMatchTimeSpec(*dataptr, squid_curtime);
 }
 
+static int
+aclMatchUrlPort(void * *dataptr, aclCheck_t * checklist)
+{
+    request_t *r = checklist->request;
+    if (NULL == r) {
+        debug(28, 1) ("WARNING: 'req_mime_type' ACL is used but there is no"
+            " HTTP request -- access denied.\n");
+        return 0;
+    }
+    return aclMatchIntegerRange(*dataptr, (int) r->port);
+}
+
+static int
+aclMatchMyPort(void * *dataptr, aclCheck_t * checklist)
+{
+    return aclMatchIntegerRange(*dataptr, (int) checklist->my_port);
+}
+
 #if SQUID_SNMP
 static int
 aclMatchWordList(wordlist * w, const char *word)
@@ -1755,28 +1879,96 @@
     }
     return 0;
 }
+
+static int
+aclMatchSNMPCommunity(void **dataptr, aclCheck_t *checklist)
+{
+    return aclMatchWordList(*dataptr, checklist->snmp_community);
+}
 #endif
 
+static int 
+aclMatchProto(void **dataptr, aclCheck_t *checklist)
+{
+    request_t *r = checklist->request;
+    if (NULL == r) {
+        debug(28, 1) ("WARNING: 'proto' ACL is used but there is no"
+            " HTTP request -- access denied.\n");
+        return 0;
+    }
+    return aclMatchInteger(*dataptr, r->protocol);
+}
+
 static int
-aclMatchAcl(acl * ae, aclCheck_t * checklist)
+aclMatchMethod(void **dataptr, aclCheck_t *checklist)
+{
+    request_t *r = checklist->request;
+    if (NULL == r) {
+        debug(28, 1) ("WARNING: 'method' ACL is used but there is no"
+            " HTTP request -- access denied.\n");
+        return 0;
+    }
+    return aclMatchInteger(*dataptr, r->method);
+}
+
+
+static int
+aclMatchSrcAsn(void **dataptr, aclCheck_t *checklist)
+{
+    return asnMatchIp(*dataptr, checklist->src_addr);
+}
+
+static int
+aclMatchDstAsn(void **dataptr, aclCheck_t *checklist)
 {
     request_t *r = checklist->request;
     const ipcache_addrs *ia = NULL;
+    int k;
+    if (NULL == r) {
+        debug(28, 1) ("WARNING: 'dst_asn' ACL is used but there is no"
+            " HTTP request -- access denied.\n");
+        return 0;
+    }
+
+    ia = ipcache_gethostbyname(r->host, IP_LOOKUP_IF_MISS);
+    if (ia) {
+        for (k = 0; k < (int) ia->count; k++) {
+            if (asnMatchIp(*dataptr, ia->in_addrs[k]))
+                return 1;
+        }
+        return 0;
+    } else if (checklist->state[ACL_DST_ASN] == ACL_LOOKUP_NONE) {
+//FIXME        debug(28, 3) ("asnMatchAcl: Can't yet compare '%s' ACL for '%s'\n",
+//            ae->name, r->host);
+        checklist->state[ACL_DST_ASN] = ACL_LOOKUP_NEEDED;
+    } else {
+        return asnMatchIp(*dataptr, no_addr);
+    }
+    return 0;
+}
+
+
+static int
+aclMatchAcl(acl * ae, aclCheck_t * checklist)
+{
 #if 0
+    request_t *r = checklist->request;
+    const ipcache_addrs *ia = NULL;
     const char *fqdn = NULL;
     char *esc_buf;
     const char *header;
     const char *browser;
-#endif
     int k;
     http_hdr_type headertype;
+#endif
     if (!ae)
 	return 0;
+#if 0
     switch (ae->type) {
-//    case ACL_DST_IP:
-//    case ACL_DST_DOMAIN:
-//    case ACL_DST_DOM_REGEX:
-//    case ACL_URLPATH_REGEX:
+    case ACL_DST_IP:
+    case ACL_DST_DOMAIN:
+    case ACL_DST_DOM_REGEX:
+    case ACL_URLPATH_REGEX:
     case ACL_URL_PORT:
     case ACL_PROTO:
     case ACL_METHOD:
@@ -1791,6 +1983,7 @@
     default:
 	break;
     }
+#endif
     debug(28, 3) ("aclMatchAcl: checking '%s'\n", ae->cfgline);
     switch (ae->type) {
     case ACL_DYNAMIC:
@@ -1804,10 +1997,18 @@
     case ACL_SRC_DOM_REGEX:
     case ACL_URLPATH_REGEX:
     case ACL_URL_REGEX:
-    case ACL_BROWSER:
     case ACL_REQ_MIME_TYPE:
     case ACL_REP_MIME_TYPE:
     case ACL_TIME:
+#if USE_IDENT
+    case ACL_IDENT:
+    case ACL_IDENT_REGEX:
+#endif
+    case ACL_PROXY_AUTH:
+    case ACL_PROXY_AUTH_REGEX:
+    case ACL_METHOD:
+    case ACL_SRC_ASN:
+    case ACL_DST_ASN:
 	fatal("old code\n");
 #if 0
 	return aclMatchIp(&ae->data, checklist->src_addr);
@@ -1899,7 +2100,6 @@
 	safe_free(esc_buf);
 	return k;
 	/* NOTREACHED */
-#endif
     case ACL_MAXCONN:
 	k = clientdbEstablished(checklist->src_addr, 0);
 	return ((k > ((intlist *) ae->data)->i) ? 1 : 0);
@@ -1934,16 +2134,7 @@
     case ACL_METHOD:
 	return aclMatchInteger(ae->data, r->method);
 	/* NOTREACHED */
-#if 0
-    case ACL_BROWSER:
-	browser = httpHeaderGetStr(&checklist->request->header, HDR_USER_AGENT);
-	if (NULL == browser)
-	    return 0;
-	return aclMatchRegex(ae->data, browser);
-	/* NOTREACHED */
-#endif
     case ACL_PROXY_AUTH:
-    case ACL_PROXY_AUTH_REGEX:
 	if (NULL == r) {
 	    return -1;
 	} else if (!r->flags.accelerated) {
@@ -2010,9 +2201,6 @@
 	    return asnMatchIp(ae->data, no_addr);
 	}
 	return 0;
-#if USE_ARP_ACL
-    case ACL_SRC_ARP:
-	return aclMatchArp(&ae->data, checklist->src_addr);
 #endif
 #if 0
     case ACL_REQ_MIME_TYPE:
@@ -2377,7 +2565,7 @@
 }
 
 static void
-aclFreeUserData(void *data)
+aclDestroyUserList(parserNameNode *parserName, void *data)
 {
     acl_user_data *d = data;
     if (d->names)
@@ -2385,7 +2573,6 @@
     memFree(d, MEM_ACL_USER_DATA);
 }
 
-
 void
 aclDestroyAcls(acl ** head)
 {
@@ -2403,25 +2590,34 @@
         case ACL_DST_DOM_REGEX:
         case ACL_URL_REGEX:
         case ACL_URLPATH_REGEX:
-        case ACL_BROWSER:
         case ACL_REP_MIME_TYPE:
         case ACL_REQ_MIME_TYPE:
         case ACL_TIME:
+#if USE_IDENT
+	case ACL_IDENT:
+        case ACL_IDENT_REGEX:
+#endif
+	case ACL_PROXY_AUTH:
+        case ACL_PROXY_AUTH_REGEX:
+        case ACL_METHOD:
+        case ACL_SRC_ASN:
+        case ACL_DST_ASN:
 	    fatal("old code somewhere!\n");
 #if 0
 	    splay_destroy(a->data, aclFreeIpData);
 #endif
 	    break;
-#if USE_ARP_ACL
-	case ACL_SRC_ARP:
-#endif
 	case ACL_DST_DOMAIN:
 	case ACL_SRC_DOMAIN:
+#if SRC_RTT_NOT_YET_FINISHED
+        case ACL_NETDB_SRC_RTT:
+#endif
             fatal("old code somewhere!\n");
 #if 0
 	    splay_destroy(a->data, xfree);
 #endif
 	    break;
+#if 0
 #if SQUID_SNMP
 	case ACL_SNMP_COMMUNITY:
 	    wordlistDestroy((wordlist **) & a->data);
@@ -2433,33 +2629,16 @@
 	    break;
 #endif
 	case ACL_PROXY_AUTH:
-	    aclFreeUserData(a->data);
-	    break;
-#if 0
-	case ACL_TIME:
-	    aclDestroyTimeList(a->data);
-	    break;
-#endif
-#if USE_IDENT
-	case ACL_IDENT_REGEX:
-#endif
-	case ACL_PROXY_AUTH_REGEX:
-	    aclDestroyRegexList(NULL, a->data);
+	    aclDestroyUserList(NULL, a->data);
 	    break;
 	case ACL_PROTO:
 	case ACL_METHOD:
-	case ACL_SRC_ASN:
-	case ACL_DST_ASN:
 #if SRC_RTT_NOT_YET_FINISHED
 	case ACL_NETDB_SRC_RTT:
 #endif
-	case ACL_MAXCONN:
-	    intlistDestroy((intlist **) & a->data);
-	    break;
-	case ACL_URL_PORT:
-	case ACL_MY_PORT:
-	    aclDestroyIntRange(a->data);
+	    free_intlist(NULL, (intlist **) & a->data);
 	    break;
+#endif
 	case ACL_NONE:
 	case ACL_ENUM_MAX:
 	    debug(28, 1) ("aclDestroyAcls: no case for ACL type %d\n", a->type);
@@ -2522,8 +2701,9 @@
 }
 
 static void
-aclDestroyIntRange(intrange * list)
+aclDestroyIntRange(parserNameNode *parserName, void * data)
 {
+    intrange * list = data;
     intrange *w = NULL;
     intrange *n = NULL;
     for (w = list; w; w = n) {
@@ -2773,43 +2953,19 @@
     case ACL_DST_DOM_REGEX:
     case ACL_URL_REGEX:
     case ACL_URLPATH_REGEX:
-    case ACL_BROWSER:
     case ACL_REQ_MIME_TYPE:
     case ACL_REP_MIME_TYPE:
-    case ACL_TIME:
-        fatal("old code in Dump\n");
-#if 0
-	return aclDumpDomainList(a->data);
-#endif
-#if SQUID_SNMP
-    case ACL_SNMP_COMMUNITY:
-	return wordlistDup(a->data);
-#endif
 #if USE_IDENT
     case ACL_IDENT:
-	return aclDumpUserList(a->data);
     case ACL_IDENT_REGEX:
-	return aclDumpRegexList(a->data);
 #endif
     case ACL_PROXY_AUTH:
-	return aclDumpUserList(a->data);
     case ACL_PROXY_AUTH_REGEX:
-	return aclDumpRegexList(a->data);
+    case ACL_TIME:
+    case ACL_METHOD:
     case ACL_SRC_ASN:
-    case ACL_MAXCONN:
     case ACL_DST_ASN:
-	return aclDumpIntlistList(a->data);
-    case ACL_URL_PORT:
-    case ACL_MY_PORT:
-	return aclDumpIntRangeList(a->data);
-    case ACL_PROTO:
-	return aclDumpProtoList(a->data);
-    case ACL_METHOD:
-	return aclDumpMethodList(a->data);
-#if USE_ARP_ACL
-    case ACL_SRC_ARP:
-	return aclDumpArpList(a->data);
-#endif
+        fatal("old code in Dump\n");
     case ACL_NONE:
     case ACL_ENUM_MAX:
 	break;
@@ -2910,409 +3066,146 @@
     }
 }
 
-/*
- * This function traverses all ACL elements referenced
- * by an access list (presumably 'http_access').   If 
- * it finds a PURGE method ACL, then it returns TRUE,
- * otherwise FALSE.
- */
-int
-aclPurgeMethodInUse(acl_access * a)
+static void
+dump_intlistList(StoreEntry * entry, const char *name, void const * const data)
 {
-    acl_list *b;
-    for (; a; a = a->next) {
-	for (b = a->acl_list; b; b = b->next) {
-	    if (ACL_METHOD != b->acl->type)
-		continue;
-	    if (aclMatchInteger(b->acl->data, METHOD_PURGE))
-		return 1;
-	}
+    acl * ae=*(acl * *)data;
+    wordlist *w;
+    wordlist *v;
+    while (ae != NULL) {
+        debug(3, 3) ("dump_intlistList: %s %s\n", name, ae->name);
+        v = w = aclDumpIntlistList(ae->data);
+        while (v != NULL) {
+            debug(3, 3) ("dump_intlistList: %s %s %s\n", name, ae->name, v->key);
+            storeAppendPrintf(entry, "%s %s %s %s\n",
+                name,
+                ae->name,
+                aclTypeToStr(ae->type),
+                v->key);
+            v = v->next;
+        }
+        wordlistDestroy(&w);
+        ae = ae->next;
     }
-    return 0;
 }
 
-
-#if USE_ARP_ACL
-/* ==== BEGIN ARP ACL SUPPORT ============================================= */
-
-/*
- * From:    dale@server.ctam.bitmcnit.bryansk.su (Dale)
- * To:      wessels@nlanr.net
- * Subject: Another Squid patch... :)
- * Date:    Thu, 04 Dec 1997 19:55:01 +0300
- * ============================================================================
- * 
- * Working on setting up a proper firewall for a network containing some
- * Win'95 computers at our Univ, I've discovered that some smart students
- * avoid the restrictions easily just changing their IP addresses in Win'95
- * Contol Panel... It has been getting boring, so I took Squid-1.1.18
- * sources and added a new acl type for hard-wired access control:
- * 
- * acl <name> arp <Ethernet address> ...
- * 
- * For example,
- * 
- * acl students arp 00:00:21:55:ed:22 00:00:21:ff:55:38
- *
- * NOTE: Linux code by David Luyer <luyer@ucs.uwa.edu.au>.
- *       Original (BSD-specific) code no longer works.
- *       Solaris code by R. Gancarz <radekg@solaris.elektrownia-lagisza.com.pl>
- */
-
-#ifdef _SQUID_SOLARIS_
-#include <sys/sockio.h>
-#else
-#include <sys/sysctl.h>
-#endif
-#ifdef _SQUID_LINUX_
-#include <net/if_arp.h>
-#include <sys/ioctl.h>
-#else
-#include <net/if_dl.h>
-#endif
-#include <net/route.h>
-#include <net/if.h>
-#if HAVE_NETINET_IF_ETHER_H
-#include <netinet/if_ether.h>
-#endif
-
-/*
- * Decode an ascii representation (asc) of an ethernet adress, and place
- * it in eth[6].
- */
-static int
-decode_eth(const char *asc, char *eth)
+static void
+dump_IntRangeList(StoreEntry * entry, const char *name, void const * const data)
 {
-    int a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0;
-    if (sscanf(asc, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6) {
-	debug(28, 0) ("decode_eth: Invalid ethernet address '%s'\n", asc);
-	return 0;		/* This is not valid address */
+    acl * ae=*(acl * *)data;
+    wordlist *w;
+    wordlist *v;
+    while (ae != NULL) {
+        debug(3, 3) ("dump_IntRangeList: %s %s\n", name, ae->name);
+        v = w = aclDumpIntRangeList(ae->data);
+        while (v != NULL) {
+            debug(3, 3) ("dump_IntRangeList: %s %s %s\n", name, ae->name, v->key);
+            storeAppendPrintf(entry, "%s %s %s %s\n",
+                name,
+                ae->name,
+                aclTypeToStr(ae->type),
+                v->key);
+            v = v->next;
+        }
+        wordlistDestroy(&w);
+        ae = ae->next;
     }
-    eth[0] = (u_char) a1;
-    eth[1] = (u_char) a2;
-    eth[2] = (u_char) a3;
-    eth[3] = (u_char) a4;
-    eth[4] = (u_char) a5;
-    eth[5] = (u_char) a6;
-    return 1;
 }
 
-static acl_arp_data *
-aclParseArpData(const char *t)
+static void
+dump_UserList(StoreEntry * entry, const char *name, void const * const data)
 {
-    LOCAL_ARRAY(char, eth, 256);
-    acl_arp_data *q = xcalloc(1, sizeof(acl_arp_data));
-    debug(28, 5) ("aclParseArpData: %s\n", t);
-    if (sscanf(t, "%[0-9a-fA-F:]", eth) != 1) {
-	debug(28, 0) ("aclParseArpData: Bad ethernet address: '%s'\n", t);
-	safe_free(q);
-	return NULL;
-    }
-    if (!decode_eth(eth, q->eth)) {
-	debug(28, 0) ("%s line %d: %s\n",
-	    cfg_filename, config_lineno, config_input_line);
-	debug(28, 0) ("aclParseArpData: Ignoring invalid ARP acl entry: can't parse '%s'\n", eth);
-	safe_free(q);
-	return NULL;
+    acl * ae=*(acl * *)data;
+    wordlist *w;
+    wordlist *v;
+    while (ae != NULL) {
+        debug(3, 3) ("dump_UserList: %s %s\n", name, ae->name);
+        v = w = aclDumpUserList(ae->data);
+        while (v != NULL) {
+            debug(3, 3) ("dump_UserList: %s %s %s\n", name, ae->name, v->key);
+            storeAppendPrintf(entry, "%s %s %s %s\n",
+                name,
+                ae->name,
+                aclTypeToStr(ae->type),
+                v->key);
+            v = v->next;
+        }
+        wordlistDestroy(&w);
+        ae = ae->next;
     }
-    return q;
 }
 
-
-/*******************/
-/* aclParseArpList */
-/*******************/
 static void
-aclParseArpList(void *curlist)
+dump_ProtoList(StoreEntry * entry, const char *name, void const * const data)
 {
-    char *t = NULL;
-    splayNode **Top = curlist;
-    acl_arp_data *q = NULL;
-    while ((t = strtokFile())) {
-	if ((q = aclParseArpData(t)) == NULL)
-	    continue;
-	*Top = splay_insert(q, *Top, aclArpCompare);
+    acl * ae=*(acl * *)data;
+    wordlist *w;
+    wordlist *v;
+    while (ae != NULL) {
+        debug(3, 3) ("dump_ProtoList: %s %s\n", name, ae->name);
+        v = w = aclDumpProtoList(ae->data);
+        while (v != NULL) {
+            debug(3, 3) ("dump_ProtoList: %s %s %s\n", name, ae->name, v->key);
+            storeAppendPrintf(entry, "%s %s %s %s\n",
+                name,
+                ae->name,
+                aclTypeToStr(ae->type),
+                v->key);
+            v = v->next;
+        }
+        wordlistDestroy(&w);
+        ae = ae->next;
     }
 }
 
-/***************/
-/* aclMatchArp */
-/***************/
-static int
-aclMatchArp(void *dataptr, struct in_addr c)
+static void
+dump_MethodList(StoreEntry * entry, const char *name, void const * const data)
 {
-#if defined(_SQUID_LINUX_)
-    struct arpreq arpReq;
-    struct sockaddr_in ipAddr;
-    unsigned char ifbuffer[sizeof(struct ifreq) * 64];
-    struct ifconf ifc;
-    struct ifreq *ifr;
-    int offset;
-    splayNode **Top = dataptr;
-    /*
-     * The linux kernel 2.2 maintains per interface ARP caches and
-     * thus requires an interface name when doing ARP queries.
-     * 
-     * The older 2.0 kernels appear to use a unified ARP cache,
-     * and require an empty interface name
-     * 
-     * To support both, we attempt the lookup with a blank interface
-     * name first. If that does not succeed, the try each interface
-     * in turn
-     */
-    /*
-     * Set up structures for ARP lookup with blank interface name
-     */
-    ipAddr.sin_family = AF_INET;
-    ipAddr.sin_port = 0;
-    ipAddr.sin_addr = c;
-    memset(&arpReq, '\0', sizeof(arpReq));
-    xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
-    /* Query ARP table */
-    if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) {
-	/* Skip non-ethernet interfaces */
-	if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) {
-	    return 0;
-	}
-	debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n",
-	    arpReq.arp_ha.sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff,
-	    arpReq.arp_ha.sa_data[2] & 0xff, arpReq.arp_ha.sa_data[3] & 0xff,
-	    arpReq.arp_ha.sa_data[4] & 0xff, arpReq.arp_ha.sa_data[5] & 0xff);
-	/* Do lookup */
-	*Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);
-	debug(28, 3) ("aclMatchArp: '%s' %s\n",
-	    inet_ntoa(c), splayLastResult ? "NOT found" : "found");
-	return (0 == splayLastResult);
-    }
-    /* lookup list of interface names */
-    ifc.ifc_len = sizeof(ifbuffer);
-    ifc.ifc_buf = ifbuffer;
-    if (ioctl(HttpSockets[0], SIOCGIFCONF, &ifc) < 0) {
-	debug(28, 1) ("Attempt to retrieve interface list failed: %s\n",
-	    xstrerror());
-	return 0;
-    }
-    if (ifc.ifc_len > sizeof(ifbuffer)) {
-	debug(28, 1) ("Interface list too long - %d\n", ifc.ifc_len);
-	return 0;
-    }
-    /* Attempt ARP lookup on each interface */
-    offset = 0;
-    while (offset < ifc.ifc_len) {
-	ifr = (struct ifreq *) (ifbuffer + offset);
-	offset += sizeof(*ifr);
-	/* Skip loopback and aliased interfaces */
-	if (0 == strncmp(ifr->ifr_name, "lo", 2))
-	    continue;
-	if (NULL != strchr(ifr->ifr_name, ':'))
-	    continue;
-	debug(28, 4) ("Looking up ARP address for %s on %s\n", inet_ntoa(c),
-	    ifr->ifr_name);
-	/* Set up structures for ARP lookup */
-	ipAddr.sin_family = AF_INET;
-	ipAddr.sin_port = 0;
-	ipAddr.sin_addr = c;
-	memset(&arpReq, '\0', sizeof(arpReq));
-	xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
-	strncpy(arpReq.arp_dev, ifr->ifr_name, sizeof(arpReq.arp_dev) - 1);
-	arpReq.arp_dev[sizeof(arpReq.arp_dev) - 1] = '\0';
-	/* Query ARP table */
-	if (-1 == ioctl(HttpSockets[0], SIOCGARP, &arpReq)) {
-	    /*
-	     * Query failed.  Do not log failed lookups or "device
-	     * not supported"
-	     */
-	    if (ENXIO == errno)
-		(void) 0;
-	    else if (ENODEV == errno)
-		(void) 0;
-	    else
-		debug(28, 1) ("ARP query failed: %s: %s\n",
-		    ifr->ifr_name, xstrerror());
-	    continue;
-	}
-	/* Skip non-ethernet interfaces */
-	if (arpReq.arp_ha.sa_family != ARPHRD_ETHER)
-	    continue;
-	debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x on %s\n",
-	    arpReq.arp_ha.sa_data[0] & 0xff,
-	    arpReq.arp_ha.sa_data[1] & 0xff,
-	    arpReq.arp_ha.sa_data[2] & 0xff,
-	    arpReq.arp_ha.sa_data[3] & 0xff,
-	    arpReq.arp_ha.sa_data[4] & 0xff,
-	    arpReq.arp_ha.sa_data[5] & 0xff, ifr->ifr_name);
-	/* Do lookup */
-	*Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);
-	/* Return if match, otherwise continue to other interfaces */
-	if (0 == splayLastResult) {
-	    debug(28, 3) ("aclMatchArp: %s found on %s\n",
-		inet_ntoa(c), ifr->ifr_name);
-	    return 1;
-	}
-	/*
-	 * Should we stop looking here? Can the same IP address
-	 * exist on multiple interfaces?
-	 */
-    }
-#elif defined(_SQUID_SOLARIS_)
-    struct arpreq arpReq;
-    struct sockaddr_in ipAddr;
-    unsigned char ifbuffer[sizeof(struct ifreq) * 64];
-    struct ifconf ifc;
-    struct ifreq *ifr;
-    int offset;
-    splayNode **Top = dataptr;
-    /*
-     * Set up structures for ARP lookup with blank interface name
-     */
-    ipAddr.sin_family = AF_INET;
-    ipAddr.sin_port = 0;
-    ipAddr.sin_addr = c;
-    memset(&arpReq, '\0', sizeof(arpReq));
-    xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
-    /* Query ARP table */
-    if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) {
-	/*
-	 *  Solaris (at least 2.6/x86) does not use arp_ha.sa_family -
-	 * it returns 00:00:00:00:00:00 for non-ethernet media 
-	 */
-	if (arpReq.arp_ha.sa_data[0] == 0 &&
-	    arpReq.arp_ha.sa_data[1] == 0 &&
-	    arpReq.arp_ha.sa_data[2] == 0 &&
-	    arpReq.arp_ha.sa_data[3] == 0 &&
-	    arpReq.arp_ha.sa_data[4] == 0 && arpReq.arp_ha.sa_data[5] == 0)
-	    return 0;
-	debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n",
-	    arpReq.arp_ha.sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff,
-	    arpReq.arp_ha.sa_data[2] & 0xff, arpReq.arp_ha.sa_data[3] & 0xff,
-	    arpReq.arp_ha.sa_data[4] & 0xff, arpReq.arp_ha.sa_data[5] & 0xff);
-	/* Do lookup */
-	*Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);
-	debug(28, 3) ("aclMatchArp: '%s' %s\n",
-	    inet_ntoa(c), splayLastResult ? "NOT found" : "found");
-	return (0 == splayLastResult);
+    acl * ae=*(acl * *)data;
+    wordlist *w;
+    wordlist *v;
+    while (ae != NULL) {
+        debug(3, 3) ("dump_MethodList: %s %s\n", name, ae->name);
+        v = w = aclDumpMethodList(ae->data);
+        while (v != NULL) {
+            debug(3, 3) ("dump_MethodList: %s %s %s\n", name, ae->name, v->key);
+            storeAppendPrintf(entry, "%s %s %s %s\n",
+                name,
+                ae->name,
+                aclTypeToStr(ae->type),
+                v->key);
+            v = v->next;
+        }
+        wordlistDestroy(&w);
+        ae = ae->next;
     }
-#else
-    WRITE ME;
-#endif
-    /*
-     * Address was not found on any interface
-     */
-    debug(28, 3) ("aclMatchArp: %s NOT found\n", inet_ntoa(c));
-    return 0;
 }
 
-static int
-aclArpCompare(const void *a, const void *b)
+/*
+ * This function traverses all ACL elements referenced
+ * by an access list (presumably 'http_access').   If 
+ * it finds a PURGE method ACL, then it returns TRUE,
+ * otherwise FALSE.
+ */
+int
+aclPurgeMethodInUse(acl_access * a)
 {
-#if defined(_SQUID_LINUX_)
-    const unsigned short *d1 = a;
-    const unsigned short *d2 = b;
-    if (d1[0] != d2[0])
-	return (d1[0] > d2[0]) ? 1 : -1;
-    if (d1[1] != d2[1])
-	return (d1[1] > d2[1]) ? 1 : -1;
-    if (d1[2] != d2[2])
-	return (d1[2] > d2[2]) ? 1 : -1;
-#elif defined(_SQUID_SOLARIS_)
-    const unsigned char *d1 = a;
-    const unsigned char *d2 = b;
-    if (d1[0] != d2[0])
-	return (d1[0] > d2[0]) ? 1 : -1;
-    if (d1[1] != d2[1])
-	return (d1[1] > d2[1]) ? 1 : -1;
-    if (d1[2] != d2[2])
-	return (d1[2] > d2[2]) ? 1 : -1;
-    if (d1[3] != d2[3])
-	return (d1[3] > d2[3]) ? 1 : -1;
-    if (d1[4] != d2[4])
-	return (d1[4] > d2[4]) ? 1 : -1;
-    if (d1[5] != d2[5])
-	return (d1[5] > d2[5]) ? 1 : -1;
-#else
-    WRITE ME;
-#endif
-    return 0;
-}
-
-#if UNUSED_CODE
-/**********************************************************************
-* This is from the pre-splay-tree code for BSD
-* I suspect the Linux approach will work on most O/S and be much
-* better - <luyer@ucs.uwa.edu.au>
-***********************************************************************
-static int
-checkARP(u_long ip, char *eth)
-{
-    int mib[6] =
-    {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO};
-    size_t needed;
-    char *buf, *next, *lim;
-    struct rt_msghdr *rtm;
-    struct sockaddr_inarp *sin;
-    struct sockaddr_dl *sdl;
-    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
-	debug(28, 0) ("Can't estimate ARP table size!\n");
-	return 0;
-    }
-    if ((buf = xmalloc(needed)) == NULL) {
-	debug(28, 0) ("Can't allocate temporary ARP table!\n");
-	return 0;
-    }
-    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
-	debug(28, 0) ("Can't retrieve ARP table!\n");
-	xfree(buf);
-	return 0;
-    }
-    lim = buf + needed;
-    for (next = buf; next < lim; next += rtm->rtm_msglen) {
-	rtm = (struct rt_msghdr *) next;
-	sin = (struct sockaddr_inarp *) (rtm + 1);
-	sdl = (struct sockaddr_dl *) (sin + 1);
-	if (sin->sin_addr.s_addr == ip) {
-	    if (sdl->sdl_alen)
-		if (!memcmp(LLADDR(sdl), eth, 6)) {
-		    xfree(buf);
-		    return 1;
-		}
-	    break;
+    acl_list *b;
+    for (; a; a = a->next) {
+	for (b = a->acl_list; b; b = b->next) {
+	    if (ACL_METHOD != b->acl->type)
+		continue;
+	    if (aclMatchInteger(b->acl->data, METHOD_PURGE))
+		return 1;
 	}
     }
-    xfree(buf);
     return 0;
 }
-**********************************************************************/
-#endif
-
-static void
-aclDumpArpListWalkee(void *node, void *state)
-{
-    acl_arp_data *arp = node;
-    wordlist **W = state;
-    static char buf[24];
-    while (*W != NULL)
-	W = &(*W)->next;
-    snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
-	arp->eth[0], arp->eth[1], arp->eth[2], arp->eth[3],
-	arp->eth[4], arp->eth[5]);
-    wordlistAdd(state, buf);
-}
-
-static wordlist *
-aclDumpArpList(void *data)
-{
-    wordlist *w = NULL;
-    splay_walk(data, aclDumpArpListWalkee, &w);
-    return w;
-}
-
-/* ==== END ARP ACL SUPPORT =============================================== */
-#endif /* USE_ARP_ACL */
 
 /* === CONFIG SUPPORT ROUTINES === */
 
 static int
-check_null_acl(acl * a)
+check_null_acl()
 {
 //    return a == NULL;
     // FIXME: heal the abstraction
@@ -3322,7 +3215,7 @@
 /* temp home to test with */
 static void
 default_if_none_acl(void * data){
-        if (check_null_acl(Config.aclList)) {
+        if (check_null_acl()) {
                 default_line("acl all src 0.0.0.0/0.0.0.0");
         }
 }
@@ -3496,6 +3389,15 @@
     parserRegisterType("domainlist", aclParseDomainList, aclDestroyDomainList, dump_DomainList);
     parserRegisterType("regexlist", aclParseRegexList, aclDestroyRegexList, dump_RegexList);
     parserRegisterType("timespec", aclParseTimeSpec, aclDestroyTimeSpecList, dump_TimeSpec);
+    parserRegisterType("intlist", aclParseIntRange, free_intlist, dump_intlistList);
+    parserRegisterType("intrange", aclParseIntRange, aclDestroyIntRange, dump_IntRangeList);
+    parserRegisterType("userlist", aclParseUserList, aclDestroyUserList, dump_UserList);
+    parserRegisterType("aclwordlist", aclParseWordList, free_wordlist, dump_wordlist);
+    parserRegisterType("protolist", aclParseProtoList, free_intlist, dump_ProtoList);
+    parserRegisterType("methodlist", aclParseMethodList, free_intlist, dump_MethodList);
+#if 0
+    parserRegisterType("arplist", aclParseArpList, aclDestroyArpList, dump_ArpList);
+#endif
 
     /* register the acl instance names */
     aclRegisterAclName("src", parserTypeByName("iplist"), aclMatchSrc);
@@ -3514,9 +3416,38 @@
     aclRegisterAclName("browser", parserTypeByName("regexlist"), aclMatchBrowser);
     aclRegisterAclName("req_mime_type", parserTypeByName("regexlist"), aclMatchRepMimeType);
     aclRegisterAclName("rep_mime_type", parserTypeByName("regexlist"), aclMatchReqMimeType);
+#if USE_IDENT
+    aclRegisterAclName("ident", parserTypeByName("userlist"), aclMatchIdent);
+    aclRegisterAclName("ident_regex", parserTypeByName("regexlist"), aclMatchIdentRegex);
+#endif
+    aclRegisterAclName("proxy_auth", parserTypeByName("userlist"), aclMatchProxyAuthModuleB);
+    aclRegisterAclName("proxy_auth_regex", parserTypeByName("regexlist"), aclMatchProxyAuthModule);
 
     aclRegisterAclName("time", parserTypeByName("timespec"), aclMatchTime);
-//    aclParseIpList(&A->data);aclParseDomainList(&A->data);aclParseTimeSpec(&A->data);
+
+    aclRegisterAclName("maxconn", parserTypeByName("int"), aclMatchMaxConn);
+
+    aclRegisterAclName("port", parserTypeByName("intrange"), aclMatchUrlPort);
+    aclRegisterAclName("myport", parserTypeByName("intrange"), aclMatchMyPort);
+
+    aclRegisterAclName("snmp_community", parserTypeByName("aclwordlist"), aclMatchSNMPCommunity);
+
+    aclRegisterAclName("proto", parserTypeByName("protolist"), aclMatchProto);
+    aclRegisterAclName("method", parserTypeByName("methodlist"), aclMatchMethod);
+
+    aclRegisterAclName("src_as", parserTypeByName("intlist"), aclMatchSrcAsn);
+    aclRegisterAclName("dst_as", parserTypeByName("intlist"), aclMatchDstAsn);
+
+#if 0
+#if USE_ARP_ACL
+    aclRegisterAclName("arp", parserTypeByName("arplist"), aclMatchSrcArp);
+#endif
+#endif
+
+#if SRC_RTT_NOT_YET_FINISHED
+    aclRegisterAclName("src_rtt", parserTypeByName("intlist"),aclMatchSrcRTT);
+#endif
+
 
     if (aclinstances)
         debug(3,0)("reconfiguring is broken just now!!! \n\n");
Index: squid/src/acl.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/acl.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- squid/src/acl.h	24 Apr 2001 13:35:01 -0000	1.1.2.1
+++ squid/src/acl.h	25 Apr 2001 12:28:59 -0000	1.1.2.2
@@ -35,6 +35,7 @@
 #define _ACL_H_
 
 typedef struct _aclName aclName;
+typedef int ACLMATCH(void * * , aclCheck_t *);
 
 struct _acl {
     char name[ACL_NAME_SZ];
@@ -45,4 +46,6 @@
     acl *next;
 };
 
+extern aclName *aclRegisterAclName(const char *, parserTypeNode *, ACLMATCH *);
+
 #endif /* ACL_H */
Index: squid/src/asn.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/asn.c,v
retrieving revision 1.9.4.2
retrieving revision 1.9.4.3
diff -u -r1.9.4.2 -r1.9.4.3
--- squid/src/asn.c	24 Apr 2001 13:34:16 -0000	1.9.4.2
+++ squid/src/asn.c	25 Apr 2001 12:28:59 -0000	1.9.4.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: asn.c,v 1.9.4.2 2001/04/24 13:34:16 rbcollins Exp $
+ * $Id: asn.c,v 1.9.4.3 2001/04/25 12:28:59 rbcollins Exp $
  *
  * DEBUG: section 53    AS Number handling
  * AUTHOR: Duane Wessels, Kostas Anagnostakis
@@ -89,7 +89,7 @@
 static STCB asHandleReply;
 static int destroyRadixNode(struct radix_node *rn, void *w);
 static int printRadixNode(struct radix_node *rn, void *w);
-static void asnAclInitialize(acl * acls);
+static void asnAclInitialize();
 static void asStateFree(void *data);
 static void destroyRadixNodeInfo(as_info *);
 static OBJH asnStats;
@@ -134,12 +134,24 @@
 }
 
 static void
-asnAclInitialize(acl * acls)
+asnAclInitialize()
 {
     acl *a;
     intlist *i;
+    parserNameNode *aclparserName = parserNameByName("acl");
+    parserNameNode *parserName;
+    dlink_node *node;
     debug(53, 3) ("asnAclInitialize\n");
-    for (a = acls; a; a = a->next) {
+
+    // FIXME: heal the abstraction
+    if (!aclparserName || aclparserName->children.head==NULL)
+	return;
+
+    node=aclparserName->children.head;
+    while (node) {
+	parserName=node->data;
+	node=node->next;
+	a=parserName->location;
 	if (a->type != ACL_DST_ASN && a->type != ACL_SRC_ASN)
 	    continue;
 	for (i = a->data; i; i = i->next)
@@ -160,7 +172,7 @@
     if (0 == inited++)
 	rn_init();
     rn_inithead((void **) &AS_tree_head, 8);
-    asnAclInitialize(Config.aclList);
+    asnAclInitialize();
     cachemgrRegister("asndb", "AS Number Database", asnStats, 0, 1);
 }
 
Index: squid/src/cache_cf.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cache_cf.c,v
retrieving revision 1.18.4.25
retrieving revision 1.18.4.26
diff -u -r1.18.4.25 -r1.18.4.26
--- squid/src/cache_cf.c	24 Apr 2001 13:34:16 -0000	1.18.4.25
+++ squid/src/cache_cf.c	25 Apr 2001 12:28:59 -0000	1.18.4.26
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.c,v 1.18.4.25 2001/04/24 13:34:16 rbcollins Exp $
+ * $Id: cache_cf.c,v 1.18.4.26 2001/04/25 12:28:59 rbcollins Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -208,8 +208,10 @@
 /****************** END OF WORDLIST ROUTINES ****************/
 
 void
-intlistDestroy(intlist ** list)
+free_intlist(parserNameNode *parserName, void *data)
 {
+    intlist ** list=data;
+
     intlist *w = NULL;
     intlist *n = NULL;
     for (w = *list; w; w = n) {
@@ -2208,7 +2210,7 @@
     *var = (u_short) i;
 }
 
-static void
+void
 dump_wordlist(StoreEntry * entry, const char *name, void const * const data)
 {
     wordlist * list=*(wordlist **)data;
Index: squid/src/enums.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/enums.h,v
retrieving revision 1.14.4.5
retrieving revision 1.14.4.6
diff -u -r1.14.4.5 -r1.14.4.6
--- squid/src/enums.h	24 Apr 2001 13:34:16 -0000	1.14.4.5
+++ squid/src/enums.h	25 Apr 2001 12:28:59 -0000	1.14.4.6
@@ -1,6 +1,6 @@
 
 /*
- * $Id: enums.h,v 1.14.4.5 2001/04/24 13:34:16 rbcollins Exp $
+ * $Id: enums.h,v 1.14.4.6 2001/04/25 12:28:59 rbcollins Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -104,29 +104,18 @@
     ACL_TIME,
     ACL_URLPATH_REGEX,
     ACL_URL_REGEX,
-    ACL_URL_PORT,
-    ACL_MY_PORT,
 #if USE_IDENT
     ACL_IDENT,
     ACL_IDENT_REGEX,
 #endif
-    ACL_PROTO,
     ACL_METHOD,
-    ACL_BROWSER,
     ACL_PROXY_AUTH,
     ACL_PROXY_AUTH_REGEX,
     ACL_SRC_ASN,
     ACL_DST_ASN,
-#if USE_ARP_ACL
-    ACL_SRC_ARP,
-#endif
-#if SQUID_SNMP
-    ACL_SNMP_COMMUNITY,
-#endif
 #if SRC_RTT_NOT_YET_FINISHED
     ACL_NETDB_SRC_RTT,
 #endif
-    ACL_MAXCONN,
     ACL_REQ_MIME_TYPE,
     ACL_REP_MIME_TYPE,
     ACL_DYNAMIC,
Index: squid/src/structs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/structs.h,v
retrieving revision 1.24.4.18
retrieving revision 1.24.4.19
diff -u -r1.24.4.18 -r1.24.4.19
--- squid/src/structs.h	24 Apr 2001 13:34:16 -0000	1.24.4.18
+++ squid/src/structs.h	25 Apr 2001 12:28:59 -0000	1.24.4.19
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.24.4.18 2001/04/24 13:34:16 rbcollins Exp $
+ * $Id: structs.h,v 1.24.4.19 2001/04/25 12:28:59 rbcollins Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -163,14 +163,6 @@
     acl_deny_info_list *next;
 };
 
-#if USE_ARP_ACL
-
-struct _acl_arp_data {
-    char eth[6];
-};
-
-#endif
-
 struct _String {
     /* never reference these directly! */
     unsigned short int size;	/* buffer size; 64K limit */
@@ -529,8 +521,10 @@
 	int ie_refresh;
 	int pipeline_prefetch;
     } onoff;
+#if 0
     acl *aclList;
     dlink_list aclList2;
+#endif
     struct {
 	acl_access *http;
 	acl_access *icp;
