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 <stdint.h>
18 #include <stdbool.h>
19 #include <stdlib.h>
20 #include <stdio.h>
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
41 static const int SERVER_RUNING_TIME = 10; // the value is in units of seconds.
42
43 struct ServerContext {
44 int broadCastFlagEnable;
45 DhcpAddressPool addressPool;
46 DhcpServerCallback callback;
47 DhcpConfig config;
48 int serverFd;
49 int looperState;
50 int initialized;
51 };
52
53 class DhcpServerTest : public testing::Test {
54 public:
SetUpTestCase()55 static void SetUpTestCase()
56 {}
TearDownTestCase()57 static void TearDownTestCase()
58 {}
SetUp()59 virtual void SetUp()
60 {}
TearDown()61 virtual void TearDown()
62 {
63 SystemFuncMock::GetInstance().SetMockFlag(false);
64 }
65
66 int InitServerConfig(DhcpConfig *config);
67 int FreeServerConfig(DhcpConfig *config);
68 int TestDhcpRequest(uint32_t testIp, uint32_t srvId);
69 int TestDhcpRequestByMac(uint32_t testIp, uint32_t srvId, uint8_t *macAddr);
70 int TestDhcpRelease(uint32_t testIp, uint32_t srvId);
71 int InitDhcpRequests();
72 int InitDhcpErrorRequests();
73 bool InitBindingRecodersTest();
74 bool FixedOptionsTest();
75 int InitDhcpClient();
76 bool ServerRun(void);
77 bool StartServerTest();
78 void DelayStopServer();
79
80 private:
81 DhcpServerContext *m_pServerCtx = nullptr;
82 DhcpConfig m_serverConfg;
83 thread delayStopTh;
84
85 DhcpClientContext *m_pMockClient = nullptr;
86 DhcpClientConfig m_clientConfg;
87 };
88
InitServerConfig(DhcpConfig * config)89 int DhcpServerTest::InitServerConfig(DhcpConfig *config)
90 {
91 if (!config) {
92 return RET_FAILED;
93 }
94 const char* testIfaceName = "test_if0";
95 uint32_t serverId = ParseIpAddr("192.168.189.254");
96 uint32_t netmask = ParseIpAddr("255.255.255.0");
97 uint32_t beginIp = ParseIpAddr("192.168.189.100");
98 uint32_t endIp = ParseIpAddr("192.168.189.200");
99 if (serverId == 0 || netmask == 0 || beginIp == 0 || endIp == 0) {
100 printf("failed to parse address.\n");
101 return RET_FAILED;
102 }
103 if (memset_s(config, sizeof(DhcpConfig), 0, sizeof(DhcpConfig)) != EOK) {
104 return RET_FAILED;
105 }
106 if (memset_s(config->ifname, sizeof(config->ifname), '\0', sizeof(config->ifname)) != EOK) {
107 return RET_FAILED;
108 }
109 if (strncpy_s(config->ifname, sizeof(config->ifname), testIfaceName, strlen(testIfaceName)) != EOK) {
110 return RET_FAILED;
111 }
112 config->serverId = serverId;
113 config->netmask = netmask;
114 config->pool.beginAddress = beginIp;
115 config->pool.endAddress = endIp;
116 config->broadcast = 1;
117 if (InitOptionList(&config->options) != RET_SUCCESS) {
118 return RET_FAILED;
119 }
120 return RET_SUCCESS;
121 }
122
123 extern "C" void InitBindingRecoders(DhcpAddressPool *pool);
InitBindingRecodersTest()124 bool DhcpServerTest::InitBindingRecodersTest()
125 {
126 if (!m_pServerCtx) {
127 return false;
128 }
129 ServerContext *srvIns = (ServerContext *)m_pServerCtx->instance;
130
131 AddressBinding bind = {0};
132 bind.bindingMode = BIND_MODE_DYNAMIC;
133 uint8_t testMac1[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x09, 0};
134 uint32_t testIp1 = ParseIpAddr("192.168.189.101");
135 bind.ipAddress = testIp1;
136 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
137 bind.chaddr[i] = testMac1[i];
138 }
139 if (AddLease(&srvIns->addressPool, &bind) != RET_SUCCESS) {
140 LOGE("failed to add lease recoder.");
141 return false;
142 }
143
144 uint8_t testMac5[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0e, 0};
145 uint32_t testIp5 = ParseIpAddr("192.168.189.130");
146 bind.ipAddress = testIp5;
147 bind.bindingMode = BIND_MODE_DYNAMIC;
148 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
149 bind.chaddr[i] = testMac5[i];
150 }
151 bind.expireIn = Tmspsec();
152 bind.bindingTime = bind.expireIn - DHCP_LEASE_TIME;
153 if (AddLease(&srvIns->addressPool, &bind) != RET_SUCCESS) {
154 LOGE("failed to add lease recoder.");
155 return false;
156 }
157
158 uint8_t testMac6[DHCP_HWADDR_LENGTH] = {0x00, 0xae, 0x3c, 0x65, 0x3a, 0x0e, 0};
159 uint32_t testIp6 = ParseIpAddr("192.168.189.118");
160 bind.ipAddress = testIp6;
161 bind.bindingMode = BIND_MODE_DYNAMIC;
162 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
163 bind.chaddr[i] = testMac6[i];
164 }
165 bind.expireIn = Tmspsec();
166 bind.bindingTime = bind.expireIn - DHCP_LEASE_TIME;
167 if (AddLease(&srvIns->addressPool, &bind) != RET_SUCCESS) {
168 LOGE("failed to add lease recoder.");
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 = (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 LOGE("[InitDhcpRequests] TestDhcpRequest2 failed");
417 return RET_FAILED;
418 }
419 testIp = ParseIpAddr("192.168.189.120");
420 uint8_t testMac1[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0a, 0};
421 uint8_t testMac2[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0b, 0};
422 uint8_t testMac3[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0c, 0};
423 if (TestDhcpRequestByMac(testIp, srvId, testMac1) != RET_SUCCESS) {
424 LOGE("[InitDhcpRequests] TestDhcpRequestByMac1 failed");
425 return RET_FAILED;
426 }
427 DhcpMsgManager::GetInstance().SetClientIp(testIp);
428 if (TestDhcpRequest(testIp, srvId) != RET_SUCCESS) {
429 LOGE("[InitDhcpRequests] TestDhcpRequest3 failed");
430 return RET_FAILED;
431 }
432 testIp = ParseIpAddr("192.168.189.101");
433 if (TestDhcpRequestByMac(testIp, srvId, testMac2) != RET_SUCCESS) {
434 LOGE("[InitDhcpRequests] TestDhcpRequestByMac2 failed");
435 return RET_FAILED;
436 }
437 testIp = ParseIpAddr("192.168.189.120");
438 DhcpMsgManager::GetInstance().SetClientIp(testIp);
439 if (TestDhcpRequestByMac(testIp, srvId, testMac3) != RET_SUCCESS) {
440 LOGE("[InitDhcpRequests] TestDhcpRequestByMac3 failed");
441 return RET_FAILED;
442 }
443 DhcpMsgManager::GetInstance().SetClientIp(0);
444 uint8_t testMac4[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x0d, 0};
445 testIp = ParseIpAddr("192.168.190.210");
446 if (TestDhcpRequestByMac(testIp, srvId, testMac4) != RET_SUCCESS) {
447 LOGE("[InitDhcpRequests] TestDhcpRequestByMac4 failed");
448 return RET_FAILED;
449 }
450 uint8_t testMac5[DHCP_HWADDR_LENGTH] = {0x0a, 0x0e, 0x3c, 0x65, 0x3a, 0x0e, 0};
451 testIp = ParseIpAddr("192.168.189.130");
452 DhcpMsgManager::GetInstance().SetClientIp(testIp);
453 if (TestDhcpRequestByMac(testIp, srvId, testMac5) != RET_SUCCESS) {
454 LOGE("[InitDhcpRequests] TestDhcpRequestByMac5 failed");
455 return RET_FAILED;
456 }
457 DhcpMsgManager::GetInstance().SetClientIp(0);
458 return RET_SUCCESS;
459 }
460
InitDhcpErrorRequests()461 int DhcpServerTest::InitDhcpErrorRequests()
462 {
463 uint32_t srvId = ParseIpAddr("192.168.100.254");
464 uint32_t testIp = ParseIpAddr("192.168.100.101");
465 DhcpMsgInfo msgInfo = {{0}, 0, {0}};
466 InitOptionList(&msgInfo.options);
467 if (!InitMessage(m_pMockClient, &msgInfo, DHCPREQUEST)) {
468 LOGE("failed to init dhcp message.");
469 FreeOptionList(&msgInfo.options);
470 return RET_FAILED;
471 }
472
473 DhcpOption optReqIp = {REQUESTED_IP_ADDRESS_OPTION, 0, {0}};
474 AppendAddressOption(&optReqIp, testIp);
475 PushFrontOption(&msgInfo.options, &optReqIp);
476 DhcpOption optSrvId = {SERVER_IDENTIFIER_OPTION, 0, {0}};
477 AppendAddressOption(&optSrvId, srvId);
478 PushFrontOption(&msgInfo.options, &optSrvId);
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, DHCP_MESSAGE_TYPE_OPTION);
486 if (SendDhcpMessage(m_pMockClient, &msgInfo) != RET_SUCCESS) {
487 LOGE("failed to send dhcp message.");
488 FreeOptionList(&msgInfo.options);
489 return RET_FAILED;
490 }
491
492 RemoveOption(&msgInfo.options, END_OPTION);
493 RemoveOption(&msgInfo.options, SERVER_IDENTIFIER_OPTION);
494 if (SendDhcpMessage(m_pMockClient, &msgInfo) != RET_SUCCESS) {
495 LOGE("failed to send dhcp message.");
496 FreeOptionList(&msgInfo.options);
497 return RET_FAILED;
498 }
499 return RET_SUCCESS;
500 }
501
InitDhcpClient()502 int DhcpServerTest::InitDhcpClient()
503 {
504 uint8_t testMacAddr[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x09, 0};
505
506 LOGI("init mock dhcp client.");
507 const char* testIfname = "test_if0";
508
509 if (memset_s(&m_clientConfg, sizeof(DhcpClientConfig), 0, sizeof(DhcpClientConfig)) != EOK) {
510 return RET_FAILED;
511 }
512 if (!FillHwAddr(m_clientConfg.chaddr, DHCP_HWADDR_LENGTH, testMacAddr, MAC_ADDR_LENGTH)) {
513 LOGE("FillHwAddr failed");
514 return RET_FAILED;
515 }
516 if (memset_s(m_clientConfg.ifname, IFACE_NAME_SIZE, '\0', IFACE_NAME_SIZE) != EOK) {
517 return RET_FAILED;
518 }
519 if (memcpy_s(m_clientConfg.ifname, IFACE_NAME_SIZE, testIfname, strlen(testIfname)) != EOK) {
520 return RET_FAILED;
521 }
522
523 m_pMockClient = InitialDhcpClient(&m_clientConfg);
524 if (!m_pMockClient) {
525 LOGE("[InitDhcpClient] InitialDhcpClient failed");
526 return RET_FAILED;
527 }
528 if (DhcpDiscover(m_pMockClient) != RET_SUCCESS) {
529 LOGE("[InitDhcpClient] DhcpDiscover1 failed");
530 return RET_FAILED;
531 }
532 uint32_t testIp = ParseIpAddr("192.168.189.102");
533 uint32_t srvId = ParseIpAddr("192.168.189.254");
534 DhcpMsgManager::GetInstance().SetClientIp(testIp);
535 if (DhcpDiscover(m_pMockClient) != RET_SUCCESS) {
536 LOGE("[InitDhcpClient] DhcpDiscover2 failed");
537 return RET_FAILED;
538 }
539 InitDhcpRequests();
540 InitDhcpErrorRequests();
541 if (DhcpInform(m_pMockClient) != RET_SUCCESS) {
542 LOGE("[InitDhcpClient] DhcpInform1 failed");
543 return RET_FAILED;
544 }
545 DhcpMsgManager::GetInstance().SetClientIp(testIp);
546 if (DhcpInform(m_pMockClient) != RET_SUCCESS) {
547 LOGE("[InitDhcpClient] DhcpInform2 failed");
548 return RET_FAILED;
549 }
550 DhcpMsgManager::GetInstance().SetClientIp(0);
551 if (DhcpDecline(m_pMockClient) != RET_SUCCESS) {
552 LOGE("[InitDhcpClient] DhcpDecline1 failed");
553 return RET_FAILED;
554 }
555 testIp = ParseIpAddr("192.168.189.118");
556 DhcpMsgManager::GetInstance().SetClientIp(testIp);
557 if (DhcpDecline(m_pMockClient) != RET_SUCCESS) {
558 LOGE("[InitDhcpClient] DhcpDecline2 failed");
559 return RET_FAILED;
560 }
561 DhcpMsgManager::GetInstance().SetClientIp(0);
562 if (DhcpRelease(m_pMockClient) != RET_SUCCESS) {
563 LOGE("[InitDhcpClient] DhcpRelease failed");
564 return RET_FAILED;
565 }
566 testIp = ParseIpAddr("192.168.189.102");
567 if (TestDhcpRelease(testIp, srvId)) {
568 LOGE("[InitDhcpClient] TestDhcpRelease failed");
569 return RET_FAILED;
570 }
571 return RET_SUCCESS;
572 }
573
FreeServerConfig(DhcpConfig * config)574 int DhcpServerTest::FreeServerConfig(DhcpConfig *config)
575 {
576 if (!config) {
577 return RET_FAILED;
578 }
579 FreeOptionList(&config->options);
580 return RET_SUCCESS;
581 }
582
583 HWTEST_F(DhcpServerTest, InitializeServerTest, TestSize.Level1)
584 {
585 SystemFuncMock::GetInstance().SetMockFlag(true);
586 EXPECT_CALL(SystemFuncMock::GetInstance(), socket(_, _, _)).WillRepeatedly(Return(1));
587 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, _, _, _)).WillRepeatedly(Return(0));
588 EXPECT_CALL(SystemFuncMock::GetInstance(), select(_, _, _, _, _)).WillRepeatedly(Return(0));
589 EXPECT_CALL(SystemFuncMock::GetInstance(), recvfrom(_, _, _, _, _, _)).WillRepeatedly(Return(0));
590 EXPECT_CALL(SystemFuncMock::GetInstance(), bind(_, _, _)).WillRepeatedly(Return(0));
591 EXPECT_CALL(SystemFuncMock::GetInstance(), close(_)).WillRepeatedly(Return(0));
592 DhcpConfig config;
593 PDhcpServerContext ctx = InitializeServer(nullptr);
594 EXPECT_TRUE(ctx == nullptr);
595 ASSERT_TRUE(memset_s(&config, sizeof(DhcpConfig), 0, sizeof(DhcpConfig)) == EOK);
596 ctx = InitializeServer(&config);
597 EXPECT_TRUE(ctx == nullptr);
598 EXPECT_TRUE(strcpy_s(config.ifname, sizeof(config.ifname), "test_if0") == EOK);
599 ctx = InitializeServer(&config);
600 EXPECT_TRUE(ctx == nullptr);
601
602 EXPECT_EQ(RET_SUCCESS, InitServerConfig(&config));
603 ctx = InitializeServer(&config);
604 ASSERT_TRUE(ctx != nullptr);
605
606 EXPECT_EQ(RET_SUCCESS, FreeServerConfig(&config));
607 EXPECT_EQ(RET_SUCCESS, FreeServerContext(&ctx));
608 }
609
610 extern "C" int InitServer(const char *ifname);
611
612 HWTEST_F(DhcpServerTest, InitServerByIfaceTest, TestSize.Level1)
613 {
614 const int SO_BROADCAST = 6;
615 const int SO_REUSEADDR = 2;
616 SystemFuncMock::GetInstance().SetMockFlag(true);
617 EXPECT_CALL(SystemFuncMock::GetInstance(), socket(_, _, _))
618 .WillOnce(Return(-1))
619 .WillRepeatedly(Return(1));
620 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, SO_REUSEADDR, _, _))
621 .WillOnce(Return(-1))
622 .WillRepeatedly(Return(0));
623 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, SO_BROADCAST, _, _))
624 .WillOnce(Return(-1))
625 .WillRepeatedly(Return(0));
626 EXPECT_CALL(SystemFuncMock::GetInstance(), select(_, _, _, _, _)).WillRepeatedly(Return(0));
627 EXPECT_CALL(SystemFuncMock::GetInstance(), recvfrom(_, _, _, _, _, _)).WillRepeatedly(Return(0));
628 EXPECT_CALL(SystemFuncMock::GetInstance(), bind(_, _, _))
629 .WillOnce(Return(-1))
630 .WillRepeatedly(Return(0));
631 EXPECT_CALL(SystemFuncMock::GetInstance(), close(_)).WillRepeatedly(Return(0));
632 const char* ifaceName = "test_if01";
633 EXPECT_EQ(-1, InitServer(ifaceName));
634 EXPECT_EQ(-1, InitServer(ifaceName));
635 EXPECT_EQ(-1, InitServer(ifaceName));
636 EXPECT_EQ(1, InitServer(ifaceName));
637 }
638
639 HWTEST_F(DhcpServerTest, StartServerTest, TestSize.Level1)
640 {
641 SystemFuncMock::GetInstance().SetMockFlag(true);
642 EXPECT_TRUE(StartServerTest());
643 }
644
645 HWTEST_F(DhcpServerTest, ReceiveDhcpMessageFailedTest, TestSize.Level1)
646 {
647 SystemFuncMock::GetInstance().SetMockFlag(true);
648 ON_CALL(SystemFuncMock::GetInstance(), select(_, _, _, _, _))
649 .WillByDefault(Return(0));
650 ON_CALL(SystemFuncMock::GetInstance(), recvfrom(_, _, _, _, _, _))
651 .WillByDefault(Return((int)sizeof(DhcpMsgInfo)));
652 DhcpMsgInfo msgInfo = {{0}, 0, {0}};
653 uint8_t testMac1[DHCP_HWADDR_LENGTH] = {0x00, 0x0e, 0x3c, 0x65, 0x3a, 0x09, 0};
654
655 int ret = ReceiveDhcpMessage(1, &msgInfo); // failed to select isset.
656 EXPECT_TRUE(ret == RET_FAILED || ret == RET_ERROR);
657 ret = ReceiveDhcpMessage(1, &msgInfo); // message length error
658 EXPECT_TRUE(ret == RET_FAILED || ret == RET_ERROR);
659 ret = ReceiveDhcpMessage(1, &msgInfo); // dhcp message type error
660 EXPECT_TRUE(ret == RET_FAILED || ret == RET_ERROR);
661 msgInfo.packet.hlen = 128;
662 ret = ReceiveDhcpMessage(1, &msgInfo); // hlen error
663 EXPECT_TRUE(ret == RET_FAILED || ret == RET_ERROR);
664 msgInfo.packet.hlen = 16;
665 msgInfo.packet.op = BOOTREPLY;
666 ret = ReceiveDhcpMessage(1, &msgInfo); // client op type error
667 EXPECT_TRUE(ret == RET_FAILED || ret == RET_ERROR);
668 msgInfo.packet.op = BOOTREQUEST;
669 ret = ReceiveDhcpMessage(1, &msgInfo); // client hardware address error
670 EXPECT_TRUE(ret == RET_FAILED || ret == RET_ERROR);
671 for (int i = 0; i < MAC_ADDR_LENGTH; ++i) {
672 msgInfo.packet.chaddr[i] = testMac1[i];
673 }
674 ret = ReceiveDhcpMessage(1, &msgInfo);
675 EXPECT_TRUE(ret == RET_FAILED || ret == RET_ERROR);
676 }
677
678 extern "C" int FillReply(PDhcpServerContext ctx, PDhcpMsgInfo received, PDhcpMsgInfo reply);
679 HWTEST_F(DhcpServerTest, FillReplyFailedTest, TestSize.Level1)
680 {
681 DhcpServerContext tempCtx;
682 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
683 ASSERT_TRUE(memset_s(tempCtx.ifname, sizeof(tempCtx.ifname), '\0', sizeof(tempCtx.ifname)) == EOK);
684 DhcpMsgInfo recv, repl;
685 ASSERT_TRUE(memset_s(&recv, sizeof(DhcpMsgInfo), 0, sizeof(DhcpMsgInfo)) == EOK);
686 ASSERT_TRUE(memset_s(&repl, sizeof(DhcpMsgInfo), 0, sizeof(DhcpMsgInfo)) == EOK);
687 EXPECT_EQ(RET_ERROR, FillReply(&tempCtx, &recv, nullptr));
688 EXPECT_EQ(RET_FAILED, FillReply(&tempCtx, &recv, &repl));
689 recv.packet.flags = 1;
690 ServerContext srvInst;
691 ASSERT_TRUE(memset_s(&srvInst, sizeof(ServerContext), 0, sizeof(ServerContext)) == EOK);
692 tempCtx.instance = &srvInst;
693 recv.packet.siaddr = ParseIpAddr("192.168.189.252");
694 srvInst.addressPool.gateway = ParseIpAddr("192.168.189.254");
695 recv.packet.giaddr = ParseIpAddr("192.168.189.254");
696 EXPECT_EQ(RET_SUCCESS, FillReply(&tempCtx, &recv, &repl));
697 recv.packet.giaddr = 0;
698 EXPECT_EQ(RET_SUCCESS, FillReply(&tempCtx, &recv, &repl));
699 }
700
701 extern "C" int BindNetInterface(int fd, const char *ifname);
702 HWTEST_F(DhcpServerTest, BindNetInterfaceFailedTest, TestSize.Level1)
703 {
704 SystemFuncMock::GetInstance().SetMockFlag(true);
705 EXPECT_CALL(SystemFuncMock::GetInstance(), setsockopt(_, _, _, _, _))
706 .WillOnce(Return(-1))
707 .WillOnce(Return(0));
708 const char* ifaceName = "test_if01";
709 EXPECT_EQ(RET_FAILED, BindNetInterface(1, nullptr));
710 EXPECT_EQ(RET_FAILED, BindNetInterface(1, ifaceName));
711 EXPECT_EQ(RET_SUCCESS, BindNetInterface(1, ifaceName));
712 }
713
714 extern "C" int AddReplyServerIdOption(PDhcpOptionList options, uint32_t serverId);
715 HWTEST_F(DhcpServerTest, AddReplyServerIdOptionFailedTest, TestSize.Level1)
716 {
717 uint32_t srvId = ParseIpAddr("192.168.189.254");
718 ASSERT_TRUE(srvId != 0);
719 DhcpOptionList opts;
720 ASSERT_TRUE(memset_s(&opts, sizeof(DhcpOptionList), '\0', sizeof(DhcpOptionList)) == EOK);
721 EXPECT_EQ(RET_FAILED, AddReplyServerIdOption(nullptr, 0));
722 EXPECT_EQ(RET_FAILED, AddReplyServerIdOption(&opts, 0));
723
724 EXPECT_EQ(RET_SUCCESS, AddReplyServerIdOption(&opts, srvId));
725 EXPECT_EQ(RET_SUCCESS, AddReplyServerIdOption(&opts, srvId));
726 }
727
728 extern "C" int InitServerFixedOptions(DhcpConfig *config, DhcpServerContext *ctx);
729 HWTEST_F(DhcpServerTest, InitServerFixedOptionsFailedTest, TestSize.Level1)
730 {
731 DhcpServerContext tempCtx;
732 tempCtx.instance = nullptr;
733 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
734 ASSERT_TRUE(memset_s(tempCtx.ifname, sizeof(tempCtx.ifname), '\0', sizeof(tempCtx.ifname)) == EOK);
735 DhcpConfig tempConfig;
736 ASSERT_TRUE(memset_s(&tempConfig, sizeof(DhcpConfig), 0, sizeof(DhcpConfig)) == EOK);
737 EXPECT_EQ(RET_FAILED, InitServerFixedOptions(nullptr, &tempCtx));
738 EXPECT_EQ(RET_FAILED, InitServerFixedOptions(&tempConfig, &tempCtx));
739
740 ServerContext srvInst;
741 ASSERT_TRUE(memset_s(&srvInst, sizeof(ServerContext), 0, sizeof(ServerContext)) == EOK);
742 tempCtx.instance = &srvInst;
743 EXPECT_EQ(RET_FAILED, InitServerFixedOptions(&tempConfig, &tempCtx));
744 }
745
746
747 extern "C" int AppendReplyTimeOptions(PDhcpServerContext ctx, PDhcpOptionList options);
748 HWTEST_F(DhcpServerTest, AppendReplyTimeOptionsFailedTest, TestSize.Level1)
749 {
750 DhcpServerContext tempCtx;
751 tempCtx.instance = nullptr;
752 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
753 ASSERT_TRUE(memset_s(tempCtx.ifname, sizeof(tempCtx.ifname), '\0', sizeof(tempCtx.ifname)) == EOK);
754 EXPECT_EQ(RET_FAILED, AppendReplyTimeOptions(nullptr, nullptr));
755 EXPECT_EQ(RET_FAILED, AppendReplyTimeOptions(&tempCtx, nullptr));
756 }
757
758 HWTEST_F(DhcpServerTest, FreeServerContextFailedTest, TestSize.Level1)
759 {
760 EXPECT_EQ(RET_FAILED, FreeServerContext(nullptr));
761 }
762
763 extern "C" AddressBinding *GetBinding(DhcpAddressPool *pool, PDhcpMsgInfo received);
764 HWTEST_F(DhcpServerTest, GetBindingFailedTest, TestSize.Level1)
765 {
766 DhcpAddressPool tempPool;
767 DhcpMsgInfo msgInfo;
768 ASSERT_TRUE(memset_s(&tempPool, sizeof(DhcpAddressPool), 0, sizeof(DhcpAddressPool)) == EOK);
769 ASSERT_TRUE(memset_s(&msgInfo, sizeof(DhcpMsgInfo), 0, sizeof(DhcpMsgInfo)) == EOK);
770 EXPECT_TRUE(GetBinding(&tempPool, nullptr) == nullptr);
771 EXPECT_TRUE(GetBinding(nullptr, &msgInfo) == nullptr);
772 ASSERT_EQ(RET_SUCCESS, InitAddressPool(&tempPool, "test_if01", nullptr));
773 EXPECT_TRUE(GetBinding(&tempPool, &msgInfo) != nullptr);
774 FreeAddressPool(&tempPool);
775 }
776
777 extern "C" int SendDhcpReply(PDhcpServerContext ctx, int replyType, PDhcpMsgInfo reply);
778 HWTEST_F(DhcpServerTest, SendDhcpReplyTest, TestSize.Level1)
779 {
780 DhcpServerContext tempCtx;
781 tempCtx.instance = nullptr;
782 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
783 EXPECT_EQ(RET_FAILED, SendDhcpReply(&tempCtx, REPLY_NAK, nullptr));
784 EXPECT_EQ(RET_FAILED, SendDhcpReply(nullptr, REPLY_NAK, nullptr));
785 }
786
787 HWTEST_F(DhcpServerTest, SaveLeaseFailedTest, TestSize.Level1)
788 {
789 DhcpServerContext tempCtx;
790 tempCtx.instance = nullptr;
791 ASSERT_TRUE(memset_s(&tempCtx, sizeof(DhcpServerContext), 0, sizeof(DhcpServerContext)) == EOK);
792 EXPECT_EQ(RET_FAILED, SaveLease(nullptr));
793 EXPECT_EQ(RET_FAILED, SaveLease(&tempCtx));
794 }
795