* BNetworkInterface must adopt the family from the address, if possible. This
should fix "ifconfig" for IPv6. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38177 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -13,11 +13,29 @@
|
|||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
do_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address,
|
do_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address,
|
||||||
bool readBack = false)
|
bool readBack = false)
|
||||||
{
|
{
|
||||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
int family = AF_INET;
|
||||||
|
if (!readBack)
|
||||||
|
family = family_from_interface_address(address);
|
||||||
|
|
||||||
|
int socket = ::socket(family, SOCK_DGRAM, 0);
|
||||||
if (socket < 0)
|
if (socket < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
@@ -34,7 +52,7 @@ do_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address,
|
|||||||
address.Mask().Length());
|
address.Mask().Length());
|
||||||
memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(),
|
memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(),
|
||||||
address.Broadcast().Length());
|
address.Broadcast().Length());
|
||||||
|
|
||||||
if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
|
if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
@@ -59,9 +77,9 @@ do_ifaliasreq(const char* name, int32 option,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
do_request(ifreq& request, const char* name, int option)
|
do_request(int family, ifreq& request, const char* name, int option)
|
||||||
{
|
{
|
||||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
int socket = ::socket(family, SOCK_DGRAM, 0);
|
||||||
if (socket < 0)
|
if (socket < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
@@ -181,7 +199,7 @@ BNetworkInterface::SetTo(uint32 index)
|
|||||||
ifreq request;
|
ifreq request;
|
||||||
request.ifr_index = index;
|
request.ifr_index = index;
|
||||||
|
|
||||||
status_t status = do_request(request, "", SIOCGIFNAME);
|
status_t status = do_request(AF_INET, request, "", SIOCGIFNAME);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -194,7 +212,7 @@ bool
|
|||||||
BNetworkInterface::Exists() const
|
BNetworkInterface::Exists() const
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
return do_request(request, Name(), SIOCGIFINDEX) == B_OK;
|
return do_request(AF_INET, request, Name(), SIOCGIFINDEX) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -209,7 +227,7 @@ uint32
|
|||||||
BNetworkInterface::Flags() const
|
BNetworkInterface::Flags() const
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
if (do_request(request, Name(), SIOCGIFFLAGS) != B_OK)
|
if (do_request(AF_INET, request, Name(), SIOCGIFFLAGS) != B_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return request.ifr_flags;
|
return request.ifr_flags;
|
||||||
@@ -220,7 +238,7 @@ uint32
|
|||||||
BNetworkInterface::MTU() const
|
BNetworkInterface::MTU() const
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
if (do_request(request, Name(), SIOCGIFMTU) != B_OK)
|
if (do_request(AF_INET, request, Name(), SIOCGIFMTU) != B_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return request.ifr_mtu;
|
return request.ifr_mtu;
|
||||||
@@ -231,7 +249,7 @@ int32
|
|||||||
BNetworkInterface::Media() const
|
BNetworkInterface::Media() const
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
if (do_request(request, Name(), SIOCGIFMEDIA) != B_OK)
|
if (do_request(AF_INET, request, Name(), SIOCGIFMEDIA) != B_OK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return request.ifr_media;
|
return request.ifr_media;
|
||||||
@@ -242,7 +260,7 @@ uint32
|
|||||||
BNetworkInterface::Metric() const
|
BNetworkInterface::Metric() const
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
if (do_request(request, Name(), SIOCGIFMETRIC) != B_OK)
|
if (do_request(AF_INET, request, Name(), SIOCGIFMETRIC) != B_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return request.ifr_metric;
|
return request.ifr_metric;
|
||||||
@@ -253,7 +271,7 @@ uint32
|
|||||||
BNetworkInterface::Type() const
|
BNetworkInterface::Type() const
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
if (do_request(request, Name(), SIOCGIFTYPE) != B_OK)
|
if (do_request(AF_INET, request, Name(), SIOCGIFTYPE) != B_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return request.ifr_type;
|
return request.ifr_type;
|
||||||
@@ -264,7 +282,7 @@ status_t
|
|||||||
BNetworkInterface::GetStats(ifreq_stats& stats)
|
BNetworkInterface::GetStats(ifreq_stats& stats)
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
status_t status = do_request(request, Name(), SIOCGIFSTATS);
|
status_t status = do_request(AF_INET, request, Name(), SIOCGIFSTATS);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -285,7 +303,7 @@ BNetworkInterface::SetFlags(uint32 flags)
|
|||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
request.ifr_flags = flags;
|
request.ifr_flags = flags;
|
||||||
return do_request(request, Name(), SIOCSIFFLAGS);
|
return do_request(AF_INET, request, Name(), SIOCSIFFLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -294,7 +312,7 @@ BNetworkInterface::SetMTU(uint32 mtu)
|
|||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
request.ifr_mtu = mtu;
|
request.ifr_mtu = mtu;
|
||||||
return do_request(request, Name(), SIOCSIFMTU);
|
return do_request(AF_INET, request, Name(), SIOCSIFMTU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -303,7 +321,7 @@ BNetworkInterface::SetMedia(int32 media)
|
|||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
request.ifr_media = media;
|
request.ifr_media = media;
|
||||||
return do_request(request, Name(), SIOCSIFMEDIA);
|
return do_request(AF_INET, request, Name(), SIOCSIFMEDIA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -312,7 +330,7 @@ BNetworkInterface::SetMetric(uint32 metric)
|
|||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
request.ifr_metric = metric;
|
request.ifr_metric = metric;
|
||||||
return do_request(request, Name(), SIOCSIFMETRIC);
|
return do_request(AF_INET, request, Name(), SIOCSIFMETRIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -320,7 +338,7 @@ int32
|
|||||||
BNetworkInterface::CountAddresses() const
|
BNetworkInterface::CountAddresses() const
|
||||||
{
|
{
|
||||||
ifreq request;
|
ifreq request;
|
||||||
if (do_request(request, Name(), B_SOCKET_COUNT_ALIASES) != B_OK)
|
if (do_request(AF_INET, request, Name(), B_SOCKET_COUNT_ALIASES) != B_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return request.ifr_count;
|
return request.ifr_count;
|
||||||
@@ -349,7 +367,7 @@ BNetworkInterface::FindAddress(const BNetworkAddress& address)
|
|||||||
strlcpy(request.ifra_name, Name(), IF_NAMESIZE);
|
strlcpy(request.ifra_name, Name(), IF_NAMESIZE);
|
||||||
request.ifra_index = -1;
|
request.ifra_index = -1;
|
||||||
memcpy(&request.ifra_addr, &address.SockAddr(), address.Length());
|
memcpy(&request.ifra_addr, &address.SockAddr(), address.Length());
|
||||||
|
|
||||||
if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq))
|
if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq))
|
||||||
< 0)
|
< 0)
|
||||||
return errno;
|
return errno;
|
||||||
@@ -373,7 +391,7 @@ BNetworkInterface::FindFirstAddress(int family)
|
|||||||
strlcpy(request.ifra_name, Name(), IF_NAMESIZE);
|
strlcpy(request.ifra_name, Name(), IF_NAMESIZE);
|
||||||
request.ifra_index = -1;
|
request.ifra_index = -1;
|
||||||
request.ifra_addr.ss_family = AF_UNSPEC;
|
request.ifra_addr.ss_family = AF_UNSPEC;
|
||||||
|
|
||||||
if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq))
|
if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq))
|
||||||
< 0)
|
< 0)
|
||||||
return errno;
|
return errno;
|
||||||
@@ -413,7 +431,8 @@ BNetworkInterface::RemoveAddress(const BNetworkInterfaceAddress& address)
|
|||||||
memcpy(&request.ifr_addr, &address.Address().SockAddr(),
|
memcpy(&request.ifr_addr, &address.Address().SockAddr(),
|
||||||
address.Address().Length());
|
address.Address().Length());
|
||||||
|
|
||||||
return do_request(request, Name(), B_SOCKET_REMOVE_ALIAS);
|
return do_request(family_from_interface_address(address), request, Name(),
|
||||||
|
B_SOCKET_REMOVE_ALIAS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -423,7 +442,7 @@ BNetworkInterface::RemoveAddress(const BNetworkAddress& address)
|
|||||||
ifreq request;
|
ifreq request;
|
||||||
memcpy(&request.ifr_addr, &address.SockAddr(), address.Length());
|
memcpy(&request.ifr_addr, &address.SockAddr(), address.Length());
|
||||||
|
|
||||||
return do_request(request, Name(), B_SOCKET_REMOVE_ALIAS);
|
return do_request(address.Family(), request, Name(), B_SOCKET_REMOVE_ALIAS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user