Author: kallisti5 Date: 2011-02-21 03:48:48 +0100 (Mon, 21 Feb 2011) New Revision: 40590 Changeset: http://dev.haiku-os.org/changeset/40590 Modified: haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.cpp haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h Log: 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) Modified: haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp =================================================================== --- haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp 2011-02-21 01:56:00 UTC (rev 40589) +++ haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/InterfaceWindow.cpp 2011-02-21 02:48:48 UTC (rev 40590) @@ -60,24 +60,25 @@ 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 @@ 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); } } Modified: haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.cpp =================================================================== --- haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.cpp 2011-02-21 01:56:00 UTC (rev 40589) +++ haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.cpp 2011-02-21 02:48:48 UTC (rev 40590) @@ -38,22 +38,9 @@ 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() { 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 @@ 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 - ifconf config; - config.ifc_len = sizeof(config.ifc_value); - if (ioctl(fSocket[AF_INET], SIOCGRTSIZE, &config, sizeof(config)) < 0) - return; + // --- 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; + uint32 size = (uint32)config.ifc_value; + if (size == 0) + return; - void* buffer = malloc(size); - if (buffer == NULL) - 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; + MemoryDeleter bufferDeleter(buffer); + config.ifc_len = size; + config.ifc_buf = buffer; - if (ioctl(fSocket[AF_INET], SIOCGRTTABLE, &config, sizeof(config)) < 0) - return; + if (ioctl(fProtocols[index].socket_id, SIOCGRTTABLE, + &config, sizeof(config)) < 0) + return; - ifreq* interface = (ifreq*)buffer; - ifreq* end = (ifreq*)((uint8*)buffer + size); + ifreq* interface = (ifreq*)buffer; + ifreq* end = (ifreq*)((uint8*)buffer + size); - while (interface < end) { - route_entry& route = interface->ifr_route; + 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); - } + if ((route.flags & RTF_GATEWAY) != 0) { + if (inet_id == AF_INET) { + char addressOut[INET_ADDRSTRLEN]; + sockaddr_in* socketAddr + = (sockaddr_in*)route.gateway; - 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; + inet_ntop(inet_id, &socketAddr->sin_addr, + addressOut, INET_ADDRSTRLEN); - interface = (ifreq *)((addr_t)interface + IF_NAMESIZE - + sizeof(route_entry) + addressSize); - } + fGateway[inet_id].SetTo(addressOut); - fDisabled = (fNetworkInterface.Flags() & IFF_UP) == 0; + } else if (inet_id == AF_INET6) { + char addressOut[INET6_ADDRSTRLEN]; + sockaddr_in6* socketAddr + = (sockaddr_in6*)route.gateway; - // Obtain selfconfiguration options + inet_ntop(inet_id, &socketAddr->sin6_addr, + addressOut, INET6_ADDRSTRLEN); - // 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()) + fGateway[inet_id].SetTo(addressOut); - fAutoConfigure[AF_INET] = (fNetworkInterface.Flags() - & (IFF_AUTO_CONFIGURED | IFF_CONFIGURING)) != 0; + } else { + printf("Cannot pull routes for unknown protocol: %d\n", + inet_id); + fGateway[inet_id].SetTo(""); + } - fAutoConfigure[AF_INET6] = (fNetworkInterface.Flags() - & (IFF_AUTO_CONFIGURED | IFF_CONFIGURING)) != 0; + } + 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; + } + } + } + // Read wireless network from interfaces - fWirelessNetwork.SetTo(NULL); BPath path; Modified: haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h =================================================================== --- haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h 2011-02-21 01:56:00 UTC (rev 40589) +++ haiku/trunk/src/tests/kits/net/preflet/InterfacesAddOn/NetworkSettings.h 2011-02-21 02:48:48 UTC (rev 40590) @@ -19,19 +19,33 @@ #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 { 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 @@ 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;