1 /*
2 * Copyright (c) 2024 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 <arpa/inet.h>
17 #include <cerrno>
18 #include <climits>
19 #include <cstdlib>
20 #include <cstring>
21 #include <fcntl.h>
22 #include <linux/filter.h>
23 #include <linux/if_packet.h>
24 #include <linux/if_tun.h>
25 #include <linux/ipv6.h>
26 #include <list>
27 #include <mutex>
28 #include <net/if.h>
29 #include <netinet/in.h>
30 #include <sys/ioctl.h>
31 #include <sys/socket.h>
32 #include <unistd.h>
33
34 #include "clat_utils.h"
35 #include "ffrt.h"
36 #include "net_manager_constants.h"
37 #include "netnative_log_wrapper.h"
38 #include "securec.h"
39
40 namespace OHOS {
41 namespace nmd {
42 using namespace OHOS::NetManagerStandard;
43 ffrt::mutex g_tunV4AddrMutex;
44 std::list<in_addr_t> g_tunV4AddrInUse;
45
IsIpv4AddressFree(const in_addr_t v4Addr)46 bool IsIpv4AddressFree(const in_addr_t v4Addr)
47 {
48 std::lock_guard<ffrt::mutex> lock(g_tunV4AddrMutex);
49 if (std::find(g_tunV4AddrInUse.begin(), g_tunV4AddrInUse.end(), v4Addr) != g_tunV4AddrInUse.end()) {
50 return false;
51 }
52 int s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
53 if (s == -1) {
54 return false;
55 }
56
57 // check if the address is available by trying to connect to it
58 sockaddr_in sin = {
59 .sin_family = AF_INET,
60 .sin_port = htons(WKN_DNS_PORT),
61 .sin_addr = {v4Addr},
62 };
63 socklen_t len = sizeof(sin);
64 const bool inuse = !connect(s, reinterpret_cast<sockaddr *>(&sin), sizeof(sin)) &&
65 !getsockname(s, reinterpret_cast<sockaddr *>(&sin), &len) &&
66 len == static_cast<socklen_t>(sizeof(sin)) && sin.sin_addr.s_addr == v4Addr;
67
68 close(s);
69 g_tunV4AddrInUse.emplace_back(v4Addr);
70 return !inuse;
71 }
72
FreeTunV4Addr(const std::string & v4AddrStr)73 void FreeTunV4Addr(const std::string &v4AddrStr)
74 {
75 std::lock_guard<ffrt::mutex> lock(g_tunV4AddrMutex);
76 in_addr v4Addr;
77 if (inet_pton(AF_INET, v4AddrStr.c_str(), &v4Addr) != 1) {
78 NETNATIVE_LOGW("fail to free tun v4 address, tun address invalid");
79 return;
80 }
81 g_tunV4AddrInUse.remove(v4Addr.s_addr);
82 }
83
GetAvailableIpv4Address(const in_addr initV4Addr,const int16_t prefixLen)84 in_addr_t GetAvailableIpv4Address(const in_addr initV4Addr, const int16_t prefixLen)
85 {
86 if (prefixLen < 0 || prefixLen > V4ADDR_BIT_LEN) {
87 return INADDR_NONE;
88 }
89 const uint32_t mask = 0xffffffff >> (V4ADDR_BIT_LEN - prefixLen) << (V4ADDR_BIT_LEN - prefixLen);
90 uint32_t v4Num = ntohl(initV4Addr.s_addr);
91 const uint32_t initV4Num = v4Num;
92 const uint32_t prefix = v4Num & mask;
93
94 do {
95 if (IsIpv4AddressFree(htonl(v4Num))) {
96 return htonl(v4Num);
97 }
98 v4Num = prefix | ((v4Num + 1) & ~mask);
99 } while (v4Num != initV4Num);
100
101 return INADDR_NONE;
102 }
103
SelectIpv4Address(const std::string & initV4AddrStr,int prefixLen,std::string & v4AddrStr)104 int32_t SelectIpv4Address(const std::string &initV4AddrStr, int prefixLen, std::string &v4AddrStr)
105 {
106 in_addr initV4Addr;
107 if (inet_pton(AF_INET, initV4AddrStr.c_str(), &initV4Addr) != 1) {
108 NETNATIVE_LOGW("fail to select ipv4 address for tun, init address invalid");
109 return NETMANAGER_ERR_INVALID_PARAMETER;
110 }
111
112 in_addr v4Addr = {GetAvailableIpv4Address(initV4Addr, prefixLen)};
113 if (v4Addr.s_addr == INADDR_NONE) {
114 NETNATIVE_LOGW("No free IPv4 address in %{public}d", prefixLen);
115 return NETMANAGER_ERR_OPERATION_FAILED;
116 }
117
118 char addrstr[INET_ADDRSTRLEN];
119 inet_ntop(AF_INET, reinterpret_cast<void *>(&v4Addr), addrstr, sizeof(addrstr));
120 v4AddrStr = addrstr;
121 return NETMANAGER_SUCCESS;
122 }
123
Checksum32To16(uint32_t sum32)124 uint16_t Checksum32To16(uint32_t sum32)
125 {
126 while (sum32 >> (sizeof(uint16_t) * CHAR_BIT)) {
127 sum32 = (sum32 & 0xffff) + (sum32 >> (sizeof(uint16_t) * CHAR_BIT));
128 }
129 return sum32;
130 }
131
AdjustChecksum(uint16_t oldSum16,uint32_t oldSumHdr,uint32_t newSumHdr)132 uint16_t AdjustChecksum(uint16_t oldSum16, uint32_t oldSumHdr, uint32_t newSumHdr)
133 {
134 // More details in RFC 1624.
135 oldSum16 = ~oldSum16;
136 uint16_t sumFolded = Checksum32To16(newSumHdr + oldSum16);
137 uint16_t oldFolded = Checksum32To16(oldSumHdr);
138 if (sumFolded > oldFolded) {
139 return ~(sumFolded - oldFolded);
140 }
141 return ~(sumFolded - oldFolded - 1);
142 }
143
AddChecksum(uint32_t sum,const void * data,int len)144 uint32_t AddChecksum(uint32_t sum, const void *data, int len)
145 {
146 const uint16_t *single16 = reinterpret_cast<const uint16_t *>(data);
147 int multiplier = sizeof(uint32_t) / sizeof(uint16_t);
148 while (len >= multiplier) {
149 sum += *single16;
150 single16++;
151 len -= multiplier;
152 }
153 if (len) {
154 sum += *reinterpret_cast<const uint8_t *>(single16);
155 }
156
157 return sum;
158 }
159
MakeChecksumNeutral(in6_addr & v6Addr,const in_addr & v4Addr,const in6_addr & nat64Prefix)160 void MakeChecksumNeutral(in6_addr &v6Addr, const in_addr &v4Addr, const in6_addr &nat64Prefix)
161 {
162 arc4random_buf(&v6Addr.s6_addr[CLAT_V6ADDR_RANDOMIZE_OFFSET], CLAT_V6ADDR_RANDOMIZE_BIT_LENGTH);
163
164 size_t adjustOffset = CLAT_V6ADDR_RANDOMIZE_OFFSET + CLAT_V6ADDR_NEUTRALIZE_OFFSET;
165 uint16_t middleBytes = (v6Addr.s6_addr[adjustOffset] << CHAR_BIT) + v6Addr.s6_addr[adjustOffset + 1];
166
167 uint32_t v4Checksum = AddChecksum(0, &v4Addr, sizeof(v4Addr));
168 uint32_t v6Checksum = AddChecksum(0, &nat64Prefix, sizeof(nat64Prefix)) + AddChecksum(0, &v6Addr, sizeof(v6Addr));
169
170 uint16_t delta = AdjustChecksum(middleBytes, v4Checksum, v6Checksum);
171 v6Addr.s6_addr[adjustOffset] = delta >> CHAR_BIT;
172 v6Addr.s6_addr[adjustOffset + 1] = delta & 0xff;
173 }
174
GetSuitableIpv6Address(const std::string & v6IfaceStr,const in_addr v4Addr,const in6_addr & nat64Prefix,in6_addr & v6Addr,const uint32_t mark)175 int32_t GetSuitableIpv6Address(const std::string &v6IfaceStr, const in_addr v4Addr, const in6_addr &nat64Prefix,
176 in6_addr &v6Addr, const uint32_t mark)
177 {
178 int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
179 if (s == -1)
180 return NETMANAGER_ERR_OPERATION_FAILED;
181
182 if (setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark))) {
183 auto err = errno;
184 NETNATIVE_LOGW("setsockopt(SOL_SOCKET, SO_MARK) failed: %{public}s", strerror(err));
185 close(s);
186 return NETMANAGER_ERR_OPERATION_FAILED;
187 }
188
189 if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, v6IfaceStr.c_str(), v6IfaceStr.length())) {
190 auto err = errno;
191 NETNATIVE_LOGW("setsockopt(SOL_SOCKET, SO_BINDTODEVICE, '%{public}s') failed: %{public}s", v6IfaceStr.c_str(),
192 strerror(err));
193 close(s);
194 return NETMANAGER_ERR_OPERATION_FAILED;
195 }
196
197 sockaddr_in6 sin6;
198 sin6.sin6_family = AF_INET6;
199 sin6.sin6_addr = nat64Prefix;
200 if (connect(s, reinterpret_cast<sockaddr *>(&sin6), sizeof(sin6))) {
201 close(s);
202 return NETMANAGER_ERR_OPERATION_FAILED;
203 }
204
205 socklen_t len = sizeof(sin6);
206 if (getsockname(s, reinterpret_cast<sockaddr *>(&sin6), &len)) {
207 close(s);
208 return NETMANAGER_ERR_OPERATION_FAILED;
209 }
210
211 v6Addr = sin6.sin6_addr;
212
213 MakeChecksumNeutral(v6Addr, v4Addr, nat64Prefix);
214 close(s);
215
216 return 0;
217 }
218
GenerateIpv6Address(const std::string & v6IfaceStr,const std::string & v4AddrStr,const std::string & prefix64Str,uint32_t mark,std::string & v6AddrStr)219 int32_t GenerateIpv6Address(const std::string &v6IfaceStr, const std::string &v4AddrStr, const std::string &prefix64Str,
220 uint32_t mark, std::string &v6AddrStr)
221 {
222 if (v6IfaceStr.empty()) {
223 NETNATIVE_LOGW("fail to generate ipv6 address, ipv6 interface name null");
224 return NETMANAGER_ERR_INVALID_PARAMETER;
225 }
226
227 in_addr v4Addr;
228 if (inet_pton(AF_INET, v4AddrStr.c_str(), &v4Addr) != 1) {
229 NETNATIVE_LOGW("fail to generate ipv6 address, ipv4 address invalid");
230 return NETMANAGER_ERR_INVALID_PARAMETER;
231 }
232
233 in6_addr prefix64;
234 if (inet_pton(AF_INET6, prefix64Str.c_str(), &prefix64) != 1) {
235 NETNATIVE_LOGW("fail to generate ipv6 address, prefix invalid");
236 return NETMANAGER_ERR_INVALID_PARAMETER;
237 }
238
239 in6_addr v6Addr;
240 int32_t ret = GetSuitableIpv6Address(v6IfaceStr, v4Addr, prefix64, v6Addr, mark);
241 if (ret != NETMANAGER_SUCCESS) {
242 NETNATIVE_LOGW("Unable to find global source address on %{public}s for %{public}s", v6IfaceStr.c_str(),
243 prefix64Str.c_str());
244 return ret;
245 }
246
247 char addrstr[INET6_ADDRSTRLEN];
248 if (!inet_ntop(AF_INET6, reinterpret_cast<void *>(&v6Addr), addrstr, sizeof(addrstr))) {
249 NETNATIVE_LOGW("fail to generate ipv6 address, ipv6 address invalid");
250 return NETMANAGER_ERR_OPERATION_FAILED;
251 }
252 v6AddrStr = addrstr;
253 return NETMANAGER_SUCCESS;
254 }
255
CalChecksum(const void * data,int len)256 uint16_t CalChecksum(const void *data, int len)
257 {
258 uint32_t tempSum = AddChecksum(0xffff, data, len);
259 return ~Checksum32To16(tempSum);
260 }
261
CreateTunInterface(const std::string & tunIface,int & fd)262 int32_t CreateTunInterface(const std::string &tunIface, int &fd)
263 {
264 fd = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
265 if (fd == -1) {
266 NETNATIVE_LOGW("open tun device failed, errno: %{public}d", errno);
267 return NETMANAGER_ERR_OPERATION_FAILED;
268 }
269
270 struct ifreq ifr = {};
271 ifr.ifr_flags = static_cast<short>(IFF_TUN | IFF_TUN_EXCL);
272
273 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, tunIface.c_str(), tunIface.length()) != EOK) {
274 close(fd);
275 return NETMANAGER_ERR_OPERATION_FAILED;
276 }
277 if (ioctl(fd, TUNSETIFF, &ifr, sizeof(ifr))) {
278 close(fd);
279 NETNATIVE_LOGW("ioctl(TUNSETIFF) failed");
280 return NETMANAGER_ERR_OPERATION_FAILED;
281 }
282
283 return NETMANAGER_SUCCESS;
284 }
285
OpenPacketSocket(int & readSock6)286 int32_t OpenPacketSocket(int &readSock6)
287 {
288 readSock6 = socket(AF_PACKET, SOCK_RAW | SOCK_CLOEXEC, 0);
289 if (readSock6 < 0) {
290 NETNATIVE_LOGW("packet socket failed");
291 return NETMANAGER_ERR_OPERATION_FAILED;
292 }
293 const int on = 1;
294
295 if (setsockopt(readSock6, SOL_PACKET, PACKET_AUXDATA, &on, sizeof(on))) {
296 NETNATIVE_LOGW("packet socket auxdata enablement failed");
297 close(readSock6);
298 return NETMANAGER_ERR_OPERATION_FAILED;
299 }
300
301 if (setsockopt(readSock6, SOL_PACKET, PACKET_VNET_HDR, &on, sizeof(on))) {
302 NETNATIVE_LOGW("packet socket vnet_hdr enablement failed");
303 close(readSock6);
304 return NETMANAGER_ERR_OPERATION_FAILED;
305 }
306 return NETMANAGER_SUCCESS;
307 }
308
OpenRawSocket6(const uint32_t mark,int & writeSock6)309 int32_t OpenRawSocket6(const uint32_t mark, int &writeSock6)
310 {
311 writeSock6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_RAW);
312 if (writeSock6 < 0) {
313 NETNATIVE_LOGW("raw socket failed");
314 return NETMANAGER_ERR_OPERATION_FAILED;
315 }
316
317 if (setsockopt(writeSock6, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
318 NETNATIVE_LOGW("could not set mark on raw socket");
319 close(writeSock6);
320 return NETMANAGER_ERR_OPERATION_FAILED;
321 }
322
323 return NETMANAGER_SUCCESS;
324 }
325
ConfigureWriteSocket(int sockFd,const std::string & v6Iface)326 int32_t ConfigureWriteSocket(int sockFd, const std::string &v6Iface)
327 {
328 if (sockFd < 0) {
329 NETNATIVE_LOGW("Invalid file descriptor");
330 return NETMANAGER_ERR_INVALID_PARAMETER;
331 }
332
333 int ret = setsockopt(sockFd, SOL_SOCKET, SO_BINDTODEVICE, v6Iface.c_str(),
334 static_cast<socklen_t>(strlen(v6Iface.c_str())));
335 if (ret) {
336 NETNATIVE_LOGW("setsockopt SO_BINDTODEVICE failed: %{public}s", strerror(errno));
337 return NETMANAGER_ERR_OPERATION_FAILED;
338 }
339 return NETMANAGER_SUCCESS;
340 }
341
AddFilterAndBindPacketSocket(const int sock,const in6_addr * const addr,const int ifIndex)342 int AddFilterAndBindPacketSocket(const int sock, const in6_addr *const addr, const int ifIndex)
343 {
344 sock_filter filter[] = {
345 BPF_STMT(BPF_LD | BPF_W | BPF_ABS, static_cast<__u32>(SKF_NET_OFF) + offsetof(ipv6hdr, daddr.s6_addr32[0])),
346 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ntohl(addr->s6_addr32[0]), 1, 0),
347 BPF_STMT(BPF_RET | BPF_K, 0),
348 BPF_STMT(BPF_LD | BPF_W | BPF_ABS, static_cast<__u32>(SKF_NET_OFF) + offsetof(ipv6hdr, daddr.s6_addr32[1])),
349 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ntohl(addr->s6_addr32[1]), 1, 0),
350 BPF_STMT(BPF_RET | BPF_K, 0),
351 BPF_STMT(BPF_LD | BPF_W | BPF_ABS, static_cast<__u32>(SKF_NET_OFF) + offsetof(ipv6hdr, daddr.s6_addr32[2])),
352 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ntohl(addr->s6_addr32[2]), 1, 0),
353 BPF_STMT(BPF_RET | BPF_K, 0),
354 BPF_STMT(BPF_LD | BPF_W | BPF_ABS, static_cast<__u32>(SKF_NET_OFF) + offsetof(ipv6hdr, daddr.s6_addr32[3])),
355 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ntohl(addr->s6_addr32[3]), 1, 0),
356 BPF_STMT(BPF_RET | BPF_K, 0),
357 BPF_STMT(BPF_RET | BPF_K, 0xFFFFFFFF),
358 };
359 sock_fprog filterProg = {sizeof(filter) / sizeof(filter[0]), filter};
360
361 if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filterProg, sizeof(filterProg))) {
362 auto err = errno;
363 NETNATIVE_LOGW("attach packet filter failed: %{public}s", strerror(err));
364 return -err;
365 }
366
367 sockaddr_ll sll = {
368 .sll_family = AF_PACKET,
369 .sll_protocol = htons(ETH_P_IPV6),
370 .sll_ifindex = ifIndex,
371 .sll_pkttype = PACKET_OTHERHOST,
372 };
373 if (bind(sock, reinterpret_cast<sockaddr *>(&sll), sizeof(sll))) {
374 auto err = errno;
375 NETNATIVE_LOGW("binding packet socket failed: %{public}s", strerror(err));
376 return -err;
377 }
378 return 0;
379 }
380
ConfigureReadSocket(int sockFd,const std::string & addrStr,int ifIndex)381 int32_t ConfigureReadSocket(int sockFd, const std::string &addrStr, int ifIndex)
382 {
383 if (sockFd < 0) {
384 NETNATIVE_LOGW("Invalid file descriptor");
385 return NETMANAGER_ERR_INVALID_PARAMETER;
386 }
387
388 in6_addr addr;
389 if (inet_pton(AF_INET6, addrStr.c_str(), &addr) != 1) {
390 NETNATIVE_LOGW("Invalid IPv6 address");
391 return NETMANAGER_ERR_INVALID_PARAMETER;
392 }
393
394 int ret = AddFilterAndBindPacketSocket(sockFd, &addr, ifIndex);
395 if (ret < 0) {
396 NETNATIVE_LOGW("configure packet socket failed");
397 return NETMANAGER_ERR_OPERATION_FAILED;
398 }
399 return NETMANAGER_SUCCESS;
400 }
401
SetTunInterfaceAddress(const std::string & ifName,const std::string & tunAddr,int32_t prefix)402 int32_t SetTunInterfaceAddress(const std::string &ifName, const std::string &tunAddr, int32_t prefix)
403 {
404 ifreq ifr = {};
405 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
406 NETNATIVE_LOGE("memset_s ifr failed!");
407 return NETMANAGER_ERROR;
408 }
409 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ifName.c_str(), strlen(ifName.c_str())) != EOK) {
410 NETNATIVE_LOGE("strcpy_s ifr name fail");
411 return NETMANAGER_ERROR;
412 }
413
414 in_addr ipv4Addr = {};
415 if (inet_aton(tunAddr.c_str(), &ipv4Addr) == 0) {
416 NETNATIVE_LOGE("addr inet_aton error");
417 return NETMANAGER_ERROR;
418 }
419
420 int socketfd = socket(AF_INET, SOCK_DGRAM, 0);
421 auto sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_addr);
422 sin->sin_family = AF_INET;
423 sin->sin_addr = ipv4Addr;
424 if (ioctl(socketfd, SIOCSIFADDR, &ifr) < 0) {
425 NETNATIVE_LOGE("ioctl set ipv4 address failed: %{public}d", errno);
426 close(socketfd);
427 return NETMANAGER_ERROR;
428 }
429
430 if (prefix <= 0 || prefix > V4ADDR_BIT_LEN) {
431 NETNATIVE_LOGE("prefix: %{public}d error", prefix);
432 close(socketfd);
433 return NETMANAGER_ERROR;
434 }
435 in_addr_t mask = prefix ? (~0 << (V4ADDR_BIT_LEN - prefix)) : 0;
436 sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_netmask);
437 sin->sin_family = AF_INET;
438 sin->sin_addr.s_addr = htonl(mask);
439 if (ioctl(socketfd, SIOCSIFNETMASK, &ifr) < 0) {
440 NETNATIVE_LOGE("ioctl set ip mask failed: %{public}d", errno);
441 close(socketfd);
442 return NETMANAGER_ERROR;
443 }
444 close(socketfd);
445 return NETMANAGER_SUCCESS;
446 }
447
448 } // namespace nmd
449 } // namespace OHOS