[haiku-commits] r39595 - haiku/trunk/src/servers/net

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 23 Nov 2010 22:11:04 +0100 (CET)

Author: axeld
Date: 2010-11-23 22:11:04 +0100 (Tue, 23 Nov 2010)
New Revision: 39595
Changeset: http://dev.haiku-os.org/changeset/39595

Modified:
   haiku/trunk/src/servers/net/AutoconfigLooper.cpp
   haiku/trunk/src/servers/net/DHCPClient.cpp
   haiku/trunk/src/servers/net/DHCPClient.h
   haiku/trunk/src/servers/net/Jamfile
   haiku/trunk/src/servers/net/NetServer.cpp
   haiku/trunk/src/servers/net/NetServer.h
   haiku/trunk/src/servers/net/Services.cpp
Log:
* Now uses the new network API instead of directly using socket ioctls.
  This makes the code much cleaner and simpler.
* Completely untested, though (will do that next).


Modified: haiku/trunk/src/servers/net/AutoconfigLooper.cpp
===================================================================
--- haiku/trunk/src/servers/net/AutoconfigLooper.cpp    2010-11-23 21:05:32 UTC 
(rev 39594)
+++ haiku/trunk/src/servers/net/AutoconfigLooper.cpp    2010-11-23 21:11:04 UTC 
(rev 39595)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -17,7 +17,8 @@
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
-#include <net_notifications.h>
+#include <NetworkInterface.h>
+#include <NetworkNotifications.h>
 
 #include "DHCPClient.h"
 #include "NetServer.h"
@@ -57,21 +58,12 @@
 void
 AutoconfigLooper::_Configure()
 {
-       ifreq request;
-       if (!prepare_request(request, fDevice.String()))
-               return;
-
        // set IFF_CONFIGURING flag on interface
 
-       int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
-       if (socket < 0)
-               return;
+       BNetworkInterface interface(fDevice.String());
+       int32 flags = interface.Flags() & ~IFF_AUTO_CONFIGURED;
+       interface.SetFlags(flags | IFF_CONFIGURING);
 
-       if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0) {
-               request.ifr_flags |= IFF_CONFIGURING;
-               ioctl(socket, SIOCSIFFLAGS, &request, sizeof(struct ifreq));
-       }
-
        // remove current handler
 
        _RemoveClient();
@@ -81,10 +73,8 @@
        fCurrentClient = new DHCPClient(fTarget, fDevice.String());
        AddHandler(fCurrentClient);
 
-       if (fCurrentClient->Initialize() == B_OK) {
-               close(socket);
+       if (fCurrentClient->Initialize() == B_OK)
                return;
-       }
 
        _RemoveClient();
 
@@ -94,23 +84,20 @@
        // TODO: have a look at zeroconf
        // TODO: this could also be done add-on based
 
