• 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 "dhcp_config.h"
17 #include <cerrno>
18 #include <securec.h>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <string.h>
22 #include <sys/time.h>
23 #include "address_utils.h"
24 #include "common_util.h"
25 #include "dhcp_define.h"
26 #include "dhcp_logger.h"
27 #include "dhcp_common_utils.h"
28 
29 DEFINE_DHCPLOG_DHCP_LABEL("DhcpServerConfig");
30 
31 #define FILE_LINE_LEN_MAX       1024
32 #define FILE_LINE_DELIMITER     "="
33 
SetEnableConfigInfo(DhcpConfig * dhcpConfig,const char * pKey,const char * pValue)34 static int SetEnableConfigInfo(DhcpConfig *dhcpConfig, const char *pKey, const char *pValue)
35 {
36     if ((dhcpConfig == nullptr) || (pKey == nullptr) || (pValue == nullptr)) {
37         DHCP_LOGE("SetEnableConfigInfo param dhcpConfig or pKey or pValue is nullptr!");
38         return RET_FAILED;
39     }
40 
41     uint32_t uValue = OHOS::DHCP::CheckDataToUint(pValue);
42     if ((uValue != 0) && (uValue != 1)) {
43         DHCP_LOGE("enable:%s error", pValue);
44         return RET_FAILED;
45     }
46 
47     if (strcmp(pKey, "distribution") == 0) {
48         dhcpConfig->distribution = uValue;
49     } else if (strcmp(pKey, "broadcast") == 0) {
50         dhcpConfig->broadcast = uValue;
51     }
52     return RET_SUCCESS;
53 }
54 
SetTimeConfigInfo(DhcpConfig * dhcpConfig,const char * pKey,const char * pValue)55 static int SetTimeConfigInfo(DhcpConfig *dhcpConfig, const char *pKey, const char *pValue)
56 {
57     if ((dhcpConfig == nullptr) || (pKey == nullptr) || (pValue == nullptr)) {
58         DHCP_LOGE("SetTimeConfigInfo param dhcpConfig or pKey or pValue is nullptr!");
59         return RET_FAILED;
60     }
61 
62     uint32_t uValue = 0;
63     if ((uValue = OHOS::DHCP::CheckDataToUint(pValue)) == 0) {
64         DHCP_LOGE("CheckDataToUint failed, time:%{public}s", pValue);
65         return RET_FAILED;
66     }
67 
68     if (strcmp(pKey, "leaseTime") == 0) {
69         dhcpConfig->leaseTime = uValue;
70     } else if (strcmp(pKey, "renewalTime") == 0) {
71         dhcpConfig->renewalTime = uValue;
72     } else if (strcmp(pKey, "rebindingTime") == 0) {
73         dhcpConfig->rebindingTime = uValue;
74     }
75     return RET_SUCCESS;
76 }
77 
SetNetConfigInfo(DhcpConfig * dhcpConfig,const char * pKey,const char * pValue,int common)78 static int SetNetConfigInfo(DhcpConfig *dhcpConfig, const char *pKey, const char *pValue, int common)
79 {
80     if ((dhcpConfig == nullptr) || (pKey == nullptr) || (pValue == nullptr)) {
81         DHCP_LOGE("SetNetConfigInfo param dhcpConfig or pKey or pValue is nullptr!");
82         return RET_FAILED;
83     }
84 
85     uint32_t uValue = 0;
86     if ((uValue = ParseIpAddr(pValue)) == 0) {
87         DHCP_LOGE("ParseIpAddr failed, ip:%s", pValue);
88         return RET_FAILED;
89     }
90 
91     if (((strcmp(pKey, "serverId") == 0) && common) || ((strcmp(pKey, "server") == 0) && !common)) {
92         dhcpConfig->serverId = uValue;
93     } else if (strcmp(pKey, "gateway") == 0) {
94         dhcpConfig->gateway = uValue;
95     } else if (strcmp(pKey, "netmask") == 0) {
96         dhcpConfig->netmask = uValue;
97     }
98     return RET_SUCCESS;
99 }
100 
SetIpAddressPool(DhcpConfig * dhcpConfig,const char * pValue)101 static int SetIpAddressPool(DhcpConfig *dhcpConfig, const char *pValue)
102 {
103     if ((dhcpConfig == nullptr) || (pValue == nullptr)) {
104         DHCP_LOGE("SetIpAddressPool param dhcpConfig or pValue is nullptr!");
105         return RET_FAILED;
106     }
107 
108     char *pSrc = (char *)pValue;
109     char *pSave = nullptr;
110     char *pTok = strtok_r(pSrc, ",", &pSave);
111     if (((pTok == nullptr) || (strlen(pTok) == 0)) || ((pSave == nullptr) || (strlen(pSave) == 0))) {
112         DHCP_LOGE("strtok_r pTok or pSave nullptr or len is 0!");
113         return RET_FAILED;
114     }
115 
116     uint32_t begin;
117     if ((begin = ParseIpAddr(pTok)) == 0) {
118         DHCP_LOGE("ParseIpAddr begin:%s failed!", pTok);
119         return RET_FAILED;
120     }
121     dhcpConfig->pool.beginAddress = begin;
122     uint32_t end;
123     if ((end = ParseIpAddr(pSave)) == 0) {
124         DHCP_LOGE("ParseIpAddr end:%s failed!", pSave);
125         return RET_FAILED;
126     }
127     dhcpConfig->pool.endAddress = end;
128     return RET_SUCCESS;
129 }
130 
SetDnsInfo(DhcpConfig * dhcpConfig,const char * pValue)131 static int SetDnsInfo(DhcpConfig *dhcpConfig, const char *pValue)
132 {
133     if ((dhcpConfig == nullptr) || (pValue == nullptr)) {
134         DHCP_LOGE("SetDnsInfo param dhcpConfig or pValue is nullptr!");
135         return RET_FAILED;
136     }
137 
138     char *pSrc = (char *)pValue;
139     char *pSave = nullptr;
140     char *pTok = strtok_r(pSrc, ",", &pSave);
141     if ((pTok == nullptr) || (strlen(pTok) == 0)) {
142         DHCP_LOGE("strtok_r pTok nullptr or len is 0!");
143         return RET_FAILED;
144     }
145 
146     DhcpOption optDns = {DOMAIN_NAME_SERVER_OPTION, 0, {0}};
147     if (GetOption(&dhcpConfig->options, optDns.code) != nullptr) {
148         RemoveOption(&dhcpConfig->options, optDns.code);
149     }
150 
151     uint32_t dnsAddress;
152     while (pTok != nullptr) {
153         if ((dnsAddress = ParseIpAddr(pTok)) == 0) {
154             DHCP_LOGE("ParseIpAddr %s failed, code:%d", pTok, optDns.code);
155             return RET_FAILED;
156         }
157         if (AppendAddressOption(&optDns, dnsAddress) != RET_SUCCESS) {
158             DHCP_LOGW("failed append dns option.");
159         }
160         pTok = strtok_r(nullptr, ",", &pSave);
161     }
162     PushBackOption(&dhcpConfig->options, &optDns);
163     return RET_SUCCESS;
164 }
165 
SetIfnameInfo(DhcpConfig * dhcpConfig,const char * pValue)166 static int SetIfnameInfo(DhcpConfig *dhcpConfig, const char *pValue)
167 {
168     if ((dhcpConfig == nullptr) || (pValue == nullptr)) {
169         DHCP_LOGE("SetIfnameInfo dhcpConfig or pValue is nullptr!");
170         return RET_FAILED;
171     }
172     if (strlen(pValue) >= IFACE_NAME_SIZE) {
173         DHCP_LOGE("ifname:%s too long!", pValue);
174         return RET_FAILED;
175     }
176     if (memset_s(dhcpConfig->ifname, IFACE_NAME_SIZE, '\0', IFACE_NAME_SIZE) != EOK ||
177         strncpy_s(dhcpConfig->ifname, IFACE_NAME_SIZE, pValue, strlen(pValue)) != EOK) {
178         return RET_FAILED;
179     }
180     return RET_SUCCESS;
181 }
182 
SetDhcpConfig(DhcpConfig * dhcpConfig,const char * strLine,int common)183 static int SetDhcpConfig(DhcpConfig *dhcpConfig, const char *strLine, int common)
184 {
185     if ((strLine == nullptr) || (strlen(strLine) == 0)) {
186         DHCP_LOGE("SetDhcpConfig param strLine is nullptr or len = 0!");
187         return RET_FAILED;
188     }
189 
190     char *pSrc = (char *)strLine;
191     char *pSave = nullptr;
192     char *pTok = strtok_r(pSrc, FILE_LINE_DELIMITER, &pSave);
193     if (pTok == nullptr) {
194         DHCP_LOGE("strtok_r pTok nullptr!");
195         return RET_FAILED;
196     }
197     if (strcmp(pTok, "interface") == 0) {
198         return SetIfnameInfo(dhcpConfig, pSave);
199     } else if (strcmp(pTok, "dns") == 0) {
200         return SetDnsInfo(dhcpConfig, pSave);
201     } else if (strcmp(pTok, "pool") == 0) {
202         return SetIpAddressPool(dhcpConfig, pSave);
203     } else if ((((strcmp(pTok, "serverId") == 0) && common) || ((strcmp(pTok, "server") == 0) && !common)) ||
204         (strcmp(pTok, "gateway") == 0) || (strcmp(pTok, "netmask") == 0)) {
205         return SetNetConfigInfo(dhcpConfig, pTok, pSave, common);
206     } else if ((strcmp(pTok, "leaseTime") == 0) || (strcmp(pTok, "renewalTime") == 0) ||
207                (strcmp(pTok, "rebindingTime") == 0)) {
208         return SetTimeConfigInfo(dhcpConfig, pTok, pSave);
209     } else if ((strcmp(pTok, "distribution") == 0) || (strcmp(pTok, "broadcast") == 0)) {
210         return SetEnableConfigInfo(dhcpConfig, pTok, pSave);
211     } else {
212         DHCP_LOGD("invalid key:%s", pTok);
213         return RET_SUCCESS;
214     }
215 }
216 
ProcessFile(FILE * fp,const char * ifname,DhcpConfig * dhcpConfig,const char * configFile)217 static int ProcessFile(FILE *fp, const char *ifname, DhcpConfig *dhcpConfig, const char *configFile)
218 {
219     int bComm = 1;
220     int bValid = 1;
221     char strLine[FILE_LINE_LEN_MAX] = {0};
222     while (fgets(strLine, FILE_LINE_LEN_MAX, fp) != nullptr) {
223         DHCP_LOGI("fgets strLine = %{public}s", strLine);
224         if ((strchr(strLine, '#') != nullptr) || (strchr(strLine, '=') == nullptr) ||
225             !RemoveSpaceCharacters(strLine, FILE_LINE_LEN_MAX)) {
226             if (memset_s(strLine, FILE_LINE_LEN_MAX, 0, FILE_LINE_LEN_MAX) != EOK) {
227                 break;
228             }
229             continue;
230         }
231         if (memcmp(strLine, "interface", strlen("interface")) == 0) {
232             bComm = 0;
233             bValid = 0;
234             if ((ifname == nullptr) || (strlen(ifname) == 0) || (strstr(strLine, ifname) != nullptr)) {
235                 DHCP_LOGI("%s %s find ifname:%s", configFile, strLine, ((ifname == nullptr) ? "" : ifname));
236                 bValid = 1;
237             } else {
238                 DHCP_LOGI("%s %s no find ifname:%s", configFile, strLine, ifname);
239             }
240         }
241         if (bValid && SetDhcpConfig(dhcpConfig, strLine, bComm) != RET_SUCCESS) {
242             DHCP_LOGE("set dhcp config %s %s failed", configFile, strLine);
243 
244             return RET_FAILED;
245         }
246         if (memset_s(strLine, FILE_LINE_LEN_MAX, 0, FILE_LINE_LEN_MAX) != EOK) {
247             break;
248         }
249     }
250     return RET_SUCCESS;
251 }
252 
ParseConfigFile(const char * configFile,const char * ifname,DhcpConfig * dhcpConfig)253 static int ParseConfigFile(const char *configFile, const char *ifname, DhcpConfig *dhcpConfig)
254 {
255     if ((configFile == nullptr) || (strlen(configFile) == 0) || (dhcpConfig == nullptr)) {
256         DHCP_LOGE("ParseConfigFile param configFile or dhcpConfig is nullptr or len = 0!");
257         return RET_FAILED;
258     }
259     char *realPaths = realpath(configFile, nullptr);
260     if (realPaths == nullptr) {
261         DHCP_LOGE("realpath failed, error: ");
262         return RET_FAILED;
263     }
264     FILE *fp = fopen(realPaths, "r");
265     if (fp == nullptr) {
266         DHCP_LOGE("fopen %{public}s failed, err:%{public}d", configFile, errno);
267         free(realPaths);
268         return RET_FAILED;
269     }
270     if (ProcessFile(fp, ifname, dhcpConfig, realPaths) != RET_SUCCESS) {
271         (void)fclose(fp);
272         free(realPaths);
273         return RET_FAILED;
274     }
275     if (fclose(fp) != 0) {
276         DHCP_LOGE("ParseConfigFile fclose fp failed!");
277     }
278     free(realPaths);
279     return RET_SUCCESS;
280 }
281 
CheckDhcpConfig(DhcpConfig * config)282 static int CheckDhcpConfig(DhcpConfig *config)
283 {
284     if (config == nullptr) {
285         DHCP_LOGE("CheckDhcpConfig param config is null");
286         return DHCP_FALSE;
287     }
288     if ((strlen(config->ifname) > 0) && ((config->serverId == 0))) {
289         DHCP_LOGE("failed to config serverId or netmask");
290         return DHCP_FALSE;
291     }
292 
293     if (config->renewalTime == 0) {
294         config->renewalTime = config->leaseTime * DHCP_RENEWAL_MULTIPLE;
295     }
296     if (config->rebindingTime == 0) {
297         config->rebindingTime = config->leaseTime * DHCP_REBIND_MULTIPLE;
298     }
299     return DHCP_TRUE;
300 }
301 
LoadConfig(const char * configFile,const char * ifname,DhcpConfig * config)302 int LoadConfig(const char *configFile, const char *ifname, DhcpConfig *config)
303 {
304     if ((configFile == nullptr) || (strlen(configFile) == 0) || (ifname == nullptr) || (strlen(ifname) == 0) ||
305         (config == nullptr)) {
306         DHCP_LOGE("LoadConfig param configFile or ifname or config is nullptr or len = 0!");
307         return RET_FAILED;
308     }
309 
310     /* Default config. */
311     config->leaseTime = DHCP_LEASE_TIME;
312     config->distribution = 1;
313     config->broadcast = 1;
314 
315     /* Set file config. */
316     if (ParseConfigFile(configFile, ifname, config) != RET_SUCCESS) {
317         DHCP_LOGE("parse config file %{public}s error!", configFile);
318         return RET_FAILED;
319     }
320     DHCP_LOGI("parse config file %{public}s success", configFile);
321 
322     if (!CheckDhcpConfig(config)) {
323         DHCP_LOGE("check dhcp config failed");
324         return RET_FAILED;
325     }
326 
327     if ((strlen(config->ifname) == 0) && SetIfnameInfo(config, ifname) != RET_SUCCESS) {
328         DHCP_LOGE("set ifname %s error!", ifname);
329         return RET_FAILED;
330     }
331     return RET_SUCCESS;
332 }
333