diff --git a/src/preferences/network/EthernetSettingsView.cpp b/src/preferences/network/EthernetSettingsView.cpp index cc46182a4a..877c1fd153 100644 --- a/src/preferences/network/EthernetSettingsView.cpp +++ b/src/preferences/network/EthernetSettingsView.cpp @@ -10,6 +10,7 @@ */ #include "EthernetSettingsView.h" +#include "settings.h" #include #include @@ -64,8 +65,7 @@ EthernetSettingsView::_PrepareRequest(struct ifreq& request, const char* name) } void -EthernetSettingsView::_GatherInterfaces() -{ +EthernetSettingsView::_GatherInterfaces() { // iterate over all interfaces and retrieve minimal status ifconf config; @@ -94,6 +94,7 @@ EthernetSettingsView::_GatherInterfaces() if (strncmp(interface->ifr_name, "loop", 4) && interface->ifr_name[0]) { fInterfaces.AddItem(new BString(interface->ifr_name)); + fSettings.AddItem(new Settings(interface->ifr_name)); } @@ -130,6 +131,7 @@ EthernetSettingsView::EthernetSettingsView(BRect rect) SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + fSettings.MakeEmpty(); fSocket = socket(AF_INET, SOCK_DGRAM, 0); _GatherInterfaces(); @@ -236,122 +238,36 @@ EthernetSettingsView::_ShowConfiguration(BMessage* message) const char* name; if (message->FindString("interface", &name) != B_OK) return; - - ifreq request; - if (!_PrepareRequest(request, name)) - return; - - BString text = "dummy"; - char address[32]; - sockaddr_in* inetAddress = NULL; - // Obtain IP. - if (ioctl(fSocket, SIOCGIFADDR, &request, - sizeof(request)) < 0) { - return; - } - - inetAddress = (sockaddr_in*)&request.ifr_addr; - if (inet_ntop(AF_INET, &inetAddress->sin_addr, address, - sizeof(address)) == NULL) { + int i; + for (i=0; iGetName(), name) == 0) { + fIPTextControl->SetText(fSettings.ItemAt(i)->GetIP()); + fGatewayTextControl->SetText(fSettings.ItemAt(i)->GetGateway()); + fNetMaskTextControl->SetText(fSettings.ItemAt(i)->GetNetmask()); + + + + if (fSettings.ItemAt(i)->fNameservers.CountItems() == 2) { + fSecondaryDNSTextControl->SetText( + fSettings.ItemAt(i)->fNameservers.ItemAt(1)->String()); + } + + if (fSettings.ItemAt(i)->fNameservers.CountItems() >= 1) { + fPrimaryDNSTextControl->SetText( + fSettings.ItemAt(i)->fNameservers.ItemAt(0)->String()); + } + } else { return; } - - fIPTextControl->SetText(address); - - // Obtain netmask. - if (ioctl(fSocket, SIOCGIFNETMASK, &request, - sizeof(request)) < 0) { - return; } - inetAddress = (sockaddr_in*)&request.ifr_mask; - if (inet_ntop(AF_INET, &inetAddress->sin_addr, address, - sizeof(address)) == NULL) { - return; - } - - fNetMaskTextControl->SetText(address); - - // Obtain gateway - - char* gwAddress; - ifconf config; - config.ifc_len = sizeof(config.ifc_value); - if (ioctl(fSocket, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0) - return; - - uint32 size = (uint32)config.ifc_value; - if (size == 0) - return; - - void *buffer = malloc(size); - if (buffer == NULL) - return; - - config.ifc_len = size; - config.ifc_buf = buffer; - - if (ioctl(fSocket, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0) { - free(buffer); - 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) { - inetAddress = (sockaddr_in *)route.gateway; - - - gwAddress = inet_ntoa(inetAddress->sin_addr); - fGatewayTextControl->SetText(gwAddress); - } - - 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); - - } - - free(buffer); // Obtain DNS - //resolv.conf is always actual. - BFile file; - BString* line; - int i = 0; - char* ch = "0"; - if (file.SetTo("/etc/resolv.conf", B_READ_ONLY) != B_OK) - return; - - off_t length; - file.GetSize(&length); - - /* - The idea here is to iterate over resolv.conf - and look for the nameservers. - - Both netserver and DHCPClient will write to resolv.conf - so we can trust that the information on the file is actual. - - I need help with this routine :$ - */ + diff --git a/src/preferences/network/EthernetSettingsView.h b/src/preferences/network/EthernetSettingsView.h index 2a1d8c9c52..4c6db29360 100644 --- a/src/preferences/network/EthernetSettingsView.h +++ b/src/preferences/network/EthernetSettingsView.h @@ -11,6 +11,7 @@ #ifndef ETHERNET_SETTINGS_VIEW_H #define ETHERNET_SETTINGS_VIEW_H +#include "settings.h" #include #include @@ -46,6 +47,8 @@ class EthernetSettingsView : public BView { BTextControl* fPrimaryDNSTextControl; BTextControl* fSecondaryDNSTextControl; BObjectList fInterfaces; + BObjectList fSettings; + int32 fStatus; int fSocket; void _GatherInterfaces(); diff --git a/src/preferences/network/Jamfile b/src/preferences/network/Jamfile index 0c5b618aa8..46624d5911 100644 --- a/src/preferences/network/Jamfile +++ b/src/preferences/network/Jamfile @@ -6,9 +6,10 @@ UsePrivateHeaders shared ; Preference Network : EthernetSettingsWindow.cpp + settings.cpp EthernetSettingsView.cpp EthernetSettings.cpp - : be root $(TARGET_NETWORK_LIBS) + : be root $(HAIKU_NETWORK_LIBS) ; Package haiku-networksettings : diff --git a/src/preferences/network/settings.cpp b/src/preferences/network/settings.cpp new file mode 100644 index 0000000000..0bc88809c1 --- /dev/null +++ b/src/preferences/network/settings.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2004-2007 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Author: + * Andre Alves Garzia, andre@andregarzia.com + */ + +#include "settings.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +Settings::Settings(const char *name) +{ + fSocket = socket(AF_INET, SOCK_DGRAM, 0); + fName = name; + ReadConfiguration(); +} + +Settings::~Settings() +{ + close(fSocket); + +} + +bool +Settings::_PrepareRequest(struct ifreq& request) +{ + //This function is used for talking direct to the stack. + //It´s used by _ShowConfiguration. + + const char* name = fName.String(); + + if (strlen(name) > IF_NAMESIZE) + return false; + + strcpy(request.ifr_name, name); + return true; +} + + +void +Settings::ReadConfiguration() +{ + + ifreq request; + if (!_PrepareRequest(request)) + return; + + BString text = "dummy"; + char address[32]; + sockaddr_in* inetAddress = NULL; + + // Obtain IP. + if (ioctl(fSocket, SIOCGIFADDR, &request, + sizeof(request)) < 0) { + return; + } + + inetAddress = (sockaddr_in*)&request.ifr_addr; + if (inet_ntop(AF_INET, &inetAddress->sin_addr, address, + sizeof(address)) == NULL) { + return; + } + + fIP = address; + + // Obtain netmask. + if (ioctl(fSocket, SIOCGIFNETMASK, &request, + sizeof(request)) < 0) { + return; + } + + inetAddress = (sockaddr_in*)&request.ifr_mask; + if (inet_ntop(AF_INET, &inetAddress->sin_addr, address, + sizeof(address)) == NULL) { + return; + } + + fNetmask = address; + + // Obtain gateway + + char* gwAddress; + ifconf config; + config.ifc_len = sizeof(config.ifc_value); + if (ioctl(fSocket, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 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, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 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) { + inetAddress = (sockaddr_in *)route.gateway; + + + gwAddress = inet_ntoa(inetAddress->sin_addr); + fGateway = gwAddress; + } + + 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); + + } + + bufferDeleter.Detach(); + free(buffer); + + // Now that silly DNS problem... + fNameservers.MakeEmpty(); + +#define MATCH(line, name) \ + (!strncmp(line, name, sizeof(name) - 1) && \ + (line[sizeof(name) - 1] == ' ' || \ + line[sizeof(name) - 1] == '\t')) + + + int nserv = 0; + char buf[1024]; + register FILE *fp; + register char *cp, **pp; + register int n; + int MAXNS = 2; + + if ((fp = fopen("/etc/resolv.conf", "r")) != NULL) { + /* read the config file */ + while (fgets(buf, sizeof(buf), fp) != NULL) { + /* skip comments */ + if (*buf == ';' || *buf == '#') + continue; + + /* read nameservers to query */ + if (MATCH(buf, "nameserver") && nserv < MAXNS) { + char sbuf[2]; + + cp = buf + sizeof("nameserver") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; + cp[strcspn(cp, ";# \t\n")] = '\0'; + if ((*cp != '\0') && (*cp != '\n')) { + fNameservers.AddItem(new BString(cp)); + nserv++; + } + } + continue; + } + fclose(fp); + } +} diff --git a/src/preferences/network/settings.h b/src/preferences/network/settings.h new file mode 100644 index 0000000000..f14648c586 --- /dev/null +++ b/src/preferences/network/settings.h @@ -0,0 +1,47 @@ +/* + * Copyright 2004-2007 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Author: + * Andre Alves Garzia, andre@andregarzia.com + */ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include +#include + +class Settings { + public: + Settings(const char* name); + virtual ~Settings(); + + void SetName(BString name); + void SetIP(BString ip); + void SetGateway(BString ip); + void SetNetmask(BString ip); + void SetAutoConfigure(bool t); + + const char* GetIP() {return fIP.String(); } + const char* GetGateway() {return fGateway.String(); } + const char* GetNetmask() {return fNetmask.String(); } + const char* GetName() {return fName.String(); } + bool GetAutoConfigure() const {return fAuto; } + BObjectList fNameservers; + + void SaveProfile(BString profileName); + void LoadProfile(BString profileName); + void SaveConfiguration(); + void ReadConfiguration(); + + private: + bool _PrepareRequest(struct ifreq& request); + BString fIP; + BString fGateway; + BString fNetmask; + BString fName; + int fSocket; + bool fAuto; +}; + +#endif /* SETTINGS_H */