]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/eui/Eui48.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / eui / Eui48.cc
index d7d9ab7a785f1ea9375f7a7d95e2505e39661816..de50ac701aaa99027dfe9ad199264b6eeba1ab89 100644 (file)
@@ -1,37 +1,13 @@
 /*
- * DEBUG: section 89    EUI-48 Lookup
- * AUTHOR: Duane Wessels
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
  *
- * 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>
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
+/* DEBUG: section 89    EUI-48 Lookup */
+
 #include "squid.h"
 
 #if USE_SQUID_EUI
 #include "globals.h"
 #include "ip/Address.h"
 
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
+#include <cerrno>
 
 /* START Legacy includes pattern */
-/* TODO: clean this up so we dont have per-OS requirements.
+/* TODO: clean this up so we do not have per-OS requirements.
          The files are checked for existence individually
          and can be wrapped
  */
@@ -59,8 +33,9 @@ struct arpreq {
     struct sockaddr arp_ha;   /* hardware address */
     int arp_flags;            /* flags */
 };
-
-#include <Iphlpapi.h>
+#if HAVE_IPHLPAPI_H
+#include <iphlpapi.h>
+#endif
 #endif
 
 #if HAVE_SYS_PARAM_H
@@ -104,7 +79,7 @@ struct arpreq {
  * 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
+ * Control 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> ...
@@ -126,7 +101,7 @@ Eui::Eui48::decode(const char *asc)
     if (sscanf(asc, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6) {
         debugs(28, DBG_CRITICAL, "Decode EUI-48: Invalid ethernet address '" << asc << "'");
         clear();
-        return false;          /* This is not valid address */
+        return false;       /* This is not valid address */
     }
 
     eui[0] = (u_char) a1;
@@ -135,18 +110,23 @@ Eui::Eui48::decode(const char *asc)
     eui[3] = (u_char) a4;
     eui[4] = (u_char) a5;
     eui[5] = (u_char) a6;
+
+    debugs(28, 4, "id=" << (void*)this << " decoded " << asc);
     return true;
 }
 
 bool
-Eui::Eui48::encode(char *buf, const int len)
+Eui::Eui48::encode(char *buf, const int len) const
 {
-    if (len < SZ_EUI48_BUF) return false;
+    if (len < SZ_EUI48_BUF)
+        return false;
 
     snprintf(buf, len, "%02x:%02x:%02x:%02x:%02x:%02x",
              eui[0] & 0xff, eui[1] & 0xff,
              eui[2] & 0xff, eui[3] & 0xff,
              eui[4] & 0xff, eui[5] & 0xff);
+
+    debugs(28, 4, "id=" << (void*)this << " encoded " << buf);
     return true;
 }
 
@@ -154,9 +134,6 @@ Eui::Eui48::encode(char *buf, const int len)
 bool
 Eui::Eui48::lookup(const Ip::Address &c)
 {
-#if !_SQUID_WINDOWS_
-#endif /* !_SQUID_WINDOWS_ */
-
     Ip::Address ipAddr = c;
     ipAddr.port(0);
 
@@ -171,7 +148,8 @@ Eui::Eui48::lookup(const Ip::Address &c)
     /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */
     int tmpSocket = socket(AF_INET,SOCK_STREAM,0);
     if (tmpSocket < 0) {
-        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerr(xerrno));
         clear();
         return false;
     }
@@ -198,16 +176,18 @@ Eui::Eui48::lookup(const Ip::Address &c)
     ipAddr.getSockAddr(*sa);
 
     /* Query ARP table */
+    debugs(28, 4, "id=" << (void*)this << " query ARP table");
     if (ioctl(tmpSocket, SIOCGARP, &arpReq) != -1) {
         /* Skip non-ethernet interfaces */
         close(tmpSocket);
 
         if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) {
+            debugs(28, 4, "id=" << (void*)this << " ... not an Ethernet interface: " << arpReq.arp_ha.sa_data);
             clear();
             return false;
         }
 
-        debugs(28, 4, "Got address "<< std::setfill('0') << std::hex <<
+        debugs(28, 4, "id=" << (void*)this << " got address "<< std::setfill('0') << std::hex <<
                std::setw(2) << (arpReq.arp_ha.sa_data[0] & 0xff)  << ":" <<
                std::setw(2) << (arpReq.arp_ha.sa_data[1] & 0xff)  << ":" <<
                std::setw(2) << (arpReq.arp_ha.sa_data[2] & 0xff)  << ":" <<
@@ -225,7 +205,8 @@ Eui::Eui48::lookup(const Ip::Address &c)
     ifc.ifc_buf = (char *)ifbuffer;
 
     if (ioctl(tmpSocket, SIOCGIFCONF, &ifc) < 0) {
-        debugs(28, DBG_IMPORTANT, "Attempt to retrieve interface list failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(28, DBG_IMPORTANT, "Attempt to retrieve interface list failed: " << xstrerr(xerrno));
         clear();
         close(tmpSocket);
         return false;
@@ -240,20 +221,22 @@ Eui::Eui48::lookup(const Ip::Address &c)
 
     /* Attempt ARP lookup on each interface */
     offset = 0;
-
+    debugs(28, 4, "id=" << (void*)this << " query ARP on each interface (" << ifc.ifc_len << " found)");
     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))
+        debugs(28, 4, "id=" << (void*)this << " found interface " << ifr->ifr_name);
+
+        /* Skip loopback and aliased interfaces */
+        if (!strncmp(ifr->ifr_name, "lo", 2))
             continue;
 
-        if (NULL != strchr(ifr->ifr_name, ':'))
+        if (strchr(ifr->ifr_name, ':'))
             continue;
 
-        debugs(28, 4, "Looking up ARP address for " << ipAddr << " on " << ifr->ifr_name);
+        debugs(28, 4, "id=" << (void*)this << " looking up ARP address for " << ipAddr << " on " << ifr->ifr_name);
 
         /* Set up structures for ARP lookup */
 
@@ -268,26 +251,21 @@ Eui::Eui48::lookup(const Ip::Address &c)
 
         /* Query ARP table */
         if (-1 == ioctl(tmpSocket, 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
-                debugs(28, DBG_IMPORTANT, "ARP query " << ipAddr << " failed: " << ifr->ifr_name << ": " << xstrerror());
+            int xerrno = errno;
+            //  Query failed.  Do not log failed lookups or "device not supported"
+            if (ENXIO != xerrno && ENODEV != xerrno)
+                debugs(28, DBG_IMPORTANT, "ARP query " << ipAddr << " failed: " << ifr->ifr_name << ": " << xstrerr(xerrno));
 
             continue;
         }
 
         /* Skip non-ethernet interfaces */
-        if (arpReq.arp_ha.sa_family != ARPHRD_ETHER)
+        if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) {
+            debugs(28, 4, "id=" << (void*)this << "... not an Ethernet interface");
             continue;
+        }
 
-        debugs(28, 4, "Got address "<< std::setfill('0') << std::hex <<
+        debugs(28, 4, "id=" << (void*)this << " got address "<< std::setfill('0') << std::hex <<
                std::setw(2) << (arpReq.arp_ha.sa_data[0] & 0xff)  << ":" <<
                std::setw(2) << (arpReq.arp_ha.sa_data[1] & 0xff)  << ":" <<
                std::setw(2) << (arpReq.arp_ha.sa_data[2] & 0xff)  << ":" <<
@@ -315,7 +293,8 @@ Eui::Eui48::lookup(const Ip::Address &c)
     /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */
     int tmpSocket = socket(AF_INET,SOCK_STREAM,0);
     if (tmpSocket < 0) {
-        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerr(xerrno));
         clear();
         return false;
     }
@@ -354,6 +333,8 @@ Eui::Eui48::lookup(const Ip::Address &c)
 
         set(arpReq.arp_ha.sa_data, 6);
         return true;
+    } else {
+        close(tmpSocket);
     }
 
 #elif _SQUID_FREEBSD_ || _SQUID_NETBSD_ || _SQUID_OPENBSD_ || _SQUID_DRAGONFLY_ || _SQUID_KFREEBSD_
@@ -390,7 +371,11 @@ Eui::Eui48::lookup(const Ip::Address &c)
 
     mib[4] = NET_RT_FLAGS;
 
+#if defined(RTF_LLDATA)
+    mib[5] = RTF_LLDATA;
+#else
     mib[5] = RTF_LLINFO;
+#endif
 
     if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
         debugs(28, DBG_CRITICAL, "Can't estimate ARP table size!");
@@ -528,7 +513,7 @@ Eui::Eui48::lookup(const Ip::Address &c)
     /*
      * Address was not found on any interface
      */
-    debugs(28, 3, HERE << ipAddr << " NOT found");
+    debugs(28, 3, "id=" << (void*)this << ' ' << ipAddr << " NOT found");
 
     clear();
     return false;
@@ -537,3 +522,4 @@ Eui::Eui48::lookup(const Ip::Address &c)
 /* ==== END EUI LOOKUP SUPPORT =============================================== */
 
 #endif /* USE_SQUID_EUI */
+