Author: phoudoin Date: 2010-06-11 03:00:49 +0200 (Fri, 11 Jun 2010) New Revision: 37091 Changeset: http://dev.haiku-os.org/changeset/37091/haiku Modified: haiku/trunk/src/preferences/network/EthernetSettingsView.cpp haiku/trunk/src/preferences/network/Settings.cpp haiku/trunk/src/preferences/network/Settings.h haiku/trunk/src/servers/net/NetServer.cpp haiku/trunk/src/servers/net/Settings.cpp Log: Add interface disabling support. Modified: haiku/trunk/src/preferences/network/EthernetSettingsView.cpp =================================================================== --- haiku/trunk/src/preferences/network/EthernetSettingsView.cpp 2010-06-10 17:45:38 UTC (rev 37090) +++ haiku/trunk/src/preferences/network/EthernetSettingsView.cpp 2010-06-11 01:00:49 UTC (rev 37091) @@ -74,7 +74,9 @@ static const uint32 kMsgClose = 'clse'; static const uint32 kMsgField = 'fild'; static const uint32 kMsgInfo = 'info'; -static const uint32 kMsgMode = 'mode'; +static const uint32 kMsgStaticMode = 'stcm'; +static const uint32 kMsgDHCPMode = 'dynm'; +static const uint32 kMsgDisabledMode = 'disa'; static const uint32 kMsgChange = 'chng'; @@ -127,12 +129,12 @@ BPopUpMenu* modeMenu = new BPopUpMenu("modes"); modeMenu->AddItem(new BMenuItem(B_TRANSLATE("Static"), - new BMessage(kMsgMode))); + new BMessage(kMsgStaticMode))); modeMenu->AddItem(new BMenuItem(B_TRANSLATE("DHCP"), - new BMessage(kMsgMode))); - //modeMenu->AddSeparatorItem(); - //BMenuItem* offItem = new BMenuItem("Disabled", NULL); - //modeMenu->AddItem(offItem); + new BMessage(kMsgDHCPMode))); + modeMenu->AddSeparatorItem(); + modeMenu->AddItem(new BMenuItem(B_TRANSLATE("Disabled"), + new BMessage(kMsgDisabledMode))); fDeviceMenuField = new BMenuField(B_TRANSLATE("Adapter:"), deviceMenu); layout->AddItem(fDeviceMenuField->CreateLabelLayoutItem(), 0, 0); @@ -320,15 +322,19 @@ fGatewayTextControl->SetText(settings->Gateway()); fNetMaskTextControl->SetText(settings->Netmask()); - if (settings->AutoConfigure() == true) + enableControls = false; + + if (settings->IsDisabled()) + item = fTypeMenuField->Menu()->FindItem(B_TRANSLATE("Disabled")); + else if (settings->AutoConfigure() == true) item = fTypeMenuField->Menu()->FindItem(B_TRANSLATE("DHCP")); - else + else { item = fTypeMenuField->Menu()->FindItem(B_TRANSLATE("Static")); + enableControls = true; + } if (item) item->SetMarked(true); - enableControls = settings->AutoConfigure() == false; - if (settings->NameServers().CountItems() >= 2) { fSecondaryDNSTextControl->SetText( settings->NameServers().ItemAt(1)->String()); @@ -371,6 +377,10 @@ strcmp(fTypeMenuField->Menu()->FindMarked()->Label(), B_TRANSLATE("DHCP")) == 0); + fCurrentSettings->SetDisabled( + strcmp(fTypeMenuField->Menu()->FindMarked()->Label(), + B_TRANSLATE("Disabled")) == 0); + fCurrentSettings->NameServers().MakeEmpty(); fCurrentSettings->NameServers().AddItem(new BString( fPrimaryDNSTextControl->Text())); @@ -444,7 +454,9 @@ // loop over all adapters. open the settings file only once, // append the settins of each non-autoconfiguring adapter for (int i = 0; i < fSettings.CountItems(); i++) { - if (fSettings.ItemAt(i)->AutoConfigure()) + Settings* settings = fSettings.ItemAt(i); + + if (settings->AutoConfigure()) continue; if (fp == NULL) { @@ -456,16 +468,20 @@ } } - fprintf(fp, "interface %s {\n\t\taddress {\n", - fSettings.ItemAt(i)->Name()); - fprintf(fp, "\t\t\tfamily\tinet\n"); - fprintf(fp, "\t\t\taddress\t%s\n", - fSettings.ItemAt(i)->IP()); - fprintf(fp, "\t\t\tgateway\t%s\n", - fSettings.ItemAt(i)->Gateway()); - fprintf(fp, "\t\t\tmask\t%s\n", - fSettings.ItemAt(i)->Netmask()); - fprintf(fp, "\t\t}\n}\n\n"); + fprintf(fp, "interface %s {\n", + settings->Name()); + + if (settings->IsDisabled()) + fprintf(fp, "\tdisabled\ttrue\n"); + else { + fprintf(fp, "\taddress {\n"); + fprintf(fp, "\t\tfamily\tinet\n"); + fprintf(fp, "\t\taddress\t%s\n", settings->IP()); + fprintf(fp, "\t\tgateway\t%s\n", settings->Gateway()); + fprintf(fp, "\t\tmask\t%s\n", settings->Netmask()); + fprintf(fp, "\t}\n"); + } + fprintf(fp, "}\n\n"); } if (fp) { printf("%s saved.\n", path.Path()); @@ -565,10 +581,10 @@ EthernetSettingsView::MessageReceived(BMessage* message) { switch (message->what) { - case kMsgMode: - if (BMenuItem* item = fTypeMenuField->Menu()->FindMarked()) - _EnableTextControls(strcmp(item->Label(), - B_TRANSLATE("DHCP")) != 0); + case kMsgStaticMode: + case kMsgDHCPMode: + case kMsgDisabledMode: + _EnableTextControls(message->what == kMsgStaticMode); fApplyButton->SetEnabled(true); fRevertButton->SetEnabled(true); break; Modified: haiku/trunk/src/preferences/network/Settings.cpp =================================================================== --- haiku/trunk/src/preferences/network/Settings.cpp 2010-06-10 17:45:38 UTC (rev 37090) +++ haiku/trunk/src/preferences/network/Settings.cpp 2010-06-11 01:00:49 UTC (rev 37091) @@ -32,7 +32,8 @@ Settings::Settings(const char* name) : - fAuto(true), + fAuto(true), + fDisabled(false), fNameServers(5, true) { fSocket = socket(AF_INET, SOCK_DGRAM, 0); Modified: haiku/trunk/src/preferences/network/Settings.h =================================================================== --- haiku/trunk/src/preferences/network/Settings.h 2010-06-10 17:45:38 UTC (rev 37090) +++ haiku/trunk/src/preferences/network/Settings.h 2010-06-11 01:00:49 UTC (rev 37091) @@ -25,6 +25,8 @@ void SetDomain(BString domain) { fDomain = domain; } void SetAutoConfigure(bool autoConfigure) { fAuto = autoConfigure; } + void SetDisabled(bool disabled) + { fDisabled = disabled; } const char* IP() { return fIP.String(); } const char* Gateway() { return fGateway.String(); } @@ -32,6 +34,7 @@ const char* Name() { return fName.String(); } const char* Domain() { return fDomain.String(); } bool AutoConfigure() { return fAuto; } + bool IsDisabled() { return fDisabled; } BObjectList<BString>& NameServers() { return fNameServers; } @@ -47,6 +50,7 @@ BString fDomain; int fSocket; bool fAuto; + bool fDisabled; BObjectList<BString> fNameServers; }; Modified: haiku/trunk/src/servers/net/NetServer.cpp =================================================================== --- haiku/trunk/src/servers/net/NetServer.cpp 2010-06-10 17:45:38 UTC (rev 37090) +++ haiku/trunk/src/servers/net/NetServer.cpp 2010-06-11 01:00:49 UTC (rev 37091) @@ -56,6 +56,8 @@ private: bool _IsValidInterface(int socket, const char* name); void _RemoveInvalidInterfaces(int socket); + status_t _RemoveInterface(int socket, const char* name); + status_t _DisableInterface(int socket, const char* name); bool _TestForInterface(int socket, const char* name); status_t _ConfigureInterface(int socket, BMessage& interface, @@ -461,14 +463,7 @@ for (uint32 i = 0; i < count; i++) { if (!_IsValidInterface(socket, interface->ifr_name)) { // remove invalid interface - ifreq request; - if (!prepare_request(request, interface->ifr_name)) - break; - - if (ioctl(socket, SIOCDIFADDR, &request, sizeof(request)) < 0) { - fprintf(stderr, "%s: Could not delete interface %s: %s\n", - Name(), interface->ifr_name, strerror(errno)); - } + _RemoveInterface(socket, interface->ifr_name); } interface = (ifreq *)((addr_t)interface + IF_NAMESIZE @@ -528,6 +523,50 @@ status_t +NetServer::_RemoveInterface(int socket, const char* name) +{ + ifreq request; + if (!prepare_request(request, name)) + return B_ERROR; + + if (ioctl(socket, SIOCDIFADDR, &request, sizeof(request)) < 0) { + fprintf(stderr, "%s: Could not delete interface %s: %s\n", + Name(), name, strerror(errno)); + return B_ERROR; + } + + return B_OK; +} + + +status_t +NetServer::_DisableInterface(int socket, const char* name) +{ + ifreq request; + if (!prepare_request(request, name)) + return B_ERROR; + + if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) < 0) { + fprintf(stderr, "%s: Getting flags failed: %s\n", Name(), + strerror(errno)); + return B_ERROR; + } + // Set interface down + request.ifr_flags &= ~(IFF_UP | IFF_AUTO_CONFIGURED | IFF_CONFIGURING); + + if (ioctl(socket, SIOCSIFFLAGS, &request, sizeof(struct ifreq)) < 0) { + fprintf(stderr, "%s: Setting flags failed: %s\n", Name(), + strerror(errno)); + return B_ERROR; + } + + fprintf(stderr, "%s: set %s interface down...\n", Name(), name); + + return B_OK; +} + + +status_t NetServer::_ConfigureInterface(int socket, BMessage& interface, bool fromMessage) { @@ -823,7 +862,6 @@ struct stat stat; BPath path; if (entry.GetName(name) != B_OK - || !strcmp(name, "stack") || entry.GetPath(&path) != B_OK || entry.GetStat(&stat) != B_OK) continue; @@ -852,6 +890,13 @@ const char *device; if (interface.FindString("device", &device) != B_OK) continue; + + bool disabled = false; + if (interface.FindBool("disabled", &disabled) == B_OK && disabled) { + // disabled by user request + _DisableInterface(socket, device); + continue; + } if (!strncmp(device, "/dev/net/", 9)) { // it's a kernel device, check if it's present @@ -943,16 +988,8 @@ if (opcode == B_ENTRY_CREATED) _ConfigureDevice(socket, path); - else { - ifreq request; - if (!prepare_request(request, path)) - return; - - if (ioctl(socket, SIOCDIFADDR, &request, sizeof(request)) < 0) { - fprintf(stderr, "%s: Could not delete interface %s: %s\n", - Name(), path, strerror(errno)); - } - } + else + _RemoveInterface(socket, path); } Modified: haiku/trunk/src/servers/net/Settings.cpp =================================================================== --- haiku/trunk/src/servers/net/Settings.cpp 2010-06-10 17:45:38 UTC (rev 37090) +++ haiku/trunk/src/servers/net/Settings.cpp 2010-06-11 01:00:49 UTC (rev 37091) @@ -42,6 +42,7 @@ const static settings_template kInterfaceTemplate[] = { {B_STRING_TYPE, "device", NULL, true}, + {B_BOOL_TYPE, "disabled", NULL}, {B_MESSAGE_TYPE, "address", kInterfaceAddressTemplate}, {B_INT32_TYPE, "flags", NULL}, {B_INT32_TYPE, "metric", NULL},