==============================================================================
+lib/eui64_aton.h lib/eui64_aton.c:
+
+/*-
+ * Copyright 2004 The Aerospace Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions, and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of The Aerospace Corporation may not be used to endorse or
+ * promote products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+==============================================================================
+
mcast_encode() in src/access_log.c is derived from Mark Atkinson's
(mark_a@cix.compulink.co.uk) "Tiny Encryption Algorithm".
http://www.io.com/~paulhart/game/algorithms/tea.html
])
AM_CONDITIONAL(USE_SQUID_EUI, false)
+use_sq_eui="yes"
AC_ARG_ENABLE(eui,
- AS_HELP_STRING([--enable-eui],[Enable use of ARP / MAC/ EUI (ether address)]),
-[ if test "$enableval" = "yes" ; then
+ AS_HELP_STRING([--disable-eui],[Enable use of ARP / MAC/ EUI (ether address)]),
+ [use_sq_eui="$enableval"])
+if test "$use_sq_eui" = "yes" ; then
AC_MSG_NOTICE([EUI controls enabled (ether address)])
case "$host" in
*-linux-*)
)
AC_DEFINE(USE_SQUID_EUI,1,[Define this to include code which lets you use ethernet hardware addresses. This code uses functions found in 4.4 BSD derviations (e.g. FreeBSD, ?).])
AM_CONDITIONAL(USE_SQUID_EUI, true)
- fi
-])
+else
+ AC_MSG_NOTICE([EUI controls disabled (ether address)])
+fi
USE_HTCP=true
AM_CONDITIONAL(ENABLE_HTCP, false)
dnl ... and some we provide local replacements for
AC_REPLACE_FUNCS(\
drand48 \
+ eui64_aton \
inet_ntop \
inet_pton \
initgroups \
<sect1>New tags<label id="newtags">
<p>
<descrip>
+ <tag>eui_lookup</tag>
+ <p> Whether to lookup the EUI or MAC address of a connected client.
+
<tag>memory_cache_mode</tag>
<p> Controls which objects to keep in the memory cache (cache_mem)
<verb>
network Only objects fetched from network is kept in memory
</verb>
-
</descrip>
<sect1>Changes to existing tags<label id="modifiedtags">
<p>
<descrip>
+ <tag>external_acl_type</tag>
+ <p>New format tag <em>%SRCEUI48</em> EUI-48 / MAC address of client from ARP lookup.
+ <p>New format tag <em>%SRCEUI64</em> EUI-64 of clients with SLAAC address.
+
<tag>logformat</tag>
<p><em>%sn</em> Unique sequence number per log line. Ported from 2.7
+ <p><em>%>eui</em> EUI logging (EUI-48 / MAC address for IPv4, EUI-64 for IPv6)
+ Both EUI forms are logged in the same field. Type can be identified by length or byte delimiter.
<tag>windows_ipaddrchangemonitor</tag>
<p>Now only available to be set in Windows builds.
--- /dev/null
+/*
+ * Squid Change History:
+ *
+ * 2009-10-16 : import from NetBSD eui64.c.
+ * strip definitions not required by eui64_aton()
+ */
+
+/* $NetBSD: eui64.h,v 1.1 2005/07/11 15:35:25 kiyohara Exp $ */
+/*-
+ * Copyright 2004 The Aerospace Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions, and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of The Aerospace Corporation may not be used to endorse or
+ * promote products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/sys/sys/eui64.h,v 1.2 2005/01/07 02:29:23 imp Exp $
+ */
+#ifndef _SYS_EUI64_H
+#define _SYS_EUI64_H
+
+#include <sys/types.h>
+
+/**
+ * Size of the ASCII representation of an EUI-64.
+ */
+#define EUI64_SIZ 24
+
+/**
+ * The number of bytes in an EUI-64.
+ */
+#define EUI64_LEN 8
+
+/**
+ * Structure of an IEEE EUI-64.
+ */
+struct eui64 {
+ u_char octet[EUI64_LEN];
+};
+
+#ifdef __cplusplus
+extern "C"
+#endif
+int eui64_aton(const char *a, struct eui64 *e);
+
+#endif /* !_SYS_EUI64_H */
--- /dev/null
+/*
+ * Squid Change History:
+ *
+ * 2009-10-16 : import eui64_ntoa() function from NetBSD eui64.c
+ */
+
+/* $NetBSD: eui64.c,v 1.1 2005/07/11 15:35:25 kiyohara Exp $ */
+/*
+ * Copyright 2004 The Aerospace Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions, and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of The Aerospace Corporation may not be used to endorse or
+ * promote products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * EUI-64 conversion and lookup routines
+ *
+ *
+ * Converted from ether_addr.c rev
+ * FreeBSD: src/lib/libc/net/eui64.c,v 1.15 2002/04/08 07:51:10 ru Exp
+ * by Brooks Davis
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Center for Telecommunications Research
+ * Columbia University, New York City
+ */
+
+#include <stdio.h>
+#include "eui64_aton.h"
+
+
+/*
+ * Convert an ASCII representation of an EUI-64 to binary form.
+ */
+int
+eui64_aton(const char *a, struct eui64 *e)
+{
+ int i;
+ unsigned int o0, o1, o2, o3, o4, o5, o6, o7;
+
+ /* canonical form */
+ i = sscanf(a, "%x-%x-%x-%x-%x-%x-%x-%x",
+ &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
+ if (i == EUI64_LEN)
+ goto good;
+ /* ethernet form */
+ i = sscanf(a, "%x:%x:%x:%x:%x:%x:%x:%x",
+ &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
+ if (i == EUI64_LEN)
+ goto good;
+ /* classic fwcontrol/dconschat form */
+ i = sscanf(a, "0x%2x%2x%2x%2x%2x%2x%2x%2x",
+ &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
+ if (i == EUI64_LEN)
+ goto good;
+ /* MAC format (-) */
+ i = sscanf(a, "%x-%x-%x-%x-%x-%x",
+ &o0, &o1, &o2, &o5, &o6, &o7);
+ if (i == 6) {
+ o3 = 0xff;
+ o4 = 0xfe;
+ goto good;
+ }
+ /* MAC format (:) */
+ i = sscanf(a, "%x:%x:%x:%x:%x:%x",
+ &o0, &o1, &o2, &o5, &o6, &o7);
+ if (i == 6) {
+ o3 = 0xff;
+ o4 = 0xfe;
+ goto good;
+ }
+
+ return (-1);
+
+good:
+ e->octet[0]=o0;
+ e->octet[1]=o1;
+ e->octet[2]=o2;
+ e->octet[3]=o3;
+ e->octet[4]=o4;
+ e->octet[5]=o5;
+ e->octet[6]=o6;
+ e->octet[7]=o7;
+
+ return (0);
+}
*/
#include "acl/Acl.h"
-#ifdef USE_ARP_ACL
+#ifdef USE_SQUID_EUI
#include "acl/Arp.h"
+#include "acl/Eui64.h"
#endif
#include "acl/Asn.h"
#include "acl/Browser.h"
ACLStrategised<SSL *> ACLCertificate::CARegistryEntry_(new ACLCertificateData (sslGetCAAttribute), ACLCertificateStrategy::Instance(), "ca_cert");
#endif
-#ifdef USE_ARP_ACL
+#ifdef USE_SQUID_EUI
ACL::Prototype ACLARP::RegistryProtoype(&ACLARP::RegistryEntry_, "arp");
ACLARP ACLARP::RegistryEntry_("arp");
+ACL::Prototype ACLEui64::RegistryProtoype(&ACLEui64::RegistryEntry_, "eui64");
+ACLEui64 ACLEui64::RegistryEntry_("eui64");
#endif
#if USE_IDENT
lastmod = -1;
max_forwards = -1;
client_addr.SetEmpty();
+#if USE_SQUID_EUI
+ client_eui48.clear();
+ client_eui64.clear();
+#endif
my_addr.SetEmpty();
body_pipe = NULL;
// hier
return false;
client_addr = aReq->client_addr;
+#if USE_SQUID_EUI
+ client_eui48 = aReq->client_eui48;
+ client_eui64 = aReq->client_eui64;
+#endif
my_addr = aReq->my_addr;
dnsWait = aReq->dnsWait;
#ifndef SQUID_HTTPREQUEST_H
#define SQUID_HTTPREQUEST_H
-#include "HttpMsg.h"
-#include "client_side.h"
-#include "HierarchyLogEntry.h"
-#include "HttpRequestMethod.h"
+#include "config.h"
+
#if USE_ADAPTATION
#include "adaptation/History.h"
#endif
#if ICAP_CLIENT
#include "adaptation/icap/History.h"
#endif
+#include "client_side.h"
+#if USE_SQUID_EUI
+#include "eui/Eui48.h"
+#include "eui/Eui64.h"
+#endif
+#include "HierarchyLogEntry.h"
+#include "HttpMsg.h"
+#include "HttpRequestMethod.h"
/* Http Request */
//DEAD?: extern int httpRequestHdrAllowedByName(http_hdr_type id);
IpAddress indirect_client_addr;
#endif /* FOLLOW_X_FORWARDED_FOR */
+#if USE_SQUID_EUI
+ /* TODO these might be merged into one field if we can reliably map the EUI-48 into EUI-64
+ there are some OS differences in the upper bytes. */
+ Eui::Eui48 client_eui48;
+ Eui::Eui64 client_eui64;
+#endif
+
IpAddress my_addr;
HierarchyLogEntry hier;
squid_LDADD = \
$(COMMON_LIBS) \
+ eui/libeui.la \
icmp/libicmp.la icmp/libicmp-core.la \
@XTRA_OBJS@ \
@DISK_LINKOBJS@ \
#include "Store.h"
#include "acl/Checklist.h"
-
+#include "CacheManager.h"
+#if USE_SQUID_EUI
+#include "eui/Eui48.h"
+#include "eui/Eui64.h"
+#endif
#include "hier_code.h"
#include "HttpReply.h"
#include "HttpRequest.h"
#include "MemBuf.h"
#include "SquidTime.h"
-#include "CacheManager.h"
static void accessLogSquid(AccessLogEntry * al, Logfile * logfile);
static void accessLogCommon(AccessLogEntry * al, Logfile * logfile);
LFT_CLIENT_IP_ADDRESS,
LFT_CLIENT_FQDN,
LFT_CLIENT_PORT,
+#if USE_SQUID_EUI
+ LFT_CLIENT_EUI,
+#endif
/*LFT_SERVER_IP_ADDRESS, */
LFT_SERVER_IP_OR_PEER_NAME,
struct logformat_token_table_entry logformat_token_table[] = {
{">a", LFT_CLIENT_IP_ADDRESS},
-
- { ">p", LFT_CLIENT_PORT},
+ {">p", LFT_CLIENT_PORT},
{">A", LFT_CLIENT_FQDN},
+#if USE_SQUID_EUI
+ {">eui", LFT_CLIENT_EUI},
+#endif
/*{ "<a", LFT_SERVER_IP_ADDRESS }, */
/*{ "<p", LFT_SERVER_PORT }, */
}
break;
+#if USE_SQUID_EUI
+ case LFT_CLIENT_EUI:
+ if (al->request) {
+ if (al->cache.caddr.IsIPv4())
+ al->request->client_eui48.encode(tmp, 1024);
+ else
+ al->request->client_eui64.encode(tmp, 1024);
+ out = tmp;
+ }
+ break;
+#endif
+
/* case LFT_SERVER_IP_ADDRESS: */
case LFT_SERVER_IP_OR_PEER_NAME:
#include "ip/IpAddress.h"
#include "wordlist.h"
-static void aclParseArpList(SplayNode<Eui48 *> **curlist);
-static int aclMatchArp(SplayNode<Eui48 *> **dataptr, IpAddress &c);
-static SplayNode<Eui48 *>::SPLAYCMP aclArpCompare;
-static SplayNode<Eui48 *>::SPLAYWALKEE aclDumpArpListWalkee;
+static void aclParseArpList(SplayNode<Eui::Eui48 *> **curlist);
+static int aclMatchArp(SplayNode<Eui::Eui48 *> **dataptr, IpAddress &c);
+static SplayNode<Eui::Eui48 *>::SPLAYCMP aclArpCompare;
+static SplayNode<Eui::Eui48 *>::SPLAYWALKEE aclDumpArpListWalkee;
ACL *
ACLARP::~ACLARP()
{
if (data)
- data->destroy(SplayNode<Eui48*>::DefaultFree);
+ data->destroy(SplayNode<Eui::Eui48*>::DefaultFree);
}
char const *
* Solaris code by R. Gancarz <radekg@solaris.elektrownia-lagisza.com.pl>
*/
-Eui48 *
+Eui::Eui48 *
aclParseArpData(const char *t)
{
char buf[256];
- Eui48 *q = new Eui48;
+ Eui::Eui48 *q = new Eui::Eui48;
debugs(28, 5, "aclParseArpData: " << t);
if (sscanf(t, "%[0-9a-fA-F:]", buf) != 1) {
}
void
-aclParseArpList(SplayNode<Eui48 *> **curlist)
+aclParseArpList(SplayNode<Eui::Eui48 *> **curlist)
{
char *t = NULL;
- SplayNode<Eui48*> **Top = curlist;
- Eui48 *q = NULL;
+ SplayNode<Eui::Eui48*> **Top = curlist;
+ Eui::Eui48 *q = NULL;
while ((t = strtokFile())) {
if ((q = aclParseArpData(t)) == NULL)
/* aclMatchArp */
/***************/
int
-aclMatchArp(SplayNode<Eui48 *> **dataptr, IpAddress &c)
+aclMatchArp(SplayNode<Eui::Eui48 *> **dataptr, IpAddress &c)
{
- Eui48 result;
- SplayNode<Eui48 *> **Top = dataptr;
+ Eui::Eui48 result;
+ SplayNode<Eui::Eui48 *> **Top = dataptr;
if (result.lookup(c)) {
/* Do ACL match lookup */
}
static int
-aclArpCompare(Eui48 * const &a, Eui48 * const &b)
+aclArpCompare(Eui::Eui48 * const &a, Eui::Eui48 * const &b)
{
- return memcmp(a, b, sizeof(Eui48));
+ return memcmp(a, b, sizeof(Eui::Eui48));
}
static void
-aclDumpArpListWalkee(Eui48 * const &node, void *state)
+aclDumpArpListWalkee(Eui::Eui48 * const &node, void *state)
{
static char buf[48];
node->encode(buf, 48);
#include "acl/Checklist.h"
#include "splay.h"
-class Eui48;
+namespace Eui {
+ class Eui48;
+};
/// \ingroup ACLAPI
class ACLARP : public ACL
protected:
static Prototype RegistryProtoype;
static ACLARP RegistryEntry_;
- SplayNode<Eui48 *> *data;
+ SplayNode<Eui::Eui48 *> *data;
char const *class_;
};
--- /dev/null
+/*
+ * DEBUG: section 28 Access Control
+ * AUTHOR: Amos Jeffries
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+
+#if USE_SQUID_EUI
+
+#include "acl/Eui64.h"
+#include "acl/FilledChecklist.h"
+#include "eui/Eui64.h"
+#include "ip/IpAddress.h"
+#include "wordlist.h"
+
+static void aclParseEuiList(SplayNode<Eui::Eui64 *> **curlist);
+static int aclMatchEui(SplayNode<Eui::Eui64 *> **dataptr, IpAddress &c);
+static SplayNode<Eui::Eui64 *>::SPLAYCMP aclEui64Compare;
+static SplayNode<Eui::Eui64 *>::SPLAYWALKEE aclDumpEuiListWalkee;
+
+
+ACL *
+ACLEui64::clone() const
+{
+ return new ACLEui64(*this);
+}
+
+ACLEui64::ACLEui64 (char const *theClass) : data (NULL), class_ (theClass)
+{}
+
+ACLEui64::ACLEui64 (ACLEui64 const & old) : data (NULL), class_ (old.class_)
+{
+ /* we don't have copy constructors for the data yet */
+ assert (!old.data);
+}
+
+ACLEui64::~ACLEui64()
+{
+ if (data)
+ data->destroy(SplayNode<Eui::Eui64*>::DefaultFree);
+}
+
+char const *
+ACLEui64::typeString() const
+{
+ return class_;
+}
+
+bool
+ACLEui64::empty () const
+{
+ return data->empty();
+}
+
+Eui::Eui64 *
+aclParseEuiData(const char *t)
+{
+ char buf[256];
+ Eui::Eui64 *q = new Eui::Eui64;
+ debugs(28, 5, "aclParseEuiData: " << t);
+
+ if (sscanf(t, "%[0-9a-fA-F:]", buf) != 1) {
+ debugs(28, 0, "aclParseEuiData: Bad EUI-64 address: '" << t << "'");
+ safe_free(q);
+ return NULL;
+ }
+
+ if (!q->decode(buf)) {
+ debugs(28, 0, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line);
+ debugs(28, 0, "aclParseEuiData: Ignoring invalid EUI-64 acl entry: can't parse '" << buf << "'");
+ safe_free(q);
+ return NULL;
+ }
+
+ return q;
+}
+
+
+/*******************/
+/* aclParseEuiList */
+/*******************/
+void
+ACLEui64::parse()
+{
+ aclParseEuiList(&data);
+}
+
+void
+aclParseEuiList(SplayNode<Eui::Eui64 *> **curlist)
+{
+ char *t = NULL;
+ SplayNode<Eui::Eui64*> **Top = curlist;
+ Eui::Eui64 *q = NULL;
+
+ while ((t = strtokFile())) {
+ if ((q = aclParseEuiData(t)) == NULL)
+ continue;
+
+ *Top = (*Top)->insert(q, aclEui64Compare);
+ }
+}
+
+int
+ACLEui64::match(ACLChecklist *cl)
+{
+ ACLFilledChecklist *checklist = Filled(cl);
+
+ /* IPv4 does not do EUI-64 (yet) */
+ if (!checklist->src_addr.IsIPv6()) {
+ debugs(14, 3, "ACLEui64::match: IPv6 Required for EUI-64 Lookups. Skipping " << checklist->src_addr );
+ return 0;
+ }
+
+ return aclMatchEui(&data, checklist->src_addr);
+}
+
+/***************/
+/* aclMatchEui */
+/***************/
+int
+aclMatchEui(SplayNode<Eui::Eui64 *> **dataptr, IpAddress &c)
+{
+ Eui::Eui64 result;
+ SplayNode<Eui::Eui64 *> **Top = dataptr;
+
+ if (result.lookup(c)) {
+ /* Do ACL match lookup */
+ *Top = (*Top)->splay(&result, aclEui64Compare);
+ debugs(28, 3, "aclMatchEui: '" << c << "' " << (splayLastResult ? "NOT found" : "found"));
+ return (0 == splayLastResult);
+ }
+
+ /*
+ * Address was not found on any interface
+ */
+ debugs(28, 3, "aclMatchEui: " << c << " NOT found");
+ return 0;
+}
+
+static int
+aclEui64Compare(Eui::Eui64 * const &a, Eui::Eui64 * const &b)
+{
+ return memcmp(a, b, sizeof(Eui::Eui64));
+}
+
+static void
+aclDumpEuiListWalkee(Eui::Eui64 * const &node, void *state)
+{
+ static char buf[48];
+ node->encode(buf, 48);
+ wordlistAdd((wordlist **)state, buf);
+}
+
+wordlist *
+ACLEui64::dump() const
+{
+ wordlist *w = NULL;
+ data->walk(aclDumpEuiListWalkee, &w);
+ return w;
+}
+
+#endif /* USE_SQUID_EUI */
--- /dev/null
+/*
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_ACLEUI64_H
+#define SQUID_ACLEUI64_H
+
+#include "acl/Acl.h"
+#include "acl/Checklist.h"
+#include "splay.h"
+
+namespace Eui {
+ class Eui64;
+};
+
+
+/// \ingroup ACLAPI
+class ACLEui64 : public ACL
+{
+
+public:
+ MEMPROXY_CLASS(ACLEUI64);
+
+ ACLEui64(char const *);
+ ACLEui64(ACLEui64 const &);
+ ~ACLEui64();
+ ACLEui64&operator=(ACLEui64 const &);
+
+ virtual ACL *clone()const;
+ virtual char const *typeString() const;
+ virtual void parse();
+ virtual int match(ACLChecklist *checklist);
+ virtual wordlist *dump() const;
+ virtual bool empty () const;
+
+protected:
+ static Prototype RegistryProtoype;
+ static ACLEui64 RegistryEntry_;
+ SplayNode<Eui::Eui64 *> *data;
+ char const *class_;
+};
+
+MEMPROXY_CLASS_INLINE(ACLEui64);
+
+#endif /* SQUID_ACLEUI64_H */
EXTRA_libacls_la_SOURCES += $(SSL_ACLS)
-ARP_ACLS = Arp.cc Arp.h
+ARP_ACLS = Arp.cc Arp.h Eui64.cc Eui64.h
if USE_SQUID_EUI
libacls_la_SOURCES += $(ARP_ACLS)
#if USE_SQUID_ESI
#include "esi/Parser.h"
#endif
+#include "eui/Config.h"
#if USE_ADAPTATION
#include "adaptation/Config.h"
Note: after changing this, Squid service must be restarted.
DOC_END
+NAME: eui_lookup
+TYPE: onoff
+IFDEF: USE_SQUID_EUI
+DEFAULT: on
+LOC: Eui::TheConfig.euiLookup
+DOC_START
+ Whether to lookup the EUI or MAC address of a connected client.
+DOC_END
+
EOF
#include "MemBuf.h"
#include "SquidTime.h"
#include "ChunkedCodingParser.h"
+#include "eui/Config.h"
#if LINGERING_CLOSE
#define comm_close comm_lingering_close
request->flags.internal = http->flags.internal;
setLogUri (http, urlCanonicalClean(request));
request->client_addr = conn->peer;
+#if USE_SQUID_EUI
+ request->client_eui48 = conn->peer_eui48;
+ request->client_eui64 = conn->peer_eui64;
+#endif
#if FOLLOW_X_FORWARDED_FOR
request->indirect_client_addr = conn->peer;
#endif /* FOLLOW_X_FORWARDED_FOR */
}
#endif
+#if USE_SQUID_EUI
+ if (Eui::TheConfig.euiLookup) {
+ if (details->peer.IsIPv4()) {
+ connState->peer_eui48.lookup(details->peer);
+ }
+ else if (details->peer.IsIPv6()) {
+ connState->peer_eui64.lookup(details->peer);
+ }
+ }
+#endif
+
if (s->tcp_keepalive.enabled) {
commSetTcpKeepalive(newfd, s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout);
}
#ifndef SQUID_CLIENTSIDE_H
#define SQUID_CLIENTSIDE_H
-#include "comm.h"
-#include "StoreIOBuffer.h"
-#include "BodyPipe.h"
-#include "RefCount.h"
#include "base/AsyncJob.h"
+#include "BodyPipe.h"
+#include "comm.h"
#include "CommCalls.h"
+#include "eui/Eui48.h"
+#include "eui/Eui64.h"
+#include "RefCount.h"
+#include "StoreIOBuffer.h"
class ConnStateData;
bool connRegistered_;
};
+
+class ConnectionDetail;
+
/** A connection to a socket */
class ConnStateData : public BodyProducer/*, public RefCountable*/
{
char rfc931[USER_IDENT_SZ];
int nrequests;
+#if USE_SQUID_EUI
+ Eui::Eui48 peer_eui48;
+ Eui::Eui64 peer_eui64;
+#endif
+
struct {
bool readMoreRequests;
bool swanSang; // XXX: temporary flag to check proper cleanup
--- /dev/null
+#include "config.h"
+#include "eui/Config.h"
+
+Eui::EuiConfig Eui::TheConfig;
--- /dev/null
+#ifndef SQUID_EUI_CONFIG_H
+#define SQUID_EUI_CONFIG_H
+
+namespace Eui {
+
+class EuiConfig
+{
+public:
+ int euiLookup;
+};
+
+extern EuiConfig TheConfig;
+
+}; // namespace Eui
+
+#endif /* SQUID_EUI_CONFIG_H */
*/
bool
-Eui48::decode(const char *asc)
+Eui::Eui48::decode(const char *asc)
{
int a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0;
}
bool
-Eui48::encode(char *buf, const int len)
+Eui::Eui48::encode(char *buf, const int len)
{
if (len < SZ_EUI48_BUF) return false;
// return binary representation of the EUI
bool
-Eui48::lookup(IpAddress &c)
+Eui::Eui48::lookup(IpAddress &c)
{
struct arpreq arpReq;
#if !defined(_SQUID_WIN32_)
else if (ENODEV == errno)
(void) 0;
else
- debugs(28, 1, "ARP query failed: " << ifr->ifr_name << ": " << xstrerror());
+ debugs(28, 1, "ARP query " << ipAddr << " failed: " << ifr->ifr_name << ": " << xstrerror());
continue;
}
#include <cstring>
#endif
+namespace Eui {
+
class Eui48
{
unsigned char eui[SZ_EUI48_BUF];
};
+}; // namespace Eui
+
#endif /* USE_SQUID_EUI */
#endif /* _SQUID_EUI_EUI48_H */
--- /dev/null
+/*
+ * DEBUG: section ?? EUI-64 Handling
+ * AUTHOR: Amos Jeffries
+ *
+ * Copyright (c) 2009, Amos Jeffries <squid3@treenet.co.nz>
+ */
+
+#include "config.h"
+
+#if USE_SQUID_EUI
+
+#include "Debug.h"
+#include "eui/Eui64.h"
+#include "globals.h"
+#include "ip/IpAddress.h"
+
+#if HAVE_SYS_EUI64_H
+#include <sys/eui64.h>
+#else
+#include "eui64_aton.h"
+#endif
+
+bool
+Eui::Eui64::decode(const char *asc)
+{
+ if (eui64_aton(asc, (struct eui64 *)eui) != 0) return false;
+
+ return true;
+}
+
+bool
+Eui::Eui64::encode(char *buf, const int len)
+{
+ if (len < SZ_EUI64_BUF) return false;
+
+ snprintf(buf, len, "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
+ eui[0], eui[1], eui[2], eui[3],
+ eui[4], eui[5], eui[6], eui[7]);
+ return true;
+}
+
+// return binary representation of the EUI
+bool
+Eui::Eui64::lookup(IpAddress &c)
+{
+ /* try to short-circuit slow OS lookups by using SLAAC data */
+ if (lookupSlaac(c)) return true;
+
+ // find EUI-64 some other way. NDP table lookup?
+ return lookupNdp(c);
+}
+
+bool
+Eui::Eui64::lookupSlaac(IpAddress &c)
+{
+#if USE_IPV6
+ /* RFC 4291 Link-Local unicast addresses which contain SLAAC - usually trustable. */
+ if (c.IsSiteLocal6() && c.IsSlaac() ) {
+
+ // strip the final 64 bits of the address...
+ struct in6_addr tmp;
+ c.GetInAddr(tmp);
+ memcpy(eui, &(tmp.s6_addr[8]), SZ_EUI64_BUF);
+
+ return true;
+ }
+#endif
+ return false;
+}
+
+// return binary representation of the EUI
+bool
+Eui::Eui64::lookupNdp(IpAddress &c)
+{
+#if USE_IPV6
+
+#if 0 /* no OS yet supported for NDP protocol lookup */
+
+#else
+ debugs(28, 0, "ERROR: ARP / MAC / EUI-* operations not supported on this operating system.");
+#endif
+
+ /*
+ * Address was not found on any interface
+ */
+ debugs(28, 3, HERE << c << " NOT found");
+#else
+ debugs(28, 0, "ERROR: IPv6 EUI-64 operations not supported on this operating system.");
+#endif
+
+ clear();
+ return false;
+}
+
+#endif /* USE_SQUID_EUI */
--- /dev/null
+#ifndef _SQUID_EUI_EUI64_H
+#define _SQUID_EUI_EUI64_H
+
+#include "config.h"
+
+#if USE_SQUID_EUI
+
+class IpAddress;
+
+#if HAVE_CSTRING
+#include <cstring>
+#endif
+#if HAVE_SYS_EUI64_H
+#include <sys/eui64.h>
+#endif
+
+namespace Eui {
+
+/* EUI-64 is 8 bytes. */
+#if defined(EUI64_LEN)
+#define SZ_EUI64_BUF EUI64_LEN
+#else
+#define SZ_EUI64_BUF 8
+#endif
+
+class Eui64 {
+
+public:
+ Eui64() { clear(); };
+ Eui64(const Eui64 &t) { memcpy(this, &t, sizeof(Eui64)); };
+ ~Eui64() {};
+
+ const unsigned char *get(void);
+
+ bool set(const char *src, const int len) {
+ if (len > SZ_EUI64_BUF) return false;
+ if (len < SZ_EUI64_BUF) clear();
+ memcpy(eui, src, len);
+ return true;
+ };
+
+ void clear() { memset(eui, NULL, SZ_EUI64_BUF); };
+
+ /**
+ * Decode an ascii representation of an EUI-64 address.
+ *
+ * \param asc ASCII representation of an EUI-64 address
+ * \param eth Binary representation of the EUI_64 address
+ * \retval false Conversion to binary failed. Invalid address
+ * \retval true Conversion completed successfully
+ */
+ bool decode(const char *asc);
+
+ /**
+ * Encode an ascii representation (asc) of an EUI-64 address.
+ *
+ * \param buf Buffer to receive ASCII representation of an EUI-64 address
+ * \param len Length of the buffer space available. Must be >= SZ_EUI64_BUF bytes or the encode will fail.
+ * \param eui Binary representation of the EUI-64 address
+ * \retval false Conversion to ASCII failed.
+ * \retval true Conversion completed successfully.
+ */
+ bool encode(char *buf, const int len);
+
+ // lookup an EUI-64 address via IPv6 SLAAC or NDP
+ bool lookup(IpAddress &c);
+
+ // lookup an EUI-64 address via IPv6 NDP
+ bool lookupNdp(IpAddress &c);
+
+ // lookup an EUI-64 address via decoding the IPv6 address SLAAC data
+ bool lookupSlaac(IpAddress &c);
+
+private:
+ unsigned char eui[SZ_EUI64_BUF];
+};
+
+}; // namespace Eui
+
+#endif /* USE_SQUID_EUI */
+#endif /* _SQUID_EUI_EUI64_H */
noinst_LTLIBRARIES = libeui.la
libeui_la_SOURCES = \
+ Config.h \
+ Config.cc \
Eui48.h \
- Eui48.cc
+ Eui48.cc \
+ Eui64.h \
+ Eui64.cc
libeui_la_LIBADD = @EUILIB@
#endif
EXT_ACL_SRC,
EXT_ACL_SRCPORT,
+#if USE_SQUID_EUI
+ EXT_ACL_SRCEUI48,
+ EXT_ACL_SRCEUI64,
+#endif
EXT_ACL_MYADDR,
EXT_ACL_MYPORT,
EXT_ACL_URI,
format->type = _external_acl_format::EXT_ACL_SRC;
else if (strcmp(token, "%SRCPORT") == 0)
format->type = _external_acl_format::EXT_ACL_SRCPORT;
+#if USE_SQUID_EUI
+ else if (strcmp(token, "%SRCEUI48") == 0)
+ format->type = _external_acl_format::EXT_ACL_SRCEUI48;
+ else if (strcmp(token, "%SRCEUI64") == 0)
+ format->type = _external_acl_format::EXT_ACL_SRCEUI64;
+#endif
else if (strcmp(token, "%MYADDR") == 0)
format->type = _external_acl_format::EXT_ACL_MYADDR;
else if (strcmp(token, "%MYPORT") == 0)
else if (strcmp(token, "%EXT_USER") == 0)
format->type = _external_acl_format::EXT_ACL_EXT_USER;
else {
+ debugs(0,0, "ERROR: Unknown Format token " << token);
self_destruct();
}
DUMP_EXT_ACL_TYPE(SRC);
DUMP_EXT_ACL_TYPE(SRCPORT);
+#if USE_SQUID_EUI
+ DUMP_EXT_ACL_TYPE(SRCEUI48);
+ DUMP_EXT_ACL_TYPE(SRCEUI64);
+#endif
+
DUMP_EXT_ACL_TYPE(MYADDR);
DUMP_EXT_ACL_TYPE(MYPORT);
DUMP_EXT_ACL_TYPE(URI);
str = buf;
break;
+#if USE_SQUID_EUI
+ case _external_acl_format::EXT_ACL_SRCEUI48:
+ if (request->client_eui48.encode(buf, sizeof(buf)))
+ str = buf;
+ break;
+
+ case _external_acl_format::EXT_ACL_SRCEUI64:
+ if (request->client_eui64.encode(buf, sizeof(buf)))
+ str = buf;
+ break;
+#endif
+
case _external_acl_format::EXT_ACL_MYADDR:
str = request->my_addr.NtoA(buf, sizeof(buf));
break;
#endif
}
+bool IpAddress::IsSiteLocal6() const
+{
+#if USE_IPV6
+ return (m_SocketAddr.sin6_addr.s6_addr32[0] & htonl(0xff80)) == htonl(0xfe80);
+#else
+ return false;
+#endif
+}
+
+bool IpAddress::IsSlaac() const
+{
+#if USE_IPV6
+ return (m_SocketAddr.sin6_addr.s6_addr32[2] & htonl(0x000000ff)) == htonl(0x000000ff) &&
+ (m_SocketAddr.sin6_addr.s6_addr32[3] & htonl(0xff000000)) == htonl(0xfe000000);
+#else
+ return false;
+#endif
+}
+
bool IpAddress::IsNoAddr() const
{
// IFF the address == 0xff..ff (all ones)
*/
bool IsLocalhost() const;
+ /** Test whether content is an IPv6 Site-Local address.
+ \retval true if address begins with fe80::/10.
+ \retval false if --disable-ipv6 has been compiled.
+ \retval false if address does not match fe80::/10
+ */
+ bool IsSiteLocal6() const;
+
+ /** Test whether content is an IPv6 address with SLAAC EUI-64 embeded.
+ \retval true if address matches ::ff:fe00:0
+ \retval false if --disable-ipv6 has been compiled.
+ \retval false if address does not match ::ff:fe00:0
+ */
+ bool IsSlaac() const;
+
/*@}*/
/** Retrieve the Port if stored.