Impliment new struct for protocol information (friendlyname,present(working),inet AF number,socket id); Detect OS supported protocols; Draw tabs based on *working* OS protocols; make route ioctl calls ipv6 friendly (shudder); construct/deconstruct sockets based on supported protocols; no crashes! (8000 crashes later)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40590 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV
2011-02-21 02:48:48 +00:00
parent 2905062e64
commit 80d265a95f
3 changed files with 177 additions and 115 deletions
@@ -60,24 +60,25 @@ InterfaceWindow::~InterfaceWindow()
void
InterfaceWindow::MessageReceived(BMessage* message)
{
int* supportedFamilies = fNetworkSettings->ProtocolVersions();
unsigned int index;
protocols* supportedFamilies = fNetworkSettings->ProtocolVersions();
switch (message->what) {
case MSG_IP_REVERT:
for (index = 0; index < sizeof(supportedFamilies); index++)
for (int index = 0; index < MAX_PROTOCOLS; index++)
{
int protocol = supportedFamilies[index];
if (protocol > 0)
fTabIPView[protocol]->RevertFields();
if (supportedFamilies[index].present) {
int inet_id = supportedFamilies[index].inet_id;
fTabIPView[inet_id]->RevertFields();
}
}
break;
case MSG_IP_SAVE:
for (index = 0; index < sizeof(supportedFamilies); index++)
for (int index = 0; index < MAX_PROTOCOLS; index++)
{
int protocol = supportedFamilies[index];
if (protocol > 0)
fTabIPView[protocol]->SaveFields();
if (supportedFamilies[index].present) {
int inet_id = supportedFamilies[index].inet_id;
fTabIPView[inet_id]->SaveFields();
}
}
this->Quit();
break;
@@ -92,20 +93,17 @@ status_t
InterfaceWindow::_PopulateTabs()
{
BRect frame = fTabView->Bounds();
int* supportedFamilies = fNetworkSettings->ProtocolVersions();
protocols* supportedFamilies = fNetworkSettings->ProtocolVersions();
unsigned int index;
for (index = 0; index < sizeof(supportedFamilies); index++)
for (int index = 0; index < MAX_PROTOCOLS; index++)
{
int protocol = supportedFamilies[index];
if (protocol > 0)
{
fTabIPView[protocol] = new InterfaceAddressView(frame,
protocol, fNetworkSettings);
if (supportedFamilies[index].present) {
int inet_id = supportedFamilies[index].inet_id;
fTabIPView[inet_id] = new InterfaceAddressView(frame,
inet_id, fNetworkSettings);
BTab* tab = new BTab;
fTabView->AddTab(fTabIPView[protocol], tab);
tab->SetLabel((protocol == AF_INET) ? "IPv4" : "IPv6");
// TODO : find a better way
fTabView->AddTab(fTabIPView[inet_id], tab);
tab->SetLabel(supportedFamilies[index].name);
}
}
@@ -38,21 +38,8 @@ NetworkSettings::NetworkSettings(const char* name)
fDisabled(false),
fNameServers(5, true)
{
// TODO : Detect supported IP protocol versions
memset(fProtocolVersions, 0, sizeof(fProtocolVersions));
fProtocolVersions[0] = AF_INET;
fProtocolVersions[1] = AF_INET6;
unsigned int index;
for (index = 0; index < sizeof(fProtocolVersions); index++)
{
int protocol = fProtocolVersions[index];
if (protocol > 0)
fSocket[protocol] = socket(protocol, SOCK_DGRAM, 0);
}
fName = name;
_DetectProtocols();
ReadConfiguration();
}
@@ -61,15 +48,56 @@ NetworkSettings::NetworkSettings(const char* name)
NetworkSettings::~NetworkSettings()
{
unsigned int index;
for (index = 0; index < sizeof(fProtocolVersions); index++)
for (index = 0; index < MAX_PROTOCOLS; index++)
{
int protocol = fProtocolVersions[index];
if (protocol > 0)
close(fSocket[protocol]);
int socket_id = fProtocols[index].socket_id;
if (socket_id < 0)
continue;
close(socket_id);
}
}
status_t
NetworkSettings::_DetectProtocols()
{
for (int index = 0; index < MAX_PROTOCOLS; index++) {
fProtocols[index].name = NULL;
fProtocols[index].present = false;
fProtocols[index].socket_id = -1;
fProtocols[index].inet_id = -1;
}
// First we populate the struct with the possible
// protocols we could configure for an interface
// (size limit of MAX_PROTOCOLS)
fProtocols[0].name = "IPv4";
fProtocols[0].inet_id = AF_INET;
fProtocols[1].name = "IPv6";
fProtocols[1].inet_id = AF_INET6;
// Loop through each of the possible protocols and
// ensure they are functional
for (int index = 0; index < MAX_PROTOCOLS; index++) {
int inet_id = fProtocols[index].inet_id;
if (inet_id > 0)
{
fProtocols[index].socket_id = socket(inet_id, SOCK_DGRAM, 0);
if (fProtocols[index].socket_id < 0) {
printf("Protocol %s : not present\n", fProtocols[index].name);
fProtocols[index].present = false;
} else {
printf("Protocol %s : present\n", fProtocols[index].name);
fProtocols[index].present = true;
}
}
}
return B_OK;
}
// -- Interface address read code
@@ -77,85 +105,108 @@ void
NetworkSettings::ReadConfiguration()
{
BNetworkInterface fNetworkInterface(fName);
fDisabled = (fNetworkInterface.Flags() & IFF_UP) == 0;
unsigned int index;
for (index = 0; index < sizeof(fProtocolVersions); index++)
{
int protocol = fProtocolVersions[index];
for (int index = 0; index < MAX_PROTOCOLS; index++) {
int inet_id = fProtocols[index].inet_id;
if (protocol > 0) {
int32 zeroAddr = fNetworkInterface.FindFirstAddress(protocol);
if (fProtocols[index].present) {
// --- Obtain IP Addresses
int32 zeroAddr = fNetworkInterface.FindFirstAddress(inet_id);
if (zeroAddr >= 0) {
fNetworkInterface.GetAddressAt(zeroAddr,
fInterfaceAddressMap[protocol]);
fAddress[protocol]
= fInterfaceAddressMap[protocol].Address();
fNetmask[protocol]
= fInterfaceAddressMap[protocol].Mask();
fInterfaceAddressMap[inet_id]);
fAddress[inet_id].SetTo(
fInterfaceAddressMap[inet_id].Address());
fNetmask[inet_id].SetTo(
fInterfaceAddressMap[inet_id].Mask());
}
// --- Obtain gateway
// TODO : maybe in the future no ioctls?
ifconf config;
config.ifc_len = sizeof(config.ifc_value);
// Populate config with size of routing table
if (ioctl(fProtocols[index].socket_id, SIOCGRTSIZE,
&config, sizeof(config)) < 0)
return;
uint32 size = (uint32)config.ifc_value;
if (size == 0)
return;
// Malloc a buffer the size of the routing table
void* buffer = malloc(size);
if (buffer == NULL)
return;
MemoryDeleter bufferDeleter(buffer);
config.ifc_len = size;
config.ifc_buf = buffer;
if (ioctl(fProtocols[index].socket_id, SIOCGRTTABLE,
&config, sizeof(config)) < 0)
return;
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) {
if (inet_id == AF_INET) {
char addressOut[INET_ADDRSTRLEN];
sockaddr_in* socketAddr
= (sockaddr_in*)route.gateway;
inet_ntop(inet_id, &socketAddr->sin_addr,
addressOut, INET_ADDRSTRLEN);
fGateway[inet_id].SetTo(addressOut);
} else if (inet_id == AF_INET6) {
char addressOut[INET6_ADDRSTRLEN];
sockaddr_in6* socketAddr
= (sockaddr_in6*)route.gateway;
inet_ntop(inet_id, &socketAddr->sin6_addr,
addressOut, INET6_ADDRSTRLEN);
fGateway[inet_id].SetTo(addressOut);
} else {
printf("Cannot pull routes for unknown protocol: %d\n",
inet_id);
fGateway[inet_id].SetTo("");
}
}
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);
}
// --- Obtain selfconfiguration options
// TODO : This needs to be determined by protocol flags
// AutoConfiguration on the IP level doesn't exist yet
// ( fInterfaceAddressMap[AF_INET].Flags() )
if (fProtocols[index].socket_id >= 0) {
fAutoConfigure[inet_id] = (fNetworkInterface.Flags()
& (IFF_AUTO_CONFIGURED | IFF_CONFIGURING)) != 0;
}
}
}
// Obtain gateway
ifconf config;
config.ifc_len = sizeof(config.ifc_value);
if (ioctl(fSocket[AF_INET], SIOCGRTSIZE, &config, sizeof(config)) < 0)
return;
uint32 size = (uint32)config.ifc_value;
if (size == 0)
return;
void* buffer = malloc(size);
if (buffer == NULL)
return;
MemoryDeleter bufferDeleter(buffer);
config.ifc_len = size;
config.ifc_buf = buffer;
if (ioctl(fSocket[AF_INET], SIOCGRTTABLE, &config, sizeof(config)) < 0)
return;
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;
fGateway[AF_INET] = inet_ntoa(inetAddress->sin_addr);
}
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);
}
fDisabled = (fNetworkInterface.Flags() & IFF_UP) == 0;
// Obtain selfconfiguration options
// TODO : This needs to be determined by the protocol flags
// instead of the interface flag... protocol flags don't seem
// to be complete yet. (netIntAddr4.Flags() and netIntAddr6.Flags())
fAutoConfigure[AF_INET] = (fNetworkInterface.Flags()
& (IFF_AUTO_CONFIGURED | IFF_CONFIGURING)) != 0;
fAutoConfigure[AF_INET6] = (fNetworkInterface.Flags()
& (IFF_AUTO_CONFIGURED | IFF_CONFIGURING)) != 0;
// Read wireless network from interfaces
fWirelessNetwork.SetTo(NULL);
BPath path;
@@ -19,10 +19,24 @@
#include <map>
#define MAX_PROTOCOLS 7
// maximum number of protocols that could be configured
typedef std::map<int, BNetworkAddress> AddressMap;
typedef std::map<int, BNetworkInterfaceAddress> InterfaceAddressMap;
typedef std::map<int, bool> BoolMap;
typedef std::map<int, int> SocketMap;
typedef struct _protocols {
const char* name;
// Eg. "IPv4", used for user descriptions
bool present;
// Does the OS have the proper addon?
int inet_id;
// Eg. AF_INET
int socket_id;
// Socket ID used for ioctls to this proto
} protocols;
class NetworkSettings {
@@ -30,8 +44,8 @@ public:
NetworkSettings(const char* name);
virtual ~NetworkSettings();
int* ProtocolVersions()
{ return fProtocolVersions; }
protocols* ProtocolVersions()
{ return fProtocols; }
void SetIP(int family, const char* ip)
{ fAddress[family].SetTo(ip); }
@@ -76,12 +90,11 @@ public:
void WriteConfiguration();
private:
SocketMap fSocket;
status_t _DetectProtocols();
BNetworkInterface fNetworkInterface;
InterfaceAddressMap fInterfaceAddressMap;
int fProtocolVersions[3];
// OS Supported protocol versions
protocols fProtocols[MAX_PROTOCOLS];
// Stored network addresses and paramaters
BoolMap fAutoConfigure;