summaryrefslogtreecommitdiff
path: root/networking/udhcp/files.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-07-01 17:05:57 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-07-01 17:05:57 +0000
commitc82b5108e1a40f3b299043770e01d7d7db35de04 (patch)
tree35039a36868df644b8e5ffc766c1b0c921c88ab5 /networking/udhcp/files.c
parentdc7a5eae36d31f5cfc301de2499329b8a03ea660 (diff)
downloadbusybox-w32-c82b5108e1a40f3b299043770e01d7d7db35de04.tar.gz
busybox-w32-c82b5108e1a40f3b299043770e01d7d7db35de04.tar.bz2
busybox-w32-c82b5108e1a40f3b299043770e01d7d7db35de04.zip
udhcp: new config option "Rewrite the lease file at every new acknowledge"
(Mats Erik Andersson <mats@blue2net.com> (Blue2Net AB)) udhcp: consistently treat server_config.start/end IPs as host-order fix IP parsing for 64bit machines fix unsafe hton macro usage in read_opt() do not chdir("/") when daemonizing fix help text
Diffstat (limited to 'networking/udhcp/files.c')
-rw-r--r--networking/udhcp/files.c161
1 files changed, 92 insertions, 69 deletions
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index 41c8717cd..7fc734889 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -11,42 +11,30 @@
11#include "options.h" 11#include "options.h"
12 12
13 13
14/* 14/* on these functions, make sure your datatype matches */
15 * Domain names may have 254 chars, and string options can be 254
16 * chars long. However, 80 bytes will be enough for most, and won't
17 * hog up memory. If you have a special application, change it
18 */
19#define READ_CONFIG_BUF_SIZE 80
20
21/* on these functions, make sure you datatype matches */
22static int read_ip(const char *line, void *arg) 15static int read_ip(const char *line, void *arg)
23{ 16{
24 len_and_sockaddr *lsa; 17 len_and_sockaddr *lsa;
25 int retval = 0;
26 18
27 lsa = host_and_af2sockaddr(line, 0, AF_INET); 19 lsa = host_and_af2sockaddr(line, 0, AF_INET);
28 if (lsa) { 20 if (lsa) {
29 *(struct in_addr*)arg = lsa->sin.sin_addr; 21 *(uint32_t*)arg = lsa->sin.sin_addr.s_addr;
30 free(lsa); 22 free(lsa);
31 retval = 1; 23 return 1;
32 } 24 }
33 return retval; 25 return 0;
34} 26}
35 27
36static int read_mac(const char *line, void *arg) 28static int read_mac(const char *line, void *arg)
37{ 29{
38 uint8_t *mac_bytes = arg; 30 uint8_t *mac_bytes = arg;
39 struct ether_addr *temp_ether_addr; 31 struct ether_addr *temp_ether_addr;
40 int retval = 1;
41 32
42 temp_ether_addr = ether_aton(line); 33 temp_ether_addr = ether_aton(line);
43
44 if (temp_ether_addr == NULL) 34 if (temp_ether_addr == NULL)
45 retval = 0; 35 return 0;
46 else 36 memcpy(mac_bytes, temp_ether_addr, 6);
47 memcpy(mac_bytes, temp_ether_addr, 6); 37 return 1;
48
49 return retval;
50} 38}
51 39
52 40
@@ -56,14 +44,13 @@ static int read_str(const char *line, void *arg)
56 44
57 free(*dest); 45 free(*dest);
58 *dest = xstrdup(line); 46 *dest = xstrdup(line);
59
60 return 1; 47 return 1;
61} 48}
62 49
63 50
64static int read_u32(const char *line, void *arg) 51static int read_u32(const char *line, void *arg)
65{ 52{
66 *((uint32_t*)arg) = bb_strtou32(line, NULL, 10); 53 *(uint32_t*)arg = bb_strtou32(line, NULL, 10);
67 return errno == 0; 54 return errno == 0;
68} 55}
69 56
@@ -71,15 +58,16 @@ static int read_u32(const char *line, void *arg)
71static int read_yn(const char *line, void *arg) 58static int read_yn(const char *line, void *arg)
72{ 59{
73 char *dest = arg; 60 char *dest = arg;
74 int retval = 1;
75 61
76 if (!strcasecmp("yes", line)) 62 if (!strcasecmp("yes", line)) {
77 *dest = 1; 63 *dest = 1;
78 else if (!strcasecmp("no", line)) 64 return 1;
65 }
66 if (!strcasecmp("no", line)) {
79 *dest = 0; 67 *dest = 0;
80 else retval = 0; 68 return 1;
81 69 }
82 return retval; 70 return 0;
83} 71}
84 72
85 73
@@ -89,8 +77,9 @@ struct option_set *find_option(struct option_set *opt_list, char code)
89 while (opt_list && opt_list->data[OPT_CODE] < code) 77 while (opt_list && opt_list->data[OPT_CODE] < code)
90 opt_list = opt_list->next; 78 opt_list = opt_list->next;
91 79
92 if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list; 80 if (opt_list && opt_list->data[OPT_CODE] == code)
93 else return NULL; 81 return opt_list;
82 return NULL;
94} 83}
95 84
96 85
@@ -111,7 +100,7 @@ static void attach_option(struct option_set **opt_list,
111#endif 100#endif
112 101
113 /* make a new option */ 102 /* make a new option */
114 new = xmalloc(sizeof(struct option_set)); 103 new = xmalloc(sizeof(*new));
115 new->data = xmalloc(length + 2); 104 new->data = xmalloc(length + 2);
116 new->data[OPT_CODE] = option->code; 105 new->data[OPT_CODE] = option->code;
117 new->data[OPT_LEN] = length; 106 new->data[OPT_LEN] = length;
@@ -184,7 +173,7 @@ static int read_opt(const char *const_line, void *arg)
184 return 0; 173 return 0;
185 if (!strcasecmp(option->name, opt)) 174 if (!strcasecmp(option->name, opt))
186 break; 175 break;
187 option++; 176 option++;
188 } 177 }
189 178
190 do { 179 do {
@@ -199,8 +188,11 @@ static int read_opt(const char *const_line, void *arg)
199 break; 188 break;
200 case OPTION_IP_PAIR: 189 case OPTION_IP_PAIR:
201 retval = read_ip(val, buffer); 190 retval = read_ip(val, buffer);
202 if (!(val = strtok(NULL, ", \t/-"))) retval = 0; 191 val = strtok(NULL, ", \t/-");
203 if (retval) retval = read_ip(val, buffer + 4); 192 if (!val)
193 retval = 0;
194 if (retval)
195 retval = read_ip(val, buffer + 4);
204 break; 196 break;
205 case OPTION_STRING: 197 case OPTION_STRING:
206#if ENABLE_FEATURE_RFC3397 198#if ENABLE_FEATURE_RFC3397
@@ -220,22 +212,33 @@ static int read_opt(const char *const_line, void *arg)
220 buffer[0] = strtoul(val, &endptr, 0); 212 buffer[0] = strtoul(val, &endptr, 0);
221 retval = (endptr[0] == '\0'); 213 retval = (endptr[0] == '\0');
222 break; 214 break;
223 case OPTION_U16: 215 /* htonX are macros in older libc's, using temp var
224 *result_u16 = htons(strtoul(val, &endptr, 0)); 216 * in code below for safety */
225 retval = (endptr[0] == '\0'); 217 /* TODO: use bb_strtoX? */
218 case OPTION_U16: {
219 unsigned long tmp = strtoul(val, &endptr, 0);
220 *result_u16 = htons(tmp);
221 retval = (endptr[0] == '\0' /*&& tmp < 0x10000*/);
226 break; 222 break;
227 case OPTION_S16: 223 }
228 *result_u16 = htons(strtol(val, &endptr, 0)); 224 case OPTION_S16: {
225 long tmp = strtol(val, &endptr, 0);
226 *result_u16 = htons(tmp);
229 retval = (endptr[0] == '\0'); 227 retval = (endptr[0] == '\0');
230 break; 228 break;
231 case OPTION_U32: 229 }
232 *result_u32 = htonl(strtoul(val, &endptr, 0)); 230 case OPTION_U32: {
231 unsigned long tmp = strtoul(val, &endptr, 0);
232 *result_u32 = htonl(tmp);
233 retval = (endptr[0] == '\0'); 233 retval = (endptr[0] == '\0');
234 break; 234 break;
235 case OPTION_S32: 235 }
236 *result_u32 = htonl(strtol(val, &endptr, 0)); 236 case OPTION_S32: {
237 long tmp = strtol(val, &endptr, 0);
238 *result_u32 = htonl(tmp);
237 retval = (endptr[0] == '\0'); 239 retval = (endptr[0] == '\0');
238 break; 240 break;
241 }
239 default: 242 default:
240 break; 243 break;
241 } 244 }
@@ -253,7 +256,6 @@ static int read_staticlease(const char *const_line, void *arg)
253 uint8_t *mac_bytes; 256 uint8_t *mac_bytes;
254 uint32_t *ip; 257 uint32_t *ip;
255 258
256
257 /* Allocate memory for addresses */ 259 /* Allocate memory for addresses */
258 mac_bytes = xmalloc(sizeof(unsigned char) * 8); 260 mac_bytes = xmalloc(sizeof(unsigned char) * 8);
259 ip = xmalloc(sizeof(uint32_t)); 261 ip = xmalloc(sizeof(uint32_t));
@@ -275,39 +277,54 @@ static int read_staticlease(const char *const_line, void *arg)
275} 277}
276 278
277 279
280struct config_keyword {
281 const char *keyword;
282 int (*handler)(const char *line, void *var);
283 void *var;
284 const char *def;
285};
286
278static const struct config_keyword keywords[] = { 287static const struct config_keyword keywords[] = {
279 /* keyword handler variable address default */ 288 /* keyword handler variable address default */
280 {"start", read_ip, &(server_config.start), "192.168.0.20"}, 289 {"start", read_ip, &(server_config.start_ip), "192.168.0.20"},
281 {"end", read_ip, &(server_config.end), "192.168.0.254"}, 290 {"end", read_ip, &(server_config.end_ip), "192.168.0.254"},
282 {"interface", read_str, &(server_config.interface), "eth0"}, 291 {"interface", read_str, &(server_config.interface), "eth0"},
283 {"option", read_opt, &(server_config.options), ""}, 292 {"option", read_opt, &(server_config.options), ""},
284 {"opt", read_opt, &(server_config.options), ""}, 293 {"opt", read_opt, &(server_config.options), ""},
285 {"max_leases", read_u32, &(server_config.max_leases), "254"}, 294 /* Avoid "max_leases value not sane" warning by setting default
286 {"remaining", read_yn, &(server_config.remaining), "yes"}, 295 * to default_end_ip - default_start_ip + 1: */
287 {"auto_time", read_u32, &(server_config.auto_time), "7200"}, 296 {"max_leases", read_u32, &(server_config.max_leases), "235"},
288 {"decline_time",read_u32, &(server_config.decline_time),"3600"}, 297 {"remaining", read_yn, &(server_config.remaining), "yes"},
289 {"conflict_time",read_u32,&(server_config.conflict_time),"3600"}, 298 {"auto_time", read_u32, &(server_config.auto_time), "7200"},
290 {"offer_time", read_u32, &(server_config.offer_time), "60"}, 299 {"decline_time", read_u32, &(server_config.decline_time), "3600"},
291 {"min_lease", read_u32, &(server_config.min_lease), "60"}, 300 {"conflict_time",read_u32, &(server_config.conflict_time),"3600"},
292 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE}, 301 {"offer_time", read_u32, &(server_config.offer_time), "60"},
293 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"}, 302 {"min_lease", read_u32, &(server_config.min_lease), "60"},
294 {"notify_file", read_str, &(server_config.notify_file), ""}, 303 {"lease_file", read_str, &(server_config.lease_file), LEASES_FILE},
295 {"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"}, 304 {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
296 {"sname", read_str, &(server_config.sname), ""}, 305 {"notify_file", read_str, &(server_config.notify_file), ""},
297 {"boot_file", read_str, &(server_config.boot_file), ""}, 306 {"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"},
298 {"static_lease",read_staticlease, &(server_config.static_leases), ""}, 307 {"sname", read_str, &(server_config.sname), ""},
299 /*ADDME: static lease */ 308 {"boot_file", read_str, &(server_config.boot_file), ""},
300 {"", NULL, NULL, ""} 309 {"static_lease", read_staticlease, &(server_config.static_leases), ""},
310 /* ADDME: static lease */
301}; 311};
302 312
303 313
314/*
315 * Domain names may have 254 chars, and string options can be 254
316 * chars long. However, 80 bytes will be enough for most, and won't
317 * hog up memory. If you have a special application, change it
318 */
319#define READ_CONFIG_BUF_SIZE 80
320
304int read_config(const char *file) 321int read_config(const char *file)
305{ 322{
306 FILE *in; 323 FILE *in;
307 char buffer[READ_CONFIG_BUF_SIZE], *token, *line; 324 char buffer[READ_CONFIG_BUF_SIZE], *token, *line;
308 int i, lm = 0; 325 int i, lm = 0;
309 326
310 for (i = 0; keywords[i].keyword[0]; i++) 327 for (i = 0; i < ARRAY_SIZE(keywords); i++)
311 if (keywords[i].def[0]) 328 if (keywords[i].def[0])
312 keywords[i].handler(keywords[i].def, keywords[i].var); 329 keywords[i].handler(keywords[i].def, keywords[i].var);
313 330
@@ -337,7 +354,7 @@ int read_config(const char *file)
337 while (i >= 0 && isspace(line[i])) 354 while (i >= 0 && isspace(line[i]))
338 line[i--] = '\0'; 355 line[i--] = '\0';
339 356
340 for (i = 0; keywords[i].keyword[0]; i++) 357 for (i = 0; i < ARRAY_SIZE(keywords); i++)
341 if (!strcasecmp(token, keywords[i].keyword)) 358 if (!strcasecmp(token, keywords[i].keyword))
342 if (!keywords[i].handler(line, keywords[i].var)) { 359 if (!keywords[i].handler(line, keywords[i].var)) {
343 bb_error_msg("cannot parse line %d of %s", lm, file); 360 bb_error_msg("cannot parse line %d of %s", lm, file);
@@ -348,6 +365,10 @@ int read_config(const char *file)
348 } 365 }
349 } 366 }
350 fclose(in); 367 fclose(in);
368
369 server_config.start_ip = ntohl(server_config.start_ip);
370 server_config.end_ip = ntohl(server_config.end_ip);
371
351 return 1; 372 return 1;
352} 373}
353 374
@@ -408,9 +429,11 @@ void read_leases(const char *file)
408 && full_read(fp, &lease, sizeof(lease)) == sizeof(lease) 429 && full_read(fp, &lease, sizeof(lease)) == sizeof(lease)
409 ) { 430 ) {
410 /* ADDME: is it a static lease */ 431 /* ADDME: is it a static lease */
411 if (lease.yiaddr >= server_config.start && lease.yiaddr <= server_config.end) { 432 uint32_t y = ntohl(lease.yiaddr);
433 if (y >= server_config.start_ip && y <= server_config.end_ip) {
412 lease.expires = ntohl(lease.expires); 434 lease.expires = ntohl(lease.expires);
413 if (!server_config.remaining) lease.expires -= time(0); 435 if (!server_config.remaining)
436 lease.expires -= time(0);
414 if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) { 437 if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) {
415 bb_error_msg("too many leases while loading %s", file); 438 bb_error_msg("too many leases while loading %s", file);
416 break; 439 break;