1 /*
2 * Copyright (C) 2021 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 "ip_tools.h"
17
18 namespace OHOS {
19 namespace Wifi {
ConvertIpv4Address(unsigned int addressIpv4)20 std::string IpTools::ConvertIpv4Address(unsigned int addressIpv4)
21 {
22 std::string address;
23 if (addressIpv4 == 0) {
24 return address;
25 }
26
27 std::ostringstream stream;
28 stream<<((addressIpv4>>BITS_24) & 0xFF)<<"."<<((addressIpv4>>BITS_16) & 0xFF)<<"."
29 <<((addressIpv4>>BITS_8) & 0xFF)<<"."<<(addressIpv4 & 0xFF);
30 address = stream.str();
31
32 return address;
33 }
34
ConvertIpv4Address(const std::string & address)35 unsigned int IpTools::ConvertIpv4Address(const std::string &address)
36 {
37 std::string tmpAddress = address;
38 unsigned int addrInt = 0;
39 unsigned int i = 0;
40 for (i = 0; i < IPV4_DOT_NUM; i++) {
41 std::string::size_type npos = tmpAddress.find(".");
42 if (npos == std::string::npos) {
43 break;
44 }
45 std::string value = tmpAddress.substr(0, npos);
46 unsigned int tmp = std::atoi(value.c_str());
47 if ((tmp < MIN_BYTE) || (tmp > MAX_BYTE)) {
48 break;
49 }
50 addrInt += tmp << ((IPV4_DOT_NUM - i) * BIT_NUM_BYTE);
51 tmpAddress = tmpAddress.substr(npos + 1);
52 }
53
54 if (i != IPV4_DOT_NUM) {
55 return 0;
56 }
57 int tmp = std::atoi(tmpAddress.c_str());
58 if ((tmp < MIN_BYTE) || (tmp > MAX_BYTE)) {
59 return 0;
60 }
61 addrInt += tmp;
62
63 return addrInt;
64 }
65
ConvertIpv6Address(const std::vector<unsigned char> & addressIpv6)66 std::string IpTools::ConvertIpv6Address(const std::vector<unsigned char> &addressIpv6)
67 {
68 std::string address;
69 if (addressIpv6.size() != IPV6_BYTE_NUM) {
70 return address;
71 }
72
73 std::ostringstream stream;
74 stream << std::hex << std::setw(POS_2) << std::setfill('0') << static_cast<int>(addressIpv6[0]);
75 stream << std::hex << std::setw(POS_2) << std::setfill('0') << static_cast<int>(addressIpv6[1]);
76 for (int i = POS_2; i < IPV6_BYTE_NUM; i += POS_2) {
77 stream << ":";
78 stream << std::hex << std::setw(POS_2) << std::setfill('0') << static_cast<int>(addressIpv6[i]);
79 stream << std::hex << std::setw(POS_2) << std::setfill('0') << static_cast<int>(addressIpv6[i + 1]);
80 }
81 address = stream.str();
82
83 return address;
84 }
85
ConvertIpv6Address(const std::string & address,std::vector<unsigned char> & addressIpv6)86 void IpTools::ConvertIpv6Address(const std::string &address, std::vector<unsigned char> &addressIpv6)
87 {
88 std::string tmpAddress = address;
89 addressIpv6.clear();
90 std::vector<unsigned char> ipv6;
91 int i = 0;
92 for (i = 0; i < IPV6_COLON_NUM; i++) {
93 std::string::size_type npos = tmpAddress.find(":");
94 if (npos == std::string::npos) {
95 break;
96 }
97
98 std::string value = tmpAddress.substr(0, npos);
99 if (value.size() != IPV6_DIGIT_NUM_PER_SEG) {
100 break;
101 }
102 ipv6.push_back(std::stoi(value.substr(POS_0, HEX_BYTE_DIGIT_NUM), nullptr, HEX_FORM));
103 ipv6.push_back(std::stoi(value.substr(POS_2, HEX_BYTE_DIGIT_NUM), nullptr, HEX_FORM));
104 tmpAddress = tmpAddress.substr(npos + 1);
105 }
106
107 if (i != IPV6_COLON_NUM) {
108 return;
109 }
110 if (tmpAddress.size() != IPV6_DIGIT_NUM_PER_SEG) {
111 return;
112 }
113 ipv6.push_back(std::stoi(tmpAddress.substr(POS_0, HEX_BYTE_DIGIT_NUM), nullptr, HEX_FORM));
114 ipv6.push_back(std::stoi(tmpAddress.substr(POS_2, HEX_BYTE_DIGIT_NUM), nullptr, HEX_FORM));
115
116 addressIpv6.assign(ipv6.begin(), ipv6.end());
117 return;
118 }
119
ConvertIpv4Mask(int prefixLength)120 std::string IpTools::ConvertIpv4Mask(int prefixLength)
121 {
122 std::string netMask;
123 if (prefixLength <= MIN_PREFIX_LEN || prefixLength > MAX_PREFIX_LEN) {
124 const int defaultPrefix = 24;
125 prefixLength = defaultPrefix;
126 }
127
128 int mask[IPV4_BYTE_NUM] = {0, 0, 0, 0};
129 int quot = prefixLength / BIT_NUM_PER_BYTE;
130 unsigned int remain = prefixLength % BIT_NUM_PER_BYTE;
131 for (int i = 0; i < quot; i++) {
132 mask[i] = MAX_IPV4_MASK_BYTE;
133 }
134 if (quot < IPV4_BYTE_NUM) {
135 mask[quot] = (MAX_BYTE + 1) - (1 << (BIT_NUM_PER_BYTE - remain));
136 }
137 std::ostringstream stream;
138 stream << mask[POS_0] << "." << mask[POS_1] << "." << mask[POS_2] << "." << mask[POS_3];
139 netMask = stream.str();
140
141 return netMask;
142 }
143
ConvertIpv6Mask(int prefixLength)144 std::string IpTools::ConvertIpv6Mask(int prefixLength)
145 {
146 std::string netMask;
147 if (prefixLength < MIN_PREFIX_LEN || prefixLength > MAX_IPV6_PREFIX_LEN) {
148 return netMask;
149 }
150
151 std::ostringstream stream;
152 stream << prefixLength;
153 netMask = stream.str();
154
155 return netMask;
156 }
157
GetMaskLength(std::string mask)158 int IpTools::GetMaskLength(std::string mask)
159 {
160 int netMask = 0;
161 const int constMask = 0x80000000;
162 unsigned int maskTmp = ntohl(static_cast<int>(inet_addr(mask.c_str())));
163 while (maskTmp & constMask) {
164 netMask++;
165 maskTmp = (maskTmp << 1);
166 }
167
168 return netMask;
169 }
170
171 /**
172 * @Description : Obtains the length based on the subnet mask.
173 *
174 * @param mask - The mask.[in]
175 * @return int
176 */
GetIPV6MaskLength(std::string ip)177 int IpTools::GetIPV6MaskLength(std::string ip)
178 {
179 constexpr int32_t LENGTH_8 = 8;
180 constexpr int32_t LENGTH_7 = 7;
181 constexpr int32_t LENGTH_6 = 6;
182 constexpr int32_t LENGTH_5 = 5;
183 constexpr int32_t LENGTH_4 = 4;
184 constexpr int32_t LENGTH_3 = 3;
185 constexpr int32_t LENGTH_2 = 2;
186 constexpr int32_t LENGTH_1 = 1;
187 if (ip.empty()) {
188 return 0;
189 }
190 in6_addr addr{};
191 inet_pton(AF_INET6, ip.c_str(), &addr);
192 int32_t prefixLen = 0;
193 for (int32_t i = 0; i < BITS_16; ++i) {
194 if (addr.s6_addr[i] == 0xFF) {
195 prefixLen += LENGTH_8;
196 } else if (addr.s6_addr[i] == 0xFE) {
197 prefixLen += LENGTH_7;
198 break;
199 } else if (addr.s6_addr[i] == 0xFC) {
200 prefixLen += LENGTH_6;
201 break;
202 } else if (addr.s6_addr[i] == 0xF8) {
203 prefixLen += LENGTH_5;
204 break;
205 } else if (addr.s6_addr[i] == 0xF0) {
206 prefixLen += LENGTH_4;
207 break;
208 } else if (addr.s6_addr[i] == 0xE0) {
209 prefixLen += LENGTH_3;
210 break;
211 } else if (addr.s6_addr[i] == 0xC0) {
212 prefixLen += LENGTH_2;
213 break;
214 } else if (addr.s6_addr[i] == 0x80) {
215 prefixLen += LENGTH_1;
216 break;
217 } else {
218 break;
219 }
220 }
221 return prefixLen;
222 }
223
GetExclusionObjectList(const std::string & exclusionObjectList,std::vector<std::string> & exclusionList)224 void IpTools::GetExclusionObjectList(const std::string &exclusionObjectList, std::vector<std::string> &exclusionList)
225 {
226 std::string tmpExclusionList = exclusionObjectList;
227 std::vector<std::string> list;
228 int listNum = count(tmpExclusionList.begin(), tmpExclusionList.end(), ',');
229 int i = 0;
230 for (i = 0; i < listNum; ++i) {
231 std::string::size_type npos = tmpExclusionList.find(",");
232 if (npos == std::string::npos) {
233 break;
234 }
235
236 std::string exclusionOne = tmpExclusionList.substr(0, npos);
237 /* Do you need to check whether the format of this website is correct? */
238 list.push_back(exclusionOne);
239 tmpExclusionList = tmpExclusionList.substr(npos + 1);
240 }
241 if (i != listNum) {
242 return;
243 }
244 list.push_back(tmpExclusionList);
245 exclusionList.assign(list.begin(), list.end());
246 return;
247 }
248 } // namespace Wifi
249 } // namespace OHOS