aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2002-07-03 11:46:38 +0000
committerandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2002-07-03 11:46:38 +0000
commit900987843e32563488974222031be9c97c060610 (patch)
tree905d4f1b1e557950272ac98e1540fa06f732f42f /libbb
parent26e899536049e29919abd9101799745ceaffff25 (diff)
downloadbusybox-w32-900987843e32563488974222031be9c97c060610.tar.gz
busybox-w32-900987843e32563488974222031be9c97c060610.tar.bz2
busybox-w32-900987843e32563488974222031be9c97c060610.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! git-svn-id: svn://busybox.net/trunk/busybox@5003 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Makefile.in4
-rw-r--r--libbb/create_icmp6_socket.c39
-rw-r--r--libbb/inet_common.c64
-rw-r--r--libbb/interface.c101
-rw-r--r--libbb/xgethostbyname2.c37
5 files changed, 238 insertions, 7 deletions
diff --git a/libbb/Makefile.in b/libbb/Makefile.in
index 2af70f8c7..70cc26dc1 100644
--- a/libbb/Makefile.in
+++ b/libbb/Makefile.in
@@ -40,7 +40,9 @@ LIBBB_SRC:= \
40 dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \ 40 dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \
41 simplify_path.c inet_common.c inode_hash.c obscure.c pwd2spwd.c xfuncs.c \ 41 simplify_path.c inet_common.c inode_hash.c obscure.c pwd2spwd.c xfuncs.c \
42 correct_password.c change_identity.c setup_environment.c run_shell.c \ 42 correct_password.c change_identity.c setup_environment.c run_shell.c \
43 pw_encrypt.c restricted_shell.c 43 pw_encrypt.c restricted_shell.c xgethostbyname2.c create_icmp6_socket.c \
44 xconnect.c
45
44LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC)) 46LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
45 47
46LIBBB_MSRC:=$(LIBBB_DIR)messages.c 48LIBBB_MSRC:=$(LIBBB_DIR)messages.c
diff --git a/libbb/create_icmp6_socket.c b/libbb/create_icmp6_socket.c
new file mode 100644
index 000000000..a09565605
--- /dev/null
+++ b/libbb/create_icmp6_socket.c
@@ -0,0 +1,39 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * create raw socket for icmp (IPv6 version) protocol test permision
6 * and drop root privilegies if running setuid
7 *
8 */
9
10#include <sys/types.h>
11#include <netdb.h>
12#include <sys/socket.h>
13#include <errno.h>
14#include <unistd.h>
15#include "libbb.h"
16
17#if CONFIG_FEATURE_IPV6
18int create_icmp6_socket(void)
19{
20 struct protoent *proto;
21 int sock;
22
23 proto = getprotobyname("ipv6-icmp");
24 /* if getprotobyname failed, just silently force
25 * proto->p_proto to have the correct value for "ipv6-icmp" */
26 if ((sock = socket(AF_INET6, SOCK_RAW,
27 (proto ? proto->p_proto : IPPROTO_ICMPV6))) < 0) {
28 if (errno == EPERM)
29 error_msg_and_die("permission denied. (are you root?)");
30 else
31 perror_msg_and_die(can_not_create_raw_socket);
32 }
33
34 /* drop root privs if running setuid */
35 setuid(getuid());
36
37 return sock;
38}
39#endif
diff --git a/libbb/inet_common.c b/libbb/inet_common.c
index c1e5953fe..c7bf409c4 100644
--- a/libbb/inet_common.c
+++ b/libbb/inet_common.c
@@ -4,7 +4,7 @@
4 * 4 *
5 * Heavily modified by Manuel Novoa III Mar 12, 2001 5 * Heavily modified by Manuel Novoa III Mar 12, 2001
6 * 6 *
7 * Version: $Id: inet_common.c,v 1.2 2002/06/06 12:11:55 andersen Exp $ 7 * Version: $Id: inet_common.c,v 1.3 2002/07/03 11:46:36 andersen Exp $
8 * 8 *
9 */ 9 */
10 10
@@ -177,3 +177,65 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
177 177
178 return (0); 178 return (0);
179} 179}
180
181#if CONFIG_FEATURE_IPV6
182
183int INET6_resolve(char *name, struct sockaddr_in6 *sin6)
184{
185 struct addrinfo req, *ai;
186 int s;
187
188 memset (&req, '\0', sizeof req);
189 req.ai_family = AF_INET6;
190 if ((s = getaddrinfo(name, NULL, &req, &ai))) {
191 fprintf(stderr, "getaddrinfo: %s: %d\n", name, s);
192 return -1;
193 }
194 memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
195
196 freeaddrinfo(ai);
197
198 return (0);
199}
200
201#ifndef IN6_IS_ADDR_UNSPECIFIED
202#define IN6_IS_ADDR_UNSPECIFIED(a) \
203 (((__u32 *) (a))[0] == 0 && ((__u32 *) (a))[1] == 0 && \
204 ((__u32 *) (a))[2] == 0 && ((__u32 *) (a))[3] == 0)
205#endif
206
207
208int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, int numeric)
209{
210 int s;
211
212 /* Grmpf. -FvK */
213 if (sin6->sin6_family != AF_INET6) {
214#ifdef DEBUG
215 fprintf(stderr, _("rresolve: unsupport address family %d !\n"),
216 sin6->sin6_family);
217#endif
218 errno = EAFNOSUPPORT;
219 return (-1);
220 }
221 if (numeric & 0x7FFF) {
222 inet_ntop(AF_INET6, &sin6->sin6_addr, name, len);
223 return (0);
224 }
225 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
226 if (numeric & 0x8000)
227 strcpy(name, "default");
228 else
229 strcpy(name, "*");
230 return (0);
231 }
232
233 if ((s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6),
234 name, len , NULL, 0, 0))) {
235 fputs("getnameinfo failed\n", stderr);
236 return -1;
237 }
238 return (0);
239}
240
241#endif /* CONFIG_FEATURE_IPV6 */
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
436static void INET6_reserror(char *text)
437{
438 herror(text);
439}
440
441/* Display an Internet socket address. */
442static 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. */
453static 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
465static 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
479static 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
490static 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. */
429static char *UNSPEC_print(unsigned char *ptr) 504static 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;
diff --git a/libbb/xgethostbyname2.c b/libbb/xgethostbyname2.c
new file mode 100644
index 000000000..c66acfee1
--- /dev/null
+++ b/libbb/xgethostbyname2.c
@@ -0,0 +1,37 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini xgethostbyname2 implementation.
4 *
5 * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <netdb.h>
24#include "libbb.h"
25
26
27#if CONFIG_FEATURE_IPV6
28struct hostent *xgethostbyname2(const char *name, int af)
29{
30 struct hostent *retval;
31
32 if ((retval = gethostbyname2(name, af)) == NULL)
33 herror_msg_and_die("%s", name);
34
35 return retval;
36}
37#endif