aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-11-16 20:17:12 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-11-16 20:17:12 +0100
commita092a89d8f052072e562861f2968573d89e10dd5 (patch)
tree43e7300d1825899e5c95ae9f557d0e2d1efde228 /networking/udhcp
parent39b233182c0a13200be051b993da181a1db80a87 (diff)
downloadbusybox-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.c19
-rw-r--r--networking/udhcp/common.h3
-rw-r--r--networking/udhcp/d6_common.h5
-rw-r--r--networking/udhcp/d6_dhcpc.c126
-rw-r--r--networking/udhcp/dhcpc.c18
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 */
544int 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 */
312int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC;
313
311POP_SAVED_FUNCTION_VISIBILITY 314POP_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
86struct client6_data_t { 89struct 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
132static 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 */
133static char **fill_envp(struct d6_packet *packet 139static 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: 225static 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
126static 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 */
145static int mton(uint32_t mask) 127static int mton(uint32_t mask)
146{ 128{