-       if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0
-               && (request.ifr_flags & IFF_CONFIGURING) == 0) {
+       if ((interface.Flags() & IFF_CONFIGURING) == 0) {
                // Someone else configured the interface in the mean time
-               close(socket);
                return;
        }
 
-       close(socket);
+       BMessage message(kMsgConfigureInterface);
+       message.AddString("device", fDevice.String());
+       message.AddBool("auto", true);
 
-       BMessage interface(kMsgConfigureInterface);
-       interface.AddString("device", fDevice.String());
-       interface.AddBool("auto", true);
-
-       uint8 mac[6];
+       BNetworkAddress link;
        uint8 last = 56;
-       if (get_mac_address(fDevice.String(), mac) == B_OK) {
+       if (interface.GetHardwareAddress(link) == B_OK) {
                // choose IP address depending on the MAC address, if available
+               uint8* mac = link.LinkLevelAddress();
                last = mac[0] ^ mac[1] ^ mac[2] ^ mac[3] ^ mac[4] ^ mac[5];
                if (last > 253)
                        last = 253;
@@ -126,11 +113,11 @@
        snprintf(string, sizeof(string), "169.254.0.%u", last);
 
        BMessage address;
-       address.AddString("family", "inet");
+       address.AddInt32("family", AF_INET);
        address.AddString("address", string);
-       interface.AddMessage("address", &address);
+       message.AddMessage("address", &address);
 
-       fTarget.SendMessage(&interface);
+       fTarget.SendMessage(&message);
 }
 
 

Modified: haiku/trunk/src/servers/net/DHCPClient.cpp
===================================================================
--- haiku/trunk/src/servers/net/DHCPClient.cpp  2010-11-23 21:05:32 UTC (rev 
39594)
+++ haiku/trunk/src/servers/net/DHCPClient.cpp  2010-11-23 21:11:04 UTC (rev 
39595)
@@ -13,6 +13,8 @@
 
 #include <Message.h>
 #include <MessageRunner.h>
+#include <NetworkDevice.h>
+#include <NetworkInterface.h>
 
 #include <arpa/inet.h>
 #include <errno.h>
@@ -332,23 +334,24 @@
 
 
 DHCPClient::DHCPClient(BMessenger target, const char* device)
-       : AutoconfigClient("dhcp", target, device),
+       :
+       AutoconfigClient("dhcp", target, device),
        fConfiguration(kMsgConfigureInterface),
        fResolverConfiguration(kMsgConfigureResolver),
        fRunner(NULL),
+       fServer(AF_INET, NULL, DHCP_SERVER_PORT),
        fLeaseTime(0)
 {
        fStartTime = system_time();
        fTransactionID = (uint32)fStartTime;
 
-       fStatus = get_mac_address(device, fMAC);
-       if (fStatus < B_OK)
+       BNetworkAddress link;
+       BNetworkInterface interface(device);
+       fStatus = interface.GetHardwareAddress(link);
+       if (fStatus != B_OK)
                return;
 
-       memset(&fServer, 0, sizeof(struct sockaddr_in));
-       fServer.sin_family = AF_INET;
-       fServer.sin_len = sizeof(struct sockaddr_in);
-       fServer.sin_port = htons(DHCP_SERVER_PORT);
+       memcpy(fMAC, link.LinkLevelAddress(), sizeof(fMAC));
 
        openlog_thread("DHCP", 0, LOG_DAEMON);
 }
@@ -393,12 +396,7 @@
        if (socket < 0)
                return errno;
 
-       sockaddr_in local;
-       memset(&local, 0, sizeof(struct sockaddr_in));
-       local.sin_family = AF_INET;
-       local.sin_len = sizeof(struct sockaddr_in);
-       local.sin_port = htons(DHCP_CLIENT_PORT);
-       local.sin_addr.s_addr = INADDR_ANY;
+       BNetworkAddress local(AF_INET, NULL, DHCP_CLIENT_PORT);
 
        // Enable reusing the port . This is needed in case there is more
        // than 1 interface that needs to be configured. Note that the only 
reason
@@ -407,17 +405,13 @@
        int option = 1;
        setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &option, sizeof(option));
 
-       if (bind(socket, (struct sockaddr*)&local, sizeof(local)) < 0) {
+       if (bind(socket, local, local.Length()) < 0) {
                close(socket);
                return errno;
        }
 
-       sockaddr_in broadcast;
-       memset(&broadcast, 0, sizeof(struct sockaddr_in));
-       broadcast.sin_family = AF_INET;
-       broadcast.sin_len = sizeof(struct sockaddr_in);
-       broadcast.sin_port = htons(DHCP_SERVER_PORT);
-       broadcast.sin_addr.s_addr = INADDR_BROADCAST;
+       BNetworkAddress broadcast;
+       broadcast.SetToBroadcast(AF_INET, DHCP_SERVER_PORT);
 
        option = 1;
        setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
@@ -425,19 +419,10 @@
        if (state == INIT) {
                // The local interface does not have an address yet, bind the 
socket
                // to the device directly.
-               int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0);
-               if (linkSocket >= 0) {
-                       // we need to know the index of the device to be able 
to bind to it
-                       ifreq request;
-                       prepare_request(request, Device());
-                       if (ioctl(linkSocket, SIOCGIFINDEX, &request, 
sizeof(struct ifreq))
-                                       == 0) {
-                               setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE,
-                                       &request.ifr_index, sizeof(int));
-                       }
+               BNetworkDevice device(Device());
+               int index = device.Index();
 
-                       close(linkSocket);
-               }
+               setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, &index, 
sizeof(int));
        }
 
        bigtime_t previousLeaseTime = fLeaseTime;
