diff options
Diffstat (limited to 'networking/udhcp/d6_dhcpc.c')
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 126 |
1 files changed, 104 insertions, 22 deletions
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)) { |