3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2019 Google LLC.
5 * Copyright (c) 2013-2017 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * This file defines the <tt>Inet::InterfaceId</tt> type alias and related
23 * classes for iterating on the list of system network interfaces and the list
24 * of system interface addresses.
29 #include <inet/InetConfig.h>
31 #include <inet/IPAddress.h>
32 #include <inet/InetError.h>
33 #include <support/DLLUtil.h>
35 #if CHIP_SYSTEM_CONFIG_USE_LWIP
36 #include <lwip/netif.h>
37 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
39 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
42 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
44 #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
50 #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
62 * @typedef InterfaceId
64 * @brief Indicator for system network interfaces.
67 * Portability depends on never witnessing this alias. It may be replaced by a
68 * concrete opaque class in the future.
70 * Note Well: The term "interface identifier" also conventionally refers to
71 * the lower 64 bits of an IPv6 address in all the relevant IETF standards
72 * documents, where the abbreviation "IID" is often used. In this text, the
73 * term "interface indicator" refers to values of this type alias.
76 #if CHIP_SYSTEM_CONFIG_USE_LWIP
77 typedef struct netif * InterfaceId;
78 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
80 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
81 typedef unsigned InterfaceId;
82 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
84 #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
85 typedef int InterfaceId;
89 * @def INET_NULL_INTERFACEID
91 * @brief The distinguished value indicating no network interface.
94 * Note Well: This is not the indicator of a "null" network interface. This
95 * value can be used to indicate the absence of a specific network interface,
96 * or to specify that any applicable network interface is acceptable. Usage
97 * varies depending on context.
100 #if CHIP_SYSTEM_CONFIG_USE_LWIP
101 #define INET_NULL_INTERFACEID NULL
102 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
104 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
105 #define INET_NULL_INTERFACEID 0
106 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
109 * @brief Test \c ID for inequivalence with \c INET_NULL_INTERFACEID
112 * This macro resolves to an expression that evaluates \c false if the
113 * argument is equivalent to \c INET_NULL_INTERFACEID and \c true otherwise.
115 #define IsInterfaceIdPresent(intfId) ((intfId) != INET_NULL_INTERFACEID)
117 extern INET_ERROR GetInterfaceName(InterfaceId intfId, char * nameBuf, size_t nameBufSize);
118 extern INET_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId);
119 extern uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen);
122 * @brief Iterator for the list of system network interfaces.
125 * Use objects of this class to iterate the list of system network interfaces.
127 * Methods on an individual instance of this class are *not* thread-safe;
128 * however separate instances may be used simultaneously by multiple threads.
130 * On multi-threaded LwIP systems, instances are thread-safe relative to other
131 * threads accessing the global LwIP state provided that the other threads hold
132 * the LwIP core lock while mutating the list of netifs, and that netif object
133 * themselves are never destroyed.
135 * On sockets-based systems, iteration is always stable in the face of changes
136 * to the underlying system's interfaces.
138 * On LwIP systems, iteration is stable except in the case where the currently
139 * selected interface is removed from the list, in which case iteration ends
142 class InterfaceIterator
146 ~InterfaceIterator();
150 InterfaceId GetInterface();
151 InterfaceId GetInterfaceId();
152 INET_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);
154 bool SupportsMulticast();
155 bool HasBroadcastAddress();
157 #if CHIP_SYSTEM_CONFIG_USE_LWIP
158 static constexpr size_t kMaxIfNameLength = 13; // Names are formatted as %c%c%d
159 #elif CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
160 static constexpr size_t kMaxIfNameLength = IF_NAMESIZE;
161 #elif CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
162 static constexpr size_t kMaxIfNameLength = Z_DEVICE_MAX_NAME_LEN;
163 #elif defined(IFNAMSIZ)
164 static constexpr size_t kMaxIfNameLength = IFNAMSIZ;
166 // No constant available here - set some reasonable size
167 static constexpr size_t kMaxIfNameLength = 33;
171 #if CHIP_SYSTEM_CONFIG_USE_LWIP
172 struct netif * mCurNetif;
173 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
175 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
176 struct if_nameindex * mIntfArray;
179 bool mIntfFlagsCached;
182 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
184 #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
185 InterfaceId mCurrentId = 1;
186 net_if * mCurrentInterface = nullptr;
187 #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
191 * @brief Iterator for the list of system network interface IP addresses.
194 * Use objects of this class to iterate the list of system network interface
195 * interface IP addresses.
197 * Methods on an individual instance of this class are *not* thread-safe;
198 * however separate instances may be used simultaneously by multiple threads.
200 * On multi-threaded LwIP systems, instances are thread-safe relative to other
201 * threads accessing the global LwIP state provided that: 1) other threads hold
202 * the LwIP core lock while mutating the list of netifs; and 2) netif object
203 * themselves are never destroyed.
205 * On sockets-based systems, iteration is always stable in the face of changes
206 * to the underlying system's interfaces and/or addresses.
208 * On LwIP systems, iteration is stable except in the case where the interface
209 * associated with the current address is removed, in which case iteration may
212 class DLL_EXPORT InterfaceAddressIterator
215 InterfaceAddressIterator();
216 ~InterfaceAddressIterator();
220 IPAddress GetAddress();
221 uint8_t GetPrefixLength();
222 uint8_t GetIPv6PrefixLength();
223 void GetAddressWithPrefix(IPPrefix & addrWithPrefix);
224 InterfaceId GetInterface();
225 InterfaceId GetInterfaceId();
226 INET_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);
228 bool SupportsMulticast();
229 bool HasBroadcastAddress();
232 #if CHIP_SYSTEM_CONFIG_USE_LWIP
235 kBeforeStartIndex = -1
238 InterfaceIterator mIntfIter;
240 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
242 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
243 struct ifaddrs * mAddrsList;
244 struct ifaddrs * mCurAddr;
245 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
247 #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
248 InterfaceIterator mIntfIter;
249 net_if_ipv6 * mIpv6 = nullptr;
250 int mCurAddrIndex = -1;
251 #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
254 #if CHIP_SYSTEM_CONFIG_USE_LWIP
256 inline InterfaceIterator::InterfaceIterator(void)
258 mCurNetif = netif_list;
261 inline InterfaceIterator::~InterfaceIterator(void) {}
263 inline bool InterfaceIterator::HasCurrent(void)
265 return mCurNetif != NULL;
268 inline InterfaceId InterfaceIterator::GetInterfaceId(void)
273 inline InterfaceAddressIterator::InterfaceAddressIterator(void)
275 mCurAddrIndex = kBeforeStartIndex;
278 inline InterfaceAddressIterator::~InterfaceAddressIterator(void) {}
280 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
282 #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
283 inline InterfaceIterator::~InterfaceIterator() = default;
284 inline InterfaceAddressIterator::~InterfaceAddressIterator() = default;
285 #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
288 * @brief Deprecated alias for \c GetInterfaceId(void)
290 inline InterfaceId InterfaceIterator::GetInterface()
292 return GetInterfaceId();
296 * @brief Deprecated alias for \c GetInterfaceId(void)
298 inline InterfaceId InterfaceAddressIterator::GetInterface()
300 return GetInterfaceId();
304 * @brief Deprecated alias for \c GetPrefixLength(void)
306 inline uint8_t InterfaceAddressIterator::GetIPv6PrefixLength()
308 return GetPrefixLength();