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 30namespace OHOS { 31namespace HDI { 32namespace Wlan { 33namespace Chip { 34namespace V1_0 { 35const char K_WLAN0_INTERFACE_NAME[] = "wlan0"; 36const int MAC_LEN = 6; 37const int MAC_POS_1 = 1; 38const int MAC_POS_2 = 2; 39const int MAC_POS_3 = 3; 40const int MAC_POS_4 = 4; 41const int MAC_POS_5 = 5; 42 43bool 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 61bool 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 75bool 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 102bool IfaceTool::SetWifiUpState(bool requestUp) 103{ 104 return SetUpState(K_WLAN0_INTERFACE_NAME, requestUp); 105} 106 107bool 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}