* Implemented node monitoring: if you change the interfaces settings file, the

networking stack is reconfigured automatically.
* The previous default route is now removed before installing a new one.
* "gateway" was missing in the driver settings to BMessage conversion template,
  and thus, it was only set to a default value in case there was no settings
  file.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19086 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-10-19 13:37:13 +00:00
parent 535df2cff3
commit b01a3a33a6
3 changed files with 144 additions and 18 deletions

View File

@ -13,6 +13,7 @@
#include <Application.h>
#include <Directory.h>
#include <Entry.h>
#include <NodeMonitor.h>
#include <Path.h>
#include <TextView.h>
@ -37,6 +38,7 @@ class NetServer : public BApplication {
virtual void AboutRequested();
virtual void ReadyToRun();
virtual void MessageReceived(BMessage* message);
private:
bool _PrepareRequest(ifreq& request, const char* name);
@ -44,6 +46,7 @@ class NetServer : public BApplication {
status_t _ConfigureInterface(int socket, BMessage& interface);
status_t _ConfigureDevice(int socket, const char* path);
void _ConfigureDevices(int socket, const char* path);
void _ConfigureInterfaces(int socket);
void _BringUpInterfaces();
Settings fSettings;
@ -153,10 +156,38 @@ NetServer::AboutRequested()
void
NetServer::ReadyToRun()
{
fSettings.StartMonitoring(this);
_BringUpInterfaces();
}
void
NetServer::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_NODE_MONITOR:
fSettings.Update(message);
break;
case kMsgInterfaceSettingsUpdated:
{
// we need a socket to talk to the networking stack
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
if (socket < 0)
break;
_ConfigureInterfaces(socket);
close(socket);
break;
}
default:
BApplication::MessageReceived(message);
return;
}
}
bool
NetServer::_PrepareRequest(ifreq& request, const char* name)
{
@ -304,10 +335,13 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface)
&& parse_address(familyIndex, string, gateway)) {
route_entry route;
memset(&route, 0, sizeof(route_entry));
route.gateway = &gateway;
route.flags = RTF_STATIC | RTF_DEFAULT | RTF_GATEWAY;
route.gateway = &gateway;
request.ifr_route = route;
ioctl(socket, SIOCDELRT, &request, sizeof(request));
// Try to remove a previous default route, doesn't matter
// if it fails.
if (ioctl(socket, SIOCADDRT, &request, sizeof(request)) < 0) {
fprintf(stderr, "%s: Could not add route for %s: %s\n",
@ -465,19 +499,8 @@ NetServer::_ConfigureDevices(int socket, const char* startPath)
void
NetServer::_BringUpInterfaces()
NetServer::_ConfigureInterfaces(int socket)
{
// we need a socket to talk to the networking stack
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
if (socket < 0) {
fprintf(stderr, "%s: The networking stack doesn't seem to be available.\n",
Name());
Quit();
return;
}
// First, we look into the settings, and try to bring everything up from there
BMessage interface;
uint32 cookie = 0;
while (fSettings.GetNextInterface(cookie, interface) == B_OK) {
@ -492,16 +515,32 @@ NetServer::_BringUpInterfaces()
continue;
}
// try to bring the interface up
_ConfigureInterface(socket, interface);
}
}
void
NetServer::_BringUpInterfaces()
{
// we need a socket to talk to the networking stack
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
if (socket < 0) {
fprintf(stderr, "%s: The networking stack doesn't seem to be available.\n",
Name());
Quit();
return;
}
// First, we look into the settings, and try to bring everything up from there
_ConfigureInterfaces(socket);
// check configuration
if (!_TestForInterface(socket, "loop")) {
// there is no loopback interface, create one
interface.MakeEmpty();
BMessage interface;
interface.AddString("device", "loop");
BMessage address;
address.AddString("family", "inet");

View File

@ -9,7 +9,9 @@
#include "Settings.h"
#include <Directory.h>
#include <FindDirectory.h>
#include <NodeMonitor.h>
#include <Path.h>
#include <stdio.h>
@ -23,6 +25,7 @@ const static settings_template kInterfaceAddressTemplate[] = {
{B_STRING_TYPE, "mask", NULL},
{B_STRING_TYPE, "peer", NULL},
{B_STRING_TYPE, "broadcast", NULL},
{B_STRING_TYPE, "gateway", NULL},
{0, NULL, NULL}
};
@ -66,12 +69,13 @@ Settings::~Settings()
status_t
Settings::_GetPath(const char* name, BPath& path)
{
if (find_directory(B_COMMON_SETTINGS_DIRECTORY, &path) != B_OK)
if (find_directory(B_COMMON_SETTINGS_DIRECTORY, &path, true) != B_OK)
return B_ERROR;
path.Append("network");
path.Append(name);
create_directory(path.Path(), 0755);
path.Append(name);
return B_OK;
}
@ -186,6 +190,81 @@ Settings::_Load()
}
status_t
Settings::StartMonitoring(const BMessenger& target)
{
fListener = target;
BPath path;
status_t status = _GetPath("interfaces", path);
if (status < B_OK)
return status;
node_ref ref;
BNode node;
BPath parent;
if (path.GetParent(&parent) == B_OK) {
status = node.SetTo(parent.Path());
if (status < B_OK)
return status;
status = node.GetNodeRef(&ref);
if (status < B_OK)
return status;
status = watch_node(&ref, B_WATCH_DIRECTORY, target);
if (status < B_OK)
return status;
}
status = node.SetTo(path.Path());
if (status < B_OK)
return status;
status = node.GetNodeRef(&ref);
if (status < B_OK)
return status;
return watch_node(&ref, B_WATCH_STAT, target);
}
status_t
Settings::StopMonitoring(const BMessenger& target)
{
// TODO: this needs to be changed in case the server will watch
// anything else but settings
return stop_watching(target);
}
status_t
Settings::Update(BMessage* message)
{
const char* name;
int32 opcode;
if (message->FindInt32("opcode", &opcode) < B_OK
|| message->FindString("name", &name) < B_OK)
return B_BAD_VALUE;
if (opcode == B_ENTRY_REMOVED)
return B_OK;
if (!strcmp(name, "interfaces")) {
status_t status = _ConvertFromDriverSettings("interfaces",
kInterfaceTemplate, fInterfaces);
if (status < B_OK)
return status;
BMessage update(kMsgInterfaceSettingsUpdated);
fListener.SendMessage(&update);
}
return B_OK;
}
status_t
Settings::GetNextInterface(uint32& cookie, BMessage& interface)
{

View File

@ -11,6 +11,7 @@
#include <driver_settings.h>
#include <Message.h>
#include <Messenger.h>
class BPath;
@ -28,6 +29,10 @@ class Settings {
~Settings();
status_t GetNextInterface(uint32& cookie, BMessage& interface);
status_t StartMonitoring(const BMessenger& target);
status_t StopMonitoring(const BMessenger& target);
status_t Update(BMessage* message);
private:
status_t _Load();
@ -42,8 +47,11 @@ class Settings {
status_t _ConvertFromDriverSettings(const char* path,
const settings_template* settingsTemplate, BMessage& message);
BMessenger fListener;
BMessage fInterfaces;
bool fUpdated;
};
static const uint32 kMsgInterfaceSettingsUpdated = 'SUif';
#endif // SETTINGS_H