From: hno <> Date: Mon, 18 Oct 2004 04:13:02 +0000 (+0000) Subject: Bug #909: FreeBSD support for ARP acls X-Git-Tag: SQUID_3_0_PRE4~1019 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9a2f11703091c92a6347700429146b12dada36fe;p=thirdparty%2Fsquid.git Bug #909: FreeBSD support for ARP acls By Glen Gibb, ported to Squid-3 by Guido. --- diff --git a/configure.in b/configure.in index c4848447cf..843f0d57d9 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Configuration input file for Squid dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.360 2004/10/10 03:03:32 hno Exp $ +dnl $Id: configure.in,v 1.361 2004/10/17 22:13:02 hno Exp $ dnl dnl dnl @@ -13,7 +13,7 @@ AC_CONFIG_SRCDIR([src/main.cc]) AC_CONFIG_AUX_DIR(cfgaux) AM_INIT_AUTOMAKE(squid, 3.0-PRE3-CVS) AM_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.360 $)dnl +AC_REVISION($Revision: 1.361 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE @@ -666,6 +666,8 @@ AC_ARG_ENABLE(arp-acl, ;; *-solaris-*) ;; + *-freebsd*) + ;; *) echo "WARNING: ARP ACL support probably won't work on $host." sleep 10 diff --git a/src/ACLARP.cc b/src/ACLARP.cc index 10e42042e6..bf3f1fc987 100644 --- a/src/ACLARP.cc +++ b/src/ACLARP.cc @@ -1,5 +1,5 @@ /* - * $Id: ACLARP.cc,v 1.5 2004/08/30 05:12:30 robertc Exp $ + * $Id: ACLARP.cc,v 1.6 2004/10/17 22:13:03 hno Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -49,6 +49,9 @@ #endif #include #include +#ifdef _SQUID_FREEBSD__ +#include +#endif #if HAVE_NETINET_IF_ETHER_H #include #endif @@ -423,7 +426,122 @@ aclMatchArp(SplayNode **dataptr, struct in_addr c) return (0 == splayLastResult); } +#elif defined(_SQUID_FREEBSD_) + + 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; + + int mib[6]; + + size_t needed; + + char *lim, *buf, *next; + + struct rt_msghdr *rtm; + + struct sockaddr_inarp *sin; + + struct sockaddr_dl *sdl; + + /* + * 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 */ + mib[0] = CTL_NET; + + mib[1] = PF_ROUTE; + + mib[2] = 0; + + mib[3] = AF_INET; + + mib[4] = NET_RT_FLAGS; + + mib[5] = RTF_LLINFO; + + 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); */ + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + + (char *) sdl = (char *) sin + ROUNDUP(sin->sin_len); + + if (c.s_addr == sin->sin_addr.s_addr) { + if (sdl->sdl_alen) { + + arpReq.arp_ha.sa_len = sizeof(struct sockaddr); + arpReq.arp_ha.sa_family = AF_UNSPEC; + memcpy(arpReq.arp_ha.sa_data, LLADDR(sdl), sdl->sdl_alen); + } + } + } + + xfree(buf); + + 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 = (*Top)->splay(&arpReq.arp_ha.sa_data, aclArpCompare); + + debug(28, 3) ("aclMatchArp: '%s' %s\n", + inet_ntoa(c), splayLastResult ? "NOT found" : "found"); + + return (0 == splayLastResult); + #else + WRITE ME; #endif