view: Turkish translation.
[wine/testsucceed.git] / dlls / iphlpapi / ifenum.c
blobc6ab7e1499144d1423a5fb9458618cebec2ddbc4
1 /* Copyright (C) 2003,2006 Juan Lang
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * Implementation notes
18 * FIXME:
19 * - I don't support IPv6 addresses here, since SIOCGIFCONF can't return them
21 * There are three implemented methods for determining the MAC address of an
22 * interface:
23 * - a specific IOCTL (Linux)
24 * - looking in the ARP cache (at least Solaris)
25 * - using the sysctl interface (FreeBSD and MacOSX)
26 * Solaris and some others have SIOCGENADDR, but I haven't gotten that to work
27 * on the Solaris boxes at SourceForge's compile farm, whereas SIOCGARP does.
30 #include "config.h"
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
41 #include <sys/types.h>
43 #ifdef HAVE_SYS_SOCKET_H
44 #include <sys/socket.h>
45 #endif
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
49 #endif
51 #ifdef HAVE_ARPA_INET_H
52 #include <arpa/inet.h>
53 #endif
55 #ifdef HAVE_NET_IF_H
56 #include <net/if.h>
57 #endif
59 #ifdef HAVE_NET_IF_ARP_H
60 #include <net/if_arp.h>
61 #endif
63 #ifdef HAVE_NET_ROUTE_H
64 #include <net/route.h>
65 #endif
67 #ifdef HAVE_SYS_IOCTL_H
68 #include <sys/ioctl.h>
69 #endif
71 #ifdef HAVE_SYS_SYSCTL_H
72 #include <sys/sysctl.h>
73 #endif
75 #ifdef HAVE_SYS_SOCKIO_H
76 #include <sys/sockio.h>
77 #endif
79 #ifdef HAVE_NET_IF_DL_H
80 #include <net/if_dl.h>
81 #endif
83 #ifdef HAVE_NET_IF_TYPES_H
84 #include <net/if_types.h>
85 #endif
87 #include "ifenum.h"
89 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
90 #define ifreq_len(ifr) \
91 max(sizeof(struct ifreq), sizeof((ifr)->ifr_name)+(ifr)->ifr_addr.sa_len)
92 #else
93 #define ifreq_len(ifr) sizeof(struct ifreq)
94 #endif
96 #ifndef ETH_ALEN
97 #define ETH_ALEN 6
98 #endif
100 #ifndef INADDR_NONE
101 #define INADDR_NONE (~0U)
102 #endif
104 #define INITIAL_INTERFACES_ASSUMED 4
106 #define INDEX_IS_LOOPBACK 0x00800000
108 /* Functions */
110 static int isLoopbackInterface(int fd, const char *name)
112 int ret = 0;
114 if (name) {
115 struct ifreq ifr;
117 lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
118 if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
119 ret = ifr.ifr_flags & IFF_LOOPBACK;
121 return ret;
124 /* The comments say MAX_ADAPTER_NAME is required, but really only IF_NAMESIZE
125 * bytes are necessary.
127 char *getInterfaceNameByIndex(DWORD index, char *name)
129 return if_indextoname(index, name);
132 DWORD getInterfaceIndexByName(const char *name, PDWORD index)
134 DWORD ret;
135 unsigned int idx;
137 if (!name)
138 return ERROR_INVALID_PARAMETER;
139 if (!index)
140 return ERROR_INVALID_PARAMETER;
141 idx = if_nametoindex(name);
142 if (idx) {
143 *index = idx;
144 ret = NO_ERROR;
146 else
147 ret = ERROR_INVALID_DATA;
148 return ret;
151 DWORD getNumNonLoopbackInterfaces(void)
153 DWORD numInterfaces;
154 int fd = socket(PF_INET, SOCK_DGRAM, 0);
156 if (fd != -1) {
157 struct if_nameindex *indexes = if_nameindex();
159 if (indexes) {
160 struct if_nameindex *p;
162 for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
163 if (!isLoopbackInterface(fd, p->if_name))
164 numInterfaces++;
165 if_freenameindex(indexes);
167 else
168 numInterfaces = 0;
169 close(fd);
171 else
172 numInterfaces = 0;
173 return numInterfaces;
176 DWORD getNumInterfaces(void)
178 DWORD numInterfaces;
179 struct if_nameindex *indexes = if_nameindex();
181 if (indexes) {
182 struct if_nameindex *p;
184 for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
185 numInterfaces++;
186 if_freenameindex(indexes);
188 else
189 numInterfaces = 0;
190 return numInterfaces;
193 InterfaceIndexTable *getInterfaceIndexTable(void)
195 DWORD numInterfaces;
196 InterfaceIndexTable *ret;
197 struct if_nameindex *indexes = if_nameindex();
199 if (indexes) {
200 struct if_nameindex *p;
202 for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
203 numInterfaces++;
204 ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
205 sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
206 if (ret) {
207 for (p = indexes; p && p->if_name; p++)
208 ret->indexes[ret->numIndexes++] = p->if_index;
210 if_freenameindex(indexes);
212 else
213 ret = NULL;
214 return ret;
217 InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void)
219 DWORD numInterfaces;
220 InterfaceIndexTable *ret;
221 int fd = socket(PF_INET, SOCK_DGRAM, 0);
223 if (fd != -1) {
224 struct if_nameindex *indexes = if_nameindex();
226 if (indexes) {
227 struct if_nameindex *p;
229 for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
230 if (!isLoopbackInterface(fd, p->if_name))
231 numInterfaces++;
232 ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
233 sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
234 if (ret) {
235 for (p = indexes; p && p->if_name; p++)
236 if (!isLoopbackInterface(fd, p->if_name))
237 ret->indexes[ret->numIndexes++] = p->if_index;
239 if_freenameindex(indexes);
241 else
242 ret = NULL;
243 close(fd);
245 else
246 ret = NULL;
247 return ret;
250 static DWORD getInterfaceBCastAddrByName(const char *name)
252 DWORD ret = INADDR_ANY;
254 if (name) {
255 int fd = socket(PF_INET, SOCK_DGRAM, 0);
257 if (fd != -1) {
258 struct ifreq ifr;
260 lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
261 if (ioctl(fd, SIOCGIFBRDADDR, &ifr) == 0)
262 memcpy(&ret, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
263 close(fd);
266 return ret;
269 static DWORD getInterfaceMaskByName(const char *name)
271 DWORD ret = INADDR_NONE;
273 if (name) {
274 int fd = socket(PF_INET, SOCK_DGRAM, 0);
276 if (fd != -1) {
277 struct ifreq ifr;
279 lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
280 if (ioctl(fd, SIOCGIFNETMASK, &ifr) == 0)
281 memcpy(&ret, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
282 close(fd);
285 return ret;
288 #if defined (SIOCGIFHWADDR)
289 DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
290 PDWORD type)
292 DWORD ret;
293 int fd;
295 if (!name || !len || !addr || !type)
296 return ERROR_INVALID_PARAMETER;
298 fd = socket(PF_INET, SOCK_DGRAM, 0);
299 if (fd != -1) {
300 struct ifreq ifr;
302 memset(&ifr, 0, sizeof(struct ifreq));
303 lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
304 if ((ioctl(fd, SIOCGIFHWADDR, &ifr)))
305 ret = ERROR_INVALID_DATA;
306 else {
307 unsigned int addrLen;
309 switch (ifr.ifr_hwaddr.sa_family)
311 #ifdef ARPHRD_LOOPBACK
312 case ARPHRD_LOOPBACK:
313 addrLen = 0;
314 *type = MIB_IF_TYPE_LOOPBACK;
315 break;
316 #endif
317 #ifdef ARPHRD_ETHER
318 case ARPHRD_ETHER:
319 addrLen = ETH_ALEN;
320 *type = MIB_IF_TYPE_ETHERNET;
321 break;
322 #endif
323 #ifdef ARPHRD_FDDI
324 case ARPHRD_FDDI:
325 addrLen = ETH_ALEN;
326 *type = MIB_IF_TYPE_FDDI;
327 break;
328 #endif
329 #ifdef ARPHRD_IEEE802
330 case ARPHRD_IEEE802: /* 802.2 Ethernet && Token Ring, guess TR? */
331 addrLen = ETH_ALEN;
332 *type = MIB_IF_TYPE_TOKENRING;
333 break;
334 #endif
335 #ifdef ARPHRD_IEEE802_TR
336 case ARPHRD_IEEE802_TR: /* also Token Ring? */
337 addrLen = ETH_ALEN;
338 *type = MIB_IF_TYPE_TOKENRING;
339 break;
340 #endif
341 #ifdef ARPHRD_SLIP
342 case ARPHRD_SLIP:
343 addrLen = 0;
344 *type = MIB_IF_TYPE_SLIP;
345 break;
346 #endif
347 #ifdef ARPHRD_PPP
348 case ARPHRD_PPP:
349 addrLen = 0;
350 *type = MIB_IF_TYPE_PPP;
351 break;
352 #endif
353 default:
354 addrLen = min(MAX_INTERFACE_PHYSADDR, sizeof(ifr.ifr_hwaddr.sa_data));
355 *type = MIB_IF_TYPE_OTHER;
357 if (addrLen > *len) {
358 ret = ERROR_INSUFFICIENT_BUFFER;
359 *len = addrLen;
361 else {
362 if (addrLen > 0)
363 memcpy(addr, ifr.ifr_hwaddr.sa_data, addrLen);
364 /* zero out remaining bytes for broken implementations */
365 memset(addr + addrLen, 0, *len - addrLen);
366 *len = addrLen;
367 ret = NO_ERROR;
370 close(fd);
372 else
373 ret = ERROR_NO_MORE_FILES;
374 return ret;
376 #elif defined (SIOCGARP)
377 DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
378 PDWORD type)
380 DWORD ret;
381 int fd;
383 if (!name || !len || !addr || !type)
384 return ERROR_INVALID_PARAMETER;
386 fd = socket(PF_INET, SOCK_DGRAM, 0);
387 if (fd != -1) {
388 if (isLoopbackInterface(fd, name)) {
389 *type = MIB_IF_TYPE_LOOPBACK;
390 memset(addr, 0, *len);
391 *len = 0;
392 ret=NOERROR;
394 else {
395 struct arpreq arp;
396 struct sockaddr_in *saddr;
397 struct ifreq ifr;
399 /* get IP addr */
400 lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
401 ioctl(fd, SIOCGIFADDR, &ifr);
402 memset(&arp, 0, sizeof(struct arpreq));
403 arp.arp_pa.sa_family = AF_INET;
404 saddr = (struct sockaddr_in *)&arp; /* proto addr is first member */
405 saddr->sin_family = AF_INET;
406 memcpy(&saddr->sin_addr.s_addr, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
407 if ((ioctl(fd, SIOCGARP, &arp)))
408 ret = ERROR_INVALID_DATA;
409 else {
410 /* FIXME: heh: who said it was ethernet? */
411 int addrLen = ETH_ALEN;
413 if (addrLen > *len) {
414 ret = ERROR_INSUFFICIENT_BUFFER;
415 *len = addrLen;
417 else {
418 if (addrLen > 0)
419 memcpy(addr, &arp.arp_ha.sa_data[0], addrLen);
420 /* zero out remaining bytes for broken implementations */
421 memset(addr + addrLen, 0, *len - addrLen);
422 *len = addrLen;
423 *type = MIB_IF_TYPE_ETHERNET;
424 ret = NO_ERROR;
428 close(fd);
430 else
431 ret = ERROR_NO_MORE_FILES;
433 return ret;
435 #elif defined (HAVE_SYS_SYSCTL_H) && defined (HAVE_NET_IF_DL_H)
436 DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
437 PDWORD type)
439 DWORD ret;
440 struct if_msghdr *ifm;
441 struct sockaddr_dl *sdl;
442 u_char *p, *buf;
443 size_t mibLen;
444 int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
445 int addrLen;
446 BOOL found = FALSE;
448 if (!name || !len || !addr || !type)
449 return ERROR_INVALID_PARAMETER;
451 if (sysctl(mib, 6, NULL, &mibLen, NULL, 0) < 0)
452 return ERROR_NO_MORE_FILES;
454 buf = HeapAlloc(GetProcessHeap(), 0, mibLen);
455 if (!buf)
456 return ERROR_NOT_ENOUGH_MEMORY;
458 if (sysctl(mib, 6, buf, &mibLen, NULL, 0) < 0) {
459 HeapFree(GetProcessHeap(), 0, buf);
460 return ERROR_NO_MORE_FILES;
463 ret = ERROR_INVALID_DATA;
464 for (p = buf; !found && p < buf + mibLen; p += ifm->ifm_msglen) {
465 ifm = (struct if_msghdr *)p;
466 sdl = (struct sockaddr_dl *)(ifm + 1);
468 if (ifm->ifm_type != RTM_IFINFO || (ifm->ifm_addrs & RTA_IFP) == 0)
469 continue;
471 if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
472 memcmp(sdl->sdl_data, name, max(sdl->sdl_nlen, strlen(name))) != 0)
473 continue;
475 found = TRUE;
476 addrLen = min(MAX_INTERFACE_PHYSADDR, sdl->sdl_alen);
477 if (addrLen > *len) {
478 ret = ERROR_INSUFFICIENT_BUFFER;
479 *len = addrLen;
481 else {
482 if (addrLen > 0)
483 memcpy(addr, LLADDR(sdl), addrLen);
484 /* zero out remaining bytes for broken implementations */
485 memset(addr + addrLen, 0, *len - addrLen);
486 *len = addrLen;
487 #if defined(HAVE_NET_IF_TYPES_H)
488 switch (sdl->sdl_type)
490 case IFT_ETHER:
491 *type = MIB_IF_TYPE_ETHERNET;
492 break;
493 case IFT_FDDI:
494 *type = MIB_IF_TYPE_FDDI;
495 break;
496 case IFT_ISO88024: /* Token Bus */
497 *type = MIB_IF_TYPE_TOKENRING;
498 break;
499 case IFT_ISO88025: /* Token Ring */
500 *type = MIB_IF_TYPE_TOKENRING;
501 break;
502 case IFT_PPP:
503 *type = MIB_IF_TYPE_PPP;
504 break;
505 case IFT_SLIP:
506 *type = MIB_IF_TYPE_SLIP;
507 break;
508 case IFT_LOOP:
509 *type = MIB_IF_TYPE_LOOPBACK;
510 break;
511 default:
512 *type = MIB_IF_TYPE_OTHER;
514 #else
515 /* default if we don't know */
516 *type = MIB_IF_TYPE_ETHERNET;
517 #endif
518 ret = NO_ERROR;
521 HeapFree(GetProcessHeap(), 0, buf);
522 return ret;
524 #endif
526 DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr,
527 PDWORD type)
529 char nameBuf[IF_NAMESIZE];
530 char *name = getInterfaceNameByIndex(index, nameBuf);
532 if (name)
533 return getInterfacePhysicalByName(name, len, addr, type);
534 else
535 return ERROR_INVALID_DATA;
538 static DWORD getInterfaceMtuByName(const char *name, PDWORD mtu)
540 DWORD ret;
541 int fd;
543 if (!name)
544 return ERROR_INVALID_PARAMETER;
545 if (!mtu)
546 return ERROR_INVALID_PARAMETER;
548 fd = socket(PF_INET, SOCK_DGRAM, 0);
549 if (fd != -1) {
550 struct ifreq ifr;
552 lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
553 if ((ioctl(fd, SIOCGIFMTU, &ifr)))
554 ret = ERROR_INVALID_DATA;
555 else {
556 #ifndef __sun
557 *mtu = ifr.ifr_mtu;
558 #else
559 *mtu = ifr.ifr_metric;
560 #endif
561 ret = NO_ERROR;
563 close(fd);
565 else
566 ret = ERROR_NO_MORE_FILES;
567 return ret;
570 static DWORD getInterfaceStatusByName(const char *name, PDWORD status)
572 DWORD ret;
573 int fd;
575 if (!name)
576 return ERROR_INVALID_PARAMETER;
577 if (!status)
578 return ERROR_INVALID_PARAMETER;
580 fd = socket(PF_INET, SOCK_DGRAM, 0);
581 if (fd != -1) {
582 struct ifreq ifr;
584 lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
585 if ((ioctl(fd, SIOCGIFFLAGS, &ifr)))
586 ret = ERROR_INVALID_DATA;
587 else {
588 if (ifr.ifr_flags & IFF_UP)
589 *status = MIB_IF_OPER_STATUS_OPERATIONAL;
590 else
591 *status = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
592 ret = NO_ERROR;
594 close(fd);
596 else
597 ret = ERROR_NO_MORE_FILES;
598 return ret;
601 DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
603 BYTE addr[MAX_INTERFACE_PHYSADDR];
604 DWORD ret, len = sizeof(addr), type;
606 if (!name)
607 return ERROR_INVALID_PARAMETER;
608 if (!entry)
609 return ERROR_INVALID_PARAMETER;
611 if (getInterfacePhysicalByName(name, &len, addr, &type) == NO_ERROR) {
612 WCHAR *assigner;
613 const char *walker;
615 memset(entry, 0, sizeof(MIB_IFROW));
616 for (assigner = entry->wszName, walker = name; *walker;
617 walker++, assigner++)
618 *assigner = *walker;
619 *assigner = 0;
620 getInterfaceIndexByName(name, &entry->dwIndex);
621 entry->dwPhysAddrLen = len;
622 memcpy(entry->bPhysAddr, addr, len);
623 memset(entry->bPhysAddr + len, 0, sizeof(entry->bPhysAddr) - len);
624 entry->dwType = type;
625 /* FIXME: how to calculate real speed? */
626 getInterfaceMtuByName(name, &entry->dwMtu);
627 /* lie, there's no "administratively down" here */
628 entry->dwAdminStatus = MIB_IF_ADMIN_STATUS_UP;
629 getInterfaceStatusByName(name, &entry->dwOperStatus);
630 /* punt on dwLastChange? */
631 entry->dwDescrLen = min(strlen(name), MAX_INTERFACE_DESCRIPTION - 1);
632 memcpy(entry->bDescr, name, entry->dwDescrLen);
633 entry->bDescr[entry->dwDescrLen] = '\0';
634 entry->dwDescrLen++;
635 ret = NO_ERROR;
637 else
638 ret = ERROR_INVALID_DATA;
639 return ret;
642 DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
644 char nameBuf[IF_NAMESIZE];
645 char *name = getInterfaceNameByIndex(index, nameBuf);
647 if (name)
648 return getInterfaceEntryByName(name, entry);
649 else
650 return ERROR_INVALID_DATA;
653 /* Enumerates the IP addresses in the system using SIOCGIFCONF, returning
654 * the count to you in *pcAddresses. It also returns to you the struct ifconf
655 * used by the call to ioctl, so that you may process the addresses further.
656 * Free ifc->ifc_buf using HeapFree.
657 * Returns NO_ERROR on success, something else on failure.
659 static DWORD enumIPAddresses(PDWORD pcAddresses, struct ifconf *ifc)
661 DWORD ret;
662 int fd;
664 fd = socket(PF_INET, SOCK_DGRAM, 0);
665 if (fd != -1) {
666 int ioctlRet = 0;
667 DWORD guessedNumAddresses = 0, numAddresses = 0;
668 caddr_t ifPtr;
670 ret = NO_ERROR;
671 ifc->ifc_len = 0;
672 ifc->ifc_buf = NULL;
673 /* there is no way to know the interface count beforehand,
674 so we need to loop again and again upping our max each time
675 until returned < max */
676 do {
677 HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
678 if (guessedNumAddresses == 0)
679 guessedNumAddresses = INITIAL_INTERFACES_ASSUMED;
680 else
681 guessedNumAddresses *= 2;
682 ifc->ifc_len = sizeof(struct ifreq) * guessedNumAddresses;
683 ifc->ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc->ifc_len);
684 ioctlRet = ioctl(fd, SIOCGIFCONF, ifc);
685 } while (ioctlRet == 0 &&
686 ifc->ifc_len == (sizeof(struct ifreq) * guessedNumAddresses));
688 if (ioctlRet == 0) {
689 ifPtr = ifc->ifc_buf;
690 while (ifPtr && ifPtr < ifc->ifc_buf + ifc->ifc_len) {
691 numAddresses++;
692 ifPtr += ifreq_len((struct ifreq *)ifPtr);
695 else
696 ret = ERROR_INVALID_PARAMETER; /* FIXME: map from errno to Win32 */
697 if (!ret)
698 *pcAddresses = numAddresses;
699 else
701 HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
702 ifc->ifc_buf = NULL;
704 close(fd);
706 else
707 ret = ERROR_NO_SYSTEM_RESOURCES;
708 return ret;
711 DWORD getNumIPAddresses(void)
713 DWORD numAddresses = 0;
714 struct ifconf ifc;
716 if (!enumIPAddresses(&numAddresses, &ifc))
717 HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
718 return numAddresses;
721 DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
723 DWORD ret;
725 if (!ppIpAddrTable)
726 ret = ERROR_INVALID_PARAMETER;
727 else
729 DWORD numAddresses = 0;
730 struct ifconf ifc;
732 ret = enumIPAddresses(&numAddresses, &ifc);
733 if (!ret)
735 *ppIpAddrTable = HeapAlloc(heap, flags, sizeof(MIB_IPADDRTABLE) +
736 (numAddresses - 1) * sizeof(MIB_IPADDRROW));
737 if (*ppIpAddrTable) {
738 DWORD i = 0, bcast;
739 caddr_t ifPtr;
741 ret = NO_ERROR;
742 (*ppIpAddrTable)->dwNumEntries = numAddresses;
743 ifPtr = ifc.ifc_buf;
744 while (!ret && ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
745 struct ifreq *ifr = (struct ifreq *)ifPtr;
747 ret = getInterfaceIndexByName(ifr->ifr_name,
748 &(*ppIpAddrTable)->table[i].dwIndex);
749 memcpy(&(*ppIpAddrTable)->table[i].dwAddr, ifr->ifr_addr.sa_data + 2,
750 sizeof(DWORD));
751 (*ppIpAddrTable)->table[i].dwMask =
752 getInterfaceMaskByName(ifr->ifr_name);
753 /* the dwBCastAddr member isn't the broadcast address, it indicates
754 * whether the interface uses the 1's broadcast address (1) or the
755 * 0's broadcast address (0).
757 bcast = getInterfaceBCastAddrByName(ifr->ifr_name);
758 (*ppIpAddrTable)->table[i].dwBCastAddr =
759 (bcast & (*ppIpAddrTable)->table[i].dwMask) ? 1 : 0;
760 /* FIXME: hardcoded reasm size, not sure where to get it */
761 (*ppIpAddrTable)->table[i].dwReasmSize = 65535;
763 (*ppIpAddrTable)->table[i].unused1 = 0;
764 (*ppIpAddrTable)->table[i].wType = 0;
765 ifPtr += ifreq_len(ifr);
766 i++;
769 else
770 ret = ERROR_OUTOFMEMORY;
771 HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
774 return ret;
777 char *toIPAddressString(unsigned int addr, char string[16])
779 if (string) {
780 struct in_addr iAddr;
782 iAddr.s_addr = addr;
783 /* extra-anal, just to make auditors happy */
784 lstrcpynA(string, inet_ntoa(iAddr), 16);
786 return string;