diff options
Diffstat (limited to 'networking/ifconfig.c')
-rw-r--r-- | networking/ifconfig.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/networking/ifconfig.c b/networking/ifconfig.c index 0b834e7c7..9e87c8be5 100644 --- a/networking/ifconfig.c +++ b/networking/ifconfig.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * Foundation; either version 2 of the License, or (at | 15 | * Foundation; either version 2 of the License, or (at |
16 | * your option) any later version. | 16 | * your option) any later version. |
17 | * | 17 | * |
18 | * $Id: ifconfig.c,v 1.16 2001/11/10 11:22:43 andersen Exp $ | 18 | * $Id: ifconfig.c,v 1.17 2002/07/03 11:46:34 andersen Exp $ |
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
@@ -27,6 +27,9 @@ | |||
27 | * args missing from initial port. | 27 | * args missing from initial port. |
28 | * | 28 | * |
29 | * Still missing: media, tunnel. | 29 | * Still missing: media, tunnel. |
30 | * | ||
31 | * 2002-04-20 | ||
32 | * IPV6 support added by Bart Visscher <magick@linux-fan.com> | ||
30 | */ | 33 | */ |
31 | 34 | ||
32 | #include <stdio.h> | 35 | #include <stdio.h> |
@@ -65,6 +68,14 @@ | |||
65 | #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */ | 68 | #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */ |
66 | #endif | 69 | #endif |
67 | 70 | ||
71 | #if CONFIG_FEATURE_IPV6 | ||
72 | struct in6_ifreq { | ||
73 | struct in6_addr ifr6_addr; | ||
74 | uint32_t ifr6_prefixlen; | ||
75 | int ifr6_ifindex; | ||
76 | }; | ||
77 | #endif | ||
78 | |||
68 | /* | 79 | /* |
69 | * Here are the bit masks for the "flags" member of struct options below. | 80 | * Here are the bit masks for the "flags" member of struct options below. |
70 | * N_ signifies no arg prefix; M_ signifies arg prefixed by '-'. | 81 | * N_ signifies no arg prefix; M_ signifies arg prefixed by '-'. |
@@ -143,6 +154,7 @@ | |||
143 | #define ARG_KEEPALIVE (A_ARG_REQ | A_CAST_CHAR_PTR) | 154 | #define ARG_KEEPALIVE (A_ARG_REQ | A_CAST_CHAR_PTR) |
144 | #define ARG_OUTFILL (A_ARG_REQ | A_CAST_CHAR_PTR) | 155 | #define ARG_OUTFILL (A_ARG_REQ | A_CAST_CHAR_PTR) |
145 | #define ARG_HOSTNAME (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_COLON_CHK) | 156 | #define ARG_HOSTNAME (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER | A_COLON_CHK) |
157 | #define ARG_ADD_DEL (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER) | ||
146 | 158 | ||
147 | 159 | ||
148 | /* | 160 | /* |
@@ -187,6 +199,10 @@ static const struct arg1opt Arg1Opt[] = { | |||
187 | {"SIOCSIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq)}, | 199 | {"SIOCSIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq)}, |
188 | #endif | 200 | #endif |
189 | /* Last entry if for unmatched (possibly hostname) arg. */ | 201 | /* Last entry if for unmatched (possibly hostname) arg. */ |
202 | #if CONFIG_FEATURE_IPV6 | ||
203 | {"SIOCSIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr)}, /* IPv6 version ignores the offset */ | ||
204 | {"SIOCDIFADDR", SIOCDIFADDR, ifreq_offsetof(ifr_addr)}, /* IPv6 version ignores the offset */ | ||
205 | #endif | ||
190 | {"SIOCSIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr)}, | 206 | {"SIOCSIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr)}, |
191 | }; | 207 | }; |
192 | 208 | ||
@@ -212,6 +228,10 @@ static const struct options OptArray[] = { | |||
212 | {"io_addr", N_ARG, ARG_IO_ADDR, 0}, | 228 | {"io_addr", N_ARG, ARG_IO_ADDR, 0}, |
213 | {"irq", N_ARG, ARG_IRQ, 0}, | 229 | {"irq", N_ARG, ARG_IRQ, 0}, |
214 | #endif | 230 | #endif |
231 | #if CONFIG_FEATURE_IPV6 | ||
232 | {"add", N_ARG, ARG_ADD_DEL, 0}, | ||
233 | {"del", N_ARG, ARG_ADD_DEL, 0}, | ||
234 | #endif | ||
215 | {"arp", N_CLR | M_SET, 0, IFF_NOARP}, | 235 | {"arp", N_CLR | M_SET, 0, IFF_NOARP}, |
216 | {"trailers", N_CLR | M_SET, 0, IFF_NOTRAILERS}, | 236 | {"trailers", N_CLR | M_SET, 0, IFF_NOTRAILERS}, |
217 | {"promisc", N_SET | M_CLR, 0, IFF_PROMISC}, | 237 | {"promisc", N_SET | M_CLR, 0, IFF_PROMISC}, |
@@ -244,6 +264,9 @@ int ifconfig_main(int argc, char **argv) | |||
244 | { | 264 | { |
245 | struct ifreq ifr; | 265 | struct ifreq ifr; |
246 | struct sockaddr_in sai; | 266 | struct sockaddr_in sai; |
267 | #if CONFIG_FEATURE_IPV6 | ||
268 | struct sockaddr_in6 sai6; | ||
269 | #endif | ||
247 | #ifdef CONFIG_FEATURE_IFCONFIG_HW | 270 | #ifdef CONFIG_FEATURE_IFCONFIG_HW |
248 | struct sockaddr sa; | 271 | struct sockaddr sa; |
249 | #endif | 272 | #endif |
@@ -334,12 +357,54 @@ int ifconfig_main(int argc, char **argv) | |||
334 | #ifdef CONFIG_FEATURE_IFCONFIG_HW | 357 | #ifdef CONFIG_FEATURE_IFCONFIG_HW |
335 | if (mask & A_CAST_RESOLVE) { | 358 | if (mask & A_CAST_RESOLVE) { |
336 | #endif | 359 | #endif |
360 | #if CONFIG_FEATURE_IPV6 | ||
361 | char *prefix; | ||
362 | int prefix_len=0; | ||
363 | #endif | ||
364 | |||
337 | safe_strncpy(host, *argv, (sizeof host)); | 365 | safe_strncpy(host, *argv, (sizeof host)); |
366 | #if CONFIG_FEATURE_IPV6 | ||
367 | if ((prefix = strchr(host, '/'))) { | ||
368 | prefix_len = atol(prefix + 1); | ||
369 | if ((prefix_len < 0) || (prefix_len > 128)) { | ||
370 | ++goterr; | ||
371 | goto LOOP; | ||
372 | } | ||
373 | *prefix = 0; | ||
374 | } | ||
375 | #endif | ||
376 | |||
338 | sai.sin_family = AF_INET; | 377 | sai.sin_family = AF_INET; |
339 | sai.sin_port = 0; | 378 | sai.sin_port = 0; |
340 | if (!strcmp(host, bb_INET_default)) { | 379 | if (!strcmp(host, bb_INET_default)) { |
341 | /* Default is special, meaning 0.0.0.0. */ | 380 | /* Default is special, meaning 0.0.0.0. */ |
342 | sai.sin_addr.s_addr = INADDR_ANY; | 381 | sai.sin_addr.s_addr = INADDR_ANY; |
382 | #if CONFIG_FEATURE_IPV6 | ||
383 | } else | ||
384 | if (inet_pton(AF_INET6, host, &sai6.sin6_addr) > 0) { | ||
385 | int sockfd6; | ||
386 | struct in6_ifreq ifr6; | ||
387 | |||
388 | memcpy((char *) &ifr6.ifr6_addr, (char *) &sai6.sin6_addr, | ||
389 | sizeof(struct in6_addr)); | ||
390 | |||
391 | /* Create a channel to the NET kernel. */ | ||
392 | if ((sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { | ||
393 | perror_msg_and_die("socket6"); | ||
394 | } | ||
395 | if (ioctl(sockfd6, SIOGIFINDEX, &ifr) < 0) { | ||
396 | perror("SIOGIFINDEX"); | ||
397 | ++goterr; | ||
398 | continue; | ||
399 | } | ||
400 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; | ||
401 | ifr6.ifr6_prefixlen = prefix_len; | ||
402 | if (ioctl(sockfd6, a1op->selector, &ifr6) < 0) { | ||
403 | perror(a1op->name); | ||
404 | ++goterr; | ||
405 | } | ||
406 | continue; | ||
407 | #endif | ||
343 | } else if (inet_aton(host, &sai.sin_addr) == 0) { | 408 | } else if (inet_aton(host, &sai.sin_addr) == 0) { |
344 | /* It's not a dotted quad. */ | 409 | /* It's not a dotted quad. */ |
345 | ++goterr; | 410 | ++goterr; |