• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 
16 #include "system_func_mock.h"
17 #include "address_utils.h"
18 #include "dhcp_define.h"
19 #include "dhcp_ipv4.h"
20 #include "dhcp_logger.h"
21 #include "dhcp_message.h"
22 #include "dhcp_message_sim.h"
23 #include "dhcp_option.h"
24 #include "securec.h"
25 #include <stdint.h>
26 #include <sys/select.h>
27 #include <sys/time.h>
28 
29 using namespace OHOS::Wifi;
30 
31 #define MAGIC_COOKIE_LENGTH 4
32 #define OPT_HEADER_LENGTH 2
33 #define TIME_SEC_TO_USEC (1000 * 1000)
34 
35 #undef LOG_TAG
36 #define LOG_TAG "DhcpServerSystemFuncMock"
37 
38 static bool g_mockTag = false;
39 
GetInstance()40 SystemFuncMock &SystemFuncMock::GetInstance()
41 {
42     static SystemFuncMock gSystemFuncMock;
43     return gSystemFuncMock;
44 };
45 
SystemFuncMock()46 SystemFuncMock::SystemFuncMock() {}
47 
~SystemFuncMock()48 SystemFuncMock::~SystemFuncMock() {}
49 
SetMockFlag(bool flag)50 void SystemFuncMock::SetMockFlag(bool flag)
51 {
52     g_mockTag = flag;
53 }
54 
GetMockFlag(void)55 bool SystemFuncMock::GetMockFlag(void)
56 {
57     return g_mockTag;
58 }
59 
60 extern "C" {
61 struct in_addr {
62     uint32_t s_addr;
63 };
64 
65 struct sockaddr_in {
66     short int sin_family;
67     unsigned short int sin_port;
68     struct in_addr sin_addr;
69     unsigned char sin_zero[8];
70 };
71 
72 int __real_socket(int __domain, int __type, int __protocol);
__wrap_socket(int __domain,int __type,int __protocol)73 int __wrap_socket(int __domain, int __type, int __protocol)
74 {
75     LOGD("==>socket.");
76     if (g_mockTag) {
77         LOGD(" ==>mock enable.");
78         return SystemFuncMock::GetInstance().socket(__domain, __type, __protocol);
79     } else {
80         LOGD(" ==>mock disable.");
81     }
82     return __real_socket(__domain, __type, __protocol);
83 }
84 
85 int __real_setsockopt(int __fd, int __level, int __optname, const void *__optval, socklen_t __optlen);
__wrap_setsockopt(int __fd,int __level,int __optname,const void * __optval,socklen_t __optlen)86 int __wrap_setsockopt(int __fd, int __level, int __optname, const void *__optval, socklen_t __optlen)
87 {
88     LOGD("==>setsockopt.");
89     if (g_mockTag) {
90         LOGD(" ==>mock enable.");
91         return SystemFuncMock::GetInstance().setsockopt(__fd, __level, __optname, __optval, __optlen);
92     } else {
93         LOGD(" ==>mock disable.");
94     }
95     return __real_setsockopt(__fd, __level, __optname, __optval, __optlen);
96 }
97 
98 int __real_select(int __nfds, fd_set *__readfds, fd_set *__writefds, fd_set *__exceptfds, struct timeval *__timeout);
__wrap_select(int __nfds,fd_set * __readfds,fd_set * __writefds,fd_set * __exceptfds,struct timeval * __timeout)99 int __wrap_select(int __nfds, fd_set *__readfds, fd_set *__writefds, fd_set *__exceptfds, struct timeval *__timeout)
100 {
101     const unsigned int SLEEP_TIEM = 300000;
102     LOGD("==>select.");
103     if (g_mockTag) {
104         LOGD(" ==>mock enable.");
105         LOGD("message queue total: %d.", DhcpMsgManager::GetInstance().SendTotal());
106         if (DhcpMsgManager::GetInstance().SendTotal() > 0) {
107             FD_CLR(__nfds, __readfds);
108             usleep(SLEEP_TIEM);
109             return 1;
110         }
111         int retval = SystemFuncMock::GetInstance().select(__nfds, __readfds, __writefds, __exceptfds, __timeout);
112         if (retval == 0) {
113             if (__timeout != nullptr) {
114                 usleep(DHCP_SEL_WAIT_TIMEOUTS * 1000);
115                 LOGD("select time out.");
116             }
117         }
118         return retval;
119     } else {
120         LOGD(" ==>mock disable.");
121     }
122     return __real_select(__nfds, __readfds, __writefds, __exceptfds, __timeout);
123 }
124 
125 int __real_bind(int __fd, struct sockaddr *__addr, socklen_t __len);
__wrap_bind(int __fd,struct sockaddr * __addr,socklen_t __len)126 int __wrap_bind(int __fd, struct sockaddr *__addr, socklen_t __len)
127 {
128     LOGD("==>bind.");
129     if (g_mockTag) {
130         LOGD(" ==>mock enable.");
131         return SystemFuncMock::GetInstance().bind(__fd, __addr, __len);
132     } else {
133         LOGD(" ==>mock disable.");
134     }
135     return __real_bind(__fd, __addr, __len);
136 }
137 
138 int __real_close(int _fileno);
__wrap_close(int _fileno)139 int __wrap_close(int _fileno)
140 {
141     LOGD("==>close.");
142     if (g_mockTag) {
143         LOGD(" ==>mock enable.");
144         return SystemFuncMock::GetInstance().close(_fileno);
145     } else {
146         LOGD(" ==>mock disable.");
147     }
148     return __real_close(_fileno);
149 }
150 
recvfrom(int __fd,void * __buf,size_t __n,int __flags,struct sockaddr * __addr,socklen_t * __addr_len)151 ssize_t recvfrom(int __fd, void *__buf, size_t __n, int __flags, struct sockaddr *__addr, socklen_t *__addr_len)
152 {
153     LOGD("==>recvfrom.");
154     if (g_mockTag) {
155         LOGD(" ==>mock enable.");
156         if (DhcpMsgManager::GetInstance().SendTotal() > 0 && __buf) {
157             LOGD("== new message received.");
158             DhcpMessage msg = { 0 };
159             if (DhcpMsgManager::GetInstance().FrontSendMsg(&msg)) {
160                 (void)memcpy_s(__buf, __n, &msg, sizeof(DhcpMessage));
161                 DhcpMsgManager::GetInstance().PopSendMsg();
162                 uint32_t srcIp = DhcpMsgManager::GetInstance().GetClientIp();
163                 if (__addr != nullptr && srcIp != 0) {
164                     struct sockaddr_in *sAddr = (struct sockaddr_in *)__addr;
165                     sAddr->sin_addr.s_addr = HostToNetwork(srcIp);
166                     DhcpMsgManager::GetInstance().SetClientIp(0);
167                 }
168                 return sizeof(DhcpMessage);
169             }
170         }
171     } else {
172         LOGD(" ==>mock disable.");
173     }
174     return SystemFuncMock::GetInstance().recvfrom(__fd, __buf, __n, __flags, __addr, __addr_len);
175 }
176 
ParseMockOptions(DhcpMessage * packet)177 int ParseMockOptions(DhcpMessage *packet)
178 {
179     if (packet == nullptr) {
180         LOGD("dhcp message pointer is null.");
181         return RET_FAILED;
182     }
183     DhcpMsgInfo reply;
184     if (memset_s(&reply, sizeof(DhcpMsgInfo), 0, sizeof(DhcpMsgInfo)) != EOK) {
185         LOGD("failed to reset dhcp message info.");
186         return RET_FAILED;
187     }
188     int retval = RET_FAILED;
189     if (memcpy_s(&reply.packet, sizeof(reply.packet), packet, sizeof(DhcpMessage)) != EOK) {
190         LOGD("failed to fill dhcp message.");
191         return RET_FAILED;
192     }
193     reply.length = sizeof(DhcpMessage);
194     if (InitOptionList(&reply.options) != RET_SUCCESS) {
195         LOGD("failed to init dhcp option list.");
196         return retval;
197     }
198     FreeOptionList(&reply.options);
199     return retval;
200 }
201 
sendto(int __fd,const void * __buf,size_t __n,int __flags,struct sockaddr * __addr,socklen_t __addr_len)202 ssize_t sendto(int __fd, const void *__buf, size_t __n, int __flags, struct sockaddr *__addr, socklen_t __addr_len)
203 {
204     LOGD("==>sendto.");
205     if (g_mockTag) {
206         LOGD(" ==>mock enable.");
207         if (__buf == nullptr) {
208             return SystemFuncMock::GetInstance().sendto(__fd, __buf, __n, __flags, __addr, __addr_len);
209         }
210     } else {
211         LOGD(" ==>mock disable.");
212     }
213     return SystemFuncMock::GetInstance().sendto(__fd, __buf, __n, __flags, __addr, __addr_len);
214 }
215 }
216