CVS: winex/dlls/netapi32 netapi32.c,1.6,1.7
[email protected] 31 Jul 2007 17:31:40 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/dlls/netapi32 netapi32.c,1.6,1.7Update of /var/lib/cvsd/cvsroot/winex/dlls/netapi32
In directory agravaine:/tmp/cvs-serv20246/dlls/netapi32
Modified Files:
netapi32.c
Log Message:
- fix interface checking to not use hardcoded buffer size
- support retrieving MAC address on MacOS X
Index: netapi32.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/netapi32/netapi32.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- netapi32.c 31 Jul 2007 17:31:31 -0000 1.6
+++ netapi32.c 31 Jul 2007 17:31:38 -0000 1.7
@@ -37,14 +37,11 @@
#endif
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-# ifndef max
-# define max(a,b) ((a) > (b) ? (a) : (b))
-# endif
-# define ifreq_size(i) max(sizeof(struct ifreq),\
-sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
-# else
-# define ifreq_size(i) sizeof(struct ifreq)
-# endif /* defined(HAVE_STRUCT_SOCKADDR_SA_LEN) */
+#define ifreq_len(ifr) \
+ max(sizeof(struct ifreq), sizeof((ifr)->ifr_name)+(ifr)->ifr_addr.sa_len)
+#else
+#define ifreq_len(ifr) sizeof(struct ifreq)
+#endif
WINE_DEFAULT_DEBUG_CHANNEL(netbios);
@@ -76,7 +73,57 @@
memcpy(address, (unsigned char *) ifr->ifr_enaddr, 6);
return 0;
}
-# else
+#elif defined(__APPLE__)
+#include <sys/sysctl.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+
+int get_hw_address (int sd, struct ifreq *ifr, unsigned char *addr)
+{
+ DWORD ret;
+ struct if_msghdr *ifm;
+ struct sockaddr_dl *sdl;
+ u_char *p, *buf;
+ size_t mibLen;
+ int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
+ int addrLen;
+ BOOL found = FALSE;
+
+ if (sysctl(mib, 6, NULL, &mibLen, NULL, 0) < 0)
+ return -1;
+
+ buf = HeapAlloc(GetProcessHeap(), 0, mibLen);
+ if (!buf)
+ return -1;
+
+ if (sysctl(mib, 6, buf, &mibLen, NULL, 0) < 0) {
+ HeapFree(GetProcessHeap(), 0, buf);
+ return -1;
+ }
+
+ ret = ERROR_INVALID_DATA;
+ for (p = buf; !found && p < buf + mibLen; p += ifm->ifm_msglen) {
+ ifm = (struct if_msghdr *)p;
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+
+ if (ifm->ifm_type != RTM_IFINFO || (ifm->ifm_addrs & RTA_IFP) == 0)
+ continue;
+
+ if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
+ memcmp(sdl->sdl_data, ifr->ifr_name,
+ max(sdl->sdl_nlen, strlen(ifr->ifr_name))) != 0)
+ continue;
+
+ found = TRUE;
+ addrLen = min(8, sdl->sdl_alen);
+ if (addrLen > 0)
+ memcpy(addr, LLADDR(sdl), addrLen);
+ /* zero out remaining bytes for broken implementations */
+ }
+ HeapFree(GetProcessHeap(), 0, buf);
+ return 0;
+}
+#else
int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
{
return -1;
@@ -88,10 +135,11 @@
{
#ifdef HAVE_NET_IF_H
int sd;
- struct ifreq ifr, *ifrp;
struct ifconf ifc;
- unsigned char buf[1024];
- int i, ofs;
+ int i;
+ int lastlen, numAddresses = 2;
+ int ioctlRet = 0;
+ caddr_t ifPtr;
#endif
LANA_ENUM *lanas = NULL;
@@ -114,24 +162,49 @@
if (sd < 0)
return NRC_OPENERROR;
- memset(buf, 0, sizeof(buf));
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
- /* get the ifconf interface */
- if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)
+ ifc.ifc_len = 0;
+ ifc.ifc_buf = NULL;
+
+ do {
+ lastlen = ifc.ifc_len;
+ HeapFree (GetProcessHeap (), 0, ifc.ifc_buf);
+ numAddresses *= 2;
+
+ ifc.ifc_len = sizeof (struct ifreq) * numAddresses;
+ ifc.ifc_buf = HeapAlloc (GetProcessHeap (), 0, ifc.ifc_len);
+ if (!ifc.ifc_buf)
+ {
+ close (sd);
+ return NRC_OPENERROR;
+ }
+
+ ioctlRet = ioctl (sd, SIOCGIFCONF, (char *)&ifc);
+ } while ((ioctlRet == 0) && (ifc.ifc_len != lastlen));
+
+ if (ioctlRet)
{
- close(sd);
- return NRC_OPENERROR;
+ HeapFree (GetProcessHeap (), 0, ifc.ifc_buf);
+ close (sd);
+ return NRC_OPENERROR;
}
/* loop through the interfaces, looking for a valid one */
/* n = ifc.ifc_len; */
- ofs = 0;
- for (i = 0; i < ifc.ifc_len; i++)
+ ifPtr = ifc.ifc_buf;
+ i = 0;
+ while (ifPtr && (ifPtr < (ifc.ifc_buf + ifc.ifc_len)))
{
unsigned char *a = NETBIOS_Adapter[i].address;
+ struct ifreq ifr, *ifrp;
+
+ ifrp = (struct ifreq *)ifPtr;
+
+ ifPtr += ifreq_len ((struct ifreq *)ifPtr);
+ i++;
+
+ if (ifrp->ifr_addr.sa_family != AF_INET)
+ continue;
- ifrp = (struct ifreq *)((char *)ifc.ifc_buf+ofs);
strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
/* try to get the address for this interface */
@@ -145,17 +218,18 @@
a[0],a[1],a[2],a[3],a[4],a[5]);
if (a[0] || a[1] || a[2] || a[3] || a[4] || a[5])
- NETBIOS_Adapter[i].valid = TRUE;
+ NETBIOS_Adapter[i - 1].valid = TRUE;
if (lanas)
{
- lanas->lana[lanas->length] = i;
+ lanas->lana[lanas->length] = i - 1;
lanas->length++;
}
}
- ofs += ifreq_size(ifr);
}
close(sd);
+ HeapFree (GetProcessHeap (), 0, ifc.ifc_buf);
+
#endif /* HAVE_NET_IF_H */
EnumDone = TRUE;
return NRC_GOODRET;