]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug #909: FreeBSD support for ARP acls
authorhno <>
Mon, 18 Oct 2004 04:13:02 +0000 (04:13 +0000)
committerhno <>
Mon, 18 Oct 2004 04:13:02 +0000 (04:13 +0000)
By Glen Gibb, ported to Squid-3 by Guido.

configure.in
src/ACLARP.cc

index c4848447cf6fc5f28a7ec4c8d7f8f146fddbd948..843f0d57d951b2bc44b2ef071836d5c37ca4d208 100644 (file)
@@ -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
index 10e42042e685da856e87ac1c6024fd1d15850bdb..bf3f1fc987038185a31212e598e4a9d42d9844f2 100644 (file)
@@ -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 <net/route.h>
 #include <net/if.h>
+#ifdef _SQUID_FREEBSD__
+#include <net/if_arp.h>
+#endif
 #if HAVE_NETINET_IF_ETHER_H
 #include <netinet/if_ether.h>
 #endif
@@ -423,7 +426,122 @@ aclMatchArp(SplayNode<acl_arp_data *> **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<acl_arp_data *> **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