IPv6 Phase 3: DNS resolver with AAAA and ip6.arpa support
authorRemco Rijnders <remmy@serenity-irc.net>
Sat, 7 Mar 2026 17:17:36 +0000 (12:17 -0500)
committerRemco Rijnders <remmy@serenity-irc.net>
Sat, 7 Mar 2026 17:17:36 +0000 (12:17 -0500)
Update the custom DNS resolver to handle IPv6 addresses:

- Change struct hent.h_addr_list from struct in_addr[] to struct irc_addr[]
- Change ResRQ.addr from struct in_addr to struct irc_addr
- Add T_AAAA record handling in proc_answer()
- Support ip6.arpa nibble-format reverse queries for IPv6 PTR lookups
- Update gethost_byaddr() to take struct irc_addr* instead of char*
- Update cache code (find_cache_number, make_cache, update_list) to use
  h_length for address size instead of hardcoded sizeof(struct in_addr)
- Add irc_addr_from_v6(), irc_addr_from_hostent(), irc_addr_raw() helpers
- Replace inetntoa_v4 bridge with cache_addr_str for cached hostent display
- Update all DNS callback sites to use irc_addr_from_hostent()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
include/h.h
include/irc_addr.h
include/res.h
src/res.c
src/s_bsd.c
src/s_conf.c
src/s_ping.c

index 10b5e2de321f2a833e1fae3270838ddefe593c44..607d0d7875769e8a5f2fe859ca3b48caf62b3cec 100644 (file)
@@ -253,7 +253,7 @@ extern      void    report_classes (aClient *);
 extern int     res_init();
 extern u_long  cres_mem(aClient *);
 extern struct  hostent *get_res (char *);
-extern struct  hostent *gethost_byaddr (char *, Link *);
+extern struct  hostent *gethost_byaddr (struct irc_addr *, Link *);
 extern struct  hostent *gethost_byname (char *, Link *);
 extern void    flush_cache ();
 extern int     init_resolver (int);
index 539d87810e8061f76d5c76a4749212a0ae99f884..680fa6d4a4e5fec92dd3d95c48f609a5a4b74e7d 100644 (file)
@@ -131,5 +131,34 @@ static inline struct irc_addr irc_addr_from_v4(const struct in_addr *v4)
     return a;
 }
 
+/* Create an irc_addr from a raw struct in6_addr */
+static inline struct irc_addr irc_addr_from_v6(const struct in6_addr *v6)
+{
+    struct irc_addr a;
+    IRC_ADDR_ZERO(&a);
+    a.family = AF_INET6;
+    memcpy(&a.addr.v6, v6, sizeof(struct in6_addr));
+    return a;
+}
+
+/* Create an irc_addr from a hostent result (checks h_addrtype) */
+static inline struct irc_addr irc_addr_from_hostent(const struct hostent *hp)
+{
+    if (hp->h_addrtype == AF_INET6)
+       return irc_addr_from_v6((struct in6_addr *) hp->h_addr);
+    return irc_addr_from_v4((struct in_addr *) hp->h_addr);
+}
+
+/* Extract raw address bytes and return the size (4 or 16) */
+static inline int irc_addr_raw(const struct irc_addr *a, const void **out)
+{
+    if (a->family == AF_INET6) {
+       *out = &a->addr.v6;
+       return 16;
+    }
+    *out = &a->addr.v4;
+    return 4;
+}
+
 #endif /* __irc_addr_include__ */
 
index 85a5aa08b2c9dfb707144bff02e784db856a0e51..b70b26617763c338ee7dea960d861a4a9f5c99f4 100644 (file)
 struct hent {
        char    *h_name;        /* official name of host */
        char    *h_aliases[MAXALIASES]; /* alias list */
-       int     h_addrtype;     /* host address type */
-       int     h_length;       /* length of address */
+       int     h_addrtype;     /* host address type (AF_INET or AF_INET6) */
+       int     h_length;       /* length of address (4 or 16) */
        /* list of addresses from name server */
-       struct  in_addr h_addr_list[MAXADDRS];
+       struct  irc_addr h_addr_list[MAXADDRS];
 #define        h_addr  h_addr_list[0]  /* address, for backward compatiblity */
 };
 
