OSDN Git Service

A patch from Michal Moskal <malekith@pld.org.pl> to include
authorEric Andersen <andersen@codepoet.org>
Mon, 9 Jul 2001 21:20:20 +0000 (21:20 -0000)
committerEric Andersen <andersen@codepoet.org>
Mon, 9 Jul 2001 21:20:20 +0000 (21:20 -0000)
partial IPV6 support.  This adds things like gethostbyname2().
Off by defaut, of course,

14 files changed:
Makefile
extra/Configs/Config.arm
extra/Configs/Config.cross.arm.uclinux
extra/Configs/Config.i386
extra/Configs/Config.m68k
extra/Configs/Config.m68k.coff
extra/Configs/Config.mips
extra/Configs/Config.mipsel
extra/Configs/Config.powerpc
extra/Configs/Config.sh
include/netdb.h
libc/inet/Makefile
libc/inet/ntop.c
libc/inet/resolv.c

index 96f1d88..98ab12e 100644 (file)
--- a/Makefile
+++ b/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 \
index 21c66bc..408a23f 100644 (file)
@@ -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
 
index 9f34e83..f61a8d2 100644 (file)
@@ -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
 
index 1876d05..b383ebd 100644 (file)
@@ -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
 
index becad56..dc6e107 100644 (file)
@@ -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
 
index e70220a..c0bbd3f 100644 (file)
@@ -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
 
index 30778e8..163a9aa 100644 (file)
@@ -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
 
index 30778e8..163a9aa 100644 (file)
@@ -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
 
index 836b1df..659231d 100644 (file)
@@ -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
 
index 39736b4..9012530 100644 (file)
@@ -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
 
index 888b87d..96358bd 100644 (file)
@@ -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 *));
index e6ffff6..6fd7501 100644 (file)
@@ -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 \
index 6d7e691..521c1de 100644 (file)
 #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;
index 00b7a76..034bb80 100644 (file)
  *
  *                              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;