diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-11-16 20:17:12 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-11-16 20:17:12 +0100 |
commit | a092a89d8f052072e562861f2968573d89e10dd5 (patch) | |
tree | 43e7300d1825899e5c95ae9f557d0e2d1efde228 /networking/udhcp | |
parent | 39b233182c0a13200be051b993da181a1db80a87 (diff) | |
download | busybox-w32-a092a89d8f052072e562861f2968573d89e10dd5.tar.gz busybox-w32-a092a89d8f052072e562861f2968573d89e10dd5.tar.bz2 busybox-w32-a092a89d8f052072e562861f2968573d89e10dd5.zip |
udhcpc6: rudimentary code to export data to script; fix IAADDR parsing
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/udhcp')
-rw-r--r-- | networking/udhcp/common.c | 19 | ||||
-rw-r--r-- | networking/udhcp/common.h | 3 | ||||
-rw-r--r-- | networking/udhcp/d6_common.h | 5 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 126 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 18 |
5 files changed, 131 insertions, 40 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 2e6113627..a89dce3ae 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -539,3 +539,22 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) | |||
539 | 539 | ||
540 | return retval; | 540 | return retval; |
541 | } | 541 | } |
542 | |||
543 | /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ | ||
544 | int FAST_FUNC sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) | ||
545 | { | ||
546 | char hexstrbuf[16 * 2]; | ||
547 | bin2hex(hexstrbuf, (void*)ip, 16); | ||
548 | return sprintf(dest, /* "%s" */ | ||
549 | "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", | ||
550 | /* pre, */ | ||
551 | hexstrbuf + 0 * 4, | ||
552 | hexstrbuf + 1 * 4, | ||
553 | hexstrbuf + 2 * 4, | ||
554 | hexstrbuf + 3 * 4, | ||
555 | hexstrbuf + 4 * 4, | ||
556 | hexstrbuf + 5 * 4, | ||
557 | hexstrbuf + 6 * 4, | ||
558 | hexstrbuf + 7 * 4 | ||
559 | ); | ||
560 | } | ||
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index a7f9395b8..479ae49f3 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -308,6 +308,9 @@ int arpping(uint32_t test_nip, | |||
308 | uint8_t *from_mac, | 308 | uint8_t *from_mac, |
309 | const char *interface) FAST_FUNC; | 309 | const char *interface) FAST_FUNC; |
310 | 310 | ||
311 | /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ | ||
312 | int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC; | ||
313 | |||
311 | POP_SAVED_FUNCTION_VISIBILITY | 314 | POP_SAVED_FUNCTION_VISIBILITY |
312 | 315 | ||
313 | #endif | 316 | #endif |
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h index 36d822f7e..4dd7e621e 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h | |||
@@ -81,11 +81,16 @@ struct d6_option { | |||
81 | #define D6_OPT_RECONF_MSG 19 | 81 | #define D6_OPT_RECONF_MSG 19 |
82 | #define D6_OPT_RECONF_ACCEPT 20 | 82 | #define D6_OPT_RECONF_ACCEPT 20 |
83 | 83 | ||
84 | #define D6_OPT_IA_PD 25 | ||
85 | #define D6_OPT_IAPREFIX 26 | ||
86 | |||
84 | /*** Other shared functions ***/ | 87 | /*** Other shared functions ***/ |
85 | 88 | ||
86 | struct client6_data_t { | 89 | struct client6_data_t { |
87 | struct d6_option *server_id; | 90 | struct d6_option *server_id; |
88 | struct d6_option *ia_na; | 91 | struct d6_option *ia_na; |
92 | char **env_ptr; | ||
93 | unsigned env_idx; | ||
89 | }; | 94 | }; |
90 | 95 | ||
91 | #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) | 96 | #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 5c98e82f1..23e6862dc 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -129,32 +129,114 @@ static void *d6_store_blob(void *dst, const void *src, unsigned len) | |||
129 | 129 | ||
130 | /*** Script execution code ***/ | 130 | /*** Script execution code ***/ |
131 | 131 | ||
132 | static char** new_env(void) | ||
133 | { | ||
134 | client6_data.env_ptr = xrealloc_vector(client6_data.env_ptr, 3, client6_data.env_idx); | ||
135 | return &client6_data.env_ptr[client6_data.env_idx++]; | ||
136 | } | ||
137 | |||
132 | /* put all the parameters into the environment */ | 138 | /* put all the parameters into the environment */ |
133 | static char **fill_envp(struct d6_packet *packet | 139 | static void option_to_env(uint8_t *option, uint8_t *option_end) |
134 | UNUSED_PARAM | ||
135 | ) | ||
136 | { | 140 | { |
137 | int envc; | 141 | /* "length minus 4" */ |
138 | char **envp, **curr; | 142 | int len_m4 = option_end - option - 4; |
143 | while (len_m4 >= 0) { | ||
144 | uint32_t v32; | ||
145 | char ipv6str[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]; | ||
139 | 146 | ||
140 | #define BITMAP unsigned | 147 | if (option[0] != 0 || option[2] != 0) |
141 | #define BBITS (sizeof(BITMAP) * 8) | 148 | break; |
142 | #define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1))) | 149 | |
143 | #define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS]) | 150 | switch (option[1]) { |
144 | ///BITMAP found_opts[256 / BBITS]; | 151 | //case D6_OPT_CLIENTID: |
152 | //case D6_OPT_SERVERID: | ||
153 | case D6_OPT_IA_NA: | ||
154 | case D6_OPT_IA_PD: | ||
155 | option_to_env(option + 16, option + 4 + option[3]); | ||
156 | break; | ||
157 | //case D6_OPT_IA_TA: | ||
158 | case D6_OPT_IAADDR: | ||
159 | /* 0 1 2 3 | ||
160 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
161 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
162 | * | OPTION_IAADDR | option-len | | ||
163 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
164 | * | | | ||
165 | * | IPv6 address | | ||
166 | * | | | ||
167 | * | | | ||
168 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
169 | * | preferred-lifetime | | ||
170 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
171 | * | valid-lifetime | | ||
172 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
173 | */ | ||
174 | sprint_nip6(ipv6str, option + 4); | ||
175 | *new_env() = xasprintf("ipv6=%s", ipv6str); | ||
176 | |||
177 | move_from_unaligned32(v32, option + 4 + 16 + 4); | ||
178 | *new_env() = xasprintf("lease=%u", (unsigned)v32); | ||
179 | break; | ||
180 | |||
181 | //case D6_OPT_ORO: | ||
182 | //case D6_OPT_PREFERENCE: | ||
183 | //case D6_OPT_ELAPSED_TIME: | ||
184 | //case D6_OPT_RELAY_MSG: | ||
185 | //case D6_OPT_AUTH: | ||
186 | //case D6_OPT_UNICAST: | ||
187 | //case D6_OPT_STATUS_CODE: | ||
188 | //case D6_OPT_RAPID_COMMIT: | ||
189 | //case D6_OPT_USER_CLASS: | ||
190 | //case D6_OPT_VENDOR_CLASS: | ||
191 | //case D6_OPT_VENDOR_OPTS: | ||
192 | //case D6_OPT_INTERFACE_ID: | ||
193 | //case D6_OPT_RECONF_MSG: | ||
194 | //case D6_OPT_RECONF_ACCEPT: | ||
195 | |||
196 | case D6_OPT_IAPREFIX: | ||
197 | /* 0 1 2 3 | ||
198 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
199 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
200 | * | OPTION_IAPREFIX | option-length | | ||
201 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
202 | * | preferred-lifetime | | ||
203 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
204 | * | valid-lifetime | | ||
205 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
206 | * | prefix-length | | | ||
207 | * +-+-+-+-+-+-+-+-+ IPv6 prefix | | ||
208 | * | (16 octets) | | ||
209 | * | | | ||
210 | * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
211 | * | | | ||
212 | * +-+-+-+-+-+-+-+-+ | ||
213 | */ | ||
214 | //move_from_unaligned32(v32, option + 4 + 4); | ||
215 | //*new_env() = xasprintf("lease=%u", (unsigned)v32); | ||
145 | 216 | ||
146 | ///memset(found_opts, 0, sizeof(found_opts)); | 217 | sprint_nip6(ipv6str, option + 4 + 4 + 1); |
218 | *new_env() = xasprintf("ipv6prefix=%s/%u", ipv6str, (unsigned)(option[4 + 4])); | ||
219 | } | ||
220 | option += 4 + option[3]; | ||
221 | len_m4 -= 4 + option[3]; | ||
222 | } | ||
223 | } | ||
147 | 224 | ||
148 | /* We need 2 elements for: | 225 | static char **fill_envp(struct d6_packet *packet) |
149 | * "interface=IFACE" | 226 | { |
150 | * terminating NULL | 227 | char **envp, **curr; |
151 | */ | 228 | |
152 | envc = 2; | 229 | client6_data.env_ptr = NULL; |
230 | client6_data.env_idx = 0; | ||
231 | |||
232 | *new_env() = xasprintf("interface=%s", client_config.interface); | ||
153 | 233 | ||
154 | curr = envp = xzalloc(sizeof(envp[0]) * envc); | 234 | if (packet) |
235 | option_to_env(packet->d6_options, packet->d6_options + sizeof(packet->d6_options)); | ||
155 | 236 | ||
156 | *curr = xasprintf("interface=%s", client_config.interface); | 237 | envp = curr = client6_data.env_ptr; |
157 | putenv(*curr++); | 238 | while (*curr) |
239 | putenv(*curr++); | ||
158 | 240 | ||
159 | return envp; | 241 | return envp; |
160 | } | 242 | } |
@@ -1329,19 +1411,19 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1329 | free(client6_data.ia_na); | 1411 | free(client6_data.ia_na); |
1330 | client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); | 1412 | client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); |
1331 | if (!client6_data.ia_na) { | 1413 | if (!client6_data.ia_na) { |
1332 | bb_error_msg("no lease time, ignoring packet"); | 1414 | bb_error_msg("no %s option, ignoring packet", "IA_NA"); |
1333 | continue; | 1415 | continue; |
1334 | } | 1416 | } |
1335 | if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { | 1417 | if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { |
1336 | bb_error_msg("IA_NA option is too short:%d bytes", client6_data.ia_na->len); | 1418 | bb_error_msg("IA_NA option is too short:%d bytes", client6_data.ia_na->len); |
1337 | continue; | 1419 | continue; |
1338 | } | 1420 | } |
1339 | iaaddr = d6_find_option(client6_data.ia_na->data, | 1421 | iaaddr = d6_find_option(client6_data.ia_na->data + 4 + 4 + 4, |
1340 | client6_data.ia_na->data + client6_data.ia_na->len, | 1422 | client6_data.ia_na->data + client6_data.ia_na->len, |
1341 | D6_OPT_IAADDR | 1423 | D6_OPT_IAADDR |
1342 | ); | 1424 | ); |
1343 | if (!iaaddr) { | 1425 | if (!iaaddr) { |
1344 | bb_error_msg("no lease time, ignoring packet"); | 1426 | bb_error_msg("no %s option, ignoring packet", "IAADDR"); |
1345 | continue; | 1427 | continue; |
1346 | } | 1428 | } |
1347 | if (iaaddr->len < (16 + 4 + 4)) { | 1429 | if (iaaddr->len < (16 + 4 + 4)) { |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 3c4e8dee1..43d682341 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -123,24 +123,6 @@ static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) | |||
123 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); | 123 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); |
124 | } | 124 | } |
125 | 125 | ||
126 | static int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) | ||
127 | { | ||
128 | char hexstrbuf[16 * 2]; | ||
129 | bin2hex(hexstrbuf, (void*)ip, 16); | ||
130 | return sprintf(dest, /* "%s" */ | ||
131 | "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", | ||
132 | /* pre, */ | ||
133 | hexstrbuf + 0 * 4, | ||
134 | hexstrbuf + 1 * 4, | ||
135 | hexstrbuf + 2 * 4, | ||
136 | hexstrbuf + 3 * 4, | ||
137 | hexstrbuf + 4 * 4, | ||
138 | hexstrbuf + 5 * 4, | ||
139 | hexstrbuf + 6 * 4, | ||
140 | hexstrbuf + 7 * 4 | ||
141 | ); | ||
142 | } | ||
143 | |||
144 | /* really simple implementation, just count the bits */ | 126 | /* really simple implementation, just count the bits */ |
145 | static int mton(uint32_t mask) | 127 | static int mton(uint32_t mask) |
146 | { | 128 | { |