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 <map>
18 #include <getopt.h>
19 #include <securec.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <cstdio>
23 #include <string.h>
24 #include "address_utils.h"
25 #include "dhcp_s_define.h"
26 #include "dhcp_logger.h"
27
28 DEFINE_DHCPLOG_DHCP_LABEL("DhcpArgument");
29
30 static std::map<std::string, ArgumentInfo> 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
HasArgument(const char * argument)53 int HasArgument(const char *argument)
54 {
55 char name[ARGUMENT_NAME_SIZE] = {'\0'};
56 if (!argument) {
57 return 0;
58 }
59 size_t ssize = strlen(argument);
60 if (ssize > ARGUMENT_NAME_SIZE) {
61 ssize = ARGUMENT_NAME_SIZE;
62 }
63 if (memcpy_s(name, ARGUMENT_NAME_SIZE, argument, ssize) != EOK) {
64 DHCP_LOGE("failed to set argument name.");
65 return 0;
66 }
67 if (g_argumentsTable.empty()) {
68 return 0;
69 }
70 if (g_argumentsTable.count(name) > 0) {
71 return 1;
72 }
73 return 0;
74 }
75
InitArguments(void)76 int InitArguments(void)
77 {
78 DHCP_LOGI("start InitArguments.");
79 g_argumentsTable.clear();
80 DHCP_LOGI("end InitArguments.");
81 return RET_SUCCESS;
82 }
83
GetArgument(const char * name)84 ArgumentInfo *GetArgument(const char *name)
85 {
86 char argName[ARGUMENT_NAME_SIZE] = {'\0'};
87 size_t ssize = strlen(name);
88 if (ssize > ARGUMENT_NAME_SIZE) {
89 ssize = ARGUMENT_NAME_SIZE;
90 }
91 if (memcpy_s(argName, ARGUMENT_NAME_SIZE, name, ssize) != EOK) {
92 DHCP_LOGE("failed to set argument name.");
93 return nullptr;
94 }
95 if (g_argumentsTable.count(argName) > 0) {
96 return &g_argumentsTable[argName];
97 }
98 return nullptr;
99 }
100
PutArgument(const char * argument,const char * val)101 int PutArgument(const char *argument, const char *val)
102 {
103 DHCP_LOGI("start PutArgument.");
104 if (!argument) {
105 return RET_FAILED;
106 }
107 if (!val) {
108 return RET_FAILED;
109 }
110
111 if (HasArgument(argument)) {
112 return RET_FAILED;
113 }
114
115 ArgumentInfo arg;
116 size_t ssize = strlen(argument);
117 if (ssize >= ARGUMENT_NAME_SIZE) {
118 ssize = ARGUMENT_NAME_SIZE -1;
119 }
120 size_t vlen = strlen(val);
121 if (memset_s(arg.name, ARGUMENT_NAME_SIZE, '\0', ARGUMENT_NAME_SIZE) != EOK) {
122 DHCP_LOGE("failed to reset argument name.");
123 return RET_ERROR;
124 }
125 if (memcpy_s(arg.name, ARGUMENT_NAME_SIZE, argument, ssize) != EOK) {
126 DHCP_LOGE("failed to set argument name.");
127 return RET_ERROR;
128 }
129 if (vlen >= ARGUMENT_VALUE_SIZE) {
130 DHCP_LOGE("value string too long.");
131 return RET_ERROR;
132 }
133 if (memset_s(arg.value, ARGUMENT_VALUE_SIZE, '\0', ARGUMENT_NAME_SIZE) != EOK) {
134 DHCP_LOGE("failed to reset argument value.");
135 return RET_ERROR;
136 }
137 if (memcpy_s(arg.value, ARGUMENT_VALUE_SIZE, val, vlen) != EOK) {
138 DHCP_LOGE("failed to set argument value.");
139 return RET_ERROR;
140 }
141 g_argumentsTable[std::string(arg.name)] = arg;
142 return RET_SUCCESS;
143 }
144
ParseArguments(const std::string & ifName,const std::string & netMask,const std::string & ipRange,const std::string & localIp)145 int ParseArguments(const std::string& ifName, const std::string& netMask, const std::string& ipRange,
146 const std::string& localIp)
147 {
148 DHCP_LOGI("start ParseArguments.");
149 PutArgument("ifname", ifName.c_str());
150 PutIpArgument("server", localIp.c_str());
151 PutIpArgument("netmask", netMask.c_str());
152 PutPoolArgument("pool", ipRange.c_str());
153 return 0;
154 }
155
FreeArguments(void)156 void FreeArguments(void)
157 {
158 g_argumentsTable.clear();
159 }
160