Exemple #1
0
status_t
BNetworkRoster::GetNextInterface(uint32* cookie,
                                 BNetworkInterface& interface) const
{
    // TODO: think about caching the interfaces!

    if (cookie == NULL)
        return B_BAD_VALUE;

    // get a list of all interfaces

    int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
    if (socket < 0)
        return errno;

    FileDescriptorCloser closer(socket);

    ifconf config;
    config.ifc_len = sizeof(config.ifc_value);
    if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
        return errno;

    size_t count = (size_t)config.ifc_value;
    if (count == 0)
        return B_BAD_VALUE;

    char* buffer = (char*)malloc(count * sizeof(struct ifreq));
    if (buffer == NULL)
        return B_NO_MEMORY;

    MemoryDeleter deleter(buffer);

    config.ifc_len = count * sizeof(struct ifreq);
    config.ifc_buf = buffer;
    if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
        return errno;

    ifreq* interfaces = (ifreq*)buffer;
    ifreq* end = (ifreq*)(buffer + config.ifc_len);

    for (uint32 i = 0; interfaces < end; i++) {
        interface.SetTo(interfaces[0].ifr_name);
        if (i == *cookie) {
            (*cookie)++;
            return B_OK;
        }

        interfaces = (ifreq*)((uint8*)interfaces
                              + _SIZEOF_ADDR_IFREQ(interfaces[0]));
    }

    return B_BAD_VALUE;
}