/* Copyright (C) 2003,2006 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Implementation notes
 * Interface index fun:
 * - Windows may rely on an index being cleared in the topmost 8 bits in some
 *   APIs; see GetFriendlyIfIndex and the mention of "backward compatible"
 *   indexes.  It isn't clear which APIs might fail with non-backward-compatible
 *   indexes, but I'll keep them bits clear just in case.
 * - Even though if_nametoindex and if_indextoname seem to be pretty portable,
 *   Linux, at any rate, uses the same interface index for all virtual
 *   interfaces of a real interface as well as for the real interface itself.
 *   If I used the Linux index as my index, this would break my statement that
 *   an index is a key, and that an interface has 0 or 1 IP addresses.
 *   If that behavior were consistent across UNIXen (I don't know), it could
 *   help me implement multiple IP addresses more in the Windows way.
 * I used to assert I could not use UNIX interface indexes as my iphlpapi
 * indexes due to restrictions in netapi32 and wsock32, but I have removed
 * those restrictions, so using if_nametoindex and if_indextoname rather
 * than my current mess would probably be better.
 * FIXME:
 * - I don't support IPv6 addresses here, since SIOCGIFCONF can't return them
 *
 * There are three implemented methods for determining the MAC address of an
 * interface:
 * - a specific IOCTL (Linux)
 * - looking in the ARP cache (at least Solaris)
 * - using the sysctl interface (FreeBSD and MacOSX)
 * Solaris and some others have SIOCGENADDR, but I haven't gotten that to work
 * on the Solaris boxes at SourceForge's compile farm, whereas SIOCGARP does.
 */

#include "config.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <sys/types.h>

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif

#ifdef HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#endif

#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif

#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif

#ifdef HAVE_NET_IF_DL_H
#include <net/if_dl.h>
#endif

#ifdef HAVE_NET_IF_TYPES_H
#include <net/if_types.h>
#endif

#include "ifenum.h"

#ifdef 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

#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif

#ifndef INADDR_NONE
#define INADDR_NONE (~0U)
#endif

#define INITIAL_INTERFACES_ASSUMED 4

#define INDEX_IS_LOOPBACK 0x00800000

/* Type declarations */

typedef struct _InterfaceNameMapEntry {
  char  name[IFNAMSIZ];
  BOOL  inUse;
  BOOL  usedLastPass;
} InterfaceNameMapEntry;

typedef struct _InterfaceNameMap {
  DWORD numInterfaces;
  DWORD nextAvailable;
  DWORD numAllocated;
  InterfaceNameMapEntry table[1];
} InterfaceNameMap;

/* Global variables */

static CRITICAL_SECTION mapCS;
static InterfaceNameMap *gNonLoopbackInterfaceMap = NULL;
static InterfaceNameMap *gLoopbackInterfaceMap = NULL;

/* Functions */

void interfaceMapInit(void)
{
    InitializeCriticalSection(&mapCS);
}

void interfaceMapFree(void)
{
    DeleteCriticalSection(&mapCS);
    HeapFree(GetProcessHeap(), 0, gNonLoopbackInterfaceMap);
    HeapFree(GetProcessHeap(), 0, gLoopbackInterfaceMap);
}

/* Sizes the passed-in map to have enough space for numInterfaces interfaces.
 * If map is NULL, allocates a new map.  If it is not, may reallocate the
 * existing map and return a map of increased size.  Returns the allocated map,
 * or NULL if it could not allocate a map of the requested size.
 */
static InterfaceNameMap *sizeMap(InterfaceNameMap *map, DWORD numInterfaces)
{
  if (!map) {
    numInterfaces = max(numInterfaces, INITIAL_INTERFACES_ASSUMED);
    map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
     sizeof(InterfaceNameMap) +
     (numInterfaces - 1) * sizeof(InterfaceNameMapEntry));
    if (map)
      map->numAllocated = numInterfaces;
  }
  else {
    if (map->numAllocated < numInterfaces) {
      map = HeapReAlloc(GetProcessHeap(), 0, map,
       sizeof(InterfaceNameMap) +
       (numInterfaces - 1) * sizeof(InterfaceNameMapEntry));
      if (map)
        memset(&map->table[map->numAllocated], 0,
         (numInterfaces - map->numAllocated) * sizeof(InterfaceNameMapEntry));
    }
  }
  return map;
}

