haiku/src/kits/network/interfaces.cpp
Axel Dörfler 5adca30a18 Merge of branches/team/network/new_stack - not yet complete as SVN does only support
replacing files when merging when you don't have deleted them manually (for some reason,
it only works as part of the merge operation, and we didn't copy the whole tree to
have "a fresh start" - next time we know better, at least if SVN still suffers from
that same limitation).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18456 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-08-08 12:33:33 +00:00

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);
}