diff --git a/src/inet/InetInterface.cpp b/src/inet/InetInterface.cpp index 42e431106a962f..99f74c007ec953 100644 --- a/src/inet/InetInterface.cpp +++ b/src/inet/InetInterface.cpp @@ -69,54 +69,16 @@ namespace chip { namespace Inet { -/** - * @brief Get the name of a network interface - * - * @param[in] intfId a network interface - * @param[in] nameBuf region of memory to write the interface name - * @param[in] nameBufSize size of the region denoted by \c nameBuf - * - * @retval CHIP_NO_ERROR successful result, interface name written - * @retval CHIP_ERROR_NO_MEMORY name is too large to be written in buffer - * @retval other another system or platform error - * - * @details - * Writes the name of the network interface as \c NUL terminated text string - * at \c nameBuf. The name of the unspecified network interface is the empty - * string. - */ +#if CHIP_SYSTEM_CONFIG_USE_LWIP + DLL_EXPORT CHIP_ERROR GetInterfaceName(InterfaceId intfId, char * nameBuf, size_t nameBufSize) { if (intfId != INET_NULL_INTERFACEID) { -#if CHIP_SYSTEM_CONFIG_USE_LWIP int status = snprintf(nameBuf, nameBufSize, "%c%c%d", intfId->name[0], intfId->name[1], intfId->num); if (status >= static_cast(nameBufSize)) return CHIP_ERROR_NO_MEMORY; return CHIP_NO_ERROR; -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - char intfName[IF_NAMESIZE]; - if (if_indextoname(intfId, intfName) == nullptr) - return CHIP_ERROR_POSIX(errno); - if (strlen(intfName) >= nameBufSize) - return CHIP_ERROR_NO_MEMORY; - strcpy(nameBuf, intfName); - return CHIP_NO_ERROR; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - net_if * currentInterface = net_if_get_by_index(intfId); - if (!currentInterface) - return CHIP_ERROR_INCORRECT_STATE; - const char * name = net_if_get_device(currentInterface)->name; - if (strlen(name) >= nameBufSize) - return CHIP_ERROR_NO_MEMORY; - strcpy(nameBuf, name); - return CHIP_NO_ERROR; - -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF } if (nameBufSize < 1) @@ -126,26 +88,8 @@ DLL_EXPORT CHIP_ERROR GetInterfaceName(InterfaceId intfId, char * nameBuf, size_ return CHIP_NO_ERROR; } -/** - * @brief Search the list of network interfaces for the indicated name. - * - * @param[in] intfName name of the network interface to find - * @param[out] intfId indicator of the network interface to assign - * - * @retval CHIP_NO_ERROR success, network interface indicated - * @retval INET_ERROR_UNKNOWN_INTERFACE no network interface found - * @retval other another system or platform error - * - * @details - * On LwIP, this function must be called with the LwIP stack lock acquired. - * - * The \c intfId parameter is not updated unless the value returned is - * \c CHIP_NO_ERROR. It should be initialized with \c INET_NULL_INTERFACEID - * before calling this function. - */ DLL_EXPORT CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId) { -#if CHIP_SYSTEM_CONFIG_USE_LWIP if (strlen(intfName) < 3) return INET_ERROR_UNKNOWN_INTERFACE; char * parseEnd; @@ -167,33 +111,215 @@ DLL_EXPORT CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & int } intfId = INET_NULL_INTERFACEID; return INET_ERROR_UNKNOWN_INTERFACE; -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP +} -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - intfId = if_nametoindex(intfName); - if (intfId == 0) - return (errno == ENXIO) ? INET_ERROR_UNKNOWN_INTERFACE : CHIP_ERROR_POSIX(errno); - return CHIP_NO_ERROR; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS +bool InterfaceIterator::Next() +{ -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - int currentId = 0; - net_if * currentInterface; + // Lock LwIP stack + LOCK_TCPIP_CORE(); - while ((currentInterface = net_if_get_by_index(++currentId)) != nullptr) + // Verify the previous netif is still on the list if netifs. If so, + // advance to the next nextif. + struct netif * prevNetif = mCurNetif; +#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 0 && defined(NETIF_FOREACH) + NETIF_FOREACH(mCurNetif) +#else + for (mCurNetif = netif_list; mCurNetif != NULL; mCurNetif = mCurNetif->next) +#endif { - if (strcmp(net_if_get_device(currentInterface)->name, intfName) == 0) + if (mCurNetif == prevNetif) { - intfId = currentId; - return CHIP_NO_ERROR; + mCurNetif = mCurNetif->next; + break; } } - return INET_ERROR_UNKNOWN_INTERFACE; -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -} // namespace Inet + + // Unlock LwIP stack + UNLOCK_TCPIP_CORE(); + + return mCurNetif != NULL; +} + +CHIP_ERROR InterfaceIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) +{ + VerifyOrReturnError(HasCurrent(), CHIP_ERROR_INCORRECT_STATE); + return ::chip::Inet::GetInterfaceName(mCurNetif, nameBuf, nameBufSize); +} + +bool InterfaceIterator::IsUp() +{ + return HasCurrent() && netif_is_up(mCurNetif); +} + +bool InterfaceIterator::SupportsMulticast() +{ + return HasCurrent() && +#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 + (mCurNetif->flags & (NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_BROADCAST)) != 0; +#else + (mCurNetif->flags & NETIF_FLAG_POINTTOPOINT) == 0; +#endif // LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 +} + +bool InterfaceIterator::HasBroadcastAddress() +{ + return HasCurrent() && (mCurNetif->flags & NETIF_FLAG_BROADCAST) != 0; +} + +bool InterfaceAddressIterator::HasCurrent() +{ + return mIntfIter.HasCurrent() && ((mCurAddrIndex != kBeforeStartIndex) || Next()); +} + +bool InterfaceAddressIterator::Next() +{ + mCurAddrIndex++; + + while (mIntfIter.HasCurrent()) + { + struct netif * curIntf = mIntfIter.GetInterfaceId(); + + while (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES) + { + if (ip6_addr_isvalid(netif_ip6_addr_state(curIntf, mCurAddrIndex))) + { + return true; + } + mCurAddrIndex++; + } + +#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 + if (mCurAddrIndex == LWIP_IPV6_NUM_ADDRESSES) + { + if (!ip4_addr_isany(netif_ip4_addr(curIntf))) + { + return true; + } + } +#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 + + mIntfIter.Next(); + mCurAddrIndex = 0; + } + + return false; +} + +IPAddress InterfaceAddressIterator::GetAddress() +{ + if (HasCurrent()) + { + struct netif * curIntf = mIntfIter.GetInterfaceId(); + + if (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES) + { + return IPAddress::FromIPv6(*netif_ip6_addr(curIntf, mCurAddrIndex)); + } +#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 + else + { + return IPAddress::FromIPv4(*netif_ip4_addr(curIntf)); + } +#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 + } + + return IPAddress::Any; +} + +uint8_t InterfaceAddressIterator::GetPrefixLength() +{ + if (HasCurrent()) + { + if (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES) + { + return 64; + } +#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 + else + { + struct netif * curIntf = mIntfIter.GetInterfaceId(); + return NetmaskToPrefixLength((const uint8_t *) netif_ip4_netmask(curIntf), 4); + } +#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 + } + return 0; +} + +InterfaceId InterfaceAddressIterator::GetInterfaceId() +{ + if (HasCurrent()) + { + return mIntfIter.GetInterfaceId(); + } + return INET_NULL_INTERFACEID; +} + +CHIP_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) +{ + VerifyOrReturnError(HasCurrent(), CHIP_ERROR_INCORRECT_STATE); + return mIntfIter.GetInterfaceName(nameBuf, nameBufSize); +} + +bool InterfaceAddressIterator::IsUp() +{ + if (HasCurrent()) + { + return mIntfIter.IsUp(); + } + return false; +} + +bool InterfaceAddressIterator::SupportsMulticast() +{ + if (HasCurrent()) + { + return mIntfIter.SupportsMulticast(); + } + return false; +} + +bool InterfaceAddressIterator::HasBroadcastAddress() +{ + if (HasCurrent()) + { + return mIntfIter.HasBroadcastAddress(); + } + return false; +} + +#endif // CHIP_SYSTEM_CONFIG_USE_LWIP #if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS +DLL_EXPORT CHIP_ERROR GetInterfaceName(InterfaceId intfId, char * nameBuf, size_t nameBufSize) +{ + if (intfId != INET_NULL_INTERFACEID) + { + char intfName[IF_NAMESIZE]; + if (if_indextoname(intfId, intfName) == nullptr) + return CHIP_ERROR_POSIX(errno); + if (strlen(intfName) >= nameBufSize) + return CHIP_ERROR_NO_MEMORY; + strcpy(nameBuf, intfName); + return CHIP_NO_ERROR; + } + + if (nameBufSize < 1) + return CHIP_ERROR_NO_MEMORY; + + nameBuf[0] = 0; + return CHIP_NO_ERROR; +} + +DLL_EXPORT CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId) +{ + intfId = if_nametoindex(intfName); + if (intfId == 0) + return (errno == ENXIO) ? INET_ERROR_UNKNOWN_INTERFACE : CHIP_ERROR_POSIX(errno); + return CHIP_NO_ERROR; +} + static int sIOCTLSocket = -1; /** @@ -234,27 +360,13 @@ int GetIOCTLSocket() */ void CloseIOCTLSocket() { - if (sIOCTLSocket == -1) + if (sIOCTLSocket != -1) { close(sIOCTLSocket); sIOCTLSocket = -1; } } -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -/** - * @fn InterfaceIterator::InterfaceIterator(void) - * - * @brief Constructs an InterfaceIterator object. - * - * @details - * Starts the iterator at the first network interface. On some platforms, - * this constructor may allocate resources recycled by the destructor. - */ - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - #if __ANDROID__ && __ANDROID_API__ < 24 static struct if_nameindex * backport_if_nameindex(void); @@ -400,23 +512,6 @@ InterfaceIterator::InterfaceIterator() mIntfFlagsCached = false; } -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -InterfaceIterator::InterfaceIterator() : mCurrentInterface(net_if_get_by_index(mCurrentId)) {} -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - -/** - * @fn InterfaceIterator::~InterfaceIterator(void) - * - * @brief Destroys an InterfaceIterator object. - * - * @details - * Recycles any resources allocated by the constructor. - */ - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - InterfaceIterator::~InterfaceIterator() { if (mIntfArray != nullptr) @@ -430,54 +525,13 @@ InterfaceIterator::~InterfaceIterator() } } -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -/** - * @fn bool InterfaceIterator::HasCurrent(void) - * - * @brief Test whether the iterator is positioned on an interface - * - * @return \c true if the iterator is positioned on an interface; - * \c false if positioned beyond the end of the interface list. - */ - -#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS bool InterfaceIterator::HasCurrent() { return (mIntfArray != nullptr) ? mIntfArray[mCurIntf].if_index != 0 : Next(); } -#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -bool InterfaceIterator::HasCurrent(void) -{ - return mCurrentInterface != nullptr; -} -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -/** - * @fn bool InterfaceIterator::Next(void) - * - * @brief Advance the iterator to the next network interface. - * - * @return \c false if advanced beyond the end, else \c true. - * - * @details - * Advances the internal iterator to the next network interface or to a position - * beyond the end of the interface list. - * - * On multi-threaded LwIP systems, this method is thread-safe relative to other - * threads accessing the global LwIP state provided that: 1) the other threads - * hold the LwIP core lock while mutating the list of netifs; and 2) netif objects - * themselves are never destroyed. - * - * Iteration is stable in the face of changes to the underlying system's - * interfaces, *except* in the case of LwIP systems when the currently selected - * interface is removed from the list, which causes iteration to end immediately. - */ bool InterfaceIterator::Next() { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS if (mIntfArray == nullptr) { @@ -494,319 +548,279 @@ bool InterfaceIterator::Next() mIntfFlagsCached = false; } return (mIntfArray != nullptr && mIntfArray[mCurIntf].if_index != 0); +} -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS +InterfaceId InterfaceIterator::GetInterfaceId() +{ + return (HasCurrent()) ? mIntfArray[mCurIntf].if_index : INET_NULL_INTERFACEID; +} -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - mCurrentInterface = net_if_get_by_index(++mCurrentId); - return HasCurrent(); -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF +CHIP_ERROR InterfaceIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) +{ + VerifyOrReturnError(HasCurrent(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(strlen(mIntfArray[mCurIntf].if_name) < nameBufSize, CHIP_ERROR_NO_MEMORY); + strncpy(nameBuf, mIntfArray[mCurIntf].if_name, nameBufSize); + return CHIP_NO_ERROR; +} -#if CHIP_SYSTEM_CONFIG_USE_LWIP +bool InterfaceIterator::IsUp() +{ + return (GetFlags() & IFF_UP) != 0; +} - // Lock LwIP stack - LOCK_TCPIP_CORE(); +bool InterfaceIterator::SupportsMulticast() +{ + return (GetFlags() & IFF_MULTICAST) != 0; +} - // Verify the previous netif is still on the list if netifs. If so, - // advance to the next nextif. - struct netif * prevNetif = mCurNetif; -#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 0 && defined(NETIF_FOREACH) - NETIF_FOREACH(mCurNetif) -#else - for (mCurNetif = netif_list; mCurNetif != NULL; mCurNetif = mCurNetif->next) -#endif +bool InterfaceIterator::HasBroadcastAddress() +{ + return (GetFlags() & IFF_BROADCAST) != 0; +} + +short InterfaceIterator::GetFlags() +{ + struct ifreq intfData; + + if (!mIntfFlagsCached && HasCurrent()) { - if (mCurNetif == prevNetif) + strncpy(intfData.ifr_name, mIntfArray[mCurIntf].if_name, IFNAMSIZ); + intfData.ifr_name[IFNAMSIZ - 1] = '\0'; + + int res = ioctl(GetIOCTLSocket(), SIOCGIFFLAGS, &intfData); + if (res == 0) { - mCurNetif = mCurNetif->next; - break; + mIntfFlags = intfData.ifr_flags; + mIntfFlagsCached = true; } + CloseIOCTLSocket(); } - // Unlock LwIP stack - UNLOCK_TCPIP_CORE(); - - return mCurNetif != NULL; - -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP + return mIntfFlags; } -/** - * @fn InterfaceId InterfaceIterator::GetInterfaceId(void) - * - * @brief Returns the network interface id at the current iterator position. - * - * @retval INET_NULL_INTERFACEID if advanced beyond the end of the list. - * @retval id the current network interface id. - */ +InterfaceAddressIterator::InterfaceAddressIterator() +{ + mAddrsList = nullptr; + mCurAddr = nullptr; +} -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS -InterfaceId InterfaceIterator::GetInterfaceId() +InterfaceAddressIterator::~InterfaceAddressIterator() { - return (HasCurrent()) ? mIntfArray[mCurIntf].if_index : INET_NULL_INTERFACEID; + if (mAddrsList != nullptr) + { + freeifaddrs(mAddrsList); + mAddrsList = mCurAddr = nullptr; + } } -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -InterfaceId InterfaceIterator::GetInterfaceId(void) +bool InterfaceAddressIterator::HasCurrent() { - return HasCurrent() ? mCurrentId : INET_NULL_INTERFACEID; + return (mAddrsList != nullptr) ? (mCurAddr != nullptr) : Next(); } -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -/** - * @brief Get the name of the current network interface - * - * @param[in] nameBuf region of memory to write the interface name - * @param[in] nameBufSize size of the region denoted by \c nameBuf - * - * @retval CHIP_NO_ERROR successful result, interface name written - * @retval CHIP_ERROR_INCORRECT_STATE - * iterator is positioned beyond the end of - * the list - * @retval CHIP_ERROR_NO_MEMORY name is too large to be written in buffer - * @retval other another system or platform error - * - * @details - * Writes the name of the network interface as \c NUL terminated text string - * at \c nameBuf. - */ -CHIP_ERROR InterfaceIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) +bool InterfaceAddressIterator::Next() { - VerifyOrReturnError(HasCurrent(), CHIP_ERROR_INCORRECT_STATE); + while (true) + { + if (mAddrsList == nullptr) + { + int res = getifaddrs(&mAddrsList); + if (res < 0) + { + return false; + } + mCurAddr = mAddrsList; + } + else if (mCurAddr != nullptr) + { + mCurAddr = mCurAddr->ifa_next; + } -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - VerifyOrReturnError(strlen(mIntfArray[mCurIntf].if_name) < nameBufSize, CHIP_ERROR_NO_MEMORY); - strncpy(nameBuf, mIntfArray[mCurIntf].if_name, nameBufSize); - return CHIP_NO_ERROR; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS + if (mCurAddr == nullptr) + { + return false; + } -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - return ::chip::Inet::GetInterfaceName(mCurrentId, nameBuf, nameBufSize); -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF + if (mCurAddr->ifa_addr != nullptr && + (mCurAddr->ifa_addr->sa_family == AF_INET6 +#if INET_CONFIG_ENABLE_IPV4 + || mCurAddr->ifa_addr->sa_family == AF_INET +#endif // INET_CONFIG_ENABLE_IPV4 + )) + { + return true; + } + } +} -#if CHIP_SYSTEM_CONFIG_USE_LWIP - return ::chip::Inet::GetInterfaceName(mCurNetif, nameBuf, nameBufSize); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP +IPAddress InterfaceAddressIterator::GetAddress() +{ + if (HasCurrent()) + { + return IPAddress::FromSockAddr(*mCurAddr->ifa_addr); + } - return CHIP_ERROR_NOT_IMPLEMENTED; + return IPAddress::Any; } -/** - * @brief Returns whether the current network interface is up. - * - * @return \c true if current network interface is up, \c false if not - * or if the iterator is positioned beyond the end of the list. - */ -bool InterfaceIterator::IsUp() +uint8_t InterfaceAddressIterator::GetPrefixLength() { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return (GetFlags() & IFF_UP) != 0; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - return HasCurrent() && net_if_is_up(mCurrentInterface); -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF + if (HasCurrent()) + { + if (mCurAddr->ifa_addr->sa_family == AF_INET6) + { +#if !__MBED__ + struct sockaddr_in6 & netmask = *reinterpret_cast(mCurAddr->ifa_netmask); + return NetmaskToPrefixLength(netmask.sin6_addr.s6_addr, 16); +#else // __MBED__ + // netmask is not available through an API for IPv6 interface in Mbed. + // Default prefix length to 64. + return 64; +#endif // !__MBED__ + } + if (mCurAddr->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in & netmask = *reinterpret_cast(mCurAddr->ifa_netmask); + return NetmaskToPrefixLength(reinterpret_cast(&netmask.sin_addr.s_addr), 4); + } + } + return 0; +} -#if CHIP_SYSTEM_CONFIG_USE_LWIP - return HasCurrent() && netif_is_up(mCurNetif); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP +InterfaceId InterfaceAddressIterator::GetInterfaceId() +{ + if (HasCurrent()) + { + return if_nametoindex(mCurAddr->ifa_name); + } + return INET_NULL_INTERFACEID; } -/** - * @brief Returns whether the current network interface supports multicast. - * - * @return \c true if current network interface supports multicast, \c false - * if not, or if the iterator is positioned beyond the end of the list. - */ -bool InterfaceIterator::SupportsMulticast() +CHIP_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return (GetFlags() & IFF_MULTICAST) != 0; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS + VerifyOrReturnError(HasCurrent(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(strlen(mCurAddr->ifa_name) < nameBufSize, CHIP_ERROR_NO_MEMORY); + strncpy(nameBuf, mCurAddr->ifa_name, nameBufSize); + return CHIP_NO_ERROR; +} -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - return HasCurrent() && NET_IF_MAX_IPV6_MADDR > 0; -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF +bool InterfaceAddressIterator::IsUp() +{ + if (HasCurrent()) + { + return (mCurAddr->ifa_flags & IFF_UP) != 0; + } + return false; +} -#if CHIP_SYSTEM_CONFIG_USE_LWIP - return HasCurrent() && -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 - (mCurNetif->flags & (NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_BROADCAST)) != 0; -#else - (mCurNetif->flags & NETIF_FLAG_POINTTOPOINT) == 0; -#endif // LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP +bool InterfaceAddressIterator::SupportsMulticast() +{ + if (HasCurrent()) + { + return (mCurAddr->ifa_flags & IFF_MULTICAST) != 0; + } + return false; } -/** - * @brief Returns whether the current network interface has a broadcast address. - * - * @return \c true if current network interface has a broadcast address, \c false - * if not, or if the iterator is positioned beyond the end of the list. - */ -bool InterfaceIterator::HasBroadcastAddress() +bool InterfaceAddressIterator::HasBroadcastAddress() { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return (GetFlags() & IFF_BROADCAST) != 0; + if (HasCurrent()) + { + return (mCurAddr->ifa_flags & IFF_BROADCAST) != 0; + } + return false; +} + #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - // Zephyr seems to handle broadcast address for IPv4 implicitly - return HasCurrent() && INET_CONFIG_ENABLE_IPV4; -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -#if CHIP_SYSTEM_CONFIG_USE_LWIP - return HasCurrent() && (mCurNetif->flags & NETIF_FLAG_BROADCAST) != 0; -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP -} +DLL_EXPORT CHIP_ERROR GetInterfaceName(InterfaceId intfId, char * nameBuf, size_t nameBufSize) +{ + if (intfId != INET_NULL_INTERFACEID) + { + net_if * currentInterface = net_if_get_by_index(intfId); + if (!currentInterface) + return CHIP_ERROR_INCORRECT_STATE; + const char * name = net_if_get_device(currentInterface)->name; + if (strlen(name) >= nameBufSize) + return CHIP_ERROR_NO_MEMORY; + strcpy(nameBuf, name); + return CHIP_NO_ERROR; + } -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS + if (nameBufSize < 1) + return CHIP_ERROR_NO_MEMORY; -/** - * @fn short InterfaceIterator::GetFlags(void) - * - * @brief Returns the ifr_flags value for the current interface. - */ -short InterfaceIterator::GetFlags() + nameBuf[0] = 0; + return CHIP_NO_ERROR; +} +DLL_EXPORT CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId) { - struct ifreq intfData; + int currentId = 0; + net_if * currentInterface; - if (!mIntfFlagsCached && HasCurrent()) + while ((currentInterface = net_if_get_by_index(++currentId)) != nullptr) { - strncpy(intfData.ifr_name, mIntfArray[mCurIntf].if_name, IFNAMSIZ); - intfData.ifr_name[IFNAMSIZ - 1] = '\0'; - - int res = ioctl(GetIOCTLSocket(), SIOCGIFFLAGS, &intfData); - if (res == 0) + if (strcmp(net_if_get_device(currentInterface)->name, intfName) == 0) { - mIntfFlags = intfData.ifr_flags; - mIntfFlagsCached = true; + intfId = currentId; + return CHIP_NO_ERROR; } } + return INET_ERROR_UNKNOWN_INTERFACE; +} - return mIntfFlags; +InterfaceIterator::InterfaceIterator() : mCurrentInterface(net_if_get_by_index(mCurrentId)) {} + +bool InterfaceIterator::HasCurrent(void) +{ + return mCurrentInterface != nullptr; +} + +bool InterfaceIterator::Next() +{ + mCurrentInterface = net_if_get_by_index(++mCurrentId); + return HasCurrent(); } -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS +InterfaceId InterfaceIterator::GetInterfaceId(void) +{ + return HasCurrent() ? mCurrentId : INET_NULL_INTERFACEID; +} -#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS -/** - * @fn InterfaceAddressIterator::InterfaceAddressIterator(void) - * - * @brief Constructs an InterfaceAddressIterator object. - * - * @details - * Starts the iterator at the first network address. On some platforms, - * this constructor may allocate resources recycled by the destructor. - */ -InterfaceAddressIterator::InterfaceAddressIterator() +CHIP_ERROR InterfaceIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) { - mAddrsList = nullptr; - mCurAddr = nullptr; + VerifyOrReturnError(HasCurrent(), CHIP_ERROR_INCORRECT_STATE); + return ::chip::Inet::GetInterfaceName(mCurrentId, nameBuf, nameBufSize); } -#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -InterfaceAddressIterator::InterfaceAddressIterator() = default; -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF +bool InterfaceIterator::IsUp() +{ + return HasCurrent() && net_if_is_up(mCurrentInterface); +} -/** - * @fn InterfaceAddressIterator::~InterfaceAddressIterator(void) - * - * @brief Destroys an InterfaceAddressIterator object. - * - * @details - * Recycles any resources allocated by the constructor. - */ +bool InterfaceIterator::SupportsMulticast() +{ + return HasCurrent() && NET_IF_MAX_IPV6_MADDR > 0; +} -#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS -InterfaceAddressIterator::~InterfaceAddressIterator() +bool InterfaceIterator::HasBroadcastAddress() { - if (mAddrsList != nullptr) - { - freeifaddrs(mAddrsList); - mAddrsList = mCurAddr = nullptr; - } + // Zephyr seems to handle broadcast address for IPv4 implicitly + return HasCurrent() && INET_CONFIG_ENABLE_IPV4; } -#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS -/** - * @fn bool InterfaceIterator::HasCurrent(void) - * - * @brief Test whether the iterator is positioned on an interface address - * - * @return \c true if the iterator is positioned on an interface address; - * \c false if positioned beyond the end of the address list. - */ +InterfaceAddressIterator::InterfaceAddressIterator() = default; + bool InterfaceAddressIterator::HasCurrent() { -#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return (mAddrsList != nullptr) ? (mCurAddr != nullptr) : Next(); -#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF return mIntfIter.HasCurrent() && (mCurAddrIndex >= 0 || Next()); -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - return mIntfIter.HasCurrent() && ((mCurAddrIndex != kBeforeStartIndex) || Next()); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP } -/** - * @fn bool InterfaceAddressIterator::Next(void) - * - * @brief Advance the iterator to the next interface address. - * - * @return \c false if advanced beyond the end, else \c true. - * - * @details - * Advances the iterator to the next interface address or to a position - * beyond the end of the address list. - * - * On LwIP, this method is thread-safe provided that: 1) other threads hold - * the LwIP core lock while mutating the netif list; and 2) netif objects - * themselves are never destroyed. Additionally, iteration on LwIP systems - * will terminate early if the current interface is removed from the list. - */ bool InterfaceAddressIterator::Next() { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - while (true) - { - if (mAddrsList == nullptr) - { - int res = getifaddrs(&mAddrsList); - if (res < 0) - { - return false; - } - mCurAddr = mAddrsList; - } - else if (mCurAddr != nullptr) - { - mCurAddr = mCurAddr->ifa_next; - } - - if (mCurAddr == nullptr) - { - return false; - } - - if (mCurAddr->ifa_addr != nullptr && - (mCurAddr->ifa_addr->sa_family == AF_INET6 -#if INET_CONFIG_ENABLE_IPV4 - || mCurAddr->ifa_addr->sa_family == AF_INET -#endif // INET_CONFIG_ENABLE_IPV4 - )) - { - return true; - } - } -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF while (mIntfIter.HasCurrent()) { if (mCurAddrIndex == -1) // first address for the current interface @@ -824,283 +838,73 @@ bool InterfaceAddressIterator::Next() } return false; -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - mCurAddrIndex++; - - while (mIntfIter.HasCurrent()) - { - struct netif * curIntf = mIntfIter.GetInterfaceId(); - - while (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES) - { - if (ip6_addr_isvalid(netif_ip6_addr_state(curIntf, mCurAddrIndex))) - { - return true; - } - mCurAddrIndex++; - } - -#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 - if (mCurAddrIndex == LWIP_IPV6_NUM_ADDRESSES) - { - if (!ip4_addr_isany(netif_ip4_addr(curIntf))) - { - return true; - } - } -#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 - - mIntfIter.Next(); - mCurAddrIndex = 0; - } - - return false; -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP } -/** - * @fn IPAddress InterfaceAddressIterator::GetAddress(void) - * - * @brief Get the current interface address. - * - * @return the current interface address or \c IPAddress::Any if the iterator - * is positioned beyond the end of the address list. - */ IPAddress InterfaceAddressIterator::GetAddress() { if (HasCurrent()) { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return IPAddress::FromSockAddr(*mCurAddr->ifa_addr); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF return IPAddress::FromIPv6(mIpv6->unicast[mCurAddrIndex].address.in6_addr); -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - struct netif * curIntf = mIntfIter.GetInterfaceId(); - - if (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES) - { - return IPAddress::FromIPv6(*netif_ip6_addr(curIntf, mCurAddrIndex)); - } -#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 - else - { - return IPAddress::FromIPv4(*netif_ip4_addr(curIntf)); - } -#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP } return IPAddress::Any; } -/** - * @fn uint8_t InterfaceAddressIterator::GetPrefixLength(void) - * - * @brief Gets the network prefix associated with the current interface address. - * - * @return the network prefix (in bits) or 0 if the iterator is positioned beyond - * the end of the address list. - * - * @details - * On LwIP, this method simply returns the hard-coded constant 64. - * - * Note Well: the standard subnet prefix on all links other than PPP - * links is 64 bits. On PPP links and some non-broadcast multipoint access - * links, the convention is either 127 bits or 128 bits, but it might be - * something else. On most platforms, the system's interface address - * structure can represent arbitrary prefix lengths between 0 and 128. - */ uint8_t InterfaceAddressIterator::GetPrefixLength() { if (HasCurrent()) { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - if (mCurAddr->ifa_addr->sa_family == AF_INET6) - { -#if !__MBED__ - struct sockaddr_in6 & netmask = *reinterpret_cast(mCurAddr->ifa_netmask); - return NetmaskToPrefixLength(netmask.sin6_addr.s6_addr, 16); -#else // __MBED__ - // netmask is not available through an API for IPv6 interface in Mbed. - // Default prefix length to 64. - return 64; -#endif // !__MBED__ - } - if (mCurAddr->ifa_addr->sa_family == AF_INET) - { - struct sockaddr_in & netmask = *reinterpret_cast(mCurAddr->ifa_netmask); - return NetmaskToPrefixLength(reinterpret_cast(&netmask.sin_addr.s_addr), 4); - } -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF net_if * const iface = net_if_get_by_index(mIntfIter.GetInterfaceId()); net_if_ipv6_prefix * const prefix = net_if_ipv6_prefix_get(iface, &mIpv6->unicast[mCurAddrIndex].address.in6_addr); return prefix ? prefix->len : 128; -#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - if (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES) - { - return 64; - } -#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 - else - { - struct netif * curIntf = mIntfIter.GetInterfaceId(); - return NetmaskToPrefixLength((const uint8_t *) netif_ip4_netmask(curIntf), 4); - } -#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4 -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP } return 0; } -/** - * @fn InterfaceId InterfaceAddressIterator::GetInterfaceId(void) - * - * @brief Returns the network interface id associated with the current - * interface address. - * - * @return the interface id or \c INET_NULL_INTERFACEID if the iterator - * is positioned beyond the end of the address list. - */ InterfaceId InterfaceAddressIterator::GetInterfaceId() { if (HasCurrent()) { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return if_nametoindex(mCurAddr->ifa_name); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF return mIntfIter.GetInterfaceId(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF } return INET_NULL_INTERFACEID; } -/** - * @fn CHIP_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) - * - * @brief Get the name of the network interface associated with the - * current interface address. - * - * @param[in] nameBuf region of memory to write the interface name - * @param[in] nameBufSize size of the region denoted by \c nameBuf - * - * @retval CHIP_NO_ERROR successful result, interface name written - * @retval CHIP_ERROR_NO_MEMORY name is too large to be written in buffer - * @retval CHIP_ERROR_INCORRECT_STATE - * the iterator is not currently positioned on an - * interface address - * @retval other another system or platform error - * - * @details - * Writes the name of the network interface as \c NUL terminated text string - * at \c nameBuf. - */ CHIP_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) { VerifyOrReturnError(HasCurrent(), CHIP_ERROR_INCORRECT_STATE); - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - VerifyOrReturnError(strlen(mCurAddr->ifa_name) < nameBufSize, CHIP_ERROR_NO_MEMORY); - strncpy(nameBuf, mCurAddr->ifa_name, nameBufSize); - return CHIP_NO_ERROR; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF return mIntfIter.GetInterfaceName(nameBuf, nameBufSize); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF - - return CHIP_ERROR_NOT_IMPLEMENTED; } -/** - * @fn bool InterfaceAddressIterator::IsUp(void) - * - * @brief Returns whether the network interface associated with the current - * interface address is up. - * - * @return \c true if current network interface is up, \c false if not, or - * if the iterator is not positioned on an interface address. - */ bool InterfaceAddressIterator::IsUp() { if (HasCurrent()) { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return (mCurAddr->ifa_flags & IFF_UP) != 0; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF return mIntfIter.IsUp(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF } return false; } -/** - * @fn bool InterfaceAddressIterator::SupportsMulticast(void) - * - * @brief Returns whether the network interface associated with the current - * interface address supports multicast. - * - * @return \c true if multicast is supported, \c false if not, or - * if the iterator is not positioned on an interface address. - */ bool InterfaceAddressIterator::SupportsMulticast() { if (HasCurrent()) { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return (mCurAddr->ifa_flags & IFF_MULTICAST) != 0; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF return mIntfIter.SupportsMulticast(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF } return false; } -/** - * @fn bool InterfaceAddressIterator::HasBroadcastAddress(void) - * - * @brief Returns whether the network interface associated with the current - * interface address has an IPv4 broadcast address. - * - * @return \c true if the interface has a broadcast address, \c false if not, or - * if the iterator is not positioned on an interface address. - */ bool InterfaceAddressIterator::HasBroadcastAddress() { if (HasCurrent()) { -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - return (mCurAddr->ifa_flags & IFF_BROADCAST) != 0; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS - -#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF return mIntfIter.HasBroadcastAddress(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF } return false; } -/** - * @fn void InterfaceAddressIterator::GetAddressWithPrefix(IPPrefix & addrWithPrefix) - * - * @brief Returns an IPPrefix containing the address and prefix length - * for the current address. - */ +#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF + void InterfaceAddressIterator::GetAddressWithPrefix(IPPrefix & addrWithPrefix) { if (HasCurrent()) @@ -1114,11 +918,6 @@ void InterfaceAddressIterator::GetAddressWithPrefix(IPPrefix & addrWithPrefix) } } -/** - * @fn uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen) - * - * @brief Compute a prefix length from a variable-length netmask. - */ uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen) { uint8_t prefixLen = 0; diff --git a/src/inet/InetInterface.h b/src/inet/InetInterface.h index 98010f690c2874..c5e512f95767d0 100644 --- a/src/inet/InetInterface.h +++ b/src/inet/InetInterface.h @@ -114,8 +114,40 @@ typedef int InterfaceId; */ #define IsInterfaceIdPresent(intfId) ((intfId) != INET_NULL_INTERFACEID) +/** + * Get the name of the network interface + * + * @param[in] intfId A network interface. + * @param[in] nameBuf Region of memory to write the interface name. + * @param[in] nameBufSize Size of the region denoted by \c nameBuf. + * + * @retval CHIP_NO_ERROR Successful result, interface name written. + * @retval CHIP_ERROR_BUFFER_TOO_SMALL Buffer is too small for the interface name. + * @retval other Another system or platform error. + * + * Writes the name of the network interface as a \c NUL terminated text string at \c nameBuf. + * The name of the unspecified network interface is the empty string. + */ extern CHIP_ERROR GetInterfaceName(InterfaceId intfId, char * nameBuf, size_t nameBufSize); + +/** + * Search the list of network interfaces for the indicated name. + * + * @param[in] intfName Name of the network interface to find. + * @param[out] intfId Indicator of the network interface to assign. + * + * @retval CHIP_NO_ERROR Success, network interface indicated. + * @retval INET_ERROR_UNKNOWN_INTERFACE No network interface found. + * @retval other Another system or platform error. + * + * @note + * On LwIP, this function must be called with the LwIP stack lock acquired. + */ extern CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId); + +/** + * Compute a prefix length from a variable-length netmask. + */ extern uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen); /** @@ -142,16 +174,94 @@ extern uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLe class InterfaceIterator { public: + /** + * Constructs an InterfaceIterator object. + * + * Starts the iterator at the first network interface. On some platforms, + * this constructor may allocate resources recycled by the destructor. + */ InterfaceIterator(); ~InterfaceIterator(); + /** + * Test whether the iterator is positioned on an interface + * + * @return \c true if the iterator is positioned on an interface; + * \c false if positioned beyond the end of the interface list. + */ bool HasCurrent(); + + /** + * Advance the iterator to the next network interface. + * + * @return \c false if advanced beyond the end, else \c true. + * + * Advances the internal iterator to the next network interface or to a position + * beyond the end of the interface list. + * + * On multi-threaded LwIP systems, this method is thread-safe relative to other + * threads accessing the global LwIP state provided that: 1) the other threads + * hold the LwIP core lock while mutating the list of netifs; and 2) netif objects + * themselves are never destroyed. + * + * Iteration is stable in the face of changes to the underlying system's + * interfaces, *except* in the case of LwIP systems when the currently selected + * interface is removed from the list, which causes iteration to end immediately. + */ bool Next(); - InterfaceId GetInterface(); + + /** + * NetworkInterface InterfaceIterator::GetInterfaceId(void) + * + * Returns the network interface id at the current iterator position. + * + * @retval id The current network interface id. + * @retval NetworkInterface() If advanced beyond the end of the list. + */ InterfaceId GetInterfaceId(); + + /** + * @brief Deprecated alias for \c GetInterfaceId(void) + */ + InterfaceId GetInterface() { return GetInterfaceId(); } + + /** + * Get the name of the current network interface + * + * @param[in] nameBuf Region of memory to write the interface name. + * @param[in] nameBufSize Size of the region denoted by \c nameBuf. + * + * @retval CHIP_NO_ERROR Successful result, interface name written. + * @retval CHIP_ERROR_INCORRECT_STATE Iterator is positioned beyond the end of the list. + * @retval CHIP_ERROR_BUFFER_TOO_SMALL Name is too large to be written in buffer. + * @retval other Another system or platform error. + * + * Writes the name of the network interface as \c NUL terminated text string at \c nameBuf. + */ CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize); + + /** + * Returns whether the current network interface is up. + * + * @return \c true if current network interface is up, \c false if not + * or if the iterator is positioned beyond the end of the list. + */ bool IsUp(); + + /** + * Returns whether the current network interface supports multicast. + * + * @return \c true if current network interface supports multicast, \c false + * if not, or if the iterator is positioned beyond the end of the list. + */ bool SupportsMulticast(); + + /** + * Returns whether the current network interface has a broadcast address. + * + * @return \c true if current network interface has a broadcast address, \c false + * if not, or if the iterator is positioned beyond the end of the list. + */ bool HasBroadcastAddress(); #if CHIP_SYSTEM_CONFIG_USE_LWIP @@ -212,20 +322,149 @@ class InterfaceIterator class DLL_EXPORT InterfaceAddressIterator { public: + /** + * Constructs an InterfaceAddressIterator object. + * + * Starts the iterator at the first network address. On some platforms, + * this constructor may allocate resources recycled by the destructor. + */ InterfaceAddressIterator(); + + /** + * Destroys an InterfaceAddressIterator object. + * + * Recycles any resources allocated by the constructor. + */ ~InterfaceAddressIterator(); + /** + * Test whether the iterator is positioned on an interface address + * + * @return \c true if the iterator is positioned on an interface address; + * \c false if positioned beyond the end of the address list. + */ bool HasCurrent(); + + /** + * @fn bool InterfaceAddressIterator::Next(void) + * + * @brief Advance the iterator to the next interface address. + * + * @return \c false if advanced beyond the end, else \c true. + * + * @details + * Advances the iterator to the next interface address or to a position + * beyond the end of the address list. + * + * On LwIP, this method is thread-safe provided that: 1) other threads hold + * the LwIP core lock while mutating the netif list; and 2) netif objects + * themselves are never destroyed. Additionally, iteration on LwIP systems + * will terminate early if the current interface is removed from the list. + */ bool Next(); + + /** + * @fn IPAddress InterfaceAddressIterator::GetAddress(void) + * + * @brief Get the current interface address. + * + * @return the current interface address or \c IPAddress::Any if the iterator + * is positioned beyond the end of the address list. + */ IPAddress GetAddress(); + + /** + * @fn uint8_t InterfaceAddressIterator::GetPrefixLength(void) + * + * @brief Gets the network prefix associated with the current interface address. + * + * @return the network prefix (in bits) or 0 if the iterator is positioned beyond + * the end of the address list. + * + * @details + * On LwIP, this method simply returns the hard-coded constant 64. + * + * Note Well: the standard subnet prefix on all links other than PPP + * links is 64 bits. On PPP links and some non-broadcast multipoint access + * links, the convention is either 127 bits or 128 bits, but it might be + * something else. On most platforms, the system's interface address + * structure can represent arbitrary prefix lengths between 0 and 128. + */ uint8_t GetPrefixLength(); - uint8_t GetIPv6PrefixLength(); + + /** + * @brief Deprecated alias for \c GetPrefixLength(void) + */ + uint8_t GetIPv6PrefixLength() { return GetPrefixLength(); } + + /** + * @fn void InterfaceAddressIterator::GetAddressWithPrefix(IPPrefix & addrWithPrefix) + * + * @brief Returns an IPPrefix containing the address and prefix length + * for the current address. + */ void GetAddressWithPrefix(IPPrefix & addrWithPrefix); - InterfaceId GetInterface(); + + /** + * @fn NetworkInterface InterfaceAddressIterator::GetInterfaceId(void) + * + * @brief Returns the network interface id associated with the current + * interface address. + * + * @return the interface id or \c NetworkInterface() if the iterator + * is positioned beyond the end of the address list. + */ InterfaceId GetInterfaceId(); + + /** + * @brief Deprecated alias for \c GetInterfaceId(void) + */ + InterfaceId GetInterface() { return GetInterfaceId(); } + + /** + * @fn CHIP_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize) + * + * @brief Get the name of the network interface associated with the + * current interface address. + * + * @param[in] nameBuf region of memory to write the interface name + * @param[in] nameBufSize size of the region denoted by \c nameBuf + * + * @retval CHIP_NO_ERROR successful result, interface name written + * @retval CHIP_ERROR_BUFFER_TOO_SMALL name is too large to be written in buffer + * @retval CHIP_ERROR_INCORRECT_STATE + * the iterator is not currently positioned on an + * interface address + * @retval other another system or platform error + * + * @details + * Writes the name of the network interface as \c NUL terminated text string + * at \c nameBuf. + */ CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize); + + /** + * Returns whether the network interface associated with the current interface address is up. + * + * @return \c true if current network interface is up, \c false if not, or + * if the iterator is not positioned on an interface address. + */ bool IsUp(); + + /** + * Returns whether the network interface associated with the current interface address supports multicast. + * + * @return \c true if multicast is supported, \c false if not, or + * if the iterator is not positioned on an interface address. + */ bool SupportsMulticast(); + + /** + * Returns whether the network interface associated with the current interface address has an IPv4 broadcast address. + * + * @return \c true if the interface has a broadcast address, \c false if not, or + * if the iterator is not positioned on an interface address. + */ bool HasBroadcastAddress(); private: @@ -284,29 +523,5 @@ inline InterfaceIterator::~InterfaceIterator() = default; inline InterfaceAddressIterator::~InterfaceAddressIterator() = default; #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF -/** - * @brief Deprecated alias for \c GetInterfaceId(void) - */ -inline InterfaceId InterfaceIterator::GetInterface() -{ - return GetInterfaceId(); -} - -/** - * @brief Deprecated alias for \c GetInterfaceId(void) - */ -inline InterfaceId InterfaceAddressIterator::GetInterface() -{ - return GetInterfaceId(); -} - -/** - * @brief Deprecated alias for \c GetPrefixLength(void) - */ -inline uint8_t InterfaceAddressIterator::GetIPv6PrefixLength() -{ - return GetPrefixLength(); -} - } // namespace Inet } // namespace chip