static int isLoopbackInterface(int fd, const char *name)
{
  int ret = 0;

  if (name) {
    struct ifreq ifr;

    lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
    if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
      ret = ifr.ifr_flags & IFF_LOOPBACK;
  }
  return ret;
}

static void countInterfaces(int fd, caddr_t buf, size_t len)
{
  caddr_t ifPtr = buf;
  DWORD numNonLoopbackInterfaces = 0, numLoopbackInterfaces = 0;

  while (ifPtr && ifPtr < buf + len) {
    struct ifreq *ifr = (struct ifreq *)ifPtr;

    if (isLoopbackInterface(fd, ifr->ifr_name))
      numLoopbackInterfaces++;
    else
      numNonLoopbackInterfaces++;
    ifPtr += ifreq_len(ifr);
  }
  gNonLoopbackInterfaceMap = sizeMap(gNonLoopbackInterfaceMap,
   numNonLoopbackInterfaces);
  gLoopbackInterfaceMap = sizeMap(gLoopbackInterfaceMap,
   numLoopbackInterfaces);
}

/* Stores the name in the given map, and increments the map's numInterfaces
 * member if stored successfully.  Will store in the same slot as previously if
 * usedLastPass is set, otherwise will store in a new slot.
 * Assumes map and name are not NULL, and the usedLastPass flag is set
 * correctly for each entry in the map, and that map->numInterfaces <
 * map->numAllocated.
 * FIXME: this is kind of expensive, doing a linear scan of the map with a
 * string comparison of each entry to find the old slot.
 */
static void storeInterfaceInMap(InterfaceNameMap *map, const char *name)
{
  if (map && name) {
    DWORD ndx;
    BOOL stored = FALSE;

    /* look for previous slot, mark in use if so */
    for (ndx = 0; !stored && ndx < map->nextAvailable; ndx++) {
      if (map->table[ndx].usedLastPass && !strncmp(map->table[ndx].name, name,
       sizeof(map->table[ndx].name))) {
        map->table[ndx].inUse = TRUE;
        stored = TRUE;
      }
    }
    /* look for new slot */
    for (ndx = 0; !stored && ndx < map->numAllocated; ndx++) {
      if (!map->table[ndx].inUse) {
        lstrcpynA(map->table[ndx].name, name, IFNAMSIZ);
        map->table[ndx].inUse = TRUE;
        stored = TRUE;
        if (ndx >= map->nextAvailable)
          map->nextAvailable = ndx + 1;
      }
    }
    if (stored)
      map->numInterfaces++;
  }
}

/* Sets all used entries' usedLastPass flag to their inUse flag, clears
 * their inUse flag, and clears their numInterfaces member.
 */
static void markOldInterfaces(InterfaceNameMap *map)
{
  if (map) {
    DWORD ndx;

    map->numInterfaces = 0;
    for (ndx = 0; ndx < map->nextAvailable; ndx++) {
      map->table[ndx].usedLastPass = map->table[ndx].inUse;
      map->table[ndx].inUse = FALSE;
    }
  }
}

static void classifyInterfaces(int fd, caddr_t buf, size_t len)
{
  caddr_t ifPtr = buf;

  markOldInterfaces(gNonLoopbackInterfaceMap);
  markOldInterfaces(gLoopbackInterfaceMap);
  while (ifPtr && ifPtr < buf + len) {
    struct ifreq *ifr = (struct ifreq *)ifPtr;

    if (ifr->ifr_addr.sa_family == AF_INET) {
      if (isLoopbackInterface(fd, ifr->ifr_name))
        storeInterfaceInMap(gLoopbackInterfaceMap, ifr->ifr_name);
      else
        storeInterfaceInMap(gNonLoopbackInterfaceMap, ifr->ifr_name);
    }
    ifPtr += ifreq_len(ifr);
  }
}

