mirror of
https://github.com/MariaDB/server.git
synced 2026-05-06 23:25:34 +02:00
my_gethwaddr() on Solaris and Windows
This commit is contained in:
parent
45ee26699e
commit
f3523559aa
3 changed files with 87 additions and 22 deletions
|
|
@ -16,11 +16,22 @@
|
|||
/* get hardware address for an interface */
|
||||
/* if there are many available, any non-zero one can be used */
|
||||
|
||||
#define DONT_DEFINE_VOID /* windows includes break if we do */
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
#ifndef MAIN
|
||||
|
||||
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
|
||||
{
|
||||
uint i, res= 1;
|
||||
|
||||
for (i= 0; i < len; i++)
|
||||
if ((*to++= *from++))
|
||||
res= 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#include <net/ethernet.h>
|
||||
|
|
@ -32,11 +43,10 @@
|
|||
my_bool my_gethwaddr(uchar *to)
|
||||
{
|
||||
size_t len;
|
||||
char *buf, *next, *end;
|
||||
uchar *buf, *next, *end, *addr;
|
||||
struct if_msghdr *ifm;
|
||||
struct sockaddr_dl *sdl;
|
||||
int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
|
||||
char zero_array[ETHER_ADDR_LEN] = {0};
|
||||
int res= 1, mib[6]= {CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
|
||||
|
||||
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
|
||||
goto err;
|
||||
|
|
@ -52,9 +62,9 @@ my_bool my_gethwaddr(uchar *to)
|
|||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type == RTM_IFINFO)
|
||||
{
|
||||
sdl= (struct sockaddr_dl *)(ifm + 1);
|
||||
memcpy(to, LLADDR(sdl), ETHER_ADDR_LEN);
|
||||
res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
addr= LLADDR(sdl);
|
||||
res= memcpy_and_test(to, addr, ETHER_ADDR_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,40 +72,94 @@ err:
|
|||
return res;
|
||||
}
|
||||
|
||||
#elif __linux__
|
||||
|
||||
#elif defined(__linux__) || defined(__sun__)
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if_arp.h>
|
||||
#ifdef HAVE_SYS_SOCKIO_H
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
my_bool my_gethwaddr(uchar *to)
|
||||
{
|
||||
int fd, res= 1;
|
||||
struct ifreq ifr;
|
||||
char zero_array[ETHER_ADDR_LEN] = {0};
|
||||
struct ifreq ifr[32];
|
||||
struct ifconf ifc;
|
||||
|
||||
ifc.ifc_req= ifr;
|
||||
ifc.ifc_len= sizeof(ifr);
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
goto err;
|
||||
|
||||
bzero(&ifr, sizeof(ifr));
|
||||
strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
|
||||
|
||||
do
|
||||
if (ioctl(fd, SIOCGIFCONF, (char*)&ifc) >= 0)
|
||||
{
|
||||
if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0)
|
||||
uint i;
|
||||
for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++)
|
||||
{
|
||||
memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
|
||||
res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
|
||||
#ifdef SIOCGIFHWADDR
|
||||
if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0)
|
||||
res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data,
|
||||
ETHER_ADDR_LEN);
|
||||
#else
|
||||
/*
|
||||
A bug in OpenSolaris prevents non-root from getting a mac address:
|
||||
http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4720634
|
||||
|
||||
Thus, we'll use an alternative method and extract the address from the
|
||||
arp table.
|
||||
*/
|
||||
struct arpreq arpr;
|
||||
arpr.arp_pa= ifr[i].ifr_addr;
|
||||
|
||||
if (ioctl(fd, SIOCGARP, (char*)&arpr) >= 0)
|
||||
res= memcpy_and_test(to, (uchar *)&arpr.arp_ha.sa_data,
|
||||
ETHER_ADDR_LEN);
|
||||
#endif
|
||||
}
|
||||
} while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6');
|
||||
}
|
||||
|
||||
close(fd);
|
||||
err:
|
||||
return res;
|
||||
}
|
||||
|
||||
#else /* FreeBSD elif linux */
|
||||
#elif defined(_WIN32)
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
my_bool my_gethwaddr(uchar *to)
|
||||
{
|
||||
my_bool res= 1;
|
||||
|
||||
IP_ADAPTER_INFO *info= NULL;
|
||||
ULONG info_len= 0;
|
||||
|
||||
if (GetAdaptersInfo(info, &info_len) != ERROR_BUFFER_OVERFLOW)
|
||||
goto err;
|
||||
|
||||
info= alloca(info_len);
|
||||
|
||||
if (GetAdaptersInfo(info, &info_len) != NO_ERROR)
|
||||
goto err;
|
||||
|
||||
while (info && res)
|
||||
{
|
||||
if (info->Type == MIB_IF_TYPE_ETHERNET &&
|
||||
info->AddressLength == ETHER_ADDR_LEN)
|
||||
res= memcpy_and_test(to, info->Address, ETHER_ADDR_LEN);
|
||||
}
|
||||
|
||||
err:
|
||||
return res;
|
||||
}
|
||||
|
||||
#else /* neither FreeBSD nor linux not Windows */
|
||||
/* just fail */
|
||||
my_bool my_gethwaddr(uchar *to __attribute__((unused)))
|
||||
{
|
||||
|
|
@ -114,7 +178,7 @@ int main(int argc __attribute__((unused)),char **argv)
|
|||
printf("my_gethwaddr failed with errno %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
for (i=0; i < sizeof(mac); i++)
|
||||
for (i= 0; i < sizeof(mac); i++)
|
||||
{
|
||||
if (i) printf(":");
|
||||
printf("%02x", mac[i]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue