diff -ur dancer-ircd-1.0.31+maint5/include/client.h dancer-ircd-1.0.31+maint5+IPv6/include/client.h
--- dancer-ircd-1.0.31+maint5/include/client.h	Fri Dec 14 13:42:01 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/include/client.h	Mon Apr  1 01:20:10 2002
@@ -47,8 +47,8 @@
 #include "umodes.h"
 #include <sys/time.h>
 
-#define HOSTIPLEN       16      /* Length of dotted quad form of IP        */
-                                /* - Dianora                               */
+#define HOSTIPLEN       70      /* MUCH bigger for ipv6 :)*/
+                                /* - stu                               */
 #define PASSWDLEN       60
 #define IDLEN           12      /* this is the maximum length, not the actual
                                    generated length; DO NOT CHANGE! */
@@ -193,7 +193,7 @@
 #endif
 
   /* I have these everywhere now */
-  struct in_addr    ip;         /* keep real ip# too */
+  struct IN_ADDR    ip;         /* keep real ip# too */
   char              dnshost[HOSTLEN + 1]; /* Resolved hostname (or sockhost) */
   char              spoofhost[HOSTLEN + 1]; /* Hostname to spoof to, when user is spoofed */
   /*
diff -ur dancer-ircd-1.0.31+maint5/include/config.h dancer-ircd-1.0.31+maint5+IPv6/include/config.h
--- dancer-ircd-1.0.31+maint5/include/config.h	Sat Mar 30 22:48:41 2002
+++ dancer-ircd-1.0.31+maint5+IPv6/include/config.h	Mon Apr  1 01:20:10 2002
@@ -54,6 +54,13 @@
 #define CHALLENGERESPONSE
 #define CHALLENGERESPONSE_FALLBACK
 
+/* IPV6 Support - stu
+ */
+
+#define IPV6
+
+
+
 /***************** MAKE SURE THIS IS CORRECT!!!!!!!!! **************/
 /* ONLY EDIT "HARD_FDLIMIT_" and "INIT_MAXCLIENTS" */
 
diff -ur dancer-ircd-1.0.31+maint5/include/config.h.opn dancer-ircd-1.0.31+maint5+IPv6/include/config.h.opn
--- dancer-ircd-1.0.31+maint5/include/config.h.opn	Fri Mar 29 00:39:07 2002
+++ dancer-ircd-1.0.31+maint5+IPv6/include/config.h.opn	Mon Apr  1 01:25:33 2002
@@ -54,6 +54,13 @@
 #define CHALLENGERESPONSE
 #define CHALLENGERESPONSE_FALLBACK
 
+/* IPV6 Support - stu
+ */
+
+#define IPV6
+
+
+
 /***************** MAKE SURE THIS IS CORRECT!!!!!!!!! **************/
 /* ONLY EDIT "HARD_FDLIMIT_" and "INIT_MAXCLIENTS" */
 
diff -ur dancer-ircd-1.0.31+maint5/include/ircd_defs.h dancer-ircd-1.0.31+maint5+IPv6/include/ircd_defs.h
--- dancer-ircd-1.0.31+maint5/include/ircd_defs.h	Sat Mar 16 17:41:18 2002
+++ dancer-ircd-1.0.31+maint5+IPv6/include/ircd_defs.h	Mon Apr  1 01:20:10 2002
@@ -103,5 +103,25 @@
 
 #endif
 
+#ifdef IPV6
+#define IN_ADDR     in6_addr
+#define S_ADDR      s6_addr
+#define SOCKADDR_IN sockaddr_in6
+#define SIN_PORT    sin6_port
+#define SIN_ADDR    sin6_addr
+#define SIN_FAMILY  sin6_family
+#define AFINET      AF_INET6
+#define INADDRANY   in6addr_any
+#else
+#define IN_ADDR     in_addr
+#define S_ADDR      s_addr
+#define SOCKADDR_IN sockaddr_in
+#define SIN_PORT    sin_port
+#define SIN_ADDR    sin_addr
+#define SIN_FAMILY  sin_family
+#define AFINET      AF_INET
+#define INADDRANY   INADDR_ANY
+#endif
+				
 
 #endif /* INCLUDED_ircd_defs_h */
diff -ur dancer-ircd-1.0.31+maint5/include/listener.h dancer-ircd-1.0.31+maint5+IPv6/include/listener.h
--- dancer-ircd-1.0.31+maint5/include/listener.h	Wed Dec 12 15:05:17 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/include/listener.h	Mon Apr  1 01:20:10 2002
@@ -43,7 +43,7 @@
   int              active;             /* current state of listener */
   int              index;              /* index into poll array */
   time_t           last_accept;        /* last time listener accepted */
-  struct in_addr   addr;               /* virtual address or INADDR_ANY */
+  struct IN_ADDR   addr;               /* virtual address or INADDR_ANY */
   char             vhost[HOSTLEN + 1]; /* virtual name of listener */
   int              server_port;        /* servers can connect here */
   int              user_port;          /* users can connect here */
@@ -58,7 +58,7 @@
 extern void        close_listeners(void);
 extern void        free_listener(struct Listener* listener);
 extern const char* get_listener_name(const struct Listener* listener);
-extern struct Listener* make_listener(int port, struct in_addr addr);
+extern struct Listener* make_listener(int port, struct IN_ADDR addr);
 extern void        mark_listeners_closing(void);
 extern void        show_ports(struct Client* client);
 
diff -ur dancer-ircd-1.0.31+maint5/include/res.h dancer-ircd-1.0.31+maint5+IPv6/include/res.h
--- dancer-ircd-1.0.31+maint5/include/res.h	Sat Dec 15 15:10:05 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/include/res.h	Mon Apr  1 01:20:10 2002
@@ -29,6 +29,9 @@
 extern void get_res(void);
 extern struct DNSReply* gethost_byname(const char* name, 
                                        const struct DNSQuery* req);
+extern struct DNSReply* gethost_byname_type(const char* name,
+                                       const struct DNSQuery* req,
+                                       int type);
 extern struct DNSReply* gethost_byaddr(const char* name, 
                                        const struct DNSQuery* req);
 extern int             init_resolver(void);
diff -ur dancer-ircd-1.0.31+maint5/include/s_bsd.h dancer-ircd-1.0.31+maint5+IPv6/include/s_bsd.h
--- dancer-ircd-1.0.31+maint5/include/s_bsd.h	Wed Dec 12 15:05:17 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/include/s_bsd.h	Mon Apr  1 01:20:10 2002
@@ -52,6 +52,7 @@
 extern int   set_sock_buffers(int, int);
 extern int   send_queued(struct Client*);
 extern int   deliver_it(struct Client*, const char*, int);
-
+extern char  *inetntop(int, const void*, char*, size_t);
+extern int   inetpton(int af, const char *src, void *dst);
 #endif /* INCLUDED_s_bsd_h */
 
diff -ur dancer-ircd-1.0.31+maint5/include/s_conf.h dancer-ircd-1.0.31+maint5+IPv6/include/s_conf.h
--- dancer-ircd-1.0.31+maint5/include/s_conf.h	Sat Mar 16 01:17:18 2002
+++ dancer-ircd-1.0.31+maint5+IPv6/include/s_conf.h	Mon Apr  1 01:20:10 2002
@@ -53,7 +53,7 @@
   unsigned int     status;   /* If CONF_ILLEGAL, delete when no clients */
   u_int32_t        flags;
   int              clients;  /* Number of *LOCAL* clients using this */
-  struct in_addr   ipnum;    /* ip number of host field */
+  struct IN_ADDR   ipnum;    /* ip number of host field */
   unsigned long    ip;       /* only used for I D lines etc. */
   unsigned long    ip_mask;
   char*            name;     /* IRC name, nick, server name, or original u@h */
@@ -236,7 +236,7 @@
 extern struct ConfItem* find_conf_by_abbrevname(const char* name, unsigned int status);
 extern struct ConfItem* find_kill (struct Client *);
 extern struct ConfItem* find_tkline(const char*, const char*, unsigned long);
-extern int conf_connect_allowed(struct in_addr addr);
+extern int conf_connect_allowed(struct IN_ADDR addr);
 extern char *oper_flags_as_string(user_modes);
 extern int rehash_dump(struct Client *);
 extern int find_q_line(char*, char*, char *);
diff -ur dancer-ircd-1.0.31+maint5/src/client.c dancer-ircd-1.0.31+maint5+IPv6/src/client.c
--- dancer-ircd-1.0.31+maint5/src/client.c	Mon Mar 18 01:42:07 2002
+++ dancer-ircd-1.0.31+maint5+IPv6/src/client.c	Mon Apr  1 01:20:10 2002
@@ -314,8 +314,11 @@
         {
           if(dline_in_progress)
             {
+#ifdef IPV6
+              if( (aconf = match_Dline(ntohl((uint32_t)cptr->ip.S_ADDR))) )
+#else
               if( (aconf = match_Dline(ntohl(cptr->ip.s_addr))) )
-
+#endif
                   /* if there is a returned 
                    * struct ConfItem then kill it
                    */
@@ -1440,8 +1443,13 @@
       if(sptr->flags & FLAGS_IPHASH)
         remove_one_ip(sptr);
 #else
+#ifdef IPV6
+      if(sptr->flags & FLAGS_IPHASH)
+        remove_one_ip((unsigned long)sptr->ip.s6_addr);
+#else
       if(sptr->flags & FLAGS_IPHASH)
         remove_one_ip(sptr->ip.s_addr);
+#endif /* IPv6 */             
 #endif
       fdlist_delete(sptr->fd, FDL_OPER | FDL_BUSY);
 #if 0
diff -ur dancer-ircd-1.0.31+maint5/src/ircd.c dancer-ircd-1.0.31+maint5+IPv6/src/ircd.c
--- dancer-ircd-1.0.31+maint5/src/ircd.c	Wed Dec 12 15:05:17 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/ircd.c	Mon Apr  1 01:20:10 2002
@@ -264,7 +264,7 @@
             close(fd);
           }
       }