static void enumerateInterfaces(void)
{
  int fd;

  fd = socket(PF_INET, SOCK_DGRAM, 0);
  if (fd != -1) {
    int ret, guessedNumInterfaces;
    struct ifconf ifc;

    /* try to avoid silly heap action by starting with the right size buffer */
    guessedNumInterfaces = 0;
    if (gNonLoopbackInterfaceMap)
      guessedNumInterfaces += gNonLoopbackInterfaceMap->numInterfaces;
    if (gLoopbackInterfaceMap)
      guessedNumInterfaces += gLoopbackInterfaceMap->numInterfaces;

    ret = 0;
    memset(&ifc, 0, sizeof(ifc));
    /* there is no way to know the interface count beforehand,
       so we need to loop again and again upping our max each time
       until returned < max */
    do {
      if (guessedNumInterfaces == 0)
        guessedNumInterfaces = INITIAL_INTERFACES_ASSUMED;
      else
        guessedNumInterfaces *= 2;
      HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
      ifc.ifc_len = sizeof(struct ifreq) * guessedNumInterfaces;
      ifc.ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc.ifc_len);
      ret = ioctl(fd, SIOCGIFCONF, &ifc);
    } while (ret == 0 &&
     ifc.ifc_len == (sizeof(struct ifreq) * guessedNumInterfaces));

    if (ret == 0) {
      EnterCriticalSection(&mapCS);
      countInterfaces(fd, ifc.ifc_buf, ifc.ifc_len);
      classifyInterfaces(fd, ifc.ifc_buf, ifc.ifc_len);
      LeaveCriticalSection(&mapCS);
    }

    HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
    close(fd);
  }
}

DWORD getNumNonLoopbackInterfaces(void)
{
  enumerateInterfaces();
  return gNonLoopbackInterfaceMap ? gNonLoopbackInterfaceMap->numInterfaces : 0;
}

DWORD getNumInterfaces(void)
{
  DWORD ret = getNumNonLoopbackInterfaces();

  ret += gLoopbackInterfaceMap ? gLoopbackInterfaceMap->numInterfaces : 0;
  return ret;
}

const char *getInterfaceNameByIndex(DWORD index)
{
  DWORD realIndex;
  InterfaceNameMap *map;
  const char *ret = NULL;

  EnterCriticalSection(&mapCS);
  if (index & INDEX_IS_LOOPBACK) {
    realIndex = index ^ INDEX_IS_LOOPBACK;
    map = gLoopbackInterfaceMap;
  }
  else {
    realIndex = index;
    map = gNonLoopbackInterfaceMap;
  }
  if (map && realIndex < map->nextAvailable)
    ret = map->table[realIndex].name;
  LeaveCriticalSection(&mapCS);
  return ret;
}

DWORD getInterfaceIndexByName(const char *name, PDWORD index)
{
  DWORD ndx, ret;
  BOOL found = FALSE;

  if (!name)
    return ERROR_INVALID_PARAMETER;
  if (!index)
    return ERROR_INVALID_PARAMETER;

  EnterCriticalSection(&mapCS);
  for (ndx = 0; !found && gNonLoopbackInterfaceMap &&
   ndx < gNonLoopbackInterfaceMap->nextAvailable; ndx++)
    if (!strncmp(gNonLoopbackInterfaceMap->table[ndx].name, name, IFNAMSIZ)) {
      found = TRUE;
      *index = ndx;
    }
  for (ndx = 0; !found && gLoopbackInterfaceMap &&
   ndx < gLoopbackInterfaceMap->nextAvailable; ndx++)
    if (!strncmp(gLoopbackInterfaceMap->table[ndx].name, name, IFNAMSIZ)) {
      found = TRUE;
      *index = ndx | INDEX_IS_LOOPBACK;
    }
  LeaveCriticalSection(&mapCS);
  if (found)
    ret = NO_ERROR;
  else
    ret = ERROR_INVALID_DATA;
  return ret;
}

static void addMapEntriesToIndexTable(InterfaceIndexTable *table,
 const InterfaceNameMap *map)
{
  if (table && map) {
    DWORD ndx;

    for (ndx = 0; ndx < map->nextAvailable &&
     table->numIndexes < table->numAllocated; ndx++)
      if (map->table[ndx].inUse) {
        DWORD externalNdx = ndx;

        if (map == gLoopbackInterfaceMap)
          externalNdx |= INDEX_IS_LOOPBACK;
        table->indexes[table->numIndexes++] = externalNdx;
      }
  }
}

InterfaceIndexTable *getInterfaceIndexTable(void)
{
  DWORD numInterfaces;
  InterfaceIndexTable *ret;
 
  EnterCriticalSection(&mapCS);
  numInterfaces = getNumInterfaces();
  ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
   sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
  if (ret) {
    ret->numAllocated = numInterfaces;
    addMapEntriesToIndexTable(ret, gNonLoopbackInterfaceMap);
    addMapEntriesToIndexTable(ret, gLoopbackInterfaceMap);
  }
  LeaveCriticalSection(&mapCS);
  return ret;
}

InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void)
{
  DWORD numInterfaces;
  InterfaceIndexTable *ret;

  EnterCriticalSection(&mapCS);
  numInterfaces = getNumNonLoopbackInterfaces();
  ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
   sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
  if (ret) {
    ret->numAllocated = numInterfaces;
    addMapEntriesToIndexTable(ret, gNonLoopbackInterfaceMap);
  }
  LeaveCriticalSection(&mapCS);
  return ret;
}

static DWORD getInterfaceBCastAddrByName(const char *name)
{
  DWORD ret = INADDR_ANY;

  if (name) {
    int fd = socket(PF_INET, SOCK_DGRAM, 0);

    if (fd != -1) {
      struct ifreq ifr;

      lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
      if (ioctl(fd, SIOCGIFBRDADDR, &ifr) == 0)
        memcpy(&ret, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
      close(fd);
    }
  }
  return ret;
}

static DWORD getInterfaceMaskByName(const char *name)
{
  DWORD ret = INADDR_NONE;

  if (name) {
    int fd = socket(PF_INET, SOCK_DGRAM, 0);

    if (fd != -1) {
      struct ifreq ifr;

      lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
      if (ioctl(fd, SIOCGIFNETMASK, &ifr) == 0)
        memcpy(&ret, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
      close(fd);
    }
  }
  return ret;
}

#if defined (SIOCGIFHWADDR)
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
 PDWORD type)
{
  DWORD ret;
  int fd;

  if (!name || !len || !addr || !type)
    return ERROR_INVALID_PARAMETER;

  fd = socket(PF_INET, SOCK_DGRAM, 0);
  if (fd != -1) {
    struct ifreq ifr;

    memset(&ifr, 0, sizeof(struct ifreq));
    lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
    if ((ioctl(fd, SIOCGIFHWADDR, &ifr)))
      ret = ERROR_INVALID_DATA;
    else {
      unsigned int addrLen;

      switch (ifr.ifr_hwaddr.sa_family)
      {
#ifdef ARPHRD_LOOPBACK
        case ARPHRD_LOOPBACK:
          addrLen = 0;
          *type = MIB_IF_TYPE_LOOPBACK;
          break;
#endif
#ifdef ARPHRD_ETHER
        case ARPHRD_ETHER:
          addrLen = ETH_ALEN;
          *type = MIB_IF_TYPE_ETHERNET;
          break;
#endif
#ifdef ARPHRD_FDDI
        case ARPHRD_FDDI:
          addrLen = ETH_ALEN;
          *type = MIB_IF_TYPE_FDDI;
          break;
#endif
#ifdef ARPHRD_IEEE802
        case ARPHRD_IEEE802: /* 802.2 Ethernet && Token Ring, guess TR? */
          addrLen = ETH_ALEN;
          *type = MIB_IF_TYPE_TOKENRING;
          break;
#endif
#ifdef ARPHRD_IEEE802_TR
        case ARPHRD_IEEE802_TR: /* also Token Ring? */
          addrLen = ETH_ALEN;
          *type = MIB_IF_TYPE_TOKENRING;
          break;
#endif
#ifdef ARPHRD_SLIP
        case ARPHRD_SLIP:
          addrLen = 0;
          *type = MIB_IF_TYPE_SLIP;
          break;
#endif
#ifdef ARPHRD_PPP
        case ARPHRD_PPP:
          addrLen = 0;
          *type = MIB_IF_TYPE_PPP;
          break;
#endif
        default:
          addrLen = min(MAX_INTERFACE_PHYSADDR, sizeof(ifr.ifr_hwaddr.sa_data));
          *type = MIB_IF_TYPE_OTHER;
      }
      if (addrLen > *len) {
        ret = ERROR_INSUFFICIENT_BUFFER;
        *len = addrLen;
      }
      else {
        if (addrLen > 0)
          memcpy(addr, ifr.ifr_hwaddr.sa_data, addrLen);
        /* zero out remaining bytes for broken implementations */
        memset(addr + addrLen, 0, *len - addrLen);
        *len = addrLen;
        ret = NO_ERROR;
      }
    }
    close(fd);
  }
  else
    ret = ERROR_NO_MORE_FILES;
  return ret;
}
#elif defined (SIOCGARP)
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
 PDWORD type)
{
  DWORD ret;
  int fd;

  if (!name || !len || !addr || !type)
    return ERROR_INVALID_PARAMETER;

  fd = socket(PF_INET, SOCK_DGRAM, 0);
  if (fd != -1) {
    if (isLoopbackInterface(fd, name)) {
      *type = MIB_IF_TYPE_LOOPBACK;
      memset(addr, 0, *len);
      *len = 0;
      ret=NOERROR;
    }
    else {
      struct arpreq arp;
      struct sockaddr_in *saddr;
      struct ifreq ifr;

      /* get IP addr */
      lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
      ioctl(fd, SIOCGIFADDR, &ifr);
      memset(&arp, 0, sizeof(struct arpreq));
      arp.arp_pa.sa_family = AF_INET;
      saddr = (struct sockaddr_in *)&arp; /* proto addr is first member */
      saddr->sin_family = AF_INET;
      memcpy(&saddr->sin_addr.s_addr, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
      if ((ioctl(fd, SIOCGARP, &arp)))
        ret = ERROR_INVALID_DATA;
      else {
        /* FIXME:  heh:  who said it was ethernet? */
        int addrLen = ETH_ALEN;

        if (addrLen > *len) {
          ret = ERROR_INSUFFICIENT_BUFFER;
          *len = addrLen;
        }
        else {
          if (addrLen > 0)
            memcpy(addr, &arp.arp_ha.sa_data[0], addrLen);
          /* zero out remaining bytes for broken implementations */
          memset(addr + addrLen, 0, *len - addrLen);
          *len = addrLen;
          *type = MIB_IF_TYPE_ETHERNET;
          ret = NO_ERROR;
        }
      }
    }
    close(fd);
  }
    else
      ret = ERROR_NO_MORE_FILES;

  return ret;
}
#elif defined (HAVE_SYS_SYSCTL_H) && defined (HAVE_NET_IF_DL_H)
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
 PDWORD type)
{
  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 (!name || !len || !addr || !type)
    return ERROR_INVALID_PARAMETER;

  if (sysctl(mib, 6, NULL, &mibLen, NULL, 0) < 0)
    return ERROR_NO_MORE_FILES;

  buf = HeapAlloc(GetProcessHeap(), 0, mibLen);
  if (!buf)
    return ERROR_NOT_ENOUGH_MEMORY;

  if (sysctl(mib, 6, buf, &mibLen, NULL, 0) < 0) {
    HeapFree(GetProcessHeap(), 0, buf);
    return ERROR_NO_MORE_FILES;
  }

  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, name, max(sdl->sdl_nlen, strlen(name))) != 0)
      continue;

    found = TRUE;
    addrLen = min(MAX_INTERFACE_PHYSADDR, sdl->sdl_alen);
    if (addrLen > *len) {
      ret = ERROR_INSUFFICIENT_BUFFER;
      *len = addrLen;
    }
    else {
      if (addrLen > 0)
        memcpy(addr, LLADDR(sdl), addrLen);
      /* zero out remaining bytes for broken implementations */
      memset(addr + addrLen, 0, *len - addrLen);
      *len = addrLen;
#if defined(HAVE_NET_IF_TYPES_H)
      switch (sdl->sdl_type)
      {
        case IFT_ETHER:
          *type = MIB_IF_TYPE_ETHERNET;
          break;
        case IFT_FDDI:
          *type = MIB_IF_TYPE_FDDI;
          break;
        case IFT_ISO88024: /* Token Bus */
          *type = MIB_IF_TYPE_TOKENRING;
          break;
        case IFT_ISO88025: /* Token Ring */
          *type = MIB_IF_TYPE_TOKENRING;
          break;
        case IFT_PPP:
          *type = MIB_IF_TYPE_PPP;
          break;
        case IFT_SLIP:
          *type = MIB_IF_TYPE_SLIP;
          break;
        case IFT_LOOP:
          *type = MIB_IF_TYPE_LOOPBACK;
          break;
        default:
          *type = MIB_IF_TYPE_OTHER;
      }
#else
      /* default if we don't know */
      *type = MIB_IF_TYPE_ETHERNET;
#endif
      ret = NO_ERROR;
    }
  }
  HeapFree(GetProcessHeap(), 0, buf);
  return ret;
}
#endif

DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr,
 PDWORD type)
{
  const char *name = getInterfaceNameByIndex(index);

  if (name)
    return getInterfacePhysicalByName(name, len, addr, type);
  else
    return ERROR_INVALID_DATA;
}

static DWORD getInterfaceMtuByName(const char *name, PDWORD mtu)
{
  DWORD ret;
  int fd;

  if (!name)
    return ERROR_INVALID_PARAMETER;
  if (!mtu)
    return ERROR_INVALID_PARAMETER;

  fd = socket(PF_INET, SOCK_DGRAM, 0);
  if (fd != -1) {
    struct ifreq ifr;

    lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
    if ((ioctl(fd, SIOCGIFMTU, &ifr)))
      ret = ERROR_INVALID_DATA;
    else {
#ifndef __sun
      *mtu = ifr.ifr_mtu;
#else
      *mtu = ifr.ifr_metric;
#endif
      ret = NO_ERROR;
    }
    close(fd);
  }
  else
    ret = ERROR_NO_MORE_FILES;
  return ret;
}

static DWORD getInterfaceStatusByName(const char *name, PDWORD status)
{
  DWORD ret;
  int fd;

  if (!name)
    return ERROR_INVALID_PARAMETER;
  if (!status)
    return ERROR_INVALID_PARAMETER;

  fd = socket(PF_INET, SOCK_DGRAM, 0);
  if (fd != -1) {
    struct ifreq ifr;

    lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
    if ((ioctl(fd, SIOCGIFFLAGS, &ifr)))
      ret = ERROR_INVALID_DATA;
    else {
      if (ifr.ifr_flags & IFF_UP)
        *status = MIB_IF_OPER_STATUS_OPERATIONAL;
      else
        *status = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
      ret = NO_ERROR;
    }
    close(fd);
  }
  else
    ret = ERROR_NO_MORE_FILES;
  return ret;
}

DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
{
  BYTE addr[MAX_INTERFACE_PHYSADDR];
  DWORD ret, len = sizeof(addr), type;

  if (!name)
    return ERROR_INVALID_PARAMETER;
  if (!entry)
    return ERROR_INVALID_PARAMETER;

  if (getInterfacePhysicalByName(name, &len, addr, &type) == NO_ERROR) {
    WCHAR *assigner;
    const char *walker;

    memset(entry, 0, sizeof(MIB_IFROW));
    for (assigner = entry->wszName, walker = name; *walker; 
     walker++, assigner++)
      *assigner = *walker;
    *assigner = 0;
    getInterfaceIndexByName(name, &entry->dwIndex);
    entry->dwPhysAddrLen = len;
    memcpy(entry->bPhysAddr, addr, len);
    memset(entry->bPhysAddr + len, 0, sizeof(entry->bPhysAddr) - len);
    entry->dwType = type;
    /* FIXME: how to calculate real speed? */
    getInterfaceMtuByName(name, &entry->dwMtu);
    /* lie, there's no "administratively down" here */
    entry->dwAdminStatus = MIB_IF_ADMIN_STATUS_UP;
    getInterfaceStatusByName(name, &entry->dwOperStatus);
    /* punt on dwLastChange? */
    entry->dwDescrLen = min(strlen(name), MAX_INTERFACE_DESCRIPTION - 1);
    memcpy(entry->bDescr, name, entry->dwDescrLen);
    entry->bDescr[entry->dwDescrLen] = '\0';
    entry->dwDescrLen++;
    ret = NO_ERROR;
  }
  else
    ret = ERROR_INVALID_DATA;
  return ret;
}

DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
{
  const char *name = getInterfaceNameByIndex(index);

  if (name)
    return getInterfaceEntryByName(name, entry);
  else
    return ERROR_INVALID_DATA;
}

/* Enumerates the IP addresses in the system using SIOCGIFCONF, returning
 * the count to you in *pcAddresses.  It also returns to you the struct ifconf
 * used by the call to ioctl, so that you may process the addresses further.
 * Free ifc->ifc_buf using HeapFree.
 * Returns NO_ERROR on success, something else on failure.
 */
