aboutsummaryrefslogtreecommitdiff
path: root/networking/ifconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/ifconfig.c')
-rw-r--r--networking/ifconfig.c67
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
72struct 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;