diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-26 08:35:24 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-26 08:35:24 +0100 |
commit | a8f6b9998727ad67db4b812270a1bbceea011dde (patch) | |
tree | fbe3633852270c9fd33674513fdb289a617697ad /networking/udhcp/files.c | |
parent | 7e6add1dfca95183bf409820066fab975979bf06 (diff) | |
download | busybox-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.c | 212 |
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 */ |
25 | static 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 | |||
37 | static int FAST_FUNC read_str(const char *line, void *arg) | 25 | static 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 | ||
52 | static 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 */ | ||
68 | struct 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 */ | ||
79 | static 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 */ | ||
148 | int 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 | |||
244 | static int FAST_FUNC read_staticlease(const char *const_line, void *arg) | 40 | static 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 | ||
278 | static const struct config_keyword keywords[] = { | 74 | static 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), ""}, |