Add interface disabling support.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37091 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin 2010-06-11 01:00:49 +00:00
parent b35f3d132c
commit 2d3904fe20
5 changed files with 104 additions and 45 deletions

View File

@ -74,7 +74,9 @@ static const uint32 kMsgRevert = 'rvrt';
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 @@ EthernetSettingsView::EthernetSettingsView()
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 @@ EthernetSettingsView::_ShowConfiguration(Settings* settings)
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 @@ EthernetSettingsView::_ApplyControlsToConfiguration()
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 @@ EthernetSettingsView::_SaveAdaptersConfiguration()
// 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 @@ EthernetSettingsView::_SaveAdaptersConfiguration()
}
}
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 @@ void
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;

View File

@ -33,6 +33,7 @@
Settings::Settings(const char* name)
:
fAuto(true),
fDisabled(false),
fNameServers(5, true)
{
fSocket = socket(AF_INET, SOCK_DGRAM, 0);

View File

@ -25,6 +25,8 @@ public:
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 @@ public:
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 @@ private:
BString fDomain;
int fSocket;
bool fAuto;
bool fDisabled;
BObjectList<BString> fNameServers;
};

View File

@ -56,6 +56,8 @@ public:
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 @@ NetServer::_RemoveInvalidInterfaces(int socket)
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
@ -527,6 +522,50 @@ NetServer::_TestForInterface(int socket, const char* name)
}
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 @@ NetServer::_ConfigureDevices(int socket, const char* startPath,
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;
@ -853,6 +891,13 @@ NetServer::_ConfigureInterfaces(int socket, BMessage* _missingDevice)
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
BEntry entry(device);
@ -943,16 +988,8 @@ NetServer::_HandleDeviceMonitor(int socket, BMessage* message)
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);
}

View File

@ -42,6 +42,7 @@ const static settings_template kInterfaceAddressTemplate[] = {
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},