[haiku-commits] BRANCH axeld-github.network-preferences [557c74fbfc68] src/servers/net src/kits/network/libnetapi headers/os/add-ons/network_settings src/preferences/network src/add-ons/network_settings/ipv4

  • From: axeld-github.network-preferences <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 26 Feb 2015 23:16:36 +0100 (CET)

added 2 changesets to branch 'refs/remotes/axeld-github/network-preferences'
old head: 3c89e7f782bcf786adc08dc9ebd974ece0364182
new head: 557c74fbfc685880a6657774fff7e9ec2822248e
overview: https://github.com/axeld/haiku/compare/3c89e7f782bc...557c74fbfc68

----------------------------------------------------------------------------

9ae216885e29: Moved more functionality from net_server to NetworkSettings.
  
  * Added (still incomplete) helper classes for the settings messages.
  * The net_server now uses these classes for its interfaces, and services.
  * Renamed service_address to service_connection, as that better matches
    what it is used for.

557c74fbfc68: Network: broadcast updates, remove apply button.
  
  * Network now monitors all network, and network settings changes, and
    will notify all add-ons about those changes.
  * Removed the global apply button. Instead, the static IP configuration
    now got that button. All other changes will be instant.

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

13 files changed, 823 insertions(+), 425 deletions(-)
.../add-ons/network_settings/NetworkSettings.h   | 107 +++++
.../network_settings/NetworkSettingsAddOn.h      |   8 +-
.../network_settings/ipv4/IPv4InterfaceAddOn.cpp |  18 +-
.../ipv4/InterfaceAddressView.cpp                |  84 +++-
.../network_settings/ipv4/InterfaceAddressView.h |   6 +
src/kits/network/libnetapi/NetworkSettings.cpp   | 466 ++++++++++++++++++-
src/preferences/network/NetworkSettingsAddOn.cpp |  12 +
src/preferences/network/NetworkWindow.cpp        |  52 ++-
src/preferences/network/NetworkWindow.h          |   4 +-
src/servers/net/NetServer.cpp                    | 149 +-----
src/servers/net/NetServer.h                      |  25 -
src/servers/net/Services.cpp                     | 311 ++++---------
src/servers/net/Services.h                       |   6 +-

############################################################################

Commit:      9ae216885e297e6f36ee58d16ada49b3f064d9c0
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Feb 26 12:05:21 2015 UTC

Moved more functionality from net_server to NetworkSettings.

* Added (still incomplete) helper classes for the settings messages.
* The net_server now uses these classes for its interfaces, and services.
* Renamed service_address to service_connection, as that better matches
  what it is used for.

----------------------------------------------------------------------------

diff --git a/headers/os/add-ons/network_settings/NetworkSettings.h 
b/headers/os/add-ons/network_settings/NetworkSettings.h
index 6f68393..7105241 100644
--- a/headers/os/add-ons/network_settings/NetworkSettings.h
+++ b/headers/os/add-ons/network_settings/NetworkSettings.h
@@ -9,9 +9,13 @@
 #define SETTINGS_H
 
 
+#include <vector>
+
 #include <Message.h>
 #include <Messenger.h>
+#include <NetworkAddress.h>
 #include <Path.h>
+#include <StringList.h>
 
 
 namespace BNetworkKit {
@@ -20,6 +24,7 @@ namespace BNetworkKit {
 class BNetworkSettings {
 public:
        static  const uint32            kMsgInterfaceSettingsUpdated = 'SUif';
+       static  const uint32            kMsgNetworkSettingsUpdated = 'SUnw';
        static  const uint32            kMsgServiceSettingsUpdated = 'SUsv';
 
 public:
@@ -88,7 +93,109 @@ private:
 };
 
 
+class BNetworkInterfaceAddressSettings {
+public:
+                                                               
BNetworkInterfaceAddressSettings(
+                                                                       const 
BMessage& data);
+                                                               
~BNetworkInterfaceAddressSettings();
+
+                       int                                     Family() const;
+                       bool                            AutoConfigure() const;
+
+                       const BNetworkAddress&
+                                                               Address() const;
+                       const BNetworkAddress&
+                                                               Mask() const;
+                       const BNetworkAddress&
+                                                               Peer() const;
+                       const BNetworkAddress&
+                                                               Broadcast() 
const;
+                       const BNetworkAddress&
+                                                               Gateway() const;
+
+private:
+                       int32                           fFamily;
+                       bool                            fAutoConfigure;
+                       BNetworkAddress         fAddress;
+                       BNetworkAddress         fMask;
+                       BNetworkAddress         fPeer;
+                       BNetworkAddress         fBroadcast;
+                       BNetworkAddress         fGateway;
+};
+
+
+class BNetworkInterfaceSettings {
+public:
+                                                               
BNetworkInterfaceSettings(
+                                                                       const 
BMessage& message);
+                                                               
~BNetworkInterfaceSettings();
+
+                       const char*                     Name() const;
+
+};
+
+
 }      // namespace BNetworkKit
 
 
+class BNetworkServiceAddressSettings {
+public:
+                                                               
BNetworkServiceAddressSettings();
+                                                               
BNetworkServiceAddressSettings(
+                                                                       const 
BMessage& data, int family = -1,
+                                                                       int 
type = -1, int protocol = -1,
+                                                                       int 
port = -1);
+                                                               
~BNetworkServiceAddressSettings();
+
+                       int                                     Family() const;
+                       void                            SetFamily(int family);
+                       int                                     Protocol() 
const;
+                       void                            SetProtocol(int 
protocol);
+                       int                                     Type() const;
+                       void                            SetType(int type);
+
+                       const BNetworkAddress&
+                                                               Address() const;
+                       BNetworkAddress&        Address();
+
+                       status_t                        GetMessage(BMessage& 
data);
+
+                       bool                            operator==(
+                                                                       const 
BNetworkServiceAddressSettings& other)
+                                                                               
const;
+
+private:
+                       int32                           fFamily;
+                       int                                     fProtocol;
+                       int                                     fType;
+                       BNetworkAddress         fAddress;
+};
+
+
+class BNetworkServiceSettings {
+public:
+                                                               
BNetworkServiceSettings(
+                                                                       const 
BMessage& message);
+                                                               
~BNetworkServiceSettings();
+
+                       status_t                        InitCheck() const;
+
+                       const char*                     Name() const;
+                       bool                            IsStandAlone() const;
+
+                       int32                           CountArguments() const;
+                       const char*                     ArgumentAt(int32 index) 
const;
+
+                       int32                           CountAddresses() const;
+                       const BNetworkServiceAddressSettings&
+                                                               AddressAt(int32 
index) const;
+
+private:
+                       const BMessage&         fData;
+                       BStringList                     fArguments;
+                       std::vector<BNetworkServiceAddressSettings>
+                                                               fAddresses;
+};
+
+
 #endif // SETTINGS_H
diff --git a/src/kits/network/libnetapi/NetworkSettings.cpp 
b/src/kits/network/libnetapi/NetworkSettings.cpp
index fc5fd05..87eed54 100644
--- a/src/kits/network/libnetapi/NetworkSettings.cpp
+++ b/src/kits/network/libnetapi/NetworkSettings.cpp
@@ -9,6 +9,7 @@
 
 #include <NetworkSettings.h>
 
+#include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -115,6 +116,119 @@ const static settings_template kServicesTemplate[] = {
 };
 
 
