diff options
author | Michael Santos <[email protected]> | 2010-07-21 14:50:58 -0400 |
---|---|---|
committer | Raimo Niskanen <[email protected]> | 2010-09-03 16:52:28 +0200 |
commit | 8393c5d5b682f8acbdc0ecf5b0e6f87589a314cb (patch) | |
tree | 969d5157e09771f4743cfa52987abb62a2fc9a28 /erts/emulator/drivers/common/inet_drv.c | |
parent | d61d41e235bc464a15925e6fd1b7e9138477d3b3 (diff) | |
download | otp-8393c5d5b682f8acbdc0ecf5b0e6f87589a314cb.tar.gz otp-8393c5d5b682f8acbdc0ecf5b0e6f87589a314cb.tar.bz2 otp-8393c5d5b682f8acbdc0ecf5b0e6f87589a314cb.zip |
inet: support retrieving MAC address on BSD
On systems supporting getaddrinfo(), support looking up the MAC
address from inet:ifget/2. The results have the same quirks as with
Linux: if the MAC address is longer than 6 bytes (e.g., fw0 under
Mac OS X), the address is truncated; if the interface does not have
a MAC address (e.g., lo0), an address consisting of 0's is returned.
Diffstat (limited to 'erts/emulator/drivers/common/inet_drv.c')
-rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 8e312c0292..dfa3814d78 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -48,6 +48,12 @@ #include <sys/uio.h> #endif +#ifdef HAVE_NET_IF_DL_H +#include <net/if_dl.h> +#endif +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif /* All platforms fail on malloc errors. */ #define FATAL_MALLOC @@ -4089,6 +4095,10 @@ static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize) } +/* FIXME: temporary hack */ +#ifndef IFHWADDRLEN +#define IFHWADDRLEN 6 +#endif static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, char** rbuf, int rsize) @@ -4128,6 +4138,32 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, /* raw memcpy (fix include autoconf later) */ sys_memcpy(sptr, (char*)(&ifreq.ifr_hwaddr.sa_data), IFHWADDRLEN); sptr += IFHWADDRLEN; +#elif defined(HAVE_GETIFADDRS) + struct ifaddrs *ifa, *ifp; + int found = 0; + + if (getifaddrs(&ifa) == -1) + goto error; + + for (ifp = ifa; ifp; ifp = ifp->ifa_next) { + if ((ifp->ifa_addr->sa_family == AF_LINK) && + (sys_strcmp(ifp->ifa_name, ifreq.ifr_name) == 0)) { + found = 1; + break; + } + } + + if (found == 0) { + freeifaddrs(ifa); + break; + } + + buf_check(sptr, s_end, 1+IFHWADDRLEN); + *sptr++ = INET_IFOPT_HWADDR; + sys_memcpy(sptr, ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_data + + ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_nlen, IFHWADDRLEN); + freeifaddrs(ifa); + sptr += IFHWADDRLEN; #endif break; } @@ -4240,10 +4276,6 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, return ctl_error(EINVAL, rbuf, rsize); } -/* FIXME: temporary hack */ -#ifndef IFHWADDRLEN -#define IFHWADDRLEN 6 -#endif static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len, char** rbuf, int rsize) |