From cdf51ff0be2d71b61dec430d08c985f20cc5dffd Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 11 Jun 2014 00:33:00 +0100 Subject: [PATCH 1/1] 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 Signed-off-by: Ian Jackson --- client/adh-opts.c | 5 ++- client/adh-query.c | 1 + client/adnshost.h | 2 +- regress/case-v6-map.err | 0 regress/case-v6-map.out | 11 ++++++ regress/case-v6-map.sys | 79 +++++++++++++++++++++++++++++++++++++++++ src/adns.h | 1 + src/types.c | 19 +++++++++- 8 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 regress/case-v6-map.err create mode 100644 regress/case-v6-map.out create mode 100644 regress/case-v6-map.sys diff --git a/client/adh-opts.c b/client/adh-opts.c index 34ce334..7670ba5 100644 --- a/client/adh-opts.c +++ b/client/adh-opts.c @@ -31,7 +31,7 @@ int ov_env=1, ov_pipe=0, ov_asynch=0; int ov_verbose= 0; adns_rrtype ov_type= adns_r_none; int ov_search=0, ov_qc_query=0, ov_qc_anshost=0, ov_qc_cname=1; -int ov_tcp=0, ov_cname=0, ov_format=fmt_default; +int ov_tcp=0, ov_cname=0, ov_v6map=0, ov_format=fmt_default; char *ov_id= 0; struct perqueryflags_remember ov_pqfr = { 1,1,1, tm_none }; @@ -105,6 +105,9 @@ static const struct optioninfo perquery_options[]= { "Ta", "ttl-abs", &ov_pqfr.ttl, tm_abs }, { ot_value, "Do not show the TTL (default)", "Tn", "no-ttl", &ov_pqfr.ttl, tm_none }, + + { ot_flag, "Return IPv4 addresses as IPv6-mapped", + "Am", "--addr-ipv6-mapped", &ov_v6map, 1 }, { ot_desconly, "per-query CNAME handling mode:" }, { ot_value, "Call it an error if a CNAME is found", diff --git a/client/adh-query.c b/client/adh-query.c index 90598fe..aa2918e 100644 --- a/client/adh-query.c +++ b/client/adh-query.c @@ -92,6 +92,7 @@ static void prep_query(struct query_node **qun_r, int *quflags_r) { (ov_qc_query ? adns_qf_quoteok_query : 0) | (ov_qc_anshost ? adns_qf_quoteok_anshost : 0) | (ov_qc_cname ? 0 : adns_qf_quoteok_cname) | + (ov_v6map ? adns_qf_ipv6_mapv4 : 0) | ov_cname; *qun_r= qun; diff --git a/client/adnshost.h b/client/adnshost.h index fcc96a3..69d9374 100644 --- a/client/adnshost.h +++ b/client/adnshost.h @@ -80,7 +80,7 @@ extern int ov_env, ov_pipe, ov_asynch; extern int ov_verbose; extern adns_rrtype ov_type; extern int ov_search, ov_qc_query, ov_qc_anshost, ov_qc_cname; -extern int ov_tcp, ov_cname, ov_format; +extern int ov_tcp, ov_cname, ov_format, ov_v6map; extern char *ov_id; extern struct perqueryflags_remember ov_pqfr; diff --git a/regress/case-v6-map.err b/regress/case-v6-map.err new file mode 100644 index 0000000..e69de29 diff --git a/regress/case-v6-map.out b/regress/case-v6-map.out new file mode 100644 index 0000000..28d4081 --- /dev/null +++ b/regress/case-v6-map.out @@ -0,0 +1,11 @@ +adns debug: using nameserver 172.29.199.224 +distorted.org.uk flags 4096 type 65537 A(addr) submitted +distorted.org.uk flags 4096 type 65551 MX(+addr) submitted +distorted.org.uk flags 4096 type 65537 A(addr) submitted +distorted.org.uk flags 4096 type MX(+addr): OK; nrrs=1; cname=$; owner=$; ttl=14400 + 50 mail.distorted.org.uk ok 0 ok "OK" ( INET6 ::ffff:172.29.199.180 ) +distorted.org.uk flags 4096 type A(addr): OK; nrrs=1; cname=$; owner=$; ttl=14400 + INET6 ::ffff:172.29.199.180 +distorted.org.uk flags 4096 type A(addr): OK; nrrs=1; cname=$; owner=$; ttl=14400 + INET 172.29.199.180 +rc=0 diff --git a/regress/case-v6-map.sys b/regress/case-v6-map.sys new file mode 100644 index 0000000..97a1eb3 --- /dev/null +++ b/regress/case-v6-map.sys @@ -0,0 +1,79 @@ +./adnstest distorted +:16842753,16842767,65537 0x1000/distorted.org.uk + start 1402443121.225484 + socket domain=PF_INET type=SOCK_DGRAM + socket=6 + +0.000067 + fcntl fd=6 cmd=F_GETFL + fcntl=~O_NONBLOCK&... + +0.000031 + fcntl fd=6 cmd=F_SETFL O_NONBLOCK|... + fcntl=OK + +0.000027 + sendto fd=6 addr=172.29.199.224:53 + 31200100 00010000 00000000 09646973 746f7274 6564036f 72670275 6b000001 + 0001. + sendto=34 + +0.000188 + sendto fd=6 addr=172.29.199.224:53 + 31210100 00010000 00000000 09646973 746f7274 6564036f 72670275 6b00000f + 0001. + sendto=34 + +0.000110 + sendto fd=6 addr=172.29.199.224:53 + 31230100 00010000 00000000 09646973 746f7274 6564036f 72670275 6b000001 + 0001. + sendto=34 + +0.000101 + select max=7 rfds=[6] wfds=[] efds=[] to=1.999601 + select=1 rfds=[6] wfds=[] efds=[] + +0.001672 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 31208580 00010001 00040008 09646973 746f7274 6564036f 72670275 6b000001 + 0001c00c 00010001 00003840 0004ac1d c7b4c00c 00020001 00003840 000d0776 + 616d7069 7265026e 73c00cc0 0c000200 01000038 40000c09 70726563 6973696f + 6ec046c0 0c000200 01000038 40000906 72616469 7573c046 c00c0002 00010000 + 3840000d 0a74656c 65636173 746572c0 46c06f00 01000100 00384000 04ac1dc7 + 01c06f00 1c000100 00384000 10200104 70974000 01000000 00000000 01c03e00 + 01000100 00384000 04ac1dc7 05c03e00 1c000100 00384000 10200104 70974000 + 01000000 00000000 05c05700 01000100 00384000 04ac1dc7 b2c05700 1c000100 + 00384000 1020010b a801d900 02000000 00000000 02c08400 01000100 00384000 + 04ac1dc7 b3c08400 1c000100 00384000 1020010b a801d900 02000000 00000000 + 03. + +0.000436 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 31218580 00010001 0004000a 09646973 746f7274 6564036f 72670275 6b00000f + 0001c00c 000f0001 00003840 00090032 046d6169 6cc00cc0 0c000200 01000038 + 40000c06 72616469 7573026e 73c00cc0 0c000200 01000038 40000c09 70726563 + 6973696f 6ec04ac0 0c000200 01000038 40000a07 76616d70 697265c0 4ac00c00 + 02000100 00384000 0d0a7465 6c656361 73746572 c04ac030 00010001 00003840 + 0004ac1d c7b4c030 001c0001 00003840 00102001 0ba801d9 00020000 00000000 + 0004c043 00010001 00003840 0004ac1d c701c043 001c0001 00003840 00102001 + 04709740 00010000 00000000 0001c073 00010001 00003840 0004ac1d c705c073 + 001c0001 00003840 00102001 04709740 00010000 00000000 0005c05b 00010001 + 00003840 0004ac1d c7b2c05b 001c0001 00003840 00102001 0ba801d9 00020000 + 00000000 0002c089 00010001 00003840 0004ac1d c7b3c089 001c0001 00003840 + 00102001 0ba801d9 00020000 00000000 0003. + +0.000356 + recvfrom fd=6 buflen=512 + recvfrom=OK addr=172.29.199.224:53 + 31238580 00010001 00040008 09646973 746f7274 6564036f 72670275 6b000001 + 0001c00c 00010001 00003840 0004ac1d c7b4c00c 00020001 00003840 00100a74 + 656c6563 61737465 72026e73 c00cc00c 00020001 00003840 000a0776 616d7069 + 7265c049 c00c0002 00010000 3840000c 09707265 63697369 6f6ec049 c00c0002 + 00010000 38400009 06726164 697573c0 49c08800 01000100 00384000 04ac1dc7 + 01c08800 1c000100 00384000 10200104 70974000 01000000 00000000 01c05a00 + 01000100 00384000 04ac1dc7 05c05a00 1c000100 00384000 10200104 70974000 + 01000000 00000000 05c07000 01000100 00384000 04ac1dc7 b2c07000 1c000100 + 00384000 1020010b a801d900 02000000 00000000 02c03e00 01000100 00384000 + 04ac1dc7 b3c03e00 1c000100 00384000 1020010b a801d900 02000000 00000000 + 03. + +0.000329 + recvfrom fd=6 buflen=512 + recvfrom=EAGAIN + +0.000049 + close fd=6 + close=OK + +0.000145 diff --git a/src/adns.h b/src/adns.h index 2458333..7d78bf7 100644 --- a/src/adns.h +++ b/src/adns.h @@ -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 % in IPv6 literals */ adns_qf_addrlit_scope_numeric=0x00004000,/* % 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, -- 2.30.2