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 <gtest/gtest.h>
17 #include <cstdint>
18 #include <cstdbool>
19 #include <cstdlib>
20 #include <cstdio>
21 #include <thread>
22 #include "dhcp_server.h"
23 #include "address_utils.h"
24 #include "dhcp_config.h"
25 #include "dhcp_option.h"
26 #include "dhcp_logger.h"
27 #include "system_func_mock.h"
28 #include "dhcp_message_sim.h"
29 #include "dhcp_ipv4.h"
30 #include "common_util.h"
31 #include "securec.h"
32
33 using namespace testing::ext;
34 using namespace std;
35 using namespace OHOS::Wifi;
36
37 #undef LOG_TAG
38 #define LOG_TAG "DhcpServerTest"
39
40 struct ServerContext {
41 int broadCastFlagEnable;
42 DhcpAddressPool addressPool;
43 DhcpServerCallback callback;
44 DhcpConfig config;
45 int serverFd;
46 int looperState;
47 int initialized;
48 };
49
50 namespace OHOS {
51 namespace Wifi {
52 constexpr int SERVER_RUNING_TIME = 10; // the value is in units of seconds.
53
54 class DhcpServerTest : public testing::Test {
55 public:
SetUpTestCase()56 static void SetUpTestCase()
57 {}
TearDownTestCase()58 static void TearDownTestCase()
59 {}
SetUp()60 virtual void SetUp()
61 {}
TearDown()62 virtual void TearDown()
63 {
64 SystemFuncMock::GetInstance().SetMockFlag(false);
65 }
66
67 int InitServerConfig(DhcpConfig *config);
68 int FreeServerConfig(DhcpConfig *config);
69 int TestDhcpRequest(uint32_t testIp, uint32_t srvId);
70 int TestDhcpRequestByMac(uint32_t testIp, uint32_t srvId, uint8_t *macAddr);
71 int TestDhcpRelease(uint32_t testIp, uint32_t srvId);
72 int InitDhcpRequests();
73 int InitDhcpErrorRequests();
74 bool InitBindingRecodersTest();
75 bool FixedOptionsTest();
76 int InitDhcpClient();
77 bool ServerRun(void);
78 bool StartServerTest();
79 void DelayStopServer();
80 int InitClientIp(void);
81
82 private:
83 DhcpServerContext *m_pServerCtx = nullptr;
84 DhcpConfig m_serverConfg;
85 thread delayStopTh;
86
87 DhcpClientContext *m_pMockClient = nullptr;
88 DhcpClientConfig m_clientConfg;
89 };
90
InitServerConfig(DhcpConfig * config)91 int DhcpServerTest::InitServerConfig(DhcpConfig *config)
92 {
93 if (!config) {
94 return RET_FAILED;
95 }
96 const char* testIfaceName = "test_if0";
97 uint32_t serverId = ParseIpAddr("192.168.189.254");
98 uint32_t netmask = ParseIpAddr("255.255.255.0");
99 uint32_t beginIp = ParseIpAddr("192.168.189.100");
100 uint32_t endIp = ParseIpAddr("192.168.189.200");
101 if (serverId == 0 || netmask == 0 || beginIp == 0 || endIp == 0) {
102 printf("failed to parse address.\n");
103 return RET_FAILED;
104 }
105 if (memset_s(config, sizeof(DhcpConfig), 0, sizeof(DhcpConfig)) != EOK) {
106 return RET_FAILED;
107 }
108 if (memset_s(config->ifname, sizeof(config->ifname), '\0', sizeof(config->ifname)) != EOK) {
109 return RET_FAILED;
110 }
111 if (strncpy_s(config->ifname, sizeof(config->ifname), testIfaceName, strlen(testIfaceName)) != EOK) {
112 return RET_FAILED;
113 }
114 config->serverId = serverId;
115 config->netmask = netmask;
116 config->pool.beginAddress = beginIp;
117 config->pool.endAddress = endIp;
118 config->broadcast = 1;
119 if (InitOptionList(&config->options) != RET_SUCCESS) {
120 return RET_FAILED;
121 }
122 return RET_SUCCESS;
123 }
124
125 extern "C" void InitBindingRecoders(DhcpAddressPool *pool);
InitBindingRecodersTest()126 bool DhcpServerTest::InitBindingRecodersTest()
127 {
128 if (!m_pServerCtx) {
129 return false;
130 }
131 ServerContext *srvIns = reinterpret_cast<ServerContext *>(m_pServerCtx->instance);
132
133 AddressBinding bind = {0};
134 bind.bindingMode = BIND_MODE_DYNAMIC;
135 const uint8_t testMac1[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x09, 0};
136 uint32_t testIp1 = ParseIpAddr("192.168.189.101");
137 bind.ipAddress = testIp1;
138 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
139 bind.chaddr[i] = testMac1[i];
140 }
141 if (AddLease(&srvIns->addressPool, &bind) != RET_SUCCESS) {
142 LOGE("failed to add lease recoder.");
143 return false;
144 }
145
146 const uint8_t testMac5[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0e, 0};
147 uint32_t testIp5 = ParseIpAddr("192.168.189.130");
148 bind.ipAddress = testIp5;
149 bind.bindingMode = BIND_MODE_DYNAMIC;
150 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
151 bind.chaddr[i] = testMac5[i];
152 }
153 bind.expireIn = Tmspsec();
154 bind.bindingTime = bind.expireIn - DHCP_LEASE_TIME;
155 if (AddLease(&srvIns->addressPool, &bind) != RET_SUCCESS) {
156 return false;
157 }
158
159 const uint8_t testMac6[DHCP_HWADDR_LENGTH] = {0x00, 0xae, 0x3c, 0x65, 0x3a, 0x0e, 0};
160 uint32_t testIp6 = ParseIpAddr("192.168.189.118");
161 bind.ipAddress = testIp6;
162 bind.bindingMode = BIND_MODE_DYNAMIC;
163 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
164 bind.chaddr[i] = testMac6[i];
165 }
166 bind.expireIn = Tmspsec();
167 bind.bindingTime = bind.expireIn - DHCP_LEASE_TIME;
168 if (AddLease(&srvIns->addressPool, &bind) != RET_SUCCESS) {
169 return false;
170 }
171 srvIns->addressPool.leaseTime = DHCP_LEASE_TIME;
172 srvIns->addressPool.renewalTime = DHCP_RENEWAL_TIME;
173 InitBindingRecoders(nullptr);
174 DhcpAddressPool pool;
175 if (memset_s(&pool, sizeof(DhcpAddressPool), 0, sizeof(DhcpAddressPool)) != EOK) {
176 return false;
177 }
178 InitBindingRecoders(&pool);
179 InitBindingRecoders(&srvIns->addressPool);
180 return true;
181 }
182
183
FixedOptionsTest()184 bool DhcpServerTest::FixedOptionsTest()
185 {
186 const char *serverVendorId = "ohos-dhcp-server";
187 DhcpOption optVendorId = {VENDOR_CLASS_IDENTIFIER_OPTION, 0, {0}};
188 if (FillOption(&optVendorId, serverVendorId, strlen(serverVendorId)) != RET_SUCCESS) {
189 return false;
190 }
191 if (PushBackOption(&m_serverConfg.options, &optVendorId) != RET_SUCCESS) {
192 return false;
193 }
194 return true;
195 }
196
TestServerCallback(int state,int code,const char * ifname)197 static int TestServerCallback(int state, int code, const char *ifname)
198 {
199 int ret = 0;
200 switch (state) {
201 case ST_STARTING: {
202 if (code == 0) {
203 LOGD(" callback[%s] ==> server starting ...", ifname);
204 } else if (code == 1) {
205 LOGD(" callback[%s] ==> server started.", ifname);
206 } else if (code == NUM_TWO) {
207 LOGD(" callback[%s] ==> server start failed.", ifname);
208 }
209 break;
210 }
211 case ST_RELOADNG: {
212 LOGD(" callback[%s] ==> reloading ...", ifname);
213 break;
214 }
215 case ST_STOPED: {
216 LOGD(" callback[%s] ==> server stopped.", ifname);
217 break;
218 }
219 default:
220 break;
221 }
222 return ret;
223 }
224
ServerRun(void)225 bool DhcpServerTest::ServerRun(void)
226 {
227 LOGD("begin test start dhcp server.");
228 int retval = true;
229 EXPECT_CALL(SystemFuncMock::GetInstance(), socket(_, _, _)).WillRepeatedly(Return(1));
230 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, _, _, _)).WillRepeatedly(Return(0));
231 EXPECT_CALL(SystemFuncMock::GetInstance(), select(_, _, _, _, _)).WillRepeatedly(Return(0));
232 EXPECT_CALL(SystemFuncMock::GetInstance(), bind(_, _, _)).WillRepeatedly(Return(0));
233 EXPECT_CALL(SystemFuncMock::GetInstance(), sendto(_, _, _, _, _, _)).WillRepeatedly(Return(sizeof(DhcpMessage)));
234 EXPECT_CALL(SystemFuncMock::GetInstance(), recvfrom(_, _, _, _, _, _)).WillRepeatedly(Return(0));
235 EXPECT_CALL(SystemFuncMock::GetInstance(), close(_)).WillRepeatedly(Return(0));
236
237 m_pServerCtx = InitializeServer(&m_serverConfg);
238 if (!m_pServerCtx) {
239 LOGE("failed to initialized dhcp server context.");
240 retval = false;
241 }
242 if (!InitBindingRecodersTest()) {
243 LOGE("failed to initialize binding recoders.");
244 retval = false;
245 }
246 RegisterDhcpCallback(m_pServerCtx, TestServerCallback);
247 if (StartDhcpServer(nullptr) != RET_FAILED) {
248 LOGE("failed to start dhcp server. \n");
249 retval = false;
250 }
251 DhcpServerContext tempCtx;
252 memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext));
253 memset_s(tempCtx.ifname, sizeof(tempCtx.ifname), '\0', sizeof(tempCtx.ifname));
254 if (StartDhcpServer(&tempCtx) != RET_FAILED) {
255 LOGE("failed to start dhcp server. \n");
256 retval = false;
257 }
258 strcpy_s(tempCtx.ifname, sizeof(tempCtx.ifname), "test_if1");
259 if (StartDhcpServer(&tempCtx) != RET_FAILED) {
260 LOGE("failed to start dhcp server. \n");
261 retval = false;
262 }
263 if (m_pServerCtx && StartDhcpServer(m_pServerCtx) != RET_SUCCESS) {
264 LOGE("failed to start dhcp server. \n");
265 retval = false;
266 }
267 if (SaveLease(m_pServerCtx) != RET_SUCCESS) {
268 retval = false;
269 }
270 if (m_pServerCtx) {
271 FreeServerContext(&m_pServerCtx);
272 }
273 return retval;
274 }
275
StartServerTest()276 bool DhcpServerTest::StartServerTest()
277 {
278 bool retval = true;
279 LOGI("start dhcp server test...");
280 if (InitServerConfig(&m_serverConfg) != RET_SUCCESS) {
281 LOGE("failed to initialized dhcp server config.");
282 retval = false;
283 }
284 if (!FixedOptionsTest()) {
285 LOGE("failed to initialized fixed options.");
286 retval = false;
287 }
288 delayStopTh = std::thread(std::bind(&DhcpServerTest::DelayStopServer, this));
289 delayStopTh.detach();
290 if (InitDhcpClient() != RET_SUCCESS) {
291 retval = false;
292 }
293 LOGI("wait for test completed...");
294 retval = ServerRun();
295 return retval;
296 }
297
DelayStopServer()298 void DhcpServerTest::DelayStopServer()
299 {
300 const int SLEEP_TIME = 3;
301 const int SLEEP_TIME1 = 1;
302 const int SLEEP_TIME2 = 1;
303 LOGI("wait for dhcp server stopped...");
304 LOGI("wait %d seconds...\n", SERVER_RUNING_TIME);
305 EXPECT_CALL(SystemFuncMock::GetInstance(), close(_)).WillRepeatedly(Return(0));
306 std::this_thread::sleep_for(std::chrono::seconds(SLEEP_TIME));
307 if (m_pServerCtx && m_pServerCtx->instance) {
308 ServerContext *srvIns = reinterpret_cast<ServerContext *>(m_pServerCtx->instance);
309 srvIns->looperState = SLEEP_TIME;
310 }
311 std::this_thread::sleep_for(std::chrono::seconds(SERVER_RUNING_TIME));
312 if (StopDhcpServer(m_pServerCtx) != RET_SUCCESS) {
313 LOGE("failed to stop dhcp server.");
314 return;
315 }
316 int waitSesc = 0;
317 while (waitSesc < SERVER_RUNING_TIME) {
318 if (GetServerStatus(m_pServerCtx) == ST_STOPED) {
319 LOGI("dhcp server stopped.");
320 break;
321 } else {
322 std::this_thread::sleep_for(std::chrono::seconds(SLEEP_TIME1));
323 waitSesc++;
324 }
325 }
326 std::this_thread::sleep_for(std::chrono::seconds(SLEEP_TIME2));
327 }
328
TestDhcpRequest(uint32_t testIp,uint32_t srvId)329 int DhcpServerTest::TestDhcpRequest(uint32_t testIp, uint32_t srvId)
330 {
331 return TestDhcpRequestByMac(testIp, srvId, nullptr);
332 }
333
TestDhcpRequestByMac(uint32_t testIp,uint32_t srvId,uint8_t * macAddr)334 int DhcpServerTest::TestDhcpRequestByMac(uint32_t testIp, uint32_t srvId, uint8_t *macAddr)
335 {
336 DhcpMsgInfo msgInfo = {{0}, 0, {0}};
337 InitOptionList(&msgInfo.options);
338 if (!InitMessage(m_pMockClient, &msgInfo, DHCPREQUEST)) {
339 LOGE("failed to init dhcp message.");
340 FreeOptionList(&msgInfo.options);
341 return RET_FAILED;
342 }
343 RemoveOption(&msgInfo.options, END_OPTION);
344 if (srvId != 0) {
345 DhcpOption optSrvId = {SERVER_IDENTIFIER_OPTION, 0, {0}};
346 AppendAddressOption(&optSrvId, srvId);
347 PushFrontOption(&msgInfo.options, &optSrvId);
348 }
349 DhcpOption optReqIp = {REQUESTED_IP_ADDRESS_OPTION, 0, {0}};
350 AppendAddressOption(&optReqIp, testIp);
351 PushBackOption(&msgInfo.options, &optReqIp);
352 DhcpOption endOpt = {END_OPTION, 0, {0}};
353 PushBackOption(&msgInfo.options, &endOpt);
354 msgInfo.packet.ciaddr = testIp;
355 if (macAddr != nullptr) {
356 if (!FillHwAddr(msgInfo.packet.chaddr, DHCP_HWADDR_LENGTH, macAddr, MAC_ADDR_LENGTH)) {
357 return DHCP_FALSE;
358 }
359 }
360 if (SendDhcpMessage(m_pMockClient, &msgInfo) != RET_SUCCESS) {
361 LOGE("failed to send dhcp message.");
362 FreeOptionList(&msgInfo.options);
363 return RET_FAILED;
364 }
365 FreeOptionList(&msgInfo.options);
366 return RET_SUCCESS;
367 }
368
TestDhcpRelease(uint32_t testIp,uint32_t srvId)369 int DhcpServerTest::TestDhcpRelease(uint32_t testIp, uint32_t srvId)
370 {
371 DhcpMsgInfo msgInfo = {{0}, 0, {0}};
372 InitOptionList(&msgInfo.options);
373 if (!InitMessage(m_pMockClient, &msgInfo, DHCPRELEASE)) {
374 LOGE("failed to init dhcp message.");
375 FreeOptionList(&msgInfo.options);
376 return RET_FAILED;
377 }
378 RemoveOption(&msgInfo.options, END_OPTION);
379 if (srvId != 0) {
380 DhcpOption optSrvId = {SERVER_IDENTIFIER_OPTION, 0, {0}};
381 AppendAddressOption(&optSrvId, srvId);
382 PushBackOption(&msgInfo.options, &optSrvId);
383 }
384 DhcpOption optReqIp = {REQUESTED_IP_ADDRESS_OPTION, 0, {0}};
385 AppendAddressOption(&optReqIp, testIp);
386 PushBackOption(&msgInfo.options, &optReqIp);
387 msgInfo.packet.ciaddr = testIp;
388
389 DhcpOption endOpt = {END_OPTION, 0, {0}};
390 PushBackOption(&msgInfo.options, &endOpt);
391 if (SendDhcpMessage(m_pMockClient, &msgInfo) != RET_SUCCESS) {
392 LOGE("failed to send dhcp message.");
393 FreeOptionList(&msgInfo.options);
394 return RET_FAILED;
395 }
396 FreeOptionList(&msgInfo.options);
397 return RET_SUCCESS;
398 }
399
InitDhcpRequests()400 int DhcpServerTest::InitDhcpRequests()
401 {
402 uint32_t testIp = ParseIpAddr("192.168.189.101");
403 uint32_t srvId = ParseIpAddr("192.168.189.254");
404 DhcpMsgManager::GetInstance().SetClientIp(testIp);
405 if (DhcpRequest(m_pMockClient) != RET_SUCCESS) {
406 LOGE("[InitDhcpRequests] DhcpRequest failed");
407 return RET_FAILED;
408 }
409 DhcpMsgManager::GetInstance().SetClientIp(0);
410 if (TestDhcpRequest(testIp, srvId) != RET_SUCCESS) {
411 LOGE("[InitDhcpRequests] TestDhcpRequest1 failed");
412 return RET_FAILED;
413 }
414 testIp = ParseIpAddr("192.168.189.102");
415 if (TestDhcpRequest(testIp, 0) != RET_SUCCESS) {
416 return RET_FAILED;
417 }
418 testIp = ParseIpAddr("192.168.189.120");
419 uint8_t testMac1[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0a, 0};
420 uint8_t testMac2[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0b, 0};
421 uint8_t testMac3[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0c, 0};
422 if (TestDhcpRequestByMac(testIp, srvId, testMac1) != RET_SUCCESS) {
423 return RET_FAILED;
424 }
425 DhcpMsgManager::GetInstance().SetClientIp(testIp);
426 if (TestDhcpRequest(testIp, srvId) != RET_SUCCESS) {
427 return RET_FAILED;
428 }
429 testIp = ParseIpAddr("192.168.189.101");
430 if (TestDhcpRequestByMac(testIp, srvId, testMac2) != RET_SUCCESS) {
431 return RET_FAILED;
432 }
433 testIp = ParseIpAddr("192.168.189.120");
434 DhcpMsgManager::GetInstance().SetClientIp(testIp);
435 if (TestDhcpRequestByMac(testIp, srvId, testMac3) != RET_SUCCESS) {
436 return RET_FAILED;
437 }
438 DhcpMsgManager::GetInstance().SetClientIp(0);
439 uint8_t testMac4[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0d, 0};
440 testIp = ParseIpAddr("192.168.190.210");
441 if (TestDhcpRequestByMac(testIp, srvId, testMac4) != RET_SUCCESS) {
442 return RET_FAILED;
443 }
444 uint8_t testMac5[DHCP_HWADDR_LENGTH] = {0x0a, 0x0e, 0x3c, 0x65, 0x3a, 0x0e, 0};
445 testIp = ParseIpAddr("192.168.189.130");
446 DhcpMsgManager::GetInstance().SetClientIp(testIp);
447 if (TestDhcpRequestByMac(testIp, srvId, testMac5) != RET_SUCCESS) {
448 return RET_FAILED;
449 }
450 DhcpMsgManager::GetInstance().SetClientIp(0);
451 return RET_SUCCESS;
452 }
453
InitDhcpErrorRequests()454 int DhcpServerTest::InitDhcpErrorRequests()
455 {
456 uint32_t srvId = ParseIpAddr("192.168.100.254");
457 uint32_t testIp = ParseIpAddr("192.168.100.101");
458 DhcpMsgInfo msgInfo = {{0}, 0, {0}};
459 InitOptionList(&msgInfo.options);
460 if (!InitMessage(m_pMockClient, &msgInfo, DHCPREQUEST)) {
461 LOGE("failed to init dhcp message.");
462 FreeOptionList(&msgInfo.options);
463 return RET_FAILED;
464 }
465
466 DhcpOption optReqIp = {REQUESTED_IP_ADDRESS_OPTION, 0, {0}};
467 AppendAddressOption(&optReqIp, testIp);
468 PushFrontOption(&msgInfo.options, &optReqIp);
469 DhcpOption optSrvId = {SERVER_IDENTIFIER_OPTION, 0, {0}};
470 AppendAddressOption(&optSrvId, srvId);
471 PushFrontOption(&msgInfo.options, &optSrvId);
472 if (SendDhcpMessage(m_pMockClient, &msgInfo) != RET_SUCCESS) {
473 LOGE("failed to send dhcp message.");
474 FreeOptionList(&msgInfo.options);
475 return RET_FAILED;
476 }
477
478 RemoveOption(&msgInfo.options, DHCP_MESSAGE_TYPE_OPTION);
479 if (SendDhcpMessage(m_pMockClient, &msgInfo) != RET_SUCCESS) {
480 LOGE("failed to send dhcp message.");
481 FreeOptionList(&msgInfo.options);
482 return RET_FAILED;
483 }
484
485 RemoveOption(&msgInfo.options, END_OPTION);
486 RemoveOption(&msgInfo.options, SERVER_IDENTIFIER_OPTION);
487 if (SendDhcpMessage(m_pMockClient, &msgInfo) != RET_SUCCESS) {
488 LOGE("failed to send dhcp message.");
489 FreeOptionList(&msgInfo.options);
490 return RET_FAILED;
491 }
492 return RET_SUCCESS;
493 }
494
InitDhcpClient()495 int DhcpServerTest::InitDhcpClient()
496 {
497 uint8_t testMacAddr[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x09, 0};
498
499 LOGI("init mock dhcp client.");
500 const char* testIfname = "test_if0";
501
502 if (memset_s(&m_clientConfg, sizeof(DhcpClientConfig), 0, sizeof(DhcpClientConfig)) != EOK) {
503 return RET_FAILED;
504 }
505 if (!FillHwAddr(m_clientConfg.chaddr, DHCP_HWADDR_LENGTH, testMacAddr, MAC_ADDR_LENGTH)) {
506 LOGE("FillHwAddr failed");
507 return RET_FAILED;
508 }
509 if (memset_s(m_clientConfg.ifname, IFACE_NAME_SIZE, '\0', IFACE_NAME_SIZE) != EOK) {
510 return RET_FAILED;
511 }
512 if (memcpy_s(m_clientConfg.ifname, IFACE_NAME_SIZE, testIfname, strlen(testIfname)) != EOK) {
513 return RET_FAILED;
514 }
515
516 m_pMockClient = InitialDhcpClient(&m_clientConfg);
517 if (!m_pMockClient) {
518 LOGE("[InitDhcpClient] InitialDhcpClient failed");
519 return RET_FAILED;
520 }
521 if (DhcpDiscover(m_pMockClient) != RET_SUCCESS) {
522 LOGE("[InitDhcpClient] DhcpDiscover1 failed");
523 return RET_FAILED;
524 }
525 uint32_t testIp = ParseIpAddr("192.168.189.102");
526 uint32_t srvId = ParseIpAddr("192.168.189.254");
527 DhcpMsgManager::GetInstance().SetClientIp(testIp);
528 if (DhcpDiscover(m_pMockClient) != RET_SUCCESS) {
529 LOGE("[InitDhcpClient] DhcpDiscover2 failed");
530 return RET_FAILED;
531 }
532 InitDhcpRequests();
533 InitDhcpErrorRequests();
534 if (DhcpInform(m_pMockClient) != RET_SUCCESS) {
535 LOGE("[InitDhcpClient] DhcpInform1 failed");
536 return RET_FAILED;
537 }
538 if (InitClientIp() != RET_SUCCESS) {
539 return RET_FAILED;
540 }
541 testIp = ParseIpAddr("192.168.189.102");
542 if (TestDhcpRelease(testIp, srvId)) {
543 LOGE("[InitDhcpClient] TestDhcpRelease failed");
544 return RET_FAILED;
545 }
546 return RET_SUCCESS;
547 }
548
InitClientIp(void)549 int DhcpServerTest::InitClientIp(void)
550 {
551 uint32_t testIp = ParseIpAddr("192.168.189.102");
552 DhcpMsgManager::GetInstance().SetClientIp(testIp);
553 if (DhcpInform(m_pMockClient) != RET_SUCCESS) {
554 LOGE("[InitDhcpClient] DhcpInform2 failed");
555 return RET_FAILED;
556 }
557 DhcpMsgManager::GetInstance().SetClientIp(0);
558 if (DhcpDecline(m_pMockClient) != RET_SUCCESS) {
559 LOGE("[InitDhcpClient] DhcpDecline1 failed");
560 return RET_FAILED;
561 }
562 testIp = ParseIpAddr("192.168.189.118");
563 DhcpMsgManager::GetInstance().SetClientIp(testIp);
564 if (DhcpDecline(m_pMockClient) != RET_SUCCESS) {
565 LOGE("[InitDhcpClient] DhcpDecline2 failed");
566 return RET_FAILED;
567 }
568 DhcpMsgManager::GetInstance().SetClientIp(0);
569 if (DhcpRelease(m_pMockClient) != RET_SUCCESS) {
570 LOGE("[InitDhcpClient] DhcpRelease failed");
571 return RET_FAILED;
572 }
573 return RET_SUCCESS;
574 }
575
FreeServerConfig(DhcpConfig * config)576 int DhcpServerTest::FreeServerConfig(DhcpConfig *config)
577 {
578 if (!config) {
579 return RET_FAILED;
580 }
581 FreeOptionList(&config->options);
582 return RET_SUCCESS;
583 }
584
585 HWTEST_F(DhcpServerTest, InitializeServerTest, TestSize.Level1)
586 {
587 SystemFuncMock::GetInstance().SetMockFlag(true);
588 EXPECT_CALL(SystemFuncMock::GetInstance(), socket(_, _, _)).WillRepeatedly(Return(1));
589 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, _, _, _)).WillRepeatedly(Return(0));
590 EXPECT_CALL(SystemFuncMock::GetInstance(), select(_, _, _, _, _)).WillRepeatedly(Return(0));
591 EXPECT_CALL(SystemFuncMock::GetInstance(), recvfrom(_, _, _, _, _, _)).WillRepeatedly(Return(0));
592 EXPECT_CALL(SystemFuncMock::GetInstance(), bind(_, _, _)).WillRepeatedly(Return(0));
593 EXPECT_CALL(SystemFuncMock::GetInstance(), close(_)).WillRepeatedly(Return(0));
594 DhcpConfig config;
595 PDhcpServerContext ctx = InitializeServer(nullptr);
596 EXPECT_TRUE(ctx == nullptr);
597 ASSERT_TRUE(memset_s(&config, sizeof(DhcpConfig), 0, sizeof(DhcpConfig)) == EOK);
598 ctx = InitializeServer(&config);
599 EXPECT_TRUE(ctx == nullptr);
600 EXPECT_TRUE(strcpy_s(config.ifname, sizeof(config.ifname), "test_if0") == EOK);
601 ctx = InitializeServer(&config);
602 EXPECT_TRUE(ctx == nullptr);
603
604 EXPECT_EQ(RET_SUCCESS, InitServerConfig(&config));
605 ctx = InitializeServer(&config);
606 ASSERT_TRUE(ctx != nullptr);
607
608 EXPECT_EQ(RET_SUCCESS, FreeServerConfig(&config));
609 EXPECT_EQ(RET_SUCCESS, FreeServerContext(&ctx));
610 }
611
612 extern "C" int InitServer(const char *ifname);
613
614 HWTEST_F(DhcpServerTest, InitServerByIfaceTest, TestSize.Level1)
615 {
616 const int SO_BROADCAST = 6;
617 const int SO_REUSEADDR = 2;
618 SystemFuncMock::GetInstance().SetMockFlag(true);
619 EXPECT_CALL(SystemFuncMock::GetInstance(), socket(_, _, _))
620 .WillOnce(Return(-1))
621 .WillRepeatedly(Return(1));
622 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, SO_REUSEADDR, _, _))
623 .WillOnce(Return(-1))
624 .WillRepeatedly(Return(0));
625 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, SO_BROADCAST, _, _))
626 .WillOnce(Return(-1))
627 .WillRepeatedly(Return(0));
628 EXPECT_CALL(SystemFuncMock::GetInstance(), select(_, _, _, _, _)).WillRepeatedly(Return(0));
629 EXPECT_CALL(SystemFuncMock::GetInstance(), recvfrom(_, _, _, _, _, _)).WillRepeatedly(Return(0));
630 EXPECT_CALL(SystemFuncMock::GetInstance(), bind(_, _, _))
631 .WillOnce(Return(-1))
632 .WillRepeatedly(Return(0));
633 EXPECT_CALL(SystemFuncMock::GetInstance(), close(_)).WillRepeatedly(Return(0));
634 const char* ifaceName = "test_if01";
635 EXPECT_EQ(-1, InitServer(ifaceName));
636 EXPECT_EQ(-1, InitServer(ifaceName));
637 EXPECT_EQ(-1, InitServer(ifaceName));
638 EXPECT_EQ(1, InitServer(ifaceName));
639 }
640
641 HWTEST_F(DhcpServerTest, StartServerTest, TestSize.Level1)
642 {
643 SystemFuncMock::GetInstance().SetMockFlag(true);
644 EXPECT_TRUE(StartServerTest());
645 }
646
647 HWTEST_F(DhcpServerTest, ReceiveDhcpMessageFailedTest, TestSize.Level1)
648 {
649 SystemFuncMock::GetInstance().SetMockFlag(true);
650 ON_CALL(SystemFuncMock::GetInstance(), select(_, _, _, _, _))
651 .WillByDefault(Return(0));
652 ON_CALL(SystemFuncMock::GetInstance(), recvfrom(_, _, _, _, _, _))
653 .WillByDefault(Return((int)sizeof(DhcpMsgInfo)));
654 DhcpMsgInfo msgInfo = {{0}, 0, {0}};
655 const uint8_t testMac1[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x09, 0};
656
657 int ret = ReceiveDhcpMessage(1, &msgInfo); // failed to select isset.
658 EXPECT_TRUE(ret == RET_SELECT_TIME_OUT || ret == RET_ERROR || ret == RET_FAILED);
659 ret = ReceiveDhcpMessage(1, &msgInfo); // message length error
660 EXPECT_TRUE(ret == RET_SELECT_TIME_OUT || ret == RET_ERROR || ret == RET_FAILED);
661 ret = ReceiveDhcpMessage(1, &msgInfo); // dhcp message type error
662 EXPECT_TRUE(ret == RET_SELECT_TIME_OUT || ret == RET_ERROR || ret == RET_FAILED);
663 msgInfo.packet.hlen = 128;
664 ret = ReceiveDhcpMessage(1, &msgInfo); // hlen error
665 EXPECT_TRUE(ret == RET_SELECT_TIME_OUT || ret == RET_ERROR || ret == RET_FAILED);
666 msgInfo.packet.hlen = 16;
667 msgInfo.packet.op = BOOTREPLY;
668 ret = ReceiveDhcpMessage(1, &msgInfo); // client op type error
669 EXPECT_TRUE(ret == RET_SELECT_TIME_OUT || ret == RET_ERROR || ret == RET_FAILED);
670 msgInfo.packet.op = BOOTREQUEST;
671 ret = ReceiveDhcpMessage(1, &msgInfo); // client hardware address error
672 EXPECT_TRUE(ret == RET_SELECT_TIME_OUT || ret == RET_ERROR || ret == RET_FAILED);
673 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
674 msgInfo.packet.chaddr[i] = testMac1[i];
675 }
676 ret = ReceiveDhcpMessage(1, &msgInfo);
677 EXPECT_TRUE(ret == RET_SELECT_TIME_OUT || ret == RET_ERROR || ret == RET_FAILED);
678 }
679
680 extern "C" int FillReply(PDhcpServerContext ctx, PDhcpMsgInfo received, PDhcpMsgInfo reply);
681 HWTEST_F(DhcpServerTest, FillReplyFailedTest, TestSize.Level1)
682 {
683 DhcpServerContext tempCtx;
684 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
685 ASSERT_TRUE(memset_s(tempCtx.ifname, sizeof(tempCtx.ifname), '\0', sizeof(tempCtx.ifname)) == EOK);
686 DhcpMsgInfo recv, repl;
687 ASSERT_TRUE(memset_s(&recv, sizeof(DhcpMsgInfo), 0, sizeof(DhcpMsgInfo)) == EOK);
688 ASSERT_TRUE(memset_s(&repl, sizeof(DhcpMsgInfo), 0, sizeof(DhcpMsgInfo)) == EOK);
689 EXPECT_EQ(RET_ERROR, FillReply(&tempCtx, &recv, nullptr));
690 EXPECT_EQ(RET_FAILED, FillReply(&tempCtx, &recv, &repl));
691 recv.packet.flags = 1;
692 ServerContext srvInst;
693 ASSERT_TRUE(memset_s(&srvInst, sizeof(ServerContext), 0, sizeof(ServerContext)) == EOK);
694 tempCtx.instance = &srvInst;
695 recv.packet.siaddr = ParseIpAddr("192.168.189.252");
696 srvInst.addressPool.gateway = ParseIpAddr("192.168.189.254");
697 recv.packet.giaddr = ParseIpAddr("192.168.189.254");
698 EXPECT_EQ(RET_SUCCESS, FillReply(&tempCtx, &recv, &repl));
699 recv.packet.giaddr = 0;
700 EXPECT_EQ(RET_SUCCESS, FillReply(&tempCtx, &recv, &repl));
701 }
702
703 extern "C" int BindNetInterface(int fd, const char *ifname);
704 HWTEST_F(DhcpServerTest, BindNetInterfaceFailedTest, TestSize.Level1)
705 {
706 SystemFuncMock::GetInstance().SetMockFlag(true);
707 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, _, _, _))
708 .WillOnce(Return(-1))
709 .WillOnce(Return(0));
710 const char* ifaceName = "test_if01";
711 EXPECT_EQ(RET_FAILED, BindNetInterface(1, nullptr));
712 EXPECT_EQ(RET_FAILED, BindNetInterface(1, ifaceName));
713 EXPECT_EQ(RET_SUCCESS, BindNetInterface(1, ifaceName));
714 }
715
716 extern "C" int AddReplyServerIdOption(PDhcpOptionList options, uint32_t serverId);
717 HWTEST_F(DhcpServerTest, AddReplyServerIdOptionFailedTest, TestSize.Level1)
718 {
719 uint32_t srvId = ParseIpAddr("192.168.189.254");
720 ASSERT_TRUE(srvId != 0);
721 DhcpOptionList opts;
722 ASSERT_TRUE(memset_s(&opts, sizeof(DhcpOptionList), '\0', sizeof(DhcpOptionList)) == EOK);
723 EXPECT_EQ(RET_FAILED, AddReplyServerIdOption(nullptr, 0));
724 EXPECT_EQ(RET_FAILED, AddReplyServerIdOption(&opts, 0));
725
726 EXPECT_EQ(RET_SUCCESS, AddReplyServerIdOption(&opts, srvId));
727 EXPECT_EQ(RET_SUCCESS, AddReplyServerIdOption(&opts, srvId));
728 }
729
730 extern "C" int InitServerFixedOptions(DhcpConfig *config, DhcpServerContext *ctx);
731 HWTEST_F(DhcpServerTest, InitServerFixedOptionsFailedTest, TestSize.Level1)
732 {
733 DhcpServerContext tempCtx;
734 tempCtx.instance = nullptr;
735 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
736 ASSERT_TRUE(memset_s(tempCtx.ifname, sizeof(tempCtx.ifname), '\0', sizeof(tempCtx.ifname)) == EOK);
737 DhcpConfig tempConfig;
738 ASSERT_TRUE(memset_s(&tempConfig, sizeof(DhcpConfig), 0, sizeof(DhcpConfig)) == EOK);
739 EXPECT_EQ(RET_FAILED, InitServerFixedOptions(nullptr, &tempCtx));
740 EXPECT_EQ(RET_FAILED, InitServerFixedOptions(&tempConfig, &tempCtx));
741
742 ServerContext srvInst;
743 ASSERT_TRUE(memset_s(&srvInst, sizeof(ServerContext), 0, sizeof(ServerContext)) == EOK);
744 tempCtx.instance = &srvInst;
745 EXPECT_EQ(RET_FAILED, InitServerFixedOptions(&tempConfig, &tempCtx));
746 }
747
748 extern "C" int AppendReplyTimeOptions(PDhcpServerContext ctx, PDhcpOptionList options);
749 HWTEST_F(DhcpServerTest, AppendReplyTimeOptionsFailedTest, TestSize.Level1)
750 {
751 DhcpServerContext tempCtx;
752 tempCtx.instance = nullptr;
753 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
754 ASSERT_TRUE(memset_s(tempCtx.ifname, sizeof(tempCtx.ifname), '\0', sizeof(tempCtx.ifname)) == EOK);
755 EXPECT_EQ(RET_FAILED, AppendReplyTimeOptions(nullptr, nullptr));
756 EXPECT_EQ(RET_FAILED, AppendReplyTimeOptions(&tempCtx, nullptr));
757 }
758
759 HWTEST_F(DhcpServerTest, FreeServerContextFailedTest, TestSize.Level1)
760 {
761 EXPECT_EQ(RET_FAILED, FreeServerContext(nullptr));
762 }
763
764 extern "C" AddressBinding *GetBinding(DhcpAddressPool *pool, PDhcpMsgInfo received);
765 HWTEST_F(DhcpServerTest, GetBindingFailedTest, TestSize.Level1)
766 {
767 DhcpAddressPool tempPool;
768 DhcpMsgInfo msgInfo;
769 ASSERT_TRUE(memset_s(&tempPool, sizeof(DhcpAddressPool), 0, sizeof(DhcpAddressPool)) == EOK);
770 ASSERT_TRUE(memset_s(&msgInfo, sizeof(DhcpMsgInfo), 0, sizeof(DhcpMsgInfo)) == EOK);
771 EXPECT_TRUE(GetBinding(&tempPool, nullptr) == nullptr);
772 EXPECT_TRUE(GetBinding(nullptr, &msgInfo) == nullptr);
773 ASSERT_EQ(RET_SUCCESS, InitAddressPool(&tempPool, "test_if01", nullptr));
774 EXPECT_TRUE(GetBinding(&tempPool, &msgInfo) != nullptr);
775 FreeAddressPool(&tempPool);
776 }
777
778 extern "C" int SendDhcpReply(PDhcpServerContext ctx, int replyType, PDhcpMsgInfo reply);
779 HWTEST_F(DhcpServerTest, SendDhcpReplyTest, TestSize.Level1)
780 {
781 DhcpServerContext tempCtx;
782 tempCtx.instance = nullptr;
783 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
784 EXPECT_EQ(RET_FAILED, SendDhcpReply(&tempCtx, REPLY_NAK, nullptr));
785 EXPECT_EQ(RET_FAILED, SendDhcpReply(nullptr, REPLY_NAK, nullptr));
786 }
787
788 HWTEST_F(DhcpServerTest, SaveLeaseFailedTest, TestSize.Level1)
789 {
790 DhcpServerContext tempCtx;
791 tempCtx.instance = nullptr;
792 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
793 EXPECT_EQ(RET_FAILED, SaveLease(nullptr));
794 EXPECT_EQ(RET_FAILED, SaveLease(&tempCtx));
795 }
796 }
797 }
798