127 lines
2.3 KiB
C++
127 lines
2.3 KiB
C++
|
/*
|
||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||
|
* Distributed under the terms of the MIT License.
|
||
|
*
|
||
|
* Authors:
|
||
|
* Axel Dörfler, axeld@pinc-software.de
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <net/if.h>
|
||
|
#include <sys/socket.h>
|
||
|
#include <sys/sockio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
|
||
|
namespace BPrivate {
|
||
|
class Socket {
|
||
|
public:
|
||
|
Socket()
|
||
|
{
|
||
|
fFD = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
}
|
||
|
|
||
|
~Socket()
|
||
|
{
|
||
|
if (fFD >= 0)
|
||
|
close(fFD);
|
||
|
}
|
||
|
|
||
|
int FD() const { return fFD; }
|
||
|
|
||
|
private:
|
||
|
int fFD;
|
||
|
};
|
||
|
} // namespace BPrivate
|
||
|
|
||
|
|
||
|
// #pragma mark -
|
||
|
|
||
|
|
||
|
unsigned
|
||
|
if_nametoindex(const char *name)
|
||
|
{
|
||
|
BPrivate::Socket socket;
|
||
|
if (socket.FD() < 0)
|
||
|
return 0;
|
||
|
|
||
|
ifreq request;
|
||
|
strlcpy(request.ifr_name, name, IF_NAMESIZE);
|
||
|
if (ioctl(socket.FD(), SIOCGIFINDEX, &request, sizeof(struct ifreq)) < 0)
|
||
|
return 0;
|
||
|
|
||
|
return request.ifr_index;
|
||
|
}
|
||
|
|
||
|
|
||
|
char *
|
||
|
if_indextoname(unsigned index, char *nameBuffer)
|
||
|
{
|
||
|
BPrivate::Socket socket;
|
||
|
if (socket.FD() < 0)
|
||
|
return NULL;
|
||
|
|
||
|
ifreq request;
|
||
|
request.ifr_index = index;
|
||
|
if (ioctl(socket.FD(), SIOCGIFNAME, &request, sizeof(struct ifreq)) < 0)
|
||
|
return NULL;
|
||
|
|
||
|
strlcpy(nameBuffer, request.ifr_name, IF_NAMESIZE);
|
||
|
return nameBuffer;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
struct if_nameindex *
|
||
|
if_nameindex(void)
|
||
|
{
|
||
|
BPrivate::Socket socket;
|
||
|
if (socket.FD() < 0)
|
||
|
return NULL;
|
||
|
|
||
|
// get a list of all interfaces
|
||
|
|
||
|
ifconf config;
|
||
|
config.ifc_len = sizeof(config.ifc_value);
|
||
|
if (ioctl(socket.FD(), SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
|
||
|
return NULL;
|
||
|
|
||
|
int count = (int)config.ifc_value;
|
||
|
ifreq* interfaces = (ifreq*)malloc(count * sizeof(struct ifreq));
|
||
|
if (interfaces == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
config.ifc_len = count * sizeof(struct ifreq);
|
||
|
config.ifc_req = interfaces;
|
||
|
if (ioctl(socket.FD(), SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
|
||
|
return NULL;
|
||
|
|
||
|
struct if_nameindex *interfaceArray = (struct if_nameindex *)malloc(
|
||
|
sizeof(struct if_nameindex) * (count + 1));
|
||
|
if (interfaceArray == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
interfaceArray[i].if_index = interfaces[i].ifr_index;
|
||
|
interfaceArray[i].if_name = strdup(interfaces[i].ifr_name);
|
||
|
}
|
||
|
|
||
|
interfaceArray[count].if_index = 0;
|
||
|
interfaceArray[count].if_name = NULL;
|
||
|
|
||
|
return interfaceArray;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
if_freenameindex(struct if_nameindex *interfaceArray)
|
||
|
{
|
||
|
for (int i = 0; interfaceArray[i].if_name; i++) {
|
||
|
free(interfaceArray[i].if_name);
|
||
|
}
|
||
|
free(interfaceArray);
|
||
|
}
|
||
|
|