diff options
Diffstat (limited to 'networking/udhcp/common.c')
-rw-r--r-- | networking/udhcp/common.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index bc41c8d4d..0cf4dab63 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -142,7 +142,7 @@ const char dhcp_option_strings[] ALIGN1 = | |||
142 | * udhcp_str2optset: to determine how many bytes to allocate. | 142 | * udhcp_str2optset: to determine how many bytes to allocate. |
143 | * xmalloc_optname_optval: to estimate string length | 143 | * xmalloc_optname_optval: to estimate string length |
144 | * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type]) | 144 | * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type]) |
145 | * is the number of elements, multiply in by one element's string width | 145 | * is the number of elements, multiply it by one element's string width |
146 | * (len_of_option_as_string[opt_type]) and you know how wide string you need. | 146 | * (len_of_option_as_string[opt_type]) and you know how wide string you need. |
147 | */ | 147 | */ |
148 | const uint8_t dhcp_option_lengths[] ALIGN1 = { | 148 | const uint8_t dhcp_option_lengths[] ALIGN1 = { |
@@ -162,7 +162,18 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { | |||
162 | [OPTION_S32] = 4, | 162 | [OPTION_S32] = 4, |
163 | /* Just like OPTION_STRING, we use minimum length here */ | 163 | /* Just like OPTION_STRING, we use minimum length here */ |
164 | [OPTION_STATIC_ROUTES] = 5, | 164 | [OPTION_STATIC_ROUTES] = 5, |
165 | [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ | 165 | [OPTION_6RD] = 12, /* ignored by udhcp_str2optset */ |
166 | /* The above value was chosen as follows: | ||
167 | * len_of_option_as_string[] for this option is >60: it's a string of the form | ||
168 | * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ". | ||
169 | * Each additional ipv4 address takes 4 bytes in binary option and appends | ||
170 | * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 4 | ||
171 | * but this severely overestimates string length: instead of 16 bytes, | ||
172 | * it adds >60 for every 4 bytes in binary option. | ||
173 | * We cheat and declare here that option is in units of 12 bytes. | ||
174 | * This adds more than 60 bytes for every three ipv4 addresses - more than enough. | ||
175 | * (Even 16 instead of 12 should work, but let's be paranoid). | ||
176 | */ | ||
166 | }; | 177 | }; |
167 | 178 | ||
168 | 179 | ||
@@ -172,7 +183,7 @@ static void log_option(const char *pfx, const uint8_t *opt) | |||
172 | if (dhcp_verbose >= 2) { | 183 | if (dhcp_verbose >= 2) { |
173 | char buf[256 * 2 + 2]; | 184 | char buf[256 * 2 + 2]; |
174 | *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; | 185 | *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; |
175 | bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); | 186 | bb_error_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); |
176 | } | 187 | } |
177 | } | 188 | } |
178 | #else | 189 | #else |
@@ -246,7 +257,7 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
246 | continue; /* complain and return NULL */ | 257 | continue; /* complain and return NULL */ |
247 | 258 | ||
248 | if (optionptr[OPT_CODE] == code) { | 259 | if (optionptr[OPT_CODE] == code) { |
249 | log_option("Option found", optionptr); | 260 | log_option("option found", optionptr); |
250 | return optionptr + OPT_DATA; | 261 | return optionptr + OPT_DATA; |
251 | } | 262 | } |
252 | 263 | ||
@@ -258,7 +269,7 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
258 | } | 269 | } |
259 | 270 | ||
260 | /* log3 because udhcpc uses it a lot - very noisy */ | 271 | /* log3 because udhcpc uses it a lot - very noisy */ |
261 | log3("Option 0x%02x not found", code); | 272 | log3("option 0x%02x not found", code); |
262 | return NULL; | 273 | return NULL; |
263 | } | 274 | } |
264 | 275 | ||
@@ -292,7 +303,7 @@ void FAST_FUNC udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addo | |||
292 | addopt[OPT_CODE]); | 303 | addopt[OPT_CODE]); |
293 | return; | 304 | return; |
294 | } | 305 | } |
295 | log_option("Adding option", addopt); | 306 | log_option("adding option", addopt); |
296 | memcpy(optionptr + end, addopt, len); | 307 | memcpy(optionptr + end, addopt, len); |
297 | optionptr[end + len] = DHCP_END; | 308 | optionptr[end + len] = DHCP_END; |
298 | } | 309 | } |
@@ -391,7 +402,7 @@ static NOINLINE void attach_option( | |||
391 | struct option_set *new, **curr; | 402 | struct option_set *new, **curr; |
392 | 403 | ||
393 | /* make a new option */ | 404 | /* make a new option */ |
394 | log2("Attaching option %02x to list", optflag->code); | 405 | log2("attaching option %02x to list", optflag->code); |
395 | new = xmalloc(sizeof(*new)); | 406 | new = xmalloc(sizeof(*new)); |
396 | new->data = xmalloc(length + OPT_DATA); | 407 | new->data = xmalloc(length + OPT_DATA); |
397 | new->data[OPT_CODE] = optflag->code; | 408 | new->data[OPT_CODE] = optflag->code; |
@@ -411,7 +422,7 @@ static NOINLINE void attach_option( | |||
411 | unsigned old_len; | 422 | unsigned old_len; |
412 | 423 | ||
413 | /* add it to an existing option */ | 424 | /* add it to an existing option */ |
414 | log2("Attaching option %02x to existing member of list", optflag->code); | 425 | log2("attaching option %02x to existing member of list", optflag->code); |
415 | old_len = existing->data[OPT_LEN]; | 426 | old_len = existing->data[OPT_LEN]; |
416 | if (old_len + length < 255) { | 427 | if (old_len + length < 255) { |
417 | /* actually 255 is ok too, but adding a space can overlow it */ | 428 | /* actually 255 is ok too, but adding a space can overlow it */ |