diff options
author | Mark Wooding <mdw@distorted.org.uk> | 2014-06-11 00:33:00 +0100 |
---|---|---|
committer | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2014-10-19 21:09:57 +0100 |
commit | cdf51ff0be2d71b61dec430d08c985f20cc5dffd (patch) | |
tree | aaa00c0aa8ac078d770fa20aa1b08745c6b30b87 /src | |
parent | 2ca5496dfc95d6e40596d9f1d83929cc5a3bc495 (diff) |
Support v6-mapping IPv4 addresses found doing addr lookups.
Not available if the client doesn't have the larger adns_rr_addr
structure.
Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/adns.h | 1 | ||||
-rw-r--r-- | src/types.c | 19 |
2 files changed, 19 insertions, 1 deletions
@@ -102,6 +102,7 @@ typedef enum { /* In general, or together the desired flags: */ adns_qf_quotefail_cname=0x00000080,/* refuse if quote-req chars in CNAME we go via */ adns_qf_cname_loose= 0x00000100,/* allow refs to CNAMEs - without, get _s_cname */ adns_qf_cname_forbid= 0x00000200,/* don't follow CNAMEs, instead give _s_cname */ + adns_qf_ipv6_mapv4= 0x00001000,/* ... return IPv4 addresses as v6-mapped */ adns_qf_addrlit_scope_forbid=0x00002000,/* forbid %<scope> in IPv6 literals */ adns_qf_addrlit_scope_numeric=0x00004000,/* %<scope> may only be numeric */ adns_qf_addrlit_ipv4_quadonly=0x00008000,/* reject non-dotted-quad ipv4 */ diff --git a/src/types.c b/src/types.c index 29e16ad..d4693c2 100644 --- a/src/types.c +++ b/src/types.c @@ -382,6 +382,7 @@ static adns_status pap_addr(const parseinfo *pai, int rrty, size_t rrsz, int *cbyte_io, int max, adns_rr_addr *storeto) { const byte *dgram= pai->dgram; int af, addrlen, salen; + struct in6_addr v6map; const void *oaddr= dgram + *cbyte_io; int avail= max - *cbyte_io; int step= -1; @@ -389,10 +390,26 @@ static adns_status pap_addr(const parseinfo *pai, int rrty, size_t rrsz, switch (rrty) { case adns_r_a: + if ((pai->qu->flags & adns_qf_ipv6_mapv4) && + (pai->qu->answer->type & adns__qtf_bigaddr)) { + if (avail < 4) return adns_s_invaliddata; + memset(v6map.s6_addr + 0, 0x00, 10); + memset(v6map.s6_addr + 10, 0xff, 2); + memcpy(v6map.s6_addr + 12, oaddr, 4); + oaddr= v6map.s6_addr; avail= sizeof(v6map.s6_addr); + if (step < 0) step= 4; + goto aaaa; + } af= AF_INET; addrlen= 4; addrp= &storeto->addr.inet.sin_addr; salen= sizeof(storeto->addr.inet); break; + case adns_r_aaaa: + aaaa: + af= AF_INET6; addrlen= 16; + addrp= storeto->addr.inet6.sin6_addr.s6_addr; + salen= sizeof(storeto->addr.inet6); + break; } assert(addrp); @@ -842,7 +859,7 @@ static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io, ctx.callback= icb_hostaddr; ctx.pinfo.hostaddr= rrp; - nflags= adns_qf_quoteok_query; + nflags= adns_qf_quoteok_query | (pai->qu->flags & adns_qf_ipv6_mapv4); if (!(pai->qu->flags & adns_qf_cname_loose)) nflags |= adns_qf_cname_forbid; st= addr_submit(pai->qu, &nqu, &pai->qu->vb, id, want, |