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 "iface_tool.h"
17 #include <cstring>
18 #include <net/if.h>
19 #include <net/if_arp.h>
20 #include <netinet/in.h>
21 #include <sys/ioctl.h>
22 #include <sys/socket.h>
23 #include <linux/if_bridge.h>
24 #include <linux/if.h>
25 #include <unistd.h>
26 #include <hdf_log.h>
27 #include "unique_fd.h"
28 #include "securec.h"
29
30 namespace OHOS {
31 namespace HDI {
32 namespace Wlan {
33 namespace Chip {
34 namespace V1_0 {
35 const char K_WLAN0_INTERFACE_NAME[] = "wlan0";
36 const int MAC_LEN = 6;
37 const int MAC_POS_1 = 1;
38 const int MAC_POS_2 = 2;
39 const int MAC_POS_3 = 3;
40 const int MAC_POS_4 = 4;
41 const int MAC_POS_5 = 5;
42
GetIfState(const char * ifName,int sock,struct ifreq * ifr)43 bool GetIfState(const char* ifName, int sock, struct ifreq* ifr)
44 {
45 if (memset_s(ifr, sizeof(*ifr), 0, sizeof(*ifr)) != EOK) {
46 HDF_LOGE("memset_s failed");
47 return false;
48 }
49 if (strlcpy(ifr->ifr_name, ifName, sizeof(ifr->ifr_name)) >=
50 sizeof(ifr->ifr_name)) {
51 HDF_LOGE("Interface name is too long: %{public}s", ifName);
52 return false;
53 }
54 if (TEMP_FAILURE_RETRY(ioctl(sock, SIOCGIFFLAGS, ifr)) != 0) {
55 HDF_LOGE("Could not read interface state for %{public}s, %{public}s", ifName, strerror(errno));
56 return false;
57 }
58 return true;
59 }
60
GetUpState(const char * ifName)61 bool IfaceTool::GetUpState(const char* ifName)
62 {
63 UniqueFd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
64 if (sock.Get() < 0) {
65 HDF_LOGE("Failed to open socket to set up/down state %{public}s", strerror(errno));
66 return false;
67 }
68 struct ifreq ifr;
69 if (!GetIfState(ifName, sock.Get(), &ifr)) {
70 return false;
71 }
72 return ifr.ifr_flags & IFF_UP;
73 }
74
SetUpState(const char * ifName,bool requestUp)75 bool IfaceTool::SetUpState(const char* ifName, bool requestUp)
76 {
77 UniqueFd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
78 if (sock.Get() < 0) {
79 HDF_LOGE("Failed to open socket to set up/down state %{public}s", strerror(errno));
80 return false;
81 }
82 struct ifreq ifr;
83 if (!GetIfState(ifName, sock.Get(), &ifr)) {
84 return false;
85 }
86 const bool currentlyUp = ifr.ifr_flags & IFF_UP;
87 if (currentlyUp == requestUp) {
88 return true;
89 }
90 if (requestUp) {
91 ifr.ifr_flags |= IFF_UP;
92 } else {
93 ifr.ifr_flags &= ~IFF_UP;
94 }
95 if (TEMP_FAILURE_RETRY(ioctl(sock.Get(), SIOCSIFFLAGS, &ifr)) != 0) {
96 HDF_LOGE("Could not set interface flags for %{public}s, %{public}s", ifName, strerror(errno));
97 return false;
98 }
99 return true;
100 }
101
SetWifiUpState(bool requestUp)102 bool IfaceTool::SetWifiUpState(bool requestUp)
103 {
104 return SetUpState(K_WLAN0_INTERFACE_NAME, requestUp);
105 }
106
SetMacAddress(const char * ifName,const char * mac)107 bool IfaceTool::SetMacAddress(const char* ifName, const char* mac)
108 {
109 struct ifreq ifr;
110
111 unsigned char macBin[MAC_LEN];
112 if (sscanf_s(mac, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
113 &macBin[0], &macBin[MAC_POS_1], &macBin[MAC_POS_2],
114 &macBin[MAC_POS_3], &macBin[MAC_POS_4], &macBin[MAC_POS_5]) == EOF) {
115 return false;
116 }
117 UniqueFd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
118 if (sock.Get() < 0) {
119 HDF_LOGE("Failed to open socket to set MAC address %{public}s", strerror(errno));
120 return false;
121 }
122 if (!GetIfState(ifName, sock.Get(), &ifr)) {
123 return false;
124 }
125 if (memset_s(&ifr.ifr_hwaddr, sizeof(ifr.ifr_hwaddr), 0, sizeof(ifr.ifr_hwaddr)) < 0) {
126 HDF_LOGE("Failed to memset");
127 }
128 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
129 if (memcpy_s(ifr.ifr_hwaddr.sa_data, MAC_LEN, macBin, MAC_LEN) < 0) {
130 HDF_LOGE("Failed to memcpy");
131 }
132 if (TEMP_FAILURE_RETRY(ioctl(sock.Get(), SIOCSIFHWADDR, &ifr)) != 0) {
133 HDF_LOGE("Failed to set interface MAC address for %{public}s, %{public}s",
134 ifName, strerror(errno));
135 return false;
136 }
137 return true;
138 }
139 }
140 }
141 }
142 }
143 }