@@ -558,7 +543,7 @@
                                status = Target().SendMessage(&fConfiguration, 
&reply);
                                if (status == B_OK)
                                        status = reply.FindInt32("status", 
&fStatus);
-                                       
+
                                // configure resolver
                                reply.MakeEmpty();
                                status = 
Target().SendMessage(&fResolverConfiguration, &reply);
@@ -653,7 +638,7 @@
                                break;
                        }
                        case OPTION_SERVER_ADDRESS:
-                               fServer.sin_addr.s_addr = *(in_addr_t*)data;
+                               fServer.SetAddress(*(in_addr_t*)data);
                                break;
 
                        case OPTION_ADDRESS_LEASE_TIME:
@@ -684,8 +669,8 @@
                                        min_c(size + 1, sizeof(domain)));
 
                                syslog(LOG_INFO, "DHCP domain name: \"%s\"\n", 
domain);
-                               
-                               resolverConfiguration.AddString("domain", 
domain);      
+
+                               resolverConfiguration.AddString("domain", 
domain);
                                break;
                        }
 
@@ -718,9 +703,10 @@
                case DHCP_RELEASE:
                {
                        // add server identifier option
+                       const sockaddr_in& server = 
(sockaddr_in&)fServer.SockAddr();
                        uint8* next = message.PrepareMessage(type);
                        next = message.PutOption(next, OPTION_SERVER_ADDRESS,
-                               (uint32)fServer.sin_addr.s_addr);
+                               (uint32)server.sin_addr.s_addr);
 
                        // In RENEWAL or REBINDING state, we must set the 
client_address field, and not
                        // use OPTION_REQUEST_IP_ADDRESS for DHCP_REQUEST 
messages
@@ -805,14 +791,13 @@
 
 status_t
 DHCPClient::_SendMessage(int socket, dhcp_message& message,
-       sockaddr_in& address) const
+       const BNetworkAddress& address) const
 {
        syslog(LOG_DEBUG, "DHCP send message %u for %s\n", message.Type(),
                Device());
 
        ssize_t bytesSent = sendto(socket, &message, message.Size(),
-               address.sin_addr.s_addr == INADDR_BROADCAST ? MSG_BCAST : 0,
-               (struct sockaddr*)&address, sizeof(sockaddr_in));
+               address.IsBroadcast() ? MSG_BCAST : 0, address, 
address.Length());
        if (bytesSent < 0)
                return errno;
 

Modified: haiku/trunk/src/servers/net/DHCPClient.h
===================================================================
--- haiku/trunk/src/servers/net/DHCPClient.h    2010-11-23 21:05:32 UTC (rev 
39594)
+++ haiku/trunk/src/servers/net/DHCPClient.h    2010-11-23 21:11:04 UTC (rev 
39595)
@@ -13,9 +13,13 @@
 
 #include <netinet/in.h>
 
+#include <NetworkAddress.h>
+
+
 class BMessageRunner;
 class dhcp_message;
 
+
 enum dhcp_state {
        INIT,
        REQUESTING,
@@ -44,7 +48,7 @@
                        void                            
_PrepareMessage(dhcp_message& message,
                                                                        
dhcp_state state);
                        status_t                        _SendMessage(int 
socket, dhcp_message& message,
-                                                                       
sockaddr_in& address) const;
+                                                                       const 
BNetworkAddress& address) const;
                        dhcp_state                      _CurrentState() const;
                        void                            _ResetTimeout(int 
socket, time_t& timeout,
                                                                        uint32& 
tries);
@@ -61,7 +65,7 @@
                        uint8                           fMAC[6];
                        uint32                          fTransactionID;
                        in_addr_t                       fAssignedAddress;
-                       sockaddr_in                     fServer;
+                       BNetworkAddress         fServer;
                        bigtime_t                       fStartTime;
                        bigtime_t                       fRenewalTime;
                        bigtime_t                       fRebindingTime;

