* 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:
@@ -13,6 +13,7 @@
|
|||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ class NetServer : public BApplication {
|
|||||||
|
|
||||||
virtual void AboutRequested();
|
virtual void AboutRequested();
|
||||||
virtual void ReadyToRun();
|
virtual void ReadyToRun();
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _PrepareRequest(ifreq& request, const char* name);
|
bool _PrepareRequest(ifreq& request, const char* name);
|
||||||
@@ -44,6 +46,7 @@ class NetServer : public BApplication {
|
|||||||
status_t _ConfigureInterface(int socket, BMessage& interface);
|
status_t _ConfigureInterface(int socket, BMessage& interface);
|
||||||
status_t _ConfigureDevice(int socket, const char* path);
|
status_t _ConfigureDevice(int socket, const char* path);
|
||||||
void _ConfigureDevices(int socket, const char* path);
|
void _ConfigureDevices(int socket, const char* path);
|
||||||
|
void _ConfigureInterfaces(int socket);
|
||||||
void _BringUpInterfaces();
|
void _BringUpInterfaces();
|
||||||
|
|
||||||
Settings fSettings;
|
Settings fSettings;
|
||||||
@@ -153,10 +156,38 @@ NetServer::AboutRequested()
|
|||||||
void
|
void
|
||||||
NetServer::ReadyToRun()
|
NetServer::ReadyToRun()
|
||||||
{
|
{
|
||||||
|
fSettings.StartMonitoring(this);
|
||||||
_BringUpInterfaces();
|
_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
|
bool
|
||||||
NetServer::_PrepareRequest(ifreq& request, const char* name)
|
NetServer::_PrepareRequest(ifreq& request, const char* name)
|
||||||
{
|
{
|
||||||
@@ -304,10 +335,13 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface)
|
|||||||
&& parse_address(familyIndex, string, gateway)) {
|
&& parse_address(familyIndex, string, gateway)) {
|
||||||
route_entry route;
|
route_entry route;
|
||||||
memset(&route, 0, sizeof(route_entry));
|
memset(&route, 0, sizeof(route_entry));
|
||||||
route.gateway = &gateway;
|
|
||||||
route.flags = RTF_STATIC | RTF_DEFAULT | RTF_GATEWAY;
|
route.flags = RTF_STATIC | RTF_DEFAULT | RTF_GATEWAY;
|
||||||
|
route.gateway = &gateway;
|
||||||
|
|
||||||
request.ifr_route = route;
|
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) {
|
if (ioctl(socket, SIOCADDRT, &request, sizeof(request)) < 0) {
|
||||||
fprintf(stderr, "%s: Could not add route for %s: %s\n",
|
fprintf(stderr, "%s: Could not add route for %s: %s\n",
|
||||||
@@ -465,19 +499,8 @@ NetServer::_ConfigureDevices(int socket, const char* startPath)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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;
|
BMessage interface;
|
||||||
uint32 cookie = 0;
|
uint32 cookie = 0;
|
||||||
while (fSettings.GetNextInterface(cookie, interface) == B_OK) {
|
while (fSettings.GetNextInterface(cookie, interface) == B_OK) {
|
||||||
@@ -492,16 +515,32 @@ NetServer::_BringUpInterfaces()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to bring the interface up
|
|
||||||
|
|
||||||
_ConfigureInterface(socket, interface);
|
_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
|
// check configuration
|
||||||
|
|
||||||
if (!_TestForInterface(socket, "loop")) {
|
if (!_TestForInterface(socket, "loop")) {
|
||||||
// there is no loopback interface, create one
|
// there is no loopback interface, create one
|
||||||
interface.MakeEmpty();
|
BMessage interface;
|
||||||
interface.AddString("device", "loop");
|
interface.AddString("device", "loop");
|
||||||
BMessage address;
|
BMessage address;
|
||||||
address.AddString("family", "inet");
|
address.AddString("family", "inet");
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -23,6 +25,7 @@ const static settings_template kInterfaceAddressTemplate[] = {
|
|||||||
{B_STRING_TYPE, "mask", NULL},
|
{B_STRING_TYPE, "mask", NULL},
|
||||||
{B_STRING_TYPE, "peer", NULL},
|
{B_STRING_TYPE, "peer", NULL},
|
||||||
{B_STRING_TYPE, "broadcast", NULL},
|
{B_STRING_TYPE, "broadcast", NULL},
|
||||||
|
{B_STRING_TYPE, "gateway", NULL},
|
||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,12 +69,13 @@ Settings::~Settings()
|
|||||||
status_t
|
status_t
|
||||||
Settings::_GetPath(const char* name, BPath& path)
|
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;
|
return B_ERROR;
|
||||||
|
|
||||||
path.Append("network");
|
path.Append("network");
|
||||||
path.Append(name);
|
create_directory(path.Path(), 0755);
|
||||||
|
|
||||||
|
path.Append(name);
|
||||||
return B_OK;
|
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
|
status_t
|
||||||
Settings::GetNextInterface(uint32& cookie, BMessage& interface)
|
Settings::GetNextInterface(uint32& cookie, BMessage& interface)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
|
||||||
class BPath;
|
class BPath;
|
||||||
|
|
||||||
@@ -28,6 +29,10 @@ class Settings {
|
|||||||
~Settings();
|
~Settings();
|
||||||
|
|
||||||
status_t GetNextInterface(uint32& cookie, BMessage& interface);
|
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:
|
private:
|
||||||
status_t _Load();
|
status_t _Load();
|
||||||
@@ -42,8 +47,11 @@ class Settings {
|
|||||||
status_t _ConvertFromDriverSettings(const char* path,
|
status_t _ConvertFromDriverSettings(const char* path,
|
||||||
const settings_template* settingsTemplate, BMessage& message);
|
const settings_template* settingsTemplate, BMessage& message);
|
||||||
|
|
||||||
|
BMessenger fListener;
|
||||||
BMessage fInterfaces;
|
BMessage fInterfaces;
|
||||||
bool fUpdated;
|
bool fUpdated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint32 kMsgInterfaceSettingsUpdated = 'SUif';
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|||||||
Reference in New Issue
Block a user