diff -ur uClibc/Config uClibc-/Config --- uClibc/Config Thu May 17 22:27:31 2001 +++ uClibc-/Config Wed Jun 20 11:13:04 2001 @@ -58,6 +58,10 @@ # work at all. You have been warned. KERNEL_SOURCE=/usr/src/linux +# Set this to `false' if you don't want IPv6 resolver. +# Set it to `true' otherwise. +HAS_IPV6 = true + # Set this to `false' if your CPU doesn't have a memory management unit (MMU). # Set it to `true' otherwise. HAS_MMU = true diff -ur uClibc/Makefile uClibc-/Makefile --- uClibc/Makefile Thu May 17 07:30:43 2001 +++ uClibc-/Makefile Wed Jun 20 11:13:04 2001 @@ -77,6 +77,11 @@ @echo "#endif" >> uClibc_config.h @echo "#define linux 1" >> uClibc_config.h @echo "#define __linux__ 1" >> uClibc_config.h + @if [ "$(HAS_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 \ diff -ur uClibc/include/netdb.h uClibc-/include/netdb.h --- uClibc/include/netdb.h Mon Mar 12 11:06:18 2001 +++ uClibc-/include/netdb.h Wed Jun 20 11:13:04 2001 @@ -153,6 +153,7 @@ 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 *)); diff -ur uClibc/libc/inet/Makefile uClibc-/libc/inet/Makefile --- uClibc/libc/inet/Makefile Sat May 12 08:19:04 2001 +++ uClibc-/libc/inet/Makefile Wed Jun 20 11:13:04 2001 @@ -39,8 +39,8 @@ 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 \ diff -ur uClibc/libc/inet/ntop.c uClibc-/libc/inet/ntop.c --- uClibc/libc/inet/ntop.c Tue May 8 15:59:30 2001 +++ uClibc-/libc/inet/ntop.c Wed Jun 20 11:13:04 2001 @@ -27,6 +27,12 @@ #include #include +#ifdef __UCLIBC_HAS_IPV6__ +#define INET_IPV6 +#define SPRINTF(a) sprintf a +#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. @@ -256,6 +262,7 @@ const char *curtok; int ch, saw_xdigit; u_int val; + tp = memset(tmp, '\0', 16); endp = tp + 16; diff -ur uClibc/libc/inet/resolv.c uClibc-/libc/inet/resolv.c --- uClibc/libc/inet/resolv.c Mon Feb 26 04:48:52 2001 +++ uClibc-/libc/inet/resolv.c Wed Jun 20 11:13:04 2001 @@ -32,6 +32,10 @@ * * General cleanup * + * 20-Jun-2001 Michal Moskal + * 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 @@ -458,6 +464,9 @@ 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; @@ -466,6 +475,9 @@ 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; @@ -477,11 +489,18 @@ 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; @@ -519,11 +538,28 @@ 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; @@ -951,6 +987,92 @@ } #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] = ∈ + 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 @@ -1093,6 +1215,10 @@ 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; @@ -1135,8 +1261,24 @@ 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] = ∈ addr_list[1] = 0;