Modified: haiku/trunk/src/servers/net/Jamfile
===================================================================
--- haiku/trunk/src/servers/net/Jamfile 2010-11-23 21:05:32 UTC (rev 39594)
+++ haiku/trunk/src/servers/net/Jamfile 2010-11-23 21:11:04 UTC (rev 39595)
@@ -16,7 +16,7 @@
        DHCPClient.cpp
        Services.cpp
 
-       : be libnetwork.so $(TARGET_LIBSTDC++)
+       : be network bnetapi $(TARGET_LIBSTDC++)
        # for PPP
        #libppp.a
 ;

Modified: haiku/trunk/src/servers/net/NetServer.cpp
===================================================================
--- haiku/trunk/src/servers/net/NetServer.cpp   2010-11-23 21:05:32 UTC (rev 
39594)
+++ haiku/trunk/src/servers/net/NetServer.cpp   2010-11-23 21:11:04 UTC (rev 
39595)
@@ -29,6 +29,8 @@
 #include <Deskbar.h>
 #include <Directory.h>
 #include <Entry.h>
+#include <NetworkInterface.h>
+#include <NetworkRoster.h>
 #include <Path.h>
 #include <PathMonitor.h>
 #include <Roster.h>
@@ -54,27 +56,24 @@
        virtual void                            MessageReceived(BMessage* 
message);
 
 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,
-                                                                       bool 
fromMessage = false);
+                       bool                            
_IsValidInterface(BNetworkInterface& interface);
+                       void                            
_RemoveInvalidInterfaces();
+                       status_t                        _RemoveInterface(const 
char* name);
+                       status_t                        _DisableInterface(const 
char* name);
+                       bool                            _TestForInterface(const 
char* name);
+                       status_t                        
_ConfigureInterface(BMessage& interface);
                        status_t                        _ConfigureResolver(
                                                                        
BMessage& resolverConfiguration);
                        bool                            
