• 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_argument.h"
17 #include <getopt.h>
18 #include <securec.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include "address_utils.h"
24 #include "dhcp_s_define.h"
25 #include "dhcp_logger.h"
26 #include "hash_table.h"
27 
28 DEFINE_DHCPLOG_DHCP_LABEL("DhcpArgument");
29 
30 static HashTable g_argumentsTable;
31 
PutIpArgument(const char * argument,const char * val)32 static int PutIpArgument(const char *argument, const char *val)
33 {
34     if (!ParseIpAddr(val)) {
35         DHCP_LOGE("%s format error.", argument);
36         return RET_FAILED;
37     }
38     return PutArgument(argument, val);
39 }
40 
PutPoolArgument(const char * argument,const char * val)41 static int PutPoolArgument(const char *argument, const char *val)
42 {
43     if (!val) {
44         return 0;
45     }
46     if (strchr(val, ',') == nullptr) {
47         DHCP_LOGE("too few pool option arguments.");
48         return RET_FAILED;
49     }
50     return PutArgument(argument, val);
51 }
52 
ShowVersion(const char * argument,const char * val)53 static int ShowVersion(const char *argument, const char *val)
54 {
55     DHCP_LOGI("version:%s\n", DHCPD_VERSION);
56     return RET_SUCCESS;
57 }
58 
DefaultArgument(const char * argument,const char * val)59 static int DefaultArgument(const char *argument, const char *val)
60 {
61     DHCP_LOGI("Input argument is: [%s], value is [%s]", (argument == nullptr) ? "" : argument,
62         (val == nullptr) ? "" : val);
63     return RET_SUCCESS;
64 }
65 
66 const char *g_optionString = "i:c:d:g:s:n:P:S:Bp:o:lb:rvhD";
67 
68 static struct option g_longOptions[] = {
69     {"ifname", REQUIRED_ARG, 0, 'i'},
70     {"conf", REQUIRED_ARG, 0, 'c'},
71     {"dns", REQUIRED_ARG, 0, 'd'},
72     {"gateway", REQUIRED_ARG, 0, 'g'},
73     {"server", REQUIRED_ARG, 0, 's'},
74     {"netmask", REQUIRED_ARG, 0, 'n'},
75     {"pool", REQUIRED_ARG, 0, 'P'},
76     {"lease", REQUIRED_ARG, 0, 0},
77     {"renewal", REQUIRED_ARG, 0, 0},
78     {"rebinding", REQUIRED_ARG, 0, 0},
79     {"version", NO_ARG, 0, 'v'},
80     {"help", NO_ARG, 0, 'h'},
81     {0, 0, 0, 0},
82 };
83 
84 static DhcpUsage usages[] = {
85     {&g_longOptions[NUM_ZERO], "<interface>", "network interface name.", "--ifname eth0", 1, PutArgument},
86     {&g_longOptions[NUM_ONE], "<file>", "configure file name.", "--conf /etc/conf/dhcp_server.conf", 0, PutArgument},
87     {&g_longOptions[NUM_TWO], "<dns1>[,dns2][,dns3][...]", "domain name server IP address list.", "", 0, PutArgument},
88     {&g_longOptions[NUM_THREE], "<gateway>", "gateway option.", "", 0, PutIpArgument},
89     {&g_longOptions[NUM_FOUR], "<server>", "server identifier.", "", 1, PutIpArgument},
90     {&g_longOptions[NUM_FIVE], "<netmask>", "default subnet mask.", "", 1, PutIpArgument},
91     {&g_longOptions[NUM_SIX], "<beginip>,<endip>", "pool address range.", "", 0,
92         PutPoolArgument},
93     {&g_longOptions[NUM_SEVEN], "<leaseTime>", "set lease time value, the value is in units of seconds.", "", 0,
94         PutArgument},
95     {&g_longOptions[NUM_EIGHT], "<renewalTime>", "set renewal time value, the value is in units of seconds.", "", 0,
96         PutArgument},
97     {&g_longOptions[NUM_NINE], "<rebindingTime>", "set rebinding time value, the value is in units of seconds.", "", 0,
98         PutArgument},
99     {&g_longOptions[NUM_TEN], "", "show version information.", "", 0, ShowVersion},
100     {&g_longOptions[NUM_ELEVEN], "", "show help information.", "", 0, DefaultArgument},
101     {0, "", "", ""},
102 };
103 
HasArgument(const char * argument)104 int HasArgument(const char *argument)
105 {
106     char name[ARGUMENT_NAME_SIZE] = {'\0'};
107     if (!argument) {
108         return 0;
109     }
110     size_t ssize = strlen(argument);
111     if (ssize > ARGUMENT_NAME_SIZE) {
112         ssize = ARGUMENT_NAME_SIZE;
113     }
114     if (memcpy_s(name, ARGUMENT_NAME_SIZE, argument, ssize) != EOK) {
115         DHCP_LOGE("failed to set argument name.");
116         return 0;
117     }
118     if (ContainsKey(&g_argumentsTable, (uintptr_t)name)) {
119         return 1;
120     }
121     return 0;
122 }
123 
ShowUsage(const DhcpUsage * usage)124 static void ShowUsage(const DhcpUsage *usage)
125 {
126     if (!usage || !usage->opt) {
127         return;
128     }
129     if (usage->opt->val) {
130         DHCP_LOGI("-%{public}c,--%{public}s ", (char)usage->opt->val, usage->opt->name);
131     } else {
132         DHCP_LOGI("   --%{public}s ", usage->opt->name);
133     }
134     if (usage->params[0] == '\0') {
135         DHCP_LOGI("\t\t%{public}s\n", usage->desc);
136     } else {
137         int plen = strlen(usage->params) + strlen(usage->params);
138         if (plen < USAGE_DESC_MAX_LENGTH) {
139             DHCP_LOGI("\t\t%{public}s\t\t%{public}s\n", usage->params, usage->desc);
140         } else {
141             DHCP_LOGI("\t\t%{public}s\n", usage->params);
142             DHCP_LOGI("\t\t\t%{public}s\n\n", usage->desc);
143         }
144     }
145 }
146 
PrintRequiredArguments(void)147 void PrintRequiredArguments(void)
148 {
149     size_t argc = sizeof(usages) / sizeof(DhcpUsage);
150     DHCP_LOGI("required parameters:");
151     int idx = 0;
152     for (size_t i = 0; i < argc; i++) {
153         DhcpUsage usage = usages[i];
154         if (!usage.opt) {
155             break;
156         }
157         if (usage.required) {
158             if (idx == 0) {
159                 DHCP_LOGI("\"%{public}s\"", usage.opt->name);
160             } else {
161                 DHCP_LOGI(", \"%{public}s\"", usage.opt->name);
162             }
163             idx++;
164         }
165     }
166     DHCP_LOGI(".\n\n");
167     DHCP_LOGI("Usage: dhcp_server [options] \n");
168     DHCP_LOGI("e.g: dhcp_server -i eth0 -c /data/service/el1/public/dhcp/dhcp_server.conf \n");
169     DHCP_LOGI("     dhcp_server --help \n\n");
170 }
171 
PrintUsage(void)172 static void PrintUsage(void)
173 {
174     DHCP_LOGI("Usage: dhcp_server [options] \n\n");
175 
176     size_t argc = sizeof(usages) / sizeof(DhcpUsage);
177     for (size_t i = 0; i < argc; i++) {
178         DhcpUsage usage = usages[i];
179         if (!usage.opt) {
180             break;
181         }
182         ShowUsage(&usage);
183     }
184     DHCP_LOGI("\n");
185 }
186 
ShowHelp(int argc)187 void ShowHelp(int argc)
188 {
189     if (argc == NUM_TWO) {
190         PrintUsage();
191         return;
192     }
193 }
194 
InitArguments(void)195 int InitArguments(void)
196 {
197     DHCP_LOGI("start InitArguments.");
198     if (CreateHashTable(&g_argumentsTable, ARGUMENT_NAME_SIZE, sizeof(ArgumentInfo), INIT_ARGS_SIZE) != HASH_SUCCESS) {
199         return RET_FAILED;
200     }
201     DHCP_LOGI("end InitArguments.");
202     return RET_SUCCESS;
203 }
204 
GetArgument(const char * name)205 ArgumentInfo *GetArgument(const char *name)
206 {
207     char argName[ARGUMENT_NAME_SIZE] = {'\0'};
208     size_t ssize = strlen(name);
209     if (ssize > ARGUMENT_NAME_SIZE) {
210         ssize = ARGUMENT_NAME_SIZE;
211     }
212     if (memcpy_s(argName, ARGUMENT_NAME_SIZE, name, ssize) != EOK) {
213         DHCP_LOGE("failed to set argument name.");
214         return nullptr;
215     }
216     if (ContainsKey(&g_argumentsTable, (uintptr_t)argName)) {
217         ArgumentInfo *arg = (ArgumentInfo *)At(&g_argumentsTable, (uintptr_t)argName);
218         return arg;
219     }
220     return nullptr;
221 }
222 
PutArgument(const char * argument,const char * val)223 int PutArgument(const char *argument, const char *val)
224 {
225     DHCP_LOGI("start PutArgument.");
226     if (!argument) {
227         return RET_FAILED;
228     }
229     if (!val) {
230         return RET_FAILED;
231     }
232 
233     if (HasArgument(argument)) {
234         return RET_FAILED;
235     }
236 
237     ArgumentInfo arg;
238     size_t ssize = strlen(argument);
239     if (ssize >= ARGUMENT_NAME_SIZE) {
240         ssize = ARGUMENT_NAME_SIZE -1;
241     }
242     size_t vlen = strlen(val);
243     if (memset_s(arg.name, ARGUMENT_NAME_SIZE, '\0', ARGUMENT_NAME_SIZE) != EOK) {
244         DHCP_LOGE("failed to reset argument name.");
245         return RET_ERROR;
246     }
247     if (memcpy_s(arg.name, ARGUMENT_NAME_SIZE, argument, ssize) != EOK) {
248         DHCP_LOGE("failed to set argument name.");
249         return RET_ERROR;
250     }
251     if (vlen >= ARGUMENT_VALUE_SIZE) {
252         DHCP_LOGE("value string too long.");
253         return RET_ERROR;
254     }
255     if (memset_s(arg.value, ARGUMENT_VALUE_SIZE, '\0', ARGUMENT_NAME_SIZE) != EOK) {
256         DHCP_LOGE("failed to reset argument value.");
257         return RET_ERROR;
258     }
259     if (memcpy_s(arg.value, ARGUMENT_VALUE_SIZE, val, vlen) != EOK) {
260         DHCP_LOGE("failed to set argument value.");
261         return RET_ERROR;
262     }
263     int ret = Insert(&g_argumentsTable, (uintptr_t)arg.name, (uintptr_t)&arg);
264     if (ret == HASH_INSERTED) {
265         return RET_SUCCESS;
266     }
267     return RET_FAILED;
268 }
269 
FindIndex(int c)270 int FindIndex(int c)
271 {
272     int size = sizeof(g_longOptions) / sizeof(g_longOptions[0]);
273     for (int i = 0; i < size; ++i) {
274         if (g_longOptions[i].val == c) {
275             return i;
276         }
277     }
278     return -1;
279 }
280 
ParseArguments(const std::string & ifName,const std::string & netMask,const std::string & ipRange,const std::string & localIp)281 int ParseArguments(const std::string& ifName, const std::string& netMask, const std::string& ipRange,
282     const std::string& localIp)
283 {
284     DHCP_LOGI("start ParseArguments.");
285     PutArgument("ifname", ifName.c_str());
286     PutIpArgument("server", localIp.c_str());
287     PutIpArgument("netmask", netMask.c_str());
288     PutPoolArgument("pool", ipRange.c_str());
289     return 0;
290 }
291 
FreeArguments(void)292 void FreeArguments(void)
293 {
294     if (!Initialized(&g_argumentsTable)) {
295         return;
296     }
297     DestroyHashTable(&g_argumentsTable);
298 }
299