Move getifaddrs to libnetwork again.
* BNetworkInterfaceAddress is moved to libnetwork. It is modified to not use BNetworkAddress (which is in libbnetapi) and instead use sockaddr and sockaddr_storage directly. All callers are adjusted to this. * Some support code is shared between BNetworkInterface and BNetworkInterfaceAddress, move it to libnetwork but in the BPrivate namespace.
This commit is contained in:
parent
a66de90c49
commit
31ea76548a
@ -138,9 +138,7 @@ public:
|
|||||||
|
|
||||||
operator const sockaddr*() const;
|
operator const sockaddr*() const;
|
||||||
operator const sockaddr&() const;
|
operator const sockaddr&() const;
|
||||||
operator const sockaddr*();
|
|
||||||
operator sockaddr*();
|
operator sockaddr*();
|
||||||
operator const sockaddr&();
|
|
||||||
operator sockaddr&();
|
operator sockaddr&();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -8,11 +8,12 @@
|
|||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_types.h>
|
#include <net/if_types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <NetworkAddress.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
class BNetworkAddress;
|
||||||
class BNetworkInterface;
|
class BNetworkInterface;
|
||||||
|
|
||||||
|
|
||||||
@ -21,24 +22,20 @@ public:
|
|||||||
BNetworkInterfaceAddress();
|
BNetworkInterfaceAddress();
|
||||||
~BNetworkInterfaceAddress();
|
~BNetworkInterfaceAddress();
|
||||||
|
|
||||||
status_t SetTo(const BNetworkInterface& interface,
|
status_t SetTo(const char* interfaceName,
|
||||||
int32 index);
|
int32 index);
|
||||||
|
|
||||||
void SetAddress(const BNetworkAddress& address);
|
void SetAddress(const sockaddr& address);
|
||||||
void SetMask(const BNetworkAddress& mask);
|
void SetMask(const sockaddr& mask);
|
||||||
void SetBroadcast(const BNetworkAddress& broadcast);
|
void SetBroadcast(const sockaddr& broadcast);
|
||||||
void SetDestination(
|
void SetDestination(const sockaddr& destination);
|
||||||
const BNetworkAddress& destination);
|
|
||||||
|
|
||||||
BNetworkAddress& Address() { return fAddress; }
|
const sockaddr& Address() const { return (sockaddr&)fAddress; }
|
||||||
BNetworkAddress& Mask() { return fMask; }
|
const sockaddr& Mask() const { return (sockaddr&)fMask; }
|
||||||
BNetworkAddress& Broadcast() { return fBroadcast; }
|
const sockaddr& Broadcast() const
|
||||||
BNetworkAddress& Destination() { return fBroadcast; }
|
{ return (sockaddr&)fBroadcast; }
|
||||||
|
const sockaddr& Destination() const
|
||||||
const BNetworkAddress& Address() const { return fAddress; }
|
{ return (sockaddr&)fBroadcast; }
|
||||||
const BNetworkAddress& Mask() const { return fMask; }
|
|
||||||
const BNetworkAddress& Broadcast() const { return fBroadcast; }
|
|
||||||
const BNetworkAddress& Destination() const { return fBroadcast; }
|
|
||||||
|
|
||||||
void SetFlags(uint32 flags);
|
void SetFlags(uint32 flags);
|
||||||
uint32 Flags() const { return fFlags; }
|
uint32 Flags() const { return fFlags; }
|
||||||
@ -47,9 +44,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int32 fIndex;
|
int32 fIndex;
|
||||||
BNetworkAddress fAddress;
|
sockaddr_storage fAddress;
|
||||||
BNetworkAddress fMask;
|
sockaddr_storage fMask;
|
||||||
BNetworkAddress fBroadcast;
|
sockaddr_storage fBroadcast;
|
||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -357,9 +357,12 @@ NetworkStatusView::_ShowConfiguration(BMessage* message)
|
|||||||
|
|
||||||
size_t boldLength = text.Length();
|
size_t boldLength = text.Length();
|
||||||
|
|
||||||
text << "\n" << B_TRANSLATE("Address") << ": " << address.Address().ToString();
|
text << "\n" << B_TRANSLATE("Address") << ": "
|
||||||
text << "\n" << B_TRANSLATE("Broadcast") << ": " << address.Broadcast().ToString();
|
<< BNetworkAddress(address.Address()).ToString();
|
||||||
text << "\n" << B_TRANSLATE("Netmask") << ": " << address.Mask().ToString();
|
text << "\n" << B_TRANSLATE("Broadcast") << ": "
|
||||||
|
<< BNetworkAddress(address.Broadcast()).ToString();
|
||||||
|
text << "\n" << B_TRANSLATE("Netmask") << ": "
|
||||||
|
<< BNetworkAddress(address.Mask()).ToString();
|
||||||
|
|
||||||
BAlert* alert = new BAlert(name, text.String(), B_TRANSLATE("OK"));
|
BAlert* alert = new BAlert(name, text.String(), B_TRANSLATE("OK"));
|
||||||
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
||||||
|
@ -474,20 +474,24 @@ list_interface_addresses(BNetworkInterface& interface, uint32 flags)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
const address_family* family
|
const address_family* family
|
||||||
= address_family_for(address.Address().Family());
|
= address_family_for(address.Address().sa_family);
|
||||||
|
|
||||||
printf("\t%s addr: %s", family->name,
|
printf("\t%s addr: %s", family->name,
|
||||||
address.Address().ToString().String());
|
BNetworkAddress(address.Address()).ToString().String());
|
||||||
|
|
||||||
if ((flags & IFF_BROADCAST) != 0)
|
if ((flags & IFF_BROADCAST) != 0) {
|
||||||
printf(", Bcast: %s", address.Broadcast().ToString().String());
|
printf(", Bcast: %s",
|
||||||
|
BNetworkAddress(address.Broadcast()).ToString().String());
|
||||||
|
}
|
||||||
|
|
||||||
switch (family->preferred_format) {
|
switch (family->preferred_format) {
|
||||||
case PREFER_OUTPUT_MASK:
|
case PREFER_OUTPUT_MASK:
|
||||||
printf(", Mask: %s", address.Mask().ToString().String());
|
printf(", Mask: %s",
|
||||||
|
BNetworkAddress(address.Mask()).ToString().String());
|
||||||
break;
|
break;
|
||||||
case PREFER_OUTPUT_PREFIX_LENGTH:
|
case PREFER_OUTPUT_PREFIX_LENGTH:
|
||||||
printf(", Prefix Length: %zu", address.Mask().PrefixLength());
|
printf(", Prefix Length: %zu",
|
||||||
|
BNetworkAddress(address.Mask()).PrefixLength());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,13 +11,18 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
local architecture = $(TARGET_PACKAGING_ARCH) ;
|
local architecture = $(TARGET_PACKAGING_ARCH) ;
|
||||||
|
|
||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||||
|
|
||||||
local libnetwork = [ MultiArchDefaultGristFiles libnetwork.so ] ;
|
local libnetwork = [ MultiArchDefaultGristFiles libnetwork.so ] ;
|
||||||
SharedLibrary $(libnetwork) :
|
SharedLibrary $(libnetwork) :
|
||||||
|
getifaddrs.cpp
|
||||||
init.cpp
|
init.cpp
|
||||||
interfaces.cpp
|
interfaces.cpp
|
||||||
socket.cpp
|
socket.cpp
|
||||||
r5_compatibility.cpp
|
r5_compatibility.cpp
|
||||||
|
|
||||||
|
NetworkInterfaceAddress.cpp
|
||||||
|
|
||||||
:
|
:
|
||||||
<libbind!$(architecture)>libbind.o
|
<libbind!$(architecture)>libbind.o
|
||||||
[ TargetLibsupc++ ]
|
[ TargetLibsupc++ ]
|
||||||
|
135
src/kits/network/NetworkInterfaceAddress.cpp
Normal file
135
src/kits/network/NetworkInterfaceAddress.cpp
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, Axel Dörfler, axeld@pinc-software.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <NetworkInterface.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
int
|
||||||
|
family_from_interface_address(const BNetworkInterfaceAddress& address)
|
||||||
|
{
|
||||||
|
if (address.Address().sa_family != AF_UNSPEC)
|
||||||
|
return address.Address().sa_family;
|
||||||
|
if (address.Mask().sa_family != AF_UNSPEC)
|
||||||
|
return address.Mask().sa_family;
|
||||||
|
if (address.Destination().sa_family != AF_UNSPEC)
|
||||||
|
return address.Destination().sa_family;
|
||||||
|
|
||||||
|
return AF_INET;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
do_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address,
|
||||||
|
bool readBack = false)
|
||||||
|
{
|
||||||
|
int family = AF_INET;
|
||||||
|
if (!readBack)
|
||||||
|
family = family_from_interface_address(address);
|
||||||
|
|
||||||
|
int socket = ::socket(family, SOCK_DGRAM, 0);
|
||||||
|
if (socket < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
FileDescriptorCloser closer(socket);
|
||||||
|
|
||||||
|
ifaliasreq request;
|
||||||
|
strlcpy(request.ifra_name, name, IF_NAMESIZE);
|
||||||
|
request.ifra_index = address.Index();
|
||||||
|
request.ifra_flags = address.Flags();
|
||||||
|
|
||||||
|
memcpy(&request.ifra_addr, &address.Address(),
|
||||||
|
address.Address().sa_len);
|
||||||
|
memcpy(&request.ifra_mask, &address.Mask(),
|
||||||
|
address.Mask().sa_len);
|
||||||
|
memcpy(&request.ifra_broadaddr, &address.Broadcast(),
|
||||||
|
address.Broadcast().sa_len);
|
||||||
|
|
||||||
|
if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
if (readBack) {
|
||||||
|
address.SetFlags(request.ifra_flags);
|
||||||
|
address.SetAddress((sockaddr&)request.ifra_addr);
|
||||||
|
address.SetMask((sockaddr&)request.ifra_mask);
|
||||||
|
address.SetBroadcast((sockaddr&)request.ifra_broadaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
BNetworkInterfaceAddress::BNetworkInterfaceAddress()
|
||||||
|
:
|
||||||
|
fIndex(-1),
|
||||||
|
fFlags(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BNetworkInterfaceAddress::~BNetworkInterfaceAddress()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BNetworkInterfaceAddress::SetTo(const char* name, int32 index)
|
||||||
|
{
|
||||||
|
fIndex = index;
|
||||||
|
return do_ifaliasreq(name, B_SOCKET_GET_ALIAS, *this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNetworkInterfaceAddress::SetAddress(const sockaddr& address)
|
||||||
|
{
|
||||||
|
memcpy(&fAddress, &address, address.sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNetworkInterfaceAddress::SetMask(const sockaddr& mask)
|
||||||
|
{
|
||||||
|
memcpy(&fMask, &mask, mask.sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNetworkInterfaceAddress::SetBroadcast(const sockaddr& broadcast)
|
||||||
|
{
|
||||||
|
memcpy(&fBroadcast, &broadcast, broadcast.sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNetworkInterfaceAddress::SetDestination(const sockaddr& destination)
|
||||||
|
{
|
||||||
|
memcpy(&fBroadcast, &destination, destination.sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNetworkInterfaceAddress::SetFlags(uint32 flags)
|
||||||
|
{
|
||||||
|
fFlags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
141
src/kits/network/getifaddrs.cpp
Normal file
141
src/kits/network/getifaddrs.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
#include <NetworkAddress.h>
|
||||||
|
#include <NetworkInterface.h>
|
||||||
|
#include <NetworkRoster.h>
|
||||||
|
|
||||||
|
|
||||||
|
// This structure has an ifaddrs and all the information it refers to. We can
|
||||||
|
// allocate this in a single call to the allocator instead of allocating each
|
||||||
|
// address, the name, and the ifaddr struct itself separately. This simplifies
|
||||||
|
// the error handling and the freeing of the structure, and reduces the stress
|
||||||
|
// on the memory allocator.
|
||||||
|
struct IfaddrContainer {
|
||||||
|
ifaddrs header;
|
||||||
|
|
||||||
|
sockaddr_storage address;
|
||||||
|
sockaddr_storage mask;
|
||||||
|
sockaddr_storage destination;
|
||||||
|
char name[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
getifaddrs(struct ifaddrs **ifap)
|
||||||
|
{
|
||||||
|
if (ifap == NULL) {
|
||||||
|
errno = B_BAD_VALUE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a list of all interfaces
|
||||||
|
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (socket < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FileDescriptorCloser closer(socket);
|
||||||
|
|
||||||
|
ifconf config;
|
||||||
|
config.ifc_len = sizeof(config.ifc_value);
|
||||||
|
if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
size_t count = (size_t)config.ifc_value;
|
||||||
|
if (count == 0) {
|
||||||
|
errno = B_BAD_VALUE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* buffer = (char*)malloc(count * sizeof(struct ifreq));
|
||||||
|
if (buffer == NULL) {
|
||||||
|
errno = B_NO_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryDeleter deleter(buffer);
|
||||||
|
|
||||||
|
config.ifc_len = count * sizeof(struct ifreq);
|
||||||
|
config.ifc_buf = buffer;
|
||||||
|
if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ifreq* interfaces = (ifreq*)buffer;
|
||||||
|
ifreq* end = (ifreq*)(buffer + config.ifc_len);
|
||||||
|
|
||||||
|
struct ifaddrs* previous = NULL;
|
||||||
|
struct ifaddrs* current = NULL;
|
||||||
|
|
||||||
|
for (uint32 i = 0; interfaces < end; i++) {
|
||||||
|
BNetworkInterfaceAddress address;
|
||||||
|
int32 j = 0;
|
||||||
|
|
||||||
|
while (address.SetTo(interfaces->ifr_name, j++) == B_OK) {
|
||||||
|
IfaddrContainer* container = (IfaddrContainer*)malloc(
|
||||||
|
sizeof(IfaddrContainer) + strlen(interfaces->ifr_name) + 1);
|
||||||
|
if (container == NULL) {
|
||||||
|
freeifaddrs(previous);
|
||||||
|
errno = B_NO_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = &container->header;
|
||||||
|
|
||||||
|
strcpy(container->name, interfaces->ifr_name);
|
||||||
|
current->ifa_name = container->name;
|
||||||
|
current->ifa_flags = address.Flags();
|
||||||
|
|
||||||
|
memcpy(&container->address, &address.Address(),
|
||||||
|
address.Address().sa_len);
|
||||||
|
current->ifa_addr = (sockaddr*)&container->address;
|
||||||
|
|
||||||
|
memcpy(&container->mask, &address.Mask(), address.Mask().sa_len);
|
||||||
|
current->ifa_netmask = (sockaddr*)&container->mask;
|
||||||
|
|
||||||
|
memcpy(&container->destination, &address.Destination(),
|
||||||
|
address.Destination().sa_len);
|
||||||
|
current->ifa_dstaddr = (sockaddr*)&container->destination;
|
||||||
|
|
||||||
|
current->ifa_data = NULL;
|
||||||
|
// Could point to extra information, if we have something to
|
||||||
|
// add.
|
||||||
|
|
||||||
|
// Chain this interface with the next one
|
||||||
|
current->ifa_next = previous;
|
||||||
|
previous = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*ifap = current;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
freeifaddrs(struct ifaddrs *ifa)
|
||||||
|
{
|
||||||
|
// Since each item was allocated as a single chunk using the IfaddrContainer,
|
||||||
|
// all we need to do is free that.
|
||||||
|
struct ifaddrs* next;
|
||||||
|
while (ifa != NULL) {
|
||||||
|
next = ifa->ifa_next;
|
||||||
|
free(ifa);
|
||||||
|
ifa = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -197,7 +197,7 @@ BAbstractSocket::Connect(const BNetworkAddress& peer, int type,
|
|||||||
return fInitStatus;
|
return fInitStatus;
|
||||||
|
|
||||||
BNetworkAddress normalized = peer;
|
BNetworkAddress normalized = peer;
|
||||||
if (connect(fSocket, normalized, normalized.Length()) != 0) {
|
if (connect(fSocket, &normalized.SockAddr(), normalized.Length()) != 0) {
|
||||||
TRACE("%p: connecting to %s: %s\n", this,
|
TRACE("%p: connecting to %s: %s\n", this,
|
||||||
normalized.ToString().c_str(), strerror(errno));
|
normalized.ToString().c_str(), strerror(errno));
|
||||||
return fInitStatus = errno;
|
return fInitStatus = errno;
|
||||||
|
@ -127,9 +127,10 @@ BDatagramSocket::Write(const void* buffer, size_t size)
|
|||||||
{
|
{
|
||||||
ssize_t bytesSent;
|
ssize_t bytesSent;
|
||||||
|
|
||||||
if (!fIsConnected)
|
if (!fIsConnected) {
|
||||||
bytesSent = sendto(Socket(), buffer, size, 0, fPeer, fPeer.Length());
|
bytesSent = sendto(Socket(), buffer, size, 0, &fPeer.SockAddr(),
|
||||||
else
|
fPeer.Length());
|
||||||
|
} else
|
||||||
bytesSent = send(Socket(), buffer, size, 0);
|
bytesSent = send(Socket(), buffer, size, 0);
|
||||||
|
|
||||||
if (bytesSent < 0) {
|
if (bytesSent < 0) {
|
||||||
|
@ -79,7 +79,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
HttpResult.cpp
|
HttpResult.cpp
|
||||||
HttpTime.cpp
|
HttpTime.cpp
|
||||||
|
|
||||||
getifaddrs.cpp
|
|
||||||
notifications.cpp
|
notifications.cpp
|
||||||
|
|
||||||
$(md5Sources)
|
$(md5Sources)
|
||||||
|
@ -1188,24 +1188,12 @@ BNetworkAddress::operator sockaddr*()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BNetworkAddress::operator const sockaddr*()
|
|
||||||
{
|
|
||||||
return (sockaddr*)&fAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BNetworkAddress::operator sockaddr&()
|
BNetworkAddress::operator sockaddr&()
|
||||||
{
|
{
|
||||||
return (sockaddr&)fAddress;
|
return (sockaddr&)fAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BNetworkAddress::operator const sockaddr&()
|
|
||||||
{
|
|
||||||
return (sockaddr&)fAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - private
|
// #pragma mark - private
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,25 +8,25 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <NetServer.h>
|
#include <NetServer.h>
|
||||||
|
#include <NetworkAddress.h>
|
||||||
#include <RouteSupport.h>
|
#include <RouteSupport.h>
|
||||||
|
|
||||||
static int
|
|
||||||
family_from_interface_address(const BNetworkInterfaceAddress& address)
|
|
||||||
{
|
|
||||||
if (address.Address().Family() != AF_UNSPEC)
|
|
||||||
return address.Address().Family();
|
|
||||||
if (address.Mask().Family() != AF_UNSPEC)
|
|
||||||
return address.Mask().Family();
|
|
||||||
if (address.Destination().Family() != AF_UNSPEC)
|
|
||||||
return address.Destination().Family();
|
|
||||||
|
|
||||||
return AF_INET;
|
namespace BPrivate {
|
||||||
}
|
|
||||||
|
status_t do_ifaliasreq(const char* name, int32 option,
|
||||||
|
BNetworkInterfaceAddress& address, bool readBack = false);
|
||||||
|
int family_from_interface_address(const BNetworkInterfaceAddress& address);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -45,46 +45,6 @@ family_from_route(const route_entry& route)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
do_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address,
|
|
||||||
bool readBack = false)
|
|
||||||
{
|
|
||||||
int family = AF_INET;
|
|
||||||
if (!readBack)
|
|
||||||
family = family_from_interface_address(address);
|
|
||||||
|
|
||||||
int socket = ::socket(family, SOCK_DGRAM, 0);
|
|
||||||
if (socket < 0)
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
FileDescriptorCloser closer(socket);
|
|
||||||
|
|
||||||
ifaliasreq request;
|
|
||||||
strlcpy(request.ifra_name, name, IF_NAMESIZE);
|
|
||||||
request.ifra_index = address.Index();
|
|
||||||
request.ifra_flags = address.Flags();
|
|
||||||
|
|
||||||
memcpy(&request.ifra_addr, &address.Address().SockAddr(),
|
|
||||||
address.Address().Length());
|
|
||||||
memcpy(&request.ifra_mask, &address.Mask().SockAddr(),
|
|
||||||
address.Mask().Length());
|
|
||||||
memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(),
|
|
||||||
address.Broadcast().Length());
|
|
||||||
|
|
||||||
if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
if (readBack) {
|
|
||||||
address.SetFlags(request.ifra_flags);
|
|
||||||
address.Address().SetTo(request.ifra_addr);
|
|
||||||
address.Mask().SetTo(request.ifra_mask);
|
|
||||||
address.Broadcast().SetTo(request.ifra_broadaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
do_ifaliasreq(const char* name, int32 option,
|
do_ifaliasreq(const char* name, int32 option,
|
||||||
const BNetworkInterfaceAddress& address)
|
const BNetworkInterfaceAddress& address)
|
||||||
@ -115,65 +75,6 @@ do_request(int family, T& request, const char* name, int option)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
BNetworkInterfaceAddress::BNetworkInterfaceAddress()
|
|
||||||
:
|
|
||||||
fIndex(-1),
|
|
||||||
fFlags(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BNetworkInterfaceAddress::~BNetworkInterfaceAddress()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BNetworkInterfaceAddress::SetTo(const BNetworkInterface& interface, int32 index)
|
|
||||||
{
|
|
||||||
fIndex = index;
|
|
||||||
return do_ifaliasreq(interface.Name(), B_SOCKET_GET_ALIAS, *this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BNetworkInterfaceAddress::SetAddress(const BNetworkAddress& address)
|
|
||||||
{
|
|
||||||
fAddress = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BNetworkInterfaceAddress::SetMask(const BNetworkAddress& mask)
|
|
||||||
{
|
|
||||||
fMask = mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BNetworkInterfaceAddress::SetBroadcast(const BNetworkAddress& broadcast)
|
|
||||||
{
|
|
||||||
fBroadcast = broadcast;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BNetworkInterfaceAddress::SetDestination(const BNetworkAddress& destination)
|
|
||||||
{
|
|
||||||
fBroadcast = destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BNetworkInterfaceAddress::SetFlags(uint32 flags)
|
|
||||||
{
|
|
||||||
fFlags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
BNetworkInterface::BNetworkInterface()
|
BNetworkInterface::BNetworkInterface()
|
||||||
{
|
{
|
||||||
Unset();
|
Unset();
|
||||||
@ -380,7 +281,7 @@ BNetworkInterface::CountAddresses() const
|
|||||||
status_t
|
status_t
|
||||||
BNetworkInterface::GetAddressAt(int32 index, BNetworkInterfaceAddress& address)
|
BNetworkInterface::GetAddressAt(int32 index, BNetworkInterfaceAddress& address)
|
||||||
{
|
{
|
||||||
return address.SetTo(*this, index);
|
return address.SetTo(Name(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -445,7 +346,7 @@ status_t
|
|||||||
BNetworkInterface::AddAddress(const BNetworkAddress& local)
|
BNetworkInterface::AddAddress(const BNetworkAddress& local)
|
||||||
{
|
{
|
||||||
BNetworkInterfaceAddress address;
|
BNetworkInterfaceAddress address;
|
||||||
address.SetAddress(local);
|
address.SetAddress(local.SockAddr());
|
||||||
|
|
||||||
return do_ifaliasreq(Name(), B_SOCKET_ADD_ALIAS, address);
|
return do_ifaliasreq(Name(), B_SOCKET_ADD_ALIAS, address);
|
||||||
}
|
}
|
||||||
@ -462,8 +363,7 @@ status_t
|
|||||||
BNetworkInterface::RemoveAddress(const BNetworkInterfaceAddress& address)
|
BNetworkInterface::RemoveAddress(const BNetworkInterfaceAddress& address)
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
memcpy(&request.ifr_addr, &address.Address().SockAddr(),
|
memcpy(&request.ifr_addr, &address.Address(), address.Address().sa_len);
|
||||||
address.Address().Length());
|
|
||||||
|
|
||||||
return do_request(family_from_interface_address(address), request, Name(),
|
return do_request(family_from_interface_address(address), request, Name(),
|
||||||
B_SOCKET_REMOVE_ALIAS);
|
B_SOCKET_REMOVE_ALIAS);
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015, Haiku, Inc. All Rights Reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Adrien Destugues, pulkomandy@pulkomandy.tk
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
|
||||||
#include <NetworkAddress.h>
|
|
||||||
#include <NetworkInterface.h>
|
|
||||||
#include <NetworkRoster.h>
|
|
||||||
|
|
||||||
#include "compatibility/bsd/ifaddrs.h"
|
|
||||||
|
|
||||||
|
|
||||||
int getifaddrs(struct ifaddrs **ifap)
|
|
||||||
{
|
|
||||||
if (ifap == NULL) {
|
|
||||||
errno = B_BAD_VALUE;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
BNetworkRoster& roster = BNetworkRoster::Default();
|
|
||||||
|
|
||||||
uint32 cookie;
|
|
||||||
|
|
||||||
struct ifaddrs* previous = NULL;
|
|
||||||
struct ifaddrs* current = NULL;
|
|
||||||
BNetworkInterface* interface = new(std::nothrow) BNetworkInterface();
|
|
||||||
if (interface == NULL) {
|
|
||||||
errno = B_NO_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (roster.GetNextInterface(&cookie, *interface) == B_OK) {
|
|
||||||
BNetworkInterfaceAddress address;
|
|
||||||
int32 i = 0;
|
|
||||||
while (interface->GetAddressAt(i++, address) == B_OK) {
|
|
||||||
if (interface == NULL) {
|
|
||||||
freeifaddrs(previous);
|
|
||||||
errno = B_NO_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
current = new(std::nothrow) ifaddrs();
|
|
||||||
if (current == NULL) {
|
|
||||||
freeifaddrs(previous);
|
|
||||||
errno = B_NO_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chain this interface with the next one
|
|
||||||
current->ifa_next = previous;
|
|
||||||
previous = current;
|
|
||||||
|
|
||||||
current->ifa_data = interface;
|
|
||||||
current->ifa_name = interface->Name();
|
|
||||||
// Points to the name in the BNetworkInterface instance, which
|
|
||||||
// is added as ifa_data so freeifaddrs can release it.
|
|
||||||
current->ifa_flags = address.Flags();
|
|
||||||
current->ifa_addr = new sockaddr(address.Address().SockAddr());
|
|
||||||
current->ifa_netmask = new sockaddr(address.Mask().SockAddr());
|
|
||||||
current->ifa_dstaddr = new sockaddr(address.Destination().SockAddr());
|
|
||||||
}
|
|
||||||
|
|
||||||
interface = new(std::nothrow) BNetworkInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete interface;
|
|
||||||
*ifap = current;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
freeifaddrs(struct ifaddrs *ifa)
|
|
||||||
{
|
|
||||||
struct ifaddrs* next;
|
|
||||||
BNetworkInterface* interface = NULL;
|
|
||||||
while (ifa != NULL) {
|
|
||||||
if (ifa->ifa_data != interface) {
|
|
||||||
interface = (BNetworkInterface*)ifa->ifa_data;
|
|
||||||
delete interface;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete ifa->ifa_addr;
|
|
||||||
delete ifa->ifa_netmask;
|
|
||||||
delete ifa->ifa_dstaddr;
|
|
||||||
|
|
||||||
next = ifa->ifa_next;
|
|
||||||
delete ifa;
|
|
||||||
ifa = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -297,16 +297,16 @@ NetworkSettings::SetConfiguration()
|
|||||||
BNetworkInterfaceAddress interfaceConfig;
|
BNetworkInterfaceAddress interfaceConfig;
|
||||||
fNetworkInterface->GetAddressAt(zeroAddr,
|
fNetworkInterface->GetAddressAt(zeroAddr,
|
||||||
interfaceConfig);
|
interfaceConfig);
|
||||||
interfaceConfig.SetAddress(fAddress[inet_id]);
|
interfaceConfig.SetAddress(fAddress[inet_id].SockAddr());
|
||||||
interfaceConfig.SetMask(fNetmask[inet_id]);
|
interfaceConfig.SetMask(fNetmask[inet_id].SockAddr());
|
||||||
fNetworkInterface->SetAddress(interfaceConfig);
|
fNetworkInterface->SetAddress(interfaceConfig);
|
||||||
} else {
|
} else {
|
||||||
// TODO : test this case (no address set for this protocol)
|
// TODO : test this case (no address set for this protocol)
|
||||||
printf("no zeroAddr found for %s(%d), found %" B_PRIu32 "\n",
|
printf("no zeroAddr found for %s(%d), found %" B_PRIu32 "\n",
|
||||||
fProtocols[index].name, inet_id, zeroAddr);
|
fProtocols[index].name, inet_id, zeroAddr);
|
||||||
BNetworkInterfaceAddress interfaceConfig;
|
BNetworkInterfaceAddress interfaceConfig;
|
||||||
interfaceConfig.SetAddress(fAddress[inet_id]);
|
interfaceConfig.SetAddress(fAddress[inet_id].SockAddr());
|
||||||
interfaceConfig.SetMask(fNetmask[inet_id]);
|
interfaceConfig.SetMask(fNetmask[inet_id].SockAddr());
|
||||||
fNetworkInterface->AddAddress(interfaceConfig);
|
fNetworkInterface->AddAddress(interfaceConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ DHCPClient::_Negotiate(dhcp_state state)
|
|||||||
option = 1;
|
option = 1;
|
||||||
setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
|
setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
|
||||||
|
|
||||||
if (bind(socket, local, local.Length()) < 0) {
|
if (bind(socket, &local.SockAddr(), local.Length()) < 0) {
|
||||||
close(socket);
|
close(socket);
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
@ -613,12 +613,12 @@ NetServer::_ConfigureInterface(BMessage& message)
|
|||||||
|
|
||||||
if (!address.IsEmpty() || !mask.IsEmpty() || !broadcast.IsEmpty()) {
|
if (!address.IsEmpty() || !mask.IsEmpty() || !broadcast.IsEmpty()) {
|
||||||
BNetworkInterfaceAddress interfaceAddress;
|
BNetworkInterfaceAddress interfaceAddress;
|
||||||
interfaceAddress.SetAddress(address);
|
interfaceAddress.SetAddress(address.SockAddr());
|
||||||
interfaceAddress.SetMask(mask);
|
interfaceAddress.SetMask(mask.SockAddr());
|
||||||
if (!broadcast.IsEmpty())
|
if (!broadcast.IsEmpty())
|
||||||
interfaceAddress.SetBroadcast(broadcast);
|
interfaceAddress.SetBroadcast(broadcast.SockAddr());
|
||||||
else if (!peer.IsEmpty())
|
else if (!peer.IsEmpty())
|
||||||
interfaceAddress.SetDestination(peer);
|
interfaceAddress.SetDestination(peer.SockAddr());
|
||||||
|
|
||||||
status_t status = interface.SetAddress(interfaceAddress);
|
status_t status = interface.SetAddress(interfaceAddress);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
@ -949,9 +949,9 @@ NetServer::_ConfigureIPv6LinkLocal(const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BNetworkInterfaceAddress interfaceAddress;
|
BNetworkInterfaceAddress interfaceAddress;
|
||||||
interfaceAddress.SetAddress(localLinkAddress);
|
interfaceAddress.SetAddress(localLinkAddress.SockAddr());
|
||||||
interfaceAddress.SetMask(localLinkMask);
|
interfaceAddress.SetMask(localLinkMask.SockAddr());
|
||||||
interfaceAddress.SetBroadcast(localLinkMask);
|
interfaceAddress.SetBroadcast(localLinkMask.SockAddr());
|
||||||
|
|
||||||
/* TODO: Duplicate Address Detection. (DAD)
|
/* TODO: Duplicate Address Detection. (DAD)
|
||||||
Need to blast an icmp packet over the IPv6 network from :: to ensure
|
Need to blast an icmp packet over the IPv6 network from :: to ensure
|
||||||
|
@ -274,8 +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.Length())
|
|| bind(address.socket, &address.address.SockAddr(),
|
||||||
< 0
|
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user