_QuitLooperForDevice(const char* device);
                        AutoconfigLooper*       _LooperForDevice(const char* 
device);
-                       status_t                        _ConfigureDevice(int 
socket, const char* path);
-                       void                            _ConfigureDevices(int 
socket, const char* path,
+                       status_t                        _ConfigureDevice(const 
char* path);
+                       void                            _ConfigureDevices(const 
char* path,
                                                                        
BMessage* suggestedInterface = NULL);
-                       void                            
_ConfigureInterfaces(int socket,
+                       void                            _ConfigureInterfaces(
                                                                        
BMessage* _missingDevice = NULL);
                        void                            _BringUpInterfaces();
                        void                            _StartServices();
-                       void                            
_HandleDeviceMonitor(int socket,
-                                                                       
BMessage* message);
+                       void                            
_HandleDeviceMonitor(BMessage* message);
 
 private:
                        Settings                        fSettings;
@@ -87,164 +86,73 @@
        int                     family;
        const char*     name;
        const char*     identifiers[4];
-       bool            (*parse_address)(const char* string, sockaddr* 
_address);
-       void            (*set_any_address)(sockaddr* address);
-       void            (*set_port)(sockaddr* address, int32 port);
 };
 
 
-// AF_INET family
-static bool inet_parse_address(const char* string, sockaddr* address);
-static void inet_set_any_address(sockaddr* address);
-static void inet_set_port(sockaddr* address, int32 port);
-
 static const address_family kFamilies[] = {
        {
                AF_INET,
                "inet",
                {"AF_INET", "inet", "ipv4", NULL},
-               inet_parse_address,
-               inet_set_any_address,
-               inet_set_port
        },
-       { -1, NULL, {NULL}, NULL }
+       {
+               AF_INET6,
+               "inet6",
+               {"AF_INET6", "inet6", "ipv6", NULL},
+       },
+       { -1, NULL, {NULL} }
 };
 
 
-static bool
-inet_parse_address(const char* string, sockaddr* _address)
+int
+get_address_family(const char* argument)
 {
-       in_addr inetAddress;
-
-       if (inet_aton(string, &inetAddress) != 1)
-               return false;
-
-       sockaddr_in& address = *(sockaddr_in *)_address;
-       address.sin_family = AF_INET;
-       address.sin_len = sizeof(struct sockaddr_in);
-       address.sin_port = 0;
-       address.sin_addr = inetAddress;
-       memset(&address.sin_zero[0], 0, sizeof(address.sin_zero));
-
-       return true;
-}
-
-
-void
-inet_set_any_address(sockaddr* _address)
-{
-       sockaddr_in& address = *(sockaddr_in*)_address;
-       address.sin_family = AF_INET;
-       address.sin_len = sizeof(struct sockaddr_in);
-       address.sin_port = 0;
-       address.sin_addr.s_addr = INADDR_ANY;
-       memset(&address.sin_zero[0], 0, sizeof(address.sin_zero));
-}
-
-
-void
-inet_set_port(sockaddr* _address, int32 port)
-{
-       sockaddr_in& address = *(sockaddr_in*)_address;
-       address.sin_port = port;
-}
-
-
-//     #pragma mark -
-
-
-bool
-get_family_index(const char* name, int32& familyIndex)
-{
        for (int32 i = 0; kFamilies[i].family >= 0; i++) {
                for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
-                       if (!strcmp(name, kFamilies[i].identifiers[j])) {
+                       if (!strcmp(argument, kFamilies[i].identifiers[j])) {
                                // found a match
-                               familyIndex = i;
-                               return true;
+                               return kFamilies[i].family;
                        }
                }
        }
 
-       // defaults to AF_INET
-       familyIndex = 0;
-       return false;
+       return AF_UNSPEC;
 }
 
 
-int
-family_at_index(int32 index)
-{
-       return kFamilies[index].family;
-}
-
-
+/*!    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 familyIndex, const char* argument, struct sockaddr& 
address)
+parse_address(int32& family, const char* argument, BNetworkAddress& address)
 {
        if (argument == NULL)
                return false;
 
-       return kFamilies[familyIndex].parse_address(argument, &address);
-}
-
-
-void
-set_any_address(int32 familyIndex, struct sockaddr& address)
-{
-       kFamilies[familyIndex].set_any_address(&address);
-}
-
-
-void
-set_port(int32 familyIndex, struct sockaddr& address, int32 port)
-{
-       kFamilies[familyIndex].set_port(&address, port);
-}
-
-
-bool
-prepare_request(ifreq& request, const char* name)
-{
-       if (strlen(name) >= IF_NAMESIZE)
+       status_t status = address.SetTo(family, argument, (uint16)0,
+               B_NO_ADDRESS_RESOLUTION);
+       if (status != B_OK)
                return false;
 
-       strcpy(request.ifr_name, name);
-       return true;
-}
+       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;
 
-status_t
-get_mac_address(const char* device, uint8* address)
-{
-       int socket = ::socket(AF_LINK, SOCK_DGRAM, 0);
-       if (socket < 0)
-               return errno;
-
-       ifreq request;
-       if (!prepare_request(request, device)) {
-               close(socket);
-               return B_ERROR;
+               // Take over family from address
+               family = address.Family();
        }
 
-       if (ioctl(socket, SIOCGIFADDR, &request, sizeof(struct ifreq)) < 0) {
-               close(socket);
-               return errno;
-       }
-
-       close(socket);
-
-       sockaddr_dl &link = *(sockaddr_dl *)&request.ifr_addr;
-       if (link.sdl_type != IFT_ETHER)
-               return B_BAD_TYPE;
-
-       if (link.sdl_alen == 0)
-               return B_ENTRY_NOT_FOUND;
-
-       uint8 *mac = (uint8 *)LLADDR(&link);
-       memcpy(address, mac, 6);
-
-       return B_OK;
+       return true;
 }
 
 
@@ -252,14 +160,15 @@
 
 
 NetServer::NetServer(status_t& error)
-       : BServer(kNetServerSignature, false, &error)
+       :
+       BServer(kNetServerSignature, false, &error)
 {
 }
 
 
 NetServer::~NetServer()
 {
-       BPrivate::BPathMonitor::StopWatching("/dev/net", this); 
+       BPrivate::BPathMonitor::StopWatching("/dev/net", this);
 }
 
 
@@ -288,7 +197,7 @@
        fSettings.StartMonitoring(this);
        _BringUpInterfaces();
        _StartServices();
-       
+
        BPrivate::BPathMonitor::StartWatching("/dev/net", B_ENTRY_CREATED
                | B_ENTRY_REMOVED | B_WATCH_FILES_ONLY | B_WATCH_RECURSIVELY, 
this);
 }
@@ -301,25 +210,13 @@
                case B_PATH_MONITOR:
                {
                        fSettings.Update(message);
-                       
-                       // we need a socket to talk to the networking stack
-                       int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
-                       if (socket < 0)
-                               break;
-                       _HandleDeviceMonitor(socket, message);
-                       close(socket);
+                       _HandleDeviceMonitor(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);
+                       _ConfigureInterfaces();
                        break;
                }
 
@@ -334,32 +231,18 @@
 
                case kMsgConfigureInterface:
                {
-#if 0
-                       if (!message->ReturnAddress().IsTargetLocal()) {
-                               // for now, we only accept this message from 
add-ons
-                               break;
-                       }
-#endif
+                       status_t status = _ConfigureInterface(*message);
 
-                       // we need a socket to talk to the networking stack
-                       int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
-                       if (socket < 0)
-                               break;
-
-                       status_t status = _ConfigureInterface(socket, *message, 
true);
-
                        BMessage reply(B_REPLY);
                        reply.AddInt32("status", status);
                        message->SendReply(&reply);
-
-                       close(socket);
                        break;
                }
 
                case kMsgConfigureResolver:
                {
                        status_t status = _ConfigureResolver(*message);
-                       
+
                        BMessage reply(B_REPLY);
                        reply.AddInt32("status", status);
                        message->SendReply(&reply);
@@ -373,207 +256,107 @@
 }
 
 
-/*!
-       Checks if an interface is valid, that is, if it has an address in any
+/*!    Checks if an interface is valid, that is, if it has an address in any
        family, and, in case of ethernet, a hardware MAC address.
 */
 bool
-NetServer::_IsValidInterface(int socket, const char* name)
+NetServer::_IsValidInterface(BNetworkInterface& interface)
 {
-       ifreq request;
-       if (!prepare_request(request, name))
-               return B_ERROR;
-
        // check if it has an address
 
-       int32 addresses = 0;
-
-       for (int32 i = 0; kFamilies[i].family >= 0; i++) {
-               int familySocket = ::socket(kFamilies[i].family, SOCK_DGRAM, 0);
-               if (familySocket < 0)
-                       continue;
-
-               if (ioctl(familySocket, SIOCGIFADDR, &request, sizeof(struct 
ifreq)) == 0) {
-                       if (request.ifr_addr.sa_family == kFamilies[i].family)
-                               addresses++;
-               }
-
-               close(familySocket);
-       }
-
-       if (addresses == 0)
+       if (interface.CountAddresses() == 0)
                return false;
 
        // check if it has a hardware address, too, in case of ethernet
 
-       int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0);
-       if (linkSocket < 0)
+       BNetworkAddress link;
+       if (interface.GetHardwareAddress(link) != B_OK)
                return false;
 
-       if (ioctl(linkSocket, SIOCGIFADDR, &request, sizeof(struct ifreq)) < 0) 
{
-               close(linkSocket);
+       if (link.LinkLevelType() == IFT_ETHER && link.LinkLevelAddressLength() 
!= 6)
                return false;
-       }
 
-       close(linkSocket);
-
-       sockaddr_dl &link = *(sockaddr_dl *)&request.ifr_addr;
-       if (link.sdl_type == IFT_ETHER && link.sdl_alen < 6)
-               return false;
-
        return true;
 }
 
 
 void