@@ -37,7 +37,7 @@ typedef       struct  reslist {
        char    resend; /* send flag. 0 == dont resend */
        time_t  sentat;
        time_t  timeout;
-       struct  in_addr addr;
+       struct  irc_addr addr;
        char    *name;
        struct  reslist *next;
        Link    cinfo;
index e79c2389a086df1d7f0bed97a4af97bc99a525a1..9ec50dba133f45452335fd719dbeecf7a87ed5c3 100644 (file)
--- a/src/res.c
+++ b/src/res.c
 extern int highest_fd;
 extern aClient *local[];
 
-/* Helper: format a raw in_addr for debug/log output (resolver is still IPv4-only) */
-static char *inetntoa_v4(const struct in_addr *in)
+/* Helper: format a cached hostent address for display */
+static const char *cache_addr_str(const struct hostent *hp, const char *addr)
 {
-    struct irc_addr a = irc_addr_from_v4 (in);
-    return inetntoa (&a);
+    struct irc_addr a;
+    if (hp->h_addrtype == AF_INET6)
+       a = irc_addr_from_v6 ((struct in6_addr *) addr);
+    else
+       a = irc_addr_from_v4 ((struct in_addr *) addr);
+    return irc_addr_str (&a);
 }
 
 static char hostbuf[HOSTLEN + 1];
@@ -42,13 +46,13 @@ static ResRQ *last, *first;
 
 static void rem_cache (aCache *);
 static int do_query_name (Link *, char *, ResRQ *);
-static int do_query_number (Link *, struct in_addr *, ResRQ *);
+static int do_query_number (Link *, struct irc_addr *, ResRQ *);
 static void resend_query (ResRQ *);
 static int proc_answer (ResRQ *, HEADER *, char *, char *);
 static int query_name (char *, int, int, ResRQ *);
 static aCache *make_cache (ResRQ *);
 static aCache *find_cache_name (char *);
-static aCache *find_cache_number (ResRQ *, char *);
+static aCache *find_cache_number (ResRQ *, char *, int);
 static int send_res_msg (char *, int, int);
 static ResRQ *find_id (int);
 static int hash_number (unsigned char *);
@@ -332,16 +336,19 @@ struct hostent *gethost_byname (char *name, Link *lp)
     return NULL;
 }
 
-struct hostent *gethost_byaddr (char *addr, Link *lp)
+struct hostent *gethost_byaddr (struct irc_addr *addr, Link *lp)
 {
     aCache *cp;
+    const void *raw;
+    int alen;
 
     reinfo.re_nu_look++;
-    if ((cp = find_cache_number (NULL, addr)))
+    alen = irc_addr_raw (addr, &raw);
+    if ((cp = find_cache_number (NULL, (char *) raw, alen)))
        return (struct hostent *) &(cp->he);
     if (!lp)
        return NULL;
-    (void) do_query_number (lp, (struct in_addr *) addr, NULL);
+    (void) do_query_number (lp, addr, NULL);
     return NULL;
 }
 
@@ -374,21 +381,36 @@ static int do_query_name (Link *lp, char *name, ResRQ *rptr)
 /*
  * Use this to do reverse IP# lookups.
  */
-static int do_query_number (Link *lp, struct in_addr *numb, ResRQ *rptr)
+static int do_query_number (Link *lp, struct irc_addr *numb, ResRQ *rptr)
 {
-    char ipbuf[32];
-    u_char *cp;
-
-    cp = (u_char *) & numb->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]));
+    char ipbuf[128];
+
+    if (numb->family == AF_INET6) {
+       /* Build nibble-format ip6.arpa reverse name */
+       const u_char *b = (const u_char *) &numb->addr.v6;
+       char *p = ipbuf;
+       int i;
+       for (i = 15; i >= 0; i--) {
+           *p++ = "0123456789abcdef"[b[i] & 0x0f];
+           *p++ = '.';
+           *p++ = "0123456789abcdef"[(b[i] >> 4) & 0x0f];
+           *p++ = '.';
+       }
+       strcpy (p, "ip6.arpa.");
+    }
+    else {
+       u_char *cp = (u_char *) &numb->addr.v4.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]));
+    }
     if (!rptr) {
        rptr = make_request (lp);
        rptr->type = T_PTR;
-       rptr->addr.s_addr = numb->s_addr;
-       memcpy ((char *) &rptr->he.h_addr, (char *) &numb->s_addr, sizeof (struct in_addr));
-       rptr->he.h_length = sizeof (struct in_addr);
+       IRC_ADDR_COPY (&rptr->addr, numb);
+       IRC_ADDR_COPY (&rptr->he.h_addr, numb);
+       rptr->he.h_addrtype = numb->family;
+       rptr->he.h_length = (numb->family == AF_INET6) ? 16 : 4;
     }
     return (query_name (ipbuf, C_IN, T_PTR, rptr));
 }
