aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/common.c')
-rw-r--r--networking/udhcp/common.c27
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 */
148const uint8_t dhcp_option_lengths[] ALIGN1 = { 148const 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 */