• 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 <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