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 41namespace OHOS { 42namespace nmd { 43using namespace OHOS::NetManagerStandard; 44ffrt::mutex g_tunV4AddrMutex; 45std::list<in_addr_t> g_tunV4AddrInUse; 46 47bool 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 74void 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 85in_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 105int32_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 126uint16_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 134uint16_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 146uint32_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 162void 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 177int32_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 221int32_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 258uint16_t CalChecksum(const void *data, int len) 259{ 260 uint32_t tempSum = AddChecksum(0xffff, data, len); 261 return ~Checksum32To16(tempSum); 262} 263 264int32_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 288int32_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 311int32_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 328int32_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 344int 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 383int32_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 404int32_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