+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include <sys/sysctl.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+
+static int eth_get(const char *device, u8 ea[ETH_ALEN])
+{
+ struct if_msghdr *ifm;
+ struct sockaddr_dl *sdl;
+ u_char *p, *buf;
+ size_t len;
+ int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
+
+ if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
+ return -1;
+ if ((buf = os_malloc(len)) == NULL)
+ return -1;
+ if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+ os_free(buf);
+ return -1;
+ }
+ for (p = buf; p < buf + len; p += ifm->ifm_msglen) {
+ ifm = (struct if_msghdr *)p;
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+ if (ifm->ifm_type != RTM_IFINFO ||
+ (ifm->ifm_addrs & RTA_IFP) == 0)
+ continue;
+ if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
+ os_memcmp(sdl->sdl_data, device, sdl->sdl_nlen) != 0)
+ continue;
+ os_memcpy(ea, LLADDR(sdl), sdl->sdl_alen);
+ break;
+ }
+ os_free(buf);
+
+ if (p >= buf + len) {
+ errno = ESRCH;
+ return -1;
+ }
+ return 0;
+}
+#endif /* __FreeBSD__ */
+
+