Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2019 Google LLC.
5 : * Copyright (c) 2013-2017 Nest Labs, Inc.
6 : *
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
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
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.
18 : */
19 :
20 : /**
21 : * @file
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.
25 : */
26 :
27 : #pragma once
28 :
29 : #include <inet/InetConfig.h>
30 :
31 : #include <inet/IPAddress.h>
32 : #include <inet/InetError.h>
33 : #include <lib/support/DLLUtil.h>
34 :
35 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
36 : #include <lwip/netif.h>
37 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
38 :
39 : #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
40 : struct if_nameindex;
41 : struct ifaddrs;
42 : #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
43 :
44 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
45 : #include <zephyr/device.h>
46 :
47 : struct net_if;
48 : struct net_if_ipv4;
49 : struct net_if_ipv6;
50 : #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
51 :
52 : #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
53 : struct otIp6AddressInfo;
54 : #endif
55 :
56 : #include <stddef.h>
57 : #include <stdint.h>
58 :
59 : namespace chip {
60 : namespace Inet {
61 :
62 : class IPAddress;
63 : class IPPrefix;
64 :
65 : /**
66 : * Data type describing interface type.
67 : */
68 : enum class InterfaceType
69 : {
70 : Unknown = 0,
71 : WiFi = 1,
72 : Ethernet = 2,
73 : Cellular = 3,
74 : Thread = 4,
75 : };
76 :
77 : /**
78 : * Indicator for system network interfaces.
79 : */
80 : class InterfaceId
81 : {
82 : public:
83 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
84 : using PlatformType = struct netif *;
85 : static constexpr size_t kMaxIfNameLength = 13; // Names are formatted as %c%c%d
86 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
87 :
88 : #if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
89 : using PlatformType = unsigned int;
90 : static constexpr size_t kMaxIfNameLength = IF_NAMESIZE;
91 : #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
92 :
93 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
94 : using PlatformType = int;
95 : static constexpr size_t kMaxIfNameLength = Z_DEVICE_MAX_NAME_LEN;
96 : #endif
97 :
98 : #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
99 : using PlatformType = unsigned int;
100 : static constexpr size_t kMaxIfNameLength = 6;
101 : #endif
102 :
103 : ~InterfaceId() = default;
104 :
105 97 : constexpr InterfaceId() : mPlatformInterface(kPlatformNull) {}
106 1554 : explicit constexpr InterfaceId(PlatformType interface) : mPlatformInterface(interface) {}
107 :
108 1739 : constexpr InterfaceId(const InterfaceId & other) : mPlatformInterface(other.mPlatformInterface) {}
109 11741 : constexpr InterfaceId & operator=(const InterfaceId & other)
110 : {
111 11741 : mPlatformInterface = other.mPlatformInterface;
112 11741 : return *this;
113 : }
114 :
115 97 : static constexpr InterfaceId Null() { return InterfaceId(); }
116 :
117 9204 : constexpr bool operator==(const InterfaceId & other) const { return mPlatformInterface == other.mPlatformInterface; }
118 1308 : constexpr bool operator!=(const InterfaceId & other) const { return mPlatformInterface != other.mPlatformInterface; }
119 :
120 : /**
121 : * Test for inequivalence with the null interface.
122 : */
123 9825 : bool IsPresent() const { return mPlatformInterface != kPlatformNull; }
124 :
125 : /**
126 : * Get the underlying platform representation of the interface.
127 : */
128 131 : PlatformType GetPlatformInterface() const { return mPlatformInterface; }
129 :
130 : /**
131 : * Get the name of the network interface
132 : *
133 : * @param[in] nameBuf Region of memory to write the interface name.
134 : * @param[in] nameBufSize Size of the region denoted by \c nameBuf.
135 : *
136 : * @retval CHIP_NO_ERROR Successful result, interface name written.
137 : * @retval CHIP_ERROR_BUFFER_TOO_SMALL Buffer is too small for the interface name.
138 : * @retval other Another system or platform error.
139 : *
140 : * Writes the name of the network interface as a \c NUL terminated text string at \c nameBuf.
141 : * The name of the unspecified network interface is the empty string.
142 : */
143 : CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize) const;
144 :
145 : /**
146 : * Search the list of network interfaces for the indicated name.
147 : *
148 : * @param[in] intfName Name of the network interface to find.
149 : * @param[out] intfId Indicator of the network interface to assign.
150 : *
151 : * @retval CHIP_NO_ERROR Success, network interface indicated.
152 : * @retval INET_ERROR_UNKNOWN_INTERFACE No network interface found.
153 : * @retval other Another system or platform error.
154 : *
155 : * @note
156 : * On LwIP, this function must be called with the LwIP stack lock acquired.
157 : */
158 : static CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId);
159 :
160 : /**
161 : * Get the interface identifier for the specified IP address. If the
162 : * interface identifier cannot be derived it is set to the default InterfaceId.
163 : *
164 : * @note
165 : * This function fetches the first interface (from the configured list
166 : * of interfaces) that matches the specified IP address.
167 : */
168 : static InterfaceId FromIPAddress(const IPAddress & addr);
169 :
170 : /**
171 : * Check if there is a prefix match between the specified IPv6 address and any of
172 : * the locally configured IPv6 addresses.
173 : *
174 : * @param[in] addr The IPv6 address to check for the prefix-match.
175 : * @return true if a successful match is found, otherwise false.
176 : */
177 : static bool MatchLocalIPv6Subnet(const IPAddress & addr);
178 :
179 : /**
180 : * Get the link local IPv6 address.
181 : *
182 : * @param[out] llAddr The link local IPv6 address for the link.
183 : *
184 : * @retval #CHIP_ERROR_NOT_IMPLEMENTED If IPv6 is not supported.
185 : * @retval #CHIP_ERROR_INVALID_ARGUMENT If the link local address
186 : * is nullptr.
187 : * @retval #INET_ERROR_ADDRESS_NOT_FOUND If the link does not have
188 : * any address configured
189 : * or if no link local (fe80::)
190 : * address is present.
191 : * @retval #CHIP_NO_ERROR On success.
192 : */
193 : CHIP_ERROR GetLinkLocalAddr(IPAddress * llAddr) const;
194 :
195 : private:
196 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
197 : static constexpr PlatformType kPlatformNull = nullptr;
198 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
199 :
200 : #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
201 : static constexpr PlatformType kPlatformNull = 0;
202 : #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
203 :
204 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
205 : static constexpr PlatformType kPlatformNull = 0;
206 : #endif
207 :
208 : #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
209 : static constexpr PlatformType kPlatformNull = 0;
210 : #endif
211 :
212 : PlatformType mPlatformInterface;
213 : };
214 :
215 : /**
216 : * Compute a prefix length from a variable-length netmask.
217 : */
218 : extern uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen);
219 :
220 : /**
221 : * @brief Iterator for the list of system network interfaces.
222 : *
223 : * @details
224 : * Use objects of this class to iterate the list of system network interfaces.
225 : *
226 : * Methods on an individual instance of this class are *not* thread-safe;
227 : * however separate instances may be used simultaneously by multiple threads.
228 : *
229 : * On multi-threaded LwIP systems, instances are thread-safe relative to other
230 : * threads accessing the global LwIP state provided that the other threads hold
231 : * the LwIP core lock while mutating the list of netifs, and that netif object
232 : * themselves are never destroyed.
233 : *
234 : * On sockets-based systems, iteration is always stable in the face of changes
235 : * to the underlying system's interfaces.
236 : *
237 : * On LwIP systems, iteration is stable except in the case where the currently
238 : * selected interface is removed from the list, in which case iteration ends
239 : * immediately.
240 : */
241 : class InterfaceIterator
242 : {
243 : public:
244 : /**
245 : * Constructs an InterfaceIterator object.
246 : *
247 : * Starts the iterator at the first network interface. On some platforms,
248 : * this constructor may allocate resources recycled by the destructor.
249 : */
250 : InterfaceIterator();
251 : ~InterfaceIterator();
252 :
253 : /**
254 : * Test whether the iterator is positioned on an interface
255 : *
256 : * @return \c true if the iterator is positioned on an interface;
257 : * \c false if positioned beyond the end of the interface list.
258 : */
259 : bool HasCurrent();
260 :
261 : /**
262 : * Advance the iterator to the next network interface.
263 : *
264 : * @return \c false if advanced beyond the end, else \c true.
265 : *
266 : * Advances the internal iterator to the next network interface or to a position
267 : * beyond the end of the interface list.
268 : *
269 : * On multi-threaded LwIP systems, this method is thread-safe relative to other
270 : * threads accessing the global LwIP state provided that: 1) the other threads
271 : * hold the LwIP core lock while mutating the list of netifs; and 2) netif objects
272 : * themselves are never destroyed.
273 : *
274 : * Iteration is stable in the face of changes to the underlying system's
275 : * interfaces, *except* in the case of LwIP systems when the currently selected
276 : * interface is removed from the list, which causes iteration to end immediately.
277 : */
278 : bool Next();
279 :
280 : /**
281 : * InterfaceId InterfaceIterator::GetInterfaceId(void)
282 : *
283 : * Returns the network interface id at the current iterator position.
284 : *
285 : * @retval id The current network interface id.
286 : * @retval InterfaceId() If advanced beyond the end of the list.
287 : */
288 : InterfaceId GetInterfaceId();
289 :
290 : /**
291 : * Get the name of the current network interface
292 : *
293 : * @param[in] nameBuf Region of memory to write the interface name.
294 : * @param[in] nameBufSize Size of the region denoted by \c nameBuf.
295 : *
296 : * @retval CHIP_NO_ERROR Successful result, interface name written.
297 : * @retval CHIP_ERROR_INCORRECT_STATE Iterator is positioned beyond the end of the list.
298 : * @retval CHIP_ERROR_BUFFER_TOO_SMALL Name is too large to be written in buffer.
299 : * @retval other Another system or platform error.
300 : *
301 : * Writes the name of the network interface as \c NUL terminated text string at \c nameBuf.
302 : */
303 : CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);
304 :
305 : /**
306 : * Returns whether the current network interface is up.
307 : *
308 : * @return \c true if current network interface is up, \c false if not
309 : * or if the iterator is positioned beyond the end of the list.
310 : */
311 : bool IsUp();
312 :
313 : /**
314 : * Returns whether the current network interface is a loopback interface
315 : *
316 : * @return \c true if current network interface is a loopback interface, \c false
317 : * if not, or if the iterator is positioned beyond the end of the list.
318 : */
319 : bool IsLoopback();
320 :
321 : /**
322 : * Returns whether the current network interface supports multicast.
323 : *
324 : * @return \c true if current network interface supports multicast, \c false
325 : * if not, or if the iterator is positioned beyond the end of the list.
326 : */
327 : bool SupportsMulticast();
328 :
329 : /**
330 : * Returns whether the current network interface has a broadcast address.
331 : *
332 : * @return \c true if current network interface has a broadcast address, \c false
333 : * if not, or if the iterator is positioned beyond the end of the list.
334 : */
335 : bool HasBroadcastAddress();
336 :
337 : /**
338 : * Get the interface type of the current network interface.
339 : *
340 : * @param[out] type Object to save the interface type.
341 : */
342 : CHIP_ERROR GetInterfaceType(InterfaceType & type);
343 :
344 : /**
345 : * Get the hardware address of the current network interface
346 : *
347 : * @param[out] addressBuffer Region of memory to write the hardware address.
348 : * @param[out] addressSize Size of the address saved to a buffer.
349 : * @param[in] addressBufferSize Maximum size of a buffer to save data.
350 : */
351 : CHIP_ERROR GetHardwareAddress(uint8_t * addressBuffer, uint8_t & addressSize, uint8_t addressBufferSize);
352 :
353 : protected:
354 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
355 : struct netif * mCurNetif;
356 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
357 :
358 : #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
359 : struct if_nameindex * mIntfArray;
360 : size_t mCurIntf;
361 : short mIntfFlags;
362 : bool mIntfFlagsCached;
363 :
364 : short GetFlags();
365 : #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
366 :
367 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
368 : InterfaceId::PlatformType mCurrentId = 1;
369 : net_if * mCurrentInterface = nullptr;
370 : #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
371 : #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
372 : struct otIp6AddressInfo * mCurNetif;
373 : #endif
374 : };
375 :
376 : /**
377 : * @brief Iterator for the list of system network interface IP addresses.
378 : *
379 : * @details
380 : * Use objects of this class to iterate the list of system network interface
381 : * interface IP addresses.
382 : *
383 : * Methods on an individual instance of this class are *not* thread-safe;
384 : * however separate instances may be used simultaneously by multiple threads.
385 : *
386 : * On multi-threaded LwIP systems, instances are thread-safe relative to other
387 : * threads accessing the global LwIP state provided that: 1) other threads hold
388 : * the LwIP core lock while mutating the list of netifs; and 2) netif object
389 : * themselves are never destroyed.
390 : *
391 : * On sockets-based systems, iteration is always stable in the face of changes
392 : * to the underlying system's interfaces and/or addresses.
393 : *
394 : * On LwIP systems, iteration is stable except in the case where the interface
395 : * associated with the current address is removed, in which case iteration may
396 : * end prematurely.
397 : */
398 : class DLL_EXPORT InterfaceAddressIterator
399 : {
400 : public:
401 : /**
402 : * Constructs an InterfaceAddressIterator object.
403 : *
404 : * Starts the iterator at the first network address. On some platforms,
405 : * this constructor may allocate resources recycled by the destructor.
406 : */
407 : InterfaceAddressIterator();
408 :
409 : /**
410 : * Destroys an InterfaceAddressIterator object.
411 : *
412 : * Recycles any resources allocated by the constructor.
413 : */
414 : ~InterfaceAddressIterator();
415 :
416 : /**
417 : * Test whether the iterator is positioned on an interface address
418 : *
419 : * @return \c true if the iterator is positioned on an interface address;
420 : * \c false if positioned beyond the end of the address list.
421 : */
422 : bool HasCurrent();
423 :
424 : /**
425 : * @fn bool InterfaceAddressIterator::Next(void)
426 : *
427 : * @brief Advance the iterator to the next interface address.
428 : *
429 : * @return \c false if advanced beyond the end, else \c true.
430 : *
431 : * @details
432 : * Advances the iterator to the next interface address or to a position
433 : * beyond the end of the address list.
434 : *
435 : * On LwIP, this method is thread-safe provided that: 1) other threads hold
436 : * the LwIP core lock while mutating the netif list; and 2) netif objects
437 : * themselves are never destroyed. Additionally, iteration on LwIP systems
438 : * will terminate early if the current interface is removed from the list.
439 : */
440 : bool Next();
441 :
442 : /**
443 : * @fn IPAddress InterfaceAddressIterator::GetAddress(void)
444 : *
445 : * @brief Get the current interface address.
446 : *
447 : * @param[out] outIPAddress The current interface address
448 : *
449 : * @return CHIP_NO_ERROR if the result IPAddress is valid.
450 : * @return CHIP_ERROR_SENTINEL if the iterator is positioned beyond the end of the address list.
451 : * @return other error from lower-level code
452 : */
453 : CHIP_ERROR GetAddress(IPAddress & outIPAddress);
454 :
455 : /**
456 : * @fn uint8_t InterfaceAddressIterator::GetPrefixLength(void)
457 : *
458 : * @brief Gets the network prefix associated with the current interface address.
459 : *
460 : * @return the network prefix (in bits) or 0 if the iterator is positioned beyond
461 : * the end of the address list.
462 : *
463 : * @details
464 : * On LwIP, this method simply returns the hard-coded constant 64.
465 : *
466 : * Note Well: the standard subnet prefix on all links other than PPP
467 : * links is 64 bits. On PPP links and some non-broadcast multipoint access
468 : * links, the convention is either 127 bits or 128 bits, but it might be
469 : * something else. On most platforms, the system's interface address
470 : * structure can represent arbitrary prefix lengths between 0 and 128.
471 : */
472 : uint8_t GetPrefixLength();
473 :
474 : /**
475 : * @fn InterfaceId InterfaceAddressIterator::GetInterfaceId(void)
476 : *
477 : * @brief Returns the network interface id associated with the current
478 : * interface address.
479 : *
480 : * @return the interface id or \c InterfaceId() if the iterator
481 : * is positioned beyond the end of the address list.
482 : */
483 : InterfaceId GetInterfaceId();
484 :
485 : /**
486 : * @fn CHIP_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize)
487 : *
488 : * @brief Get the name of the network interface associated with the
489 : * current interface address.
490 : *
491 : * @param[in] nameBuf region of memory to write the interface name
492 : * @param[in] nameBufSize size of the region denoted by \c nameBuf
493 : *
494 : * @retval CHIP_NO_ERROR successful result, interface name written
495 : * @retval CHIP_ERROR_BUFFER_TOO_SMALL name is too large to be written in buffer
496 : * @retval CHIP_ERROR_INCORRECT_STATE
497 : * the iterator is not currently positioned on an
498 : * interface address
499 : * @retval other another system or platform error
500 : *
501 : * @details
502 : * Writes the name of the network interface as \c NUL terminated text string
503 : * at \c nameBuf.
504 : */
505 : CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);
506 :
507 : /**
508 : * Returns whether the network interface associated with the current interface address is up.
509 : *
510 : * @return \c true if current network interface is up, \c false if not, or
511 : * if the iterator is not positioned on an interface address.
512 : */
513 : bool IsUp();
514 :
515 : /**
516 : * Returns whether the current network interface is a loopback interface
517 : *
518 : * @return \c true if current network interface is a loopback interface, \c false
519 : * if not, or if the iterator is positioned beyond the end of the list.
520 : */
521 : bool IsLoopback();
522 :
523 : /**
524 : * Returns whether the network interface associated with the current interface address supports multicast.
525 : *
526 : * @return \c true if multicast is supported, \c false if not, or
527 : * if the iterator is not positioned on an interface address.
528 : */
529 : bool SupportsMulticast();
530 :
531 : /**
532 : * Returns whether the network interface associated with the current interface address has an IPv4 broadcast address.
533 : *
534 : * @return \c true if the interface has a broadcast address, \c false if not, or
535 : * if the iterator is not positioned on an interface address.
536 : */
537 : bool HasBroadcastAddress();
538 :
539 : private:
540 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
541 : enum
542 : {
543 : kBeforeStartIndex = -1
544 : };
545 :
546 : InterfaceIterator mIntfIter;
547 : int mCurAddrIndex;
548 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
549 :
550 : #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
551 : struct ifaddrs * mAddrsList;
552 : struct ifaddrs * mCurAddr;
553 : #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
554 :
555 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
556 : InterfaceIterator mIntfIter;
557 : net_if_ipv6 * mIpv6 = nullptr;
558 : int mCurAddrIndex = -1;
559 : #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
560 : #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
561 : const otNetifAddress * mNetifAddrList;
562 : const otNetifAddress * mCurAddr;
563 : #endif // #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
564 : };
565 :
566 : #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
567 : inline InterfaceIterator::InterfaceIterator(void) {}
568 : inline InterfaceIterator::~InterfaceIterator() = default;
569 : inline InterfaceAddressIterator::~InterfaceAddressIterator() = default;
570 : inline bool InterfaceIterator::HasCurrent(void)
571 : {
572 : return mCurNetif != NULL;
573 : }
574 : #endif
575 :
576 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
577 :
578 : inline InterfaceIterator::InterfaceIterator(void)
579 : {
580 : mCurNetif = netif_list;
581 : }
582 :
583 : inline InterfaceIterator::~InterfaceIterator(void) {}
584 :
585 : inline bool InterfaceIterator::HasCurrent(void)
586 : {
587 : return mCurNetif != NULL;
588 : }
589 :
590 : inline InterfaceId InterfaceIterator::GetInterfaceId(void)
591 : {
592 : return InterfaceId(mCurNetif);
593 : }
594 :
595 : inline InterfaceAddressIterator::InterfaceAddressIterator(void)
596 : {
597 : mCurAddrIndex = kBeforeStartIndex;
598 : }
599 :
600 : inline InterfaceAddressIterator::~InterfaceAddressIterator(void) {}
601 :
602 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
603 :
604 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
605 : inline InterfaceIterator::~InterfaceIterator() = default;
606 : inline InterfaceAddressIterator::~InterfaceAddressIterator() = default;
607 : #endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
608 :
609 : } // namespace Inet
610 : } // namespace chip
|