-NetServer::_RemoveInvalidInterfaces(int socket)
+NetServer::_RemoveInvalidInterfaces()
 {
-       // get a list of all interfaces
+       BNetworkRoster& roster = BNetworkRoster::Default();
+       BNetworkInterface interface;
+       uint32 cookie = 0;
 
-       ifconf config;
-       config.ifc_len = sizeof(config.ifc_value);
-       if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
-               return;
-
-       uint32 count = (uint32)config.ifc_value;
-       if (count == 0) {
-               // there are no interfaces yet
-               return;
-       }
-
-       void *buffer = malloc(count * sizeof(struct ifreq));
-       if (buffer == NULL) {
-               fprintf(stderr, "%s: Out of memory.\n", Name());
-               return;
-       }
-
-       config.ifc_len = count * sizeof(struct ifreq);
-       config.ifc_buf = buffer;
-       if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) {
-               free(buffer);
-               return;
-       }
-
-       ifreq *interface = (ifreq *)buffer;
-
-       for (uint32 i = 0; i < count; i++) {
-               if (!_IsValidInterface(socket, interface->ifr_name)) {
+       while (roster.GetNextInterface(&cookie, interface) == B_OK) {
+               if (!_IsValidInterface(interface)) {
                        // remove invalid interface
-                       _RemoveInterface(socket, interface->ifr_name);
+                       _RemoveInterface(interface.Name());
                }
-
-               interface = (ifreq *)((addr_t)interface + IF_NAMESIZE
-                       + interface->ifr_addr.sa_len);
        }
-
-       free(buffer);
 }
 
 
 bool
-NetServer::_TestForInterface(int socket, const char* name)
+NetServer::_TestForInterface(const char* name)
 {
-       // get a list of all interfaces
 
-       ifconf config;
-       config.ifc_len = sizeof(config.ifc_value);
-       if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
-               return false;
-
-       uint32 count = (uint32)config.ifc_value;
-       if (count == 0) {
-               // there are no interfaces yet
-               return false;
-       }
-
-       void *buffer = malloc(count * sizeof(struct ifreq));
-       if (buffer == NULL) {
-               fprintf(stderr, "%s: Out of memory.\n", Name());
-               return false;
-       }
-
-       config.ifc_len = count * sizeof(struct ifreq);
-       config.ifc_buf = buffer;
-       if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) {
-               free(buffer);
-               return false;
-       }
-
-       ifreq *interface = (ifreq *)buffer;
+       BNetworkRoster& roster = BNetworkRoster::Default();
        int32 nameLength = strlen(name);
-       bool success = false;
+       BNetworkInterface interface;
+       uint32 cookie = 0;
 
-       for (uint32 i = 0; i < count; i++) {
-               if (!strncmp(interface->ifr_name, name, nameLength)) {
-                       success = true;
-                       break;
-               }
-
-               interface = (ifreq *)((addr_t)interface + IF_NAMESIZE
-                       + interface->ifr_addr.sa_len);
+       while (roster.GetNextInterface(&cookie, interface) == B_OK) {
+               if (!strncmp(interface.Name(), name, nameLength))
+                       return true;
        }
 
-       free(buffer);
-       return success;
+       return false;
 }
 
 
 status_t
-NetServer::_RemoveInterface(int socket, const char* name)
+NetServer::_RemoveInterface(const char* name)
 {
-       ifreq request;
-       if (!prepare_request(request, name))
-               return B_ERROR;
-               
-       if (ioctl(socket, SIOCDIFADDR, &request, sizeof(request)) < 0) {
+       BNetworkRoster& roster = BNetworkRoster::Default();
+       status_t status = roster.RemoveInterface(name);
+       if (status != B_OK) {
                fprintf(stderr, "%s: Could not delete interface %s: %s\n",
-                       Name(), name, strerror(errno));
-               return B_ERROR;
+                       Name(), name, strerror(status));
+               return status;
        }
-       
+
        return B_OK;
 }
 
 
 status_t
-NetServer::_DisableInterface(int socket, const char* name)
+NetServer::_DisableInterface(const char* name)
 {
-       ifreq request;
-       if (!prepare_request(request, name))
-               return B_ERROR;
+       BNetworkInterface interface(name);
+       int32 flags = interface.Flags();
 
-       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);
+       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;
+       status_t status = interface.SetFlags(flags);
+       if (status != B_OK) {
+               fprintf(stderr, "%s: Setting flags failed: %s\n", Name(),
+                       strerror(status));
+               return status;
        }
 
-       fprintf(stderr, "%s: set %s interface down...\n", Name(), name); 
-       
+       fprintf(stderr, "%s: set %s interface down...\n", Name(), name);
        return B_OK;
 }
 
 
 status_t