static DWORD enumIPAddresses(PDWORD pcAddresses, struct ifconf *ifc)
{
  DWORD ret;
  int fd;

  fd = socket(PF_INET, SOCK_DGRAM, 0);
  if (fd != -1) {
    int ioctlRet = 0;
    DWORD guessedNumAddresses = 0, numAddresses = 0;
    caddr_t ifPtr;

    ret = NO_ERROR;
    ifc->ifc_len = 0;
    ifc->ifc_buf = NULL;
    /* there is no way to know the interface count beforehand,
       so we need to loop again and again upping our max each time
       until returned < max */
    do {
      HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
      if (guessedNumAddresses == 0)
        guessedNumAddresses = INITIAL_INTERFACES_ASSUMED;
      else
        guessedNumAddresses *= 2;
      ifc->ifc_len = sizeof(struct ifreq) * guessedNumAddresses;
      ifc->ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc->ifc_len);
      ioctlRet = ioctl(fd, SIOCGIFCONF, ifc);
    } while (ioctlRet == 0 &&
     ifc->ifc_len == (sizeof(struct ifreq) * guessedNumAddresses));

    if (ioctlRet == 0) {
      ifPtr = ifc->ifc_buf;
      while (ifPtr && ifPtr < ifc->ifc_buf + ifc->ifc_len) {
        numAddresses++;
        ifPtr += ifreq_len((struct ifreq *)ifPtr);
      }
    }
    else
      ret = ERROR_INVALID_PARAMETER; /* FIXME: map from errno to Win32 */
    if (!ret)
      *pcAddresses = numAddresses;
    else
    {
      HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
      ifc->ifc_buf = NULL;
    }
    close(fd);
  }
  else
    ret = ERROR_NO_SYSTEM_RESOURCES;
  return ret;
}

DWORD getNumIPAddresses(void)
{
  DWORD numAddresses = 0;
  struct ifconf ifc;

  if (!enumIPAddresses(&numAddresses, &ifc))
    HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
  return numAddresses;
}

DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
{
  DWORD ret;

  if (!ppIpAddrTable)
    ret = ERROR_INVALID_PARAMETER;
  else
  {
    DWORD numAddresses = 0;
    struct ifconf ifc;

    ret = enumIPAddresses(&numAddresses, &ifc);
    if (!ret)
    {
      *ppIpAddrTable = HeapAlloc(heap, flags, sizeof(MIB_IPADDRTABLE) +
       (numAddresses - 1) * sizeof(MIB_IPADDRROW));
      if (*ppIpAddrTable) {
        DWORD i = 0, bcast;
        caddr_t ifPtr;

        ret = NO_ERROR;
        (*ppIpAddrTable)->dwNumEntries = numAddresses;
        ifPtr = ifc.ifc_buf;
        while (!ret && ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
          struct ifreq *ifr = (struct ifreq *)ifPtr;

          ret = getInterfaceIndexByName(ifr->ifr_name,
           &(*ppIpAddrTable)->table[i].dwIndex);
          memcpy(&(*ppIpAddrTable)->table[i].dwAddr, ifr->ifr_addr.sa_data + 2,
           sizeof(DWORD));
          (*ppIpAddrTable)->table[i].dwMask =
           getInterfaceMaskByName(ifr->ifr_name);
          /* the dwBCastAddr member isn't the broadcast address, it indicates
           * whether the interface uses the 1's broadcast address (1) or the
           * 0's broadcast address (0).
           */
          bcast = getInterfaceBCastAddrByName(ifr->ifr_name);
          (*ppIpAddrTable)->table[i].dwBCastAddr =
           (bcast & (*ppIpAddrTable)->table[i].dwMask) ? 1 : 0;
          /* FIXME: hardcoded reasm size, not sure where to get it */
          (*ppIpAddrTable)->table[i].dwReasmSize = 65535;

          (*ppIpAddrTable)->table[i].unused1 = 0;
          (*ppIpAddrTable)->table[i].wType = 0;
          ifPtr += ifreq_len(ifr);
          i++;
        }
      }
      else
        ret = ERROR_OUTOFMEMORY;
      HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
    }
  }
  return ret;
}

char *toIPAddressString(unsigned int addr, char string[16])
{
  if (string) {
    struct in_addr iAddr;

    iAddr.s_addr = addr;
    /* extra-anal, just to make auditors happy */
    lstrcpynA(string, inet_ntoa(iAddr), 16);
  }
  return string;
}
