* 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). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39595 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -17,7 +17,8 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
#include <net_notifications.h>
|
#include <NetworkInterface.h>
|
||||||
|
#include <NetworkNotifications.h>
|
||||||
|
|
||||||
#include "DHCPClient.h"
|
#include "DHCPClient.h"
|
||||||
#include "NetServer.h"
|
#include "NetServer.h"
|
||||||
@@ -57,20 +58,11 @@ AutoconfigLooper::_RemoveClient()
|
|||||||
void
|
void
|
||||||
AutoconfigLooper::_Configure()
|
AutoconfigLooper::_Configure()
|
||||||
{
|
{
|
||||||
ifreq request;
|
|
||||||
if (!prepare_request(request, fDevice.String()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// set IFF_CONFIGURING flag on interface
|
// set IFF_CONFIGURING flag on interface
|
||||||
|
|
||||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
BNetworkInterface interface(fDevice.String());
|
||||||
if (socket < 0)
|
int32 flags = interface.Flags() & ~IFF_AUTO_CONFIGURED;
|
||||||
return;
|
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
|
// remove current handler
|
||||||
|
|
||||||
@@ -81,10 +73,8 @@ AutoconfigLooper::_Configure()
|
|||||||
fCurrentClient = new DHCPClient(fTarget, fDevice.String());
|
fCurrentClient = new DHCPClient(fTarget, fDevice.String());
|
||||||
AddHandler(fCurrentClient);
|
AddHandler(fCurrentClient);
|
||||||
|
|
||||||
if (fCurrentClient->Initialize() == B_OK) {
|
if (fCurrentClient->Initialize() == B_OK)
|
||||||
close(socket);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
_RemoveClient();
|
_RemoveClient();
|
||||||
|
|
||||||
@@ -94,23 +84,20 @@ AutoconfigLooper::_Configure()
|
|||||||
// TODO: have a look at zeroconf
|
// TODO: have a look at zeroconf
|
||||||
// TODO: this could also be done add-on based
|
// TODO: this could also be done add-on based
|
||||||
|
|
||||||
if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0
|
if ((interface.Flags() & IFF_CONFIGURING) == 0) {
|
||||||
&& (request.ifr_flags & IFF_CONFIGURING) == 0) {
|
|
||||||
// Someone else configured the interface in the mean time
|
// Someone else configured the interface in the mean time
|
||||||
close(socket);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(socket);
|
BMessage message(kMsgConfigureInterface);
|
||||||
|
message.AddString("device", fDevice.String());
|
||||||
|
message.AddBool("auto", true);
|
||||||
|
|
||||||
BMessage interface(kMsgConfigureInterface);
|
BNetworkAddress link;
|
||||||
interface.AddString("device", fDevice.String());
|
|
||||||
interface.AddBool("auto", true);
|
|
||||||
|
|
||||||
uint8 mac[6];
|
|
||||||
uint8 last = 56;
|
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
|
// 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];
|
last = mac[0] ^ mac[1] ^ mac[2] ^ mac[3] ^ mac[4] ^ mac[5];
|
||||||
if (last > 253)
|
if (last > 253)
|
||||||
last = 253;
|
last = 253;
|
||||||
@@ -126,11 +113,11 @@ AutoconfigLooper::_Configure()
|
|||||||
snprintf(string, sizeof(string), "169.254.0.%u", last);
|
snprintf(string, sizeof(string), "169.254.0.%u", last);
|
||||||
|
|
||||||
BMessage address;
|
BMessage address;
|
||||||
address.AddString("family", "inet");
|
address.AddInt32("family", AF_INET);
|
||||||
address.AddString("address", string);
|
address.AddString("address", string);
|
||||||
interface.AddMessage("address", &address);
|
message.AddMessage("address", &address);
|
||||||
|
|
||||||
fTarget.SendMessage(&interface);
|
fTarget.SendMessage(&message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <MessageRunner.h>
|
#include <MessageRunner.h>
|
||||||
|
#include <NetworkDevice.h>
|
||||||
|
#include <NetworkInterface.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -332,23 +334,24 @@ dhcp_message::FinishOptions(uint8* options)
|
|||||||
|
|
||||||
|
|
||||||
DHCPClient::DHCPClient(BMessenger target, const char* device)
|
DHCPClient::DHCPClient(BMessenger target, const char* device)
|
||||||
: AutoconfigClient("dhcp", target, device),
|
:
|
||||||
|
AutoconfigClient("dhcp", target, device),
|
||||||
fConfiguration(kMsgConfigureInterface),
|
fConfiguration(kMsgConfigureInterface),
|
||||||
fResolverConfiguration(kMsgConfigureResolver),
|
fResolverConfiguration(kMsgConfigureResolver),
|
||||||
fRunner(NULL),
|
fRunner(NULL),
|
||||||
|
fServer(AF_INET, NULL, DHCP_SERVER_PORT),
|
||||||
fLeaseTime(0)
|
fLeaseTime(0)
|
||||||
{
|
{
|
||||||
fStartTime = system_time();
|
fStartTime = system_time();
|
||||||
fTransactionID = (uint32)fStartTime;
|
fTransactionID = (uint32)fStartTime;
|
||||||
|
|
||||||
fStatus = get_mac_address(device, fMAC);
|
BNetworkAddress link;
|
||||||
if (fStatus < B_OK)
|
BNetworkInterface interface(device);
|
||||||
|
fStatus = interface.GetHardwareAddress(link);
|
||||||
|
if (fStatus != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(&fServer, 0, sizeof(struct sockaddr_in));
|
memcpy(fMAC, link.LinkLevelAddress(), sizeof(fMAC));
|
||||||
fServer.sin_family = AF_INET;
|
|
||||||
fServer.sin_len = sizeof(struct sockaddr_in);
|
|
||||||
fServer.sin_port = htons(DHCP_SERVER_PORT);
|
|
||||||
|
|
||||||
openlog_thread("DHCP", 0, LOG_DAEMON);
|
openlog_thread("DHCP", 0, LOG_DAEMON);
|
||||||
}
|
}
|
||||||
@@ -393,12 +396,7 @@ DHCPClient::_Negotiate(dhcp_state state)
|
|||||||
if (socket < 0)
|
if (socket < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
sockaddr_in local;
|
BNetworkAddress local(AF_INET, NULL, DHCP_CLIENT_PORT);
|
||||||
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;
|
|
||||||
|
|
||||||
// Enable reusing the port . This is needed in case there is more
|
// 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
|
// than 1 interface that needs to be configured. Note that the only reason
|
||||||
@@ -407,17 +405,13 @@ DHCPClient::_Negotiate(dhcp_state state)
|
|||||||
int option = 1;
|
int option = 1;
|
||||||
setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &option, sizeof(option));
|
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);
|
close(socket);
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_in broadcast;
|
BNetworkAddress broadcast;
|
||||||
memset(&broadcast, 0, sizeof(struct sockaddr_in));
|
broadcast.SetToBroadcast(AF_INET, DHCP_SERVER_PORT);
|
||||||
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;
|
|
||||||
|
|
||||||
option = 1;
|
option = 1;
|
||||||
setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
|
setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
|
||||||
@@ -425,19 +419,10 @@ DHCPClient::_Negotiate(dhcp_state state)
|
|||||||
if (state == INIT) {
|
if (state == INIT) {
|
||||||
// The local interface does not have an address yet, bind the socket
|
// The local interface does not have an address yet, bind the socket
|
||||||
// to the device directly.
|
// to the device directly.
|
||||||
int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0);
|
BNetworkDevice device(Device());
|
||||||
if (linkSocket >= 0) {
|
int index = device.Index();
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
close(linkSocket);
|
setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, &index, sizeof(int));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bigtime_t previousLeaseTime = fLeaseTime;
|
bigtime_t previousLeaseTime = fLeaseTime;
|
||||||
@@ -558,7 +543,7 @@ DHCPClient::_Negotiate(dhcp_state state)
|
|||||||
status = Target().SendMessage(&fConfiguration, &reply);
|
status = Target().SendMessage(&fConfiguration, &reply);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = reply.FindInt32("status", &fStatus);
|
status = reply.FindInt32("status", &fStatus);
|
||||||
|
|
||||||
// configure resolver
|
// configure resolver
|
||||||
reply.MakeEmpty();
|
reply.MakeEmpty();
|
||||||
status = Target().SendMessage(&fResolverConfiguration, &reply);
|
status = Target().SendMessage(&fResolverConfiguration, &reply);
|
||||||
@@ -653,7 +638,7 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPTION_SERVER_ADDRESS:
|
case OPTION_SERVER_ADDRESS:
|
||||||
fServer.sin_addr.s_addr = *(in_addr_t*)data;
|
fServer.SetAddress(*(in_addr_t*)data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPTION_ADDRESS_LEASE_TIME:
|
case OPTION_ADDRESS_LEASE_TIME:
|
||||||
@@ -684,8 +669,8 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address,
|
|||||||
min_c(size + 1, sizeof(domain)));
|
min_c(size + 1, sizeof(domain)));
|
||||||
|
|
||||||
syslog(LOG_INFO, "DHCP domain name: \"%s\"\n", domain);
|
syslog(LOG_INFO, "DHCP domain name: \"%s\"\n", domain);
|
||||||
|
|
||||||
resolverConfiguration.AddString("domain", domain);
|
resolverConfiguration.AddString("domain", domain);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,9 +703,10 @@ DHCPClient::_PrepareMessage(dhcp_message& message, dhcp_state state)
|
|||||||
case DHCP_RELEASE:
|
case DHCP_RELEASE:
|
||||||
{
|
{
|
||||||
// add server identifier option
|
// add server identifier option
|
||||||
|
const sockaddr_in& server = (sockaddr_in&)fServer.SockAddr();
|
||||||
uint8* next = message.PrepareMessage(type);
|
uint8* next = message.PrepareMessage(type);
|
||||||
next = message.PutOption(next, OPTION_SERVER_ADDRESS,
|
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
|
// In RENEWAL or REBINDING state, we must set the client_address field, and not
|
||||||
// use OPTION_REQUEST_IP_ADDRESS for DHCP_REQUEST messages
|
// use OPTION_REQUEST_IP_ADDRESS for DHCP_REQUEST messages
|
||||||
@@ -805,14 +791,13 @@ DHCPClient::_ToString(in_addr_t address) const
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
DHCPClient::_SendMessage(int socket, dhcp_message& message,
|
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(),
|
syslog(LOG_DEBUG, "DHCP send message %u for %s\n", message.Type(),
|
||||||
Device());
|
Device());
|
||||||
|
|
||||||
ssize_t bytesSent = sendto(socket, &message, message.Size(),
|
ssize_t bytesSent = sendto(socket, &message, message.Size(),
|
||||||
address.sin_addr.s_addr == INADDR_BROADCAST ? MSG_BCAST : 0,
|
address.IsBroadcast() ? MSG_BCAST : 0, address, address.Length());
|
||||||
(struct sockaddr*)&address, sizeof(sockaddr_in));
|
|
||||||
if (bytesSent < 0)
|
if (bytesSent < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,13 @@
|
|||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <NetworkAddress.h>
|
||||||
|
|
||||||
|
|
||||||
class BMessageRunner;
|
class BMessageRunner;
|
||||||
class dhcp_message;
|
class dhcp_message;
|
||||||
|
|
||||||
|
|
||||||
enum dhcp_state {
|
enum dhcp_state {
|
||||||
INIT,
|
INIT,
|
||||||
REQUESTING,
|
REQUESTING,
|
||||||
@@ -44,7 +48,7 @@ private:
|
|||||||
void _PrepareMessage(dhcp_message& message,
|
void _PrepareMessage(dhcp_message& message,
|
||||||
dhcp_state state);
|
dhcp_state state);
|
||||||
status_t _SendMessage(int socket, dhcp_message& message,
|
status_t _SendMessage(int socket, dhcp_message& message,
|
||||||
sockaddr_in& address) const;
|
const BNetworkAddress& address) const;
|
||||||
dhcp_state _CurrentState() const;
|
dhcp_state _CurrentState() const;
|
||||||
void _ResetTimeout(int socket, time_t& timeout,
|
void _ResetTimeout(int socket, time_t& timeout,
|
||||||
uint32& tries);
|
uint32& tries);
|
||||||
@@ -61,7 +65,7 @@ private:
|
|||||||
uint8 fMAC[6];
|
uint8 fMAC[6];
|
||||||
uint32 fTransactionID;
|
uint32 fTransactionID;
|
||||||
in_addr_t fAssignedAddress;
|
in_addr_t fAssignedAddress;
|
||||||
sockaddr_in fServer;
|
BNetworkAddress fServer;
|
||||||
bigtime_t fStartTime;
|
bigtime_t fStartTime;
|
||||||
bigtime_t fRenewalTime;
|
bigtime_t fRenewalTime;
|
||||||
bigtime_t fRebindingTime;
|
bigtime_t fRebindingTime;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Server net_server :
|
|||||||
DHCPClient.cpp
|
DHCPClient.cpp
|
||||||
Services.cpp
|
Services.cpp
|
||||||
|
|
||||||
: be libnetwork.so $(TARGET_LIBSTDC++)
|
: be network bnetapi $(TARGET_LIBSTDC++)
|
||||||
# for PPP
|
# for PPP
|
||||||
#libppp.a
|
#libppp.a
|
||||||
;
|
;
|
||||||
|
|||||||
+190
-453
@@ -29,6 +29,8 @@
|
|||||||
#include <Deskbar.h>
|
#include <Deskbar.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
|
#include <NetworkInterface.h>
|
||||||
|
#include <NetworkRoster.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <PathMonitor.h>
|
#include <PathMonitor.h>
|
||||||
#include <Roster.h>
|
#include <Roster.h>
|
||||||
@@ -54,27 +56,24 @@ public:
|
|||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _IsValidInterface(int socket, const char* name);
|
bool _IsValidInterface(BNetworkInterface& interface);
|
||||||
void _RemoveInvalidInterfaces(int socket);
|
void _RemoveInvalidInterfaces();
|
||||||
status_t _RemoveInterface(int socket, const char* name);
|
status_t _RemoveInterface(const char* name);
|
||||||
status_t _DisableInterface(int socket, const char* name);
|
status_t _DisableInterface(const char* name);
|
||||||
bool _TestForInterface(int socket, const char* name);
|
bool _TestForInterface(const char* name);
|
||||||
status_t _ConfigureInterface(int socket,
|
status_t _ConfigureInterface(BMessage& interface);
|
||||||
BMessage& interface,
|
|
||||||
bool fromMessage = false);
|
|
||||||
status_t _ConfigureResolver(
|
status_t _ConfigureResolver(
|
||||||
BMessage& resolverConfiguration);
|
BMessage& resolverConfiguration);
|
||||||
bool _QuitLooperForDevice(const char* device);
|
bool _QuitLooperForDevice(const char* device);
|
||||||
AutoconfigLooper* _LooperForDevice(const char* device);
|
AutoconfigLooper* _LooperForDevice(const char* device);
|
||||||
status_t _ConfigureDevice(int socket, const char* path);
|
status_t _ConfigureDevice(const char* path);
|
||||||
void _ConfigureDevices(int socket, const char* path,
|
void _ConfigureDevices(const char* path,
|
||||||
BMessage* suggestedInterface = NULL);
|
BMessage* suggestedInterface = NULL);
|
||||||
void _ConfigureInterfaces(int socket,
|
void _ConfigureInterfaces(
|
||||||
BMessage* _missingDevice = NULL);
|
BMessage* _missingDevice = NULL);
|
||||||
void _BringUpInterfaces();
|
void _BringUpInterfaces();
|
||||||
void _StartServices();
|
void _StartServices();
|
||||||
void _HandleDeviceMonitor(int socket,
|
void _HandleDeviceMonitor(BMessage* message);
|
||||||
BMessage* message);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Settings fSettings;
|
Settings fSettings;
|
||||||
@@ -87,179 +86,89 @@ struct address_family {
|
|||||||
int family;
|
int family;
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* identifiers[4];
|
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[] = {
|
static const address_family kFamilies[] = {
|
||||||
{
|
{
|
||||||
AF_INET,
|
AF_INET,
|
||||||
"inet",
|
"inet",
|
||||||
{"AF_INET", "inet", "ipv4", NULL},
|
{"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
|
int
|
||||||
inet_parse_address(const char* string, sockaddr* _address)
|
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 i = 0; kFamilies[i].family >= 0; i++) {
|
||||||
for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
|
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
|
// found a match
|
||||||
familyIndex = i;
|
return kFamilies[i].family;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaults to AF_INET
|
return AF_UNSPEC;
|
||||||
familyIndex = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
bool
|
||||||
parse_address(int32 familyIndex, const char* argument, struct sockaddr& address)
|
parse_address(int32& family, const char* argument, BNetworkAddress& address)
|
||||||
{
|
{
|
||||||
if (argument == NULL)
|
if (argument == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return kFamilies[familyIndex].parse_address(argument, &address);
|
status_t status = address.SetTo(family, argument, (uint16)0,
|
||||||
}
|
B_NO_ADDRESS_RESOLUTION);
|
||||||
|
if (status != B_OK)
|
||||||
|
|
||||||
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)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
strcpy(request.ifr_name, name);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
NetServer::NetServer(status_t& error)
|
NetServer::NetServer(status_t& error)
|
||||||
: BServer(kNetServerSignature, false, &error)
|
:
|
||||||
|
BServer(kNetServerSignature, false, &error)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NetServer::~NetServer()
|
NetServer::~NetServer()
|
||||||
{
|
{
|
||||||
BPrivate::BPathMonitor::StopWatching("/dev/net", this);
|
BPrivate::BPathMonitor::StopWatching("/dev/net", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -288,7 +197,7 @@ NetServer::ReadyToRun()
|
|||||||
fSettings.StartMonitoring(this);
|
fSettings.StartMonitoring(this);
|
||||||
_BringUpInterfaces();
|
_BringUpInterfaces();
|
||||||
_StartServices();
|
_StartServices();
|
||||||
|
|
||||||
BPrivate::BPathMonitor::StartWatching("/dev/net", B_ENTRY_CREATED
|
BPrivate::BPathMonitor::StartWatching("/dev/net", B_ENTRY_CREATED
|
||||||
| B_ENTRY_REMOVED | B_WATCH_FILES_ONLY | B_WATCH_RECURSIVELY, this);
|
| B_ENTRY_REMOVED | B_WATCH_FILES_ONLY | B_WATCH_RECURSIVELY, this);
|
||||||
}
|
}
|
||||||
@@ -301,25 +210,13 @@ NetServer::MessageReceived(BMessage* message)
|
|||||||
case B_PATH_MONITOR:
|
case B_PATH_MONITOR:
|
||||||
{
|
{
|
||||||
fSettings.Update(message);
|
fSettings.Update(message);
|
||||||
|
_HandleDeviceMonitor(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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case kMsgInterfaceSettingsUpdated:
|
case kMsgInterfaceSettingsUpdated:
|
||||||
{
|
{
|
||||||
// we need a socket to talk to the networking stack
|
_ConfigureInterfaces();
|
||||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (socket < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
_ConfigureInterfaces(socket);
|
|
||||||
close(socket);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,32 +231,18 @@ NetServer::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
case kMsgConfigureInterface:
|
case kMsgConfigureInterface:
|
||||||
{
|
{
|
||||||
#if 0
|
status_t status = _ConfigureInterface(*message);
|
||||||
if (!message->ReturnAddress().IsTargetLocal()) {
|
|
||||||
// for now, we only accept this message from add-ons
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 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);
|
BMessage reply(B_REPLY);
|
||||||
reply.AddInt32("status", status);
|
reply.AddInt32("status", status);
|
||||||
message->SendReply(&reply);
|
message->SendReply(&reply);
|
||||||
|
|
||||||
close(socket);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case kMsgConfigureResolver:
|
case kMsgConfigureResolver:
|
||||||
{
|
{
|
||||||
status_t status = _ConfigureResolver(*message);
|
status_t status = _ConfigureResolver(*message);
|
||||||
|
|
||||||
BMessage reply(B_REPLY);
|
BMessage reply(B_REPLY);
|
||||||
reply.AddInt32("status", status);
|
reply.AddInt32("status", status);
|
||||||
message->SendReply(&reply);
|
message->SendReply(&reply);
|
||||||
@@ -373,52 +256,24 @@ NetServer::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! 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.
|
family, and, in case of ethernet, a hardware MAC address.
|
||||||
*/
|
*/
|
||||||
bool
|
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
|
// check if it has an address
|
||||||
|
|
||||||
int32 addresses = 0;
|
if (interface.CountAddresses() == 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)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check if it has a hardware address, too, in case of ethernet
|
// check if it has a hardware address, too, in case of ethernet
|
||||||
|
|
||||||
int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0);
|
BNetworkAddress link;
|
||||||
if (linkSocket < 0)
|
if (interface.GetHardwareAddress(link) != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ioctl(linkSocket, SIOCGIFADDR, &request, sizeof(struct ifreq)) < 0) {
|
if (link.LinkLevelType() == IFT_ETHER && link.LinkLevelAddressLength() != 6)
|
||||||
close(linkSocket);
|
|
||||||
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 false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -426,154 +281,82 @@ NetServer::_IsValidInterface(int socket, const char* name)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NetServer::_RemoveInvalidInterfaces(int socket)
|
NetServer::_RemoveInvalidInterfaces()
|
||||||
{
|
{
|
||||||
// get a list of all interfaces
|
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||||
|
BNetworkInterface interface;
|
||||||
|
uint32 cookie = 0;
|
||||||
|
|
||||||
ifconf config;
|
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
|
||||||
config.ifc_len = sizeof(config.ifc_value);
|
if (!_IsValidInterface(interface)) {
|
||||||
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)) {
|
|
||||||
// remove invalid 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
|
bool
|
||||||
NetServer::_TestForInterface(int socket, const char* name)
|
NetServer::_TestForInterface(const char* name)
|
||||||
{
|
{
|
||||||
// get a list of all interfaces
|
|
||||||
|
|
||||||
ifconf config;
|
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||||
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;
|
|
||||||
int32 nameLength = strlen(name);
|
int32 nameLength = strlen(name);
|
||||||
bool success = false;
|
BNetworkInterface interface;
|
||||||
|
uint32 cookie = 0;
|
||||||
|
|
||||||
for (uint32 i = 0; i < count; i++) {
|
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
|
||||||
if (!strncmp(interface->ifr_name, name, nameLength)) {
|
if (!strncmp(interface.Name(), name, nameLength))
|
||||||
success = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface = (ifreq *)((addr_t)interface + IF_NAMESIZE
|
|
||||||
+ interface->ifr_addr.sa_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buffer);
|
return false;
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
NetServer::_RemoveInterface(int socket, const char* name)
|
NetServer::_RemoveInterface(const char* name)
|
||||||
{
|
{
|
||||||
ifreq request;
|
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||||
if (!prepare_request(request, name))
|
status_t status = roster.RemoveInterface(name);
|
||||||
return B_ERROR;
|
if (status != B_OK) {
|
||||||
|
|
||||||
if (ioctl(socket, SIOCDIFADDR, &request, sizeof(request)) < 0) {
|
|
||||||
fprintf(stderr, "%s: Could not delete interface %s: %s\n",
|
fprintf(stderr, "%s: Could not delete interface %s: %s\n",
|
||||||
Name(), name, strerror(errno));
|
Name(), name, strerror(status));
|
||||||
return B_ERROR;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
NetServer::_DisableInterface(int socket, const char* name)
|
NetServer::_DisableInterface(const char* name)
|
||||||
{
|
{
|
||||||
ifreq request;
|
BNetworkInterface interface(name);
|
||||||
if (!prepare_request(request, name))
|
int32 flags = interface.Flags();
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
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
|
// 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) {
|
status_t status = interface.SetFlags(flags);
|
||||||
fprintf(stderr, "%s: Setting flags failed: %s\n", Name(),
|
if (status != B_OK) {
|
||||||
strerror(errno));
|
fprintf(stderr, "%s: Setting flags failed: %s\n", Name(),
|
||||||
return B_ERROR;
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
NetServer::_ConfigureInterface(int socket, BMessage& interface,
|
NetServer::_ConfigureInterface(BMessage& interface)
|
||||||
bool fromMessage)
|
|
||||||
{
|
{
|
||||||
const char *device;
|
const char* device;
|
||||||
if (interface.FindString("device", &device) != B_OK)
|
if (interface.FindString("device", &device) != B_OK)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
ifreq request;
|
|
||||||
if (!prepare_request(request, device))
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
bool startAutoConfig = false;
|
bool startAutoConfig = false;
|
||||||
|
|
||||||
int32 flags;
|
int32 flags;
|
||||||
@@ -595,41 +378,28 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface,
|
|||||||
BMessage addressMessage;
|
BMessage addressMessage;
|
||||||
for (int32 index = 0; interface.FindMessage("address", index,
|
for (int32 index = 0; interface.FindMessage("address", index,
|
||||||
&addressMessage) == B_OK; index++) {
|
&addressMessage) == B_OK; index++) {
|
||||||
const char* family;
|
int32 family;
|
||||||
if (addressMessage.FindString("family", &family) < B_OK)
|
if (addressMessage.FindInt32("family", &family) != B_OK) {
|
||||||
continue;
|
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;
|
BNetworkInterface interface(device);
|
||||||
if (!get_family_index(family, familyIndex)) {
|
if (!interface.Exists()) {
|
||||||
// we don't support this family
|
// the interface does not exist yet, we have to add it first
|
||||||
continue;
|
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||||
}
|
|
||||||
|
|
||||||
int familySocket = socket;
|
status_t status = roster.AddInterface(interface);
|
||||||
if (family_at_index(familyIndex) != AF_INET)
|
if (status != B_OK) {
|
||||||
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) {
|
|
||||||
fprintf(stderr, "%s: Could not add interface: %s\n", Name(),
|
fprintf(stderr, "%s: Could not add interface: %s\n", Name(),
|
||||||
strerror(errno));
|
strerror(status));
|
||||||
return errno;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,129 +408,97 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface,
|
|||||||
bool autoConfig;
|
bool autoConfig;
|
||||||
if (addressMessage.FindBool("auto_config", &autoConfig) != B_OK)
|
if (addressMessage.FindBool("auto_config", &autoConfig) != B_OK)
|
||||||
autoConfig = false;
|
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;
|
BNetworkAddress address;
|
||||||
bool hasBroadcast = false;
|
BNetworkAddress mask;
|
||||||
struct sockaddr address, mask, peer, broadcast, gateway;
|
BNetworkAddress broadcast;
|
||||||
|
BNetworkAddress peer;
|
||||||
|
BNetworkAddress gateway;
|
||||||
|
|
||||||
const char* string;
|
const char* string;
|
||||||
|
|
||||||
if (!autoConfig) {
|
if (!autoConfig) {
|
||||||
if (addressMessage.FindString("address", &string) == B_OK
|
if (addressMessage.FindString("address", &string) == B_OK) {
|
||||||
&& parse_address(familyIndex, string, address)) {
|
parse_address(family, string, address);
|
||||||
hasAddress = true;
|
|
||||||
|
|
||||||
if (addressMessage.FindString("mask", &string) == B_OK
|
if (addressMessage.FindString("mask", &string) == B_OK)
|
||||||
&& parse_address(familyIndex, string, mask))
|
parse_address(family, string, mask);
|
||||||
hasMask = true;
|
|
||||||
}
|
}
|
||||||
if (addressMessage.FindString("peer", &string) == B_OK
|
|
||||||
&& parse_address(familyIndex, string, peer))
|
if (addressMessage.FindString("peer", &string) == B_OK)
|
||||||
hasPeer = true;
|
parse_address(family, string, peer);
|
||||||
if (addressMessage.FindString("broadcast", &string) == B_OK
|
|
||||||
&& parse_address(familyIndex, string, broadcast))
|
if (addressMessage.FindString("broadcast", &string) == B_OK)
|
||||||
hasBroadcast = true;
|
parse_address(family, string, broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
route_entry route;
|
|
||||||
memset(&route, 0, sizeof(route_entry));
|
|
||||||
route.flags = RTF_STATIC | RTF_DEFAULT;
|
|
||||||
|
|
||||||
request.ifr_route = route;
|
|
||||||
|
|
||||||
if (autoConfig) {
|
if (autoConfig) {
|
||||||
_QuitLooperForDevice(device);
|
_QuitLooperForDevice(device);
|
||||||
startAutoConfig = true;
|
startAutoConfig = true;
|
||||||
} else if (addressMessage.FindString("gateway", &string) == B_OK
|
} else if (addressMessage.FindString("gateway", &string) == B_OK
|
||||||
&& parse_address(familyIndex, string, gateway)) {
|
&& parse_address(family, string, gateway)) {
|
||||||
// add gateway route, if we're asked for it
|
// add gateway route, if we're asked for it
|
||||||
|
interface.RemoveDefaultRoute(family);
|
||||||
ioctl(socket, SIOCDELRT, &request, sizeof(request));
|
|
||||||
// Try to remove a previous default route, doesn't matter
|
// Try to remove a previous default route, doesn't matter
|
||||||
// if it fails.
|
// if it fails.
|
||||||
|
|
||||||
route.flags = RTF_STATIC | RTF_DEFAULT | RTF_GATEWAY;
|
status_t status = interface.AddDefaultRoute(gateway);
|
||||||
route.gateway = &gateway;
|
if (status != B_OK) {
|
||||||
|
|
||||||
request.ifr_route = route;
|
|
||||||
if (ioctl(socket, SIOCADDRT, &request, sizeof(request)) < 0) {
|
|
||||||
fprintf(stderr, "%s: Could not add route for %s: %s\n",
|
fprintf(stderr, "%s: Could not add route for %s: %s\n",
|
||||||
Name(), device, strerror(errno));
|
Name(), device, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set addresses
|
// set address/mask/broadcast/peer
|
||||||
|
|
||||||
if (hasAddress) {
|
if (!address.IsEmpty() || !mask.IsEmpty() || !broadcast.IsEmpty()) {
|
||||||
memcpy(&request.ifr_addr, &address, address.sa_len);
|
BNetworkInterfaceAddress interfaceAddress;
|
||||||
|
interfaceAddress.SetAddress(address);
|
||||||
|
interfaceAddress.SetMask(mask);
|
||||||
|
if (!broadcast.IsEmpty())
|
||||||
|
interfaceAddress.SetBroadcast(broadcast);
|
||||||
|
else if (!peer.IsEmpty())
|
||||||
|
interfaceAddress.SetDestination(peer);
|
||||||
|
|
||||||
if (ioctl(familySocket, SIOCSIFADDR, &request, sizeof(struct ifreq)) < 0) {
|
status_t status = interface.SetAddress(interfaceAddress);
|
||||||
fprintf(stderr, "%s: Setting address failed: %s\n", Name(), strerror(errno));
|
if (status != B_OK) {
|
||||||
continue;
|
fprintf(stderr, "%s: Setting address failed: %s\n", Name(),
|
||||||
}
|
strerror(status));
|
||||||
}
|
return status;
|
||||||
|
|
||||||
if (ioctl(familySocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) < 0) {
|
|
||||||
fprintf(stderr, "%s: Getting flags failed: %s\n", Name(), strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int32 currentFlags = request.ifr_flags;
|
|
||||||
|
|
||||||
if (hasMask) {
|
|
||||||
memcpy(&request.ifr_mask, &mask, mask.sa_len);
|
|
||||||
|
|
||||||
if (ioctl(familySocket, SIOCSIFNETMASK, &request, sizeof(struct ifreq)) < 0) {
|
|
||||||
fprintf(stderr, "%s: Setting subnet mask failed: %s\n", Name(), strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasBroadcast) {
|
|
||||||
memcpy(&request.ifr_broadaddr, &broadcast, broadcast.sa_len);
|
|
||||||
|
|
||||||
if (ioctl(familySocket, SIOCSIFBRDADDR, &request, sizeof(struct ifreq)) < 0) {
|
|
||||||
fprintf(stderr, "%s: Setting broadcast address failed: %s\n", Name(), strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasPeer) {
|
|
||||||
memcpy(&request.ifr_dstaddr, &peer, peer.sa_len);
|
|
||||||
|
|
||||||
if (ioctl(familySocket, SIOCSIFDSTADDR, &request, sizeof(struct ifreq)) < 0) {
|
|
||||||
fprintf(stderr, "%s: Setting peer address failed: %s\n", Name(), strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set flags
|
// set flags
|
||||||
|
|
||||||
if (flags != 0) {
|
if (flags != 0) {
|
||||||
request.ifr_flags = (currentFlags & ~IFF_CONFIGURING) | flags;
|
int32 newFlags = interface.Flags();
|
||||||
|
newFlags = (newFlags & ~IFF_CONFIGURING) | flags;
|
||||||
if (!autoConfigured)
|
if (!autoConfigured)
|
||||||
request.ifr_flags = request.ifr_flags & ~IFF_AUTO_CONFIGURED;
|
newFlags &= ~IFF_AUTO_CONFIGURED;
|
||||||
|
|
||||||
if (ioctl(familySocket, SIOCSIFFLAGS, &request, sizeof(struct ifreq)) < 0)
|
status_t status = interface.SetFlags(newFlags);
|
||||||
fprintf(stderr, "%s: Setting flags failed: %s\n", Name(), strerror(errno));
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "%s: Setting flags failed: %s\n", Name(),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set options
|
// set options
|
||||||
|
|
||||||
if (mtu != -1) {
|
if (mtu != -1) {
|
||||||
request.ifr_mtu = mtu;
|
status_t status = interface.SetMTU(mtu);
|
||||||
if (ioctl(familySocket, SIOCSIFMTU, &request, sizeof(struct ifreq)) < 0)
|
if (status != B_OK) {
|
||||||
fprintf(stderr, "%s: Setting MTU failed: %s\n", Name(), strerror(errno));
|
fprintf(stderr, "%s: Setting MTU failed: %s\n", Name(),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metric != -1) {
|
if (metric != -1) {
|
||||||
request.ifr_metric = metric;
|
status_t status = interface.SetMetric(metric);
|
||||||
if (ioctl(familySocket, SIOCSIFMETRIC, &request, sizeof(struct ifreq)) < 0)
|
if (status != B_OK) {
|
||||||
fprintf(stderr, "%s: Setting metric failed: %s\n", Name(), strerror(errno));
|
fprintf(stderr, "%s: Setting metric failed: %s\n", Name(),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,7 +538,7 @@ NetServer::_ConfigureResolver(BMessage& resolverConfiguration)
|
|||||||
const char* domain;
|
const char* domain;
|
||||||
if (resolverConfiguration.FindString("domain", &domain) == B_OK)
|
if (resolverConfiguration.FindString("domain", &domain) == B_OK)
|
||||||
fprintf(file, "domain %s\n", domain);
|
fprintf(file, "domain %s\n", domain);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -835,22 +573,22 @@ NetServer::_LooperForDevice(const char* device)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
NetServer::_ConfigureDevice(int socket, const char* path)
|
NetServer::_ConfigureDevice(const char* device)
|
||||||
{
|
{
|
||||||
// bring interface up, but don't configure it just yet
|
// bring interface up, but don't configure it just yet
|
||||||
BMessage interface;
|
BMessage interface;
|
||||||
interface.AddString("device", path);
|
interface.AddString("device", device);
|
||||||
BMessage address;
|
BMessage address;
|
||||||
address.AddString("family", "inet");
|
address.AddString("family", "inet");
|
||||||
address.AddBool("auto_config", true);
|
address.AddBool("auto_config", true);
|
||||||
interface.AddMessage("address", &address);
|
interface.AddMessage("address", &address);
|
||||||
|
|
||||||
return _ConfigureInterface(socket, interface);
|
return _ConfigureInterface(interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NetServer::_ConfigureDevices(int socket, const char* startPath,
|
NetServer::_ConfigureDevices(const char* startPath,
|
||||||
BMessage* suggestedInterface)
|
BMessage* suggestedInterface)
|
||||||
{
|
{
|
||||||
BDirectory directory(startPath);
|
BDirectory directory(startPath);
|
||||||
@@ -868,18 +606,18 @@ NetServer::_ConfigureDevices(int socket, const char* startPath,
|
|||||||
if (suggestedInterface != NULL
|
if (suggestedInterface != NULL
|
||||||
&& suggestedInterface->RemoveName("device") == B_OK
|
&& suggestedInterface->RemoveName("device") == B_OK
|
||||||
&& suggestedInterface->AddString("device", path.Path()) == B_OK
|
&& suggestedInterface->AddString("device", path.Path()) == B_OK
|
||||||
&& _ConfigureInterface(socket, *suggestedInterface) == B_OK)
|
&& _ConfigureInterface(*suggestedInterface) == B_OK)
|
||||||
suggestedInterface = NULL;
|
suggestedInterface = NULL;
|
||||||
else
|
else
|
||||||
_ConfigureDevice(socket, path.Path());
|
_ConfigureDevice(path.Path());
|
||||||
} else if (entry.IsDirectory())
|
} else if (entry.IsDirectory())
|
||||||
_ConfigureDevices(socket, path.Path(), suggestedInterface);
|
_ConfigureDevices(path.Path(), suggestedInterface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NetServer::_ConfigureInterfaces(int socket, BMessage* _missingDevice)
|
NetServer::_ConfigureInterfaces(BMessage* _missingDevice)
|
||||||
{
|
{
|
||||||
BMessage interface;
|
BMessage interface;
|
||||||
uint32 cookie = 0;
|
uint32 cookie = 0;
|
||||||
@@ -888,11 +626,11 @@ NetServer::_ConfigureInterfaces(int socket, BMessage* _missingDevice)
|
|||||||
const char *device;
|
const char *device;
|
||||||
if (interface.FindString("device", &device) != B_OK)
|
if (interface.FindString("device", &device) != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
if (interface.FindBool("disabled", &disabled) == B_OK && disabled) {
|
if (interface.FindBool("disabled", &disabled) == B_OK && disabled) {
|
||||||
// disabled by user request
|
// disabled by user request
|
||||||
_DisableInterface(socket, device);
|
_DisableInterface(device);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,7 +646,7 @@ NetServer::_ConfigureInterfaces(int socket, BMessage* _missingDevice)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ConfigureInterface(socket, interface);
|
_ConfigureInterface(interface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,17 +662,18 @@ NetServer::_BringUpInterfaces()
|
|||||||
Quit();
|
Quit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
close(socket);
|
||||||
|
|
||||||
_RemoveInvalidInterfaces(socket);
|
_RemoveInvalidInterfaces();
|
||||||
|
|
||||||
// First, we look into the settings, and try to bring everything up from there
|
// First, we look into the settings, and try to bring everything up from there
|
||||||
|
|
||||||
BMessage missingDevice;
|
BMessage missingDevice;
|
||||||
_ConfigureInterfaces(socket, &missingDevice);
|
_ConfigureInterfaces(&missingDevice);
|
||||||
|
|
||||||
// check configuration
|
// check configuration
|
||||||
|
|
||||||
if (!_TestForInterface(socket, "loop")) {
|
if (!_TestForInterface("loop")) {
|
||||||
// there is no loopback interface, create one
|
// there is no loopback interface, create one
|
||||||
BMessage interface;
|
BMessage interface;
|
||||||
interface.AddString("device", "loop");
|
interface.AddString("device", "loop");
|
||||||
@@ -943,19 +682,17 @@ NetServer::_BringUpInterfaces()
|
|||||||
address.AddString("address", "127.0.0.1");
|
address.AddString("address", "127.0.0.1");
|
||||||
interface.AddMessage("address", &address);
|
interface.AddMessage("address", &address);
|
||||||
|
|
||||||
_ConfigureInterface(socket, interface);
|
_ConfigureInterface(interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: also check if the networking driver is correctly initialized!
|
// TODO: also check if the networking driver is correctly initialized!
|
||||||
// (and check for other devices to take over its configuration)
|
// (and check for other devices to take over its configuration)
|
||||||
|
|
||||||
if (!_TestForInterface(socket, "/dev/net/")) {
|
if (!_TestForInterface("/dev/net/")) {
|
||||||
// there is no driver configured - see if there is one and try to use it
|
// there is no driver configured - see if there is one and try to use it
|
||||||
_ConfigureDevices(socket, "/dev/net",
|
_ConfigureDevices("/dev/net",
|
||||||
missingDevice.HasString("device") ? &missingDevice : NULL);
|
missingDevice.HasString("device") ? &missingDevice : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(socket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -971,7 +708,7 @@ NetServer::_StartServices()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NetServer::_HandleDeviceMonitor(int socket, BMessage* message)
|
NetServer::_HandleDeviceMonitor(BMessage* message)
|
||||||
{
|
{
|
||||||
int32 opcode;
|
int32 opcode;
|
||||||
if (message->FindInt32("opcode", &opcode) != B_OK
|
if (message->FindInt32("opcode", &opcode) != B_OK
|
||||||
@@ -983,11 +720,11 @@ NetServer::_HandleDeviceMonitor(int socket, BMessage* message)
|
|||||||
if (message->FindString("watched_path", &watchedPath) != B_OK
|
if (message->FindString("watched_path", &watchedPath) != B_OK
|
||||||
|| message->FindString("path", &path) != B_OK)
|
|| message->FindString("path", &path) != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (opcode == B_ENTRY_CREATED)
|
if (opcode == B_ENTRY_CREATED)
|
||||||
_ConfigureDevice(socket, path);
|
_ConfigureDevice(path);
|
||||||
else
|
else
|
||||||
_RemoveInterface(socket, path);
|
_RemoveInterface(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,21 +14,22 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BNetworkAddress;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: move this into a private shared header
|
||||||
// NOTE: this header is used by other applications (such as ifconfig,
|
// NOTE: this header is used by other applications (such as ifconfig,
|
||||||
// and Network) because of these three defines
|
// and Network) because of these defines
|
||||||
#define kNetServerSignature "application/x-vnd.haiku-net_server"
|
#define kNetServerSignature "application/x-vnd.haiku-net_server"
|
||||||
#define kMsgConfigureInterface 'COif'
|
#define kMsgConfigureInterface 'COif'
|
||||||
#define kMsgConfigureResolver 'COrs'
|
#define kMsgConfigureResolver 'COrs'
|
||||||
|
#define kMsgJoinNetwork 'JNnw'
|
||||||
|
#define kMsgLeaveNetwork 'LVnw'
|
||||||
|
|
||||||
|
|
||||||
extern bool get_family_index(const char* name, int32& familyIndex);
|
int get_address_family(const char* argument);
|
||||||
extern int family_at_index(int32 index);
|
bool parse_address(int32& family, const char* argument,
|
||||||
extern bool parse_address(int32 familyIndex, const char* argument,
|
BNetworkAddress& address);
|
||||||
struct sockaddr& address);
|
|
||||||
extern void set_any_address(int32 familyIndex, struct sockaddr& address);
|
|
||||||
extern void set_port(int32 familyIndex, struct sockaddr& address, int32 port);
|
|
||||||
|
|
||||||
extern bool prepare_request(ifreq& request, const char* name);
|
|
||||||
extern status_t get_mac_address(const char* device, uint8* address);
|
|
||||||
|
|
||||||
#endif // NET_SERVER_H
|
#endif // NET_SERVER_H
|
||||||
|
|||||||
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
|
#include <NetworkAddress.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@@ -31,7 +32,7 @@ struct service_address {
|
|||||||
int family;
|
int family;
|
||||||
int type;
|
int type;
|
||||||
int protocol;
|
int protocol;
|
||||||
sockaddr address;
|
BNetworkAddress address;
|
||||||
|
|
||||||
bool operator==(const struct service_address& other) const;
|
bool operator==(const struct service_address& other) const;
|
||||||
};
|
};
|
||||||
@@ -100,8 +101,7 @@ service_address::operator==(const struct service_address& other) const
|
|||||||
return family == other.family
|
return family == other.family
|
||||||
&& type == other.type
|
&& type == other.type
|
||||||
&& protocol == other.protocol
|
&& protocol == other.protocol
|
||||||
&& address.sa_len == other.address.sa_len
|
&& address == other.address;
|
||||||
&& !memcmp(&address, &other.address, address.sa_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -274,7 +274,8 @@ Services::_StartService(struct service& service)
|
|||||||
|
|
||||||
address.socket = socket(address.family, address.type, address.protocol);
|
address.socket = socket(address.family, address.type, address.protocol);
|
||||||
if (address.socket < 0
|
if (address.socket < 0
|
||||||
|| bind(address.socket, &address.address, address.address.sa_len) < 0
|
|| bind(address.socket, address.address, address.address.Length())
|
||||||
|
< 0
|
||||||
|| fcntl(address.socket, F_SETFD, FD_CLOEXEC) < 0) {
|
|| fcntl(address.socket, F_SETFD, FD_CLOEXEC) < 0) {
|
||||||
failed = true;
|
failed = true;
|
||||||
break;
|
break;
|
||||||
@@ -378,13 +379,12 @@ Services::_ToService(const BMessage& message, struct service*& service)
|
|||||||
|
|
||||||
// we default to inet/tcp/port-from-service-name if nothing is specified
|
// we default to inet/tcp/port-from-service-name if nothing is specified
|
||||||
const char* string;
|
const char* string;
|
||||||
int32 serviceFamilyIndex;
|
|
||||||
int32 serviceFamily = -1;
|
|
||||||
if (message.FindString("family", &string) != B_OK)
|
if (message.FindString("family", &string) != B_OK)
|
||||||
string = "inet";
|
string = "inet";
|
||||||
|
|
||||||
if (get_family_index(string, serviceFamilyIndex))
|
int32 serviceFamily = get_address_family(string);
|
||||||
serviceFamily = family_at_index(serviceFamilyIndex);
|
if (serviceFamily == AF_UNSPEC)
|
||||||
|
serviceFamily = AF_INET;
|
||||||
|
|
||||||
int32 serviceProtocol;
|
int32 serviceProtocol;
|
||||||
if (message.FindString("protocol", &string) == B_OK)
|
if (message.FindString("protocol", &string) == B_OK)
|
||||||
@@ -424,12 +424,10 @@ Services::_ToService(const BMessage& message, struct service*& service)
|
|||||||
if (address.FindString("family", &string) != B_OK)
|
if (address.FindString("family", &string) != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int32 familyIndex;
|
serviceAddress.family = get_address_family(string);
|
||||||
if (!get_family_index(string, familyIndex))
|
if (serviceAddress.family == AF_UNSPEC)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
serviceAddress.family = family_at_index(familyIndex);
|
|
||||||
|
|
||||||
if (address.FindString("protocol", &string) == B_OK)
|
if (address.FindString("protocol", &string) == B_OK)
|
||||||
serviceAddress.protocol = parse_protocol(string);
|
serviceAddress.protocol = parse_protocol(string);
|
||||||
else
|
else
|
||||||
@@ -443,16 +441,16 @@ Services::_ToService(const BMessage& message, struct service*& service)
|
|||||||
serviceAddress.type = serviceType;
|
serviceAddress.type = serviceType;
|
||||||
|
|
||||||
if (address.FindString("address", &string) == B_OK) {
|
if (address.FindString("address", &string) == B_OK) {
|
||||||
if (!parse_address(familyIndex, string, serviceAddress.address))
|
if (!parse_address(serviceFamily, string, serviceAddress.address))
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
set_any_address(familyIndex, serviceAddress.address);
|
serviceAddress.address.SetToWildcard(serviceFamily);
|
||||||
|
|
||||||
int32 port;
|
int32 port;
|
||||||
if (address.FindInt32("port", &port) != B_OK)
|
if (address.FindInt32("port", &port) != B_OK)
|
||||||
port = servicePort;
|
port = servicePort;
|
||||||
|
|
||||||
set_port(familyIndex, serviceAddress.address, port);
|
serviceAddress.address.SetPort(port);
|
||||||
serviceAddress.socket = -1;
|
serviceAddress.socket = -1;
|
||||||
|
|
||||||
serviceAddress.owner = service;
|
serviceAddress.owner = service;
|
||||||
@@ -472,9 +470,8 @@ Services::_ToService(const BMessage& message, struct service*& service)
|
|||||||
serviceAddress.family = serviceFamily;
|
serviceAddress.family = serviceFamily;
|
||||||
serviceAddress.type = serviceType;
|
serviceAddress.type = serviceType;
|
||||||
serviceAddress.protocol = serviceProtocol;
|
serviceAddress.protocol = serviceProtocol;
|
||||||
|
serviceAddress.address.SetToWildcard(serviceFamily, servicePort);
|
||||||
|
|
||||||
set_any_address(serviceFamilyIndex, serviceAddress.address);
|
|
||||||
set_port(serviceFamilyIndex, serviceAddress.address, servicePort);
|
|
||||||
serviceAddress.socket = -1;
|
serviceAddress.socket = -1;
|
||||||
|
|
||||||
serviceAddress.owner = service;
|
serviceAddress.owner = service;
|
||||||
|
|||||||
Reference in New Issue
Block a user