]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add +dns64prefix to dig to display any DNS64 prefixes at IPV4ONLY.ARPA
authorMark Andrews <marka@isc.org>
Thu, 25 Jul 2019 10:26:13 +0000 (20:26 +1000)
committerMark Andrews <marka@isc.org>
Tue, 24 Nov 2020 21:25:29 +0000 (08:25 +1100)
bin/dig/dig.c
bin/dig/dig.rst
bin/dig/dighost.c
bin/dig/dighost.h
bin/tests/system/dns64/ns1/ipv4only.arpa.db [new file with mode: 0644]
bin/tests/system/dns64/ns1/named.conf1.in [moved from bin/tests/system/dns64/ns1/named.conf.in with 84% similarity]
bin/tests/system/dns64/ns1/named.conf2.in [new file with mode: 0644]
bin/tests/system/dns64/ns1/named.conf3.in [new file with mode: 0644]
bin/tests/system/dns64/setup.sh
bin/tests/system/dns64/tests.sh
doc/man/dig.1in

index be48b2cc8c1463240058a2099f516e7c185a56b4..b2807cbf50a047211099c06c72162f10123c4586 100644 (file)
@@ -30,6 +30,7 @@
 #include <pk11/site.h>
 
 #include <dns/byaddr.h>
+#include <dns/dns64.h>
 #include <dns/fixedname.h>
 #include <dns/masterdump.h>
 #include <dns/message.h>
@@ -206,6 +207,8 @@ help(void) {
               "                                      fields in records)\n"
               "                 +[no]defname        (Use search list "
               "(+[no]search))\n"
+              "                 +[no]dns64prefix    (Get the DNS64 prefixes "
+              "from ipv4only.arpa)\n"
               "                 +[no]dnssec         (Request DNSSEC records)\n"
               "                 +domain=###         (Set default domainname)\n"
               "                 +[no]dscp[=###]     (Set the DSCP value to "
@@ -473,6 +476,50 @@ say_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) {
        return (ISC_R_SUCCESS);
 }
 
