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 #include "wifi_direct_ip_manager.h"
16 #include <arpa/inet.h>
17 #include "securec.h"
18 #include "conn_log.h"
19 #include "net_conn_client.h"
20 #include "softbus_error_code.h"
21 #include "softbus_socket.h"
22 #include "utils/wifi_direct_anonymous.h"
23 #include "utils/wifi_direct_utils.h"
24
25 namespace OHOS::SoftBus {
26 static constexpr int32_t U_L_BIT = 0x2;
27 static constexpr uint8_t INSERT_BYTE_0 = 0xff;
28 static constexpr uint8_t INSERT_BYTE_1 = 0xfe;
29 static constexpr int INSERT_POS = 3;
30 static constexpr int IPV6_PREFIX = 64;
31
32 static constexpr int32_t HML_IP_NET_END = 256;
33 static constexpr char HML_IP_PREFIX[] = "172.30.";
34 static constexpr char HML_IP_SOURCE_SUFFIX[] = ".2";
35 static constexpr char HML_IP_SINK_SUFFIX[] = ".1";
36
Init()37 void WifiDirectIpManager::Init()
38 {
39 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
40 }
41
ApplyIpv6(const std::string & mac)42 std::string WifiDirectIpManager::ApplyIpv6(const std::string &mac)
43 {
44 CONN_CHECK_AND_RETURN_RET_LOGE(!mac.empty(), "", CONN_WIFI_DIRECT, "mac is null");
45 auto array = WifiDirectUtils::MacStringToArray(mac);
46 if ((array[0] & U_L_BIT) == 0) {
47 array[0] |= U_L_BIT;
48 } else {
49 array[0] &= ~U_L_BIT;
50 }
51 array.insert(array.begin() + INSERT_POS, { INSERT_BYTE_0, INSERT_BYTE_1 });
52 char ip[IP_STR_MAX_LEN] {};
53 auto ret = sprintf_s(ip, sizeof(ip), "fe80::%02x%02x:%02x%02x:%02x%02x:%02x%02x%%chba0",
54 array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7]);
55 CONN_CHECK_AND_RETURN_RET_LOGE(ret > 0, "", CONN_WIFI_DIRECT, "format failed");
56
57 SoftBusSockAddrIn6 addrIn6 {};
58 if (Ipv6AddrToAddrIn(&addrIn6, ip, 0) != SOFTBUS_OK) {
59 CONN_LOGE(CONN_WIFI_DIRECT, "to addrIn6 failed");
60 return "";
61 }
62 char result[IP_STR_MAX_LEN] {};
63 if (Ipv6AddrInToAddr(&addrIn6, result, sizeof(result)) != SOFTBUS_OK) {
64 CONN_LOGE(CONN_WIFI_DIRECT, "to ip string failed");
65 return "";
66 }
67 CONN_LOGI(CONN_WIFI_DIRECT, "scopeId=%{public}u", addrIn6.sin6ScopeId);
68 std::string finalResult = result;
69 if (addrIn6.sin6ScopeId == 0) {
70 finalResult += "%chba0";
71 }
72 return finalResult;
73 }
74
ApplyIpv4(const std::vector<Ipv4Info> & localArray,const std::vector<Ipv4Info> & remoteArray,Ipv4Info & source,Ipv4Info & sink)75 int32_t WifiDirectIpManager::ApplyIpv4(
76 const std::vector<Ipv4Info> &localArray, const std::vector<Ipv4Info> &remoteArray, Ipv4Info &source, Ipv4Info &sink)
77 {
78 std::string subNet = ApplySubNet(localArray, remoteArray);
79 CONN_CHECK_AND_RETURN_RET_LOGE(
80 !subNet.empty(), SOFTBUS_CONN_APPLY_SUBNET_FAIL, CONN_WIFI_DIRECT, "apply subnet failed");
81
82 std::string sourceIp = subNet + HML_IP_SOURCE_SUFFIX;
83 std::string sinkIp = subNet + HML_IP_SINK_SUFFIX;
84 int32_t ret = source.FromIpString(sourceIp);
85 CONN_CHECK_AND_RETURN_RET_LOGW(
86 ret == SOFTBUS_OK, ret, CONN_WIFI_DIRECT, "source ip to ipv4 failed");
87 ret = sink.FromIpString(sinkIp);
88 CONN_CHECK_AND_RETURN_RET_LOGW(
89 ret == SOFTBUS_OK, ret, CONN_WIFI_DIRECT, "sink ip to ipv4 failed");
90
91 return SOFTBUS_OK;
92 }
93
ApplySubNet(const std::vector<Ipv4Info> & localArray,const std::vector<Ipv4Info> & remoteArray)94 std::string WifiDirectIpManager::ApplySubNet(
95 const std::vector<Ipv4Info> &localArray, const std::vector<Ipv4Info> &remoteArray)
96 {
97 std::array<bool, HML_IP_NET_END> bookMark {};
98 bookMark[0] = true;
99 std::string subNet;
100 for (const auto &ipv4 : localArray) {
101 bookMark[ipv4.GetSubNet()] = true;
102 }
103 for (const auto &ipv4 : remoteArray) {
104 bookMark[ipv4.GetSubNet()] = true;
105 }
106 for (uint32_t i = 0; i < bookMark.size(); i++) {
107 if (!bookMark[i]) {
108 subNet = HML_IP_PREFIX + std::to_string(i);
109 return subNet;
110 }
111 }
112 return "";
113 }
114
ConfigIpv6(const std::string & interface,const std::string & ip)115 int32_t WifiDirectIpManager::ConfigIpv6(const std::string &interface, const std::string &ip)
116 {
117 auto ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().AddInterfaceAddress(interface, ip, IPV6_PREFIX);
118 CONN_CHECK_AND_RETURN_RET_LOGE(
119 ret == 0, SOFTBUS_CONN_CONFIG_IPV6_CONFIG_IP_FAILED, CONN_WIFI_DIRECT, "add ip failed");
120 return SOFTBUS_OK;
121 }
122
ConfigIpv4(const std::string & interface,const Ipv4Info & local,const Ipv4Info & remote,const std::string & remoteMac)123 int32_t WifiDirectIpManager::ConfigIpv4(
124 const std::string &interface, const Ipv4Info &local, const Ipv4Info &remote, const std::string &remoteMac)
125 {
126 std::string localIpStr = local.ToIpString();
127 CONN_CHECK_AND_RETURN_RET_LOGE(
128 !localIpStr.empty(), SOFTBUS_CONN_CONVERT_LOCAL_IP_FAIL, CONN_WIFI_DIRECT, "convert local ip failed");
129 std::string remoteIpStr = remote.ToIpString();
130 CONN_CHECK_AND_RETURN_RET_LOGE(
131 !remoteIpStr.empty(), SOFTBUS_CONN_CONVERT_REMOTE_IP_FAIL, CONN_WIFI_DIRECT, "convert remote ip failed");
132 CONN_LOGI(CONN_WIFI_DIRECT, "localIp=%{public}s, remoteIp=%{public}s, remoteMac=%{public}s",
133 WifiDirectAnonymizeIp(localIpStr).c_str(), WifiDirectAnonymizeIp(remoteIpStr).c_str(),
134 WifiDirectAnonymizeMac(remoteMac).c_str());
135
136 int32_t ret = AddInterfaceAddress(interface, localIpStr, local.GetPrefixLength());
137 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_WIFI_DIRECT, "add ip failed");
138
139 ret = AddStaticArp(interface, remoteIpStr, remoteMac);
140 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_WIFI_DIRECT, "add static arp failed");
141 return SOFTBUS_OK;
142 }
143
ReleaseIpv4(const std::string & interface,const Ipv4Info & local,const Ipv4Info & remote,const std::string & remoteMac)144 void WifiDirectIpManager::ReleaseIpv4(
145 const std::string &interface, const Ipv4Info &local, const Ipv4Info &remote, const std::string &remoteMac)
146 {
147 std::string localIpStr = local.ToIpString();
148 CONN_CHECK_AND_RETURN_LOGE(!localIpStr.empty(), CONN_WIFI_DIRECT, "convert local ip failed");
149 std::string remoteIpStr = remote.ToIpString();
150 CONN_CHECK_AND_RETURN_LOGE(!remoteIpStr.empty(), CONN_WIFI_DIRECT, "convert remote ip failed");
151
152 CONN_LOGI(CONN_WIFI_DIRECT, "localIp=%{public}s, remoteIp=%{public}s, remoteMac=%{public}s",
153 WifiDirectAnonymizeIp(localIpStr).c_str(), WifiDirectAnonymizeIp(remoteIpStr).c_str(),
154 WifiDirectAnonymizeMac(remoteMac).c_str());
155
156 if (DeleteInterfaceAddress(interface, localIpStr, local.GetPrefixLength()) != SOFTBUS_OK) {
157 CONN_LOGE(CONN_WIFI_DIRECT, "delete ip failed. ip=%{public}s", WifiDirectAnonymizeIp(localIpStr).c_str());
158 }
159
160 if (DeleteStaticArp(interface, remoteIpStr, remoteMac) != SOFTBUS_OK) {
161 CONN_LOGE(CONN_WIFI_DIRECT, "delete arp failed. remoteIp=%{public}s, remoteMac=%{public}s",
162 WifiDirectAnonymizeIp(remoteIpStr).c_str(), WifiDirectAnonymizeMac(remoteMac).c_str());
163 }
164 }
165
ClearAllIpv4()166 void WifiDirectIpManager::ClearAllIpv4()
167 {
168 auto localIpv4Array = WifiDirectUtils::GetLocalIpv4Infos();
169 for (const auto &ipv4 : localIpv4Array) {
170 std::string ipStr = ipv4.ToIpString();
171 if (DeleteInterfaceAddress("chba0", ipStr, ipv4.GetPrefixLength()) != SOFTBUS_OK) {
172 CONN_LOGE(CONN_WIFI_DIRECT, "delete ip failed. ip=%{public}s", WifiDirectAnonymizeIp(ipStr).c_str());
173 }
174 }
175 }
176
AddInterfaceAddress(const std::string & interface,const std::string & ipString,int32_t prefixLength)177 int32_t WifiDirectIpManager::AddInterfaceAddress(
178 const std::string &interface, const std::string &ipString, int32_t prefixLength)
179 {
180 std::string gateWay;
181 int32_t ret = GetNetworkGateWay(ipString, gateWay);
182 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_WIFI_DIRECT, "get gate way failed");
183 std::string destination;
184 ret = GetNetworkDestination(ipString, destination);
185 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_WIFI_DIRECT, "get destination failed");
186
187 ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().AddInterfaceAddress(interface, ipString, prefixLength);
188 CONN_CHECK_AND_RETURN_RET_LOGE(
189 ret == NetManagerStandard::NETMANAGER_SUCCESS, ret, CONN_WIFI_DIRECT, "add ip failed ret=%{public}d", ret);
190 ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().AddNetworkRoute(
191 LOCAL_NETWORK_ID, interface, destination, gateWay);
192 CONN_CHECK_AND_RETURN_RET_LOGE(
193 ret == NetManagerStandard::NETMANAGER_SUCCESS, ret, CONN_WIFI_DIRECT, "add route failed ret=%{public}d", ret);
194 return SOFTBUS_OK;
195 }
196
DeleteInterfaceAddress(const std::string & interface,const std::string & ipString,int32_t prefixLength)197 int32_t WifiDirectIpManager::DeleteInterfaceAddress(
198 const std::string &interface, const std::string &ipString, int32_t prefixLength)
199 {
200 std::string gateWay;
201 int32_t ret = GetNetworkGateWay(ipString, gateWay);
202 CONN_CHECK_AND_RETURN_RET_LOGE(ret == 0, ret, CONN_WIFI_DIRECT, "get gate way failed");
203 std::string destination;
204 ret = GetNetworkDestination(ipString, destination);
205 CONN_CHECK_AND_RETURN_RET_LOGE(ret == 0, ret, CONN_WIFI_DIRECT, "get destination failed");
206 ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().RemoveNetworkRoute(
207 LOCAL_NETWORK_ID, interface, destination, gateWay);
208 if (ret != NetManagerStandard::NETMANAGER_SUCCESS) {
209 CONN_LOGE(CONN_WIFI_DIRECT, "remove route failed ret=%{public}d", ret);
210 }
211 ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().DelInterfaceAddress(interface, ipString, prefixLength);
212 if (ret != NetManagerStandard::NETMANAGER_SUCCESS) {
213 CONN_LOGE(CONN_WIFI_DIRECT, "delete ip failed ret=%{public}d", ret);
214 }
215 return SOFTBUS_OK;
216 }
217
AddStaticArp(const std::string & interface,const std::string & ipString,const std::string & macString)218 int32_t WifiDirectIpManager::AddStaticArp(
219 const std::string &interface, const std::string &ipString, const std::string &macString)
220 {
221 return OHOS::NetManagerStandard::NetConnClient::GetInstance().AddStaticArp(ipString, macString, interface);
222 }
223
DeleteStaticArp(const std::string & interface,const std::string & ipString,const std::string & macString)224 int32_t WifiDirectIpManager::DeleteStaticArp(
225 const std::string &interface, const std::string &ipString, const std::string &macString)
226 {
227 return OHOS::NetManagerStandard::NetConnClient::GetInstance().DelStaticArp(ipString, macString, interface);
228 }
229
GetNetworkGateWay(const std::string & ipString,std::string & gateWay)230 int32_t WifiDirectIpManager::GetNetworkGateWay(const std::string &ipString, std::string &gateWay)
231 {
232 auto pos = ipString.find_last_of('.');
233 CONN_CHECK_AND_RETURN_RET_LOGE(
234 pos != std::string::npos, SOFTBUS_CONN_FIND_DOT_FAIL, CONN_WIFI_DIRECT, "can't find dot");
235 gateWay = ipString.substr(0, pos) + ".1";
236 CONN_LOGI(CONN_WIFI_DIRECT, "gateWay=%{public}s", WifiDirectAnonymizeIp(gateWay).c_str());
237 return SOFTBUS_OK;
238 }
239
GetNetworkDestination(const std::string & ipString,std::string & destination)240 int32_t WifiDirectIpManager::GetNetworkDestination(const std::string &ipString, std::string &destination)
241 {
242 auto pos = ipString.find_last_of('.');
243 CONN_CHECK_AND_RETURN_RET_LOGE(
244 pos != std::string::npos, SOFTBUS_CONN_FIND_DOT_FAIL, CONN_WIFI_DIRECT, "can't find dot");
245 destination = ipString.substr(0, pos) + ".0/24";
246 CONN_LOGI(CONN_WIFI_DIRECT, "destination=%{public}s", WifiDirectAnonymizeIp(destination).c_str());
247 return SOFTBUS_OK;
248 }
249 } // namespace OHOS::SoftBus
250