+struct address_family {
+       int                     family;
+       const char*     name;
+       const char*     identifiers[4];
+};
+
+
+static const address_family kFamilies[] = {
+       {
+               AF_INET,
+               "inet",
+               {"AF_INET", "inet", "ipv4", NULL},
+       },
+       {
+               AF_INET6,
+               "inet6",
+               {"AF_INET6", "inet6", "ipv6", NULL},
+       },
+       { -1, NULL, {NULL} }
+};
+
+
+static int
+get_address_family(const char* argument)
+{
+       for (int32 i = 0; kFamilies[i].family >= 0; i++) {
+               for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
+                       if (!strcmp(argument, kFamilies[i].identifiers[j])) {
+                               // found a match
+                               return kFamilies[i].family;
+                       }
+               }
+       }
+
+       return AF_UNSPEC;
+}
+
+
+/*!    Parses the \a argument as network \a address for the specified \a 
family.
+       If \a family is \c AF_UNSPEC, \a family will be overwritten with the 
family
+       of the successfully parsed address.
+*/
+static bool
+parse_address(int32& family, const char* argument, BNetworkAddress& address)
+{
+       if (argument == NULL)
+               return false;
+
+       status_t status = address.SetTo(family, argument, (uint16)0,
+               B_NO_ADDRESS_RESOLUTION);
+       if (status != B_OK)
+               return false;
+
+       if (family == AF_UNSPEC) {
+               // Test if we support the resulting address family
+               bool supported = false;
+
+               for (int32 i = 0; kFamilies[i].family >= 0; i++) {
+                       if (kFamilies[i].family == address.Family()) {
+                               supported = true;
+                               break;
+                       }
+               }
+               if (!supported)
+                       return false;
+
+               // Take over family from address
+               family = address.Family();
+       }
+
+       return true;
+}
+
+
+static int
+parse_type(const char* string)
+{
+       if (!strcasecmp(string, "stream"))
+               return SOCK_STREAM;
+
+       return SOCK_DGRAM;
+}
+
+
+static int
+parse_protocol(const char* string)
+{
+       struct protoent* proto = getprotobyname(string);
+       if (proto == NULL)
+               return IPPROTO_TCP;
+
+       return proto->p_proto;
+}
+
+
+static int
+type_for_protocol(int protocol)
+{
+       // default determined by protocol
+       switch (protocol) {
+               case IPPROTO_TCP:
+                       return SOCK_STREAM;
+
+               case IPPROTO_UDP:
+               default:
+                       return SOCK_DGRAM;
+       }
+}
+
+
+// #pragma mark -
+
+
 BNetworkSettings::BNetworkSettings()
 {
        _Load();
@@ -384,7 +498,7 @@ BNetworkSettings::_Load(const char* name, uint32* _type)
                        }
 
                        if (_type != NULL)
