Browse Source

A patch from Michal Moskal <malekith@pld.org.pl> to include
partial IPV6 support. This adds things like gethostbyname2().
Off by defaut, of course,

Eric Andersen 23 years ago
parent
commit
8f6ad30191

+ 5 - 0
Makefile

@@ -98,6 +98,11 @@ uClibc_config.h: Makefile Config
 	@echo "#endif" >> uClibc_config.h
 	@echo "#define linux 1" >> uClibc_config.h 
 	@echo "#define __linux__ 1" >> uClibc_config.h 
+	@if [ "$(INCLUDE_IPV6)" = "true" ] ; then \
+	    echo "#define __UCLIBC_HAS_IPV6__ 1" >> uClibc_config.h ; \
+	else \
+	    echo "#undef __UCLIBC_HAS_IPV6__" >> uClibc_config.h ; \
+	fi
 	@if [ "$(HAS_MMU)" = "true" ] ; then \
 	    echo "#define __UCLIBC_HAS_MMU__ 1" >> uClibc_config.h ; \
 	else \

+ 4 - 0
extra/Configs/Config.arm

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = false
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.cross.arm.uclinux

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = false
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.i386

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = false
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.m68k

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = true
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.m68k.coff

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = true
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.mips

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = false
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.mipsel

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = false
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.powerpc

@@ -132,6 +132,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = false
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 4 - 0
extra/Configs/Config.sh

@@ -153,6 +153,10 @@ DOLFS = false
 # disabled.  This is off by default.
 INCLUDE_RPC = false
 
+# If you want to include support for the next version of the Internet
+# Protocol: IP version 6, enable this.  This is off by default.
+INCLUDE_IPV6 = false
+
 # If you want to compile the library as PIC code, turn this on.
 DOPIC = false
 

+ 1 - 0
include/netdb.h

@@ -153,6 +153,7 @@ void		endservent __P((void));
 void		endrpcent __P ((void));
 struct hostent	*gethostbyaddr __P((__const char *, int, int));
 struct hostent	*gethostbyname __P((__const char *));
+struct hostent	*gethostbyname2 __P((__const char *, int));
 struct hostent	*gethostent __P((void));
 struct netent	*getnetbyaddr __P((long, int)); /* u_long? */
 struct netent	*getnetbyname __P((__const char *));

+ 2 - 2
libc/inet/Makefile

@@ -39,8 +39,8 @@ MOBJ2=encodeh.o decodeh.o encoded.o decoded.o lengthd.o encodeq.o \
 	formquery.o dnslookup.o resolveaddress.o resolvemailbox.o \
 	opennameservers.o closenameservers.o resolvename.o gethostbyname.o\
 	res_init.o res_query.o gethostbyaddr.o \
-	get_hosts_byname.o get_hosts_byaddr.o read_etc_hosts.o
-
+	get_hosts_byname.o get_hosts_byaddr.o read_etc_hosts.o \
+	gethostbyname2.o
 
 MSRC3=socketcalls.c
 MOBJ3= accept.o bind.o connect.o getpeername.o getsockname.o getsockopt.o \

+ 8 - 0
libc/inet/ntop.c

@@ -29,6 +29,13 @@
 #include <stdio.h>
 #include <string.h>
 
+#ifdef __UCLIBC_HAS_IPV6__
+#define INET_IPV6
+#define SPRINTF(a) sprintf a
+#include <ctype.h>
+#endif
+
+
 /*
  * WARNING: Don't even consider trying to compile this on a system where
  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
@@ -259,6 +266,7 @@ inet_pton6(src, dst)
 	int ch, saw_xdigit;
 	u_int val;
 
+
 	tp = memset(tmp, '\0', 16);
 	endp = tp + 16;
 	colonp = NULL;

+ 142 - 0
libc/inet/resolv.c

@@ -32,6 +32,10 @@
  *
  *                              General cleanup
  *
+ * 20-Jun-2001 Michal Moskal <malekith@pld.org.pl>
+ *   partial IPv6 support (i.e. gethostbyname2() and resolve_address2()
+ *   functions added), IPv6 nameservers are also supported.
+ *
  */
 
 #define __FORCE_GLIBC__
@@ -59,6 +63,8 @@
 #define MAX_SEARCH 4
 
 #undef DEBUG
+/*#define DEBUG*/
+
 #ifdef DEBUG
 #define DPRINTF(X,args...) fprintf(stderr, X, ##args)
 #else
@@ -465,6 +471,9 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip,
 	int i, j, len, fd, pos;
 	static int ns = 0;
 	struct sockaddr_in sa;
+#ifdef __UCLIBC_HAS_IPV6__
+	struct sockaddr_in6 sa6;
+#endif /* __UCLIBC_HAS_IPV6__ */
 	int oldalarm;
 	__sighandler_t oldhandler;
 	struct resolv_header h;
@@ -473,6 +482,9 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip,
 	unsigned char * packet = malloc(PACKETSZ);
 	unsigned char * lookup = malloc(MAXDNAME);
 	int variant = 0;
+#ifdef __UCLIBC_HAS_IPV6__
+	int v6;
+#endif /* __UCLIBC_HAS_IPV6__ */
 
 	fd = -1;
 
