1 /*
2 * Copyright (C) 2022 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 "pan_network.h"
16
17 #include <arpa/inet.h>
18 #include <net/if.h>
19 #include <netinet/in.h>
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22 #include <linux/if_tun.h>
23
24 #include "interface_adapter_manager.h"
25 #include "interface_adapter_classic.h"
26 #include "pan_service.h"
27
28 namespace OHOS {
29 namespace bluetooth {
PanNetwork()30 PanNetwork::PanNetwork()
31 {
32 pollThreadId_ = static_cast<pthread_t>(-1);
33 fd_ = -1;
34 keepPolling_ = false;
35 }
36
~PanNetwork()37 PanNetwork::~PanNetwork()
38 {
39 Close();
40 }
41
Open()42 int PanNetwork::Open()
43 {
44 pthread_t threadId;
45 int inetSocket = -1;
46 int ret = PAN_FAILURE;
47
48 if (fd_ < 0) {
49 LOG_DEBUG("[Pan Network]%{public}s():fd is null,creat fd", __FUNCTION__);
50 fd_ = open(PAN_DEVICE_PATH, O_RDWR);
51 if (fd_ < 0) {
52 LOG_ERROR("[Pan Network]%{public}s():open %{public}s failed, fd = %{public}d error = %{public}d",
53 __FUNCTION__, PAN_DEVICE_PATH, fd_, errno);
54 return PAN_FAILURE;
55 } else {
56 LOG_DEBUG("[Pan Network]%{public}s(): fd = %{public}d", __FUNCTION__, fd_);
57 }
58 ret = TunSetIff();
59 if (ret == PAN_SUCCESS) {
60 inetSocket = socket(AF_INET, SOCK_DGRAM, 0);
61 }
62
63 if ((ret == PAN_SUCCESS) && (inetSocket >= 0)) {
64 ret = SetMacAddress(inetSocket);
65 }
66
67 if ((ret == PAN_SUCCESS) && (inetSocket >= 0)) {
68 ret = SetIffUp(inetSocket);
69 }
70
71 if ((ret == PAN_SUCCESS) && (inetSocket >= 0)) {
72 ret = SetIpAddress(inetSocket);
73 }
74
75 if ((ret == PAN_SUCCESS) && (inetSocket >= 0)) {
76 ret = SetIffUp(inetSocket);
77 }
78 if (inetSocket >= 0) {
79 close(inetSocket);
80 }
81
82 if (ret == PAN_SUCCESS) {
83 LOG_DEBUG("[Pan Network]%{public}s():create thread", __FUNCTION__);
84 threadId = CreateThread(PollEventThread, this);
85 if (threadId == static_cast<pthread_t>(-1)) {
86 LOG_DEBUG("[Pan Network]%{public}s():create thread failed", __FUNCTION__);
87 ret = PAN_FAILURE;
88 } else {
89 pollThreadId_ = threadId;
90 }
91 }
92 }
93 return ret;
94 }
95
TunSetIff()96 int PanNetwork::TunSetIff()
97 {
98 LOG_DEBUG("[Pan Network]%{public}s():", __FUNCTION__);
99 struct ifreq ifr;
100 int err;
101
102 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
103 LOG_ERROR("[Pan Network] %{public}s:memset error.", __func__);
104 return PAN_FAILURE;
105 }
106 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
107 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, PAN_NETWORK_NAME, strlen(PAN_NETWORK_NAME)) != EOK) {
108 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
109 }
110 err = ioctl(fd_, TUNSETIFF, &ifr);
111 if (err < 0) {
112 LOG_ERROR("[Pan Network]%{public}s(): tun set iff error:%{public}d", __FUNCTION__, err);
113 return PAN_FAILURE;
114 }
115 return PAN_SUCCESS;
116 }
117
SetMacAddress(int inetSocket)118 int PanNetwork::SetMacAddress(int inetSocket)
119 {
120 LOG_DEBUG("[Pan Network]%{public}s():", __FUNCTION__);
121 struct ifreq ifr;
122 int err;
123
124 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
125 LOG_ERROR("[Pan Network] %{public}s:memset error.", __func__);
126 return PAN_FAILURE;
127 }
128 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, PAN_NETWORK_NAME, strlen(PAN_NETWORK_NAME)) != EOK) {
129 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
130 return PAN_FAILURE;
131 }
132 err = ioctl(inetSocket, SIOCGIFHWADDR, &ifr);
133 if (err < 0) {
134 LOG_ERROR("[Pan Network]%{public}s(): get network hardware error:%{public}d", __FUNCTION__, err);
135 return PAN_FAILURE;
136 }
137 BtAddr btAddr;
138 RawAddress(PanService::GetLocalAddress()).ConvertToUint8(btAddr.addr);
139 for (int i = 0; i < BT_ADDRESS_LENGTH; i++) {
140 ifr.ifr_hwaddr.sa_data[i] = btAddr.addr[BT_ADDRESS_LENGTH - i -1];
141 }
142 if (ifr.ifr_hwaddr.sa_data[0] & 0x01) {
143 LOG_DEBUG("[Pan Network]%{public}s():use unicast MAC address", __FUNCTION__);
144 ifr.ifr_hwaddr.sa_data[0] &= ~0x01;
145 }
146 err = ioctl(inetSocket, SIOCSIFHWADDR, &ifr);
147 if (err < 0) {
148 LOG_ERROR("[Pan Network]%{public}s(): set network hardware error:%{public}d", __FUNCTION__, err);
149 return PAN_FAILURE;
150 }
151 return PAN_SUCCESS;
152 }
153
SetIpAddress(int inetSocket)154 int PanNetwork::SetIpAddress(int inetSocket)
155 {
156 LOG_DEBUG("[Pan Network]%{public}s():", __FUNCTION__);
157 struct ifreq ifr;
158 struct in_addr ipv4Addr = {INADDR_ANY};
159 struct in_addr mask4Addr = {INADDR_ANY};
160 size_t mask = 0xffffffff;
161
162 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
163 LOG_ERROR("[Pan Network] %{public}s:memset error.", __func__);
164 return PAN_FAILURE;
165 }
166 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, PAN_NETWORK_NAME, strlen(PAN_NETWORK_NAME)) != EOK) {
167 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
168 return PAN_FAILURE;
169 }
170
171 if (inet_aton(PAN_NETWORK_IPV4_ADDRESS, &ipv4Addr) == 0) {
172 LOG_ERROR("[Pan Network] %{public}s:inet_aton error.", __func__);
173 return PAN_FAILURE;
174 }
175 mask = mask >> (MAX_MASK_LENGTH - PAN_NETWORK_IPV4_PREFIX_LENGTH);
176 mask4Addr.s_addr = mask;
177
178 struct sockaddr_in *sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr);
179 sin->sin_family = AF_INET;
180 sin->sin_port = 0;
181 sin->sin_addr = ipv4Addr;
182 if (ioctl(inetSocket, SIOCSIFADDR, &ifr) < 0) {
183 LOG_ERROR("[Pan Network]%{public}s(): ioctl set ip address failed", __FUNCTION__);
184 return PAN_FAILURE;
185 }
186 sin->sin_addr = mask4Addr;
187 if (ioctl(inetSocket, SIOCSIFNETMASK, &ifr) < 0) {
188 LOG_ERROR("[Pan Network]%{public}s(): ioctl set mask address failed", __FUNCTION__);
189 return PAN_FAILURE;
190 }
191
192 if (ioctl(inetSocket, SIOCGIFADDR, &ifr) < 0) {
193 LOG_ERROR("[Pan Network]%{public}s(): ioctl get ip address failed", __FUNCTION__);
194 return PAN_SUCCESS;
195 }
196 ipv4Addr.s_addr = (reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr))->sin_addr.s_addr;
197 std::string ipv4AddrStr = std::string(inet_ntoa(ipv4Addr));
198 LOG_DEBUG("[Pan Network]%{public}s(): ip address is ipv4AddrStr=%{public}s",
199 __FUNCTION__, ipv4AddrStr.c_str());
200 return PAN_SUCCESS;
201 }
202
SetIffUp(int inetSocket)203 int PanNetwork::SetIffUp(int inetSocket)
204 {
205 LOG_DEBUG("[Pan Network]%{public}s():", __FUNCTION__);
206 struct ifreq ifr;
207 int err;
208
209 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
210 LOG_ERROR("[Pan Network] %{public}s:memset error.", __func__);
211 return PAN_FAILURE;
212 }
213 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, PAN_NETWORK_NAME, strlen(PAN_NETWORK_NAME)) != EOK) {
214 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
215 return PAN_FAILURE;
216 }
217 ifr.ifr_flags |= IFF_UP;
218 ifr.ifr_flags |= IFF_MULTICAST;
219
220 err = ioctl(inetSocket, SIOCSIFFLAGS, &ifr);
221 if (err < 0) {
222 LOG_ERROR("[Pan Network]%{public}s(): up network error:%{public}d", __FUNCTION__, err);
223 return PAN_FAILURE;
224 }
225 return PAN_SUCCESS;
226 }
227
SetIffdown(int inetSocket)228 int PanNetwork::SetIffdown(int inetSocket)
229 {
230 LOG_DEBUG("[Pan Network]%{public}s():", __FUNCTION__);
231 struct ifreq ifr;
232 int err;
233
234 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
235 LOG_ERROR("[Pan Network] %{public}s:memset error.", __func__);
236 return PAN_FAILURE;
237 }
238 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, PAN_NETWORK_NAME, strlen(PAN_NETWORK_NAME)) != EOK) {
239 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
240 return PAN_FAILURE;
241 }
242 ifr.ifr_flags &= ~IFF_UP;
243
244 err = ioctl(inetSocket, SIOCSIFFLAGS, &ifr);
245 if (err < 0) {
246 LOG_ERROR("[Pan Network]%{public}s(): down network error:%{public}d", __FUNCTION__, err);
247 return PAN_FAILURE;
248 }
249 return PAN_SUCCESS;
250 }
251
Close()252 int PanNetwork::Close()
253 {
254 LOG_DEBUG("[Pan Network]%{public}s():", __FUNCTION__);
255 int ret = PAN_FAILURE;
256 int inetSocket;
257
258 if (isRemoteDeviceBusy_) {
259 isRemoteDeviceBusy_ = false;
260 std::lock_guard<std::mutex> lock(mutexBusyChanged_);
261 cvWaitBusyChanged_.notify_all();
262 }
263
264 if (keepPolling_) {
265 keepPolling_ = false;
266 pthread_join(pollThreadId_, nullptr);
267 }
268 pollThreadId_ = static_cast<pthread_t>(-1);
269
270 if (fd_ >= 0) {
271 LOG_DEBUG("[Pan Network]%{public}s(): Closing fd=%{public}d", __FUNCTION__, fd_);
272 inetSocket = socket(AF_INET, SOCK_DGRAM, 0);
273 if (inetSocket < 0) {
274 LOG_ERROR("[Pan Network]%{public}s(): get AF_INET socket inetSocket:%{public}d", __FUNCTION__, inetSocket);
275 ret = PAN_FAILURE;
276 } else {
277 SetIffdown(inetSocket);
278 close(inetSocket);
279 }
280
281 close(fd_);
282 fd_ = -1;
283 }
284
285 return PAN_SUCCESS;
286 }
287
ReceiveRemoteBusy(bool isBusy)288 int PanNetwork::ReceiveRemoteBusy(bool isBusy)
289 {
290 isRemoteDeviceBusy_ = isBusy;
291 if (!isBusy) {
292 std::lock_guard<std::mutex> lock(mutexBusyChanged_);
293 cvWaitBusyChanged_.notify_all();
294 }
295 return PAN_SUCCESS;
296 }
297
WriteData(EthernetHeader head,uint8_t * data,int len)298 int PanNetwork::WriteData(EthernetHeader head, uint8_t *data, int len)
299 {
300 LOG_DEBUG("[Pan Network]%{public}s(): len=%{public}d", __FUNCTION__, len);
301 if (fd_ < 0) {
302 LOG_ERROR("[Pan Network]%{public}s(): fd is not open", __FUNCTION__);
303 return PAN_FAILURE;
304 }
305 ssize_t ret;
306 uint8_t packet[PAN_MAX_NETWORK_PACKET_SIZE] = {0};
307 head.protocol = htons(head.protocol);
308 if (memcpy_s(packet, PAN_MAX_NETWORK_PACKET_SIZE, &head, sizeof(head)) != EOK) {
309 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
310 return PAN_FAILURE;
311 }
312 if (len > (PAN_MAX_NETWORK_PACKET_SIZE - sizeof(head))) {
313 LOG_ERROR("[Pan Network]%{public}s(): data length is exceeded limit", __FUNCTION__);
314 return PAN_FAILURE;
315 }
316 if (memcpy_s(packet + sizeof(head), PAN_MAX_NETWORK_PACKET_SIZE - sizeof(head), data, len) != EOK) {
317 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
318 return PAN_FAILURE;
319 }
320 do {
321 } while ((ret = write(fd_, packet, len + sizeof(head))) == -1 && errno == EINTR);
322 if (ret < 0) {
323 int rtn = errno;
324 LOG_ERROR("[Pan Network]%{public}s(): Cannot write to :%{public}s", __FUNCTION__, strerror(errno));
325 return rtn;
326 }
327 return PAN_SUCCESS;
328 }
329
CreateThread(void * (* startRoutine)(void *),void * arg)330 pthread_t PanNetwork::CreateThread(void* (*startRoutine)(void*), void* arg)
331 {
332 LOG_DEBUG("[Pan Network]%{public}s():create_thread: entered", __FUNCTION__);
333 pthread_attr_t threadAttr;
334
335 pthread_attr_init(&threadAttr);
336 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE);
337 pthread_t threadId = static_cast<pthread_t>(-1);
338 if (pthread_create(&threadId, &threadAttr, startRoutine, arg) != 0) {
339 LOG_ERROR("[Pan Network]%{public}s():pthread_create : %{public}s", __FUNCTION__, strerror(errno));
340 return static_cast<pthread_t>(-1);
341 }
342 LOG_DEBUG("[Pan Network]%{public}s():%{public}lu: threadcreated successfully", __FUNCTION__, threadId);
343 return threadId;
344 }
345
PollEventThread(void * arg)346 void* PanNetwork::PollEventThread(void* arg)
347 {
348 PanNetwork *network = (PanNetwork*)arg;
349 if (network != nullptr) {
350 network->PollEventThread_();
351 } else {
352 LOG_ERROR("[Pan Network]%{public}s():Thread creat fail, is null", __FUNCTION__);
353 }
354 return nullptr;
355 }
356
PollEventThread_()357 void PanNetwork::PollEventThread_()
358 {
359 HILOGI("[Pan Network] Thread: %{public}d, fd: %{public}d execute", static_cast<int>(pollThreadId_), fd_);
360 struct pollfd pfds[1];
361 keepPolling_ = true;
362 pfds[0].fd = fd_;
363 pfds[0].events = POLLIN;
364
365 SetPanNetworkNonBlocking(fd_);
366
367 while (keepPolling_) {
368 int ret;
369 std::unique_lock<std::mutex> lock(mutexBusyChanged_);
370 if (isRemoteDeviceBusy_) {
371 cvWaitBusyChanged_.wait(lock, [this] { return !isRemoteDeviceBusy_; });
372 }
373 do {
374 } while ((ret = poll(pfds, 1, POLL_TIMEOUT)) == -1 && errno == EINTR);
375 if (ret < 0) {
376 LOG_ERROR("[Pan Network]%{public}s(): Cannot poll for fds: %{public}s", __FUNCTION__,
377 strerror(errno));
378 break;
379 }
380 if (pfds[0].revents & POLLIN) {
381 LOG_DEBUG("[Pan Network]%{public}s(): POLLIN", __FUNCTION__);
382 ReadPanNetworkEvent();
383 }
384 }
385 LOG_DEBUG("[Pan Network]%{public}s(): exit", __FUNCTION__);
386 keepPolling_ = false;
387 pollThreadId_ = static_cast<pthread_t>(-1);
388 }
389
SetPanNetworkNonBlocking(int fd)390 void PanNetwork::SetPanNetworkNonBlocking(int fd)
391 {
392 int opts = fcntl(fd, F_GETFL);
393 if (opts < 0) {
394 LOG_DEBUG("[Pan Network]%{public}s(): Getting flags failed (%{public}s)", __FUNCTION__,
395 strerror(errno));
396 return;
397 }
398
399 opts |= O_NONBLOCK;
400
401 if (fcntl(fd, F_SETFL, opts) < 0) {
402 LOG_DEBUG("[Pan Network]%{public}s(): Setting non-blocking flag failed (%{public}s)", __FUNCTION__,
403 strerror(errno));
404 }
405 }
406
ReadPanNetworkEvent()407 int PanNetwork::ReadPanNetworkEvent()
408 {
409 uint8_t packet[PAN_MAX_NETWORK_PACKET_SIZE] = {0};
410 ssize_t packetSize;
411
412 do {
413 } while ((packetSize = read(fd_, &packet, sizeof(packet))) == -1 && errno == EINTR);
414
415 if (packetSize <= 0) {
416 LOG_ERROR("[Pan Network]%{public}s():read err", __FUNCTION__);
417 return PAN_FAILURE;
418 }
419 if (packetSize > PAN_MAX_NETWORK_PACKET_SIZE) {
420 LOG_ERROR("[Pan Network]%{public}s():packet size is too large packetSize=%{public}zu",
421 __FUNCTION__, packetSize);
422 return PAN_FAILURE;
423 }
424 if (packetSize > sizeof(EthernetHeader)) {
425 EthernetHeader head;
426 if (memcpy_s(&head, sizeof(head), &packet, sizeof(head)) != EOK) {
427 LOG_ERROR("[Pan Network]%{public}s(): memcpy error", __FUNCTION__);
428 return PAN_FAILURE;
429 }
430 uint16_t protocol = ntohs(head.protocol);
431 if ((protocol != ETH_P_IP) && (protocol != ETH_P_ARP) && (protocol != ETH_P_IPV6)) {
432 LOG_ERROR("[Pan Network]%{public}s(): unknown protocol 0x%{public}x", __FUNCTION__, protocol);
433 return PAN_FAILURE;
434 }
435 head.protocol = protocol;
436
437 PanService::GetService()->PanSendData(head, packet + sizeof(head), packetSize - sizeof(head));
438 }
439 return PAN_SUCCESS;
440 }
441 } // namespace bluetooth
442 } // namespace OHOS
443