Hi,
this new Patch Version have many improves.

1. without IPv6 there is no longer used new syscalls 
(gethostbyname2,inet_ntop,inet_pton)
2. It can on runtime downgreade to IPv4
3. In IPv6 mode it can handle IPv4 Adresses
4. Checked with following input www.ix.de , 217.110.115.160 , 
www.ipv6.euronet.be
+ Adress is shown as expected
+ Connection work clean :-)
+ checked also with IPv4 only where www.ipv6.euronet.be don't work (as 
expected because its ipv6 only)

The only part witch make trouble WITH IPV6 is ftp. There is the question 
if anyone like to help meon this part.
Because i have no experience on FTP Protocol since jet, i found the 
right RFC's and see that for IPv6 there are
2 new Command's witch i think will not so hard to build in.

Cu Thomas
diff -ubr wget-1.8.1/src/connect.c wget-1.8.1_ipv6/src/connect.c
--- wget-1.8.1/src/connect.c    Tue Nov 27 14:55:40 2001
+++ wget-1.8.1_ipv6/src/connect.c       Tue Jan 15 17:36:18 2002
@@ -55,6 +55,8 @@
 extern int errno;
 #endif
 
+// #define IPV6
+
 /* Variables shared by bindport and acceptport: */
 static int msock = -1;
 static struct sockaddr *addr;
