Implement BNetworkRoster::GetNextRoute()
Implement BNetworkRoster::GetNextRoute() and used it in Network preflet.
This commit is contained in:
parent
e4b939faa4
commit
0074cea398
@ -12,6 +12,7 @@
|
||||
|
||||
class BMessenger;
|
||||
class BNetworkInterface;
|
||||
struct route_entry;
|
||||
struct wireless_network;
|
||||
|
||||
|
||||
@ -30,6 +31,10 @@ public:
|
||||
status_t RemoveInterface(
|
||||
const BNetworkInterface& interface);
|
||||
|
||||
status_t GetNextRoute(uint32* cookie,
|
||||
route_entry& entry,
|
||||
const char* interface = NULL) const;
|
||||
|
||||
int32 CountPersistentNetworks() const;
|
||||
status_t GetNextPersistentNetwork(uint32* cookie,
|
||||
wireless_network& network) const;
|
||||
|
@ -17,6 +17,37 @@
|
||||
#include <NetServer.h>
|
||||
|
||||
|
||||
enum preferredPrefixFormat {
|
||||
PREFIX_PREFER_NETMASK = 0,
|
||||
PREFIX_PREFER_CIDR,
|
||||
};
|
||||
|
||||
struct address_family {
|
||||
int family;
|
||||
const char* name;
|
||||
const char* identifiers[4];
|
||||
int maxAddressLength;
|
||||
int preferredPrefixFormat;
|
||||
};
|
||||
|
||||
static const address_family kFamilies[] = {
|
||||
{
|
||||
AF_INET,
|
||||
"IPv4",
|
||||
{"AF_INET", "inet", "ipv4", NULL},
|
||||
15,
|
||||
PREFIX_PREFER_NETMASK,
|
||||
},
|
||||
{
|
||||
AF_INET6,
|
||||
"IPv6",
|
||||
{"AF_INET6", "inet6", "ipv6", NULL},
|
||||
39,
|
||||
PREFIX_PREFER_CIDR,
|
||||
},
|
||||
{ -1, NULL, {NULL}, -1, -1 }
|
||||
};
|
||||
|
||||
// TODO: using AF_INET for the socket isn't really a smart idea, as one
|
||||
// could completely remove IPv4 support from the stack easily.
|
||||
// Since in the stack, device_interfaces are pretty much interfaces now, we
|
||||
@ -162,6 +193,74 @@ BNetworkRoster::RemoveInterface(const BNetworkInterface& interface)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BNetworkRoster::GetNextRoute(uint32* cookie, route_entry& entry,
|
||||
const char* interfaceName) const
|
||||
{
|
||||
// TODO: Cache the routes ?
|
||||
|
||||
if (cookie == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (socket < 0)
|
||||
return errno;
|
||||
|
||||
FileDescriptorCloser fdCloser(socket);
|
||||
|
||||
// Obtain gateway
|
||||
ifconf config;
|
||||
config.ifc_len = sizeof(config.ifc_value);
|
||||
if (ioctl(socket, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
|
||||
return errno;
|
||||
|
||||
uint32 size = (uint32)config.ifc_value;
|
||||
if (size == 0)
|
||||
return B_ERROR;
|
||||
|
||||
void* buffer = malloc(size);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
MemoryDeleter bufferDeleter(buffer);
|
||||
config.ifc_len = size;
|
||||
config.ifc_buf = buffer;
|
||||
|
||||
if (ioctl(socket, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
|
||||
return errno;
|
||||
|
||||
ifreq* interface = (ifreq*)buffer;
|
||||
ifreq* end = (ifreq*)((uint8*)buffer + size);
|
||||
|
||||
uint32 index = 0;
|
||||
while (interface < end) {
|
||||
route_entry& route = interface->ifr_route;
|
||||
// Filter by interface name
|
||||
if (interfaceName == NULL
|
||||
|| !strcmp(interfaceName, interface->ifr_name)) {
|
||||
if (index == *cookie) {
|
||||
entry = route;
|
||||
return B_OK;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
int32 addressSize = 0;
|
||||
if (route.destination != NULL)
|
||||
addressSize += route.destination->sa_len;
|
||||
if (route.mask != NULL)
|
||||
addressSize += route.mask->sa_len;
|
||||
if (route.gateway != NULL)
|
||||
addressSize += route.gateway->sa_len;
|
||||
|
||||
interface = (ifreq *)((addr_t)interface + IF_NAMESIZE
|
||||
+ sizeof(route_entry) + addressSize);
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BNetworkRoster::CountPersistentNetworks() const
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
@ -28,6 +29,7 @@
|
||||
#include <FindDirectory.h>
|
||||
#include <NetworkDevice.h>
|
||||
#include <NetworkInterface.h>
|
||||
#include <NetworkRoster.h>
|
||||
#include <Path.h>
|
||||
#include <String.h>
|
||||
|
||||
@ -35,59 +37,18 @@
|
||||
|
||||
|
||||
static status_t
|
||||
GetDefaultGateway(BString& gateway)
|
||||
GetDefaultGateway(const char* name, BString& gateway)
|
||||
{
|
||||
// TODO: This method is here because BNetworkInterface
|
||||
// doesn't yet have any route getting methods
|
||||
|
||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (socket < 0)
|
||||
return errno;
|
||||
|
||||
FileDescriptorCloser fdCloser(socket);
|
||||
|
||||
// Obtain gateway
|
||||
ifconf config;
|
||||
config.ifc_len = sizeof(config.ifc_value);
|
||||
if (ioctl(socket, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
|
||||
return errno;
|
||||
|
||||
uint32 size = (uint32)config.ifc_value;
|
||||
if (size == 0)
|
||||
return B_ERROR;
|
||||
|
||||
void* buffer = malloc(size);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
MemoryDeleter bufferDeleter(buffer);
|
||||
config.ifc_len = size;
|
||||
config.ifc_buf = buffer;
|
||||
|
||||
if (ioctl(socket, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
|
||||
return errno;
|
||||
|
||||
ifreq* interface = (ifreq*)buffer;
|
||||
ifreq* end = (ifreq*)((uint8*)buffer + size);
|
||||
|
||||
while (interface < end) {
|
||||
route_entry& route = interface->ifr_route;
|
||||
|
||||
if ((route.flags & RTF_GATEWAY) != 0) {
|
||||
sockaddr_in* inetAddress = (sockaddr_in*)route.gateway;
|
||||
uint32 index = 0;
|
||||
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||
route_entry routeEntry;
|
||||
while (roster.GetNextRoute(&index, routeEntry, name) == B_OK) {
|
||||
if ((routeEntry.flags & RTF_GATEWAY) != 0) {
|
||||
sockaddr_in* inetAddress = (sockaddr_in*)routeEntry.gateway;
|
||||
gateway = inet_ntoa(inetAddress->sin_addr);
|
||||
break;
|
||||
}
|
||||
|
||||
int32 addressSize = 0;
|
||||
if (route.destination != NULL)
|
||||
addressSize += route.destination->sa_len;
|
||||
if (route.mask != NULL)
|
||||
addressSize += route.mask->sa_len;
|
||||
if (route.gateway != NULL)
|
||||
addressSize += route.gateway->sa_len;
|
||||
|
||||
interface = (ifreq *)((addr_t)interface + IF_NAMESIZE
|
||||
+ sizeof(route_entry) + addressSize);
|
||||
index++;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@ -145,7 +106,7 @@ Settings::ReadConfiguration()
|
||||
fIP = address.Address().ToString();
|
||||
fNetmask = address.Mask().ToString();
|
||||
|
||||
if (GetDefaultGateway(fGateway) != B_OK)
|
||||
if (GetDefaultGateway(fName.String(), fGateway) != B_OK)
|
||||
return;
|
||||
|
||||
uint32 flags = interface.Flags();
|
||||
|
Loading…
Reference in New Issue
Block a user