1 /*
2 * Copyright (c) 2021-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 "interface_manager.h"
17
18 #include <arpa/inet.h>
19 #include <cerrno>
20 #include <cstdlib>
21 #include <cstring>
22 #include <dirent.h>
23 #include <fcntl.h>
24 #include <linux/if_ether.h>
25 #include <net/if.h>
26 #include <netinet/in.h>
27 #include <sys/ioctl.h>
28 #include <sys/socket.h>
29 #include <sys/types.h>
30 #include <system_error>
31 #include <unistd.h>
32 #include <regex>
33
34 #include "netlink_manager.h"
35 #include "netlink_socket.h"
36 #include "netlink_socket_diag.h"
37 #include "net_manager_constants.h"
38 #include "netmanager_base_common_utils.h"
39 #include "netnative_log_wrapper.h"
40 #include "securec.h"
41
42 namespace OHOS {
43 namespace nmd {
44 using namespace NetManagerStandard;
45 using namespace NetManagerStandard::CommonUtils;
46
47 namespace {
48 constexpr const char *SYS_NET_PATH = "/sys/class/net/";
49 constexpr const char *MTU_PATH = "/mtu";
50 constexpr int32_t FILE_PERMISSION = 0666;
51 constexpr uint32_t ARRAY_OFFSET_1_INDEX = 1;
52 constexpr uint32_t ARRAY_OFFSET_2_INDEX = 2;
53 constexpr uint32_t ARRAY_OFFSET_3_INDEX = 3;
54 constexpr uint32_t ARRAY_OFFSET_4_INDEX = 4;
55 constexpr uint32_t ARRAY_OFFSET_5_INDEX = 5;
56 constexpr uint32_t MOVE_BIT_LEFT31 = 31;
57 constexpr uint32_t BIT_MAX = 32;
58 constexpr uint32_t IOCTL_RETRY_TIME = 32;
59 constexpr int32_t MAX_MTU_LEN = 11;
60 constexpr int32_t MAC_ADDRESS_STR_LEN = 18;
61 constexpr int32_t MAC_SSCANF_SPACE = 3;
62 const std::regex REGEX_CMD_MAC_ADDRESS("^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$");
63
CheckFilePath(const std::string & fileName,std::string & realPath)64 bool CheckFilePath(const std::string &fileName, std::string &realPath)
65 {
66 char tmpPath[PATH_MAX] = {0};
67 if (!realpath(fileName.c_str(), tmpPath)) {
68 NETNATIVE_LOGE("file name is illegal");
69 return false;
70 }
71 realPath = tmpPath;
72 return true;
73 }
74 } // namespace
75
GetMtu(const char * interfaceName)76 int InterfaceManager::GetMtu(const char *interfaceName)
77 {
78 if (interfaceName == nullptr) {
79 NETNATIVE_LOGE("interfaceName is null");
80 return -1;
81 }
82
83 if (!CheckIfaceName(interfaceName)) {
84 NETNATIVE_LOGE("GetMtu isIfaceName fail %{public}d", errno);
85 return -1;
86 }
87 std::string mtuPath = std::string(SYS_NET_PATH).append(interfaceName).append(MTU_PATH);
88 std::string realPath;
89 if (!CheckFilePath(mtuPath, realPath)) {
90 NETNATIVE_LOGE("file does not exist! ");
91 return -1;
92 }
93 int fd = open(realPath.c_str(), 0, FILE_PERMISSION);
94 if (fd == -1) {
95 NETNATIVE_LOGE("GetMtu open fail %{public}d", errno);
96 return -1;
97 }
98
99 char originMtuValue[MAX_MTU_LEN] = {0};
100 int nread = read(fd, originMtuValue, (sizeof(char) * (MAX_MTU_LEN - 1)));
101 if (nread == -1 || nread == 0) {
102 NETNATIVE_LOGE("GetMtu read fail %{public}d", errno);
103 close(fd);
104 return -1;
105 }
106 close(fd);
107
108 int32_t mtu = -1;
109 mtu = StrToInt(originMtuValue);
110 return mtu;
111 }
112
SetMtu(const char * interfaceName,const char * mtuValue)113 int InterfaceManager::SetMtu(const char *interfaceName, const char *mtuValue)
114 {
115 if (interfaceName == nullptr || mtuValue == nullptr) {
116 NETNATIVE_LOGE("interfaceName or mtuValue is null");
117 return -1;
118 }
119
120 if (!CheckIfaceName(interfaceName)) {
121 NETNATIVE_LOGE("SetMtu isIfaceName fail %{public}d", errno);
122 }
123 int32_t sockfd = socket(AF_INET, SOCK_DGRAM, 0);
124 if (sockfd < 0) {
125 NETNATIVE_LOGE("SetMtu socket fail %{public}d", errno);
126 return -1;
127 }
128
129 struct ifreq ifr;
130 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
131 close(sockfd);
132 return -1;
133 }
134 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, interfaceName, strlen(interfaceName)) != EOK) {
135 close(sockfd);
136 return -1;
137 }
138
139 int32_t mtu = StrToInt(mtuValue);
140 ifr.ifr_mtu = mtu;
141
142 if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) {
143 NETNATIVE_LOGE("SetMtu ioctl fail %{public}d", errno);
144 close(sockfd);
145 return -1;
146 }
147
148 close(sockfd);
149 return 0;
150 }
151
GetInterfaceNames()152 std::vector<std::string> InterfaceManager::GetInterfaceNames()
153 {
154 std::vector<std::string> ifaceNames;
155 DIR *dir(nullptr);
156 struct dirent *de(nullptr);
157
158 dir = opendir(SYS_NET_PATH);
159 if (dir == nullptr) {
160 NETNATIVE_LOGE("GetInterfaceNames opendir fail %{public}d", errno);
161 return ifaceNames;
162 }
163
164 de = readdir(dir);
165 while (de != nullptr) {
166 if ((de->d_name[0] != '.') && ((de->d_type == DT_DIR) || (de->d_type == DT_LNK))) {
167 ifaceNames.push_back(std::string(de->d_name));
168 }
169 de = readdir(dir);
170 }
171 closedir(dir);
172
173 return ifaceNames;
174 }
175
ModifyAddress(uint32_t action,const char * interfaceName,const char * addr,int prefixLen)176 int InterfaceManager::ModifyAddress(uint32_t action, const char *interfaceName, const char *addr, int prefixLen)
177 {
178 if (interfaceName == nullptr || addr == nullptr) {
179 return -1;
180 }
181 uint32_t index = if_nametoindex(interfaceName);
182 if (index == 0) {
183 NETNATIVE_LOGE("ModifyAddress, if_nametoindex error %{public}d", errno);
184 return -errno;
185 }
186 auto family = CommonUtils::GetAddrFamily(addr);
187 if (family != AF_INET && family != AF_INET6) {
188 NETNATIVE_LOGE("Ivalid ip address: %{public}s", CommonUtils::ToAnonymousIp(addr).c_str());
189 return NETMANAGER_ERR_PARAMETER_ERROR;
190 }
191
192 ifaddrmsg ifm = {static_cast<uint8_t>(family), static_cast<uint8_t>(prefixLen), 0, 0, index};
193 nmd::NetlinkMsg nlmsg(NLM_F_CREATE | NLM_F_EXCL, nmd::NETLINK_MAX_LEN, getpid());
194 nlmsg.AddAddress(action, ifm);
195
196 if (family == AF_INET6) {
197 in6_addr in6Addr;
198 if (inet_pton(AF_INET6, addr, &in6Addr) == -1) {
199 NETNATIVE_LOGE("Modify ipv6 address, inet_pton error %{public}d", errno);
200 return NETMANAGER_ERR_INTERNAL;
201 }
202 nlmsg.AddAttr(IFA_LOCAL, &in6Addr, sizeof(in6Addr));
203 } else {
204 in_addr inAddr;
205 if (inet_pton(AF_INET, addr, &inAddr) == -1) {
206 NETNATIVE_LOGE("Modify ipv4 address, inet_pton error %{public}d", errno);
207 return NETMANAGER_ERR_INTERNAL;
208 }
209 nlmsg.AddAttr(IFA_LOCAL, &inAddr, sizeof(inAddr));
210 if (action == RTM_NEWADDR) {
211 inAddr.s_addr |= htonl((1U << (BIT_MAX - prefixLen)) - 1);
212 nlmsg.AddAttr(IFA_BROADCAST, &inAddr, sizeof(inAddr));
213 }
214 }
215
216 NETNATIVE_LOGI("ModifyAddress:%{public}u %{public}s %{public}s %{public}d", action, interfaceName,
217 ToAnonymousIp(addr).c_str(), prefixLen);
218
219 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
220 }
221
AddAddress(const char * interfaceName,const char * addr,int prefixLen)222 int InterfaceManager::AddAddress(const char *interfaceName, const char *addr, int prefixLen)
223 {
224 return ModifyAddress(RTM_NEWADDR, interfaceName, addr, prefixLen);
225 }
226
DelAddress(const char * interfaceName,const char * addr,int prefixLen)227 int InterfaceManager::DelAddress(const char *interfaceName, const char *addr, int prefixLen)
228 {
229 NetLinkSocketDiag socketDiag;
230 socketDiag.DestroyLiveSockets(addr, true);
231 return ModifyAddress(RTM_DELADDR, interfaceName, addr, prefixLen);
232 }
233
DelAddress(const char * interfaceName,const char * addr,int prefixLen,const std::string & netCapabilities)234 int InterfaceManager::DelAddress(const char *interfaceName, const char *addr, int prefixLen,
235 const std::string &netCapabilities)
236 {
237 NetLinkSocketDiag socketDiag;
238 socketDiag.SetSocketDestroyType(netCapabilities);
239 socketDiag.DestroyLiveSockets(addr, true);
240 return 0;
241 }
242
Ipv4NetmaskToPrefixLength(in_addr_t mask)243 int Ipv4NetmaskToPrefixLength(in_addr_t mask)
244 {
245 int prefixLength = 0;
246 uint32_t m = ntohl(mask);
247 const uint32_t referenceValue = 1;
248 while (m & (referenceValue << MOVE_BIT_LEFT31)) {
249 prefixLength++;
250 m = m << referenceValue;
251 }
252 return prefixLength;
253 }
254
HwAddrToStr(char * hwaddr)255 std::string HwAddrToStr(char *hwaddr)
256 {
257 char buf[64] = {'\0'};
258 if (hwaddr != nullptr) {
259 errno_t result =
260 sprintf_s(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", hwaddr[0], hwaddr[ARRAY_OFFSET_1_INDEX],
261 hwaddr[ARRAY_OFFSET_2_INDEX], hwaddr[ARRAY_OFFSET_3_INDEX], hwaddr[ARRAY_OFFSET_4_INDEX],
262 hwaddr[ARRAY_OFFSET_5_INDEX]);
263 if (result != 0) {
264 NETNATIVE_LOGE("[hwAddrToStr]: result %{public}d", result);
265 }
266 }
267 return std::string(buf);
268 }
269
UpdateIfaceConfigFlags(unsigned flags,nmd::InterfaceConfigurationParcel & ifaceConfig)270 void UpdateIfaceConfigFlags(unsigned flags, nmd::InterfaceConfigurationParcel &ifaceConfig)
271 {
272 ifaceConfig.flags.emplace_back(flags & IFF_UP ? "up" : "down");
273 if (flags & IFF_BROADCAST) {
274 ifaceConfig.flags.emplace_back("broadcast");
275 }
276 if (flags & IFF_LOOPBACK) {
277 ifaceConfig.flags.emplace_back("loopback");
278 }
279 if (flags & IFF_POINTOPOINT) {
280 ifaceConfig.flags.emplace_back("point-to-point");
281 }
282 if (flags & IFF_RUNNING) {
283 ifaceConfig.flags.emplace_back("running");
284 }
285 if (flags & IFF_MULTICAST) {
286 ifaceConfig.flags.emplace_back("multicast");
287 }
288 }
289
GetIfaceConfig(const std::string & ifName)290 InterfaceConfigurationParcel InterfaceManager::GetIfaceConfig(const std::string &ifName)
291 {
292 NETNATIVE_LOG_D("GetIfaceConfig in. ifName %{public}s", ifName.c_str());
293 struct in_addr addr = {};
294 nmd::InterfaceConfigurationParcel ifaceConfig;
295
296 int fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
297 struct ifreq ifr = {};
298 auto ret = strncpy_s(ifr.ifr_name, IFNAMSIZ, ifName.c_str(), ifName.length());
299 if (ret != 0) {
300 NETNATIVE_LOGW("IfName copy failed, no need to return.");
301 }
302
303 ifaceConfig.ifName = ifName;
304 if (ioctl(fd, SIOCGIFADDR, &ifr) != -1) {
305 addr.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
306 ifaceConfig.ipv4Addr = std::string(inet_ntoa(addr));
307 }
308 if (ioctl(fd, SIOCGIFNETMASK, &ifr) != -1) {
309 ifaceConfig.prefixLength = Ipv4NetmaskToPrefixLength(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
310 }
311 if (ioctl(fd, SIOCGIFFLAGS, &ifr) != -1) {
312 UpdateIfaceConfigFlags(ifr.ifr_flags, ifaceConfig);
313 }
314 if (ioctl(fd, SIOCGIFHWADDR, &ifr) != -1) {
315 ifaceConfig.hwAddr = HwAddrToStr(ifr.ifr_hwaddr.sa_data);
316 }
317 close(fd);
318 return ifaceConfig;
319 }
320
SetIfaceConfig(const nmd::InterfaceConfigurationParcel & ifaceConfig)321 int InterfaceManager::SetIfaceConfig(const nmd::InterfaceConfigurationParcel &ifaceConfig)
322 {
323 struct ifreq ifr = {};
324 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ifaceConfig.ifName.c_str(), ifaceConfig.ifName.length()) != 0) {
325 NETNATIVE_LOGE("ifaceConfig strncpy_s error.");
326 return -1;
327 }
328
329 if (ifaceConfig.flags.empty()) {
330 NETNATIVE_LOGE("ifaceConfig flags is empty.");
331 return -1;
332 }
333 int fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
334 if (fd < 0) {
335 NETNATIVE_LOGE("ifaceConfig socket error, errno[%{public}d]", errno);
336 return -1;
337 }
338 if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
339 char errmsg[INTERFACE_ERR_MAX_LEN] = {0};
340 strerror_r(errno, errmsg, INTERFACE_ERR_MAX_LEN);
341 NETNATIVE_LOGE("fail to set interface config. strerror[%{public}s]", errmsg);
342 close(fd);
343 return -1;
344 }
345 short flags = ifr.ifr_flags;
346 auto fit = std::find(ifaceConfig.flags.begin(), ifaceConfig.flags.end(), "up");
347 if (fit != std::end(ifaceConfig.flags)) {
348 uint16_t ifrFlags = static_cast<uint16_t>(ifr.ifr_flags);
349 ifrFlags = ifrFlags | IFF_UP;
350 ifr.ifr_flags = static_cast<short>(ifrFlags);
351 }
352 fit = std::find(ifaceConfig.flags.begin(), ifaceConfig.flags.end(), "down");
353 if (fit != std::end(ifaceConfig.flags)) {
354 ifr.ifr_flags = (short)((uint16_t)ifr.ifr_flags & (~IFF_UP));
355 }
356 if (ifr.ifr_flags == flags) {
357 close(fd);
358 return 1;
359 }
360 uint32_t retry = 0;
361 do {
362 if (ioctl(fd, SIOCSIFFLAGS, &ifr) != -1) {
363 break;
364 }
365 ++retry;
366 } while (errno == ETIMEDOUT && retry < IOCTL_RETRY_TIME);
367 NETNATIVE_LOGI("set ifr flags=[%{public}d] strerror=[%{public}s] retry=[%{public}u]", ifr.ifr_flags,
368 strerror(errno), retry);
369 close(fd);
370 return 1;
371 }
372
SetIpAddress(const std::string & ifaceName,const std::string & ipAddress)373 int InterfaceManager::SetIpAddress(const std::string &ifaceName, const std::string &ipAddress)
374 {
375 struct ifreq ifr;
376 struct in_addr ipv4Addr = {INADDR_ANY};
377
378 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
379 NETNATIVE_LOGE("memset is false");
380 return -1;
381 }
382 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ifaceName.c_str(), strlen(ifaceName.c_str())) != EOK) {
383 NETNATIVE_LOGE("strncpy is false");
384 return -1;
385 }
386 if (inet_aton(ipAddress.c_str(), &ipv4Addr) == 0) {
387 NETNATIVE_LOGE("set net ip is false");
388 return -1;
389 }
390 sockaddr_in *sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr);
391 sin->sin_family = AF_INET;
392 sin->sin_port = 0;
393 sin->sin_addr = ipv4Addr;
394 int32_t inetSocket = socket(AF_INET, SOCK_DGRAM, 0);
395 if (ioctl(inetSocket, SIOCSIFADDR, &ifr) < 0) {
396 NETNATIVE_LOGE("set ip address ioctl SIOCSIFADDR error: %{public}s", strerror(errno));
397 close(inetSocket);
398 return -1;
399 }
400 close(inetSocket);
401 return 0;
402 }
403
SetIffUp(const std::string & ifaceName)404 int InterfaceManager::SetIffUp(const std::string &ifaceName)
405 {
406 struct ifreq ifr;
407
408 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
409 NETNATIVE_LOGE("memset is false");
410 return -1;
411 }
412 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ifaceName.c_str(), strlen(ifaceName.c_str())) != EOK) {
413 NETNATIVE_LOGE("strncpy is false");
414 return -1;
415 }
416 uint32_t flagVal = (IFF_UP | IFF_MULTICAST);
417 ifr.ifr_flags = static_cast<short int>(flagVal);
418
419 int32_t inetSocket = socket(AF_INET, SOCK_DGRAM, 0);
420 if (ioctl(inetSocket, SIOCSIFFLAGS, &ifr) < 0) {
421 NETNATIVE_LOGE("set iface up ioctl SIOCSIFFLAGS error: %{public}s", strerror(errno));
422 close(inetSocket);
423 return -1;
424 }
425 close(inetSocket);
426 return 0;
427 }
428
AddStaticArp(const std::string & ipAddr,const std::string & macAddr,const std::string & ifName)429 int32_t InterfaceManager::AddStaticArp(const std::string &ipAddr, const std::string &macAddr,
430 const std::string &ifName)
431 {
432 arpreq req = {};
433 req.arp_flags = ATF_PERM;
434 int32_t res = AssembleArp(ipAddr, macAddr, ifName, req);
435 if (res != NETMANAGER_SUCCESS) {
436 NETNATIVE_LOGE("AssembleArp error");
437 return res;
438 }
439
440 int32_t inetSocket = socket(AF_INET, SOCK_DGRAM, 0);
441 if (ioctl(inetSocket, SIOCSARP, &req) < 0) {
442 NETNATIVE_LOGE("AddStaticArp ioctl SIOCSARP error: %{public}s", strerror(errno));
443 close(inetSocket);
444 return NETMANAGER_ERR_OPERATION_FAILED;
445 }
446 close(inetSocket);
447 return NETMANAGER_SUCCESS;
448 }
449
DelStaticArp(const std::string & ipAddr,const std::string & macAddr,const std::string & ifName)450 int32_t InterfaceManager::DelStaticArp(const std::string &ipAddr, const std::string &macAddr,
451 const std::string &ifName)
452 {
453 arpreq req = {};
454 req.arp_flags = ATF_PERM;
455 int32_t res = AssembleArp(ipAddr, macAddr, ifName, req);
456 if (res != NETMANAGER_SUCCESS) {
457 NETNATIVE_LOGE("AssembleArp error");
458 return res;
459 }
460
461 int32_t inetSocket = socket(AF_INET, SOCK_DGRAM, 0);
462 if (ioctl(inetSocket, SIOCDARP, &req) < 0) {
463 NETNATIVE_LOGE("DelStaticArp ioctl SIOCDARP error: %{public}s", strerror(errno));
464 close(inetSocket);
465 return NETMANAGER_ERR_OPERATION_FAILED;
466 }
467 close(inetSocket);
468 return NETMANAGER_SUCCESS;
469 }
470
AssembleArp(const std::string & ipAddr,const std::string & macAddr,const std::string & ifName,arpreq & req)471 int32_t InterfaceManager::AssembleArp(const std::string &ipAddr, const std::string &macAddr,
472 const std::string &ifName, arpreq &req)
473 {
474 if (!IsValidIPV4(ipAddr)) {
475 NETNATIVE_LOGE("ipAddr error");
476 return NETMANAGER_ERR_PARAMETER_ERROR;
477 }
478
479 if (!regex_match(macAddr, REGEX_CMD_MAC_ADDRESS)) {
480 NETNATIVE_LOGE("macAddr error");
481 return NETMANAGER_ERR_PARAMETER_ERROR;
482 }
483
484 sockaddr& ethAddrStruct = req.arp_ha;
485 ethAddrStruct.sa_family = ARPHRD_ETHER;
486 if (MacStringToArray(macAddr, ethAddrStruct) != 0) {
487 NETNATIVE_LOGE("macStringToArray error");
488 return NETMANAGER_ERR_OPERATION_FAILED;
489 }
490
491 in_addr ipv4Addr = {};
492 if (inet_aton(ipAddr.c_str(), &ipv4Addr) == 0) {
493 NETNATIVE_LOGE("addr inet_aton error");
494 return NETMANAGER_ERR_OPERATION_FAILED;
495 }
496 auto sin = reinterpret_cast<sockaddr_in *>(&req.arp_pa);
497 sin->sin_family = AF_INET;
498 sin->sin_addr = ipv4Addr;
499
500 if (strncpy_s(req.arp_dev, sizeof(req.arp_dev),
501 ifName.c_str(), ifName.size()) != 0) {
502 NETNATIVE_LOGE("strncpy_s is false");
503 return NETMANAGER_ERR_OPERATION_FAILED;
504 }
505
506 auto uFlags = static_cast<unsigned int>(req.arp_flags);
507 uFlags |= ATF_COM;
508 req.arp_flags = static_cast<int>(uFlags);
509
510 return NETMANAGER_SUCCESS;
511 }
512
AddStaticIpv6Addr(const std::string & ipv6Addr,const std::string & macAddr,const std::string & ifName)513 int32_t InterfaceManager::AddStaticIpv6Addr(const std::string &ipv6Addr, const std::string &macAddr,
514 const std::string &ifName)
515 {
516 NETNATIVE_LOGI("AddStaticIpv6Addr");
517 nmd::NetlinkMsg nlmsg(NLM_F_CREATE | NLM_F_REPLACE, nmd::NETLINK_MAX_LEN, getpid());
518 int32_t res = AssembleIPv6Neighbor(ipv6Addr, macAddr, ifName, nlmsg, RTM_NEWNEIGH);
519 if (res != NETMANAGER_SUCCESS) {
520 NETNATIVE_LOGE("AssembleIPv6Neighbor error");
521 return res;
522 }
523 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
524 }
525
DelStaticIpv6Addr(const std::string & ipv6Addr,const std::string & macAddr,const std::string & ifName)526 int32_t InterfaceManager::DelStaticIpv6Addr(const std::string &ipv6Addr, const std::string &macAddr,
527 const std::string &ifName)
528 {
529 NETNATIVE_LOGI("DelStaticIpv6Addr");
530 nmd::NetlinkMsg nlmsg(NLM_F_EXCL, nmd::NETLINK_MAX_LEN, getpid());
531 int32_t res = AssembleIPv6Neighbor(ipv6Addr, macAddr, ifName, nlmsg, RTM_DELNEIGH);
532 if (res != NETMANAGER_SUCCESS) {
533 NETNATIVE_LOGE("AssembleIPv6Neighbor error");
534 return res;
535 }
536 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
537 }
538
AssembleIPv6Neighbor(const std::string & ipv6Addr,const std::string & macAddr,const std::string & ifName,nmd::NetlinkMsg & nlmsg,uint16_t action)539 int32_t InterfaceManager::AssembleIPv6Neighbor(const std::string &ipv6Addr, const std::string &macAddr,
540 const std::string &ifName, nmd::NetlinkMsg &nlmsg, uint16_t action)
541 {
542 if (!IsValidIPV6(ipv6Addr)) {
543 NETNATIVE_LOGE("ipv6Addr error");
544 return NETMANAGER_ERR_PARAMETER_ERROR;
545 }
546
547 if (!regex_match(macAddr, REGEX_CMD_MAC_ADDRESS)) {
548 NETNATIVE_LOGE("macAddr error");
549 return NETMANAGER_ERR_PARAMETER_ERROR;
550 }
551
552 uint8_t macBin[MAC_ADDRESS_INT_LEN];
553 if (MacStringToBinary(macAddr, macBin) != 0) {
554 NETNATIVE_LOGE("MacStringToArray error");
555 return NETMANAGER_ERR_OPERATION_FAILED;
556 }
557
558 uint32_t index = if_nametoindex(ifName.c_str());
559 if (index == 0) {
560 NETNATIVE_LOGE("AssembleIPv6Neighbor, ifName error %{public}d", errno);
561 return NETMANAGER_ERR_OPERATION_FAILED;
562 }
563
564 struct in6_addr in6Addr;
565 if (inet_pton(AF_INET6, ipv6Addr.c_str(), reinterpret_cast<void *>(&in6Addr)) == -1) {
566 NETNATIVE_LOGE("addr inet_pton error %{public}d", errno);
567 return NETMANAGER_ERR_OPERATION_FAILED;
568 }
569
570 struct ndmsg ndm = {};
571 ndm.ndm_family = AF_INET6;
572 ndm.ndm_ifindex = static_cast<int32_t>(index);
573 ndm.ndm_pad1 = 0;
574 ndm.ndm_pad2 = 0;
575 if (action == RTM_NEWNEIGH) {
576 ndm.ndm_state = NUD_PERMANENT;
577 }
578 ndm.ndm_flags = 0;
579 ndm.ndm_type = RTN_UNICAST;
580
581 nlmsg.AddNeighbor(action, ndm);
582 nlmsg.AddAttr(NDA_DST, &in6Addr, sizeof(in6Addr));
583 nlmsg.AddAttr(NDA_LLADDR, macBin, sizeof(macBin));
584 return NETMANAGER_SUCCESS;
585 }
586
MacStringToArray(const std::string & macAddr,sockaddr & macSock)587 int32_t InterfaceManager::MacStringToArray(const std::string &macAddr, sockaddr &macSock)
588 {
589 char strMac[MAC_ADDRESS_INT_LEN] = {};
590 char strAddr[MAC_ADDRESS_STR_LEN] = {};
591 uint32_t v = 0;
592 if (memcpy_s(strAddr, MAC_ADDRESS_STR_LEN, macAddr.c_str(), macAddr.size()) != 0) {
593 NETNATIVE_LOGE("memcpy_s is false");
594 return NETMANAGER_ERR_OPERATION_FAILED;
595 }
596
597 for (int i = 0; i < MAC_ADDRESS_INT_LEN; i++) {
598 if (sscanf_s(strAddr+MAC_SSCANF_SPACE*i, "%2x", &v) <= 0) {
599 NETNATIVE_LOGE("sscanf_s is false");
600 return NETMANAGER_ERR_OPERATION_FAILED;
601 }
602 strMac[i] = (char)v;
603 }
604
605 if (memcpy_s(macSock.sa_data, sizeof(macSock.sa_data),
606 strMac, MAC_ADDRESS_INT_LEN) != 0) {
607 NETNATIVE_LOGE("memcpy_s is false");
608 return NETMANAGER_ERR_OPERATION_FAILED;
609 }
610
611 return NETMANAGER_SUCCESS;
612 }
613
MacStringToBinary(const std::string & macAddr,uint8_t (& macBin)[MAC_ADDRESS_INT_LEN])614 int32_t InterfaceManager::MacStringToBinary(const std::string &macAddr, uint8_t (&macBin)[MAC_ADDRESS_INT_LEN])
615 {
616 char strAddr[MAC_ADDRESS_STR_LEN] = {};
617 uint32_t v = 0;
618 if (memcpy_s(strAddr, MAC_ADDRESS_STR_LEN, macAddr.c_str(), macAddr.size()) != 0) {
619 NETNATIVE_LOGE("memcpy_s is false");
620 return NETMANAGER_ERR_OPERATION_FAILED;
621 }
622
623 for (int i = 0; i < MAC_ADDRESS_INT_LEN; i++) {
624 if (sscanf_s(strAddr+MAC_SSCANF_SPACE*i, "%2x", &v) <= 0) {
625 NETNATIVE_LOGE("sscanf_s is false");
626 return NETMANAGER_ERR_OPERATION_FAILED;
627 }
628 macBin[i] = static_cast<uint8_t>(v);
629 }
630
631 return NETMANAGER_SUCCESS;
632 }
633 } // namespace nmd
634 } // namespace OHOS
635