@@ -78,13 +80,12 @@
 int
 connect_to_one (const unsigned char *addr, unsigned short port, int silent)
 {
-  struct sockaddr_in sock_name;
+  SOCKADDR_IN sock_name;
   int sock, save_errno;
-
+  int sockaddr_len=get_socklen(ip_default_family);
   /* Set port and protocol */
-  sock_name.sin_family = AF_INET;
-  sock_name.sin_port = htons (port);
-  memcpy ((unsigned char *)&sock_name.sin_addr, addr, 4);
+  set_ip_address(ip_default_family,port,addr,(struct sockaddr *)&sock_name);
+
 
   if (!silent)
     {
@@ -99,15 +100,14 @@
     }
 
   /* Make an internet socket, stream type.  */
-  sock = socket (AF_INET, SOCK_STREAM, 0);
+  sock = socket (ip_default_family, SOCK_STREAM, 0);
   if (sock < 0)
     goto out;
 
   if (opt.bind_address)
     {
       /* Bind the client side to the requested address. */
-      if (bind (sock, (struct sockaddr *)opt.bind_address,
-               sizeof (*opt.bind_address)))
+      if (bind (sock, (struct sockaddr *)opt.bind_address,sockaddr_len))
        {
          close (sock);
          sock = -1;
@@ -116,7 +116,7 @@
     }
 
   /* Connect the socket to the remote host.  */
-  if (connect (sock, (struct sockaddr *)&sock_name, sizeof (sock_name)) < 0)
+  if (connect (sock, (struct sockaddr *)&sock_name,sockaddr_len) < 0)
     {
       close (sock);
       sock = -1;
@@ -151,7 +151,7 @@
   address_list_get_bounds (al, &start, &end);
   for (i = start; i < end; i++)
     {
-      unsigned char addr[4];
+      ip_address addr;
       int sock;
       address_list_copy_one (al, i, addr);
 
@@ -210,11 +210,13 @@
 bindport (unsigned short *port)
 {
   int optval = 1;
-  static struct sockaddr_in srv;
+  static SOCKADDR_IN srv={0};
+  int sockaddr_len=get_socklen(ip_default_family);
+  
 
   msock = -1;
   addr = (struct sockaddr *) &srv;
-  if ((msock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+  if ((msock = socket (ip_default_family, SOCK_STREAM, 0)) < 0)
     return CONSOCKERR;
   if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
                  (char *)&optval, sizeof (optval)) < 0)
@@ -222,14 +224,13 @@
 
   if (opt.bind_address == NULL)
     {
-      srv.sin_family = AF_INET;
-      srv.sin_addr.s_addr = htonl (INADDR_ANY);
+      set_ip_address(ip_default_family,htons(*port),NULL,(struct sockaddr*)&srv);
     }
   else
     srv = *opt.bind_address;
 
-  srv.sin_port = htons (*port);
-  if (bind (msock, addr, sizeof (struct sockaddr_in)) < 0)
+  set_port(*port,(struct sockaddr*)&srv);
+  if (bind (msock, addr, sockaddr_len) < 0)
     {
       CLOSE (msock);
       msock = -1;
@@ -241,14 +242,14 @@
       /* #### addrlen should be a 32-bit type, which int is not
          guaranteed to be.  Oh, and don't try to make it a size_t,
          because that can be 64-bit.  */
-      int addrlen = sizeof (struct sockaddr_in);
+      int addrlen = sockaddr_len;
       if (getsockname (msock, addr, &addrlen) < 0)
        {
          CLOSE (msock);
          msock = -1;
          return CONPORTERR;
        }
-      *port = ntohs (srv.sin_port);
+      *port=get_port((struct sockaddr*)&srv);
     }
   if (listen (msock, 1) < 0)
     {
@@ -292,7 +293,7 @@
 uerr_t
 acceptport (int *sock)
 {
-  int addrlen = sizeof (struct sockaddr_in);
+  int addrlen = get_socklen(ip_default_family);
 
 #ifdef HAVE_SELECT
   if (select_fd (msock, opt.timeout, 0) <= 0)
@@ -322,8 +323,8 @@
 unsigned char *
 conaddr (int fd)
 {
-  static unsigned char res[4];
-  struct sockaddr_in mysrv;
+  static ip_address res;
+  SOCKADDR_IN  mysrv;
   struct sockaddr *myaddr;
   int addrlen = sizeof (mysrv);        /* see bindport() for discussion of
                                    using `int' here. */
@@ -331,7 +332,11 @@
   myaddr = (struct sockaddr *) (&mysrv);
   if (getsockname (fd, myaddr, (int *)&addrlen) < 0)
     return NULL;
-  memcpy (res, &mysrv.sin_addr, 4);
+#ifdef IPV6
+  memcpy (res, &mysrv.sin6_addr, sizeof(ip_address));
+#else
+  memcpy (res, &mysrv.sin_addr, sizeof(ip_address));
+#endif
   return res;
 }
 
diff -ubr wget-1.8.1/src/host.c wget-1.8.1_ipv6/src/host.c
--- wget-1.8.1/src/host.c       Tue Dec 11 08:32:57 2001
+++ wget-1.8.1_ipv6/src/host.c  Tue Jan 15 17:37:48 2002
@@ -18,6 +18,7 @@
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <config.h>
+#include <netdb.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -65,8 +66,13 @@
 # endif
 #endif
 
-/* An IPv4 address is simply a 4-byte quantity. */
-typedef unsigned char ipv4_address[4];
+#ifdef IPV6
+int     ip_default_family = AF_INET6;
+#else
+int     ip_default_family = AF_INET;
+#endif
+
+
 
 /* Mapping between known hosts and to lists of their addresses. */
 
@@ -77,7 +83,8 @@
 
 struct address_list {
   int count;                   /* number of adrresses */
-  ipv4_address *addresses;     /* pointer to the string of addresses */
+  int ip_family;
+  ip_address *addresses;       /* pointer to the string of addresses */
 
   int faulty;                  /* number of addresses known not to
                                   work. */
@@ -85,6 +92,105 @@
                                   not. */
 };
 
+void
+set_ip_address(int ip_family,unsigned short port,const unsigned char*addr,struct 
+sockaddr *sock_name)
+{
+  if(ip_family==AF_INET) 
+    {
+      struct sockaddr_in *ip_sock=(struct sockaddr_in *)sock_name;
+      ip_sock->sin_family=ip_family;
+      ip_sock->sin_port=htons(port);
+      if(addr==NULL) memset((unsigned char*)&ip_sock->sin_addr,0   ,4);
+      else          memcpy((unsigned char*)&ip_sock->sin_addr,addr,4);
+    }
+#ifdef IPV6
+  if(ip_family==AF_INET6) 
+    {
+      struct sockaddr_in6 *ip_sock=(struct sockaddr_in6*)sock_name;
+      ip_sock->sin6_family=AF_INET6;
+      ip_sock->sin6_port=htons(port);
+      if(addr==NULL) memset(ip_sock->sin6_addr.in6_u.u6_addr8,0   ,16);
+      else          memcpy(ip_sock->sin6_addr.in6_u.u6_addr8,addr,16);
+    }
+#endif  
+}
+void set_port(unsigned short port,struct sockaddr *sock_name)
+{
+  if(sock_name->sa_family==AF_INET)
+    {
+      struct sockaddr_in *ip_sock=(struct sockaddr_in *)&sock_name;
+      ip_sock->sin_port=htons(port);
+    }
+#ifdef IPV6
+  if(sock_name->sa_family==AF_INET6)
+    {
+      struct sockaddr_in6 *ip_sock=(struct sockaddr_in6*)&sock_name;
+      ip_sock->sin6_port=htons(port);
+    }
+#endif
+}
+void set_family(int ip_family,struct sockaddr *sock_name)
+{
+  if(ip_family==AF_INET)
+    {
+      struct sockaddr_in *ip_sock=(struct sockaddr_in *)&sock_name;
+      ip_sock->sin_family=ip_family;
+    }
+#ifdef IPV6
+  if(ip_family==AF_INET6)
+    {
+      struct sockaddr_in6 *ip_sock=(struct sockaddr_in6*)&sock_name;
+      ip_sock->sin6_family=ip_family;
+    }
+#endif
+}
+
+const unsigned char *get_addr(struct sockaddr *sock_name)
+{ 
+  if(sock_name->sa_family==AF_INET)
+    {
+      struct sockaddr_in *ip_sock=(struct sockaddr_in *)&sock_name;
+      return (unsigned char*)&ip_sock->sin_addr;
+    }
+#ifdef IPV6
+  if(sock_name->sa_family==AF_INET6)
+    {
+      struct sockaddr_in6 *ip_sock=(struct sockaddr_in6*)&sock_name;
+      return ip_sock->sin6_addr.in6_u.u6_addr8;
+    }
+#endif
+  return NULL;
+}
+
+unsigned short get_port(struct sockaddr *sock_name)
+{
+  if(sock_name->sa_family==AF_INET)
+    {
+      struct sockaddr_in *ip_sock=(struct sockaddr_in *)&sock_name;
+      return ntohs(ip_sock->sin_port);
+    }
+#ifdef IPV6
+  if(sock_name->sa_family==AF_INET6)
+    {
+      struct sockaddr_in6 *ip_sock=(struct sockaddr_in6*)&sock_name;
+      return ntohs(ip_sock->sin6_port);
+    }
+#endif
+  return -1;
+}
+int get_socklen(int ip_family) 
+{
+  if(ip_family==AF_INET) return sizeof(struct sockaddr_in);
+#ifdef IPV6
+  if(ip_family==AF_INET6) return sizeof(struct sockaddr_in6);
+#endif
+  return 0;
+}
+
+
+
+
+
 /* Get the bounds of the address list.  */
 
 void
@@ -101,7 +207,7 @@
                       unsigned char *ip_store)
 {
   assert (index >= al->faulty && index < al->count);
-  memcpy (ip_store, al->addresses + index, sizeof (ipv4_address));
+  memcpy (ip_store, al->addresses + index, sizeof (ip_address));
 }
 
 /* Check whether two address lists have all their IPs in common.  */
@@ -114,7 +220,7 @@
   if (al1->count != al2->count)
     return 0;
   return 0 == memcmp (al1->addresses, al2->addresses,
-                     al1->count * sizeof (ipv4_address));
+                     al1->count * sizeof (ip_address));
 }
 
 /* Mark the INDEXth element of AL as faulty, so that the next time
@@ -152,26 +258,25 @@
   assert (count > 0);
   al->count     = count;
   al->faulty    = 0;
-  al->addresses = xmalloc (count * sizeof (ipv4_address));
+  al->addresses = xmalloc (count * sizeof (ip_address));
   al->refcount  = 1;
 
   for (i = 0; i < count; i++)
-    memcpy (al->addresses + i, h_addr_list[i], sizeof (ipv4_address));
-
+    memcpy (al->addresses + i, h_addr_list[i], sizeof (ip_address));
   return al;
 }
 
 /* Like address_list_new, but initialized with only one address. */
 
 static struct address_list *
-address_list_new_one (const char *addr)
+address_list_new_one (const char *addr,int ip_family) 
 {
   struct address_list *al = xmalloc (sizeof (struct address_list));
   al->count     = 1;
   al->faulty    = 0;
-  al->addresses = xmalloc (sizeof (ipv4_address));
+  al->addresses = xmalloc (sizeof (ip_address));
   al->refcount  = 1;
-  memcpy (al->addresses, addr, sizeof (ipv4_address));
+  memcpy (al->addresses, addr, sizeof (ip_address));
 
   return al;
 }
@@ -201,7 +306,14 @@
 char *
 pretty_print_address (const void *addr)
 {
+#ifdef IPV6
+  char buf[128];
+  if(NULL==inet_ntop(ip_default_family,addr,buf,128)) return NULL;
+  if(0==strncmp(buf,"::ffff:",7)) return strdup(buf+7);
+  return strdup(buf);
+#else
   return inet_ntoa (*(struct in_addr *)addr);
+#endif
 }
 
 /* Add host name HOST with the address ADDR_TEXT to the cache.
@@ -233,30 +345,41 @@
 lookup_host (const char *host, int silent)
 {
   struct address_list *al = NULL;
-  unsigned long addr;
+  ip_address addr;
   struct hostent *hptr;
+  int ret;
 
-  /* If the address is of the form d.d.d.d, no further lookup is
-     needed.  */
-  addr = (unsigned long)inet_addr (host);
-  if ((int)addr != -1)
+  /* If the address is of the form that if valid for <family>, 
+     no further lookup is needed.  */
+
+#ifdef IPV6
+  ret=inet_pton(ip_default_family,host,addr);
+  if(0>ret)
     {
+    int offset;
+#else
+  long tmp_ipv4=(long)inet_addr (host);
+  if((int)tmp_ipv4!=-1)
+    {
+      int offset;
+      memcpy(addr,&tmp_ipv4,4);
+#endif
+
       /* ADDR is defined to be in network byte order, which is what
         this returns, so we can just copy it to STORE_IP.  However,
         on big endian 64-bit architectures the value will be stored
         in the *last*, not first four bytes.  OFFSET makes sure that
         we copy the correct four bytes.  */
-      int offset;
+  
 #ifdef WORDS_BIGENDIAN
-      offset = sizeof (unsigned long) - sizeof (ipv4_address);
+      offset = sizeof (unsigned long) - sizeof (ip_address);
 #else
       offset = 0;
 #endif
-      return address_list_new_one ((char *)&addr + offset);
+      return address_list_new_one ((char *)&addr + offset,ip_default_family);
     }
 
-  /* By now we know that the host name we got is not of the form
-     d.d.d.d.  Try to find it in our cache of host names.  */
+  
   if (host_name_addresses_map)
     al = hash_table_get (host_name_addresses_map, host);
 
@@ -270,8 +393,13 @@
   if (!silent)
     logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
 
-  /* Look up the host using gethostbyname().  */
-  hptr = gethostbyname (host);
+  /* Look up the host using getipnodebyname().  */
+#ifdef IPV6
+           hptr = gethostbyname2(host,ip_default_family);
+  if(!hptr) hptr = gethostbyname2(host,AF_INET);
+#else
+  hptr = gethostbyname(host);
+#endif
   if (!hptr)
     {
       if (!silent)
@@ -284,8 +412,32 @@
 
   /* Do all systems have h_addr_list, or is it a newer thing?  If the
      latter, use address_list_new_one.  */
+#ifdef IPV6  
+  if(hptr->h_addrtype==AF_INET && ip_default_family==AF_INET6) 
+    {
+      unsigned char IPv64[12]={0,0,0,0, 0,0,0,0, 0,0,0xff,0xff};
+      struct hostent *HOSTENT;
+      int count=0,i;
+      while(hptr->h_addr_list[count]) 
+        count++;
+
+      HOSTENT=xmalloc(sizeof(struct hostent));
+      HOSTENT->h_name=strdup(hptr->h_name);
+      HOSTENT->h_aliases=NULL;
+      HOSTENT->h_addrtype=AF_INET6;
+      HOSTENT->h_length=16;
+      HOSTENT->h_addr_list=xmalloc((count+1)*sizeof(char*));
+      HOSTENT->h_addr_list[count]=NULL;
+      for(i=0;i<count;i++)
+        {
+         HOSTENT->h_addr_list[i]=xmalloc(16);
+          memcpy ((HOSTENT->h_addr_list[i])+12, hptr->h_addr_list[i], 4);
+          memcpy ((HOSTENT->h_addr_list[i])+ 0, IPv64         ,12);
+        }
+      hptr=HOSTENT;
+    } 
+#endif  
   al = address_list_new (hptr->h_addr_list);
-
   /* Cache the lookup information. */
   cache_host_lookup (host, al);
 
diff -ubr wget-1.8.1/src/host.h wget-1.8.1_ipv6/src/host.h
--- wget-1.8.1/src/host.h       Tue Dec 11 08:32:58 2001
+++ wget-1.8.1_ipv6/src/host.h  Tue Jan 15 17:35:51 2002
@@ -19,6 +19,7 @@
 
 #ifndef HOST_H
 #define HOST_H
+#include <netdb.h>
 
 struct url;
 struct address_list;
@@ -43,5 +44,31 @@
 int sufmatch PARAMS ((const char **, const char *));
 
 void host_cleanup PARAMS ((void));
+void set_ip_address(int ip_family,unsigned short port,
+               const unsigned char*addr,struct sockaddr *sock_name);
+void set_port  (unsigned short port,struct sockaddr *sock_name);       
+void set_family(int ip_family,struct sockaddr *sock_name);     
+
+const unsigned char *get_addr(struct sockaddr *sock_name);
+unsigned short       get_port(struct sockaddr *sock_name);
+// #define IPV6
+/*
+       IPv6 support added by Thomas Lussnig <[EMAIL PROTECTED]>
+       Date: 15.01.2001 02:36:05
+       If there are mistakes please inform me, but i will not work till the
+       morning on it.
+*/
+
+#ifdef IPV6
+/* An IPv6 address is simply a 16-byte quantity. */
+typedef unsigned char ip_address[16];
+typedef struct sockaddr_in6    SOCKADDR_IN;
+#else
+/* An IPv4 address is simply a 4-byte quantity. */
+typedef unsigned char ip_address[4];
+typedef struct sockaddr_in     SOCKADDR_IN;
+#endif
+extern int     ip_default_family;      /* defined in host.c */
+
 
 #endif /* HOST_H */
diff -ubr wget-1.8.1/src/init.c wget-1.8.1_ipv6/src/init.c
--- wget-1.8.1/src/init.c       Thu Dec 13 19:19:03 2001
+++ wget-1.8.1_ipv6/src/init.c  Tue Jan 15 12:10:32 2002
@@ -526,8 +526,8 @@
 cmd_address (const char *com, const char *val, void *closure)
 {
   struct address_list *al;
-  struct sockaddr_in sin;
-  struct sockaddr_in **target = (struct sockaddr_in **)closure;
+  SOCKADDR_IN sin;
+  SOCKADDR_IN **target = (SOCKADDR_IN **)closure;
 
   memset (&sin, '\0', sizeof (sin));
 
@@ -538,11 +538,10 @@
               exec_name, com, val);
       return 0;
     }
-  address_list_copy_one (al, 0, (unsigned char *)&sin.sin_addr);
+  set_family(ip_default_family,  (struct sockaddr*)&sin);
+  set_port  (0,(struct sockaddr*)&sin);
+  address_list_copy_one(al, 0,get_addr((struct sockaddr*)&sin));
   address_list_release (al);
-
-  sin.sin_family = AF_INET;
-  sin.sin_port = 0;
 
   FREE_MAYBE (*target);
 
diff -ubr wget-1.8.1/src/options.h wget-1.8.1_ipv6/src/options.h
--- wget-1.8.1/src/options.h    Fri Nov 30 07:39:08 2001
+++ wget-1.8.1_ipv6/src/options.h       Tue Jan 15 01:05:44 2002
@@ -19,6 +19,7 @@
 
 /* Needed for FDP.  */
 #include <stdio.h>
+#include "host.h"
 
 struct options
 {
@@ -153,7 +154,7 @@
   int page_requisites;         /* Whether we need to download all files
                                   necessary to display a page properly. */
 
-  struct sockaddr_in *bind_address; /* What local IP address to bind to. */
+  SOCKADDR_IN *bind_address;   /* What local IP address to bind to. */
 
 #ifdef HAVE_SSL
   char *sslcertfile;           /* external client cert to use. */

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to