From a690e25952e477f92930a8bc34d52d2e2ffe2a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 17 Aug 2010 09:15:33 +0000 Subject: [PATCH] * 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 --- .../network/libnetapi/NetworkInterface.cpp | 61 ++++++++++++------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/src/kits/network/libnetapi/NetworkInterface.cpp b/src/kits/network/libnetapi/NetworkInterface.cpp index 67cb6177ca..223dc24078 100644 --- a/src/kits/network/libnetapi/NetworkInterface.cpp +++ b/src/kits/network/libnetapi/NetworkInterface.cpp @@ -13,11 +13,29 @@ #include +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 do_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address, 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) return errno; @@ -34,7 +52,7 @@ do_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address, address.Mask().Length()); memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(), address.Broadcast().Length()); - + if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0) return errno; @@ -59,9 +77,9 @@ do_ifaliasreq(const char* name, int32 option, 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) return errno; @@ -181,7 +199,7 @@ BNetworkInterface::SetTo(uint32 index) ifreq request; request.ifr_index = index; - status_t status = do_request(request, "", SIOCGIFNAME); + status_t status = do_request(AF_INET, request, "", SIOCGIFNAME); if (status != B_OK) return status; @@ -194,7 +212,7 @@ bool BNetworkInterface::Exists() const { 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 { ifreq request; - if (do_request(request, Name(), SIOCGIFFLAGS) != B_OK) + if (do_request(AF_INET, request, Name(), SIOCGIFFLAGS) != B_OK) return 0; return request.ifr_flags; @@ -220,7 +238,7 @@ uint32 BNetworkInterface::MTU() const { ifreq request; - if (do_request(request, Name(), SIOCGIFMTU) != B_OK) + if (do_request(AF_INET, request, Name(), SIOCGIFMTU) != B_OK) return 0; return request.ifr_mtu; @@ -231,7 +249,7 @@ int32 BNetworkInterface::Media() const { ifreq request; - if (do_request(request, Name(), SIOCGIFMEDIA) != B_OK) + if (do_request(AF_INET, request, Name(), SIOCGIFMEDIA) != B_OK) return -1; return request.ifr_media; @@ -242,7 +260,7 @@ uint32 BNetworkInterface::Metric() const { ifreq request; - if (do_request(request, Name(), SIOCGIFMETRIC) != B_OK) + if (do_request(AF_INET, request, Name(), SIOCGIFMETRIC) != B_OK) return 0; return request.ifr_metric; @@ -253,7 +271,7 @@ uint32 BNetworkInterface::Type() const { ifreq request; - if (do_request(request, Name(), SIOCGIFTYPE) != B_OK) + if (do_request(AF_INET, request, Name(), SIOCGIFTYPE) != B_OK) return 0; return request.ifr_type; @@ -264,7 +282,7 @@ status_t BNetworkInterface::GetStats(ifreq_stats& stats) { ifreq request; - status_t status = do_request(request, Name(), SIOCGIFSTATS); + status_t status = do_request(AF_INET, request, Name(), SIOCGIFSTATS); if (status != B_OK) return status; @@ -285,7 +303,7 @@ BNetworkInterface::SetFlags(uint32 flags) { ifreq request; 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; 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; 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; 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 { 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 request.ifr_count; @@ -349,7 +367,7 @@ BNetworkInterface::FindAddress(const BNetworkAddress& address) strlcpy(request.ifra_name, Name(), IF_NAMESIZE); request.ifra_index = -1; memcpy(&request.ifra_addr, &address.SockAddr(), address.Length()); - + if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq)) < 0) return errno; @@ -373,7 +391,7 @@ BNetworkInterface::FindFirstAddress(int family) strlcpy(request.ifra_name, Name(), IF_NAMESIZE); request.ifra_index = -1; request.ifra_addr.ss_family = AF_UNSPEC; - + if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq)) < 0) return errno; @@ -413,7 +431,8 @@ BNetworkInterface::RemoveAddress(const BNetworkInterfaceAddress& address) memcpy(&request.ifr_addr, &address.Address().SockAddr(), 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; 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); }