@@ -484,11 +496,18 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip,
 	ns %= nscount;
 
 	while (retries++ < MAX_RETRIES) {
+#ifdef __UCLIBC_HAS_IPV6__
+		v6 = (inet_pton(AF_INET6, nsip[ns], &sa6.sin6_addr) > 0);
+#endif /* __UCLIBC_HAS_IPV6__ */
 
 		if (fd != -1)
 			close(fd);
 
+#ifndef __UCLIBC_HAS_IPV6__
 		fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+#else /* __UCLIBC_HAS_IPV6__ */
+		fd = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+#endif /* __UCLIBC_HAS_IPV6__ */
 
 		if (fd == -1)
 			goto fail;
@@ -526,11 +545,28 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip,
 		DPRINTF("On try %d, sending query to port %d of machine %s\n",
 				retries, NAMESERVER_PORT, nsip[ns]);
 
+#ifndef __UCLIBC_HAS_IPV6__
 		sa.sin_family = AF_INET;
 		sa.sin_port = htons(NAMESERVER_PORT);
 		sa.sin_addr.s_addr = inet_addr(nsip[ns]);
+#else /* __UCLIBC_HAS_IPV6__ */
+		if (v6) {
+			sa6.sin6_family = AF_INET6;
+			sa6.sin6_port = htons(NAMESERVER_PORT);
+			/* sa6.sin6_addr is already here */
+		} else {
+			sa.sin_family = AF_INET;
+			sa.sin_port = htons(NAMESERVER_PORT);
+			sa.sin_addr.s_addr = inet_addr(nsip[ns]);
+		}
+#endif /* __UCLIBC_HAS_IPV6__ */
 
+#ifndef __UCLIBC_HAS_IPV6__
 		if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
+#else /* __UCLIBC_HAS_IPV6__ */
+		if (connect(fd, (struct sockaddr *) (v6 ? &sa6 : &sa), 
+			    v6 ? sizeof(sa6) : sizeof(sa)) == -1) {
+#endif /* __UCLIBC_HAS_IPV6__ */
 			if (errno == ENETUNREACH) {
 				/* routing error, presume not transient */
 				goto tryall;
@@ -958,6 +994,92 @@ struct hostent *gethostbyname(const char *name)
 }
 #endif
 
+#ifdef L_gethostbyname2
+
+struct hostent *gethostbyname2(const char *name, int family)
+{
+#ifndef __UCLIBC_HAS_IPV6__
+	return family == AF_INET ? gethostbyname(name) : (struct hostent*)0;
+#else /* __UCLIBC_HAS_IPV6__ */
+	static struct hostent h;
+	static char namebuf[256];
+	static struct in6_addr in;
+	static struct in6_addr *addr_list[2];
+	struct hostent *hp;
+	unsigned char *packet;
+	struct resolv_answer a;
+	int i;
+	int nest = 0;
+
+	if (family == AF_INET)
+		return gethostbyname(name);
+		
+	if (family != AF_INET6)
+		return NULL;
+		
+	open_nameservers();
+
+	if (!name)
+		return 0;
+
+	if ((hp = get_hosts_byname(name))) /* do /etc/hosts first */
+		return(hp);
+
+	memset(&h, 0, sizeof(h));
+
+	addr_list[0] = &in;
+	addr_list[1] = 0;
+	
+	strncpy(namebuf, name, sizeof(namebuf));
+
+	/* First check if this is already an address */
+	if (inet_pton(AF_INET6, name, &in)) {
+	    h.h_name = namebuf;
+	    h.h_addrtype = AF_INET6;
+	    h.h_length = sizeof(in);
+	    h.h_addr_list = (char **) addr_list;
+	    return &h;
+	}
+
+	for (;;) {
+
+		i = dns_lookup(namebuf, T_AAAA, nameservers, nameserver, &packet, &a);
+
+		if (i < 0)
+			return 0;
+
+		strncpy(namebuf, a.dotted, sizeof(namebuf));
+		free(a.dotted);
+
+
+		if (a.atype == T_CNAME) {		/* CNAME */
+			DPRINTF("Got a CNAME in gethostbyname()\n");
+			i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
+			free(packet);
+
+			if (i < 0)
+				return 0;
+			if (++nest > MAX_RECURSE)
+				return 0;
+			continue;
+		} else if (a.atype == T_AAAA) {	/* ADDRESS */
+			memcpy(&in, a.rdata, sizeof(in));
+			h.h_name = namebuf;
+			h.h_addrtype = AF_INET6;
+			h.h_length = sizeof(in);
+			h.h_addr_list = (char **) addr_list;
+			free(packet);
+			break;
+		} else {
+			free(packet);
+			return 0;
+		}
+	}
+
+	return &h;
+#endif /* __UCLIBC_HAS_IPV6__ */
+}
+#endif
 
 #ifdef L_getnetbyname
 
@@ -1100,6 +1222,10 @@ struct hostent * read_etc_hosts(const char * name, int ip)
 	static struct hostent	h;
 	static struct in_addr	in;
 	static struct in_addr	*addr_list[2];
+#ifdef __UCLIBC_HAS_IPV6__
+	static struct in6_addr	in6;
+	static struct in6_addr	*addr_list6[2];
+#endif /* __UCLIBC_HAS_IPV6__ */
 	static char				line[80];
 	FILE					*fp;
 	char					*cp;
@@ -1142,8 +1268,24 @@ struct hostent * read_etc_hosts(const char * name, int ip)
 				continue;
 		}
 
+#ifndef __UCLIBC_HAS_IPV6__
 		if (inet_aton(alias[0], &in) == 0)
 			break; /* bad ip address */
+#else /* __UCLIBC_HAS_IPV6__ */
+		if (inet_aton(alias[0], &in) == 0) {
+			if (inet_pton(AF_INET6, alias[0], &in6) == 0) {
+				addr_list6[0] = &in6;
+				addr_list6[1] = 0;
+				h.h_name = alias[1];
+				h.h_addrtype = AF_INET6;
+				h.h_length = sizeof(in6);
+				h.h_addr_list = (char**) addr_list6;
+				fclose(fp);
+				return(&h);
+			} else
+				break; /* bad ip address */
+		}
+#endif /* __UCLIBC_HAS_IPV6__ */
 
 		addr_list[0] = &in;
 		addr_list[1] = 0;