Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / inet / IPAddress-StringFuncts.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
5  *
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
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 /**
20  *    @file
21  *      This file implements the human-readable string formatting and
22  *      parsing methods from class <tt>Inet::IPAddress</tt>.
23  *
24  */
25
26 #ifndef __STDC_LIMIT_MACROS
27 #define __STDC_LIMIT_MACROS
28 #endif
29 #include <limits>
30 #include <stdint.h>
31 #include <string.h>
32
33 #include <inet/InetLayer.h>
34 #include <support/CodeUtils.h>
35
36 #if !CHIP_SYSTEM_CONFIG_USE_LWIP
37 #include <arpa/inet.h>
38 #endif
39
40 namespace chip {
41 namespace Inet {
42
43 char * IPAddress::ToString(char * buf, uint32_t bufSize) const
44 {
45 #if CHIP_SYSTEM_CONFIG_USE_LWIP
46 #if INET_CONFIG_ENABLE_IPV4
47     if (IsIPv4())
48     {
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
56     }
57     else
58 #endif // INET_CONFIG_ENABLE_IPV4
59     {
60         ip6_addr_t ip6_addr = ToIPv6();
61         ip6addr_ntoa_r(&ip6_addr, buf, (int) bufSize);
62     }
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.
67     bufSize =
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
70     if (IsIPv4())
71     {
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);
76     }
77     else
78 #endif // INET_CONFIG_ENABLE_IPV4
79     {
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);
84     }
85 #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
86
87     return buf;
88 }
89
90 bool IPAddress::FromString(const char * str, IPAddress & output)
91 {
92 #if INET_CONFIG_ENABLE_IPV4
93     if (strchr(str, ':') == nullptr)
94     {
95 #if CHIP_SYSTEM_CONFIG_USE_LWIP
96 #if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
97         ip4_addr_t ipv4Addr;
98         if (!ip4addr_aton(str, &ipv4Addr))
99             return false;
100 #else  // LWIP_VERSION_MAJOR <= 1
101         ip_addr_t ipv4Addr;
102         if (!ipaddr_aton(str, &ipv4Addr))
103             return false;
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)
108             return false;
109 #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
110         output = FromIPv4(ipv4Addr);
111     }
112     else
113 #endif // INET_CONFIG_ENABLE_IPV4
114     {
115 #if CHIP_SYSTEM_CONFIG_USE_LWIP
116         ip6_addr_t ipv6Addr;
117         if (!ip6addr_aton(str, &ipv6Addr))
118             return false;
119 #else  // !CHIP_SYSTEM_CONFIG_USE_LWIP
120         struct in6_addr ipv6Addr;
121         if (inet_pton(AF_INET6, str, &ipv6Addr) < 1)
122             return false;
123 #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
124         output = FromIPv6(ipv6Addr);
125     }
126
127     return true;
128 }
129
130 bool IPAddress::FromString(const char * str, size_t strLen, IPAddress & output)
131 {
132     bool res = false;
133
134     if (strLen < INET6_ADDRSTRLEN)
135     {
136         char hostNameBuf[INET6_ADDRSTRLEN];
137         memcpy(hostNameBuf, str, strLen);
138         hostNameBuf[strLen] = 0;
139         res                 = IPAddress::FromString(hostNameBuf, output);
140     }
141
142     return res;
143 }
144
145 } // namespace Inet
146 } // namespace chip