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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user