From 06554482af2de923e8b5c2849f315138cada24e3 Mon Sep 17 00:00:00 2001 From: Trond Norbye Date: Fri, 8 Apr 2011 16:31:57 +0200 Subject: Use libdlpi to get physical address --- erts/configure.in | 6 ++++- erts/emulator/drivers/common/inet_drv.c | 46 ++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/erts/configure.in b/erts/configure.in index e3eb6034e6..992df948cf 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1479,7 +1479,7 @@ AC_CHECK_HEADERS(fcntl.h limits.h unistd.h syslog.h dlfcn.h ieeefp.h \ sys/types.h sys/stropts.h sys/sysctl.h \ sys/ioctl.h sys/time.h sys/uio.h \ sys/socket.h sys/sockio.h sys/socketio.h \ - net/errno.h malloc.h arpa/nameser.h \ + net/errno.h malloc.h arpa/nameser.h libdlpi.h \ pty.h util.h utmp.h langinfo.h poll.h sdkddkver.h) AC_CHECK_HEADER(sys/resource.h, @@ -4303,6 +4303,10 @@ AH_BOTTOM([ #endif ]) +dnl ---------------------------------------------------------------------- +dnl Check the availability for libdlpi +dnl ---------------------------------------------------------------------- +AC_CHECK_LIB(dlpi, dlpi_open) dnl ---------------------------------------------------------------------- dnl Output the result. diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 1fe9e04341..455006533e 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -4222,6 +4222,31 @@ static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize) return sp - sbuf; } +#ifdef HAVE_LIBDLPI_H +#include +static int hwaddr_libdlpi_lookup(const char *ifnm, + uchar_t *addr, size_t *alen) +{ + dlpi_handle_t handle; + dlpi_info_t linkinfo; + int ret = -1; + + if (dlpi_open(ifnm, &handle, 0) != DLPI_SUCCESS) { + return -1; + } + + if (dlpi_get_physaddr(handle, DL_CURR_PHYS_ADDR, + addr, alen) == DLPI_SUCCESS && + dlpi_info(handle, &linkinfo, 0) == DLPI_SUCCESS) + { + ret = 0; + } + + dlpi_close(handle); + return ret; +} +#endif + /* FIXME: temporary hack */ #ifndef IFHWADDRLEN #define IFHWADDRLEN 6 @@ -4257,7 +4282,26 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, break; case INET_IFOPT_HWADDR: { -#ifdef SIOCGIFHWADDR +#ifdef HAVE_LIBDLPI_H + { + /* + ** OpenSolaris have SIGCGIFHWADDR, but no ifr_hwaddr member.. + ** The proper way to get the mac address would be to + ** use libdlpi... + */ + uchar_t addr[DLPI_PHYSADDR_MAX]; + size_t alen = sizeof(addr); + + if (hwaddr_libdlpi_lookup(ifreq.ifr_name, addr, &alen) == 0) { + buf_check(sptr, s_end, 1+2+alen); + *sptr++ = INET_IFOPT_HWADDR; + put_int16(alen, sptr); + sptr += 2; + sys_memcpy(sptr, addr, alen); + sptr += alen; + } + } +#elif defined(SIOCGIFHWADDR) if (ioctl(desc->s, SIOCGIFHWADDR, (char *)&ifreq) < 0) break; buf_check(sptr, s_end, 1+2+IFHWADDRLEN); -- cgit v1.2.3 From 5643ef4f4203734cdc4f6c7fe9898d288d721fb8 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 24 Nov 2011 18:22:34 +0100 Subject: Work around gcc linking with own view of default libs on Solaris Also use 64-bit lib when necessary, specify runtime lib path for secondary dependency libs, and better check before using SIOCGIFHWADDR. --- erts/configure.in | 57 ++++++++++++++++++++++++++++++--- erts/emulator/drivers/common/inet_drv.c | 2 +- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/erts/configure.in b/erts/configure.in index 992df948cf..699e30c297 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1482,6 +1482,58 @@ AC_CHECK_HEADERS(fcntl.h limits.h unistd.h syslog.h dlfcn.h ieeefp.h \ net/errno.h malloc.h arpa/nameser.h libdlpi.h \ pty.h util.h utmp.h langinfo.h poll.h sdkddkver.h) +AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr], [], [], + [#ifdef __WIN32__ + #else + #ifdef VXWORKS + #else + #include + #endif + #endif + ]) + +dnl ---------------------------------------------------------------------- +dnl Check the availability for libdlpi +dnl ---------------------------------------------------------------------- +AC_CHECK_LIB(dlpi, dlpi_open) +if test x"$ac_cv_lib_dlpi_dlpi_open" = x"no"; then + unset -v ac_cv_lib_dlpi_dlpi_open + dnl Try again now with -L/lib (or ditto 64) as argument to linker since + dnl gcc makes /usr/ccs/bin/ld ignore the crle configured linker default paths + dnl typically causing dlpi not being found on Solaris et.al + save_ldflags="$LDFLAGS" + try_dlpi_lib=/lib + if test x"$ac_cv_sizeof_void_p" = x"8"; then + if test -d /lib64; then + try_dlpi_lib=/lib64 + elif test -d /lib/64; then + try_dlpi_lib=/lib/64 + fi + fi + if test ! -f "$try_dlpi_lib/libdlpi.so" && \ + test -f "$try_dlpi_lib/libdlpi.so.1" + then + dnl It looks like there is a missing symlink + dnl - let's be helpful and notify the user + dnl NOTE this help is far from perfect e.g if there would be no + dnl *.so.1 but a *.so.1.123 or *.so.2 this will be no help + AC_MSG_ERROR( + [Your OS installation is missing a symbolic link. + Maybe it lacks some development package(s)... + It can anyhow be fixed with the following command: + # ln -s libdlpi.so.1 $try_dlpi_lib/libdlpi.so + ]) + fi + LDFLAGS="-L$try_dlpi_lib -R$try_dlpi_lib $LDFLAGS" + unset -v try_dlpi_lib + AC_MSG_NOTICE([Extending the search to include /lib]) + AC_CHECK_LIB(dlpi, dlpi_open) + if test x"$ac_cv_lib_dlpi_dlpi_open" = x"no"; then + LDFLAGS="$save_ldflags" + fi + unset -v save_ldflags +fi + AC_CHECK_HEADER(sys/resource.h, [AC_DEFINE(HAVE_SYS_RESOURCE_H, 1, [Define to 1 if you have the header file]) @@ -4303,11 +4355,6 @@ AH_BOTTOM([ #endif ]) -dnl ---------------------------------------------------------------------- -dnl Check the availability for libdlpi -dnl ---------------------------------------------------------------------- -AC_CHECK_LIB(dlpi, dlpi_open) - dnl ---------------------------------------------------------------------- dnl Output the result. dnl ---------------------------------------------------------------------- diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 455006533e..9dbe66170d 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -4301,7 +4301,7 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, sptr += alen; } } -#elif defined(SIOCGIFHWADDR) +#elif defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR) if (ioctl(desc->s, SIOCGIFHWADDR, (char *)&ifreq) < 0) break; buf_check(sptr, s_end, 1+2+IFHWADDRLEN); -- cgit v1.2.3 From cc6a54d8f4467083fd2b450764a7178918667e96 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 25 Nov 2011 11:39:10 +0100 Subject: Cleanup - remove unnecesary bracket level and configure for ifreq.ifr_enaddr --- erts/configure.in | 10 ++++++++++ erts/emulator/drivers/common/inet_drv.c | 30 ++++++++++++++---------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/erts/configure.in b/erts/configure.in index 699e30c297..d67b9cec1f 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1492,6 +1492,16 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr], [], [], #endif ]) +AC_CHECK_MEMBERS([struct ifreq.ifr_enaddr], [], [], + [#ifdef __WIN32__ + #else + #ifdef VXWORKS + #else + #include + #endif + #endif + ]) + dnl ---------------------------------------------------------------------- dnl Check the availability for libdlpi dnl ---------------------------------------------------------------------- diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 9dbe66170d..27868b0f73 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -4283,24 +4283,22 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, case INET_IFOPT_HWADDR: { #ifdef HAVE_LIBDLPI_H - { - /* - ** OpenSolaris have SIGCGIFHWADDR, but no ifr_hwaddr member.. - ** The proper way to get the mac address would be to - ** use libdlpi... - */ - uchar_t addr[DLPI_PHYSADDR_MAX]; - size_t alen = sizeof(addr); - - if (hwaddr_libdlpi_lookup(ifreq.ifr_name, addr, &alen) == 0) { - buf_check(sptr, s_end, 1+2+alen); - *sptr++ = INET_IFOPT_HWADDR; - put_int16(alen, sptr); + /* + ** OpenSolaris have SIGCGIFHWADDR, but no ifr_hwaddr member.. + ** The proper way to get the mac address would be to + ** use libdlpi... + */ + uchar_t addr[DLPI_PHYSADDR_MAX]; + size_t alen = sizeof(addr); + + if (hwaddr_libdlpi_lookup(ifreq.ifr_name, addr, &alen) == 0) { + buf_check(sptr, s_end, 1+2+alen); + *sptr++ = INET_IFOPT_HWADDR; + put_int16(alen, sptr); sptr += 2; sys_memcpy(sptr, addr, alen); sptr += alen; - } - } + } #elif defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR) if (ioctl(desc->s, SIOCGIFHWADDR, (char *)&ifreq) < 0) break; @@ -4310,7 +4308,7 @@ 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(SIOCGENADDR) +#elif defined(SIOCGENADDR) && defined(HAVE_STRUCT_IFREQ_IFR_ENADDR) if (ioctl(desc->s, SIOCGENADDR, (char *)&ifreq) < 0) break; buf_check(sptr, s_end, 1+2+sizeof(ifreq.ifr_enaddr)); -- cgit v1.2.3