]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add API to get ethernet address from interface
authorAlan T. DeKok <aland@freeradius.org>
Wed, 27 May 2020 13:57:08 +0000 (09:57 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 27 May 2020 13:57:08 +0000 (09:57 -0400)
src/lib/util/inet.c
src/lib/util/inet.h

index 8b76ad0e2beca4863f34a81b9701b182a25c8225..4152c4645b007cfae9a9900821dfe4e9ae556151 100644 (file)
 #include <sys/types.h>
 #include <ifaddrs.h>
 
+#ifdef HAVE_LINUX_IF_PACKET_H
+#  include <linux/if_packet.h>
+#  include <linux/if_ether.h>
+#endif
+
+#include <net/if_arp.h>
+
+/*
+ *     Apple, *BSD
+ */
+#ifndef __linux__
+#include <net/if_dl.h>
+#endif
+
 bool fr_reverse_lookups = false;               //!< IP -> hostname lookups?
 bool fr_hostname_lookups = true;               //!< hostname -> IP lookups?
 
@@ -1403,3 +1417,47 @@ int fr_interface_to_ipaddr(char const *interface, fr_ipaddr_t *ipaddr, int af, b
        freeifaddrs(list);
        return rcode;
 }
+
+/*
+ *     AF_PACKET on Linux
+ *     AF_LINK on BSD
+ */
+#ifndef AF_LINK
+#define AF_LINK AF_PACKET
+#endif
+
+int fr_interface_to_ethernet(char const *interface, uint8_t ethernet[static 6])
+{
+       struct ifaddrs *list = NULL;
+       struct ifaddrs *i;
+       int rcode = -1;
+
+       if (getifaddrs(&list) < 0) return -1;
+
+       for (i = list; i != NULL; i = i->ifa_next) {
+               if (!i->ifa_addr || !i->ifa_name || (i->ifa_addr->sa_family != AF_LINK)) continue;
+               if (strcmp(i->ifa_name, interface) != 0) continue;
+
+#ifdef __linux__
+               struct sockaddr_ll *ll;
+
+               ll = (struct sockaddr_ll *) i->ifa_addr;
+               if ((ll->sll_hatype != 1) || (ll->sll_halen != 6)) continue;
+
+               memcpy(ethernet, ll->sll_addr, 6);
+
+#else
+               struct sockaddr_dl *ll;
+
+               ll = (struct sockaddr_dl *) i->ifa_addr;
+               if (ll->sdl_alen != 6) continue;
+
+               memcpy(ethernet, LLADDR(ll), 6);
+#endif
+               rcode = 0;
+               break;
+       }
+
+       freeifaddrs(list);
+       return rcode;
+}
index 638b033f08aeb56c24068ff919dd4dc83491f498..e6db8c07e087a3303186b5ce39b9fa5bae69bbd6 100644 (file)
@@ -141,6 +141,7 @@ int fr_ipaddr_from_ifindex(fr_ipaddr_t *out, int fd, int af, int if_index);
 char   *fr_ipaddr_to_interface(TALLOC_CTX *ctx, fr_ipaddr_t *ipaddr);
 int    fr_interface_to_ipaddr(char const *interface, fr_ipaddr_t *ipaddr, int af, bool link_local);
 
+int    fr_interface_to_ethernet(char const *interface, uint8_t ethernet[static 6]);
 /*
  *     Comparison
  */