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