-#endif
+#endif 
      setsid();
     }
   close_all_connections();
diff -ur dancer-ircd-1.0.31+maint5/src/listener.c dancer-ircd-1.0.31+maint5+IPv6/src/listener.c
--- dancer-ircd-1.0.31+maint5/src/listener.c	Wed Dec 12 15:05:17 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/listener.c	Mon Apr  1 01:20:10 2002
@@ -37,8 +37,11 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <netdb.h>
+#include <sys/types.h>
 #include <sys/socket.h>
+#include <netinet/in.h>
 #include <arpa/inet.h>
+#include <stdio.h>
 
 #ifndef INADDR_NONE
 #define INADDR_NONE ((unsigned int) 0xffffffff)
@@ -46,7 +49,7 @@
 
 struct Listener* ListenerPollList = 0;
 
-struct Listener* make_listener(int port, struct in_addr addr)
+struct Listener* make_listener(int port, struct IN_ADDR addr)
 {
   struct Listener* listener = 
     (struct Listener*) MyMalloc(sizeof(struct Listener));
@@ -57,7 +60,11 @@
   listener->name        = me.name;
   listener->fd          = -1;
   listener->port        = port;
+#ifdef IPV6
+  memcpy(listener->addr.S_ADDR, addr.S_ADDR, sizeof(struct IN_ADDR));
+#else
   listener->addr.s_addr = addr.s_addr;
+#endif
 
 #ifdef NULL_POINTER_NOT_ZERO
   listener->next = NULL;
@@ -155,14 +162,14 @@
 
 static int inetport(struct Listener* listener)
 {
-  struct sockaddr_in port_sin;
+  struct SOCKADDR_IN port_sin;
   int                fd;
   int                opt = 1;
 
   /*
    * At first, open a new socket
    */
-  fd = socket(AF_INET, SOCK_STREAM, 0);
+  fd = socket(AFINET, SOCK_STREAM, 0);
 
   if (-1 == fd) {
     report_error("opening listener socket %s:%s", 
@@ -191,20 +198,33 @@
    * else assume it is already open and try get something from it.
    */
   memset(&port_sin, 0, sizeof(port_sin));
-  port_sin.sin_family = AF_INET;
+  port_sin.SIN_FAMILY = AFINET;
+  port_sin.SIN_PORT   = htons(listener->port);
+#ifdef IPV6
+  bcopy((const char*)listener->addr.S_ADDR, (char*)port_sin.SIN_ADDR.S_ADDR, sizeof(struct IN_ADDR));
+  if ( bcmp((char*)listener->addr.S_ADDR, &INADDRANY, sizeof(struct IN_ADDR)) == 0 ) {
+#else
   port_sin.sin_addr   = listener->addr;
-  port_sin.sin_port   = htons(listener->port);
+  if (INADDRANY != listener->addr.s_addr) {
+#endif
 
-  if (INADDR_ANY != listener->addr.s_addr) {
-    struct hostent* hp;
+	struct addrinfo *ans;
+	int ret;
+	char port[5];
+    char tmp[HOSTLEN];
     /*
-     * XXX - blocking call to gethostbyaddr
+     * XXX - blocking call to getaddrinfo 
      */
-    if ((hp = gethostbyaddr((char*) &listener->addr, 
-                            sizeof(struct sockaddr_in), AF_INET))) {
-      strncpy_irc(listener->vhost, hp->h_name, HOSTLEN);
-      listener->name = listener->vhost;
-    }
+
+	sprintf( port, "%d", listener->port);
+#ifdef IPV6
+    inetntop(AFINET, &listener->addr, tmp, HOSTLEN);
+#else
+    inet_ntop(AF_INET, &listener->addr, tmp, HOSTLEN);
+#endif
+	ret = getaddrinfo(tmp, port, NULL, &ans ); 
+	if( ret == 0 )
+	  strncpy_irc(listener->vhost, ans->ai_canonname, HOSTLEN);
   }
 
   if (bind(fd, (struct sockaddr*) &port_sin, sizeof(port_sin))) {
@@ -232,13 +252,16 @@
   return 1;
 }
 
-static struct Listener* find_listener(int port, struct in_addr addr)
+static struct Listener* find_listener(int port, struct IN_ADDR addr)
 {
   struct Listener* listener;
-  for (listener = ListenerPollList; listener; listener = listener->next) {
-    if (port == listener->port && addr.s_addr == listener->addr.s_addr)
+  for (listener = ListenerPollList; listener; listener = listener->next) 
+#ifdef IPV6
+    if(port == listener->port && bcmp((const char*)addr.S_ADDR, (const char*)listener->addr.S_ADDR, sizeof(struct IN_ADDR)) ==0)
+#else
+    if(port == listener->port && addr.s_addr == listener->addr.s_addr)
+#endif
       return listener;
-  }
   return 0;
 }
  
@@ -247,12 +270,12 @@
  * add_listener- create a new listener 
  * port - the port number to listen on
  * vhost_ip - if non-null must contain a valid IP address string in
- * the format "255.255.255.255"
+ * the format "255.255.255.255", or even an ipv6 address
  */
 void add_listener(int port, const char* vhost_ip, int is_server, int is_user, int is_hidden)
 {
   struct Listener* listener;
-  struct in_addr   vaddr;
+  struct IN_ADDR   vaddr;
 
   /*
    * if no port in conf line, don't bother
@@ -260,12 +283,21 @@
   if (0 == port)
     return;
 
-  vaddr.s_addr = INADDR_ANY;
+#ifdef IPV6
+  vaddr = INADDRANY;
+#else
+  vaddr.s_addr = INADDRANY;
+#endif
 
   if (vhost_ip[0]) {
+#ifdef IPV6
+    if(inetpton(AFINET, vhost_ip, &vaddr) == 0) 
+      return;
+#else
     vaddr.s_addr = inet_addr(vhost_ip);
     if (INADDR_NONE == vaddr.s_addr)
       return;
+#endif
   }
 
   if ((listener = find_listener(port, vaddr))) {
@@ -342,10 +374,10 @@
 void accept_connection(struct Listener* listener)
 {
   static time_t      last_oper_notice = 0;
-  struct sockaddr_in addr;
-  socklen_t          addrlen = sizeof(struct sockaddr_in);
+  struct SOCKADDR_IN addr;
+  socklen_t          addrlen = sizeof(struct SOCKADDR_IN);
   int                fd;
-
+  
   assert(0 != listener);
 
   listener->last_accept = CurrentTime;
@@ -402,7 +434,7 @@
   /*
    * check conf for ip address access
    */
-  if (!conf_connect_allowed(addr.sin_addr)) {
+  if (!conf_connect_allowed(addr.SIN_ADDR)) {
     ServerStats->is_ref++;
 #ifdef REPORT_DLINE_TO_USER
      send(fd, "NOTICE DLINE :*** You have been D-lined\r\n", 41, 0);
@@ -412,7 +444,6 @@
   }
   ServerStats->is_ac++;
   nextping = CurrentTime;
-
   add_connection(listener, fd);
 }
 
diff -ur dancer-ircd-1.0.31+maint5/src/m_chall.c dancer-ircd-1.0.31+maint5+IPv6/src/m_chall.c
--- dancer-ircd-1.0.31+maint5/src/m_chall.c	Wed Dec 12 15:05:17 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/m_chall.c	Mon Apr  1 01:20:10 2002
@@ -18,6 +18,12 @@
 #include "s_cr.h"
 #include "s_serv.h"
 #include "umodes.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
 
 /*
  * m_functions execute protocol messages on this server:
@@ -147,8 +153,14 @@
     return exit_client(cptr, cptr, cptr, "Access denied. No C line");    
   }
   
-  /* Check if the ip matches the c/n IPs */
+  /* Check if the ip matches the c/n IPs */ 
+#ifdef IPV6
+  if((bcmp((char*)cptr->ip.S_ADDR, (char*)c_conf->ipnum.S_ADDR, sizeof(struct IN_ADDR) != 0)) ||
+        (bcmp((char*)cptr->ip.S_ADDR, (char*)n_conf->ipnum.S_ADDR,  sizeof(struct IN_ADDR)) != 0))
+  {
+#else
   if ( (cptr->ip.s_addr != c_conf->ipnum.s_addr) || (cptr->ip.s_addr != n_conf->ipnum.s_addr)) {
+#endif
     sendto_ops_flag(UMODE_SERVCONNECT, "Challenge rejected. C/N line IP doesn't match connection");
     log(L_NOTICE, "Challenge rejected. C/N line IP doesn't match connection");
     sendto_one(cptr, "ERROR :Access denied. C/N line don't match you"); 
diff -ur dancer-ircd-1.0.31+maint5/src/m_kline.c dancer-ircd-1.0.31+maint5+IPv6/src/m_kline.c
--- dancer-ircd-1.0.31+maint5/src/m_kline.c	Sat Dec 15 20:01:19 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/m_kline.c	Mon Apr  1 01:20:10 2002
@@ -1233,7 +1233,7 @@
       host = cidr_form_host;
 
       ip_mask = 0xFFFFFF00L;
-      ip_host = ntohl(acptr->ip.s_addr);
+      ip_host = ntohl((unsigned long)acptr->ip.S_ADDR);
     }
 
 
diff -ur dancer-ircd-1.0.31+maint5/src/m_quit.c dancer-ircd-1.0.31+maint5+IPv6/src/m_quit.c
--- dancer-ircd-1.0.31+maint5/src/m_quit.c	Thu Dec 13 13:41:54 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/m_quit.c	Mon Apr  1 01:20:10 2002
@@ -151,7 +151,7 @@
 #ifdef ANTI_SPAM_EXIT_MESSAGE
   if( !IsServer(sptr) && MyConnect(sptr) &&
      (sptr->firsttime + ANTI_SPAM_EXIT_MESSAGE_TIME) > CurrentTime)
-    comment = "Client Quit";
+    strcpy(comment, "Client Quit");
 #endif
   if (IsPerson(sptr))
     {
diff -ur dancer-ircd-1.0.31+maint5/src/match.c dancer-ircd-1.0.31+maint5+IPv6/src/match.c
--- dancer-ircd-1.0.31+maint5/src/match.c	Wed Dec 12 15:05:17 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/match.c	Mon Apr  1 01:20:10 2002
@@ -403,7 +403,7 @@
 /* 7 */      PRINT_C|DIGIT_C|NICK_C|CHAN_C|NONEOS_C|USER_C|HOST_C,
 /* 8 */      PRINT_C|DIGIT_C|NICK_C|CHAN_C|NONEOS_C|USER_C|HOST_C,
 /* 9 */      PRINT_C|DIGIT_C|NICK_C|CHAN_C|NONEOS_C|USER_C|HOST_C,
-/* : */      PRINT_C|CHAN_C|NONEOS_C,
+/* : */      PRINT_C|CHAN_C|NONEOS_C|HOST_C,
 /* ; */      PRINT_C|CHAN_C|NONEOS_C,
 /* < */      PRINT_C|CHAN_C|NONEOS_C,
 /* = */      PRINT_C|CHAN_C|NONEOS_C,
diff -ur dancer-ircd-1.0.31+maint5/src/res.c dancer-ircd-1.0.31+maint5+IPv6/src/res.c
--- dancer-ircd-1.0.31+maint5/src/res.c	Sat Dec 15 15:09:24 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/res.c	Mon Apr  1 01:20:10 2002
@@ -69,10 +69,10 @@
  * macros used to calulate offsets into fixed query buffer
  */
 #define ALIAS_BLEN (size_t) ((RES_MAXALIASES + 1) * sizeof(char*))
-#define ADDRS_BLEN (size_t) ((RES_MAXADDRS + 1) * sizeof(struct in_addr*))
+#define ADDRS_BLEN (size_t) ((RES_MAXADDRS + 1) * sizeof(struct IN_ADDR*))
 
 #define ADDRS_OFFSET  (size_t) (ALIAS_BLEN + ADDRS_BLEN)
-#define ADDRS_DLEN    (size_t) (RES_MAXADDRS * sizeof(struct in_addr))
+#define ADDRS_DLEN    (size_t) (RES_MAXADDRS * sizeof(struct IN_ADDR))
 #define NAMES_OFFSET  (size_t) (ADDRS_OFFSET + ADDRS_DLEN)
 #define MAXGETHOSTLEN (size_t) (NAMES_OFFSET + MAXPACKET)
 
@@ -167,7 +167,7 @@
   char            resend;            /* send flag. 0 == dont resend */
   time_t          sentat;
   time_t          timeout;
-  struct in_addr  addr;
+  struct IN_ADDR  addr;
   char*           name;
   struct reslist* next;
   struct DNSQuery query;             /* query callback for this request */
@@ -217,9 +217,10 @@
 static void     rem_cache(aCache*);
 static void     do_query_name(const struct DNSQuery* query, 
                               const char* name, 
-                              ResRQ* request);
+                              ResRQ* request,
+                              int type);
 static void     do_query_number(const struct DNSQuery* query,
-                                const struct in_addr*, 
+                                const struct IN_ADDR*, 
                                 ResRQ* request);
 static void     query_name(const char* name, 
                            int query_class, 
@@ -330,6 +331,7 @@
 #ifdef DEBUG
   _res.options |= RES_DEBUG;
 #endif
+  _res.options |= RES_USE_INET6;
   if (ResolverFileDescriptor < 0) {
     ResolverFileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
     set_non_blocking(ResolverFileDescriptor);
@@ -454,9 +456,11 @@
   request->retries = 3;
   request->resend  = 1;
   request->timeout = 2;    /* start at 2 and exponential inc. */
+#ifndef IPV6
   request->addr.s_addr      = INADDR_NONE;
-  request->he.h.h_addrtype  = AF_INET;
-  request->he.h.h_length    = sizeof(struct in_addr);
+#endif
+  request->he.h.h_addrtype  = AFINET;
+  request->he.h.h_length    = sizeof(struct IN_ADDR);
   request->query.vptr       = query->vptr;
   request->query.callback   = query->callback;
 
@@ -624,10 +628,12 @@
 }
 
 /*
- * gethost_byname - get host address from name
+ * gethost_byname_type - get host address from name
  */
-struct DNSReply* gethost_byname(const char* name, 
-                               const struct DNSQuery* query)
+
+struct DNSReply* gethost_byname_type(const char* name, 
+                               const struct DNSQuery* query,
+                               int type)
 {
   aCache* cp;
   assert(0 != name);
@@ -636,11 +642,22 @@
   if ((cp = find_cache_name(name)))
     return &(cp->reply);
 
-  do_query_name(query, name, NULL);
+  do_query_name(query, name, NULL, type);
   nextDNSCheck = 1;
   return NULL;
 }
 
+/* Try to get a IPv6 address first, un;ess we're not using IPv6; in which case
+ * just look up boring old v4 - stu
+ */
+struct DNSReply* gethost_byname(const char* name, const struct DNSQuery* query)
+{
+#ifdef IPV6
+  return gethost_byname_type(name, query, T_AAAA);
+#else
+  return gethost_byname_type(name, query, T_A);
+#endif
+}
 /*
  * gethost_byaddr - get host name from address
  */
@@ -655,7 +672,7 @@
   if ((cp = find_cache_number(NULL, addr)))
     return &(cp->reply);
 
-  do_query_number(query, (const struct in_addr*) addr, NULL);
+  do_query_number(query, (const struct IN_ADDR*)addr, NULL);
   nextDNSCheck = 1;
   return NULL;
 }
@@ -663,7 +680,7 @@
  * do_query_name - nameserver lookup name
  */
 static void do_query_name(const struct DNSQuery* query, 
-                          const char* name, ResRQ* request)
+                          const char* name, ResRQ* request, int type)
 {
   char  hname[HOSTLEN + 1];
   assert(0 != name);
@@ -674,33 +691,73 @@
 
   if (!request) {
     request       = make_request(query);
-    request->type = T_A;
+    request->type = type;
     request->name = (char*) MyMalloc(strlen(hname) + 1);
     strcpy(request->name, hname);
   }
-  query_name(hname, C_IN, T_A, request);
+  query_name(hname, C_IN, type, request);
 }
 
 /*
  * do_query_number - Use this to do reverse IP# lookups.
  */
 static void do_query_number(const struct DNSQuery* query, 
-                            const struct in_addr* addr,
+                            const struct IN_ADDR* addr,
                             ResRQ* request)
 {
-  char  ipbuf[32];
+  char  ipbuf[128];
   const unsigned char* cp;
 
-  assert(0 != addr);
-  cp = (const unsigned char*) &addr->s_addr;
-  ircsnprintf(ipbuf, 32, "%u.%u.%u.%u.in-addr.arpa.",
-	      (unsigned int)(cp[3]), (unsigned int)(cp[2]),
-	      (unsigned int)(cp[1]), (unsigned int)(cp[0]));
+#ifdef IPV6
+    cp = (const u_char *)addr->s6_addr;
+    if (cp[0]==0 && cp[1]==0 && cp[2]==0 && cp[3]==0 && cp[4]==0 &&
+        cp[5]==0 && cp[6]==0 && cp[7]==0 && cp[8]==0 && cp[9]==0 &&
+        ((cp[10]==0 && cp[11]==0) || (cp[10]==0xff && cp[11]==0xff)))
+        {
+        (void)sprintf(ipbuf, "%u.%u.%u.%u.in-addr.arpa.",
+                  (u_int)(cp[15]), (u_int)(cp[14]),
+                  (u_int)(cp[13]), (u_int)(cp[12]));
+        }
+    else
+        {
+        (void)sprintf(ipbuf, 
+"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.int.",
+        (u_int)(cp[15]&0xf), (u_int)(cp[15]>>4),
+        (u_int)(cp[14]&0xf), (u_int)(cp[14]>>4),
+        (u_int)(cp[13]&0xf), (u_int)(cp[13]>>4),
+        (u_int)(cp[12]&0xf), (u_int)(cp[12]>>4),
+        (u_int)(cp[11]&0xf), (u_int)(cp[11]>>4),
+        (u_int)(cp[10]&0xf), (u_int)(cp[10]>>4),
+        (u_int)(cp[9]&0xf), (u_int)(cp[9]>>4),
+        (u_int)(cp[8]&0xf), (u_int)(cp[8]>>4),
+        (u_int)(cp[7]&0xf), (u_int)(cp[7]>>4),
+        (u_int)(cp[6]&0xf), (u_int)(cp[6]>>4),
+        (u_int)(cp[5]&0xf), (u_int)(cp[5]>>4),
+        (u_int)(cp[4]&0xf), (u_int)(cp[4]>>4),
+        (u_int)(cp[3]&0xf), (u_int)(cp[3]>>4),
+        (u_int)(cp[2]&0xf), (u_int)(cp[2]>>4),
+        (u_int)(cp[1]&0xf), (u_int)(cp[1]>>4),
+        (u_int)(cp[0]&0xf), (u_int)(cp[0]>>4));
+        }
+#else
+    cp = (const u_char *)&addr->s_addr;
+    (void)sprintf(ipbuf, "%u.%u.%u.%u.in-addr.arpa.",
+              (u_int)(cp[3]), (u_int)(cp[2]),
+              (u_int)(cp[1]), (u_int)(cp[0]));
+#endif
 
+  assert(0 != addr);
   if (!request) {
     request              = make_request(query);
     request->type        = T_PTR;
-    request->addr.s_addr = addr->s_addr;
+#ifdef IPV6
+        bcopy((const char *)addr->s6_addr,
+            (char *)&request->addr.s6_addr, sizeof(struct in6_addr));
+#else
+        bcopy((const char *)&addr->s_addr,
+            (char *)&request->addr.s_addr, sizeof(struct in_addr));
+#endif
+
   }
   query_name(ipbuf, C_IN, T_PTR, request);
 }
@@ -760,8 +817,11 @@
   case T_PTR:
     do_query_number(NULL, &request->addr, request);
     break;
+#ifdef IPV6
+  case T_AAAA:
+#endif
   case T_A:
-    do_query_name(NULL, request->name, request);
+    do_query_name(NULL, request->name, request, request->type);
     break;
   default:
     break;
@@ -775,7 +835,7 @@
 static int proc_answer(ResRQ* request, HEADER* header,
                        char* buf, char* eob)
 {
-  char   hostbuf[HOSTLEN + 1]; /* working buffer */
+  char   hostbuf[HOSTLEN+1+100]; /* working buffer */
   unsigned char*  current;              /* current position in buf */
   char** alias;                /* alias list */
   char** addr;                 /* address list */
@@ -784,7 +844,7 @@
   char*  endp;                 /* end of our buffer */
   int    query_class;          /* answer class */
   int    type;                 /* answer type */
-  int    rd_length;            /* record data length */
+  unsigned int    rd_length;            /* record data length */
   int    answer_count = 0;     /* answer counter */
   int    n;                    /* temp count */
   int    addr_count  = 0;      /* number of addresses in hostent */
@@ -832,8 +892,9 @@
   /*
    * make address point to first available address slot
    */
-  address = request->he.buf + ADDRS_OFFSET +
-                    (sizeof(struct in_addr) * addr_count);
+      address = request->he.buf + ADDRS_OFFSET +
+                     (sizeof(struct IN_ADDR) * addr_count);
+
   /*
    * find the end of the alias list
    */
@@ -908,21 +969,43 @@
     /* add_local_domain(hostbuf, HOSTLEN); */
 
     switch(type) {
-    case T_A:
+#ifdef IPV6
+      case T_AAAA:
+#endif
+      case T_A:
       /*
        * check for invalid rd_length or too many addresses
        */
-      if (rd_length != sizeof(struct in_addr))
+      if (rd_length != ((type==T_AAAA) ? sizeof(struct in6_addr) :
+          sizeof(struct in_addr)))
         return answer_count;
       if (++addr_count < RES_MAXADDRS) {
         if (answer_count == 1)
           hp->h_addrtype = (query_class == C_IN) ?  AF_INET : AF_UNSPEC;
 
-        memcpy(address, current, sizeof(struct in_addr));
+
+#ifdef IPV6
+        if (type == T_AAAA)
+          bcopy((const char*)current, address, rd_length);
+        else {
+          struct in6_addr tmp;
+          char nam[HOSTLEN];
+          bcopy(address, (char*)tmp.s6_addr, sizeof(struct in6_addr));
+          inetntop(AFINET, &tmp, nam, HOSTLEN);
+          
+          /* ugly hack */
+          memset(tmp.s6_addr, 0, 10);
+          tmp.s6_addr[10] = tmp.s6_addr[11] = 0xff;
+          memcpy(tmp.s6_addr+12, current, 4);
+          bcopy((const char*)tmp.s6_addr, address, sizeof(struct in6_addr));
+        }
+#else
+        bcopy(current, address, rd_length);
+#endif
+
         *addr++ = address;
         *addr = 0;
-        address += sizeof(struct in_addr);
-
+        address += sizeof(struct IN_ADDR);
         if (!hp->h_name) {
           strcpy(name, hostbuf);
           hp->h_name = name;
@@ -1004,8 +1087,10 @@
   aCache*            cp = NULL;
   size_t             rc;
   int                answer_count;
+  int                type;
   socklen_t          len = sizeof(struct sockaddr_in);
   struct sockaddr_in res_sin;
+  struct IN_ADDR     mapped; /* Temp struct to test for a v4 mapped address */
 
   rc = recvfrom(ResolverFileDescriptor, buf, sizeof(buf), 0, 
                 (struct sockaddr*) &res_sin, &len);
@@ -1043,6 +1128,11 @@
     ++reinfo.re_errors;
     if (SERVFAIL == header->rcode)
       resend_query(request);
+	else if(request->type == T_AAAA)
+	{
+      request->type = T_A;
+      resend_query(request);
+	}
     else {
       /*
        * If a bad error was returned, we stop here and dont send
@@ -1083,7 +1173,21 @@
        * type we automatically gain the use of the cache with no
        * extra kludges.
        */
-      reply = gethost_byname(request->he.h.h_name, &request->query);
+#ifdef  IPV6
+      bcopy((const char*)request->addr.S_ADDR, (char*)&mapped.S_ADDR, sizeof(struct IN_ADDR));
+      if (IN6_IS_ADDR_V4MAPPED(&mapped))
+      {
+        type = T_A;
+      }
+      else
+      {
+        type = T_AAAA;
+      }
+#else
+      type = T_A;
+#endif
+
+      reply = gethost_byname_type(request->he.h.h_name, &request->query, type);
       if (0 == reply) {
         /*
          * If name wasn't found, a request has been queued and it will
@@ -1443,7 +1547,7 @@
   ap = addrs;
   for (i = 0; (s = request->he.h.h_addr_list[i]); i++) {
     for (j = 0; (t = cp->he.h.h_addr_list[j]); j++) {
-      if (!memcmp(t, s, sizeof(struct in_addr)))
+      if (!memcmp(t, s, sizeof(struct IN_ADDR)))
         break;
     }
     if (!t) {
@@ -1514,7 +1618,7 @@
   int     hashv;
   int     i;
 #ifdef  DEBUG
-  struct in_addr* ip = (struct in_addr*) addr;
+  struct IN_ADDR* ip = (struct IN_ADDR*) addr;
 #endif
 
   assert(0 != addr);
@@ -1527,7 +1631,7 @@
 
   for (; cp; cp = cp->hnum_next) {
     for (i = 0; cp->he.h.h_addr_list[i]; i++) {
-      if (!memcmp(cp->he.h.h_addr_list[i], addr, sizeof(struct in_addr))) {
+      if (!memcmp(cp->he.h.h_addr_list[i], addr, sizeof(struct IN_ADDR))) {
         cainfo.ca_nu_hits++;
         update_list(NULL, cp);
         return cp;
@@ -1548,7 +1652,7 @@
     if (hashv == hash_number((unsigned char*)cp->he.h.h_addr_list[0]))
       continue;
     for (i = 1; cp->he.h.h_addr_list[i]; i++) {
-      if (!memcmp(cp->he.h.h_addr_list[i], addr, sizeof(struct in_addr))) {
+      if (!memcmp(cp->he.h.h_addr_list[i], addr, sizeof(struct IN_ADDR))) {
         cainfo.ca_nu_hits++;
         update_list(NULL, cp);
         return cp;
@@ -1747,7 +1851,7 @@
     h = &c->he.h;
     for (i = 0; h->h_addr_list[i]; i++) {
       im += sizeof(char *);
-      im += sizeof(struct in_addr);
+      im += sizeof(struct IN_ADDR);
     }
     im += sizeof(char *);
     for (i = 0; h->h_aliases[i]; i++) {
@@ -1766,3 +1870,4 @@
              me.name, RPL_STATSDEBUG, sptr->name, sm, im, nm);
   return ts + sm + im + nm;
 }
+
diff -ur dancer-ircd-1.0.31+maint5/src/s_auth.c dancer-ircd-1.0.31+maint5+IPv6/src/s_auth.c
--- dancer-ircd-1.0.31+maint5/src/s_auth.c	Sat Dec 15 15:11:43 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/s_auth.c	Mon Apr  1 01:20:10 2002
@@ -53,6 +53,10 @@
 #include <sys/socket.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 /*
  * a bit different approach
@@ -179,30 +183,59 @@
   if (reply)
     {
       struct hostent* hp = reply->hp;
+#ifdef IPV6
+      struct in6_addr temp;
+      char name[HOSTLEN]; 
+#endif
       int i;
       /*
        * Verify that the host to ip mapping is correct both ways and that
        * the ip#(s) for the socket is listed for the host.
        */
       for (i = 0; hp->h_addr_list[i]; ++i)
-	{
-	  if (memcmp(hp->h_addr_list[i], (char*) &auth->client->ip,
-		     sizeof(struct in_addr)) == 0)
-	    break;
-	}
+      {
+#ifdef IPV6
+        inetntop(AFINET, hp->h_addr_list[i], name, HOSTLEN);
+        inetpton(AFINET, name, &temp);
+        if (!bcmp((char*)&temp, (char*)&auth->client->ip, sizeof(struct IN_ADDR)))
+            break;
+#else
+        if (!bcmp(hp->h_addr_list[i], (char *)&auth->client->ip,
+            sizeof(struct IN_ADDR)))
+#endif
+              break;
+      }
+/*#ifdef IPV6
+      {
+		char lookupname[HOSTLEN];
+		char name[HOSTLEN];
+
+		inet_ntop(AF_INET, &auth->client->ip, name, HOSTLEN);
+		inet_ntop(AF_INET, hp->h_addr_list[i], lookupname, HOSTLEN);
+	    if (strcmp(lookupname, name) == 0)
+	      break;
+  	  }
+#else
+      {
+        if (memcmp(hp->h_addr_list[i], (char*) &auth->client->ip,
+        sizeof(struct in_addr)) == 0)
+        break;
+      }
+#endif
+*/
       if (!hp->h_addr_list[i])
-	{
-	  sendheader(auth->client, REPORT_IP_MISMATCH);
-	}
+  	  {
+	    sendheader(auth->client, REPORT_IP_MISMATCH);
+	  }
       else
-	{
-	  ++reply->ref_count;
-	  auth->client->dns_reply = reply;
-	  strncpy_irc(auth->client->host, hp->h_name, HOSTLEN);
-	  strip_colour(auth->client->host);
-	  strncpy_irc(auth->client->dnshost, auth->client->host, HOSTLEN);
-	  sendheader(auth->client, REPORT_FIN_DNS);
-	}
+	  {
+	    ++reply->ref_count;
+	    auth->client->dns_reply = reply;
+	    strncpy_irc(auth->client->host, hp->h_name, HOSTLEN);
+	    strip_colour(auth->client->host);
+	    strncpy_irc(auth->client->dnshost, auth->client->host, HOSTLEN);
+	    sendheader(auth->client, REPORT_FIN_DNS);
+	  }
     }
   else
     {
@@ -256,9 +289,9 @@
  */
 static int start_auth_query(struct AuthRequest* auth)
 {
-  struct sockaddr_in sock;
-  struct sockaddr_in localaddr;
-  socklen_t          locallen = sizeof(struct sockaddr_in);
+  struct SOCKADDR_IN sock;
+  struct SOCKADDR_IN localaddr;
+  socklen_t          locallen = sizeof(struct SOCKADDR_IN);
   int                fd;
 
   /* Hack. But it should work. */
@@ -266,7 +299,7 @@
   return 0;
 #endif
 
-  if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+  if ((fd = socket(AFINET, SOCK_STREAM, 0)) == -1)
     {
       /* er .. on the off chance we're having ident errors, we may leak a
        * server ip to a +d user. on the other hand, we should be spilling
@@ -307,7 +340,7 @@
    */
   memset(&localaddr, 0, locallen);
   getsockname(auth->client->fd, (struct sockaddr*) &localaddr, &locallen);
-  localaddr.sin_port = htons(0);
+  localaddr.SIN_PORT = htons(0);
 
   if (bind(fd, (struct sockaddr*) &localaddr, sizeof(localaddr))) 
     {
@@ -316,11 +349,15 @@
       close(fd);
       return 0;
     }
-
-  memcpy(&sock.sin_addr, &auth->client->ip, sizeof(struct in_addr));
   
-  sock.sin_port = htons(113);
-  sock.sin_family = AF_INET;
+#ifdef IPV6
+  bcopy((const char*)auth->client->ip.S_ADDR, (char*)sock.SIN_ADDR.S_ADDR, sizeof(struct IN_ADDR));
+#else
+  sock.sin_addr.s_addr = auth->client->ip.s_addr;
+#endif
+  
+  sock.SIN_PORT = htons(113);
+  sock.SIN_FAMILY = AFINET;
 
   if (connect(fd, (struct sockaddr*) &sock, sizeof(sock)) == -1) 
     {
@@ -419,6 +456,13 @@
 
   sendheader(client, REPORT_DO_DNS);
 
+/*#ifdef IPV6
+  inet_ntop(AF_INET, &client->ip, encoded, HOSTLEN);
+  client->dns_reply = gethost_byaddr((const char*) , &query);
+#else
+  client->dns_reply = gethost_byaddr((const char*) &client->ip, &query);
+#endif
+*/
   client->dns_reply = gethost_byaddr((const char*) &client->ip, &query);
   if (client->dns_reply)
     {
@@ -493,11 +537,11 @@
  */
 void send_auth_query(struct AuthRequest* auth)
 {
-  struct sockaddr_in us;
-  struct sockaddr_in them;
+  struct SOCKADDR_IN us;
+  struct SOCKADDR_IN them;
   char            authbuf[32];
-  socklen_t       ulen = sizeof(struct sockaddr_in);
-  socklen_t       tlen = sizeof(struct sockaddr_in);
+  socklen_t       ulen = sizeof(struct sockaddr);
+  socklen_t       tlen = sizeof(struct sockaddr);
 
   if (getsockname(auth->client->fd, (struct sockaddr *)&us,   &ulen) ||
       getpeername(auth->client->fd, (struct sockaddr *)&them, &tlen)) {
@@ -508,8 +552,8 @@
     return;
   }
   ircsnprintf(authbuf, 32, "%u , %u\r\n",
-	      (unsigned int) ntohs(them.sin_port),
-	      (unsigned int) ntohs(us.sin_port));
+	      (unsigned int) ntohs(them.SIN_PORT),
+	      (unsigned int) ntohs(us.SIN_PORT));
 
   if (send(auth->fd, authbuf, strlen(authbuf), 0) == -1) {
     if (EAGAIN == errno)
diff -ur dancer-ircd-1.0.31+maint5/src/s_bsd.c dancer-ircd-1.0.31+maint5+IPv6/src/s_bsd.c
--- dancer-ircd-1.0.31+maint5/src/s_bsd.c	Sat Dec 15 15:11:43 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/s_bsd.c	Mon Apr  1 01:20:10 2002
@@ -82,7 +82,7 @@
 #define INADDR_NONE ((unsigned int) 0xffffffff)
 #endif
 
-extern struct sockaddr_in vserv;               /* defined in s_conf.c */
+extern struct SOCKADDR_IN vserv;               /* defined in s_conf.c */
 
 const char* const NONB_ERROR_MSG   = "set_non_blocking failed for %s:%s"; 
 const char* const OPT_ERROR_MSG    = "disable_sock_options failed for %s:%s";
@@ -92,7 +92,7 @@
 
 int            highest_fd = 0;
 
-static struct sockaddr_in mysk;
+static struct SOCKADDR_IN mysk;
 static char readBuf[READBUF_SIZE];
 #ifndef USE_POLL
 /*
@@ -187,7 +187,13 @@
   struct ConfItem* aconf = (struct ConfItem*) vptr;
   aconf->dns_pending = 0;
   if (reply) {
+#ifdef IPV6
+    char name[HOSTLEN];
+    inet_ntop(AF_INET, reply->hp->h_addr, name, HOSTLEN);
+	inetpton(AFINET, name, &aconf->ipnum);
+#else
     memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+#endif
     connect_server(aconf, 0, reply);
   }
   else
@@ -213,8 +219,11 @@
 static int disable_sock_options(int fd)
 {
 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
-  if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, NULL, 0))
-    return 0;
+/* Broken on ipv6 - stu */
+#ifndef IPV6
+    if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, NULL, 0))
+      return 0;
+#endif /* IPv6 */ 
 #endif
   return 1;
 }
@@ -396,14 +405,14 @@
  */
 static int connect_inet(struct ConfItem *aconf, struct Client *cptr)
 {
-  static struct sockaddr_in con_sin;
+  static struct SOCKADDR_IN con_sin;
   assert(0 != aconf);
   assert(0 != cptr);
   /*
    * Might as well get sockhost from here, the connection is attempted
    * with it so if it fails its useless.
    */
-  cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
+  cptr->fd = socket(AFINET, SOCK_STREAM, 0);
 
   if (cptr->fd == -1)
     {
@@ -417,11 +426,11 @@
       return 0;
     }
 
-  mysk.sin_port   = 0;
-  mysk.sin_family = AF_INET;
+  mysk.SIN_PORT   = 0;
+  mysk.SIN_FAMILY = AFINET;
 
   memset(&con_sin, 0, sizeof(con_sin));
-  con_sin.sin_family  = AF_INET;
+  con_sin.SIN_FAMILY  = AFINET;
 
   /*
    * Bind to a local IP# (with unknown port - let unix decide) so
@@ -434,30 +443,40 @@
    */
   if (specific_virtual_host)
     {
-      mysk.sin_addr = vserv.sin_addr;
+#ifdef IPV6
+      bcopy((char*)&vserv.SIN_ADDR, (char*)&mysk.SIN_ADDR, sizeof(struct IN_ADDR)); 
+#else
+       mysk.SIN_ADDR = vserv.SIN_ADDR;
+#endif
 
       /*
        * No, we do bind it if we have virtual host support. If we don't
        * explicitly bind it, it will default to IN_ADDR_ANY and we lose
        * due to the other server not allowing our base IP --smg
        */        
-      if (bind(cptr->fd, (struct sockaddr*) &mysk, sizeof(mysk)))
+      if (bind(cptr->fd, (struct sockaddr*) &mysk, sizeof(mysk))) 
         {
           report_error("error binding to local port for %s:%s", 
                        cptr->name, errno);
           return 0;
         }
     }
+#ifdef IPV6
+  bcopy((char*)&aconf->ipnum, (char*)&con_sin.SIN_ADDR, sizeof(struct IN_ADDR));
+#else
   con_sin.sin_addr.s_addr = aconf->ipnum.s_addr;
-  con_sin.sin_port        = htons(aconf->port);
+#endif
+  con_sin.SIN_PORT        = htons(aconf->port);
   /*
    * save connect info in client
    */
-  cptr->ip.s_addr     = aconf->ipnum.s_addr;
+  bcopy((char*)&aconf->ipnum, (char*)&cptr->ip, sizeof(struct IN_ADDR));
   cptr->port          = aconf->port;
-  strncpy_irc(cptr->sockhost, inetntoa((const char*) &cptr->ip.s_addr), 
-              HOSTIPLEN);
-
+#ifdef IPV6
+  inetntop(AFINET, &cptr->ip, cptr->sockhost, sizeof(struct IN_ADDR)); 
+#else
+  inet_ntop(AF_INET, &cptr->ip, cptr->sockhost, sizeof(struct in_addr));
+#endif
   if (!set_non_blocking(cptr->fd))
     report_error(NONB_ERROR_MSG, get_client_name(cptr, MASK_IP), errno);
 
@@ -488,6 +507,7 @@
  * XXX - if this comes from an m_connect message and a dns query needs to
  * be done, we loose the information about who started the connection and
  * it's considered an auto connect.
+ *
  */
 int connect_server(struct ConfItem* aconf, 
                    struct Client* by, struct DNSReply* reply)
@@ -501,7 +521,6 @@
   log(L_NOTICE, "Connect to %s %s[%s] @%s:%d",
       aconf->name, aconf->user, 
       aconf->host, inetntoa((char*)&aconf->ipnum), aconf->port);
-
   /*
    * if this is coming from m_connect, we have just checked this
    * NOTE: aconf should ALWAYS be a valid C:line
@@ -531,9 +550,16 @@
    * address will have been set so we don't need to worry about 
    * looping dns queries.
    */
+#ifdef IPV6
+  if (INADDR_NONE == aconf->ipnum.S_ADDR[0]) {
+    assert(0 == reply);
+	inetpton(AFINET, aconf->host, &aconf->ipnum);
+    if (aconf->ipnum.S_ADDR[0] == INADDR_NONE) {
+#else
   if (INADDR_NONE == aconf->ipnum.s_addr) {
     assert(0 == reply);
     if ((aconf->ipnum.s_addr = inet_addr(aconf->host)) == INADDR_NONE) {
+#endif
       struct DNSQuery  query;
       
       query.vptr     = aconf;
@@ -544,7 +570,7 @@
         aconf->dns_pending = 1;
         return 0;
       }
-      memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+      bcopy(reply->hp->h_addr, (char*)aconf->ipnum.S_ADDR, sizeof(struct IN_ADDR));
     }
   }
   cptr = make_client(NULL);
@@ -745,8 +771,9 @@
 void add_connection(struct Listener* listener, int fd)
 {
   struct Client*           new_client;
-  struct sockaddr_in addr;
-  socklen_t          len = sizeof(struct sockaddr_in);
+  struct SOCKADDR_IN addr;
+  struct IN_ADDR temp;
+  socklen_t          len = sizeof(struct SOCKADDR_IN);
 
   assert(0 != listener);
 
@@ -754,7 +781,7 @@
    * get the client socket name from the socket
    * the client has already been checked out in accept_connection
    */
-  if (getpeername(fd, (struct sockaddr*) &addr, &len)) {
+  if (getpeername(fd, (struct sockaddr*)&addr, &len)) {
     report_error("Failed in adding new connection %s :%s", 
                  get_listener_name(listener), errno);
     ServerStats->is_ref++;
@@ -768,15 +795,19 @@
    * copy address to 'sockhost' as a string, copy it to host too
    * so we have something valid to put into error messages...
    */
-  strncpy_irc(new_client->sockhost, 
-              inetntoa((char*) &addr.sin_addr), HOSTIPLEN);
+#ifdef IPV6
+  inetntop(AFINET, (char*)&addr.SIN_ADDR, new_client->sockhost, HOSTLEN);
+#else
+  inet_ntop(AF_INET, (char*)&addr.SIN_ADDR, new_client->sockhost, HOSTLEN);
+#endif
+  bcopy((char*)&addr.SIN_ADDR.S_ADDR, (char*)&new_client->ip.S_ADDR, sizeof(struct IN_ADDR));
   strncpy_irc(new_client->host, new_client->sockhost, HOSTLEN);
   /* Also record sockhost as dnshost for now */
   strncpy_irc(new_client->dnshost, new_client->sockhost, HOSTLEN);
   /* And fill in the default spoof host, if nothing else is set later */
   strncpy_irc(new_client->spoofhost, SPOOF_LIMIT_HOST, HOSTLEN);
-  new_client->ip.s_addr = addr.sin_addr.s_addr;
-  new_client->port      = ntohs(addr.sin_port);
+
+  new_client->port      = ntohs(addr.SIN_PORT);
   new_client->fd        = fd;
 
   new_client->listener  = listener;
@@ -1418,4 +1449,110 @@
 }
 
 #endif /* USE_POLL */
+
+/* This is unshamedly "borrowed" from ircnet's ircd.  They seem to know what 
+ * they're doing - stu 08/02/02
+ */
+
+#ifdef IPV6
+/* Broken old kame defines :( - Stu */
+#undef IN6_IS_ADDR_V4MAPPED
+#define IN6_IS_ADDR_V4MAPPED(a)           \
+    ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
+     (*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
+     (*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
+
+/*
+ * inetntop: return the : notation of a given IPv6 internet number.
+ *           or the dotted-decimal notation for IPv4
+ *           make sure the compressed representation (rfc 1884) isn't used.
+ */
+char *inetntop(int af, const void *in, char *out, size_t the_size)
+{
+  static char local_dummy[128]; 
+
+  if (!inet_ntop(af, in, local_dummy, the_size))
+  {
+    /* good that every function calling this one
+    * checks the return value ... NOT */
+    return NULL;
+  }
+  /* quick and dirty hack to give ipv4 just ipv4 instead of
+  * ::ffff:ipv4 - Q */
+  if (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)in))
+  {
+    char    *p;
+                
+    if (!(p = strstr(local_dummy, ":ffff:")) &&
+        !(p = strstr(local_dummy, ":FFFF:")))
+    {
+      return NULL;    /* crash and burn */
+    }
+    strcpy(out, p + 6);
+    return out;
+  }
+  if (strstr(local_dummy, "::"))
+  {
+    char cnt = 0, *cp = local_dummy, *op = out;
+    while (*cp)
+    {
+      if (*cp == ':')
+        cnt += 1;
+      if (*cp++ == '.')
+      {
+        cnt += 1;
+        break;
+      }
+    }
+    cp = local_dummy;
+    while (*cp)
+    {
+      *op++ = *cp++;
+      if (*(cp-1) == ':' && *cp == ':')
+      {
+        if ((cp-1) == local_dummy)
+        {
+          op--;
+          *op++ = '0';
+          *op++ = ':';
+        }
+
+        *op++ = '0';
+        while (cnt++ < 7)
+        {
+          *op++ = ':';
+          *op++ = '0';
+        }
+      }
+    }
+    if (*(op-1)==':') *op++ = '0';
+    *op = '\0';
+  }
+  else
+    bcopy(local_dummy, out, 64);
+  return out;
+}
+/* inetpton(af, src, dst)
+**
+** This is a wrapper for inet_pton(), so we can use ipv4 addresses with an
+** af of AF_INET6, and that it gets converted to ipv4 mapped ipv6.
+*/
+int     inetpton(int af, const char *src, void *dst)
+{
+  int     i;
+
+        /* an empty string should listen to all */
+  if (af == AF_INET6 && *src && !strchr(src, ':'))
+  {
+    i = inet_pton(AF_INET, src, dst);
+
+                /* ugly hack - made slighty better, but not much*/
+    memcpy((char*)dst + 12, dst, 4);
+    memset((char*)dst, 0, 10);
+    memset((char*)dst + 10, 0xff, 2);
+    return i;
+  }
+  return inet_pton(af, src, dst);
+}
+#endif
 
diff -ur dancer-ircd-1.0.31+maint5/src/s_conf.c dancer-ircd-1.0.31+maint5+IPv6/src/s_conf.c
--- dancer-ircd-1.0.31+maint5/src/s_conf.c	Sat Dec 15 20:01:42 2001
+++ dancer-ircd-1.0.31+maint5+IPv6/src/s_conf.c	Mon Apr  1 01:20:10 2002
@@ -53,12 +53,13 @@
 #include <fcntl.h>
 #include <assert.h>
 #include <sys/file.h>
+#include <ctype.h>
 
 #ifndef INADDR_NONE
 #define INADDR_NONE ((unsigned int) 0xffffffff)
 #endif
 
-struct sockaddr_in vserv;
+struct SOCKADDR_IN vserv;
 int                specific_virtual_host = 0;
 int kline_count = 0;
 
@@ -152,7 +153,13 @@
   struct ConfItem* aconf = (struct ConfItem*) vptr;
   aconf->dns_pending = 0;
   if (reply)
-    memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+  {
+#ifdef IPV6
+	bcopy(reply->hp->h_addr, (char*)aconf->ipnum.S_ADDR, sizeof(struct in6_addr));
+#else
+     memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+#endif
+  }
 }
 
 /*
@@ -183,7 +190,12 @@
   aconf = (struct ConfItem*) MyMalloc(sizeof(struct ConfItem));
   memset(aconf, 0, sizeof(struct ConfItem));
   aconf->status       = CONF_ILLEGAL;
+#ifdef IPV6
+  memcpy(aconf->ipnum.S_ADDR, &INADDRANY, sizeof(struct IN_ADDR));
+#else
   aconf->ipnum.s_addr = INADDR_NONE;
+#endif
+
 
 #if defined(NULL_POINTER_NOT_ZERO)
   aconf->next = NULL;
@@ -403,8 +415,9 @@
 
   if (IsGotId(cptr))
     {
-      aconf = find_matching_mtrie_conf(cptr->sockhost, cptr->username, nick,
-                                       ntohl(cptr->ip.s_addr));
+        aconf = find_matching_mtrie_conf(cptr->sockhost, cptr->username, nick,
+                                       ntohl((unsigned long)cptr->ip.S_ADDR));
+
       /* Keep the IP-based aconf if it is not an I:line match, but
        *  if there was either no match or an I:line match, look for
        *  a hostname-based aconf because it may override
@@ -412,15 +425,16 @@
       if (!aconf || (aconf->status & CONF_CLIENT))
 	{
 	  struct ConfItem *aconf2;
-	  aconf2 = find_matching_mtrie_conf(cptr->host, cptr->username, nick,
-					    ntohl(cptr->ip.s_addr));
+      aconf2 = find_matching_mtrie_conf(cptr->host, cptr->username, nick,
+              ntohl((unsigned long)cptr->ip.S_ADDR));
+              
 	  /* Keep the IP-based aconf iff nothing matches the host-based one */
 	  if (aconf2)
 	    aconf = aconf2;
 	}
       if(aconf && !IsConfElined(aconf))
         {
-          if((tkline_conf = find_tkline(cptr->host, cptr->username, ntohl(cptr->ip.s_addr))))
+          if((tkline_conf = find_tkline(cptr->host, cptr->username, ntohl((unsigned long)cptr->ip.S_ADDR))))
             aconf = tkline_conf;
         }
     }
@@ -430,7 +444,7 @@
       strncpy_irc(&non_ident[1],username, USERLEN - 1);
       non_ident[USERLEN] = '\0';
       aconf = find_matching_mtrie_conf(cptr->sockhost, non_ident, nick,
-                                       ntohl(cptr->ip.s_addr));
+                                       ntohl((unsigned long)cptr->ip.S_ADDR));
       /* Keep the IP-based aconf if it is not an I:line match, but
        *  if there was either no match or an I:line match, look for
        *  a hostname-based aconf because it may override
@@ -439,14 +453,14 @@
 	{
 	  struct ConfItem *aconf2;
 	  aconf2 = find_matching_mtrie_conf(cptr->host, non_ident, nick,
-					    ntohl(cptr->ip.s_addr));
+					    ntohl((unsigned long)cptr->ip.S_ADDR));
 	  /* Keep the IP-based aconf iff nothing matches the host-based one */
 	  if (aconf2)
 	    aconf = aconf2;
 	}
       if(aconf && !IsConfElined(aconf))
         {
-          if( (tkline_conf = find_tkline(cptr->host, non_ident, ntohl(cptr->ip.s_addr))) )
+          if( (tkline_conf = find_tkline(cptr->host, non_ident, ntohl((unsigned long)cptr->ip.S_ADDR))) )
             aconf = tkline_conf;
         }
     }
@@ -635,7 +649,7 @@
 find_or_add_ip(aClient *cptr)
 #endif
 {
-  unsigned long ip_in=cptr->ip.s_addr;        
+  unsigned long ip_in=(unsigned long)cptr->ip.S_ADDR;        
 #ifdef LIMIT_UH
   Link *new_link;
 #endif
@@ -1619,8 +1633,7 @@
       p++;
       DupString(comh,p);
     }
-                  
-  bconf = make_conf();
+  bconf = make_conf();                
   DupString(bconf->name, aconf->name);
   if(aconf->passwd)
     DupString(bconf->passwd,aconf->passwd);
@@ -2370,8 +2383,12 @@
             if ((aconf->passwd[0] != '\0') && (aconf->passwd[0] != '*'))
             {
                 memset(&vserv,0, sizeof(vserv));
-                vserv.sin_family = AF_INET;
-                vserv.sin_addr.s_addr = inet_addr(aconf->passwd);
+                vserv.SIN_FAMILY = AFINET;
+#ifdef IPV6
+                inetpton(AFINET, aconf->passwd, &vserv.SIN_ADDR);
+#else
+                inet_pton(AF_INET, aconf->passwd, &vserv.SIN_ADDR);
+#endif
                 specific_virtual_host = 1;
             }
           }
@@ -2756,35 +2773,40 @@
 static void lookup_confhost(struct ConfItem* aconf)
 {
   struct DNSReply* dns_reply;
-  unsigned long    ip;
-  unsigned long    mask;
 
   if (BadPtr(aconf->host) || BadPtr(aconf->name))
-    {
-      log(L_ERROR, "Host/server name error: (%s) (%s)",
-          aconf->host, aconf->name);
-      return;
-    }
+  {
+    log(L_ERROR, "Host/server name error: (%s) (%s)",
+        aconf->host, aconf->name);
+    return;
+  }
 
   /*
   ** Do name lookup now on hostnames given and store the
   ** ip numbers in conf structure.
   */
+  /* Why, why why? - Stu 
   if (is_address(aconf->host, &ip, &mask))
-    {
-      aconf->ipnum.s_addr = htonl(ip);
-    }
-  else if (0 != (dns_reply = conf_dns_lookup(aconf)))
-    memcpy(&aconf->ipnum, dns_reply->hp->h_addr, sizeof(struct in_addr));
+  {
+  */
+#ifdef IPV6
+  if(inetpton(AFINET, aconf->host, &aconf->ipnum))
+      ;
+#else
+  if (isdigit(*aconf->host))
+      aconf->ipnum.s_addr = inet_addr(aconf->host);
+#endif
+  else if (0 != (dns_reply = conf_dns_lookup(aconf))) 
+      memcpy(&aconf->ipnum, dns_reply->hp->h_addr, sizeof(struct IN_ADDR));
   
 }
 
 /*
  * conf_connect_allowed (untested)
  */
-int conf_connect_allowed(struct in_addr addr)
+int conf_connect_allowed(struct IN_ADDR addr)
 {
-  struct ConfItem *aconf = match_Dline(ntohl((unsigned long)addr.s_addr));
+  struct ConfItem *aconf = match_Dline(ntohl((unsigned long)addr.S_ADDR));
 
   if (aconf && !IsConfElined(aconf))
     return 0;
@@ -2804,14 +2826,14 @@
   struct ConfItem *aconf;
   assert(0 != cptr);
   aconf = find_is_klined(cptr->sockhost, cptr->username, cptr->name,
-			 cptr->ip.s_addr);
+			 (unsigned long)cptr->ip.S_ADDR);
   /* Keep the IP-based aconf if it is not an I:line match, but
    *  if there was either no match or an I:line match, look for
    *  a hostname-based aconf because it may override
    */
   if (!aconf)
     aconf = find_is_klined(cptr->host, cptr->username,
-			   cptr->name, cptr->ip.s_addr);
+			   cptr->name, (unsigned long)cptr->ip.S_ADDR);
   /* If client is e-lined, then its not k-linable */
   return (IsElined(cptr)) ? 0 : aconf;
 }
@@ -3845,12 +3867,30 @@
     return((char *)NULL);
 
   field = line;
-  if ((end = strchr(line,':')) == NULL)
+  /* Have we got a v6 æddress encoded in a field? */
+#ifdef IPV6
+  if(line[0] == '[')
+  {
+    line++;
+	field++;
+    if((end = strchr(line, ']')) == (char *)NULL)
     {
       line = (char *)NULL;
       if ((end = strchr(field,'\n')) == (char *)NULL)
-        end = field + strlen(field);
-    }
+      end = field + strlen(field);
+    } 
+    else
+      line = end + 2;
+  }
+  else if ((end = strchr(line,':')) == NULL)
+#else
+  if ((end = strchr(line,':')) == NULL)
+#endif
+  {
+    line = (char *)NULL;
+    if ((end = strchr(field,'\n')) == (char *)NULL)
+      end = field + strlen(field);
+  }
   else
     line = end + 1;
   *end = '\0';
diff -ur dancer-ircd-1.0.31+maint5/src/s_serv.c dancer-ircd-1.0.31+maint5+IPv6/src/s_serv.c
--- dancer-ircd-1.0.31+maint5/src/s_serv.c	Wed Mar 27 23:39:55 2002
+++ dancer-ircd-1.0.31+maint5+IPv6/src/s_serv.c	Mon Apr  1 01:24:19 2002
@@ -440,9 +440,13 @@
    * if the C:line doesn't have an IP address assigned put the one from
    * the client socket there
    */ 
+#ifdef IPV6
+  if (0 == c_conf->ipnum.S_ADDR[0])
+    memcpy(c_conf->ipnum.S_ADDR, cptr->ip.S_ADDR, sizeof(struct in6_addr));
+#else
   if (INADDR_NONE == c_conf->ipnum.s_addr)
     c_conf->ipnum.s_addr = cptr->ip.s_addr;
-
+#endif
   Debug((DEBUG_DNS,"sv_cl: access ok: [%s]", cptr->host));
 
   return 1;
@@ -501,7 +505,7 @@
       sendto_one(cptr, "NICK %s %d %lu %s %s %s %s %lu :%s", acptr->name, 
                  acptr->hopcount + 1, acptr->tsinfo, ubuf /* current umodes */,
                  acptr->username, acptr->host,
-                 acptr->user->server, (long int)acptr->ip.s_addr, acptr->info);
+                 acptr->user->server, (long int)acptr->ip.S_ADDR, acptr->info);
       c = umode_difference(&user_umodes, &acptr->allowed_umodes);
       if (*c)
 	sendto_one(cptr, ":%s OPER %s %s", me.name, acptr->name, c);
Only in dancer-ircd-1.0.31+maint5+IPv6/src: s_serv.c.orig
Only in dancer-ircd-1.0.31+maint5+IPv6/src: s_serv.c.rej
diff -ur dancer-ircd-1.0.31+maint5/src/s_user.c dancer-ircd-1.0.31+maint5+IPv6/src/s_user.c
--- dancer-ircd-1.0.31+maint5/src/s_user.c	Wed Mar 27 23:44:53 2002
+++ dancer-ircd-1.0.31+maint5+IPv6/src/s_user.c	Mon Apr  1 01:20:42 2002
@@ -62,7 +62,10 @@
 #include <time.h>
 #include <sys/stat.h>
 #include <ctype.h>
-
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #ifdef PACE_WALLOPS
 time_t LastUsedWallops = 0;
 #endif
@@ -561,7 +564,6 @@
           release_client_dns_reply(cptr);
           break;
         }
-
       if(!valid_hostname(sptr->host))
         {
           sendto_one(sptr,":%s NOTICE %s :*** Notice -- hostname %s isn't valid, using default",
@@ -724,7 +726,7 @@
       if (acptr)
 	{
 	  /* OK, it's from a remote server. I'm going to check against *MY* K:lines. */
-	  aconf = find_matching_mtrie_conf(sptr->host, sptr->username, sptr->name, ntohl(sptr->ip.s_addr));
+	  aconf = find_matching_mtrie_conf(sptr->host, sptr->username, sptr->name, ntohl((unsigned int)sptr->ip.S_ADDR));
 	  
 	  if (aconf && (aconf->status & CONF_KILL))
 	    {
@@ -925,7 +927,7 @@
   sendto_serv_butone(cptr, "NICK %s %d %lu %s %s %s %s %lu :%s",
                      nick, sptr->hopcount+1, sptr->tsinfo, ubuf,
                      sptr->username, sptr->host, user->server,
-		     (long int)sptr->ip.s_addr,
+		     (long int)sptr->ip.S_ADDR,
                      sptr->info);
 
   /* Propagate spoofhost if necessary */
@@ -964,10 +966,16 @@
   while (*p) {
     if (!IsHostChar(*p))
       return NO;
-    if ('.' == *p++)
+    if ('.' == *p || ':' == *p)
+    {
+      ++p;
       ++dots;
+    }
     else
+    {
+      ++p;
       ++chars;
+    }
   }
   return (0 == dots || chars < dots) ? NO : YES;
 }
@@ -1981,56 +1989,61 @@
   oflags = sptr->flags;
 
   if (!MyConnect(sptr))
-    {
-      /*
-       * coming from another server, take the server's word for it
-       */
-      user->server = find_or_add(server);
-      strncpy_irc(sptr->host, host, HOSTLEN); 
-      strncpy_irc(sptr->dnshost, host, HOSTLEN); 
-      strncpy_irc(sptr->origname, sptr->name, HOSTLEN);
-      strncpy_irc(sptr->spoofhost, SPOOF_LIMIT_HOST, HOSTLEN);
-    }
+  {
+    /*
+    * coming from another server, take the server's word for it
+    */
+    user->server = find_or_add(server);
+    strncpy_irc(sptr->host, host, HOSTLEN); 
+    strncpy_irc(sptr->dnshost, host, HOSTLEN); 
+    strncpy_irc(sptr->origname, sptr->name, HOSTLEN);
+    strncpy_irc(sptr->spoofhost, SPOOF_LIMIT_HOST, HOSTLEN);
+  }
   else
+  {
+    if (!IsUnknown(sptr))
     {
-      if (!IsUnknown(sptr))
-        {
-          sendto_one(sptr, form_str(ERR_ALREADYREGISTRED), me.name, nick);
-          return 0;
-        }
+      sendto_one(sptr, form_str(ERR_ALREADYREGISTRED), me.name, nick);
+      return 0;
+    }
 #ifndef NO_DEFAULT_INVISIBLE
-      SetBit(sptr->umodes,UMODE_INVISIBLE);
+    SetBit(sptr->umodes,UMODE_INVISIBLE);
 #endif
 
-      if (IsInvisible(sptr))
-        Count.invisi++;
-      /*
-       * don't take the clients word for it, ever
-       *  strncpy_irc(user->host, host, HOSTLEN); 
-       */
-      user->server = me.name;
-    }
+    if (IsInvisible(sptr))
+      Count.invisi++;
+    /*
+     * don't take the clients word for it, ever
+     *  strncpy_irc(user->host, host, HOSTLEN); 
+     */
+    user->server = me.name;
+  }
   strncpy_irc(sptr->info, realname, REALLEN);
   strip_colour(sptr->info);
 
   if (ip)
-    {
-      sptr->ip.s_addr = strtoul(ip, NULL, 10);
-      strncpy_irc(sptr->sockhost, inetntoa((const char*) &sptr->ip.s_addr), HOSTIPLEN);
-    }
+  {
+#ifdef IPV6
+    inetpton(AFINET, ip, &sptr->ip);
+    inetntop(AFINET, &sptr->ip, sptr->sockhost, HOSTIPLEN);
+#else
+    sptr->ip.s_addr = strtoul(ip, NULL, 10);
+    strncpy_irc(sptr->sockhost, inetntoa((const char*) &sptr->ip.s_addr), HOSTIPLEN);
+#endif
+  }
 
   if (sptr->name[0]) /* NICK already received, now I have USER... */
     return register_user(cptr, sptr, sptr->name, username);
   else
+  {
+    if (!IsGotId(sptr)) 
     {
-      if (!IsGotId(sptr)) 
-        {
-          /*
-           * save the username in the client
-           */
-          strncpy_irc(sptr->username, username, USERLEN);
-        }
+      /*
+       * save the username in the client
+       */
+      strncpy_irc(sptr->username, username, USERLEN);
     }
+  }
   return 0;
 }
 
