Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2021 Project CHIP Authors
4 : * Copyright (c) 2019 Google LLC.
5 : * Copyright (c) 2013-2018 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 class <tt>Inet::IPAddress</tt> and
23 : * related enumerated constants. The CHIP Inet Layer uses objects
24 : * of this class to represent Internet protocol addresses of both
25 : * IPv4 and IPv6 address families. (IPv4 addresses are stored
26 : * internally as IPv4-Mapped IPv6 addresses.)
27 : */
28 :
29 : #pragma once
30 :
31 : #include <stddef.h>
32 : #include <stdint.h>
33 : #include <string.h>
34 : #include <type_traits>
35 :
36 : #include <lib/core/CHIPError.h>
37 : #include <lib/support/BitFlags.h>
38 : #include <lib/support/DLLUtil.h>
39 :
40 : #include <inet/InetConfig.h>
41 : #include <inet/InetError.h>
42 :
43 : #include "inet/IANAConstants.h"
44 :
45 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
46 : #include <lwip/init.h>
47 : #include <lwip/ip_addr.h>
48 : #if INET_CONFIG_ENABLE_IPV4
49 : #include <lwip/ip4_addr.h>
50 : #endif // INET_CONFIG_ENABLE_IPV4
51 : #include <lwip/inet.h>
52 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
53 :
54 : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
55 : #include <openthread/icmp6.h>
56 : #include <openthread/ip6.h>
57 : #if CHIP_DEVICE_LAYER_TARGET_NRFCONNECT || CHIP_DEVICE_LAYER_TARGET_ZEPHYR
58 : // Currently to use openthread endpoint in nRFConnect, we must fetch defines from zephyr's net
59 : // OpenThread header. It will be removed once the Zephyr version is updated to 4.2.0.
60 : #include <zephyr/net/openthread.h>
61 : #endif
62 : #endif // CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
63 :
64 : #if CHIP_SYSTEM_CONFIG_USE_POSIX_SOCKETS
65 : #include <net/if.h>
66 : #include <netinet/in.h>
67 : #include <sys/socket.h>
68 : #endif // CHIP_SYSTEM_CONFIG_USE_POSIX_SOCKETS
69 :
70 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_SOCKETS
71 : #include "ZephyrSocket.h" // nogncheck
72 : #endif
73 :
74 : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT && INET_CONFIG_ENABLE_IPV4
75 : #error Forbidden : native Open Thread implementation with IPV4 enabled
76 : #endif
77 :
78 : #include <inet/InetInterface.h>
79 :
80 : #define NL_INET_IPV6_ADDR_LEN_IN_BYTES (16)
81 : #define NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES (14)
82 :
83 : namespace chip {
84 : namespace Inet {
85 :
86 : /**
87 : * Internet protocol address family
88 : */
89 : enum class IPAddressType : uint8_t
90 : {
91 : kUnknown = 0, ///< Not used.
92 : #if INET_CONFIG_ENABLE_IPV4
93 : kIPv4 = 1, ///< Internet protocol version 4.
94 : #endif // INET_CONFIG_ENABLE_IPV4
95 : kIPv6 = 2, ///< Internet protocol version 6.
96 : kAny = 3 ///< The unspecified internet address (independent of protocol version).
97 : };
98 :
99 : /**
100 : * Internet protocol v6 multicast flags
101 : *
102 : * Values of the \c IPv6MulticastFlag type are used to call the <tt>IPAddress::MakeIPv6Multicast()</tt> methods.
103 : * They indicate the type of IPv6 multicast address to create. These numbers are registered by IETF with IANA.
104 : */
105 : enum class IPv6MulticastFlag : uint8_t
106 : {
107 : /** The multicast address is (1) transient (i.e., dynamically-assigned) rather than (0) well-known (i.e, IANA-assigned). */
108 : kTransient = 0x01,
109 :
110 : /** The multicast address is (1) based on a network prefix. */
111 : kPrefix = 0x02
112 : };
113 : using IPv6MulticastFlags = BitFlags<IPv6MulticastFlag>;
114 :
115 : #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
116 : /**
117 : * SockAddr should be used when calling any API that returns (by copying into
118 : * it) a sockaddr, because that will need enough storage that it can hold data
119 : * for any socket type.
120 : *
121 : * It can also be used when calling an API that accepts a sockaddr, to simplify
122 : * the type-punning needed.
123 : */
124 : union SockAddr
125 : {
126 : sockaddr any;
127 : sockaddr_in in;
128 : sockaddr_in6 in6;
129 : sockaddr_storage storage;
130 : };
131 :
132 : /**
133 : * SockAddrWithoutStorage can be used any time we want to do the sockaddr
134 : * type-punning but will not store the data ourselves (e.g. we're working with
135 : * an existing sockaddr pointer, and reintepret it as a
136 : * pointer-to-SockAddrWithoutStorage).
137 : */
138 : union SockAddrWithoutStorage
139 : {
140 : sockaddr any;
141 : sockaddr_in in;
142 : sockaddr_in6 in6;
143 : };
144 : #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
145 :
146 : /**
147 : * @brief Internet protocol address
148 : *
149 : * @details
150 : * The CHIP Inet Layer uses objects of this class to represent Internet
151 : * protocol addresses (independent of protocol version).
152 : *
153 : */
154 : class DLL_EXPORT IPAddress
155 : {
156 : public:
157 : /**
158 : * Maximum length of the string representation of an IP address, including a terminating NUL.
159 : */
160 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
161 : static constexpr uint16_t kMaxStringLength = IP6ADDR_STRLEN_MAX;
162 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
163 : #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
164 : static constexpr uint16_t kMaxStringLength = INET6_ADDRSTRLEN;
165 : #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
166 :
167 : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
168 : #ifndef INET6_ADDRSTRLEN
169 : #define INET6_ADDRSTRLEN OT_IP6_ADDRESS_STRING_SIZE
170 : #endif
171 : static constexpr uint16_t kMaxStringLength = OT_IP6_ADDRESS_STRING_SIZE;
172 : #endif
173 : static constexpr uint16_t kMaxAddressWithInterfaceLength = kMaxStringLength + 1 + Inet::InterfaceId::kMaxIfNameLength;
174 :
175 : IPAddress() = default;
176 :
177 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
178 : explicit IPAddress(const ip6_addr_t & ipv6Addr);
179 : #if INET_CONFIG_ENABLE_IPV4 || LWIP_IPV4
180 : explicit IPAddress(const ip4_addr_t & ipv4Addr);
181 : explicit IPAddress(const ip_addr_t & addr);
182 : #endif // INET_CONFIG_ENABLE_IPV4
183 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
184 :
185 : #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
186 : explicit IPAddress(const struct in6_addr & ipv6Addr);
187 : #if INET_CONFIG_ENABLE_IPV4
188 : explicit IPAddress(const struct in_addr & ipv4Addr);
189 : #endif // INET_CONFIG_ENABLE_IPV4
190 : #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
191 :
192 : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
193 : explicit IPAddress(const otIp6Address & ipv6Addr);
194 : #endif
195 :
196 : /**
197 : * @brief Opaque word array to contain IP addresses (independent of protocol version)
198 : *
199 : * @details
200 : * IPv6 address use all 128-bits split into four 32-bit network byte
201 : * ordered unsigned integers. IPv4 addresses are IPv4-Mapped IPv6 addresses,
202 : * i.e. the first two words are zero, the third word contains 0xFFFF in
203 : * network byte order, and the fourth word contains the IPv4
204 : * address in network byte order.
205 : */
206 : uint32_t Addr[4];
207 :
208 : /**
209 : * @brief Test whether address is IPv6 compatible.
210 : *
211 : * @details
212 : * Use this method to check if the address belongs to the IPv6 address
213 : * family. Note well: the unspecified address is not an IPv6 address.
214 : *
215 : * @retval true The address is IPv6 and not the unspecified address.
216 : * @retval false The address is IPv4 or the unspecified address.
217 : */
218 : bool IsIPv6() const;
219 :
220 : /**
221 : * @brief Test whether address is IPv6 global unicast address.
222 : *
223 : * @details
224 : * Use this method to check if the address belongs to the IPv6 address
225 : * family and has the global unicast address prefix.
226 : *
227 : * @retval true Address is IPv6 global unicast
228 : * @retval false Otherwise
229 : */
230 : bool IsIPv6GlobalUnicast() const;
231 :
232 : /**
233 : * @brief Test whether address is IPv6 unique-local address (ULA).
234 : *
235 : * @details
236 : * Use this method to check if the address belongs to the IPv6 address
237 : * family and has the reserved IPv6 unique-local address prefix.
238 : *
239 : * @retval true Address is IPv6 unique-local
240 : * @retval false Otherwise
241 : */
242 : bool IsIPv6ULA() const;
243 :
244 : /**
245 : * @brief Test whether address is IPv6 link-local address (LL).
246 : *
247 : * @details
248 : * Use this method to check if the address belongs to the IPv6 address
249 : * family and has the reserved IPv6 link-local address prefix.
250 : *
251 : * @retval true Address is IPv6 link-local
252 : * @retval false Otherwise
253 : */
254 : bool IsIPv6LinkLocal() const;
255 :
256 : /**
257 : * @brief Test whether address is IPv6 multicast.
258 : *
259 : * @details
260 : * Use this method to check if the address belongs to the IPv6 address
261 : * family and has the reserved IPv6 multicast address prefix.
262 : *
263 : * @retval true Address is IPv6 multicast
264 : * @retval false Otherwise
265 : */
266 : bool IsIPv6Multicast() const;
267 :
268 : /**
269 : * @brief Test whether address is IPv4 or IPv6 multicast.
270 : *
271 : * @details
272 : * Use this method to check if the address belongs to the IPv4 or IPv6 address
273 : * family and has the reserved IPv4 or IPv6 multicast address prefix.
274 : *
275 : * @retval true Address is IPv4 or IPv6 multicast
276 : * @retval false Otherwise
277 : */
278 : bool IsMulticast() const;
279 :
280 : /**
281 : * @brief Extract the IID of an IPv6 ULA address.
282 : *
283 : * @details
284 : * Use this method with an IPv6 unique-local address (ULA) to extract the
285 : * identifier identifier (IID), which is the least significant 64 bits of
286 : * the address.
287 : *
288 : * @return 64-bit interface identifier, or zero if the IP address is not
289 : * an IPv6 unique-local address.
290 : */
291 : uint64_t InterfaceId() const;
292 :
293 : /**
294 : * @brief Extract the 16-bit subnet identifier of an IPv6 ULA address.
295 : *
296 : * @details
297 : * Use this method with an IPv6 unique-local address (ULA) to extract the
298 : * subnet identifier, which is the least significant 16 bits of the
299 : * network prefix. The network prefix is the most significant 64 bits of
300 : * of the address. In other words, the subnet identifier is located in
301 : * the 7th and 8th bytes of a 16-byte address.
302 : *
303 : * @return 16-bit subnet identifier, or zero if the IP address is not
304 : * an IPv6 unique-local address.
305 : */
306 : uint16_t Subnet() const;
307 :
308 : /**
309 : * @brief Extract the 16-bit global network identifier of an IPv6 ULA
310 : * address.
311 : *
312 : * @details
313 : * Use this method with an IPv6 unique-local address (ULA) to extract the
314 : * global network identifier, which is the 40 bits immediately following
315 : * the distinguished ULA network prefix, i.e. fd00::/8. In other words,
316 : * the global network identifier is located in the five bytes from the 2nd
317 : * 2nd through the 6th bytes in the address.
318 : *
319 : * @return 40-bit global network identifier, or zero if the IP address
320 : * is not an IPv6 unique-local address.
321 : */
322 : uint64_t GlobalId() const;
323 :
324 : /**
325 : * @brief Extract the type of the IP address.
326 : *
327 : * @details
328 : * Use this method to return an value of the enumerated type \c
329 : * IPAddressType to indicate the type of the IP address.
330 : *
331 : * @retval IPAddressType::kIPv4 The address is IPv4.
332 : * @retval IPAddressType::kIPv6 The address is IPv6.
333 : * @retval IPAddressType::kAny The address is the unspecified address.
334 : */
335 : IPAddressType Type() const;
336 :
337 : /**
338 : * @brief Compare this IP address with another for equivalence.
339 : *
340 : * @param[in] other The address to compare.
341 : *
342 : * @retval true If equivalent to \c other
343 : * @retval false Otherwise
344 : */
345 : bool operator==(const IPAddress & other) const;
346 :
347 : /**
348 : * @brief Compare this IP address with another for inequivalence.
349 : *
350 : * @param[in] other The address to compare.
351 : *
352 : * @retval true If equivalent to \c other
353 : * @retval false Otherwise
354 : */
355 : bool operator!=(const IPAddress & other) const;
356 :
357 : /**
358 : * @brief Emit the IP address in conventional text presentation format.
359 : *
360 : * @param[out] buf The address of the emitted text.
361 : * @param[in] bufSize The size of the buffer for the emitted text.
362 : *
363 : * @details
364 : * Use <tt>ToString(char *buf, uint32_t bufSize) const</tt> to write the
365 : * conventional text presentation form of the IP address to the memory
366 : * located at \c buf and extending as much as \c bufSize bytes, including
367 : * its NUL termination character.
368 : *
369 : * Note Well: not compliant with RFC 5952 on some platforms. Specifically,
370 : * zero compression may not be applied according to section 4.2.
371 : *
372 : * @return The argument \c buf if no formatting error, or zero otherwise.
373 : */
374 : char * ToString(char * buf, uint32_t bufSize) const;
375 : char * ToString(char * buf, uint32_t bufSize, const Inet::InterfaceId & interfaceId) const;
376 :
377 : /**
378 : * A version of ToString that writes to a literal and deduces how much space
379 : * it as to work with.
380 : */
381 : template <uint32_t N>
382 15492 : inline char * ToString(char (&buf)[N]) const
383 : {
384 15492 : return ToString(buf, N);
385 : }
386 :
387 : template <uint32_t N>
388 : inline char * ToString(char (&buf)[N], const Inet::InterfaceId & interfaceId) const
389 : {
390 : return ToString(buf, N, interfaceId);
391 : }
392 :
393 : /**
394 : * @brief Scan the IP address from its conventional presentation text.
395 : *
396 : * @param[in] str The address of the emitted text.
397 : * @param[out] output The object to set to the scanned address.
398 : *
399 : * @details
400 : * Use <tt>FromString(const char *str, IPAddress& output)</tt> to
401 : * overwrite an IP address by scanning the conventional text presentation
402 : * located at \c str.
403 : *
404 : * @retval true The presentation format is valid
405 : * @retval false Otherwise
406 : */
407 : static bool FromString(const char * str, IPAddress & output);
408 :
409 : /**
410 : * @brief Scan the IP address from its conventional presentation text.
411 : *
412 : * @param[in] str A pointer to the text to be scanned.
413 : * @param[in] strLen The length of the text to be scanned.
414 : * @param[out] output The object to set to the scanned address.
415 : *
416 : * @details
417 : * Use <tt>FromString(const char *str, size_t strLen, IPAddress& output)</tt> to
418 : * overwrite an IP address by scanning the conventional text presentation
419 : * located at \c str.
420 : *
421 : * @retval true The presentation format is valid
422 : * @retval false Otherwise
423 : */
424 : static bool FromString(const char * str, size_t strLen, IPAddress & output);
425 :
426 : /**
427 : * @brief
428 : * Scan the IP address from its conventional presentation text, including
429 : * the interface ID if present. (e.g. "fe80::2%wlan0"). If no interface ID
430 : * is present, then ifaceOutput will be set to the null interface ID.
431 : *
432 : * @param[in] str A pointer to the text to be scanned.
433 : * @param[out] addrOutput The object to set to the IP address.
434 : * @param[out] ifaceOutput The object to set to the interface ID.
435 : *
436 : * @retval true The presentation format is valid
437 : * @retval false Otherwise
438 : */
439 : static bool FromString(const char * str, IPAddress & addrOutput, Inet::InterfaceId & ifaceOutput);
440 :
441 : /**
442 : * @brief Emit the IP address in standard network representation.
443 : *
444 : * @param[in,out] p Reference to the cursor to use for writing.
445 : *
446 : * @details
447 : * Use <tt>WriteAddress(uint8_t *&p)</tt> to encode the IP address in
448 : * the binary format defined by RFC 4291 for IPv6 addresses. IPv4
449 : * addresses are encoded according to section 2.5.5.2 "IPv4-Mapped
450 : * IPv6 Address".
451 : */
452 : void WriteAddress(uint8_t *& p) const;
453 :
454 : /**
455 : * @brief Emit the IP address in standard network representation.
456 : *
457 : * @param[in,out] p Reference to the cursor to use for reading.
458 : * @param[out] output Object to receive decoded IP address.
459 : *
460 : * @details
461 : * Use <tt>ReadAddress(uint8_t *&p, IPAddress &output)</tt> to decode
462 : * the IP address at \c p to the object \c output.
463 : */
464 : static void ReadAddress(const uint8_t *& p, IPAddress & output);
465 :
466 : /**
467 : * @brief Test whether address is IPv4 compatible.
468 : *
469 : * @details
470 : * Use this method to check if the address belongs to the IPv4 address
471 : * family. Note well: the unspecified address is not an IPv4 address.
472 : *
473 : * @retval true The address is IPv4 and not the unspecified address.
474 : * @retval false The address is IPv6 or the unspecified address.
475 : */
476 : bool IsIPv4() const;
477 :
478 : /**
479 : * @brief Test whether address is IPv4 multicast.
480 : *
481 : * @details
482 : * Use this method to check if the address is an IPv4 multicast
483 : * address.
484 : *
485 : * @retval true Address is the IPv4 multicast
486 : * @retval false Otherwise
487 : */
488 : bool IsIPv4Multicast() const;
489 :
490 : /**
491 : * @brief Test whether address is IPv4 broadcast.
492 : *
493 : * @details
494 : * Use this method to check if the address is the special purpose IPv4
495 : * broadcast address.
496 : *
497 : * @retval true Address is the IPv4 broadcast
498 : * @retval false Otherwise
499 : */
500 : bool IsIPv4Broadcast() const;
501 :
502 : /**
503 : * @fn ToIPv4() const
504 : *
505 : * @brief Extract the IPv4 address as a platform data structure.
506 : *
507 : * @details
508 : * Use <tt>ToIPv4() const</tt> to extract the content as an IPv4 address,
509 : * if possible. IPv6 addresses and the unspecified address are
510 : * extracted as <tt>0.0.0.0</tt>.
511 : *
512 : * The result is either of type <tt>struct in_addr</tt> (on POSIX) or
513 : * <tt>ip4_addr_t</tt> (on LwIP).
514 : *
515 : * @return The encapsulated IPv4 address, or \c 0.0.0.0 if the address is
516 : * either unspecified or not an IPv4 address.
517 : */
518 :
519 : /**
520 : * @fn ToIPv6() const
521 : *
522 : * @brief Extract the IPv6 address as a platform data structure.
523 : *
524 : * @details
525 : * Use <tt>ToIPv6() const</tt> to extract the content as an IPv6 address,
526 : * if possible. IPv4 addresses and the unspecified address are extracted
527 : * as <tt>[::]</tt>.
528 : *
529 : * The result is either of type <tt>struct in6_addr</tt> (on POSIX) or
530 : * <tt>ip6_addr_t</tt> (on LwIP).
531 : *
532 : * @return The encapsulated IPv4 address, or \c [::] if the address is
533 : * either unspecified or not an IPv4 address.
534 : */
535 :
536 : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
537 :
538 : /**
539 : * @fn ToLwIPAddr() const
540 : *
541 : * @brief Extract the IP address as a LwIP ip_addr_t structure.
542 : *
543 : * @details
544 : * Use <tt>ToLwIPAddr() const</tt> to extract the content as an IP address,
545 : * if possible.
546 : *
547 : * @return An LwIP ip_addr_t structure corresponding to the IP address.
548 : */
549 : ip_addr_t ToLwIPAddr(void) const;
550 :
551 : /**
552 : * Extract the IP address as a LwIP ip_addr_t structure.
553 : *
554 : * If the IP address is Any, the result is IP6_ADDR_ANY unless the requested addressType is kIPv4.
555 : * If the requested addressType is IPAddressType::kAny, extracts the IP address as an LwIP ip_addr_t structure.
556 : * Otherwise, returns INET_ERROR_WRONG_ADDRESS_TYPE if the requested addressType does not match the IP address.
557 : */
558 : CHIP_ERROR ToLwIPAddr(IPAddressType addressType, ip_addr_t & outAddress) const;
559 :
560 : /**
561 : * @brief Convert the INET layer address type to its underlying LwIP type.
562 : *
563 : * @details
564 : * Use <tt>ToLwIPAddrType(IPAddressType)</tt> to convert the IP address type
565 : * to its underlying LwIP address type code.
566 : */
567 : static lwip_ip_addr_type ToLwIPAddrType(IPAddressType);
568 :
569 : ip6_addr_t ToIPv6(void) const;
570 :
571 : #if INET_CONFIG_ENABLE_IPV4
572 : ip4_addr_t ToIPv4(void) const;
573 : #endif // INET_CONFIG_ENABLE_IPV4
574 :
575 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
576 :
577 : #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
578 :
579 : struct in6_addr ToIPv6() const;
580 :
581 : #if INET_CONFIG_ENABLE_IPV4
582 : struct in_addr ToIPv4() const;
583 : #endif // INET_CONFIG_ENABLE_IPV4
584 :
585 : /**
586 : * Get the IP address from a SockAddr.
587 : */
588 : static CHIP_ERROR GetIPAddressFromSockAddr(const SockAddrWithoutStorage & sockaddr, IPAddress & outIPAddress);
589 1112 : static CHIP_ERROR GetIPAddressFromSockAddr(const sockaddr & sockaddr, IPAddress & outIPAddress)
590 : {
591 1112 : return GetIPAddressFromSockAddr(reinterpret_cast<const SockAddrWithoutStorage &>(sockaddr), outIPAddress);
592 : }
593 496 : static IPAddress FromSockAddr(const sockaddr_in6 & sockaddr) { return IPAddress(sockaddr.sin6_addr); }
594 : #if INET_CONFIG_ENABLE_IPV4
595 671 : static IPAddress FromSockAddr(const sockaddr_in & sockaddr) { return IPAddress(sockaddr.sin_addr); }
596 : #endif // INET_CONFIG_ENABLE_IPV4
597 :
598 : #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_USE_NETWORK_FRAMEWORK
599 :
600 : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
601 : otIp6Address ToIPv6() const;
602 : static IPAddress FromOtAddr(const otIp6Address & address);
603 : #endif // CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
604 :
605 : /**
606 : * @brief Construct an IPv6 unique-local address (ULA) from its parts.
607 : *
608 : * @details
609 : * Use <tt>MakeULA(uint64_t globalId, uint16_t subnet, uint64_t
610 : * interfaceId)</tt> to construct a unique-local address (ULA) with global
611 : * network identifier \c globalId, subnet identifier \c subnet and
612 : * interface identifier (IID) \c interfaceId.
613 : *
614 : * @return The constructed IP address.
615 : */
616 : static IPAddress MakeULA(uint64_t globalId, uint16_t subnet, uint64_t interfaceId);
617 :
618 : /**
619 : * @brief Construct an IPv6 link-local address (LL) from its IID.
620 : *
621 : * @details
622 : * Use <tt>MakeLLA(uint64_t interfaceId)</tt> to construct an IPv6
623 : * link-local address (LL) with interface identifier \c interfaceId.
624 : *
625 : * @return The constructed IP address.
626 : */
627 : static IPAddress MakeLLA(uint64_t interfaceId);
628 :
629 : /**
630 : * @brief Construct an IPv6 multicast address from its parts.
631 : *
632 : * @details
633 : * Use <tt>MakeIPv6Multicast(uint8_t flags, uint8_t scope,
634 : * uint8_t groupId[14])</tt> to construct an IPv6 multicast
635 : * address with \c flags for routing scope \c scope and group
636 : * identifier octets \c groupId.
637 : *
638 : * @return The constructed IP address.
639 : */
640 : static IPAddress MakeIPv6Multicast(IPv6MulticastFlags aFlags, uint8_t aScope,
641 : const uint8_t aGroupId[NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES]);
642 :
643 : /**
644 : * @brief Construct an IPv6 multicast address from its parts.
645 : *
646 : * @details
647 : * Use <tt>MakeIPv6Multicast(uint8_t flags, uint8_t scope,
648 : * uint32_t groupId)</tt> to construct an IPv6 multicast
649 : * address with \c flags for routing scope \c scope and group
650 : * identifier \c groupId.
651 : *
652 : * @return The constructed IP address.
653 : */
654 : static IPAddress MakeIPv6Multicast(IPv6MulticastFlags aFlags, uint8_t aScope, uint32_t aGroupId);
655 :
656 : /**
657 : * @brief Construct a well-known IPv6 multicast address from its parts.
658 : *
659 : * @details
660 : * Use <tt>MakeIPv6WellKnownMulticast(uint8_t scope, uint32_t
661 : * groupId)</tt> to construct an IPv6 multicast address for
662 : * routing scope \c scope and group identifier \c groupId.
663 : *
664 : * @return The constructed IP address.
665 : */
666 : static IPAddress MakeIPv6WellKnownMulticast(uint8_t aScope, uint32_t aGroupId);
667 :
668 : /**
669 : * @brief Construct a transient IPv6 multicast address from its parts.
670 : *
671 : * @details
672 : * Use <tt>MakeIPv6TransientMulticast(uint8_t flags, uint8_t scope,
673 : * uint8_t groupId[14])</tt> to construct a transient IPv6
674 : * multicast address with \c flags for routing scope \c scope and
675 : * group identifier octets \c groupId.
676 : *
677 : * @return The constructed IP address.
678 : */
679 : static IPAddress MakeIPv6TransientMulticast(IPv6MulticastFlags aFlags, uint8_t aScope,
680 : const uint8_t aGroupId[NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES]);
681 :
682 : /**
683 : * @brief Construct a transient, prefix IPv6 multicast address from its parts.
684 : *
685 : * @details
686 : * Use <tt>MakeIPv6PrefixMulticast(uint8_t scope, uint8_t
687 : * prefixlen, const uint64_t prefix, uint32_t groupId)</tt> to
688 : * construct a transient, prefix IPv6 multicast address with for
689 : * routing scope \c scope and group identifier octets \c groupId,
690 : * qualified by the prefix \c prefix of length \c prefixlen bits.
691 : *
692 : * @return The constructed IP address.
693 : */
694 : static IPAddress MakeIPv6PrefixMulticast(uint8_t aScope, uint8_t aPrefixLength, const uint64_t & aPrefix, uint32_t aGroupId);
695 :
696 : /**
697 : * @brief Construct the well-known IPv6 multicast address ff05::fa.
698 : *
699 : * @details
700 : * Returns the site-local scoped well-known multicast address
701 : * with group identifier 0xFA, used for Matter groupcast messaging.
702 : *
703 : * @return The constructed IP address.
704 : */
705 : static IPAddress MakeIPv6MatterIANAMulticastAddr();
706 :
707 : /**
708 : * @brief The distinguished unspecified IP address object.
709 : *
710 : * @details
711 : * This object is used as a constant for equivalence comparisons. It must
712 : * not be modified by users of the CHIP Inet Layer.
713 : */
714 : static IPAddress Any;
715 :
716 : /**
717 : * Creates a loopback of the specified type. Type MUST be IPv6/v4.
718 : *
719 : * If type is anything else (or IPv4 is not available) an IPv6
720 : * loopback will be created.
721 : */
722 : static IPAddress Loopback(IPAddressType type);
723 : };
724 :
725 : static_assert(std::is_trivial<IPAddress>::value, "IPAddress is not trivial");
726 :
727 : } // namespace Inet
728 : } // namespace chip
|