• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cerrno>
17 #include <netdb.h>
18 
19 #include "net_address.h"
20 #include "netstack_log.h"
21 #include "socket_exec_common.h"
22 #include "securec.h"
23 
24 namespace OHOS::NetStack::Socket {
25 
NetAddress()26 NetAddress::NetAddress() : family_(Family::IPv4), port_(0) {}
27 
NetAddress(const NetAddress & other)28 NetAddress::NetAddress(const NetAddress &other) : address_(other.address_), family_(other.family_), port_(other.port_)
29 {
30 }
31 
SetIpAddress(const std::string & address)32 void NetAddress::SetIpAddress(const std::string &address)
33 {
34     if (address.empty()) {
35         return;
36     }
37     if (address == "localhost") {
38         if (family_ == Family::IPv4) {
39             address_ = ConvertAddressToIp(address, AF_INET);
40         } else if (family_ == Family::IPv6) {
41             address_ = ConvertAddressToIp(address, AF_INET6);
42         }
43         return;
44     }
45     if (family_ == Family::IPv4) {
46         in6_addr ipv6{};
47         if (inet_pton(AF_INET6, address.c_str(), &ipv6) > 0) {
48             return;
49         }
50         auto pos = address.find('%');
51         if (pos != std::string::npos) {
52             auto subAddr = address.substr(0, pos);
53             in6_addr newIpv6{};
54             if (inet_pton(AF_INET6, subAddr.c_str(), &newIpv6) > 0) {
55                 return;
56             }
57         }
58         in_addr ipv4{};
59         if (inet_pton(AF_INET, address.c_str(), &(ipv4.s_addr)) > 0) {
60             address_ = address;
61             return;
62         }
63     } else {
64         in6_addr ipv6{};
65         if (inet_pton(AF_INET6, address.c_str(), &ipv6) > 0) {
66             address_ = address;
67             return;
68         }
69     }
70     SetIpAddressInner(address);
71 }
72 
SetIpAddressInner(const std::string & address)73 void NetAddress::SetIpAddressInner(const std::string &address)
74 {
75     if (family_ == Family::IPv4) {
76         constexpr int LONG_BASE = 10;
77         char *error = nullptr;
78         auto inet = std::strtol(address.c_str(), &error, LONG_BASE);
79         if (error && *error == '\0' && inet >= 0 && inet <= UINT32_MAX) {
80             in_addr addr{};
81             addr.s_addr = static_cast<in_addr_t>(inet);
82             address_ = inet_ntoa(addr);
83         }
84     } else if (family_ == Family::IPv6) {
85         auto pos = address.find('%');
86         if (pos == std::string::npos) {
87             return;
88         }
89         auto subAddr = address.substr(0, pos);
90         in6_addr ipv6{};
91         if (inet_pton(AF_INET6, subAddr.c_str(), &ipv6) > 0) {
92             address_ = subAddr;
93             return;
94         }
95     }
96 }
97 
SetRawAddress(const std::string & address)98 void NetAddress::SetRawAddress(const std::string &address)
99 {
100     address_ = address;
101 }
102 
SetAddress(const std::string & address)103 void NetAddress::SetAddress(const std::string &address)
104 {
105     if (family_ == Family::IPv4) {
106         struct in_addr ipv4;
107         if (inet_pton(AF_INET, address.c_str(), &(ipv4.s_addr)) > 0) {
108             address_ = address;
109             return;
110         }
111     } else {
112         struct in6_addr ipv6;
113         if (inet_pton(AF_INET6, address.c_str(), &ipv6) > 0) {
114             address_ = address;
115             return;
116         }
117     }
118 
119     struct addrinfo hints;
120     sa_family_t saFamily = GetSaFamily();
121     if (memset_s(&hints, sizeof hints, 0, sizeof hints) != EOK) {
122         NETSTACK_LOGE("memory operation fail");
123     }
124     hints.ai_family = saFamily;
125     char ipStr[INET6_ADDRSTRLEN];
126     struct addrinfo *res = nullptr;
127     int status = getaddrinfo(address.c_str(), nullptr, &hints, &res);
128     if (status != 0 || res == nullptr) {
129         NETSTACK_LOGE("getaddrinfo status is %{public}d, error is %{public}s", status, gai_strerror(status));
130         return;
131     }
132 
133     void *addr = nullptr;
134     if (res->ai_family == AF_INET) {
135         auto *ipv4 = reinterpret_cast<struct sockaddr_in *>(res->ai_addr);
136         addr = &(ipv4->sin_addr);
137     } else {
138         struct sockaddr_in6 *ipv6 = reinterpret_cast<struct sockaddr_in6 *>(res->ai_addr);
139         addr = &(ipv6->sin6_addr);
140     }
141     inet_ntop(res->ai_family, addr, ipStr, sizeof ipStr);
142     address_ = ipStr;
143     freeaddrinfo(res);
144 }
145 
SetAddress(const std::string & address,bool resolveDns)146 void NetAddress::SetAddress(const std::string &address, bool resolveDns)
147 {
148     if (!resolveDns && family_ == Family::DOMAIN_NAME) {
149         address_ = address;
150     } else {
151         SetAddress(address);
152     }
153 }
154 
SetFamilyByJsValue(uint32_t family)155 void NetAddress::SetFamilyByJsValue(uint32_t family)
156 {
157     if (static_cast<Family>(family) == Family::IPv4) {
158         family_ = Family::IPv4;
159     } else if (static_cast<Family>(family) == Family::IPv6) {
160         family_ = Family::IPv6;
161     } else if (static_cast<Family>(family) == Family::DOMAIN_NAME) {
162         family_ = Family::DOMAIN_NAME;
163     } else {
164         // do nothing
165     }
166 }
167 
SetFamilyBySaFamily(sa_family_t family)168 void NetAddress::SetFamilyBySaFamily(sa_family_t family)
169 {
170     if (family == AF_INET6) {
171         family_ = Family::IPv6;
172     }
173 }
174 
SetPort(uint16_t port)175 void NetAddress::SetPort(uint16_t port)
176 {
177     port_ = port;
178 }
179 
GetAddress() const180 const std::string &NetAddress::GetAddress() const
181 {
182     return address_;
183 }
184 
GetSaFamily() const185 sa_family_t NetAddress::GetSaFamily() const
186 {
187     if (family_ == Family::IPv6) {
188         return AF_INET6;
189     }
190     return AF_INET;
191 }
192 
GetJsValueFamily() const193 uint32_t NetAddress::GetJsValueFamily() const
194 {
195     return static_cast<uint32_t>(family_);
196 }
197 
GetPort() const198 uint16_t NetAddress::GetPort() const
199 {
200     return port_;
201 }
202 
GetFamily() const203 NetAddress::Family NetAddress::GetFamily() const
204 {
205     return family_;
206 }
207 
operator =(const NetAddress & other)208 NetAddress &NetAddress::operator=(const NetAddress &other)
209 {
210     address_ = other.GetAddress();
211     family_ = other.GetFamily();
212     port_ = other.GetPort();
213     return *this;
214 }
215 } // namespace OHOS::NetStack::Socket
216