aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/files.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-03-26 08:35:24 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-03-26 08:35:24 +0100
commita8f6b9998727ad67db4b812270a1bbceea011dde (patch)
treefbe3633852270c9fd33674513fdb289a617697ad /networking/udhcp/files.c
parent7e6add1dfca95183bf409820066fab975979bf06 (diff)
downloadbusybox-w32-a8f6b9998727ad67db4b812270a1bbceea011dde.tar.gz
busybox-w32-a8f6b9998727ad67db4b812270a1bbceea011dde.tar.bz2
busybox-w32-a8f6b9998727ad67db4b812270a1bbceea011dde.zip
udhcp: move options.c to common.c; disable unused bool and s16 option code
function old new delta udhcp_add_binary_option - 94 +94 udhcp_str2nip - 42 +42 len_of_option_as_string 12 10 -2 dhcp_option_lengths 12 10 -2 udhcpc_main 2859 2851 -8 read_nip 42 - -42 xmalloc_optname_optval 590 536 -54 udhcp_str2optset 443 366 -77 udhcp_add_option_string 86 - -86 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 0/5 up/down: 136/-271) Total: -135 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/udhcp/files.c')
-rw-r--r--networking/udhcp/files.c212
1 files changed, 4 insertions, 208 deletions
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index fddda4cba..1f25bb105 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -22,18 +22,6 @@ static inline uint64_t hton64(uint64_t v)
22#define ntoh64(v) hton64(v) 22#define ntoh64(v) hton64(v)
23 23
24/* on these functions, make sure your datatype matches */ 24/* on these functions, make sure your datatype matches */
25static int FAST_FUNC read_nip(const char *line, void *arg)
26{
27 len_and_sockaddr *lsa;
28
29 lsa = host_and_af2sockaddr(line, 0, AF_INET);
30 if (!lsa)
31 return 0;
32 *(uint32_t*)arg = lsa->u.sin.sin_addr.s_addr;
33 free(lsa);
34 return 1;
35}
36
37static int FAST_FUNC read_str(const char *line, void *arg) 25static int FAST_FUNC read_str(const char *line, void *arg)
38{ 26{
39 char **dest = arg; 27 char **dest = arg;
@@ -49,198 +37,6 @@ static int FAST_FUNC read_u32(const char *line, void *arg)
49 return errno == 0; 37 return errno == 0;
50} 38}
51 39
52static int read_yn(const char *line, void *arg)
53{
54 char *dest = arg;
55
56 if (strcasecmp("yes", line) == 0) {
57 *dest = 1;
58 return 1;
59 }
60 if (strcasecmp("no", line) == 0) {
61 *dest = 0;
62 return 1;
63 }
64 return 0;
65}
66
67/* find option 'code' in opt_list */
68struct option_set* FAST_FUNC find_option(struct option_set *opt_list, uint8_t code)
69{
70 while (opt_list && opt_list->data[OPT_CODE] < code)
71 opt_list = opt_list->next;
72
73 if (opt_list && opt_list->data[OPT_CODE] == code)
74 return opt_list;
75 return NULL;
76}
77
78/* add an option to the opt_list */
79static NOINLINE void attach_option(
80 struct option_set **opt_list,
81 const struct dhcp_option *option,
82 char *buffer,
83 int length)
84{
85 struct option_set *existing, *new, **curr;
86#if ENABLE_FEATURE_UDHCP_RFC3397
87 char *allocated = NULL;
88#endif
89
90 existing = find_option(*opt_list, option->code);
91 if (!existing) {
92 log2("Attaching option %02x to list", option->code);
93#if ENABLE_FEATURE_UDHCP_RFC3397
94 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035) {
95 /* reuse buffer and length for RFC1035-formatted string */
96 allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length);
97 }
98#endif
99 /* make a new option */
100 new = xmalloc(sizeof(*new));
101 new->data = xmalloc(length + OPT_DATA);
102 new->data[OPT_CODE] = option->code;
103 new->data[OPT_LEN] = length;
104 memcpy(new->data + OPT_DATA, buffer, length);
105
106 curr = opt_list;
107 while (*curr && (*curr)->data[OPT_CODE] < option->code)
108 curr = &(*curr)->next;
109
110 new->next = *curr;
111 *curr = new;
112 goto ret;
113 }
114
115 if (option->flags & OPTION_LIST) {
116 unsigned old_len;
117
118 /* add it to an existing option */
119 log1("Attaching option %02x to existing member of list", option->code);
120 old_len = existing->data[OPT_LEN];
121#if ENABLE_FEATURE_UDHCP_RFC3397
122 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STR1035) {
123 /* reuse buffer and length for RFC1035-formatted string */
124 allocated = buffer = (char *)dname_enc(existing->data + OPT_DATA, old_len, buffer, &length);
125 }
126#endif
127 if (old_len + length < 255) {
128 /* actually 255 is ok too, but adding a space can overlow it */
129
130 existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length);
131 if ((option->flags & OPTION_TYPE_MASK) == OPTION_STRING) {
132 /* add space separator between STRING options in a list */
133 existing->data[OPT_DATA + old_len] = ' ';
134 old_len++;
135 }
136 memcpy(existing->data + OPT_DATA + old_len, buffer, length);
137 existing->data[OPT_LEN] = old_len + length;
138 } /* else, ignore the data, we could put this in a second option in the future */
139 } /* else, ignore the new data */
140
141 ret: ;
142#if ENABLE_FEATURE_UDHCP_RFC3397
143 free(allocated);
144#endif
145}
146
147/* read a dhcp option and add it to opt_list */
148int FAST_FUNC udhcp_str2optset(const char *const_line, void *arg)
149{
150 struct option_set **opt_list = arg;
151 char *opt, *val, *endptr;
152 char *line;
153 const struct dhcp_option *option;
154 int retval, length, idx;
155 char buffer[8] ALIGNED(4);
156 uint16_t *result_u16 = (uint16_t *) buffer;
157 uint32_t *result_u32 = (uint32_t *) buffer;
158
159 /* Cheat, the only *const* line possible is "" */
160 line = (char *) const_line;
161 opt = strtok(line, " \t=");
162 if (!opt)
163 return 0;
164
165 idx = index_in_strings(dhcp_option_strings, opt); /* NB: was strcasecmp! */
166 if (idx < 0)
167 return 0;
168 option = &dhcp_options[idx];
169
170 retval = 0;
171 do {
172 val = strtok(NULL, ", \t");
173 if (!val)
174 break;
175 length = dhcp_option_lengths[option->flags & OPTION_TYPE_MASK];
176 retval = 0;
177 opt = buffer; /* new meaning for variable opt */
178 switch (option->flags & OPTION_TYPE_MASK) {
179 case OPTION_IP:
180 retval = read_nip(val, buffer);
181 break;
182 case OPTION_IP_PAIR:
183 retval = read_nip(val, buffer);
184 val = strtok(NULL, ", \t/-");
185 if (!val)
186 retval = 0;
187 if (retval)
188 retval = read_nip(val, buffer + 4);
189 break;
190 case OPTION_STRING:
191#if ENABLE_FEATURE_UDHCP_RFC3397
192 case OPTION_STR1035:
193#endif
194 length = strnlen(val, 254);
195 if (length > 0) {
196 opt = val;
197 retval = 1;
198 }
199 break;
200 case OPTION_BOOLEAN:
201 retval = read_yn(val, buffer);
202 break;
203 case OPTION_U8:
204 buffer[0] = strtoul(val, &endptr, 0);
205 retval = (endptr[0] == '\0');
206 break;
207 /* htonX are macros in older libc's, using temp var
208 * in code below for safety */
209 /* TODO: use bb_strtoX? */
210 case OPTION_U16: {
211 unsigned long tmp = strtoul(val, &endptr, 0);
212 *result_u16 = htons(tmp);
213 retval = (endptr[0] == '\0' /*&& tmp < 0x10000*/);
214 break;
215 }
216 case OPTION_S16: {
217 long tmp = strtol(val, &endptr, 0);
218 *result_u16 = htons(tmp);
219 retval = (endptr[0] == '\0');
220 break;
221 }
222 case OPTION_U32: {
223 unsigned long tmp = strtoul(val, &endptr, 0);
224 *result_u32 = htonl(tmp);
225 retval = (endptr[0] == '\0');
226 break;
227 }
228 case OPTION_S32: {
229 long tmp = strtol(val, &endptr, 0);
230 *result_u32 = htonl(tmp);
231 retval = (endptr[0] == '\0');
232 break;
233 }
234 default:
235 break;
236 }
237 if (retval)
238 attach_option(opt_list, option, opt, length);
239 } while (retval && option->flags & OPTION_LIST);
240
241 return retval;
242}
243
244static int FAST_FUNC read_staticlease(const char *const_line, void *arg) 40static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
245{ 41{
246 char *line; 42 char *line;
@@ -257,7 +53,7 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
257 53
258 /* Read ip */ 54 /* Read ip */
259 ip_string = strtok_r(NULL, " \t", &line); 55 ip_string = strtok_r(NULL, " \t", &line);
260 if (!ip_string || !read_nip(ip_string, &nip)) 56 if (!ip_string || !udhcp_str2nip(ip_string, &nip))
261 return 0; 57 return 0;
262 58
263 add_static_lease(arg, (uint8_t*) &mac_bytes, nip); 59 add_static_lease(arg, (uint8_t*) &mac_bytes, nip);
@@ -277,8 +73,8 @@ struct config_keyword {
277 73
278static const struct config_keyword keywords[] = { 74static const struct config_keyword keywords[] = {
279 /* keyword handler variable address default */ 75 /* keyword handler variable address default */
280 {"start", read_nip, &(server_config.start_ip), "192.168.0.20"}, 76 {"start", udhcp_str2nip, &(server_config.start_ip), "192.168.0.20"},
281 {"end", read_nip, &(server_config.end_ip), "192.168.0.254"}, 77 {"end", udhcp_str2nip, &(server_config.end_ip), "192.168.0.254"},
282 {"interface", read_str, &(server_config.interface), "eth0"}, 78 {"interface", read_str, &(server_config.interface), "eth0"},
283 /* Avoid "max_leases value not sane" warning by setting default 79 /* Avoid "max_leases value not sane" warning by setting default
284 * to default_end_ip - default_start_ip + 1: */ 80 * to default_end_ip - default_start_ip + 1: */
@@ -290,7 +86,7 @@ static const struct config_keyword keywords[] = {
290 {"min_lease", read_u32, &(server_config.min_lease_sec),"60"}, 86 {"min_lease", read_u32, &(server_config.min_lease_sec),"60"},
291 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE}, 87 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
292 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, 88 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
293 {"siaddr", read_nip, &(server_config.siaddr_nip), "0.0.0.0"}, 89 {"siaddr", udhcp_str2nip, &(server_config.siaddr_nip), "0.0.0.0"},
294 /* keywords with no defaults must be last! */ 90 /* keywords with no defaults must be last! */
295 {"option", udhcp_str2optset, &(server_config.options), ""}, 91 {"option", udhcp_str2optset, &(server_config.options), ""},
296 {"opt", udhcp_str2optset, &(server_config.options), ""}, 92 {"opt", udhcp_str2optset, &(server_config.options), ""},