Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / inet / InetInterface.h
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 <support/DLLUtil.h>
34
35 #if CHIP_SYSTEM_CONFIG_USE_LWIP
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 <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 #include <stddef.h>
53 #include <stdint.h>
54
55 namespace chip {
56 namespace Inet {
57
58 class IPAddress;
59 class IPPrefix;
60
61 /**
62  * @typedef     InterfaceId
63  *
64  * @brief       Indicator for system network interfaces.
65  *
66  * @details
67  *  Portability depends on never witnessing this alias. It may be replaced by a
68  *  concrete opaque class in the future.
69  *
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.
74  */
75
76 #if CHIP_SYSTEM_CONFIG_USE_LWIP
77 typedef struct netif * InterfaceId;
78 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
79
80 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
81 typedef unsigned InterfaceId;
82 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
83
84 #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
85 typedef int InterfaceId;
86 #endif
87
88 /**
89  * @def     INET_NULL_INTERFACEID
90  *
91  * @brief   The distinguished value indicating no network interface.
92  *
93  * @details
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.
98  */
99
100 #if CHIP_SYSTEM_CONFIG_USE_LWIP
101 #define INET_NULL_INTERFACEID NULL
102 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
103
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
107
108 /**
109  * @brief   Test \c ID for inequivalence with \c INET_NULL_INTERFACEID
110  *
111  * @details
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.
114  */
115 #define IsInterfaceIdPresent(intfId) ((intfId) != INET_NULL_INTERFACEID)
116
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);
120
121 /**
122  * @brief   Iterator for the list of system network interfaces.
123  *
124  * @details
125  *  Use objects of this class to iterate the list of system network interfaces.
126  *
127  *  Methods on an individual instance of this class are *not* thread-safe;
128  *  however separate instances may be used simultaneously by multiple threads.
129  *
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.
134  *
135  *  On sockets-based systems, iteration is always stable in the face of changes
136  *  to the underlying system's interfaces.
137  *
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
140  *  immediately.
141  */
142 class InterfaceIterator
143 {
144 public:
145     InterfaceIterator();
146     ~InterfaceIterator();
147
148     bool HasCurrent();
149     bool Next();
150     InterfaceId GetInterface();
151     InterfaceId GetInterfaceId();
152     INET_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);
153     bool IsUp();
154     bool SupportsMulticast();
155     bool HasBroadcastAddress();
156
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;
165 #else
166     // No constant available here - set some reasonable size
167     static constexpr size_t kMaxIfNameLength = 33;
168 #endif
169
170 protected:
171 #if CHIP_SYSTEM_CONFIG_USE_LWIP
172     struct netif * mCurNetif;
173 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
174
175 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
176     struct if_nameindex * mIntfArray;
177     size_t mCurIntf;
178     short mIntfFlags;
179     bool mIntfFlagsCached;
180
181     short GetFlags();
182 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
183
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
188 };
189
190 /**
191  * @brief   Iterator for the list of system network interface IP addresses.
192  *
193  * @details
194  *  Use objects of this class to iterate the list of system network interface
195  *  interface IP addresses.
196  *
197  *  Methods on an individual instance of this class are *not* thread-safe;
198  *  however separate instances may be used simultaneously by multiple threads.
199  *
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.
204  *
205  *  On sockets-based systems, iteration is always stable in the face of changes
206  *  to the underlying system's interfaces and/or addresses.
207  *
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
210  *  end prematurely.
211  */
212 class DLL_EXPORT InterfaceAddressIterator
213 {
214 public:
215     InterfaceAddressIterator();
216     ~InterfaceAddressIterator();
217
218     bool HasCurrent();
219     bool Next();
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);
227     bool IsUp();
228     bool SupportsMulticast();
229     bool HasBroadcastAddress();
230
231 private:
232 #if CHIP_SYSTEM_CONFIG_USE_LWIP
233     enum
234     {
235         kBeforeStartIndex = -1
236     };
237
238     InterfaceIterator mIntfIter;
239     int mCurAddrIndex;
240 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
241
242 #if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
243     struct ifaddrs * mAddrsList;
244     struct ifaddrs * mCurAddr;
245 #endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
246
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
252 };
253
254 #if CHIP_SYSTEM_CONFIG_USE_LWIP
255
256 inline InterfaceIterator::InterfaceIterator(void)
257 {
258     mCurNetif = netif_list;
259 }
260
261 inline InterfaceIterator::~InterfaceIterator(void) {}
262
263 inline bool InterfaceIterator::HasCurrent(void)
264 {
265     return mCurNetif != NULL;
266 }
267
268 inline InterfaceId InterfaceIterator::GetInterfaceId(void)
269 {
270     return mCurNetif;
271 }
272
273 inline InterfaceAddressIterator::InterfaceAddressIterator(void)
274 {
275     mCurAddrIndex = kBeforeStartIndex;
276 }
277
278 inline InterfaceAddressIterator::~InterfaceAddressIterator(void) {}
279
280 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
281
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
286
287 /**
288  * @brief    Deprecated alias for \c GetInterfaceId(void)
289  */
290 inline InterfaceId InterfaceIterator::GetInterface()
291 {
292     return GetInterfaceId();
293 }
294
295 /**
296  * @brief    Deprecated alias for \c GetInterfaceId(void)
297  */
298 inline InterfaceId InterfaceAddressIterator::GetInterface()
299 {
300     return GetInterfaceId();
301 }
302
303 /**
304  * @brief    Deprecated alias for \c GetPrefixLength(void)
305  */
306 inline uint8_t InterfaceAddressIterator::GetIPv6PrefixLength()
307 {
308     return GetPrefixLength();
309 }
310
311 } // namespace Inet
312 } // namespace chip