@@ -455,12 +477,12 @@ static int proc_answer (ResRQ *rptr, HEADER *hptr, char *buf, char *eob)
     char *cp, **alias;
     struct hent *hp;
     int class, type, dlen, len, ans = 0, n;
-    struct in_addr dr, *adr;
+    struct irc_addr *adr;
 
     cp = buf + sizeof (HEADER);
     hp = (struct hent *) &(rptr->he);
     adr = &hp->h_addr;
-    while (adr->s_addr)
+    while (!irc_addr_is_zero (adr))
        adr++;
     alias = hp->h_aliases;
     while (*alias)
@@ -503,10 +525,26 @@ static int proc_answer (ResRQ *rptr, HEADER *hptr, char *buf, char *eob)
            hp->h_length = dlen;
            if (ans == 1)
                hp->h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
-           memcpy ((char *) &dr, cp, dlen);
-           adr->s_addr = dr.s_addr;
+           adr->family = AF_INET;
+           memcpy (&adr->addr.v4, cp, dlen);
            Debug ((DEBUG_INFO, "got ip # %s for %s",
-                   inetntoa_v4 (adr), hostbuf));
+                   irc_addr_str (adr), hostbuf));
+           if (!hp->h_name) {
+               hp->h_name = (char *) MyMalloc (len + 1);
+               (void) strcpy (hp->h_name, hostbuf);
+           }
+           ans++;
+           adr++;
+           cp += dlen;
+           break;
+       case T_AAAA:
+           hp->h_length = dlen;
+           if (ans == 1)
+               hp->h_addrtype = (class == C_IN) ? AF_INET6 : AF_UNSPEC;
+           adr->family = AF_INET6;
+           memcpy (&adr->addr.v6, cp, dlen);
+           Debug ((DEBUG_INFO, "got ipv6 # %s for %s",
+                   irc_addr_str (adr), hostbuf));
            if (!hp->h_name) {
                hp->h_name = (char *) MyMalloc (len + 1);
                (void) strcpy (hp->h_name, hostbuf);
@@ -654,12 +692,12 @@ struct hostent *get_res (char *lp)
        struct hostent *hp2 = NULL;
 
        Debug ((DEBUG_DNS, "relookup %s <-> %s",
-               rptr->he.h_name, inetntoa_v4 (&rptr->he.h_addr)));
+               rptr->he.h_name, irc_addr_str (&rptr->he.h_addr)));
 
        if (!rptr->he.h_name) {
            char badip[128];
            sprintf (badip, "%s (a = %d)",
-                    inetntoa_v4 (&rptr->he.h_addr), a);
+                    irc_addr_str (&rptr->he.h_addr), a);
 
            sendto_realops ("WARNING: Error in lookup of %s.", badip);
            sendto_serv_butone (&me, ":%s GLOBOPS :Error in lookup of %s.",
@@ -813,7 +851,7 @@ static void update_list (ResRQ *rptr, aCache *cachep)
 {
     aCache **cpp, *cp = cachep;
     char *s, *t, **base;
-    int i, j;
+    int i, j, n;
     int addrcount;
 
     /*
@@ -875,41 +913,47 @@ static void update_list (ResRQ *rptr, aCache *cachep)
     /*
      * Do the same again for IP#'s.
      */
-    for (s = (char *) &rptr->he.h_addr.s_addr;
-        ((struct in_addr *) s)->s_addr; s += sizeof (struct in_addr)) {
-       for (i = 0; (t = cp->he.h_addr_list[i]); i++)
-           if (!memcmp (s, t, sizeof (struct in_addr)))
+    {
+       int addr_sz = cp->he.h_length;
+       int k;
+       for (k = 0; !irc_addr_is_zero (&rptr->he.h_addr_list[k]); k++) {
+           const void *raw;
+           int alen = irc_addr_raw (&rptr->he.h_addr_list[k], &raw);
+           if (alen != addr_sz)
+               continue;  /* skip mismatched address families */
+           for (i = 0; (t = cp->he.h_addr_list[i]); i++)
+               if (!memcmp (raw, t, addr_sz))
+                   break;
+           if (i >= MAXADDRS || addrcount >= MAXADDRS)
                break;
-       if (i >= MAXADDRS || addrcount >= MAXADDRS)
-           break;
-       /*
-        * Oh man this is bad...I *HATE* it. -avalon
-        *
-        * Whats it do ?  Reallocate two arrays, one of pointers
-        * to "char *" and the other of IP addresses.  Contents of
-        * the IP array *MUST* be preserved and the pointers into
-        * it recalculated.
-        */
-       if (!t) {
-           base = cp->he.h_addr_list;
-           addrcount++;
-           t = (char *) MyRealloc (*base,
-                                   addrcount * sizeof (struct in_addr));
-           base =
-               (char **) MyRealloc ((char *) base,
-                                    (addrcount + 1) * sizeof (char *));
-           cp->he.h_addr_list = base;
+           /*
+            * Oh man this is bad...I *HATE* it. -avalon
+            *
+            * Whats it do ?  Reallocate two arrays, one of pointers
+            * to "char *" and the other of IP addresses.  Contents of
+            * the IP array *MUST* be preserved and the pointers into
+            * it recalculated.
+            */
+           if (!t) {
+               base = cp->he.h_addr_list;
+               addrcount++;
+               t = (char *) MyRealloc (*base,
+                                       addrcount * addr_sz);
+               base =
+                   (char **) MyRealloc ((char *) base,
+                                        (addrcount + 1) * sizeof (char *));
+               cp->he.h_addr_list = base;
 #ifdef DEBUG
-           Debug ((DEBUG_DNS, "u_l:add IP %x hal %x ac %d",
-                   ntohl (((struct in_addr *) s)->s_addr),
-                   cp->he.h_addr_list, addrcount));
+               Debug ((DEBUG_DNS, "u_l:add IP hal %x ac %d",
+                       cp->he.h_addr_list, addrcount));
 #endif
-           for (; addrcount; addrcount--) {
-               *base++ = t;
-               t += sizeof (struct in_addr);
+               for (n = addrcount; n; n--) {
+                   *base++ = t;
+                   t += addr_sz;
+               }
+               *base = NULL;
+               memcpy (*--base, raw, addr_sz);
            }
-           *base = NULL;
-           memcpy (*--base, s, sizeof (struct in_addr));
        }
     }
     return;
@@ -957,30 +1001,30 @@ static aCache *find_cache_name (char *name)
 /*
  * find a cache entry by ip# and update its expire time
  */
-static aCache *find_cache_number (ResRQ *rptr, char *numb)
+static aCache *find_cache_number (ResRQ *rptr, char *numb, int addrlen)
 {
     aCache *cp;
     int hashv, i;
-#ifdef DEBUG
-    struct in_addr *ip = (struct in_addr *) numb;
-#endif
 
     hashv = hash_number ((u_char *) numb);
 
     cp = hashtable[hashv].num_list;
 #ifdef DEBUG
-    Debug ((DEBUG_DNS, "find_cache_number:find %s[%08x]: hashv = %d",
-           inetntoa_v4 ((struct in_addr *) numb), ntohl (ip->s_addr), hashv));
+    Debug ((DEBUG_DNS, "find_cache_number:find hashv = %d addrlen = %d",
+           hashv, addrlen));
 #endif
 
     for (; cp; cp = cp->hnum_next)
-       for (i = 0; cp->he.h_addr_list[i]; i++)
-           if (!memcmp (cp->he.h_addr_list[i], numb, sizeof (struct in_addr))) {
-               cainfo.ca_nu_hits++;
-               update_list (rptr, cp);
-               return cp;
-           }
+       if (cp->he.h_length == addrlen)
+           for (i = 0; cp->he.h_addr_list[i]; i++)
+               if (!memcmp (cp->he.h_addr_list[i], numb, addrlen)) {
+                   cainfo.ca_nu_hits++;
+                   update_list (rptr, cp);
+                   return cp;
+               }
     for (cp = cachetop; cp; cp = cp->list_next) {
+       if (cp->he.h_length != addrlen)
+           continue;
        /*
         * single address entry...would have been done by hashed
         * search above...
@@ -994,7 +1038,7 @@ static aCache *find_cache_number (ResRQ *rptr, char *numb)
        if (hashv == hash_number ((u_char *) cp->he.h_addr_list[0]))
            continue;
        for (i = 1; cp->he.h_addr_list[i]; i++)
-           if (!memcmp (cp->he.h_addr_list[i], numb, sizeof (struct in_addr))) {
+           if (!memcmp (cp->he.h_addr_list[i], numb, addrlen)) {
                cainfo.ca_nu_hits++;
                update_list (rptr, cp);
                return cp;
@@ -1013,19 +1057,23 @@ static aCache *make_cache (ResRQ *rptr)
     /*
        ** shouldn't happen but it just might...
      */
-    if (!rptr->he.h_name || !rptr->he.h_addr.s_addr)
+    if (!rptr->he.h_name || irc_addr_is_zero (&rptr->he.h_addr))
        return NULL;
     /*
        ** Make cache entry.  First check to see if the cache already exists
        ** and if so, return a pointer to it.
      */
-    if ((cp = find_cache_number (rptr, (char *) &rptr->he.h_addr.s_addr)))
-       return cp;
-    for (i = 1; rptr->he.h_addr_list[i].s_addr; i++)
-       if ((cp = find_cache_number (rptr,
-                                    (char *) &(rptr->he.h_addr_list[i].
-                                               s_addr))))
+    {
+       const void *raw;
+       int alen = irc_addr_raw (&rptr->he.h_addr, &raw);
+       if ((cp = find_cache_number (rptr, (char *) raw, alen)))
            return cp;
+       for (i = 1; !irc_addr_is_zero (&rptr->he.h_addr_list[i]); i++) {
+           alen = irc_addr_raw (&rptr->he.h_addr_list[i], &raw);
+           if ((cp = find_cache_number (rptr, (char *) raw, alen)))
+               return cp;
+       }
+    }
 
     /*
        ** a matching entry wasnt found in the cache so go and make one up.
@@ -1035,23 +1083,28 @@ static aCache *make_cache (ResRQ *rptr)
 
     hp = &cp->he;
     for (i = 0; i < MAXADDRS; i++)
-       if (!rptr->he.h_addr_list[i].s_addr)
+       if (irc_addr_is_zero (&rptr->he.h_addr_list[i]))
            break;
 
     /*
        ** build two arrays, one for IP#'s, another of pointers to them.
      */
-    t = hp->h_addr_list = (char **) MyMalloc (sizeof (char *) * (i + 1));
-    memset ((char *) t, 0, sizeof (char *) * (i + 1));
-
-    s = (char *) MyMalloc (sizeof (struct in_addr) * i);
-    memset (s, 0, sizeof (struct in_addr) * i);
-
-    for (n = 0; n < i; n++, s += sizeof (struct in_addr)) {
-       *t++ = s;
-       memcpy (s, (char *) &(rptr->he.h_addr_list[n].s_addr), sizeof (struct in_addr));
+    {
+       int addr_sz = rptr->he.h_length;
+       t = hp->h_addr_list = (char **) MyMalloc (sizeof (char *) * (i + 1));
+       memset ((char *) t, 0, sizeof (char *) * (i + 1));
+
+       s = (char *) MyMalloc (addr_sz * i);
+       memset (s, 0, addr_sz * i);
+
+       for (n = 0; n < i; n++, s += addr_sz) {
+           const void *raw;
+           irc_addr_raw (&rptr->he.h_addr_list[n], &raw);
+           *t++ = s;
+           memcpy (s, raw, addr_sz);
+       }
+       *t = (char *) NULL;
     }
-    *t = (char *) NULL;
 
     /*
        ** an array of pointers to CNAMEs.
@@ -1134,9 +1187,8 @@ static void rem_cache (aCache *ocp)
      */
     hashv = hash_number ((u_char *) hp->h_addr);
 #ifdef DEBUG
-    Debug ((DEBUG_DEBUG, "rem_cache: h_addr %s hashv %d next %#x first %#x",
-           inetntoa_v4 ((struct in_addr *) hp->h_addr), hashv, ocp->hnum_next,
-           hashtable[hashv].num_list));
+    Debug ((DEBUG_DEBUG, "rem_cache: h_addr hashv %d next %#x first %#x",
+           hashv, ocp->hnum_next, hashtable[hashv].num_list));
 #endif
     for (cp = &hashtable[hashv].num_list; *cp; cp = &((*cp)->hnum_next))
        if (*cp == ocp) {
@@ -1212,14 +1264,14 @@ int m_dns (aClient *cptr, aClient *sptr, int parc, char *parv[])
        for (cp = cachetop; cp; cp = cp->list_next) {
            sendto_one (sptr, "NOTICE %s :Ex %d ttl %d host %s(%s)",
                        parv[0], cp->expireat - time (NULL), cp->ttl,
-                       cp->he.h_name, inetntoa_v4 ((struct in_addr *) cp->he.h_addr));
+                       cp->he.h_name, cache_addr_str (&cp->he, cp->he.h_addr));
            for (i = 0; cp->he.h_aliases[i]; i++)
                sendto_one (sptr, "NOTICE %s : %s = %s (CN)",
                            parv[0], cp->he.h_name, cp->he.h_aliases[i]);
            for (i = 1; cp->he.h_addr_list[i]; i++)
                sendto_one (sptr, "NOTICE %s : %s = %s (IP)",
                            parv[0], cp->he.h_name,
-                           inetntoa_v4 ((struct in_addr *) cp->he.h_addr_list[i]));
+                           cache_addr_str (&cp->he, cp->he.h_addr_list[i]));
        }
        return 0;
     }
@@ -1250,7 +1302,7 @@ u_long cres_mem (aClient *sptr)
        h = &c->he;
        for (i = 0; h->h_addr_list[i]; i++) {
            im += sizeof (char *);
-           im += sizeof (struct in_addr);
+           im += h->h_length;
        }
        im += sizeof (char *);
        for (i = 0; h->h_aliases[i]; i++) {
index b001a8af61171d0bc45a5bcd5785da3fb0f26733..f295276cd567fa40726e59378cf169439bf3d164 100644 (file)
@@ -469,8 +469,10 @@ int check_client (aClient *cptr)
      * the ip#(s) for the socket is listed for the host.
      */
     if (hp) {
+       const void *raw;
+       int alen = irc_addr_raw (&cptr->ip, &raw);
        for (i = 0; hp->h_addr_list[i]; i++)
-           if (!memcmp (hp->h_addr_list[i], (char *) &cptr->ip.addr.v4, sizeof (struct in_addr)))
+           if (hp->h_length == alen && !memcmp (hp->h_addr_list[i], raw, alen))
                break;
        if (!hp->h_addr_list[i]) {
            sendto_ops ("IP# Mismatch: %s != %s",
@@ -588,8 +590,10 @@ int check_server (aClient *cptr, struct hostent *hp, aConfItem *c_conf, aConfIte
      * with the resolver's cached result.
      */
     if (hp) {
+       const void *raw;
+       int alen = irc_addr_raw (&cptr->ip, &raw);
        for (i = 0; hp->h_addr_list[i]; i++)
-           if (!memcmp (hp->h_addr_list[i], (char *) &cptr->ip.addr.v4, sizeof (struct in_addr)))
+           if (hp->h_length == alen && !memcmp (hp->h_addr_list[i], raw, alen))
                break;
        if (!hp->h_addr_list[i]) {
            sendto_ops ("IP# Mismatch: %s != %s",
@@ -650,7 +654,11 @@ int check_server (aClient *cptr, struct hostent *hp, aConfItem *c_conf, aConfIte
     }
     else
        for (i = 0; hp->h_addr_list[i]; i++) {
-           struct irc_addr tmp_ip = irc_addr_from_v4 ((struct in_addr *) hp->h_addr_list[i]);
+           struct irc_addr tmp_ip;
+           if (hp->h_addrtype == AF_INET6)
+               tmp_ip = irc_addr_from_v6 ((struct in6_addr *) hp->h_addr_list[i]);
+           else
+               tmp_ip = irc_addr_from_v4 ((struct in_addr *) hp->h_addr_list[i]);
            if (!c_conf)
                c_conf =
                    find_conf_ip (lp, &tmp_ip, cptr->username,
@@ -1037,7 +1045,7 @@ aClient * add_connection (aClient *cptr, int fd)
        lin.flags = ASYNC_CLIENT;
        lin.value.cptr = acptr;
        Debug ((DEBUG_DNS, "lookup %s", inetntoa (&acptr->ip)));
-       acptr->hostp = gethost_byaddr ((char *) &acptr->ip.addr.v4, &lin);
+       acptr->hostp = gethost_byaddr (&acptr->ip, &lin);
        if (!acptr->hostp)
            SetDNS (acptr);
        else if (acptr->cc)
@@ -1446,7 +1454,7 @@ int connect_server (aConfItem *aconf, aClient *by, struct hostent *hp)
                    hp, aconf, aconf->name, s));
            if (!hp)
                return 0;
-           aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
+           aconf->ipnum = irc_addr_from_hostent (hp);
        }
     }
     cptr = make_client (NULL, NULL);
@@ -1560,7 +1568,7 @@ static struct sockaddr * connect_inet (aConfItem *aconf, aClient *cptr, int *len
                Debug ((DEBUG_FATAL, "%s: unknown host", aconf->host));
                return NULL;
            }
-           aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
+           aconf->ipnum = irc_addr_from_hostent (hp);
        }
     }
 
@@ -1802,7 +1810,7 @@ static void do_dns_async ()
        case ASYNC_CONNECT:
            aconf = ln.value.aconf;
            if (hp && aconf) {
-               aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
+               aconf->ipnum = irc_addr_from_hostent (hp);
                (void) connect_server (aconf, NULL, hp);
            }
            else
@@ -1812,7 +1820,7 @@ static void do_dns_async ()
        case ASYNC_CONF:
            aconf = ln.value.aconf;
            if (hp && aconf)
-               aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
+               aconf->ipnum = irc_addr_from_hostent (hp);
            break;
        case ASYNC_SERVER:
            cptr = ln.value.cptr;
@@ -1825,7 +1833,7 @@ static void do_dns_async ()
            cptr = ln.value.cptr;
            del_queries ((char *) cptr);
            if (hp) {
-               cptr->ip = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
+               cptr->ip = irc_addr_from_hostent (hp);
                if (ping_server (cptr, hp) != -1)
                    break;
            }
index b4b913a83d4c711898e970a5231a02778fa0bfd6..9e3c509a5e508154c3b3b4e53413d7170d8fd7f9 100644 (file)
@@ -1456,7 +1456,7 @@ static int lookup_confhost (aConfItem *aconf)
            goto badlookup;
     }
     else if ((hp = gethost_byname (s, &ln)))
-       aconf->ipnum = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
+       aconf->ipnum = irc_addr_from_hostent (hp);
 
     if (irc_addr_is_zero (&aconf->ipnum) && isdigit (*s))
        goto badlookup;
index 107aaf6cb31ad1868b16b266f2b3cdc42aeea6d6..7d445bd7c1ef1c6edcb909bef3029e3cdc89c7a7 100644 (file)
@@ -244,7 +244,7 @@ int ping_server (aClient *cptr, struct hostent *hp)
            Debug ((DEBUG_NOTICE, "ping_sv: hp %x ac %x ho %s", hp, cptr, s));
            if (!hp)
                return 0;
-           cptr->ip = irc_addr_from_v4 ((struct in_addr *) hp->h_addr);
+           cptr->ip = irc_addr_from_hostent (hp);
        }
     }
     return start_ping (cptr);