• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = CheckDataToUint(value);
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 = CheckDataLegal(tmpAddress);
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     if (prefixLength < MIN_PREFIX_LEN || prefixLength > MAX_IPV6_PREFIX_LEN) {
152         return "";
153     }
154     // 初始化 16 字节的 IPv6 掩码(全 0)
155     uint8_t mask[16];
156     memset_s(mask, sizeof(mask), 0, sizeof(mask));
157 
158     // 逐字节设置掩码
159     uint8_t bytesLen = 8;
160     uint8_t ipv6Bytes = 16;
161     for (unsigned int i = 0; i < ipv6Bytes; i++) {
162         if (prefixLength >= bytesLen) {
163             mask[i] = 0xFF;  // 当前字节全 1
164             prefixLength -= bytesLen;
165         } else if (prefixLength > 0) {
166             mask[i] = 0xFF << (bytesLen - prefixLength);  // 部分 1
167             prefixLength = 0;
168         }
169         // 剩余字节保持 0
170     }
171 
172     // 转换为 IPv6 字符串格式(压缩形式,如 "ffff::")
173     char buffer[INET6_ADDRSTRLEN];
174     inet_ntop(AF_INET6, mask, buffer, INET6_ADDRSTRLEN);
175     return std::string(buffer);
176 }
177 
GetMaskLength(std::string mask)178 int IpTools::GetMaskLength(std::string mask)
179 {
180     int netMask = 0;
181     const unsigned int constMask = 0x80000000;
182     unsigned int maskTmp = ntohl(static_cast<int>(inet_addr(mask.c_str())));
183     while (maskTmp & constMask) {
184         netMask++;
185         maskTmp = (maskTmp << 1);
186     }
187 
188     return netMask;
189 }
190 
191 /**
192     * @Description : Obtains the length based on the subnet mask.
193     *
194     * @param mask - The mask.[in]
195     * @return int
196 */
GetIPV6MaskLength(std::string ip)197 int IpTools::GetIPV6MaskLength(std::string ip)
198 {
199     constexpr int32_t LENGTH_8 = 8;
200     constexpr int32_t LENGTH_7 = 7;
201     constexpr int32_t LENGTH_6 = 6;
202     constexpr int32_t LENGTH_5 = 5;
203     constexpr int32_t LENGTH_4 = 4;
204     constexpr int32_t LENGTH_3 = 3;
205     constexpr int32_t LENGTH_2 = 2;
206     constexpr int32_t LENGTH_1 = 1;
207     if (ip.empty()) {
208         return 0;
209     }
210     in6_addr addr{};
211     inet_pton(AF_INET6, ip.c_str(), &addr);
212     int32_t prefixLen = 0;
213     for (int32_t i = 0; i < BITS_16; ++i) {
214         if (addr.s6_addr[i] == 0xFF) {
215             prefixLen += LENGTH_8;
216         } else if (addr.s6_addr[i] == 0xFE) {
217             prefixLen += LENGTH_7;
218             break;
219         } else if (addr.s6_addr[i] == 0xFC) {
220             prefixLen += LENGTH_6;
221             break;
222         } else if (addr.s6_addr[i] == 0xF8) {
223             prefixLen += LENGTH_5;
224             break;
225         } else if (addr.s6_addr[i] == 0xF0) {
226             prefixLen += LENGTH_4;
227             break;
228         } else if (addr.s6_addr[i] == 0xE0) {
229             prefixLen += LENGTH_3;
230             break;
231         } else if (addr.s6_addr[i] == 0xC0) {
232             prefixLen += LENGTH_2;
233             break;
234         } else if (addr.s6_addr[i] == 0x80) {
235             prefixLen += LENGTH_1;
236             break;
237         } else {
238             break;
239         }
240     }
241     return prefixLen;
242 }
243 
GetExclusionObjectList(const std::string & exclusionObjectList,std::vector<std::string> & exclusionList)244 void IpTools::GetExclusionObjectList(const std::string &exclusionObjectList, std::vector<std::string> &exclusionList)
245 {
246     std::string tmpExclusionList = exclusionObjectList;
247     std::vector<std::string> list;
248     int listNum = count(tmpExclusionList.begin(), tmpExclusionList.end(), ',');
249     int i = 0;
250     for (i = 0; i < listNum; ++i) {
251         std::string::size_type npos = tmpExclusionList.find(",");
252         if (npos == std::string::npos) {
253             break;
254         }
255 
256         std::string exclusionOne = tmpExclusionList.substr(0, npos);
257         /* Do you need to check whether the format of this website is correct? */
258         list.push_back(exclusionOne);
259         tmpExclusionList = tmpExclusionList.substr(npos + 1);
260     }
261     if (i != listNum) {
262         return;
263     }
264     list.push_back(tmpExclusionList);
265     exclusionList.assign(list.begin(), list.end());
266     return;
267 }
268 
ConvertIpv6AddressToCompleted(const std::string & address)269 std::string IpTools::ConvertIpv6AddressToCompleted(const std::string &address)
270 {
271     size_t dblColonPos = address.find("::");
272     bool hasDblColon = (dblColonPos != std::string::npos);
273     std::vector<std::string> parts;
274     std::string firstPart = address.substr(0, dblColonPos);
275     std::string secondPart = hasDblColon ? address.substr(dblColonPos + 2) : "";
276 
277     std::istringstream firstStream(firstPart);
278     std::string segment;
279     while (getline(firstStream, segment, ':')) {
280         parts.push_back(segment);
281     }
282 
283     std::istringstream secondStream(secondPart);
284     std::vector<std::string> secondParts;
285     while (getline(secondStream, segment, ':')) {
286         secondParts.push_back(segment);
287     }
288 
289     size_t totalParts = 8;
290     size_t existingParts = parts.size() + secondParts.size();
291     size_t zeroPartsToInsert = totalParts - existingParts;
292     int8_t bitNum = 4;
293     parts.insert(parts.end(), zeroPartsToInsert, "0");
294     parts.insert(parts.end(), secondParts.begin(), secondParts.end());
295     std::ostringstream stream;
296     for (size_t i = 0; i < parts.size(); i++) {
297         if (i != 0) {
298             stream << ":";
299         }
300         std::string seg = parts[i];
301         if (seg.empty()) {
302             seg = "0";
303         }
304         unsigned int num = std::stoul(seg, nullptr, 16);
305         stream << std::setw(bitNum) << std::setfill('0') << std::hex << num;
306     }
307     return stream.str();
308 }
309 }  // namespace Wifi
310 }  // namespace OHOS