aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/drivers/common/inet_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/drivers/common/inet_drv.c')
-rw-r--r--erts/emulator/drivers/common/inet_drv.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 56799555a9..7d952b0c71 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -4233,6 +4233,31 @@ static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize)
return sp - sbuf;
}
+#ifdef HAVE_LIBDLPI_H
+#include <libdlpi.h>
+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
@@ -4268,7 +4293,24 @@ 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) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR)
if (ioctl(desc->s, SIOCGIFHWADDR, (char *)&ifreq) < 0)
break;
buf_check(sptr, s_end, 1+2+IFHWADDRLEN);
@@ -4277,7 +4319,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));
@@ -10322,6 +10364,7 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event)
int code;
void * extra = NULL;
char * ptr;
+ int nsz;
inet_input_count(desc, n);
udesc->i_ptr += n;
@@ -10335,17 +10378,19 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event)
ptr = udesc->i_buf->orig_bytes + sizeof(other) - len;
sys_memcpy(ptr, abuf, len);
+ nsz = udesc->i_ptr - ptr;
+
/* Check if we need to reallocate binary */
- if ((desc->mode == INET_MODE_BINARY) &&
- (desc->hsz < (udesc->i_ptr - ptr)) &&
- ((udesc->i_ptr - ptr) + BIN_REALLOC_MARGIN(desc->bufsz) >=
- udesc->i_bufsz)) {
+ if ((desc->mode == INET_MODE_BINARY)
+ && (desc->hsz < (nsz - len))
+ && (nsz + BIN_REALLOC_MARGIN(desc->bufsz) < udesc->i_bufsz)) {
ErlDrvBinary* tmp;
int bufsz;
bufsz = udesc->i_ptr - udesc->i_buf->orig_bytes;
if ((tmp = realloc_buffer(udesc->i_buf, bufsz)) != NULL) {
udesc->i_buf = tmp;
udesc->i_bufsz = bufsz;
+ udesc->i_ptr = NULL; /* not used from here */
}
}
#ifdef HAVE_SCTP
@@ -10353,8 +10398,8 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event)
#endif
/* Actual parsing and return of the data received, occur here: */
code = packet_reply_binary_data(desc, len, udesc->i_buf,
- ptr - udesc->i_buf->orig_bytes,
- udesc->i_ptr - ptr,
+ (sizeof(other) - len),
+ nsz,
extra);
free_buffer(udesc->i_buf);
udesc->i_buf = NULL;