+/*%
+ * short_form message print handler.  Calls above say_message()
+ */
+static isc_result_t
+dns64prefix_answer(dns_message_t *msg, isc_buffer_t *buf) {
+       dns_rdataset_t *rdataset = NULL;
+       dns_fixedname_t fixed;
+       dns_name_t *name;
+       isc_result_t result;
+       isc_netprefix_t prefix[10];
+       size_t i, count = 10;
+
+       name = dns_fixedname_initname(&fixed);
+       result = dns_name_fromstring(name, "ipv4only.arpa", 0, NULL);
+       check_result(result, "dns_name_fromstring");
+
+       result = dns_message_findname(msg, DNS_SECTION_ANSWER, name,
+                                     dns_rdatatype_aaaa, dns_rdatatype_none,
+                                     NULL, &rdataset);
+       if (result == DNS_R_NXDOMAIN || result == DNS_R_NXRRSET) {
+               return (ISC_R_SUCCESS);
+       } else if (result != ISC_R_SUCCESS) {
+               return (result);
+       }
+
+       result = dns_dns64_findprefix(rdataset, prefix, &count);
+       if (result == ISC_R_NOTFOUND)
+               return (ISC_R_SUCCESS);
+       if (count > 10)
+               count = 10;
+       for (i = 0; i < count; i++) {
+               result = isc_netaddr_totext(&prefix[i].addr, buf);
+               if (result != ISC_R_SUCCESS) {
+                       return (result);
+               }
+               result = isc_buffer_printf(buf, "/%u\n", prefix[i].prefixlen);
+               if (result != ISC_R_SUCCESS) {
+                       return (result);
+               }
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
 /*%
  * short_form message print handler.  Calls above say_message()
  */
@@ -559,6 +606,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
        dns_master_style_t *style = NULL;
        unsigned int styleflags = 0;
        bool isquery = (msg == query->lookup->sendmsg);
+       bool dns64prefix = query->lookup->dns64prefix;
 
        UNUSED(msgbuf);
 
@@ -623,14 +671,15 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
        check_result(result, "dns_master_stylecreate");
 
        if (query->lookup->cmdline[0] != 0) {
-               if (!short_form && printcmd) {
+               if (!short_form && !dns64prefix && printcmd) {
                        printf("%s", query->lookup->cmdline);
                }
                query->lookup->cmdline[0] = '\0';
        }
        debug("printmessage(%s %s %s)", headers ? "headers" : "noheaders",
              query->lookup->comments ? "comments" : "nocomments",
-             short_form ? "short_form" : "long_form");
+             short_form ? "short_form"
+                        : dns64prefix ? "dns64prefix_form" : "long_form");
 
        flags = 0;
        if (!headers) {
@@ -751,7 +800,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
                printf("    %s:\n", isquery ? "query_message_data"
                                            : "response_message_data");
                result = dns_message_headertotext(msg, style, flags, buf);
-       } else if (query->lookup->comments && !short_form) {
+       } else if (query->lookup->comments && !short_form && !dns64prefix) {
                if (query->lookup->cmdline[0] != '\0' && printcmd) {
                        printf("; %s\n", query->lookup->cmdline);
                }
@@ -832,7 +881,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
 
 repopulate_buffer:
 
-       if (query->lookup->comments && headers && !short_form) {
+       if (query->lookup->comments && headers && !short_form && !dns64prefix) {
                result = dns_message_pseudosectiontotext(
                        msg, DNS_PSEUDOSECTION_OPT, style, flags, buf);
                if (result == ISC_R_NOSPACE) {
@@ -846,7 +895,7 @@ repopulate_buffer:
        }
 
        if (query->lookup->section_question && headers) {
-               if (!short_form) {
+               if (!short_form && !dns64prefix) {
                        result = dns_message_sectiontotext(
                                msg, DNS_SECTION_QUESTION, style, flags, buf);
                        if (result == ISC_R_NOSPACE) {
@@ -856,13 +905,18 @@ repopulate_buffer:
                }
        }
        if (query->lookup->section_answer) {
-               if (!short_form) {
+               if (!short_form && !dns64prefix) {
                        result = dns_message_sectiontotext(
                                msg, DNS_SECTION_ANSWER, style, flags, buf);
                        if (result == ISC_R_NOSPACE) {
                                goto buftoosmall;
                        }
                        check_result(result, "dns_message_sectiontotext");
+               } else if (dns64prefix) {
+                       result = dns64prefix_answer(msg, buf);
+                       if (result == ISC_R_NOSPACE)
+                               goto buftoosmall;
+                       check_result(result, "dns64prefix_answer");
                } else {
                        result = short_answer(msg, flags, buf, query);
                        if (result == ISC_R_NOSPACE) {
@@ -872,7 +926,7 @@ repopulate_buffer:
                }
        }
        if (query->lookup->section_authority) {
-               if (!short_form) {
+               if (!short_form && !dns64prefix) {
                        result = dns_message_sectiontotext(
                                msg, DNS_SECTION_AUTHORITY, style, flags, buf);
                        if (result == ISC_R_NOSPACE) {
@@ -882,7 +936,7 @@ repopulate_buffer:
                }
        }
        if (query->lookup->section_additional) {
-               if (!short_form) {
+               if (!short_form && !dns64prefix) {
                        result = dns_message_sectiontotext(
                                msg, DNS_SECTION_ADDITIONAL, style, flags, buf);
                        if (result == ISC_R_NOSPACE) {
@@ -976,8 +1030,9 @@ printgreeting(int argc, char **argv, dig_lookup_t *lookup) {
  * XXX doc options
  */
 
-static void
-plus_option(char *option, bool is_batchfile, dig_lookup_t *lookup) {
+static dig_lookup_t *
+plus_option(char *option, bool is_batchfile, bool *need_clone,
+           dig_lookup_t *lookup) {
        isc_result_t result;
        char *cmd, *value, *last = NULL, *code, *extra;
        uint32_t num;
@@ -988,7 +1043,7 @@ plus_option(char *option, bool is_batchfile, dig_lookup_t *lookup) {
 
        if ((cmd = strtok_r(option, "=", &last)) == NULL) {
                printf(";; Invalid option %s\n", option);
-               return;
+               return (lookup);
        }
        if (strncasecmp(cmd, "no", 2) == 0) {
                cmd += 2;
@@ -1155,13 +1210,57 @@ plus_option(char *option, bool is_batchfile, dig_lookup_t *lookup) {
                                usesearch = state;
                        }
                        break;
-               case 'n': /* dnssec */
-                       FULLCHECK("dnssec");
-               dnssec:
-                       if (state && lookup->edns == -1) {
-                               lookup->edns = DEFAULT_EDNS_VERSION;
+               case 'n':
+                       switch (cmd[2]) {
+                       case 's':
+                               switch (cmd[3]) {
+                               case '6': /* dns64prefix */
+                                       FULLCHECK("dns64prefix");
+                                       if (state) {
+                                               if (*need_clone) {
+                                                       lookup = clone_lookup(
+                                                               default_lookup,
+                                                               true);
+                                               }
+                                               *need_clone = true;
+                                               lookup->dns64prefix = state;
+                                               strlcpy(lookup->textname,
+                                                       "ipv4only.arpa",
+                                                       sizeof(lookup->textname));
+                                               printcmd = false;
+                                               lookup->section_additional =
+                                                       false;
+                                               lookup->section_answer = true;
+                                               lookup->section_authority =
+                                                       false;
+                                               lookup->section_question =
+                                                       false;
+                                               lookup->comments = false;
+                                               lookup->stats = false;
+                                               lookup->rrcomments = -1;
+                                               lookup->rdtype =
+                                                       dns_rdatatype_aaaa;
+                                               lookup->rdtypeset = true;
+                                               ISC_LIST_APPEND(lookup_list,
+                                                               lookup, link);
+                                       }
+                                       break;
+                               case 's': /* dnssec */
+                                       FULLCHECK("dnssec");
+                               dnssec:
+                                       if (state && lookup->edns == -1) {
+                                               lookup->edns =
+                                                       DEFAULT_EDNS_VERSION;
+                                       }
+                                       lookup->dnssec = state;
+                                       break;
+                               default:
+                                       goto invalid_option;
+                               }
+                               break;
+                       default:
+                               goto invalid_option;
                        }
-                       lookup->dnssec = state;
                        break;
                case 'o': /* domain ... but treat "do" as synonym for dnssec */
                        if (cmd[2] == '\0') {
@@ -1871,7 +1970,7 @@ plus_option(char *option, bool is_batchfile, dig_lookup_t *lookup) {
                fprintf(stderr, "Invalid option: +%s\n", option);
                usage();
        }
-       return;
+       return (lookup);
 
 #if !TARGET_OS_IPHONE
 exit_or_usage:
@@ -2382,7 +2481,8 @@ parse_args(bool is_batchfile, bool config_only, int argc, char **argv) {
                                }
                        }
                } else if (rv[0][0] == '+') {
-                       plus_option(&rv[0][1], is_batchfile, lookup);
+                       lookup = plus_option(&rv[0][1], is_batchfile,
+                                            &need_clone, lookup);
                } else if (rv[0][0] == '-') {
                        if (rc <= 1) {
                                if (dash_option(&rv[0][1], NULL, &lookup,
index 891d54e7c92d59157103bc2ad9c4d0034f5210bf..9df9ef2c1ec78b0c16925f292933239c306987f8 100644 (file)
@@ -297,6 +297,9 @@ abbreviation is unambiguous; for example, ``+cd`` is equivalent to
 ``+[no]defname``
    This option, which is deprecated, is treated as a synonym for ``+[no]search``.
 
+``+[no]dns64prefix``
+   Lookup IPV4ONLY.ARPA AAAA and print any DNS64 prefixes found.
+
 ``+[no]dnssec``
    This option requests that DNSSEC records be sent by setting the DNSSEC OK (DO) bit in
    the OPT record in the additional section of the query.
index 7eaa453791cdd77e15664287eacc64474c364223..99aa077ea7e6ceaf85e235242859bb4510681706 100644 (file)
@@ -632,6 +632,7 @@ make_empty_lookup(void) {
        looknew->ignore = false;
        looknew->servfail_stops = true;
        looknew->besteffort = true;
+       looknew->dns64prefix = false;
        looknew->dnssec = false;
        looknew->ednsflags = 0;
        looknew->opcode = dns_opcode_query;
@@ -778,6 +779,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
        looknew->ignore = lookold->ignore;
        looknew->servfail_stops = lookold->servfail_stops;
        looknew->besteffort = lookold->besteffort;
+       looknew->dns64prefix = lookold->dns64prefix;
        looknew->dnssec = lookold->dnssec;
        looknew->ednsflags = lookold->ednsflags;
        looknew->opcode = lookold->opcode;
@@ -3726,7 +3728,7 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
        }
 
        debug("before parse starts");
-       parseflags = DNS_MESSAGEPARSE_PRESERVEORDER;
+       parseflags = l->dns64prefix ? 0 : DNS_MESSAGEPARSE_PRESERVEORDER;
        if (l->besteffort) {
                parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
                parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION;
index c91c850e888ed5798fbc8203db2d3f4087354f8c..bae21a37cdd982e6270c426c15f5f0dc383d4cd0 100644 (file)
@@ -101,27 +101,27 @@ typedef struct dig_searchlist dig_searchlist_t;
 struct dig_lookup {
        unsigned int magic;
        isc_refcount_t references;
-       bool pending,                      /*%< Pending a successful answer */
-               doing_xfr, ns_search_only, /*%< dig +nssearch, host -C */
-               identify, /*%< Append an "on server <foo>" message */
-               identify_previous_line, /*% Prepend a "Nameserver <foo>:"
-                                        * message, with newline and tab */
-               ignore, recurse, aaonly, adflag, cdflag, raflag, tcflag, zflag,
+       bool aaonly, adflag, badcookie, besteffort, cdflag, comments,
+               dns64prefix, dnssec, doing_xfr, done_as_is, ednsneg, expandaaaa,
+               expire, header_only, identify, /*%< Append an "on server <foo>"
+                                                 message */
+               identify_previous_line,        /*% Prepend a "Nameserver <foo>:"
+                                                 message, with newline and tab */
+               idnin, idnout, ignore, mapped, multiline, need_search,
+               new_search, noclass, nocrypto, nottl,
+               ns_search_only,  /*%< dig +nssearch, host -C */
+               nsid,            /*% Name Server ID (RFC 5001) */
+               onesoa, pending, /*%< Pending a successful answer */
+               print_unknown_format, qr, raflag, recurse, section_additional,
+               section_answer, section_authority, section_question,
+               seenbadcookie, sendcookie, servfail_stops,
+               setqid, /*% use a speciied query ID */
+               stats, tcflag, tcp_keepalive, tcp_mode, tcp_mode_set,
+               tls_mode,   /*% connect using TLS */
                trace,      /*% dig +trace */
-               trace_root, /*% initial query for either +trace or +nssearch
-                            * */
-               tcp_mode, tcp_mode_set, comments, stats, section_question,
-               section_answer, section_authority, section_additional,
-               servfail_stops, new_search, need_search, done_as_is, besteffort,
-               dnssec, expire, sendcookie, seenbadcookie, badcookie,
-               nsid, /*% Name Server ID (RFC 5001) */
-               tcp_keepalive, header_only, ednsneg, mapped,
-               print_unknown_format, multiline, nottl, noclass, onesoa,
-               use_usec, nocrypto, ttlunits, idnin, idnout, expandaaaa, qr,
-               setqid,        /*% use a specified query ID */
-               tls_mode;      /*% connect using TLS */
-       char textname[MXNAME]; /*% Name we're going to be
-                               * looking up */
+               trace_root, /*% initial query for either +trace or +nssearch */
+               ttlunits, use_usec, waiting_connect, zflag;
+       char textname[MXNAME]; /*% Name we're going to be looking up */
        char cmdline[MXNAME];
        dns_rdatatype_t rdtype;
        dns_rdatatype_t qrdtype;
diff --git a/bin/tests/system/dns64/ns1/ipv4only.arpa.db b/bin/tests/system/dns64/ns1/ipv4only.arpa.db
new file mode 100644 (file)
index 0000000..92257ad
--- /dev/null
@@ -0,0 +1,4 @@
+ipv4only.arpa.         3600    IN      SOA     . . 2018112766 7200 3600 604800 3600
+ipv4only.arpa.         3600    IN      NS      .
+ipv4only.arpa.         3600    IN      A       192.0.0.170
+ipv4only.arpa.         3600    IN      A       192.0.0.171
similarity index 84%
rename from bin/tests/system/dns64/ns1/named.conf.in
rename to bin/tests/system/dns64/ns1/named.conf1.in
index 900e9fae178aebb1e87ce0563cdf114ee61e93c9..f2c3a2c473d948d6116f306db925f7a6cd9cb623 100644 (file)
 
 // NS1
 
+include "../../common/rndc.key";
+
+controls {
+        inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
 acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
 
 options {
@@ -49,4 +55,7 @@ zone "signed" {
        file "signed.db.signed";
 };
 
-// include "trusted.conf";
+zone "ipv4only.arpa" {
+       type master;
+       file "ipv4only.arpa.db";
+};
diff --git a/bin/tests/system/dns64/ns1/named.conf2.in b/bin/tests/system/dns64/ns1/named.conf2.in
new file mode 100644 (file)
index 0000000..5b5b0b4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+// NS1
+
+include "../../common/rndc.key";
+
+controls {
+        inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
+
+options {
+       query-source address 10.53.0.1;
+       notify-source 10.53.0.1;
+       transfer-source 10.53.0.1;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.1; };
+       listen-on-v6 { none; };
+       allow-recursion { 10.53.0.1; };
+       notify yes;
+       dnssec-validation yes;
+
+       dns64 2001:bbbb::/96 {
+               clients { any; };
+               mapped { !rfc1918; any; };
+               exclude { 2001:eeee::/32; 64:FF9B::/96; ::ffff:0000:0000/96; };
+               suffix ::;
+               recursive-only yes;
+       };
+       dns64 2001:aaaa::/64 {
+               mapped { !rfc1918; any; };
+       };
+};
+
+zone "." {
+       type primary;
+       file "root.db";
+};
+
+zone "example" {
+       type primary;
+       file "example.db";
+};
+
+zone "signed" {
+       type primary;
+       file "signed.db.signed";
+};
+
+zone "ipv4only.arpa" {
+       type master;
+       file "ipv4only.arpa.db";
+};
diff --git a/bin/tests/system/dns64/ns1/named.conf3.in b/bin/tests/system/dns64/ns1/named.conf3.in
new file mode 100644 (file)
index 0000000..2b4212c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+// NS1
+
+include "../../common/rndc.key";
+
+controls {
+        inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
+
+options {
+       query-source address 10.53.0.1;
+       notify-source 10.53.0.1;
+       transfer-source 10.53.0.1;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.1; };
+       listen-on-v6 { none; };
+       allow-recursion { 10.53.0.1; };
+       notify yes;
+       dnssec-validation yes;
+};
+
+zone "." {
+       type primary;
+       file "root.db";
+};
+
+zone "example" {
+       type primary;
+       file "example.db";
+};
+
+zone "signed" {
+       type primary;
+       file "signed.db.signed";
+};
+
+zone "ipv4only.arpa" {
+       type master;
+       file "ipv4only.arpa.db";
+};
index 4ef2c8e467c84b7ce228ac754e82bdaf4e2e2d7a..1ab143111c51322e89430144dabc524b7631e9fa 100644 (file)
@@ -11,7 +11,7 @@
 
 . ../conf.sh
 
-copy_setports ns1/named.conf.in ns1/named.conf
+copy_setports ns1/named.conf1.in ns1/named.conf
 copy_setports ns2/named.conf.in ns2/named.conf
 
 cd ns1 && $SHELL sign.sh
index 3126a02bd5d14deb49fa65179be1c6a40bf7eec0..753de1f2aa3e912d1265a25c230815537225ff98 100644 (file)
@@ -1399,5 +1399,35 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
+echo_i "checking 'dig +dns64prefix' ($n)"
+$DIG $DIGOPTS +dns64prefix @10.53.0.1 > dig.out.ns1.test$n || ret=1
+grep '^2001:bbbb::/96$' dig.out.ns1.test$n > /dev/null || ret=1
+test $(wc -l < dig.out.ns1.test$n) -eq 1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+copy_setports ns1/named.conf2.in ns1/named.conf
+rndc_reload ns1 10.53.0.1
+
+echo_i "checking 'dig +dns64prefix' with multiple prefixes ($n)"
+$DIG $DIGOPTS +dns64prefix @10.53.0.1 > dig.out.ns1.test$n || ret=1
+grep '^2001:bbbb::/96$' dig.out.ns1.test$n > /dev/null || ret=1
+grep '2001:aaaa::/64' dig.out.ns1.test$n > /dev/null || ret=1
+test $(wc -l < dig.out.ns1.test$n) -eq 2 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+copy_setports ns1/named.conf3.in ns1/named.conf
+rndc_reload ns1 10.53.0.1
+
+echo_i "checking 'dig +dns64prefix' with no prefixes ($n)"
+$DIG $DIGOPTS +dns64prefix @10.53.0.1 > dig.out.ns1.test$n || ret=1
+test $(wc -l < dig.out.ns1.test$n) -eq 0 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1
index 51b131ec6c4ce94b07d4f35e2d046f9b6a552e1b..71dd657d6d4d173e2f9332e388846a104131ab58 100644 (file)
@@ -309,6 +309,9 @@ key ID is displayed as the replacement, e.g. \fB[ key id = value ]\fP\&.
 .B \fB+[no]defname\fP
 This option, which is deprecated, is treated as a synonym for \fB+[no]search\fP\&.
 .TP
+.B \fB+[no]dns64prefix\fP
+Lookup IPV4ONLY.ARPA AAAA and print any DNS64 prefixes found.
+.TP
 .B \fB+[no]dnssec\fP
 This option requests that DNSSEC records be sent by setting the DNSSEC OK (DO) bit in
 the OPT record in the additional section of the query.