-                               *_type = kMsgInterfaceSettingsUpdated;
+                               *_type = kMsgNetworkSettingsUpdated;
                }
        }
        if (name == NULL || strcmp(name, kServicesSettingsName) == 0) {
@@ -672,3 +786,353 @@ BNetworkSettings::_RemoveItem(BMessage& container, const 
char* itemField,
 
        return B_ENTRY_NOT_FOUND;
 }
+
+
+// #pragma mark - BNetworkInterfaceAddressSettings
+
+
+BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings(
+       const BMessage& data)
+{
+       if (data.FindInt32("family", &fFamily) != B_OK) {
+               const char* familyString;
+               if (data.FindString("family", &familyString) == B_OK) {
+                       fFamily = get_address_family(familyString);
+                       if (fFamily == AF_UNSPEC) {
+                               // we don't support this family
+                               fprintf(stderr, "Ignore unknown family: %s\n",
+                                       familyString);
+                               return;
+                       }
+               } else
+                       fFamily = AF_UNSPEC;
+       }
+
+       fAutoConfigure = data.GetBool("auto_config", false);
+
+       if (!fAutoConfigure) {
+               if (parse_address(fFamily, data.GetString("address", NULL), 
fAddress))
+                       parse_address(fFamily, data.GetString("mask", NULL), 
fMask);
+
+               parse_address(fFamily, data.GetString("peer", NULL), fPeer);
+               parse_address(fFamily, data.GetString("broadcast", NULL), 
fBroadcast);
+               parse_address(fFamily, data.GetString("gateway", NULL), 
fGateway);
+       }
+}
+
+
+BNetworkInterfaceAddressSettings::~BNetworkInterfaceAddressSettings()
+{
+}
+
+
+int
+BNetworkInterfaceAddressSettings::Family() const
+{
+       return fFamily;
+}
+
+
+bool
+BNetworkInterfaceAddressSettings::AutoConfigure() const
+{
+       return fAutoConfigure;
+}
+
+
+const BNetworkAddress&
+BNetworkInterfaceAddressSettings::Address() const
+{
+       return fAddress;
+}
+
+
+const BNetworkAddress&
+BNetworkInterfaceAddressSettings::Mask() const
+{
+       return fMask;
+}
+
+
+const BNetworkAddress&
+BNetworkInterfaceAddressSettings::Peer() const
+{
+       return fPeer;
+}
+
+
+const BNetworkAddress&
+BNetworkInterfaceAddressSettings::Broadcast() const
+{
+       return fBroadcast;
+}
+
+
+const BNetworkAddress&
+BNetworkInterfaceAddressSettings::Gateway() const
+{
+       return fGateway;
+}
+
+
+// #pragma mark - BNetworkServiceAddress
+
+
+BNetworkServiceAddressSettings::BNetworkServiceAddressSettings()
+{
+}
+
+
+BNetworkServiceAddressSettings::BNetworkServiceAddressSettings(
+       const BMessage& data, int serviceFamily, int serviceType,
+       int serviceProtocol, int servicePort)
+{
+       // TODO: dump problems in the settings to syslog
+       if (data.FindInt32("family", &fFamily) != B_OK) {
+               const char* familyString;
+               if (data.FindString("family", &familyString) == B_OK) {
+                       fFamily = get_address_family(familyString);
+                       if (fFamily == AF_UNSPEC) {
+                               // we don't support this family
+                               fprintf(stderr, "Ignore unknown family: %s\n",
+                                       familyString);
+                               return;
+                       }
+               } else
+                       fFamily = serviceFamily;
+       }
+
+       if (!parse_address(fFamily, data.GetString("address"), fAddress))
+               fAddress.SetToWildcard(fFamily);
+
+       const char* string;
+       if (data.FindString("protocol", &string) == B_OK)
+               fProtocol = parse_protocol(string);
+       else
+               fProtocol = serviceProtocol;
+
+       if (data.FindString("type", &string) == B_OK)
+               fType = parse_type(string);
+       else if (fProtocol != serviceProtocol)
+               fType = type_for_protocol(fProtocol);
+       else
+               fType = serviceType;
+
+       fAddress.SetPort(data.GetInt32("port", servicePort));
+}
+
+
+BNetworkServiceAddressSettings::~BNetworkServiceAddressSettings()
+{
+}
+
+
+int
+BNetworkServiceAddressSettings::Family() const
+{
+       return fFamily;
+}
+
+
+void
+BNetworkServiceAddressSettings::SetFamily(int family)
+{
+       fFamily = family;
+}
+
+
+int
+BNetworkServiceAddressSettings::Protocol() const
+{
+       return fProtocol;
+}
+
+
+void
+BNetworkServiceAddressSettings::SetProtocol(int protocol)
+{
+       fProtocol = protocol;
+}
+
+
+int
+BNetworkServiceAddressSettings::Type() const
+{
+       return fType;
+}
+
+
+void
+BNetworkServiceAddressSettings::SetType(int type)
+{
+       fType = type;
+}
+
+
+const BNetworkAddress&
+BNetworkServiceAddressSettings::Address() const
+{
+       return fAddress;
+}
+
+
+BNetworkAddress&
+BNetworkServiceAddressSettings::Address()
+{
+       return fAddress;
+}
+
+
+status_t
+BNetworkServiceAddressSettings::GetMessage(BMessage& data)
+{
+       // TODO!
+       return B_NOT_SUPPORTED;
+}
+
+
+bool
+BNetworkServiceAddressSettings::operator==(
+       const BNetworkServiceAddressSettings& other) const
+{
+       return Family() == other.Family()
+               && Type() == other.Type()
+               && Protocol() == other.Protocol()
+               && Address() == other.Address();
+}
+
+
+// #pragma mark - BNetworkServiceSettings
+
+
+BNetworkServiceSettings::BNetworkServiceSettings(const BMessage& message)
+       :
+       fData(message)
+{
+       // TODO: user/group is currently ignored!
+
+       // Default family/port/protocol/type for all addresses
+
+       // we default to inet/tcp/port-from-service-name if nothing is specified
+       const char* string;
+       if (message.FindString("family", &string) != B_OK)
+               string = "inet";
+
+       int32 serviceFamily = get_address_family(string);
+       if (serviceFamily == AF_UNSPEC)
+               serviceFamily = AF_INET;
+
+       int32 serviceProtocol;
+       if (message.FindString("protocol", &string) == B_OK)
+               serviceProtocol = parse_protocol(string);
+       else {
+               string = "tcp";
+                       // we set 'string' here for an eventual call to 
getservbyname()
+                       // below
+               serviceProtocol = IPPROTO_TCP;
+       }
+
+       int32 servicePort;
+       if (message.FindInt32("port", &servicePort) != B_OK) {
+               struct servent* servent = getservbyname(Name(), string);
+               if (servent != NULL)
+                       servicePort = ntohs(servent->s_port);
+               else
+                       servicePort = -1;
+       }
+
+       int32 serviceType = -1;
+       if (message.FindString("type", &string) == B_OK) {
+               serviceType = parse_type(string);
+       } else {
+               serviceType = type_for_protocol(serviceProtocol);
+       }
+
+       const char* argument;
+       for (int i = 0; message.FindString("launch", i, &argument) == B_OK; 
i++) {
+               fArguments.Add(argument);
+       }
+
+       BMessage addressData;
+       int32 i = 0;
+       for (; message.FindMessage("address", i, &addressData) == B_OK; i++) {
+               BNetworkServiceAddressSettings address(addressData, 
serviceFamily,
+                       serviceType, serviceProtocol, servicePort);
+               fAddresses.push_back(address);
+       }
+
+       if (i == 0 && (serviceFamily < 0 || servicePort < 0)) {
+               // no address specified
+               printf("service %s has no address specified\n", Name());
+               return;
+       }
+
+       if (i == 0) {
+               // no address specified, but family/port were given; add empty 
address
+               BNetworkServiceAddressSettings address;
+               address.SetFamily(serviceFamily);
+               address.SetType(serviceType);
+               address.SetProtocol(serviceProtocol);
+               address.Address().SetToWildcard(serviceFamily, servicePort);
+
+               fAddresses.push_back(address);
+       }
+}
+
+
+BNetworkServiceSettings::~BNetworkServiceSettings()
+{
+}
+
+
+status_t
+BNetworkServiceSettings::InitCheck() const
+{
+       if (fData.HasString("name") && fData.HasString("launch")
+               && CountAddresses() > 0)
+               return B_OK;
+
+       return B_BAD_VALUE;
+}
+
+
+const char*
+BNetworkServiceSettings::Name() const
+{
+       return fData.GetString("name");
+}
+
+
+bool
+BNetworkServiceSettings::IsStandAlone() const
+{
+       return fData.GetBool("stand_alone");
+}
+
+
+int32
+BNetworkServiceSettings::CountArguments() const
+{
+       return fArguments.CountStrings();
+}
+
+
+const char*
+BNetworkServiceSettings::ArgumentAt(int32 index) const
+{
+       return fArguments.StringAt(index);
+}
+
+
+int32
+BNetworkServiceSettings::CountAddresses() const
+{
+       return fAddresses.size();
+}
+
+
+const BNetworkServiceAddressSettings&
+BNetworkServiceSettings::AddressAt(int32 index) const
+{
+       return fAddresses[index];
+}
diff --git a/src/servers/net/NetServer.cpp b/src/servers/net/NetServer.cpp
index f7bf6e5..06ed2ad 100644
--- a/src/servers/net/NetServer.cpp
+++ b/src/servers/net/NetServer.cpp
@@ -107,28 +107,6 @@ private:
 };
 
 
-struct address_family {
-       int                     family;
-       const char*     name;
-       const char*     identifiers[4];
-};
-
-
-static const address_family kFamilies[] = {
-       {
-               AF_INET,
-               "inet",
-               {"AF_INET", "inet", "ipv4", NULL},
-       },
-       {
-               AF_INET6,
-               "inet6",
-               {"AF_INET6", "inet6", "ipv6", NULL},
-       },
-       { -1, NULL, {NULL} }
-};
-
-
 // #pragma mark - private functions
 
 
@@ -156,61 +134,6 @@ set_80211(const char* name, int32 type, void* data,
 }
 
 
-// #pragma mark - exported functions
-
-
-int
-get_address_family(const char* argument)
-{
-       for (int32 i = 0; kFamilies[i].family >= 0; i++) {
-               for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
-                       if (!strcmp(argument, kFamilies[i].identifiers[j])) {
-                               // found a match
-                               return kFamilies[i].family;
-                       }
-               }
-       }
-
-       return AF_UNSPEC;
-}
-
-
-/*!    Parses the \a argument as network \a address for the specified \a 
family.
-       If \a family is \c AF_UNSPEC, \a family will be overwritten with the 
family
-       of the successfully parsed address.
-*/
-bool
-parse_address(int32& family, const char* argument, BNetworkAddress& address)
-{
-       if (argument == NULL)
-               return false;
-
-       status_t status = address.SetTo(family, argument, (uint16)0,
-               B_NO_ADDRESS_RESOLUTION);
-       if (status != B_OK)
-               return false;
-
-       if (family == AF_UNSPEC) {
-               // Test if we support the resulting address family
-               bool supported = false;
-
-               for (int32 i = 0; kFamilies[i].family >= 0; i++) {
-                       if (kFamilies[i].family == address.Family()) {
-                               supported = true;
-                               break;
-                       }
-               }
-               if (!supported)
-                       return false;
-
-               // Take over family from address
-               family = address.Family();
-       }
-
-       return true;
-}
-
-
 //     #pragma mark -
 
 
@@ -254,7 +177,7 @@ NetServer::ReadyToRun()
        _BringUpInterfaces();
        _StartServices();
 
-       BPrivate::BPathMonitor::StartWatching("/dev/net", 
+       BPrivate::BPathMonitor::StartWatching("/dev/net",
                B_WATCH_FILES_ONLY | B_WATCH_RECURSIVELY, this);
 }
 
@@ -548,60 +471,19 @@ NetServer::_ConfigureInterface(BMessage& message)
        BMessage addressMessage;
        for (int32 index = 0; message.FindMessage("address", index,
                        &addressMessage) == B_OK; index++) {
-               int32 family;
-               if (addressMessage.FindInt32("family", &family) != B_OK) {
-                       const char* familyString;
-                       if (addressMessage.FindString("family", &familyString) 
== B_OK) {
-                               if (get_address_family(familyString) == 
AF_UNSPEC) {
-                                       // we don't support this family
-                                       fprintf(stderr, "%s: Ignore unknown 
family: %s\n", Name(),
-                                               familyString);
-                                       continue;
-                               }
-                       } else
-                               family = AF_UNSPEC;
-               }
-
-               // retrieve addresses
-
-               bool autoConfig;
-               if (addressMessage.FindBool("auto_config", &autoConfig) != B_OK)
-                       autoConfig = false;
-
-               BNetworkAddress address;
-               BNetworkAddress mask;
-               BNetworkAddress broadcast;
-               BNetworkAddress peer;
-               BNetworkAddress gateway;
-
-               const char* string;
-
-               if (!autoConfig) {
-                       if (addressMessage.FindString("address", &string) == 
B_OK) {
-                               parse_address(family, string, address);
-
-                               if (addressMessage.FindString("mask", &string) 
== B_OK)
-                                       parse_address(family, string, mask);
-                       }
-
-                       if (addressMessage.FindString("peer", &string) == B_OK)
-                               parse_address(family, string, peer);
-
-                       if (addressMessage.FindString("broadcast", &string) == 
B_OK)
-                               parse_address(family, string, broadcast);
-               }
+               BNetworkInterfaceAddressSettings 
addressSettings(addressMessage);
 
-               if (autoConfig) {
+               if (addressSettings.AutoConfigure()) {
                        _QuitLooperForDevice(name);
                        startAutoConfig = true;
-               } else if (addressMessage.FindString("gateway", &string) == B_OK
-                       && parse_address(family, string, gateway)) {
+               } else if (!addressSettings.Gateway().IsEmpty()) {
                        // add gateway route, if we're asked for it
-                       interface.RemoveDefaultRoute(family);
+                       interface.RemoveDefaultRoute(addressSettings.Family());
                                // Try to remove a previous default route, 
doesn't matter
                                // if it fails.
 
-                       status_t status = interface.AddDefaultRoute(gateway);
+                       status_t status = interface.AddDefaultRoute(
+                               addressSettings.Gateway());
                        if (status != B_OK) {
                                fprintf(stderr, "%s: Could not add route for 
%s: %s\n",
                                        Name(), name, strerror(errno));
@@ -610,14 +492,17 @@ NetServer::_ConfigureInterface(BMessage& message)
 
                // set address/mask/broadcast/peer
 
-               if (!address.IsEmpty() || !mask.IsEmpty() || 
!broadcast.IsEmpty()) {
+               if (!addressSettings.Address().IsEmpty()
+                       || !addressSettings.Mask().IsEmpty()
+                       || !addressSettings.Broadcast().IsEmpty()
+                       || !addressSettings.Peer().IsEmpty()) {
                        BNetworkInterfaceAddress interfaceAddress;
-                       interfaceAddress.SetAddress(address);
-                       interfaceAddress.SetMask(mask);
-                       if (!broadcast.IsEmpty())
-                               interfaceAddress.SetBroadcast(broadcast);
-                       else if (!peer.IsEmpty())
-                               interfaceAddress.SetDestination(peer);
+                       interfaceAddress.SetAddress(addressSettings.Address());
+                       interfaceAddress.SetMask(addressSettings.Mask());
+                       if (!addressSettings.Broadcast().IsEmpty())
+                               
interfaceAddress.SetBroadcast(addressSettings.Broadcast());
+                       else if (!addressSettings.Peer().IsEmpty())
+                               
interfaceAddress.SetDestination(addressSettings.Peer());
 
                        status_t status = 
interface.SetAddress(interfaceAddress);
                        if (status != B_OK) {
diff --git a/src/servers/net/NetServer.h b/src/servers/net/NetServer.h
deleted file mode 100644
index 44282fd..0000000
--- a/src/servers/net/NetServer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
- * Distributed under the terms of the MIT License.
- *
- * Authors:
- *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
- */
-#ifndef NET_SERVER_H
-#define NET_SERVER_H
-
-
-#include <SupportDefs.h>
-
-#include <NetServer.h>
-
-
-class BNetworkAddress;
-
-
-int get_address_family(const char* argument);
-bool parse_address(int32& family, const char* argument,
-       BNetworkAddress& address);
-
-
-#endif // NET_SERVER_H
diff --git a/src/servers/net/Services.cpp b/src/servers/net/Services.cpp
index 1ccc956..db1f18b 100644
--- a/src/servers/net/Services.cpp
+++ b/src/servers/net/Services.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -8,47 +8,51 @@
 
 
 #include "Services.h"
-#include "NetServer.h"
-#include "Settings.h"
 
-#include <Autolock.h>
-#include <NetworkAddress.h>
+#include <new>
+//#include <vector>
 
 #include <errno.h>
-#include <netdb.h>
 #include <netinet/in.h>
-#include <new>
 #include <stdlib.h>
 #include <strings.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
-#include <vector>
+
+#include <Autolock.h>
+#include <NetworkAddress.h>
+#include <NetworkSettings.h>
+
 
 using namespace std;
 
-struct service_address {
+struct service_connection {
        struct service* owner;
        int             socket;
-       int             family;
-       int             type;
-       int             protocol;
-       BNetworkAddress address;
+       BNetworkServiceAddressSettings address;
 
-       bool operator==(const struct service_address& other) const;
+       //service_connection() : owner(NULL), socket(-1) {}
+
+       int Family() const { return address.Family(); }
+       int Protocol() const { return address.Protocol(); }
+       int Type() const { return address.Type(); }
+       const BNetworkAddress& Address() const { return address.Address(); }
+
+       bool operator==(const struct service_connection& other) const;
 };
 
-typedef std::vector<service_address> AddressList;
+typedef std::vector<service_connection> ConnectionList;
 typedef std::vector<std::string> StringList;
 
 struct service {
-       std::string     name;
-       StringList      arguments;
-       uid_t           user;
-       gid_t           group;
-       AddressList     addresses;
-       uint32          update;
-       bool            stand_alone;
-       pid_t           process;
+       std::string             name;
+       StringList              arguments;
+       uid_t                   user;
+       gid_t                   group;
+       ConnectionList  connections;
+       uint32                  update;
+       bool                    stand_alone;
+       pid_t                   process;
 
        ~service();
        bool operator!=(const struct service& other) const;
@@ -56,52 +60,13 @@ struct service {
 };
 
 
-int
-parse_type(const char* string)
-{
-       if (!strcasecmp(string, "stream"))
-               return SOCK_STREAM;
-
-       return SOCK_DGRAM;
-}
-
-
-int
-parse_protocol(const char* string)
-{
-       struct protoent* proto = getprotobyname(string);
-       if (proto == NULL)
-               return IPPROTO_TCP;
-
-       return proto->p_proto;
-}
-
-
-int
-type_for_protocol(int protocol)
-{
-       // default determined by protocol
-       switch (protocol) {
-               case IPPROTO_TCP:
-                       return SOCK_STREAM;
-
-               case IPPROTO_UDP:
-               default:
-                       return SOCK_DGRAM;
-       }
-}
-
-
 //     #pragma mark -
 
 
 bool
-service_address::operator==(const struct service_address& other) const
+service_connection::operator==(const struct service_connection& other) const
 {
-       return family == other.family
-               && type == other.type
-               && protocol == other.protocol
-               && address == other.address;
+       return address == other.address;
 }
 
 
@@ -111,11 +76,11 @@ service_address::operator==(const struct service_address& 
other) const
 service::~service()
 {
        // close all open sockets
-       AddressList::const_iterator iterator = addresses.begin();
-       for (; iterator != addresses.end(); iterator++) {
-               const service_address& address = *iterator;
+       ConnectionList::const_iterator iterator = connections.begin();
+       for (; iterator != connections.end(); iterator++) {
+               const service_connection& connection = *iterator;
 
-               close(address.socket);
+               close(connection.socket);
        }
 }
 
@@ -132,32 +97,33 @@ service::operator==(const struct service& other) const
 {
        if (name != other.name
                || arguments.size() != other.arguments.size()
-               || addresses.size() != other.addresses.size()
+               || connections.size() != other.connections.size()
                || stand_alone != other.stand_alone)
                return false;
 
-       // compare arguments
+       // Compare arguments
 
        for(size_t i = 0; i < arguments.size(); i++) {
                if (arguments[i] != other.arguments[i])
                        return false;
        }
 
-       // compare addresses
+       // Compare connections
 
-       AddressList::const_iterator iterator = addresses.begin();
-       for (; iterator != addresses.end(); iterator++) {
-               const service_address& address = *iterator;
+       ConnectionList::const_iterator iterator = connections.begin();
+       for (; iterator != connections.end(); iterator++) {
+               const service_connection& connection = *iterator;
 
-               // find address in other addresses
+               // Find address in other addresses
 
-               AddressList::const_iterator otherIterator = 
other.addresses.begin();
-               for (; otherIterator != other.addresses.end(); otherIterator++) 
{
-                       if (address == *otherIterator)
+               ConnectionList::const_iterator otherIterator
+                       = other.connections.begin();
+               for (; otherIterator != other.connections.end(); 
otherIterator++) {
+                       if (connection == *otherIterator)
                                break;
                }
 
-               if (otherIterator == other.addresses.end())
+               if (otherIterator == other.connections.end())
                        return false;
        }
 
@@ -268,20 +234,22 @@ Services::_StartService(struct service& service)
        // create socket
 
        bool failed = false;
-       AddressList::iterator iterator = service.addresses.begin();
-       for (; iterator != service.addresses.end(); iterator++) {
-               service_address& address = *iterator;
-
-               address.socket = socket(address.family, address.type, 
address.protocol);
-               if (address.socket < 0
-                       || bind(address.socket, address.address, 
address.address.Length())
-                                       < 0
-                       || fcntl(address.socket, F_SETFD, FD_CLOEXEC) < 0) {
+       ConnectionList::iterator iterator = service.connections.begin();
+       for (; iterator != service.connections.end(); iterator++) {
+               service_connection& connection = *iterator;
+
+               connection.socket = socket(connection.Family(),
+                       connection.Type(), connection.Protocol());
+               if (connection.socket < 0
+                       || bind(connection.socket, connection.Address(),
+                               connection.Address().Length()) < 0
+                       || fcntl(connection.socket, F_SETFD, FD_CLOEXEC) < 0) {
                        failed = true;
                        break;
                }
 
-               if (address.type == SOCK_STREAM && listen(address.socket, 50) < 
0) {
+               if (connection.Type() == SOCK_STREAM
+                       && listen(connection.socket, 50) < 0) {
                        failed = true;
                        break;
                }
@@ -297,13 +265,13 @@ Services::_StartService(struct service& service)
        fNameMap[service.name] = &service;
        service.update = fUpdate;
 
-       iterator = service.addresses.begin();
-       for (; iterator != service.addresses.end(); iterator++) {
-               service_address& address = *iterator;
+       iterator = service.connections.begin();
+       for (; iterator != service.connections.end(); iterator++) {
+               service_connection& connection = *iterator;
 
-               fSocketMap[address.socket] = &address;
-               _UpdateMinMaxSocket(address.socket);
-               FD_SET(address.socket, &fSet);
+               fSocketMap[connection.socket] = &connection;
+               _UpdateMinMaxSocket(connection.socket);
+               FD_SET(connection.socket, &fSet);
        }
 
        _NotifyListener();
@@ -325,17 +293,17 @@ Services::_StopService(struct service& service)
        }
 
        if (!service.stand_alone) {
-               AddressList::const_iterator iterator = 
service.addresses.begin();
-               for (; iterator != service.addresses.end(); iterator++) {
-                       const service_address& address = *iterator;
+               ConnectionList::const_iterator iterator = 
service.connections.begin();
+               for (; iterator != service.connections.end(); iterator++) {
+                       const service_connection& connection = *iterator;
 
                        ServiceSocketMap::iterator socketIterator
-                               = fSocketMap.find(address.socket);
+                               = fSocketMap.find(connection.socket);
                        if (socketIterator != fSocketMap.end())
                                fSocketMap.erase(socketIterator);
 
-                       close(address.socket);
-                       FD_CLR(address.socket, &fSet);
+                       close(connection.socket);
+                       FD_CLR(connection.socket, &fSet);
                }
        }
 
@@ -353,129 +321,32 @@ Services::_StopService(struct service& service)
 status_t
 Services::_ToService(const BMessage& message, struct service*& service)
 {
-       // get mandatory fields
-       const char* name;
-       if (message.FindString("name", &name) != B_OK
-               || !message.HasString("launch"))
-               return B_BAD_VALUE;
+       BNetworkServiceSettings settings(message);
+       status_t status = settings.InitCheck();
+       if (status != B_OK)
+               return status;
 
        service = new (std::nothrow) ::service;
        if (service == NULL)
                return B_NO_MEMORY;
 
-       service->name = name;
-
-       const char* argument;
-       for (int i = 0; message.FindString("launch", i, &argument) == B_OK; 
i++) {
-               service->arguments.push_back(argument);
-       }
-
-       service->stand_alone = false;
+       service->name = settings.Name();
+       service->stand_alone = settings.IsStandAlone();
        service->process = -1;
 
-       // TODO: user/group is currently ignored!
-
-       // Default family/port/protocol/type for all addresses
-
-       // we default to inet/tcp/port-from-service-name if nothing is specified
-       const char* string;
-       if (message.FindString("family", &string) != B_OK)
-               string = "inet";
-
-       int32 serviceFamily = get_address_family(string);
-       if (serviceFamily == AF_UNSPEC)
-               serviceFamily = AF_INET;
-
-       int32 serviceProtocol;
-       if (message.FindString("protocol", &string) == B_OK)
-               serviceProtocol = parse_protocol(string);
-       else {
-               string = "tcp";
-                       // we set 'string' here for an eventual call to 
getservbyname()
-                       // below
-               serviceProtocol = IPPROTO_TCP;
-       }
-
-       int32 servicePort;
-       if (message.FindInt32("port", &servicePort) != B_OK) {
-               struct servent* servent = getservbyname(name, string);
-               if (servent != NULL)
-                       servicePort = ntohs(servent->s_port);
-               else
-                       servicePort = -1;
-       }
-
-       int32 serviceType = -1;
-       if (message.FindString("type", &string) == B_OK) {
-               serviceType = parse_type(string);
-       } else {
-               serviceType = type_for_protocol(serviceProtocol);
-       }
-
-       bool standAlone = false;
-       if (message.FindBool("stand_alone", &standAlone) == B_OK)
-               service->stand_alone = standAlone;
-
-       BMessage address;
-       int32 i = 0;
-       for (; message.FindMessage("address", i, &address) == B_OK; i++) {
-               // TODO: dump problems in the settings to syslog
-               service_address serviceAddress;
-               if (address.FindString("family", &string) != B_OK)
-                       continue;
-
-               serviceAddress.family = get_address_family(string);
-               if (serviceAddress.family == AF_UNSPEC)
-                       continue;
-
-               if (address.FindString("protocol", &string) == B_OK)
-                       serviceAddress.protocol = parse_protocol(string);
-               else
-                       serviceAddress.protocol = serviceProtocol;
-
-               if (message.FindString("type", &string) == B_OK)
-                       serviceAddress.type = parse_type(string);
-               else if (serviceAddress.protocol != serviceProtocol)
-                       serviceAddress.type = 
type_for_protocol(serviceAddress.protocol);
-               else
-                       serviceAddress.type = serviceType;
-
-               if (address.FindString("address", &string) == B_OK) {
-                       if (!parse_address(serviceFamily, string, 
serviceAddress.address))
-                               continue;
-               } else
-                       serviceAddress.address.SetToWildcard(serviceFamily);
-
-               int32 port;
-               if (address.FindInt32("port", &port) != B_OK)
-                       port = servicePort;
-
-               serviceAddress.address.SetPort(port);
-               serviceAddress.socket = -1;
-
-               serviceAddress.owner = service;
-               service->addresses.push_back(serviceAddress);
-       }
-
-       if (i == 0 && (serviceFamily < 0 || servicePort < 0)) {
-               // no address specified
-               printf("service %s has no address specified\n", name);
-               delete service;
-               return B_BAD_VALUE;
-       }
-
-       if (i == 0) {
-               // no address specified, but family/port were given; add empty 
address
-               service_address serviceAddress;
-               serviceAddress.family = serviceFamily;
-               serviceAddress.type = serviceType;
-               serviceAddress.protocol = serviceProtocol;
-               serviceAddress.address.SetToWildcard(serviceFamily, 
servicePort);
+       // Copy launch arguments
+       for (int32 i = 0; i < settings.CountArguments(); i++)
+               service->arguments.push_back(settings.ArgumentAt(i));
 
-               serviceAddress.socket = -1;
+       // Copy addresses to listen to
+       for (int32 i = 0; i < settings.CountAddresses(); i++) {
+               const BNetworkServiceAddressSettings& address = 
settings.AddressAt(i);
+               service_connection connection;
+               connection.owner = service;
+               connection.socket = -1;
+               connection.address = address;
 
-               serviceAddress.owner = service;
-               service->addresses.push_back(serviceAddress);
+               service->connections.push_back(connection);
        }
 
        return B_OK;
@@ -614,16 +485,16 @@ Services::_Listener()
                        if (iterator == fSocketMap.end())
                                continue;
 
-                       struct service_address& address = *iterator->second;
+                       struct service_connection& connection = 
*iterator->second;
                        int socket;
 
-                       if (address.type == SOCK_STREAM) {
+                       if (connection.Type() == SOCK_STREAM) {
                                // accept incoming connection
                                int value = 1;
                                ioctl(i, FIONBIO, &value);
                                        // make sure we don't wait for the 
connection
 
-                               socket = accept(address.socket, NULL, NULL);
+                               socket = accept(connection.socket, NULL, NULL);
 
                                value = 0;
                                ioctl(i, FIONBIO, &value);
@@ -631,11 +502,11 @@ Services::_Listener()
                                if (socket < 0)
                                        continue;
                        } else
-                               socket = address.socket;
+                               socket = connection.socket;
 
                        // launch this service's handler
 
-                       _LaunchService(*address.owner, socket);
+                       _LaunchService(*connection.owner, socket);
                }
        }
        return B_OK;
diff --git a/src/servers/net/Services.h b/src/servers/net/Services.h
index 7e399a0..4a1c6c1 100644
--- a/src/servers/net/Services.h
+++ b/src/servers/net/Services.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -18,9 +18,9 @@
 
 
 struct service;
-struct service_address;
+struct service_connection;
 typedef std::map<std::string, service*> ServiceNameMap;
-typedef std::map<int, service_address*> ServiceSocketMap;
+typedef std::map<int, service_connection*> ServiceSocketMap;
 
 
 class Services : public BHandler {

############################################################################

Commit:      557c74fbfc685880a6657774fff7e9ec2822248e
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Feb 26 23:08:45 2015 UTC

Network: broadcast updates, remove apply button.

* Network now monitors all network, and network settings changes, and
  will notify all add-ons about those changes.
* Removed the global apply button. Instead, the static IP configuration
  now got that button. All other changes will be instant.

----------------------------------------------------------------------------

diff --git a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h 
b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h
index 34cbc54..3bd9d42 100644
--- a/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h
+++ b/headers/os/add-ons/network_settings/NetworkSettingsAddOn.h
@@ -23,6 +23,10 @@ enum BNetworkSettingsType {
        B_NETWORK_SETTINGS_TYPE_OTHER = 'othr'
 };
 
+enum {
+       kMsgSettingsItemUpdated = 'SIup'
+};
+
 class BNetworkProfile;
 class BNetworkSettings;
 
@@ -42,10 +46,12 @@ public:
                        const BNetworkProfile*
                                                                Profile() const;
 
-       virtual status_t                        Apply() = 0;
        virtual status_t                        Revert() = 0;
        virtual bool                            IsRevertable() = 0;
 
+       virtual void                            SettingsUpdated(uint32 type);
+       virtual void                            ConfigurationUpdated(const 
BMessage& message);
+
 private:
                        const BNetworkProfile*
                                                                fProfile;
diff --git a/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp 
b/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp
index 038b0a3..f4856ac 100644
--- a/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp
+++ b/src/add-ons/network_settings/ipv4/IPv4InterfaceAddOn.cpp
@@ -42,10 +42,11 @@ public:
        virtual BListItem*                      ListItem();
        virtual BView*                          View();
 
-       virtual status_t                        Apply();
        virtual status_t                        Revert();
        virtual bool                            IsRevertable();
 
+       virtual void                            ConfigurationUpdated(const 
BMessage& message);
+
 private:
                        BNetworkSettings&       fSettings;
                        BStringItem*            fItem;
@@ -95,13 +96,6 @@ IPv4InterfaceItem::View()
 
 
 status_t
-IPv4InterfaceItem::Apply()
-{
-       return B_OK;
-}
-
-
-status_t
 IPv4InterfaceItem::Revert()
 {
        return B_OK;
@@ -115,6 +109,14 @@ IPv4InterfaceItem::IsRevertable()
 }
 
 
+void
+IPv4InterfaceItem::ConfigurationUpdated(const BMessage& message)
+{
+       if (fView != NULL)
+               fView->ConfigurationUpdated(message);
+}
+
+
 // #pragma mark -
 
 
diff --git a/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp 
b/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp
index 2b7961c..1f41cc7 100644
--- a/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp
+++ b/src/add-ons/network_settings/ipv4/InterfaceAddressView.cpp
@@ -12,6 +12,7 @@
 
 #include <stdio.h>
 
+#include <Button.h>
 #include <Catalog.h>
 #include <ControlLook.h>
 #include <LayoutBuilder.h>
@@ -31,6 +32,7 @@
 const uint32 kModeAuto = 'iato';
 const uint32 kModeStatic = 'istc';
 const uint32 kModeDisabled = 'ioff';
+const uint32 kMsgApply = 'aply';
 
 
 // #pragma mark - InterfaceAddressView
@@ -82,6 +84,11 @@ InterfaceAddressView::InterfaceAddressView(int family,
        fGatewayField->SetToolTip(B_TRANSLATE("Your gateway to the internet"));
        fGatewayField->TextView()->SetExplicitMinSize(BSize(minimumWidth, 
B_SIZE_UNSET));
 
+       fApplyButton = new BButton("apply", B_TRANSLATE("Apply"),
+               new BMessage(kMsgApply));
+       fApplyButton->SetExplicitAlignment(
+               BAlignment(B_ALIGN_RIGHT, B_ALIGN_VERTICAL_UNSET));
+
        fSettings.GetInterface(interface, fOriginalInterface);
        fInterfaceSettings = fOriginalInterface;
        _UpdateFields();
@@ -93,6 +100,7 @@ InterfaceAddressView::InterfaceAddressView(int family,
                        .AddTextControl(fNetmaskField, 0, 2, B_ALIGN_RIGHT)
                        .AddTextControl(fGatewayField, 0, 3, B_ALIGN_RIGHT)
                .End()
+               .Add(fApplyButton)
                .AddGlue();
 }
 
@@ -120,6 +128,11 @@ InterfaceAddressView::MessageReceived(BMessage* message)
                case kModeStatic:
                case kModeDisabled:
                        _SetModeField(message->what);
+                       if (message->what != kModeStatic)
+                               _UpdateSettings();
+                       break;
+
+               case kMsgApply:
                        _UpdateSettings();
                        break;
 
@@ -129,18 +142,6 @@ InterfaceAddressView::MessageReceived(BMessage* message)
 }
 
 
-// #pragma mark - InterfaceAddressView private methods
-
-
-void
-InterfaceAddressView::_EnableFields(bool enable)
-{
-       fAddressField->SetEnabled(enable);
-       fNetmaskField->SetEnabled(enable);
-       fGatewayField->SetEnabled(enable);
-}
-
-
 // #pragma mark - InterfaceAddressView public methods
 
 
@@ -177,23 +178,51 @@ InterfaceAddressView::Revert()
 }
 
 
-status_t
-InterfaceAddressView::Save()
+void
+InterfaceAddressView::ConfigurationUpdated(const BMessage& message)
+{
+       const char* device = message.GetString("device", NULL);
+       if (strcmp(device, fInterface.Name()) != 0)
+               return;
+
+       _UpdateFields();
+}
+
+
+// #pragma mark - InterfaceAddressView private methods
+
+
+void
+InterfaceAddressView::_Apply()
 {
        BMenuItem* item = fModePopUpMenu->FindMarked();
        if (item == NULL)
-               return B_ERROR;
+               return;
 /*
        fSettings->SetIP(fFamily, fAddressField->Text());
        fSettings->SetNetmask(fFamily, fNetmaskField->Text());
        fSettings->SetGateway(fFamily, fGatewayField->Text());
        fSettings->SetAutoConfigure(fFamily, item->Command() == kModeAuto);
 */
-       return B_OK;
 }
 
 
 void
+InterfaceAddressView::_EnableFields(bool enable)
+{
+       fAddressField->SetEnabled(enable);
+       fNetmaskField->SetEnabled(enable);
+       fGatewayField->SetEnabled(enable);
+}
+
+
+/*!    Updates the UI to match the current interface configuration.
+
+       The interface settings may be consulted to determine if the
+       automatic configuration has been specified, if there was no
+       configuration yet.
+*/
+void
 InterfaceAddressView::_UpdateFields()
 {
        bool autoConfigure = (fInterface.Flags()
@@ -257,4 +286,27 @@ InterfaceAddressView::_SetModeField(uint32 mode)
 void
 InterfaceAddressView::_UpdateSettings()
 {
+       BMessage interface;
+       fSettings.GetInterface(fInterface.Name(), interface);
+
+       interface.SetString("device", fInterface.Name());
+
+       uint32 mode = kModeAuto;
+       BMenuItem* item = fModePopUpMenu->FindMarked();
+       if (item != NULL)
+               mode = item->Message()->what;
+
+       // Remove previous address for family
+
+       switch (mode) {
+               case kModeAuto:
+               default:
+                       break;
+               case kModeDisabled:
+                       break;
+               case kModeStatic:
+                       break;
+       }
+
+       fSettings.AddInterface(interface);
 }
diff --git a/src/add-ons/network_settings/ipv4/InterfaceAddressView.h 
b/src/add-ons/network_settings/ipv4/InterfaceAddressView.h
index 54db382..e6ed57b 100644
--- a/src/add-ons/network_settings/ipv4/InterfaceAddressView.h
+++ b/src/add-ons/network_settings/ipv4/InterfaceAddressView.h
@@ -15,6 +15,7 @@
 #include <NetworkSettings.h>
 
 
+class BButton;
 class BMenuField;
 class BMessage;
 class BPopUpMenu;
@@ -38,7 +39,11 @@ public:
                        status_t                        Revert();
                        status_t                        Save();
 
+                       void                            
ConfigurationUpdated(const BMessage& message);
+
+
 private:
+                       void                            _Apply();
                        void                            _EnableFields(bool 
enable);
                        void                            _UpdateFields();
                        void                            _SetModeField(uint32 
mode);
@@ -57,6 +62,7 @@ private:
                        BTextControl*           fAddressField;
                        BTextControl*           fNetmaskField;
                        BTextControl*           fGatewayField;
+                       BButton*                        fApplyButton;
 };
 
 
diff --git a/src/preferences/network/NetworkSettingsAddOn.cpp 
b/src/preferences/network/NetworkSettingsAddOn.cpp
index 13992a7..b1ee4a6 100644
--- a/src/preferences/network/NetworkSettingsAddOn.cpp
+++ b/src/preferences/network/NetworkSettingsAddOn.cpp
@@ -40,6 +40,18 @@ BNetworkSettingsItem::Profile() const
 }
 
 
+void
+BNetworkSettingsItem::SettingsUpdated(uint32 type)
+{
+}
+
+
+void
+BNetworkSettingsItem::ConfigurationUpdated(const BMessage& message)
+{
+}
+
+
 // #pragma mark -
 
 
diff --git a/src/preferences/network/NetworkWindow.cpp 
b/src/preferences/network/NetworkWindow.cpp
index 62b65d7..1b5deca 100644
--- a/src/preferences/network/NetworkWindow.cpp
+++ b/src/preferences/network/NetworkWindow.cpp
@@ -26,6 +26,7 @@
 #include <Directory.h>
 #include <LayoutBuilder.h>
 #include <NetworkInterface.h>
+#include <NetworkNotifications.h>
 #include <NetworkRoster.h>
 #include <OutlineListView.h>
 #include <Path.h>
@@ -49,7 +50,6 @@ const char* kNetworkStatusSignature = 
"application/x-vnd.Haiku-NetworkStatus";
 static const uint32 kMsgProfileSelected = 'prof';
 static const uint32 kMsgProfileManage = 'mngp';
 static const uint32 kMsgProfileNew = 'newp';
-static const uint32 kMsgApply = 'aply';
 static const uint32 kMsgRevert = 'rvrt';
 static const uint32 kMsgToggleReplicant = 'trep';
 static const uint32 kMsgItemSelected = 'ItSl';
@@ -78,10 +78,6 @@ NetworkWindow::NetworkWindow()
 
        // Settings section
 
-       fApplyButton = new BButton("apply", B_TRANSLATE("Apply"),
-               new BMessage(kMsgApply));
-       SetDefaultButton(fApplyButton);
-
        fRevertButton = new BButton("revert", B_TRANSLATE("Revert"),
                new BMessage(kMsgRevert));
        // fRevertButton->SetEnabled(false);
@@ -124,7 +120,6 @@ NetworkWindow::NetworkWindow()
                .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
                        .Add(fRevertButton)
                        .AddGlue()
-                       .Add(fApplyButton)
                .End();
 
        _ScanInterfaces();
@@ -141,11 +136,15 @@ NetworkWindow::NetworkWindow()
        CenterOnScreen();
 
        fSettings.StartMonitoring(this);
+       start_watching_network(B_WATCH_NETWORK_INTERFACE_CHANGES
+               | B_WATCH_NETWORK_LINK_CHANGES | B_WATCH_NETWORK_WLAN_CHANGES, 
this);
 }
 
 
 NetworkWindow::~NetworkWindow()
 {
+       stop_watching_network(this);
+       fSettings.StopMonitoring(this);
 }
 
 
@@ -170,10 +169,7 @@ NetworkWindow::MessageReceived(BMessage* message)
                        if (message->FindString("path", &path) != B_OK)
                                break;
 
-                       BPath name(path);
-                       bool isCurrent = strcmp(name.Leaf(), "current") == 0;
-
-                       fApplyButton->SetEnabled(!isCurrent);
+                       // TODO!
                        break;
                }
 
@@ -196,14 +192,6 @@ NetworkWindow::MessageReceived(BMessage* message)
                        break;
                }
 
-               case kMsgApply:
-               {
-                       SettingsMap::const_iterator iterator = 
fSettingsMap.begin();
-                       for (; iterator != fSettingsMap.end(); iterator++)
-                               iterator->second->Apply();
-                       break;
-               }
-
                case kMsgToggleReplicant:
                {
                        _ShowReplicant(
@@ -217,6 +205,16 @@ NetworkWindow::MessageReceived(BMessage* message)
                        break;
                }
 
+               case B_NETWORK_MONITOR:
+                       _BroadcastConfigurationUpdate(*message);
+                       break;
+
+               case BNetworkSettings::kMsgInterfaceSettingsUpdated:
+               case BNetworkSettings::kMsgNetworkSettingsUpdated:
+               case BNetworkSettings::kMsgServiceSettingsUpdated:
+                       _BroadcastSettingsUpdate(message->what);
+                       break;
+
                default:
                        inherited::MessageReceived(message);
        }
@@ -453,6 +451,24 @@ NetworkWindow::_SelectItem(BListItem* listItem)
 
 
 void
+NetworkWindow::_BroadcastSettingsUpdate(uint32 type)
+{
+       SettingsMap::const_iterator iterator = fSettingsMap.begin();
+       for (; iterator != fSettingsMap.end(); iterator++)
+               iterator->second->SettingsUpdated(type);
+}
+
+
+void
+NetworkWindow::_BroadcastConfigurationUpdate(const BMessage& message)
+{
+       SettingsMap::const_iterator iterator = fSettingsMap.begin();
+       for (; iterator != fSettingsMap.end(); iterator++)
+               iterator->second->ConfigurationUpdated(message);
+}
+
+
+void
 NetworkWindow::_ShowReplicant(bool show)
 {
        if (show) {
diff --git a/src/preferences/network/NetworkWindow.h 
b/src/preferences/network/NetworkWindow.h
index 8731f07..75ab6ec 100644
--- a/src/preferences/network/NetworkWindow.h
+++ b/src/preferences/network/NetworkWindow.h
@@ -44,6 +44,9 @@ private:
                                                                
_SettingsItemFor(BListItem* item);
                        BListItem*                      
_ListItemFor(BNetworkSettingsType type);
                        void                            _SelectItem(BListItem* 
listItem);
+                       void                            
_BroadcastSettingsUpdate(uint32 type);
+                       void                            
_BroadcastConfigurationUpdate(
+                                                                       const 
BMessage& message);
 
                        bool                            _IsReplicantInstalled();
                        void                            _ShowReplicant(bool 
show);
@@ -69,7 +72,6 @@ private:
                        BView*                          fAddOnShellView;
 
                        BButton*                        fRevertButton;
-                       BButton*                        fApplyButton;
 };
 
 


Other related posts:

  • » [haiku-commits] BRANCH axeld-github.network-preferences [557c74fbfc68] src/servers/net src/kits/network/libnetapi headers/os/add-ons/network_settings src/preferences/network src/add-ons/network_settings/ipv4 - axeld-github . network-preferences