Exemple #1
0
int32_t OsNetworkListAdapters(OsContext* aContext, OsNetworkAdapter** aAdapters, uint32_t aUseLoopback)
{
#ifdef DEFINE_BIG_ENDIAN
#define MakeIpAddress(aByte1, aByte2, aByte3, aByte4) \
        (aByte4 | (aByte3<<8) | (aByte2<<16) | (aByte1<<24))
#elif defined(DEFINE_LITTLE_ENDIAN)
#define MakeIpAddress(aByte1, aByte2, aByte3, aByte4) \
        (aByte1 | (aByte2<<8) | (aByte3<<16) | (aByte4<<24))
#else
#error "Endianness must be defined."
#endif

    int32_t ret = -1;
    struct ifaddrs* networkIf;
    struct ifaddrs* iter;
    int32_t includeLoopback = 1;
#ifdef PLATFORM_MACOSX_GNU
    aUseLoopback = 0;
#endif
    *aAdapters = NULL;
    if (TEMP_FAILURE_RETRY(getifaddrs(&networkIf)) == -1) {
        return -1;
    }
    TIpAddress loopbackAddr = MakeIpAddress(127, 0, 0, 1);
    /* first check whether we have any suitable interfaces other than loopback */
    if (aUseLoopback == 0) {
        iter = networkIf;
        while (iter != NULL) {
            if (iter->ifa_addr != NULL &&
                iter->ifa_addr->sa_family == AF_INET &&
                (iter->ifa_flags & IFF_RUNNING) != 0 &&
                ((struct sockaddr_in*)iter->ifa_addr)->sin_addr.s_addr != loopbackAddr) {
                includeLoopback = 0;
                break;
            }
            iter = iter->ifa_next;
        }
    }
    /* ...then allocate/populate the list */
    iter = networkIf;
    OsNetworkAdapter* head = NULL;
    OsNetworkAdapter* tail = NULL;
    while (iter != NULL) {
        if (iter->ifa_addr == NULL || iter->ifa_addr->sa_family != AF_INET ||
            (iter->ifa_flags & IFF_RUNNING) == 0 ||
            (includeLoopback == 0 && ((struct sockaddr_in*)iter->ifa_addr)->sin_addr.s_addr == loopbackAddr) ||
            (aUseLoopback == 1 && ((struct sockaddr_in*)iter->ifa_addr)->sin_addr.s_addr != loopbackAddr)) {
            iter = iter->ifa_next;
            continue;
        }

        OsNetworkAdapter* iface = (OsNetworkAdapter*)calloc(1, sizeof(*iface));
        if (iface == NULL) {
            OsNetworkFreeInterfaces(head);
            goto exit;
        }
        if (head == NULL) {
            head = iface;
        }
        iface->iName = (char*)malloc(strlen(iter->ifa_name) + 1);
        if (iface->iName == NULL) {
            OsNetworkFreeInterfaces(head);
            goto exit;
        }
        (void)strcpy(iface->iName, iter->ifa_name);
        iface->iAddress = ((struct sockaddr_in*)iter->ifa_addr)->sin_addr.s_addr;
        iface->iNetMask = ((struct sockaddr_in*)iter->ifa_netmask)->sin_addr.s_addr;
        if (tail != NULL) {
            tail->iNext = iface;
        }
        tail = iface;
        iter = iter->ifa_next;
    }
    ret = 0;
    *aAdapters = head;
exit:
    freeifaddrs(networkIf);
    return ret;
}
Exemple #2
0
int32_t OsNetworkListAdapters(OsContext* aContext, OsNetworkAdapter** aInterfaces, uint32_t aUseLoopback)
{
#define MakeIpAddress(aByte1, aByte2, aByte3, aByte4) \
        (aByte1 | (aByte2<<8) | (aByte3<<16) | (aByte4<<24))

    MIB_IFTABLE* ifTable          = NULL;
    MIB_IPADDRTABLE* addrTable    = NULL;
    ULONG bytes                   = 0;
    OsNetworkAdapter* head      = NULL;
    int32_t index                 = 0;
    const TIpAddress loopbackAddr = MakeIpAddress(127, 0, 0, 1);
    int32_t includeLoopback       = 1;
    uint32_t i;

    if (ERROR_INSUFFICIENT_BUFFER != GetIpAddrTable(NULL, &bytes, FALSE)) {
        return -1;
    }
    addrTable = (MIB_IPADDRTABLE*)malloc(bytes);
    if (NO_ERROR != GetIpAddrTable(addrTable, &bytes, FALSE)) {
        goto failure;
    }
    bytes = 0;
    if (ERROR_INSUFFICIENT_BUFFER != GetIfTable(NULL, &bytes, FALSE)) {
        goto failure;
    }
    ifTable = (MIB_IFTABLE*)malloc(bytes);
    if (NO_ERROR != GetIfTable(ifTable, &bytes, FALSE)) {
        goto failure;
    }

    if (aUseLoopback == LOOPBACK_EXCLUDE) {
        // Only include loopback if there are no non-loopback adapters
        for (i=0; i<addrTable->dwNumEntries; i++) {
            MIB_IPADDRROW* addrRow = &(addrTable->table[i]);
            if (addrRow->dwAddr != loopbackAddr) {
                includeLoopback = 0;
                break;
            }
        }
    }

    for (i=0; i<addrTable->dwNumEntries; i++) {
        MIB_IPADDRROW* addrRow = &(addrTable->table[i]);
        MIB_IFROW* ifRow = NULL;
        OsNetworkAdapter* nif;
        size_t len;
        DWORD j = 0;

        for (; j< ifTable->dwNumEntries; j++) {
            MIB_IFROW* tmp = &ifTable->table[j];
            if (tmp->dwIndex == addrRow->dwIndex) {
                ifRow = tmp;
                break;
            }
        }
        if (ifRow == NULL) {
            fprintf(stderr, "Unable to match ifRow to addrRow\n");
            continue;
        }

        if ((addrRow->dwAddr == loopbackAddr && includeLoopback == 0) ||
            (addrRow->dwAddr != loopbackAddr && aUseLoopback == LOOPBACK_USE)) {
            continue;
        }
        if (-1 != aContext->iTestInterfaceIndex && index++ != aContext->iTestInterfaceIndex) {
            continue;
        }
        if (addrRow->dwAddr == 0 || addrRow->dwMask == 0) {
            continue;
        }

        nif = (OsNetworkAdapter*)calloc(1, sizeof(*nif));
        if (nif == NULL) {
            goto failure;
        }
        nif->iReserved = ifRow->dwType;
        nif->iAddress = addrRow->dwAddr;
        nif->iNetMask = addrRow->dwMask;
        len = ifRow->dwDescrLen;
        nif->iName = (char*)malloc(len+1);
        if (NULL == nif->iName) {
            free(nif);
            goto failure;
        }
        for (j=0; j<len; j++) {
            nif->iName[j] = (char)ifRow->bDescr[j];
        }
        nif->iName[len] = '\0';

        if (head == NULL) {
            head = nif;
        }
        else {
            TIpAddress subnet = (nif->iAddress & nif->iNetMask);
            OsNetworkAdapter* p1 = head;
            OsNetworkAdapter* prev = NULL;
            while (NULL != p1) {
                if ((p1->iAddress & p1->iNetMask) == subnet) {
                    while (NULL != p1 && IF_TYPE_ETHERNET_CSMACD == p1->iReserved) {
                        prev = p1;
                        p1 = p1->iNext;
                    }
                    break;
                }
                prev = p1;
                p1 = p1->iNext;
            }
            if (NULL == prev) {
                nif->iNext = head;
                head = nif;
            }
            else {
                nif->iNext = prev->iNext;
                prev->iNext = nif;
            }
        }
    }

    free(addrTable);
    free(ifTable);
    *aInterfaces = head;
    return 0;

failure:
    free(addrTable);
    free(ifTable);
    OsNetworkFreeInterfaces(head);
    return -1;
}