blob: 20668153ad4ad6e25c85aa89677e381cfbb41980 [file] [log] [blame]
/*
*
* Copyright (c) 2019 Google LLC.
* Copyright (c) 2013-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file defines the <tt>nl::Inet::InterfaceId</tt> type alias and related
* classes for iterating on the list of system network interfaces and the list
* of system interface addresses.
*/
#ifndef INETINTERFACE_H
#define INETINTERFACE_H
#include <stddef.h>
#include <stdint.h>
#include <Weave/Support/NLDLLUtil.h>
#include <InetLayer/IPAddress.h>
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#include <lwip/netif.h>
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
struct if_nameindex;
struct ifaddrs;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
namespace nl {
namespace Inet {
class IPAddress;
class IPPrefix;
/**
* @typedef InterfaceId
*
* @brief Indicator for system network interfaces.
*
* @details
* Portability depends on never witnessing this alias. It may be replaced by a
* concrete opaque class in the future.
*
* Note Well: The term "interface identifier" also conventionally refers to
* the lower 64 bits of an IPv6 address in all the relevant IETF standards
* documents, where the abbreviation "IID" is often used. In this text, the
* term "interface indicator" refers to values of this type alias.
*/
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
typedef struct netif *InterfaceId;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
typedef unsigned InterfaceId;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
/**
* @def INET_NULL_INTERFACEID
*
* @brief The distinguished value indicating no network interface.
*
* @details
* Note Well: This is not the indicator of a "null" network interface. This
* value can be used to indicate the absence of a specific network interface,
* or to specify that any applicable network interface is acceptable. Usage
* varies depending on context.
*/
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#define INET_NULL_INTERFACEID NULL
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#define INET_NULL_INTERFACEID 0
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
/**
* @brief Test \c ID for inequivalence with \c INET_NULL_INTERFACEID
*
* @details
* This macro resolves to an expression that evaluates \c false if the
* argument is equivalent to \c INET_NULL_INTERFACEID and \c true otherwise.
*/
#define IsInterfaceIdPresent(intfId) ((intfId) != INET_NULL_INTERFACEID)
extern INET_ERROR GetInterfaceName(InterfaceId intfId, char *nameBuf, size_t nameBufSize);
extern INET_ERROR InterfaceNameToId(const char *intfName, InterfaceId& intfId);
extern uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen);
/**
* @brief Iterator for the list of system network interfaces.
*
* @details
* Use objects of this class to iterate the list of system network interfaces.
*
* Methods on an individual instance of this class are *not* thread-safe;
* however separate instances may be used simultaneously by multiple threads.
*
* On multi-threaded LwIP systems, instances are thread-safe relative to other
* threads accessing the global LwIP state provided that the other threads hold
* the LwIP core lock while mutating the list of netifs, and that netif object
* themselves are never destroyed.
*
* On sockets-based systems, iteration is always stable in the face of changes
* to the underlying system's interfaces.
*
* On LwIP systems, iteration is stable except in the case where the currently
* selected interface is removed from the list, in which case iteration ends
* immediately.
*/
class InterfaceIterator
{
public:
InterfaceIterator(void);
~InterfaceIterator(void);
bool HasCurrent(void);
bool Next(void);
InterfaceId GetInterface(void);
InterfaceId GetInterfaceId(void);
INET_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);
bool IsUp(void);
bool SupportsMulticast(void);
bool HasBroadcastAddress(void);
protected:
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
struct netif * mCurNetif;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
struct if_nameindex * mIntfArray;
size_t mCurIntf;
short mIntfFlags;
bool mIntfFlagsCached;
short GetFlags(void);
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
};
/**
* @brief Iterator for the list of system network interface IP addresses.
*
* @details
* Use objects of this class to iterate the list of system network interface
* interface IP addresses.
*
* Methods on an individual instance of this class are *not* thread-safe;
* however separate instances may be used simultaneously by multiple threads.
*
* On multi-threaded LwIP systems, instances are thread-safe relative to other
* threads accessing the global LwIP state provided that: 1) other threads hold
* the LwIP core lock while mutating the list of netifs; and 2) netif object
* themselves are never destroyed.
*
* On sockets-based systems, iteration is always stable in the face of changes
* to the underlying system's interfaces and/or addresses.
*
* On LwIP systems, iteration is stable except in the case where the interface
* associated with the current address is removed, in which case iteration may
* end prematurely.
*/
class NL_DLL_EXPORT InterfaceAddressIterator
{
public:
InterfaceAddressIterator(void);
~InterfaceAddressIterator(void);
bool HasCurrent(void);
bool Next(void);
IPAddress GetAddress(void);
uint8_t GetPrefixLength(void);
uint8_t GetIPv6PrefixLength(void);
void GetAddressWithPrefix(IPPrefix & addrWithPrefix);
InterfaceId GetInterface(void);
InterfaceId GetInterfaceId(void);
INET_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);
bool IsUp(void);
bool SupportsMulticast(void);
bool HasBroadcastAddress(void);
private:
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
enum
{
kBeforeStartIndex = -1
};
InterfaceIterator mIntfIter;
int mCurAddrIndex;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
struct ifaddrs * mAddrsList;
struct ifaddrs * mCurAddr;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
};
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
inline InterfaceIterator::InterfaceIterator(void)
{
mCurNetif = netif_list;
}
inline InterfaceIterator::~InterfaceIterator(void)
{
}
inline bool InterfaceIterator::HasCurrent(void)
{
return mCurNetif != NULL;
}
inline InterfaceId InterfaceIterator::GetInterfaceId(void)
{
return mCurNetif;
}
inline InterfaceAddressIterator::InterfaceAddressIterator(void)
{
mCurAddrIndex = kBeforeStartIndex;
}
inline InterfaceAddressIterator::~InterfaceAddressIterator(void)
{
}
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
/**
* @brief Deprecated alias for \c GetInterfaceId(void)
*/
inline InterfaceId InterfaceIterator::GetInterface(void)
{
return GetInterfaceId();
}
/**
* @brief Deprecated alias for \c GetInterfaceId(void)
*/
inline InterfaceId InterfaceAddressIterator::GetInterface(void)
{
return GetInterfaceId();
}
/**
* @brief Deprecated alias for \c GetPrefixLength(void)
*/
inline uint8_t InterfaceAddressIterator::GetIPv6PrefixLength(void)
{
return GetPrefixLength();
}
} // namespace Inet
} // namespace nl
#endif /* INETINTERFACE_H */