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 ...]