* 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:
parent
535df2cff3
commit
b01a3a33a6
@ -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");
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user