diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-07-03 11:46:38 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-07-03 11:46:38 +0000 |
commit | 51b8bd68bb22b1cc5d95e418813c2f08a194ec2b (patch) | |
tree | 905d4f1b1e557950272ac98e1540fa06f732f42f /libbb/interface.c | |
parent | 599e3ce163c43c3dfb24d06f8f707c783bc9ab9c (diff) | |
download | busybox-w32-51b8bd68bb22b1cc5d95e418813c2f08a194ec2b.tar.gz busybox-w32-51b8bd68bb22b1cc5d95e418813c2f08a194ec2b.tar.bz2 busybox-w32-51b8bd68bb22b1cc5d95e418813c2f08a194ec2b.zip |
This patch from Bart Visscher <magick@linux-fan.com> adds
IPV6 support to busybox. This patch does the following:
* Add IPv6 support to libbb
* Enable IPv6 interface address display
* Add IPv6 config option
* Adds ping6, an adaptation of the ping applet for IPv6
* Adds support routines for ping6:
- xgethostbyname2
- create_icmp6_socket
* Adds ifconfig support for IPv6
* Add support IPv6 to netstat
* Add IPv6 support to route
Thanks Bart!
Diffstat (limited to 'libbb/interface.c')
-rw-r--r-- | libbb/interface.c | 101 |
1 files changed, 96 insertions, 5 deletions
diff --git a/libbb/interface.c b/libbb/interface.c index 9ecb81b9f..5800e0f6a 100644 --- a/libbb/interface.c +++ b/libbb/interface.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * that either displays or sets the characteristics of | 15 | * that either displays or sets the characteristics of |
16 | * one or more of the system's networking interfaces. | 16 | * one or more of the system's networking interfaces. |
17 | * | 17 | * |
18 | * Version: $Id: interface.c,v 1.7 2001/11/10 11:22:46 andersen Exp $ | 18 | * Version: $Id: interface.c,v 1.8 2002/07/03 11:46:36 andersen Exp $ |
19 | * | 19 | * |
20 | * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> | 20 | * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> |
21 | * and others. Copyright 1993 MicroWalt Corporation | 21 | * and others. Copyright 1993 MicroWalt Corporation |
@@ -52,6 +52,10 @@ | |||
52 | #undef HAVE_AFECONET | 52 | #undef HAVE_AFECONET |
53 | #undef HAVE_AFASH | 53 | #undef HAVE_AFASH |
54 | 54 | ||
55 | #if CONFIG_FEATURE_IPV6 | ||
56 | #define HAVE_AFINET6 1 | ||
57 | #endif | ||
58 | |||
55 | /* | 59 | /* |
56 | * | 60 | * |
57 | * Device Hardware types. | 61 | * Device Hardware types. |
@@ -77,6 +81,7 @@ | |||
77 | 81 | ||
78 | #define _(x) x | 82 | #define _(x) x |
79 | #define _PATH_PROCNET_DEV "/proc/net/dev" | 83 | #define _PATH_PROCNET_DEV "/proc/net/dev" |
84 | #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6" | ||
80 | #define new(p) ((p) = xcalloc(1,sizeof(*(p)))) | 85 | #define new(p) ((p) = xcalloc(1,sizeof(*(p)))) |
81 | #define KRELEASE(maj,min,patch) ((maj) * 65536 + (min)*256 + (patch)) | 86 | #define KRELEASE(maj,min,patch) ((maj) * 65536 + (min)*256 + (patch)) |
82 | 87 | ||
@@ -425,6 +430,76 @@ static struct aftype inet_aftype = | |||
425 | 430 | ||
426 | #endif /* HAVE_AFINET */ | 431 | #endif /* HAVE_AFINET */ |
427 | 432 | ||
433 | #if HAVE_AFINET6 | ||
434 | |||
435 | #ifdef KEEP_UNUSED | ||
436 | static void INET6_reserror(char *text) | ||
437 | { | ||
438 | herror(text); | ||
439 | } | ||
440 | |||
441 | /* Display an Internet socket address. */ | ||
442 | static char *INET6_print(unsigned char *ptr) | ||
443 | { | ||
444 | static char name[80]; | ||
445 | |||
446 | inet_ntop(AF_INET6, (struct in6_addr *) ptr, name, 80); | ||
447 | return name; | ||
448 | } | ||
449 | #endif /* KEEP_UNUSED */ | ||
450 | |||
451 | /* Display an Internet socket address. */ | ||
452 | /* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */ | ||
453 | static char *INET6_sprint(struct sockaddr *sap, int numeric) | ||
454 | { | ||
455 | static char buff[128]; | ||
456 | |||
457 | if (sap->sa_family == 0xFFFF || sap->sa_family == 0) | ||
458 | return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff)); | ||
459 | if (INET6_rresolve(buff, sizeof(buff), (struct sockaddr_in6 *) sap, numeric) != 0) | ||
460 | return safe_strncpy(buff, _("[UNKNOWN]"), sizeof(buff)); | ||
461 | return (buff); | ||
462 | } | ||
463 | |||
464 | #ifdef KEEP_UNUSED | ||
465 | static int INET6_getsock(char *bufp, struct sockaddr *sap) | ||
466 | { | ||
467 | struct sockaddr_in6 *sin6; | ||
468 | |||
469 | sin6 = (struct sockaddr_in6 *) sap; | ||
470 | sin6->sin6_family = AF_INET6; | ||
471 | sin6->sin6_port = 0; | ||
472 | |||
473 | if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0) | ||
474 | return (-1); | ||
475 | |||
476 | return 16; /* ?;) */ | ||
477 | } | ||
478 | |||
479 | static int INET6_input(int type, char *bufp, struct sockaddr *sap) | ||
480 | { | ||
481 | switch (type) { | ||
482 | case 1: | ||
483 | return (INET6_getsock(bufp, sap)); | ||
484 | default: | ||
485 | return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap)); | ||
486 | } | ||
487 | } | ||
488 | #endif /* KEEP_UNUSED */ | ||
489 | |||
490 | static struct aftype inet6_aftype = | ||
491 | { | ||
492 | "inet6", "IPv6", AF_INET6, sizeof(struct in6_addr), | ||
493 | NULL /* UNUSED INET6_print */, INET6_sprint, | ||
494 | NULL /* UNUSED INET6_input */, NULL /* UNUSED INET6_reserror */, | ||
495 | NULL /*INET6_rprint */ , NULL /*INET6_rinput */ , | ||
496 | NULL /* UNUSED INET6_getnetmask */, | ||
497 | -1, | ||
498 | NULL | ||
499 | }; | ||
500 | |||
501 | #endif /* HAVE_AFINET6 */ | ||
502 | |||
428 | /* Display an UNSPEC address. */ | 503 | /* Display an UNSPEC address. */ |
429 | static char *UNSPEC_print(unsigned char *ptr) | 504 | static char *UNSPEC_print(unsigned char *ptr) |
430 | { | 505 | { |
@@ -1709,7 +1784,6 @@ static void ife_print(struct interface *ptr) | |||
1709 | char addr6[40], devname[20]; | 1784 | char addr6[40], devname[20]; |
1710 | struct sockaddr_in6 sap; | 1785 | struct sockaddr_in6 sap; |
1711 | int plen, scope, dad_status, if_idx; | 1786 | int plen, scope, dad_status, if_idx; |
1712 | extern struct aftype inet6_aftype; | ||
1713 | char addr6p[8][5]; | 1787 | char addr6p[8][5]; |
1714 | #endif | 1788 | #endif |
1715 | 1789 | ||
@@ -1756,8 +1830,24 @@ static void ife_print(struct interface *ptr) | |||
1756 | #endif | 1830 | #endif |
1757 | 1831 | ||
1758 | #if HAVE_AFINET6 | 1832 | #if HAVE_AFINET6 |
1759 | /* FIXME: should be integrated into interface.c. */ | ||
1760 | 1833 | ||
1834 | #define IPV6_ADDR_ANY 0x0000U | ||
1835 | |||
1836 | #define IPV6_ADDR_UNICAST 0x0001U | ||
1837 | #define IPV6_ADDR_MULTICAST 0x0002U | ||
1838 | #define IPV6_ADDR_ANYCAST 0x0004U | ||
1839 | |||
1840 | #define IPV6_ADDR_LOOPBACK 0x0010U | ||
1841 | #define IPV6_ADDR_LINKLOCAL 0x0020U | ||
1842 | #define IPV6_ADDR_SITELOCAL 0x0040U | ||
1843 | |||
1844 | #define IPV6_ADDR_COMPATv4 0x0080U | ||
1845 | |||
1846 | #define IPV6_ADDR_SCOPE_MASK 0x00f0U | ||
1847 | |||
1848 | #define IPV6_ADDR_MAPPED 0x1000U | ||
1849 | #define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */ | ||
1850 | |||
1761 | if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) { | 1851 | if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) { |
1762 | while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", | 1852 | while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", |
1763 | addr6p[0], addr6p[1], addr6p[2], addr6p[3], | 1853 | addr6p[0], addr6p[1], addr6p[2], addr6p[3], |
@@ -1767,11 +1857,12 @@ static void ife_print(struct interface *ptr) | |||
1767 | sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", | 1857 | sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", |
1768 | addr6p[0], addr6p[1], addr6p[2], addr6p[3], | 1858 | addr6p[0], addr6p[1], addr6p[2], addr6p[3], |
1769 | addr6p[4], addr6p[5], addr6p[6], addr6p[7]); | 1859 | addr6p[4], addr6p[5], addr6p[6], addr6p[7]); |
1770 | inet6_aftype.input(1, addr6, (struct sockaddr *) &sap); | 1860 | inet_pton(AF_INET6, addr6, (struct sockaddr *) &sap.sin6_addr); |
1861 | sap.sin6_family=AF_INET6; | ||
1771 | printf(_(" inet6 addr: %s/%d"), | 1862 | printf(_(" inet6 addr: %s/%d"), |
1772 | inet6_aftype.sprint((struct sockaddr *) &sap, 1), plen); | 1863 | inet6_aftype.sprint((struct sockaddr *) &sap, 1), plen); |
1773 | printf(_(" Scope:")); | 1864 | printf(_(" Scope:")); |
1774 | switch (scope) { | 1865 | switch (scope & IPV6_ADDR_SCOPE_MASK) { |
1775 | case 0: | 1866 | case 0: |
1776 | printf(_("Global")); | 1867 | printf(_("Global")); |
1777 | break; | 1868 | break; |