chiark / gitweb /
Support v6-mapping IPv4 addresses found doing addr lookups.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 10 Jun 2014 23:33:00 +0000 (00:33 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 19 Oct 2014 20:09:57 +0000 (21:09 +0100)
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>
client/adh-opts.c
client/adh-query.c
client/adnshost.h
regress/case-v6-map.err [new file with mode: 0644]
regress/case-v6-map.out [new file with mode: 0644]
regress/case-v6-map.sys [new file with mode: 0644]
src/adns.h
src/types.c

index 34ce33477f4f3645eb4ea8961a2f90cfedc07d3f..7670ba5a115b9a24662c40f8a18bc9d40a394ea3 100644 (file)
@@ -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_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 };
 
 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 },
     "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",
   
   { ot_desconly, "per-query CNAME handling mode:" },
   { ot_value,            "Call it an error if a CNAME is found",
index 90598fe0e024c311c1098e3fe00197c2fe2df077..aa2918e430dff8b57fe4e0200a718e663145082c 100644 (file)
@@ -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_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;
     ov_cname;
     
   *qun_r= qun;
index fcc96a3186ab9292461f42b18a09b8baaf4840bc..69d93745832b2c48d3026b6361f29132815b69c8 100644 (file)
@@ -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_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;
 
 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 (file)
index 0000000..e69de29
diff --git a/regress/case-v6-map.out b/regress/case-v6-map.out
new file mode 100644 (file)
index 0000000..28d4081
--- /dev/null
@@ -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 (file)
index 0000000..97a1eb3
--- /dev/null
@@ -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
index 245833360bf873d5cd4987403c8c0abd2a113b85..7d78bf7ed7dded496ed5e8862bd5569bd7589a01 100644 (file)
@@ -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_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 */
  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 */
index 29e16ad75f24415fc4e797d1af8fa77539fe690a..d4693c251bcf54cb2b262b6e34f94c1523beb794 100644 (file)
@@ -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;
                            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;
   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:
 
   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;
     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);
 
   }
   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;
   
   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,
   if (!(pai->qu->flags & adns_qf_cname_loose)) nflags |= adns_qf_cname_forbid;
   
   st= addr_submit(pai->qu, &nqu, &pai->qu->vb, id, want,