Erlang/OTP Forums

Author Message

<  Erlang patches mailing list  ~  [PATCH] inet: support retrieving MAC address on BSD

Guest
Posted: Wed Jul 21, 2010 6:51 pm Reply with quote
Guest
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.
---
erts/configure.in | 3 ++
erts/emulator/drivers/common/inet_drv.c | 40 +++++++++++++++++++++++++++---
2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/erts/configure.in b/erts/configure.in
index 63bf548..74cb953 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1764,6 +1764,9 @@ AC_CHECK_FUNCS([fdatasync])
dnl Find which C libraries are required to use fdatasync
AC_SEARCH_LIBS(fdatasync, [rt])

+AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h)
+AC_CHECK_FUNCS([getifaddrs])
+
dnl ----------------------------------------------------------------------
dnl Checks for features/quirks in the system that affects Erlang.
dnl ----------------------------------------------------------------------
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 0ea5493..e55208f 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)
--
1.5.6.4


________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Wed Jul 21, 2010 6:51 pm Reply with quote
Guest
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.
---
erts/configure.in | 3 ++
erts/emulator/drivers/common/inet_drv.c | 40 +++++++++++++++++++++++++++---
2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/erts/configure.in b/erts/configure.in
index 63bf548..74cb953 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1764,6 +1764,9 @@ AC_CHECK_FUNCS([fdatasync])
dnl Find which C libraries are required to use fdatasync
AC_SEARCH_LIBS(fdatasync, [rt])

+AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h)
+AC_CHECK_FUNCS([getifaddrs])
+
dnl ----------------------------------------------------------------------
dnl Checks for features/quirks in the system that affects Erlang.
dnl ----------------------------------------------------------------------
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 0ea5493..e55208f 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)
--
1.5.6.4


________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org

Post received from mailinglist

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum