Author: axeld Date: 2010-08-17 11:15:33 +0200 (Tue, 17 Aug 2010) New Revision: 38177 Changeset: http://dev.haiku-os.org/changeset/38177 Modified: haiku/trunk/src/kits/network/libnetapi/NetworkInterface.cpp Log: * BNetworkInterface must adopt the family from the address, if possible. This should fix "ifconfig" for IPv6. Modified: haiku/trunk/src/kits/network/libnetapi/NetworkInterface.cpp =================================================================== --- haiku/trunk/src/kits/network/libnetapi/NetworkInterface.cpp 2010-08-17 08:27:20 UTC (rev 38176) +++ haiku/trunk/src/kits/network/libnetapi/NetworkInterface.cpp 2010-08-17 09:15:33 UTC (rev 38177) @@ -13,11 +13,29 @@ #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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { ifreq request; request.ifr_flags = flags; - return do_request(request, Name(), SIOCSIFFLAGS); + return do_request(AF_INET, request, Name(), SIOCSIFFLAGS); } @@ -294,7 +312,7 @@ { ifreq request; request.ifr_mtu = mtu; - return do_request(request, Name(), SIOCSIFMTU); + return do_request(AF_INET, request, Name(), SIOCSIFMTU); } @@ -303,7 +321,7 @@ { ifreq request; request.ifr_media = media; - return do_request(request, Name(), SIOCSIFMEDIA); + return do_request(AF_INET, request, Name(), SIOCSIFMEDIA); } @@ -312,7 +330,7 @@ { ifreq request; request.ifr_metric = metric; - return do_request(request, Name(), SIOCSIFMETRIC); + return do_request(AF_INET, request, Name(), SIOCSIFMETRIC); } @@ -320,7 +338,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); }