示例#1
0
/* 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;
    int lastlen;

    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 is constant across 2 calls */
    do {
      lastlen = ifc->ifc_len;
      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 != lastlen));

    if (ioctlRet == 0) {
      ifPtr = ifc->ifc_buf;
      while (ifPtr && ifPtr < ifc->ifc_buf + ifc->ifc_len) {
        struct ifreq *ifr = (struct ifreq *)ifPtr;

        if (ifr->ifr_addr.sa_family == AF_INET)
          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;
}
示例#2
0
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)
    {
      DWORD size = sizeof(MIB_IPADDRTABLE);

      if (numAddresses > 1)
        size += (numAddresses - 1) * sizeof(MIB_IPADDRROW);
      *ppIpAddrTable = HeapAlloc(heap, flags, size);
      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;

          ifPtr += ifreq_len(ifr);

          if (ifr->ifr_addr.sa_family != AF_INET)
             continue;

          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;
          i++;
        }
      }
      else
        ret = ERROR_OUTOFMEMORY;
      HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
    }
  }
  return ret;
}
示例#3
0
static UCHAR NETBIOS_Enum(PNCB ncb)
{
#ifdef HAVE_NET_IF_H
    int             sd;
    struct ifconf   ifc;
    int             i;
    int             lastlen, numAddresses = 2;
    int             ioctlRet = 0;
    caddr_t         ifPtr;
#endif
    LANA_ENUM *lanas = NULL;

    if (ncb)
    {
        lanas = (PLANA_ENUM) ncb->ncb_buffer;
        lanas->length = 0;
    }

    TRACE("NCBENUM\n");

#ifdef HAVE_NET_IF_H
    /* BSD 4.4 defines the size of an ifreq to be
     * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
     * However, under earlier systems, sa_len isn't present, so
     *  the size is just sizeof(struct ifreq)
     */

    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sd < 0)
        return NRC_OPENERROR;

    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)
    {
        HeapFree (GetProcessHeap (), 0, ifc.ifc_buf);
        close (sd);
        return NRC_OPENERROR;
    }

    /* loop through the interfaces, looking for a valid one */
    /* n = ifc.ifc_len; */
    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;

        strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);

        /* try to get the address for this interface */
        if(get_hw_address(sd, &ifr, a)==0)
        {
            /* make sure it's not blank */
            /* if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
            continue; */

            TRACE("Found valid adapter %d at %02x:%02x:%02x:%02x:%02x:%02x\n", i,
                  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 - 1].valid = TRUE;

            if (lanas)
            {
                lanas->lana[lanas->length] = i - 1;
                lanas->length++;
            }
        }
    }
    close(sd);
    HeapFree (GetProcessHeap (), 0, ifc.ifc_buf);

#endif /* HAVE_NET_IF_H */
    EnumDone = TRUE;
    return NRC_GOODRET;
}