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