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