--------------------- PatchSet 3988 Date: 2007/01/07 21:34:13 Author: amosjeffries Branch: squid3-ipv6 Tag: (none) Log: More Dual-Stack support. Members: lib/rfc1035.c:1.5.2.5->1.5.2.6 Index: squid3/lib/rfc1035.c =================================================================== RCS file: /cvsroot/squid-sf//squid3/lib/rfc1035.c,v retrieving revision 1.5.2.5 retrieving revision 1.5.2.6 diff -u -r1.5.2.5 -r1.5.2.6 --- squid3/lib/rfc1035.c 7 Jan 2007 03:46:05 -0000 1.5.2.5 +++ squid3/lib/rfc1035.c 7 Jan 2007 21:34:13 -0000 1.5.2.6 @@ -1,6 +1,6 @@ /* - * $Id: rfc1035.c,v 1.5.2.5 2007/01/07 03:46:05 amosjeffries Exp $ + * $Id: rfc1035.c,v 1.5.2.6 2007/01/07 21:34:13 amosjeffries Exp $ * * Low level DNS protocol routines * AUTHOR: Duane Wessels @@ -689,18 +689,13 @@ static rfc1035_message h; size_t offset = 0; - static char rev[45]; - - /* FIXME: at this point it doesn't really matter what the underlying protocol is. */ - /* the rDNS deals with that later. */ - /* we only need to know what type of struct IN_ADDR is and how to reverse it here. */ - /* this will be the same (for each) regardless of the protocol used. */ - /* Clients will need to rDNS IPv4 ADDR when using IPv4, and vice versa. */ - /* BUT: How to tell that reliably at runtime ??? */ + static char rev[75]; + unsigned int i; + const u_char* r = &addr; #if INET6 - /* Even IPv4 systems may want to rDNS an IPv6 Addr. */ - if( sizeof(addr) == sizeof(in6_addr)) + + if(qid == RFC1035_TYPE_AAAA) { /* RFC1886 says: */ /* 4321:0:1:2:3:4:567:89ab */ @@ -712,10 +707,9 @@ /* work from the raw addr field. anything else may have representation changes. */ /* The sin6_port and sin6_addr members shall be in network byte order. */ - const u_char* r = &addr; - snprintf(rev, szIP6rDNS, - "%x.%x.%x.%x." - "%x.%x.%x.%x." + snprintf(rev, 72, + "%x.%x.%x.%x." // 8 + "%x.%x.%x.%x." // 6 "%x.%x.%x.%x." "%x.%x.%x.%x." "%x.%x.%x.%x." @@ -724,14 +718,14 @@ "%x.%x.%x.%x." "ip6.arpa." , - r[0], r[1], r[2], r[3], - r[4], r[5], r[6], r[7], - r[8], r[9], r[10], r[11], - r[12], r[13], r[14], r[15], - r[16], r[17], r[18], r[19], - r[20], r[21], r[22], r[23], - r[24], r[25], r[26], r[27], - r[28], r[29], r[30], r[31], + r[31], r[30], r[29], r[28], + r[27], r[26], r[25], r[24], + r[23], r[22], r[21], r[20], + r[19], r[18], r[17], r[16], + r[15], r[14], r[13], r[12], + r[11], r[10], r[9], r[8], + r[7], r[6], r[5], r[4], + r[3], r[2], r[1], r[0] ); /* TODO: @@ -740,45 +734,44 @@ * if someone wants it they can ask. */ } - /* even IPv6 People may need to rDNS the odd IPv4 Addr sometimes. */ - else if(sizeof(addr) == sizeof(in_addr)) + else if (qid == RFC1035_TYPE_A) { + char *junk = inet_ntop(addr); + if(strncmp("::ffff:",junk, 6) == 0) + { + /* Under IPv6 the 29-32 Bytes of in6_addr are network-byte-order IPv4 Addr. */ + i = (unsigned int) ntohl( 28+r ); + +#else /* ! INET6 */ + i = (unsigned int) ntohl(addr.s_addr); + #endif /* INET6 */ - unsigned int i; - i = (unsigned int) ntohl(addr.s_addr); - snprintf(rev, 32, "%u.%u.%u.%u.in-addr.arpa.", - i & 255, - (i >> 8) & 255, - (i >> 16) & 255, - (i >> 24) & 255); -#ifdef INET6 + snprintf(rev, 32, "%u.%u.%u.%u.in-addr.arpa.", + i & 255, + (i >> 8) & 255, + (i >> 16) & 255, + (i >> 24) & 255); +#if INET6 + } + else + { + /* FIXME debug output. Query Died. */ + /* "WARNING: IP Address Type of 'A' Does not match Data Content of %s.\n",junk */ + } +#ifdef INET6DUALSTACK } - /* Hmm, I seem to have done something wrong... */ - else + else /* Unknown Input Record Type */ { - self_destruct(); + /* FIXME debug output. Query Died. */ + /* "WARNING: Dropped PTR QUery for unknown RR Type.\n" */ + return ??; } -#endif +#endif /* INET6DUALSTACK */ - memset(&h, '\0', sizeof(h)); - h.id = qid; - h.qr = 0; - h.rd = 1; - h.opcode = 0; /* QUERY */ - h.qdcount = (unsigned int) 1; - offset += rfc1035HeaderPack(buf + offset, sz - offset, &h); - offset += rfc1035QuestionPack(buf + offset, - sz - offset, - rev, - RFC1035_TYPE_PTR, - RFC1035_CLASS_IN); - if (query) { - query->qtype = RFC1035_TYPE_PTR; - query->qclass = RFC1035_CLASS_IN; - xstrncpy(query->name, rev, sizeof(query->name)); - } - assert(offset <= sz); - return offset; +#endif /* INET6 */ + + + return rfc1035BuildHostQuery(rev, buf, sz, qid, RFC1035_TYPE_PTR, RFC1035_CLASS_IN); }