From 7568b5719e357ebd97a685785237d5155b2c6504 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Wed, 27 May 2020 09:57:08 -0400 Subject: [PATCH] add API to get ethernet address from interface --- src/lib/util/inet.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/util/inet.h | 1 + 2 files changed, 59 insertions(+) diff --git a/src/lib/util/inet.c b/src/lib/util/inet.c index 8b76ad0e2b..4152c4645b 100644 --- a/src/lib/util/inet.c +++ b/src/lib/util/inet.c @@ -34,6 +34,20 @@ #include #include +#ifdef HAVE_LINUX_IF_PACKET_H +# include +# include +#endif + +#include + +/* + * Apple, *BSD + */ +#ifndef __linux__ +#include +#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; +} diff --git a/src/lib/util/inet.h b/src/lib/util/inet.h index 638b033f08..e6db8c07e0 100644 --- a/src/lib/util/inet.h +++ b/src/lib/util/inet.h @@ -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 */ -- 2.47.3