1 /*
2 * Copyright (c) 2025 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 "multi_vpn_manager.h"
17
18 #include <sys/ioctl.h>
19 #include <thread>
20 #include <linux/ppp_defs.h>
21 #include <linux/if_ppp.h>
22 #include <linux/if_tun.h>
23 #include "init_socket.h"
24 #include "net_manager_constants.h"
25 #include "netmanager_base_common_utils.h"
26 #include "netnative_log_wrapper.h"
27 #include "securec.h"
28 #include "netlink_socket.h"
29 #include "route_manager.h"
30
31 namespace OHOS {
32 namespace NetManagerStandard {
33
34 namespace {
35 constexpr uint32_t DEFAULT_MTU = 1500;
36 constexpr int32_t NET_MASK_MAX_LENGTH = 32;
37 constexpr int32_t MAX_UNIX_SOCKET_CLIENT = 5;
38 } // namespace
39
SendVpnInterfaceFdToClient(int32_t clientFd,int32_t tunFd)40 int32_t MultiVpnManager::SendVpnInterfaceFdToClient(int32_t clientFd, int32_t tunFd)
41 {
42 char buf[1] = {0};
43 iovec iov;
44 iov.iov_base = buf;
45 iov.iov_len = sizeof(buf);
46 union {
47 cmsghdr align;
48 char cmsg[CMSG_SPACE(sizeof(int32_t))];
49 } cmsgu;
50 if (memset_s(cmsgu.cmsg, sizeof(cmsgu.cmsg), 0, sizeof(cmsgu.cmsg)) != EOK) {
51 NETNATIVE_LOGE("memset_s cmsgu.cmsg failed!");
52 return NETMANAGER_ERROR;
53 }
54 msghdr message;
55 if (memset_s(&message, sizeof(message), 0, sizeof(message)) != EOK) {
56 NETNATIVE_LOGE("memset_s message failed!");
57 return NETMANAGER_ERROR;
58 }
59
60 message.msg_iov = &iov;
61 message.msg_iovlen = 1;
62 message.msg_control = cmsgu.cmsg;
63 message.msg_controllen = sizeof(cmsgu.cmsg);
64 cmsghdr *cmsgh = CMSG_FIRSTHDR(&message);
65 cmsgh->cmsg_len = CMSG_LEN(sizeof(tunFd));
66 cmsgh->cmsg_level = SOL_SOCKET;
67 cmsgh->cmsg_type = SCM_RIGHTS;
68 if (memcpy_s(CMSG_DATA(cmsgh), sizeof(tunFd), &tunFd, sizeof(tunFd)) != EOK) {
69 NETNATIVE_LOGE("memcpy_s cmsgu failed!");
70 return NETMANAGER_ERROR;
71 }
72 if (sendmsg(clientFd, &message, 0) < 0) {
73 NETNATIVE_LOGE("sendmsg error: %{public}d, clientfd[%{public}d], tunfd[%{public}d]", errno, clientFd, tunFd);
74 return NETMANAGER_ERROR;
75 }
76 return NETMANAGER_SUCCESS;
77 }
78
InitIfreq(ifreq & ifr,const std::string & ifName)79 int32_t MultiVpnManager::InitIfreq(ifreq &ifr, const std::string &ifName)
80 {
81 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
82 NETNATIVE_LOGE("memset_s ifr failed!");
83 return NETMANAGER_ERROR;
84 }
85 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ifName.c_str(), strlen(ifName.c_str())) != EOK) {
86 NETNATIVE_LOGE("strcpy_s ifr name fail");
87 return NETMANAGER_ERROR;
88 }
89 return NETMANAGER_SUCCESS;
90 }
91
SetVpnResult(std::atomic_int & fd,unsigned long cmd,ifreq & ifr)92 int32_t MultiVpnManager::SetVpnResult(std::atomic_int &fd, unsigned long cmd, ifreq &ifr)
93 {
94 if (fd > 0) {
95 if (ioctl(fd, cmd, &ifr) < 0) {
96 NETNATIVE_LOGE("set vpn error, errno:%{public}d", errno);
97 return NETMANAGER_ERROR;
98 }
99 }
100 return NETMANAGER_SUCCESS;
101 }
102
SetVpnMtu(const std::string & ifName,int32_t mtu)103 int32_t MultiVpnManager::SetVpnMtu(const std::string &ifName, int32_t mtu)
104 {
105 if (mtu <= 0) {
106 NETNATIVE_LOGE("invalid mtu value");
107 return NETMANAGER_ERROR;
108 }
109
110 ifreq ifr;
111 if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) {
112 return NETMANAGER_ERROR;
113 }
114 ifr.ifr_mtu = mtu;
115
116 std::atomic_int net4Sock = socket(AF_INET, SOCK_DGRAM, 0);
117 if (net4Sock < 0) {
118 NETNATIVE_LOGE("create SOCK_DGRAM ipv4 failed: %{public}d", errno);
119 return NETMANAGER_ERROR;
120 }
121 int32_t ret4 = SetVpnResult(net4Sock, SIOCSIFMTU, ifr);
122 close(net4Sock);
123 if (ret4 == NETMANAGER_ERROR) {
124 NETNATIVE_LOGI("set MTU failed");
125 return NETMANAGER_ERROR;
126 }
127 return NETMANAGER_SUCCESS;
128 }
129
AddVpnRemoteAddress(const std::string & ifName,std::atomic_int & net4Sock,ifreq & ifr)130 int32_t MultiVpnManager::AddVpnRemoteAddress(const std::string &ifName, std::atomic_int &net4Sock, ifreq &ifr)
131 {
132 /* ppp need set dst ip */
133 if (strstr(ifName.c_str(), PPP_CARD_NAME) != NULL) {
134 in_addr remoteIpv4Addr = {};
135 if (inet_aton(remoteIpv4Addr_.c_str(), &remoteIpv4Addr) == 0) {
136 NETNATIVE_LOGE("addr inet_aton error");
137 return NETMANAGER_ERROR;
138 }
139 auto remoteAddr = reinterpret_cast<sockaddr_in *>(&ifr.ifr_dstaddr);
140 remoteAddr->sin_family = AF_INET;
141 remoteAddr->sin_addr = remoteIpv4Addr;
142 if (ioctl(net4Sock, SIOCSIFDSTADDR, &ifr) < 0) {
143 NETNATIVE_LOGE("ioctl set ipv4 address failed: %{public}d", errno);
144 return NETMANAGER_ERROR;
145 }
146 }
147 return NETMANAGER_SUCCESS;
148 }
149
SetVpnAddress(const std::string & ifName,const std::string & vpnAddr,int32_t prefix)150 int32_t MultiVpnManager::SetVpnAddress(const std::string &ifName, const std::string &vpnAddr, int32_t prefix)
151 {
152 ifreq ifr = {};
153 if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) {
154 return NETMANAGER_ERROR;
155 }
156 std::atomic_int net4Sock = socket(AF_INET, SOCK_DGRAM, 0);
157 if (net4Sock < 0) {
158 NETNATIVE_LOGE("create SOCK_DGRAM ipv4 failed: %{public}d", errno);
159 return NETMANAGER_ERROR;
160 }
161 in_addr ipv4Addr = {};
162 if (inet_aton(vpnAddr.c_str(), &ipv4Addr) == 0) {
163 NETNATIVE_LOGE("addr inet_aton error");
164 close(net4Sock);
165 return NETMANAGER_ERROR;
166 }
167
168 auto sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_addr);
169 sin->sin_family = AF_INET;
170 sin->sin_addr = ipv4Addr;
171 if (ioctl(net4Sock, SIOCSIFADDR, &ifr) < 0) {
172 NETNATIVE_LOGE("ioctl set ipv4 address failed: %{public}d", errno);
173 close(net4Sock);
174 return NETMANAGER_ERROR;
175 }
176 /* ppp need set dst ip */
177 if (AddVpnRemoteAddress(ifName, net4Sock, ifr) != NETMANAGER_SUCCESS) {
178 close(net4Sock);
179 return NETMANAGER_ERROR;
180 }
181 if (prefix <= 0 || prefix > NET_MASK_MAX_LENGTH) {
182 NETNATIVE_LOGE("prefix: %{public}d error", prefix);
183 close(net4Sock);
184 return NETMANAGER_ERROR;
185 }
186 in_addr_t mask = prefix ? (~0 << (NET_MASK_MAX_LENGTH - prefix)) : 0;
187 sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_netmask);
188 sin->sin_family = AF_INET;
189 sin->sin_addr.s_addr = htonl(mask);
190 if (ioctl(net4Sock, SIOCSIFNETMASK, &ifr) < 0) {
191 NETNATIVE_LOGE("ioctl set ip mask failed: %{public}d", errno);
192 close(net4Sock);
193 return NETMANAGER_ERROR;
194 }
195
196 SetVpnUp(ifName);
197 close(net4Sock);
198 NETNATIVE_LOGI("set ip address success");
199 return NETMANAGER_SUCCESS;
200 }
201
SetVpnUp(const std::string & ifName)202 int32_t MultiVpnManager::SetVpnUp(const std::string &ifName)
203 {
204 ifreq ifr = {};
205 if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) {
206 return NETMANAGER_ERROR;
207 }
208 ifr.ifr_flags = IFF_UP | IFF_NOARP;
209 std::atomic_int net4Sock = socket(AF_INET, SOCK_DGRAM, 0);
210 if (net4Sock < 0) {
211 NETNATIVE_LOGE("create SOCK_DGRAM ipv4 failed: %{public}d", errno);
212 return NETMANAGER_ERROR;
213 }
214 int32_t ret4 = SetVpnResult(net4Sock, SIOCSIFFLAGS, ifr);
215 close(net4Sock);
216 if (ret4 == NETMANAGER_ERROR) {
217 NETNATIVE_LOGI("set iff up failed");
218 return NETMANAGER_ERROR;
219 }
220 return NETMANAGER_SUCCESS;
221 }
222
SetVpnDown(const std::string & ifName)223 int32_t MultiVpnManager::SetVpnDown(const std::string &ifName)
224 {
225 ifreq ifr = {};
226 if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) {
227 return NETMANAGER_ERROR;
228 }
229 ifr.ifr_flags &= ~IFF_UP;
230 std::atomic_int net4Sock = socket(AF_INET, SOCK_DGRAM, 0);
231 if (net4Sock < 0) {
232 NETNATIVE_LOGE("create SOCK_DGRAM ipv4 failed: %{public}d", errno);
233 return NETMANAGER_ERROR;
234 }
235 int32_t ret4 = SetVpnResult(net4Sock, SIOCSIFFLAGS, ifr);
236 close(net4Sock);
237 if (ret4 == NETMANAGER_ERROR) {
238 NETNATIVE_LOGI("set iff down failed");
239 return NETMANAGER_ERROR;
240 }
241 return NETMANAGER_SUCCESS;
242 }
243
CreateVpnInterface(const std::string & ifName)244 int32_t MultiVpnManager::CreateVpnInterface(const std::string &ifName)
245 {
246 int32_t ret = NETMANAGER_SUCCESS;
247 if (strstr(ifName.c_str(), XFRM_CARD_NAME) != NULL) {
248 uint32_t ifNameId = CommonUtils::StrToUint(ifName.substr(strlen(XFRM_CARD_NAME)));
249 ret = nmd::CreateVpnIfByNetlink(ifName.c_str(), ifNameId, phyName_.c_str(), DEFAULT_MTU);
250 } else if (strstr(ifName.c_str(), PPP_CARD_NAME) != NULL) {
251 ret = CreatePppInterface(ifName);
252 } else if (strstr(ifName.c_str(), MULTI_TUN_CARD_NAME) != NULL) {
253 ret = CreateMultiTunInterface(ifName);
254 } else {
255 NETNATIVE_LOGE("CreateVpnInterface failed, invalid ifName");
256 return NETMANAGER_ERROR;
257 }
258 return ret;
259 }
260
DestroyVpnInterface(const std::string & ifName)261 int32_t MultiVpnManager::DestroyVpnInterface(const std::string &ifName)
262 {
263 NETNATIVE_LOGI("destroy vpn interface:%{public}s", ifName.c_str());
264 bool isXfrm = strstr(ifName.c_str(), XFRM_CARD_NAME) != NULL;
265 bool isPpp = strstr(ifName.c_str(), PPP_CARD_NAME) != NULL;
266 bool isMultiTun = strstr(ifName.c_str(), MULTI_TUN_CARD_NAME) != NULL;
267 if (!isXfrm && !isPpp && !isMultiTun) {
268 NETNATIVE_LOGE("DestroyVpnInterface failed, invalid ifName");
269 return NETMANAGER_ERROR;
270 }
271 SetVpnDown(ifName);
272 nmd::DeleteVpnIfByNetlink(ifName.c_str());
273 if (isPpp || isMultiTun) {
274 DestroyMultiVpnFd(ifName);
275 }
276 return NETMANAGER_SUCCESS;
277 }
278
CreatePppInterface(const std::string & ifName)279 int32_t MultiVpnManager::CreatePppInterface(const std::string &ifName)
280 {
281 auto it = multiVpnFdMap_.find(ifName);
282 if (it == multiVpnFdMap_.end()) {
283 NETNATIVE_LOGE("ifName not exist");
284 return NETMANAGER_ERROR;
285 }
286 ifreq ifr = {};
287 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
288 NETNATIVE_LOGE("memset_s ifr failed!");
289 return NETMANAGER_ERROR;
290 }
291 int32_t currentIfunit = 0;
292 if (ioctl(multiVpnFdMap_[ifName], PPPIOCGUNIT, ¤tIfunit) < 0) {
293 NETNATIVE_LOGE("ioctl PPPIOCDISCONN failed errno: %{public}d", errno);
294 }
295 NETNATIVE_LOGI("Created PPP interface: currentIfunit:%{public}d\n", currentIfunit);
296 std::string oldName = "ppp" + std::to_string(currentIfunit);
297 SetVpnDown(oldName);
298 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, oldName.c_str(), strlen(oldName.c_str())) != EOK) {
299 NETNATIVE_LOGE("strcpy_s ifr name fail");
300 return NETMANAGER_ERROR;
301 }
302 ifr.ifr_name[IFNAMSIZ - 1] = '\0';
303 if (strncpy_s(ifr.ifr_newname, IFNAMSIZ, ifName.c_str(), strlen(ifName.c_str())) != EOK) {
304 NETNATIVE_LOGE("strcpy_s ifr name fail");
305 return NETMANAGER_ERROR;
306 }
307 ifr.ifr_newname[IFNAMSIZ - 1] = '\0';
308 std::atomic_int net4Sock = socket(AF_INET, SOCK_DGRAM, 0);
309 if (net4Sock < 0) {
310 NETNATIVE_LOGE("create SOCK_DGRAM ipv4 failed: %{public}d", errno);
311 return NETMANAGER_ERROR;
312 }
313 int32_t ioRet = ioctl(net4Sock, SIOCSIFNAME, &ifr);
314 close(net4Sock);
315 if (ioRet < 0) {
316 NETNATIVE_LOGE("ioctl failed errno: %{public}d", errno);
317 return NETMANAGER_ERROR;
318 }
319 NETNATIVE_LOGI("Created PPP interface");
320 return NETMANAGER_SUCCESS;
321 }
322
CreatePppFd(const std::string & ifName)323 void MultiVpnManager::CreatePppFd(const std::string &ifName)
324 {
325 if (strstr(ifName.c_str(), PPP_CARD_NAME) == NULL) {
326 NETNATIVE_LOGE("CreatePppFd failed");
327 return;
328 }
329 multiVpnListeningName_ = ifName;
330 StartMultiVpnInterfaceFdListen();
331 }
332
CreateMultiTunInterface(const std::string & ifName)333 int32_t MultiVpnManager::CreateMultiTunInterface(const std::string &ifName)
334 {
335 int32_t multiVpnFd = 0;
336 if (GetMultiVpnFd(ifName, multiVpnFd) != NETMANAGER_SUCCESS) {
337 return NETMANAGER_ERROR;
338 }
339
340 ifreq ifr = {};
341 if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) {
342 return NETMANAGER_ERROR;
343 }
344
345 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
346 if (ioctl(multiVpnFd, TUNSETIFF, &ifr) < 0) {
347 NETNATIVE_LOGE("multi tun set iff error: %{public}d", errno);
348 return NETMANAGER_ERROR;
349 }
350 multiVpnListeningName_ = ifName;
351 StartMultiVpnInterfaceFdListen();
352 return NETMANAGER_SUCCESS;
353 }
354
GetMultiVpnFd(const std::string & ifName,int32_t & multiVpnFd)355 int32_t MultiVpnManager::GetMultiVpnFd(const std::string &ifName, int32_t &multiVpnFd)
356 {
357 std::lock_guard<std::mutex> autoLock(mutex_);
358 auto it = multiVpnFdMap_.find(ifName);
359 if (it != multiVpnFdMap_.end()) {
360 NETNATIVE_LOGE("ifName already exist");
361 multiVpnFd = it->second.load();
362 return NETMANAGER_SUCCESS;
363 }
364 if (strstr(ifName.c_str(), PPP_CARD_NAME) != NULL) {
365 multiVpnFd = open(PPP_DEVICE_PATH, O_RDWR | O_NONBLOCK | O_CLOEXEC);
366 } else if (strstr(ifName.c_str(), MULTI_TUN_CARD_NAME) != NULL) {
367 multiVpnFd = open(TUN_DEVICE_PATH, O_RDWR | O_NONBLOCK | O_CLOEXEC);
368 } else {
369 NETNATIVE_LOGE("GetMultiVpnFd faild, IfName err");
370 return NETMANAGER_ERROR;
371 }
372 if (multiVpnFd <= 0) {
373 NETNATIVE_LOGE("open virtual device failed: %{public}d", errno);
374 return NETMANAGER_ERROR;
375 }
376 multiVpnFdMap_[ifName] = multiVpnFd;
377 return NETMANAGER_SUCCESS;
378 }
379
SetVpnRemoteAddress(const std::string & remoteIp)380 void MultiVpnManager::SetVpnRemoteAddress(const std::string &remoteIp)
381 {
382 remoteIpv4Addr_ = remoteIp;
383 }
384
DestroyMultiVpnFd(const std::string & ifName)385 int32_t MultiVpnManager::DestroyMultiVpnFd(const std::string &ifName)
386 {
387 std::lock_guard<std::mutex> autoLock(mutex_);
388 if (strstr(ifName.c_str(), PPP_CARD_NAME) == NULL && strstr(ifName.c_str(), MULTI_TUN_CARD_NAME) == NULL) {
389 NETNATIVE_LOGE("DestroyMultiVpnFd faild, IfName err");
390 return NETMANAGER_ERROR;
391 }
392 auto it = multiVpnFdMap_.find(ifName);
393 if (it == multiVpnFdMap_.end()) {
394 NETNATIVE_LOGE("ifName not exist");
395 return NETMANAGER_ERROR;
396 }
397 auto multiVpnFd = it->second.load();
398 if (multiVpnFd != 0) {
399 close(multiVpnFd);
400 }
401 multiVpnFdMap_.erase(it);
402 return NETMANAGER_SUCCESS;
403 }
404
StartMultiVpnInterfaceFdListen()405 void MultiVpnManager::StartMultiVpnInterfaceFdListen()
406 {
407 if (multiVpnListeningFlag_) {
408 NETNATIVE_LOGI("MultiVpnInterface fd is listening...");
409 return;
410 }
411 NETNATIVE_LOGI("StartMultiVpnInterfaceFdListen...");
412 multiVpnListeningFlag_ = true;
413 std::thread t([sp = shared_from_this()]() { sp->StartMultiVpnSocketListen(); });
414 t.detach();
415 pthread_setname_np(t.native_handle(), "unix_socket_multivpnfd");
416 }
417
StartMultiVpnSocketListen()418 void MultiVpnManager::StartMultiVpnSocketListen()
419 {
420 NETNATIVE_LOGI("StartMultiVpnSocketListen...");
421 int32_t serverfd = GetControlSocket("multivpnfd");
422 if (listen(serverfd, MAX_UNIX_SOCKET_CLIENT) < 0) {
423 multiVpnListeningFlag_ = false;
424 NETNATIVE_LOGE("listen socket error: %{public}d", errno);
425 return;
426 }
427
428 sockaddr_in clientAddr;
429 socklen_t len = sizeof(clientAddr);
430 int32_t clientFd = accept(serverfd, reinterpret_cast<sockaddr *>(&clientAddr), &len);
431 if (clientFd < 0) {
432 NETNATIVE_LOGE("accept socket error: %{public}d", errno);
433 multiVpnListeningFlag_ = false;
434 return;
435 }
436 int32_t multiVpnFd = -1;
437 if (GetMultiVpnFd(multiVpnListeningName_, multiVpnFd) == NETMANAGER_SUCCESS) {
438 SendVpnInterfaceFdToClient(clientFd, multiVpnFd);
439 }
440 multiVpnListeningFlag_ = false;
441 close(clientFd);
442 }
443
SetXfrmPhyIfName(const std::string & phyName)444 void MultiVpnManager::SetXfrmPhyIfName(const std::string &phyName)
445 {
446 phyName_ = phyName;
447 }
448
SetVpnCallMode(const std::string & message)449 int32_t MultiVpnManager::SetVpnCallMode(const std::string &message)
450 {
451 if (message.empty()) {
452 NETNATIVE_LOGE("message is empty");
453 return NETMANAGER_ERROR;
454 }
455 return nmd::RouteManager::SetVpnCallMode(message);
456 }
457 } // namespace NetManagerStandard
458 } // namespace OHOS
459