1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "iface_tool.h" 17094332d3Sopenharmony_ci#include <cstring> 18094332d3Sopenharmony_ci#include <net/if.h> 19094332d3Sopenharmony_ci#include <net/if_arp.h> 20094332d3Sopenharmony_ci#include <netinet/in.h> 21094332d3Sopenharmony_ci#include <sys/ioctl.h> 22094332d3Sopenharmony_ci#include <sys/socket.h> 23094332d3Sopenharmony_ci#include <linux/if_bridge.h> 24094332d3Sopenharmony_ci#include <linux/if.h> 25094332d3Sopenharmony_ci#include <unistd.h> 26094332d3Sopenharmony_ci#include <hdf_log.h> 27094332d3Sopenharmony_ci#include "unique_fd.h" 28094332d3Sopenharmony_ci#include "securec.h" 29094332d3Sopenharmony_ci 30094332d3Sopenharmony_cinamespace OHOS { 31094332d3Sopenharmony_cinamespace HDI { 32094332d3Sopenharmony_cinamespace Wlan { 33094332d3Sopenharmony_cinamespace Chip { 34094332d3Sopenharmony_cinamespace V1_0 { 35094332d3Sopenharmony_ciconst char K_WLAN0_INTERFACE_NAME[] = "wlan0"; 36094332d3Sopenharmony_ciconst int MAC_LEN = 6; 37094332d3Sopenharmony_ciconst int MAC_POS_1 = 1; 38094332d3Sopenharmony_ciconst int MAC_POS_2 = 2; 39094332d3Sopenharmony_ciconst int MAC_POS_3 = 3; 40094332d3Sopenharmony_ciconst int MAC_POS_4 = 4; 41094332d3Sopenharmony_ciconst int MAC_POS_5 = 5; 42094332d3Sopenharmony_ci 43094332d3Sopenharmony_cibool GetIfState(const char* ifName, int sock, struct ifreq* ifr) 44094332d3Sopenharmony_ci{ 45094332d3Sopenharmony_ci if (memset_s(ifr, sizeof(*ifr), 0, sizeof(*ifr)) != EOK) { 46094332d3Sopenharmony_ci HDF_LOGE("memset_s failed"); 47094332d3Sopenharmony_ci return false; 48094332d3Sopenharmony_ci } 49094332d3Sopenharmony_ci if (strlcpy(ifr->ifr_name, ifName, sizeof(ifr->ifr_name)) >= 50094332d3Sopenharmony_ci sizeof(ifr->ifr_name)) { 51094332d3Sopenharmony_ci HDF_LOGE("Interface name is too long: %{public}s", ifName); 52094332d3Sopenharmony_ci return false; 53094332d3Sopenharmony_ci } 54094332d3Sopenharmony_ci if (TEMP_FAILURE_RETRY(ioctl(sock, SIOCGIFFLAGS, ifr)) != 0) { 55094332d3Sopenharmony_ci HDF_LOGE("Could not read interface state for %{public}s, %{public}s", ifName, strerror(errno)); 56094332d3Sopenharmony_ci return false; 57094332d3Sopenharmony_ci } 58094332d3Sopenharmony_ci return true; 59094332d3Sopenharmony_ci} 60094332d3Sopenharmony_ci 61094332d3Sopenharmony_cibool IfaceTool::GetUpState(const char* ifName) 62094332d3Sopenharmony_ci{ 63094332d3Sopenharmony_ci UniqueFd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)); 64094332d3Sopenharmony_ci if (sock.Get() < 0) { 65094332d3Sopenharmony_ci HDF_LOGE("Failed to open socket to set up/down state %{public}s", strerror(errno)); 66094332d3Sopenharmony_ci return false; 67094332d3Sopenharmony_ci } 68094332d3Sopenharmony_ci struct ifreq ifr; 69094332d3Sopenharmony_ci if (!GetIfState(ifName, sock.Get(), &ifr)) { 70094332d3Sopenharmony_ci return false; 71094332d3Sopenharmony_ci } 72094332d3Sopenharmony_ci return ifr.ifr_flags & IFF_UP; 73094332d3Sopenharmony_ci} 74094332d3Sopenharmony_ci 75094332d3Sopenharmony_cibool IfaceTool::SetUpState(const char* ifName, bool requestUp) 76094332d3Sopenharmony_ci{ 77094332d3Sopenharmony_ci UniqueFd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)); 78094332d3Sopenharmony_ci if (sock.Get() < 0) { 79094332d3Sopenharmony_ci HDF_LOGE("Failed to open socket to set up/down state %{public}s", strerror(errno)); 80094332d3Sopenharmony_ci return false; 81094332d3Sopenharmony_ci } 82094332d3Sopenharmony_ci struct ifreq ifr; 83094332d3Sopenharmony_ci if (!GetIfState(ifName, sock.Get(), &ifr)) { 84094332d3Sopenharmony_ci return false; 85094332d3Sopenharmony_ci } 86094332d3Sopenharmony_ci const bool currentlyUp = ifr.ifr_flags & IFF_UP; 87094332d3Sopenharmony_ci if (currentlyUp == requestUp) { 88094332d3Sopenharmony_ci return true; 89094332d3Sopenharmony_ci } 90094332d3Sopenharmony_ci if (requestUp) { 91094332d3Sopenharmony_ci ifr.ifr_flags |= IFF_UP; 92094332d3Sopenharmony_ci } else { 93094332d3Sopenharmony_ci ifr.ifr_flags &= ~IFF_UP; 94094332d3Sopenharmony_ci } 95094332d3Sopenharmony_ci if (TEMP_FAILURE_RETRY(ioctl(sock.Get(), SIOCSIFFLAGS, &ifr)) != 0) { 96094332d3Sopenharmony_ci HDF_LOGE("Could not set interface flags for %{public}s, %{public}s", ifName, strerror(errno)); 97094332d3Sopenharmony_ci return false; 98094332d3Sopenharmony_ci } 99094332d3Sopenharmony_ci return true; 100094332d3Sopenharmony_ci} 101094332d3Sopenharmony_ci 102094332d3Sopenharmony_cibool IfaceTool::SetWifiUpState(bool requestUp) 103094332d3Sopenharmony_ci{ 104094332d3Sopenharmony_ci return SetUpState(K_WLAN0_INTERFACE_NAME, requestUp); 105094332d3Sopenharmony_ci} 106094332d3Sopenharmony_ci 107094332d3Sopenharmony_cibool IfaceTool::SetMacAddress(const char* ifName, const char* mac) 108094332d3Sopenharmony_ci{ 109094332d3Sopenharmony_ci struct ifreq ifr; 110094332d3Sopenharmony_ci 111094332d3Sopenharmony_ci unsigned char macBin[MAC_LEN]; 112094332d3Sopenharmony_ci if (sscanf_s(mac, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", 113094332d3Sopenharmony_ci &macBin[0], &macBin[MAC_POS_1], &macBin[MAC_POS_2], 114094332d3Sopenharmony_ci &macBin[MAC_POS_3], &macBin[MAC_POS_4], &macBin[MAC_POS_5]) == EOF) { 115094332d3Sopenharmony_ci return false; 116094332d3Sopenharmony_ci } 117094332d3Sopenharmony_ci UniqueFd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)); 118094332d3Sopenharmony_ci if (sock.Get() < 0) { 119094332d3Sopenharmony_ci HDF_LOGE("Failed to open socket to set MAC address %{public}s", strerror(errno)); 120094332d3Sopenharmony_ci return false; 121094332d3Sopenharmony_ci } 122094332d3Sopenharmony_ci if (!GetIfState(ifName, sock.Get(), &ifr)) { 123094332d3Sopenharmony_ci return false; 124094332d3Sopenharmony_ci } 125094332d3Sopenharmony_ci if (memset_s(&ifr.ifr_hwaddr, sizeof(ifr.ifr_hwaddr), 0, sizeof(ifr.ifr_hwaddr)) < 0) { 126094332d3Sopenharmony_ci HDF_LOGE("Failed to memset"); 127094332d3Sopenharmony_ci } 128094332d3Sopenharmony_ci ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; 129094332d3Sopenharmony_ci if (memcpy_s(ifr.ifr_hwaddr.sa_data, MAC_LEN, macBin, MAC_LEN) < 0) { 130094332d3Sopenharmony_ci HDF_LOGE("Failed to memcpy"); 131094332d3Sopenharmony_ci } 132094332d3Sopenharmony_ci if (TEMP_FAILURE_RETRY(ioctl(sock.Get(), SIOCSIFHWADDR, &ifr)) != 0) { 133094332d3Sopenharmony_ci HDF_LOGE("Failed to set interface MAC address for %{public}s, %{public}s", 134094332d3Sopenharmony_ci ifName, strerror(errno)); 135094332d3Sopenharmony_ci return false; 136094332d3Sopenharmony_ci } 137094332d3Sopenharmony_ci return true; 138094332d3Sopenharmony_ci} 139094332d3Sopenharmony_ci} 140094332d3Sopenharmony_ci} 141094332d3Sopenharmony_ci} 142094332d3Sopenharmony_ci} 143094332d3Sopenharmony_ci}