-NetServer::_ConfigureInterface(int socket, BMessage& interface,
-       bool fromMessage)
+NetServer::_ConfigureInterface(BMessage& interface)
 {
-       const char *device;
+       const char* device;
        if (interface.FindString("device", &device) != B_OK)
                return B_BAD_VALUE;
 
-       ifreq request;
-       if (!prepare_request(request, device))
-               return B_ERROR;
-
        bool startAutoConfig = false;
 
        int32 flags;
@@ -595,41 +378,28 @@
        BMessage addressMessage;
        for (int32 index = 0; interface.FindMessage("address", index,
                        &addressMessage) == B_OK; index++) {
-               const char* family;
-               if (addressMessage.FindString("family", &family) < B_OK)
-                       continue;
+               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
+                                       continue;
+                               }
+                       }
+               } else
+                       family = AF_UNSPEC;
 
-               int32 familyIndex;
-               if (!get_family_index(family, familyIndex)) {
-                       // we don't support this family
-                       continue;
-               }
+               BNetworkInterface interface(device);
+               if (!interface.Exists()) {
+                       // the interface does not exist yet, we have to add it 
first
+                       BNetworkRoster& roster = BNetworkRoster::Default();
 
-               int familySocket = socket;
-               if (family_at_index(familyIndex) != AF_INET)
-                       socket = ::socket(family_at_index(familyIndex), 
SOCK_DGRAM, 0);
-               if (socket < 0) {
-                       // the family is not available in this environment
-                       continue;
-               }
-
-               uint32 interfaceIndex = 0;
-               if (ioctl(socket, SIOCGIFINDEX, &request, sizeof(request)) >= 0)
-                       interfaceIndex = request.ifr_index;
-
-               if (interfaceIndex == 0) {
-                       // we need to create the interface first
-                       ifaliasreq request;
-                       strlcpy(request.ifra_name, device, IF_NAMESIZE);
-
-                       request.ifra_addr.ss_family = AF_UNSPEC;
-                       request.ifra_mask.ss_family = AF_UNSPEC;
-                       request.ifra_broadaddr.ss_family = AF_UNSPEC;
-
-                       if (ioctl(socket, SIOCAIFADDR, &request, 
sizeof(request)) < 0) {
+                       status_t status = roster.AddInterface(interface);
+                       if (status != B_OK) {
                                fprintf(stderr, "%s: Could not add interface: 
%s\n", Name(),
-                                       strerror(errno));
-                               return errno;
+                                       strerror(status));
+                               return status;
                        }
                }
 
@@ -638,129 +408,97 @@
                bool autoConfig;
                if (addressMessage.FindBool("auto_config", &autoConfig) != B_OK)
                        autoConfig = false;
-#if 0
-               if (autoConfig && fromMessage) {
-                       // we don't accept auto-config messages this way
-                       continue;
-               }
-#endif
 
-               bool hasAddress = false, hasMask = false, hasPeer = false;
-               bool hasBroadcast = false;
-               struct sockaddr address, mask, peer, broadcast, gateway;
+               BNetworkAddress address;
+               BNetworkAddress mask;
+               BNetworkAddress broadcast;
+               BNetworkAddress peer;
+               BNetworkAddress gateway;
+
                const char* string;
 
                if (!autoConfig) {
-                       if (addressMessage.FindString("address", &string) == 
B_OK
-                               && parse_address(familyIndex, string, address)) 
{
-                               hasAddress = true;
+                       if (addressMessage.FindString("address", &string) == 
B_OK) {
+                               parse_address(family, string, address);
 
-                               if (addressMessage.FindString("mask", &string) 
== B_OK
-                                       && parse_address(familyIndex, string, 
mask))
-                                       hasMask = true;
+                               if (addressMessage.FindString("mask", &string) 
== B_OK)
+                                       parse_address(family, string, mask);

[... truncated: 448 lines follow ...]

Other related posts: