3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2013-2017 Nest Labs, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This file implements the human-readable string formatting and
22 * parsing methods from class <tt>Inet::IPAddress</tt>.
26 #ifndef __STDC_LIMIT_MACROS
27 #define __STDC_LIMIT_MACROS
33 #include <inet/InetLayer.h>
34 #include <support/CodeUtils.h>
36 #if !CHIP_SYSTEM_CONFIG_USE_LWIP
37 #include <arpa/inet.h>
43 char * IPAddress::ToString(char * buf, uint32_t bufSize) const
45 #if CHIP_SYSTEM_CONFIG_USE_LWIP
46 #if INET_CONFIG_ENABLE_IPV4
49 #if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
50 ip4_addr_t ip4_addr = ToIPv4();
51 ip4addr_ntoa_r(&ip4_addr, buf, (int) bufSize);
52 #else // LWIP_VERSION_MAJOR <= 1
53 ip_addr_t ip4_addr = ToIPv4();
54 ipaddr_ntoa_r(&ip4_addr, buf, (int) bufSize);
55 #endif // LWIP_VERSION_MAJOR <= 1
58 #endif // INET_CONFIG_ENABLE_IPV4
60 ip6_addr_t ip6_addr = ToIPv6();
61 ip6addr_ntoa_r(&ip6_addr, buf, (int) bufSize);
63 #else // !CHIP_SYSTEM_CONFIG_USE_LWIP
64 // socklen_t is sometimes signed, sometimes not, so the only safe way to do
65 // this is to promote everything to an unsigned type that's known to be big
66 // enough for everything, then cast back to uint32_t after taking the min.
68 static_cast<uint32_t>(min(static_cast<uintmax_t>(std::numeric_limits<socklen_t>::max()), static_cast<uintmax_t>(bufSize)));
69 #if INET_CONFIG_ENABLE_IPV4
72 const void * addr = &Addr[3];
73 const char * s = inet_ntop(AF_INET, addr, buf, static_cast<socklen_t>(bufSize));
74 // This cast is safe because |s| points into |buf| which is not const.
75 buf = const_cast<char *>(s);
78 #endif // INET_CONFIG_ENABLE_IPV4
80 const void * addr = &Addr[0];
81 const char * s = inet_ntop(AF_INET6, addr, buf, static_cast<socklen_t>(bufSize));
82 // This cast is safe because |s| points into |buf| which is not const.
83 buf = const_cast<char *>(s);
85 #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
90 bool IPAddress::FromString(const char * str, IPAddress & output)
92 #if INET_CONFIG_ENABLE_IPV4
93 if (strchr(str, ':') == nullptr)
95 #if CHIP_SYSTEM_CONFIG_USE_LWIP
96 #if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
98 if (!ip4addr_aton(str, &ipv4Addr))
100 #else // LWIP_VERSION_MAJOR <= 1
102 if (!ipaddr_aton(str, &ipv4Addr))
104 #endif // LWIP_VERSION_MAJOR <= 1
105 #else // !CHIP_SYSTEM_CONFIG_USE_LWIP
106 struct in_addr ipv4Addr;
107 if (inet_pton(AF_INET, str, &ipv4Addr) < 1)
109 #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
110 output = FromIPv4(ipv4Addr);
113 #endif // INET_CONFIG_ENABLE_IPV4
115 #if CHIP_SYSTEM_CONFIG_USE_LWIP
117 if (!ip6addr_aton(str, &ipv6Addr))
119 #else // !CHIP_SYSTEM_CONFIG_USE_LWIP
120 struct in6_addr ipv6Addr;
121 if (inet_pton(AF_INET6, str, &ipv6Addr) < 1)
123 #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
124 output = FromIPv6(ipv6Addr);
130 bool IPAddress::FromString(const char * str, size_t strLen, IPAddress & output)
134 if (strLen < INET6_ADDRSTRLEN)
136 char hostNameBuf[INET6_ADDRSTRLEN];
137 memcpy(hostNameBuf, str, strLen);
138 hostNameBuf[strLen] = 0;
139 res = IPAddress::FromString(hostNameBuf, output);