[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: [BusyBox] Basic IPv6 support in libbb
From: Bart Visscher <magick () Linux-Fan ! com>
Date: 2002-04-28 8:55:43
[Download RAW message or body]
Changelog:
* Add IPv6 support to libbb
* Enable IPv6 interface address display
* Add IPv6 config option
["00-libbb-basic-ipv6.patch" (text/x-patch)]
diff -ru -X exclude -P busybox-new-0/include/inet_common.h busybox-new-1/include/inet_common.h
--- busybox-new-0/include/inet_common.h Wed Apr 24 22:27:17 2002
+++ busybox-new-1/include/inet_common.h Thu Apr 25 20:46:19 2002
@@ -28,3 +28,6 @@
*/
extern int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
int numeric, unsigned int netmask);
+
+extern int INET6_resolve(char *name, struct sockaddr_in6 *sin6);
+extern int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, int numeric);
diff -ru -X exclude -P busybox-new-0/libbb/inet_common.c busybox-new-1/libbb/inet_common.c
--- busybox-new-0/libbb/inet_common.c Wed Apr 24 22:27:17 2002
+++ busybox-new-1/libbb/inet_common.c Thu Apr 25 20:46:19 2002
@@ -172,3 +172,65 @@
return (0);
}
+
+#if CONFIG_FEATURE_IPV6
+
+int INET6_resolve(char *name, struct sockaddr_in6 *sin6)
+{
+ struct addrinfo req, *ai;
+ int s;
+
+ memset (&req, '\0', sizeof req);
+ req.ai_family = AF_INET6;
+ if ((s = getaddrinfo(name, NULL, &req, &ai))) {
+ fprintf(stderr, "getaddrinfo: %s: %d\n", name, s);
+ return -1;
+ }
+ memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
+
+ freeaddrinfo(ai);
+
+ return (0);
+}
+
+#ifndef IN6_IS_ADDR_UNSPECIFIED
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((__u32 *) (a))[0] == 0 && ((__u32 *) (a))[1] == 0 && \
+ ((__u32 *) (a))[2] == 0 && ((__u32 *) (a))[3] == 0)
+#endif
+
+
+int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, int numeric)
+{
+ int s;
+
+ /* Grmpf. -FvK */
+ if (sin6->sin6_family != AF_INET6) {
+#ifdef DEBUG
+ fprintf(stderr, _("rresolve: unsupport address family %d !\n"),
+ sin6->sin6_family);
+#endif
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ if (numeric & 0x7FFF) {
+ inet_ntop(AF_INET6, &sin6->sin6_addr, name, len);
+ return (0);
+ }
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ if (numeric & 0x8000)
+ strcpy(name, "default");
+ else
+ strcpy(name, "*");
+ return (0);
+ }
+
+ if ((s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6),
+ name, len , NULL, 0, 0))) {
+ fputs("getnameinfo failed\n", stderr);
+ return -1;
+ }
+ return (0);
+}
+
+#endif /* CONFIG_FEATURE_IPV6 */
diff -ru -X exclude -P busybox-new-0/libbb/interface.c busybox-new-1/libbb/interface.c
--- busybox-new-0/libbb/interface.c Wed Apr 24 22:27:17 2002
+++ busybox-new-1/libbb/interface.c Thu Apr 25 20:47:27 2002
@@ -52,6 +52,10 @@
#undef HAVE_AFECONET
#undef HAVE_AFASH
+#if CONFIG_FEATURE_IPV6
+#define HAVE_AFINET6 1
+#endif
+
/*
*
* Device Hardware types.
@@ -77,6 +81,7 @@
#define _(x) x
#define _PATH_PROCNET_DEV "/proc/net/dev"
+#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
#define new(p) ((p) = xcalloc(1,sizeof(*(p))))
#define KRELEASE(maj,min,patch) ((maj) * 65536 + (min)*256 + (patch))
@@ -425,6 +430,76 @@
#endif /* HAVE_AFINET */
+#if HAVE_AFINET6
+
+#ifdef KEEP_UNUSED
+static void INET6_reserror(char *text)
+{
+ herror(text);
+}
+
+/* Display an Internet socket address. */
+static char *INET6_print(unsigned char *ptr)
+{
+ static char name[80];
+
+ inet_ntop(AF_INET6, (struct in6_addr *) ptr, name, 80);
+ return name;
+}
+#endif /* KEEP_UNUSED */
+
+/* Display an Internet socket address. */
+/* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */
+static char *INET6_sprint(struct sockaddr *sap, int numeric)
+{
+ static char buff[128];
+
+ if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
+ return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
+ if (INET6_rresolve(buff, sizeof(buff), (struct sockaddr_in6 *) sap, numeric) != 0)
+ return safe_strncpy(buff, _("[UNKNOWN]"), sizeof(buff));
+ return (buff);
+}
+
+#ifdef KEEP_UNUSED
+static int INET6_getsock(char *bufp, struct sockaddr *sap)
+{
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *) sap;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = 0;
+
+ if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0)
+ return (-1);
+
+ return 16; /* ?;) */
+}
+
+static int INET6_input(int type, char *bufp, struct sockaddr *sap)
+{
+ switch (type) {
+ case 1:
+ return (INET6_getsock(bufp, sap));
+ default:
+ return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap));
+ }
+}
+#endif /* KEEP_UNUSED */
+
+static struct aftype inet6_aftype =
+{
+ "inet6", "IPv6", AF_INET6, sizeof(struct in6_addr),
+ NULL /* UNUSED INET6_print */, INET6_sprint,
+ NULL /* UNUSED INET6_input */, NULL /* UNUSED INET6_reserror */,
+ NULL /*INET6_rprint */ , NULL /*INET6_rinput */ ,
+ NULL /* UNUSED INET6_getnetmask */,
+ -1,
+ NULL
+};
+
+#endif /* HAVE_AFINET6 */
+
/* Display an UNSPEC address. */
static char *UNSPEC_print(unsigned char *ptr)
{
@@ -1709,7 +1784,6 @@
char addr6[40], devname[20];
struct sockaddr_in6 sap;
int plen, scope, dad_status, if_idx;
- extern struct aftype inet6_aftype;
char addr6p[8][5];
#endif
@@ -1756,8 +1830,24 @@
#endif
#if HAVE_AFINET6
- /* FIXME: should be integrated into interface.c. */
+#define IPV6_ADDR_ANY 0x0000U
+
+#define IPV6_ADDR_UNICAST 0x0001U
+#define IPV6_ADDR_MULTICAST 0x0002U
+#define IPV6_ADDR_ANYCAST 0x0004U
+
+#define IPV6_ADDR_LOOPBACK 0x0010U
+#define IPV6_ADDR_LINKLOCAL 0x0020U
+#define IPV6_ADDR_SITELOCAL 0x0040U
+
+#define IPV6_ADDR_COMPATv4 0x0080U
+
+#define IPV6_ADDR_SCOPE_MASK 0x00f0U
+
+#define IPV6_ADDR_MAPPED 0x1000U
+#define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */
+
if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
@@ -1767,11 +1857,12 @@
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
- inet6_aftype.input(1, addr6, (struct sockaddr *) &sap);
+ inet_pton(AF_INET6, addr6, (struct sockaddr *) &sap.sin6_addr);
+ sap.sin6_family=AF_INET6;
printf(_(" inet6 addr: %s/%d"),
inet6_aftype.sprint((struct sockaddr *) &sap, 1), plen);
printf(_(" Scope:"));
- switch (scope) {
+ switch (scope & IPV6_ADDR_SCOPE_MASK) {
case 0:
printf(_("Global"));
break;
diff -ru -X exclude -P busybox-new-0/sysdeps/linux/config.in busybox-new-1/sysdeps/linux/config.in
--- busybox-new-0/sysdeps/linux/config.in Sat Nov 10 13:07:23 2001
+++ busybox-new-1/sysdeps/linux/config.in Thu Apr 25 20:46:19 2002
@@ -15,6 +15,7 @@
bool 'Enable locale support (system needs locale for this to work)' CONFIG_LOCALE_SUPPORT
bool 'Support for devfs' CONFIG_FEATURE_DEVFS
bool 'Clean up all memory before exiting (usually not needed)' CONFIG_FEATURE_CLEAN_UP
+bool 'Enable IPv6 support' CONFIG_FEATURE_IPV6
endmenu
source archival/config.in
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic